diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlExporter.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlExporter.java index 9897735de5cfc5ffaa43123b20eeb70f84616ef8..3e8819a342f1f91c004c230e26bdf9967e09cbb3 100644 --- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlExporter.java +++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/SbmlExporter.java @@ -20,8 +20,6 @@ import org.sbml.jsbml.ext.layout.Layout; import org.sbml.jsbml.ext.layout.LayoutModelPlugin; import org.sbml.jsbml.ext.multi.MultiModelPlugin; import org.sbml.jsbml.ext.multi.MultiSpeciesType; -import org.sbml.jsbml.ext.multi.PossibleSpeciesFeatureValue; -import org.sbml.jsbml.ext.multi.SpeciesFeatureType; import org.sbml.jsbml.ext.render.GlobalRenderInformation; import org.sbml.jsbml.ext.render.RenderLayoutPlugin; @@ -29,23 +27,16 @@ import lcsb.mapviewer.common.Configuration; import lcsb.mapviewer.common.exception.InvalidStateException; import lcsb.mapviewer.converter.model.sbml.compartment.SbmlCompartmentExporter; import lcsb.mapviewer.converter.model.sbml.reaction.SbmlReactionExporter; -import lcsb.mapviewer.converter.model.sbml.species.SBOTermSpeciesType; import lcsb.mapviewer.converter.model.sbml.species.SbmlSpeciesExporter; import lcsb.mapviewer.converter.model.sbml.units.SbmlUnitExporter; import lcsb.mapviewer.model.map.InconsistentModelException; -import lcsb.mapviewer.model.map.species.Complex; -import lcsb.mapviewer.model.map.species.Element; -import lcsb.mapviewer.model.map.species.Protein; import lcsb.mapviewer.model.map.species.Species; -import lcsb.mapviewer.modelutils.map.ElementUtils; public class SbmlExporter { @SuppressWarnings("unused") private static Logger logger = Logger.getLogger(SbmlExporter.class); - private int idCounter = 0; - /** * Set of SBML extensions that should be used during export. */ @@ -94,10 +85,8 @@ public class SbmlExporter { createSbmlLayout(model, result); } - MultiModelPlugin multiPlugin = null; if (usedExtensions.contains(SbmlExtension.MULTI)) { - multiPlugin = createSbmlMultiPlugin(result); - assignModelDataToTypes(multiPlugin, model); + createSbmlMultiPlugin(result); } SbmlCompartmentExporter compartmentExporter = new SbmlCompartmentExporter(result, model, usedExtensions); @@ -119,40 +108,6 @@ public class SbmlExporter { return doc; } - private void assignModelDataToTypes(MultiModelPlugin multiPlugin, lcsb.mapviewer.model.map.model.Model model) { - for (Species species : model.getSpeciesList()) { - MultiSpeciesType speciesType = speciesTypeByClass.get(species.getClass()); - addStructuralStateToPossibleValues(speciesType, species); - if (species instanceof Species) { - addPositionToCompartmentToPossibleValues(speciesType, ((Species) species)); - } - } - - } - - private void addStructuralStateToPossibleValues(MultiSpeciesType speciesType, Species species) { - String structuralState = null; - if (species instanceof Protein) { - structuralState = ((Protein) species).getStructuralState(); - } else if (species instanceof Complex) { - structuralState = ((Complex) species).getStructuralState(); - } - if (structuralState != null) { - SpeciesFeatureType feature = speciesType.getListOfSpeciesFeatureTypes() - .get(MultiPackageNamingUtils.getStructuralStateFeatureId(species)); - addPosibleValueToFeature(feature, structuralState); - } - - } - - private void addPositionToCompartmentToPossibleValues(MultiSpeciesType speciesType, Species species) { - if (species.getPositionToCompartment() != null) { - SpeciesFeatureType feature = speciesType.getListOfSpeciesFeatureTypes() - .get(MultiPackageNamingUtils.getPositionToCompartmentFeatureId(species)); - addPosibleValueToFeature(feature, species.getPositionToCompartment().name()); - } - } - /** * Create SBML layout for the given model. * @@ -192,58 +147,9 @@ public class SbmlExporter { protected MultiModelPlugin createSbmlMultiPlugin(Model result) { MultiModelPlugin multiPlugin = new MultiModelPlugin(result); result.addExtension("multi", multiPlugin); - for (Class<? extends Element> clazz : new ElementUtils().getAvailableElementSubclasses()) { - if (Species.class.isAssignableFrom(clazz)) { - createSpeciesTypeForClass(multiPlugin, clazz); - } - } return multiPlugin; } - @SuppressWarnings("unchecked") - private void createSpeciesTypeForClass(MultiModelPlugin multiPlugin, Class<? extends Element> clazz) { - MultiSpeciesType speciesType = new MultiSpeciesType(); - speciesType.setName(clazz.getSimpleName()); - speciesType.setId(MultiPackageNamingUtils.getSpeciesTypeId(clazz)); - if (Protein.class.isAssignableFrom(clazz) || Complex.class.isAssignableFrom(clazz)) { - createStructuralStateFeature(clazz, speciesType); - } - createPositionToCompartmentFeature(clazz, speciesType); - multiPlugin.getListOfSpeciesTypes().add(speciesType); - speciesTypeByClass.put(clazz, speciesType); - speciesType.setSBOTerm(SBOTermSpeciesType.getTermByType((Class<? extends Species>) clazz)); - } - - private void createStructuralStateFeature(Class<? extends Element> clazz, MultiSpeciesType speciesType) { - SpeciesFeatureType feature = new SpeciesFeatureType(); - feature.setName("Structural state"); - feature.setId(MultiPackageNamingUtils.getStructuralStateFeatureId(clazz)); - addPosibleValueToFeature(feature, ""); - speciesType.getListOfSpeciesFeatureTypes().add(feature); - } - - private void createPositionToCompartmentFeature(Class<? extends Element> clazz, MultiSpeciesType speciesType) { - SpeciesFeatureType feature = new SpeciesFeatureType(); - feature.setName("Position to compartment"); - feature.setId(MultiPackageNamingUtils.getPositionToCompartmentFeatureId(clazz)); - addPosibleValueToFeature(feature, "undefined"); - speciesType.getListOfSpeciesFeatureTypes().add(feature); - } - - private void addPosibleValueToFeature(SpeciesFeatureType feature, String value) { - boolean alreadyExists = false; - for (PossibleSpeciesFeatureValue existingValue : feature.getListOfPossibleSpeciesFeatureValues()) { - if (existingValue.getName().equals(value)) { - alreadyExists = true; - } - } - if (!alreadyExists) { - PossibleSpeciesFeatureValue featureEmptyValue = new PossibleSpeciesFeatureValue(); - featureEmptyValue.setId(feature.getId() + "_" + (idCounter++)); - featureEmptyValue.setName(value); - feature.getListOfPossibleSpeciesFeatureValues().add(featureEmptyValue); - } - } /** * Creates SBML render plugin for SBML model. diff --git a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/species/SbmlSpeciesExporter.java b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/species/SbmlSpeciesExporter.java index 04e566a37f31ae43e4bef280bc642d2ac2cc6d77..eb1b3053c6da1e9d591440e0dc0659d53af24a72 100644 --- a/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/species/SbmlSpeciesExporter.java +++ b/converter-sbml/src/main/java/lcsb/mapviewer/converter/model/sbml/species/SbmlSpeciesExporter.java @@ -6,6 +6,7 @@ import java.util.List; import org.apache.log4j.Logger; import org.sbml.jsbml.Model; import org.sbml.jsbml.ext.layout.AbstractReferenceGlyph; +import org.sbml.jsbml.ext.multi.MultiModelPlugin; import org.sbml.jsbml.ext.multi.MultiSpeciesPlugin; import org.sbml.jsbml.ext.multi.MultiSpeciesType; import org.sbml.jsbml.ext.multi.PossibleSpeciesFeatureValue; @@ -14,19 +15,20 @@ import org.sbml.jsbml.ext.multi.SpeciesFeatureType; import org.sbml.jsbml.ext.multi.SpeciesFeatureValue; import org.sbml.jsbml.ext.render.LocalStyle; -import lcsb.mapviewer.common.exception.InvalidStateException; import lcsb.mapviewer.converter.model.sbml.MultiPackageNamingUtils; import lcsb.mapviewer.converter.model.sbml.SbmlElementExporter; import lcsb.mapviewer.converter.model.sbml.SbmlExtension; import lcsb.mapviewer.converter.model.sbml.compartment.SbmlCompartmentExporter; import lcsb.mapviewer.model.map.InconsistentModelException; import lcsb.mapviewer.model.map.species.Complex; +import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.Protein; import lcsb.mapviewer.model.map.species.Species; -import lcsb.mapviewer.modelutils.map.ElementUtils; public class SbmlSpeciesExporter extends SbmlElementExporter<Species, org.sbml.jsbml.Species> { + private static int idCounter = 0; + /** * Default class logger. */ @@ -84,18 +86,9 @@ public class SbmlSpeciesExporter extends SbmlElementExporter<Species, org.sbml.j structuralState = ((Complex) element).getStructuralState(); } if (structuralState != null) { - SpeciesFeatureType structuralStateFeature = speciesType - .getSpeciesFeatureType(MultiPackageNamingUtils.getStructuralStateFeatureId(element)); - PossibleSpeciesFeatureValue structuralStateFeatureValue = null; - for (PossibleSpeciesFeatureValue value : structuralStateFeature.getListOfPossibleSpeciesFeatureValues()) { - if (value.getName().equals(structuralState)) { - structuralStateFeatureValue = value; - } - } - if (structuralStateFeatureValue == null) { - throw new InvalidStateException( - new ElementUtils().getElementTag(element) + "Cannot find structural state value for: " + structuralState); - } + SpeciesFeatureType structuralStateFeature = getStructuralStateFeature(element.getClass(), speciesType); + PossibleSpeciesFeatureValue structuralStateFeatureValue = getPosibleFeatureIdByName(structuralState, + structuralStateFeature); SpeciesFeature feature = multiExtension.createSpeciesFeature(); feature.setSpeciesFeatureType(structuralStateFeature.getId()); @@ -105,25 +98,29 @@ public class SbmlSpeciesExporter extends SbmlElementExporter<Species, org.sbml.j } } - private void assignPostionToCompartmentToMulti(Species element, MultiSpeciesPlugin multiExtension, - MultiSpeciesType speciesType) { - String positionToCompartmentName = "undefined"; - if (element.getPositionToCompartment() != null) { - positionToCompartmentName = element.getPositionToCompartment().name(); - } - SpeciesFeatureType structuralStateFeature = speciesType - .getSpeciesFeatureType(MultiPackageNamingUtils.getPositionToCompartmentFeatureId(element)); + private PossibleSpeciesFeatureValue getPosibleFeatureIdByName(String featureValueName, + SpeciesFeatureType speciesFeature) { PossibleSpeciesFeatureValue structuralStateFeatureValue = null; - for (PossibleSpeciesFeatureValue value : structuralStateFeature.getListOfPossibleSpeciesFeatureValues()) { - if (value.getName().equals(positionToCompartmentName)) { + for (PossibleSpeciesFeatureValue value : speciesFeature.getListOfPossibleSpeciesFeatureValues()) { + if (value.getName().equals(featureValueName)) { structuralStateFeatureValue = value; } } if (structuralStateFeatureValue == null) { - throw new InvalidStateException( - new ElementUtils().getElementTag(element) + "Cannot find position to compartment value for: " - + positionToCompartmentName); + structuralStateFeatureValue = addPosibleValueToFeature(speciesFeature, featureValueName); } + return structuralStateFeatureValue; + } + + private void assignPostionToCompartmentToMulti(Species element, MultiSpeciesPlugin multiExtension, + MultiSpeciesType speciesType) { + String positionToCompartmentName = "undefined"; + if (element.getPositionToCompartment() != null) { + positionToCompartmentName = element.getPositionToCompartment().name(); + } + SpeciesFeatureType structuralStateFeature = getPositionToCompartmentFeature(element.getClass(), speciesType); + PossibleSpeciesFeatureValue structuralStateFeatureValue = getPosibleFeatureIdByName(positionToCompartmentName, + structuralStateFeature); SpeciesFeature feature = multiExtension.createSpeciesFeature(); feature.setSpeciesFeatureType(structuralStateFeature.getId()); @@ -133,8 +130,10 @@ public class SbmlSpeciesExporter extends SbmlElementExporter<Species, org.sbml.j } private MultiSpeciesType getMultiSpeciesType(Species element) { - MultiSpeciesType speciesType = getMultiPlugin() - .getSpeciesType(MultiPackageNamingUtils.getSpeciesTypeId(element)); + MultiSpeciesType speciesType = getMultiPlugin().getSpeciesType(MultiPackageNamingUtils.getSpeciesTypeId(element)); + if (speciesType == null) { + speciesType = createSpeciesTypeForClass(getMultiPlugin(), element.getClass()); + } return speciesType; } @@ -170,7 +169,8 @@ public class SbmlSpeciesExporter extends SbmlElementExporter<Species, org.sbml.j } multiDistinguisher = structuralState; } - String result =element.getClass().getSimpleName() + "\n" + element.getName() + "\n" + compartmentName + "\n" + complexName + String result = element.getClass().getSimpleName() + "\n" + element.getName() + "\n" + compartmentName + "\n" + + complexName + "\n" + multiDistinguisher; return result; } @@ -181,4 +181,65 @@ public class SbmlSpeciesExporter extends SbmlElementExporter<Species, org.sbml.j return style; } + @SuppressWarnings("unchecked") + private MultiSpeciesType createSpeciesTypeForClass(MultiModelPlugin multiPlugin, Class<? extends Element> clazz) { + MultiSpeciesType speciesType = new MultiSpeciesType(); + speciesType.setName(clazz.getSimpleName()); + speciesType.setId(MultiPackageNamingUtils.getSpeciesTypeId(clazz)); + multiPlugin.getListOfSpeciesTypes().add(speciesType); + speciesType.setSBOTerm(SBOTermSpeciesType.getTermByType((Class<? extends Species>) clazz)); + return speciesType; + } + + private SpeciesFeatureType getStructuralStateFeature(Class<? extends Element> clazz, MultiSpeciesType speciesType) { + SpeciesFeatureType feature = speciesType + .getSpeciesFeatureType(MultiPackageNamingUtils.getStructuralStateFeatureId(clazz)); + if (feature == null) { + feature = new SpeciesFeatureType(); + feature.setName("Structural state"); + feature.setId(MultiPackageNamingUtils.getStructuralStateFeatureId(clazz)); + addPosibleValueToFeature(feature, ""); + speciesType.getListOfSpeciesFeatureTypes().add(feature); + } + return feature; + } + + private SpeciesFeatureType getPositionToCompartmentFeature(Class<? extends Element> clazz, + MultiSpeciesType speciesType) { + SpeciesFeatureType feature = speciesType + .getSpeciesFeatureType(MultiPackageNamingUtils.getPositionToCompartmentFeatureId(clazz)); + if (feature == null) { + feature = new SpeciesFeatureType(); + feature.setName("Position to compartment"); + feature.setId(MultiPackageNamingUtils.getPositionToCompartmentFeatureId(clazz)); + addPosibleValueToFeature(feature, "undefined"); + speciesType.getListOfSpeciesFeatureTypes().add(feature); + } + return feature; + } + + private PossibleSpeciesFeatureValue addPosibleValueToFeature(SpeciesFeatureType feature, String value) { + PossibleSpeciesFeatureValue result = null; + for (PossibleSpeciesFeatureValue existingValue : feature.getListOfPossibleSpeciesFeatureValues()) { + if (existingValue.getName().equals(value)) { + result = existingValue; + } + } + if (result == null) { + result = new PossibleSpeciesFeatureValue(); + result.setId(feature.getId() + "_" + (idCounter++)); + result.setName(value); + feature.getListOfPossibleSpeciesFeatureValues().add(result); + } + return result; + } + + private void addPositionToCompartmentToPossibleValues(MultiSpeciesType speciesType, Species species) { + if (species.getPositionToCompartment() != null) { + SpeciesFeatureType feature = speciesType.getListOfSpeciesFeatureTypes() + .get(MultiPackageNamingUtils.getPositionToCompartmentFeatureId(species)); + addPosibleValueToFeature(feature, species.getPositionToCompartment().name()); + } + } + } 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 cffe83e9340a9cbbbf15bd7a40d84a99147e78e9..5181a0ff31165f12502c278e49534c43a73b1f49 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 @@ -13,7 +13,6 @@ import java.io.File; import java.lang.reflect.Modifier; import java.nio.file.Files; import java.util.Arrays; -import java.util.HashSet; import java.util.Set; import org.apache.log4j.Logger; @@ -43,13 +42,9 @@ 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.Complex; import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.GenericProtein; -import lcsb.mapviewer.model.map.species.IonChannelProtein; -import lcsb.mapviewer.model.map.species.ReceptorProtein; import lcsb.mapviewer.model.map.species.Species; -import lcsb.mapviewer.model.map.species.TruncatedProtein; import lcsb.mapviewer.model.map.species.field.ModificationState; import lcsb.mapviewer.model.map.species.field.PositionToCompartment; import lcsb.mapviewer.model.map.species.field.Residue; @@ -431,26 +426,6 @@ public class SbmlExporterTest { assertTrue("Species types are not exported", multiPlugin.getListOfSpeciesTypes().size() > 0); } - @Test - public void testMultiExtensionTypeWithStructuralState() throws Exception { - SbmlExporter exporter = new SbmlExporter(); - SBMLDocument doc = new SBMLDocument(3, 2); - org.sbml.jsbml.Model result = doc.createModel("id"); - MultiModelPlugin multiPlugin = exporter.createSbmlMultiPlugin(result); - - Set<Class<?>> typesWithStructuralStates = new HashSet<>(); - typesWithStructuralStates.addAll(Arrays.asList(new Class<?>[] { GenericProtein.class, TruncatedProtein.class, - Complex.class, IonChannelProtein.class, ReceptorProtein.class })); - - for (Class<?> clazz : typesWithStructuralStates) { - MultiSpeciesType speciesType = multiPlugin.getSpeciesType(MultiPackageNamingUtils.getSpeciesTypeId(clazz)); - assertTrue(clazz.getSimpleName() + " doesn't have any features, but at least structuralState expected", - speciesType.getListOfSpeciesFeatureTypes().size() > 0); - - } - - } - @Test public void testMultiExtensionSBOTermsForTypes() throws Exception { SbmlExporter exporter = new SbmlExporter();