Skip to content
Snippets Groups Projects
Commit e6abcc06 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

Merge branch '550-export-to-sbgn-does-not-export-compartments-and-some-reactions' into 'master'

Resolve "Export to SBGN does not export compartments and some reactions"

Closes #550

See merge request !512
parents fc9c3548 4ddad919
No related branches found
No related tags found
2 merge requests!630WIP: Resolve "The privileges of a new user are not saved in some cases",!512Resolve "Export to SBGN does not export compartments and some reactions"
Pipeline #7515 passed
...@@ -351,7 +351,6 @@ public class RestAnnotationParser extends XmlParser { ...@@ -351,7 +351,6 @@ public class RestAnnotationParser extends XmlParser {
} }
if (notes.indexOf("</head>") >= 0) { if (notes.indexOf("</head>") >= 0) {
logger.debug("Y");
notes = notes.substring(notes.indexOf("</head>") + "</head>".length()); notes = notes.substring(notes.indexOf("</head>") + "</head>".length());
} }
notes = notes.replace("xmlns=\"http://www.w3.org/1999/xhtml\"", ""); notes = notes.replace("xmlns=\"http://www.w3.org/1999/xhtml\"", "");
......
...@@ -3,13 +3,25 @@ ...@@ -3,13 +3,25 @@
*/ */
package lcsb.mapviewer.converter.model.sbgnml; package lcsb.mapviewer.converter.model.sbgnml;
import java.io.ByteArrayInputStream;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import javax.xml.bind.JAXBException; import javax.xml.bind.JAXBException;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.log4j.Logger;
import org.apache.log4j.spi.LoggingEvent;
import org.sbgn.SbgnUtil;
import org.sbgn.bindings.Sbgn;
import lcsb.mapviewer.common.EventStorageLoggerAppender;
import lcsb.mapviewer.common.MimeType; import lcsb.mapviewer.common.MimeType;
import lcsb.mapviewer.converter.ConverterException; import lcsb.mapviewer.converter.ConverterException;
import lcsb.mapviewer.converter.ConverterParams; import lcsb.mapviewer.converter.ConverterParams;
...@@ -18,67 +30,95 @@ import lcsb.mapviewer.converter.InvalidInputDataExecption; ...@@ -18,67 +30,95 @@ import lcsb.mapviewer.converter.InvalidInputDataExecption;
import lcsb.mapviewer.model.map.InconsistentModelException; import lcsb.mapviewer.model.map.InconsistentModelException;
import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.model.map.model.Model;
import org.sbgn.SbgnUtil;
import org.sbgn.bindings.Sbgn;
/** /**
* @author Michał Kuźma * @author Michał Kuźma
* *
*/ */
public class SbgnmlXmlConverter implements IConverter { public class SbgnmlXmlConverter implements IConverter {
Logger logger = Logger.getLogger(SbgnmlXmlConverter.class);
@Override
public Model createModel(ConverterParams params) throws InvalidInputDataExecption {
SbgnmlXmlParser parser = new SbgnmlXmlParser();
return parser.createModel(params);
}
@Override
public InputStream exportModelToInputStream(Model model) throws InconsistentModelException, ConverterException {
EventStorageLoggerAppender appender = new EventStorageLoggerAppender();
Sbgn exportedData;
StringBuilder notes = new StringBuilder("");
try {
Logger.getRootLogger().addAppender(appender);
SbgnmlXmlExporter exporter = new SbgnmlXmlExporter();
exportedData = exporter.toSbgnml(model);
if (!appender.getWarnings().isEmpty()) {
for (LoggingEvent event : appender.getWarnings()) {
if (event.getMessage() instanceof String) {
notes.append("\n" + ((String) event.getMessage()));
}
}
}
} finally {
Logger.getRootLogger().removeAppender(appender);
}
try {
File tempFile = File.createTempFile("sbgnmlExportTempFile", ".tmp");
InputStream result;
SbgnUtil.writeToFile(exportedData, tempFile);
try (FileInputStream inputStream = new FileInputStream(tempFile)) {
String xml = IOUtils.toString(inputStream, "UTF-8");
if (notes.length() > 0) {
int position = xml.indexOf("<map language");
if (position < 0) {
throw new ConverterException("problematic output sbgn. Cannot find map tag");
}
String notesNode = "<notes><html:body xmlns:html=\"http://www.w3.org/1999/xhtml\">" +
StringEscapeUtils.escapeXml(notes.toString()) + "\n</html:body></notes> ";
xml = xml.substring(0, position) + notesNode + xml.substring(position, xml.length());
}
result = new ByteArrayInputStream(xml.getBytes(StandardCharsets.UTF_8));
}
return result;
} catch (IOException e) {
throw new ConverterException(e);
} catch (JAXBException e) {
throw new ConverterException(e);
}
}
@Override @Override
public Model createModel(ConverterParams params) throws InvalidInputDataExecption { public File exportModelToFile(Model model, String filePath) throws InconsistentModelException, ConverterException {
SbgnmlXmlParser parser = new SbgnmlXmlParser(); InputStream inputStream = exportModelToInputStream(model);
return parser.createModel(params);
}
@Override try {
public InputStream exportModelToInputStream(Model model) throws InconsistentModelException, ConverterException { File exportedFile = new File(filePath);
SbgnmlXmlExporter exporter = new SbgnmlXmlExporter(); if (exportedFile.getParentFile() != null) {
Sbgn exportedData = exporter.toSbgnml(model); exportedFile.getParentFile().mkdirs();
File tempFile; }
try { OutputStream outputStream = new FileOutputStream(exportedFile);
tempFile = File.createTempFile("sbgnmlExportTempFile", ".tmp"); IOUtils.copy(inputStream, outputStream);
SbgnUtil.writeToFile(exportedData, tempFile); outputStream.close();
InputStream result = new FileInputStream(tempFile);
return result;
} catch (IOException e) {
throw new ConverterException(e);
} catch (JAXBException e) {
throw new ConverterException(e);
}
}
@Override return exportedFile;
public File exportModelToFile(Model model, String filePath) throws InconsistentModelException, ConverterException { } catch (IOException e) {
SbgnmlXmlExporter exporter = new SbgnmlXmlExporter(); throw new ConverterException(e);
Sbgn exportedData = exporter.toSbgnml(model); }
File exportedFile = new File(filePath); }
if (exportedFile.getParentFile() != null) {
exportedFile.getParentFile().mkdirs();
}
try {
SbgnUtil.writeToFile(exportedData, exportedFile);
} catch (JAXBException e) {
throw new ConverterException(e);
}
return exportedFile;
}
@Override @Override
public String getCommonName() { public String getCommonName() {
return "SBGN-ML"; return "SBGN-ML";
} }
@Override @Override
public MimeType getMimeType() { public MimeType getMimeType() {
return MimeType.TEXT; return MimeType.TEXT;
} }
@Override @Override
public String getFileExtension() { public String getFileExtension() {
return "sbgn"; return "sbgn";
} }
} }
...@@ -46,6 +46,7 @@ import lcsb.mapviewer.model.map.reaction.OrOperator; ...@@ -46,6 +46,7 @@ import lcsb.mapviewer.model.map.reaction.OrOperator;
import lcsb.mapviewer.model.map.reaction.Product; import lcsb.mapviewer.model.map.reaction.Product;
import lcsb.mapviewer.model.map.reaction.Reactant; import lcsb.mapviewer.model.map.reaction.Reactant;
import lcsb.mapviewer.model.map.reaction.Reaction; 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.SplitOperator;
import lcsb.mapviewer.model.map.reaction.type.DissociationReaction; import lcsb.mapviewer.model.map.reaction.type.DissociationReaction;
import lcsb.mapviewer.model.map.reaction.type.HeterodimerAssociationReaction; import lcsb.mapviewer.model.map.reaction.type.HeterodimerAssociationReaction;
...@@ -160,11 +161,14 @@ public class SbgnmlXmlExporter { ...@@ -160,11 +161,14 @@ public class SbgnmlXmlExporter {
map.setLanguage(Language.PD.getName()); map.setLanguage(Language.PD.getName());
Sbgn sbgnData = new Sbgn(); Sbgn sbgnData = new Sbgn();
List<Species> aliases = model.getSpeciesList(); for (Element element : model.getElements()) {
if (element instanceof Species) {
for (Species a : aliases) { if (((Species) element).getComplex() == null) {
if (a.getComplex() == null) { Glyph newGlyph = aliasToGlyph(element);
Glyph newGlyph = aliasToGlyph(a); map.getGlyph().add(newGlyph);
}
} else if (element instanceof Compartment) {
Glyph newGlyph = aliasToGlyph(element);
map.getGlyph().add(newGlyph); map.getGlyph().add(newGlyph);
} }
} }
...@@ -177,9 +181,8 @@ public class SbgnmlXmlExporter { ...@@ -177,9 +181,8 @@ public class SbgnmlXmlExporter {
try { try {
map.getArc().add(getArcFromReducedReaction(reaction)); map.getArc().add(getArcFromReducedReaction(reaction));
} catch (InvalidArgumentException e) { } catch (InvalidArgumentException e) {
logger.warn("Invalid arc type." logger.warn(eu.getElementTag(reaction) + "Invalid arc type."
+ " Reduced notation reaction found of type that is not compliant with SBGN-ML format." + " Reaction: " + " Reduced notation reaction found of type that is not compliant with SBGN-ML format.");
+ reaction.getIdReaction());
} }
continue; continue;
} }
...@@ -187,7 +190,6 @@ public class SbgnmlXmlExporter { ...@@ -187,7 +190,6 @@ public class SbgnmlXmlExporter {
} }
sbgnData.setMap(map); sbgnData.setMap(map);
return sbgnData; return sbgnData;
} }
...@@ -707,7 +709,8 @@ public class SbgnmlXmlExporter { ...@@ -707,7 +709,8 @@ public class SbgnmlXmlExporter {
} }
if (reaction.getProducts().get(0).getElement() instanceof Phenotype) { if (reaction.getProducts().get(0).getElement() instanceof Phenotype) {
logger.warn("Found Phenotype being a reactant in process. That is discouraged"); logger.warn(eu.getElementTag(reaction.getProducts().get(0).getElement())
+ "Found Phenotype being a reactant in process. That is discouraged");
} }
arc.setSource(sourceTargetMap.get(reaction.getReactants().get(0).getElement().getElementId())); arc.setSource(sourceTargetMap.get(reaction.getReactants().get(0).getElement().getElementId()));
...@@ -801,13 +804,12 @@ public class SbgnmlXmlExporter { ...@@ -801,13 +804,12 @@ public class SbgnmlXmlExporter {
List<Arc> arcList = new ArrayList<>(); List<Arc> arcList = new ArrayList<>();
// Parse all nodes except NodeOperators // Parse all nodes except NodeOperators
for (AbstractNode node : reaction.getNodes().stream().filter(n -> !(n instanceof NodeOperator)) for (ReactionNode node : reaction.getReactionNodes()) {
.collect(Collectors.toList())) {
try { try {
arcList.add(getArcFromNode(node, glyphList)); arcList.add(getArcFromNode(node, glyphList));
} catch (InvalidArgumentException ex) { } catch (InvalidArgumentException ex) {
logger.warn("Node skipped in export process, since it is not compliant with SBGN-ML format: " logger.warn(
+ node.getClass().getName()); eu.getElementTag(node) + "Node skipped in export process, since it is not compliant with SBGN-ML format.");
continue; continue;
} }
} }
......
package lcsb.mapviewer.converter.model.sbgnml; package lcsb.mapviewer.converter.model.sbgnml;
import static org.junit.Assert.assertTrue;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
...@@ -10,53 +14,97 @@ import org.junit.Test; ...@@ -10,53 +14,97 @@ import org.junit.Test;
import lcsb.mapviewer.converter.ConverterParams; import lcsb.mapviewer.converter.ConverterParams;
import lcsb.mapviewer.converter.IConverter; import lcsb.mapviewer.converter.IConverter;
import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser; import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser;
import lcsb.mapviewer.model.map.compartment.Compartment;
import lcsb.mapviewer.model.map.model.Model; import lcsb.mapviewer.model.map.model.Model;
import lcsb.mapviewer.model.map.species.Element;
import lcsb.mapviewer.modelutils.map.ElementUtils;
public class CellDesignerToSbgnTest { public class CellDesignerToSbgnTest {
Logger logger = Logger.getLogger(CellDesignerToSbgnTest.class); Logger logger = Logger.getLogger(CellDesignerToSbgnTest.class);
ElementUtils eu = new ElementUtils();
@Before
public void setUp() throws Exception { @Before
} public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception { @After
} public void tearDown() throws Exception {
}
@Test
public void testSample() throws Exception { @Test
try { public void testSample() throws Exception {
IConverter converter = new CellDesignerXmlParser(); try {
IConverter converter2 = new SbgnmlXmlConverter(); IConverter converter = new CellDesignerXmlParser();
IConverter converter2 = new SbgnmlXmlConverter();
Model model;
model = converter.createModel(new ConverterParams().filename("testFiles/cellDesigner/sample.xml")); Model model = converter.createModel(new ConverterParams().filename("testFiles/cellDesigner/sample.xml"));
String output = File.createTempFile("temp-sbgn-output", ".sbgn").getAbsolutePath(); String output = File.createTempFile("temp-sbgn-output", ".sbgn").getAbsolutePath();
converter2.exportModelToFile(model, output); converter2.exportModelToFile(model, output);
new File(output).delete();
} catch (Exception e) { try (FileInputStream inputStream = new FileInputStream(output)) {
e.printStackTrace(); String everything = IOUtils.toString(inputStream, "UTF-8");
throw e; assertTrue("Warnings are not exported into sbgn", everything.contains("Element type is not supported"));
} }
} converter2.createModel(new ConverterParams().filename(output));
@Test new File(output).delete();
public void testSample2() throws Exception { } catch (Exception e) {
try { e.printStackTrace();
IConverter converter = new CellDesignerXmlParser(); throw e;
IConverter converter2 = new SbgnmlXmlConverter(); }
Model model; }
model = converter.createModel(new ConverterParams().filename("testFiles/cellDesigner/bubbles.xml"));
@Test
String output = File.createTempFile("temp-sbgn-output", ".sbgn").getAbsolutePath(); public void testSample2() throws Exception {
converter2.exportModelToFile(model, output); try {
new File(output).delete(); IConverter converter = new CellDesignerXmlParser();
} catch (Exception e) { IConverter converter2 = new SbgnmlXmlConverter();
e.printStackTrace();
throw e; Model model;
} model = converter.createModel(new ConverterParams().filename("testFiles/cellDesigner/bubbles.xml"));
}
String output = File.createTempFile("temp-sbgn-output", ".sbgn").getAbsolutePath();
converter2.exportModelToFile(model, output);
new File(output).delete();
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testCompartmentsExport() throws Exception {
try {
IConverter converter = new CellDesignerXmlParser();
IConverter converter2 = new SbgnmlXmlConverter();
Model model = converter.createModel(new ConverterParams().filename("testFiles/cellDesigner/neuron.xml"));
String output = File.createTempFile("temp-sbgn-output", ".sbgn").getAbsolutePath();
converter2.exportModelToFile(model, output);
converter2.createModel(new ConverterParams().filename(output));
String fileContent;
try (FileInputStream inputStream = new FileInputStream(output)) {
fileContent = IOUtils.toString(inputStream, "UTF-8");
}
for (Element element : model.getElements()) {
if (element instanceof Compartment) {
assertTrue(eu.getElementTag(element) + " comparmtent is not exported",
fileContent.contains(element.getElementId()));
}
}
new File(output).delete();
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
} }
This diff is collapsed.
...@@ -834,64 +834,6 @@ Name: Carney complex, multiple neoplasia and lentiginosis ...@@ -834,64 +834,6 @@ Name: Carney complex, multiple neoplasia and lentiginosis
Description: RecName: Full=Sodium/calcium exchanger 1; AltName: Full=Na(+)/Ca(2+)-exchange protein 1; Flags: Precursor; Description: RecName: Full=Sodium/calcium exchanger 1; AltName: Full=Na(+)/Ca(2+)-exchange protein 1; Flags: Precursor;
Previous Symbols: Previous Symbols:
Synonyms: CNC, NCX1 Synonyms: CNC, NCX1
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:vCard="http://www.w3.org/2001/vcard-rdf/3.0#" xmlns:bqbiol="http://biomodels.net/biology-qualifiers/" xmlns:bqmodel="http://biomodels.net/model-qualifiers/">
<rdf:Description rdf:about="#s15">
<bqbiol:hasVersion>
<rdf:Bag>
<rdf:li rdf:resource="urn:miriam:refseq:NP_066920.1"/></rdf:Bag>
</bqbiol:hasVersion>
<bqbiol:hasVersion>
<rdf:Bag>
<rdf:li rdf:resource="urn:miriam:ncbigene:6546"/>
</rdf:Bag>
</bqbiol:hasVersion>
<bqbiol:hasVersion>
<rdf:Bag>
<rdf:li rdf:resource="urn:miriam:refseq:NP_001106273.1"/>
</rdf:Bag>
</bqbiol:hasVersion>
<bqbiol:hasVersion>
<rdf:Bag>
<rdf:li rdf:resource="urn:miriam:kegg.genes:hsa:6546"/>
</rdf:Bag>
</bqbiol:hasVersion>
<bqbiol:hasVersion>
<rdf:Bag>
<rdf:li rdf:resource="urn:miriam:reactome:REACT_20130"/>
</rdf:Bag>
</bqbiol:hasVersion>
<bqbiol:hasVersion>
<rdf:Bag>
<rdf:li rdf:resource="urn:miriam:pharmgkb.pathways:PA314"/>
</rdf:Bag>
</bqbiol:hasVersion>
<bqbiol:hasVersion>
<rdf:Bag>
<rdf:li rdf:resource="urn:miriam:refseq:NP_001106272.1"/>
</rdf:Bag>
</bqbiol:hasVersion>
<bqbiol:hasVersion>
<rdf:Bag>
<rdf:li rdf:resource="urn:miriam:kegg.genes:hsa%3A6546"/>
</rdf:Bag>
</bqbiol:hasVersion>
<bqbiol:hasVersion>
<rdf:Bag>
<rdf:li rdf:resource="urn:miriam:refseq:NP_001239553.1"/>
</rdf:Bag>
</bqbiol:hasVersion>
<bqbiol:hasVersion>
<rdf:Bag>
<rdf:li rdf:resource="urn:miriam:hgnc:2141"/>
</rdf:Bag>
</bqbiol:hasVersion>
<bqbiol:hasVersion>
<rdf:Bag>
<rdf:li rdf:resource="urn:miriam:refseq:NP_001106271.1"/>
</rdf:Bag>
</bqbiol:hasVersion>
</rdf:Description>
</rdf:RDF>
</body> </body>
</html> </html>
</notes> </notes>
......
...@@ -14,6 +14,7 @@ import org.reflections.Reflections; ...@@ -14,6 +14,7 @@ import org.reflections.Reflections;
import lcsb.mapviewer.common.exception.NotImplementedException; import lcsb.mapviewer.common.exception.NotImplementedException;
import lcsb.mapviewer.model.map.BioEntity; import lcsb.mapviewer.model.map.BioEntity;
import lcsb.mapviewer.model.map.reaction.Reaction; import lcsb.mapviewer.model.map.reaction.Reaction;
import lcsb.mapviewer.model.map.reaction.ReactionNode;
import lcsb.mapviewer.model.map.species.Element; import lcsb.mapviewer.model.map.species.Element;
/** /**
...@@ -257,4 +258,8 @@ public final class ElementUtils { ...@@ -257,4 +258,8 @@ public final class ElementUtils {
ElementUtils.reactionClasses = reactionClasses; ElementUtils.reactionClasses = reactionClasses;
} }
public String getElementTag(ReactionNode node) {
return "[" + node.getClass().getSimpleName() + "]" + getElementTag(node.getElement());
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment