From 09c23a938d68bd3993f88cc0a5ff31bb917e4948 Mon Sep 17 00:00:00 2001 From: cfrainay <clement.frainay@inrae.fr> Date: Thu, 28 Jul 2022 16:44:43 +0200 Subject: [PATCH 1/3] Add app to turn SBML into lists of entities --- .../attributes/DecomposeSBML.java | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/DecomposeSBML.java diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/DecomposeSBML.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/DecomposeSBML.java new file mode 100644 index 000000000..c483a3f9d --- /dev/null +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/DecomposeSBML.java @@ -0,0 +1,134 @@ +package fr.inrae.toulouse.metexplore.met4j_toolbox.attributes; + +import fr.inrae.toulouse.metexplore.met4j_core.biodata.*; +import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; +import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; +import org.kohsuke.args4j.Option; + +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; + +public class DecomposeSBML extends AbstractMet4jApplication { + + + @ParameterType(name= EnumParameterTypes.InputFile) + @Format(name= EnumFormats.Sbml) + @Option(name = "-i", usage = "Input SBML file", required = true) + public String sbml; + + @ParameterType(name= EnumParameterTypes.Boolean) + @Option(name = "-m", aliases = {"--metabolites"}, usage = "Extract Metabolites", required = false) + public Boolean printMetabolites = false; + @ParameterType(name= EnumParameterTypes.Boolean) + @Option(name = "-r", aliases = {"--reactions"}, usage = "Extract Reactions", required = false) + public Boolean printReactions = false; + @ParameterType(name= EnumParameterTypes.Boolean) + @Option(name = "-c", aliases = {"--compartments"}, usage = "Extract Compartments", required = false) + public Boolean printCompartments = false; + @ParameterType(name= EnumParameterTypes.Boolean) + @Option(name = "-p", aliases = {"--pathways"}, usage = "Extract Pathways", required = false) + public Boolean printPathways = false; + @ParameterType(name= EnumParameterTypes.Boolean) + @Option(name = "-g", aliases = {"--genes"}, usage = "Extract Genes", required = false) + public Boolean printGenes = false; + + @ParameterType(name= EnumParameterTypes.Boolean) + @Option(name = "-nt", aliases = {"--noTypeCol"}, usage = "Do not output type column", required = false) + public Boolean noTypeCol = false; + + @ParameterType(name= EnumParameterTypes.OutputFile) + @Format(name= EnumFormats.Tsv) + @Option(name = "-o", usage = "Output file", required=true) + public String outputFile; + + /** + * <p>main.</p> + * + * @param args an array of {@link java.lang.String} objects. + */ + public static void main(String[] args) { + DecomposeSBML app = new DecomposeSBML(); + app.parseArguments(args); + app.run(); + } + + /** + * <p>run.</p> + */ + public void run() { + + String fileIn = this.sbml; + JsbmlReader reader = new JsbmlReader(fileIn); + BioNetwork network = null; + try { + network = reader.read(); + } catch (Met4jSbmlReaderException e) { + System.err.println("Error while reading the SBML file"); + System.err.println(e.getMessage()); + System.exit(1); + } + + //default case: everything printed + if(!(printMetabolites|printReactions|printPathways|printGenes|printCompartments)){ + printMetabolites=printReactions=printPathways=printGenes=printCompartments=true; + } + + try (PrintWriter writer = new PrintWriter(new FileWriter(this.outputFile, false))) { + + if(!noTypeCol) writer.println("ID\tEntity.Type"); + if(printMetabolites){ + for (BioMetabolite metabolite : network.getMetabolitesView()) { + writer.println(noTypeCol ? metabolite.getId() : metabolite.getId() + "\tMETABOLITE"); + } + } + if(printReactions){ + for (BioReaction reaction : network.getReactionsView()) { + writer.println(noTypeCol ? reaction.getId() : reaction.getId() + "\tREACTION"); + } + } + if(printGenes){ + for (BioGene gene : network.getGenesView()) { + writer.println(noTypeCol ? gene.getId() : gene.getId() + "\tGENE"); + } + } + if(printPathways){ + for (BioPathway pathway : network.getPathwaysView()) { + writer.println(noTypeCol ? pathway.getId() : pathway.getId() + "\tPATHWAY"); + } + } + if(printCompartments){ + for (BioCompartment compartment : network.getCompartmentsView()) { + writer.println(noTypeCol ? compartment.getId() : compartment.getId() + "\tCOMPARTMENT"); + } + } + + } catch (IOException e) { + System.err.println("Error while writing SBML entities"); + System.exit(1); + } + } + + @Override + public String getLabel() { + return this.getClass().getSimpleName(); + } + + @Override + public String getLongDescription() { + return "Parse SBML to render list of composing entities: metabolites, reactions, genes, pathways and compartments. " + + "The output file is a tsv with two columns, one with entities identifiers, and one with the entity type. " + + "If no entity type is selected, by default all of them are taken into account. " + + "Only identifiers are written, attributes can be extracted from dedicated apps or from the SBML2Tab."; + } + + @Override + public String getShortDescription() { + return "Parse SBML to render list of composing entities: metabolites, reactions, genes and others."; + } +} -- GitLab From 06239a8fc1f9a00956394da2e1291a094502d3e7 Mon Sep 17 00:00:00 2001 From: cfrainay <clement.frainay@inrae.fr> Date: Thu, 28 Jul 2022 17:54:57 +0200 Subject: [PATCH 2/3] Add app to get substrates and/or products list from a list of reactions --- .../attributes/GetReactantsFromReactions.java | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/GetReactantsFromReactions.java diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/GetReactantsFromReactions.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/GetReactantsFromReactions.java new file mode 100644 index 000000000..336ac4dd7 --- /dev/null +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/GetReactantsFromReactions.java @@ -0,0 +1,141 @@ +package fr.inrae.toulouse.metexplore.met4j_toolbox.attributes; + +import fr.inrae.toulouse.metexplore.met4j_core.biodata.*; +import fr.inrae.toulouse.metexplore.met4j_core.biodata.collection.BioCollection; +import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; +import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; +import fr.inrae.toulouse.metexplore.met4j_mapping.Mapper; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; +import org.kohsuke.args4j.Option; + +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; + +public class GetReactantsFromReactions extends AbstractMet4jApplication { + + + @ParameterType(name= EnumParameterTypes.InputFile) + @Format(name= EnumFormats.Sbml) + @Option(name = "-i", usage = "Input SBML file", required = true) + public String sbml; + + @ParameterType(name= EnumParameterTypes.InputFile) + @Format(name= EnumFormats.Tsv) + @Option(name = "-r", usage = "Input Reaction file", required = true) + public String reactionFile; + + @ParameterType(name= EnumParameterTypes.Text) + @Option(name = "-sep", usage = "Separator in reaction file", required = false) + public String sep = "\t"; + @ParameterType(name= EnumParameterTypes.Boolean) + @Option(name = "-header", usage = "Skip reaction file header", required = false) + public boolean hasHeader = false; + @ParameterType(name= EnumParameterTypes.Integer) + @Option(name = "-col", usage = "Column number in reaction file (first as 1)", required = false) + public int i=1; + + @ParameterType(name= EnumParameterTypes.Boolean) + @Option(name = "-s", aliases = {"--substrates"}, usage = "Extract substrates only", required = false) + public Boolean printSubstrates = false; + @ParameterType(name= EnumParameterTypes.Boolean) + @Option(name = "-p", aliases = {"--products"}, usage = "Extract products only", required = false) + public Boolean printProducts = false; + + @ParameterType(name= EnumParameterTypes.OutputFile) + @Format(name= EnumFormats.Tsv) + @Option(name = "-o", usage = "Output file", required=true) + public String outputFile; + + /** + * <p>main.</p> + * + * @param args an array of {@link java.lang.String} objects. + */ + public static void main(String[] args) { + GetReactantsFromReactions app = new GetReactantsFromReactions(); + app.parseArguments(args); + app.run(); + } + + + /** + * <p>run.</p> + */ + public void run() { + + //read SBML, create bionetwork + String fileIn = this.sbml; + JsbmlReader reader = new JsbmlReader(fileIn); + BioNetwork network = null; + try { + network = reader.read(); + } catch (Met4jSbmlReaderException e) { + System.err.println("Error while reading the SBML file"); + System.err.println(e.getMessage()); + System.exit(1); + } + + //Import Reaction File + BioCollection<BioReaction> input = new BioCollection<>(); + try { + BioNetwork finalNetwork = network; + Mapper map = new Mapper(finalNetwork, bioNetwork -> { + return finalNetwork.getReactionsView(); + }) + .columnSeparator(sep) + .idColumn(i) + .skipIfNotFound(); + if(hasHeader) map = map.skipHeader(); + input = map.map(reactionFile); + System.err.println(input.size()+" reactions mapped"); + System.err.println(map.getNumberOfSkippedEntries()+" reactions not found in model"); + } catch (IOException e) { + System.err.println("Error while reading the Reaction file"); + System.err.println(e.getMessage()); + System.exit(1); + } + + //default case: everything printed + if(!(printSubstrates|printProducts)){ + printSubstrates=printProducts=true; + } + + //Print output + try (PrintWriter writer = new PrintWriter(new FileWriter(this.outputFile, false))) { + for (BioReaction r : input){ + BioCollection<BioMetabolite> metabolites = new BioCollection<>(); + if(printSubstrates || r.isReversible()) metabolites.addAll(network.getLefts(r)); + if(printProducts || r.isReversible()) metabolites.addAll(network.getRights(r)); + for (BioMetabolite m : metabolites) { + writer.println(r.getId()+"\t"+m.getId()); + } + } + } catch (IOException e) { + System.err.println("Error while writing SBML entities"); + System.exit(1); + } + } + + @Override + public String getLabel() { + return this.getClass().getSimpleName(); + } + + @Override + public String getLongDescription() { + return "Get reactants lists from a list of reactions and a GSMN. Output a tab-separated file " + + "with one row per reactant, reaction identifiers in first column, reactant identifiers in second column. " + + "It can provides substrates, products, or both (by default). In the case of reversible reactions, " + + "all reactants are considered both substrates and products"; + } + + @Override + public String getShortDescription() { + return "Get reactants lists from a list of reactions and a GSMN."; + } +} -- GitLab From 3df40b4bd07cec01727d2294379890ca5a45cd4c Mon Sep 17 00:00:00 2001 From: cfrainay <clement.frainay@inrae.fr> Date: Thu, 28 Jul 2022 18:10:04 +0200 Subject: [PATCH 3/3] Add app to get gene list from a list of reactions and SBML GPR annotations --- .../attributes/GetGenesFromReactions.java | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/GetGenesFromReactions.java diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/GetGenesFromReactions.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/GetGenesFromReactions.java new file mode 100644 index 000000000..777cba704 --- /dev/null +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/attributes/GetGenesFromReactions.java @@ -0,0 +1,128 @@ +package fr.inrae.toulouse.metexplore.met4j_toolbox.attributes; + +import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioGene; +import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioMetabolite; +import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioNetwork; +import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioReaction; +import fr.inrae.toulouse.metexplore.met4j_core.biodata.collection.BioCollection; +import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.JsbmlReader; +import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException; +import fr.inrae.toulouse.metexplore.met4j_mapping.Mapper; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.AbstractMet4jApplication; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumFormats; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.EnumParameterTypes; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.Format; +import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.annotations.ParameterType; +import org.kohsuke.args4j.Option; + +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; + +public class GetGenesFromReactions extends AbstractMet4jApplication { + + + @ParameterType(name= EnumParameterTypes.InputFile) + @Format(name= EnumFormats.Sbml) + @Option(name = "-i", usage = "Input SBML file", required = true) + public String sbml; + + @ParameterType(name= EnumParameterTypes.InputFile) + @Format(name= EnumFormats.Tsv) + @Option(name = "-r", usage = "Input Reaction file", required = true) + public String reactionFile; + + @ParameterType(name= EnumParameterTypes.Text) + @Option(name = "-sep", usage = "Separator in reaction file", required = false) + public String sep = "\t"; + @ParameterType(name= EnumParameterTypes.Boolean) + @Option(name = "-header", usage = "Skip reaction file header", required = false) + public boolean hasHeader = false; + @ParameterType(name= EnumParameterTypes.Integer) + @Option(name = "-col", usage = "Column number in reaction file (first as 1)", required = false) + public int i=1; + + @ParameterType(name= EnumParameterTypes.OutputFile) + @Format(name= EnumFormats.Tsv) + @Option(name = "-o", usage = "Output file", required=true) + public String outputFile; + + /** + * <p>main.</p> + * + * @param args an array of {@link String} objects. + */ + public static void main(String[] args) { + GetGenesFromReactions app = new GetGenesFromReactions(); + app.parseArguments(args); + app.run(); + } + + + /** + * <p>run.</p> + */ + public void run() { + + //read SBML, create bionetwork + String fileIn = this.sbml; + JsbmlReader reader = new JsbmlReader(fileIn); + BioNetwork network = null; + try { + network = reader.read(); + } catch (Met4jSbmlReaderException e) { + System.err.println("Error while reading the SBML file"); + System.err.println(e.getMessage()); + System.exit(1); + } + + //Import Reaction File + BioCollection<BioReaction> input = new BioCollection<>(); + try { + BioNetwork finalNetwork = network; + Mapper map = new Mapper(finalNetwork, bioNetwork -> { + return finalNetwork.getReactionsView(); + }) + .columnSeparator(sep) + .idColumn(i) + .skipIfNotFound(); + if(hasHeader) map = map.skipHeader(); + input = map.map(reactionFile); + System.err.println(input.size()+" reactions mapped"); + System.err.println(map.getNumberOfSkippedEntries()+" reactions not found in model"); + } catch (IOException e) { + System.err.println("Error while reading the Reaction file"); + System.err.println(e.getMessage()); + System.exit(1); + } + + //Print output + try (PrintWriter writer = new PrintWriter(new FileWriter(this.outputFile, false))) { + for (BioReaction r : input){ + BioCollection<BioGene> genes = network.getGenesFromReactions(r); + for (BioGene g : genes) { + writer.println(r.getId()+"\t"+g.getId()); + } + } + } catch (IOException e) { + System.err.println("Error while writing SBML entities"); + System.exit(1); + } + } + + @Override + public String getLabel() { + return this.getClass().getSimpleName(); + } + + @Override + public String getLongDescription() { + return "Get associated gene list from a list of reactions and a GSMN. Parse GSMN GPR annotations and output a tab-separated file " + + "with one row per gene, associated reaction identifiers from input file in first column, gene identifiers in second column."; + } + + @Override + public String getShortDescription() { + return "Get gene lists from a list of reactions and a GSMN."; + } +} -- GitLab