From 23a161c895257f4a06357c6f46f9c3f99b4a9ed6 Mon Sep 17 00:00:00 2001 From: Piotr Gawron <piotr.gawron@uni.lu> Date: Thu, 21 Dec 2017 17:38:05 +0100 Subject: [PATCH] simple export of reaction layout --- .../model/sbml/SbmlBioEntityExporter.java | 2 +- .../model/sbml/SbmlReactionExporter.java | 85 +++++++++++++++++-- .../model/sbml/SbmlExporterTest.java | 43 ++++++++++ 3 files changed, 121 insertions(+), 9 deletions(-) diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlBioEntityExporter.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlBioEntityExporter.java index 4e9d5a26ab..97f1c528a8 100644 --- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlBioEntityExporter.java +++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlBioEntityExporter.java @@ -57,7 +57,7 @@ public abstract class SbmlBioEntityExporter<T extends BioEntity, S extends org.s public abstract S createSbmlElement(T element) throws InconsistentModelException; protected S getSbmlElement(T element, String compartmentName) throws InconsistentModelException { - String mapKey = element.getName() + "\n" + compartmentName; + String mapKey = element.getClass().getSimpleName() + "\n" + element.getElementId() + "\n" + compartmentName; if (sbmlElementByElementNameAndCompartmentName.get(mapKey) == null) { S sbmlElement = createSbmlElement(element); sbmlElement.setName(element.getName()); diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionExporter.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionExporter.java index e6be4a1c1e..de7951c7cb 100644 --- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionExporter.java +++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlReactionExporter.java @@ -1,17 +1,30 @@ package lcsb.mapviewer.converter.model.sbml; +import java.awt.geom.Line2D; import java.util.Collection; +import java.util.HashMap; +import java.util.Map; import org.apache.log4j.Logger; +import org.sbml.jsbml.SimpleSpeciesReference; import org.sbml.jsbml.Species; +import org.sbml.jsbml.SpeciesReference; import org.sbml.jsbml.ext.layout.AbstractReferenceGlyph; +import org.sbml.jsbml.ext.layout.Curve; import org.sbml.jsbml.ext.layout.Layout; +import org.sbml.jsbml.ext.layout.LineSegment; +import org.sbml.jsbml.ext.layout.Point; +import org.sbml.jsbml.ext.layout.ReactionGlyph; +import org.sbml.jsbml.ext.layout.SpeciesReferenceGlyph; +import org.sbml.jsbml.ext.layout.SpeciesReferenceRole; import lcsb.mapviewer.model.map.InconsistentModelException; +import lcsb.mapviewer.model.map.modifier.Inhibition; import lcsb.mapviewer.model.map.reaction.Modifier; 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; public class SbmlReactionExporter extends SbmlBioEntityExporter<Reaction, org.sbml.jsbml.Reaction> { Logger logger = Logger.getLogger(SbmlReactionExporter.class); @@ -23,29 +36,36 @@ public class SbmlReactionExporter extends SbmlBioEntityExporter<Reaction, org.sb this.speciesExporter = speciesExporter; } + Map<ReactionNode, SimpleSpeciesReference> speciesReferenceByReactionNode = new HashMap<>(); + @Override public org.sbml.jsbml.Reaction createSbmlElement(Reaction reaction) throws InconsistentModelException { + logger.debug(reaction); org.sbml.jsbml.Reaction result = sbmlModel.createReaction("reaction_" + (getNextId())); for (Product product : reaction.getProducts()) { Species sbmlSymbol = speciesExporter.sbmlElementByElementId.get(product.getElement().getElementId()); - result.createProduct(sbmlSymbol); + SpeciesReference speciesReference = result.createProduct(sbmlSymbol); + speciesReferenceByReactionNode.put(product, speciesReference); } for (Reactant reactant : reaction.getReactants()) { Species sbmlSymbol = speciesExporter.sbmlElementByElementId.get(reactant.getElement().getElementId()); - result.createReactant(sbmlSymbol); + SpeciesReference speciesReference = result.createReactant(sbmlSymbol); + logger.debug(reactant); + speciesReferenceByReactionNode.put(reactant, speciesReference); } for (Modifier modifier : reaction.getModifiers()) { Species sbmlSymbol = speciesExporter.sbmlElementByElementId.get(modifier.getElement().getElementId()); - result.createModifier(sbmlSymbol); + SimpleSpeciesReference speciesReference = result.createModifier(sbmlSymbol); + speciesReferenceByReactionNode.put(modifier, speciesReference); } return result; } @Override protected AbstractReferenceGlyph createElementGlyph(String sbmlElementId, String glyphId) { -// AbstractReferenceGlyph speciesGlyph = layout.createReactionGlyph(glyphId, sbmlElementId); -// return speciesGlyph; - return null; + ReactionGlyph reactionGlyph = layout.createReactionGlyph(glyphId, sbmlElementId); + + return reactionGlyph; } @Override @@ -54,9 +74,58 @@ public class SbmlReactionExporter extends SbmlBioEntityExporter<Reaction, org.sb } @Override - protected void assignLayoutToGlyph(Reaction element, AbstractReferenceGlyph compartmentGlyph) { - // TODO Auto-generated method stub + protected void assignLayoutToGlyph(Reaction reaction, AbstractReferenceGlyph compartmentGlyph) { + logger.debug(reaction); + ReactionGlyph reactionGlyph = (ReactionGlyph) compartmentGlyph; + boolean firstReactant = true; + for (Reactant reactant : reaction.getReactants()) { + SpeciesReferenceGlyph reactantGlyph = createNodeGlyph(reactionGlyph, reactant); + if (firstReactant) { + reactantGlyph.setRole(SpeciesReferenceRole.SUBSTRATE); + } else { + reactantGlyph.setRole(SpeciesReferenceRole.SIDESUBSTRATE); + } + firstReactant = false; + } + boolean firstProduct = true; + for (Product product : reaction.getProducts()) { + SpeciesReferenceGlyph productGlyph = createNodeGlyph(reactionGlyph, product); + if (firstProduct) { + productGlyph.setRole(SpeciesReferenceRole.PRODUCT); + } else { + productGlyph.setRole(SpeciesReferenceRole.SIDEPRODUCT); + } + firstProduct = false; + } + for (Modifier modifier : reaction.getModifiers()) { + SpeciesReferenceGlyph modifierGlyph = createNodeGlyph(reactionGlyph, modifier); + if (modifier instanceof Inhibition) { + modifierGlyph.setRole(SpeciesReferenceRole.INHIBITOR); + } else { + modifierGlyph.setRole(SpeciesReferenceRole.MODIFIER); + } + } + + } + private SpeciesReferenceGlyph createNodeGlyph(ReactionGlyph reactionGlyph, ReactionNode node) { + SpeciesReferenceGlyph reactantGlyph = reactionGlyph.createSpeciesReferenceGlyph("node_" + getNextId()); + reactantGlyph.setSpeciesGlyph(speciesExporter.sbmlGlyphByElementId.get(node.getElement().getElementId()).getId()); + reactantGlyph.setCurve(createCurve(node)); + logger.debug(node); + reactantGlyph.setSpeciesReference(speciesReferenceByReactionNode.get(node)); + return reactantGlyph; + } + + private Curve createCurve(ReactionNode reactant) { + Curve curve = new Curve(); + for (Line2D line : reactant.getLine().getLines()) { + LineSegment segment = new LineSegment(); + segment.setStart(new Point(line.getX1(), line.getY1())); + segment.setEnd(new Point(line.getX2(), line.getY2())); + curve.addCurveSegment(segment); + } + return curve; } } diff --git a/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/SbmlExporterTest.java b/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/SbmlExporterTest.java index 32345a0b66..54d333f7fc 100644 --- a/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/SbmlExporterTest.java +++ b/converter-sbml/src/test/java/lcsb/mapviewer/converter/model/sbml/SbmlExporterTest.java @@ -6,6 +6,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.awt.Desktop; +import java.awt.geom.Point2D; import java.io.ByteArrayInputStream; import java.io.File; import java.nio.file.Files; @@ -13,15 +14,21 @@ import java.nio.file.Files; import org.apache.log4j.Logger; import org.junit.Test; +import lcsb.mapviewer.common.Configuration; import lcsb.mapviewer.converter.ConverterParams; import lcsb.mapviewer.converter.graphics.AbstractImageGenerator; import lcsb.mapviewer.converter.graphics.NormalImageGenerator; import lcsb.mapviewer.converter.graphics.PngImageGenerator; +import lcsb.mapviewer.model.graphics.PolylineData; import lcsb.mapviewer.model.map.compartment.Compartment; import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.model.map.model.ModelFullIndexed; +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.type.StateTransitionReaction; +import lcsb.mapviewer.model.map.species.GenericProtein; import lcsb.mapviewer.model.map.species.Species; public class SbmlExporterTest { @@ -152,4 +159,40 @@ public class SbmlExporterTest { assertNotNull(deserializedModel); } + @Test + public void testExportReactionWithLayout() throws Exception { + Model model = new ModelFullIndexed(null); + GenericProtein p1 = new GenericProtein("s1"); + p1.setWidth(100); + p1.setHeight(20); + p1.setX(10); + p1.setY(10); + model.addElement(p1); + GenericProtein p2 = new GenericProtein("s2"); + p2.setWidth(100); + p2.setHeight(20); + p2.setX(10); + p2.setY(50); + model.addElement(p2); + Reaction reaction = new StateTransitionReaction(); + Reactant reactant = new Reactant(p1); + Product product = new Product(p2); + PolylineData reactantLine = new PolylineData(); + reactantLine.addPoint(new Point2D.Double(50, 20)); + reactantLine.addPoint(new Point2D.Double(50, 30)); + reactant.setLine(reactantLine); + PolylineData productLine = new PolylineData(); + productLine.addPoint(new Point2D.Double(50, 40)); + productLine.addPoint(new Point2D.Double(50, 60)); + product.setLine(productLine); + reaction.addReactant(reactant); + reaction.addProduct(product); + model.addReaction(reaction); + Model deserializedModel = getModelAfterSerializing(model); + Reaction deserializedReaction = deserializedModel.getReactions().iterator().next(); + assertEquals(reactantLine.length(), deserializedReaction.getReactants().get(0).getLine().length(), Configuration.EPSILON); + assertEquals(productLine.length(), deserializedReaction.getProducts().get(0).getLine().length(), Configuration.EPSILON); + + } + } -- GitLab