From 609847438d6e7818bc3c35ac7e656f268811351d Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Thu, 12 Jul 2018 13:02:45 +0200
Subject: [PATCH] BindingRegion data model is supported

---
 .../celldesigner/species/GeneXmlParser.java   | 16 +++-
 .../CellDesignerModificationResidue.java      | 38 +++++++-
 .../structure/fields/ModificationType.java    |  1 +
 .../CellDesignerXmlParserTest.java            | 29 +++++-
 .../species/GeneXmlParserTest.java            |  4 +-
 .../testFiles/gene_with_regulatory_region.xml | 90 +++++++++++++++++++
 .../map/species/field/BindingRegion.java      | 10 +--
 .../map/species/field/RegulatoryRegion.java   | 69 ++++++++++++++
 8 files changed, 244 insertions(+), 13 deletions(-)
 create mode 100644 converter-CellDesigner/testFiles/gene_with_regulatory_region.xml
 create mode 100644 model/src/main/java/lcsb/mapviewer/model/map/species/field/RegulatoryRegion.java

diff --git a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/species/GeneXmlParser.java b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/species/GeneXmlParser.java
index c4f99ad170..433c5eeecf 100644
--- a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/species/GeneXmlParser.java
+++ b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/species/GeneXmlParser.java
@@ -15,8 +15,10 @@ import lcsb.mapviewer.converter.model.celldesigner.structure.CellDesignerGene;
 import lcsb.mapviewer.converter.model.celldesigner.structure.fields.CellDesignerModificationResidue;
 import lcsb.mapviewer.converter.model.celldesigner.structure.fields.ModificationType;
 import lcsb.mapviewer.model.map.species.Gene;
+import lcsb.mapviewer.model.map.species.field.CodingRegion;
 import lcsb.mapviewer.model.map.species.field.ModificationResidue;
 import lcsb.mapviewer.model.map.species.field.ModificationSite;
+import lcsb.mapviewer.model.map.species.field.RegulatoryRegion;
 
 /**
  * Class that performs parsing of the CellDesigner xml for
@@ -97,6 +99,8 @@ public class GeneXmlParser extends AbstractElementXmlParser<CellDesignerGene, Ge
     residue.setIdModificationResidue(getNodeAttr("id", residueNode));
     residue.setName(getNodeAttr("name", residueNode));
     residue.setSide(getNodeAttr("side", residueNode));
+    residue.setSize(getNodeAttr("size", residueNode));
+    residue.setActive(getNodeAttr("active", residueNode));
     residue.setAngle(getNodeAttr("pos", residueNode));
     String type = getNodeAttr("type", residueNode);
     try {
@@ -161,9 +165,19 @@ public class GeneXmlParser extends AbstractElementXmlParser<CellDesignerGene, Ge
     if (!mr.getName().equals("")) {
       attributes += " name=\"" + escapeXml(mr.getName()) + "\"";
     }
+    String type = null;
     if (mr instanceof ModificationSite) {
-      attributes += " type=\"Modification Site\"";
+      type = ModificationType.MODIFICATION_SITE.getCellDesignerName();
+    } else if (mr instanceof RegulatoryRegion) {
+      type = ModificationType.REGULATORY_REGION.getCellDesignerName();
+      attributes += " size=\"" + ((RegulatoryRegion) mr).getWidth() / mr.getSpecies().getWidth() + "\"";
+    } else if (mr instanceof CodingRegion) {
+      type = ModificationType.CODING_REGION.getCellDesignerName();
+      attributes += " size=\"" + ((RegulatoryRegion) mr).getWidth() / mr.getSpecies().getWidth() + "\"";
+    } else {
+      throw new InvalidArgumentException("Don't know how to handle: " + mr.getClass());
     }
+    attributes += " type=\"" + type + "\"";
     attributes += " pos=\"" + converter.getAngleForPoint(mr.getSpecies(), mr.getPosition()) + "\"";
     result += "<celldesigner:region " + attributes + ">";
     result += "</celldesigner:region>\n";
diff --git a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/structure/fields/CellDesignerModificationResidue.java b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/structure/fields/CellDesignerModificationResidue.java
index 96a93eeaca..2124f8e0b8 100644
--- a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/structure/fields/CellDesignerModificationResidue.java
+++ b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/structure/fields/CellDesignerModificationResidue.java
@@ -16,6 +16,7 @@ import lcsb.mapviewer.model.map.species.field.ModificationResidue;
 import lcsb.mapviewer.model.map.species.field.ModificationSite;
 import lcsb.mapviewer.model.map.species.field.ModificationState;
 import lcsb.mapviewer.model.map.species.field.ProteinBindingDomain;
+import lcsb.mapviewer.model.map.species.field.RegulatoryRegion;
 import lcsb.mapviewer.model.map.species.field.Residue;
 
 /**
@@ -46,6 +47,8 @@ public class CellDesignerModificationResidue implements Serializable {
    */
   private String name = "";
 
+  private Boolean active = null;
+
   private ModificationType modificationType;
 
   /**
@@ -125,16 +128,20 @@ public class CellDesignerModificationResidue implements Serializable {
     } else if (mr instanceof ProteinBindingDomain) {
       this.size = ((CodingRegion) mr).getWidth() / mr.getSpecies().getWidth();
       this.modificationType = ModificationType.PROTEIN_BINDING_DOMAIN;
+    } else if (mr instanceof RegulatoryRegion) {
+      this.size = ((RegulatoryRegion) mr).getWidth() / mr.getSpecies().getWidth();
+      this.modificationType = ModificationType.REGULATORY_REGION;
     } else if (mr instanceof BindingRegion) {
       this.modificationType = ModificationType.BINDING_REGION;
       if (Math.abs(mr.getPosition().getX() - mr.getSpecies().getX()) < Configuration.EPSILON) {
         this.size = ((BindingRegion) mr).getHeight() / mr.getSpecies().getHeight();
-      } else if (Math.abs(mr.getPosition().getX() - mr.getSpecies().getX() - mr.getSpecies().getWidth()) < Configuration.EPSILON) {
+      } else if (Math
+          .abs(mr.getPosition().getX() - mr.getSpecies().getX() - mr.getSpecies().getWidth()) < Configuration.EPSILON) {
         this.size = ((BindingRegion) mr).getHeight() / mr.getSpecies().getHeight();
       } else {
         this.size = ((BindingRegion) mr).getWidth() / mr.getSpecies().getWidth();
       }
-      
+
     } else {
       throw new InvalidArgumentException("Unknown modification type: " + mr.getClass());
     }
@@ -377,6 +384,8 @@ public class CellDesignerModificationResidue implements Serializable {
       return createCodingRegion(element, converter);
     } else if (modificationType.equals(ModificationType.PROTEIN_BINDING_DOMAIN)) {
       return createProteinBindingDomain(element, converter);
+    } else if (modificationType.equals(ModificationType.REGULATORY_REGION)) {
+      return createRegulatoryRegion(element, converter);
     } else {
       throw new InvalidArgumentException("Unknown modification type: " + modificationType);
     }
@@ -416,6 +425,15 @@ public class CellDesignerModificationResidue implements Serializable {
     return result;
   }
 
+  private RegulatoryRegion createRegulatoryRegion(Element element, CellDesignerAliasConverter converter) {
+    RegulatoryRegion result = new RegulatoryRegion();
+    result.setWidth(element.getWidth() * size);
+    result.setIdModificationResidue(idModificationResidue);
+    result.setName(name);
+    result.setPosition(converter.getResidueCoordinates(element, angle));
+    return result;
+  }
+
   private ModificationSite createModificationSite(Element element, CellDesignerAliasConverter converter) {
     ModificationSite result = new ModificationSite();
     result.setState(this.getState());
@@ -482,4 +500,20 @@ public class CellDesignerModificationResidue implements Serializable {
     this.pos = pos;
   }
 
+  public Boolean getActive() {
+    return active;
+  }
+
+  public void setActive(Boolean active) {
+    this.active = active;
+  }
+
+  public void setActive(String text) {
+    if (text == null) {
+      this.active = null;
+    } else {
+      this.active = "true".equalsIgnoreCase(text);
+    }
+  }
+
 }
diff --git a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/structure/fields/ModificationType.java b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/structure/fields/ModificationType.java
index 73220c2ffa..7f69cd78eb 100644
--- a/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/structure/fields/ModificationType.java
+++ b/converter-CellDesigner/src/main/java/lcsb/mapviewer/converter/model/celldesigner/structure/fields/ModificationType.java
@@ -7,6 +7,7 @@ public enum ModificationType {
   CODING_REGION("CodingRegion"), //
   PROTEIN_BINDING_DOMAIN("proteinBindingDomain"), //
   RESIDUE(null), //
+  REGULATORY_REGION("RegulatoryRegion"), //
   MODIFICATION_SITE("Modification Site");//
 
   private String cellDesignerName;
diff --git a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParserTest.java b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParserTest.java
index 102960dae0..67e8f4af53 100644
--- a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParserTest.java
+++ b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/CellDesignerXmlParserTest.java
@@ -52,6 +52,7 @@ import lcsb.mapviewer.model.map.species.SimpleMolecule;
 import lcsb.mapviewer.model.map.species.Species;
 import lcsb.mapviewer.model.map.species.field.BindingRegion;
 import lcsb.mapviewer.model.map.species.field.ModificationResidue;
+import lcsb.mapviewer.model.map.species.field.RegulatoryRegion;
 
 public class CellDesignerXmlParserTest extends CellDesignerTestFunctions {
   Logger logger = Logger.getLogger(CellDesignerXmlParserTest.class);
@@ -1019,7 +1020,33 @@ public class CellDesignerXmlParserTest extends CellDesignerTestFunctions {
       String xml = parser.toXml(model);
       InputStream is = new ByteArrayInputStream(xml.getBytes("UTF-8"));
       Model model2 = parser.createModel(new ConverterParams().inputStream(is));
-      
+
+      model.setName(null);
+      ModelComparator comparator = new ModelComparator();
+      assertEquals(0, comparator.compare(model, model2));
+    } catch (Exception e) {
+      e.printStackTrace();
+      throw e;
+    }
+  }
+
+  @Test
+  public void testRegulatoryRegion() throws Exception {
+    try {
+      CellDesignerXmlParser parser = new CellDesignerXmlParser();
+      Model model = parser.createModel(new ConverterParams().filename("testFiles/gene_with_regulatory_region.xml"));
+      Gene gene = model.getElementByElementId("sa1");
+      assertEquals(1, gene.getModificationResidues().size());
+      ModificationResidue residue = gene.getModificationResidues().get(0);
+      assertTrue(residue instanceof RegulatoryRegion);
+      RegulatoryRegion bindingRegion = (RegulatoryRegion) residue;
+      assertEquals(bindingRegion.getPosition().getY(), gene.getY(), Configuration.EPSILON);
+      assertTrue(bindingRegion.getWidth() > bindingRegion.getHeight());
+
+      String xml = parser.toXml(model);
+      InputStream is = new ByteArrayInputStream(xml.getBytes("UTF-8"));
+      Model model2 = parser.createModel(new ConverterParams().inputStream(is));
+
       model.setName(null);
       ModelComparator comparator = new ModelComparator();
       assertEquals(0, comparator.compare(model, model2));
diff --git a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/species/GeneXmlParserTest.java b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/species/GeneXmlParserTest.java
index 346852b131..c4c864b485 100644
--- a/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/species/GeneXmlParserTest.java
+++ b/converter-CellDesigner/src/test/java/lcsb/mapviewer/converter/model/celldesigner/species/GeneXmlParserTest.java
@@ -151,12 +151,12 @@ public class GeneXmlParserTest extends CellDesignerTestFunctions {
   @Test
   public void testModificationResidueToXml() throws Exception {
     try {
-      Protein protein = new GenericProtein("id");
+      Gene protein = new Gene("id");
       protein.setX(10);
       protein.setY(10);
       protein.setWidth(10);
       protein.setHeight(10);
-      Residue mr = new Residue();
+      ModificationSite mr = new ModificationSite();
       mr.setIdModificationResidue("i");
       mr.setName("a");
       mr.setPosition(new Point2D.Double(3.0, 2.0));
diff --git a/converter-CellDesigner/testFiles/gene_with_regulatory_region.xml b/converter-CellDesigner/testFiles/gene_with_regulatory_region.xml
new file mode 100644
index 0000000000..aeaa022524
--- /dev/null
+++ b/converter-CellDesigner/testFiles/gene_with_regulatory_region.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sbml xmlns="http://www.sbml.org/sbml/level2/version4" xmlns:celldesigner="http://www.sbml.org/2001/ns/celldesigner" level="2" version="4">
+<model metaid="untitled" id="untitled">
+<annotation>
+<celldesigner:extension>
+<celldesigner:modelVersion>4.0</celldesigner:modelVersion>
+<celldesigner:modelDisplay sizeX="600" sizeY="400"/>
+<celldesigner:listOfCompartmentAliases/>
+<celldesigner:listOfComplexSpeciesAliases/>
+<celldesigner:listOfSpeciesAliases>
+<celldesigner:speciesAlias id="sa1" species="s1">
+<celldesigner:activity>inactive</celldesigner:activity>
+<celldesigner:bounds x="224.0" y="259.5" w="70.0" h="25.0"/>
+<celldesigner:font size="12"/>
+<celldesigner:view state="usual"/>
+<celldesigner:usualView>
+<celldesigner:innerPosition x="0.0" y="0.0"/>
+<celldesigner:boxSize width="70.0" height="25.0"/>
+<celldesigner:singleLine width="1.0"/>
+<celldesigner:paint color="ffffff66" scheme="Color"/>
+</celldesigner:usualView>
+<celldesigner:briefView>
+<celldesigner:innerPosition x="0.0" y="0.0"/>
+<celldesigner:boxSize width="80.0" height="60.0"/>
+<celldesigner:singleLine width="0.0"/>
+<celldesigner:paint color="3fff0000" scheme="Color"/>
+</celldesigner:briefView>
+<celldesigner:info state="empty" angle="-1.5707963267948966"/>
+</celldesigner:speciesAlias>
+</celldesigner:listOfSpeciesAliases>
+<celldesigner:listOfGroups/>
+<celldesigner:listOfProteins/>
+<celldesigner:listOfGenes>
+<celldesigner:gene id="gn1" name="s1" type="GENE">
+<celldesigner:listOfRegions>
+<celldesigner:region id="tr1" name="xx" size="0.78" pos="0.0" type="RegulatoryRegion" active="false"/>
+</celldesigner:listOfRegions>
+</celldesigner:gene>
+</celldesigner:listOfGenes>
+<celldesigner:listOfRNAs/>
+<celldesigner:listOfAntisenseRNAs/>
+<celldesigner:listOfLayers/>
+<celldesigner:listOfBlockDiagrams/>
+</celldesigner:extension>
+</annotation>
+<listOfUnitDefinitions>
+<unitDefinition metaid="substance" id="substance" name="substance">
+<listOfUnits>
+<unit metaid="CDMT00001" kind="mole"/>
+</listOfUnits>
+</unitDefinition>
+<unitDefinition metaid="volume" id="volume" name="volume">
+<listOfUnits>
+<unit metaid="CDMT00002" kind="litre"/>
+</listOfUnits>
+</unitDefinition>
+<unitDefinition metaid="area" id="area" name="area">
+<listOfUnits>
+<unit metaid="CDMT00003" kind="metre" exponent="2"/>
+</listOfUnits>
+</unitDefinition>
+<unitDefinition metaid="length" id="length" name="length">
+<listOfUnits>
+<unit metaid="CDMT00004" kind="metre"/>
+</listOfUnits>
+</unitDefinition>
+<unitDefinition metaid="time" id="time" name="time">
+<listOfUnits>
+<unit metaid="CDMT00005" kind="second"/>
+</listOfUnits>
+</unitDefinition>
+</listOfUnitDefinitions>
+<listOfCompartments>
+<compartment metaid="default" id="default" size="1" units="volume"/>
+</listOfCompartments>
+<listOfSpecies>
+<species metaid="s1" id="s1" name="s1" compartment="default" initialAmount="0">
+<annotation>
+<celldesigner:extension>
+<celldesigner:positionToCompartment>inside</celldesigner:positionToCompartment>
+<celldesigner:speciesIdentity>
+<celldesigner:class>GENE</celldesigner:class>
+<celldesigner:geneReference>gn1</celldesigner:geneReference>
+</celldesigner:speciesIdentity>
+</celldesigner:extension>
+</annotation>
+</species>
+</listOfSpecies>
+</model>
+</sbml>
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/field/BindingRegion.java b/model/src/main/java/lcsb/mapviewer/model/map/species/field/BindingRegion.java
index f2b163b7c7..b334ee3191 100644
--- a/model/src/main/java/lcsb/mapviewer/model/map/species/field/BindingRegion.java
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/field/BindingRegion.java
@@ -8,18 +8,14 @@ import javax.persistence.Entity;
 import org.apache.log4j.Logger;
 
 import lcsb.mapviewer.common.exception.NotImplementedException;
-import lcsb.mapviewer.model.map.species.AntisenseRna;
-import lcsb.mapviewer.model.map.species.Gene;
-import lcsb.mapviewer.model.map.species.Rna;
+import lcsb.mapviewer.model.map.species.Protein;
 import lcsb.mapviewer.model.map.species.Species;
 
 /**
- * This structure contains information about Coding Region for one of the
+ * This structure contains information about Binding Region for one of the
  * following {@link Species}:
  * <ul>
- * <li>{@link Rna}</li>
- * <li>{@link AntisenseRna}</li>
- * <li>{@link Gene}</li>
+ * <li>{@link Protein}</li>
  * </ul>
  * 
  * @author Piotr Gawron
diff --git a/model/src/main/java/lcsb/mapviewer/model/map/species/field/RegulatoryRegion.java b/model/src/main/java/lcsb/mapviewer/model/map/species/field/RegulatoryRegion.java
new file mode 100644
index 0000000000..c2aa45c683
--- /dev/null
+++ b/model/src/main/java/lcsb/mapviewer/model/map/species/field/RegulatoryRegion.java
@@ -0,0 +1,69 @@
+package lcsb.mapviewer.model.map.species.field;
+
+import java.io.Serializable;
+
+import javax.persistence.DiscriminatorValue;
+import javax.persistence.Entity;
+
+import org.apache.log4j.Logger;
+
+import lcsb.mapviewer.common.exception.NotImplementedException;
+import lcsb.mapviewer.model.map.species.Gene;
+import lcsb.mapviewer.model.map.species.Species;
+
+/**
+ * This structure contains information about Regulatory Region for one of the
+ * following {@link Species}:
+ * <ul>
+ * <li>{@link Gene}</li>
+ * </ul>
+ * 
+ * @author Piotr Gawron
+ * 
+ */
+@Entity
+@DiscriminatorValue("MODIFICATION_SITE")
+public class RegulatoryRegion extends AbstractRegionModification implements Serializable {
+
+  /**
+   * 
+   */
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * Default class logger.
+   */
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(RegulatoryRegion.class);
+
+  /**
+   * Default constructor.
+   */
+  public RegulatoryRegion() {
+
+  }
+
+  /**
+   * Constructor that initialize object with the data from the parameter.
+   * 
+   * @param original
+   *          object from which we initialize data
+   */
+  public RegulatoryRegion(RegulatoryRegion original) {
+    super(original);
+  }
+
+  /**
+   * Creates a copy of current object.
+   * 
+   * @return copy of the object
+   */
+  public RegulatoryRegion copy() {
+    if (this.getClass() == RegulatoryRegion.class) {
+      return new RegulatoryRegion(this);
+    } else {
+      throw new NotImplementedException("Method copy() should be overriden in class " + this.getClass());
+    }
+
+  }
+}
-- 
GitLab