diff --git a/met4j-graph/src/main/java/fr/inrae/toulouse/metexplore/met4j_graph/computation/connect/weighting/CustomWeightPolicy.java b/met4j-graph/src/main/java/fr/inrae/toulouse/metexplore/met4j_graph/computation/connect/weighting/CustomWeightPolicy.java new file mode 100644 index 0000000000000000000000000000000000000000..fc17ea42a66c097a1ce97cb6a0a910f255031de1 --- /dev/null +++ b/met4j-graph/src/main/java/fr/inrae/toulouse/metexplore/met4j_graph/computation/connect/weighting/CustomWeightPolicy.java @@ -0,0 +1,34 @@ +package fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting; + +import fr.inrae.toulouse.metexplore.met4j_core.biodata.BioEntity; +import fr.inrae.toulouse.metexplore.met4j_graph.core.BioGraph; +import fr.inrae.toulouse.metexplore.met4j_graph.core.Edge; +import fr.inrae.toulouse.metexplore.met4j_graph.core.WeightingPolicy; + +import java.util.function.Function; + +/** + * An all-purpose class to provides edge weights from a given function + * @param <V> + * @param <E> + * @param <G> + */ +public class CustomWeightPolicy<V extends BioEntity, E extends Edge<V>,G extends BioGraph<V,E>> extends WeightingPolicy<V,E,G> { + + Function<E,Double> lambda; + + /** + * Create a CustomWeightPolicy + * @param function that takes an edge an return its weight + */ + public CustomWeightPolicy(Function<E,Double> function){ + this.lambda=function; + } + + @Override + public void setWeight(G bioGraph) { + for(E edge : bioGraph.edgeSet()){ + bioGraph.setEdgeWeight(edge,lambda.apply(edge)); + } + } +} diff --git a/met4j-graph/src/main/java/fr/inrae/toulouse/metexplore/met4j_graph/computation/connect/weighting/WeightUtils.java b/met4j-graph/src/main/java/fr/inrae/toulouse/metexplore/met4j_graph/computation/connect/weighting/WeightUtils.java index 6e531ac1c537c3613ba13f18a31d5895b89d17bd..1a9819936240d551ac40083f41323b844b315413 100644 --- a/met4j-graph/src/main/java/fr/inrae/toulouse/metexplore/met4j_graph/computation/connect/weighting/WeightUtils.java +++ b/met4j-graph/src/main/java/fr/inrae/toulouse/metexplore/met4j_graph/computation/connect/weighting/WeightUtils.java @@ -40,6 +40,7 @@ import java.io.FileWriter; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.function.DoubleFunction; import fr.inrae.toulouse.metexplore.met4j_graph.core.BioGraph; import fr.inrae.toulouse.metexplore.met4j_graph.core.Edge; @@ -57,6 +58,20 @@ public class WeightUtils { */ public WeightUtils() { } + + /** + * Apply a function on every edge weight + * @param g the graph + * @param lambda a function that takes an edge weight (Double) and produce a Double + * @param <E> Edge type + * @param <G> Graph type + */ + public static <E extends Edge<?>, G extends BioGraph<?,E>> void process(G g, DoubleFunction<Double> lambda){ + for(E e : g.edgeSet()){ + double w = g.getEdgeWeight(e); + g.setEdgeWeight(e, lambda.apply(w)); + } + } /** * Scale weights between 0 and 1. diff --git a/met4j-graph/src/main/java/fr/inrae/toulouse/metexplore/met4j_graph/core/BioGraph.java b/met4j-graph/src/main/java/fr/inrae/toulouse/metexplore/met4j_graph/core/BioGraph.java index 73cbcaf53a5a12d8eda89b30be0fc0371e6c10bb..5522c93150f804447f21ed8ba0d5605b5ecb8d4f 100644 --- a/met4j-graph/src/main/java/fr/inrae/toulouse/metexplore/met4j_graph/core/BioGraph.java +++ b/met4j-graph/src/main/java/fr/inrae/toulouse/metexplore/met4j_graph/core/BioGraph.java @@ -525,13 +525,15 @@ public abstract class BioGraph<V extends BioEntity, E extends Edge<V>> extends D } /** - * For each edges in the graph, create a copy with reversed source and target. - * This makes this directed graph effectively undirected, but with twice the number of edges + * For each edges in the graph, create a copy with reversed source and target (if not existing already). + * This makes this directed graph effectively undirected, but with twice the number of edges. + * Reversed edges keep the same weight as their origin. */ public void asUndirected(){ - - for(E e : new HashSet<>(this.edgeSet())){ - this.addEdge(reverseEdge(e)); + for(E edge : new HashSet<>(this.edgeSet())){ + E reversedEdge = this.reverseEdge(edge); + this.addEdge(reversedEdge); + this.setEdgeWeight(reversedEdge, this.getEdgeWeight(edge)); } } diff --git a/met4j-graph/src/main/java/fr/inrae/toulouse/metexplore/met4j_graph/core/compound/CompoundGraph.java b/met4j-graph/src/main/java/fr/inrae/toulouse/metexplore/met4j_graph/core/compound/CompoundGraph.java index 5ec7f02027a9c208c724003216a58820fd042385..88b425119f6bfa59160279dba468ae83412d68b0 100644 --- a/met4j-graph/src/main/java/fr/inrae/toulouse/metexplore/met4j_graph/core/compound/CompoundGraph.java +++ b/met4j-graph/src/main/java/fr/inrae/toulouse/metexplore/met4j_graph/core/compound/CompoundGraph.java @@ -220,23 +220,6 @@ public class CompoundGraph extends BioGraph<BioMetabolite, ReactionEdge> { return null; } - @Override - /** - * Handle graph as undirected by creating reverse edges for each existing edge. Do not duplicated edges for reversible reactions - */ - public void asUndirected(){ - for(ReactionEdge e : new HashSet<>(this.edgeSet())){ - if(e.getReaction()==null){ - this.addEdge(reverseEdge(e)); - }else if(!e.getReaction().isReversible()){ - this.addEdge(reverseEdge(e)); - }else if(this.getEdge(e.getV2(),e.getV1(),e.getReaction())==null){ - this.addEdge(reverseEdge(e)); - } - } - } - - /** {@inheritDoc} */ @Override public ReactionEdge copyEdge(ReactionEdge edge) { diff --git a/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestCompoundGraph.java b/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestCompoundGraph.java index d9608c79e4eddef8b2ef7a8502a81ce8816b05ee..e76de06db5590d8dd2cf69f5bda58be0f7c54c0f 100644 --- a/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestCompoundGraph.java +++ b/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestCompoundGraph.java @@ -138,6 +138,9 @@ public class TestCompoundGraph { cg.addEdgesFromReaction(bn,r3); Assert.assertEquals(3, cg.vertexSet().size()); Assert.assertEquals(4, cg.edgeSet().size()); + cg.removeEdge(cg.getEdge(v2,v3,r3)); + Assert.assertEquals(3, cg.vertexSet().size()); + Assert.assertEquals(3, cg.edgeSet().size()); } @Test @@ -171,13 +174,20 @@ public class TestCompoundGraph { assertTrue(g2.containsEdge(e2)); assertTrue(g2.containsVertex(v1)); assertTrue(g2.containsVertex(v2)); + BioMetabolite v4 = new BioMetabolite("v4"); + g2.addVertex(v4); + g2.addEdge(v3,v4,new ReactionEdge(v3,v4,new BioReaction("r4"))); + Assert.assertEquals(cg.vertexSet().size()+1, g2.vertexSet().size()); + Assert.assertEquals(cg.edgeSet().size()+1, g2.edgeSet().size()); + } @Test public void testAddEdge(){ - CompoundGraph g2 = (CompoundGraph) cg.clone(); - g2.addEdge(v3, v1); - Assert.assertEquals(3, g2.edgeSet().size()); + cg.addEdge(v3, v1); + Assert.assertEquals(3, cg.edgeSet().size()); + cg.removeEdge(v3,v1); + Assert.assertEquals(2, cg.edgeSet().size()); } @Test @@ -202,4 +212,40 @@ public class TestCompoundGraph { assertTrue(gr2.containsVertex(v2)); assertTrue(gr2.containsVertex(v3)); } + + @Test + public void testAsUndirected() { + cg.setEdgeWeight(e1,42); + CompoundGraph g2 = new CompoundGraph(cg); + g2.asUndirected(); + Assert.assertEquals(cg.vertexSet().size(), g2.vertexSet().size()); + Assert.assertEquals(cg.edgeSet().size()*2, g2.edgeSet().size()); + for(ReactionEdge e : cg.edgeSet()){ + assertTrue(g2.containsEdge(e.getV1(),e.getV2())); + assertTrue(g2.containsEdge(e.getV2(),e.getV1())); + } + assertEquals(42, g2.getEdgeWeight(g2.getEdge(v1, v2, r1)),Double.MIN_VALUE); + assertEquals(42, g2.getEdgeWeight(g2.getEdge(v2, v1, r1)),Double.MIN_VALUE); + cg.setEdgeWeight(e1,1.0); + } + + @Test + public void testAsUndirected2() { + CompoundGraph g2 = new CompoundGraph(cg); + ReactionEdge e3 = new ReactionEdge(v2, v1, r1); + ReactionEdge e4 = new ReactionEdge(v3, v2, new BioReaction("r4")); + g2.addEdge(e3); g2.setEdgeWeight(e3,42); + g2.addEdge(e4); + g2.asUndirected(); + + Assert.assertEquals(cg.vertexSet().size(), g2.vertexSet().size()); + Assert.assertEquals(cg.edgeSet().size()*2+2, g2.edgeSet().size()); + for(ReactionEdge e : cg.edgeSet()){ + assertTrue(g2.containsEdge(e.getV1(),e.getV2())); + assertTrue(g2.containsEdge(e.getV2(),e.getV1())); + } + assertEquals(1.0, g2.getEdgeWeight(g2.getEdge(v1, v2, r1)),Double.MIN_VALUE); + assertEquals(42.0, g2.getEdgeWeight(g2.getEdge(v2, v1, r1)),Double.MIN_VALUE); + } + } diff --git a/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestShortestPaths.java b/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestShortestPaths.java index cfdb3f2ced419caff1c46198c38ae44f8848612e..788116daf49aa7fc32ed464759f49a49069e26d2 100644 --- a/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestShortestPaths.java +++ b/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestShortestPaths.java @@ -43,6 +43,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.FloydWarshall; import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.KShortestPath; @@ -50,6 +51,7 @@ import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.ShortestPath import fr.inrae.toulouse.metexplore.met4j_graph.computation.analyze.centrality.PathBasedCentrality; import fr.inrae.toulouse.metexplore.met4j_graph.computation.utils.ComputeAdjacencyMatrix; import fr.inrae.toulouse.metexplore.met4j_graph.core.BioPath; +import fr.inrae.toulouse.metexplore.met4j_graph.core.GraphFactory; 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_mathUtils.matrix.BioMatrix; @@ -180,7 +182,7 @@ public class TestShortestPaths { BioPath<BioMetabolite,ReactionEdge> path = pathSearch.getShortest(a, new BioMetabolite("u")); System.out.println(path); } - + @Test public void testGetShortestundirected() { ReactionEdge[] expectedPath = {bc, ab}; @@ -188,8 +190,8 @@ public class TestShortestPaths { BioPath<BioMetabolite,ReactionEdge> path = pathSearch.getShortest(c, a); assertNotNull(path); List<ReactionEdge> sp = path.getEdgeList(); - assertTrue("wrong path", Arrays.asList(expectedPath).containsAll(sp)); - assertTrue("wrong path", sp.containsAll(Arrays.asList(expectedPath))); + assertTrue("wrong path "+sp, Arrays.asList(expectedPath).containsAll(sp)); + assertTrue("wrong path "+sp, sp.containsAll(Arrays.asList(expectedPath))); g.setEdgeWeight(bc, 1000.0); g.setEdgeWeight(ab, 1000.0); @@ -200,6 +202,60 @@ public class TestShortestPaths { assertTrue("wrong weighted path", Arrays.asList(expectedLightestPath).containsAll(res)); assertTrue("wrong weighted path", res.containsAll(Arrays.asList(expectedLightestPath))); } + + @Test + public void testShortestVsShortestUnion() { + + ShortestPath<BioMetabolite, ReactionEdge, CompoundGraph> pathSearch = new ShortestPath<>(g, false); + BioPath<BioMetabolite,ReactionEdge> path1 = pathSearch.getShortest(c, a); + + HashSet source = new HashSet(); source.add(c); + HashSet target = new HashSet(); target.add(a); + List<BioPath<BioMetabolite,ReactionEdge>> pathUnion = pathSearch.getShortestPathsUnionList(source, target); + assertEquals(1,pathUnion.size()); + BioPath<BioMetabolite,ReactionEdge> path2 = pathUnion.get(0); + assertNotNull(path1); + assertNotNull(path2); + assertEquals(path1.getEdgeList(), path2.getEdgeList()); + + g.setEdgeWeight(bc, 1000.0); + g.setEdgeWeight(ab, 1000.0); + BioPath<BioMetabolite,ReactionEdge> path3 =pathSearch.getShortest(c, a); + List<BioPath<BioMetabolite,ReactionEdge>> pathUnion2 = pathSearch.getShortestPathsUnionList(source, target); + assertEquals(1,pathUnion2.size()); + BioPath<BioMetabolite,ReactionEdge> path4 = pathUnion2.get(0); + assertNotNull(path3); + assertNotNull(path4); + assertEquals(path3.getEdgeList(), path4.getEdgeList()); + } + + @Test + public void testUndirectedShortestVsShortestOnUndirected() { + + ShortestPath<BioMetabolite, ReactionEdge, CompoundGraph> pathSearch = new ShortestPath<>(g, false); + BioPath<BioMetabolite,ReactionEdge> path1 = pathSearch.getShortest(c, a); + + CompoundGraph g2 = CompoundGraph.getFactory().createGraphFromElements(g.vertexSet(),g.edgeSet()); + g2.asUndirected(); + ShortestPath<BioMetabolite, ReactionEdge, CompoundGraph> pathSearch2 = new ShortestPath<>(g2, false); + BioPath<BioMetabolite,ReactionEdge> path2 = pathSearch2.getShortest(c, a); + + assertEquals(path1.getEdgeList().stream().map(e->e.getReaction().getId()).collect(Collectors.toList()), + path2.getEdgeList().stream().map(e->e.getReaction().getId()).collect(Collectors.toList())); + + + g.setEdgeWeight(bc, 1000.0); + g.setEdgeWeight(ab, 1000.0); + BioPath<BioMetabolite,ReactionEdge> path3 =pathSearch.getShortest(c, a); + CompoundGraph g3 = CompoundGraph.getFactory().createGraphFromElements(g.vertexSet(),g.edgeSet()); + g3.asUndirected(); + BioPath<BioMetabolite,ReactionEdge> path4 = new ShortestPath<>(g3, false).getShortest(c,a); + + assertEquals(path3.getEdgeList().stream().map(e->e.getReaction().getId()).collect(Collectors.toList()), + path4.getEdgeList().stream().map(e->e.getReaction().getId()).collect(Collectors.toList())); + + } + // @Test // public void testReversibility() { diff --git a/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestWeightUtils.java b/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestWeightUtils.java index 67893b9a6ae61df26209f6a9119af9371ea2bcf6..b7df0ec723895a9f0ca7b8146b334526377a4f6f 100644 --- a/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestWeightUtils.java +++ b/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestWeightUtils.java @@ -106,6 +106,31 @@ public class TestWeightUtils { g.setEdgeWeight(e, 0.0); } } + + @Test + public void testProcess(){ + double abWeight,bcWeight,adWeight,efWeight,bxWeight,ebWeight,deWeight,fcWeight,ycWeight; + abWeight=1;g.setEdgeWeight(ab, abWeight); + bcWeight=2;g.setEdgeWeight(bc, bcWeight); + adWeight=3;g.setEdgeWeight(ad, adWeight); + efWeight=4;g.setEdgeWeight(ef, efWeight); + bxWeight=5;g.setEdgeWeight(bx, bxWeight); + ebWeight=6;g.setEdgeWeight(eb, ebWeight); + deWeight=7;g.setEdgeWeight(de, deWeight); + fcWeight=8;g.setEdgeWeight(fc, fcWeight); + ycWeight=9;g.setEdgeWeight(yc, ycWeight); + WeightUtils.process(g, w -> StrictMath.pow(w, 2)); + + assertEquals("wrong weight after pow", 1, g.getEdgeWeight(ab),Double.MIN_VALUE); + assertEquals("wrong weight after pow", 9, g.getEdgeWeight(ad),Double.MIN_VALUE); + assertEquals("wrong weight after pow", 4, g.getEdgeWeight(bc),Double.MIN_VALUE); + assertEquals("wrong weight after pow", 25, g.getEdgeWeight(bx),Double.MIN_VALUE); + assertEquals("wrong weight after pow", 49, g.getEdgeWeight(de),Double.MIN_VALUE); + assertEquals("wrong weight after pow", 36, g.getEdgeWeight(eb),Double.MIN_VALUE); + assertEquals("wrong weight after pow", 16, g.getEdgeWeight(ef),Double.MIN_VALUE); + assertEquals("wrong weight after pow", 64, g.getEdgeWeight(fc),Double.MIN_VALUE); + assertEquals("wrong weight after pow", 81, g.getEdgeWeight(yc),Double.MIN_VALUE); + } /** * Test the weights inversion diff --git a/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestWeightingPolicy.java b/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestWeightingPolicy.java index 291b6a2272bc0e1adb93c5290ee6d265b8897f87..08ad8f683f83b2c42df0953b770b9a0fc51e7c76 100644 --- a/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestWeightingPolicy.java +++ b/met4j-graph/src/test/java/fr/inrae/toulouse/metexplore/met4j_graph/TestWeightingPolicy.java @@ -175,15 +175,42 @@ public class TestWeightingPolicy { adWeight=efWeight=4; bxWeight=1; wp.setWeight(g); - assertEquals("wrong weight with probability weighting policy", abWeight, g.getEdgeWeight(ab),Double.MIN_VALUE); - assertEquals("wrong weight with probability weighting policy", adWeight, g.getEdgeWeight(ad),Double.MIN_VALUE); - assertEquals("wrong weight with probability weighting policy", bcWeight, g.getEdgeWeight(bc),Double.MIN_VALUE); - assertEquals("wrong weight with probability weighting policy", bxWeight, g.getEdgeWeight(bx),Double.MIN_VALUE); - assertEquals("wrong weight with probability weighting policy", deWeight, g.getEdgeWeight(de),Double.MIN_VALUE); - assertEquals("wrong weight with probability weighting policy", ebWeight, g.getEdgeWeight(eb),Double.MIN_VALUE); - assertEquals("wrong weight with probability weighting policy", efWeight, g.getEdgeWeight(ef),Double.MIN_VALUE); - assertEquals("wrong weight with probability weighting policy", fcWeight, g.getEdgeWeight(fc),Double.MIN_VALUE); - assertEquals("wrong weight with probability weighting policy", ycWeight, g.getEdgeWeight(yc),Double.MIN_VALUE); + assertEquals("wrong weight with degree weighting policy", abWeight, g.getEdgeWeight(ab),Double.MIN_VALUE); + assertEquals("wrong weight with degree weighting policy", adWeight, g.getEdgeWeight(ad),Double.MIN_VALUE); + assertEquals("wrong weight with degree weighting policy", bcWeight, g.getEdgeWeight(bc),Double.MIN_VALUE); + assertEquals("wrong weight with degree weighting policy", bxWeight, g.getEdgeWeight(bx),Double.MIN_VALUE); + assertEquals("wrong weight with degree weighting policy", deWeight, g.getEdgeWeight(de),Double.MIN_VALUE); + assertEquals("wrong weight with degree weighting policy", ebWeight, g.getEdgeWeight(eb),Double.MIN_VALUE); + assertEquals("wrong weight with degree weighting policy", efWeight, g.getEdgeWeight(ef),Double.MIN_VALUE); + assertEquals("wrong weight with degree weighting policy", fcWeight, g.getEdgeWeight(fc),Double.MIN_VALUE); + assertEquals("wrong weight with degree weighting policy", ycWeight, g.getEdgeWeight(yc),Double.MIN_VALUE); + } + + @Test + public void testCustomWeightPolicy(){ + WeightingPolicy<BioMetabolite,ReactionEdge,CompoundGraph> wp = new CustomWeightPolicy<BioMetabolite,ReactionEdge,CompoundGraph>( + e -> { + Double w = Double.valueOf(g.inDegreeOf(e.getV2())); + w += Double.valueOf(g.outDegreeOf(e.getV2())); + w = StrictMath.pow(w,2); + return w; + }); + double abWeight,bcWeight,adWeight,efWeight,bxWeight,ebWeight,deWeight,fcWeight,ycWeight; + abWeight=ebWeight=16; + bcWeight=fcWeight=ycWeight=deWeight=9; + adWeight=efWeight=4; + bxWeight=1; + wp.setWeight(g); + assertEquals("wrong weight with custom weighting policy", abWeight, g.getEdgeWeight(ab),Double.MIN_VALUE); + assertEquals("wrong weight with custom weighting policy", adWeight, g.getEdgeWeight(ad),Double.MIN_VALUE); + assertEquals("wrong weight with custom weighting policy", bcWeight, g.getEdgeWeight(bc),Double.MIN_VALUE); + assertEquals("wrong weight with custom weighting policy", bxWeight, g.getEdgeWeight(bx),Double.MIN_VALUE); + assertEquals("wrong weight with custom weighting policy", deWeight, g.getEdgeWeight(de),Double.MIN_VALUE); + assertEquals("wrong weight with custom weighting policy", ebWeight, g.getEdgeWeight(eb),Double.MIN_VALUE); + assertEquals("wrong weight with custom weighting policy", efWeight, g.getEdgeWeight(ef),Double.MIN_VALUE); + assertEquals("wrong weight with custom weighting policy", fcWeight, g.getEdgeWeight(fc),Double.MIN_VALUE); + assertEquals("wrong weight with custom weighting policy", ycWeight, g.getEdgeWeight(yc),Double.MIN_VALUE); + } /** diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/CompoundNet.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/CompoundNet.java index 53e189201eff26cd59a8a9175aa8e0e2954c6fb9..2ddae4d1d022464da946864cf5d8a53a7a98c665 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/CompoundNet.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/CompoundNet.java @@ -131,18 +131,30 @@ public class CompoundNet extends AbstractMet4jApplication { if (weightFile != null) { System.err.println("Setting edge weights..."); wp = new WeightsFromFile(weightFile); - } else if (degree) { + } else if (degree && !undirected) { System.err.println("Setting edge weights..."); int pow = 2; wp = new DegreeWeightPolicy(pow); } wp.setWeight(graph); + System.out.println(" Done."); //invert graph as undirected (copy edge weight to reversed edge) if(undirected){ System.out.print("Create Undirected..."); graph.asUndirected(); System.out.println(" Done."); + if(degree){ + //since degree weighting policy is not symmetric, for undirected case we create reversed edges, apply + //a corrected degree computation for each edge, and treat the graph as normal + System.err.println("Setting edge weights (target degree)..."); + int pow = 2; + wp = new DegreeWeightPolicy(1); + wp.setWeight(graph); + //adjust degree to ignore edges added for undirected case support + WeightUtils.process(graph, x -> StrictMath.pow((x/2),pow)); + System.out.println(" Done."); + } } //merge compartment diff --git a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DistanceMatrix.java b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DistanceMatrix.java index 38220f317d50710c543f42e59798609c181d26ad..a6d784fbfafb447045837dd53b3dc4372b55a3ee 100644 --- a/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DistanceMatrix.java +++ b/met4j-toolbox/src/main/java/fr/inrae/toulouse/metexplore/met4j_toolbox/networkAnalysis/DistanceMatrix.java @@ -6,9 +6,11 @@ import fr.inrae.toulouse.metexplore.met4j_core.biodata.collection.BioCollection; // import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.FloydWarshall; // import fr.inrae.toulouse.metexplore.met4j_graph.computation.utils.ComputeAdjacencyMatrix; import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.ShortestPath; +import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting.CustomWeightPolicy; import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting.UnweightedPolicy; import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting.DegreeWeightPolicy; import fr.inrae.toulouse.metexplore.met4j_graph.computation.connect.weighting.WeightsFromFile; +import fr.inrae.toulouse.metexplore.met4j_graph.core.BioGraph; import fr.inrae.toulouse.metexplore.met4j_graph.core.BioPath; import fr.inrae.toulouse.metexplore.met4j_graph.core.WeightingPolicy; import fr.inrae.toulouse.metexplore.met4j_graph.core.compound.CompoundGraph; @@ -117,8 +119,23 @@ public class DistanceMatrix extends AbstractMet4jApplication { if (weightFile != null) { wp = new WeightsFromFile(weightFile, true); } else if (degree) { - int pow = 2; - wp = new DegreeWeightPolicy(pow); + if(!undirected){ + int pow = 2; + wp = new DegreeWeightPolicy(pow); + }else{ + //since degree weighting policy is not symmetric, for undirected case we create reversed edges, apply + //a corrected degree computation for each edge, and treat the graph as normal + graph.asUndirected(); + undirected=false; + wp = new CustomWeightPolicy<BioMetabolite,ReactionEdge,CompoundGraph>( + e -> { + Double w = Double.valueOf(graph.inDegreeOf(e.getV2())); + w += Double.valueOf(graph.outDegreeOf(e.getV2())); + w = w/2; //adjust for undirected doubled edges + w = StrictMath.pow(w,2); + return w; + }); + } } wp.setWeight(graph);