Commit 1d1e8893 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

import of Sbgml provides center line for reaction

parent c017f87a
......@@ -7,7 +7,8 @@ import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.apache.logging.log4j.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.sbgn.ArcClazz;
import org.sbgn.GlyphClazz;
import org.sbgn.SbgnUtil;
......@@ -23,10 +24,12 @@ import org.sbgn.bindings.Sbgn;
import lcsb.mapviewer.common.comparator.DoubleComparator;
import lcsb.mapviewer.common.exception.InvalidArgumentException;
import lcsb.mapviewer.common.geometry.PointTransformation;
import lcsb.mapviewer.converter.InvalidInputDataExecption;
import lcsb.mapviewer.converter.ZIndexPopulator;
import lcsb.mapviewer.converter.graphics.bioEntity.element.species.SpeciesConverter;
import lcsb.mapviewer.converter.model.celldesigner.geometry.CellDesignerAliasConverter;
import lcsb.mapviewer.converter.model.celldesigner.geometry.ReactionCellDesignerConverter;
import lcsb.mapviewer.converter.model.celldesigner.types.ModifierType;
import lcsb.mapviewer.converter.model.celldesigner.types.ModifierTypeUtils;
import lcsb.mapviewer.converter.model.sbgnml.structures.Process;
......@@ -117,11 +120,15 @@ public class SbgnmlXmlParser {
*/
private static final Color COMPARTMENT_COLOR = new Color(0.5f, 0.5f, 1.0f);
private final PointTransformation pt = new PointTransformation();
/**
* Method used to create a model from SBGN-ML file.
*
* @param filename The filename of the input file.
* @param inputSbgnmlFile the input file.
* @param filename
* The filename of the input file.
* @param inputSbgnmlFile
* the input file.
*
* @return valid model parsed from the file
* @throws InvalidInputDataExecption
......@@ -169,7 +176,7 @@ public class SbgnmlXmlParser {
try {
parseProcess(p, model);
} catch (Exception e) {
logger.warn("Unable to parse the process: " + p.getCentralPoint().getId());
throw new InvalidInputDataExecption("Unable to parse the process: " + p.getCentralPoint().getId(), e);
}
}
......@@ -186,7 +193,7 @@ public class SbgnmlXmlParser {
}
}
}
new ZIndexPopulator().populateZIndex(model);
return model;
......@@ -473,8 +480,8 @@ public class SbgnmlXmlParser {
}
try {
parsePhenotypeArc(a, model);
} catch (Exception ex) {
logger.warn(ex.getMessage());
} catch (Exception e) {
logger.warn(e.getMessage(), e);
}
break;
}
......@@ -506,15 +513,15 @@ public class SbgnmlXmlParser {
/**
* Method used to parse arc going to or from a phenotype.
*
* @param a
* @param arc
* arc to be parsed
* @param model
* model to be updated
*/
private void parsePhenotypeArc(Arc a, Model model) {
private void parsePhenotypeArc(Arc arc, Model model) {
Reaction reaction;
switch (ArcClazz.fromClazz(a.getClazz())) {
switch (ArcClazz.fromClazz(arc.getClazz())) {
case INHIBITION:
reaction = new NegativeInfluenceReaction();
......@@ -532,36 +539,62 @@ public class SbgnmlXmlParser {
throw new InvalidArgumentException();
}
reaction.setIdReaction(a.getId());
reaction.setModel(model);
reaction.setIdReaction(arc.getId());
Reactant reactant = new Reactant();
reactant.setReaction(reaction);
Glyph source = (Glyph) a.getSource();
reactant.setElement(model.getElementByElementId(source.getId()));
List<Point2D> reactantPointList = new ArrayList<>();
reactantPointList.add(new Point2D.Double(a.getStart().getX(), a.getStart().getY()));
reactantPointList.add(new Point2D.Double(a.getStart().getX(), a.getStart().getY()));
PolylineData reactantLine = new PolylineData(reactantPointList);
ArrowTypeData atd = new ArrowTypeData();
atd.setArrowType(ArrowType.NONE);
atd.setArrowLineType(LineType.SOLID);
reactantLine.setEndAtd(atd);
Glyph source = (Glyph) arc.getSource();
Glyph target = (Glyph) arc.getTarget();
List<Point2D> productPointList = getLinePoints(arc);
if (productPointList.size() == 2) {
Point2D secondPoint = pt.getPointOnLine(productPointList.get(0), productPointList.get(1), 0.4);
Point2D thirdPoint = pt.getPointOnLine(productPointList.get(0), productPointList.get(1), 0.6);
productPointList.add(1, secondPoint);
productPointList.add(2, thirdPoint);
}
if (productPointList.size() == 3) {
if (productPointList.get(0).distance(productPointList.get(1)) > productPointList.get(1)
.distance(productPointList.get(2))) {
Point2D newPoint = pt.getPointOnLine(productPointList.get(0), productPointList.get(1), 0.5);
productPointList.add(1, newPoint);
} else {
Point2D newPoint = pt.getPointOnLine(productPointList.get(1), productPointList.get(2), 0.5);
productPointList.add(2, newPoint);
}
}
int reactantPointEnds = (productPointList.size()-1) / 2;
int productPointStarts = reactantPointEnds + 1;
Reactant reactant = new Reactant(model.getElementByElementId(source.getId()));
Product product = new Product(model.getElementByElementId(target.getId()));
PolylineData reactantLine = new PolylineData(productPointList.subList(0, reactantPointEnds + 1)).copy();
reactantLine.setEndAtd(createDefaultArrowTypeData());
reactant.setLine(reactantLine);
reaction.addReactant(reactant);
Product product = new Product();
product.setReaction(reaction);
Glyph target = (Glyph) a.getTarget();
product.setElement(model.getElementByElementId(target.getId()));
List<Point2D> productPointList = getLinePoints(a);
PolylineData productLine = parseLine(a, productPointList);
PolylineData centerLine = new PolylineData(productPointList.subList(reactantPointEnds, productPointStarts + 1))
.copy();
reaction.setLine(centerLine);
ArrowTypeData productAtd = extractArrowTypeDataFromArc(arc);
PolylineData productLine = new PolylineData(
productPointList.subList(productPointStarts, productPointList.size())).copy();
productLine.setEndAtd(productAtd);
product.setLine(productLine);
reaction.addReactant(reactant);
reaction.addProduct(product);
model.addReaction(reaction);
}
private ArrowTypeData createDefaultArrowTypeData() {
ArrowTypeData atd = new ArrowTypeData();
atd.setArrowType(ArrowType.NONE);
atd.setArrowLineType(LineType.SOLID);
return atd;
}
/**
* Method used to parse a single species.
*
......@@ -969,16 +1002,16 @@ public class SbgnmlXmlParser {
/**
* Method used to parse line points from SBGN-ML arc.
*
* @param a
* @param arc
* SBGN-ML arc
* @return list of line points
*/
private List<Point2D> getLinePoints(Arc a) {
private List<Point2D> getLinePoints(Arc arc) {
List<Point2D> pointList = new ArrayList<>();
Point2D startPoint = new Point2D.Double(a.getStart().getX(), a.getStart().getY());
Point2D endPoint = new Point2D.Double(a.getEnd().getX(), a.getEnd().getY());
Point2D startPoint = new Point2D.Double(arc.getStart().getX(), arc.getStart().getY());
Point2D endPoint = new Point2D.Double(arc.getEnd().getX(), arc.getEnd().getY());
pointList.add(startPoint);
for (Next nextPoint : a.getNext()) {
for (Next nextPoint : arc.getNext()) {
pointList.add(new Point2D.Double(nextPoint.getX(), nextPoint.getY()));
}
pointList.add(endPoint);
......@@ -996,6 +1029,12 @@ public class SbgnmlXmlParser {
*/
private PolylineData parseLine(Arc a, List<Point2D> pointList) {
PolylineData line = new PolylineData(pointList);
ArrowTypeData atd = extractArrowTypeDataFromArc(a);
line.setEndAtd(atd.copy());
return line;
}
private ArrowTypeData extractArrowTypeDataFromArc(Arc a) {
ArrowTypeData atd = new ArrowTypeData();
switch (ArcClazz.fromClazz(a.getClazz())) {
......@@ -1027,8 +1066,7 @@ public class SbgnmlXmlParser {
throw new InvalidArgumentException("Wrong arc class.");
}
atd.setArrowLineType(LineType.SOLID);
line.setEndAtd(atd.copy());
return line;
return atd;
}
/**
......@@ -1082,7 +1120,7 @@ public class SbgnmlXmlParser {
portPoint = new Point2D.Double(p.getRevProductArcs().get(0).getStart().getX(),
p.getRevProductArcs().get(0).getStart().getY());
}
PolylineData line = new PolylineData(centerOfReactionPoint, portPoint);
PolylineData line = new PolylineData(portPoint, centerOfReactionPoint);
ArrowTypeData atd = new ArrowTypeData();
atd.setArrowType(ArrowType.NONE);
atd.setArrowLineType(LineType.SOLID);
......@@ -1200,7 +1238,6 @@ public class SbgnmlXmlParser {
AndOperator andOperator = null;
if (p.getReagentArcs().size() > 1 || p.getRevReagentArcs().size() > 1) {
andOperator = getReactionPortAndOperator(p);
andOperator.setReaction(reaction);
reaction.addNode(andOperator);
}
......@@ -1209,7 +1246,6 @@ public class SbgnmlXmlParser {
if ((p.getProductArcs().size() > 1 && !p.isReversible())
|| (p.isReversible() && p.getRevProductArcs().size() > 1)) {
splitOperator = getReactionPortSplitOperator(p);
splitOperator.setReaction(reaction);
reaction.addNode(splitOperator);
}
......@@ -1240,11 +1276,6 @@ public class SbgnmlXmlParser {
Glyph target = (Glyph) a.getTarget();
product.setElement(model.getElementByElementId(target.getId()));
List<Point2D> pointList = getLinePoints(a);
if (p.getRevProductArcs().size() >= 1) {
pointList.add(0, getCenterPointFromProcess(p));
} else {
pointList.add(0, pointList.get(0));
}
PolylineData line = parseLine(a, pointList);
product.setLine(line);
if (splitOperator != null) {
......@@ -1258,11 +1289,6 @@ public class SbgnmlXmlParser {
Glyph source = (Glyph) a.getTarget();
reactant.setElement(model.getElementByElementId(source.getId()));
List<Point2D> pointList = getLinePoints(a);
if (p.getRevReagentArcs().size() <= 1) {
pointList.add(0, getCenterPointFromProcess(p));
} else {
pointList.add(0, pointList.get(0));
}
PolylineData line = parseLine(a, pointList);
line = line.reverse();
reactant.setLine(line);
......@@ -1273,6 +1299,26 @@ public class SbgnmlXmlParser {
reaction.addReactant(reactant);
}
}
Point2D centerPointStart = reaction.getReactants().get(0).getLine().getEndPoint();
if (andOperator != null) {
andOperator.getLine().trimEnd(ReactionCellDesignerConverter.RECT_SIZE / 2 - 1);
centerPointStart = andOperator.getLine().getEndPoint();
} else {
reaction.getReactants().get(0).getLine().trimEnd(ReactionCellDesignerConverter.RECT_SIZE / 2 - 1);
}
Point2D centerPointEnd = reaction.getProducts().get(0).getLine().getBeginPoint();
if (splitOperator != null) {
splitOperator.getLine().trimEnd(ReactionCellDesignerConverter.RECT_SIZE / 2 - 1);
centerPointEnd = splitOperator.getLine().getEndPoint();
} else {
reaction.getProducts().get(0).getLine().trimBegin(ReactionCellDesignerConverter.RECT_SIZE / 2 - 1);
}
PolylineData centerLine = new PolylineData(pt.copyPoint(centerPointStart), pt.copyPoint(centerPointEnd));
reaction.setLine(centerLine);
for (Arc a : p.getModifierArcs()) {
Modifier modifier = null;
try {
......
......@@ -4,7 +4,8 @@ import static org.junit.Assert.assertEquals;
import java.io.File;
import org.apache.logging.log4j.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
......@@ -23,7 +24,7 @@ import lcsb.mapviewer.persist.dao.map.ModelDao;
@Transactional
@ContextConfiguration(classes = SpringSBGNMLConverterTestConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class DbSerializationTest {
public class DbSerializationTest extends SbgnmlTestFunctions {
@Autowired
ModelDao modelDao;
@Autowired
......
package lcsb.mapviewer.converter.model.sbgnml;
import java.awt.Desktop;
import java.io.File;
import java.nio.file.Files;
import lcsb.mapviewer.converter.graphics.AbstractImageGenerator;
import lcsb.mapviewer.converter.graphics.NormalImageGenerator;
import lcsb.mapviewer.converter.graphics.PngImageGenerator;
import lcsb.mapviewer.model.map.model.Model;
public class SbgnmlTestFunctions {
protected void showImage(Model model) throws Exception {
String dir = Files.createTempDirectory("sbml-temp-images-dir").toFile().getAbsolutePath();
AbstractImageGenerator.Params params = new AbstractImageGenerator.Params().height(model.getHeight())
.width(model.getWidth()).nested(true).scale(1).level(20).x(0).y(0).model(model);
NormalImageGenerator nig = new PngImageGenerator(params);
String pathWithouExtension = dir + "/" + model.getName();
String pngFilePath = pathWithouExtension.concat(".png");
nig.saveToFile(pngFilePath);
Desktop.getDesktop().open(new File(pngFilePath));
}
}
package lcsb.mapviewer.converter.model.sbgnml;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.awt.geom.Point2D;
import org.apache.logging.log4j.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Test;
import lcsb.mapviewer.common.Configuration;
import lcsb.mapviewer.converter.ConverterParams;
import lcsb.mapviewer.converter.Converter;
import lcsb.mapviewer.converter.ConverterParams;
import lcsb.mapviewer.model.map.compartment.Compartment;
import lcsb.mapviewer.model.map.model.Model;
import lcsb.mapviewer.model.map.reaction.NodeOperator;
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.species.Complex;
import lcsb.mapviewer.model.map.species.GenericProtein;
import lcsb.mapviewer.model.map.species.field.Residue;
......@@ -76,4 +82,35 @@ public class SbgnmlXmlParserTest2 {
}
}
@Test
public void testCoordinatesOfOperators() throws Exception {
Converter converter = new SbgnmlXmlConverter();
Model model = converter
.createModel(new ConverterParams().filename("testFiles/sbgnmlParserTestFiles/sbgnmlFiles/clone-marker.sbgn"));
Reaction reaction = model.getReactionByReactionId("glyph9");
Reactant r1 = reaction.getReactants().get(0);
Reactant r2 = reaction.getReactants().get(1);
Product p1 = reaction.getProducts().get(0);
Product p2 = reaction.getProducts().get(1);
NodeOperator inputOperator = null;
NodeOperator outputOperator= null;
for (NodeOperator operator: reaction.getOperators()) {
if (operator.isProductOperator()) {
outputOperator = operator;
} else {
inputOperator = operator;
}
}
assertEquals(r1.getLine().getEndPoint(), inputOperator.getLine().getBeginPoint());
assertEquals(r2.getLine().getEndPoint(), inputOperator.getLine().getBeginPoint());
assertEquals(p1.getLine().getBeginPoint(), outputOperator.getLine().getBeginPoint());
assertEquals(p2.getLine().getBeginPoint(), outputOperator.getLine().getBeginPoint());
}
}
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