Merge branch 'develop' into JAL-1705_trialMerge
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 28 Jan 2016 12:07:40 +0000 (12:07 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Thu, 28 Jan 2016 12:07:40 +0000 (12:07 +0000)
Conflicts:
src/jalview/analysis/AlignmentUtils.java
src/jalview/analysis/CrossRef.java
src/jalview/structure/StructureSelectionManager.java
src/jalview/ws/dbsources/Uniprot.java
test/jalview/analysis/AlignmentUtilsTests.java
test/jalview/util/MappingUtilsTest.java
test/jalview/ws/seqfetcher/DbRefFetcherTest.java

95 files changed:
RELEASE
help/html/features/annotation.html
help/html/menus/alignmentMenu.html
help/html/menus/alwannotationpanel.html
help/html/menus/alwedit.html
help/html/releases.html
help/html/whatsNew.html
resources/lang/Messages.properties
schemas/sifts/alignment.xsd [new file with mode: 0644]
schemas/sifts/dataTypes.xsd [new file with mode: 0644]
schemas/sifts/eFamily.xsd [new file with mode: 0644]
src/MCview/PDBfile.java
src/jalview/analysis/AlignSeq.java
src/jalview/analysis/AlignmentUtils.java
src/jalview/analysis/CrossRef.java
src/jalview/analysis/Dna.java
src/jalview/analysis/SequenceIdMatcher.java
src/jalview/api/DBRefEntryI.java [new file with mode: 0644]
src/jalview/api/SiftsClientI.java [new file with mode: 0644]
src/jalview/appletgui/APopupMenu.java
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/AnnotationPanel.java
src/jalview/appletgui/ScalePanel.java
src/jalview/appletgui/SeqPanel.java
src/jalview/bin/Cache.java
src/jalview/commands/TrimRegionCommand.java
src/jalview/controller/AlignViewController.java
src/jalview/datamodel/AlignmentAnnotation.java
src/jalview/datamodel/ColumnSelection.java
src/jalview/datamodel/DBRefEntry.java
src/jalview/datamodel/Sequence.java
src/jalview/datamodel/SequenceGroup.java
src/jalview/datamodel/SequenceI.java
src/jalview/ext/jmol/JalviewJmolBinding.java
src/jalview/ext/jmol/JmolCommands.java
src/jalview/ext/jmol/PDBFileWithJmol.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AnnotationPanel.java
src/jalview/gui/Jalview2XML.java
src/jalview/gui/Jalview2XML_V1.java
src/jalview/gui/PopupMenu.java
src/jalview/gui/Preferences.java
src/jalview/gui/ScalePanel.java
src/jalview/gui/SeqPanel.java
src/jalview/gui/SequenceFetcher.java
src/jalview/gui/StructureChooser.java
src/jalview/gui/TreePanel.java
src/jalview/io/ClustalFile.java
src/jalview/io/FastaFile.java
src/jalview/io/MSFfile.java
src/jalview/io/ModellerDescription.java
src/jalview/io/PIRFile.java
src/jalview/io/PfamFile.java
src/jalview/io/PileUpfile.java
src/jalview/io/SequenceAnnotationReport.java
src/jalview/io/StockholmFile.java
src/jalview/io/WSWUBlastClient.java
src/jalview/io/vamsas/Datasetsequence.java
src/jalview/io/vamsas/Sequencemapping.java
src/jalview/javascript/JsSelectionSender.java
src/jalview/jbgui/GPreferences.java
src/jalview/jbgui/GStructureChooser.java
src/jalview/renderer/AnnotationRenderer.java
src/jalview/structure/StructureMapping.java
src/jalview/structure/StructureSelectionManager.java
src/jalview/util/Comparison.java
src/jalview/util/MappingUtils.java
src/jalview/viewmodel/AlignmentViewport.java
src/jalview/ws/DBRefFetcher.java
src/jalview/ws/DasSequenceFeatureFetcher.java
src/jalview/ws/dbsources/Pdb.java
src/jalview/ws/dbsources/Uniprot.java
src/jalview/ws/seqfetcher/ASequenceFetcher.java
src/jalview/ws/sifts/MappingOutputPojo.java [new file with mode: 0644]
src/jalview/ws/sifts/SiftsClient.java [new file with mode: 0644]
src/jalview/ws/sifts/SiftsException.java [new file with mode: 0644]
src/jalview/ws/sifts/SiftsSettings.java [new file with mode: 0644]
src/jalview/xml/binding/sifts/Alignment.java [new file with mode: 0644]
src/jalview/xml/binding/sifts/EntityType.java [new file with mode: 0644]
src/jalview/xml/binding/sifts/Entry.java [new file with mode: 0644]
src/jalview/xml/binding/sifts/ObjectFactory.java [new file with mode: 0644]
src/jalview/xml/binding/sifts/package-info.java [new file with mode: 0644]
test/jalview/analysis/AlignmentUtilsTests.java
test/jalview/commands/TrimRegionCommandTest.java [new file with mode: 0644]
test/jalview/datamodel/ColumnSelectionTest.java
test/jalview/datamodel/SequenceTest.java
test/jalview/ext/jmol/PDBFileWithJmolTest.java
test/jalview/io/1a70.xml.gz [new file with mode: 0644]
test/jalview/io/PfamFormatInputTest.java [new file with mode: 0644]
test/jalview/util/ComparisonTest.java
test/jalview/util/DBRefUtilsTest.java
test/jalview/util/MappingUtilsTest.java
test/jalview/ws/dbsources/UniprotTest.java
test/jalview/ws/seqfetcher/DbRefFetcherTest.java
test/jalview/ws/sifts/SiftsClientTest.java [new file with mode: 0644]

diff --git a/RELEASE b/RELEASE
index 933f887..6cd9254 100644 (file)
--- a/RELEASE
+++ b/RELEASE
@@ -1,2 +1,2 @@
 jalview.release=Release_2_9_0b1_Branch
-jalview.version=2.9.0b1
+jalview.version=2.9.0b2
index 318c112..a645630 100755 (executable)
@@ -117,7 +117,7 @@ found not to match.
 </li>
 <li>Label<br><em>Set the text label at the selected positions. A
 dialog box will open for you to enter the text.  If
-more that one consecutive position is marked with the same label, only
+more than one consecutive position is marked with the same label, only
 the first position's label will be rendered.</em>
 </li>
 <li>Colour<br><em>Changes the colour of the annotation text label.</em>
index b006c89..ce339cc 100755 (executable)
             &quot;Deselect All&quot; to deselect all columns.</em></li>
         <li><strong>Remove Right (Control R)<br>
         </strong><em>If the alignment has marked columns, the alignment will
-            be trimmed to the left of the leftmost marked column. To
+            be trimmed to the right of the rightmost marked column. To
             mark a column, mouse click the scale bar above the
             alignment. Click again to unmark a column, or select
             &quot;Deselect All&quot; to deselect all columns.</em></li>
index be2daae..ad9596a 100755 (executable)
             Consecutive arrows will be joined together to form a single
             green arrow.</em></li>
         <li><strong>Label</strong><br> <em>Sets the text
-            label at the selected positions. If more that one
+            label at the selected positions. If more than one
             consecutive position is marked with the same label, only the
             first position's label will be rendered.</em></li>
         <li><strong>Colour</strong><br> <em>Changes the
index a8390c2..846a1bd 100755 (executable)
@@ -75,7 +75,7 @@
         deselect all columns.</em></li>
     <li><strong>Remove Right (Control R)<br>
     </strong><em>If the alignment has marked columns, the alignment will be
-        trimmed to the left of the leftmost marked column. To mark a
+        trimmed to the right of the rightmost marked column. To mark a
         column, mouse click the scale bar above the alignment. Click
         again to unmark a column, or select &quot;Deselect All&quot; to
         deselect all columns.</em></li>
index 73f6952..23e958c 100755 (executable)
     <tr>
       <td width="60" nowrap>
         <div align="center">
+          <strong><a name="Jalview.2.9.0b2">2.9.0b2</a><br />
+            <em>16/10/2015</em></strong>
+        </div>
+      </td>
+      <td>
+      <em>General</em>
+      <ul>
+            <li>Time stamps for signed Jalview application and applet jars</li>
+      </ul>
+      </td>
+      <td>
+        <div align="left">
+        <em>Application</em><ul>
+          <li>Duplicate group consensus and conservation rows shown when tree is partitioned</li>
+            <li>Erratic behaviour when tree partitions made with multiple cDNA/Protein split views</li>
+            </ul>
+        </div>
+      </td>
+    </tr>
+    <tr>
+      <td width="60" nowrap>
+        <div align="center">
           <strong><a name="Jalview.2.9.0b1">2.9.0b1</a><br />
             <em>8/10/2015</em></strong>
         </div>
index 67d89b7..19be76f 100755 (executable)
     <strong>What's new ?</strong>
   </p>
   <p>
-    Jalview 2.9.0b1 is a bug fix release for Jalview 2.9, which has been in development since December 2014. In addition
-    to a multitude of bug fixes and minor improvements (both small, and
+    Jalview 2.9.0b2 is a bug fix release for Jalview 2.9.
+    The release of Jalview 2.9 in September 2015 included
+    a multitude of bug fixes and minor improvements (both small, and
     rather big!), it also brings major new capabilities for codon-level
     analysis of protein alignments and the retrieval and manipulation of
-    structural data.</p><p>For the patches since version 2.9 was release, see the
-    <a href="releases.html#Jalview.2.9.0b1">Jalview 2.9.0b1 Release Notes</a>.
+    structural data.</p><p>For the patches since version 2.9 was released, see the
+    <a href="releases.html#Jalview.2.9.0b2">Jalview 2.9.0b2 Release Notes</a>.
   </p>
   <p>
     <strong>Highlights in Jalview 2.9</strong>
index 6bbe798..876b815 100644 (file)
@@ -1281,3 +1281,6 @@ exception.pdb_rest_service_no_longer_available = PDB rest services no longer ava
 exception.resource_not_be_found = The requested resource could not be found
 exception.pdb_server_error = There seems to be an error from the PDB server
 exception.pdb_server_unreachable = Jalview is unable to reach the PDBe Solr server. \nPlease ensure that you are connected to the internet and try again.
+label.nw_mapping = Needleman & Wunsch Alignment
+label.sifts_mapping = SIFTs Mapping
+label.mapping_method = Sequence \u27f7 Structure mapping method
diff --git a/schemas/sifts/alignment.xsd b/schemas/sifts/alignment.xsd
new file mode 100644 (file)
index 0000000..7731048
--- /dev/null
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema targetNamespace="http://www.ebi.ac.uk/pdbe/docs/sifts/eFamily.xsd"
+       elementFormDefault="qualified" attributeFormDefault="unqualified"
+       xmlns:data="http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd"
+       xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+       xmlns="http://www.ebi.ac.uk/pdbe/docs/sifts/alignment.xsd" version="1.1">
+       <xsd:import namespace="http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd"
+               schemaLocation="dataTypes.xsd"/>
+       <xsd:element name="alignment">
+               <xsd:annotation>
+                       <xsd:documentation>This section of the schema deals with alignments.  The alignment can be either a sequence alignment or a structural alignment.</xsd:documentation>
+               </xsd:annotation>
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element name="alignObject" maxOccurs="unbounded">
+                                       <xsd:annotation>
+                                               <xsd:documentation>description of object. id e.g. 1tim.A,8tim.B, P001228, ...; type: type of object e.g.: protein, dna. version: last time this object has been changed (sometimes not so easy to know ...)</xsd:documentation>
+                                       </xsd:annotation>
+                                       <xsd:complexType>
+                                               <xsd:sequence>
+                                                       <xsd:element name="alignObjectDetail" minOccurs="0"
+                                                               maxOccurs="unbounded">
+                                                               <xsd:complexType mixed="true">
+                                                                       <xsd:attributeGroup ref="data:detail"/>
+                                                               </xsd:complexType>
+                                                       </xsd:element>
+                                                       <xsd:element name="sequence" minOccurs="0">
+                                                               <xsd:complexType mixed="true">
+                                                                       <xsd:attributeGroup ref="data:region"/>
+                                                               </xsd:complexType>
+                                                       </xsd:element>
+                                               </xsd:sequence>
+                                               <xsd:attribute name="objectVersion" type="xsd:string" use="required"/>
+                                               <xsd:attribute name="intObjectId" type="xsd:string" use="required"/>
+                                               <xsd:attribute name="type" type="xsd:string" use="optional"/>
+                                               <xsd:attributeGroup ref="data:dbRef"/>
+                                       </xsd:complexType>
+                               </xsd:element>
+                               <xsd:element name="score" minOccurs="0" maxOccurs="unbounded">
+                                       <xsd:annotation>
+                                               <xsd:documentation>e.g.: number of identical residues, % id residues, aligmnent score, e-value, p-value, etc.</xsd:documentation>
+                                       </xsd:annotation>
+                                       <xsd:complexType>
+                                               <xsd:attribute name="methodName" type="xsd:string" use="required"/>
+                                               <xsd:attribute name="scoreValue" type="xsd:string" use="required"/>
+                                       </xsd:complexType>
+                               </xsd:element>
+                               <xsd:element name="block" maxOccurs="unbounded">
+                                       <xsd:complexType>
+                                               <xsd:sequence>
+                                                       <xsd:element name="segment" maxOccurs="unbounded">
+                                                               <xsd:annotation>
+                                                                       <xsd:documentation>the alignment given for a single object</xsd:documentation>
+                                                                       <xsd:documentation>the alignment given for a single object</xsd:documentation>
+                                                               </xsd:annotation>
+                                                               <xsd:complexType>
+                                                                       <xsd:sequence minOccurs="0">
+                                                                               <xsd:element name="cigar" type="data:cigarstring">
+                                                                                       <xsd:annotation>
+                                                                                               <xsd:documentation>e.g. 2D23M4I</xsd:documentation>
+                                                                                       </xsd:annotation>
+                                                                               </xsd:element>
+                                                                       </xsd:sequence>
+                                                                       <xsd:attributeGroup ref="data:region"/>
+                                                                       <xsd:attribute name="intObjectId" use="required"/>
+                                                                       <xsd:attribute name="strand" use="optional"/>
+                                                               </xsd:complexType>
+                                                       </xsd:element>
+                                               </xsd:sequence>
+                                               <xsd:attribute name="blockScore" type="xsd:string" use="optional"/>
+                                               <xsd:attribute name="blockOrder" type="xsd:integer" use="required"/>
+                                       </xsd:complexType>
+                               </xsd:element>
+                               <xsd:element name="geo3d" minOccurs="0" maxOccurs="unbounded">
+                                       <xsd:annotation>
+                                               <xsd:documentation>geometrical operation to perform on 3D object</xsd:documentation>
+                                       </xsd:annotation>
+                                       <xsd:complexType>
+                                               <xsd:sequence>
+                                                       <xsd:element name="vector">
+                                                               <xsd:complexType>
+                                                                       <xsd:attribute name="x" type="xsd:float" use="required"/>
+                                                                       <xsd:attribute name="y" type="xsd:float" use="required"/>
+                                                                       <xsd:attribute name="z" type="xsd:float" use="required"/>
+                                                               </xsd:complexType>
+                                                       </xsd:element>
+                                                       <xsd:element name="matrix" maxOccurs="unbounded">
+                                                               <xsd:complexType>
+                                                                       <xsd:sequence>
+                                                                               <xsd:element name="max11">
+                                                                                       <xsd:complexType>
+                                                                                               <xsd:attribute name="coord" type="xsd:float"
+                                                                                               use="required"/>
+                                                                                       </xsd:complexType>
+                                                                               </xsd:element>
+                                                                               <xsd:element name="max12">
+                                                                                       <xsd:complexType>
+                                                                                               <xsd:attribute name="coord" type="xsd:float"
+                                                                                               use="required"/>
+                                                                                       </xsd:complexType>
+                                                                               </xsd:element>
+                                                                               <xsd:element name="max13">
+                                                                                       <xsd:complexType>
+                                                                                               <xsd:attribute name="coord" type="xsd:float"
+                                                                                               use="required"/>
+                                                                                       </xsd:complexType>
+                                                                               </xsd:element>
+                                                                               <xsd:element name="max21">
+                                                                                       <xsd:complexType>
+                                                                                               <xsd:attribute name="coord" type="xsd:float"
+                                                                                               use="required"/>
+                                                                                       </xsd:complexType>
+                                                                               </xsd:element>
+                                                                               <xsd:element name="max22">
+                                                                                       <xsd:complexType>
+                                                                                               <xsd:attribute name="coord" type="xsd:float"
+                                                                                               use="required"/>
+                                                                                       </xsd:complexType>
+                                                                               </xsd:element>
+                                                                               <xsd:element name="max23">
+                                                                                       <xsd:complexType>
+                                                                                               <xsd:attribute name="coord" type="xsd:float"
+                                                                                               use="required"/>
+                                                                                       </xsd:complexType>
+                                                                               </xsd:element>
+                                                                               <xsd:element name="max31">
+                                                                                       <xsd:complexType>
+                                                                                               <xsd:attribute name="coord" type="xsd:float"
+                                                                                               use="required"/>
+                                                                                       </xsd:complexType>
+                                                                               </xsd:element>
+                                                                               <xsd:element name="max32">
+                                                                                       <xsd:complexType>
+                                                                                               <xsd:attribute name="coord" type="xsd:float"
+                                                                                               use="required"/>
+                                                                                       </xsd:complexType>
+                                                                               </xsd:element>
+                                                                               <xsd:element name="max33">
+                                                                                       <xsd:complexType>
+                                                                                               <xsd:attribute name="coord" type="xsd:float"
+                                                                                               use="required"/>
+                                                                                       </xsd:complexType>
+                                                                               </xsd:element>
+                                                                       </xsd:sequence>
+                                                               </xsd:complexType>
+                                                       </xsd:element>
+                                               </xsd:sequence>
+                                               <xsd:attribute name="intObjectId" type="xsd:string" use="required"/>
+                                       </xsd:complexType>
+                               </xsd:element>
+                       </xsd:sequence>
+                       <xsd:attribute name="alignType" type="xsd:string" use="required"/>
+               </xsd:complexType>
+       </xsd:element>
+</xsd:schema>
\ No newline at end of file
diff --git a/schemas/sifts/dataTypes.xsd b/schemas/sifts/dataTypes.xsd
new file mode 100644 (file)
index 0000000..f0947b4
--- /dev/null
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema targetNamespace="http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd"
+       elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.0"
+       xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+       xmlns="http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd">
+       <xsd:simpleType name="entityType">
+               <xsd:restriction base="xsd:string">
+                       <xsd:enumeration value="protein"/>
+                       <xsd:enumeration value="RNA"/>
+                       <xsd:enumeration value="DNA"/>
+                       <xsd:enumeration value="domain"/>
+               </xsd:restriction>
+       </xsd:simpleType>
+       <xsd:simpleType name="dbChainId">
+               <xsd:restriction base="xsd:string">
+                       <xsd:minLength value="1"/>
+                       <xsd:maxLength value="2"/>
+               </xsd:restriction>
+       </xsd:simpleType>
+       <xsd:simpleType name="chainId">
+               <xsd:restriction base="xsd:string">
+                       <xsd:minLength value="1"/>
+                       <xsd:maxLength value="1"/>
+               </xsd:restriction>
+       </xsd:simpleType>
+       <xsd:simpleType name="cigarstring">
+               <xsd:restriction base="xsd:string">
+                       <xsd:minLength value="1"/>
+                       <xsd:whiteSpace value="collapse"/>
+                       <xsd:pattern value="(\d{0,5}\w{1})*"/>
+               </xsd:restriction>
+       </xsd:simpleType>
+       <xsd:attributeGroup name="dbRef">
+               <xsd:attribute name="dbSource" use="required">
+                       <xsd:simpleType>
+                               <xsd:restriction base="xsd:string">
+                                       <xsd:enumeration value="PDBe"/>
+                                       <xsd:enumeration value="UniProt"/>
+                                       <xsd:enumeration value="Pfam"/>
+                                       <xsd:enumeration value="CATH"/>
+                                       <xsd:enumeration value="SCOP"/>
+                                       <xsd:enumeration value="InterPro"/>
+                                       <xsd:enumeration value="PDB"/>
+                                       <xsd:enumeration value="NCBI"/>
+                                       <xsd:enumeration value="EC"/>
+                                       <xsd:enumeration value="GO"/>
+                                       <xsd:enumeration value="Astral"/>
+                               </xsd:restriction>
+                       </xsd:simpleType>
+               </xsd:attribute>
+               <xsd:attribute name="dbCoordSys" use="required">
+                       <xsd:simpleType>
+                               <xsd:restriction base="xsd:string">
+                                       <xsd:enumeration value="PDBe"/>
+                                       <xsd:enumeration value="PDBseqres"/>
+                                       <xsd:enumeration value="PDBresnum"/>
+                                       <xsd:enumeration value="UniProt"/>
+                                       <xsd:enumeration value="Astral"/>
+                               </xsd:restriction>
+                       </xsd:simpleType>
+               </xsd:attribute>
+               <xsd:attribute name="dbAccessionId" type="xsd:string" use="required"/>
+               <xsd:attribute name="dbEvidence" type="xsd:string"/>
+               <xsd:attribute name="dbVersion" type="xsd:string" use="optional"/>
+       </xsd:attributeGroup>
+       <xsd:attributeGroup name="resRef">
+               <xsd:attribute name="dbResNum" use="required">
+                       <xsd:simpleType>
+                               <xsd:restriction base="xsd:string">
+                                       <xsd:minLength value="1"/>
+                                       <xsd:pattern value="-?\d+(\S+)?"/>
+                               </xsd:restriction>
+                       </xsd:simpleType>
+               </xsd:attribute>
+               <xsd:attribute name="dbResName" use="required">
+                       <xsd:simpleType>
+                               <xsd:restriction base="xsd:string">
+                                       <xsd:minLength value="1"/>
+                                       <xsd:maxLength value="3"/>
+                                       <xsd:pattern value="\w{1,3}"/>
+                               </xsd:restriction>
+                       </xsd:simpleType>
+               </xsd:attribute>
+       </xsd:attributeGroup>
+       <xsd:attributeGroup name="detail">
+               <xsd:attribute name="dbSource" use="optional">
+                       <xsd:simpleType>
+                               <xsd:restriction base="xsd:string">
+                                       <xsd:enumeration value="PDBe"/>
+                                       <xsd:enumeration value="UniProt"/>
+                                       <xsd:enumeration value="Pfam"/>
+                                       <xsd:enumeration value="CATH"/>
+                                       <xsd:enumeration value="SCOP"/>
+                                       <xsd:enumeration value="InterPro"/>
+                                       <xsd:enumeration value="PDB"/>
+                                       <xsd:enumeration value="NCBI"/>
+                                       <xsd:enumeration value="EC"/>
+                                       <xsd:enumeration value="GO"/>
+                                       <xsd:enumeration value="Astral"/>
+                               </xsd:restriction>
+                       </xsd:simpleType>
+               </xsd:attribute>
+               <xsd:attribute name="property" type="xsd:string" use="required"/>
+       </xsd:attributeGroup>
+       <xsd:attributeGroup name="region">
+               <xsd:attribute name="start" use="optional">
+                       <xsd:simpleType>
+                               <xsd:restriction base="xsd:string">
+                                       <xsd:minLength value="1"/>
+                                       <xsd:pattern value="-?\d+(.\S)?"/>
+                               </xsd:restriction>
+                       </xsd:simpleType>
+               </xsd:attribute>
+               <xsd:attribute name="end" use="optional">
+                       <xsd:simpleType>
+                               <xsd:restriction base="xsd:string">
+                                       <xsd:minLength value="1"/>
+                                       <xsd:pattern value="-?\d+(.\S)?"/>
+                               </xsd:restriction>
+                       </xsd:simpleType>
+               </xsd:attribute>
+       </xsd:attributeGroup>
+       <xsd:attributeGroup name="listdbRef">
+               <xsd:attribute name="dbVersion" type="xsd:string" use="optional"/>
+               <xsd:attribute name="dbSource" use="required">
+                       <xsd:simpleType>
+                               <xsd:restriction base="xsd:string">
+                                       <xsd:enumeration value="PDBe"/>
+                                       <xsd:enumeration value="UniProt"/>
+                                       <xsd:enumeration value="Pfam"/>
+                                       <xsd:enumeration value="CATH"/>
+                                       <xsd:enumeration value="SCOP"/>
+                                       <xsd:enumeration value="InterPro"/>
+                                       <xsd:enumeration value="PDB"/>
+                                       <xsd:enumeration value="NCBI"/>
+                                       <xsd:enumeration value="EC"/>
+                                       <xsd:enumeration value="GO"/>
+                                       <xsd:enumeration value="Astral"/>
+                               </xsd:restriction>
+                       </xsd:simpleType>
+               </xsd:attribute>
+               <xsd:attribute name="dbCoordSys" use="required">
+                       <xsd:simpleType>
+                               <xsd:restriction base="xsd:string">
+                                       <xsd:enumeration value="PDBe"/>
+                                       <xsd:enumeration value="PDBseqres"/>
+                                       <xsd:enumeration value="PDBresnum"/>
+                                       <xsd:enumeration value="UniProt"/>
+                                       <xsd:enumeration value="Astral"/>
+                               </xsd:restriction>
+                       </xsd:simpleType>
+               </xsd:attribute>
+       </xsd:attributeGroup>
+</xsd:schema>
\ No newline at end of file
diff --git a/schemas/sifts/eFamily.xsd b/schemas/sifts/eFamily.xsd
new file mode 100644 (file)
index 0000000..250f1f4
--- /dev/null
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- edited with XMLSpy v2016 (http://www.altova.com) by Charles (student) -->
+<xsd:schema xmlns="http://www.ebi.ac.uk/pdbe/docs/sifts/eFamily.xsd" xmlns:data="http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd" xmlns:align="http://www.ebi.ac.uk/pdbe/docs/sifts/alignment.xsd" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" targetNamespace="http://www.ebi.ac.uk/pdbe/docs/sifts/eFamily.xsd" elementFormDefault="qualified" attributeFormDefault="unqualified" version="2.0">
+       <xsd:include schemaLocation="alignment.xsd"/>
+       <xsd:import namespace="http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd" schemaLocation="dataTypes.xsd"/>
+       <xsd:annotation>
+               <xsd:documentation>The eFamily schema is designed to allow the members of the eFamily consortium to exchange domain definitions.  As members of the different databases use different underlying data (languages) so we need a way of getting between the co-ordinates systems. MSD are to provide the mapping between the co-ordinates (translator), hence the reason for the incorporation of the mappings into the core of the schema. 
+               </xsd:documentation>
+       </xsd:annotation>
+       <xsd:element name="entry">
+               <xsd:annotation>
+                       <xsd:documentation>The entry represents a database entry.  This schema is currently designed for domain and mapping entires.</xsd:documentation>
+               </xsd:annotation>
+               <xsd:complexType>
+                       <xsd:sequence>
+                               <xsd:element name="listDB" minOccurs="1" maxOccurs="1">
+                                       <xsd:complexType mixed="false">
+                                               <xsd:sequence minOccurs="1" maxOccurs="unbounded">
+                                                       <xsd:element name="db">
+                                                               <xsd:complexType>
+                                                                       <xsd:attributeGroup ref="data:listdbRef"/>
+                                                               </xsd:complexType>
+                                                       </xsd:element>
+                                               </xsd:sequence>
+                                       </xsd:complexType>
+                               </xsd:element>
+                               <xsd:element name="entryDetail" minOccurs="0" maxOccurs="unbounded">
+                                       <xsd:annotation>
+                                               <xsd:documentation>This is a free text field that allows someone to attach some sort of documentation to the entry</xsd:documentation>
+                                       </xsd:annotation>
+                                       <xsd:complexType mixed="true">
+                                               <xsd:attributeGroup ref="data:detail"/>
+                                       </xsd:complexType>
+                               </xsd:element>
+                               <xsd:element name="entity" maxOccurs="unbounded">
+                                       <xsd:annotation>
+                                               <xsd:documentation> An entity is a single domain definition.  In the case of SCOP, there is only one entity per entry, but in the case of Pfam, an entry is a collection of domains/entities.</xsd:documentation>
+                                       </xsd:annotation>
+                                       <xsd:complexType>
+                                               <xsd:sequence>
+                                                       <xsd:element name="entityDetail" minOccurs="0" maxOccurs="unbounded">
+                                                               <xsd:annotation>
+                                                                       <xsd:documentation>This is a free text field that allows someone to attach some sort of documentation to the entity</xsd:documentation>
+                                                               </xsd:annotation>
+                                                               <xsd:complexType mixed="true">
+                                                                       <xsd:attributeGroup ref="data:detail"/>
+                                                               </xsd:complexType>
+                                                       </xsd:element>
+                                                       <xsd:element name="segment" maxOccurs="unbounded">
+                                                               <xsd:annotation>
+                                                                       <xsd:documentation>An entity may not comprise of a single continuous region. This may be used to a chimeric structure or a discontinuous domain</xsd:documentation>
+                                                               </xsd:annotation>
+                                                               <xsd:complexType>
+                                                                       <xsd:sequence>
+                                                                               <xsd:element name="listResidue" minOccurs="0">
+                                                                                       <xsd:annotation>
+                                                                                               <xsd:documentation>Contains a set of residues objects</xsd:documentation>
+                                                                                       </xsd:annotation>
+                                                                                       <xsd:complexType>
+                                                                                               <xsd:sequence>
+                                                                                                       <xsd:element name="residue" maxOccurs="unbounded">
+                                                                                                               <xsd:annotation>
+                                                                                                                       <xsd:documentation>A single residue object.  This object can contain information on what the residue is,  general annotation, the numbering system and co-ordinate mapping </xsd:documentation>
+                                                                                                               </xsd:annotation>
+                                                                                                               <xsd:complexType>
+                                                                                                                       <xsd:sequence>
+                                                                                                                               <xsd:element name="crossRefDb" minOccurs="0" maxOccurs="unbounded">
+                                                                                                                                       <xsd:annotation>
+                                                                                                                                               <xsd:documentation>Allows the linking between different co-ordinate systems</xsd:documentation>
+                                                                                                                                       </xsd:annotation>
+                                                                                                                                       <xsd:complexType>
+                                                                                                                                               <xsd:attributeGroup ref="data:dbRef"/>
+                                                                                                                                               <xsd:attributeGroup ref="data:resRef"/>
+                                                                                                                                               <xsd:attribute name="dbChainId" type="data:chainId" use="optional"/>
+                                                                                                                                       </xsd:complexType>
+                                                                                                                               </xsd:element>
+                                                                                                                               <xsd:element name="residueDetail" minOccurs="0" maxOccurs="unbounded">
+                                                                                                                                       <xsd:annotation>
+                                                                                                                                               <xsd:documentation>This allows one to add information to the residues.  For example whether it is observed or whether it is an active site residue</xsd:documentation>
+                                                                                                                                       </xsd:annotation>
+                                                                                                                                       <xsd:complexType mixed="true">
+                                                                                                                                               <xsd:attributeGroup ref="data:detail"/>
+                                                                                                                                       </xsd:complexType>
+                                                                                                                               </xsd:element>
+                                                                                                                       </xsd:sequence>
+                                                                                                                       <xsd:attributeGroup ref="data:resRef"/>
+                                                                                                                       <xsd:attributeGroup ref="data:listdbRef"/>
+                                                                                                               </xsd:complexType>
+                                                                                                       </xsd:element>
+                                                                                               </xsd:sequence>
+                                                                                       </xsd:complexType>
+                                                                               </xsd:element>
+                                                                               <xsd:element name="listMapRegion" minOccurs="0">
+                                                                                       <xsd:annotation>
+                                                                                               <xsd:documentation>Allows cross referencing to another database.  For example, one may wish to include which the taxon that a mapping or sequence corresponds</xsd:documentation>
+                                                                                       </xsd:annotation>
+                                                                                       <xsd:complexType>
+                                                                                               <xsd:sequence>
+                                                                                                       <xsd:element name="mapRegion" maxOccurs="unbounded">
+                                                                                                               <xsd:annotation>
+                                                                                                                       <xsd:documentation>Defines the database that is being cross mapped to</xsd:documentation>
+                                                                                                               </xsd:annotation>
+                                                                                                               <xsd:complexType>
+                                                                                                                       <xsd:sequence>
+                                                                                                                               <xsd:element name="db">
+                                                                                                                                       <xsd:annotation>
+                                                                                                                                               <xsd:documentation>Contains the mapping coordinates.  The start end tags refer to the master databse co-ordinates.  The tags prefixed with sys refer to the database being mapped to.</xsd:documentation>
+                                                                                                                                       </xsd:annotation>
+                                                                                                                                       <xsd:complexType>
+                                                                                                                                               <xsd:sequence>
+                                                                                                                                                       <xsd:element name="dbDetail" minOccurs="0" maxOccurs="unbounded">
+                                                                                                                                                               <xsd:complexType mixed="true">
+                                                                                                                                                                       <xsd:attributeGroup ref="data:detail"/>
+                                                                                                                                                               </xsd:complexType>
+                                                                                                                                                       </xsd:element>
+                                                                                                                                               </xsd:sequence>
+                                                                                                                                               <xsd:attributeGroup ref="data:dbRef"/>
+                                                                                                                                               <xsd:attribute name="dbChainId" type="data:dbChainId" use="optional"/>
+                                                                                                                                               <xsd:attributeGroup ref="data:region"/>
+                                                                                                                                       </xsd:complexType>
+                                                                                                                               </xsd:element>
+                                                                                                                       </xsd:sequence>
+                                                                                                                       <xsd:attributeGroup ref="data:region"/>
+                                                                                                               </xsd:complexType>
+                                                                                                       </xsd:element>
+                                                                                               </xsd:sequence>
+                                                                                       </xsd:complexType>
+                                                                               </xsd:element>
+                                                                               <xsd:element name="segmentDetail" minOccurs="0" maxOccurs="unbounded">
+                                                                                       <xsd:annotation>
+                                                                                               <xsd:documentation>This is a free text field that allows someone to attach some sort of documentation to the segment</xsd:documentation>
+                                                                                       </xsd:annotation>
+                                                                                       <xsd:complexType mixed="true">
+                                                                                               <xsd:attributeGroup ref="data:detail"/>
+                                                                                       </xsd:complexType>
+                                                                               </xsd:element>
+                                                                       </xsd:sequence>
+                                                                       <xsd:attribute name="segId" type="xsd:string" use="required"/>
+                                                                       <xsd:attributeGroup ref="data:region"/>
+                                                               </xsd:complexType>
+                                                       </xsd:element>
+                                               </xsd:sequence>
+                                               <xsd:attribute name="type" type="data:entityType" use="required"/>
+                                               <xsd:attribute name="entityId" type="xsd:string" use="required"/>
+                                       </xsd:complexType>
+                               </xsd:element>
+                               <xsd:element ref="alignment" minOccurs="0" maxOccurs="unbounded"/>
+                       </xsd:sequence>
+                       <xsd:attributeGroup ref="data:dbRef"/>
+                       <xsd:attribute name="date" type="xsd:date" use="required"/>
+                       <xsd:attribute name="dbEntryVersion" type="xsd:date" use="required"/>
+               </xsd:complexType>
+       </xsd:element>
+</xsd:schema>
index c1018a3..58611e2 100755 (executable)
@@ -24,6 +24,8 @@ import jalview.analysis.AlignSeq;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.io.FileParse;
@@ -94,11 +96,13 @@ public class PDBfile extends jalview.io.AlignFile
     doParse();
   }
 
+  @Override
   public String print()
   {
     return null;
   }
 
+  @Override
   public void parse() throws IOException
   {
     // TODO set the filename sensibly - try using data source name.
@@ -285,8 +289,8 @@ public class PDBfile extends jalview.io.AlignFile
    */
   protected SequenceI postProcessChain(PDBChain chain)
   {
-    SequenceI dataset = chain.sequence;
-    dataset.setName(id + "|" + dataset.getName());
+    SequenceI pdbSequence = chain.sequence;
+    pdbSequence.setName(id + "|" + pdbSequence.getName());
     PDBEntry entry = new PDBEntry();
     entry.setId(id);
     entry.setType(PDBEntry.Type.PDB);
@@ -305,9 +309,16 @@ public class PDBfile extends jalview.io.AlignFile
       // TODO: decide if we should dump the datasource to disk
       entry.setFile(getDataName());
     }
-    dataset.addPDBId(entry);
+    pdbSequence.addPDBId(entry);
+
+    DBRefEntry sourceDBRef = new DBRefEntry();
+    sourceDBRef.setAccessionId(id);
+    sourceDBRef.setSource(DBRefSource.PDB);
+    sourceDBRef.setStartRes(pdbSequence.getStart());
+    sourceDBRef.setEndRes(pdbSequence.getEnd());
+    pdbSequence.setSourceDBRef(sourceDBRef);
     // PDBChain objects maintain reference to dataset
-    SequenceI chainseq = dataset.deriveSequence();
+    SequenceI chainseq = pdbSequence.deriveSequence();
     seqs.addElement(chainseq);
 
     AlignmentAnnotation[] chainannot = chainseq.getAnnotation();
index 3ca3d90..369721d 100755 (executable)
@@ -577,7 +577,8 @@ public class AlignSeq
       }
     }
     int len = 72 - maxid - 1;
-    int nochunks = ((aseq1.length - count) / len) + 1;
+    int nochunks = ((aseq1.length - count) / len)
+            + ((aseq1.length - count) % len > 0 ? 1 : 0);
     pid = 0;
 
     output.append("Score = ").append(score[maxi][maxj]).append(NEWLINE);
@@ -662,9 +663,8 @@ public class AlignSeq
     }
 
     pid = pid / (aseq1.length - count) * 100;
-    output = output.append(new Format("Percentage ID = %2.2f\n\n")
+    output = output.append(new Format("Percentage ID = %2.2f\n")
             .form(pid));
-
     try
     {
       os.print(output.toString());
@@ -948,6 +948,7 @@ public class AlignSeq
   public static void displayMatrix(Graphics g, int[][] mat, int n, int m,
           int psize)
   {
+    // TODO method dosen't seem to be referenced anywhere delete??
     int max = -1000;
     int min = 1000;
 
index 2311dea..fe95dca 100644 (file)
@@ -1301,7 +1301,7 @@ public class AlignmentUtils
       return false;
     }
     String name = seq2.getName();
-    final DBRefEntry[] xrefs = seq1.getDBRef();
+    final DBRefEntry[] xrefs = seq1.getDBRefs();
     if (xrefs != null)
     {
       for (DBRefEntry xref : xrefs)
@@ -1553,7 +1553,7 @@ public class AlignmentUtils
   protected static void transferDbRefs(SequenceI from, SequenceI to)
   {
     String cdsAccId = FeatureProperties.getCodingFeature(DBRefSource.EMBL);
-    DBRefEntry[] cdsRefs = DBRefUtils.selectRefs(from.getDBRef(),
+    DBRefEntry[] cdsRefs = DBRefUtils.selectRefs(from.getDBRefs(),
             DBRefSource.CODINGDBS);
     if (cdsRefs != null)
     {
index e96d9d7..21fd08d 100644 (file)
@@ -98,7 +98,7 @@ public class CrossRef
         {
           dss = dss.getDatasetSequence();
         }
-        DBRefEntry[] rfs = findXDbRefs(dna, dss.getDBRef());
+        DBRefEntry[] rfs = findXDbRefs(dna, dss.getDBRefs());
         if (rfs != null)
         {
           for (DBRefEntry ref : rfs)
@@ -112,13 +112,13 @@ public class CrossRef
         if (dataset != null)
         {
           // search for references to this sequence's direct references.
-          DBRefEntry[] lrfs = CrossRef.findXDbRefs(!dna, seq.getDBRef());
+          DBRefEntry[] lrfs = CrossRef.findXDbRefs(!dna, seq.getDBRefs());
           List<SequenceI> rseqs = new ArrayList<SequenceI>();
           CrossRef.searchDatasetXrefs(seq, !dna, lrfs, dataset, rseqs,
                   null); // don't need to specify codon frame for mapping here
           for (SequenceI rs : rseqs)
           {
-            DBRefEntry[] xrs = findXDbRefs(dna, rs.getDBRef());
+            DBRefEntry[] xrs = findXDbRefs(dna, rs.getDBRefs());
             if (xrs != null)
             {
               for (DBRefEntry ref : xrs)
@@ -170,7 +170,7 @@ public class CrossRef
     Vector cseqs = new Vector();
     for (int s = 0; s < seqs.length; s++)
     {
-      DBRefEntry[] cdna = findXDbRefs(true, seqs[s].getDBRef());
+      DBRefEntry[] cdna = findXDbRefs(true, seqs[s].getDBRefs());
       for (int c = 0; c < cdna.length; c++)
       {
         if (cdna[c].getSource().equals(DBRefSource.EMBLCDS))
@@ -231,12 +231,12 @@ public class CrossRef
         dss = dss.getDatasetSequence();
       }
       boolean found = false;
-      DBRefEntry[] xrfs = CrossRef.findXDbRefs(dna, dss.getDBRef());
+      DBRefEntry[] xrfs = CrossRef.findXDbRefs(dna, dss.getDBRefs());
       if ((xrfs == null || xrfs.length == 0) && dataset != null)
       {
         System.out.println("Attempting to find ds Xrefs refs.");
         // FIXME should be dss not seq here?
-        DBRefEntry[] lrfs = CrossRef.findXDbRefs(!dna, seq.getDBRef());
+        DBRefEntry[] lrfs = CrossRef.findXDbRefs(!dna, seq.getDBRefs());
         // less ambiguous would be a 'find primary dbRefEntry' method.
         // filter for desired source xref here
         found = CrossRef.searchDatasetXrefs(dss, !dna, lrfs, dataset,
@@ -342,7 +342,7 @@ public class CrossRef
               for (int rs = 0; rs < retrieved.length; rs++)
               {
                 // TODO: examine each sequence for 'redundancy'
-                DBRefEntry[] dbr = retrieved[rs].getDBRef();
+                DBRefEntry[] dbr = retrieved[rs].getDBRefs();
                 if (dbr != null && dbr.length > 0)
                 {
                   for (int di = 0; di < dbr.length; di++)
@@ -514,7 +514,7 @@ public class CrossRef
             }
 
             // look for direct or indirect references in common
-            DBRefEntry[] poss = nxt.getDBRef(), cands = null;
+            DBRefEntry[] poss = nxt.getDBRefs(), cands = null;
             if (direct)
             {
               cands = jalview.util.DBRefUtils.searchRefs(poss, xrf);
index f8bb9f9..be138f3 100644 (file)
@@ -208,13 +208,13 @@ public class Dna
     for (int gd = 0; gd < selection.length; gd++)
     {
       SequenceI dna = selection[gd];
-      DBRefEntry[] dnarefs = DBRefUtils.selectRefs(dna.getDBRef(),
+      DBRefEntry[] dnarefs = DBRefUtils.selectRefs(dna.getDBRefs(),
               jalview.datamodel.DBRefSource.DNACODINGDBS);
       if (dnarefs != null)
       {
         // intersect with pep
         List<DBRefEntry> mappedrefs = new ArrayList<DBRefEntry>();
-        DBRefEntry[] refs = dna.getDBRef();
+        DBRefEntry[] refs = dna.getDBRefs();
         for (int d = 0; d < refs.length; d++)
         {
           if (refs[d].getMap() != null && refs[d].getMap().getMap() != null
@@ -773,7 +773,7 @@ public class Dna
   {
     SequenceFeature[] sfs = dna.getSequenceFeatures();
     Boolean fgstate;
-    DBRefEntry[] dnarefs = DBRefUtils.selectRefs(dna.getDBRef(),
+    DBRefEntry[] dnarefs = DBRefUtils.selectRefs(dna.getDBRefs(),
             DBRefSource.DNACODINGDBS);
     if (dnarefs != null)
     {
index f7c7cb4..23e9a14 100755 (executable)
@@ -63,9 +63,9 @@ public class SequenceIdMatcher
         dbseq = dbseq.getDatasetSequence();
       }
       // add in any interesting identifiers
-      if (dbseq.getDBRef() != null)
+      if (dbseq.getDBRefs() != null)
       {
-        DBRefEntry dbr[] = dbseq.getDBRef();
+        DBRefEntry dbr[] = dbseq.getDBRefs();
         SeqIdName sid = null;
         for (int r = 0; r < dbr.length; r++)
         {
diff --git a/src/jalview/api/DBRefEntryI.java b/src/jalview/api/DBRefEntryI.java
new file mode 100644 (file)
index 0000000..b927fa5
--- /dev/null
@@ -0,0 +1,72 @@
+package jalview.api;
+
+
+public interface DBRefEntryI
+{
+  public boolean equalRef(DBRefEntryI entry);
+
+  /**
+   * 
+   * @return Source DB name for this entry
+   */
+  public String getSource();
+
+  /**
+   * 
+   * @return Accession Id for this entry
+   */
+  public String getAccessionId();
+
+  /**
+   * 
+   * @param accessionId
+   *          Accession Id for this entry
+   */
+  public void setAccessionId(String accessionId);
+
+  /**
+   * 
+   * @param source
+   *          Source DB name for this entry
+   */
+  public void setSource(String source);
+
+  /**
+   * 
+   * @return Source DB version for this entry
+   */
+  public String getVersion();
+
+  /**
+   * 
+   * @param version
+   *          Source DB version for this entry
+   */
+  public void setVersion(String version);
+
+  /**
+   * 
+   * @param startRes
+   *          index of start residue in the source DB
+   */
+  public void setStartRes(int startRes);
+
+  /**
+   * 
+   * @return index of start residue in the source DB
+   */
+  public int getStartRes();
+
+  /**
+   * 
+   * @param endRes
+   *          index of end residue in the source DB
+   */
+  public void setEndRes(int endRes);
+
+  /**
+   * 
+   * @return index of end residue in the source DB
+   */
+  public int getEndRes();
+}
diff --git a/src/jalview/api/SiftsClientI.java b/src/jalview/api/SiftsClientI.java
new file mode 100644 (file)
index 0000000..e2fac14
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.api;
+
+import jalview.datamodel.SequenceI;
+import jalview.structure.StructureMapping;
+import jalview.ws.sifts.MappingOutputPojo;
+import jalview.ws.sifts.SiftsException;
+import jalview.xml.binding.sifts.Entry.Entity;
+
+import java.util.HashMap;
+import java.util.HashSet;
+
+public interface SiftsClientI
+{
+  /**
+   * Get the DB Accession Id for the SIFTs Entry
+   * 
+   * @return
+   */
+  public String getDbAccessionId();
+
+  /**
+   * Get DB Coordinate system for the SIFTs Entry
+   * 
+   * @return
+   */
+  public String getDbCoordSys();
+
+  /**
+   * Get DB Evidence for the SIFTs Entry
+   * 
+   * @return
+   */
+  public String getDbEvidence();
+
+  /**
+   * Get DB Source for the SIFTs Entry
+   * 
+   * @return
+   */
+  public String getDbSource();
+
+  /**
+   * Get DB version for the SIFTs Entry
+   * 
+   * @return
+   */
+  public String getDbVersion();
+
+  /**
+   * Get Number of Entities available in the SIFTs Entry
+   * 
+   * @return
+   */
+  public int getEntityCount();
+
+  /**
+   * Get a unique Entity by its Id
+   * 
+   * @param id
+   *          ID of the entity to fetch
+   * @return Entity
+   * @throws Exception
+   */
+  public Entity getEntityById(String id) throws SiftsException;
+
+  /**
+   * Get all accession Ids available in the current SIFTs entry
+   * 
+   * @return a unique set of discovered accession strings
+   */
+  public HashSet<String> getAllMappingAccession();
+
+  /**
+   * Check if the accessionId is available in current SIFTs Entry
+   * 
+   * @param accessionId
+   * @return
+   */
+  public boolean isAccessionMatched(String accessionId);
+
+  /**
+   * Get the standard DB referenced by the SIFTs Entry
+   * 
+   * @return
+   */
+  public String[] getEntryDBs();
+
+  /**
+   * 
+   * @param mop
+   *          MappingOutputPojo
+   * @return Sequence<->Structure mapping as int[][]
+   * @throws SiftsException
+   */
+  public StringBuffer getMappingOutput(MappingOutputPojo mop)
+          throws SiftsException;
+
+  /**
+   * 
+   * @param seq
+   *          sequence to generate mapping against the structure
+   * @param pdbFile
+   *          PDB file for the mapping
+   * @param chain
+   *          the chain of the entry to use for mapping
+   * @return StructureMapping
+   * @throws SiftsException
+   */
+  public StructureMapping getSiftsStructureMapping(SequenceI seq,
+          String pdbFile, String chain) throws SiftsException;
+  
+  /**
+   * Get residue by residue mapping for a given Sequence and SIFTs entity
+   * 
+   * @param entityId
+   *          Id of the target entity in the SIFTs entry
+   * @param seq
+   *          SequenceI
+   * @return generated mapping
+   * @throws Exception
+   */
+  public HashMap<Integer, int[]> getGreedyMapping(String entityId,
+          SequenceI seq,
+          java.io.PrintStream os) throws SiftsException;
+}
\ No newline at end of file
index 1d2feb2..748954a 100644 (file)
@@ -274,7 +274,7 @@ public class APopupMenu extends java.awt.PopupMenu implements
 
           // collect matching db-refs
           DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(
-                  seq.getDBRef(), new String[] { target });
+                  seq.getDBRefs(), new String[] { target });
           // collect id string too
           String id = seq.getName();
           String descr = seq.getDescription();
index 84e9087..e5f0053 100644 (file)
@@ -752,6 +752,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       {
         viewport.showAllHiddenColumns();
       }
+      viewport.sendSelection();
     }
   }
 
@@ -923,12 +924,15 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
   {
     boolean showForAlignment = showAlignmentAnnotations.getState();
     boolean showForSequences = showSequenceAnnotations.getState();
-    for (AlignmentAnnotation aa : alignPanel.getAlignment()
+    if (alignPanel.getAlignment().getAlignmentAnnotation() != null)
+    {
+      for (AlignmentAnnotation aa : alignPanel.getAlignment()
             .getAlignmentAnnotation())
     {
       boolean visible = (aa.sequenceRef == null ? showForAlignment
               : showForSequences);
       aa.visible = visible;
+      }
     }
     alignPanel.validateAnnotationDimensions(true);
     validate();
@@ -1070,11 +1074,14 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     else if (source == invertSequenceMenuItem)
     {
       invertSequenceMenuItem_actionPerformed();
+      // uncomment to slave sequence selections in split frame
+      // viewport.sendSelection();
     }
     else if (source == invertColSel)
     {
       viewport.invertColumnSelection();
       alignPanel.paintAlignment(true);
+      viewport.sendSelection();
     }
     else if (source == remove2LeftMenuItem)
     {
@@ -1108,27 +1115,34 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     {
       viewport.showAllHiddenColumns();
       alignPanel.paintAlignment(true);
+      viewport.sendSelection();
     }
     else if (source == showSeqs)
     {
       viewport.showAllHiddenSeqs();
       alignPanel.paintAlignment(true);
+      // uncomment if we want to slave sequence selections in split frame
+      // viewport.sendSelection();
     }
     else if (source == hideColumns)
     {
       viewport.hideSelectedColumns();
       alignPanel.paintAlignment(true);
+      viewport.sendSelection();
     }
     else if (source == hideSequences
             && viewport.getSelectionGroup() != null)
     {
       viewport.hideAllSelectedSeqs();
       alignPanel.paintAlignment(true);
+      // uncomment if we want to slave sequence selections in split frame
+      // viewport.sendSelection();
     }
     else if (source == hideAllButSelection)
     {
       toggleHiddenRegions(false, false);
       alignPanel.paintAlignment(true);
+      viewport.sendSelection();
     }
     else if (source == hideAllSelection)
     {
@@ -1137,12 +1151,14 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       viewport.hideAllSelectedSeqs();
       viewport.hideSelectedColumns();
       alignPanel.paintAlignment(true);
+      viewport.sendSelection();
     }
     else if (source == showAllHidden)
     {
       viewport.showAllHiddenColumns();
       viewport.showAllHiddenSeqs();
       alignPanel.paintAlignment(true);
+      viewport.sendSelection();
     }
     else if (source == showGroupConsensus)
     {
@@ -2263,7 +2279,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     ColumnSelection colSel = viewport.getColumnSelection();
     int column;
 
-    if (colSel.size() > 0)
+    if (!colSel.isEmpty())
     {
       if (trimLeft)
       {
@@ -2288,18 +2304,14 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       TrimRegionCommand trimRegion;
       if (trimLeft)
       {
-        trimRegion = new TrimRegionCommand("Remove Left",
-                TrimRegionCommand.TRIM_LEFT, seqs, column,
-                viewport.getAlignment(), viewport.getColumnSelection(),
-                viewport.getSelectionGroup());
+        trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
+                column, viewport.getAlignment());
         viewport.setStartRes(0);
       }
       else
       {
-        trimRegion = new TrimRegionCommand("Remove Right",
-                TrimRegionCommand.TRIM_RIGHT, seqs, column,
-                viewport.getAlignment(), viewport.getColumnSelection(),
-                viewport.getSelectionGroup());
+        trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
+                column, viewport.getAlignment());
       }
 
       statusBar.setText(MessageManager.formatMessage(
index 32d528c..d642c14 100755 (executable)
@@ -150,7 +150,7 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
 
     String label = "";
     if (av.getColumnSelection() != null
-            && av.getColumnSelection().size() > 0
+            && !av.getColumnSelection().isEmpty()
             && anot[av.getColumnSelection().getMin()] != null)
     {
       label = anot[av.getColumnSelection().getMin()].displayCharacter;
@@ -158,9 +158,9 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
 
     if (evt.getActionCommand().equals(REMOVE))
     {
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int sel : av.getColumnSelection().getSelected())
       {
-        anot[av.getColumnSelection().columnAt(i)] = null;
+        anot[sel] = null;
       }
     }
     else if (evt.getActionCommand().equals(LABEL))
@@ -177,10 +177,8 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
         aa[activeRow].hasText = true;
       }
 
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int index : av.getColumnSelection().getSelected())
       {
-        int index = av.getColumnSelection().columnAt(i);
-
         if (!av.getColumnSelection().isVisible(index))
         {
           continue;
@@ -201,10 +199,8 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
 
       Color col = udc.getColor();
 
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int index : av.getColumnSelection().getSelected())
       {
-        int index = av.getColumnSelection().columnAt(i);
-
         if (!av.getColumnSelection().isVisible(index))
         {
           continue;
@@ -262,10 +258,8 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
         }
       }
 
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int index : av.getColumnSelection().getSelected())
       {
-        int index = av.getColumnSelection().columnAt(i);
-
         if (!av.getColumnSelection().isVisible(index))
         {
           continue;
index 769ac8b..3c6a4f1 100755 (executable)
@@ -70,6 +70,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
 
   }
 
+  @Override
   public void mousePressed(MouseEvent evt)
   {
     int x = (evt.getX() / av.getCharWidth()) + av.getStartRes();
@@ -88,111 +89,140 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     max = res;
     if ((evt.getModifiers() & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK)
     {
-      PopupMenu pop = new PopupMenu();
-      if (reveal != null)
+      rightMouseButtonPressed(evt, res);
+    }
+    else
+    {
+      leftMouseButtonPressed(evt, res);
+    }
+  }
+
+  /**
+   * Handles left mouse button pressed (selection / clear selections)
+   * 
+   * @param evt
+   * @param res
+   */
+  protected void leftMouseButtonPressed(MouseEvent evt, final int res)
+  {
+    if (!evt.isControlDown() && !evt.isShiftDown())
+    {
+      av.getColumnSelection().clear();
+    }
+
+    av.getColumnSelection().addElement(res);
+    SequenceGroup sg = new SequenceGroup();
+    for (int i = 0; i < av.getAlignment().getSequences().size(); i++)
+    {
+      sg.addSequence(av.getAlignment().getSequenceAt(i), false);
+    }
+
+    sg.setStartRes(res);
+    sg.setEndRes(res);
+    av.setSelectionGroup(sg);
+
+    if (evt.isShiftDown())
+    {
+      int min = Math.min(av.getColumnSelection().getMin(), res);
+      int max = Math.max(av.getColumnSelection().getMax(), res);
+      for (int i = min; i < max; i++)
       {
-        MenuItem item = new MenuItem(
-                MessageManager.getString("label.reveal"));
-        item.addActionListener(new ActionListener()
-        {
-          public void actionPerformed(ActionEvent e)
-          {
-            av.showColumn(reveal[0]);
-            reveal = null;
-            ap.paintAlignment(true);
-            if (ap.overviewPanel != null)
-            {
-              ap.overviewPanel.updateOverviewImage();
-            }
-          }
-        });
-        pop.add(item);
+        av.getColumnSelection().addElement(i);
+      }
+      sg.setStartRes(min);
+      sg.setEndRes(max);
+    }
+    ap.paintAlignment(true);
+    av.sendSelection();
+  }
 
-        if (av.getColumnSelection().hasManyHiddenColumns())
+  /**
+   * Handles right mouse button press. If pressed in a selected column, opens
+   * context menu for 'Hide Columns'. If pressed on a hidden columns marker,
+   * opens context menu for 'Reveal / Reveal All'. Else does nothing.
+   * 
+   * @param evt
+   * @param res
+   */
+  protected void rightMouseButtonPressed(MouseEvent evt, final int res)
+  {
+    PopupMenu pop = new PopupMenu();
+    if (reveal != null)
+    {
+      MenuItem item = new MenuItem(
+              MessageManager.getString("label.reveal"));
+      item.addActionListener(new ActionListener()
+      {
+        @Override
+        public void actionPerformed(ActionEvent e)
         {
-          item = new MenuItem(MessageManager.getString("action.reveal_all"));
-          item.addActionListener(new ActionListener()
+          av.showColumn(reveal[0]);
+          reveal = null;
+          ap.paintAlignment(true);
+          if (ap.overviewPanel != null)
           {
-            public void actionPerformed(ActionEvent e)
-            {
-              av.showAllHiddenColumns();
-              reveal = null;
-              ap.paintAlignment(true);
-              if (ap.overviewPanel != null)
-              {
-                ap.overviewPanel.updateOverviewImage();
-              }
-            }
-          });
-          pop.add(item);
+            ap.overviewPanel.updateOverviewImage();
+          }
+          av.sendSelection();
         }
-        this.add(pop);
-        pop.show(this, evt.getX(), evt.getY());
-      }
-      else if (av.getColumnSelection().contains(res))
+      });
+      pop.add(item);
+
+      if (av.getColumnSelection().hasManyHiddenColumns())
       {
-        MenuItem item = new MenuItem(
-                MessageManager.getString("label.hide_columns"));
+        item = new MenuItem(MessageManager.getString("action.reveal_all"));
         item.addActionListener(new ActionListener()
         {
+          @Override
           public void actionPerformed(ActionEvent e)
           {
-            av.hideColumns(res, res);
-            if (av.getSelectionGroup() != null
-                    && av.getSelectionGroup().getSize() == av
-                            .getAlignment().getHeight())
-            {
-              av.setSelectionGroup(null);
-            }
-
+            av.showAllHiddenColumns();
+            reveal = null;
             ap.paintAlignment(true);
             if (ap.overviewPanel != null)
             {
               ap.overviewPanel.updateOverviewImage();
             }
+            av.sendSelection();
           }
         });
         pop.add(item);
-        this.add(pop);
-        pop.show(this, evt.getX(), evt.getY());
       }
+      this.add(pop);
+      pop.show(this, evt.getX(), evt.getY());
     }
-    else
-    // LEFT MOUSE TO SELECT
+    else if (av.getColumnSelection().contains(res))
     {
-      if (!evt.isControlDown() && !evt.isShiftDown())
-      {
-        av.getColumnSelection().clear();
-      }
-
-      av.getColumnSelection().addElement(res);
-      SequenceGroup sg = new SequenceGroup();
-      for (int i = 0; i < av.getAlignment().getSequences().size(); i++)
-      {
-        sg.addSequence(av.getAlignment().getSequenceAt(i), false);
-      }
-
-      sg.setStartRes(res);
-      sg.setEndRes(res);
-      av.setSelectionGroup(sg);
-
-      if (evt.isShiftDown())
+      MenuItem item = new MenuItem(
+              MessageManager.getString("label.hide_columns"));
+      item.addActionListener(new ActionListener()
       {
-        int min = Math.min(av.getColumnSelection().getMin(), res);
-        int max = Math.max(av.getColumnSelection().getMax(), res);
-        for (int i = min; i < max; i++)
+        @Override
+        public void actionPerformed(ActionEvent e)
         {
-          av.getColumnSelection().addElement(i);
+          av.hideColumns(res, res);
+          if (av.getSelectionGroup() != null
+                  && av.getSelectionGroup().getSize() == av
+                          .getAlignment().getHeight())
+          {
+            av.setSelectionGroup(null);
+          }
+
+          ap.paintAlignment(true);
+          if (ap.overviewPanel != null)
+          {
+            ap.overviewPanel.updateOverviewImage();
+          }
+          av.sendSelection();
         }
-        sg.setStartRes(min);
-        sg.setEndRes(max);
-      }
+      });
+      pop.add(item);
+      this.add(pop);
+      pop.show(this, evt.getX(), evt.getY());
     }
-
-    ap.paintAlignment(true);
-    av.sendSelection();
   }
 
+  @Override
   public void mouseReleased(MouseEvent evt)
   {
     mouseDragging = false;
@@ -232,6 +262,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     av.sendSelection();
   }
 
+  @Override
   public void mouseDragged(MouseEvent evt)
   {
     mouseDragging = true;
@@ -301,6 +332,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseEntered(MouseEvent evt)
   {
     if (mouseDragging)
@@ -309,6 +341,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseExited(MouseEvent evt)
   {
     if (mouseDragging)
@@ -317,11 +350,13 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseClicked(MouseEvent evt)
   {
 
   }
 
+  @Override
   public void mouseMoved(MouseEvent evt)
   {
     if (!av.hasHiddenColumns())
@@ -346,11 +381,13 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     repaint();
   }
 
+  @Override
   public void update(Graphics g)
   {
     paint(g);
   }
 
+  @Override
   public void paint(Graphics g)
   {
     drawScale(g, av.getStartRes(), av.getEndRes(), getSize().width,
@@ -371,9 +408,8 @@ public class ScalePanel extends Panel implements MouseMotionListener,
     ColumnSelection cs = av.getColumnSelection();
     gg.setColor(new Color(220, 0, 0));
     int avcharWidth = av.getCharWidth(), avcharHeight = av.getCharHeight();
-    for (int i = 0; i < cs.size(); i++)
+    for (int sel : cs.getSelected())
     {
-      int sel = cs.columnAt(i);
       if (av.hasHiddenColumns())
       {
         sel = av.getColumnSelection().findColumnPosition(sel);
index b4fefec..479b746 100644 (file)
@@ -489,6 +489,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     return false;
   }
 
+  @Override
   public void mousePressed(MouseEvent evt)
   {
     lastMousePress = evt.getPoint();
@@ -539,6 +540,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     return;
   }
 
+  @Override
   public void mouseClicked(MouseEvent evt)
   {
     SequenceI sequence = av.getAlignment().getSequenceAt(findSeq(evt));
@@ -572,6 +574,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseReleased(MouseEvent evt)
   {
     mouseDragging = false;
@@ -715,6 +718,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
 
   String lastMessage;
 
+  @Override
   public void mouseOverSequence(SequenceI sequence, int index, int pos)
   {
     String tmp = sequence.hashCode() + index + "";
@@ -726,6 +730,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     lastMessage = tmp;
   }
 
+  @Override
   public void highlightSequence(SearchResults results)
   {
     if (av.isFollowHighlight())
@@ -746,12 +751,14 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     return this.ap == null ? null : this.ap.av;
   }
 
+  @Override
   public void updateColours(SequenceI seq, int index)
   {
     System.out.println("update the seqPanel colours");
     // repaint();
   }
 
+  @Override
   public void mouseMoved(MouseEvent evt)
   {
     int res = findRes(evt);
@@ -912,6 +919,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
 
   Tooltip tooltip;
 
+  @Override
   public void mouseDragged(MouseEvent evt)
   {
     if (mouseWheelPressed)
@@ -1659,6 +1667,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     seqCanvas.repaint();
   }
 
+  @Override
   public void mouseEntered(MouseEvent e)
   {
     if (oldSeq < 0)
@@ -1673,6 +1682,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseExited(MouseEvent e)
   {
     if (av.getWrapAlignment())
@@ -1732,6 +1742,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
       running = false;
     }
 
+    @Override
     public void run()
     {
       running = true;
@@ -1776,6 +1787,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
   /**
    * modify current selection according to a received message.
    */
+  @Override
   public void selection(SequenceGroup seqsel, ColumnSelection colsel,
           SelectionSource source)
   {
@@ -1821,7 +1833,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
         sgroup = seqsel.intersect(av.getAlignment(),
                 (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null);
         if ((sgroup == null || sgroup.getSize() == 0)
-                && (colsel == null || colsel.size() == 0))
+                && (colsel == null || colsel.isEmpty()))
         {
           // don't copy columns if the region didn't intersect.
           copycolsel = false;
@@ -1843,7 +1855,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     {
       // the current selection is unset or from a previous message
       // so import the new colsel.
-      if (colsel == null || colsel.size() == 0)
+      if (colsel == null || colsel.isEmpty())
       {
         if (av.getColumnSelection() != null)
         {
index 4ea90e8..b492067 100755 (executable)
@@ -22,6 +22,7 @@ package jalview.bin;
 
 import jalview.ws.dbsources.das.api.DasSourceRegistryI;
 import jalview.ws.dbsources.das.datamodel.DasSourceRegistry;
+import jalview.ws.sifts.SiftsSettings;
 
 import java.awt.Color;
 import java.io.BufferedReader;
@@ -216,6 +217,10 @@ public class Cache
 
   public static final String DAS_ACTIVE_SOURCE = "DAS_ACTIVE_SOURCE";
 
+  public static final String DEFAULT_SIFTS_DOWNLOAD_DIR = System
+          .getProperty("user.home")
+          + File.separatorChar
+          + ".sifts_downloads" + File.separatorChar;
   /**
    * Initialises the Jalview Application Log
    */
@@ -394,6 +399,13 @@ public class Cache
       codeInstallation = " (" + codeInstallation + ")";
     }
     new BuildDetails(codeVersion, null, codeInstallation);
+
+    SiftsSettings
+            .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false));
+
+    SiftsSettings.setSiftDownloadDirectory(jalview.bin.Cache.getDefault(
+            "sifts_download_dir", DEFAULT_SIFTS_DOWNLOAD_DIR));
+
     System.out
             .println("Jalview Version: " + codeVersion + codeInstallation);
 
@@ -407,6 +419,7 @@ public class Cache
 
       class VersionChecker extends Thread
       {
+        @Override
         public void run()
         {
           String orgtimeout = System
index b4d92a0..dc6c424 100644 (file)
 package jalview.commands;
 
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.ColumnSelection;
-import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
-import jalview.util.ShiftList;
-
-import java.util.List;
 
 public class TrimRegionCommand extends EditCommand
 {
-  public static String TRIM_LEFT = "TrimLeft";
-
-  public static String TRIM_RIGHT = "TrimRight";
-
-  public ColumnSelection colSel = null;
-
-  int[] start;
-
-  ShiftList shiftList;
-
-  SequenceGroup selectionGroup;
-
-  List<int[]> deletedHiddenColumns;
-
   int columnsDeleted;
 
-  public TrimRegionCommand(String description, String command,
-          SequenceI[] seqs, int column, AlignmentI al,
-          ColumnSelection colSel, SequenceGroup selectedRegion)
+  /**
+   * Constructs and performs a trim alignment command
+   * 
+   * @param description
+   *          (to show in Undo/Redo menu)
+   * @param trimLeft
+   *          if true trim to left of column, else to right
+   * @param seqs
+   *          the sequences to trim
+   * @param column
+   *          the alignment column (base 0) from which to trim
+   * @param al
+   */
+  public TrimRegionCommand(String description, boolean trimLeft,
+          SequenceI[] seqs, int column, AlignmentI al)
   {
     this.description = description;
-    this.selectionGroup = selectedRegion;
-    this.colSel = colSel;
-    if (command.equalsIgnoreCase(TRIM_LEFT))
+    if (trimLeft)
     {
       if (column == 0)
       {
@@ -64,109 +55,24 @@ public class TrimRegionCommand extends EditCommand
 
       setEdit(new Edit(Action.CUT, seqs, 0, column, al));
     }
-    else if (command.equalsIgnoreCase(TRIM_RIGHT))
+    else
     {
       int width = al.getWidth() - column - 1;
-      if (width < 2)
+      if (width < 1)
       {
         return;
       }
 
-      columnsDeleted = width - 1;
+      columnsDeleted = width;
 
       setEdit(new Edit(Action.CUT, seqs, column + 1, width, al));
     }
 
-    // We need to keep a record of the sequence start
-    // in order to restore the state after a redo
-    int i, isize = getEdit(0).seqs.length;
-    start = new int[isize];
-    for (i = 0; i < isize; i++)
-    {
-      start[i] = getEdit(0).seqs[i].getStart();
-    }
 
     performEdit(0, null);
   }
 
-  void cut(Edit command)
-  {
-    int column, j, jSize = command.seqs.length;
-    for (j = 0; j < jSize; j++)
-    {
-      if (command.position == 0)
-      {
-        // This is a TRIM_LEFT command
-        column = command.seqs[j].findPosition(command.number);
-        command.seqs[j].setStart(column);
-      }
-      else
-      {
-        // This is a TRIM_RIGHT command
-        column = command.seqs[j].findPosition(command.position) - 1;
-        command.seqs[j].setEnd(column);
-      }
-    }
-
-    super.cut(command, null);
-
-    if (command.position == 0)
-    {
-      deletedHiddenColumns = colSel.compensateForEdit(0, command.number);
-      if (selectionGroup != null)
-      {
-        selectionGroup.adjustForRemoveLeft(command.number);
-      }
-    }
-    else
-    {
-      deletedHiddenColumns = colSel.compensateForEdit(command.position,
-              command.number);
-      if (selectionGroup != null)
-      {
-        selectionGroup.adjustForRemoveRight(command.position);
-      }
-    }
-  }
-
-  void paste(Edit command)
-  {
-    super.paste(command, null);
-    int column, j, jSize = command.seqs.length;
-    for (j = 0; j < jSize; j++)
-    {
-      if (command.position == 0)
-      {
-        command.seqs[j].setStart(start[j]);
-      }
-      else
-      {
-        column = command.seqs[j].findPosition(command.number
-                + command.position) - 1;
-        command.seqs[j].setEnd(column);
-      }
-    }
-
-    if (command.position == 0)
-    {
-      colSel.compensateForEdit(0, -command.number);
-      if (selectionGroup != null)
-      {
-        selectionGroup.adjustForRemoveLeft(-command.number);
-      }
-    }
-
-    if (deletedHiddenColumns != null)
-    {
-      int[] region;
-      for (int i = 0; i < deletedHiddenColumns.size(); i++)
-      {
-        region = deletedHiddenColumns.get(i);
-        colSel.hideColumns(region[0], region[1]);
-      }
-    }
-  }
-
+  @Override
   public int getSize()
   {
     return columnsDeleted;
index e4f11e0..151af0e 100644 (file)
@@ -83,8 +83,7 @@ public class AlignViewController implements AlignViewControllerI
     SequenceGroup sg = viewport.getSelectionGroup();
     ColumnSelection cs = viewport.getColumnSelection();
     SequenceGroup[] gps = null;
-    if (sg != null
-            && (cs == null || cs.getSelected() == null || cs.size() == 0))
+    if (sg != null && (cs == null || cs.isEmpty()))
     {
       gps = jalview.analysis.Grouping.makeGroupsFrom(viewport
               .getSequenceSelection(), viewport.getAlignmentView(true)
index 9bd1f2e..7990a5c 100755 (executable)
@@ -245,6 +245,7 @@ public class AlignmentAnnotation
    * 
    * @see java.lang.Object#finalize()
    */
+  @Override
   protected void finalize() throws Throwable
   {
     sequenceRef = null;
@@ -1304,7 +1305,8 @@ public class AlignmentAnnotation
    * @note caller should add the remapped annotation to newref if they have not
    *       already
    */
-  public void remap(SequenceI newref, int[][] mapping, int from, int to,
+  public void remap(SequenceI newref, HashMap<Integer, int[]> mapping,
+          int from, int to,
           int idxoffset)
   {
     if (mapping != null)
@@ -1312,7 +1314,7 @@ public class AlignmentAnnotation
       Map<Integer, Annotation> old = sequenceMapping;
       Map<Integer, Annotation> remap = new HashMap<Integer, Annotation>();
       int index = -1;
-      for (int mp[] : mapping)
+      for (int mp[] : mapping.values())
       {
         if (index++ < 0)
         {
index 57db830..6fb584c 100644 (file)
@@ -34,9 +34,15 @@ import java.util.Vector;
  */
 public class ColumnSelection
 {
+  /*
+   * list of selected columns (not ordered)
+   */
   Vector<Integer> selected = new Vector<Integer>();
 
-  // Vector of int [] {startCol, endCol}
+  /*
+   * list of hidden column [start, end] ranges; the list is maintained in
+   * ascending start column order
+   */
   Vector<int[]> hiddenColumns;
 
   /**
@@ -102,10 +108,10 @@ public class ColumnSelection
   }
 
   /**
-   * 
-   * @return Vector containing selected columns as Integers
+   * Returns a list of selected columns. The list contains no duplicates but is
+   * not necessarily ordered.
    */
-  public Vector<Integer> getSelected()
+  public List<Integer> getSelected()
   {
     return selected;
   }
@@ -123,26 +129,11 @@ public class ColumnSelection
   }
 
   /**
-   * Column number at position i in selection
-   * 
-   * @param i
-   *          index into selected columns
-   * 
-   * @return column number in alignment
-   */
-  public int columnAt(int i)
-  {
-    return selected.elementAt(i).intValue();
-  }
-
-  /**
-   * DOCUMENT ME!
-   * 
-   * @return DOCUMENT ME!
+   * Answers true if no columns are selected, else false
    */
-  public int size()
+  public boolean isEmpty()
   {
-    return selected.size();
+    return selected == null || selected.isEmpty();
   }
 
   /**
@@ -154,11 +145,11 @@ public class ColumnSelection
   {
     int max = -1;
 
-    for (int i = 0; i < selected.size(); i++)
+    for (int sel : getSelected())
     {
-      if (columnAt(i) > max)
+      if (sel > max)
       {
-        max = columnAt(i);
+        max = sel;
       }
     }
 
@@ -174,11 +165,11 @@ public class ColumnSelection
   {
     int min = 1000000000;
 
-    for (int i = 0; i < selected.size(); i++)
+    for (int sel : getSelected())
     {
-      if (columnAt(i) < min)
+      if (sel < min)
       {
-        min = columnAt(i);
+        min = sel;
       }
     }
 
@@ -196,9 +187,9 @@ public class ColumnSelection
   public List<int[]> compensateForEdit(int start, int change)
   {
     List<int[]> deletedHiddenColumns = null;
-    for (int i = 0; i < size(); i++)
+    for (int i = 0; i < selected.size(); i++)
     {
-      int temp = columnAt(i);
+      int temp = selected.get(i);
 
       if (temp >= start)
       {
@@ -254,13 +245,13 @@ public class ColumnSelection
    */
   private void compensateForDelEdits(int start, int change)
   {
-    for (int i = 0; i < size(); i++)
+    for (int i = 0; i < selected.size(); i++)
     {
-      int temp = columnAt(i);
+      int temp = selected.get(i);
 
       if (temp >= start)
       {
-        // if this ever changes to List.set(), swap parameter order!!
+        // if this ever changes to List.set(), must swap parameter order!!!
         selected.setElementAt(new Integer(temp - change), i);
       }
     }
@@ -638,14 +629,20 @@ public class ColumnSelection
 
   public void hideSelectedColumns()
   {
-    while (size() > 0)
+    while (!selected.isEmpty())
     {
-      int column = getSelected().firstElement().intValue();
+      int column = selected.get(0).intValue();
       hideColumns(column);
     }
 
   }
 
+  /**
+   * Adds the specified column range to the hidden columns
+   * 
+   * @param start
+   * @param end
+   */
   public void hideColumns(int start, int end)
   {
     if (hiddenColumns == null)
@@ -653,48 +650,68 @@ public class ColumnSelection
       hiddenColumns = new Vector<int[]>();
     }
 
-    boolean added = false;
-    boolean overlap = false;
-
+    /*
+     * traverse existing hidden ranges and insert / amend / append as
+     * appropriate
+     */
     for (int i = 0; i < hiddenColumns.size(); i++)
     {
       int[] region = hiddenColumns.elementAt(i);
-      if (start <= region[1] && end >= region[0])
+
+      if (end < region[0] - 1)
       {
-        hiddenColumns.removeElementAt(i);
-        overlap = true;
-        break;
+        /*
+         * insert discontiguous preceding range
+         */
+        hiddenColumns.insertElementAt(new int[] { start, end }, i);
+        return;
       }
-      else if (end < region[0] && start < region[0])
+
+      if (end <= region[1])
       {
-        hiddenColumns.insertElementAt(new int[] { start, end }, i);
-        added = true;
-        break;
+        /*
+         * new range overlaps existing, or is contiguous preceding it - adjust
+         * start column
+         */
+        region[0] = Math.min(region[0], start);
+        return;
       }
-    }
 
-    if (overlap)
-    {
-      hideColumns(start, end);
-    }
-    else if (!added)
-    {
-      hiddenColumns.addElement(new int[] { start, end });
+      if (start <= region[1] + 1)
+      {
+        /*
+         * new range overlaps existing, or is contiguous following it - adjust
+         * start and end columns
+         */
+        region[0] = Math.min(region[0], start);
+        region[1] = Math.max(region[1], end);
+        return;
+      }
     }
 
+    /*
+     * remaining case is that the new range follows everything else
+     */
+      hiddenColumns.addElement(new int[] { start, end });
   }
 
   /**
-   * This method will find a range of selected columns around the column
-   * specified
+   * Hides the specified column and any adjacent selected columns
    * 
    * @param res
    *          int
    */
   public void hideColumns(int col)
   {
-    // First find out range of columns to hide
-    int min = col, max = col + 1;
+    /*
+     * deselect column (whether selected or not!)
+     */
+    removeElement(col);
+
+    /*
+     * find adjacent selected columns
+     */
+    int min = col - 1, max = col + 1;
     while (contains(min))
     {
       removeElement(min);
@@ -707,6 +724,9 @@ public class ColumnSelection
       max++;
     }
 
+    /*
+     * min, max are now the closest unselected columns
+     */
     min++;
     max--;
     if (min > max)
@@ -717,6 +737,9 @@ public class ColumnSelection
     hideColumns(min, max);
   }
 
+  /**
+   * Unhides, and adds to the selection list, all hidden columns
+   */
   public void revealAllHiddenColumns()
   {
     if (hiddenColumns != null)
@@ -734,12 +757,18 @@ public class ColumnSelection
     hiddenColumns = null;
   }
 
-  public void revealHiddenColumns(int res)
+  /**
+   * Reveals, and marks as selected, the hidden column range with the given
+   * start column
+   * 
+   * @param start
+   */
+  public void revealHiddenColumns(int start)
   {
     for (int i = 0; i < hiddenColumns.size(); i++)
     {
       int[] region = hiddenColumns.elementAt(i);
-      if (res == region[0])
+      if (start == region[0])
       {
         for (int j = region[0]; j < region[1] + 1; j++)
         {
@@ -760,9 +789,8 @@ public class ColumnSelection
   {
     if (hiddenColumns != null)
     {
-      for (int i = 0; i < hiddenColumns.size(); i++)
+      for (int[] region : hiddenColumns)
       {
-        int[] region = hiddenColumns.elementAt(i);
         if (column >= region[0] && column <= region[1])
         {
           return false;
@@ -1078,7 +1106,7 @@ public class ColumnSelection
    */
   public void addElementsFrom(ColumnSelection colsel)
   {
-    if (colsel != null && colsel.size() > 0)
+    if (colsel != null && !colsel.isEmpty())
     {
       for (Integer col : colsel.getSelected())
       {
index 0581845..0b1fb6d 100755 (executable)
  */
 package jalview.datamodel;
 
-public class DBRefEntry
+import jalview.api.DBRefEntryI;
+
+public class DBRefEntry implements DBRefEntryI
 {
   String source = "", version = "", accessionId = "";
 
+  private int startRes, endRes;
   /**
    * maps from associated sequence to the database sequence's coordinate system
    */
@@ -98,7 +101,8 @@ public class DBRefEntry
    * @param entry
    * @return true if source, accession and version are equal with those of entry
    */
-  public boolean equalRef(DBRefEntry entry)
+  @Override
+  public boolean equalRef(DBRefEntryI entry)
   {
     if (entry == null)
     {
@@ -108,63 +112,59 @@ public class DBRefEntry
     {
       return true;
     }
-    if ((source != null && entry.source != null && source
-            .equalsIgnoreCase(entry.source))
-            && (accessionId != null && entry.accessionId != null && accessionId
-                    .equalsIgnoreCase(entry.accessionId))
-            && (version != null && entry.version != null && version
-                    .equalsIgnoreCase(entry.version)))
+    if (entry != null
+            && (source != null && entry.getSource() != null && source
+                    .equalsIgnoreCase(entry.getSource()))
+            && (accessionId != null && entry.getAccessionId() != null && accessionId
+                    .equalsIgnoreCase(entry.getAccessionId()))
+            && (version != null && entry.getVersion() != null && version
+                    .equalsIgnoreCase(entry.getVersion())))
     {
       return true;
     }
     return false;
   }
 
+  @Override
   public String getSource()
   {
     return source;
   }
 
+  @Override
   public String getVersion()
   {
     return version;
   }
 
+  @Override
   public String getAccessionId()
   {
     return accessionId;
   }
 
-  /**
-   * @param accessionId
-   *          the accessionId to set
-   */
+
+  @Override
   public void setAccessionId(String accessionId)
   {
     this.accessionId = accessionId;
   }
 
-  /**
-   * @param source
-   *          the source to set
-   */
+
+  @Override
   public void setSource(String source)
   {
     this.source = source;
   }
 
-  /**
-   * @param version
-   *          the version to set
-   */
+
+  @Override
   public void setVersion(String version)
   {
     this.version = version;
   }
 
-  /**
-   * @return the map
-   */
+
   public Mapping getMap()
   {
     return map;
@@ -194,8 +194,33 @@ public class DBRefEntry
             + ((accessionId != null) ? accessionId : "");
   }
 
+  @Override
   public String toString()
   {
     return getSrcAccString();
   }
+
+  @Override
+  public int getStartRes()
+  {
+    return startRes;
+  }
+
+  @Override
+  public void setStartRes(int startRes)
+  {
+    this.startRes = startRes;
+  }
+
+  @Override
+  public int getEndRes()
+  {
+    return endRes;
+  }
+
+  @Override
+  public void setEndRes(int endRes)
+  {
+    this.endRes = endRes;
+  }
 }
index 5e3fbc5..7b05649 100755 (executable)
@@ -21,6 +21,7 @@
 package jalview.datamodel;
 
 import jalview.analysis.AlignSeq;
+import jalview.api.DBRefEntryI;
 import jalview.util.StringUtils;
 
 import java.util.ArrayList;
@@ -55,6 +56,8 @@ public class Sequence extends ASequence implements SequenceI
 
   String vamsasId;
 
+  DBRefEntryI sourceDBRef;
+
   DBRefEntry[] dbrefs;
 
   RNA rna;
@@ -216,6 +219,7 @@ public class Sequence extends ASequence implements SequenceI
     initSeqAndName(seq.getName(), seq.getSequence(), seq.getStart(),
             seq.getEnd());
     description = seq.getDescription();
+    sourceDBRef = seq.getSourceDBRef();
     if (seq.getSequenceFeatures() != null)
     {
       SequenceFeature[] sf = seq.getSequenceFeatures();
@@ -225,10 +229,10 @@ public class Sequence extends ASequence implements SequenceI
       }
     }
     setDatasetSequence(seq.getDatasetSequence());
-    if (datasetSequence == null && seq.getDBRef() != null)
+    if (datasetSequence == null && seq.getDBRefs() != null)
     {
       // only copy DBRefs if we really are a dataset sequence
-      DBRefEntry[] dbr = seq.getDBRef();
+      DBRefEntry[] dbr = seq.getDBRefs();
       for (int i = 0; i < dbr.length; i++)
       {
         addDBRef(new DBRefEntry(dbr[i]));
@@ -908,18 +912,18 @@ public class Sequence extends ASequence implements SequenceI
   }
 
   @Override
-  public void setDBRef(DBRefEntry[] dbref)
+  public void setDBRefs(DBRefEntry[] dbref)
   {
     dbrefs = dbref;
   }
 
   @Override
-  public DBRefEntry[] getDBRef()
+  public DBRefEntry[] getDBRefs()
   {
     if (dbrefs == null && datasetSequence != null
             && this != datasetSequence)
     {
-      return datasetSequence.getDBRef();
+      return datasetSequence.getDBRefs();
     }
     return dbrefs;
   }
@@ -1078,8 +1082,8 @@ public class Sequence extends ASequence implements SequenceI
       datasetSequence.setDescription(getDescription());
       setSequenceFeatures(null);
       // move database references onto dataset sequence
-      datasetSequence.setDBRef(getDBRef());
-      setDBRef(null);
+      datasetSequence.setDBRefs(getDBRefs());
+      setDBRefs(null);
       datasetSequence.setPDBId(getAllPDBEntries());
       setPDBId(null);
       datasetSequence.updatePDBIds();
@@ -1254,7 +1258,7 @@ public class Sequence extends ASequence implements SequenceI
       }
     }
     // transfer database references
-    DBRefEntry[] entryRefs = entry.getDBRef();
+    DBRefEntry[] entryRefs = entry.getDBRefs();
     if (entryRefs != null)
     {
       for (int r = 0; r < entryRefs.length; r++)
@@ -1354,4 +1358,16 @@ public class Sequence extends ASequence implements SequenceI
     return null;
   }
 
+  @Override
+  public void setSourceDBRef(DBRefEntryI dbRef)
+  {
+    this.sourceDBRef = dbRef;
+  }
+
+  @Override
+  public DBRefEntryI getSourceDBRef()
+  {
+    return this.sourceDBRef;
+  }
+
 }
index cc70e25..0e8fa17 100755 (executable)
@@ -209,7 +209,7 @@ public class SequenceGroup implements AnnotatedCollectionI
       if (seqs[ipos] != null)
       {
         seqs[ipos].setDescription(seq.getDescription());
-        seqs[ipos].setDBRef(seq.getDBRef());
+        seqs[ipos].setDBRefs(seq.getDBRefs());
         seqs[ipos].setSequenceFeatures(seq.getSequenceFeatures());
         if (seq.getDatasetSequence() != null)
         {
index 0e649c0..f1cba43 100755 (executable)
@@ -20,6 +20,8 @@
  */
 package jalview.datamodel;
 
+import jalview.api.DBRefEntryI;
+
 import java.util.List;
 import java.util.Vector;
 
@@ -296,9 +298,9 @@ public interface SequenceI extends ASequenceI
 
   public void setVamsasId(String id);
 
-  public void setDBRef(DBRefEntry[] dbs);
+  public void setDBRefs(DBRefEntry[] dbs);
 
-  public DBRefEntry[] getDBRef();
+  public DBRefEntry[] getDBRefs();
 
   /**
    * add the given entry to the list of DBRefs for this sequence, or replace a
@@ -429,4 +431,8 @@ public interface SequenceI extends ASequenceI
    * @return
    */
   public PDBEntry getPDBEntry(String pdbId);
+
+  public void setSourceDBRef(DBRefEntryI dbRef);
+
+  public DBRefEntryI getSourceDBRef();
 }
index b464c94..a1b6917 100644 (file)
@@ -552,6 +552,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
     System.out.println("JMOL CREATE IMAGE");
   }
 
+  @Override
   public String createImage(String fileName, String type,
           Object textOrBytes, int quality)
   {
@@ -559,6 +560,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
     return null;
   }
 
+  @Override
   public String eval(String strEval)
   {
     // System.out.println(strEval);
@@ -569,11 +571,13 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
   // End StructureListener
   // //////////////////////////
 
+  @Override
   public float[][] functionXY(String functionName, int x, int y)
   {
     return null;
   }
 
+  @Override
   public float[][][] functionXYZ(String functionName, int nx, int ny, int nz)
   {
     // TODO Auto-generated method stub
@@ -737,6 +741,11 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
   {
     if (atoms != null)
     {
+      if (resetLastRes.length() > 0)
+      {
+        viewer.evalStringQuiet(resetLastRes.toString());
+        resetLastRes.setLength(0);
+      }
       for (AtomSpec atom : atoms)
       {
         highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
@@ -768,17 +777,10 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
     }
 
     jmolHistory(false);
-    // if (!pdbfile.equals(pdbentry.getFile()))
-    // return;
-    if (resetLastRes.length() > 0)
-    {
-      viewer.evalStringQuiet(resetLastRes.toString());
-    }
 
     StringBuilder cmd = new StringBuilder(64);
     cmd.append("select " + pdbResNum); // +modelNum
 
-    resetLastRes.setLength(0);
     resetLastRes.append("select " + pdbResNum); // +modelNum
 
     cmd.append(":");
@@ -1264,6 +1266,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
    */
   public abstract void sendConsoleMessage(String strStatus);
 
+  @Override
   public void setCallbackFunction(String callbackType,
           String callbackFunction)
   {
index 19f535c..d5676c5 100644 (file)
@@ -64,7 +64,9 @@ public class JmolCommands
       ArrayList<String> str = new ArrayList<String>();
 
       if (mapping == null || mapping.length < 1)
+      {
         continue;
+      }
 
       int lastPos = -1;
       for (int s = 0; s < sequence[pdbfnum].length; s++)
@@ -85,14 +87,18 @@ public class JmolCommands
               int pos = mapping[m].getPDBResNum(asp.findPosition(r));
 
               if (pos < 1 || pos == lastPos)
+              {
                 continue;
+              }
 
               lastPos = pos;
 
               Color col = sr.getResidueBoxColour(sequence[pdbfnum][s], r);
 
               if (fr != null)
+              {
                 col = fr.findFeatureColour(col, sequence[pdbfnum][s], r);
+              }
               String newSelcom = (mapping[m].getChain() != " " ? ":"
                       + mapping[m].getChain() : "")
                       + "/"
@@ -125,7 +131,7 @@ public class JmolCommands
               command.append("select " + pos);
               command.append(newSelcom);
             }
-            break;
+            // break;
           }
         }
       }
index 8d76afc..d32a10d 100644 (file)
@@ -28,10 +28,13 @@ import jalview.datamodel.SequenceI;
 import jalview.io.AlignFile;
 import jalview.io.FileParse;
 import jalview.schemes.ResidueProperties;
+import jalview.util.Comparison;
 import jalview.util.MessageManager;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Hashtable;
+import java.util.List;
 import java.util.Map;
 
 import javajs.awt.Dimension;
@@ -39,11 +42,13 @@ import javajs.awt.Dimension;
 import org.jmol.api.JmolStatusListener;
 import org.jmol.api.JmolViewer;
 import org.jmol.c.CBK;
+import org.jmol.c.STR;
 import org.jmol.modelset.Group;
 import org.jmol.modelset.Model;
 import org.jmol.modelset.ModelSet;
 import org.jmol.modelsetbio.BioModel;
 import org.jmol.modelsetbio.BioPolymer;
+import org.jmol.modelsetbio.Monomer;
 import org.jmol.viewer.Viewer;
 
 /**
@@ -84,6 +89,8 @@ public class PDBFileWithJmol extends AlignFile implements
       {
         viewer = (Viewer) JmolViewer.allocateViewer(null, null, null, null,
                 null, "-x -o -n", this);
+        // ensure the 'new' (DSSP) not 'old' (Ramachandran) SS method is used
+        viewer.setBooleanProperty("defaultStructureDSSP", true);
       } catch (ClassCastException x)
       {
         throw new Error(MessageManager.formatMessage(
@@ -108,229 +115,96 @@ public class PDBFileWithJmol extends AlignFile implements
     }
   }
 
-  /*
-   * (non-Javadoc)
+  /**
+   * Convert Jmol's secondary structure code to Jalview's, and stored it in the
+   * secondary structure arrays at the given sequence position
    * 
-   * @see jalview.io.AlignFile#parse()
+   * @param proteinStructureSubType
+   * @param pos
+   * @param secstr
+   * @param secstrcode
    */
-  @Override
-  public void parse() throws IOException
+  protected void setSecondaryStructure(STR proteinStructureSubType,
+          int pos, char[] secstr, char[] secstrcode)
   {
-    Viewer jmd = getJmolData();
-    jmd.openReader(getDataName(), getDataName(), getReader());
-    waitForScript(jmd);
-
-    if (jmd.ms.mc > 0)
+    switch (proteinStructureSubType)
     {
-      ModelSet ms = jmd.ms;
-      // Jmol 14.2 added third argument doReport = false
-      ms.calculateStructures(null, true, false, false, true);
-      // System.out.println("Structs\n"+structs);
-      Group group = null;
-      int modelIndex = -1;
-      for (Model model : ms.am)
-      {
-        modelIndex++;
-        for (BioPolymer bp : ((BioModel) model).bioPolymers)
-        {
-          int lastChainId = 0; // int value of character e.g. 65 for A
-          String lastChainIdAlpha = "";
-
-          int[] groups = bp.getLeadAtomIndices();
-          char seq[] = new char[groups.length], secstr[] = new char[groups.length], secstrcode[] = new char[groups.length];
-          int groupc = 0, len = 0, firstrnum = 1, lastrnum = 0;
-
-          do
-          {
-            if (groupc >= groups.length
-                    || ms.at[groups[groupc]].group.chain.chainID != lastChainId)
-            {
-              /*
-               * on change of chain (or at end), construct the sequence and
-               * secondary structure annotation for the last chain
-               */
-              if (len > 0)
-              {
-                boolean isNa = bp.isNucleic();
-                // normalise sequence from Jmol to jalview
-                int[] cinds = isNa ? ResidueProperties.nucleotideIndex
-                        : ResidueProperties.aaIndex;
-                int nonGap = isNa ? ResidueProperties.maxNucleotideIndex
-                        : ResidueProperties.maxProteinIndex;
-                char ngc = 'X';
-                char newseq[] = new char[len];
-                Annotation asecstr[] = new Annotation[len + firstrnum - 1];
-                for (int p = 0; p < len; p++)
-                {
-                  newseq[p] = cinds[seq[p]] == nonGap ? ngc : seq[p];
-                  if (secstr[p] >= 'A' && secstr[p] <= 'z')
-                  {
-                    try
-                    {
-                      asecstr[p] = new Annotation("" + secstr[p], null,
-                              secstrcode[p], Float.NaN);
-                    } catch (ArrayIndexOutOfBoundsException e)
-                    {
-                      // skip - patch for JAL-1836
-                    }
-                  }
-                }
-                String modelTitle = (String) ms
-                        .getInfo(modelIndex, "title");
-                SequenceI sq = new Sequence("" + getDataName() + "|"
-                        + modelTitle + "|" + lastChainIdAlpha, newseq,
-                        firstrnum, lastrnum);
-                PDBEntry pdbe = new PDBEntry();
-                pdbe.setFile(getDataName());
-                pdbe.setId(getDataName());
-                pdbe.setProperty(new Hashtable());
-                // pdbe.getProperty().put("CHAIN", "" + _lastChainId);
-                pdbe.setChainCode(lastChainIdAlpha);
-                sq.addPDBId(pdbe);
-                // JAL-1533
-                // Need to put the number of models for this polymer somewhere
-                // for Chimera/others to grab
-                // pdbe.getProperty().put("PDBMODELS", biopoly.)
-                seqs.add(sq);
-                if (!isNa)
-                {
-                  String mt = modelTitle == null ? getDataName()
-                          : modelTitle;
-                  if (lastChainId >= ' ')
-                  {
-                    mt += lastChainIdAlpha;
-                  }
-                  AlignmentAnnotation ann = new AlignmentAnnotation(
-                          "Secondary Structure", "Secondary Structure for "
-                                  + mt, asecstr);
-                  ann.belowAlignment = true;
-                  ann.visible = true;
-                  ann.autoCalculated = false;
-                  ann.setCalcId(getClass().getName());
-                  sq.addAlignmentAnnotation(ann);
-                  ann.adjustForAlignment();
-                  ann.validateRangeAndDisplay();
-                  annotations.add(ann);
-                }
-              }
-              len = 0;
-              firstrnum = 1;
-              lastrnum = 0;
-            }
-            if (groupc < groups.length)
-            {
-              group = ms.at[groups[groupc]].group;
-              if (len == 0)
-              {
-                firstrnum = group.getResno();
-                lastChainId = group.chain.chainID;
-                lastChainIdAlpha = group.chain.getIDStr();
-              }
-              else
-              {
-                lastrnum = group.getResno();
-              }
-              seq[len] = group.getGroup1();
-
-              /*
-               * JAL-1828 replace a modified amino acid with its standard
-               * equivalent (e.g. MSE with MET->M) to maximise sequence matching
-               */
-              String threeLetterCode = group.getGroup3();
-              String canonical = ResidueProperties
-                      .getCanonicalAminoAcid(threeLetterCode);
-              if (canonical != null
-                      && !canonical.equalsIgnoreCase(threeLetterCode))
-              {
-                seq[len] = ResidueProperties
-                        .getSingleCharacterCode(canonical);
-              }
-              switch (group.getProteinStructureSubType())
-              {
-              case HELIX310:
-                if (secstr[len] == 0)
-                {
-                  secstr[len] = '3';
-                }
-              case HELIXALPHA:
-                if (secstr[len] == 0)
-                {
-                  secstr[len] = 'H';
-                }
-              case HELIXPI:
-                if (secstr[len] == 0)
-                {
-                  secstr[len] = 'P';
-                }
-              case HELIX:
-                if (secstr[len] == 0)
-                {
-                  secstr[len] = 'H';
-                }
-                secstrcode[len] = 'H';
-                break;
-              case SHEET:
-                secstr[len] = 'E';
-                secstrcode[len] = 'E';
-                break;
-              default:
-                secstr[len] = 0;
-                secstrcode[len] = 0;
-              }
-              len++;
-            }
-          } while (groupc++ < groups.length);
-        }
-      }
+    case HELIX310:
+      secstr[pos] = '3';
+      break;
+    case HELIX:
+    case HELIXALPHA:
+      secstr[pos] = 'H';
+      break;
+    case HELIXPI:
+      secstr[pos] = 'P';
+      break;
+    case SHEET:
+      secstr[pos] = 'E';
+      break;
+    default:
+      secstr[pos] = 0;
+    }
 
-      /*
-       * lastScriptTermination = -9465; String dsspOut =
-       * jmd.evalString("calculate STRUCTURE"); if (dsspOut.equals("pending")) {
-       * while (lastScriptTermination == -9465) { try { Thread.sleep(50); }
-       * catch (Exception x) { } ; } } System.out.println(lastConsoleEcho);
-       */
+    switch (proteinStructureSubType)
+    {
+    case HELIX310:
+    case HELIXALPHA:
+    case HELIXPI:
+    case HELIX:
+      secstrcode[pos] = 'H';
+      break;
+    case SHEET:
+      secstrcode[pos] = 'E';
+      break;
+    default:
+      secstrcode[pos] = 0;
     }
   }
 
-  /*
-   * (non-Javadoc)
+  /**
+   * Convert any non-standard peptide codes to their standard code table
+   * equivalent. (Initial version only does Selenomethionine MSE->MET.)
    * 
-   * @see jalview.io.AlignFile#print()
+   * @param threeLetterCode
+   * @param seq
+   * @param pos
+   */
+  protected void replaceNonCanonicalResidue(String threeLetterCode,
+          char[] seq, int pos)
+  {
+    String canonical = ResidueProperties
+            .getCanonicalAminoAcid(threeLetterCode);
+    if (canonical != null && !canonical.equalsIgnoreCase(threeLetterCode))
+    {
+      seq[pos] = ResidueProperties.getSingleCharacterCode(canonical);
+    }
+  }
+
+  /**
+   * Not implemented - returns null
    */
   @Override
   public String print()
   {
-    // TODO Auto-generated method stub
     return null;
   }
 
+  /**
+   * Not implemented
+   */
   @Override
   public void setCallbackFunction(String callbackType,
           String callbackFunction)
   {
-    // TODO Auto-generated method stub
-
   }
 
-  /*
-   * @Override public void notifyCallback(EnumCallback type, Object[] data) {
-   * try { switch (type) { case ERROR: case SCRIPT:
-   * notifyScriptTermination((String) data[2], ((Integer) data[3]).intValue());
-   * break; case MESSAGE: sendConsoleMessage((data == null) ? ((String) null) :
-   * (String) data[1]); break; case LOADSTRUCT: notifyFileLoaded((String)
-   * data[1], (String) data[2], (String) data[3], (String) data[4], ((Integer)
-   * data[5]).intValue());
-   * 
-   * break; default: // System.err.println("Unhandled callback " + type + " " //
-   * + data[1].toString()); break; } } catch (Exception e) {
-   * System.err.println("Squashed Jmol callback handler error:");
-   * e.printStackTrace(); } }
-   */
-  public void notifyCallback(CBK type, Object[] data)
+  @Override
+  public void notifyCallback(CBK cbType, Object[] data)
   {
     String strInfo = (data == null || data[1] == null ? null : data[1]
             .toString());
-    switch (type)
+    switch (cbType)
     {
     case ECHO:
       sendConsoleEcho(strInfo);
@@ -407,49 +281,63 @@ public class PDBFileWithJmol extends AlignFile implements
     }
   }
 
+  /**
+   * Not implemented - returns null
+   */
   @Override
   public String eval(String strEval)
   {
-    // TODO Auto-generated method stub
     return null;
   }
 
+  /**
+   * Not implemented - returns null
+   */
   @Override
   public float[][] functionXY(String functionName, int x, int y)
   {
-    // TODO Auto-generated method stub
     return null;
   }
 
+  /**
+   * Not implemented - returns null
+   */
   @Override
   public float[][][] functionXYZ(String functionName, int nx, int ny, int nz)
   {
-    // TODO Auto-generated method stub
     return null;
   }
 
+  /**
+   * Not implemented - returns null
+   */
   @Override
-  public String createImage(String fileName, String type,
+  public String createImage(String fileName, String imageType,
           Object text_or_bytes, int quality)
   {
-    // TODO Auto-generated method stub
     return null;
   }
 
+  /**
+   * Not implemented - returns null
+   */
   @Override
   public Map<String, Object> getRegistryInfo()
   {
-    // TODO Auto-generated method stub
     return null;
   }
 
+  /**
+   * Not implemented
+   */
   @Override
   public void showUrl(String url)
   {
-    // TODO Auto-generated method stub
-
   }
 
+  /**
+   * Not implemented - returns null
+   */
   @Override
   public Dimension resizeInnerPanel(String data)
   {
@@ -462,4 +350,322 @@ public class PDBFileWithJmol extends AlignFile implements
     return null;
   }
 
+  /**
+   * Calls the Jmol library to parse the PDB file, and then inspects the
+   * resulting object model to generate Jalview-style sequences, with secondary
+   * structure annotation added where available (i.e. where it has been computed
+   * by Jmol using DSSP).
+   * 
+   * @see jalview.io.AlignFile#parse()
+   */
+  @Override
+  public void parse() throws IOException
+  {
+    Viewer jmolModel = getJmolData();
+    jmolModel.openReader(getDataName(), getDataName(), getReader());
+    waitForScript(jmolModel);
+
+    /*
+     * Convert one or more Jmol Model objects to Jalview sequences
+     */
+    if (jmolModel.ms.mc > 0)
+    {
+      parseBiopolymers(jmolModel.ms);
+    }
+  }
+
+  /**
+   * Process the Jmol BioPolymer array and generate a Jalview sequence for each
+   * chain found (including any secondary structure annotation from DSSP)
+   * 
+   * @param ms
+   * @throws IOException
+   */
+  public void parseBiopolymers(ModelSet ms) throws IOException
+  {
+    int modelIndex = -1;
+    for (Model model : ms.am)
+    {
+      modelIndex++;
+      String modelTitle = (String) ms.getInfo(modelIndex, "title");
+
+      /*
+       * Chains can span BioPolymers, so first make a flattened list, 
+       * and then work out the lengths of chains present
+       */
+      List<Monomer> monomers = getMonomers(ms, (BioModel) model);
+      List<Integer> chainLengths = getChainLengths(monomers);
+
+      /*
+       * now chop up the Monomer list to make Jalview Sequences
+       */
+      int from = 0;
+      for (int length : chainLengths)
+      {
+        buildSequenceFromChain(monomers.subList(from, from + length), modelTitle);
+        from += length;
+      }
+    }
+  }
+
+  /**
+   * Helper method to construct a sequence for one chain and add it to the seqs
+   * list
+   * 
+   * @param monomers
+   *          a list of all monomers in the chain
+   * @param modelTitle
+   */
+  protected void buildSequenceFromChain(List<Monomer> monomers, String modelTitle)
+  {
+    final int length = monomers.size();
+
+    /*
+     * arrays to hold sequence and secondary structure
+     */
+    char[] seq = new char[length];
+    char[] secstr = new char[length];
+    char[] secstrcode = new char[length];
+
+    /*
+     * populate the sequence and secondary structure arrays
+     */
+    extractJmolChainData(monomers, seq, secstr, secstrcode);
+
+    /*
+     * grab chain code and start position from first residue;
+     */
+    String chainId = monomers.get(0).chain.getIDStr();
+    int firstResNum = monomers.get(0).getResno();
+    if (firstResNum < 1)
+    {
+      // Jalview doesn't like residue < 1, so force this to 1
+      System.err.println("Converting chain " + chainId + " first RESNUM ("
+              + firstResNum + ") to 1");
+      firstResNum = 1;
+    }
+
+    /*
+     * convert any non-gap unknown residues to 'X'
+     */
+    convertNonGapCharacters(seq);
+
+    /*
+     * construct and add the Jalview sequence
+     */
+    String seqName = "" + getDataName() + "|" + modelTitle + "|"
+            + chainId;
+    SequenceI sq = new Sequence(seqName, seq, firstResNum, firstResNum + length - 1);
+    seqs.add(sq);
+
+    /*
+     * add secondary structure predictions (if any)
+     */
+    addSecondaryStructureAnnotation(modelTitle, sq, secstr, secstrcode,
+            chainId, firstResNum);
+
+    /*
+     * record the PDB id for the sequence
+     */
+    addPdbid(sq, chainId);
+  }
+
+  /**
+   * Scans the list of (Jmol) Monomer objects, and adds the residue for each to
+   * the sequence array, and any converted secondary structure prediction to the
+   * secondary structure arrays
+   * 
+   * @param monomers
+   * @param seq
+   * @param secstr
+   * @param secstrcode
+   */
+  protected void extractJmolChainData(List<Monomer> monomers, char[] seq,
+          char[] secstr, char[] secstrcode)
+  {
+    int pos = 0;
+    for (Monomer monomer : monomers)
+    {
+      seq[pos] = monomer.getGroup1();
+
+      /*
+       * JAL-1828 replace a modified amino acid with its standard
+       * equivalent (e.g. MSE with MET->M) to maximise sequence matching
+       */
+      replaceNonCanonicalResidue(monomer.getGroup3(), seq, pos);
+
+      /*
+       * if Jmol has derived a secondary structure prediction for
+       * this position, convert it to Jalview equivalent and save it
+       */
+      setSecondaryStructure(monomer.getProteinStructureSubType(), pos,
+              secstr, secstrcode);
+      pos++;
+    }
+  }
+
+  /**
+   * Helper method that adds an AlignmentAnnotation for secondary structure to
+   * the sequence, provided at least one secondary structure prediction has been
+   * made
+   * 
+   * @param modelTitle
+   * @param seq
+   * @param secstr
+   * @param secstrcode
+   * @param chainId
+   * @param firstResNum
+   * @return
+   */
+  protected void addSecondaryStructureAnnotation(String modelTitle,
+          SequenceI sq, char[] secstr, char[] secstrcode,
+          String chainId, int firstResNum)
+  {
+    char[] seq = sq.getSequence();
+    boolean ssFound = false;
+    Annotation asecstr[] = new Annotation[seq.length + firstResNum - 1];
+    for (int p = 0; p < seq.length; p++)
+    {
+      if (secstr[p] >= 'A' && secstr[p] <= 'z')
+      {
+        asecstr[p] = new Annotation(String.valueOf(secstr[p]), null,
+                secstrcode[p], Float.NaN);
+        ssFound = true;
+      }
+    }
+
+    if (ssFound)
+    {
+      String mt = modelTitle == null ? getDataName() : modelTitle;
+      mt += chainId;
+      AlignmentAnnotation ann = new AlignmentAnnotation(
+              "Secondary Structure", "Secondary Structure for " + mt,
+              asecstr);
+      ann.belowAlignment = true;
+      ann.visible = true;
+      ann.autoCalculated = false;
+      ann.setCalcId(getClass().getName());
+      ann.adjustForAlignment();
+      ann.validateRangeAndDisplay();
+      annotations.add(ann);
+      sq.addAlignmentAnnotation(ann);
+    }
+  }
+
+  /**
+   * Replace any non-gap miscellaneous characters with 'X'
+   * 
+   * @param seq
+   * @return
+   */
+  protected void convertNonGapCharacters(char[] seq)
+  {
+    boolean isNa = Comparison.areNucleotide(new char[][] { seq });
+    int[] cinds = isNa ? ResidueProperties.nucleotideIndex
+            : ResidueProperties.aaIndex;
+    int nonGap = isNa ? ResidueProperties.maxNucleotideIndex
+            : ResidueProperties.maxProteinIndex;
+
+    for (int p = 0; p < seq.length; p++)
+    {
+      if (cinds[seq[p]] == nonGap)
+      {
+        seq[p] = 'X';
+      }
+    }
+  }
+
+  /**
+   * Add a PDBEntry giving the source of PDB data to the sequence
+   * 
+   * @param sq
+   * @param chainId
+   */
+  protected void addPdbid(SequenceI sq, String chainId)
+  {
+    PDBEntry pdbe = new PDBEntry();
+    pdbe.setFile(getDataName());
+    pdbe.setId(getDataName());
+    pdbe.setProperty(new Hashtable());
+    pdbe.setChainCode(chainId);
+    sq.addPDBId(pdbe);
+  }
+
+  /**
+   * Scans the list of Monomers (residue models), inspecting the chain id for
+   * each, and returns an array whose length is the number of chains, and values
+   * the length of each chain
+   * 
+   * @param monomers
+   * @return
+   */
+  protected List<Integer> getChainLengths(List<Monomer> monomers)
+  {
+    List<Integer> chainLengths = new ArrayList<Integer>();
+    int lastChainId = -1;
+    int length = 0;
+
+    for (Monomer monomer : monomers)
+    {
+      int chainId = monomer.chain.chainID;
+      if (chainId != lastChainId && length > 0)
+      {
+        /*
+         * change of chain - record the length of the last one
+         */
+        chainLengths.add(length);
+        length = 0;
+      }
+      lastChainId = chainId;
+      length++;
+    }
+    if (length > 0)
+    {
+      /*
+       * record the length of the final chain
+       */
+      chainLengths.add(length);
+    }
+
+    return chainLengths;
+  }
+
+  /**
+   * Returns a flattened list of Monomer (residues) in order, across all
+   * BioPolymers in the model. This simplifies assembling chains which span
+   * BioPolymers. The result omits any alternate residues reported for the same
+   * sequence position (RESNUM value).
+   * 
+   * @param ms
+   * @param model
+   * @return
+   */
+  protected List<Monomer> getMonomers(ModelSet ms, BioModel model)
+  {
+    List<Monomer> result = new ArrayList<Monomer>();
+    int lastResNo = Integer.MIN_VALUE;
+
+    for (BioPolymer bp : model.bioPolymers)
+    {
+      for (int groupLeadAtoms : bp.getLeadAtomIndices())
+      {
+        Group group = ms.at[groupLeadAtoms].group;
+        if (group instanceof Monomer)
+        {
+          /*
+           * ignore alternate residue at same position
+           * example: 1ejg has residues A:LEU, B:ILE at RESNUM=25
+           */
+          int resNo = group.getResno();
+          if (lastResNo != resNo)
+          {
+            result.add((Monomer) group);
+          }
+          lastResNo = resNo;
+        }
+      }
+    }
+    return result;
+  }
+
 }
index e8eb03b..5ff7c6c 100644 (file)
@@ -2548,7 +2548,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     ColumnSelection colSel = viewport.getColumnSelection();
     int column;
 
-    if (colSel.size() > 0)
+    if (!colSel.isEmpty())
     {
       if (trimLeft)
       {
@@ -2573,18 +2573,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       TrimRegionCommand trimRegion;
       if (trimLeft)
       {
-        trimRegion = new TrimRegionCommand("Remove Left",
-                TrimRegionCommand.TRIM_LEFT, seqs, column,
-                viewport.getAlignment(), viewport.getColumnSelection(),
-                viewport.getSelectionGroup());
+        trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
+                column, viewport.getAlignment());
         viewport.setStartRes(0);
       }
       else
       {
-        trimRegion = new TrimRegionCommand("Remove Right",
-                TrimRegionCommand.TRIM_RIGHT, seqs, column,
-                viewport.getAlignment(), viewport.getColumnSelection(),
-                viewport.getSelectionGroup());
+        trimRegion = new TrimRegionCommand("Remove Right", false, seqs,
+                column, viewport.getAlignment());
       }
 
       statusBar.setText(MessageManager.formatMessage(
@@ -2971,6 +2967,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   {
     viewport.showAllHiddenColumns();
     repaint();
+    viewport.sendSelection();
   }
 
   @Override
@@ -3061,6 +3058,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public void hideAllButSelection_actionPerformed(ActionEvent e)
   {
     toggleHiddenRegions(false, false);
+    viewport.sendSelection();
   }
 
   /*
@@ -3078,6 +3076,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     viewport.hideAllSelectedSeqs();
     viewport.hideSelectedColumns();
     alignPanel.paintAlignment(true);
+    viewport.sendSelection();
   }
 
   /*
@@ -3093,6 +3092,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     viewport.showAllHiddenColumns();
     viewport.showAllHiddenSeqs();
     alignPanel.paintAlignment(true);
+    viewport.sendSelection();
   }
 
   @Override
@@ -3100,6 +3100,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   {
     viewport.hideSelectedColumns();
     alignPanel.paintAlignment(true);
+    viewport.sendSelection();
   }
 
   @Override
@@ -5513,8 +5514,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           @Override
           public void run()
           {
+            boolean isNuclueotide = alignPanel.alignFrame
+                    .getViewport().getAlignment()
+                    .isNucleotide();
             new jalview.ws.DBRefFetcher(alignPanel.av
-                    .getSequenceSelection(), alignPanel.alignFrame)
+                    .getSequenceSelection(),
+                    alignPanel.alignFrame, null,
+                    alignPanel.alignFrame.featureSettings,
+                    isNuclueotide)
                     .fetchDBRefs(false);
           }
         }).start();
@@ -5583,9 +5590,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                       @Override
                       public void run()
                       {
+                        boolean isNuclueotide = alignPanel.alignFrame
+                                .getViewport().getAlignment()
+                                .isNucleotide();
                         new jalview.ws.DBRefFetcher(alignPanel.av
                                 .getSequenceSelection(),
-                                alignPanel.alignFrame, dassource)
+                                alignPanel.alignFrame, dassource,
+                                alignPanel.alignFrame.featureSettings,
+                                isNuclueotide)
                                 .fetchDBRefs(false);
                       }
                     }).start();
@@ -5619,9 +5631,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                       @Override
                       public void run()
                       {
+                        boolean isNuclueotide = alignPanel.alignFrame
+                                .getViewport().getAlignment()
+                                .isNucleotide();
                         new jalview.ws.DBRefFetcher(alignPanel.av
                                 .getSequenceSelection(),
-                                alignPanel.alignFrame, dassource)
+                                alignPanel.alignFrame, dassource,
+                                alignPanel.alignFrame.featureSettings,
+                                isNuclueotide)
                                 .fetchDBRefs(false);
                       }
                     }).start();
@@ -5670,9 +5687,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                         @Override
                         public void run()
                         {
+                          boolean isNuclueotide = alignPanel.alignFrame
+                                  .getViewport().getAlignment()
+                                  .isNucleotide();
                           new jalview.ws.DBRefFetcher(alignPanel.av
                                   .getSequenceSelection(),
-                                  alignPanel.alignFrame, dassrc)
+                                  alignPanel.alignFrame, dassrc,
+                                  alignPanel.alignFrame.featureSettings,
+                                  isNuclueotide)
                                   .fetchDBRefs(false);
                         }
                       }).start();
index 77d6b51..a70d4b9 100755 (executable)
@@ -289,14 +289,14 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
 
     if (evt.getActionCommand().equals(REMOVE))
     {
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int sel : av.getColumnSelection().getSelected())
       {
-        anot[av.getColumnSelection().columnAt(i)] = null;
+        anot[sel] = null;
       }
     }
     else if (evt.getActionCommand().equals(LABEL))
     {
-      String exMesg = collectAnnotVals(anot, av.getColumnSelection(), LABEL);
+      String exMesg = collectAnnotVals(anot, LABEL);
       String label = JOptionPane.showInputDialog(this,
               MessageManager.getString("label.enter_label"), exMesg);
 
@@ -310,10 +310,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         aa[activeRow].hasText = true;
       }
 
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int index : av.getColumnSelection().getSelected())
       {
-        int index = av.getColumnSelection().columnAt(i);
-
         if (!av.getColumnSelection().isVisible(index))
         {
           continue;
@@ -338,10 +336,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
               MessageManager.getString("label.select_foreground_colour"),
               Color.black);
 
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int index : av.getColumnSelection().getSelected())
       {
-        int index = av.getColumnSelection().columnAt(i);
-
         if (!av.getColumnSelection().isVisible(index))
         {
           continue;
@@ -399,10 +395,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
           aa[activeRow].showAllColLabels = true;
         }
       }
-      for (int i = 0; i < av.getColumnSelection().size(); i++)
+      for (int index : av.getColumnSelection().getSelected())
       {
-        int index = av.getColumnSelection().columnAt(i);
-
         if (!av.getColumnSelection().isVisible(index))
         {
           continue;
@@ -428,16 +422,14 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     return;
   }
 
-  private String collectAnnotVals(Annotation[] anot,
-          ColumnSelection columnSelection, String label2)
+  private String collectAnnotVals(Annotation[] anot, String label2)
   {
     String collatedInput = "";
     String last = "";
     ColumnSelection viscols = av.getColumnSelection();
     // TODO: refactor and save av.getColumnSelection for efficiency
-    for (int i = 0; i < columnSelection.size(); i++)
+    for (int index : viscols.getSelected())
     {
-      int index = columnSelection.columnAt(i);
       // always check for current display state - just in case
       if (!viscols.isVisible(index))
       {
index 96abf81..3f3e8f6 100644 (file)
@@ -1949,16 +1949,16 @@ public class Jalview2XML
     if (jds.getDatasetSequence() != null)
     {
       vamsasSeq.setDsseqid(seqHash(jds.getDatasetSequence()));
-      if (jds.getDatasetSequence().getDBRef() != null)
+      if (jds.getDatasetSequence().getDBRefs() != null)
       {
-        dbrefs = jds.getDatasetSequence().getDBRef();
+        dbrefs = jds.getDatasetSequence().getDBRefs();
       }
     }
     else
     {
       vamsasSeq.setDsseqid(id); // so we can tell which sequences really are
       // dataset sequences only
-      dbrefs = jds.getDBRef();
+      dbrefs = jds.getDBRefs();
     }
     if (dbrefs != null)
     {
index b551f5d..61e20fa 100755 (executable)
@@ -44,6 +44,8 @@ import jalview.util.jarInputStreamProvider;
 import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
 
 import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.UnknownHostException;
 import java.util.Hashtable;
 import java.util.Vector;
 import java.util.jar.JarEntry;
@@ -51,8 +53,6 @@ import java.util.jar.JarInputStream;
 
 import javax.swing.JOptionPane;
 
-import org.exolab.castor.xml.IDResolver;
-
 /**
  * DOCUMENT ME!
  * 
@@ -127,33 +127,29 @@ public class Jalview2XML_V1
           jarentry = jin.getNextJarEntry();
         }
 
-        class NoDescIDResolver implements IDResolver
-        {
-          public Object resolve(String idref)
-          {
-            System.out.println(idref + " used");
-            return null;
-          }
-        }
-
         if (jarentry != null)
         {
-          InputStreamReader in = new InputStreamReader(jin, "UTF-8");
-          JalviewModel object = new JalviewModel();
+          entryCount++;
+          if (jarentry.getName().endsWith(".xml"))
+          {
+            Reader in = new InputStreamReader(jin, "UTF-8");
+            JalviewModel object = new JalviewModel();
 
-          object = object.unmarshal(in);
+            object = object.unmarshal(in);
 
-          af = LoadFromObject(object, file);
-          entryCount++;
+            af = LoadFromObject(object, file);
+          }
         }
+        jin.close();
       } while (jarentry != null);
-    } catch (final java.net.UnknownHostException ex)
+    } catch (final UnknownHostException ex)
     {
       ex.printStackTrace();
       if (raiseGUI)
       {
         javax.swing.SwingUtilities.invokeLater(new Runnable()
         {
+          @Override
           public void run()
           {
 
@@ -176,6 +172,7 @@ public class Jalview2XML_V1
       {
         javax.swing.SwingUtilities.invokeLater(new Runnable()
         {
+          @Override
           public void run()
           {
 
index fee47e5..e86b2c5 100644 (file)
@@ -642,7 +642,7 @@ public class PopupMenu extends JPopupMenu
 
           // collect matching db-refs
           DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(
-                  seq.getDBRef(), new String[] { urlLink.getTarget() });
+                  seq.getDBRefs(), new String[] { urlLink.getTarget() });
           // collect id string too
           String id = seq.getName();
           String descr = seq.getDescription();
@@ -896,7 +896,7 @@ public class PopupMenu extends JPopupMenu
       {
         sqi = sqi.getDatasetSequence();
       }
-      DBRefEntry[] dbr = sqi.getDBRef();
+      DBRefEntry[] dbr = sqi.getDBRefs();
       if (dbr != null && dbr.length > 0)
       {
         for (int d = 0; d < dbr.length; d++)
@@ -2451,9 +2451,13 @@ public class PopupMenu extends JPopupMenu
       @Override
       public void run()
       {
+        boolean isNuclueotide = ap.alignFrame.getViewport().getAlignment()
+                .isNucleotide();
 
-        new jalview.ws.DBRefFetcher(sequences, ap.alignFrame)
+        new jalview.ws.DBRefFetcher(sequences, ap.alignFrame, null,
+                ap.alignFrame.featureSettings, isNuclueotide)
                 .fetchDBRefs(false);
+
       }
 
     });
index 5cb6512..c7e1332 100755 (executable)
@@ -30,6 +30,7 @@ import jalview.jbgui.GPreferences;
 import jalview.jbgui.GSequenceLink;
 import jalview.schemes.ColourSchemeProperty;
 import jalview.util.MessageManager;
+import jalview.ws.sifts.SiftsSettings;
 
 import java.awt.BorderLayout;
 import java.awt.Color;
@@ -313,6 +314,18 @@ public class Preferences extends GPreferences
       }
     });
 
+    if (Cache.getDefault("MAP_WITH_SIFTS", false))
+    {
+      siftsMapping.setSelected(true);
+    }
+    else
+    {
+      nwMapping.setSelected(true);
+    }
+
+    SiftsSettings
+            .setMapWithSifts(Cache.getDefault("MAP_WITH_SIFTS", false));
+
     /*
      * Set Connections tab defaults
      */
@@ -384,6 +397,7 @@ public class Preferences extends GPreferences
    * 
    * @param e
    */
+  @Override
   public void ok_actionPerformed(ActionEvent e)
   {
     if (!validateSettings())
@@ -492,6 +506,9 @@ public class Preferences extends GPreferences
     Cache.applicationProperties.setProperty(STRUCTURE_DISPLAY, structViewer
             .getSelectedItem().toString());
     Cache.setOrRemove(CHIMERA_PATH, chimeraPath.getText());
+    Cache.applicationProperties.setProperty("MAP_WITH_SIFTS",
+            Boolean.toString(siftsMapping.isSelected()));
+    SiftsSettings.setMapWithSifts(siftsMapping.isSelected());
 
     /*
      * Save Output settings
@@ -647,6 +664,7 @@ public class Preferences extends GPreferences
   /**
    * DOCUMENT ME!
    */
+  @Override
   public void startupFileTextfield_mouseClicked()
   {
     JalviewFileChooser chooser = new JalviewFileChooser(
@@ -676,6 +694,7 @@ public class Preferences extends GPreferences
    * @param e
    *          DOCUMENT ME!
    */
+  @Override
   public void cancel_actionPerformed(ActionEvent e)
   {
     try
@@ -694,6 +713,7 @@ public class Preferences extends GPreferences
    * @param e
    *          DOCUMENT ME!
    */
+  @Override
   public void annotations_actionPerformed(ActionEvent e)
   {
     conservation.setEnabled(annotations.isSelected());
@@ -707,6 +727,7 @@ public class Preferences extends GPreferences
             && (identity.isSelected() || showGroupConsensus.isSelected()));
   }
 
+  @Override
   public void newLink_actionPerformed(ActionEvent e)
   {
 
@@ -733,6 +754,7 @@ public class Preferences extends GPreferences
     }
   }
 
+  @Override
   public void editLink_actionPerformed(ActionEvent e)
   {
     GSequenceLink link = new GSequenceLink();
@@ -774,6 +796,7 @@ public class Preferences extends GPreferences
     }
   }
 
+  @Override
   public void deleteLink_actionPerformed(ActionEvent e)
   {
     int index = linkNameList.getSelectedIndex();
@@ -796,6 +819,7 @@ public class Preferences extends GPreferences
     linkURLList.setListData(urlLinks);
   }
 
+  @Override
   public void defaultBrowser_mouseClicked(MouseEvent e)
   {
     JFileChooser chooser = new JFileChooser(".");
@@ -818,6 +842,7 @@ public class Preferences extends GPreferences
    * jalview.jbgui.GPreferences#showunconserved_actionPerformed(java.awt.event
    * .ActionEvent)
    */
+  @Override
   protected void showunconserved_actionPerformed(ActionEvent e)
   {
     // TODO Auto-generated method stub
index 62cd3f1..b2c9a12 100755 (executable)
@@ -84,6 +84,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
    * @param evt
    *          DOCUMENT ME!
    */
+  @Override
   public void mousePressed(MouseEvent evt)
   {
     int x = (evt.getX() / av.getCharWidth()) + av.getStartRes();
@@ -108,109 +109,136 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
 
     if (SwingUtilities.isRightMouseButton(evt))
     {
-      JPopupMenu pop = new JPopupMenu();
-      if (reveal != null)
+      rightMouseButtonPressed(evt, res);
+    }
+    else
+    {
+      leftMouseButtonPressed(evt, res);
+    }
+  }
+
+  /**
+   * Handles right mouse button press. If pressed in a selected column, opens
+   * context menu for 'Hide Columns'. If pressed on a hidden columns marker,
+   * opens context menu for 'Reveal / Reveal All'. Else does nothing.
+   * 
+   * @param evt
+   * @param res
+   */
+  protected void rightMouseButtonPressed(MouseEvent evt, final int res)
+  {
+    JPopupMenu pop = new JPopupMenu();
+    if (reveal != null)
+    {
+      JMenuItem item = new JMenuItem(
+              MessageManager.getString("label.reveal"));
+      item.addActionListener(new ActionListener()
       {
-        JMenuItem item = new JMenuItem(
-                MessageManager.getString("label.reveal"));
-        item.addActionListener(new ActionListener()
+        @Override
+        public void actionPerformed(ActionEvent e)
         {
-          public void actionPerformed(ActionEvent e)
+          av.showColumn(reveal[0]);
+          reveal = null;
+          ap.paintAlignment(true);
+          if (ap.overviewPanel != null)
           {
-            av.showColumn(reveal[0]);
-            reveal = null;
-            ap.paintAlignment(true);
-            if (ap.overviewPanel != null)
-            {
-              ap.overviewPanel.updateOverviewImage();
-            }
+            ap.overviewPanel.updateOverviewImage();
           }
-        });
-        pop.add(item);
-
-        if (av.getColumnSelection().hasHiddenColumns())
-        {
-          item = new JMenuItem(
-                  MessageManager.getString("action.reveal_all"));
-          item.addActionListener(new ActionListener()
-          {
-            public void actionPerformed(ActionEvent e)
-            {
-              av.showAllHiddenColumns();
-              reveal = null;
-              ap.paintAlignment(true);
-              if (ap.overviewPanel != null)
-              {
-                ap.overviewPanel.updateOverviewImage();
-              }
-            }
-          });
-          pop.add(item);
+          av.sendSelection();
         }
-        pop.show(this, evt.getX(), evt.getY());
-      }
-      else if (av.getColumnSelection().contains(res))
+      });
+      pop.add(item);
+
+      if (av.getColumnSelection().hasHiddenColumns())
       {
-        JMenuItem item = new JMenuItem(
-                MessageManager.getString("label.hide_columns"));
+        item = new JMenuItem(MessageManager.getString("action.reveal_all"));
         item.addActionListener(new ActionListener()
         {
+          @Override
           public void actionPerformed(ActionEvent e)
           {
-            av.hideColumns(res, res);
-            if (av.getSelectionGroup() != null
-                    && av.getSelectionGroup().getSize() == av
-                            .getAlignment().getHeight())
-            {
-              av.setSelectionGroup(null);
-            }
-
+            av.showAllHiddenColumns();
+            reveal = null;
             ap.paintAlignment(true);
             if (ap.overviewPanel != null)
             {
               ap.overviewPanel.updateOverviewImage();
             }
+            av.sendSelection();
           }
         });
         pop.add(item);
-        pop.show(this, evt.getX(), evt.getY());
       }
+      pop.show(this, evt.getX(), evt.getY());
     }
-    else
-    // LEFT MOUSE TO SELECT
+    else if (av.getColumnSelection().contains(res))
     {
-      if (!evt.isControlDown() && !evt.isShiftDown())
+      JMenuItem item = new JMenuItem(
+              MessageManager.getString("label.hide_columns"));
+      item.addActionListener(new ActionListener()
       {
-        av.getColumnSelection().clear();
-      }
+        @Override
+        public void actionPerformed(ActionEvent e)
+        {
+          av.hideColumns(res, res);
+          if (av.getSelectionGroup() != null
+                  && av.getSelectionGroup().getSize() == av.getAlignment()
+                          .getHeight())
+          {
+            av.setSelectionGroup(null);
+          }
 
-      av.getColumnSelection().addElement(res);
-      SequenceGroup sg = new SequenceGroup();
-      // try to be as quick as possible
-      SequenceI[] iVec = av.getAlignment().getSequencesArray();
-      for (int i = 0; i < iVec.length; i++)
-      {
-        sg.addSequence(iVec[i], false);
-        iVec[i] = null;
-      }
-      iVec = null;
-      sg.setStartRes(res);
-      sg.setEndRes(res);
+          ap.paintAlignment(true);
+          if (ap.overviewPanel != null)
+          {
+            ap.overviewPanel.updateOverviewImage();
+          }
+          av.sendSelection();
+        }
+      });
+      pop.add(item);
+      pop.show(this, evt.getX(), evt.getY());
+    }
+  }
 
-      if (evt.isShiftDown())
+  /**
+   * Handles left mouse button press
+   * 
+   * @param evt
+   * @param res
+   */
+  protected void leftMouseButtonPressed(MouseEvent evt, final int res)
+  {
+    if (!evt.isControlDown() && !evt.isShiftDown())
+    {
+      av.getColumnSelection().clear();
+    }
+
+    av.getColumnSelection().addElement(res);
+    SequenceGroup sg = new SequenceGroup();
+    // try to be as quick as possible
+    SequenceI[] iVec = av.getAlignment().getSequencesArray();
+    for (int i = 0; i < iVec.length; i++)
+    {
+      sg.addSequence(iVec[i], false);
+      iVec[i] = null;
+    }
+    iVec = null;
+    sg.setStartRes(res);
+    sg.setEndRes(res);
+
+    if (evt.isShiftDown())
+    {
+      int min = Math.min(av.getColumnSelection().getMin(), res);
+      int max = Math.max(av.getColumnSelection().getMax(), res);
+      for (int i = min; i < max; i++)
       {
-        int min = Math.min(av.getColumnSelection().getMin(), res);
-        int max = Math.max(av.getColumnSelection().getMax(), res);
-        for (int i = min; i < max; i++)
-        {
-          av.getColumnSelection().addElement(i);
-        }
-        sg.setStartRes(min);
-        sg.setEndRes(max);
+        av.getColumnSelection().addElement(i);
       }
-      av.setSelectionGroup(sg);
+      sg.setStartRes(min);
+      sg.setEndRes(max);
     }
-
+    av.setSelectionGroup(sg);
     ap.paintAlignment(false);
     av.sendSelection();
   }
@@ -221,6 +249,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
    * @param evt
    *          DOCUMENT ME!
    */
+  @Override
   public void mouseReleased(MouseEvent evt)
   {
     mouseDragging = false;
@@ -268,6 +297,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
    * @param evt
    *          DOCUMENT ME!
    */
+  @Override
   public void mouseDragged(MouseEvent evt)
   {
     mouseDragging = true;
@@ -337,6 +367,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseEntered(MouseEvent evt)
   {
     if (mouseDragging)
@@ -345,6 +376,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseExited(MouseEvent evt)
   {
     if (mouseDragging)
@@ -353,10 +385,12 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
     }
   }
 
+  @Override
   public void mouseClicked(MouseEvent evt)
   {
   }
 
+  @Override
   public void mouseMoved(MouseEvent evt)
   {
     if (!av.hasHiddenColumns())
@@ -398,6 +432,7 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
    * @param g
    *          DOCUMENT ME!
    */
+  @Override
   public void paintComponent(Graphics g)
   {
     drawScale(g, av.getStartRes(), av.getEndRes(), getWidth(), getHeight());
@@ -430,9 +465,8 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
     {
       gg.setColor(new Color(220, 0, 0));
 
-      for (int i = 0; i < cs.size(); i++)
+      for (int sel : cs.getSelected())
       {
-        int sel = cs.columnAt(i);
         if (av.hasHiddenColumns())
         {
           if (cs.isVisible(sel))
index fe05e6e..cce2ee0 100644 (file)
@@ -801,6 +801,7 @@ public class SeqPanel extends JPanel implements MouseListener,
    * 
    * @see javax.swing.JComponent#getToolTipLocation(java.awt.event.MouseEvent)
    */
+  @Override
   public Point getToolTipLocation(MouseEvent event)
   {
     int x = event.getX(), w = getWidth();
@@ -1962,7 +1963,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       sgroup = seqsel.intersect(av.getAlignment(),
               (av.hasHiddenRows()) ? av.getHiddenRepSequences() : null);
       if ((sgroup == null || sgroup.getSize() == 0)
-              || (colsel == null || colsel.size() == 0))
+              || (colsel == null || colsel.isEmpty()))
       {
         // don't copy columns if the region didn't intersect.
         copycolsel = false;
@@ -1983,7 +1984,7 @@ public class SeqPanel extends JPanel implements MouseListener,
     {
       // the current selection is unset or from a previous message
       // so import the new colsel.
-      if (colsel == null || colsel.size() == 0)
+      if (colsel == null || colsel.isEmpty())
       {
         if (av.getColumnSelection() != null)
         {
index ad3fcc9..2004761 100755 (executable)
@@ -644,7 +644,7 @@ public class SequenceFetcher extends JPanel implements Runnable
                 {
                   if (rs[r] != null
                           && (found = DBRefUtils.searchRefs(
-                                  rs[r].getDBRef(), dbr)) != null
+                                  rs[r].getDBRefs(), dbr)) != null
                           && found.length > 0)
                   {
                     rfound = true;
index 63a8654..cf58322 100644 (file)
@@ -21,7 +21,9 @@
 
 package jalview.gui;
 
+import jalview.bin.Jalview;
 import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 import jalview.jbgui.GStructureChooser;
@@ -30,6 +32,7 @@ import jalview.structure.StructureSelectionManager;
 import jalview.util.MessageManager;
 import jalview.ws.dbsources.PDBRestClient;
 import jalview.ws.dbsources.PDBRestClient.PDBDocField;
+import jalview.ws.sifts.SiftsSettings;
 import jalview.ws.uimodel.PDBRestRequest;
 import jalview.ws.uimodel.PDBRestResponse;
 import jalview.ws.uimodel.PDBRestResponse.PDBResponseSummary;
@@ -54,7 +57,8 @@ import javax.swing.table.AbstractTableModel;
  *
  */
 @SuppressWarnings("serial")
-public class StructureChooser extends GStructureChooser
+public class StructureChooser extends GStructureChooser implements
+        IProgressIndicator
 {
   private boolean structuresDiscovered = false;
 
@@ -89,6 +93,11 @@ public class StructureChooser extends GStructureChooser
    */
   public void init()
   {
+    if (!Jalview.isHeadlessMode())
+    {
+      progressBar = new ProgressBar(this.statusPanel, this.statusBar);
+    }
+
     Thread discoverPDBStructuresThread = new Thread(new Runnable()
     {
       @Override
@@ -145,7 +154,7 @@ public class StructureChooser extends GStructureChooser
       PDBRestRequest pdbRequest = new PDBRestRequest();
       pdbRequest.setAllowEmptySeq(false);
       pdbRequest.setResponseSize(500);
-      pdbRequest.setFieldToSearchBy("(text:");
+      pdbRequest.setFieldToSearchBy("(");
       pdbRequest.setWantedFields(wantedFields);
       pdbRequest.setSearchTerm(buildQuery(seq) + ")");
       pdbRequest.setAssociatedSequence(seq);
@@ -233,18 +242,10 @@ public class StructureChooser extends GStructureChooser
 
   public static String buildQuery(SequenceI seq)
   {
+    boolean isPDBRefsFound = false;
+    boolean isUniProtRefsFound = false;
+    StringBuilder queryBuilder = new StringBuilder();
     HashSet<String> seqRefs = new LinkedHashSet<String>();
-    String seqName = seq.getName();
-    String[] names = seqName.toLowerCase().split("\\|");
-    for (String name : names)
-    {
-      // System.out.println("Found name : " + name);
-      name.trim();
-      if (isValidSeqName(name))
-      {
-        seqRefs.add(name);
-      }
-    }
 
     if (seq.getAllPDBEntries() != null)
     {
@@ -252,40 +253,77 @@ public class StructureChooser extends GStructureChooser
       {
         if (isValidSeqName(entry.getId()))
         {
-          seqRefs.add(entry.getId());
+          queryBuilder.append(PDBRestClient.PDBDocField.PDB_ID.getCode())
+                  .append(":")
+.append(entry.getId().toLowerCase())
+                  .append(" OR ");
+          isPDBRefsFound = true;
+          // seqRefs.add(entry.getId());
         }
       }
     }
 
-    if (seq.getDBRef() != null && seq.getDBRef().length != 0)
+    if (seq.getDBRefs() != null && seq.getDBRefs().length != 0)
     {
-      int count = 0;
-      for (DBRefEntry dbRef : seq.getDBRef())
+      for (DBRefEntry dbRef : seq.getDBRefs())
       {
         if (isValidSeqName(getDBRefId(dbRef)))
         {
-          seqRefs.add(getDBRefId(dbRef));
-        }
-        ++count;
-        if (count > 10)
-        {
-          break;
+          if (dbRef.getSource().equalsIgnoreCase(DBRefSource.UNIPROT))
+          {
+            queryBuilder
+                    .append(PDBRestClient.PDBDocField.UNIPROT_ACCESSION
+                            .getCode()).append(":")
+                    .append(getDBRefId(dbRef))
+                    .append(" OR ");
+            queryBuilder
+                    .append(PDBRestClient.PDBDocField.UNIPROT_ID.getCode())
+                    .append(":")
+                    .append(getDBRefId(dbRef)).append(" OR ");
+            isUniProtRefsFound = true;
+          }
+          else if (dbRef.getSource().equalsIgnoreCase(DBRefSource.PDB))
+          {
+
+            queryBuilder.append(PDBRestClient.PDBDocField.PDB_ID.getCode())
+                    .append(":").append(getDBRefId(dbRef).toLowerCase())
+                    .append(" OR ");
+            isPDBRefsFound = true;
+          }
+          else
+          {
+            seqRefs.add(getDBRefId(dbRef));
+          }
         }
       }
     }
 
-    StringBuilder queryBuilder = new StringBuilder();
-    for (String seqRef : seqRefs)
+    if (!isPDBRefsFound && !isUniProtRefsFound)
     {
-      queryBuilder.append("text:").append(seqRef).append(" OR ");
+      String seqName = seq.getName();
+      String[] names = seqName.toLowerCase().split("\\|");
+      for (String name : names)
+      {
+        // System.out.println("Found name : " + name);
+        name.trim();
+        if (isValidSeqName(name))
+        {
+          seqRefs.add(name);
+        }
+      }
+
+      for (String seqRef : seqRefs)
+      {
+        queryBuilder.append("text:").append(seqRef).append(" OR ");
+      }
     }
-    int endIndex = queryBuilder.lastIndexOf(" OR ");
 
+    int endIndex = queryBuilder.lastIndexOf(" OR ");
     if (queryBuilder.toString().length() < 6)
     {
       return null;
     }
-    String query = queryBuilder.toString().substring(5, endIndex);
+    String query = queryBuilder.toString().substring(0, endIndex);
     return query;
   }
 
@@ -349,7 +387,7 @@ public class StructureChooser extends GStructureChooser
           PDBRestRequest pdbRequest = new PDBRestRequest();
           pdbRequest.setAllowEmptySeq(false);
           pdbRequest.setResponseSize(1);
-          pdbRequest.setFieldToSearchBy("(text:");
+          pdbRequest.setFieldToSearchBy("(");
           pdbRequest.setFieldToSortBy(fieldToFilterBy,
                   !chk_invertFilter.isSelected());
           pdbRequest.setSearchTerm(buildQuery(seq) + ")");
@@ -420,6 +458,7 @@ public class StructureChooser extends GStructureChooser
   /**
    * Handles action event for btn_pdbFromFile
    */
+  @Override
   public void pdbFromFile_actionPerformed()
   {
     jalview.io.JalviewFileChooser chooser = new jalview.io.JalviewFileChooser(
@@ -445,6 +484,7 @@ public class StructureChooser extends GStructureChooser
    * Populates the filter combo-box options dynamically depending on discovered
    * structures
    */
+  @Override
   protected void populateFilterComboBox()
   {
     if (isStructuresDiscovered())
@@ -473,6 +513,7 @@ public class StructureChooser extends GStructureChooser
   /**
    * Updates the displayed view based on the selected filter option
    */
+  @Override
   protected void updateCurrentView()
   {
     FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
@@ -503,6 +544,7 @@ public class StructureChooser extends GStructureChooser
    * Validates user selection and activates the view button if all parameters
    * are correct
    */
+  @Override
   public void validateSelections()
   {
     FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
@@ -635,6 +677,15 @@ public class StructureChooser extends GStructureChooser
   @Override
   public void ok_ActionPerformed()
   {
+    final long progressSessionId = System.currentTimeMillis();
+    final StructureSelectionManager ssm = ap.getStructureSelectionManager();
+    ssm.setProgressIndicator(this);
+    ssm.setProgressSessionId(progressSessionId);
+    new Thread(new Runnable()
+    {
+      @Override
+      public void run()
+      {
     FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
             .getSelectedItem());
     String currentView = selectedFilterOpt.getView();
@@ -667,8 +718,7 @@ public class StructureChooser extends GStructureChooser
       }
       SequenceI[] selectedSeqs = selectedSeqsToView
               .toArray(new SequenceI[selectedSeqsToView.size()]);
-      launchStructureViewer(ap.getStructureSelectionManager(),
-              pdbEntriesToView, ap, selectedSeqs);
+          launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
     }
     else if (currentView == VIEWS_LOCAL_PDB)
     {
@@ -691,8 +741,7 @@ public class StructureChooser extends GStructureChooser
       }
       SequenceI[] selectedSeqs = selectedSeqsToView
               .toArray(new SequenceI[selectedSeqsToView.size()]);
-      launchStructureViewer(ap.getStructureSelectionManager(),
-              pdbEntriesToView, ap, selectedSeqs);
+          launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
     }
     else if (currentView == VIEWS_ENTER_ID)
     {
@@ -714,8 +763,8 @@ public class StructureChooser extends GStructureChooser
       }
 
       PDBEntry[] pdbEntriesToView = new PDBEntry[] { pdbEntry };
-      launchStructureViewer(ap.getStructureSelectionManager(),
-              pdbEntriesToView, ap, new SequenceI[] { selectedSequence });
+          launchStructureViewer(ssm, pdbEntriesToView, ap,
+                  new SequenceI[] { selectedSequence });
     }
     else if (currentView == VIEWS_FROM_FILE)
     {
@@ -730,22 +779,35 @@ public class StructureChooser extends GStructureChooser
                       jalview.io.AppletFormatAdapter.FILE,
                       selectedSequence, true, Desktop.instance);
 
-      launchStructureViewer(ap.getStructureSelectionManager(),
-              new PDBEntry[] { fileEntry }, ap,
-              new SequenceI[] { selectedSequence });
+          launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap,
+                  new SequenceI[] { selectedSequence });
     }
     mainFrame.dispose();
+      }
+    }).start();
   }
 
-  private void launchStructureViewer(final StructureSelectionManager ssm,
+  private void launchStructureViewer(StructureSelectionManager ssm,
           final PDBEntry[] pdbEntriesToView,
-          final AlignmentPanel alignPanel, final SequenceI[] sequences)
+          final AlignmentPanel alignPanel, SequenceI[] sequences)
   {
+    ssm.setProgressBar("Launching PDB structure viewer..");
     final StructureViewer sViewer = new StructureViewer(ssm);
-    new Thread(new Runnable()
+
+    if (SiftsSettings.isMapWithSifts())
     {
-      public void run()
+      for (SequenceI seq : sequences)
       {
+        if (seq.getSourceDBRef() == null)
+        {
+          ssm.setProgressBar(null);
+          ssm.setProgressBar("Fetching Database refs..");
+          new jalview.ws.DBRefFetcher(sequences, null, null, null, false)
+                  .fetchDBRefs(true);
+          break;
+        }
+      }
+    }
         if (pdbEntriesToView.length > 1)
         {
           ArrayList<SequenceI[]> seqsMap = new ArrayList<SequenceI[]>();
@@ -754,20 +816,24 @@ public class StructureChooser extends GStructureChooser
             seqsMap.add(new SequenceI[] { seq });
           }
           SequenceI[][] collatedSeqs = seqsMap.toArray(new SequenceI[0][0]);
+      ssm.setProgressBar(null);
+      ssm.setProgressBar("Fetching PDB Structures for selected entries..");
           sViewer.viewStructures(pdbEntriesToView, collatedSeqs, alignPanel);
         }
         else
         {
+      ssm.setProgressBar(null);
+      ssm.setProgressBar("Fetching PDB Structure for "
+              + pdbEntriesToView[0].getId());
           sViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel);
         }
-      }
-    }).start();
   }
 
   /**
    * Populates the combo-box used in associating manually fetched structures to
    * a unique sequence when more than one sequence selection is made.
    */
+  @Override
   public void populateCmbAssociateSeqOptions(
           JComboBox<AssociateSeqOptions> cmb_assSeq, JLabel lbl_associateSeq)
   {
@@ -812,6 +878,7 @@ public class StructureChooser extends GStructureChooser
   {
     new Thread()
     {
+      @Override
       public void run()
       {
         errorWarning.setLength(0);
@@ -968,4 +1035,24 @@ public class StructureChooser extends GStructureChooser
     }
 
   }
+
+  private IProgressIndicator progressBar;
+
+  @Override
+  public void setProgressBar(String message, long id)
+  {
+    progressBar.setProgressBar(message, id);
+  }
+
+  @Override
+  public void registerHandler(long id, IProgressIndicatorHandler handler)
+  {
+    progressBar.registerHandler(id, handler);
+  }
+
+  @Override
+  public boolean operationInProgress()
+  {
+    return progressBar.operationInProgress();
+  }
 }
index d2c86c8..9522144 100755 (executable)
@@ -840,7 +840,7 @@ public class TreePanel extends GTreePanel
           {
             // search dbrefs, features and annotation
             DBRefEntry[] refs = jalview.util.DBRefUtils.selectRefs(
-                    sq.getDBRef(),
+                    sq.getDBRefs(),
                     new String[] { labelClass.toUpperCase() });
             if (refs != null)
             {
index a9295a3..f7a45de 100755 (executable)
@@ -47,11 +47,13 @@ public class ClustalFile extends AlignFile
     super(source);
   }
 
+  @Override
   public void initData()
   {
     super.initData();
   }
 
+  @Override
   public void parse() throws IOException
   {
     int i = 0;
@@ -193,6 +195,7 @@ public class ClustalFile extends AlignFile
     }
   }
 
+  @Override
   public String print()
   {
     return print(getSeqsAsArray());
@@ -233,7 +236,7 @@ public class ClustalFile extends AlignFile
     maxid++;
 
     int len = 60;
-    int nochunks = (max / len) + 1;
+    int nochunks = (max / len) + (max % len > 0 ? 1 : 0);
 
     for (i = 0; i < nochunks; i++)
     {
index b867ba4..4c2265c 100755 (executable)
@@ -77,6 +77,7 @@ public class FastaFile extends AlignFile
    * @throws IOException
    *           DOCUMENT ME!
    */
+  @Override
   public void parse() throws IOException
   {
     StringBuffer sb = new StringBuffer();
@@ -173,7 +174,7 @@ public class FastaFile extends AlignFile
     addProperties(al);
     for (int i = 0; i < annotations.size(); i++)
     {
-      AlignmentAnnotation aa = (AlignmentAnnotation) annotations
+      AlignmentAnnotation aa = annotations
               .elementAt(i);
       aa.setPadGaps(true, al.getGapCharacter());
       al.addAnnotation(aa);
@@ -209,7 +210,8 @@ public class FastaFile extends AlignFile
 
       out.append(newline);
 
-      int nochunks = (s[i].getLength() / len) + 1;
+      int nochunks = (s[i].getLength() / len)
+              + (s[i].getLength() % len > 0 ? 1 : 0);
 
       for (int j = 0; j < nochunks; j++)
       {
@@ -238,6 +240,7 @@ public class FastaFile extends AlignFile
    * 
    * @return DOCUMENT ME!
    */
+  @Override
   public String print()
   {
     return print(getSeqsAsArray());
index 3de5b30..f62ad81 100755 (executable)
@@ -69,6 +69,7 @@ public class MSFfile extends AlignFile
   /**
    * DOCUMENT ME!
    */
+  @Override
   public void parse() throws IOException
   {
     int i = 0;
@@ -343,12 +344,7 @@ public class MSFfile extends AlignFile
     out.append(newline);
     int len = 50;
 
-    int nochunks = (max / len) + 1;
-
-    if ((max % len) == 0)
-    {
-      nochunks--;
-    }
+    int nochunks = (max / len) + (max % len > 0 ? 1 : 0);
 
     for (i = 0; i < nochunks; i++)
     {
@@ -410,6 +406,7 @@ public class MSFfile extends AlignFile
    * 
    * @return DOCUMENT ME!
    */
+  @Override
   public String print()
   {
     return print(getSeqsAsArray());
index 55324ad..1ab9545 100755 (executable)
@@ -268,10 +268,10 @@ public class ModellerDescription
       // sets the local reference field
       int t = 0; // sequence
       if (seq.getDatasetSequence() != null
-              && seq.getDatasetSequence().getDBRef() != null)
+              && seq.getDatasetSequence().getDBRefs() != null)
       {
         jalview.datamodel.DBRefEntry[] dbr = seq.getDatasetSequence()
-                .getDBRef();
+                .getDBRefs();
         int i, j;
         for (i = 0, j = dbr.length; i < j; i++)
         {
index cd3c7a0..5f5c23c 100755 (executable)
@@ -46,6 +46,7 @@ public class PIRFile extends AlignFile
     super(source);
   }
 
+  @Override
   public void parse() throws IOException
   {
     StringBuffer sequence;
@@ -100,6 +101,7 @@ public class PIRFile extends AlignFile
     }
   }
 
+  @Override
   public String print()
   {
     return print(getSeqsAsArray());
@@ -174,7 +176,8 @@ public class PIRFile extends AlignFile
           }
         }
       }
-      int nochunks = (seq.length() / len) + 1;
+      int nochunks = (seq.length() / len)
+              + (seq.length() % len > 0 ? 1 : 0);
 
       for (int j = 0; j < nochunks; j++)
       {
index 07ba3f5..71cc7f0 100755 (executable)
@@ -26,9 +26,8 @@ import jalview.util.Format;
 import jalview.util.MessageManager;
 
 import java.io.IOException;
-import java.util.Hashtable;
-import java.util.StringTokenizer;
-import java.util.Vector;
+import java.util.ArrayList;
+import java.util.HashMap;
 
 public class PfamFile extends AlignFile
 {
@@ -47,57 +46,70 @@ public class PfamFile extends AlignFile
     super(source);
   }
 
+  @Override
   public void initData()
   {
     super.initData();
   }
 
+  @Override
   public void parse() throws IOException
   {
     int i = 0;
     String line;
 
-    Hashtable seqhash = new Hashtable();
-    Vector headers = new Vector();
-
+    HashMap<String, StringBuffer> seqhash = new HashMap<String, StringBuffer>();
+    ArrayList<String> headers = new ArrayList<String>();
+    boolean useTabs = false;
+    int spces;
     while ((line = nextLine()) != null)
     {
-      if (line.indexOf(" ") != 0)
+      if (line.indexOf("#") == 0)
+      {
+        // skip comment lines
+        continue;
+      }
+      // locate first space or (if already checked), tab
+      if (useTabs)
+      {
+        spces = line.indexOf("\t");
+      }
+      else
       {
-        if (line.indexOf("#") != 0)
+        spces = line.indexOf(" ");
+        // check to see if we ought to split on tabs instead.
+        if (!useTabs && spces == -1)
         {
-          // TODO: verify pfam format requires spaces and not tab characters -
-          // if not upgrade to use stevesoft regex and look for whitespace.
-          StringTokenizer str = new StringTokenizer(line, " ");
-          String id = "";
-
-          if (str.hasMoreTokens())
-          {
-            id = str.nextToken();
-
-            StringBuffer tempseq;
-
-            if (seqhash.containsKey(id))
-            {
-              tempseq = (StringBuffer) seqhash.get(id);
-            }
-            else
-            {
-              tempseq = new StringBuffer();
-              seqhash.put(id, tempseq);
-            }
-
-            if (!(headers.contains(id)))
-            {
-              headers.addElement(id);
-            }
-            if (str.hasMoreTokens())
-            {
-              tempseq.append(str.nextToken());
-            }
-          }
+          useTabs = true;
+          spces = line.indexOf("\t");
         }
       }
+      if (spces <= 0)
+      {
+        // no sequence data to split on
+        continue;
+      }
+      String id = line.substring(0, spces);
+      StringBuffer tempseq;
+
+      if (seqhash.containsKey(id))
+      {
+        tempseq = seqhash.get(id);
+      }
+      else
+      {
+        tempseq = new StringBuffer();
+        seqhash.put(id, tempseq);
+      }
+
+      if (!(headers.contains(id)))
+      {
+        headers.add(id);
+      }
+      if (spces + 1 < line.length())
+      {
+        tempseq.append(line.substring(spces + 1));
+      }
     }
 
     this.noSeqs = headers.size();
@@ -110,23 +122,23 @@ public class PfamFile extends AlignFile
 
     for (i = 0; i < headers.size(); i++)
     {
-      if (seqhash.get(headers.elementAt(i)) != null)
+      if (seqhash.get(headers.get(i)) != null)
       {
-        if (maxLength < seqhash.get(headers.elementAt(i)).toString()
+        if (maxLength < seqhash.get(headers.get(i)).toString()
                 .length())
         {
-          maxLength = seqhash.get(headers.elementAt(i)).toString().length();
+          maxLength = seqhash.get(headers.get(i)).toString().length();
         }
 
-        Sequence newSeq = parseId(headers.elementAt(i).toString());
-        newSeq.setSequence(seqhash.get(headers.elementAt(i).toString())
+        Sequence newSeq = parseId(headers.get(i).toString());
+        newSeq.setSequence(seqhash.get(headers.get(i).toString())
                 .toString());
         seqs.addElement(newSeq);
       }
       else
       {
         System.err.println("PFAM File reader: Can't find sequence for "
-                + headers.elementAt(i));
+                + headers.get(i));
       }
     }
   }
@@ -178,6 +190,7 @@ public class PfamFile extends AlignFile
     return out.toString();
   }
 
+  @Override
   public String print()
   {
     return print(getSeqsAsArray());
index 9570552..79c6531 100755 (executable)
@@ -76,11 +76,13 @@ public class PileUpfile extends MSFfile
    * 
    * @return DOCUMENT ME!
    */
+  @Override
   public String print()
   {
     return print(getSeqsAsArray());
   }
 
+  @Override
   public String print(SequenceI[] s)
   {
     StringBuffer out = new StringBuffer("PileUp");
@@ -141,12 +143,7 @@ public class PileUpfile extends MSFfile
 
     int len = 50;
 
-    int nochunks = (max / len) + 1;
-
-    if ((max % len) == 0)
-    {
-      nochunks--;
-    }
+    int nochunks = (max / len) + (max % len > 0 ? 1 : 0);
 
     for (i = 0; i < nochunks; i++)
     {
index 72f8044..d3a1d09 100644 (file)
@@ -230,7 +230,7 @@ public class SequenceAnnotationReport
     {
 
       // collect matching db-refs
-      DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(seq.getDBRef(),
+      DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(seq.getDBRefs(),
               new String[] { target });
       // collect id string too
       String id = seq.getName();
@@ -346,7 +346,7 @@ public class SequenceAnnotationReport
     {
       ds = ds.getDatasetSequence();
     }
-    DBRefEntry[] dbrefs = ds.getDBRef();
+    DBRefEntry[] dbrefs = ds.getDBRefs();
     if (showDbRefs && dbrefs != null)
     {
       for (int i = 0; i < dbrefs.length; i++)
index 9135b92..23c4d21 100644 (file)
@@ -900,18 +900,18 @@ public class StockholmFile extends AlignFile
       {
         maxid = tmp.length();
       }
-      if (s[in].getDBRef() != null)
+      if (s[in].getDBRefs() != null)
       {
-        for (int idb = 0; idb < s[in].getDBRef().length; idb++)
+        for (int idb = 0; idb < s[in].getDBRefs().length; idb++)
         {
           if (dataRef == null)
           {
             dataRef = new Hashtable();
           }
 
-          String datAs1 = s[in].getDBRef()[idb].getSource().toString()
+          String datAs1 = s[in].getDBRefs()[idb].getSource().toString()
                   + " ; "
-                  + s[in].getDBRef()[idb].getAccessionId().toString();
+                  + s[in].getDBRefs()[idb].getAccessionId().toString();
           dataRef.put(tmp, datAs1);
         }
       }
index a6c1111..9d9b940 100755 (executable)
@@ -176,7 +176,7 @@ public class WSWUBlastClient
           }
         }
 
-        DBRefEntry[] entries = oldseq.getDBRef();
+        DBRefEntry[] entries = oldseq.getDBRefs();
         if (entries != null)
         {
           oldseq.addDBRef(new jalview.datamodel.DBRefEntry(
index f1b9f1a..9db7a8e 100644 (file)
@@ -175,10 +175,10 @@ public class Datasetsequence extends DatastoreItem
     boolean modifiedthedoc = false;
     SequenceI sq = (SequenceI) jvobj;
 
-    if (sq.getDatasetSequence() == null && sq.getDBRef() != null)
+    if (sq.getDatasetSequence() == null && sq.getDBRefs() != null)
     {
       // only sync database references for dataset sequences
-      DBRefEntry[] entries = sq.getDBRef();
+      DBRefEntry[] entries = sq.getDBRefs();
       // jalview.datamodel.DBRefEntry dbentry;
       for (int db = 0; db < entries.length; db++)
       {
index 31ccc48..160f5e2 100644 (file)
@@ -386,7 +386,7 @@ public class Sequencemapping extends Rangetype
   private void matchConjugateDBRefs(SequenceI from, SequenceI to,
           jalview.util.MapList smap)
   {
-    if (from.getDBRef() == null && to.getDBRef() == null)
+    if (from.getDBRefs() == null && to.getDBRefs() == null)
     {
       if (jalview.bin.Cache.log.isDebugEnabled())
       {
@@ -400,11 +400,11 @@ public class Sequencemapping extends Rangetype
       jalview.bin.Cache.log.debug("Matching conjugate refs for "
               + from.getName() + " and " + to.getName());
     }
-    jalview.datamodel.DBRefEntry[] fdb = from.getDBRef();
+    jalview.datamodel.DBRefEntry[] fdb = from.getDBRefs();
     jalview.datamodel.DBRefEntry[] tdb = new jalview.datamodel.DBRefEntry[to
-            .getDBRef().length];
-    int tdblen = to.getDBRef().length;
-    System.arraycopy(to.getDBRef(), 0, tdb, 0, tdblen);
+            .getDBRefs().length];
+    int tdblen = to.getDBRefs().length;
+    System.arraycopy(to.getDBRefs(), 0, tdb, 0, tdblen);
     Vector matched = new Vector();
     jalview.util.MapList smapI = smap.getInverse();
     for (int f = 0; f < fdb.length; f++)
index 60cff9a..dc08b59 100644 (file)
@@ -50,7 +50,6 @@ public class JsSelectionSender extends JSFunctionExec implements
     try
     {
       String setid = "";
-      String viewid = "";
       AlignFrame src = _af;
       if (source != null)
       {
@@ -82,19 +81,16 @@ public class JsSelectionSender extends JSFunctionExec implements
           end = seqsel.getEndRes();
         }
       }
-      if (colsel != null && colsel.size() > 0)
+      if (colsel != null && !colsel.isEmpty())
       {
         if (end == -1)
         {
           end = colsel.getMax() + 1;
         }
         cols = new String[colsel.getSelected().size()];
-        int d = 0, r = -1;
         for (int i = 0; i < cols.length; i++)
         {
-          cols[i] = ""
-                  + (1 + ((Integer) colsel.getSelected().elementAt(i))
-                          .intValue());
+          cols[i] = "" + (1 + colsel.getSelected().get(i).intValue());
         }
       }
       else
index b12355a..b5c1804 100755 (executable)
@@ -44,6 +44,7 @@ import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 
 import javax.swing.BorderFactory;
+import javax.swing.ButtonGroup;
 import javax.swing.DefaultListCellRenderer;
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
@@ -52,6 +53,7 @@ import javax.swing.JFileChooser;
 import javax.swing.JLabel;
 import javax.swing.JList;
 import javax.swing.JPanel;
+import javax.swing.JRadioButton;
 import javax.swing.JScrollPane;
 import javax.swing.JTabbedPane;
 import javax.swing.JTextField;
@@ -156,6 +158,12 @@ public class GPreferences extends JPanel
 
   protected JTextField chimeraPath = new JTextField();
 
+  protected ButtonGroup mappingMethod = new ButtonGroup();
+
+  protected JRadioButton siftsMapping = new JRadioButton();
+
+  protected JRadioButton nwMapping = new JRadioButton();
+
   /*
    * Colours tab components
    */
@@ -509,6 +517,7 @@ public class GPreferences extends JPanel
     newLink.setText(MessageManager.getString("action.new"));
     newLink.addActionListener(new java.awt.event.ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         newLink_actionPerformed(e);
@@ -518,6 +527,7 @@ public class GPreferences extends JPanel
     editLink.setText(MessageManager.getString("action.edit"));
     editLink.addActionListener(new java.awt.event.ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         editLink_actionPerformed(e);
@@ -527,6 +537,7 @@ public class GPreferences extends JPanel
     deleteLink.setText(MessageManager.getString("action.delete"));
     deleteLink.addActionListener(new java.awt.event.ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         deleteLink_actionPerformed(e);
@@ -535,6 +546,7 @@ public class GPreferences extends JPanel
 
     linkURLList.addListSelectionListener(new ListSelectionListener()
     {
+      @Override
       public void valueChanged(ListSelectionEvent e)
       {
         int index = linkURLList.getSelectedIndex();
@@ -544,6 +556,7 @@ public class GPreferences extends JPanel
 
     linkNameList.addListSelectionListener(new ListSelectionListener()
     {
+      @Override
       public void valueChanged(ListSelectionEvent e)
       {
         int index = linkNameList.getSelectedIndex();
@@ -571,6 +584,7 @@ public class GPreferences extends JPanel
 
     defaultBrowser.addMouseListener(new MouseAdapter()
     {
+      @Override
       public void mouseClicked(MouseEvent e)
       {
         if (e.getClickCount() > 1)
@@ -585,6 +599,7 @@ public class GPreferences extends JPanel
     useProxy.setText(MessageManager.getString("label.use_proxy_server"));
     useProxy.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         useProxy_actionPerformed();
@@ -653,6 +668,7 @@ public class GPreferences extends JPanel
     ok.setText(MessageManager.getString("action.ok"));
     ok.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         ok_actionPerformed(e);
@@ -662,6 +678,7 @@ public class GPreferences extends JPanel
     cancel.setText(MessageManager.getString("action.cancel"));
     cancel.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         cancel_actionPerformed(e);
@@ -693,6 +710,7 @@ public class GPreferences extends JPanel
     minColour.setPreferredSize(new Dimension(40, 20));
     minColour.addMouseListener(new MouseAdapter()
     {
+      @Override
       public void mousePressed(MouseEvent e)
       {
         minColour_actionPerformed(minColour);
@@ -707,6 +725,7 @@ public class GPreferences extends JPanel
     maxColour.setPreferredSize(new Dimension(40, 20));
     maxColour.addMouseListener(new MouseAdapter()
     {
+      @Override
       public void mousePressed(MouseEvent e)
       {
         maxColour_actionPerformed(maxColour);
@@ -764,7 +783,7 @@ public class GPreferences extends JPanel
     final int width = 400;
     final int height = 22;
     final int lineSpacing = 25;
-    int ypos = 30;
+    int ypos = 15;
 
     structFromPdb.setFont(LABEL_FONT);
     structFromPdb
@@ -859,13 +878,30 @@ public class GPreferences extends JPanel
     structureTab.add(chimeraPath);
 
     ypos += lineSpacing;
-    // scrl_pdbDocFieldConfig.setPreferredSize(new Dimension(450, 100));
-    // scrl_pdbDocFieldConfig
-    // .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
-    // scrl_pdbDocFieldConfig.setBounds();
+    nwMapping.setFont(LABEL_FONT);
+    nwMapping.setText(MessageManager.getString("label.nw_mapping"));
+    siftsMapping.setFont(LABEL_FONT);
+    siftsMapping.setText(MessageManager.getString("label.sifts_mapping"));
+    mappingMethod.add(nwMapping);
+    mappingMethod.add(siftsMapping);
+    JPanel mappingPanel = new JPanel();
+    mappingPanel.setFont(LABEL_FONT);
+    TitledBorder mmTitledBorder = new TitledBorder(
+            MessageManager.getString("label.mapping_method"));
+    mmTitledBorder.setTitleFont(LABEL_FONT);
+    mappingPanel.setBorder(mmTitledBorder);
+    mappingPanel.setBounds(new Rectangle(10, ypos, 452, 45));
+    // GridLayout mappingLayout = new GridLayout();
+    mappingPanel.setLayout(new GridLayout());
+    mappingPanel.add(nwMapping);
+    mappingPanel.add(siftsMapping);
+    structureTab.add(mappingPanel);
+
+    ypos += lineSpacing;
+    ypos += lineSpacing;
     PDBDocFieldPreferences docFieldPref = new PDBDocFieldPreferences(
             PreferenceSource.PREFERENCES);
-    docFieldPref.setBounds(new Rectangle(10, ypos + 5, 450, 120));
+    docFieldPref.setBounds(new Rectangle(10, ypos, 450, 120));
     structureTab.add(docFieldPref);
 
     return structureTab;
@@ -1018,6 +1054,7 @@ public class GPreferences extends JPanel
     annotations.setBounds(new Rectangle(169, 12, 200, 23));
     annotations.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         annotations_actionPerformed(e);
@@ -1025,6 +1062,7 @@ public class GPreferences extends JPanel
     });
     identity.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         annotations_actionPerformed(e);
@@ -1032,6 +1070,7 @@ public class GPreferences extends JPanel
     });
     showGroupConsensus.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         annotations_actionPerformed(e);
@@ -1045,6 +1084,7 @@ public class GPreferences extends JPanel
             .getString("action.show_unconserved"));
     showUnconserved.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         showunconserved_actionPerformed(e);
@@ -1112,6 +1152,7 @@ public class GPreferences extends JPanel
     startupFileTextfield.setBounds(new Rectangle(172, 310, 330, 20));
     startupFileTextfield.addMouseListener(new MouseAdapter()
     {
+      @Override
       public void mouseClicked(MouseEvent e)
       {
         if (e.getClickCount() > 1)
index 67b3a20..d8cff06 100644 (file)
@@ -34,6 +34,7 @@ import java.awt.BorderLayout;
 import java.awt.CardLayout;
 import java.awt.Dimension;
 import java.awt.FlowLayout;
+import java.awt.GridLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
@@ -69,6 +70,12 @@ import javax.swing.event.DocumentListener;
 public abstract class GStructureChooser extends JPanel implements
         ItemListener
 {
+  protected JPanel statusPanel = new JPanel();
+
+  public JLabel statusBar = new JLabel();
+
+  private JPanel pnl_actionsAndStatus = new JPanel(new BorderLayout());
+
   protected String frameTitle = MessageManager
           .getString("label.structure_chooser");
 
@@ -152,6 +159,7 @@ public abstract class GStructureChooser extends JPanel implements
 
   protected JTable tbl_summary = new JTable()
   {
+    @Override
     public String getToolTipText(MouseEvent evt)
     {
       String toolTipText = null;
@@ -213,11 +221,13 @@ public abstract class GStructureChooser extends JPanel implements
     tbl_summary.getTableHeader().setReorderingAllowed(false);
     tbl_summary.addMouseListener(new MouseAdapter()
     {
+      @Override
       public void mouseClicked(MouseEvent e)
       {
         validateSelections();
       }
 
+      @Override
       public void mouseReleased(MouseEvent e)
       {
         validateSelections();
@@ -260,11 +270,13 @@ public abstract class GStructureChooser extends JPanel implements
     tbl_local_pdb.getTableHeader().setReorderingAllowed(false);
     tbl_local_pdb.addMouseListener(new MouseAdapter()
     {
+      @Override
       public void mouseClicked(MouseEvent e)
       {
         validateSelections();
       }
 
+      @Override
       public void mouseReleased(MouseEvent e)
       {
         validateSelections();
@@ -313,6 +325,7 @@ public abstract class GStructureChooser extends JPanel implements
     btn_view.setText(MessageManager.getString("action.view"));
     btn_view.addActionListener(new java.awt.event.ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         ok_ActionPerformed();
@@ -334,6 +347,7 @@ public abstract class GStructureChooser extends JPanel implements
     btn_cancel.setText(MessageManager.getString("action.cancel"));
     btn_cancel.addActionListener(new java.awt.event.ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         mainFrame.dispose();
@@ -356,6 +370,7 @@ public abstract class GStructureChooser extends JPanel implements
     btn_pdbFromFile.setText(btn_title + "              ");
     btn_pdbFromFile.addActionListener(new java.awt.event.ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         pdbFromFile_actionPerformed();
@@ -440,6 +455,7 @@ public abstract class GStructureChooser extends JPanel implements
             .getString("label.configure_displayed_columns");
     ChangeListener changeListener = new ChangeListener()
     {
+      @Override
       public void stateChanged(ChangeEvent changeEvent)
       {
         JTabbedPane sourceTabbedPane = (JTabbedPane) changeEvent
@@ -483,7 +499,12 @@ public abstract class GStructureChooser extends JPanel implements
     this.setLayout(mainLayout);
     this.add(pnl_main, java.awt.BorderLayout.NORTH);
     this.add(pnl_switchableViews, java.awt.BorderLayout.CENTER);
-    this.add(pnl_actions, java.awt.BorderLayout.SOUTH);
+    // this.add(pnl_actions, java.awt.BorderLayout.SOUTH);
+    statusPanel.setLayout(new GridLayout());
+    pnl_actionsAndStatus.add(pnl_actions, BorderLayout.CENTER);
+    pnl_actionsAndStatus.add(statusPanel, BorderLayout.SOUTH);
+    statusPanel.add(statusBar, null);
+    this.add(pnl_actionsAndStatus, java.awt.BorderLayout.SOUTH);
 
     mainFrame.setVisible(true);
     mainFrame.setContentPane(this);
@@ -564,6 +585,7 @@ public abstract class GStructureChooser extends JPanel implements
       this.view = view;
     }
 
+    @Override
     public String toString()
     {
       return this.name;
@@ -596,6 +618,7 @@ public abstract class GStructureChooser extends JPanel implements
       this.sequence = seq;
     }
 
+    @Override
     public String toString()
     {
       return name;
index e5c2218..007df3e 100644 (file)
@@ -598,10 +598,8 @@ public class AnnotationRenderer
 
               if (columnSelection != null)
               {
-                for (int n = 0; n < columnSelection.size(); n++)
+                for (int v : columnSelection.getSelected())
                 {
-                  int v = columnSelection.columnAt(n);
-
                   if (v == column)
                   {
                     g.fillRect(x * charWidth, y, charWidth, charHeight);
index a62f1ae..3fcb5e9 100644 (file)
@@ -23,6 +23,8 @@ package jalview.structure;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.SequenceI;
 
+import java.util.HashMap;
+
 public class StructureMapping
 {
   String mappingDetails;
@@ -35,11 +37,19 @@ public class StructureMapping
 
   String pdbchain;
 
-  // Mapping index 0 is resNum, index 1 is atomNo
-  int[][] mapping;
+  public static final int UNASSIGNED_VALUE = -1;
+
+  private static final int PDB_RES_NUM_INDEX = 0;
+
+  private static final int PDB_ATOM_NUM_INDEX = 1;
+
+  // Mapping key is residue index while value is an array containing PDB resNum,
+  // and atomNo
+  HashMap<Integer, int[]> mapping;
 
   public StructureMapping(SequenceI seq, String pdbfile, String pdbid,
-          String chain, int[][] mapping, String mappingDetails)
+          String chain, HashMap<Integer, int[]> mapping,
+          String mappingDetails)
   {
     sequence = seq;
     this.pdbfile = pdbfile;
@@ -71,13 +81,14 @@ public class StructureMapping
    */
   public int getAtomNum(int seqpos)
   {
-    if (mapping.length > seqpos)
+    int[] resNumAtomMap = mapping.get(seqpos);
+    if (resNumAtomMap != null)
     {
-      return mapping[seqpos][1];
+      return resNumAtomMap[PDB_ATOM_NUM_INDEX];
     }
     else
     {
-      return 0;
+      return UNASSIGNED_VALUE;
     }
   }
 
@@ -88,13 +99,14 @@ public class StructureMapping
    */
   public int getPDBResNum(int seqpos)
   {
-    if (mapping.length > seqpos)
+    int[] resNumAtomMap = mapping.get(seqpos);
+    if (resNumAtomMap != null)
     {
-      return mapping[seqpos][0];
+      return resNumAtomMap[PDB_RES_NUM_INDEX];
     }
     else
     {
-      return 0;
+      return UNASSIGNED_VALUE;
     }
   }
 
@@ -105,14 +117,14 @@ public class StructureMapping
    */
   public int getSeqPos(int pdbResNum)
   {
-    for (int i = 0; i < mapping.length; i++)
+    for (Integer seqPos : mapping.keySet())
     {
-      if (mapping[i][0] == pdbResNum)
+      if (pdbResNum == getPDBResNum(seqPos))
       {
-        return i;
+        return seqPos;
       }
     }
-    return -1;
+    return UNASSIGNED_VALUE;
   }
 
   /**
index b497824..871f076 100644 (file)
@@ -32,9 +32,13 @@ import jalview.datamodel.Annotation;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SearchResults;
 import jalview.datamodel.SequenceI;
+import jalview.gui.IProgressIndicator;
 import jalview.io.AppletFormatAdapter;
 import jalview.util.MappingUtils;
 import jalview.util.MessageManager;
+import jalview.ws.sifts.SiftsClient;
+import jalview.ws.sifts.SiftsException;
+import jalview.ws.sifts.SiftsSettings;
 
 import java.io.PrintStream;
 import java.util.ArrayList;
@@ -65,6 +69,10 @@ public class StructureSelectionManager
 
   private boolean addTempFacAnnot = false;
 
+  private IProgressIndicator progressIndicator;
+
+  private long progressSessionId;
+
   /*
    * Set of any registered mappings between (dataset) sequences.
    */
@@ -322,9 +330,9 @@ public class StructureSelectionManager
    * @param forStructureView
    *          when true, record the mapping for use in mouseOvers
    * 
-   * @param sequence
+   * @param sequenceArray
    *          - one or more sequences to be mapped to pdbFile
-   * @param targetChains
+   * @param targetChainIds
    *          - optional chain specification for mapping each sequence to pdb
    *          (may be nill, individual elements may be nill)
    * @param pdbFile
@@ -334,7 +342,8 @@ public class StructureSelectionManager
    * @return null or the structure data parsed as a pdb file
    */
   synchronized public PDBfile setMapping(boolean forStructureView,
-          SequenceI[] sequence, String[] targetChains, String pdbFile,
+          SequenceI[] sequenceArray, String[] targetChainIds,
+          String pdbFile,
           String protocol)
   {
     /*
@@ -344,7 +353,7 @@ public class StructureSelectionManager
     boolean parseSecStr = processSecondaryStructure;
     if (isPDBFileRegistered(pdbFile))
     {
-      for (SequenceI sq : sequence)
+      for (SequenceI sq : sequenceArray)
       {
         SequenceI ds = sq;
         while (ds.getDatasetSequence() != null)
@@ -368,10 +377,13 @@ public class StructureSelectionManager
       }
     }
     PDBfile pdb = null;
+    boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts();
+    SiftsClient siftsClient = null;
     try
     {
       pdb = new PDBfile(addTempFacAnnot, parseSecStr, secStructServices,
               pdbFile, protocol);
+
       if (pdb.id != null && pdb.id.trim().length() > 0
               && AppletFormatAdapter.FILE.equals(protocol))
       {
@@ -383,36 +395,48 @@ public class StructureSelectionManager
       return null;
     }
 
-    String targetChain;
-    for (int s = 0; s < sequence.length; s++)
+    try
+    {
+      if (isMapUsingSIFTs)
+      {
+        siftsClient = new SiftsClient(pdb);
+      }
+    } catch (SiftsException e)
+    {
+      isMapUsingSIFTs = false;
+      e.printStackTrace();
+    }
+
+    String targetChainId;
+    for (int s = 0; s < sequenceArray.length; s++)
     {
       boolean infChain = true;
-      final SequenceI seq = sequence[s];
-      if (targetChains != null && targetChains[s] != null)
+      final SequenceI seq = sequenceArray[s];
+      if (targetChainIds != null && targetChainIds[s] != null)
       {
         infChain = false;
-        targetChain = targetChains[s];
+        targetChainId = targetChainIds[s];
       }
       else if (seq.getName().indexOf("|") > -1)
       {
-        targetChain = seq.getName().substring(
+        targetChainId = seq.getName().substring(
                 seq.getName().lastIndexOf("|") + 1);
-        if (targetChain.length() > 1)
+        if (targetChainId.length() > 1)
         {
-          if (targetChain.trim().length() == 0)
+          if (targetChainId.trim().length() == 0)
           {
-            targetChain = " ";
+            targetChainId = " ";
           }
           else
           {
             // not a valid chain identifier
-            targetChain = "";
+            targetChainId = "";
           }
         }
       }
       else
       {
-        targetChain = "";
+        targetChainId = "";
       }
 
       /*
@@ -426,7 +450,7 @@ public class StructureSelectionManager
       boolean first = true;
       for (PDBChain chain : pdb.chains)
       {
-        if (targetChain.length() > 0 && !targetChain.equals(chain.id)
+        if (targetChainId.length() > 0 && !targetChainId.equals(chain.id)
                 && !infChain)
         {
           continue; // don't try to map chains don't match.
@@ -442,7 +466,7 @@ public class StructureSelectionManager
         // as.traceAlignment();
 
         if (first || as.maxscore > max
-                || (as.maxscore == max && chain.id.equals(targetChain)))
+                || (as.maxscore == max && chain.id.equals(targetChainId)))
         {
           first = false;
           maxChain = chain;
@@ -455,90 +479,154 @@ public class StructureSelectionManager
       {
         continue;
       }
-      final StringBuilder mappingDetails = new StringBuilder(128);
-      mappingDetails.append(NEWLINE).append("PDB Sequence is :")
-              .append(NEWLINE).append("Sequence = ")
-              .append(maxChain.sequence.getSequenceAsString());
-      mappingDetails.append(NEWLINE).append("No of residues = ")
-              .append(maxChain.residues.size()).append(NEWLINE)
-              .append(NEWLINE);
-      PrintStream ps = new PrintStream(System.out)
+
+      if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
       {
-        @Override
-        public void print(String x)
-        {
-          mappingDetails.append(x);
-        }
+        pdbFile = "INLINE" + pdb.id;
+      }
 
-        @Override
-        public void println()
-        {
-          mappingDetails.append(NEWLINE);
-        }
-      };
-
-      maxAlignseq.printAlignment(ps);
-
-      mappingDetails.append(NEWLINE).append("PDB start/end ");
-      mappingDetails.append(String.valueOf(maxAlignseq.seq2start)).append(
-              " ");
-      mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
-
-      mappingDetails.append(NEWLINE).append("SEQ start/end ");
-      mappingDetails.append(
-              String.valueOf(maxAlignseq.seq1start + seq.getStart() - 1))
-              .append(" ");
-      mappingDetails.append(String.valueOf(maxAlignseq.seq1end
-              + seq.getEnd() - 1));
-
-      maxChain.makeExactMapping(maxAlignseq, seq);
-      jalview.datamodel.Mapping sqmpping = maxAlignseq
-              .getMappingFromS1(false);
-      jalview.datamodel.Mapping omap = new jalview.datamodel.Mapping(
-              sqmpping.getMap().getInverse());
-      maxChain.transferRESNUMFeatures(seq, null);
-
-      // allocate enough slots to store the mapping from positions in
-      // sequence[s] to the associated chain
-      int[][] mapping = new int[seq.findPosition(seq.getLength()) + 2][2];
-      int resNum = -10000;
-      int index = 0;
-
-      do
+      ArrayList<StructureMapping> seqToStrucMapping = null;
+      if (isMapUsingSIFTs)
       {
-        Atom tmp = maxChain.atoms.elementAt(index);
-        if (resNum != tmp.resNumber && tmp.alignmentMapping != -1)
+        setProgressBar(null);
+        setProgressBar("Obtaining mapping with SIFTS");
+        try
         {
-          resNum = tmp.resNumber;
-          if (tmp.alignmentMapping >= -1)
+          jalview.datamodel.Mapping sqmpping = maxAlignseq
+                  .getMappingFromS1(false);
+          seqToStrucMapping = new ArrayList<StructureMapping>();
+          if (targetChainId != null && !targetChainId.trim().isEmpty())
           {
-            // TODO (JAL-1836) address root cause: negative residue no in PDB
-            // file
-            mapping[tmp.alignmentMapping + 1][0] = tmp.resNumber;
-            mapping[tmp.alignmentMapping + 1][1] = tmp.atomIndex;
+            StructureMapping curChainMapping = siftsClient
+                    .getSiftsStructureMapping(seq, pdbFile, targetChainId);
+            seqToStrucMapping.add(curChainMapping);
+            maxChainId = targetChainId;
+            PDBChain chain = pdb.findChain(targetChainId);
+            if (chain != null)
+            {
+              chain.transferResidueAnnotation(curChainMapping, sqmpping);
+            }
           }
+          else
+          {
+            for (PDBChain chain : pdb.chains)
+            {
+              StructureMapping curChainMapping = siftsClient
+                      .getSiftsStructureMapping(seq, pdbFile, chain.id);
+              seqToStrucMapping.add(curChainMapping);
+              maxChainId = chain.id;
+              chain.transferResidueAnnotation(curChainMapping, sqmpping);
+            }
+          }
+        } catch (SiftsException e)
+        {
+          e.printStackTrace();
+          System.err
+                  .println(">>>>>>> SIFTs mapping could not be obtained... Now mapping with NW alignment");
+          setProgressBar(null);
+          setProgressBar("SIFTs mapping could not be obtained... Now mapping with NW alignment");
+          seqToStrucMapping = getNWMappings(seq, pdbFile, maxChainId,
+                  maxChain, pdb, maxAlignseq);
         }
-
-        index++;
-      } while (index < maxChain.atoms.size());
-
-      if (protocol.equals(jalview.io.AppletFormatAdapter.PASTE))
+      }
+      else
       {
-        pdbFile = "INLINE" + pdb.id;
+        setProgressBar(null);
+        setProgressBar("Obtaining mapping with NW alignment");
+        seqToStrucMapping = getNWMappings(seq, pdbFile,
+                maxChainId, maxChain, pdb,
+                maxAlignseq);
       }
-      StructureMapping newMapping = new StructureMapping(seq, pdbFile,
-              pdb.id, maxChainId, mapping, mappingDetails.toString());
+
       if (forStructureView)
       {
-        mappings.add(newMapping);
+        // mappings.add(seqToStrucMapping);
+        mappings.addAll(seqToStrucMapping);
       }
-      maxChain.transferResidueAnnotation(newMapping, sqmpping);
     }
-    // ///////
-
     return pdb;
   }
 
+  private ArrayList<StructureMapping> getNWMappings(SequenceI seq,
+          String pdbFile,
+          String maxChainId, PDBChain maxChain, PDBfile pdb,
+          AlignSeq maxAlignseq)
+  {
+    final StringBuilder mappingDetails = new StringBuilder(128);
+    mappingDetails.append(NEWLINE).append(
+            "Sequence \u27f7 Structure mapping details");
+    mappingDetails.append(NEWLINE);
+    mappingDetails
+            .append("Method: inferred with Needleman & Wunsch alignment");
+    mappingDetails.append(NEWLINE).append("PDB Sequence is :")
+            .append(NEWLINE).append("Sequence = ")
+            .append(maxChain.sequence.getSequenceAsString());
+    mappingDetails.append(NEWLINE).append("No of residues = ")
+            .append(maxChain.residues.size()).append(NEWLINE)
+            .append(NEWLINE);
+    PrintStream ps = new PrintStream(System.out)
+    {
+      @Override
+      public void print(String x)
+      {
+        mappingDetails.append(x);
+      }
+
+      @Override
+      public void println()
+      {
+        mappingDetails.append(NEWLINE);
+      }
+    };
+
+    maxAlignseq.printAlignment(ps);
+
+    mappingDetails.append(NEWLINE).append("PDB start/end ");
+    mappingDetails.append(String.valueOf(maxAlignseq.seq2start))
+            .append(" ");
+    mappingDetails.append(String.valueOf(maxAlignseq.seq2end));
+    mappingDetails.append(NEWLINE).append("SEQ start/end ");
+    mappingDetails.append(
+            String.valueOf(maxAlignseq.seq1start + (seq.getStart() - 1)))
+            .append(" ");
+    mappingDetails.append(String.valueOf(maxAlignseq.seq1end
+            + (seq.getStart() - 1)));
+    mappingDetails.append(NEWLINE);
+    maxChain.makeExactMapping(maxAlignseq, seq);
+    jalview.datamodel.Mapping sqmpping = maxAlignseq
+            .getMappingFromS1(false);
+    maxChain.transferRESNUMFeatures(seq, null);
+
+    HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
+    int resNum = -10000;
+    int index = 0;
+
+    do
+    {
+      Atom tmp = maxChain.atoms.elementAt(index);
+      if (resNum != tmp.resNumber && tmp.alignmentMapping != -1)
+      {
+        resNum = tmp.resNumber;
+        if (tmp.alignmentMapping >= -1)
+        {
+          // TODO (JAL-1836) address root cause: negative residue no in PDB
+          // file
+          mapping.put(tmp.alignmentMapping + 1, new int[] { tmp.resNumber,
+              tmp.atomIndex });
+        }
+      }
+
+      index++;
+    } while (index < maxChain.atoms.size());
+
+    StructureMapping nwMapping = new StructureMapping(seq, pdbFile,
+            pdb.id, maxChainId, mapping, mappingDetails.toString());
+    maxChain.transferResidueAnnotation(nwMapping, sqmpping);
+    ArrayList<StructureMapping> mappings = new ArrayList<StructureMapping>();
+    mappings.add(nwMapping);
+    return mappings;
+  }
+
   public void removeStructureViewerListener(Object svl, String[] pdbfiles)
   {
     listeners.removeElement(svl);
@@ -1146,8 +1234,34 @@ public class StructureSelectionManager
     return null;
   }
 
+  public IProgressIndicator getProgressIndicator()
+  {
+    return progressIndicator;
+  }
+
+  public void setProgressIndicator(IProgressIndicator progressIndicator)
+  {
+    this.progressIndicator = progressIndicator;
+  }
+
+  public long getProgressSessionId()
+  {
+    return progressSessionId;
+  }
+
+  public void setProgressSessionId(long progressSessionId)
+  {
+    this.progressSessionId = progressSessionId;
+  }
+
+  public void setProgressBar(String message)
+  {
+    progressIndicator.setProgressBar(message, progressSessionId);
+  }
+
   public List<AlignedCodonFrame> getSequenceMappings()
   {
     return seqmappings;
   }
+
 }
index 95f298b..8902e2c 100644 (file)
@@ -262,9 +262,35 @@ public class Comparison
     {
       return false;
     }
+    char[][] letters = new char[seqs.length][];
+    for (int i = 0; i < seqs.length; i++)
+    {
+      if (seqs[i] != null)
+      {
+        char[] sequence = seqs[i].getSequence();
+        if (sequence != null)
+        {
+          letters[i] = sequence;
+        }
+      }
+    }
+
+    return areNucleotide(letters);
+  }
+
+  /**
+   * Answers true if more than 85% of the sequence residues (ignoring gaps) are
+   * A, G, C, T or U, else false. This is just a heuristic guess and may give a
+   * wrong answer (as AGCT are also amino acid codes).
+   * 
+   * @param letters
+   * @return
+   */
+  public static final boolean areNucleotide(char[][] letters)
+  {
     int ntCount = 0;
     int aaCount = 0;
-    for (SequenceI seq : seqs)
+    for (char[] seq : letters)
     {
       if (seq == null)
       {
@@ -272,7 +298,7 @@ public class Comparison
       }
       // TODO could possibly make an informed guess just from the first sequence
       // to save a lengthy calculation
-      for (char c : seq.getSequence())
+      for (char c : seq)
       {
         if ('a' <= c && c <= 'z')
         {
index 22714b8..1bbfc73 100644 (file)
@@ -522,74 +522,158 @@ public final class MappingUtils
 
     char fromGapChar = mapFrom.getAlignment().getGapCharacter();
 
-    // FIXME allow for hidden columns
-
     /*
      * For each mapped column, find the range of columns that residues in that
      * column map to.
      */
-    for (Object obj : colsel.getSelected())
+    List<SequenceI> fromSequences = mapFrom.getAlignment().getSequences();
+    List<SequenceI> toSequences = mapTo.getAlignment().getSequences();
+
+    for (Integer sel : colsel.getSelected())
     {
-      int col = ((Integer) obj).intValue();
-      int mappedToMin = Integer.MAX_VALUE;
-      int mappedToMax = Integer.MIN_VALUE;
+      mapColumn(sel.intValue(), codonFrames, mappedColumns, fromSequences,
+              toSequences, fromGapChar);
+    }
+
+    for (int[] hidden : colsel.getHiddenColumns())
+    {
+      mapHiddenColumns(hidden, codonFrames, mappedColumns, fromSequences,
+              toSequences, fromGapChar);
+    }
+    return mappedColumns;
+  }
+
+  /**
+   * Helper method that maps a [start, end] hidden column range to its mapped
+   * equivalent
+   * 
+   * @param hidden
+   * @param mappings
+   * @param mappedColumns
+   * @param fromSequences
+   * @param toSequences
+   * @param fromGapChar
+   */
+  protected static void mapHiddenColumns(int[] hidden,
+          List<AlignedCodonFrame> mappings,
+          ColumnSelection mappedColumns, List<SequenceI> fromSequences,
+          List<SequenceI> toSequences, char fromGapChar)
+  {
+    for (int col = hidden[0]; col <= hidden[1]; col++)
+    {
+      int[] mappedTo = findMappedColumns(col, mappings, fromSequences,
+              toSequences, fromGapChar);
 
       /*
-       * For each sequence in the 'from' alignment
+       * Add the range of hidden columns to the mapped selection (converting
+       * base 1 to base 0).
        */
-      for (SequenceI fromSeq : mapFrom.getAlignment().getSequences())
+      if (mappedTo != null)
       {
-        /*
-         * Ignore gaps (unmapped anyway)
-         */
-        if (fromSeq.getCharAt(col) == fromGapChar)
-        {
-          continue;
-        }
+        mappedColumns.hideColumns(mappedTo[0] - 1, mappedTo[1] - 1);
+      }
+    }
+  }
+
+  /**
+   * Helper method to map one column selection
+   * 
+   * @param col
+   *          the column number (base 0)
+   * @param mappings
+   *          the sequence mappings
+   * @param mappedColumns
+   *          the mapped column selections to add to
+   * @param fromSequences
+   * @param toSequences
+   * @param fromGapChar
+   */
+  protected static void mapColumn(int col,
+          List<AlignedCodonFrame> mappings,
+          ColumnSelection mappedColumns, List<SequenceI> fromSequences,
+          List<SequenceI> toSequences, char fromGapChar)
+  {
+    int[] mappedTo = findMappedColumns(col, mappings, fromSequences,
+            toSequences, fromGapChar);
+
+    /*
+     * Add the range of mapped columns to the mapped selection (converting
+     * base 1 to base 0). Note that this may include intron-only regions which
+     * lie between the start and end ranges of the selection.
+     */
+    if (mappedTo != null)
+    {
+      for (int i = mappedTo[0]; i <= mappedTo[1]; i++)
+      {
+        mappedColumns.addElement(i - 1);
+      }
+    }
+  }
+
+  /**
+   * Helper method to find the range of columns mapped to from one column.
+   * Returns the maximal range of columns mapped to from all sequences in the
+   * source column, or null if no mappings were found.
+   * 
+   * @param col
+   * @param mappings
+   * @param fromSequences
+   * @param toSequences
+   * @param fromGapChar
+   * @return
+   */
+  protected static int[] findMappedColumns(int col,
+          List<AlignedCodonFrame> mappings, List<SequenceI> fromSequences,
+          List<SequenceI> toSequences, char fromGapChar)
+  {
+    int[] mappedTo = new int[] { Integer.MAX_VALUE, Integer.MIN_VALUE };
+    boolean found = false;
+
+    /*
+     * For each sequence in the 'from' alignment
+     */
+    for (SequenceI fromSeq : fromSequences)
+    {
+      /*
+       * Ignore gaps (unmapped anyway)
+       */
+      if (fromSeq.getCharAt(col) == fromGapChar)
+      {
+        continue;
+      }
+
+      /*
+       * Get the residue position and find the mapped position.
+       */
+      int residuePos = fromSeq.findPosition(col);
+      SearchResults sr = buildSearchResults(fromSeq, residuePos,
+              mappings);
+      for (Match m : sr.getResults())
+      {
+        int mappedStartResidue = m.getStart();
+        int mappedEndResidue = m.getEnd();
+        SequenceI mappedSeq = m.getSequence();
 
         /*
-         * Get the residue position and find the mapped position.
+         * Locate the aligned sequence whose dataset is mappedSeq. TODO a
+         * datamodel that can do this efficiently.
          */
-        int residuePos = fromSeq.findPosition(col);
-        SearchResults sr = buildSearchResults(fromSeq, residuePos,
-                codonFrames);
-        for (Match m : sr.getResults())
+        for (SequenceI toSeq : toSequences)
         {
-          int mappedStartResidue = m.getStart();
-          int mappedEndResidue = m.getEnd();
-          SequenceI mappedSeq = m.getSequence();
-
-          /*
-           * Locate the aligned sequence whose dataset is mappedSeq. TODO a
-           * datamodel that can do this efficiently.
-           */
-          for (SequenceI toSeq : mapTo.getAlignment().getSequences())
+          if (toSeq.getDatasetSequence() == mappedSeq)
           {
-            if (toSeq.getDatasetSequence() == mappedSeq)
-            {
-              int mappedStartCol = toSeq.findIndex(mappedStartResidue);
-              int mappedEndCol = toSeq.findIndex(mappedEndResidue);
-              mappedToMin = Math.min(mappedToMin, mappedStartCol);
-              mappedToMax = Math.max(mappedToMax, mappedEndCol);
-              // System.out.println(fromSeq.getName() + " mapped to cols "
-              // + mappedStartCol + ":" + mappedEndCol);
-              break;
-              // note: remove break if we ever want to map one to many sequences
-            }
+            int mappedStartCol = toSeq.findIndex(mappedStartResidue);
+            int mappedEndCol = toSeq.findIndex(mappedEndResidue);
+            mappedTo[0] = Math.min(mappedTo[0], mappedStartCol);
+            mappedTo[1] = Math.max(mappedTo[1], mappedEndCol);
+            found = true;
+            break;
+            // note: remove break if we ever want to map one to many sequences
           }
         }
       }
-      /*
-       * Add the range of mapped columns to the mapped selection (converting
-       * base 1 to base 0). Note that this may include intron-only regions which
-       * lie between the start and end ranges of the selection.
-       */
-      for (int i = mappedToMin; i <= mappedToMax; i++)
-      {
-        mappedColumns.addElement(i - 1);
-      }
     }
-    return mappedColumns;
+    return found ? mappedTo : null;
   }
 
   /**
index 3d807e2..ab9740c 100644 (file)
@@ -1203,7 +1203,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    */
   public boolean isColSelChanged(boolean b)
   {
-    int hc = (colSel == null || colSel.size() == 0) ? -1 : colSel
+    int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel
             .hashCode();
     if (hc != -1 && hc != colselhash)
     {
@@ -1298,7 +1298,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
 
   public void hideSelectedColumns()
   {
-    if (colSel.size() < 1)
+    if (colSel.isEmpty())
     {
       return;
     }
index 9d91e31..dff1b98 100644 (file)
@@ -28,9 +28,9 @@ import jalview.datamodel.DBRefSource;
 import jalview.datamodel.Mapping;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
-import jalview.gui.AlignFrame;
 import jalview.gui.CutAndPasteTransfer;
 import jalview.gui.Desktop;
+import jalview.gui.FeatureSettings;
 import jalview.gui.IProgressIndicator;
 import jalview.gui.OOMWarning;
 import jalview.util.MessageManager;
@@ -57,7 +57,7 @@ public class DBRefFetcher implements Runnable
 {
   SequenceI[] dataset;
 
-  IProgressIndicator af;
+  IProgressIndicator progressWindow;
 
   CutAndPasteTransfer output = new CutAndPasteTransfer();
 
@@ -91,34 +91,25 @@ public class DBRefFetcher implements Runnable
   }
 
   /**
-   * Creates a new SequenceFeatureFetcher object and fetches from the currently
-   * selected set of databases.
+   * Creates a new DBRefFetcher object and fetches from the currently selected
+   * set of databases, if this is null then it fetches based on feature settings
    * 
    * @param seqs
-   *          fetch references for these sequences
-   * @param af
-   *          the parent alignframe for progress bar monitoring.
-   */
-  public DBRefFetcher(SequenceI[] seqs, AlignFrame af)
-  {
-    this(seqs, af, null);
-  }
-
-  /**
-   * Creates a new SequenceFeatureFetcher object and fetches from the currently
-   * selected set of databases.
-   * 
-   * @param seqs
-   *          fetch references for these sequences
-   * @param af
-   *          the parent alignframe for progress bar monitoring.
+   *          fetch references for these SequenceI array
+   * @param progressIndicatorFrame
+   *          the frame for progress bar monitoring
    * @param sources
-   *          array of database source strings to query references from
+   *          array of DbSourceProxy to query references form
+   * @param featureSettings
+   *          FeatureSettings to get alternative DbSourceProxy from
+   * @param isNucleotide
+   *          indicates if the array of SequenceI are Nucleotides or not
    */
-  public DBRefFetcher(SequenceI[] seqs, AlignFrame af,
-          DbSourceProxy[] sources)
+  public DBRefFetcher(SequenceI[] seqs,
+          IProgressIndicator progressIndicatorFrame,
+          DbSourceProxy[] sources, FeatureSettings featureSettings, boolean isNucleotide)
   {
-    this.af = af;
+    this.progressWindow = progressIndicatorFrame;
     alseqs = new SequenceI[seqs.length];
     SequenceI[] ds = new SequenceI[seqs.length];
     for (int i = 0; i < seqs.length; i++)
@@ -135,7 +126,8 @@ public class DBRefFetcher implements Runnable
     }
     this.dataset = ds;
     // TODO Jalview 2.5 lots of this code should be in the gui package!
-    sfetcher = jalview.gui.SequenceFetcher.getSequenceFetcherSingleton(af);
+    sfetcher = jalview.gui.SequenceFetcher
+            .getSequenceFetcherSingleton(progressIndicatorFrame);
     // set default behaviour for transferring excess sequence data to the
     // dataset
     trimDsSeqs = Cache.getDefault("TRIM_FETCHED_DATASET_SEQS", true);
@@ -145,7 +137,7 @@ public class DBRefFetcher implements Runnable
       String[] defdb = null, otherdb = sfetcher
               .getDbInstances(jalview.ws.dbsources.das.datamodel.DasSequenceSource.class);
       List<DbSourceProxy> selsources = new ArrayList<DbSourceProxy>();
-      Vector dasselsrc = (af.featureSettings != null) ? af.featureSettings
+      Vector dasselsrc = (featureSettings != null) ? featureSettings
               .getSelectedSources() : new jalview.gui.DasSourceBrowser()
               .getSelectedSources();
       Enumeration<jalviewSourceI> en = dasselsrc.elements();
@@ -163,7 +155,7 @@ public class DBRefFetcher implements Runnable
         }
       }
       // select appropriate databases based on alignFrame context.
-      if (af.getViewport().getAlignment().isNucleotide())
+      if (isNucleotide)
       {
         defdb = DBRefSource.DNACODINGDBS;
       }
@@ -294,8 +286,12 @@ public class DBRefFetcher implements Runnable
     }
     running = true;
     long startTime = System.currentTimeMillis();
-    af.setProgressBar(MessageManager.getString("status.fetching_db_refs"),
+    if (progressWindow != null)
+    {
+      progressWindow.setProgressBar(
+              MessageManager.getString("status.fetching_db_refs"),
             startTime);
+    }
     try
     {
       if (Cache.getDefault("DBREFFETCH_USEPICR", false))
@@ -393,7 +389,7 @@ public class DBRefFetcher implements Runnable
             {
               SequenceI sequence = dataset[seqIndex];
               DBRefEntry[] uprefs = jalview.util.DBRefUtils.selectRefs(
-                      sequence.getDBRef(),
+                      sequence.getDBRefs(),
                       new String[] { dbsource.getDbSource() }); // jalview.datamodel.DBRefSource.UNIPROT
               // });
               // check for existing dbrefs to use
@@ -472,11 +468,14 @@ public class DBRefFetcher implements Runnable
       // of the viewed sequence
 
     }
+    if (progressWindow != null)
+    {
+      progressWindow.setProgressBar(
+              MessageManager.getString("label.dbref_search_completed"),
+              startTime);
+      // promptBeforeBlast();
 
-    af.setProgressBar(
-            MessageManager.getString("label.dbref_search_completed"),
-            startTime);
-    // promptBeforeBlast();
+    }
 
     running = false;
 
@@ -517,7 +516,7 @@ public class DBRefFetcher implements Runnable
       Vector sequenceMatches = new Vector();
       // look for corresponding accession ids
       DBRefEntry[] entryRefs = jalview.util.DBRefUtils.selectRefs(
-              entry.getDBRef(), new String[] { dbSource });
+              entry.getDBRefs(), new String[] { dbSource });
       if (entryRefs == null)
       {
         System.err
@@ -584,8 +583,8 @@ public class DBRefFetcher implements Runnable
         // no existing references
         // TODO: test for legacy where uniprot or EMBL refs exist but no
         // mappings are made (but content matches retrieved set)
-        boolean updateRefFrame = sequence.getDBRef() == null
-                || sequence.getDBRef().length == 0;
+        boolean updateRefFrame = sequence.getDBRefs() == null
+                || sequence.getDBRefs().length == 0;
         // TODO:
         // verify sequence against the entry sequence
 
@@ -730,7 +729,7 @@ public class DBRefFetcher implements Runnable
     for (int i = 0; sequencesArray != null && i < sequencesArray.length; i++)
     {
       nseq.addElement(sequencesArray[i]);
-      DBRefEntry dbr[] = sequencesArray[i].getDBRef();
+      DBRefEntry dbr[] = sequencesArray[i].getDBRefs();
       jalview.datamodel.Mapping map = null;
       for (int r = 0; (dbr != null) && r < dbr.length; r++)
       {
index 808d9a0..d7ba24d 100644 (file)
@@ -181,7 +181,7 @@ public class DasSequenceFeatureFetcher
     int refCount = 0;
     for (int i = 0; i < sequences.length; i++)
     {
-      DBRefEntry[] dbref = sequences[i].getDBRef();
+      DBRefEntry[] dbref = sequences[i].getDBRefs();
       if (dbref != null)
       {
         for (int j = 0; j < dbref.length; j++)
@@ -238,6 +238,7 @@ public class DasSequenceFeatureFetcher
 
   class FetchSeqFeatures implements Runnable
   {
+    @Override
     public void run()
     {
       startFetching();
@@ -247,10 +248,15 @@ public class DasSequenceFeatureFetcher
 
   class FetchDBRefs implements Runnable
   {
+    @Override
     public void run()
     {
       running = true;
-      new DBRefFetcher(sequences, af).fetchDBRefs(true);
+      boolean isNuclueotide = af.getViewport().getAlignment()
+              .isNucleotide();
+      new jalview.ws.DBRefFetcher(sequences, af, null, af.featureSettings,
+              isNuclueotide).fetchDBRefs(true);
+
       startFetching();
       setGuiFetchComplete();
     }
@@ -638,7 +644,7 @@ public class DasSequenceFeatureFetcher
       return null;
     }
     DBRefEntry[] uprefs = jalview.util.DBRefUtils.selectRefs(
-            seq.getDBRef(), new String[] {
+            seq.getDBRefs(), new String[] {
             // jalview.datamodel.DBRefSource.PDB,
             jalview.datamodel.DBRefSource.UNIPROT,
             // jalview.datamodel.DBRefSource.EMBL - not tested on any EMBL coord
index b9fb8f3..3fd7541 100644 (file)
@@ -100,7 +100,7 @@ public class Pdb extends EbiFileRetrievedProxy
   @Override
   public AlignmentI getSequenceRecords(String queries) throws Exception
   {
-    AlignmentI pdbfile = null;
+    AlignmentI pdbAlignment = null;
     Vector result = new Vector();
     String chain = null;
     String id = null;
@@ -134,12 +134,12 @@ public class Pdb extends EbiFileRetrievedProxy
     try
     {
 
-      pdbfile = new FormatAdapter().readFile(file,
+      pdbAlignment = new FormatAdapter().readFile(file,
               jalview.io.AppletFormatAdapter.FILE, "PDB");
-      if (pdbfile != null)
+      if (pdbAlignment != null)
       {
         List<SequenceI> toremove = new ArrayList<SequenceI>();
-        for (SequenceI pdbcs : pdbfile.getSequences())
+        for (SequenceI pdbcs : pdbAlignment.getSequences())
         {
           String chid = null;
           // Mapping map=null;
@@ -191,18 +191,18 @@ public class Pdb extends EbiFileRetrievedProxy
         // now remove marked sequences
         for (SequenceI pdbcs : toremove)
         {
-          pdbfile.deleteSequence(pdbcs);
+          pdbAlignment.deleteSequence(pdbcs);
           if (pdbcs.getAnnotation() != null)
           {
             for (AlignmentAnnotation aa : pdbcs.getAnnotation())
             {
-              pdbfile.deleteAnnotation(aa);
+              pdbAlignment.deleteAnnotation(aa);
             }
           }
         }
       }
 
-      if (pdbfile == null || pdbfile.getHeight() < 1)
+      if (pdbAlignment == null || pdbAlignment.getHeight() < 1)
       {
         throw new Exception(MessageManager.formatMessage(
                 "exception.no_pdb_records_for_chain", new String[] { id,
@@ -214,7 +214,7 @@ public class Pdb extends EbiFileRetrievedProxy
       stopQuery();
       throw (ex);
     }
-    return pdbfile;
+    return pdbAlignment;
   }
 
   /*
index 0a252b1..02da009 100644 (file)
  */
 package jalview.ws.dbsources;
 
+import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.DBRefSource;
 import jalview.datamodel.PDBEntry;
+import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.datamodel.UniprotEntry;
@@ -35,6 +37,7 @@ import java.io.File;
 import java.io.FileReader;
 import java.io.Reader;
 import java.net.URL;
+import java.util.ArrayList;
 import java.util.Vector;
 
 import org.exolab.castor.mapping.Mapping;
@@ -48,11 +51,11 @@ import com.stevesoft.pat.Regex;
  */
 public class Uniprot extends DbSourceProxyImpl
 {
-
   private static final String BAR_DELIMITER = "|";
 
-  private static final String NEWLINE = "\n";
-
+  /*
+   * Castor mapping loaded from uniprot_mapping.xml
+   */
   private static Mapping map;
 
   /**
@@ -71,7 +74,7 @@ public class Uniprot extends DbSourceProxyImpl
   @Override
   public String getAccessionSeparator()
   {
-    return null; // ";";
+    return null;
   }
 
   /*
@@ -167,32 +170,13 @@ public class Uniprot extends DbSourceProxyImpl
 
       if (entries != null)
       {
-        /*
-         * If Castor binding included sequence@length, we could guesstimate the
-         * size of buffer to hold the alignment
-         */
-        StringBuffer result = new StringBuffer(128);
-        // First, make the new sequences
+        ArrayList<SequenceI> seqs = new ArrayList<SequenceI>();
         for (UniprotEntry entry : entries)
         {
-          StringBuilder name = constructSequenceFastaHeader(entry);
-
-          result.append(name).append(NEWLINE)
-                  .append(entry.getUniprotSequence().getContent())
-                  .append(NEWLINE);
+          seqs.add(uniprotEntryToSequenceI(entry));
         }
+        al = new Alignment(seqs.toArray(new SequenceI[0]));
 
-        // Then read in the features and apply them to the dataset
-        al = parseResult(result.toString());
-        if (al != null)
-        {
-          // Decorate the alignment with database entries.
-          addUniprotXrefs(al, entries);
-        }
-        else
-        {
-          results = result;
-        }
       }
       stopQuery();
       return al;
@@ -204,99 +188,95 @@ public class Uniprot extends DbSourceProxyImpl
   }
 
   /**
-   * Construct a Fasta-format sequence header by concatenating the source,
-   * accession id(s) and name(s), delimited by '|', plus any protein names, now
-   * with space rather than bar delimiter
    * 
    * @param entry
-   * @return
+   *          UniprotEntry
+   * @return SequenceI instance created from the UniprotEntry instance
    */
-  public static StringBuilder constructSequenceFastaHeader(
-          UniprotEntry entry)
-  {
-    StringBuilder name = new StringBuilder(32);
-    name.append(">UniProt/Swiss-Prot");
+  public SequenceI uniprotEntryToSequenceI(UniprotEntry entry){
+    String id = getUniprotEntryId(entry);
+    SequenceI sequence = new Sequence(id, entry.getUniprotSequence()
+            .getContent());
+    sequence.setDescription(getUniprotEntryDescription(entry));
+
+    final String dbVersion = getDbVersion();
+    ArrayList<DBRefEntry> dbRefs = new ArrayList<DBRefEntry>();
     for (String accessionId : entry.getAccession())
     {
-      name.append(BAR_DELIMITER);
-      name.append(accessionId);
+      DBRefEntry dbRef = new DBRefEntry(DBRefSource.UNIPROT, dbVersion,
+              accessionId);
+      dbRefs.add(dbRef);
     }
-    for (String n : entry.getName())
+    sequence.setSourceDBRef((dbRefs != null && dbRefs.size() > 0) ? dbRefs
+            .get(0) : null);
+
+    Vector<PDBEntry> onlyPdbEntries = new Vector<PDBEntry>();
+    for (PDBEntry pdb : entry.getDbReference())
     {
-      name.append(BAR_DELIMITER);
-      name.append(n);
+      DBRefEntry dbr = new DBRefEntry();
+      dbr.setSource(pdb.getType());
+      dbr.setAccessionId(pdb.getId());
+      dbr.setVersion(DBRefSource.UNIPROT + ":" + dbVersion);
+      dbRefs.add(dbr);
+      if ("PDB".equals(pdb.getType()))
+      {
+        onlyPdbEntries.addElement(pdb);
+      }
     }
 
-    if (entry.getProtein() != null && entry.getProtein().getName() != null)
+    sequence.setPDBId(onlyPdbEntries);
+    if (entry.getFeature() != null)
     {
-      for (String nm : entry.getProtein().getName())
+      for (SequenceFeature sf : entry.getFeature())
       {
-        name.append(" ").append(nm);
+        sf.setFeatureGroup("Uniprot");
+        sequence.addSequenceFeature(sf);
       }
     }
-    return name;
+    sequence.setDBRefs(dbRefs.toArray(new DBRefEntry[0]));
+    return sequence;
   }
 
   /**
-   * add an ordered set of UniprotEntry objects to an ordered set of seuqences.
    * 
-   * @param al
-   *          - a sequence of n sequences
-   * @param entries
-   *          a list of n uniprot entries to be analysed.
+   * @param entry
+   *          UniportEntry
+   * @return protein name(s) delimited by a white space character
    */
-  public void addUniprotXrefs(AlignmentI al, Vector<UniprotEntry> entries)
+  public static String getUniprotEntryDescription(UniprotEntry entry)
   {
-    final String dbVersion = getDbVersion();
-
-    for (int i = 0; i < entries.size(); i++)
+    StringBuilder desc = new StringBuilder(32);
+    if (entry.getProtein() != null && entry.getProtein().getName() != null)
     {
-      UniprotEntry entry = entries.elementAt(i);
-      Vector<PDBEntry> onlyPdbEntries = new Vector<PDBEntry>();
-      Vector<DBRefEntry> dbxrefs = new Vector<DBRefEntry>();
-
-      for (PDBEntry pdb : entry.getDbReference())
-      {
-        DBRefEntry dbr = new DBRefEntry();
-        dbr.setSource(pdb.getType());
-        dbr.setAccessionId(pdb.getId());
-        dbr.setVersion(DBRefSource.UNIPROT + ":" + dbVersion);
-        dbxrefs.addElement(dbr);
-        if ("PDB".equals(pdb.getType()))
-        {
-          onlyPdbEntries.addElement(pdb);
-        }
-      }
-
-      SequenceI sq = al.getSequenceAt(i);
-      while (sq.getDatasetSequence() != null)
-      {
-        sq = sq.getDatasetSequence();
-      }
-
-      for (String accessionId : entry.getAccession())
+      for (String nm : entry.getProtein().getName())
       {
-        /*
-         * add as uniprot whether retrieved from uniprot or uniprot_name
-         */
-        sq.addDBRef(new DBRefEntry(DBRefSource.UNIPROT, dbVersion,
-                accessionId));
+        desc.append(nm).append(" ");
       }
+    }
+    return desc.toString();
+  }
 
-      for (DBRefEntry dbRef : dbxrefs)
-      {
-        sq.addDBRef(dbRef);
-      }
-      sq.setPDBId(onlyPdbEntries);
-      if (entry.getFeature() != null)
-      {
-        for (SequenceFeature sf : entry.getFeature())
-        {
-          sf.setFeatureGroup("Uniprot");
-          sq.addSequenceFeature(sf);
-        }
-      }
+  /**
+   *
+   * @param entry
+   *          UniportEntry
+   * @return The accession id(s) and name(s) delimited by '|'.
+   */
+  public static String getUniprotEntryId(UniprotEntry entry)
+  {
+    StringBuilder name = new StringBuilder(32);
+    name.append("UniProt/Swiss-Prot");
+    for (String accessionId : entry.getAccession())
+    {
+      name.append(BAR_DELIMITER);
+      name.append(accessionId);
+    }
+    for (String n : entry.getName())
+    {
+      name.append(BAR_DELIMITER);
+      name.append(n);
     }
+    return name.toString();
   }
 
   /*
@@ -332,13 +312,4 @@ public class Uniprot extends DbSourceProxyImpl
   {
     return 0;
   }
-
-  @Override
-  public int getMaximumQueryCount()
-  {
-    // relocated this commented out code...
-    // addDbSourceProperty(DBRefSource.MULTIACC, new Integer(50));
-    // return 50;
-    return super.getMaximumQueryCount();
-  }
 }
index 9e438d3..7d88414 100644 (file)
@@ -206,7 +206,7 @@ public class ASequenceFetcher
                 {
                   rseqs.addElement(seqs[is]);
                   DBRefEntry[] frefs = DBRefUtils.searchRefs(seqs[is]
-                          .getDBRef(), new DBRefEntry(db, null, null));
+                          .getDBRefs(), new DBRefEntry(db, null, null));
                   if (frefs != null)
                   {
                     for (DBRefEntry dbr : frefs)
diff --git a/src/jalview/ws/sifts/MappingOutputPojo.java b/src/jalview/ws/sifts/MappingOutputPojo.java
new file mode 100644 (file)
index 0000000..c06e51f
--- /dev/null
@@ -0,0 +1,129 @@
+package jalview.ws.sifts;
+
+public class MappingOutputPojo
+{
+  private String seqName;
+
+  private String seqResidue;
+
+  private int seqStart;
+
+  private int seqEnd;
+
+  private String strName;
+
+  private String strResidue;
+
+  private int strStart;
+
+  private int strEnd;
+
+  private String type;
+
+  private int wrapHeight;
+
+  private static final int MAX_ID_LENGTH = 30;
+
+  public String getSeqName()
+  {
+    return seqName;
+  }
+
+  public void setSeqName(String seqName)
+  {
+    this.seqName = (seqName.length() > MAX_ID_LENGTH) ? seqName.substring(
+            0, MAX_ID_LENGTH) : seqName;
+  }
+
+  public String getSeqResidue()
+  {
+    return seqResidue;
+  }
+
+  public void setSeqResidue(String seqResidue)
+  {
+    this.seqResidue = seqResidue;
+  }
+
+  public int getSeqStart()
+  {
+    return seqStart;
+  }
+
+  public void setSeqStart(int seqStart)
+  {
+    this.seqStart = seqStart;
+  }
+
+  public int getSeqEnd()
+  {
+    return seqEnd;
+  }
+
+  public void setSeqEnd(int seqEnd)
+  {
+    this.seqEnd = seqEnd;
+  }
+
+  public String getStrName()
+  {
+    return strName;
+  }
+
+  public void setStrName(String strName)
+  {
+    this.strName = (strName.length() > MAX_ID_LENGTH) ? strName.substring(
+            0, MAX_ID_LENGTH) : strName;
+  }
+
+  public String getStrResidue()
+  {
+    return strResidue;
+  }
+
+  public void setStrResidue(String strResidue)
+  {
+    this.strResidue = strResidue;
+  }
+
+  public int getStrStart()
+  {
+    return strStart;
+  }
+
+  public void setStrStart(int strStart)
+  {
+    this.strStart = strStart;
+  }
+
+  public int getStrEnd()
+  {
+    return strEnd;
+  }
+
+  public void setStrEnd(int strEnd)
+  {
+    this.strEnd = strEnd;
+  }
+
+  public String getType()
+  {
+    return type;
+  }
+
+  public void setType(String type)
+  {
+    this.type = type;
+  }
+
+  public int getWrapHeight()
+  {
+    return wrapHeight;
+  }
+
+  public void setWrapHeight(int wrapHeight)
+  {
+    this.wrapHeight = wrapHeight;
+  }
+
+}
diff --git a/src/jalview/ws/sifts/SiftsClient.java b/src/jalview/ws/sifts/SiftsClient.java
new file mode 100644 (file)
index 0000000..7d5ae2e
--- /dev/null
@@ -0,0 +1,1033 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ws.sifts;
+
+import jalview.analysis.AlignSeq;
+import jalview.api.DBRefEntryI;
+import jalview.api.SiftsClientI;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.SequenceI;
+import jalview.schemes.ResidueProperties;
+import jalview.structure.StructureMapping;
+import jalview.util.Format;
+import jalview.xml.binding.sifts.Entry;
+import jalview.xml.binding.sifts.Entry.Entity;
+import jalview.xml.binding.sifts.Entry.Entity.Segment;
+import jalview.xml.binding.sifts.Entry.Entity.Segment.ListMapRegion.MapRegion;
+import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue;
+import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue.CrossRefDb;
+import jalview.xml.binding.sifts.Entry.Entity.Segment.ListResidue.Residue.ResidueDetail;
+import jalview.xml.binding.sifts.Entry.ListDB.Db;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.TreeMap;
+import java.util.zip.GZIPInputStream;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Unmarshaller;
+import javax.xml.stream.FactoryConfigurationError;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import MCview.Atom;
+import MCview.PDBChain;
+import MCview.PDBfile;
+
+public class SiftsClient implements SiftsClientI
+{
+  private Entry siftsEntry;
+
+  private PDBfile pdb;
+
+  private String pdbId;
+
+  private String structId;
+
+  private String segStartEnd;
+
+  private CoordinateSys seqCoordSys = CoordinateSys.UNIPROT;
+
+  private static final int BUFFER_SIZE = 4096;
+
+  public static final int UNASSIGNED = -1;
+
+  private static final int PDB_RES_POS = 0;
+
+  private static final int PDB_ATOM_POS = 1;
+
+  private static final String NOT_FOUND = "Not_Found";
+
+  private static final String NOT_OBSERVED = "Not_Observed";
+
+  private static final String SIFTS_FTP_BASE_URL = "ftp://ftp.ebi.ac.uk/pub/databases/msd/sifts/xml/";
+
+  private final static String NEWLINE = System.lineSeparator();
+
+  private final static int THRESHOLD_IN_DAYS = 2;
+
+  private String curSourceDBRef;
+
+  private HashSet<String> curDBRefAccessionIdsString;
+
+  public enum CoordinateSys
+  {
+    UNIPROT("UniProt"), PDB("PDBresnum"), PDBe("PDBe");
+    private String name;
+
+    private CoordinateSys(String name)
+    {
+      this.name = name;
+    }
+
+    public String getName()
+    {
+      return name;
+    }
+  };
+
+  public enum ResidueDetailType
+  {
+    NAME_SEC_STRUCTURE("nameSecondaryStructure"), CODE_SEC_STRUCTURE(
+            "codeSecondaryStructure"), ANNOTATION("Annotation");
+    private String code;
+
+    private ResidueDetailType(String code)
+    {
+      this.code = code;
+    }
+
+    public String getCode()
+    {
+      return code;
+    }
+  };
+
+  /**
+   * Fetch SIFTs file for the given PDBfile and construct an instance of
+   * SiftsClient
+   * 
+   * @param pdbId
+   * @throws SiftsException
+   */
+  public SiftsClient(PDBfile pdb) throws SiftsException
+  {
+    this.pdb = pdb;
+    this.pdbId = pdb.id;
+    File siftsFile = getSiftsFile(pdbId);
+    siftsEntry = parseSIFTs(siftsFile);
+  }
+
+  /**
+   * Construct an instance of SiftsClient using the supplied SIFTs file. Note:
+   * The SIFTs file should correspond to the PDB Id in PDBfile instance
+   * 
+   * @param pdbId
+   * @param siftsFile
+   * @throws SiftsException
+   * @throws Exception
+   */
+  public SiftsClient(PDBfile pdb, File siftsFile) throws SiftsException
+  {
+    this.pdb = pdb;
+    this.pdbId = pdb.id;
+    siftsEntry = parseSIFTs(siftsFile);
+  }
+
+  /**
+   * Parse the given SIFTs File and return a JAXB POJO of parsed data
+   * 
+   * @param siftFile
+   *          - the GZipped SIFTs XML file to parse
+   * @return
+   * @throws Exception
+   *           if a problem occurs while parsing the SIFTs XML
+   */
+  private Entry parseSIFTs(File siftFile) throws SiftsException
+  {
+    try (InputStream in = new FileInputStream(siftFile);
+            GZIPInputStream gzis = new GZIPInputStream(in);)
+    {
+      // System.out.println("File : " + siftFile.getAbsolutePath());
+      JAXBContext jc = JAXBContext.newInstance("jalview.xml.binding.sifts");
+      XMLStreamReader streamReader = XMLInputFactory.newInstance()
+              .createXMLStreamReader(gzis);
+      Unmarshaller um = jc.createUnmarshaller();
+      return (Entry) um.unmarshal(streamReader);
+    } catch (JAXBException e)
+    {
+      e.printStackTrace();
+      throw new SiftsException(e.getMessage());
+    } catch (FileNotFoundException e)
+    {
+      e.printStackTrace();
+      throw new SiftsException(e.getMessage());
+    } catch (XMLStreamException e)
+    {
+      e.printStackTrace();
+      throw new SiftsException(e.getMessage());
+    } catch (FactoryConfigurationError e)
+    {
+      e.printStackTrace();
+      throw new SiftsException(e.getMessage());
+    } catch (IOException e)
+    {
+      e.printStackTrace();
+      throw new SiftsException(e.getMessage());
+    }
+  }
+
+  /**
+   * Get a SIFTs XML file for a given PDB Id from Cache or download from FTP
+   * repository if not found in cache
+   * 
+   * @param pdbId
+   * @return SIFTs XML file
+   * @throws SiftsException
+   */
+  public static File getSiftsFile(String pdbId) throws SiftsException
+  {
+    File siftsFile = new File(SiftsSettings.getSiftDownloadDirectory()
+            + pdbId.toLowerCase() + ".xml.gz");
+    if (siftsFile.exists())
+    {
+      // The line below is required for unit testing... don't comment it out!!!
+      System.out.println(">>> SIFTS File already downloaded for " + pdbId);
+
+      if (isFileOlderThanThreshold(siftsFile, THRESHOLD_IN_DAYS))
+      {
+        // System.out.println("Downloaded file is out of date, hence re-downloading...");
+        siftsFile = downloadSiftsFile(pdbId.toLowerCase());
+      }
+      return siftsFile;
+    }
+    siftsFile = downloadSiftsFile(pdbId.toLowerCase());
+    return siftsFile;
+  }
+
+  /**
+   * This method enables checking if a cached file has exceeded a certain
+   * threshold(in days)
+   * 
+   * @param file
+   *          the cached file
+   * @param noOfDays
+   *          the threshold in days
+   * @return
+   */
+  public static boolean isFileOlderThanThreshold(File file, int noOfDays)
+  {
+    Path filePath = file.toPath();
+    BasicFileAttributes attr;
+    int diffInDays = 0;
+    try
+    {
+      attr = Files.readAttributes(filePath, BasicFileAttributes.class);
+      diffInDays = (int) ((new Date().getTime() - attr.lastModifiedTime()
+              .toMillis()) / (1000 * 60 * 60 * 24));
+      // System.out.println("Diff in days : " + diffInDays);
+    } catch (IOException e)
+    {
+      e.printStackTrace();
+    }
+    return noOfDays <= diffInDays;
+  }
+
+  /**
+   * Download a SIFTs XML file for a given PDB Id from an FTP repository
+   * 
+   * @param pdbId
+   * @return downloaded SIFTs XML file
+   * @throws SiftsException
+   */
+  public static File downloadSiftsFile(String pdbId) throws SiftsException
+  {
+    String siftFile = pdbId + ".xml.gz";
+    String siftsFileFTPURL = SIFTS_FTP_BASE_URL + siftFile;
+    String downloadedSiftsFile = SiftsSettings.getSiftDownloadDirectory()
+            + siftFile;
+    File siftsDownloadDir = new File(
+            SiftsSettings.getSiftDownloadDirectory());
+    if (!siftsDownloadDir.exists())
+    {
+      siftsDownloadDir.mkdirs();
+    }
+    try
+    {
+      // System.out.println(">> Download ftp url : " + siftsFileFTPURL);
+      URL url = new URL(siftsFileFTPURL);
+      URLConnection conn = url.openConnection();
+      InputStream inputStream = conn.getInputStream();
+      FileOutputStream outputStream = new FileOutputStream(
+              downloadedSiftsFile);
+      byte[] buffer = new byte[BUFFER_SIZE];
+      int bytesRead = -1;
+      while ((bytesRead = inputStream.read(buffer)) != -1)
+      {
+        outputStream.write(buffer, 0, bytesRead);
+      }
+      outputStream.close();
+      inputStream.close();
+      // System.out.println(">>> File downloaded : " + downloadedSiftsFile);
+    } catch (IOException ex)
+    {
+      throw new SiftsException(ex.getMessage());
+    }
+    return new File(downloadedSiftsFile);
+  }
+
+  /**
+   * Delete the SIFTs file for the given PDB Id in the local SIFTs download
+   * directory
+   * 
+   * @param pdbId
+   * @return true if the file was deleted or doesn't exist
+   */
+  public static boolean deleteSiftsFileByPDBId(String pdbId)
+  {
+    File siftsFile = new File(SiftsSettings.getSiftDownloadDirectory()
+            + pdbId.toLowerCase() + ".xml.gz");
+    if (siftsFile.exists())
+    {
+      return siftsFile.delete();
+    }
+    return true;
+  }
+
+  /**
+   * Get a valid SIFTs DBRef for the given sequence current SIFTs entry
+   * 
+   * @param seq
+   *          - the target sequence for the operation
+   * @return a valid DBRefEntry that is SIFTs compatible
+   * @throws Exception
+   *           if no valid source DBRefEntry was found for the given sequences
+   */
+  public DBRefEntryI getValidSourceDBRef(SequenceI seq)
+          throws SiftsException
+  {
+    DBRefEntryI sourceDBRef = null;
+    sourceDBRef = seq.getSourceDBRef();
+    if (sourceDBRef != null && isValidDBRefEntry(sourceDBRef))
+    {
+      return sourceDBRef;
+    }
+    else
+    {
+      DBRefEntry[] dbRefs = seq.getDBRefs();
+      if (dbRefs == null || dbRefs.length < 1)
+      {
+        throw new SiftsException("Could not get source DB Ref");
+      }
+
+      for (DBRefEntryI dbRef : dbRefs)
+      {
+        if (dbRef == null || dbRef.getAccessionId() == null
+                || dbRef.getSource() == null)
+        {
+          continue;
+        }
+        if (isFoundInSiftsEntry(dbRef.getAccessionId())
+                && (dbRef.getSource().equalsIgnoreCase(DBRefSource.UNIPROT) || dbRef
+                        .getSource().equalsIgnoreCase(DBRefSource.PDB)))
+        {
+          return dbRef;
+        }
+      }
+    }
+    if (sourceDBRef != null && isValidDBRefEntry(sourceDBRef))
+    {
+      return sourceDBRef;
+    }
+    throw new SiftsException("Could not get source DB Ref");
+  }
+
+  /**
+   * Check that the DBRef Entry is properly populated and is available in this
+   * SiftClient instance
+   * 
+   * @param entry
+   *          - DBRefEntry to validate
+   * @return true validation is successful otherwise false is returned.
+   */
+  private boolean isValidDBRefEntry(DBRefEntryI entry)
+  {
+    return entry != null && entry.getAccessionId() != null
+            && isFoundInSiftsEntry(entry.getAccessionId());
+  }
+
+  @Override
+  public HashSet<String> getAllMappingAccession()
+  {
+    HashSet<String> accessions = new HashSet<String>();
+    List<Entity> entities = siftsEntry.getEntity();
+    for (Entity entity : entities)
+    {
+      List<Segment> segments = entity.getSegment();
+      for (Segment segment : segments)
+      {
+        List<MapRegion> mapRegions = segment.getListMapRegion()
+                .getMapRegion();
+        for (MapRegion mapRegion : mapRegions)
+        {
+          accessions.add(mapRegion.getDb().getDbAccessionId());
+        }
+      }
+    }
+    return accessions;
+  }
+
+  @Override
+  public StructureMapping getSiftsStructureMapping(SequenceI seq,
+          String pdbFile, String chain) throws SiftsException
+  {
+    structId = (chain == null) ? pdbId : pdbId + "|" + chain;
+    System.out.println("Getting mapping for: " + pdbId + "|" + chain
+            + " : seq- " + seq.getName());
+
+    final StringBuilder mappingDetails = new StringBuilder(128);
+    PrintStream ps = new PrintStream(System.out)
+    {
+      @Override
+      public void print(String x)
+      {
+        mappingDetails.append(x);
+      }
+
+      @Override
+      public void println()
+      {
+        mappingDetails.append(NEWLINE);
+      }
+    };
+    HashMap<Integer, int[]> mapping = getGreedyMapping(chain, seq, ps);
+
+    String mappingOutput = mappingDetails.toString();
+    StructureMapping siftsMapping = new StructureMapping(seq, pdbFile,
+            pdbId, chain, mapping, mappingOutput);
+    return siftsMapping;
+  }
+
+  @Override
+  public HashMap<Integer, int[]> getGreedyMapping(String entityId,
+          SequenceI seq, java.io.PrintStream os) throws SiftsException
+  {
+    ArrayList<Integer> omitNonObserved = new ArrayList<Integer>();
+    int nonObservedShiftIndex = 0;
+    System.out.println("Generating mappings for : " + entityId);
+    Entity entity = null;
+    entity = getEntityById(entityId);
+    String originalSeq = AlignSeq.extractGaps(
+            jalview.util.Comparison.GapChars, seq.getSequenceAsString());
+    HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
+    DBRefEntryI sourceDBRef = seq.getSourceDBRef();
+    if (sourceDBRef == null)
+    {
+      sourceDBRef = getValidSourceDBRef(seq);
+      // TODO ensure sequence start/end is in the same coordinate system and
+      // consistent with the choosen sourceDBRef
+    }
+
+    // set sequence coordinate system - default value is UniProt
+    if (sourceDBRef.getSource().equalsIgnoreCase(DBRefSource.PDB))
+    {
+      seqCoordSys = CoordinateSys.PDB;
+    }
+
+    HashSet<String> dbRefAccessionIdsString = new HashSet<String>();
+    for (DBRefEntry dbref : seq.getDBRefs())
+    {
+      dbRefAccessionIdsString.add(dbref.getAccessionId().toLowerCase());
+    }
+    dbRefAccessionIdsString.add(sourceDBRef.getAccessionId().toLowerCase());
+
+    curDBRefAccessionIdsString = dbRefAccessionIdsString;
+    curSourceDBRef = sourceDBRef.getAccessionId();
+
+    TreeMap<Integer, String> resNumMap = new TreeMap<Integer, String>();
+    List<Segment> segments = entity.getSegment();
+    for (Segment segment : segments)
+    {
+      segStartEnd = segment.getStart() + " - " + segment.getEnd();
+      System.out.println("Mappging segments : " + segment.getSegId() + "\\"
+              + segStartEnd);
+      List<Residue> residues = segment.getListResidue().getResidue();
+      for (Residue residue : residues)
+      {
+        int currSeqIndex = UNASSIGNED;
+        List<CrossRefDb> cRefDbs = residue.getCrossRefDb();
+        CrossRefDb pdbRefDb = null;
+        for (CrossRefDb cRefDb : cRefDbs)
+        {
+          if (cRefDb.getDbSource().equalsIgnoreCase(DBRefSource.PDB))
+          {
+            pdbRefDb = cRefDb;
+          }
+          if (cRefDb.getDbCoordSys()
+                  .equalsIgnoreCase(seqCoordSys.getName())
+                  && isAccessionMatched(cRefDb.getDbAccessionId()))
+          {
+            String resNumIndexString = cRefDb.getDbResNum()
+                    .equalsIgnoreCase("None") ? String.valueOf(UNASSIGNED)
+                    : cRefDb.getDbResNum();
+            try
+            {
+              currSeqIndex = Integer.valueOf(resNumIndexString);
+            } catch (NumberFormatException nfe)
+            {
+              currSeqIndex = Integer.valueOf(resNumIndexString
+                      .split("[a-zA-Z]")[0]);
+            }
+            if (pdbRefDb != null)
+            {
+              break;// exit loop if pdb and uniprot are already found
+            }
+          }
+        }
+        if (currSeqIndex == UNASSIGNED)
+        {
+          continue;
+        }
+        if (currSeqIndex > seq.getStart() && currSeqIndex <= seq.getEnd())
+        {
+          int resNum;
+          try
+          {
+            resNum = (pdbRefDb == null) ? Integer.valueOf(residue
+                    .getDbResNum()) : Integer.valueOf(pdbRefDb
+                    .getDbResNum());
+          } catch (NumberFormatException nfe)
+          {
+            resNum = (pdbRefDb == null) ? Integer.valueOf(residue
+                    .getDbResNum()) : Integer.valueOf(pdbRefDb
+                    .getDbResNum().split("[a-zA-Z]")[0]);
+          }
+
+          if (isResidueObserved(residue)
+                  || seqCoordSys == CoordinateSys.UNIPROT)
+          {
+            char resCharCode = ResidueProperties
+                    .getSingleCharacterCode(residue.getDbResName());
+            resNumMap.put(currSeqIndex, String.valueOf(resCharCode));
+          }
+          else
+          {
+            omitNonObserved.add(currSeqIndex);
+            ++nonObservedShiftIndex;
+          }
+          mapping.put(currSeqIndex - nonObservedShiftIndex, new int[] {
+              Integer.valueOf(resNum), UNASSIGNED });
+        }
+      }
+    }
+    try
+    {
+      populateAtomPositions(entityId, mapping);
+    } catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+    if (seqCoordSys == CoordinateSys.UNIPROT)
+    {
+      padWithGaps(resNumMap, omitNonObserved);
+    }
+    int seqStart = UNASSIGNED;
+    int seqEnd = UNASSIGNED;
+    int pdbStart = UNASSIGNED;
+    int pdbEnd = UNASSIGNED;
+
+    Integer[] keys = mapping.keySet().toArray(new Integer[0]);
+    Arrays.sort(keys);
+    seqStart = keys[0];
+    seqEnd = keys[keys.length - 1];
+
+    String matchedSeq = originalSeq;
+    if (seqStart != UNASSIGNED)
+    {
+      pdbStart = mapping.get(seqStart)[PDB_RES_POS];
+      pdbEnd = mapping.get(seqEnd)[PDB_RES_POS];
+      int orignalSeqStart = seq.getStart();
+      if (orignalSeqStart >= 1)
+      {
+        int subSeqStart = seqStart - orignalSeqStart;
+        int subSeqEnd = seqEnd - (orignalSeqStart - 1);
+        subSeqEnd = originalSeq.length() < subSeqEnd ? originalSeq.length()
+                : subSeqEnd;
+        matchedSeq = originalSeq.substring(subSeqStart, subSeqEnd);
+      }
+    }
+
+    StringBuilder targetStrucSeqs = new StringBuilder();
+    for (String res : resNumMap.values())
+    {
+      targetStrucSeqs.append(res);
+    }
+
+    if (os != null)
+    {
+      MappingOutputPojo mop = new MappingOutputPojo();
+      mop.setSeqStart(seqStart);
+      mop.setSeqEnd(seqEnd);
+      mop.setSeqName(seq.getName());
+      mop.setSeqResidue(matchedSeq);
+
+      mop.setStrStart(pdbStart);
+      mop.setStrEnd(pdbEnd);
+      mop.setStrName(structId);
+      mop.setStrResidue(targetStrucSeqs.toString());
+
+      mop.setType("pep");
+      os.print(getMappingOutput(mop).toString());
+    }
+    return mapping;
+  }
+
+  /**
+   * Checks if the residue instance is marked 'Not_observed' or not
+   * 
+   * @param residue
+   * @return
+   */
+  private boolean isResidueObserved(Residue residue)
+  {
+    String annotation = getResidueAnnotaiton(residue,
+            ResidueDetailType.ANNOTATION);
+    if (annotation == null)
+    {
+      return true;
+    }
+    if (!annotation.equalsIgnoreCase(NOT_FOUND)
+            && annotation.equalsIgnoreCase(NOT_OBSERVED))
+    {
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Get annotation String for a given residue and annotation type
+   * 
+   * @param residue
+   * @param type
+   * @return
+   */
+  private String getResidueAnnotaiton(Residue residue,
+          ResidueDetailType type)
+  {
+    List<ResidueDetail> resDetails = residue.getResidueDetail();
+    for (ResidueDetail resDetail : resDetails)
+    {
+      if (resDetail.getProperty().equalsIgnoreCase(type.getCode()))
+      {
+        return resDetail.getContent();
+      }
+    }
+    return NOT_FOUND;
+  }
+
+  @Override
+  public boolean isAccessionMatched(String accession)
+  {
+    boolean isStrictMatch = true;
+    return isStrictMatch ? curSourceDBRef.equalsIgnoreCase(accession)
+            : curDBRefAccessionIdsString.contains(accession.toLowerCase());
+  }
+
+  private boolean isFoundInSiftsEntry(String accessionId)
+  {
+    return accessionId != null
+            && getAllMappingAccession().contains(accessionId);
+  }
+
+  /**
+   * Pad omitted residue positions in PDB sequence with gaps
+   * 
+   * @param resNumMap
+   */
+  void padWithGaps(TreeMap<Integer, String> resNumMap,
+          ArrayList<Integer> omitNonObserved)
+  {
+    if (resNumMap == null || resNumMap.isEmpty())
+    {
+      return;
+    }
+    Integer[] keys = resNumMap.keySet().toArray(new Integer[0]);
+    Arrays.sort(keys);
+    int firstIndex = keys[0];
+    int lastIndex = keys[keys.length - 1];
+    System.out.println("Min value " + firstIndex);
+    System.out.println("Max value " + lastIndex);
+    for (int x = firstIndex; x <= lastIndex; x++)
+    {
+      if (!resNumMap.containsKey(x) && !omitNonObserved.contains(x))
+      {
+        resNumMap.put(x, "-");
+      }
+    }
+  }
+
+  /**
+   * 
+   * @param chainId
+   *          Target chain to populate mapping of its atom positions.
+   * @param mapping
+   *          Two dimension array of residue index versus atom position
+   * @throws IllegalArgumentException
+   *           Thrown if chainId or mapping is null
+   */
+  void populateAtomPositions(String chainId, HashMap<Integer, int[]> mapping)
+          throws IllegalArgumentException
+  {
+    PDBChain chain = pdb.findChain(chainId);
+    if (chain == null || mapping == null)
+    {
+      throw new IllegalArgumentException(
+              "Chain id or mapping must not be null.");
+    }
+    for (int[] map : mapping.values())
+    {
+      if (map[PDB_RES_POS] != UNASSIGNED)
+      {
+        map[PDB_ATOM_POS] = getAtomIndex(map[PDB_RES_POS], chain.atoms);
+      }
+    }
+  }
+
+  /**
+   * 
+   * @param residueIndex
+   *          The residue index used for the search
+   * @param atoms
+   *          A collection of Atom to search
+   * @return atom position for the given residue index
+   */
+  int getAtomIndex(int residueIndex, Collection<Atom> atoms)
+  {
+    if (atoms == null)
+    {
+      throw new IllegalArgumentException(
+              "atoms collection must not be null!");
+    }
+    for (Atom atom : atoms)
+    {
+      if (atom.resNumber == residueIndex)
+      {
+        return atom.atomIndex;
+      }
+    }
+    return UNASSIGNED;
+  }
+
+  @Override
+  public Entity getEntityById(String id) throws SiftsException
+  {
+    List<Entity> entities = siftsEntry.getEntity();
+    for (Entity entity : entities)
+    {
+      if (!entity.getEntityId().equalsIgnoreCase(id))
+      {
+        continue;
+      }
+      return entity;
+    }
+    Entity entity = getEntityByMostOptimalMatchedId(id);
+    if (entity != null)
+    {
+      return entity;
+    }
+    throw new SiftsException("Entity " + id + " not found");
+  }
+
+  /**
+   * This method was added because EntityId is NOT always equal to ChainId.
+   * Hence, it provides the logic to greedily detect the "true" Entity for a
+   * given chainId where discrepancies exist.
+   * 
+   * @param chainId
+   * @return
+   */
+  public Entity getEntityByMostOptimalMatchedId(String chainId)
+  {
+    System.out
+            .println("--------------> advanced greedy entityId matching block entered..");
+    List<Entity> entities = siftsEntry.getEntity();
+    SiftsEntitySortPojo[] sPojo = new SiftsEntitySortPojo[entities.size()];
+    int count = 0;
+    for (Entity entity : entities)
+    {
+      sPojo[count] = new SiftsEntitySortPojo();
+      sPojo[count].entityId = entity.getEntityId();
+
+      List<Segment> segments = entity.getSegment();
+      for (Segment segment : segments)
+      {
+        List<Residue> residues = segment.getListResidue().getResidue();
+        for (Residue residue : residues)
+        {
+          List<CrossRefDb> cRefDbs = residue.getCrossRefDb();
+          for (CrossRefDb cRefDb : cRefDbs)
+          {
+            if (!cRefDb.getDbSource().equalsIgnoreCase("PDB"))
+            {
+              continue;
+            }
+            ++sPojo[count].resCount;
+            if (cRefDb.getDbChainId().equalsIgnoreCase(chainId))
+            {
+              ++sPojo[count].chainIdFreq;
+            }
+          }
+        }
+      }
+      sPojo[count].pid = 100 * (sPojo[count].chainIdFreq / sPojo[count].resCount);
+      ++count;
+    }
+    Arrays.sort(sPojo, Collections.reverseOrder());
+    System.out.println("highest matched entity : " + sPojo[0].entityId);
+    System.out.println("highest matched pid : " + sPojo[0].pid);
+
+    if (sPojo[0].entityId != null)
+    {
+      for (Entity entity : entities)
+      {
+        if (!entity.getEntityId().equalsIgnoreCase(sPojo[0].entityId))
+        {
+          continue;
+        }
+        return entity;
+      }
+    }
+    return null;
+  }
+
+  public class SiftsEntitySortPojo implements
+          Comparable<SiftsEntitySortPojo>
+  {
+    public String entityId;
+
+    public int chainIdFreq;
+
+    public int pid;
+
+    public int resCount;
+
+    @Override
+    public int compareTo(SiftsEntitySortPojo o)
+    {
+      return this.pid - o.pid;
+    }
+  }
+
+  @Override
+  public String[] getEntryDBs()
+  {
+    System.out.println("\nListing DB entries...");
+    List<String> availDbs = new ArrayList<String>();
+    List<Db> dbs = siftsEntry.getListDB().getDb();
+    for (Db db : dbs)
+    {
+      availDbs.add(db.getDbSource());
+      System.out.println(db.getDbSource() + " | " + db.getDbCoordSys());
+    }
+    return availDbs.toArray(new String[0]);
+  }
+
+  @Override
+  public StringBuffer getMappingOutput(MappingOutputPojo mp)
+          throws SiftsException
+  {
+    String seqRes = mp.getSeqResidue();
+    String seqName = mp.getSeqName();
+    int sStart = mp.getSeqStart();
+    int sEnd = mp.getSeqEnd();
+
+    String strRes = mp.getStrResidue();
+    String strName = mp.getStrName();
+    int pdbStart = mp.getStrStart();
+    int pdbEnd = mp.getStrEnd();
+
+    String type = mp.getType();
+
+    int maxid = (seqName.length() >= strName.length()) ? seqName.length()
+            : strName.length();
+    int len = 72 - maxid - 1;
+
+    int nochunks = ((seqRes.length()) / len)
+            + ((seqRes.length()) % len > 0 ? 1 : 0);
+    // output mappings
+    StringBuffer output = new StringBuffer();
+    output.append(NEWLINE);
+    output.append("Sequence âŸ· Structure mapping details").append(NEWLINE);
+    output.append("Method: SIFTS");
+    output.append(NEWLINE).append(NEWLINE);
+
+    output.append(new Format("%" + maxid + "s").form(seqName));
+    output.append(" :  ");
+    output.append(String.valueOf(sStart));
+    output.append(" - ");
+    output.append(String.valueOf(sEnd));
+    output.append(" Maps to ");
+    output.append(NEWLINE);
+    output.append(new Format("%" + maxid + "s").form(structId));
+    output.append(" :  ");
+    output.append(String.valueOf(pdbStart));
+    output.append(" - ");
+    output.append(String.valueOf(pdbEnd));
+    output.append(NEWLINE).append(NEWLINE);
+
+    int matchedSeqCount = 0;
+    for (int j = 0; j < nochunks; j++)
+    {
+      // Print the first aligned sequence
+      output.append(new Format("%" + (maxid) + "s").form(seqName)).append(
+              " ");
+
+      for (int i = 0; i < len; i++)
+      {
+        if ((i + (j * len)) < seqRes.length())
+        {
+          output.append(seqRes.charAt(i + (j * len)));
+        }
+      }
+
+      output.append(NEWLINE);
+      output.append(new Format("%" + (maxid) + "s").form(" ")).append(" ");
+
+      // Print out the matching chars
+      for (int i = 0; i < len; i++)
+      {
+        try
+        {
+          if ((i + (j * len)) < seqRes.length())
+          {
+            if (seqRes.charAt(i + (j * len)) == strRes
+                    .charAt(i + (j * len))
+                    && !jalview.util.Comparison.isGap(seqRes.charAt(i
+                            + (j * len))))
+            {
+              matchedSeqCount++;
+              output.append("|");
+            }
+            else if (type.equals("pep"))
+            {
+              if (ResidueProperties.getPAM250(seqRes.charAt(i + (j * len)),
+                      strRes.charAt(i + (j * len))) > 0)
+              {
+                output.append(".");
+              }
+              else
+              {
+                output.append(" ");
+              }
+            }
+            else
+            {
+              output.append(" ");
+            }
+          }
+        } catch (IndexOutOfBoundsException e)
+        {
+          continue;
+        }
+      }
+      // Now print the second aligned sequence
+      output = output.append(NEWLINE);
+      output = output.append(new Format("%" + (maxid) + "s").form(strName))
+              .append(" ");
+      for (int i = 0; i < len; i++)
+      {
+        if ((i + (j * len)) < strRes.length())
+        {
+          output.append(strRes.charAt(i + (j * len)));
+        }
+      }
+      output.append(NEWLINE).append(NEWLINE);
+    }
+    float pid = (float) matchedSeqCount / seqRes.length() * 100;
+    if (pid < 2)
+    {
+      throw new SiftsException("Low PID detected for SIFTs mapping...");
+    }
+    output.append("Length of alignment = " + seqRes.length()).append(
+            NEWLINE);
+    output.append(new Format("Percentage ID = %2.2f").form(pid));
+    output.append(NEWLINE);
+    return output;
+  }
+
+  @Override
+  public int getEntityCount()
+  {
+    return siftsEntry.getEntity().size();
+  }
+
+  @Override
+  public String getDbAccessionId()
+  {
+    return siftsEntry.getDbAccessionId();
+  }
+
+  @Override
+  public String getDbCoordSys()
+  {
+    return siftsEntry.getDbCoordSys();
+  }
+
+  @Override
+  public String getDbEvidence()
+  {
+    return siftsEntry.getDbEvidence();
+  }
+
+  @Override
+  public String getDbSource()
+  {
+    return siftsEntry.getDbSource();
+  }
+
+  @Override
+  public String getDbVersion()
+  {
+    return siftsEntry.getDbVersion();
+  }
+
+}
diff --git a/src/jalview/ws/sifts/SiftsException.java b/src/jalview/ws/sifts/SiftsException.java
new file mode 100644 (file)
index 0000000..2923541
--- /dev/null
@@ -0,0 +1,12 @@
+package jalview.ws.sifts;
+
+public class SiftsException extends Exception
+{
+
+  private static final long serialVersionUID = 1L;
+
+  public SiftsException(String message)
+  {
+    super(message);
+  }
+}
diff --git a/src/jalview/ws/sifts/SiftsSettings.java b/src/jalview/ws/sifts/SiftsSettings.java
new file mode 100644 (file)
index 0000000..5554658
--- /dev/null
@@ -0,0 +1,28 @@
+package jalview.ws.sifts;
+
+public class SiftsSettings
+{
+  private static boolean mapWithSifts = false;
+
+  private static String siftDownloadDirectory;
+
+  public static boolean isMapWithSifts()
+  {
+    return mapWithSifts;
+  }
+
+  public static void setMapWithSifts(boolean mapWithSifts)
+  {
+    SiftsSettings.mapWithSifts = mapWithSifts;
+  }
+
+  public static String getSiftDownloadDirectory()
+  {
+    return siftDownloadDirectory;
+  }
+
+  public static void setSiftDownloadDirectory(String siftDownloadDirectory)
+  {
+    SiftsSettings.siftDownloadDirectory = siftDownloadDirectory;
+  }
+}
diff --git a/src/jalview/xml/binding/sifts/Alignment.java b/src/jalview/xml/binding/sifts/Alignment.java
new file mode 100644 (file)
index 0000000..650ea19
--- /dev/null
@@ -0,0 +1,2310 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
+// Any modifications to this file will be lost upon recompilation of the source schema. 
+// Generated on: 2015.10.09 at 03:18:33 PM BST 
+//
+
+
+package jalview.xml.binding.sifts;
+
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlValue;
+
+
+/**
+ * <p>Java class for anonymous complex type.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * 
+ * <pre>
+ * &lt;complexType>
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="alignObject" maxOccurs="unbounded">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;sequence>
+ *                   &lt;element name="alignObjectDetail" maxOccurs="unbounded" minOccurs="0">
+ *                     &lt;complexType>
+ *                       &lt;complexContent>
+ *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+ *                         &lt;/restriction>
+ *                       &lt;/complexContent>
+ *                     &lt;/complexType>
+ *                   &lt;/element>
+ *                   &lt;element name="sequence" minOccurs="0">
+ *                     &lt;complexType>
+ *                       &lt;complexContent>
+ *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+ *                         &lt;/restriction>
+ *                       &lt;/complexContent>
+ *                     &lt;/complexType>
+ *                   &lt;/element>
+ *                 &lt;/sequence>
+ *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbRef"/>
+ *                 &lt;attribute name="objectVersion" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                 &lt;attribute name="intObjectId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                 &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *         &lt;element name="score" maxOccurs="unbounded" minOccurs="0">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;attribute name="methodName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                 &lt;attribute name="scoreValue" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *         &lt;element name="block" maxOccurs="unbounded">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;sequence>
+ *                   &lt;element name="segment" maxOccurs="unbounded">
+ *                     &lt;complexType>
+ *                       &lt;complexContent>
+ *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                           &lt;sequence minOccurs="0">
+ *                             &lt;element name="cigar" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}cigarstring"/>
+ *                           &lt;/sequence>
+ *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+ *                           &lt;attribute name="intObjectId" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
+ *                           &lt;attribute name="strand" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
+ *                         &lt;/restriction>
+ *                       &lt;/complexContent>
+ *                     &lt;/complexType>
+ *                   &lt;/element>
+ *                 &lt;/sequence>
+ *                 &lt;attribute name="blockScore" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                 &lt;attribute name="blockOrder" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *         &lt;element name="geo3d" maxOccurs="unbounded" minOccurs="0">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;sequence>
+ *                   &lt;element name="vector">
+ *                     &lt;complexType>
+ *                       &lt;complexContent>
+ *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                           &lt;attribute name="x" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+ *                           &lt;attribute name="y" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+ *                           &lt;attribute name="z" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+ *                         &lt;/restriction>
+ *                       &lt;/complexContent>
+ *                     &lt;/complexType>
+ *                   &lt;/element>
+ *                   &lt;element name="matrix" maxOccurs="unbounded">
+ *                     &lt;complexType>
+ *                       &lt;complexContent>
+ *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                           &lt;sequence>
+ *                             &lt;element name="max11">
+ *                               &lt;complexType>
+ *                                 &lt;complexContent>
+ *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                     &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+ *                                   &lt;/restriction>
+ *                                 &lt;/complexContent>
+ *                               &lt;/complexType>
+ *                             &lt;/element>
+ *                             &lt;element name="max12">
+ *                               &lt;complexType>
+ *                                 &lt;complexContent>
+ *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                     &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+ *                                   &lt;/restriction>
+ *                                 &lt;/complexContent>
+ *                               &lt;/complexType>
+ *                             &lt;/element>
+ *                             &lt;element name="max13">
+ *                               &lt;complexType>
+ *                                 &lt;complexContent>
+ *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                     &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+ *                                   &lt;/restriction>
+ *                                 &lt;/complexContent>
+ *                               &lt;/complexType>
+ *                             &lt;/element>
+ *                             &lt;element name="max21">
+ *                               &lt;complexType>
+ *                                 &lt;complexContent>
+ *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                     &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+ *                                   &lt;/restriction>
+ *                                 &lt;/complexContent>
+ *                               &lt;/complexType>
+ *                             &lt;/element>
+ *                             &lt;element name="max22">
+ *                               &lt;complexType>
+ *                                 &lt;complexContent>
+ *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                     &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+ *                                   &lt;/restriction>
+ *                                 &lt;/complexContent>
+ *                               &lt;/complexType>
+ *                             &lt;/element>
+ *                             &lt;element name="max23">
+ *                               &lt;complexType>
+ *                                 &lt;complexContent>
+ *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                     &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+ *                                   &lt;/restriction>
+ *                                 &lt;/complexContent>
+ *                               &lt;/complexType>
+ *                             &lt;/element>
+ *                             &lt;element name="max31">
+ *                               &lt;complexType>
+ *                                 &lt;complexContent>
+ *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                     &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+ *                                   &lt;/restriction>
+ *                                 &lt;/complexContent>
+ *                               &lt;/complexType>
+ *                             &lt;/element>
+ *                             &lt;element name="max32">
+ *                               &lt;complexType>
+ *                                 &lt;complexContent>
+ *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                     &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+ *                                   &lt;/restriction>
+ *                                 &lt;/complexContent>
+ *                               &lt;/complexType>
+ *                             &lt;/element>
+ *                             &lt;element name="max33">
+ *                               &lt;complexType>
+ *                                 &lt;complexContent>
+ *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                     &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+ *                                   &lt;/restriction>
+ *                                 &lt;/complexContent>
+ *                               &lt;/complexType>
+ *                             &lt;/element>
+ *                           &lt;/sequence>
+ *                         &lt;/restriction>
+ *                       &lt;/complexContent>
+ *                     &lt;/complexType>
+ *                   &lt;/element>
+ *                 &lt;/sequence>
+ *                 &lt;attribute name="intObjectId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *       &lt;/sequence>
+ *       &lt;attribute name="alignType" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ * 
+ * 
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {
+    "alignObject",
+    "score",
+    "block",
+    "geo3D"
+})
+@XmlRootElement(name = "alignment")
+public class Alignment {
+
+    @XmlElement(required = true)
+    protected List<Alignment.AlignObject> alignObject;
+    protected List<Alignment.Score> score;
+    @XmlElement(required = true)
+    protected List<Alignment.Block> block;
+    @XmlElement(name = "geo3d")
+    protected List<Alignment.Geo3D> geo3D;
+    @XmlAttribute(name = "alignType", required = true)
+    protected String alignType;
+
+    /**
+     * Gets the value of the alignObject property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the alignObject property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getAlignObject().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link Alignment.AlignObject }
+     * 
+     * 
+     */
+    public List<Alignment.AlignObject> getAlignObject() {
+        if (alignObject == null) {
+            alignObject = new ArrayList<Alignment.AlignObject>();
+        }
+        return this.alignObject;
+    }
+
+    /**
+     * Gets the value of the score property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the score property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getScore().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link Alignment.Score }
+     * 
+     * 
+     */
+    public List<Alignment.Score> getScore() {
+        if (score == null) {
+            score = new ArrayList<Alignment.Score>();
+        }
+        return this.score;
+    }
+
+    /**
+     * Gets the value of the block property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the block property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getBlock().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link Alignment.Block }
+     * 
+     * 
+     */
+    public List<Alignment.Block> getBlock() {
+        if (block == null) {
+            block = new ArrayList<Alignment.Block>();
+        }
+        return this.block;
+    }
+
+    /**
+     * Gets the value of the geo3D property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the geo3D property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getGeo3D().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link Alignment.Geo3D }
+     * 
+     * 
+     */
+    public List<Alignment.Geo3D> getGeo3D() {
+        if (geo3D == null) {
+            geo3D = new ArrayList<Alignment.Geo3D>();
+        }
+        return this.geo3D;
+    }
+
+    /**
+     * Gets the value of the alignType property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getAlignType() {
+        return alignType;
+    }
+
+    /**
+     * Sets the value of the alignType property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setAlignType(String value) {
+        this.alignType = value;
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * 
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;sequence>
+     *         &lt;element name="alignObjectDetail" maxOccurs="unbounded" minOccurs="0">
+     *           &lt;complexType>
+     *             &lt;complexContent>
+     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+     *               &lt;/restriction>
+     *             &lt;/complexContent>
+     *           &lt;/complexType>
+     *         &lt;/element>
+     *         &lt;element name="sequence" minOccurs="0">
+     *           &lt;complexType>
+     *             &lt;complexContent>
+     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+     *               &lt;/restriction>
+     *             &lt;/complexContent>
+     *           &lt;/complexType>
+     *         &lt;/element>
+     *       &lt;/sequence>
+     *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbRef"/>
+     *       &lt;attribute name="objectVersion" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       &lt;attribute name="intObjectId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       &lt;attribute name="type" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     * 
+     * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = {
+        "alignObjectDetail",
+        "sequence"
+    })
+    public static class AlignObject {
+
+        protected List<Alignment.AlignObject.AlignObjectDetail> alignObjectDetail;
+        protected Alignment.AlignObject.Sequence sequence;
+        @XmlAttribute(name = "objectVersion", required = true)
+        protected String objectVersion;
+        @XmlAttribute(name = "intObjectId", required = true)
+        protected String intObjectId;
+        @XmlAttribute(name = "type")
+        protected String type;
+        @XmlAttribute(name = "dbSource", required = true)
+        protected String dbSource;
+        @XmlAttribute(name = "dbCoordSys", required = true)
+        protected String dbCoordSys;
+        @XmlAttribute(name = "dbAccessionId", required = true)
+        protected String dbAccessionId;
+        @XmlAttribute(name = "dbEvidence")
+        protected String dbEvidence;
+        @XmlAttribute(name = "dbVersion")
+        protected String dbVersion;
+
+        /**
+         * Gets the value of the alignObjectDetail property.
+         * 
+         * <p>
+         * This accessor method returns a reference to the live list,
+         * not a snapshot. Therefore any modification you make to the
+         * returned list will be present inside the JAXB object.
+         * This is why there is not a <CODE>set</CODE> method for the alignObjectDetail property.
+         * 
+         * <p>
+         * For example, to add a new item, do as follows:
+         * <pre>
+         *    getAlignObjectDetail().add(newItem);
+         * </pre>
+         * 
+         * 
+         * <p>
+         * Objects of the following type(s) are allowed in the list
+         * {@link Alignment.AlignObject.AlignObjectDetail }
+         * 
+         * 
+         */
+        public List<Alignment.AlignObject.AlignObjectDetail> getAlignObjectDetail() {
+            if (alignObjectDetail == null) {
+                alignObjectDetail = new ArrayList<Alignment.AlignObject.AlignObjectDetail>();
+            }
+            return this.alignObjectDetail;
+        }
+
+        /**
+         * Gets the value of the sequence property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link Alignment.AlignObject.Sequence }
+         *     
+         */
+        public Alignment.AlignObject.Sequence getSequence() {
+            return sequence;
+        }
+
+        /**
+         * Sets the value of the sequence property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link Alignment.AlignObject.Sequence }
+         *     
+         */
+        public void setSequence(Alignment.AlignObject.Sequence value) {
+            this.sequence = value;
+        }
+
+        /**
+         * Gets the value of the objectVersion property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getObjectVersion() {
+            return objectVersion;
+        }
+
+        /**
+         * Sets the value of the objectVersion property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setObjectVersion(String value) {
+            this.objectVersion = value;
+        }
+
+        /**
+         * Gets the value of the intObjectId property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getIntObjectId() {
+            return intObjectId;
+        }
+
+        /**
+         * Sets the value of the intObjectId property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setIntObjectId(String value) {
+            this.intObjectId = value;
+        }
+
+        /**
+         * Gets the value of the type property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getType() {
+            return type;
+        }
+
+        /**
+         * Sets the value of the type property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setType(String value) {
+            this.type = value;
+        }
+
+        /**
+         * Gets the value of the dbSource property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getDbSource() {
+            return dbSource;
+        }
+
+        /**
+         * Sets the value of the dbSource property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setDbSource(String value) {
+            this.dbSource = value;
+        }
+
+        /**
+         * Gets the value of the dbCoordSys property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getDbCoordSys() {
+            return dbCoordSys;
+        }
+
+        /**
+         * Sets the value of the dbCoordSys property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setDbCoordSys(String value) {
+            this.dbCoordSys = value;
+        }
+
+        /**
+         * Gets the value of the dbAccessionId property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getDbAccessionId() {
+            return dbAccessionId;
+        }
+
+        /**
+         * Sets the value of the dbAccessionId property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setDbAccessionId(String value) {
+            this.dbAccessionId = value;
+        }
+
+        /**
+         * Gets the value of the dbEvidence property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getDbEvidence() {
+            return dbEvidence;
+        }
+
+        /**
+         * Sets the value of the dbEvidence property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setDbEvidence(String value) {
+            this.dbEvidence = value;
+        }
+
+        /**
+         * Gets the value of the dbVersion property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getDbVersion() {
+            return dbVersion;
+        }
+
+        /**
+         * Sets the value of the dbVersion property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setDbVersion(String value) {
+            this.dbVersion = value;
+        }
+
+
+        /**
+         * <p>Java class for anonymous complex type.
+         * 
+         * <p>The following schema fragment specifies the expected content contained within this class.
+         * 
+         * <pre>
+         * &lt;complexType>
+         *   &lt;complexContent>
+         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+         *     &lt;/restriction>
+         *   &lt;/complexContent>
+         * &lt;/complexType>
+         * </pre>
+         * 
+         * 
+         */
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "", propOrder = {
+            "content"
+        })
+        public static class AlignObjectDetail {
+
+            @XmlValue
+            protected String content;
+            @XmlAttribute(name = "dbSource")
+            protected String dbSource;
+            @XmlAttribute(name = "property", required = true)
+            protected String property;
+
+            /**
+             * Gets the value of the content property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getContent() {
+                return content;
+            }
+
+            /**
+             * Sets the value of the content property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setContent(String value) {
+                this.content = value;
+            }
+
+            /**
+             * Gets the value of the dbSource property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getDbSource() {
+                return dbSource;
+            }
+
+            /**
+             * Sets the value of the dbSource property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setDbSource(String value) {
+                this.dbSource = value;
+            }
+
+            /**
+             * Gets the value of the property property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getProperty() {
+                return property;
+            }
+
+            /**
+             * Sets the value of the property property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setProperty(String value) {
+                this.property = value;
+            }
+
+        }
+
+
+        /**
+         * <p>Java class for anonymous complex type.
+         * 
+         * <p>The following schema fragment specifies the expected content contained within this class.
+         * 
+         * <pre>
+         * &lt;complexType>
+         *   &lt;complexContent>
+         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+         *     &lt;/restriction>
+         *   &lt;/complexContent>
+         * &lt;/complexType>
+         * </pre>
+         * 
+         * 
+         */
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "", propOrder = {
+            "content"
+        })
+        public static class Sequence {
+
+            @XmlValue
+            protected String content;
+            @XmlAttribute(name = "start")
+            protected String start;
+            @XmlAttribute(name = "end")
+            protected String end;
+
+            /**
+             * Gets the value of the content property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getContent() {
+                return content;
+            }
+
+            /**
+             * Sets the value of the content property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setContent(String value) {
+                this.content = value;
+            }
+
+            /**
+             * Gets the value of the start property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getStart() {
+                return start;
+            }
+
+            /**
+             * Sets the value of the start property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setStart(String value) {
+                this.start = value;
+            }
+
+            /**
+             * Gets the value of the end property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getEnd() {
+                return end;
+            }
+
+            /**
+             * Sets the value of the end property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setEnd(String value) {
+                this.end = value;
+            }
+
+        }
+
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * 
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;sequence>
+     *         &lt;element name="segment" maxOccurs="unbounded">
+     *           &lt;complexType>
+     *             &lt;complexContent>
+     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                 &lt;sequence minOccurs="0">
+     *                   &lt;element name="cigar" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}cigarstring"/>
+     *                 &lt;/sequence>
+     *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+     *                 &lt;attribute name="intObjectId" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
+     *                 &lt;attribute name="strand" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
+     *               &lt;/restriction>
+     *             &lt;/complexContent>
+     *           &lt;/complexType>
+     *         &lt;/element>
+     *       &lt;/sequence>
+     *       &lt;attribute name="blockScore" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       &lt;attribute name="blockOrder" use="required" type="{http://www.w3.org/2001/XMLSchema}integer" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     * 
+     * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = {
+        "segment"
+    })
+    public static class Block {
+
+        @XmlElement(required = true)
+        protected List<Alignment.Block.Segment> segment;
+        @XmlAttribute(name = "blockScore")
+        protected String blockScore;
+        @XmlAttribute(name = "blockOrder", required = true)
+        protected BigInteger blockOrder;
+
+        /**
+         * Gets the value of the segment property.
+         * 
+         * <p>
+         * This accessor method returns a reference to the live list,
+         * not a snapshot. Therefore any modification you make to the
+         * returned list will be present inside the JAXB object.
+         * This is why there is not a <CODE>set</CODE> method for the segment property.
+         * 
+         * <p>
+         * For example, to add a new item, do as follows:
+         * <pre>
+         *    getSegment().add(newItem);
+         * </pre>
+         * 
+         * 
+         * <p>
+         * Objects of the following type(s) are allowed in the list
+         * {@link Alignment.Block.Segment }
+         * 
+         * 
+         */
+        public List<Alignment.Block.Segment> getSegment() {
+            if (segment == null) {
+                segment = new ArrayList<Alignment.Block.Segment>();
+            }
+            return this.segment;
+        }
+
+        /**
+         * Gets the value of the blockScore property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getBlockScore() {
+            return blockScore;
+        }
+
+        /**
+         * Sets the value of the blockScore property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setBlockScore(String value) {
+            this.blockScore = value;
+        }
+
+        /**
+         * Gets the value of the blockOrder property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link BigInteger }
+         *     
+         */
+        public BigInteger getBlockOrder() {
+            return blockOrder;
+        }
+
+        /**
+         * Sets the value of the blockOrder property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link BigInteger }
+         *     
+         */
+        public void setBlockOrder(BigInteger value) {
+            this.blockOrder = value;
+        }
+
+
+        /**
+         * <p>Java class for anonymous complex type.
+         * 
+         * <p>The following schema fragment specifies the expected content contained within this class.
+         * 
+         * <pre>
+         * &lt;complexType>
+         *   &lt;complexContent>
+         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *       &lt;sequence minOccurs="0">
+         *         &lt;element name="cigar" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}cigarstring"/>
+         *       &lt;/sequence>
+         *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+         *       &lt;attribute name="intObjectId" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
+         *       &lt;attribute name="strand" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
+         *     &lt;/restriction>
+         *   &lt;/complexContent>
+         * &lt;/complexType>
+         * </pre>
+         * 
+         * 
+         */
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "", propOrder = {
+            "cigar"
+        })
+        public static class Segment {
+
+            protected String cigar;
+            @XmlAttribute(name = "intObjectId", required = true)
+            @XmlSchemaType(name = "anySimpleType")
+            protected String intObjectId;
+            @XmlAttribute(name = "strand")
+            @XmlSchemaType(name = "anySimpleType")
+            protected String strand;
+            @XmlAttribute(name = "start")
+            protected String start;
+            @XmlAttribute(name = "end")
+            protected String end;
+
+            /**
+             * Gets the value of the cigar property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getCigar() {
+                return cigar;
+            }
+
+            /**
+             * Sets the value of the cigar property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setCigar(String value) {
+                this.cigar = value;
+            }
+
+            /**
+             * Gets the value of the intObjectId property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getIntObjectId() {
+                return intObjectId;
+            }
+
+            /**
+             * Sets the value of the intObjectId property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setIntObjectId(String value) {
+                this.intObjectId = value;
+            }
+
+            /**
+             * Gets the value of the strand property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getStrand() {
+                return strand;
+            }
+
+            /**
+             * Sets the value of the strand property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setStrand(String value) {
+                this.strand = value;
+            }
+
+            /**
+             * Gets the value of the start property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getStart() {
+                return start;
+            }
+
+            /**
+             * Sets the value of the start property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setStart(String value) {
+                this.start = value;
+            }
+
+            /**
+             * Gets the value of the end property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getEnd() {
+                return end;
+            }
+
+            /**
+             * Sets the value of the end property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setEnd(String value) {
+                this.end = value;
+            }
+
+        }
+
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * 
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;sequence>
+     *         &lt;element name="vector">
+     *           &lt;complexType>
+     *             &lt;complexContent>
+     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                 &lt;attribute name="x" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *                 &lt;attribute name="y" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *                 &lt;attribute name="z" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *               &lt;/restriction>
+     *             &lt;/complexContent>
+     *           &lt;/complexType>
+     *         &lt;/element>
+     *         &lt;element name="matrix" maxOccurs="unbounded">
+     *           &lt;complexType>
+     *             &lt;complexContent>
+     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                 &lt;sequence>
+     *                   &lt;element name="max11">
+     *                     &lt;complexType>
+     *                       &lt;complexContent>
+     *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                           &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *                         &lt;/restriction>
+     *                       &lt;/complexContent>
+     *                     &lt;/complexType>
+     *                   &lt;/element>
+     *                   &lt;element name="max12">
+     *                     &lt;complexType>
+     *                       &lt;complexContent>
+     *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                           &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *                         &lt;/restriction>
+     *                       &lt;/complexContent>
+     *                     &lt;/complexType>
+     *                   &lt;/element>
+     *                   &lt;element name="max13">
+     *                     &lt;complexType>
+     *                       &lt;complexContent>
+     *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                           &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *                         &lt;/restriction>
+     *                       &lt;/complexContent>
+     *                     &lt;/complexType>
+     *                   &lt;/element>
+     *                   &lt;element name="max21">
+     *                     &lt;complexType>
+     *                       &lt;complexContent>
+     *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                           &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *                         &lt;/restriction>
+     *                       &lt;/complexContent>
+     *                     &lt;/complexType>
+     *                   &lt;/element>
+     *                   &lt;element name="max22">
+     *                     &lt;complexType>
+     *                       &lt;complexContent>
+     *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                           &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *                         &lt;/restriction>
+     *                       &lt;/complexContent>
+     *                     &lt;/complexType>
+     *                   &lt;/element>
+     *                   &lt;element name="max23">
+     *                     &lt;complexType>
+     *                       &lt;complexContent>
+     *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                           &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *                         &lt;/restriction>
+     *                       &lt;/complexContent>
+     *                     &lt;/complexType>
+     *                   &lt;/element>
+     *                   &lt;element name="max31">
+     *                     &lt;complexType>
+     *                       &lt;complexContent>
+     *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                           &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *                         &lt;/restriction>
+     *                       &lt;/complexContent>
+     *                     &lt;/complexType>
+     *                   &lt;/element>
+     *                   &lt;element name="max32">
+     *                     &lt;complexType>
+     *                       &lt;complexContent>
+     *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                           &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *                         &lt;/restriction>
+     *                       &lt;/complexContent>
+     *                     &lt;/complexType>
+     *                   &lt;/element>
+     *                   &lt;element name="max33">
+     *                     &lt;complexType>
+     *                       &lt;complexContent>
+     *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                           &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+     *                         &lt;/restriction>
+     *                       &lt;/complexContent>
+     *                     &lt;/complexType>
+     *                   &lt;/element>
+     *                 &lt;/sequence>
+     *               &lt;/restriction>
+     *             &lt;/complexContent>
+     *           &lt;/complexType>
+     *         &lt;/element>
+     *       &lt;/sequence>
+     *       &lt;attribute name="intObjectId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     * 
+     * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = {
+        "vector",
+        "matrix"
+    })
+    public static class Geo3D {
+
+        @XmlElement(required = true)
+        protected Alignment.Geo3D.Vector vector;
+        @XmlElement(required = true)
+        protected List<Alignment.Geo3D.Matrix> matrix;
+        @XmlAttribute(name = "intObjectId", required = true)
+        protected String intObjectId;
+
+        /**
+         * Gets the value of the vector property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link Alignment.Geo3D.Vector }
+         *     
+         */
+        public Alignment.Geo3D.Vector getVector() {
+            return vector;
+        }
+
+        /**
+         * Sets the value of the vector property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link Alignment.Geo3D.Vector }
+         *     
+         */
+        public void setVector(Alignment.Geo3D.Vector value) {
+            this.vector = value;
+        }
+
+        /**
+         * Gets the value of the matrix property.
+         * 
+         * <p>
+         * This accessor method returns a reference to the live list,
+         * not a snapshot. Therefore any modification you make to the
+         * returned list will be present inside the JAXB object.
+         * This is why there is not a <CODE>set</CODE> method for the matrix property.
+         * 
+         * <p>
+         * For example, to add a new item, do as follows:
+         * <pre>
+         *    getMatrix().add(newItem);
+         * </pre>
+         * 
+         * 
+         * <p>
+         * Objects of the following type(s) are allowed in the list
+         * {@link Alignment.Geo3D.Matrix }
+         * 
+         * 
+         */
+        public List<Alignment.Geo3D.Matrix> getMatrix() {
+            if (matrix == null) {
+                matrix = new ArrayList<Alignment.Geo3D.Matrix>();
+            }
+            return this.matrix;
+        }
+
+        /**
+         * Gets the value of the intObjectId property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getIntObjectId() {
+            return intObjectId;
+        }
+
+        /**
+         * Sets the value of the intObjectId property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setIntObjectId(String value) {
+            this.intObjectId = value;
+        }
+
+
+        /**
+         * <p>Java class for anonymous complex type.
+         * 
+         * <p>The following schema fragment specifies the expected content contained within this class.
+         * 
+         * <pre>
+         * &lt;complexType>
+         *   &lt;complexContent>
+         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *       &lt;sequence>
+         *         &lt;element name="max11">
+         *           &lt;complexType>
+         *             &lt;complexContent>
+         *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                 &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+         *               &lt;/restriction>
+         *             &lt;/complexContent>
+         *           &lt;/complexType>
+         *         &lt;/element>
+         *         &lt;element name="max12">
+         *           &lt;complexType>
+         *             &lt;complexContent>
+         *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                 &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+         *               &lt;/restriction>
+         *             &lt;/complexContent>
+         *           &lt;/complexType>
+         *         &lt;/element>
+         *         &lt;element name="max13">
+         *           &lt;complexType>
+         *             &lt;complexContent>
+         *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                 &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+         *               &lt;/restriction>
+         *             &lt;/complexContent>
+         *           &lt;/complexType>
+         *         &lt;/element>
+         *         &lt;element name="max21">
+         *           &lt;complexType>
+         *             &lt;complexContent>
+         *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                 &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+         *               &lt;/restriction>
+         *             &lt;/complexContent>
+         *           &lt;/complexType>
+         *         &lt;/element>
+         *         &lt;element name="max22">
+         *           &lt;complexType>
+         *             &lt;complexContent>
+         *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                 &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+         *               &lt;/restriction>
+         *             &lt;/complexContent>
+         *           &lt;/complexType>
+         *         &lt;/element>
+         *         &lt;element name="max23">
+         *           &lt;complexType>
+         *             &lt;complexContent>
+         *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                 &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+         *               &lt;/restriction>
+         *             &lt;/complexContent>
+         *           &lt;/complexType>
+         *         &lt;/element>
+         *         &lt;element name="max31">
+         *           &lt;complexType>
+         *             &lt;complexContent>
+         *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                 &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+         *               &lt;/restriction>
+         *             &lt;/complexContent>
+         *           &lt;/complexType>
+         *         &lt;/element>
+         *         &lt;element name="max32">
+         *           &lt;complexType>
+         *             &lt;complexContent>
+         *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                 &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+         *               &lt;/restriction>
+         *             &lt;/complexContent>
+         *           &lt;/complexType>
+         *         &lt;/element>
+         *         &lt;element name="max33">
+         *           &lt;complexType>
+         *             &lt;complexContent>
+         *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                 &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+         *               &lt;/restriction>
+         *             &lt;/complexContent>
+         *           &lt;/complexType>
+         *         &lt;/element>
+         *       &lt;/sequence>
+         *     &lt;/restriction>
+         *   &lt;/complexContent>
+         * &lt;/complexType>
+         * </pre>
+         * 
+         * 
+         */
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "", propOrder = {
+            "max11",
+            "max12",
+            "max13",
+            "max21",
+            "max22",
+            "max23",
+            "max31",
+            "max32",
+            "max33"
+        })
+        public static class Matrix {
+
+            @XmlElement(required = true)
+            protected Alignment.Geo3D.Matrix.Max11 max11;
+            @XmlElement(required = true)
+            protected Alignment.Geo3D.Matrix.Max12 max12;
+            @XmlElement(required = true)
+            protected Alignment.Geo3D.Matrix.Max13 max13;
+            @XmlElement(required = true)
+            protected Alignment.Geo3D.Matrix.Max21 max21;
+            @XmlElement(required = true)
+            protected Alignment.Geo3D.Matrix.Max22 max22;
+            @XmlElement(required = true)
+            protected Alignment.Geo3D.Matrix.Max23 max23;
+            @XmlElement(required = true)
+            protected Alignment.Geo3D.Matrix.Max31 max31;
+            @XmlElement(required = true)
+            protected Alignment.Geo3D.Matrix.Max32 max32;
+            @XmlElement(required = true)
+            protected Alignment.Geo3D.Matrix.Max33 max33;
+
+            /**
+             * Gets the value of the max11 property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link Alignment.Geo3D.Matrix.Max11 }
+             *     
+             */
+            public Alignment.Geo3D.Matrix.Max11 getMax11() {
+                return max11;
+            }
+
+            /**
+             * Sets the value of the max11 property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link Alignment.Geo3D.Matrix.Max11 }
+             *     
+             */
+            public void setMax11(Alignment.Geo3D.Matrix.Max11 value) {
+                this.max11 = value;
+            }
+
+            /**
+             * Gets the value of the max12 property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link Alignment.Geo3D.Matrix.Max12 }
+             *     
+             */
+            public Alignment.Geo3D.Matrix.Max12 getMax12() {
+                return max12;
+            }
+
+            /**
+             * Sets the value of the max12 property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link Alignment.Geo3D.Matrix.Max12 }
+             *     
+             */
+            public void setMax12(Alignment.Geo3D.Matrix.Max12 value) {
+                this.max12 = value;
+            }
+
+            /**
+             * Gets the value of the max13 property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link Alignment.Geo3D.Matrix.Max13 }
+             *     
+             */
+            public Alignment.Geo3D.Matrix.Max13 getMax13() {
+                return max13;
+            }
+
+            /**
+             * Sets the value of the max13 property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link Alignment.Geo3D.Matrix.Max13 }
+             *     
+             */
+            public void setMax13(Alignment.Geo3D.Matrix.Max13 value) {
+                this.max13 = value;
+            }
+
+            /**
+             * Gets the value of the max21 property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link Alignment.Geo3D.Matrix.Max21 }
+             *     
+             */
+            public Alignment.Geo3D.Matrix.Max21 getMax21() {
+                return max21;
+            }
+
+            /**
+             * Sets the value of the max21 property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link Alignment.Geo3D.Matrix.Max21 }
+             *     
+             */
+            public void setMax21(Alignment.Geo3D.Matrix.Max21 value) {
+                this.max21 = value;
+            }
+
+            /**
+             * Gets the value of the max22 property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link Alignment.Geo3D.Matrix.Max22 }
+             *     
+             */
+            public Alignment.Geo3D.Matrix.Max22 getMax22() {
+                return max22;
+            }
+
+            /**
+             * Sets the value of the max22 property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link Alignment.Geo3D.Matrix.Max22 }
+             *     
+             */
+            public void setMax22(Alignment.Geo3D.Matrix.Max22 value) {
+                this.max22 = value;
+            }
+
+            /**
+             * Gets the value of the max23 property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link Alignment.Geo3D.Matrix.Max23 }
+             *     
+             */
+            public Alignment.Geo3D.Matrix.Max23 getMax23() {
+                return max23;
+            }
+
+            /**
+             * Sets the value of the max23 property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link Alignment.Geo3D.Matrix.Max23 }
+             *     
+             */
+            public void setMax23(Alignment.Geo3D.Matrix.Max23 value) {
+                this.max23 = value;
+            }
+
+            /**
+             * Gets the value of the max31 property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link Alignment.Geo3D.Matrix.Max31 }
+             *     
+             */
+            public Alignment.Geo3D.Matrix.Max31 getMax31() {
+                return max31;
+            }
+
+            /**
+             * Sets the value of the max31 property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link Alignment.Geo3D.Matrix.Max31 }
+             *     
+             */
+            public void setMax31(Alignment.Geo3D.Matrix.Max31 value) {
+                this.max31 = value;
+            }
+
+            /**
+             * Gets the value of the max32 property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link Alignment.Geo3D.Matrix.Max32 }
+             *     
+             */
+            public Alignment.Geo3D.Matrix.Max32 getMax32() {
+                return max32;
+            }
+
+            /**
+             * Sets the value of the max32 property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link Alignment.Geo3D.Matrix.Max32 }
+             *     
+             */
+            public void setMax32(Alignment.Geo3D.Matrix.Max32 value) {
+                this.max32 = value;
+            }
+
+            /**
+             * Gets the value of the max33 property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link Alignment.Geo3D.Matrix.Max33 }
+             *     
+             */
+            public Alignment.Geo3D.Matrix.Max33 getMax33() {
+                return max33;
+            }
+
+            /**
+             * Sets the value of the max33 property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link Alignment.Geo3D.Matrix.Max33 }
+             *     
+             */
+            public void setMax33(Alignment.Geo3D.Matrix.Max33 value) {
+                this.max33 = value;
+            }
+
+
+            /**
+             * <p>Java class for anonymous complex type.
+             * 
+             * <p>The following schema fragment specifies the expected content contained within this class.
+             * 
+             * <pre>
+             * &lt;complexType>
+             *   &lt;complexContent>
+             *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *       &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+             *     &lt;/restriction>
+             *   &lt;/complexContent>
+             * &lt;/complexType>
+             * </pre>
+             * 
+             * 
+             */
+            @XmlAccessorType(XmlAccessType.FIELD)
+            @XmlType(name = "")
+            public static class Max11 {
+
+                @XmlAttribute(name = "coord", required = true)
+                protected float coord;
+
+                /**
+                 * Gets the value of the coord property.
+                 * 
+                 */
+                public float getCoord() {
+                    return coord;
+                }
+
+                /**
+                 * Sets the value of the coord property.
+                 * 
+                 */
+                public void setCoord(float value) {
+                    this.coord = value;
+                }
+
+            }
+
+
+            /**
+             * <p>Java class for anonymous complex type.
+             * 
+             * <p>The following schema fragment specifies the expected content contained within this class.
+             * 
+             * <pre>
+             * &lt;complexType>
+             *   &lt;complexContent>
+             *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *       &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+             *     &lt;/restriction>
+             *   &lt;/complexContent>
+             * &lt;/complexType>
+             * </pre>
+             * 
+             * 
+             */
+            @XmlAccessorType(XmlAccessType.FIELD)
+            @XmlType(name = "")
+            public static class Max12 {
+
+                @XmlAttribute(name = "coord", required = true)
+                protected float coord;
+
+                /**
+                 * Gets the value of the coord property.
+                 * 
+                 */
+                public float getCoord() {
+                    return coord;
+                }
+
+                /**
+                 * Sets the value of the coord property.
+                 * 
+                 */
+                public void setCoord(float value) {
+                    this.coord = value;
+                }
+
+            }
+
+
+            /**
+             * <p>Java class for anonymous complex type.
+             * 
+             * <p>The following schema fragment specifies the expected content contained within this class.
+             * 
+             * <pre>
+             * &lt;complexType>
+             *   &lt;complexContent>
+             *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *       &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+             *     &lt;/restriction>
+             *   &lt;/complexContent>
+             * &lt;/complexType>
+             * </pre>
+             * 
+             * 
+             */
+            @XmlAccessorType(XmlAccessType.FIELD)
+            @XmlType(name = "")
+            public static class Max13 {
+
+                @XmlAttribute(name = "coord", required = true)
+                protected float coord;
+
+                /**
+                 * Gets the value of the coord property.
+                 * 
+                 */
+                public float getCoord() {
+                    return coord;
+                }
+
+                /**
+                 * Sets the value of the coord property.
+                 * 
+                 */
+                public void setCoord(float value) {
+                    this.coord = value;
+                }
+
+            }
+
+
+            /**
+             * <p>Java class for anonymous complex type.
+             * 
+             * <p>The following schema fragment specifies the expected content contained within this class.
+             * 
+             * <pre>
+             * &lt;complexType>
+             *   &lt;complexContent>
+             *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *       &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+             *     &lt;/restriction>
+             *   &lt;/complexContent>
+             * &lt;/complexType>
+             * </pre>
+             * 
+             * 
+             */
+            @XmlAccessorType(XmlAccessType.FIELD)
+            @XmlType(name = "")
+            public static class Max21 {
+
+                @XmlAttribute(name = "coord", required = true)
+                protected float coord;
+
+                /**
+                 * Gets the value of the coord property.
+                 * 
+                 */
+                public float getCoord() {
+                    return coord;
+                }
+
+                /**
+                 * Sets the value of the coord property.
+                 * 
+                 */
+                public void setCoord(float value) {
+                    this.coord = value;
+                }
+
+            }
+
+
+            /**
+             * <p>Java class for anonymous complex type.
+             * 
+             * <p>The following schema fragment specifies the expected content contained within this class.
+             * 
+             * <pre>
+             * &lt;complexType>
+             *   &lt;complexContent>
+             *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *       &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+             *     &lt;/restriction>
+             *   &lt;/complexContent>
+             * &lt;/complexType>
+             * </pre>
+             * 
+             * 
+             */
+            @XmlAccessorType(XmlAccessType.FIELD)
+            @XmlType(name = "")
+            public static class Max22 {
+
+                @XmlAttribute(name = "coord", required = true)
+                protected float coord;
+
+                /**
+                 * Gets the value of the coord property.
+                 * 
+                 */
+                public float getCoord() {
+                    return coord;
+                }
+
+                /**
+                 * Sets the value of the coord property.
+                 * 
+                 */
+                public void setCoord(float value) {
+                    this.coord = value;
+                }
+
+            }
+
+
+            /**
+             * <p>Java class for anonymous complex type.
+             * 
+             * <p>The following schema fragment specifies the expected content contained within this class.
+             * 
+             * <pre>
+             * &lt;complexType>
+             *   &lt;complexContent>
+             *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *       &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+             *     &lt;/restriction>
+             *   &lt;/complexContent>
+             * &lt;/complexType>
+             * </pre>
+             * 
+             * 
+             */
+            @XmlAccessorType(XmlAccessType.FIELD)
+            @XmlType(name = "")
+            public static class Max23 {
+
+                @XmlAttribute(name = "coord", required = true)
+                protected float coord;
+
+                /**
+                 * Gets the value of the coord property.
+                 * 
+                 */
+                public float getCoord() {
+                    return coord;
+                }
+
+                /**
+                 * Sets the value of the coord property.
+                 * 
+                 */
+                public void setCoord(float value) {
+                    this.coord = value;
+                }
+
+            }
+
+
+            /**
+             * <p>Java class for anonymous complex type.
+             * 
+             * <p>The following schema fragment specifies the expected content contained within this class.
+             * 
+             * <pre>
+             * &lt;complexType>
+             *   &lt;complexContent>
+             *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *       &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+             *     &lt;/restriction>
+             *   &lt;/complexContent>
+             * &lt;/complexType>
+             * </pre>
+             * 
+             * 
+             */
+            @XmlAccessorType(XmlAccessType.FIELD)
+            @XmlType(name = "")
+            public static class Max31 {
+
+                @XmlAttribute(name = "coord", required = true)
+                protected float coord;
+
+                /**
+                 * Gets the value of the coord property.
+                 * 
+                 */
+                public float getCoord() {
+                    return coord;
+                }
+
+                /**
+                 * Sets the value of the coord property.
+                 * 
+                 */
+                public void setCoord(float value) {
+                    this.coord = value;
+                }
+
+            }
+
+
+            /**
+             * <p>Java class for anonymous complex type.
+             * 
+             * <p>The following schema fragment specifies the expected content contained within this class.
+             * 
+             * <pre>
+             * &lt;complexType>
+             *   &lt;complexContent>
+             *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *       &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+             *     &lt;/restriction>
+             *   &lt;/complexContent>
+             * &lt;/complexType>
+             * </pre>
+             * 
+             * 
+             */
+            @XmlAccessorType(XmlAccessType.FIELD)
+            @XmlType(name = "")
+            public static class Max32 {
+
+                @XmlAttribute(name = "coord", required = true)
+                protected float coord;
+
+                /**
+                 * Gets the value of the coord property.
+                 * 
+                 */
+                public float getCoord() {
+                    return coord;
+                }
+
+                /**
+                 * Sets the value of the coord property.
+                 * 
+                 */
+                public void setCoord(float value) {
+                    this.coord = value;
+                }
+
+            }
+
+
+            /**
+             * <p>Java class for anonymous complex type.
+             * 
+             * <p>The following schema fragment specifies the expected content contained within this class.
+             * 
+             * <pre>
+             * &lt;complexType>
+             *   &lt;complexContent>
+             *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *       &lt;attribute name="coord" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+             *     &lt;/restriction>
+             *   &lt;/complexContent>
+             * &lt;/complexType>
+             * </pre>
+             * 
+             * 
+             */
+            @XmlAccessorType(XmlAccessType.FIELD)
+            @XmlType(name = "")
+            public static class Max33 {
+
+                @XmlAttribute(name = "coord", required = true)
+                protected float coord;
+
+                /**
+                 * Gets the value of the coord property.
+                 * 
+                 */
+                public float getCoord() {
+                    return coord;
+                }
+
+                /**
+                 * Sets the value of the coord property.
+                 * 
+                 */
+                public void setCoord(float value) {
+                    this.coord = value;
+                }
+
+            }
+
+        }
+
+
+        /**
+         * <p>Java class for anonymous complex type.
+         * 
+         * <p>The following schema fragment specifies the expected content contained within this class.
+         * 
+         * <pre>
+         * &lt;complexType>
+         *   &lt;complexContent>
+         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *       &lt;attribute name="x" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+         *       &lt;attribute name="y" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+         *       &lt;attribute name="z" use="required" type="{http://www.w3.org/2001/XMLSchema}float" />
+         *     &lt;/restriction>
+         *   &lt;/complexContent>
+         * &lt;/complexType>
+         * </pre>
+         * 
+         * 
+         */
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "")
+        public static class Vector {
+
+            @XmlAttribute(name = "x", required = true)
+            protected float x;
+            @XmlAttribute(name = "y", required = true)
+            protected float y;
+            @XmlAttribute(name = "z", required = true)
+            protected float z;
+
+            /**
+             * Gets the value of the x property.
+             * 
+             */
+            public float getX() {
+                return x;
+            }
+
+            /**
+             * Sets the value of the x property.
+             * 
+             */
+            public void setX(float value) {
+                this.x = value;
+            }
+
+            /**
+             * Gets the value of the y property.
+             * 
+             */
+            public float getY() {
+                return y;
+            }
+
+            /**
+             * Sets the value of the y property.
+             * 
+             */
+            public void setY(float value) {
+                this.y = value;
+            }
+
+            /**
+             * Gets the value of the z property.
+             * 
+             */
+            public float getZ() {
+                return z;
+            }
+
+            /**
+             * Sets the value of the z property.
+             * 
+             */
+            public void setZ(float value) {
+                this.z = value;
+            }
+
+        }
+
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * 
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attribute name="methodName" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *       &lt;attribute name="scoreValue" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     * 
+     * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "")
+    public static class Score {
+
+        @XmlAttribute(name = "methodName", required = true)
+        protected String methodName;
+        @XmlAttribute(name = "scoreValue", required = true)
+        protected String scoreValue;
+
+        /**
+         * Gets the value of the methodName property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getMethodName() {
+            return methodName;
+        }
+
+        /**
+         * Sets the value of the methodName property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setMethodName(String value) {
+            this.methodName = value;
+        }
+
+        /**
+         * Gets the value of the scoreValue property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getScoreValue() {
+            return scoreValue;
+        }
+
+        /**
+         * Sets the value of the scoreValue property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setScoreValue(String value) {
+            this.scoreValue = value;
+        }
+
+    }
+
+}
diff --git a/src/jalview/xml/binding/sifts/EntityType.java b/src/jalview/xml/binding/sifts/EntityType.java
new file mode 100644 (file)
index 0000000..f74da5a
--- /dev/null
@@ -0,0 +1,62 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
+// Any modifications to this file will be lost upon recompilation of the source schema. 
+// Generated on: 2015.10.09 at 03:18:33 PM BST 
+//
+
+
+package jalview.xml.binding.sifts;
+
+import javax.xml.bind.annotation.XmlEnum;
+import javax.xml.bind.annotation.XmlEnumValue;
+import javax.xml.bind.annotation.XmlType;
+
+
+/**
+ * <p>Java class for entityType.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * <p>
+ * <pre>
+ * &lt;simpleType name="entityType">
+ *   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ *     &lt;enumeration value="protein"/>
+ *     &lt;enumeration value="RNA"/>
+ *     &lt;enumeration value="DNA"/>
+ *     &lt;enumeration value="domain"/>
+ *   &lt;/restriction>
+ * &lt;/simpleType>
+ * </pre>
+ * 
+ */
+@XmlType(name = "entityType", namespace = "http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd")
+@XmlEnum
+public enum EntityType {
+
+    @XmlEnumValue("protein")
+    PROTEIN("protein"),
+    RNA("RNA"),
+    DNA("DNA"),
+    @XmlEnumValue("domain")
+    DOMAIN("domain");
+    private final String value;
+
+    EntityType(String v) {
+        value = v;
+    }
+
+    public String value() {
+        return value;
+    }
+
+    public static EntityType fromValue(String v) {
+        for (EntityType c: EntityType.values()) {
+            if (c.value.equals(v)) {
+                return c;
+            }
+        }
+        throw new IllegalArgumentException(v);
+    }
+
+}
diff --git a/src/jalview/xml/binding/sifts/Entry.java b/src/jalview/xml/binding/sifts/Entry.java
new file mode 100644 (file)
index 0000000..7429059
--- /dev/null
@@ -0,0 +1,2818 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
+// Any modifications to this file will be lost upon recompilation of the source schema. 
+// Generated on: 2015.10.09 at 03:18:33 PM BST 
+//
+
+
+package jalview.xml.binding.sifts;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlSchemaType;
+import javax.xml.bind.annotation.XmlType;
+import javax.xml.bind.annotation.XmlValue;
+import javax.xml.datatype.XMLGregorianCalendar;
+
+
+/**
+ * <p>Java class for anonymous complex type.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * 
+ * <pre>
+ * &lt;complexType>
+ *   &lt;complexContent>
+ *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *       &lt;sequence>
+ *         &lt;element name="listDB">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;sequence maxOccurs="unbounded">
+ *                   &lt;element name="db">
+ *                     &lt;complexType>
+ *                       &lt;complexContent>
+ *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}listdbRef"/>
+ *                         &lt;/restriction>
+ *                       &lt;/complexContent>
+ *                     &lt;/complexType>
+ *                   &lt;/element>
+ *                 &lt;/sequence>
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *         &lt;element name="entryDetail" maxOccurs="unbounded" minOccurs="0">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *         &lt;element name="entity" maxOccurs="unbounded">
+ *           &lt;complexType>
+ *             &lt;complexContent>
+ *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                 &lt;sequence>
+ *                   &lt;element name="entityDetail" maxOccurs="unbounded" minOccurs="0">
+ *                     &lt;complexType>
+ *                       &lt;complexContent>
+ *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+ *                         &lt;/restriction>
+ *                       &lt;/complexContent>
+ *                     &lt;/complexType>
+ *                   &lt;/element>
+ *                   &lt;element name="segment" maxOccurs="unbounded">
+ *                     &lt;complexType>
+ *                       &lt;complexContent>
+ *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                           &lt;sequence>
+ *                             &lt;element name="listResidue" minOccurs="0">
+ *                               &lt;complexType>
+ *                                 &lt;complexContent>
+ *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                     &lt;sequence>
+ *                                       &lt;element name="residue" maxOccurs="unbounded">
+ *                                         &lt;complexType>
+ *                                           &lt;complexContent>
+ *                                             &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                               &lt;sequence>
+ *                                                 &lt;element name="crossRefDb" maxOccurs="unbounded" minOccurs="0">
+ *                                                   &lt;complexType>
+ *                                                     &lt;complexContent>
+ *                                                       &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                                         &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbRef"/>
+ *                                                         &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}resRef"/>
+ *                                                         &lt;attribute name="dbChainId" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}chainId" />
+ *                                                       &lt;/restriction>
+ *                                                     &lt;/complexContent>
+ *                                                   &lt;/complexType>
+ *                                                 &lt;/element>
+ *                                                 &lt;element name="residueDetail" maxOccurs="unbounded" minOccurs="0">
+ *                                                   &lt;complexType>
+ *                                                     &lt;complexContent>
+ *                                                       &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                                         &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+ *                                                       &lt;/restriction>
+ *                                                     &lt;/complexContent>
+ *                                                   &lt;/complexType>
+ *                                                 &lt;/element>
+ *                                               &lt;/sequence>
+ *                                               &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}resRef"/>
+ *                                               &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}listdbRef"/>
+ *                                             &lt;/restriction>
+ *                                           &lt;/complexContent>
+ *                                         &lt;/complexType>
+ *                                       &lt;/element>
+ *                                     &lt;/sequence>
+ *                                   &lt;/restriction>
+ *                                 &lt;/complexContent>
+ *                               &lt;/complexType>
+ *                             &lt;/element>
+ *                             &lt;element name="listMapRegion" minOccurs="0">
+ *                               &lt;complexType>
+ *                                 &lt;complexContent>
+ *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                     &lt;sequence>
+ *                                       &lt;element name="mapRegion" maxOccurs="unbounded">
+ *                                         &lt;complexType>
+ *                                           &lt;complexContent>
+ *                                             &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                               &lt;sequence>
+ *                                                 &lt;element name="db">
+ *                                                   &lt;complexType>
+ *                                                     &lt;complexContent>
+ *                                                       &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                                         &lt;sequence>
+ *                                                           &lt;element name="dbDetail" maxOccurs="unbounded" minOccurs="0">
+ *                                                             &lt;complexType>
+ *                                                               &lt;complexContent>
+ *                                                                 &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                                                   &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+ *                                                                 &lt;/restriction>
+ *                                                               &lt;/complexContent>
+ *                                                             &lt;/complexType>
+ *                                                           &lt;/element>
+ *                                                         &lt;/sequence>
+ *                                                         &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbRef"/>
+ *                                                         &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+ *                                                         &lt;attribute name="dbChainId" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbChainId" />
+ *                                                       &lt;/restriction>
+ *                                                     &lt;/complexContent>
+ *                                                   &lt;/complexType>
+ *                                                 &lt;/element>
+ *                                               &lt;/sequence>
+ *                                               &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+ *                                             &lt;/restriction>
+ *                                           &lt;/complexContent>
+ *                                         &lt;/complexType>
+ *                                       &lt;/element>
+ *                                     &lt;/sequence>
+ *                                   &lt;/restriction>
+ *                                 &lt;/complexContent>
+ *                               &lt;/complexType>
+ *                             &lt;/element>
+ *                             &lt;element name="segmentDetail" maxOccurs="unbounded" minOccurs="0">
+ *                               &lt;complexType>
+ *                                 &lt;complexContent>
+ *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+ *                                     &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+ *                                   &lt;/restriction>
+ *                                 &lt;/complexContent>
+ *                               &lt;/complexType>
+ *                             &lt;/element>
+ *                           &lt;/sequence>
+ *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+ *                           &lt;attribute name="segId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *                         &lt;/restriction>
+ *                       &lt;/complexContent>
+ *                     &lt;/complexType>
+ *                   &lt;/element>
+ *                 &lt;/sequence>
+ *                 &lt;attribute name="type" use="required" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}entityType" />
+ *                 &lt;attribute name="entityId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+ *               &lt;/restriction>
+ *             &lt;/complexContent>
+ *           &lt;/complexType>
+ *         &lt;/element>
+ *         &lt;element ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/eFamily.xsd}alignment" maxOccurs="unbounded" minOccurs="0"/>
+ *       &lt;/sequence>
+ *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbRef"/>
+ *       &lt;attribute name="date" use="required" type="{http://www.w3.org/2001/XMLSchema}date" />
+ *       &lt;attribute name="dbEntryVersion" use="required" type="{http://www.w3.org/2001/XMLSchema}date" />
+ *     &lt;/restriction>
+ *   &lt;/complexContent>
+ * &lt;/complexType>
+ * </pre>
+ * 
+ * 
+ */
+@XmlAccessorType(XmlAccessType.FIELD)
+@XmlType(name = "", propOrder = {
+    "listDB",
+    "entryDetail",
+    "entity",
+    "alignment"
+})
+@XmlRootElement(name = "entry")
+public class Entry {
+
+    @XmlElement(required = true)
+    protected Entry.ListDB listDB;
+    protected List<Entry.EntryDetail> entryDetail;
+    @XmlElement(required = true)
+    protected List<Entry.Entity> entity;
+    protected List<Alignment> alignment;
+    @XmlAttribute(name = "date", required = true)
+    @XmlSchemaType(name = "date")
+    protected XMLGregorianCalendar date;
+    @XmlAttribute(name = "dbEntryVersion", required = true)
+    @XmlSchemaType(name = "date")
+    protected XMLGregorianCalendar dbEntryVersion;
+    @XmlAttribute(name = "dbSource", required = true)
+    protected String dbSource;
+    @XmlAttribute(name = "dbCoordSys", required = true)
+    protected String dbCoordSys;
+    @XmlAttribute(name = "dbAccessionId", required = true)
+    protected String dbAccessionId;
+    @XmlAttribute(name = "dbEvidence")
+    protected String dbEvidence;
+    @XmlAttribute(name = "dbVersion")
+    protected String dbVersion;
+
+    /**
+     * Gets the value of the listDB property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link Entry.ListDB }
+     *     
+     */
+    public Entry.ListDB getListDB() {
+        return listDB;
+    }
+
+    /**
+     * Sets the value of the listDB property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link Entry.ListDB }
+     *     
+     */
+    public void setListDB(Entry.ListDB value) {
+        this.listDB = value;
+    }
+
+    /**
+     * Gets the value of the entryDetail property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the entryDetail property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getEntryDetail().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link Entry.EntryDetail }
+     * 
+     * 
+     */
+    public List<Entry.EntryDetail> getEntryDetail() {
+        if (entryDetail == null) {
+            entryDetail = new ArrayList<Entry.EntryDetail>();
+        }
+        return this.entryDetail;
+    }
+
+    /**
+     * Gets the value of the entity property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the entity property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getEntity().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link Entry.Entity }
+     * 
+     * 
+     */
+    public List<Entry.Entity> getEntity() {
+        if (entity == null) {
+            entity = new ArrayList<Entry.Entity>();
+        }
+        return this.entity;
+    }
+
+    /**
+     * Gets the value of the alignment property.
+     * 
+     * <p>
+     * This accessor method returns a reference to the live list,
+     * not a snapshot. Therefore any modification you make to the
+     * returned list will be present inside the JAXB object.
+     * This is why there is not a <CODE>set</CODE> method for the alignment property.
+     * 
+     * <p>
+     * For example, to add a new item, do as follows:
+     * <pre>
+     *    getAlignment().add(newItem);
+     * </pre>
+     * 
+     * 
+     * <p>
+     * Objects of the following type(s) are allowed in the list
+     * {@link Alignment }
+     * 
+     * 
+     */
+    public List<Alignment> getAlignment() {
+        if (alignment == null) {
+            alignment = new ArrayList<Alignment>();
+        }
+        return this.alignment;
+    }
+
+    /**
+     * Gets the value of the date property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link XMLGregorianCalendar }
+     *     
+     */
+    public XMLGregorianCalendar getDate() {
+        return date;
+    }
+
+    /**
+     * Sets the value of the date property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link XMLGregorianCalendar }
+     *     
+     */
+    public void setDate(XMLGregorianCalendar value) {
+        this.date = value;
+    }
+
+    /**
+     * Gets the value of the dbEntryVersion property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link XMLGregorianCalendar }
+     *     
+     */
+    public XMLGregorianCalendar getDbEntryVersion() {
+        return dbEntryVersion;
+    }
+
+    /**
+     * Sets the value of the dbEntryVersion property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link XMLGregorianCalendar }
+     *     
+     */
+    public void setDbEntryVersion(XMLGregorianCalendar value) {
+        this.dbEntryVersion = value;
+    }
+
+    /**
+     * Gets the value of the dbSource property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getDbSource() {
+        return dbSource;
+    }
+
+    /**
+     * Sets the value of the dbSource property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setDbSource(String value) {
+        this.dbSource = value;
+    }
+
+    /**
+     * Gets the value of the dbCoordSys property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getDbCoordSys() {
+        return dbCoordSys;
+    }
+
+    /**
+     * Sets the value of the dbCoordSys property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setDbCoordSys(String value) {
+        this.dbCoordSys = value;
+    }
+
+    /**
+     * Gets the value of the dbAccessionId property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getDbAccessionId() {
+        return dbAccessionId;
+    }
+
+    /**
+     * Sets the value of the dbAccessionId property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setDbAccessionId(String value) {
+        this.dbAccessionId = value;
+    }
+
+    /**
+     * Gets the value of the dbEvidence property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getDbEvidence() {
+        return dbEvidence;
+    }
+
+    /**
+     * Sets the value of the dbEvidence property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setDbEvidence(String value) {
+        this.dbEvidence = value;
+    }
+
+    /**
+     * Gets the value of the dbVersion property.
+     * 
+     * @return
+     *     possible object is
+     *     {@link String }
+     *     
+     */
+    public String getDbVersion() {
+        return dbVersion;
+    }
+
+    /**
+     * Sets the value of the dbVersion property.
+     * 
+     * @param value
+     *     allowed object is
+     *     {@link String }
+     *     
+     */
+    public void setDbVersion(String value) {
+        this.dbVersion = value;
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * 
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;sequence>
+     *         &lt;element name="entityDetail" maxOccurs="unbounded" minOccurs="0">
+     *           &lt;complexType>
+     *             &lt;complexContent>
+     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+     *               &lt;/restriction>
+     *             &lt;/complexContent>
+     *           &lt;/complexType>
+     *         &lt;/element>
+     *         &lt;element name="segment" maxOccurs="unbounded">
+     *           &lt;complexType>
+     *             &lt;complexContent>
+     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                 &lt;sequence>
+     *                   &lt;element name="listResidue" minOccurs="0">
+     *                     &lt;complexType>
+     *                       &lt;complexContent>
+     *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                           &lt;sequence>
+     *                             &lt;element name="residue" maxOccurs="unbounded">
+     *                               &lt;complexType>
+     *                                 &lt;complexContent>
+     *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                                     &lt;sequence>
+     *                                       &lt;element name="crossRefDb" maxOccurs="unbounded" minOccurs="0">
+     *                                         &lt;complexType>
+     *                                           &lt;complexContent>
+     *                                             &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                                               &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbRef"/>
+     *                                               &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}resRef"/>
+     *                                               &lt;attribute name="dbChainId" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}chainId" />
+     *                                             &lt;/restriction>
+     *                                           &lt;/complexContent>
+     *                                         &lt;/complexType>
+     *                                       &lt;/element>
+     *                                       &lt;element name="residueDetail" maxOccurs="unbounded" minOccurs="0">
+     *                                         &lt;complexType>
+     *                                           &lt;complexContent>
+     *                                             &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                                               &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+     *                                             &lt;/restriction>
+     *                                           &lt;/complexContent>
+     *                                         &lt;/complexType>
+     *                                       &lt;/element>
+     *                                     &lt;/sequence>
+     *                                     &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}resRef"/>
+     *                                     &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}listdbRef"/>
+     *                                   &lt;/restriction>
+     *                                 &lt;/complexContent>
+     *                               &lt;/complexType>
+     *                             &lt;/element>
+     *                           &lt;/sequence>
+     *                         &lt;/restriction>
+     *                       &lt;/complexContent>
+     *                     &lt;/complexType>
+     *                   &lt;/element>
+     *                   &lt;element name="listMapRegion" minOccurs="0">
+     *                     &lt;complexType>
+     *                       &lt;complexContent>
+     *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                           &lt;sequence>
+     *                             &lt;element name="mapRegion" maxOccurs="unbounded">
+     *                               &lt;complexType>
+     *                                 &lt;complexContent>
+     *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                                     &lt;sequence>
+     *                                       &lt;element name="db">
+     *                                         &lt;complexType>
+     *                                           &lt;complexContent>
+     *                                             &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                                               &lt;sequence>
+     *                                                 &lt;element name="dbDetail" maxOccurs="unbounded" minOccurs="0">
+     *                                                   &lt;complexType>
+     *                                                     &lt;complexContent>
+     *                                                       &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                                                         &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+     *                                                       &lt;/restriction>
+     *                                                     &lt;/complexContent>
+     *                                                   &lt;/complexType>
+     *                                                 &lt;/element>
+     *                                               &lt;/sequence>
+     *                                               &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbRef"/>
+     *                                               &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+     *                                               &lt;attribute name="dbChainId" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbChainId" />
+     *                                             &lt;/restriction>
+     *                                           &lt;/complexContent>
+     *                                         &lt;/complexType>
+     *                                       &lt;/element>
+     *                                     &lt;/sequence>
+     *                                     &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+     *                                   &lt;/restriction>
+     *                                 &lt;/complexContent>
+     *                               &lt;/complexType>
+     *                             &lt;/element>
+     *                           &lt;/sequence>
+     *                         &lt;/restriction>
+     *                       &lt;/complexContent>
+     *                     &lt;/complexType>
+     *                   &lt;/element>
+     *                   &lt;element name="segmentDetail" maxOccurs="unbounded" minOccurs="0">
+     *                     &lt;complexType>
+     *                       &lt;complexContent>
+     *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+     *                         &lt;/restriction>
+     *                       &lt;/complexContent>
+     *                     &lt;/complexType>
+     *                   &lt;/element>
+     *                 &lt;/sequence>
+     *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+     *                 &lt;attribute name="segId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *               &lt;/restriction>
+     *             &lt;/complexContent>
+     *           &lt;/complexType>
+     *         &lt;/element>
+     *       &lt;/sequence>
+     *       &lt;attribute name="type" use="required" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}entityType" />
+     *       &lt;attribute name="entityId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     * 
+     * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = {
+        "entityDetail",
+        "segment"
+    })
+    public static class Entity {
+
+        protected List<Entry.Entity.EntityDetail> entityDetail;
+        @XmlElement(required = true)
+        protected List<Entry.Entity.Segment> segment;
+        @XmlAttribute(name = "type", required = true)
+        protected EntityType type;
+        @XmlAttribute(name = "entityId", required = true)
+        protected String entityId;
+
+        /**
+         * Gets the value of the entityDetail property.
+         * 
+         * <p>
+         * This accessor method returns a reference to the live list,
+         * not a snapshot. Therefore any modification you make to the
+         * returned list will be present inside the JAXB object.
+         * This is why there is not a <CODE>set</CODE> method for the entityDetail property.
+         * 
+         * <p>
+         * For example, to add a new item, do as follows:
+         * <pre>
+         *    getEntityDetail().add(newItem);
+         * </pre>
+         * 
+         * 
+         * <p>
+         * Objects of the following type(s) are allowed in the list
+         * {@link Entry.Entity.EntityDetail }
+         * 
+         * 
+         */
+        public List<Entry.Entity.EntityDetail> getEntityDetail() {
+            if (entityDetail == null) {
+                entityDetail = new ArrayList<Entry.Entity.EntityDetail>();
+            }
+            return this.entityDetail;
+        }
+
+        /**
+         * Gets the value of the segment property.
+         * 
+         * <p>
+         * This accessor method returns a reference to the live list,
+         * not a snapshot. Therefore any modification you make to the
+         * returned list will be present inside the JAXB object.
+         * This is why there is not a <CODE>set</CODE> method for the segment property.
+         * 
+         * <p>
+         * For example, to add a new item, do as follows:
+         * <pre>
+         *    getSegment().add(newItem);
+         * </pre>
+         * 
+         * 
+         * <p>
+         * Objects of the following type(s) are allowed in the list
+         * {@link Entry.Entity.Segment }
+         * 
+         * 
+         */
+        public List<Entry.Entity.Segment> getSegment() {
+            if (segment == null) {
+                segment = new ArrayList<Entry.Entity.Segment>();
+            }
+            return this.segment;
+        }
+
+        /**
+         * Gets the value of the type property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link EntityType }
+         *     
+         */
+        public EntityType getType() {
+            return type;
+        }
+
+        /**
+         * Sets the value of the type property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link EntityType }
+         *     
+         */
+        public void setType(EntityType value) {
+            this.type = value;
+        }
+
+        /**
+         * Gets the value of the entityId property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getEntityId() {
+            return entityId;
+        }
+
+        /**
+         * Sets the value of the entityId property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setEntityId(String value) {
+            this.entityId = value;
+        }
+
+
+        /**
+         * <p>Java class for anonymous complex type.
+         * 
+         * <p>The following schema fragment specifies the expected content contained within this class.
+         * 
+         * <pre>
+         * &lt;complexType>
+         *   &lt;complexContent>
+         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+         *     &lt;/restriction>
+         *   &lt;/complexContent>
+         * &lt;/complexType>
+         * </pre>
+         * 
+         * 
+         */
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "", propOrder = {
+            "content"
+        })
+        public static class EntityDetail {
+
+            @XmlValue
+            protected String content;
+            @XmlAttribute(name = "dbSource")
+            protected String dbSource;
+            @XmlAttribute(name = "property", required = true)
+            protected String property;
+
+            /**
+             * Gets the value of the content property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getContent() {
+                return content;
+            }
+
+            /**
+             * Sets the value of the content property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setContent(String value) {
+                this.content = value;
+            }
+
+            /**
+             * Gets the value of the dbSource property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getDbSource() {
+                return dbSource;
+            }
+
+            /**
+             * Sets the value of the dbSource property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setDbSource(String value) {
+                this.dbSource = value;
+            }
+
+            /**
+             * Gets the value of the property property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getProperty() {
+                return property;
+            }
+
+            /**
+             * Sets the value of the property property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setProperty(String value) {
+                this.property = value;
+            }
+
+        }
+
+
+        /**
+         * <p>Java class for anonymous complex type.
+         * 
+         * <p>The following schema fragment specifies the expected content contained within this class.
+         * 
+         * <pre>
+         * &lt;complexType>
+         *   &lt;complexContent>
+         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *       &lt;sequence>
+         *         &lt;element name="listResidue" minOccurs="0">
+         *           &lt;complexType>
+         *             &lt;complexContent>
+         *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                 &lt;sequence>
+         *                   &lt;element name="residue" maxOccurs="unbounded">
+         *                     &lt;complexType>
+         *                       &lt;complexContent>
+         *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                           &lt;sequence>
+         *                             &lt;element name="crossRefDb" maxOccurs="unbounded" minOccurs="0">
+         *                               &lt;complexType>
+         *                                 &lt;complexContent>
+         *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                                     &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbRef"/>
+         *                                     &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}resRef"/>
+         *                                     &lt;attribute name="dbChainId" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}chainId" />
+         *                                   &lt;/restriction>
+         *                                 &lt;/complexContent>
+         *                               &lt;/complexType>
+         *                             &lt;/element>
+         *                             &lt;element name="residueDetail" maxOccurs="unbounded" minOccurs="0">
+         *                               &lt;complexType>
+         *                                 &lt;complexContent>
+         *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                                     &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+         *                                   &lt;/restriction>
+         *                                 &lt;/complexContent>
+         *                               &lt;/complexType>
+         *                             &lt;/element>
+         *                           &lt;/sequence>
+         *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}resRef"/>
+         *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}listdbRef"/>
+         *                         &lt;/restriction>
+         *                       &lt;/complexContent>
+         *                     &lt;/complexType>
+         *                   &lt;/element>
+         *                 &lt;/sequence>
+         *               &lt;/restriction>
+         *             &lt;/complexContent>
+         *           &lt;/complexType>
+         *         &lt;/element>
+         *         &lt;element name="listMapRegion" minOccurs="0">
+         *           &lt;complexType>
+         *             &lt;complexContent>
+         *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                 &lt;sequence>
+         *                   &lt;element name="mapRegion" maxOccurs="unbounded">
+         *                     &lt;complexType>
+         *                       &lt;complexContent>
+         *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                           &lt;sequence>
+         *                             &lt;element name="db">
+         *                               &lt;complexType>
+         *                                 &lt;complexContent>
+         *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                                     &lt;sequence>
+         *                                       &lt;element name="dbDetail" maxOccurs="unbounded" minOccurs="0">
+         *                                         &lt;complexType>
+         *                                           &lt;complexContent>
+         *                                             &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                                               &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+         *                                             &lt;/restriction>
+         *                                           &lt;/complexContent>
+         *                                         &lt;/complexType>
+         *                                       &lt;/element>
+         *                                     &lt;/sequence>
+         *                                     &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbRef"/>
+         *                                     &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+         *                                     &lt;attribute name="dbChainId" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbChainId" />
+         *                                   &lt;/restriction>
+         *                                 &lt;/complexContent>
+         *                               &lt;/complexType>
+         *                             &lt;/element>
+         *                           &lt;/sequence>
+         *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+         *                         &lt;/restriction>
+         *                       &lt;/complexContent>
+         *                     &lt;/complexType>
+         *                   &lt;/element>
+         *                 &lt;/sequence>
+         *               &lt;/restriction>
+         *             &lt;/complexContent>
+         *           &lt;/complexType>
+         *         &lt;/element>
+         *         &lt;element name="segmentDetail" maxOccurs="unbounded" minOccurs="0">
+         *           &lt;complexType>
+         *             &lt;complexContent>
+         *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+         *               &lt;/restriction>
+         *             &lt;/complexContent>
+         *           &lt;/complexType>
+         *         &lt;/element>
+         *       &lt;/sequence>
+         *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+         *       &lt;attribute name="segId" use="required" type="{http://www.w3.org/2001/XMLSchema}string" />
+         *     &lt;/restriction>
+         *   &lt;/complexContent>
+         * &lt;/complexType>
+         * </pre>
+         * 
+         * 
+         */
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "", propOrder = {
+            "listResidue",
+            "listMapRegion",
+            "segmentDetail"
+        })
+        public static class Segment {
+
+            protected Entry.Entity.Segment.ListResidue listResidue;
+            protected Entry.Entity.Segment.ListMapRegion listMapRegion;
+            protected List<Entry.Entity.Segment.SegmentDetail> segmentDetail;
+            @XmlAttribute(name = "segId", required = true)
+            protected String segId;
+            @XmlAttribute(name = "start")
+            protected String start;
+            @XmlAttribute(name = "end")
+            protected String end;
+
+            /**
+             * Gets the value of the listResidue property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link Entry.Entity.Segment.ListResidue }
+             *     
+             */
+            public Entry.Entity.Segment.ListResidue getListResidue() {
+                return listResidue;
+            }
+
+            /**
+             * Sets the value of the listResidue property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link Entry.Entity.Segment.ListResidue }
+             *     
+             */
+            public void setListResidue(Entry.Entity.Segment.ListResidue value) {
+                this.listResidue = value;
+            }
+
+            /**
+             * Gets the value of the listMapRegion property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link Entry.Entity.Segment.ListMapRegion }
+             *     
+             */
+            public Entry.Entity.Segment.ListMapRegion getListMapRegion() {
+                return listMapRegion;
+            }
+
+            /**
+             * Sets the value of the listMapRegion property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link Entry.Entity.Segment.ListMapRegion }
+             *     
+             */
+            public void setListMapRegion(Entry.Entity.Segment.ListMapRegion value) {
+                this.listMapRegion = value;
+            }
+
+            /**
+             * Gets the value of the segmentDetail property.
+             * 
+             * <p>
+             * This accessor method returns a reference to the live list,
+             * not a snapshot. Therefore any modification you make to the
+             * returned list will be present inside the JAXB object.
+             * This is why there is not a <CODE>set</CODE> method for the segmentDetail property.
+             * 
+             * <p>
+             * For example, to add a new item, do as follows:
+             * <pre>
+             *    getSegmentDetail().add(newItem);
+             * </pre>
+             * 
+             * 
+             * <p>
+             * Objects of the following type(s) are allowed in the list
+             * {@link Entry.Entity.Segment.SegmentDetail }
+             * 
+             * 
+             */
+            public List<Entry.Entity.Segment.SegmentDetail> getSegmentDetail() {
+                if (segmentDetail == null) {
+                    segmentDetail = new ArrayList<Entry.Entity.Segment.SegmentDetail>();
+                }
+                return this.segmentDetail;
+            }
+
+            /**
+             * Gets the value of the segId property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getSegId() {
+                return segId;
+            }
+
+            /**
+             * Sets the value of the segId property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setSegId(String value) {
+                this.segId = value;
+            }
+
+            /**
+             * Gets the value of the start property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getStart() {
+                return start;
+            }
+
+            /**
+             * Sets the value of the start property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setStart(String value) {
+                this.start = value;
+            }
+
+            /**
+             * Gets the value of the end property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getEnd() {
+                return end;
+            }
+
+            /**
+             * Sets the value of the end property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setEnd(String value) {
+                this.end = value;
+            }
+
+
+            /**
+             * <p>Java class for anonymous complex type.
+             * 
+             * <p>The following schema fragment specifies the expected content contained within this class.
+             * 
+             * <pre>
+             * &lt;complexType>
+             *   &lt;complexContent>
+             *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *       &lt;sequence>
+             *         &lt;element name="mapRegion" maxOccurs="unbounded">
+             *           &lt;complexType>
+             *             &lt;complexContent>
+             *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *                 &lt;sequence>
+             *                   &lt;element name="db">
+             *                     &lt;complexType>
+             *                       &lt;complexContent>
+             *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *                           &lt;sequence>
+             *                             &lt;element name="dbDetail" maxOccurs="unbounded" minOccurs="0">
+             *                               &lt;complexType>
+             *                                 &lt;complexContent>
+             *                                   &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *                                     &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+             *                                   &lt;/restriction>
+             *                                 &lt;/complexContent>
+             *                               &lt;/complexType>
+             *                             &lt;/element>
+             *                           &lt;/sequence>
+             *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbRef"/>
+             *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+             *                           &lt;attribute name="dbChainId" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbChainId" />
+             *                         &lt;/restriction>
+             *                       &lt;/complexContent>
+             *                     &lt;/complexType>
+             *                   &lt;/element>
+             *                 &lt;/sequence>
+             *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+             *               &lt;/restriction>
+             *             &lt;/complexContent>
+             *           &lt;/complexType>
+             *         &lt;/element>
+             *       &lt;/sequence>
+             *     &lt;/restriction>
+             *   &lt;/complexContent>
+             * &lt;/complexType>
+             * </pre>
+             * 
+             * 
+             */
+            @XmlAccessorType(XmlAccessType.FIELD)
+            @XmlType(name = "", propOrder = {
+                "mapRegion"
+            })
+            public static class ListMapRegion {
+
+                @XmlElement(required = true)
+                protected List<Entry.Entity.Segment.ListMapRegion.MapRegion> mapRegion;
+
+                /**
+                 * Gets the value of the mapRegion property.
+                 * 
+                 * <p>
+                 * This accessor method returns a reference to the live list,
+                 * not a snapshot. Therefore any modification you make to the
+                 * returned list will be present inside the JAXB object.
+                 * This is why there is not a <CODE>set</CODE> method for the mapRegion property.
+                 * 
+                 * <p>
+                 * For example, to add a new item, do as follows:
+                 * <pre>
+                 *    getMapRegion().add(newItem);
+                 * </pre>
+                 * 
+                 * 
+                 * <p>
+                 * Objects of the following type(s) are allowed in the list
+                 * {@link Entry.Entity.Segment.ListMapRegion.MapRegion }
+                 * 
+                 * 
+                 */
+                public List<Entry.Entity.Segment.ListMapRegion.MapRegion> getMapRegion() {
+                    if (mapRegion == null) {
+                        mapRegion = new ArrayList<Entry.Entity.Segment.ListMapRegion.MapRegion>();
+                    }
+                    return this.mapRegion;
+                }
+
+
+                /**
+                 * <p>Java class for anonymous complex type.
+                 * 
+                 * <p>The following schema fragment specifies the expected content contained within this class.
+                 * 
+                 * <pre>
+                 * &lt;complexType>
+                 *   &lt;complexContent>
+                 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+                 *       &lt;sequence>
+                 *         &lt;element name="db">
+                 *           &lt;complexType>
+                 *             &lt;complexContent>
+                 *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+                 *                 &lt;sequence>
+                 *                   &lt;element name="dbDetail" maxOccurs="unbounded" minOccurs="0">
+                 *                     &lt;complexType>
+                 *                       &lt;complexContent>
+                 *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+                 *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+                 *                         &lt;/restriction>
+                 *                       &lt;/complexContent>
+                 *                     &lt;/complexType>
+                 *                   &lt;/element>
+                 *                 &lt;/sequence>
+                 *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbRef"/>
+                 *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+                 *                 &lt;attribute name="dbChainId" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbChainId" />
+                 *               &lt;/restriction>
+                 *             &lt;/complexContent>
+                 *           &lt;/complexType>
+                 *         &lt;/element>
+                 *       &lt;/sequence>
+                 *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+                 *     &lt;/restriction>
+                 *   &lt;/complexContent>
+                 * &lt;/complexType>
+                 * </pre>
+                 * 
+                 * 
+                 */
+                @XmlAccessorType(XmlAccessType.FIELD)
+                @XmlType(name = "", propOrder = {
+                    "db"
+                })
+                public static class MapRegion {
+
+                    @XmlElement(required = true)
+                    protected Entry.Entity.Segment.ListMapRegion.MapRegion.Db db;
+                    @XmlAttribute(name = "start")
+                    protected String start;
+                    @XmlAttribute(name = "end")
+                    protected String end;
+
+                    /**
+                     * Gets the value of the db property.
+                     * 
+                     * @return
+                     *     possible object is
+                     *     {@link Entry.Entity.Segment.ListMapRegion.MapRegion.Db }
+                     *     
+                     */
+                    public Entry.Entity.Segment.ListMapRegion.MapRegion.Db getDb() {
+                        return db;
+                    }
+
+                    /**
+                     * Sets the value of the db property.
+                     * 
+                     * @param value
+                     *     allowed object is
+                     *     {@link Entry.Entity.Segment.ListMapRegion.MapRegion.Db }
+                     *     
+                     */
+                    public void setDb(Entry.Entity.Segment.ListMapRegion.MapRegion.Db value) {
+                        this.db = value;
+                    }
+
+                    /**
+                     * Gets the value of the start property.
+                     * 
+                     * @return
+                     *     possible object is
+                     *     {@link String }
+                     *     
+                     */
+                    public String getStart() {
+                        return start;
+                    }
+
+                    /**
+                     * Sets the value of the start property.
+                     * 
+                     * @param value
+                     *     allowed object is
+                     *     {@link String }
+                     *     
+                     */
+                    public void setStart(String value) {
+                        this.start = value;
+                    }
+
+                    /**
+                     * Gets the value of the end property.
+                     * 
+                     * @return
+                     *     possible object is
+                     *     {@link String }
+                     *     
+                     */
+                    public String getEnd() {
+                        return end;
+                    }
+
+                    /**
+                     * Sets the value of the end property.
+                     * 
+                     * @param value
+                     *     allowed object is
+                     *     {@link String }
+                     *     
+                     */
+                    public void setEnd(String value) {
+                        this.end = value;
+                    }
+
+
+                    /**
+                     * <p>Java class for anonymous complex type.
+                     * 
+                     * <p>The following schema fragment specifies the expected content contained within this class.
+                     * 
+                     * <pre>
+                     * &lt;complexType>
+                     *   &lt;complexContent>
+                     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+                     *       &lt;sequence>
+                     *         &lt;element name="dbDetail" maxOccurs="unbounded" minOccurs="0">
+                     *           &lt;complexType>
+                     *             &lt;complexContent>
+                     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+                     *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+                     *               &lt;/restriction>
+                     *             &lt;/complexContent>
+                     *           &lt;/complexType>
+                     *         &lt;/element>
+                     *       &lt;/sequence>
+                     *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbRef"/>
+                     *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}region"/>
+                     *       &lt;attribute name="dbChainId" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbChainId" />
+                     *     &lt;/restriction>
+                     *   &lt;/complexContent>
+                     * &lt;/complexType>
+                     * </pre>
+                     * 
+                     * 
+                     */
+                    @XmlAccessorType(XmlAccessType.FIELD)
+                    @XmlType(name = "", propOrder = {
+                        "dbDetail"
+                    })
+                    public static class Db {
+
+                        protected List<Entry.Entity.Segment.ListMapRegion.MapRegion.Db.DbDetail> dbDetail;
+                        @XmlAttribute(name = "dbChainId")
+                        protected String dbChainId;
+                        @XmlAttribute(name = "dbSource", required = true)
+                        protected String dbSource;
+                        @XmlAttribute(name = "dbCoordSys", required = true)
+                        protected String dbCoordSys;
+                        @XmlAttribute(name = "dbAccessionId", required = true)
+                        protected String dbAccessionId;
+                        @XmlAttribute(name = "dbEvidence")
+                        protected String dbEvidence;
+                        @XmlAttribute(name = "dbVersion")
+                        protected String dbVersion;
+                        @XmlAttribute(name = "start")
+                        protected String start;
+                        @XmlAttribute(name = "end")
+                        protected String end;
+
+                        /**
+                         * Gets the value of the dbDetail property.
+                         * 
+                         * <p>
+                         * This accessor method returns a reference to the live list,
+                         * not a snapshot. Therefore any modification you make to the
+                         * returned list will be present inside the JAXB object.
+                         * This is why there is not a <CODE>set</CODE> method for the dbDetail property.
+                         * 
+                         * <p>
+                         * For example, to add a new item, do as follows:
+                         * <pre>
+                         *    getDbDetail().add(newItem);
+                         * </pre>
+                         * 
+                         * 
+                         * <p>
+                         * Objects of the following type(s) are allowed in the list
+                         * {@link Entry.Entity.Segment.ListMapRegion.MapRegion.Db.DbDetail }
+                         * 
+                         * 
+                         */
+                        public List<Entry.Entity.Segment.ListMapRegion.MapRegion.Db.DbDetail> getDbDetail() {
+                            if (dbDetail == null) {
+                                dbDetail = new ArrayList<Entry.Entity.Segment.ListMapRegion.MapRegion.Db.DbDetail>();
+                            }
+                            return this.dbDetail;
+                        }
+
+                        /**
+                         * Gets the value of the dbChainId property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getDbChainId() {
+                            return dbChainId;
+                        }
+
+                        /**
+                         * Sets the value of the dbChainId property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setDbChainId(String value) {
+                            this.dbChainId = value;
+                        }
+
+                        /**
+                         * Gets the value of the dbSource property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getDbSource() {
+                            return dbSource;
+                        }
+
+                        /**
+                         * Sets the value of the dbSource property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setDbSource(String value) {
+                            this.dbSource = value;
+                        }
+
+                        /**
+                         * Gets the value of the dbCoordSys property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getDbCoordSys() {
+                            return dbCoordSys;
+                        }
+
+                        /**
+                         * Sets the value of the dbCoordSys property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setDbCoordSys(String value) {
+                            this.dbCoordSys = value;
+                        }
+
+                        /**
+                         * Gets the value of the dbAccessionId property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getDbAccessionId() {
+                            return dbAccessionId;
+                        }
+
+                        /**
+                         * Sets the value of the dbAccessionId property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setDbAccessionId(String value) {
+                            this.dbAccessionId = value;
+                        }
+
+                        /**
+                         * Gets the value of the dbEvidence property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getDbEvidence() {
+                            return dbEvidence;
+                        }
+
+                        /**
+                         * Sets the value of the dbEvidence property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setDbEvidence(String value) {
+                            this.dbEvidence = value;
+                        }
+
+                        /**
+                         * Gets the value of the dbVersion property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getDbVersion() {
+                            return dbVersion;
+                        }
+
+                        /**
+                         * Sets the value of the dbVersion property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setDbVersion(String value) {
+                            this.dbVersion = value;
+                        }
+
+                        /**
+                         * Gets the value of the start property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getStart() {
+                            return start;
+                        }
+
+                        /**
+                         * Sets the value of the start property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setStart(String value) {
+                            this.start = value;
+                        }
+
+                        /**
+                         * Gets the value of the end property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getEnd() {
+                            return end;
+                        }
+
+                        /**
+                         * Sets the value of the end property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setEnd(String value) {
+                            this.end = value;
+                        }
+
+
+                        /**
+                         * <p>Java class for anonymous complex type.
+                         * 
+                         * <p>The following schema fragment specifies the expected content contained within this class.
+                         * 
+                         * <pre>
+                         * &lt;complexType>
+                         *   &lt;complexContent>
+                         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+                         *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+                         *     &lt;/restriction>
+                         *   &lt;/complexContent>
+                         * &lt;/complexType>
+                         * </pre>
+                         * 
+                         * 
+                         */
+                        @XmlAccessorType(XmlAccessType.FIELD)
+                        @XmlType(name = "", propOrder = {
+                            "content"
+                        })
+                        public static class DbDetail {
+
+                            @XmlValue
+                            protected String content;
+                            @XmlAttribute(name = "dbSource")
+                            protected String dbSource;
+                            @XmlAttribute(name = "property", required = true)
+                            protected String property;
+
+                            /**
+                             * Gets the value of the content property.
+                             * 
+                             * @return
+                             *     possible object is
+                             *     {@link String }
+                             *     
+                             */
+                            public String getContent() {
+                                return content;
+                            }
+
+                            /**
+                             * Sets the value of the content property.
+                             * 
+                             * @param value
+                             *     allowed object is
+                             *     {@link String }
+                             *     
+                             */
+                            public void setContent(String value) {
+                                this.content = value;
+                            }
+
+                            /**
+                             * Gets the value of the dbSource property.
+                             * 
+                             * @return
+                             *     possible object is
+                             *     {@link String }
+                             *     
+                             */
+                            public String getDbSource() {
+                                return dbSource;
+                            }
+
+                            /**
+                             * Sets the value of the dbSource property.
+                             * 
+                             * @param value
+                             *     allowed object is
+                             *     {@link String }
+                             *     
+                             */
+                            public void setDbSource(String value) {
+                                this.dbSource = value;
+                            }
+
+                            /**
+                             * Gets the value of the property property.
+                             * 
+                             * @return
+                             *     possible object is
+                             *     {@link String }
+                             *     
+                             */
+                            public String getProperty() {
+                                return property;
+                            }
+
+                            /**
+                             * Sets the value of the property property.
+                             * 
+                             * @param value
+                             *     allowed object is
+                             *     {@link String }
+                             *     
+                             */
+                            public void setProperty(String value) {
+                                this.property = value;
+                            }
+
+                        }
+
+                    }
+
+                }
+
+            }
+
+
+            /**
+             * <p>Java class for anonymous complex type.
+             * 
+             * <p>The following schema fragment specifies the expected content contained within this class.
+             * 
+             * <pre>
+             * &lt;complexType>
+             *   &lt;complexContent>
+             *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *       &lt;sequence>
+             *         &lt;element name="residue" maxOccurs="unbounded">
+             *           &lt;complexType>
+             *             &lt;complexContent>
+             *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *                 &lt;sequence>
+             *                   &lt;element name="crossRefDb" maxOccurs="unbounded" minOccurs="0">
+             *                     &lt;complexType>
+             *                       &lt;complexContent>
+             *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbRef"/>
+             *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}resRef"/>
+             *                           &lt;attribute name="dbChainId" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}chainId" />
+             *                         &lt;/restriction>
+             *                       &lt;/complexContent>
+             *                     &lt;/complexType>
+             *                   &lt;/element>
+             *                   &lt;element name="residueDetail" maxOccurs="unbounded" minOccurs="0">
+             *                     &lt;complexType>
+             *                       &lt;complexContent>
+             *                         &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *                           &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+             *                         &lt;/restriction>
+             *                       &lt;/complexContent>
+             *                     &lt;/complexType>
+             *                   &lt;/element>
+             *                 &lt;/sequence>
+             *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}resRef"/>
+             *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}listdbRef"/>
+             *               &lt;/restriction>
+             *             &lt;/complexContent>
+             *           &lt;/complexType>
+             *         &lt;/element>
+             *       &lt;/sequence>
+             *     &lt;/restriction>
+             *   &lt;/complexContent>
+             * &lt;/complexType>
+             * </pre>
+             * 
+             * 
+             */
+            @XmlAccessorType(XmlAccessType.FIELD)
+            @XmlType(name = "", propOrder = {
+                "residue"
+            })
+            public static class ListResidue {
+
+                @XmlElement(required = true)
+                protected List<Entry.Entity.Segment.ListResidue.Residue> residue;
+
+                /**
+                 * Gets the value of the residue property.
+                 * 
+                 * <p>
+                 * This accessor method returns a reference to the live list,
+                 * not a snapshot. Therefore any modification you make to the
+                 * returned list will be present inside the JAXB object.
+                 * This is why there is not a <CODE>set</CODE> method for the residue property.
+                 * 
+                 * <p>
+                 * For example, to add a new item, do as follows:
+                 * <pre>
+                 *    getResidue().add(newItem);
+                 * </pre>
+                 * 
+                 * 
+                 * <p>
+                 * Objects of the following type(s) are allowed in the list
+                 * {@link Entry.Entity.Segment.ListResidue.Residue }
+                 * 
+                 * 
+                 */
+                public List<Entry.Entity.Segment.ListResidue.Residue> getResidue() {
+                    if (residue == null) {
+                        residue = new ArrayList<Entry.Entity.Segment.ListResidue.Residue>();
+                    }
+                    return this.residue;
+                }
+
+
+                /**
+                 * <p>Java class for anonymous complex type.
+                 * 
+                 * <p>The following schema fragment specifies the expected content contained within this class.
+                 * 
+                 * <pre>
+                 * &lt;complexType>
+                 *   &lt;complexContent>
+                 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+                 *       &lt;sequence>
+                 *         &lt;element name="crossRefDb" maxOccurs="unbounded" minOccurs="0">
+                 *           &lt;complexType>
+                 *             &lt;complexContent>
+                 *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+                 *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbRef"/>
+                 *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}resRef"/>
+                 *                 &lt;attribute name="dbChainId" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}chainId" />
+                 *               &lt;/restriction>
+                 *             &lt;/complexContent>
+                 *           &lt;/complexType>
+                 *         &lt;/element>
+                 *         &lt;element name="residueDetail" maxOccurs="unbounded" minOccurs="0">
+                 *           &lt;complexType>
+                 *             &lt;complexContent>
+                 *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+                 *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+                 *               &lt;/restriction>
+                 *             &lt;/complexContent>
+                 *           &lt;/complexType>
+                 *         &lt;/element>
+                 *       &lt;/sequence>
+                 *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}resRef"/>
+                 *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}listdbRef"/>
+                 *     &lt;/restriction>
+                 *   &lt;/complexContent>
+                 * &lt;/complexType>
+                 * </pre>
+                 * 
+                 * 
+                 */
+                @XmlAccessorType(XmlAccessType.FIELD)
+                @XmlType(name = "", propOrder = {
+                    "crossRefDb",
+                    "residueDetail"
+                })
+                public static class Residue {
+
+                    protected List<Entry.Entity.Segment.ListResidue.Residue.CrossRefDb> crossRefDb;
+                    protected List<Entry.Entity.Segment.ListResidue.Residue.ResidueDetail> residueDetail;
+                    @XmlAttribute(name = "dbResNum", required = true)
+                    protected String dbResNum;
+                    @XmlAttribute(name = "dbResName", required = true)
+                    protected String dbResName;
+                    @XmlAttribute(name = "dbVersion")
+                    protected String dbVersion;
+                    @XmlAttribute(name = "dbSource", required = true)
+                    protected String dbSource;
+                    @XmlAttribute(name = "dbCoordSys", required = true)
+                    protected String dbCoordSys;
+
+                    /**
+                     * Gets the value of the crossRefDb property.
+                     * 
+                     * <p>
+                     * This accessor method returns a reference to the live list,
+                     * not a snapshot. Therefore any modification you make to the
+                     * returned list will be present inside the JAXB object.
+                     * This is why there is not a <CODE>set</CODE> method for the crossRefDb property.
+                     * 
+                     * <p>
+                     * For example, to add a new item, do as follows:
+                     * <pre>
+                     *    getCrossRefDb().add(newItem);
+                     * </pre>
+                     * 
+                     * 
+                     * <p>
+                     * Objects of the following type(s) are allowed in the list
+                     * {@link Entry.Entity.Segment.ListResidue.Residue.CrossRefDb }
+                     * 
+                     * 
+                     */
+                    public List<Entry.Entity.Segment.ListResidue.Residue.CrossRefDb> getCrossRefDb() {
+                        if (crossRefDb == null) {
+                            crossRefDb = new ArrayList<Entry.Entity.Segment.ListResidue.Residue.CrossRefDb>();
+                        }
+                        return this.crossRefDb;
+                    }
+
+                    /**
+                     * Gets the value of the residueDetail property.
+                     * 
+                     * <p>
+                     * This accessor method returns a reference to the live list,
+                     * not a snapshot. Therefore any modification you make to the
+                     * returned list will be present inside the JAXB object.
+                     * This is why there is not a <CODE>set</CODE> method for the residueDetail property.
+                     * 
+                     * <p>
+                     * For example, to add a new item, do as follows:
+                     * <pre>
+                     *    getResidueDetail().add(newItem);
+                     * </pre>
+                     * 
+                     * 
+                     * <p>
+                     * Objects of the following type(s) are allowed in the list
+                     * {@link Entry.Entity.Segment.ListResidue.Residue.ResidueDetail }
+                     * 
+                     * 
+                     */
+                    public List<Entry.Entity.Segment.ListResidue.Residue.ResidueDetail> getResidueDetail() {
+                        if (residueDetail == null) {
+                            residueDetail = new ArrayList<Entry.Entity.Segment.ListResidue.Residue.ResidueDetail>();
+                        }
+                        return this.residueDetail;
+                    }
+
+                    /**
+                     * Gets the value of the dbResNum property.
+                     * 
+                     * @return
+                     *     possible object is
+                     *     {@link String }
+                     *     
+                     */
+                    public String getDbResNum() {
+                        return dbResNum;
+                    }
+
+                    /**
+                     * Sets the value of the dbResNum property.
+                     * 
+                     * @param value
+                     *     allowed object is
+                     *     {@link String }
+                     *     
+                     */
+                    public void setDbResNum(String value) {
+                        this.dbResNum = value;
+                    }
+
+                    /**
+                     * Gets the value of the dbResName property.
+                     * 
+                     * @return
+                     *     possible object is
+                     *     {@link String }
+                     *     
+                     */
+                    public String getDbResName() {
+                        return dbResName;
+                    }
+
+                    /**
+                     * Sets the value of the dbResName property.
+                     * 
+                     * @param value
+                     *     allowed object is
+                     *     {@link String }
+                     *     
+                     */
+                    public void setDbResName(String value) {
+                        this.dbResName = value;
+                    }
+
+                    /**
+                     * Gets the value of the dbVersion property.
+                     * 
+                     * @return
+                     *     possible object is
+                     *     {@link String }
+                     *     
+                     */
+                    public String getDbVersion() {
+                        return dbVersion;
+                    }
+
+                    /**
+                     * Sets the value of the dbVersion property.
+                     * 
+                     * @param value
+                     *     allowed object is
+                     *     {@link String }
+                     *     
+                     */
+                    public void setDbVersion(String value) {
+                        this.dbVersion = value;
+                    }
+
+                    /**
+                     * Gets the value of the dbSource property.
+                     * 
+                     * @return
+                     *     possible object is
+                     *     {@link String }
+                     *     
+                     */
+                    public String getDbSource() {
+                        return dbSource;
+                    }
+
+                    /**
+                     * Sets the value of the dbSource property.
+                     * 
+                     * @param value
+                     *     allowed object is
+                     *     {@link String }
+                     *     
+                     */
+                    public void setDbSource(String value) {
+                        this.dbSource = value;
+                    }
+
+                    /**
+                     * Gets the value of the dbCoordSys property.
+                     * 
+                     * @return
+                     *     possible object is
+                     *     {@link String }
+                     *     
+                     */
+                    public String getDbCoordSys() {
+                        return dbCoordSys;
+                    }
+
+                    /**
+                     * Sets the value of the dbCoordSys property.
+                     * 
+                     * @param value
+                     *     allowed object is
+                     *     {@link String }
+                     *     
+                     */
+                    public void setDbCoordSys(String value) {
+                        this.dbCoordSys = value;
+                    }
+
+
+                    /**
+                     * <p>Java class for anonymous complex type.
+                     * 
+                     * <p>The following schema fragment specifies the expected content contained within this class.
+                     * 
+                     * <pre>
+                     * &lt;complexType>
+                     *   &lt;complexContent>
+                     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+                     *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}dbRef"/>
+                     *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}resRef"/>
+                     *       &lt;attribute name="dbChainId" type="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}chainId" />
+                     *     &lt;/restriction>
+                     *   &lt;/complexContent>
+                     * &lt;/complexType>
+                     * </pre>
+                     * 
+                     * 
+                     */
+                    @XmlAccessorType(XmlAccessType.FIELD)
+                    @XmlType(name = "")
+                    public static class CrossRefDb {
+
+                        @XmlAttribute(name = "dbChainId")
+                        protected String dbChainId;
+                        @XmlAttribute(name = "dbSource", required = true)
+                        protected String dbSource;
+                        @XmlAttribute(name = "dbCoordSys", required = true)
+                        protected String dbCoordSys;
+                        @XmlAttribute(name = "dbAccessionId", required = true)
+                        protected String dbAccessionId;
+                        @XmlAttribute(name = "dbEvidence")
+                        protected String dbEvidence;
+                        @XmlAttribute(name = "dbVersion")
+                        protected String dbVersion;
+                        @XmlAttribute(name = "dbResNum", required = true)
+                        protected String dbResNum;
+                        @XmlAttribute(name = "dbResName", required = true)
+                        protected String dbResName;
+
+                        /**
+                         * Gets the value of the dbChainId property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getDbChainId() {
+                            return dbChainId;
+                        }
+
+                        /**
+                         * Sets the value of the dbChainId property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setDbChainId(String value) {
+                            this.dbChainId = value;
+                        }
+
+                        /**
+                         * Gets the value of the dbSource property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getDbSource() {
+                            return dbSource;
+                        }
+
+                        /**
+                         * Sets the value of the dbSource property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setDbSource(String value) {
+                            this.dbSource = value;
+                        }
+
+                        /**
+                         * Gets the value of the dbCoordSys property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getDbCoordSys() {
+                            return dbCoordSys;
+                        }
+
+                        /**
+                         * Sets the value of the dbCoordSys property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setDbCoordSys(String value) {
+                            this.dbCoordSys = value;
+                        }
+
+                        /**
+                         * Gets the value of the dbAccessionId property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getDbAccessionId() {
+                            return dbAccessionId;
+                        }
+
+                        /**
+                         * Sets the value of the dbAccessionId property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setDbAccessionId(String value) {
+                            this.dbAccessionId = value;
+                        }
+
+                        /**
+                         * Gets the value of the dbEvidence property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getDbEvidence() {
+                            return dbEvidence;
+                        }
+
+                        /**
+                         * Sets the value of the dbEvidence property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setDbEvidence(String value) {
+                            this.dbEvidence = value;
+                        }
+
+                        /**
+                         * Gets the value of the dbVersion property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getDbVersion() {
+                            return dbVersion;
+                        }
+
+                        /**
+                         * Sets the value of the dbVersion property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setDbVersion(String value) {
+                            this.dbVersion = value;
+                        }
+
+                        /**
+                         * Gets the value of the dbResNum property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getDbResNum() {
+                            return dbResNum;
+                        }
+
+                        /**
+                         * Sets the value of the dbResNum property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setDbResNum(String value) {
+                            this.dbResNum = value;
+                        }
+
+                        /**
+                         * Gets the value of the dbResName property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getDbResName() {
+                            return dbResName;
+                        }
+
+                        /**
+                         * Sets the value of the dbResName property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setDbResName(String value) {
+                            this.dbResName = value;
+                        }
+
+                    }
+
+
+                    /**
+                     * <p>Java class for anonymous complex type.
+                     * 
+                     * <p>The following schema fragment specifies the expected content contained within this class.
+                     * 
+                     * <pre>
+                     * &lt;complexType>
+                     *   &lt;complexContent>
+                     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+                     *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+                     *     &lt;/restriction>
+                     *   &lt;/complexContent>
+                     * &lt;/complexType>
+                     * </pre>
+                     * 
+                     * 
+                     */
+                    @XmlAccessorType(XmlAccessType.FIELD)
+                    @XmlType(name = "", propOrder = {
+                        "content"
+                    })
+                    public static class ResidueDetail {
+
+                        @XmlValue
+                        protected String content;
+                        @XmlAttribute(name = "dbSource")
+                        protected String dbSource;
+                        @XmlAttribute(name = "property", required = true)
+                        protected String property;
+
+                        /**
+                         * Gets the value of the content property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getContent() {
+                            return content;
+                        }
+
+                        /**
+                         * Sets the value of the content property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setContent(String value) {
+                            this.content = value;
+                        }
+
+                        /**
+                         * Gets the value of the dbSource property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getDbSource() {
+                            return dbSource;
+                        }
+
+                        /**
+                         * Sets the value of the dbSource property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setDbSource(String value) {
+                            this.dbSource = value;
+                        }
+
+                        /**
+                         * Gets the value of the property property.
+                         * 
+                         * @return
+                         *     possible object is
+                         *     {@link String }
+                         *     
+                         */
+                        public String getProperty() {
+                            return property;
+                        }
+
+                        /**
+                         * Sets the value of the property property.
+                         * 
+                         * @param value
+                         *     allowed object is
+                         *     {@link String }
+                         *     
+                         */
+                        public void setProperty(String value) {
+                            this.property = value;
+                        }
+
+                    }
+
+                }
+
+            }
+
+
+            /**
+             * <p>Java class for anonymous complex type.
+             * 
+             * <p>The following schema fragment specifies the expected content contained within this class.
+             * 
+             * <pre>
+             * &lt;complexType>
+             *   &lt;complexContent>
+             *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+             *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+             *     &lt;/restriction>
+             *   &lt;/complexContent>
+             * &lt;/complexType>
+             * </pre>
+             * 
+             * 
+             */
+            @XmlAccessorType(XmlAccessType.FIELD)
+            @XmlType(name = "", propOrder = {
+                "content"
+            })
+            public static class SegmentDetail {
+
+                @XmlValue
+                protected String content;
+                @XmlAttribute(name = "dbSource")
+                protected String dbSource;
+                @XmlAttribute(name = "property", required = true)
+                protected String property;
+
+                /**
+                 * Gets the value of the content property.
+                 * 
+                 * @return
+                 *     possible object is
+                 *     {@link String }
+                 *     
+                 */
+                public String getContent() {
+                    return content;
+                }
+
+                /**
+                 * Sets the value of the content property.
+                 * 
+                 * @param value
+                 *     allowed object is
+                 *     {@link String }
+                 *     
+                 */
+                public void setContent(String value) {
+                    this.content = value;
+                }
+
+                /**
+                 * Gets the value of the dbSource property.
+                 * 
+                 * @return
+                 *     possible object is
+                 *     {@link String }
+                 *     
+                 */
+                public String getDbSource() {
+                    return dbSource;
+                }
+
+                /**
+                 * Sets the value of the dbSource property.
+                 * 
+                 * @param value
+                 *     allowed object is
+                 *     {@link String }
+                 *     
+                 */
+                public void setDbSource(String value) {
+                    this.dbSource = value;
+                }
+
+                /**
+                 * Gets the value of the property property.
+                 * 
+                 * @return
+                 *     possible object is
+                 *     {@link String }
+                 *     
+                 */
+                public String getProperty() {
+                    return property;
+                }
+
+                /**
+                 * Sets the value of the property property.
+                 * 
+                 * @param value
+                 *     allowed object is
+                 *     {@link String }
+                 *     
+                 */
+                public void setProperty(String value) {
+                    this.property = value;
+                }
+
+            }
+
+        }
+
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * 
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}detail"/>
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     * 
+     * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = {
+        "content"
+    })
+    public static class EntryDetail {
+
+        @XmlValue
+        protected String content;
+        @XmlAttribute(name = "dbSource")
+        protected String dbSource;
+        @XmlAttribute(name = "property", required = true)
+        protected String property;
+
+        /**
+         * Gets the value of the content property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getContent() {
+            return content;
+        }
+
+        /**
+         * Sets the value of the content property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setContent(String value) {
+            this.content = value;
+        }
+
+        /**
+         * Gets the value of the dbSource property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getDbSource() {
+            return dbSource;
+        }
+
+        /**
+         * Sets the value of the dbSource property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setDbSource(String value) {
+            this.dbSource = value;
+        }
+
+        /**
+         * Gets the value of the property property.
+         * 
+         * @return
+         *     possible object is
+         *     {@link String }
+         *     
+         */
+        public String getProperty() {
+            return property;
+        }
+
+        /**
+         * Sets the value of the property property.
+         * 
+         * @param value
+         *     allowed object is
+         *     {@link String }
+         *     
+         */
+        public void setProperty(String value) {
+            this.property = value;
+        }
+
+    }
+
+
+    /**
+     * <p>Java class for anonymous complex type.
+     * 
+     * <p>The following schema fragment specifies the expected content contained within this class.
+     * 
+     * <pre>
+     * &lt;complexType>
+     *   &lt;complexContent>
+     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *       &lt;sequence maxOccurs="unbounded">
+     *         &lt;element name="db">
+     *           &lt;complexType>
+     *             &lt;complexContent>
+     *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+     *                 &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}listdbRef"/>
+     *               &lt;/restriction>
+     *             &lt;/complexContent>
+     *           &lt;/complexType>
+     *         &lt;/element>
+     *       &lt;/sequence>
+     *     &lt;/restriction>
+     *   &lt;/complexContent>
+     * &lt;/complexType>
+     * </pre>
+     * 
+     * 
+     */
+    @XmlAccessorType(XmlAccessType.FIELD)
+    @XmlType(name = "", propOrder = {
+        "db"
+    })
+    public static class ListDB {
+
+        @XmlElement(required = true)
+        protected List<Entry.ListDB.Db> db;
+
+        /**
+         * Gets the value of the db property.
+         * 
+         * <p>
+         * This accessor method returns a reference to the live list,
+         * not a snapshot. Therefore any modification you make to the
+         * returned list will be present inside the JAXB object.
+         * This is why there is not a <CODE>set</CODE> method for the db property.
+         * 
+         * <p>
+         * For example, to add a new item, do as follows:
+         * <pre>
+         *    getDb().add(newItem);
+         * </pre>
+         * 
+         * 
+         * <p>
+         * Objects of the following type(s) are allowed in the list
+         * {@link Entry.ListDB.Db }
+         * 
+         * 
+         */
+        public List<Entry.ListDB.Db> getDb() {
+            if (db == null) {
+                db = new ArrayList<Entry.ListDB.Db>();
+            }
+            return this.db;
+        }
+
+
+        /**
+         * <p>Java class for anonymous complex type.
+         * 
+         * <p>The following schema fragment specifies the expected content contained within this class.
+         * 
+         * <pre>
+         * &lt;complexType>
+         *   &lt;complexContent>
+         *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
+         *       &lt;attGroup ref="{http://www.ebi.ac.uk/pdbe/docs/sifts/dataTypes.xsd}listdbRef"/>
+         *     &lt;/restriction>
+         *   &lt;/complexContent>
+         * &lt;/complexType>
+         * </pre>
+         * 
+         * 
+         */
+        @XmlAccessorType(XmlAccessType.FIELD)
+        @XmlType(name = "")
+        public static class Db {
+
+            @XmlAttribute(name = "dbVersion")
+            protected String dbVersion;
+            @XmlAttribute(name = "dbSource", required = true)
+            protected String dbSource;
+            @XmlAttribute(name = "dbCoordSys", required = true)
+            protected String dbCoordSys;
+
+            /**
+             * Gets the value of the dbVersion property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getDbVersion() {
+                return dbVersion;
+            }
+
+            /**
+             * Sets the value of the dbVersion property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setDbVersion(String value) {
+                this.dbVersion = value;
+            }
+
+            /**
+             * Gets the value of the dbSource property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getDbSource() {
+                return dbSource;
+            }
+
+            /**
+             * Sets the value of the dbSource property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setDbSource(String value) {
+                this.dbSource = value;
+            }
+
+            /**
+             * Gets the value of the dbCoordSys property.
+             * 
+             * @return
+             *     possible object is
+             *     {@link String }
+             *     
+             */
+            public String getDbCoordSys() {
+                return dbCoordSys;
+            }
+
+            /**
+             * Sets the value of the dbCoordSys property.
+             * 
+             * @param value
+             *     allowed object is
+             *     {@link String }
+             *     
+             */
+            public void setDbCoordSys(String value) {
+                this.dbCoordSys = value;
+            }
+
+        }
+
+    }
+
+}
diff --git a/src/jalview/xml/binding/sifts/ObjectFactory.java b/src/jalview/xml/binding/sifts/ObjectFactory.java
new file mode 100644 (file)
index 0000000..7b74e13
--- /dev/null
@@ -0,0 +1,319 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
+// Any modifications to this file will be lost upon recompilation of the source schema. 
+// Generated on: 2015.10.09 at 03:18:33 PM BST 
+//
+
+
+package jalview.xml.binding.sifts;
+
+import javax.xml.bind.annotation.XmlRegistry;
+
+
+/**
+ * This object contains factory methods for each 
+ * Java content interface and Java element interface 
+ * generated in the jalview.xml.binding.sifts package. 
+ * <p>An ObjectFactory allows you to programatically 
+ * construct new instances of the Java representation 
+ * for XML content. The Java representation of XML 
+ * content can consist of schema derived interfaces 
+ * and classes representing the binding of schema 
+ * type definitions, element declarations and model 
+ * groups.  Factory methods for each of these are 
+ * provided in this class.
+ * 
+ */
+@XmlRegistry
+public class ObjectFactory {
+
+
+    /**
+     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: jalview.xml.binding.sifts
+     * 
+     */
+    public ObjectFactory() {
+    }
+
+    /**
+     * Create an instance of {@link Entry }
+     * 
+     */
+    public Entry createEntry() {
+        return new Entry();
+    }
+
+    /**
+     * Create an instance of {@link Alignment }
+     * 
+     */
+    public Alignment createAlignment() {
+        return new Alignment();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.Geo3D }
+     * 
+     */
+    public Alignment.Geo3D createAlignmentGeo3D() {
+        return new Alignment.Geo3D();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.Geo3D.Matrix }
+     * 
+     */
+    public Alignment.Geo3D.Matrix createAlignmentGeo3DMatrix() {
+        return new Alignment.Geo3D.Matrix();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.Block }
+     * 
+     */
+    public Alignment.Block createAlignmentBlock() {
+        return new Alignment.Block();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.AlignObject }
+     * 
+     */
+    public Alignment.AlignObject createAlignmentAlignObject() {
+        return new Alignment.AlignObject();
+    }
+
+    /**
+     * Create an instance of {@link Entry.Entity }
+     * 
+     */
+    public Entry.Entity createEntryEntity() {
+        return new Entry.Entity();
+    }
+
+    /**
+     * Create an instance of {@link Entry.Entity.Segment }
+     * 
+     */
+    public Entry.Entity.Segment createEntryEntitySegment() {
+        return new Entry.Entity.Segment();
+    }
+
+    /**
+     * Create an instance of {@link Entry.Entity.Segment.ListMapRegion }
+     * 
+     */
+    public Entry.Entity.Segment.ListMapRegion createEntryEntitySegmentListMapRegion() {
+        return new Entry.Entity.Segment.ListMapRegion();
+    }
+
+    /**
+     * Create an instance of {@link Entry.Entity.Segment.ListMapRegion.MapRegion }
+     * 
+     */
+    public Entry.Entity.Segment.ListMapRegion.MapRegion createEntryEntitySegmentListMapRegionMapRegion() {
+        return new Entry.Entity.Segment.ListMapRegion.MapRegion();
+    }
+
+    /**
+     * Create an instance of {@link Entry.Entity.Segment.ListMapRegion.MapRegion.Db }
+     * 
+     */
+    public Entry.Entity.Segment.ListMapRegion.MapRegion.Db createEntryEntitySegmentListMapRegionMapRegionDb() {
+        return new Entry.Entity.Segment.ListMapRegion.MapRegion.Db();
+    }
+
+    /**
+     * Create an instance of {@link Entry.Entity.Segment.ListResidue }
+     * 
+     */
+    public Entry.Entity.Segment.ListResidue createEntryEntitySegmentListResidue() {
+        return new Entry.Entity.Segment.ListResidue();
+    }
+
+    /**
+     * Create an instance of {@link Entry.Entity.Segment.ListResidue.Residue }
+     * 
+     */
+    public Entry.Entity.Segment.ListResidue.Residue createEntryEntitySegmentListResidueResidue() {
+        return new Entry.Entity.Segment.ListResidue.Residue();
+    }
+
+    /**
+     * Create an instance of {@link Entry.ListDB }
+     * 
+     */
+    public Entry.ListDB createEntryListDB() {
+        return new Entry.ListDB();
+    }
+
+    /**
+     * Create an instance of {@link Entry.EntryDetail }
+     * 
+     */
+    public Entry.EntryDetail createEntryEntryDetail() {
+        return new Entry.EntryDetail();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.Score }
+     * 
+     */
+    public Alignment.Score createAlignmentScore() {
+        return new Alignment.Score();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.Geo3D.Vector }
+     * 
+     */
+    public Alignment.Geo3D.Vector createAlignmentGeo3DVector() {
+        return new Alignment.Geo3D.Vector();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.Geo3D.Matrix.Max11 }
+     * 
+     */
+    public Alignment.Geo3D.Matrix.Max11 createAlignmentGeo3DMatrixMax11() {
+        return new Alignment.Geo3D.Matrix.Max11();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.Geo3D.Matrix.Max12 }
+     * 
+     */
+    public Alignment.Geo3D.Matrix.Max12 createAlignmentGeo3DMatrixMax12() {
+        return new Alignment.Geo3D.Matrix.Max12();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.Geo3D.Matrix.Max13 }
+     * 
+     */
+    public Alignment.Geo3D.Matrix.Max13 createAlignmentGeo3DMatrixMax13() {
+        return new Alignment.Geo3D.Matrix.Max13();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.Geo3D.Matrix.Max21 }
+     * 
+     */
+    public Alignment.Geo3D.Matrix.Max21 createAlignmentGeo3DMatrixMax21() {
+        return new Alignment.Geo3D.Matrix.Max21();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.Geo3D.Matrix.Max22 }
+     * 
+     */
+    public Alignment.Geo3D.Matrix.Max22 createAlignmentGeo3DMatrixMax22() {
+        return new Alignment.Geo3D.Matrix.Max22();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.Geo3D.Matrix.Max23 }
+     * 
+     */
+    public Alignment.Geo3D.Matrix.Max23 createAlignmentGeo3DMatrixMax23() {
+        return new Alignment.Geo3D.Matrix.Max23();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.Geo3D.Matrix.Max31 }
+     * 
+     */
+    public Alignment.Geo3D.Matrix.Max31 createAlignmentGeo3DMatrixMax31() {
+        return new Alignment.Geo3D.Matrix.Max31();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.Geo3D.Matrix.Max32 }
+     * 
+     */
+    public Alignment.Geo3D.Matrix.Max32 createAlignmentGeo3DMatrixMax32() {
+        return new Alignment.Geo3D.Matrix.Max32();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.Geo3D.Matrix.Max33 }
+     * 
+     */
+    public Alignment.Geo3D.Matrix.Max33 createAlignmentGeo3DMatrixMax33() {
+        return new Alignment.Geo3D.Matrix.Max33();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.Block.Segment }
+     * 
+     */
+    public Alignment.Block.Segment createAlignmentBlockSegment() {
+        return new Alignment.Block.Segment();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.AlignObject.AlignObjectDetail }
+     * 
+     */
+    public Alignment.AlignObject.AlignObjectDetail createAlignmentAlignObjectAlignObjectDetail() {
+        return new Alignment.AlignObject.AlignObjectDetail();
+    }
+
+    /**
+     * Create an instance of {@link Alignment.AlignObject.Sequence }
+     * 
+     */
+    public Alignment.AlignObject.Sequence createAlignmentAlignObjectSequence() {
+        return new Alignment.AlignObject.Sequence();
+    }
+
+    /**
+     * Create an instance of {@link Entry.Entity.EntityDetail }
+     * 
+     */
+    public Entry.Entity.EntityDetail createEntryEntityEntityDetail() {
+        return new Entry.Entity.EntityDetail();
+    }
+
+    /**
+     * Create an instance of {@link Entry.Entity.Segment.SegmentDetail }
+     * 
+     */
+    public Entry.Entity.Segment.SegmentDetail createEntryEntitySegmentSegmentDetail() {
+        return new Entry.Entity.Segment.SegmentDetail();
+    }
+
+    /**
+     * Create an instance of {@link Entry.Entity.Segment.ListMapRegion.MapRegion.Db.DbDetail }
+     * 
+     */
+    public Entry.Entity.Segment.ListMapRegion.MapRegion.Db.DbDetail createEntryEntitySegmentListMapRegionMapRegionDbDbDetail() {
+        return new Entry.Entity.Segment.ListMapRegion.MapRegion.Db.DbDetail();
+    }
+
+    /**
+     * Create an instance of {@link Entry.Entity.Segment.ListResidue.Residue.CrossRefDb }
+     * 
+     */
+    public Entry.Entity.Segment.ListResidue.Residue.CrossRefDb createEntryEntitySegmentListResidueResidueCrossRefDb() {
+        return new Entry.Entity.Segment.ListResidue.Residue.CrossRefDb();
+    }
+
+    /**
+     * Create an instance of {@link Entry.Entity.Segment.ListResidue.Residue.ResidueDetail }
+     * 
+     */
+    public Entry.Entity.Segment.ListResidue.Residue.ResidueDetail createEntryEntitySegmentListResidueResidueResidueDetail() {
+        return new Entry.Entity.Segment.ListResidue.Residue.ResidueDetail();
+    }
+
+    /**
+     * Create an instance of {@link Entry.ListDB.Db }
+     * 
+     */
+    public Entry.ListDB.Db createEntryListDBDb() {
+        return new Entry.ListDB.Db();
+    }
+
+}
diff --git a/src/jalview/xml/binding/sifts/package-info.java b/src/jalview/xml/binding/sifts/package-info.java
new file mode 100644 (file)
index 0000000..aac24fe
--- /dev/null
@@ -0,0 +1,9 @@
+//
+// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 
+// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
+// Any modifications to this file will be lost upon recompilation of the source schema. 
+// Generated on: 2015.10.09 at 03:18:33 PM BST 
+//
+
+@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.ebi.ac.uk/pdbe/docs/sifts/eFamily.xsd", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
+package jalview.xml.binding.sifts;
index a48db4b..09bd64e 100644 (file)
@@ -989,7 +989,7 @@ public class AlignmentUtilsTests
     assertTrue(AlignmentUtils.haveCrossRef(seq2, seq1));
 
     // now the other way round
-    seq1.setDBRef(null);
+    seq1.setDBRefs(null);
     seq2.addDBRef(new DBRefEntry("EMBL", "1", "A12345"));
     assertTrue(AlignmentUtils.haveCrossRef(seq1, seq2));
     assertTrue(AlignmentUtils.haveCrossRef(seq2, seq1));
@@ -1125,8 +1125,8 @@ public class AlignmentUtilsTests
 
     assertEquals("GGGTTT", cdsSeq.getSequenceAsString());
     assertEquals("dna1|A12345", cdsSeq.getName());
-    assertEquals(1, cdsSeq.getDBRef().length);
-    DBRefEntry cdsRef = cdsSeq.getDBRef()[0];
+    assertEquals(1, cdsSeq.getDBRefs().length);
+    DBRefEntry cdsRef = cdsSeq.getDBRefs()[0];
     assertEquals("EMBLCDS", cdsRef.getSource());
     assertEquals("2", cdsRef.getVersion());
     assertEquals("A12345", cdsRef.getAccessionId());
@@ -1196,8 +1196,8 @@ public class AlignmentUtilsTests
     SequenceI cdsSeq = cds.get(0);
     assertEquals("GGGTTT", cdsSeq.getSequenceAsString());
     assertEquals("dna1|A12345", cdsSeq.getName());
-    assertEquals(1, cdsSeq.getDBRef().length);
-    DBRefEntry cdsRef = cdsSeq.getDBRef()[0];
+    assertEquals(1, cdsSeq.getDBRefs().length);
+    DBRefEntry cdsRef = cdsSeq.getDBRefs()[0];
     assertEquals("EMBLCDS", cdsRef.getSource());
     assertEquals("2", cdsRef.getVersion());
     assertEquals("A12345", cdsRef.getAccessionId());
@@ -1205,8 +1205,8 @@ public class AlignmentUtilsTests
     cdsSeq = cds.get(1);
     assertEquals("aaaccc", cdsSeq.getSequenceAsString());
     assertEquals("dna1|A12346", cdsSeq.getName());
-    assertEquals(1, cdsSeq.getDBRef().length);
-    cdsRef = cdsSeq.getDBRef()[0];
+    assertEquals(1, cdsSeq.getDBRefs().length);
+    cdsRef = cdsSeq.getDBRefs()[0];
     assertEquals("EMBLCDS", cdsRef.getSource());
     assertEquals("3", cdsRef.getVersion());
     assertEquals("A12346", cdsRef.getAccessionId());
@@ -1214,8 +1214,8 @@ public class AlignmentUtilsTests
     cdsSeq = cds.get(2);
     assertEquals("aaaTTT", cdsSeq.getSequenceAsString());
     assertEquals("dna1|A12347", cdsSeq.getName());
-    assertEquals(1, cdsSeq.getDBRef().length);
-    cdsRef = cdsSeq.getDBRef()[0];
+    assertEquals(1, cdsSeq.getDBRefs().length);
+    cdsRef = cdsSeq.getDBRefs()[0];
     assertEquals("EMBLCDS", cdsRef.getSource());
     assertEquals("4", cdsRef.getVersion());
     assertEquals("A12347", cdsRef.getAccessionId());
diff --git a/test/jalview/commands/TrimRegionCommandTest.java b/test/jalview/commands/TrimRegionCommandTest.java
new file mode 100644 (file)
index 0000000..d593d41
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.commands;
+
+import static org.testng.AssertJUnit.assertEquals;
+
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * Unit tests for TrimRegionCommand
+ * 
+ * @author gmcarstairs
+ *
+ */
+public class TrimRegionCommandTest
+{
+  private AlignmentI al;
+
+  @BeforeMethod(alwaysRun = true)
+  public void setUp()
+  {
+    SequenceI[] seqs = new SequenceI[2];
+    seqs[0] = new Sequence("seq0", "abcde-");
+    seqs[1] = new Sequence("seq1", "-ghjkl");
+    al = new Alignment(seqs);
+    al.setDataset(null);
+  }
+
+  /**
+   * Test performing, undoing and redoing a 'trim left'
+   */
+  @Test(groups = { "Functional" })
+  public void testTrimLeft_withUndoAndRedo()
+  {
+    TrimRegionCommand cmd = new TrimRegionCommand("Remove Left", true,
+            al.getSequencesArray(), 2, al);
+    assertEquals(2, cmd.getSize());
+    assertEquals("cde-", al.getSequenceAt(0).getSequenceAsString());
+    assertEquals("hjkl", al.getSequenceAt(1).getSequenceAsString());
+
+    /*
+     * undo and verify
+     */
+    cmd.undoCommand(new AlignmentI[] { al });
+    assertEquals("abcde-", al.getSequenceAt(0).getSequenceAsString());
+    assertEquals("-ghjkl", al.getSequenceAt(1).getSequenceAsString());
+
+    /*
+     * redo and verify
+     */
+    cmd.doCommand(new AlignmentI[] { al });
+    assertEquals("cde-", al.getSequenceAt(0).getSequenceAsString());
+    assertEquals("hjkl", al.getSequenceAt(1).getSequenceAsString());
+  }
+
+  /**
+   * Trim left of no columns - should do nothing. This is the case where the
+   * first column is selected and 'Remove Left' is selected.
+   */
+  @Test(groups = { "Functional" })
+  public void testTrimLeft_noColumns()
+  {
+    TrimRegionCommand cmd = new TrimRegionCommand("Remove Left", true,
+            al.getSequencesArray(), 0, al);
+    assertEquals(0, cmd.getSize());
+    assertEquals("abcde-", al.getSequenceAt(0).getSequenceAsString());
+    assertEquals("-ghjkl", al.getSequenceAt(1).getSequenceAsString());
+  }
+
+  /**
+   * Trim left of a single column
+   */
+  @Test(groups = { "Functional" })
+  public void testTrimLeft_oneColumn()
+  {
+    TrimRegionCommand cmd = new TrimRegionCommand("Remove Left", true,
+            al.getSequencesArray(), 1, al);
+    assertEquals(1, cmd.getSize());
+    assertEquals("bcde-", al.getSequenceAt(0).getSequenceAsString());
+    assertEquals("ghjkl", al.getSequenceAt(1).getSequenceAsString());
+  }
+
+  /**
+   * Trim right of no columns - should do nothing. This is the case where the
+   * last column is selected and 'Remove Right' is selected.
+   */
+  @Test(groups = { "Functional" })
+  public void testTrimRight_noColumns()
+  {
+    TrimRegionCommand cmd = new TrimRegionCommand("Remove Right", false,
+            al.getSequencesArray(), 5, al);
+    assertEquals(0, cmd.getSize());
+    assertEquals("abcde-", al.getSequenceAt(0).getSequenceAsString());
+    assertEquals("-ghjkl", al.getSequenceAt(1).getSequenceAsString());
+  }
+
+  /**
+   * Trim right of a single column
+   */
+  @Test(groups = { "Functional" })
+  public void testTrimRight_oneColumn()
+  {
+    TrimRegionCommand cmd = new TrimRegionCommand("Remove Right", false,
+            al.getSequencesArray(), 4, al);
+    assertEquals(1, cmd.getSize());
+    assertEquals("abcde", al.getSequenceAt(0).getSequenceAsString());
+    assertEquals("-ghjk", al.getSequenceAt(1).getSequenceAsString());
+  }
+
+  /**
+   * Test performing, undoing and redoing a 'trim right'
+   */
+  @Test(groups = { "Functional" })
+  public void testTrimRight_withUndoAndRedo()
+  {
+    TrimRegionCommand cmd = new TrimRegionCommand("Remove Right", false,
+            al.getSequencesArray(), 2, al);
+    assertEquals(3, cmd.getSize());
+    assertEquals("abc", al.getSequenceAt(0).getSequenceAsString());
+    assertEquals("-gh", al.getSequenceAt(1).getSequenceAsString());
+
+    /*
+     * undo and verify
+     */
+    cmd.undoCommand(new AlignmentI[] { al });
+    assertEquals("abcde-", al.getSequenceAt(0).getSequenceAsString());
+    assertEquals("-ghjkl", al.getSequenceAt(1).getSequenceAsString());
+
+    /*
+     * redo and verify
+     */
+    cmd.doCommand(new AlignmentI[] { al });
+    assertEquals("abc", al.getSequenceAt(0).getSequenceAsString());
+    assertEquals("-gh", al.getSequenceAt(1).getSequenceAsString());
+  }
+}
index f4c5b77..698f259 100644 (file)
 package jalview.datamodel;
 
 import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertSame;
+import static org.testng.AssertJUnit.assertTrue;
 
+import java.util.Arrays;
 import java.util.List;
 
 import org.testng.annotations.Test;
@@ -35,10 +39,10 @@ public class ColumnSelectionTest
     ColumnSelection cs = new ColumnSelection();
     cs.addElement(2);
     cs.addElement(5);
+    cs.addElement(3);
+    cs.addElement(5); // ignored
     List<Integer> sel = cs.getSelected();
-    assertEquals(2, sel.size());
-    assertEquals(new Integer(2), sel.get(0));
-    assertEquals(new Integer(5), sel.get(1));
+    assertEquals("[2, 5, 3]", sel.toString());
   }
 
   /**
@@ -80,10 +84,6 @@ public class ColumnSelectionTest
     cs.hideColumns(6, 6);
     assertEquals(5, cs.findColumnPosition(5));
 
-    // hiding column 5 makes no difference
-    cs.hideColumns(5, 5);
-    assertEquals(5, cs.findColumnPosition(5));
-
     // hiding column 4 moves column 5 to column 4
     cs.hideColumns(4, 4);
     assertEquals(4, cs.findColumnPosition(5));
@@ -92,4 +92,255 @@ public class ColumnSelectionTest
     cs.hideColumns(1, 2);
     assertEquals(2, cs.findColumnPosition(5));
   }
+
+  @Test(groups = { "Functional" })
+  public void testHideColumns()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.hideColumns(5);
+    List<int[]> hidden = cs.getHiddenColumns();
+    assertEquals(1, hidden.size());
+    assertEquals("[5, 5]", Arrays.toString(hidden.get(0)));
+
+    cs.hideColumns(3);
+    assertEquals(2, hidden.size());
+    // two hidden ranges, in order:
+    assertSame(hidden, cs.getHiddenColumns());
+    assertEquals("[3, 3]", Arrays.toString(hidden.get(0)));
+    assertEquals("[5, 5]", Arrays.toString(hidden.get(1)));
+
+    // hiding column 4 expands [3, 3] to [3, 4]
+    // not fancy enough to coalesce this into [3, 5] though
+    cs.hideColumns(4);
+    hidden = cs.getHiddenColumns();
+    assertEquals(2, hidden.size());
+    assertEquals("[3, 4]", Arrays.toString(hidden.get(0)));
+    assertEquals("[5, 5]", Arrays.toString(hidden.get(1)));
+
+    // clear hidden columns (note they are added to selected)
+    cs.revealAllHiddenColumns();
+    // it is now actually null but getter returns an empty list
+    assertTrue(cs.getHiddenColumns().isEmpty());
+
+    cs.hideColumns(3, 6);
+    hidden = cs.getHiddenColumns();
+    int[] firstHiddenRange = hidden.get(0);
+    assertEquals("[3, 6]", Arrays.toString(firstHiddenRange));
+
+    // adding a subrange of already hidden should do nothing
+    cs.hideColumns(4, 5);
+    assertEquals(1, hidden.size());
+    assertSame(firstHiddenRange, cs.getHiddenColumns().get(0));
+    cs.hideColumns(3, 5);
+    assertEquals(1, hidden.size());
+    assertSame(firstHiddenRange, cs.getHiddenColumns().get(0));
+    cs.hideColumns(4, 6);
+    assertEquals(1, hidden.size());
+    assertSame(firstHiddenRange, cs.getHiddenColumns().get(0));
+    cs.hideColumns(3, 6);
+    assertEquals(1, hidden.size());
+    assertSame(firstHiddenRange, cs.getHiddenColumns().get(0));
+
+    cs.revealAllHiddenColumns();
+    cs.hideColumns(2, 4);
+    hidden = cs.getHiddenColumns();
+    assertEquals(1, hidden.size());
+    assertEquals("[2, 4]", Arrays.toString(hidden.get(0)));
+
+    // extend contiguous with 2 positions overlap
+    cs.hideColumns(3, 5);
+    assertEquals(1, hidden.size());
+    assertEquals("[2, 5]", Arrays.toString(hidden.get(0)));
+
+    // extend contiguous with 1 position overlap
+    cs.hideColumns(5, 6);
+    assertEquals(1, hidden.size());
+    assertEquals("[2, 6]", Arrays.toString(hidden.get(0)));
+
+    // extend contiguous with overlap both ends:
+    cs.hideColumns(1, 7);
+    assertEquals(1, hidden.size());
+    assertEquals("[1, 7]", Arrays.toString(hidden.get(0)));
+  }
+
+  /**
+   * Test the method that hides a specified column including any adjacent
+   * selected columns. This is a convenience method for the case where multiple
+   * column regions are selected and then hidden using menu option View | Hide |
+   * Selected Columns.
+   */
+  @Test(groups = { "Functional" })
+  public void testHideColumns_withSelection()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    // select columns 4-6
+    cs.addElement(4);
+    cs.addElement(5);
+    cs.addElement(6);
+    // hide column 5 (and adjacent):
+    cs.hideColumns(5);
+    // 4,5,6 now hidden:
+    List<int[]> hidden = cs.getHiddenColumns();
+    assertEquals(1, hidden.size());
+    assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
+    // none now selected:
+    assertTrue(cs.getSelected().isEmpty());
+
+    // repeat, hiding column 4 (5 and 6)
+    cs = new ColumnSelection();
+    cs.addElement(4);
+    cs.addElement(5);
+    cs.addElement(6);
+    cs.hideColumns(4);
+    hidden = cs.getHiddenColumns();
+    assertEquals(1, hidden.size());
+    assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
+    assertTrue(cs.getSelected().isEmpty());
+
+    // repeat, hiding column (4, 5 and) 6
+    cs = new ColumnSelection();
+    cs.addElement(4);
+    cs.addElement(5);
+    cs.addElement(6);
+    cs.hideColumns(6);
+    hidden = cs.getHiddenColumns();
+    assertEquals(1, hidden.size());
+    assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
+    assertTrue(cs.getSelected().isEmpty());
+
+    // repeat, with _only_ adjacent columns selected
+    cs = new ColumnSelection();
+    cs.addElement(4);
+    cs.addElement(6);
+    cs.hideColumns(5);
+    hidden = cs.getHiddenColumns();
+    assertEquals(1, hidden.size());
+    assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
+    assertTrue(cs.getSelected().isEmpty());
+  }
+
+  /**
+   * Test the method that hides all (possibly disjoint) selected column ranges
+   */
+  @Test(groups = { "Functional" })
+  public void testHideSelectedColumns()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    int[] sel = { 2, 3, 4, 7, 8, 9, 20, 21, 22 };
+    for (int col : sel)
+    {
+      cs.addElement(col);
+    }
+    cs.hideColumns(15, 18);
+
+    cs.hideSelectedColumns();
+    assertTrue(cs.getSelected().isEmpty());
+    List<int[]> hidden = cs.getHiddenColumns();
+    assertEquals(4, hidden.size());
+    assertEquals("[2, 4]", Arrays.toString(hidden.get(0)));
+    assertEquals("[7, 9]", Arrays.toString(hidden.get(1)));
+    assertEquals("[15, 18]", Arrays.toString(hidden.get(2)));
+    assertEquals("[20, 22]", Arrays.toString(hidden.get(3)));
+  }
+
+  /**
+   * Test the method that reveals a range of hidden columns given the start
+   * column of the range
+   */
+  @Test(groups = { "Functional" })
+  public void testRevealHiddenColumns()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.hideColumns(5, 8);
+    cs.addElement(10);
+    cs.revealHiddenColumns(5);
+    // hidden columns list now null but getter returns empty list:
+    assertTrue(cs.getHiddenColumns().isEmpty());
+    // revealed columns are marked as selected (added to selection):
+    assertEquals("[10, 5, 6, 7, 8]", cs.getSelected().toString());
+
+    // calling with a column other than the range start does nothing:
+    cs = new ColumnSelection();
+    cs.hideColumns(5, 8);
+    List<int[]> hidden = cs.getHiddenColumns();
+    cs.revealHiddenColumns(6);
+    assertSame(hidden, cs.getHiddenColumns());
+    assertTrue(cs.getSelected().isEmpty());
+  }
+
+  @Test(groups = { "Functional" })
+  public void testRevealAllHiddenColumns()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.hideColumns(5, 8);
+    cs.hideColumns(2, 3);
+    cs.addElement(11);
+    cs.addElement(1);
+    cs.revealAllHiddenColumns();
+
+    /*
+     * revealing hidden columns adds them (in order) to the (unordered)
+     * selection list
+     */
+    assertTrue(cs.getHiddenColumns().isEmpty());
+    assertEquals("[11, 1, 2, 3, 5, 6, 7, 8]", cs.getSelected().toString());
+  }
+
+  @Test(groups = { "Functional" })
+  public void testIsVisible()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.hideColumns(2, 4);
+    cs.hideColumns(6, 7);
+    assertTrue(cs.isVisible(0));
+    assertTrue(cs.isVisible(-99));
+    assertTrue(cs.isVisible(1));
+    assertFalse(cs.isVisible(2));
+    assertFalse(cs.isVisible(3));
+    assertFalse(cs.isVisible(4));
+    assertTrue(cs.isVisible(5));
+    assertFalse(cs.isVisible(6));
+    assertFalse(cs.isVisible(7));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testGetVisibleContigs()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.hideColumns(3, 6);
+    cs.hideColumns(8, 9);
+    cs.hideColumns(12, 12);
+
+    // start position is inclusive, end position exclusive:
+    int[] visible = cs.getVisibleContigs(1, 13);
+    assertEquals("[1, 2, 7, 7, 10, 11]", Arrays.toString(visible));
+
+    visible = cs.getVisibleContigs(4, 14);
+    assertEquals("[7, 7, 10, 11, 13, 13]", Arrays.toString(visible));
+
+    visible = cs.getVisibleContigs(3, 10);
+    assertEquals("[7, 7]", Arrays.toString(visible));
+
+    visible = cs.getVisibleContigs(4, 6);
+    assertEquals("[]", Arrays.toString(visible));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testInvertColumnSelection()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(4);
+    cs.addElement(6);
+    cs.addElement(8);
+    cs.hideColumns(3, 3);
+    cs.hideColumns(6, 6);
+
+    // invert selection from start (inclusive) to end (exclusive)
+    // hidden columns are _not_ changed
+    cs.invertColumnSelection(2, 9);
+    assertEquals("[2, 5, 7]", cs.getSelected().toString());
+
+    cs.invertColumnSelection(1, 9);
+    assertEquals("[1, 4, 8]", cs.getSelected().toString());
+  }
 }
index 851caf0..dcc8ef7 100644 (file)
@@ -446,10 +446,10 @@ public class SequenceTest
     // but that doesn't distinguish it from an aligned sequence
     // which has not yet generated a dataset sequence
     // NB getDBRef looks inside dataset sequence if not null
-    DBRefEntry[] dbrefs = copy.getDBRef();
+    DBRefEntry[] dbrefs = copy.getDBRefs();
     assertEquals(1, dbrefs.length);
-    assertFalse(dbrefs[0] == seq1.getDBRef()[0]);
-    assertTrue(dbrefs[0].equals(seq1.getDBRef()[0]));
+    assertFalse(dbrefs[0] == seq1.getDBRefs()[0]);
+    assertTrue(dbrefs[0].equals(seq1.getDBRefs()[0]));
   }
 
   @Test(groups = { "Functional" })
@@ -476,9 +476,9 @@ public class SequenceTest
 
     // getDBRef looks inside dataset sequence and this is shared,
     // so holds the same dbref objects
-    DBRefEntry[] dbrefs = copy.getDBRef();
+    DBRefEntry[] dbrefs = copy.getDBRefs();
     assertEquals(1, dbrefs.length);
-    assertSame(dbrefs[0], seq1.getDBRef()[0]);
+    assertSame(dbrefs[0], seq1.getDBRefs()[0]);
   }
 
   /**
index 4ccb6e3..4dc7095 100644 (file)
@@ -33,6 +33,7 @@ import jalview.io.FileLoader;
 
 import java.util.Vector;
 
+import org.jmol.c.STR;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
@@ -44,11 +45,40 @@ import MCview.PDBfile;
  */
 public class PDBFileWithJmolTest
 {
+  /*
+   * 1GAQ has been reduced to alpha carbons only
+   * 1QCF is the full PDB file including headers, HETATM etc
+   */
   String[] testFile = new String[] { "./examples/1GAQ.txt",
       "./test/jalview/ext/jmol/1QCF.pdb" }; // ,
 
-  // "./examples/DNMT1_MOUSE.pdb"
-  // };
+  //@formatter:off
+  // a modified and very cut-down extract of 4UJ4
+  String pdbWithChainBreak =
+     "HEADER    TRANSPORT PROTEIN                       08-APR-15   4UJ4\n" +
+     // chain B has missing residues; these should all go in the same sequence:
+     "ATOM   1909  CA  VAL B 358      21.329 -19.739 -67.740  1.00201.05           C\n" +
+     "ATOM   1916  CA  GLY B 359      21.694 -23.563 -67.661  1.00198.09           C\n" +
+     "ATOM   1920  CA  LYS B 367      32.471 -12.135 -77.100  1.00257.97           C\n" +
+     "ATOM   1925  CA  ALA B 368      31.032  -9.324 -74.946  1.00276.01           C\n" +
+     // switch to chain C; should be a separate sequence
+     "ATOM   1930  CA  SER C 369      32.589  -7.517 -71.978  1.00265.44           C\n" +
+     "ATOM   1936  CA  ALA C 370      31.650  -6.849 -68.346  1.00249.48           C\n";
+  //@formatter:on
+
+  //@formatter:off
+  // a very cut-down extract of 1ejg
+  String pdbWithAltLoc =
+     "HEADER    TRANSPORT PROTEIN                       08-APR-15   1EJG\n" +
+     "ATOM    448  CA  ALA A  24       6.619  16.195   1.970  1.00  1.65           C\n" +
+     "ATOM    458  CA ALEU A  25       3.048  14.822   1.781  0.57  1.48           C\n" +
+     // alternative residue 25 entries (with ILE instead of LEU) should be ignored:
+     "ATOM    478  CA BILE A  25       3.048  14.822   1.781  0.21  1.48           C\n" +
+     // including the next altloc causes the unit test to fail but it works with the full file
+     // not sure why!
+     //     "ATOM    479  CA CILE A  25       3.048  14.822   1.781  0.22  1.48           C\n" +
+     "ATOM    512  CA  CYS A  26       4.137  11.461   3.154  1.00  1.52           C\n";
+  //@formatter:on
 
   @BeforeMethod(alwaysRun = true)
   public void setUp()
@@ -133,4 +163,79 @@ public class PDBFileWithJmolTest
             "Secondary structure not associated for sequence "
                     + sq.getName(), sq.getAnnotation()[0].sequenceRef == sq);
   }
+
+  /**
+   * Test parsing a chain with missing residues
+   * 
+   * @throws Exception
+   */
+  @Test(groups = { "Functional" })
+  public void testParse_missingResidues() throws Exception
+  {
+    PDBfile mctest = new PDBfile(false, false, false, pdbWithChainBreak,
+            AppletFormatAdapter.PASTE);
+    PDBFileWithJmol jtest = new PDBFileWithJmol(pdbWithChainBreak,
+            jalview.io.AppletFormatAdapter.PASTE);
+    Vector<SequenceI> seqs = jtest.getSeqs();
+    Vector<SequenceI> mcseqs = mctest.getSeqs();
+
+    assertEquals("Failed to find 2 sequences\n", 2, seqs.size());
+    assertEquals("Failed to find 2 sequences\n", 2, mcseqs.size());
+    assertEquals("VGKA", seqs.get(0).getSequenceAsString());
+    assertEquals("VGKA", mcseqs.get(0).getSequenceAsString());
+    assertEquals("SA", seqs.get(1).getSequenceAsString());
+    assertEquals("SA", mcseqs.get(1).getSequenceAsString());
+  }
+
+  /**
+   * Test parsing a chain with 'altloc' residues
+   * 
+   * @throws Exception
+   */
+  @Test(groups = { "Functional" })
+  public void testParse_alternativeResidues() throws Exception
+  {
+    PDBfile mctest = new PDBfile(false, false, false, pdbWithAltLoc,
+            AppletFormatAdapter.PASTE);
+    PDBFileWithJmol jtest = new PDBFileWithJmol(pdbWithAltLoc,
+            jalview.io.AppletFormatAdapter.PASTE);
+    Vector<SequenceI> seqs = jtest.getSeqs();
+    Vector<SequenceI> mcseqs = mctest.getSeqs();
+  
+    assertEquals("Failed to find 1 sequence\n", 1, seqs.size());
+    assertEquals("Failed to find 1 sequence\n", 1, mcseqs.size());
+    assertEquals("ALC", seqs.get(0).getSequenceAsString());
+    assertEquals("ALC", mcseqs.get(0).getSequenceAsString());
+  }
+
+  @Test(groups = "Functional")
+  public void testSetSecondaryStructure()
+  {
+    PDBFileWithJmol testee = new PDBFileWithJmol();
+    char[] struct = new char[10];
+    char[] structCode = new char[10];
+    struct[0] = '1';
+    structCode[0] = '1';
+
+    testee.setSecondaryStructure(STR.NONE, 0, struct, structCode);
+    testee.setSecondaryStructure(STR.HELIX, 1, struct, structCode);
+    testee.setSecondaryStructure(STR.HELIX310, 2, struct, structCode);
+    testee.setSecondaryStructure(STR.HELIXALPHA, 3, struct, structCode);
+    testee.setSecondaryStructure(STR.HELIXPI, 4, struct, structCode);
+    testee.setSecondaryStructure(STR.SHEET, 5, struct, structCode);
+
+    assertEquals(0, struct[0]);
+    assertEquals('H', struct[1]);
+    assertEquals('3', struct[2]);
+    assertEquals('H', struct[3]);
+    assertEquals('P', struct[4]);
+    assertEquals('E', struct[5]);
+
+    assertEquals(0, structCode[0]);
+    assertEquals('H', structCode[1]);
+    assertEquals('H', structCode[2]);
+    assertEquals('H', structCode[3]);
+    assertEquals('H', structCode[4]);
+    assertEquals('E', structCode[5]);
+  }
 }
diff --git a/test/jalview/io/1a70.xml.gz b/test/jalview/io/1a70.xml.gz
new file mode 100644 (file)
index 0000000..3f0b68a
Binary files /dev/null and b/test/jalview/io/1a70.xml.gz differ
diff --git a/test/jalview/io/PfamFormatInputTest.java b/test/jalview/io/PfamFormatInputTest.java
new file mode 100644 (file)
index 0000000..5dd4ecb
--- /dev/null
@@ -0,0 +1,32 @@
+package jalview.io;
+
+import jalview.datamodel.AlignmentI;
+
+import java.io.IOException;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class PfamFormatInputTest
+{
+  @Test
+  public void testPfamFormatNoLimits() throws IOException
+  {
+    AlignmentI al = new jalview.io.AppletFormatAdapter().readFile("ASEQ"
+            + '\t' + "...--FFAFAFF--", AppletFormatAdapter.PASTE, "PFAM");
+    Assert.assertEquals(1, al.getHeight(), "Wrong number of sequences");
+    Assert.assertTrue(al.hasValidSequence(),
+            "Didn't extract limits from PFAM ID");
+  }
+
+  @Test
+  public void testPfamFormatValidLimits() throws IOException
+  {
+    AlignmentI al = new jalview.io.AppletFormatAdapter().readFile(
+            "ASEQ/15-25" + '\t' + "...--FFAFAFF--",
+            AppletFormatAdapter.PASTE, "PFAM");
+    Assert.assertEquals(1, al.getHeight(), "Wrong number of sequences");
+    Assert.assertTrue(al.hasValidSequence(),
+            "Didn't extract limits from PFAM ID");
+  }
+}
index 6618789..0c2c998 100644 (file)
@@ -101,10 +101,10 @@ public class ComparisonTest
   }
 
   /**
-   * Test percentage identity calculation for two sequences.
+   * Test the percentage identity calculation for two sequences
    */
   @Test(groups = { "Functional" })
-  public void testPID_matchGaps()
+  public void testPID_includingGaps()
   {
     String seq1 = "ABCDEF";
     String seq2 = "abcdef";
@@ -114,6 +114,48 @@ public class ComparisonTest
     seq2 = "abcdefghijklmnopqrstuvwxyz";
     assertEquals("identical", 100f, Comparison.PID(seq1, seq2), 0.001f);
 
-    seq2 = "a---bcdef";
+    // 5 identical, 2 gap-gap, 2 gap-residue, 1 mismatch
+    seq1 = "a--b-cdefh";
+    seq2 = "a---bcdefg";
+    int length = seq1.length();
+
+    // match gap-residue, match gap-gap: 9/10 identical
+    assertEquals(90f, Comparison.PID(seq1, seq2, 0, length, true, false),
+            0.001f);
+    // overloaded version of the method signature above:
+    assertEquals(90f, Comparison.PID(seq1, seq2), 0.001f);
+
+    // don't match gap-residue, match gap-gap: 7/10 identical
+    assertEquals(70f, Comparison.PID(seq1, seq2, 0, length, false, false),
+            0.001f);
+  }
+
+  /**
+   * Test the percentage identity calculation for two sequences
+   */
+  @Test(groups = { "Functional" })
+  public void testPID_ungappedOnly()
+  {
+    // 5 identical, 2 gap-gap, 2 gap-residue, 1 mismatch
+    String seq1 = "a--b-cdefh";
+    String seq2 = "a---bcdefg";
+    int length = seq1.length();
+
+    /*
+     * As currently coded, 'ungappedOnly' ignores gap-residue but counts
+     * gap-gap. Is this a bug - should gap-gap also be ignored, giving a PID of
+     * 5/6?
+     * 
+     * Note also there is no variant of the calculation that penalises
+     * gap-residue i.e. counts it as a mismatch. This would give a score of 5/8
+     * (if we ignore gap-gap) or 5/10 (if we count gap-gap as a match).
+     */
+    // match gap-residue, match gap-gap: 7/8 identical
+    assertEquals(87.5f, Comparison.PID(seq1, seq2, 0, length, true, true),
+            0.001f);
+
+    // don't match gap-residue with 'ungapped only' - same as above
+    assertEquals(87.5f, Comparison.PID(seq1, seq2, 0, length, false, true),
+            0.001f);
   }
 }
index b560eb8..e1eb2a6 100644 (file)
@@ -138,7 +138,7 @@ public class DBRefUtilsTest
   {
     SequenceI seq = new Sequence("Seq1", "ABCD");
     DBRefEntry ref = DBRefUtils.parseToDbRef(seq, "EMBL", "1.2", "a7890");
-    DBRefEntry[] refs = seq.getDBRef();
+    DBRefEntry[] refs = seq.getDBRefs();
     assertEquals(1, refs.length);
     assertSame(ref, refs[0]);
     assertEquals("EMBL", ref.getSource());
@@ -156,7 +156,7 @@ public class DBRefUtilsTest
     SequenceI seq = new Sequence("Seq1", "ABCD");
     DBRefEntry ref = DBRefUtils.parseToDbRef(seq, "pdb", "1.2",
             "1WRI A; 7-80;");
-    DBRefEntry[] refs = seq.getDBRef();
+    DBRefEntry[] refs = seq.getDBRefs();
     assertEquals(1, refs.length);
     assertSame(ref, refs[0]);
     assertEquals("PDB", ref.getSource());
index b3a1d8a..7100381 100644 (file)
@@ -343,8 +343,10 @@ public class MappingUtilsTest
   protected void setupMappedAlignments() throws IOException
   {
     /*
-     * Set up dna and protein Seq1/2/3 with mappings (held on the protein
-     * viewport). Lower case for introns.
+     * Map (upper-case = coding):
+     * Seq1/10-18 AC-GctGtC-T to Seq1/40 -K-P
+     * Seq2/20-27 Tc-GA-G-T-T to Seq2/20-27 L--Q
+     * Seq3/30-38 TtTT-AaCGg- to Seq3/60-61\nG--S
      */
     AlignmentI cdna = loadAlignment(">Seq1/10-18\nAC-GctGtC-T\n"
             + ">Seq2/20-27\nTc-GA-G-T-Tc\n" + ">Seq3/30-38\nTtTT-AaCGg-\n",
@@ -778,4 +780,79 @@ public class MappingUtilsTest
             Arrays.toString(MappingUtils.flattenRanges(new int[] { 12, 12,
                 9, 7, 4, 2, 1 })));
   }
+
+  /**
+   * Test mapping a column selection including hidden columns
+   * 
+   * @throws IOException
+   */
+  @Test(groups = { "Functional" })
+  public void testMapColumnSelection_hiddenColumns() throws IOException
+  {
+    setupMappedAlignments();
+  
+    ColumnSelection proteinSelection = new ColumnSelection();
+
+    /*
+     * Column 0 in protein picks up Seq2/L, Seq3/G which map to cols 0-4 and 0-3
+     * in dna respectively, overall 0-4
+     */
+    proteinSelection.hideColumns(0);
+    ColumnSelection dnaSelection = MappingUtils.mapColumnSelection(proteinSelection,
+            proteinView, dnaView);
+    assertEquals("[]", dnaSelection.getSelected().toString());
+    List<int[]> hidden = dnaSelection.getHiddenColumns();
+    assertEquals(1, hidden.size());
+    assertEquals("[0, 4]", Arrays.toString(hidden.get(0)));
+
+    /*
+     * Column 1 in protein picks up Seq1/K which maps to cols 0-3 in dna
+     */
+    proteinSelection.revealAllHiddenColumns();
+    // the unhidden columns are now marked selected!
+    assertEquals("[0]", proteinSelection.getSelected().toString());
+    // deselect these or hideColumns will be expanded to include 0
+    proteinSelection.clear();
+    proteinSelection.hideColumns(1);
+    dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
+    hidden = dnaSelection.getHiddenColumns();
+    assertEquals(1, hidden.size());
+    assertEquals("[0, 3]", Arrays.toString(hidden.get(0)));
+
+    /*
+     * Column 2 in protein picks up gaps only - no mapping
+     */
+    proteinSelection.revealAllHiddenColumns();
+    proteinSelection.clear();
+    proteinSelection.hideColumns(2);
+    dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
+    assertTrue(dnaSelection.getHiddenColumns().isEmpty());
+
+    /*
+     * Column 3 in protein picks up Seq1/P, Seq2/Q, Seq3/S which map to columns
+     * 6-9, 6-10, 5-8 respectively, overall to 5-10
+     */
+    proteinSelection.revealAllHiddenColumns();
+    proteinSelection.clear();
+    proteinSelection.hideColumns(3); // 5-10 hidden in dna
+    proteinSelection.addElement(1); // 0-3 selected in dna
+    dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
+    assertEquals("[0, 1, 2, 3]", dnaSelection.getSelected().toString());
+    hidden = dnaSelection.getHiddenColumns();
+    assertEquals(1, hidden.size());
+    assertEquals("[5, 10]", Arrays.toString(hidden.get(0)));
+
+    /*
+     * Combine hiding columns 1 and 3 to get discontiguous hidden columns
+     */
+    proteinSelection.revealAllHiddenColumns();
+    proteinSelection.clear();
+    proteinSelection.hideColumns(1);
+    proteinSelection.hideColumns(3);
+    dnaSelection = MappingUtils.mapColumnSelection(proteinSelection, proteinView, dnaView);
+    hidden = dnaSelection.getHiddenColumns();
+    assertEquals(2, hidden.size());
+    assertEquals("[0, 3]", Arrays.toString(hidden.get(0)));
+    assertEquals("[5, 10]", Arrays.toString(hidden.get(1)));
+  }
 }
index a92b5c4..7e387bd 100644 (file)
@@ -135,9 +135,13 @@ public class UniprotTest
     Vector<UniprotEntry> entries = u.getUniprotEntries(reader);
     UniprotEntry entry = entries.get(0);
 
-    // source + accession ids + names + protein names
-    String expectedName = ">UniProt/Swiss-Prot|A9CKP4|A9CKP5|A9CKP4_AGRT5|A9CKP4_AGRT6 Mitogen-activated protein kinase 13 Henry";
-    assertEquals(expectedName, Uniprot.constructSequenceFastaHeader(entry)
-            .toString());
+    // source + accession ids + names
+    String expectedName = "UniProt/Swiss-Prot|A9CKP4|A9CKP5|A9CKP4_AGRT5|A9CKP4_AGRT6";
+    // protein names
+    String expectedDescription = "Mitogen-activated protein kinase 13 Henry ";
+
+    assertEquals(expectedName, Uniprot.getUniprotEntryId(entry));
+    assertEquals(expectedDescription,
+            Uniprot.getUniprotEntryDescription(entry));
   }
 }
index 4574a09..fae5778 100644 (file)
@@ -169,7 +169,7 @@ public class DbRefFetcherTest
             FeatureProperties.isCodingFeature(embl.getDbSource(),
                     sfs[0].getType()));
     assertEquals(embl.getDbSource(), sfs[0].getFeatureGroup());
-    DBRefEntry[] dr = DBRefUtils.selectRefs(seq.getDBRef(),
+    DBRefEntry[] dr = DBRefUtils.selectRefs(seq.getDBRefs(),
             new String[] { DBRefSource.UNIPROT, DBRefSource.UNIPROTKB,
                 DBRefSource.EMBLCDSProduct, DBRefSource.ENSEMBL });
     assertNotNull(dr);
diff --git a/test/jalview/ws/sifts/SiftsClientTest.java b/test/jalview/ws/sifts/SiftsClientTest.java
new file mode 100644 (file)
index 0000000..28b44e1
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.ws.sifts;
+
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.PrintStream;
+import java.util.HashMap;
+
+import org.testng.Assert;
+import org.testng.FileAssert;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import MCview.PDBfile;
+
+public class SiftsClientTest
+{
+  private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
+
+  public static final String DEFAULT_SIFTS_DOWNLOAD_DIR = System
+          .getProperty("user.home")
+          + File.separatorChar
+          + ".sifts_downloads" + File.separatorChar;
+
+  private String testPDBId = "1a70";
+
+  private SiftsClient siftsClient = null;
+
+  SequenceI testSeq = new Sequence(
+          "P00221",
+          "MAAT..TTTMMG..MATTFVPKPQAPPMMAALPSNTGR..SLFGLKT.GSR..GGRMTMA"
+                  + "AYKVTLVTPTGNVEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDD"
+                  + "QSFLDDDQIDEGWVLTCAAYPVSDVTIETHKEEELTA.", 1, 147);
+
+  int u = SiftsClient.UNASSIGNED;
+
+  HashMap<Integer, int[]> expectedMapping = new HashMap<Integer, int[]>();
+
+  @BeforeTest(alwaysRun = true)
+  public void populateExpectedMapping() throws SiftsException
+   {
+    for (int x = 1; x <= 97; x++)
+    {
+      expectedMapping.put(50 + x, new int[] { x, u });
+    }
+   }
+   
+  @BeforeTest(alwaysRun = true)
+  public void setUpSiftsClient() throws SiftsException
+  {
+    // SIFTs entries are updated weekly - so use saved SIFTs file to enforce
+    // test reproducibility
+    SiftsSettings.setSiftDownloadDirectory(jalview.bin.Cache.getDefault(
+            "sifts_download_dir", DEFAULT_SIFTS_DOWNLOAD_DIR));
+
+    File testSiftsFile = new File("test/jalview/io/" + testPDBId
+            + ".xml.gz");
+    PDBfile pdbFile = new PDBfile(false, false, false);
+    pdbFile.id = testPDBId;
+    siftsClient = new SiftsClient(pdbFile, testSiftsFile);
+  }
+
+  @AfterTest(alwaysRun = true)
+  public void cleanUpSiftsClient()
+  {
+    siftsClient = null;
+  }
+
+  @BeforeTest(alwaysRun = true)
+  public void setUpStreams()
+  {
+    System.setOut(new PrintStream(outContent));
+  }
+
+  @AfterTest(alwaysRun = true)
+  public void cleanUpStreams()
+  {
+    System.setOut(null);
+  }
+
+  @Test(groups = { "Functional" })
+  public void getSIFTsFileTest() throws SiftsException
+  {
+    Assert.assertTrue(SiftsClient.deleteSiftsFileByPDBId(testPDBId));
+    SiftsClient.getSiftsFile(testPDBId);
+    Assert.assertFalse(outContent.toString().contains(
+            ">>> SIFTS File already downloaded for " + testPDBId));
+
+    // test for SIFTs file caching
+    SiftsClient.getSiftsFile(testPDBId);
+    Assert.assertTrue(outContent.toString().contains(
+            ">>> SIFTS File already downloaded for " + testPDBId));
+  }
+
+  @Test(groups = { "Functional" })
+  public void downloadSiftsFileTest() throws SiftsException
+  {
+    // Assert that file isn't yet downloaded - if already downloaded, assert it
+    // is deleted
+    Assert.assertTrue(SiftsClient.deleteSiftsFileByPDBId(testPDBId));
+    File siftsFile = SiftsClient.downloadSiftsFile(testPDBId);
+    FileAssert.assertFile(siftsFile);
+    SiftsClient.downloadSiftsFile(testPDBId);
+  }
+
+  @Test(groups = { "Functional" })
+  public void getAllMappingAccessionTest()
+  {
+    Assert.assertNotNull(siftsClient);
+    Assert.assertNotNull(siftsClient.getAllMappingAccession());
+    Assert.assertTrue(siftsClient.getAllMappingAccession().size() > 1);
+  }
+
+  @Test(groups = { "Functional" })
+  public void getGreedyMappingTest()
+  {
+    Assert.assertNotNull(siftsClient);
+    Assert.assertNotNull(testSeq);
+    Assert.assertNotNull(expectedMapping);
+
+    // TODO delete when auto-fetching of DBRefEntry is implemented
+    DBRefEntry dbRef = new DBRefEntry("uniprot", "", "P00221");
+    dbRef.setStartRes(1);
+    dbRef.setEndRes(147);
+    testSeq.addDBRef(dbRef);
+    // testSeq.setSourceDBRef(dbRef);
+
+    try
+    {
+      HashMap<Integer, int[]> actualMapping = siftsClient.getGreedyMapping(
+              "A", testSeq,
+              null);
+      Assert.assertEquals(actualMapping, expectedMapping);
+      Assert.assertEquals(testSeq.getStart(), 1);
+      Assert.assertEquals(testSeq.getEnd(), 147);
+    } catch (Exception e)
+    {
+      e.printStackTrace();
+      Assert.fail("Exception thrown while generating mapping...");
+    }
+  }
+
+  @Test(groups = { "Functional" })
+  private void getAtomIndexTest()
+  {
+    // siftsClient.getAtomIndex(1, null);
+    // Assert.assertTrue(true);
+  }
+
+  @Test(
+    groups = { "Functional" },
+    expectedExceptions = IllegalArgumentException.class)
+  private void getAtomIndexNullTest()
+  {
+    siftsClient.getAtomIndex(1, null);
+  }
+
+  @Test(groups = { "Functional" })
+  private void padWithGapsTest()
+  {
+
+  }
+
+  @Test(groups = { "Functional" })
+  private void populateAtomPositionsTest()
+  {
+
+  }
+
+  @Test(groups = { "Functional" })
+  public void getValidSourceDBRefTest()
+  {
+
+  }
+
+  @Test(groups = { "Functional" })
+  public void isValidDBRefEntryTest()
+  {
+
+  }
+}