Commit 40e94d06 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

import/export of colors added

parent ee212394
package lcsb.mapviewer.converter.model.sbgnml;
import java.awt.Color;
import java.awt.geom.Point2D;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;
import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.stream.XMLStreamException;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
......@@ -12,9 +18,12 @@ import org.sbgn.*;
import org.sbgn.bindings.*;
import org.sbgn.bindings.Arc.*;
import org.sbgn.bindings.Map;
import org.xml.sax.SAXException;
import lcsb.mapviewer.common.comparator.DoubleComparator;
import lcsb.mapviewer.common.exception.InvalidArgumentException;
import lcsb.mapviewer.common.geometry.ColorParser;
import lcsb.mapviewer.converter.ConverterException;
import lcsb.mapviewer.converter.graphics.bioEntity.element.species.SpeciesConverter;
import lcsb.mapviewer.converter.graphics.bioEntity.reaction.ReactionConverter;
import lcsb.mapviewer.model.graphics.ArrowType;
......@@ -86,22 +95,30 @@ public class SbgnmlXmlExporter {
*/
private java.util.Map<String, Object> sourceTargetMap;
RenderInformation renderInformation;
ColorParser colorParser = new ColorParser();
/**
* Transforms model into SBGN-ML xml.
*
* @param model
* model that should be transformed
* @return SBGM-ML xml string for the model
* @throws ConverterException
*/
public Sbgn toSbgnml(Model model) {
public Sbgn toSbgnml(Model model) throws ConverterException {
// Reset global variables
arcCounter = 0;
parsedOperators = new HashSet<>();
operatorIds = new HashMap<>();
sourceTargetMap = new HashMap<>();
renderInformation = new RenderInformation();
Map map = new Map();
map.setId(model.getIdModel());
map.setLanguage(Language.PD.getName());
Sbgn sbgnData = new Sbgn();
for (Element element : model.getElements()) {
......@@ -131,6 +148,11 @@ public class SbgnmlXmlExporter {
}
map.getArc().addAll(getArcsFromReaction(reaction, map.getGlyph()));
}
try {
RenderUtil.setRenderInformation(map, renderInformation);
} catch (XMLStreamException | JAXBException | ParserConfigurationException | SAXException | IOException e) {
throw new ConverterException("Problem with providing render information");
}
sbgnData.getMap().add(map);
return sbgnData;
......@@ -191,11 +213,35 @@ public class SbgnmlXmlExporter {
}
}
}
addRenderInformation(newGlyph, element);
sourceTargetMap.put(newGlyph.getId(), newGlyph);
return newGlyph;
}
private void addRenderInformation(Glyph glyph, Element element) {
float lineWidth = 1.0f;
if (element instanceof Species) {
lineWidth = ((Species) element).getLineWidth().floatValue();
} else if (element instanceof Compartment) {
lineWidth = (float) ((Compartment) element).getThickness();
}
RenderUtil.addStyle(renderInformation, glyph.getId(), colorParser.colorToHtml(element.getFillColor()),
colorParser.colorToHtml(element.getBorderColor()), lineWidth);
}
private void addRenderInformation(Glyph glyph, PolylineData line) {
float lineWidth = (float) line.getWidth();
RenderUtil.addStyle(renderInformation, glyph.getId(), colorParser.colorToHtml(Color.WHITE),
colorParser.colorToHtml(line.getColor()), lineWidth);
}
private void addRenderInformation(Arc arc, PolylineData line) {
float lineWidth = (float) line.getWidth();
RenderUtil.addStyle(renderInformation, arc.getId(), colorParser.colorToHtml(Color.WHITE),
colorParser.colorToHtml(line.getColor()), lineWidth);
}
private Glyph createStateVariableForStructuralState(StructuralState structuralState) {
Glyph glyph = new Glyph();
glyph.setId(structuralState.getSpecies().getElementId() + "-state");
......@@ -611,6 +657,8 @@ public class SbgnmlXmlExporter {
sourceTargetMap.put(processGlyph.getId(), processGlyph);
addRenderInformation(processGlyph, reaction.getLine());
return processGlyph;
}
......@@ -922,6 +970,7 @@ public class SbgnmlXmlExporter {
arc.getNext().add(next);
}
addRenderInformation(arc, node.getLine());
return arc;
}
......
......@@ -16,6 +16,7 @@ import org.sbgn.bindings.Map;
import lcsb.mapviewer.common.Configuration;
import lcsb.mapviewer.common.comparator.DoubleComparator;
import lcsb.mapviewer.common.exception.InvalidArgumentException;
import lcsb.mapviewer.common.geometry.ColorParser;
import lcsb.mapviewer.common.geometry.PointTransformation;
import lcsb.mapviewer.converter.InvalidInputDataExecption;
import lcsb.mapviewer.converter.ZIndexPopulator;
......@@ -81,6 +82,10 @@ public class SbgnmlXmlParser {
Model model;
RenderInformation renderInformation;
ColorParser colorParser = new ColorParser();
/**
* Method used to create a model from SBGN-ML file.
*
......@@ -99,6 +104,7 @@ public class SbgnmlXmlParser {
model.setIdModel(filename);
Sbgn sbgnData;
Map map;
// Check if input file has valid SBGN-ML data
try {
if (!SbgnUtil.isValid(inputSbgnmlFile)) {
......@@ -107,13 +113,17 @@ public class SbgnmlXmlParser {
// Read data from file
sbgnData = SbgnUtil.readFromFile(inputSbgnmlFile);
renderInformation = RenderUtil.getRenderInformation(sbgnData);
// Extract map with all the glyphs and arcs
map = sbgnData.getMap().get(0);
if (renderInformation == null) {
renderInformation = RenderUtil.getRenderInformation(map);
}
} catch (Exception ex) {
throw new InvalidInputDataExecption("Unable to read given file.", ex);
}
// Extract map with all the glyphs and arcs
Map map = sbgnData.getMap().get(0);
adjustSizeOfElements(map);
setModelSize(map, model);
......@@ -542,6 +552,9 @@ public class SbgnmlXmlParser {
reaction.addReactant(reactant);
reaction.addProduct(product);
assignRenderInformation(reaction.getLine(), arc);
assignRenderInformation(reactant.getLine(), arc);
assignRenderInformation(product.getLine(), arc);
model.addReaction(reaction);
}
......@@ -702,9 +715,66 @@ public class SbgnmlXmlParser {
}
}
assignRenderInformation(species, glyph);
model.addElement(species);
}
private void assignRenderInformation(Element element, Glyph glyph) {
if (renderInformation != null) {
Style style = RenderUtil.getStyle(renderInformation, glyph);
if (style != null) {
try {
element.setFillColor(colorParser.parse(style.getG().getFill()));
} catch (InvalidArgumentException e) {
logger.warn(new LogMarker(ProjectLogEntryType.PARSING_ISSUE, element),
"Invalid fill color: " + style.getG().getFill());
}
try {
element.setBorderColor(colorParser.parse(style.getG().getStroke()));
} catch (InvalidArgumentException e) {
logger.warn(new LogMarker(ProjectLogEntryType.PARSING_ISSUE, element),
"Invalid border color: " + style.getG().getStroke());
}
if (style.getG().getStrokeWidth() != null) {
if (element instanceof Species) {
((Species) element).setLineWidth((double) style.getG().getStrokeWidth());
} else if (element instanceof Compartment) {
((Compartment) element).setThickness((double) style.getG().getStrokeWidth());
}
}
}
}
}
private void assignRenderInformation(PolylineData line, Arc glyph) {
if (renderInformation != null) {
Style style = RenderUtil.getStyle(renderInformation, glyph);
assignRenderInformation(line, style);
}
}
private void assignRenderInformation(PolylineData line, Style style) {
if (style != null) {
try {
Color color = colorParser.parse(style.getG().getStroke());
line.setColor(color);
} catch (InvalidArgumentException e) {
logger.warn("Invalid border color: " + style.getG().getStroke());
}
if (style.getG().getStrokeWidth() != null) {
double lineWidth = (double) style.getG().getStrokeWidth();
line.setWidth(lineWidth);
}
}
}
private void assignRenderInformation(PolylineData line, Glyph glyph) {
if (renderInformation != null) {
Style style = RenderUtil.getStyle(renderInformation, glyph);
assignRenderInformation(line, style);
}
}
/**
* Finds a compartment where element should be located (base on the
* coordinates).
......@@ -1200,11 +1270,10 @@ public class SbgnmlXmlParser {
p.getCentralPoint().getId() + ": The process must have at least one incoming arc.");
}
Reaction reaction;
if (p.getCentralPoint() == null) {
throw new InvalidArgumentException("Process has no central point.");
}
reaction = getReactionFromProcessGlyphClazz(p.getCentralPoint().getClazz());
Reaction reaction = getReactionFromProcessGlyphClazz(p.getCentralPoint().getClazz());
reaction.setIdReaction(p.getCentralPoint().getId());
reaction.setModel(model);
......@@ -1238,6 +1307,7 @@ public class SbgnmlXmlParser {
}
reaction.addReactant(reactant);
assignRenderInformation(reactant.getLine(), a);
}
for (Arc a : p.getProductArcs()) {
......@@ -1252,6 +1322,7 @@ public class SbgnmlXmlParser {
if (splitOperator != null) {
splitOperator.addOutput(product);
}
assignRenderInformation(product.getLine(), a);
reaction.addProduct(product);
} else {
Reactant reactant = new Reactant();
......@@ -1266,6 +1337,7 @@ public class SbgnmlXmlParser {
andOperator.addInput(reactant);
}
assignRenderInformation(reactant.getLine(), a);
reaction.addReactant(reactant);
}
}
......@@ -1333,7 +1405,15 @@ public class SbgnmlXmlParser {
logger.warn(ex.getMessage());
}
}
assignRenderInformation(modifier.getLine(), a);
}
assignRenderInformation(reaction.getLine(), p.getCentralPoint());
if (andOperator != null) {
assignRenderInformation(andOperator.getLine(), p.getCentralPoint());
}
if (splitOperator != null) {
assignRenderInformation(splitOperator.getLine(), p.getCentralPoint());
}
model.addReaction(reaction);
......@@ -1560,6 +1640,7 @@ public class SbgnmlXmlParser {
compartment.getY() + compartment.getThickness() + CONTAINER_NAME_MARGIN);
}
assignRenderInformation(compartment, glyph);
model.addElement(compartment);
}
}
......@@ -3,7 +3,6 @@ package lcsb.mapviewer.converter.model.sbgnml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.awt.Color;
import java.io.File;
import java.io.FileInputStream;
import java.util.HashSet;
......@@ -19,10 +18,8 @@ import lcsb.mapviewer.common.comparator.StringComparator;
import lcsb.mapviewer.converter.Converter;
import lcsb.mapviewer.converter.ConverterParams;
import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser;
import lcsb.mapviewer.model.map.Drawable;
import lcsb.mapviewer.model.map.compartment.Compartment;
import lcsb.mapviewer.model.map.model.Model;
import lcsb.mapviewer.model.map.model.ModelComparator;
import lcsb.mapviewer.model.map.species.Element;
import lcsb.mapviewer.model.map.species.Protein;
import lcsb.mapviewer.model.map.species.field.ModificationResidue;
......
package lcsb.mapviewer.converter.model.sbgnml;
import static org.junit.Assert.assertEquals;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.Collection;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import lcsb.mapviewer.converter.Converter;
import lcsb.mapviewer.converter.ConverterParams;
import lcsb.mapviewer.converter.model.celldesigner.CellDesignerXmlParser;
import lcsb.mapviewer.model.map.Drawable;
import lcsb.mapviewer.model.map.model.Model;
import lcsb.mapviewer.model.map.model.ModelComparator;
import lcsb.mapviewer.model.map.reaction.AbstractNode;
import lcsb.mapviewer.model.map.reaction.Reaction;
import lcsb.mapviewer.model.map.species.Species;
@RunWith(Parameterized.class)
public class SbgnmlSerializationTest extends SbgnmlTestFunctions {
Logger logger = LogManager.getLogger();
private Path filePath;
public SbgnmlSerializationTest(Path filePath) {
this.filePath = filePath;
}
@Parameters(name = "{index} : {0}")
public static Collection<Object[]> data() throws IOException {
Collection<Object[]> data = new ArrayList<Object[]>();
Files.walk(Paths.get("testFiles/CellDesigner-serializable")).forEach(fPath -> {
if (Files.isRegularFile(fPath)) {
data.add(new Object[] { fPath });
}
});
return data;
}
@Test
public void modelSerialization() throws Exception {
Converter converter = new CellDesignerXmlParser();
Converter sbgnmlConverter = new SbgnmlXmlConverter();
Model model = converter.createModel(new ConverterParams().filename(filePath.toString()));
String sbgn = sbgnmlConverter.model2String(model);
Model model2 = sbgnmlConverter.createModel(
new ConverterParams().inputStream(new ByteArrayInputStream(sbgn.getBytes(StandardCharsets.UTF_8))));
model2.setIdModel(model.getIdModel());
model2.setName(model.getName());
for (Drawable d : model.getDrawables()) {
d.setZ(null);
}
for (Drawable d : model2.getDrawables()) {
d.setZ(null);
}
for (Species e: model.getSpeciesList()) {
e.setInitialAmount(null);
e.setInitialConcentration(null);
e.setCharge(null);
e.setPositionToCompartment(null);
}
model.getUnits().clear();
for (Species e: model2.getSpeciesList()) {
e.setInitialAmount(null);
e.setInitialConcentration(null);
e.setCharge(null);
e.setPositionToCompartment(null);
}
assertEquals("Import/export shouldn't produce any wanrnings", 0, super.getWarnings().size());
ModelComparator mc = new ModelComparator(0.001);
assertEquals(0, mc.compare(model, model2));
}
}
......@@ -27,7 +27,7 @@ import lcsb.mapviewer.model.map.reaction.ReactionComparator;
@RunWith(Parameterized.class)
public class SbgnmlXmlParserTest extends SbgnmlTestFunctions {
Logger logger = LogManager.getLogger(SbgnmlXmlParserTest.class.getName());
Logger logger = LogManager.getLogger();
private Path filePath;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment