From 7f88dcd670899b2dcc26b700257c532ea05ecd06 Mon Sep 17 00:00:00 2001 From: Piotr Gawron <piotr.gawron@uni.lu> Date: Fri, 24 Nov 2017 16:57:28 +0100 Subject: [PATCH] operators for reaction added --- .../model/sbml/SbmlReactionParser.java | 107 +++++++++++++++++- .../converter/model/sbml/SbmlParserTest.java | 15 ++- 2 files changed, 117 insertions(+), 5 deletions(-) diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionParser.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionParser.java index bec76e8dcd..2acf38c9ff 100644 --- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionParser.java +++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionParser.java @@ -1,6 +1,7 @@ package lcsb.mapviewer.converter.model.sbml; import java.awt.geom.Point2D; +import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -23,15 +24,24 @@ import org.sbml.jsbml.ext.layout.SpeciesReferenceGlyph; import org.sbml.jsbml.util.NotImplementedException; import lcsb.mapviewer.common.exception.InvalidArgumentException; +import lcsb.mapviewer.common.exception.InvalidStateException; import lcsb.mapviewer.converter.InvalidInputDataExecption; +import lcsb.mapviewer.converter.model.celldesigner.types.ModifierType; +import lcsb.mapviewer.model.graphics.ArrowType; +import lcsb.mapviewer.model.graphics.ArrowTypeData; import lcsb.mapviewer.model.graphics.PolylineData; import lcsb.mapviewer.model.map.MiriamData; -import lcsb.mapviewer.model.map.modifier.Catalysis; +import lcsb.mapviewer.model.map.modifier.Inhibition; +import lcsb.mapviewer.model.map.modifier.Modulation; +import lcsb.mapviewer.model.map.modifier.Trigger; +import lcsb.mapviewer.model.map.reaction.AndOperator; import lcsb.mapviewer.model.map.reaction.Modifier; +import lcsb.mapviewer.model.map.reaction.NodeOperator; import lcsb.mapviewer.model.map.reaction.Product; import lcsb.mapviewer.model.map.reaction.Reactant; import lcsb.mapviewer.model.map.reaction.Reaction; import lcsb.mapviewer.model.map.reaction.ReactionNode; +import lcsb.mapviewer.model.map.reaction.SplitOperator; import lcsb.mapviewer.model.map.reaction.type.StateTransitionReaction; import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.Species; @@ -84,9 +94,40 @@ public class SbmlReactionParser { for (SpeciesReferenceGlyph speciesRefernceGlyph : glyph.getListOfSpeciesReferenceGlyphs()) { SpeciesGlyph speciesGlyph = layout.getSpeciesGlyph(speciesRefernceGlyph.getSpeciesGlyph()); ReactionNode minervaNode = null; + Class<? extends ReactionNode> nodeClass = null; + switch (speciesRefernceGlyph.getRole()) { + case ACTIVATOR: + nodeClass = Trigger.class; + break; + case INHIBITOR: + nodeClass = Inhibition.class; + break; + case MODIFIER: + nodeClass = Modulation.class; + break; + case PRODUCT: + nodeClass = Product.class; + break; + case SIDEPRODUCT: + nodeClass = Product.class; + break; + case SIDESUBSTRATE: + nodeClass = Reactant.class; + break; + case SUBSTRATE: + nodeClass = Reactant.class; + break; + case UNDEFINED: + nodeClass = null; + break; + } for (ReactionNode node : reactionWithLayout.getReactionNodes()) { if (node.getElement().getElementId().equals(speciesGlyph.getSpecies())) { - minervaNode = node; + if (nodeClass == null) { + minervaNode = node; + } else if (node.getClass().isAssignableFrom(nodeClass)) { + minervaNode = node; + } } } if (minervaNode == null) { @@ -109,22 +150,80 @@ public class SbmlReactionParser { line.addPoint(end); } } + if (minervaNode instanceof Reactant) { + line = line.reverse(); + } + if (minervaNode instanceof Product) { + ArrowTypeData atd = new ArrowTypeData(); + atd.setArrowType(ArrowType.FULL); + line.setEndAtd(atd); + } else if (minervaNode instanceof Modifier) { + for (ModifierType mt : ModifierType.values()) { + if (mt.getClazz().equals(nodeClass)) { + line.setEndAtd(mt.getAtd()); + line.setType(mt.getLineType()); + } + } + } minervaNode.setLine(line); minervaNode.setElement(minervaElement); + if (nodeClass != minervaNode.getClass()) { + reactionWithLayout.removeModifier((Modifier) minervaNode); + + try { + ReactionNode newNode = nodeClass.getConstructor().newInstance(); + newNode.setElement(minervaElement); + newNode.setLine(line); + reactionWithLayout.addNode(newNode); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException + | InvocationTargetException | NoSuchMethodException | SecurityException e) { + throw new InvalidStateException(e); + } + } + } + if (reactionWithLayout.getReactants().size()>1 && reactionWithLayout.getProducts().size()>0) { + PolylineData line = new PolylineData(); + Point2D p1 = reactionWithLayout.getReactants().get(0).getLine().getEndPoint(); + Point2D p2 = reactionWithLayout.getProducts().get(0).getLine().getBeginPoint(); + Point2D center = new Point2D.Double((p1.getX()+p2.getX())/2, (p1.getY()+p2.getY())/2); + line.addPoint(p1); + line.addPoint(center); + NodeOperator operator = new AndOperator(); + operator.addInputs(reactionWithLayout.getReactants()); + operator.setLine(line); + reactionWithLayout.addNode(operator); } + if (reactionWithLayout.getReactants().size()>0 && reactionWithLayout.getProducts().size()>1) { + PolylineData line = new PolylineData(); + Point2D p1 = reactionWithLayout.getReactants().get(0).getLine().getEndPoint(); + Point2D p2 = reactionWithLayout.getProducts().get(0).getLine().getBeginPoint(); + Point2D center = new Point2D.Double((p1.getX()+p2.getX())/2, (p1.getY()+p2.getY())/2); + line.addPoint(p2); + line.addPoint(center); + NodeOperator operator = new SplitOperator(); + operator.addOutputs(reactionWithLayout.getProducts()); + operator.setLine(line); + reactionWithLayout.addNode(operator); + } + + logger.debug(glyph.getCurve().getListOfCurveSegments().get(0)); try { minervaModel.addReaction(new StateTransitionReaction(reactionWithLayout)); } catch (InvalidArgumentException e) { throw new InvalidInputDataExecption(e); } } + Set<Reaction> elementsToRemove = new HashSet<>(); for (Reaction reaction : elements) { if (!used.contains(reaction)) { logger.warn("Layout doesn't contain information about Element: " + reaction.getIdReaction()); } else { - minervaModel.removeReaction(reaction); + elementsToRemove.add(reaction); } } + for (Reaction reaction : elementsToRemove) { + minervaModel.removeReaction(reaction); + } } protected Reaction parse(org.sbml.jsbml.Reaction sbmlReaction, Model sbmlModel) throws InvalidInputDataExecption { @@ -144,7 +243,7 @@ public class SbmlReactionParser { for (ModifierSpeciesReference modifier : sbmlReaction.getListOfModifiers()) { Species element = minervaModel.getElementByElementId(modifier.getSpecies()); - reaction.addModifier(new Catalysis(element)); + reaction.addModifier(new Modifier(element)); } return reaction; diff --git a/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/SbmlParserTest.java b/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/SbmlParserTest.java index 6673591d17..260e80486d 100644 --- a/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/SbmlParserTest.java +++ b/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/SbmlParserTest.java @@ -5,7 +5,9 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; +import java.awt.Desktop; import java.awt.Point; +import java.io.File; import java.io.FileNotFoundException; import org.apache.log4j.Logger; @@ -13,6 +15,9 @@ import org.junit.Test; import lcsb.mapviewer.converter.ConverterParams; import lcsb.mapviewer.converter.InvalidInputDataExecption; +import lcsb.mapviewer.converter.graphics.AbstractImageGenerator; +import lcsb.mapviewer.converter.graphics.NormalImageGenerator; +import lcsb.mapviewer.converter.graphics.PngImageGenerator; import lcsb.mapviewer.model.map.compartment.Compartment; import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.model.map.reaction.Reaction; @@ -94,7 +99,7 @@ public class SbmlParserTest { } @Test - public void testParseReaction() throws FileNotFoundException, InvalidInputDataExecption { + public void testParseReaction() throws Exception { Model model = parser.createModel(new ConverterParams().filename("testFiles/layoutExample/Complete_Example.xml")); assertNotNull(model); assertEquals(1, model.getReactions().size()); @@ -103,6 +108,14 @@ public class SbmlParserTest { assertNotNull(node.getLine()); assertTrue(node.getLine().length() > 0); } +// assertEquals(2, reaction.getOperators().size()); + + AbstractImageGenerator.Params params = new AbstractImageGenerator.Params().height(model.getHeight()) + .width(model.getWidth()).nested(true).scale(1).level(20).x(0).y(0).model(model); + NormalImageGenerator nig = new PngImageGenerator(params); + nig.saveToFile("tmp.png"); + Desktop.getDesktop().open(new File("tmp.png")); + } } -- GitLab