From 3923b042128a19cca2b3753bddfc925405bdd29b Mon Sep 17 00:00:00 2001
From: cfrainay <clement.frainay@inrae.fr>
Date: Wed, 31 Aug 2022 17:22:37 +0200
Subject: [PATCH 1/7] create apps to export degree and chemical similarity
 weights for compound graphs

---
 .../met4j_toolbox/generic/EdgeWeighting.java  | 136 ++++++++++++++++++
 .../ChemSimilarityWeighting.java              |  47 ++++++
 .../networkAnalysis/DegreeWeighting.java      |  32 +++++
 3 files changed, 215 insertions(+)
 create mode 100644 met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/EdgeWeighting.java
 create mode 100644 met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java
 create mode 100644 met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DegreeWeighting.java

diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/EdgeWeighting.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/EdgeWeighting.java
new file mode 100644
index 000000000..e40702f86
--- /dev/null
+++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/EdgeWeighting.java
@@ -0,0 +1,136 @@
+package fr.inrae.toulouse.metexplore.met4j_toolbox.generic;
+
+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.collection.BioCollection;
+import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting.ReactionProbabilityWeight;
+import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting.WeightUtils;
+import fr.inrae.toulouse.metexplore.met4j_graph.computation.transform.EdgeMerger;
+import fr.inrae.toulouse.metexplore.met4j_graph.computation.transform.VertexContraction;
+import fr.inrae.toulouse.metexplore.met4j_graph.core.WeightingPolicy;
+import fr.inrae.toulouse.metexplore.met4j_graph.core.compound.CompoundGraph;
+import fr.inrae.toulouse.metexplore.met4j_graph.core.compound.ReactionEdge;
+import fr.inrae.toulouse.metexplore.met4j_graph.io.Bionetwork2BioGraph;
+import fr.inrae.toulouse.metexplore.met4j_graph.io.NodeMapping;
+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_io.jsbml.reader.plugin.FBCParser;
+import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.plugin.GroupPathwayParser;
+import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.plugin.NotesParser;
+import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.plugin.PackageParser;
+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.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public abstract class EdgeWeighting extends AbstractMet4jApplication {
+
+    @Format(name= EnumFormats.Sbml)
+    @ParameterType(name= EnumParameterTypes.InputFile)
+    @Option(name = "-s", usage = "input SBML file", required = true)
+    public String inputPath = null;
+
+    @ParameterType(name= EnumParameterTypes.InputFile)
+    @Option(name = "-sc", usage = "input Side compound file", required = false)
+    public String inputSide = null;
+
+    @ParameterType(name= EnumParameterTypes.OutputFile)
+    @Option(name = "-o", usage = "output edge weight file", required = true)
+    public String outputPath = null;
+
+    enum strategy {no, by_name,by_id}
+    @Option(name = "-mc", aliases = {"--mergecomp"}, usage = "merge compartments. " +
+            "Use names if consistent and unambiguous across compartments, or identifiers if compartment suffix is present (id in form \"xxx_y\" with xxx as base identifier and y as compartment label).")
+    public strategy mergingStrat = strategy.no;
+    public String idRegex = "^(\\w+)_\\w$";
+
+    @Option(name = "-me", aliases = {"--simple"}, usage = "merge parallel edges to produce a simple graph", required = false)
+    public boolean mergeEdges = false;
+
+    @Option(name = "-un", aliases = {"--undirected"}, usage = "create as undirected", required = false)
+    public boolean undirected = false;
+
+    @Option(name = "-tp", aliases = {"--transitionproba"}, usage = "set weight as random walk transition probability, normalized by reaction", required = false)
+    public boolean computeWeight = false;
+
+    @Option(name = "-nan", aliases = {"--removeNaN"}, usage = "do not output edges with undefined weight", required = false)
+    public boolean removeNaN = false;
+
+
+    public abstract WeightingPolicy setWeightingPolicy();
+
+    public void run() throws IOException, Met4jSbmlReaderException {
+
+        WeightingPolicy wp = setWeightingPolicy();
+
+        System.out.print("Reading SBML...");
+        JsbmlReader reader = new JsbmlReader(this.inputPath);
+        ArrayList<PackageParser> pkgs = new ArrayList<>(Arrays.asList(
+                new NotesParser(false), new FBCParser(), new GroupPathwayParser()));
+        BioNetwork network = reader.read(pkgs);
+        System.out.println(" Done.");
+
+
+        System.out.print("Buildinig Network...");
+        Bionetwork2BioGraph builder = new Bionetwork2BioGraph(network);
+        CompoundGraph graph = builder.getCompoundGraph();
+        System.out.println(" Done.");
+
+        //Graph processing: side compound removal [optional]
+        if (inputSide != null) {
+            System.err.println("removing side compounds...");
+            NodeMapping<BioMetabolite, ReactionEdge, CompoundGraph> mapper = new NodeMapping<>(graph).skipIfNotFound();
+            BioCollection<BioMetabolite> sideCpds = mapper.map(inputSide);
+            boolean removed = graph.removeAllVertices(sideCpds);
+            if (removed) System.err.println(sideCpds.size() + " compounds removed.");
+        }
+
+        //Graph processing: set weights [optional]
+        wp.setWeight(graph);
+        if(removeNaN) WeightUtils.removeEdgeWithNaNWeight(graph);
+
+        //invert graph as undirected (copy edge weight to reversed edge)
+        if(undirected){
+            System.out.print("Create Undirected...");
+            graph.asUndirected();
+            System.out.println(" Done.");
+        }
+
+        //merge compartment
+        if(mergingStrat!= strategy.no){
+            System.out.print("Merging compartments...");
+            VertexContraction vc = new VertexContraction();
+            VertexContraction.Mapper merger = mergingStrat.equals(strategy.by_name) ? new VertexContraction.MapByName() : new VertexContraction.MapByIdSubString(idRegex);
+            graph = vc.decompartmentalize(graph, merger);
+            System.out.println(" Done.");
+        }
+
+        //compute transitions probability from weights
+        if(computeWeight) {
+            System.out.print("Compute transition matrix...");
+            ReactionProbabilityWeight wp2 = new ReactionProbabilityWeight();
+            wp2.setWeight(graph);
+            System.out.println(" Done.");
+        }
+
+        //merge parallel edges
+        if(mergeEdges){
+            System.out.print("Merging edges...");
+            EdgeMerger.mergeEdgesWithOverride(graph);
+            System.out.println(" Done.");
+        }
+
+        //export graph
+        System.out.print("Exporting...");
+        WeightUtils.export(graph,outputPath);
+        System.out.println(" Done.");
+        return;
+    }
+
+}
+
diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java
new file mode 100644
index 000000000..992306c91
--- /dev/null
+++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java
@@ -0,0 +1,47 @@
+package fr.inrae.toulouse.metexplore.met4j_toolbox.networkAnalysis;
+
+import fr.inrae.toulouse.metexplore.met4j_chemUtils.chemicalSimilarity.FingerprintBuilder;
+import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting.SimilarityWeightPolicy;
+import fr.inrae.toulouse.metexplore.met4j_graph.core.WeightingPolicy;
+import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.EdgeWeighting;
+import org.kohsuke.args4j.Option;
+
+public class ChemSimilarityWeighting extends EdgeWeighting {
+
+    enum strategy {EState,Extended,KlekotaRoth,MACCS,PubChem};
+    @Option(name = "-f", aliases = {"--fingerprint"}, usage = "The chemical fingerprint to use", required = false)
+    public strategy type = strategy.Extended;
+
+    @Option(name = "-d", aliases = {"--asDist"}, usage = "Use distance rather than similarity", required = false)
+    public boolean dist = false;
+    @Override
+
+
+    public WeightingPolicy setWeightingPolicy() {
+        SimilarityWeightPolicy wp = new SimilarityWeightPolicy();
+        switch(type){
+            case EState: wp.setFingerprintType(FingerprintBuilder.ESTATE);
+            case Extended: wp.setFingerprintType(FingerprintBuilder.EXTENDED);
+            case KlekotaRoth: wp.setFingerprintType(FingerprintBuilder.KLEKOTAROTH);
+            case MACCS: wp.setFingerprintType(FingerprintBuilder.MACCS);
+            case PubChem: wp.setFingerprintType(FingerprintBuilder.PUBCHEM);
+        }
+        wp.useDistance(dist);
+        return wp;
+    }
+
+    @Override
+    public String getLabel() {
+        return null;
+    }
+
+    @Override
+    public String getLongDescription() {
+        return null;
+    }
+
+    @Override
+    public String getShortDescription() {
+        return null;
+    }
+}
diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DegreeWeighting.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DegreeWeighting.java
new file mode 100644
index 000000000..b4a0f56bd
--- /dev/null
+++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DegreeWeighting.java
@@ -0,0 +1,32 @@
+package fr.inrae.toulouse.metexplore.met4j_toolbox.networkAnalysis;
+
+import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting.DegreeWeightPolicy;
+import fr.inrae.toulouse.metexplore.met4j_graph.core.WeightingPolicy;
+import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.EdgeWeighting;
+import org.kohsuke.args4j.Option;
+
+public class DegreeWeighting extends EdgeWeighting {
+
+    @Option(name = "-pow", aliases = {"--power"}, usage = "set weights as the degree raised to the power of number in parameter.", required = false)
+    public int pow = 1;
+    @Override
+    public WeightingPolicy setWeightingPolicy() {
+        DegreeWeightPolicy wp = new DegreeWeightPolicy(pow);
+        return wp;
+    }
+
+    @Override
+    public String getLabel() {
+        return null;
+    }
+
+    @Override
+    public String getLongDescription() {
+        return null;
+    }
+
+    @Override
+    public String getShortDescription() {
+        return null;
+    }
+}
-- 
GitLab


From 8b6b1cd9a99618f9b50045545325db2f4b8fa784 Mon Sep 17 00:00:00 2001
From: cfrainay <clement.frainay@inrae.fr>
Date: Wed, 21 Sep 2022 10:23:38 +0200
Subject: [PATCH 2/7] add App description and javadoc

---
 .../met4j_toolbox/generic/EdgeWeighting.java         |  3 +++
 .../networkAnalysis/ChemSimilarityWeighting.java     | 12 +++++++++---
 .../networkAnalysis/DegreeWeighting.java             | 12 +++++++++---
 3 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/EdgeWeighting.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/EdgeWeighting.java
index e40702f86..f5742b724 100644
--- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/EdgeWeighting.java
+++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/EdgeWeighting.java
@@ -28,6 +28,9 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 
+/**
+ * Abstract class for app that provides tabulated compound graph edge list, with one column with edge weight.
+ */
 public abstract class EdgeWeighting extends AbstractMet4jApplication {
 
     @Format(name= EnumFormats.Sbml)
diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java
index 992306c91..e3622cba2 100644
--- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java
+++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java
@@ -6,6 +6,9 @@ import fr.inrae.toulouse.metexplore.met4j_graph.core.WeightingPolicy;
 import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.EdgeWeighting;
 import org.kohsuke.args4j.Option;
 
+/**
+ * App that provides tabulated compound graph edge list, with one column with reactant pair's chemical similarity
+ */
 public class ChemSimilarityWeighting extends EdgeWeighting {
 
     enum strategy {EState,Extended,KlekotaRoth,MACCS,PubChem};
@@ -32,16 +35,19 @@ public class ChemSimilarityWeighting extends EdgeWeighting {
 
     @Override
     public String getLabel() {
-        return null;
+        return this.getClass().getSimpleName();
     }
 
     @Override
     public String getLongDescription() {
-        return null;
+        return "Provides tabulated compound graph edge list, with one column with reactant pair's chemical similarity." +
+                "Chemical similarity has been proposed as edge weight for finding meaningful paths in metabolic networks," +
+                " using shortest (lightest) path search. See McSha et al. 2003 (https://doi.org/10.1093/bioinformatics/btg217)," +
+                " Rahman et al. 2005 (https://doi.org/10.1093/bioinformatics/bti116) and Pertusi et al. 2014 (https://doi.org/10.1093/bioinformatics/btu760)";
     }
 
     @Override
     public String getShortDescription() {
-        return null;
+        return "Provides tabulated compound graph edge list, with one column with reactant pair's chemical similarity.";
     }
 }
diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DegreeWeighting.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DegreeWeighting.java
index b4a0f56bd..3ec24534a 100644
--- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DegreeWeighting.java
+++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DegreeWeighting.java
@@ -5,6 +5,9 @@ import fr.inrae.toulouse.metexplore.met4j_graph.core.WeightingPolicy;
 import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.EdgeWeighting;
 import org.kohsuke.args4j.Option;
 
+/**
+ * App that provides tabulated compound graph edge list, with one column with target's degree.
+ */
 public class DegreeWeighting extends EdgeWeighting {
 
     @Option(name = "-pow", aliases = {"--power"}, usage = "set weights as the degree raised to the power of number in parameter.", required = false)
@@ -17,16 +20,19 @@ public class DegreeWeighting extends EdgeWeighting {
 
     @Override
     public String getLabel() {
-        return null;
+        return this.getClass().getSimpleName();
     }
 
     @Override
     public String getLongDescription() {
-        return null;
+        return "Provides tabulated compound graph edge list, with one column with target's degree." +
+                "Degree has been proposed as edge weight for finding meaningful paths in metabolic networks," +
+                " using shortest (lightest) path search. See Croes et al. 2006 (https://doi.org/10.1016/j.jmb.2005.09.079) and" +
+                " Croes et al. 2005 (https://doi.org/10.1093/nar/gki437)";
     }
 
     @Override
     public String getShortDescription() {
-        return null;
+        return "Provides tabulated compound graph edge list, with one column with target's degree.";
     }
 }
-- 
GitLab


From 98fd83d44f7ea1cc436c2291f81bd372bbdc458e Mon Sep 17 00:00:00 2001
From: cfrainay <clement.frainay@inrae.fr>
Date: Thu, 22 Sep 2022 15:03:08 +0200
Subject: [PATCH 3/7] [mapping] Add attribute mapping in Mapper class

---
 .../metexplore/met4j_mapping/Mapper.java      | 28 ++++++++++++++++-
 .../metexplore/met4j_mapping/MapperTest.java  | 30 +++++++++++++++++++
 2 files changed, 57 insertions(+), 1 deletion(-)

diff --git a/met4j-mapping/src/main/java/fr/inrae/toulouse/metexplore/met4j_mapping/Mapper.java b/met4j-mapping/src/main/java/fr/inrae/toulouse/metexplore/met4j_mapping/Mapper.java
index 884ccb615..e41c4e390 100644
--- a/met4j-mapping/src/main/java/fr/inrae/toulouse/metexplore/met4j_mapping/Mapper.java
+++ b/met4j-mapping/src/main/java/fr/inrae/toulouse/metexplore/met4j_mapping/Mapper.java
@@ -43,7 +43,7 @@ import java.io.BufferedReader;
 import java.io.FileReader;
 import java.io.IOException;
 import java.io.Reader;
-import java.util.Collection;
+import java.util.*;
 import java.util.function.Function;
 import java.util.regex.Pattern;
 
@@ -145,6 +145,32 @@ public class Mapper<E extends BioEntity> {
         return mapping;
     }
 
+    /**
+     * From a tabulated file with one entity identifiers column and attributes columns, return a map with the corresponding entities instances found in the network as value
+     * and a list of attributes as value.
+     * @param reader the input stream holding identifiers
+     * @return a collection of matching entities
+     * @throws IOException
+     */
+    public Map<E, List<String>> mapAttributes(Reader reader) throws IOException {
+        this.skipped =0;
+        BufferedReader breader = new BufferedReader(reader);
+        HashMap<E, List<String>> mapping = new HashMap<>();
+        String line;
+        if(skipHeader) breader.readLine();
+        while ((line = breader.readLine()) != null) {
+            ArrayList<String> parsedLine = new ArrayList<String>(Arrays.asList(line.trim().split(sep)));
+            String id = parsedLine.get(col-1);
+            parsedLine.remove(col-1);
+            E e = this.get(id);
+            if(e!=null){
+                mapping.put(e,parsedLine);
+            }
+        }
+        breader.close();
+        return mapping;
+    }
+
     public int getNumberOfSkippedEntries(){
         return this.skipped;
     }
diff --git a/met4j-mapping/src/test/java/fr/inrae/toulouse/metexplore/met4j_mapping/MapperTest.java b/met4j-mapping/src/test/java/fr/inrae/toulouse/metexplore/met4j_mapping/MapperTest.java
index f8ed1a37b..771649669 100644
--- a/met4j-mapping/src/test/java/fr/inrae/toulouse/metexplore/met4j_mapping/MapperTest.java
+++ b/met4j-mapping/src/test/java/fr/inrae/toulouse/metexplore/met4j_mapping/MapperTest.java
@@ -12,6 +12,7 @@ import java.io.IOException;
 import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 
 import static org.junit.Assert.*;
 
@@ -97,6 +98,35 @@ public class MapperTest {
         }
     }
 
+    @Test
+    public void testMapper22(){
+        Mapper<BioMetabolite> m = new Mapper<>(bn, BioNetwork::getMetabolitesView)
+                .columnSeparator("\t")
+                .idColumn(2)
+                .skipHeader()
+                .skipIfNotFound();
+        try {
+            Map<BioMetabolite,List<String>> res = m.mapAttributes(r1);
+            assertEquals("wrong number of mapped entries", 3, res.size());
+            assertEquals("wrong number of skipped entries", 1, m.getNumberOfSkippedEntries());
+            assertTrue("reaction in file not found", res.keySet().contains(a));
+            assertTrue("reaction in file not found", res.keySet().contains(b));
+            assertTrue("reaction in file not found", res.keySet().contains(c));
+            assertEquals("Wrong number of attributes", 2,res.get(a).size());
+            assertEquals("Wrong number of attributes", 2,res.get(b).size());
+            assertEquals("Wrong number of attributes", 2,res.get(c).size());
+            assertEquals("Wrong attribute value", "A",res.get(a).get(0));
+            assertEquals("Wrong attribute value", "0.1",res.get(a).get(1));
+            assertEquals("Wrong attribute value", "B",res.get(b).get(0));
+            assertEquals("Wrong attribute value", "0.2",res.get(b).get(1));
+            assertEquals("Wrong attribute value", "C",res.get(c).get(0));
+            assertEquals("Wrong attribute value", "0.3",res.get(c).get(1));
+        } catch (IOException e) {
+            Assert.fail("mapping failed");
+            e.printStackTrace();
+        }
+    }
+
     @Test
     public void testMapper3(){
         Mapper<BioReaction> m = new Mapper<>(bn, BioNetwork::getReactionsView).skipIfNotFound();
-- 
GitLab


From 73150b1db1d364d606d07cf247d9466fddd5c0bf Mon Sep 17 00:00:00 2001
From: cfrainay <clement.frainay@inrae.fr>
Date: Thu, 22 Sep 2022 15:04:05 +0200
Subject: [PATCH 4/7] add optional processing in Abstract weighting app

---
 .../met4j_toolbox/generic/EdgeWeighting.java  | 20 +++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/EdgeWeighting.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/EdgeWeighting.java
index f5742b724..1cc13fb4a 100644
--- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/EdgeWeighting.java
+++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/generic/EdgeWeighting.java
@@ -76,12 +76,14 @@ public abstract class EdgeWeighting extends AbstractMet4jApplication {
         ArrayList<PackageParser> pkgs = new ArrayList<>(Arrays.asList(
                 new NotesParser(false), new FBCParser(), new GroupPathwayParser()));
         BioNetwork network = reader.read(pkgs);
+        network = processNetwork(network);
         System.out.println(" Done.");
 
 
         System.out.print("Buildinig Network...");
         Bionetwork2BioGraph builder = new Bionetwork2BioGraph(network);
         CompoundGraph graph = builder.getCompoundGraph();
+        graph = processCompoundGraph(graph);
         System.out.println(" Done.");
 
         //Graph processing: side compound removal [optional]
@@ -135,5 +137,23 @@ public abstract class EdgeWeighting extends AbstractMet4jApplication {
         return;
     }
 
+    /**
+     * Methods to add optional preprocessing of the compound graph
+     * @param graph the original compound graph
+     * @return a preprocessed graph
+     */
+    public CompoundGraph processCompoundGraph(CompoundGraph graph) {
+        return graph;
+    }
+
+    /**
+     * Methods to add optional preprocessing of SBML parsing output
+     * @param network the original network from parsed SBML
+     * @return a preprocessed network
+     */
+    public BioNetwork processNetwork(BioNetwork network) {
+        return network;
+    }
+
 }
 
-- 
GitLab


From da89456f6070f65bc6abdfb658e054fa9ce145c9 Mon Sep 17 00:00:00 2001
From: cfrainay <clement.frainay@inrae.fr>
Date: Thu, 22 Sep 2022 15:04:40 +0200
Subject: [PATCH 5/7] add missing main + add SMILE/INCHI import in chemical
 similarity weighting

---
 .../ChemSimilarityWeighting.java              | 62 ++++++++++++++++++-
 .../networkAnalysis/DegreeWeighting.java      | 14 +++++
 2 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java
index e3622cba2..42e5abc50 100644
--- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java
+++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java
@@ -1,11 +1,21 @@
 package fr.inrae.toulouse.metexplore.met4j_toolbox.networkAnalysis;
 
 import fr.inrae.toulouse.metexplore.met4j_chemUtils.chemicalSimilarity.FingerprintBuilder;
+import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioMetabolite;
+import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioNetwork;
 import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting.SimilarityWeightPolicy;
 import fr.inrae.toulouse.metexplore.met4j_graph.core.WeightingPolicy;
+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.EdgeWeighting;
 import org.kohsuke.args4j.Option;
 
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
 /**
  * App that provides tabulated compound graph edge list, with one column with reactant pair's chemical similarity
  */
@@ -15,11 +25,15 @@ public class ChemSimilarityWeighting extends EdgeWeighting {
     @Option(name = "-f", aliases = {"--fingerprint"}, usage = "The chemical fingerprint to use", required = false)
     public strategy type = strategy.Extended;
 
+    @Option(name = "-sm", aliases = {"--smileFile"}, usage = "If not present in SBML's annotations, get structure from a tabulated file with first column as compound id and second column as SMILE string, no header. Ignored if inchi file is provided", required = false)
+    public String smileFile;
+    @Option(name = "-in", aliases = {"--inchiFile"}, usage = "If not present in SBML's annotations, get structure from a tabulated file with first column as compound id and second column as InChI string, no header.", required = false)
+    public String inchiFile;
+
     @Option(name = "-d", aliases = {"--asDist"}, usage = "Use distance rather than similarity", required = false)
     public boolean dist = false;
-    @Override
-
 
+    @Override
     public WeightingPolicy setWeightingPolicy() {
         SimilarityWeightPolicy wp = new SimilarityWeightPolicy();
         switch(type){
@@ -33,6 +47,50 @@ public class ChemSimilarityWeighting extends EdgeWeighting {
         return wp;
     }
 
+    @Override
+    public BioNetwork processNetwork(BioNetwork bn){
+        if(inchiFile!=null){
+            Mapper m = new Mapper<>(bn, BioNetwork::getMetabolitesView)
+                    .columnSeparator("\t")
+                    .idColumn(1)
+                    .skipIfNotFound();
+            try {
+                Map<BioMetabolite, List<String>> att = m.mapAttributes(new BufferedReader(new FileReader(inchiFile)));
+                for(Map.Entry<BioMetabolite, List<String>> entry : att.entrySet()){
+                    entry.getKey().setInchi(entry.getValue().get(0));
+                }
+            } catch (IOException e) {
+                System.err.println("Error reading InChI file");
+                throw new RuntimeException(e);
+            }
+        } else if (smileFile!=null) {
+            Mapper m = new Mapper<>(bn, BioNetwork::getMetabolitesView)
+                    .columnSeparator("\t")
+                    .idColumn(1)
+                    .skipIfNotFound();
+            try {
+                Map<BioMetabolite, List<String>> att = m.mapAttributes(new BufferedReader(new FileReader(smileFile)));
+                for(Map.Entry<BioMetabolite, List<String>> entry : att.entrySet()){
+                    entry.getKey().setSmiles(entry.getValue().get(0));
+                }
+            } catch (IOException e) {
+                System.err.println("Error reading InChI file");
+                throw new RuntimeException(e);
+            }
+        }
+        return bn;
+    }
+
+    public static void main(String[] args) throws Met4jSbmlReaderException, IOException {
+
+        ChemSimilarityWeighting app = new ChemSimilarityWeighting();
+
+        app.parseArguments(args);
+
+        app.run();
+
+    }
+
     @Override
     public String getLabel() {
         return this.getClass().getSimpleName();
diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DegreeWeighting.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DegreeWeighting.java
index 3ec24534a..a55cb91bd 100644
--- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DegreeWeighting.java
+++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DegreeWeighting.java
@@ -2,9 +2,12 @@ package fr.inrae.toulouse.metexplore.met4j_toolbox.networkAnalysis;
 
 import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting.DegreeWeightPolicy;
 import fr.inrae.toulouse.metexplore.met4j_graph.core.WeightingPolicy;
+import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException;
 import fr.inrae.toulouse.metexplore.met4j_toolbox.generic.EdgeWeighting;
 import org.kohsuke.args4j.Option;
 
+import java.io.IOException;
+
 /**
  * App that provides tabulated compound graph edge list, with one column with target's degree.
  */
@@ -12,12 +15,23 @@ public class DegreeWeighting extends EdgeWeighting {
 
     @Option(name = "-pow", aliases = {"--power"}, usage = "set weights as the degree raised to the power of number in parameter.", required = false)
     public int pow = 1;
+
     @Override
     public WeightingPolicy setWeightingPolicy() {
         DegreeWeightPolicy wp = new DegreeWeightPolicy(pow);
         return wp;
     }
 
+    public static void main(String[] args) throws Met4jSbmlReaderException, IOException {
+
+        DegreeWeighting app = new DegreeWeighting();
+
+        app.parseArguments(args);
+
+        app.run();
+
+    }
+
     @Override
     public String getLabel() {
         return this.getClass().getSimpleName();
-- 
GitLab


From b63f6a536bdbd1350d362b3d5ed41f3c778eee49 Mon Sep 17 00:00:00 2001
From: cfrainay <clement.frainay@inrae.fr>
Date: Thu, 22 Sep 2022 15:29:24 +0200
Subject: [PATCH 6/7] add check for missing chemical structure in
 chemsimilarity

---
 .../networkAnalysis/ChemSimilarityWeighting.java    | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java
index 42e5abc50..5b1566593 100644
--- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java
+++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/ChemSimilarityWeighting.java
@@ -3,6 +3,7 @@ package fr.inrae.toulouse.metexplore.met4j_toolbox.networkAnalysis;
 import fr.inrae.toulouse.metexplore.met4j_chemUtils.chemicalSimilarity.FingerprintBuilder;
 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.utils.StringUtils;
 import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting.SimilarityWeightPolicy;
 import fr.inrae.toulouse.metexplore.met4j_graph.core.WeightingPolicy;
 import fr.inrae.toulouse.metexplore.met4j_io.jsbml.reader.Met4jSbmlReaderException;
@@ -78,6 +79,18 @@ public class ChemSimilarityWeighting extends EdgeWeighting {
                 throw new RuntimeException(e);
             }
         }
+        int s = 0;
+        int i = 0;
+        for(BioMetabolite m : bn.getMetabolitesView()){
+            if(!StringUtils.isVoid(m.getSmiles())) s++;
+            if(!StringUtils.isVoid(m.getInchi())) i++;
+        }
+        System.out.println(s+"/"+bn.getMetabolitesView().size()+" metabolites with SMILE");
+        System.out.println(i+"/"+bn.getMetabolitesView().size()+" metabolites with InChI");
+        if((i+s)==0){
+            System.err.println("Error: no chemical structure provided, unable to compute chemical similarity");
+            System.exit(1);
+        }
         return bn;
     }
 
-- 
GitLab


From 36967fd22bcc34cd024cd37504accae7dfc82d9c Mon Sep 17 00:00:00 2001
From: cfrainay <clement.frainay@inrae.fr>
Date: Thu, 22 Sep 2022 15:31:01 +0200
Subject: [PATCH 7/7] update changelog

---
 CHANGELOG.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index d7af514b8..66361e8d9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Features
 
+[met4j-toolbox] Add Apps to compute compound graph's classical weights (degree/chemical similarity)
 [met4j-graph] Add method to create RPAIRs-like tags on compound graph's edges
 
 
-- 
GitLab