From abd318d18c02ff9da2efb24080d945d69813fe99 Mon Sep 17 00:00:00 2001 From: Piotr Gawron <piotr.gawron@uni.lu> Date: Fri, 2 Feb 2018 11:16:53 +0100 Subject: [PATCH] import of sbml reaction kinetics added --- converter-sbml/.gitignore | 1 + .../model/sbml/SbmlBioEntityParser.java | 3 +- .../converter/model/sbml/SbmlParser.java | 3 -- .../model/sbml/SbmlReactionParser.java | 53 +++++++++++++++++-- .../converter/model/sbml/SbmlParserTest.java | 19 +++++++ 5 files changed, 71 insertions(+), 8 deletions(-) diff --git a/converter-sbml/.gitignore b/converter-sbml/.gitignore index 7bca1630c9..3ef28bc255 100644 --- a/converter-sbml/.gitignore +++ b/converter-sbml/.gitignore @@ -1,2 +1,3 @@ /bin/ tmp.png +tmp.xml diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlBioEntityParser.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlBioEntityParser.java index 2a03a7bd52..fc53759d70 100644 --- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlBioEntityParser.java +++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlBioEntityParser.java @@ -11,11 +11,12 @@ import org.sbml.jsbml.Annotation; import org.sbml.jsbml.ext.layout.Layout; import org.sbml.jsbml.util.NotImplementedException; +import lcsb.mapviewer.common.XmlParser; import lcsb.mapviewer.converter.InvalidInputDataExecption; import lcsb.mapviewer.model.map.BioEntity; import lcsb.mapviewer.model.map.MiriamData; -public class SbmlBioEntityParser { +public class SbmlBioEntityParser extends XmlParser{ Logger logger = Logger.getLogger(SbmlBioEntityParser.class); protected Layout layout; diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlParser.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlParser.java index 32a2964d99..7cbaa961dc 100644 --- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlParser.java +++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlParser.java @@ -106,9 +106,6 @@ public class SbmlParser implements IConverter { if (sbmlModel.getInitialAssignmentCount() > 0) { throw new NotImplementedException("InitialAssignment not implemented for model"); } - if (sbmlModel.getKineticLawCount() > 0) { - throw new NotImplementedException("KineticLaw not implemented for model"); - } if (sbmlModel.getParameterCount() > 0) { throw new NotImplementedException("Parameter not implemented for model"); } 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 fc91aa0314..0f91b7a80c 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 @@ -11,8 +11,9 @@ import java.util.Map; import java.util.Set; import org.apache.log4j.Logger; -import org.sbml.jsbml.Annotation; +import org.sbml.jsbml.KineticLaw; import org.sbml.jsbml.ListOf; +import org.sbml.jsbml.LocalParameter; import org.sbml.jsbml.Model; import org.sbml.jsbml.ModifierSpeciesReference; import org.sbml.jsbml.SpeciesReference; @@ -21,16 +22,19 @@ import org.sbml.jsbml.ext.layout.Layout; import org.sbml.jsbml.ext.layout.ReactionGlyph; import org.sbml.jsbml.ext.layout.SpeciesGlyph; import org.sbml.jsbml.ext.layout.SpeciesReferenceGlyph; -import org.sbml.jsbml.util.NotImplementedException; +import org.w3c.dom.Node; import lcsb.mapviewer.common.exception.InvalidArgumentException; import lcsb.mapviewer.common.exception.InvalidStateException; +import lcsb.mapviewer.common.exception.InvalidXmlSchemaException; 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.kinetics.SbmlArgument; +import lcsb.mapviewer.model.map.kinetics.SbmlKinetics; +import lcsb.mapviewer.model.map.kinetics.SbmlParameter; import lcsb.mapviewer.model.map.modifier.Inhibition; import lcsb.mapviewer.model.map.modifier.Modulation; import lcsb.mapviewer.model.map.modifier.Trigger; @@ -248,7 +252,7 @@ public class SbmlReactionParser extends SbmlBioEntityParser { reaction.setIdReaction(sbmlReaction.getId()); reaction.setReversible(sbmlReaction.isReversible()); if (sbmlReaction.getKineticLaw() != null) { - throw new NotImplementedException("KineticLaw not implemented"); + reaction.setKinetics(createMinervaKinetics(sbmlReaction.getKineticLaw())); } for (SpeciesReference reactant : sbmlReaction.getListOfReactants()) { Species element = minervaModel.getElementByElementId(reactant.getSpecies()); @@ -267,6 +271,47 @@ public class SbmlReactionParser extends SbmlBioEntityParser { return reaction; } + private SbmlKinetics createMinervaKinetics(KineticLaw kineticLaw) throws InvalidInputDataExecption { + SbmlKinetics result = new SbmlKinetics(); + result.setDefinition(kineticLaw.getMath().toMathML()); + for (LocalParameter parameter : kineticLaw.getListOfLocalParameters()) { + SbmlParameter minervaParameter = new SbmlParameter(parameter.getId()); + minervaParameter.setName(parameter.getName()); + minervaParameter.setValue(parameter.getValue()); + minervaParameter.setUnits(minervaModel.getUnitsByUnitId(parameter.getUnits())); + result.addParameter(minervaParameter); + } + + try { + Node node = super.getXmlDocumentFromString(result.getDefinition()); + Set<SbmlArgument> elementsUsedInKinetics = new HashSet<>(); + for (Node ciNode : super.getAllNotNecessirellyDirectChild("ci", node)) { + String id = super.getNodeValue(ciNode).trim(); + SbmlArgument element = minervaModel.getElementByElementId(id); + if (element == null) { + element = result.getParameterById(id); + } + if (element == null) { + element = minervaModel.getParameterById(id); + } + if (element == null) { + element = minervaModel.getFunctionById(id); + } + if (element != null) { + ciNode.setTextContent(element.getElementId()); + } else { + throw new InvalidXmlSchemaException("Unknown symbol in kinetics: " + id); + } + elementsUsedInKinetics.add(element); + } + result.addArguments(elementsUsedInKinetics); + } catch (InvalidXmlSchemaException e) { + throw new InvalidInputDataExecption(e); + } + + return result; + } + public void validateReactions(Set<Reaction> reactions) throws InvalidInputDataExecption { for (Reaction reaction : reactions) { if (reaction.getReactants().size() == 0) { 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 aa8225c4f0..91893ec7d4 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 @@ -40,6 +40,25 @@ public class SbmlParserTest { assertFalse(compartment.getClass().equals(Compartment.class)); } + @Test + public void testParseUnits() throws FileNotFoundException, InvalidInputDataExecption { + Model model = parser.createModel( + new ConverterParams().filename("testFiles/layoutExample/CompartmentGlyph_Example_level2_level3.xml")); + assertNotNull(model); + assertTrue("Units weren't parsed", model.getUnits().size() > 0); + } + + @Test + public void testParseKinetics() throws FileNotFoundException, InvalidInputDataExecption { + Model model = parser.createModel(new ConverterParams().filename("testFiles/layoutExample/SBML.xml")); + for (Reaction reaction : model.getReactions()) { + assertNotNull("Kinetics is not parsed", reaction.getKinetics()); + assertNotNull("No math definition for kinetic law", reaction.getKinetics().getDefinition()); + assertTrue("There should be a kinetic parameter defined", reaction.getKinetics().getParameters().size() > 0); + assertTrue("Elements used by kinetics are not available", reaction.getKinetics().getElements().size() > 0); + } + } + @Test public void testParseSpecies() throws FileNotFoundException, InvalidInputDataExecption { Model model = parser -- GitLab