Merge branch 'releases/Release_2_10_Branch'
authorJim Procter <jprocter@issues.jalview.org>
Tue, 29 Nov 2016 07:43:09 +0000 (07:43 +0000)
committerJim Procter <jprocter@issues.jalview.org>
Tue, 29 Nov 2016 07:43:09 +0000 (07:43 +0000)
178 files changed:
.classpath
AUTHORS
RELEASE
THIRDPARTYLIBS
appletlib/JmolApplet-14.2.14_2015.06.11.jar [deleted file]
appletlib/JmolApplet-14.6.4_2016.10.26.jar [new file with mode: 0644]
build.xml
examples/appletDeployment.html
examples/applets.html
examples/embedded.html
examples/embeddedWJmol.html
examples/formComplete.html
examples/javascript/facebox-1.3.js [new file with mode: 0644]
examples/javascriptLaunch.html
examples/linkedapplets_ng.html
help/help.jhm
help/helpTOC.xml
help/html/colourSchemes/abovePID.html
help/html/features/chimera.html
help/html/features/clarguments.html
help/html/features/featuresFormat.html
help/html/features/jmol.html
help/html/features/search.html
help/html/io/exportseqreport.html
help/html/keys.html
help/html/menus/alignmentMenu.html
help/html/menus/alwselect.html
help/html/misc/aaproperties.html
help/html/releases.html
help/html/webServices/dbreffetcher.html
help/html/webServices/urllinks.html
help/html/whatsNew.html
lib/Jmol-14.2.14_2015.06.11.jar [deleted file]
lib/Jmol-14.6.4_2016.10.26.jar [new file with mode: 0644]
nbproject/project.properties
resources/authors.props
resources/lang/Messages.properties
resources/lang/Messages_es.properties
src/MCview/PDBChain.java
src/ext/edu/ucsf/rbvi/strucviz2/ChimUtils.java
src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java
src/ext/edu/ucsf/rbvi/strucviz2/ChimeraModel.java
src/ext/edu/ucsf/rbvi/strucviz2/StructureManager.java
src/ext/edu/ucsf/rbvi/strucviz2/StructureSettings.java
src/ext/edu/ucsf/rbvi/strucviz2/port/ListenerThreads.java
src/jalview/analysis/AAFrequency.java
src/jalview/analysis/AlignSeq.java
src/jalview/analysis/Conservation.java
src/jalview/analysis/Finder.java
src/jalview/api/AlignViewControllerI.java
src/jalview/api/AlignViewportI.java
src/jalview/api/FeatureRenderer.java
src/jalview/appletgui/APopupMenu.java
src/jalview/appletgui/AlignViewport.java
src/jalview/appletgui/AlignmentPanel.java
src/jalview/appletgui/AppletJmol.java
src/jalview/appletgui/AppletJmolBinding.java
src/jalview/appletgui/ExtJmol.java
src/jalview/appletgui/FeatureRenderer.java
src/jalview/appletgui/Finder.java
src/jalview/appletgui/IdPanel.java
src/jalview/appletgui/SeqCanvas.java
src/jalview/appletgui/SeqPanel.java
src/jalview/appletgui/TreeCanvas.java
src/jalview/bin/Jalview.java
src/jalview/controller/AlignViewController.java
src/jalview/datamodel/AlignedCodonFrame.java
src/jalview/datamodel/Alignment.java
src/jalview/datamodel/AlignmentI.java
src/jalview/datamodel/PDBEntry.java
src/jalview/datamodel/Profile.java [new file with mode: 0644]
src/jalview/datamodel/ProfileI.java [new file with mode: 0644]
src/jalview/datamodel/Profiles.java [new file with mode: 0644]
src/jalview/datamodel/ProfilesI.java [new file with mode: 0644]
src/jalview/datamodel/ResidueCount.java [new file with mode: 0644]
src/jalview/datamodel/SearchResultMatchI.java [new file with mode: 0644]
src/jalview/datamodel/SearchResults.java
src/jalview/datamodel/SearchResultsI.java [new file with mode: 0644]
src/jalview/datamodel/SequenceFeature.java
src/jalview/datamodel/SequenceGroup.java
src/jalview/ext/android/ContainerHelpers.java [new file with mode: 0644]
src/jalview/ext/android/SparseIntArray.java [new file with mode: 0644]
src/jalview/ext/android/SparseShortArray.java [new file with mode: 0644]
src/jalview/ext/jmol/JalviewJmolBinding.java
src/jalview/ext/jmol/JmolParser.java
src/jalview/ext/rbvi/chimera/JalviewChimeraBinding.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AlignViewport.java
src/jalview/gui/AlignmentPanel.java
src/jalview/gui/AppJmol.java
src/jalview/gui/AppJmolBinding.java
src/jalview/gui/ChimeraViewFrame.java
src/jalview/gui/Desktop.java
src/jalview/gui/FeatureRenderer.java
src/jalview/gui/Finder.java
src/jalview/gui/IdPanel.java
src/jalview/gui/Jalview2XML.java
src/jalview/gui/Jalview2XML_V1.java
src/jalview/gui/JalviewChimeraBindingModel.java
src/jalview/gui/PopupMenu.java
src/jalview/gui/Preferences.java
src/jalview/gui/SeqCanvas.java
src/jalview/gui/SeqPanel.java
src/jalview/gui/StructureChooser.java
src/jalview/gui/StructureViewerBase.java
src/jalview/gui/TreeCanvas.java
src/jalview/io/AnnotationFile.java
src/jalview/io/BioJsHTMLOutput.java
src/jalview/io/HTMLOutput.java
src/jalview/io/HtmlSvgOutput.java
src/jalview/io/JnetAnnotationMaker.java
src/jalview/io/SequenceAnnotationReport.java
src/jalview/io/StructureFile.java
src/jalview/jbgui/GAlignFrame.java
src/jalview/jbgui/GSequenceLink.java
src/jalview/renderer/AnnotationRenderer.java
src/jalview/renderer/seqfeatures/FeatureRenderer.java
src/jalview/schemes/Blosum62ColourScheme.java
src/jalview/schemes/ColourSchemeI.java
src/jalview/schemes/FollowerColourScheme.java
src/jalview/schemes/PIDColourScheme.java
src/jalview/schemes/ResidueColourScheme.java
src/jalview/schemes/ResidueProperties.java
src/jalview/structure/SequenceListener.java
src/jalview/structure/StructureSelectionManager.java
src/jalview/structures/models/AAStructureBindingModel.java
src/jalview/util/ColorUtils.java
src/jalview/util/Comparison.java
src/jalview/util/DBRefUtils.java
src/jalview/util/Format.java
src/jalview/util/MappingUtils.java
src/jalview/util/Platform.java
src/jalview/util/SparseCount.java [new file with mode: 0644]
src/jalview/util/UrlConstants.java [new file with mode: 0644]
src/jalview/util/UrlLink.java
src/jalview/viewmodel/AlignmentViewport.java
src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java
src/jalview/workers/ComplementConsensusThread.java
src/jalview/workers/ConsensusThread.java
src/jalview/workers/ConservationThread.java
src/jalview/ws/sifts/SiftsClient.java
test/jalview/analysis/AAFrequencyTest.java
test/jalview/analysis/AlignmentUtilsTests.java
test/jalview/analysis/ConservationTest.java [new file with mode: 0644]
test/jalview/analysis/FinderTest.java [new file with mode: 0644]
test/jalview/analysis/scoremodels/FeatureScoreModelTest.java
test/jalview/bin/CommandLineOperations.java
test/jalview/controller/AlignViewControllerTest.java
test/jalview/datamodel/MatchTest.java
test/jalview/datamodel/ResidueCountTest.java [new file with mode: 0644]
test/jalview/datamodel/SearchResultsTest.java
test/jalview/datamodel/SequenceFeatureTest.java
test/jalview/ext/android/SparseIntArrayTest.java [new file with mode: 0644]
test/jalview/ext/android/SparseShortArrayTest.java [new file with mode: 0644]
test/jalview/ext/htsjdk/TestHtsContigDb.java
test/jalview/gui/AlignFrameTest.java
test/jalview/gui/AlignViewportTest.java
test/jalview/gui/AppVarnaTest.java
test/jalview/gui/PopupMenuTest.java
test/jalview/io/3ucu.cif [new file with mode: 0644]
test/jalview/io/BioJsHTMLOutputTest.java
test/jalview/io/JSONFileTest.java
test/jalview/io/PfamFormatInputTest.java
test/jalview/io/SequenceAnnotationReportTest.java
test/jalview/schemes/ResidueColourSchemeTest.java [new file with mode: 0644]
test/jalview/schemes/ResiduePropertiesTest.java
test/jalview/structures/models/AAStructureBindingModelTest.java
test/jalview/util/ColorUtilsTest.java
test/jalview/util/ComparisonTest.java
test/jalview/util/DBRefUtilsTest.java
test/jalview/util/FormatTest.java [new file with mode: 0644]
test/jalview/util/MappingUtilsTest.java
test/jalview/util/PlatformTest.java [new file with mode: 0644]
test/jalview/util/SparseCountTest.java [new file with mode: 0644]
test/jalview/util/UrlLinkTest.java [new file with mode: 0644]
test/jalview/ws/jabaws/DisorderAnnotExportImport.java
test/jalview/ws/sifts/SiftsClientTest.java
utils/InstallAnywhere/Jalview.iap_xml

index 6583992..8aef745 100644 (file)
@@ -64,7 +64,7 @@
        <classpathentry kind="lib" path="lib/jetty-http-9.2.10.v20150310.jar"/>
        <classpathentry kind="lib" path="lib/jetty-io-9.2.10.v20150310.jar"/>
        <classpathentry kind="lib" path="lib/java-json.jar"/>
-       <classpathentry kind="lib" path="lib/Jmol-14.2.14_2015.06.11.jar"/>
+       <classpathentry kind="lib" path="lib/Jmol-14.6.4_2016.10.26.jar"/>
        <classpathentry kind="con" path="org.testng.TESTNG_CONTAINER"/>
        <classpathentry kind="lib" path="lib/biojava-core-4.1.0.jar"/>
        <classpathentry kind="lib" path="lib/biojava-ontology-4.1.0.jar"/>
diff --git a/AUTHORS b/AUTHORS
index f0b4787..1bfc734 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -7,15 +7,16 @@ or might otherwise be considered author of Jalview.
 The people listed below are 'The Jalview Authors', who collectively
 own the copyright to the Jalview source code and permit it to be released under GPL.
 
-This is the authoritative list. It was correct on 6th Oct 2016.
+This is the authoritative list. It was correct on 23rd November 2016.
 If you are releasing a version of Jalview, please make sure any
 statement of authorship in the GUI reflects the list shown here.
 In particular, check the resources/authors.props file ! 
 
 Jim Procter
-Andrew Waterhouse
 Mungo Carstairs
 Tochukwu 'Charles' Ofoegbu
+Kira Mourao
+Andrew Waterhouse
 Jan Engelhardt
 Lauren Lui
 Anne Menard
diff --git a/RELEASE b/RELEASE
index 702d6e7..9bc5817 100644 (file)
--- a/RELEASE
+++ b/RELEASE
@@ -1,2 +1,2 @@
-jalview.release=Release_2_10_0_Branch
-jalview.version=2.10.0b1
+jalview.release=releases/Release_2_10_1_Branch
+jalview.version=2.10.1
index 31ad2f5..e0be904 100644 (file)
@@ -6,11 +6,14 @@ A number of sources have also been adapted for incorporation into Jalview's sour
 
 ext.edu.ucsf.rbvi.strucviz2 includes sources originally developed by Scooter Morris and Nadezhda Doncheva for the Cytoscape StructureViz2 plugin. It is released under the Berkley license and we hereby acknowledge its original copyright is held by the UCSF Computer Graphics Laboratory
  and the software was developed with support by the NIH National Center for Research Resources, grant P41-RR01081. 
+ jalview.ext.android includes code taken from the Android Open Source Project (https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/util).
+ The Apache 2.0 Licence (http://www.apache.org/licenses/LICENSE-2.0) is acknowledged in the source code.
 
-Licencing information for each library is given below:
+Licensing information for each library is given below:
 
 JGoogleAnalytics_0.3.jar       APL 2.0 License - http://code.google.com/p/jgoogleanalytics/
-Jmol-14.2.14_2015.06.11.jar    GPL/LGPLv2 http://sourceforge.net/projects/jmol/files/
+Jmol-14.6.4_2016.10.26.jar     GPL/LGPLv2 http://sourceforge.net/projects/jmol/files/
 VARNAv3-93.jar GPL licenced software by K�vin Darty, Alain Denise and Yann Ponty. http://varna.lri.fr
 activation.jar 
 apache-mime4j-0.6.jar
@@ -58,4 +61,5 @@ Additional dependencies
 examples/javascript/deployJava.js : http://java.com/js/deployJava.js
 examples/javascript/jquery*.js : BSD license
 examples/javascript/jshashtable-2.1.js : Apache License
+examples/javascript/facebox-1.3.js : MTI License - http://www.opensource.org/licenses/mit-license.php
 
diff --git a/appletlib/JmolApplet-14.2.14_2015.06.11.jar b/appletlib/JmolApplet-14.2.14_2015.06.11.jar
deleted file mode 100644 (file)
index 5d6338c..0000000
Binary files a/appletlib/JmolApplet-14.2.14_2015.06.11.jar and /dev/null differ
diff --git a/appletlib/JmolApplet-14.6.4_2016.10.26.jar b/appletlib/JmolApplet-14.6.4_2016.10.26.jar
new file mode 100644 (file)
index 0000000..e5c312c
Binary files /dev/null and b/appletlib/JmolApplet-14.6.4_2016.10.26.jar differ
index 1d4878b..8d27614 100755 (executable)
--- a/build.xml
+++ b/build.xml
     <property name="packageDir" value="dist" />
     <property name="outputJar" value="jalview.jar" />
     <!-- Jalview Applet JMol Jar Dependency -->
-    <property name="jmolJar" value="JmolApplet-14.2.14_2015.06.11.jar" />
+    <property name="jmolJar" value="JmolApplet-14.6.4_2016.10.26.jar" />
     <property name="varnaJar" value="VARNAv3-93.jar" />
     <property name="jsoup" value="jsoup-1.8.1.jar" />
     <property name="jsonSimple" value="json_simple-1.1.jar" />
   <!-- temporary copy of source to update timestamps -->
   <copy todir="_sourcedist">
     <fileset dir=".">
+      <exclude name=".*" />
+      <exclude name="**/.*" />
+      <exclude name="*.class" />
+      <exclude name="**/*.class" />
       <include name="LICENSE" />
       <include name="README" />
       <include name="build.xml" />
       <exclude name="utils/InstallAnywhere/**Build.iap_xml" />
       <exclude name="utils/InstallAnywhere/**Build*/**" />
       <exclude name="utils/InstallAnywhere/**Build*/**" />
+      <exclude name="utils/InstallAnywhere/.build*.*/**" />
       <exclude name="utils/InstallAnywhere/**locale*" />
       <exclude name="utils/InstallAnywhere/**locale*/**" />
+      <exclude name="utils/InstallAnywhere/**locale*/**" />
       <include name="${schemaDir}/**/*" />
       <include name="utils/**/*" />
       <include name="${docDir}/**/*" />
index 7fcca00..7b4daee 100644 (file)
@@ -33,7 +33,7 @@
     <td>Main Jalview Applet Jar</td>
   </tr>
   <tr>
-    <td><a href="http://www.jalview.org/builds/develop/examples/JmolApplet-14.2.14_2015.06.11.jar">JmolApplet-14.2.14_2015.06.11.jar</a> </td>
+    <td><a href="http://www.jalview.org/builds/develop/examples/JmolApplet-14.6.4_2016.10.26.jar">JmolApplet-14.6.4_2016.10.26.jar</a> </td>
     <td>Jmol Applet Jar</td>
   </tr>
   <tr>
@@ -48,7 +48,7 @@
 
 <p>To run Jalview applet in your web page download the Jars listed above. The snippet below shows a minimal code for embedding Jalview applet into a web page.    
 <pre><code>
-&lt;applet code="jalview.bin.JalviewLite" width="756" height="560" archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar"&gt;
+&lt;applet code="jalview.bin.JalviewLite" width="756" height="560" archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar"&gt;
        &lt;param name="permissions" value="sandbox" /&gt;
        &lt;param name="file" value="plantfdx.fa" /&gt;
        &lt;param name="features" value="plantfdx.features" /&gt;
index 1f65565..d997f14 100644 (file)
@@ -41,7 +41,7 @@ Try out JalviewLite by pressing one of the buttons below.
       <td width="10%" valign="center">
       <applet
        code="jalview.bin.JalviewLite" width="140" height="35"
-       archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">  
+       archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">  
        <param name="permissions" value="sandbox"/>
        <param name="file" value="uniref50.fa"/>
        <param name="treeFile" value="ferredoxin.nw"/>
@@ -64,7 +64,7 @@ Try out JalviewLite by pressing one of the buttons below.
     <tr>
       <td width="10%" valign="center"><applet
    code="jalview.bin.JalviewLite" width="140" height="35"
-   archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="permissions" value="sandbox"/>
 <param name="file" value="uniref50.fa"/>
 <param name="features" value="exampleFeatures.txt"/>
@@ -89,7 +89,7 @@ Try out JalviewLite by pressing one of the buttons below.
     <tr>
       <td width="10%" valign="center"><applet
    code="jalview.bin.JalviewLite" width="140" height="35"
-   archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="permissions" value="sandbox"/>
 <param name="file" value="uniref50.fa"/>
 <param name="showFullId" value="false"/>
@@ -116,7 +116,7 @@ Try out JalviewLite by pressing one of the buttons below.
     <tr>
       <td width="10%" valign="center"><applet
    code="jalview.bin.JalviewLite" width="140" height="35"
-   archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="permissions" value="sandbox"/>
 <param name="file" value="jpred_msa.fasta"/>
 <param name="jnetfile" value="jpred_msa.seq.concise"/>
@@ -147,7 +147,7 @@ Try out JalviewLite by pressing one of the buttons below.
     <tr>
       <td width="10%" valign="center"><applet
    code="jalview.bin.JalviewLite" width="140" height="35"
-   archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="permissions" value="sandbox"/>
 <param name="file" value="RF00031_folded.stk"/>
 <param name="showFullId" value="false"/>
@@ -171,7 +171,7 @@ Try out JalviewLite by pressing one of the buttons below.
       <td width="10%" valign="center">
 <applet
    code="jalview.bin.JalviewLite" width="140" height="35"
-   archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="permissions" value="sandbox"/>
 <param name="file2" value="estrogenReceptorCdna_frag.fa"/>
 <param name="file" value="estrogenReceptorProtein_frag.fa"/>
index 0d5ddf3..0cea17d 100644 (file)
@@ -40,7 +40,7 @@
   <a href="view-source:http://www.jalview.org/builds/develop/examples/embedded.html" target="_blank">View the source code for this example here</a> (If the link doesn't work on your browser try going to <a href="http://www.jalview.org/builds/develop/examples/embedded.html">this page</a> and viewing the page source manually).<p>
   <applet
    code="jalview.bin.JalviewLite" width="756" height="560"
-   archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="permissions" value="sandbox"/>
 <param name="file" value="plantfdx.fa"/>
 <param name="features" value="plantfdx.features"/>
index 501c20e..6fdcc07 100644 (file)
@@ -211,7 +211,7 @@ jQuery.extend(Drupal.settings, {"basePath":"\/","pathPrefix":"","ajaxPageState":
 <script language="JavaScript">
 // instead of this, we use a custom JmolApplet spec
 // jmolInitialize('jmol');
-jmolInitialize("","JmolApplet-14.2.14_2015.06.11.jar");
+jmolInitialize("","JmolApplet-14.6.4_2016.10.26.jar");
 </script>
 <script>
  var loglevel=1;
@@ -242,7 +242,7 @@ jmolInitialize("","JmolApplet-14.2.14_2015.06.11.jar");
  var _jvA=new Object();
  _jvA.attributes = {
   code : 'jalview.bin.JalviewLite',
-  archive : 'jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar',
+  archive : 'jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar',
   width : '500',
   height : '350',
   mayscript : 'True',
@@ -295,7 +295,7 @@ jmolInitialize("","JmolApplet-14.2.14_2015.06.11.jar");
 </div>
 <div>
 <applet
-   code="jalview.bin.JalviewLite" width="500" height="350" id="jvA" mayscript="mayscript" archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   code="jalview.bin.JalviewLite" width="500" height="350" id="jvA" mayscript="mayscript" archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="permissions" value="sandbox"/>
 <param name="java_arguments" value="-Xmx256m"/>
 <param name="externalstructureviewer" value="true"/>
index 9e89990..65a3a45 100644 (file)
@@ -36,7 +36,7 @@ instance on the page.</p>
   <a href="view-source:http://www.jalview.org/builds/develop/examples/formComplete.html" target="_blank">View the source here to see how it has been done</a>  (If the link doesn't work on your browser try going to <a href="http://www.jalview.org/builds/develop/examples/formComplete.html">this page</a> and viewing the page source manually).<br/>
 <a name="api">View the full <a href="javascript:doSubmit('jalviewLiteJs')">JalviewLite API documentation</a>.</a>
 <applet code="jalview.bin.JalviewLite" width="0" height="0"
-       archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar" name="Jalview">
+       archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar" name="Jalview">
   
   <param name="file" value="plantfdx.fa"/>
   <param name="features" value="plantfdx.features"/>
diff --git a/examples/javascript/facebox-1.3.js b/examples/javascript/facebox-1.3.js
new file mode 100644 (file)
index 0000000..ad45310
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ * Facebox (for jQuery)
+ * version: 1.2 (05/05/2008)
+ * @requires jQuery v1.2 or later
+ *
+ * Examples at http://famspam.com/facebox/
+ *
+ * Licensed under the MIT:
+ *   http://www.opensource.org/licenses/mit-license.php
+ *
+ * Copyright 2007, 2008 Chris Wanstrath [ chris@ozmm.org ]
+ *
+ * Usage:
+ *
+ *  jQuery(document).ready(function() {
+ *    jQuery('a[rel*=facebox]').facebox()
+ *  })
+ *
+ *  <a href="#terms" rel="facebox">Terms</a>
+ *    Loads the #terms div in the box
+ *
+ *  <a href="terms.html" rel="facebox">Terms</a>
+ *    Loads the terms.html page in the box
+ *
+ *  <a href="terms.png" rel="facebox">Terms</a>
+ *    Loads the terms.png image in the box
+ *
+ *
+ *  You can also use it programmatically:
+ *
+ *    jQuery.facebox('some html')
+ *    jQuery.facebox('some html', 'my-groovy-style')
+ *
+ *  The above will open a facebox with "some html" as the content.
+ *
+ *    jQuery.facebox(function($) {
+ *      $.get('blah.html', function(data) { $.facebox(data) })
+ *    })
+ *
+ *  The above will show a loading screen before the passed function is called,
+ *  allowing for a better ajaxy experience.
+ *
+ *  The facebox function can also display an ajax page, an image, or the contents of a div:
+ *
+ *    jQuery.facebox({ ajax: 'remote.html' })
+ *    jQuery.facebox({ ajax: 'remote.html' }, 'my-groovy-style')
+ *    jQuery.facebox({ image: 'stairs.jpg' })
+ *    jQuery.facebox({ image: 'stairs.jpg' }, 'my-groovy-style')
+ *    jQuery.facebox({ div: '#box' })
+ *    jQuery.facebox({ div: '#box' }, 'my-groovy-style')
+ *
+ *  Want to close the facebox?  Trigger the 'close.facebox' document event:
+ *
+ *    jQuery(document).trigger('close.facebox')
+ *
+ *  Facebox also has a bunch of other hooks:
+ *
+ *    loading.facebox
+ *    beforeReveal.facebox
+ *    reveal.facebox (aliased as 'afterReveal.facebox')
+ *    init.facebox
+ *    afterClose.facebox
+ *
+ *  Simply bind a function to any of these hooks:
+ *
+ *   $(document).bind('reveal.facebox', function() { ...stuff to do after the facebox and contents are revealed... })
+ *
+ */
+(function($) {
+  $.facebox = function(data, klass) {
+    $.facebox.loading()
+
+    if (data.ajax) fillFaceboxFromAjax(data.ajax, klass)
+    else if (data.image) fillFaceboxFromImage(data.image, klass)
+    else if (data.div) fillFaceboxFromHref(data.div, klass)
+    else if ($.isFunction(data)) data.call($)
+    else $.facebox.reveal(data, klass)
+  }
+
+  /*
+   * Public, $.facebox methods
+   */
+
+  $.extend($.facebox, {
+    settings: {
+      opacity      : 0.2,
+      overlay      : true,
+      loadingImage : 'https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/loading.gif',
+      closeImage   : 'https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/cancel.png',
+      imageTypes   : [ 'png', 'jpg', 'jpeg', 'gif' ],
+      faceboxHtml  : '\
+    <div id="facebox" style="display:none;"> \
+      <div class="popup"> \
+        <div class="content"> \
+        </div> \
+        <a href="#" class="close"><img src="https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/cancel.png" title="close" class="close_image" /></a> \
+      </div> \
+    </div>'
+    },
+
+    loading: function() {
+      init()
+      if ($('#facebox .loading').length == 1) return true
+      showOverlay()
+
+      $('#facebox .content').empty()
+      $('#facebox .body').children().hide().end().
+        append('<div class="loading"><img src="'+$.facebox.settings.loadingImage+'"/></div>')
+
+      $('#facebox').css({
+        top:   getPageScroll()[1] + (getPageHeight() / 10),
+        left:  $(window).width() / 2 - 205
+      }).show()
+
+      $(document).bind('keydown.facebox', function(e) {
+        if (e.keyCode == 27) $.facebox.close()
+        return true
+      })
+      $(document).trigger('loading.facebox')
+    },
+
+    reveal: function(data, klass) {
+      $(document).trigger('beforeReveal.facebox')
+      if (klass) $('#facebox .content').addClass(klass)
+      $('#facebox .content').append('<pre><code>'+JSON.stringify(JSON.parse(data),null,4)+'</pre></code>')
+      $('#facebox .loading').remove()
+      $('#facebox .body').children().fadeIn('normal')
+      $('#facebox').css('left', $(window).width() / 2 - ($('#facebox .popup').width() / 2))
+      $(document).trigger('reveal.facebox').trigger('afterReveal.facebox')
+    },
+
+    close: function() {
+      $(document).trigger('close.facebox')
+      return false
+    }
+  })
+
+  /*
+   * Public, $.fn methods
+   */
+
+  $.fn.facebox = function(settings) {
+    if ($(this).length == 0) return
+
+    init(settings)
+
+    function clickHandler() {
+      $.facebox.loading(true)
+
+      // support for rel="facebox.inline_popup" syntax, to add a class
+      // also supports deprecated "facebox[.inline_popup]" syntax
+      var klass = this.rel.match(/facebox\[?\.(\w+)\]?/)
+      if (klass) klass = klass[1]
+
+      fillFaceboxFromHref(this.href, klass)
+      return false
+    }
+
+    return this.bind('click.facebox', clickHandler)
+  }
+
+  /*
+   * Private methods
+   */
+
+  // called one time to setup facebox on this page
+  function init(settings) {
+    if ($.facebox.settings.inited) return true
+    else $.facebox.settings.inited = true
+
+    $(document).trigger('init.facebox')
+    makeCompatible()
+
+    var imageTypes = $.facebox.settings.imageTypes.join('|')
+    $.facebox.settings.imageTypesRegexp = new RegExp('\.(' + imageTypes + ')$', 'i')
+
+    if (settings) $.extend($.facebox.settings, settings)
+    $('body').append($.facebox.settings.faceboxHtml)
+
+    var preload = [ new Image(), new Image() ]
+    preload[0].src = $.facebox.settings.closeImage
+    preload[1].src = $.facebox.settings.loadingImage
+
+    $('#facebox').find('.b:first, .bl').each(function() {
+      preload.push(new Image())
+      preload.slice(-1).src = $(this).css('background-image').replace(/url\((.+)\)/, '$1')
+    })
+
+    $('#facebox .close').click($.facebox.close)
+    $('#facebox .close_image').attr('src', $.facebox.settings.closeImage)
+  }
+
+  // getPageScroll() by quirksmode.com
+  function getPageScroll() {
+    var xScroll, yScroll;
+    if (self.pageYOffset) {
+      yScroll = self.pageYOffset;
+      xScroll = self.pageXOffset;
+    } else if (document.documentElement && document.documentElement.scrollTop) {        // Explorer 6 Strict
+      yScroll = document.documentElement.scrollTop;
+      xScroll = document.documentElement.scrollLeft;
+    } else if (document.body) {// all other Explorers
+      yScroll = document.body.scrollTop;
+      xScroll = document.body.scrollLeft;
+    }
+    return new Array(xScroll,yScroll)
+  }
+
+  // Adapted from getPageSize() by quirksmode.com
+  function getPageHeight() {
+    var windowHeight
+    if (self.innerHeight) {    // all except Explorer
+      windowHeight = self.innerHeight;
+    } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
+      windowHeight = document.documentElement.clientHeight;
+    } else if (document.body) { // other Explorers
+      windowHeight = document.body.clientHeight;
+    }
+    return windowHeight
+  }
+
+  // Backwards compatibility
+  function makeCompatible() {
+    var $s = $.facebox.settings
+
+    $s.loadingImage = $s.loading_image || $s.loadingImage
+    $s.closeImage = $s.close_image || $s.closeImage
+    $s.imageTypes = $s.image_types || $s.imageTypes
+    $s.faceboxHtml = $s.facebox_html || $s.faceboxHtml
+  }
+
+  // Figures out what you want to display and displays it
+  // formats are:
+  //     div: #id
+  //   image: blah.extension
+  //    ajax: anything else
+  function fillFaceboxFromHref(href, klass) {
+    // div
+    if (href.match(/#/)) {
+      var url    = window.location.href.split('#')[0]
+      var target = href.replace(url,'')
+      if (target == '#') return
+      $.facebox.reveal($(target).html(), klass)
+
+    // image
+    } else if (href.match($.facebox.settings.imageTypesRegexp)) {
+      fillFaceboxFromImage(href, klass)
+    // ajax
+    } else {
+      fillFaceboxFromAjax(href, klass)
+    }
+  }
+
+  function fillFaceboxFromImage(href, klass) {
+    var image = new Image()
+    image.onload = function() {
+      $.facebox.reveal('<div class="image"><img src="' + image.src + '" /></div>', klass)
+    }
+    image.src = href
+  }
+
+  function fillFaceboxFromAjax(href, klass) {
+    $.get(href, function(data) { $.facebox.reveal(data, klass) })
+  }
+
+  function skipOverlay() {
+    return $.facebox.settings.overlay == false || $.facebox.settings.opacity === null
+  }
+
+  function showOverlay() {
+    if (skipOverlay()) return
+
+    if ($('#facebox_overlay').length == 0)
+      $("body").append('<div id="facebox_overlay" class="facebox_hide"></div>')
+
+    $('#facebox_overlay').hide().addClass("facebox_overlayBG")
+      .css('opacity', $.facebox.settings.opacity)
+      .click(function() { $(document).trigger('close.facebox') })
+      .fadeIn(200)
+    return false
+  }
+
+  function hideOverlay() {
+    if (skipOverlay()) return
+
+    $('#facebox_overlay').fadeOut(200, function(){
+      $("#facebox_overlay").removeClass("facebox_overlayBG")
+      $("#facebox_overlay").addClass("facebox_hide")
+      $("#facebox_overlay").remove()
+    })
+
+    return false
+  }
+
+  /*
+   * Bindings
+   */
+
+  $(document).bind('close.facebox', function() {
+    $(document).unbind('keydown.facebox')
+    $('#facebox').fadeOut(function() {
+      $('#facebox .content').removeClass().addClass('content')
+      $('#facebox .loading').remove()
+      $(document).trigger('afterClose.facebox')
+    })
+    hideOverlay()
+  })
+
+})(jQuery);
index 35b1d81..38f80b7 100644 (file)
@@ -110,7 +110,7 @@ function startJalview(aligURL,title,alwvar) {
 </SCRIPT>
   <form name="Form1">
 <applet name="JalviewLite"  code="jalview.bin.JalviewLite"
-archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar" width="0" height="0">
+archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar" width="0" height="0">
 <param name="debug" value="true"/>
 <param name="showbutton" value="false"/>
 </applet>
index 5890515..8ddfd2f 100644 (file)
@@ -38,7 +38,7 @@
 
 
 <applet
-   code="jalview.bin.JalviewLite" width="800" height="300" id="jvapp" mayscript="True" scriptable="True" archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   code="jalview.bin.JalviewLite" width="800" height="300" id="jvapp" mayscript="True" scriptable="True" archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="oninit" value="lJvApp"/>
 <param name="automaticScrolling" value="true"/>
 <param name="file" value="plantfdx.fa"/>
@@ -61,7 +61,7 @@
 
 
 <applet
-   code="jalview.bin.JalviewLite" width="800" height="300" id="jvfollower" mayscript="True" scriptable="True" archive="jalviewApplet.jar,JmolApplet-14.2.14_2015.06.11.jar,java-json.jar,json_simple-1.1.jar">
+   code="jalview.bin.JalviewLite" width="800" height="300" id="jvfollower" mayscript="True" scriptable="True" archive="jalviewApplet.jar,JmolApplet-14.6.4_2016.10.26.jar,java-json.jar,json_simple-1.1.jar">
 <param name="oninit" value="lJvFollow"/>
 <param name="file" value="plantfdx.fa"/>
 <param name="annotations" value="plantfdx.annotations"/>
index 407899e..e034fc2 100755 (executable)
@@ -22,7 +22,7 @@
    <mapID target="home" url="html/index.html" />
    
    <mapID target="new" url="html/whatsNew.html"/>
-   <mapID target="release" url="html/releases.html#Jalview.2.10.0b1"/>
+   <mapID target="release" url="html/releases.html#Jalview.2.10.1"/>
    <mapID target="alannotation" url="html/features/annotation.html"/>
    <mapID target="keys" url="html/keys.html"/>
    <mapID target="newkeys" url="html/features/newkeystrokes.html"/>
index bf1710c..3a6b0b3 100755 (executable)
@@ -23,9 +23,6 @@
 <!-- DO NOT WRAP THESE LINES - help2Website relies on each item being on one line! -->
        <tocitem text="Jalview Documentation" target="home" expand="true">
                        <tocitem text="What's new" target="new" expand="true">
-                               <tocitem text="Retrieval from ENSEMBL" target="ensemblfetch" />
-                               <tocitem text="UniProt Free Text Search" target="uniprotfetcher" />
-                               <tocitem text="SIFTS for mapping PDB structures to UniProt" target="siftsmapping" />
                                <tocitem text="Latest Release Notes" target="release"/>
                </tocitem>
                
index 614764b..8adacc9 100755 (executable)
@@ -35,10 +35,10 @@ td {
     <strong>Colouring above a percentage identity threshold</strong>
   </p>
   <p>Selecting this option causes the colour scheme to be applied to
-    only those residues that occur in that column more than a certain
-    percentage of the time. For instance selecting the threshold to be
-    100 will only colour those columns with 100 % identity. This
-    threshold option can be applied to the Zappo, Taylor, Hydrophobicity
-    and User colour schemes.</p>
+    only those residues that occur in that column at least a certain
+    percentage of the time. For instance, selecting the threshold to be
+    100 will only colour those columns with 100% identity, and selecting 50 will shade residues appearing in least 50% of the rows (or sequences) in each column.</p>
+   <p>The percentage calculation may include or exclude gaps in the column, depending on the option selected for the <a href="../calculations/consensus.html">consensus calculation</a>.</p>
+   <p>With a threshold of 0, colouring is unchanged.</p>
 </body>
 </html>
index 1b0b9c1..5ae00af 100644 (file)
     number and chain code ([RES]Num:Chain). Moving the mouse over an
     associated residue in an alignment window highlights the associated
     atoms in the displayed structures. When residues are selected in the
-    Chimera window, they are highlighted on the alignment. For
-    comprehensive details of Chimera's commands, refer to the tool's
-    Help menu.
+    Chimera window, they are highlighted on the alignment.
+  <p>For comprehensive details of Chimera's commands, refer to the
+    tool's Help menu.</p>
+  <p>
+    <strong>Selecting residues in Jalview from Chimera</strong><br />
+    When a selection is highlighted in a Jalview window, use the
+    <em>Select&#8594;Select Highlighted Region</em> or press <em>B</em>
+    to add the mapped positions to the alignment window's column
+    selection.<br /> <em>Hint: Use your machine's 'switch
+      application' key combination (Alt-Tab on Windows and Linux,
+      Cmd-Tab on OSX) to quickly switch between UCSF Chimera and Jalview
+      before pressing 'B' to select highlighted regions.</em>
+  </p>
   <p>
     Basic screen operations (see <a
       href="http://www.cgl.ucsf.edu/chimera/current/docs/UsersGuide/mouse.html">Chimera
index 4b4aab9..e065494 100644 (file)
       <td><div align="left">Create Scalable Vector Graphics
           file FILE from alignment.</div></td>
     </tr>
+    <tr>
+      <td><div align="center">-biojsMSA FILE</div></td>
+      <td><div align="left">Write an HTML page to display
+          the alignment with the <a href="biojsmsa.html">
+          BioJS MSAviewer MSA</a>
+          </div>
+      </td>
+    </tr>
   </table>
 </body>
 </html>
index ec1e093..fd6b99f 100755 (executable)
     a colour the feature).</p>
 
   <p>
-    If your sequence annotation is already available in GFF Format (see
-    <a href="http://gmod.org/wiki/GFF2">gmod.org/wiki/GFF2</a>), then
-    you can leave it as is, after first adding a line containing only
+    If your sequence annotation is already available in <a href="http://gmod.org/wiki/GFF2">GFF2</a> (http://gmod.org/wiki/GFF2) or
+    <a href="https://github.com/The-Sequence-Ontology/Specifications/blob/master/gff3.md">GFF3</a> 
+    (http://github.com/The-Sequence-Ontology/Specifications/blob/master/gff3.md) format, 
+    then you can leave it as is, after first adding a line containing only
     'GFF' after any Jalview feature colour definitions (<em>this
-      mixed format capability was added in Jalview 2.6</em>). Alternately,
+    mixed format capability was added in Jalview 2.6</em>). Alternately,
     you can use Jalview's own sequence feature annotation format, which
     additionally allows HTML and URLs to be directly attached to each
     piece of annotation.
index 2f10196..0cd6168 100644 (file)
       based structure superposition was added in Jalview 2.6</em>
   </p>
   <p>
-    <strong>Controls</strong><br> The structure is by default
-    rendered as a ribbon diagram. Moving the mouse over the structure
-    brings up tooltips giving the residue name, PDB residue number and
-    chain code, atom name and number
-    ([RES]Num:Chain.AtomName#AtomNumber). If a mapping exists to a
-    residue in any associated sequences, then this will be highlighted
-    in each one's alignment window. The converse also occurs - moving
-    the mouse over an associated residue in an alignment window
-    highlights the associated atoms in the displayed structures.
+    <strong>Controls</strong><br> The structure is by default rendered
+    as a ribbon diagram. Moving the mouse over the structure brings up
+    tooltips giving the residue name, PDB residue number and chain code,
+    atom name and number ([RES]Num:Chain.AtomName#AtomNumber). If a
+    mapping exists to a residue in any associated sequences, then this
+    will be highlighted in each one's alignment window. The converse
+    also occurs - moving the mouse over an associated residue in an
+    alignment window highlights the associated atoms in the displayed
+    structures. Press B or use
+    <em>Select&#8594;Select Highlighted columns</em> from any linked
+    alignment window to mark the columns highlighted after mousing over
+    the structure.
   </p>
   <p>Selecting a residue highlights its associated sequence residue
     and alpha carbon location. Double clicking an atom allows distances
index 9766782..69f3315 100755 (executable)
@@ -65,6 +65,19 @@ td {
     Settings&quot; under the &quot;View&quot; menu to change the
     visibility and colour of the new sequence feature.</p>
   <p>
+  <p>
+    <strong>Selecting regions from Search Results</strong>
+  </p>
+  <p>
+    Press 'B' or use the <em>Select Highlighted Columns</em> option from
+    the alignment window's select menu to add columns containing
+    highlighted search results to the alignment window's column
+    selection. Alt-'B' will add all but the highlighted columns, and
+    Ctrl (or Cmd) -B will toggle the column selection for the
+    highlighted region.
+  </p>
+  <p>
+  
     <strong>A quick Regular Expression Guide</strong>
   </p>
   <p>A regular expression is not just a simple text query - although
@@ -73,7 +86,7 @@ td {
     the match. For example, a simple query like &quot;ACDED&quot; would
     match all occurences of that string, but &quot;ACD+ED&quot; matches
     both 'ACDDED' and 'ACDDDDDDDDED'. More usefully, the query
-    &quot;[ILGVMA]{;5,}&quot; would find stretches of small, hydrophobic
+    &quot;[GVATC]{;5,}&quot; would find stretches of small, hydrophobic
     amino acids of at least five residues in length.</p>
   <p>
     The table below describes some of the regular expression syntax:<br>
index ba97557..3f6a058 100644 (file)
     Much of the information retrieved by Jalview about a sequence is
     visualized on the alignment. Often, however, there are a huge number
     of ontology terms, cross-references, links to publications and other
-    kinds of data shown in the sequence ID tooltip that cannot be
-    examined. In this case, you can view and export the information
-    shown in a sequence's ID tooltip by right-clicking and selecting the
+    kinds of data associated with a sequence, and only some of these are shown in 
+    sequence ID tooltip. To show the full set of annotation and database links for
+    a sequence, right-click and select the
     <strong>&quot;<em>(sequence's name)</em></em>&rarr;Sequence
       Details ...&quot;
     </strong> entry from the <a href="../menus/popupMenu.html">pop-up menu</a>.
   </p>
   <p>
     <strong>Annotation Reports for a range of sequences</strong><br />
-    If you would like to view the tooltips for a number of sequences,
+    If you would like to view database and metadata for a number of sequences,
     simply select them all and then use the <strong>Selection&rarr;Sequence
       Details ...</strong> entry in the <a href="../menus/popupMenu.html">pop-up
       menu</a>.
index 2ba9a49..1a5fc18 100755 (executable)
@@ -167,6 +167,19 @@ columns are selected, you should use the <a href="features/hiddenRegions.html">H
       <td>Both</td>
       <td>Launches the search window</td>
     </tr>
+    <tr><td><strong>B</strong></td>
+      <td>Both</td>
+      <td>Add highlighted columns to current column selection</td>
+    </tr>
+    <tr><td><strong>Alt 'B'</strong></td>
+      <td>Both</td>
+      <td>Add all but the currently highlighted columns to current selection</td>
+    </tr>
+    <tr><td><strong>Control 'B'</strong></td>
+      <td>Both</td>
+      <td>Toggle the column selection marks for the currently highlighted 
+          columns (or all others if Alt is also pressed)</td>
+    </tr>
     <tr>
       <td><strong>H</strong></td>
       <td>Both</td>
index c8b2270..167cb25 100755 (executable)
               Columns by Annotation</a></strong> <br /> <em>Select or Hide
             columns in the alignment according to secondary structure,
             labels and values shown in alignment annotation rows. </em></li>
+        <li><strong>Select Highlighted Columns</strong> <br /> <em>Selects
+        the columns currently highlighted as a result of a find, mouse
+        over, or selection event from a linked structure viewer or other
+        application. Modifiers will work on some platforms: ALT will add
+        all but the highlighted set to the column selection, and CTRL
+        (or META) will toggle the selection. </em></li>
       </ul></li>
     <li><strong>View</strong>
       <ul>
index b93f85b..07828a3 100644 (file)
           Columns by Annotation</a></strong> <br /> <em>Select or Hide columns
         in the alignment according to secondary structure, labels and
         values shown in alignment annotation rows. </em></li>
+    <li><strong>Select Highlighted Columns</strong> <br /> <em>Selects
+        the columns currently highlighted as a result of a find, mouse
+        over, or selection event from a linked structure viewer or other
+        application. Modifiers will work on some platforms: ALT will add
+        all but the highlighted set to the column selection, and CTRL
+        (or META) will toggle the selection. </em></li>
   </ul>
 </body>
 </html>
index 51274d7..b53f6ef 100755 (executable)
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  -->
 <head>
-<title>Amino Acid Properties</title>
+<style>
+body {
+    font-size: 100%;
+}
+table {
+    border: solid;
+    border-collapse: separate;
+}
+th, td {
+    border-style:none;
+    font-family: "Courier New", Courier, mono;
+    font-size: large;
+}
+</style><title>Amino Acid Properties</title>
 </head>
 <body>
   <div align="center">
     <h1>Amino Acid Properties</h1>
     <img src="properties.gif"> <br>
-    <table width="295" border="1" cellspacing="0" cellpadding="0">
-      <tr>
-        <td width="291"><pre>
-            <font size="4" face="Courier New, Courier, mono"><strong>ILVCAGMFYWHKREQDNSTPBZX-</strong>
-XXXXXXXXXXX&middot;&middot;&middot;&middot;&middot;&middot;&middot;X&middot;&middot;&middot;XX Hydrophobic
-&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;XXXXXXXXXX&middot;XXXXX Polar
-&middot;&middot;XXXX&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;XXXXX&middot;&middot;XX Small
-&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;X&middot;&middot;XX Proline
-&middot;&middot;&middot;&middot;XX&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;X&middot;&middot;&middot;&middot;XX Tiny
-XXX&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;XX Aliphatic
-&middot;&middot;&middot;&middot;&middot;&middot;&middot;XXXX&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;XX Aromatic
-&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;XXX&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;XX Positive
-&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;X&middot;X&middot;&middot;&middot;&middot;&middot;&middot;XX Negative
-&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;&middot;XXXX&middot;X&middot;&middot;&middot;&middot;&middot;&middot;XX Charged</font>
-          </pre></td>
-      </tr>
+    <table>
+    <tr><th>ILVCA</th><th>GMFYW</th><th>HKREQ</th><th>DNSTP</th><th>BZX-</th><th></th></tr>
+      <tr><td>XXXXX</td><td>XXXXX</td><td>XX&middot;&middot;&middot;</td><td>&middot;&middot;&middot;X&middot;</td><td>&middot;&middot;XX</td><td>Hydrophobic</td></tr>
+<tr><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;XX</td><td>XXXXX</td><td>XXXX&middot;</td><td>XXXX</td><td>Polar</td></tr>
+<tr><td>&middot;&middot;XXX</td><td>X&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>XXXXX</td><td>&middot;&middot;XX</td><td>Small</td></tr>
+<tr><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;X</td><td>&middot;&middot;XX</td><td>Proline</td></tr>
+<tr><td>&middot;&middot;&middot;&middot;X</td><td>X&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;X&middot;&middot;</td><td>&middot;&middot;XX</td><td>Tiny</td></tr>
+<tr><td>XXX&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;XX</td><td>Aliphatic</td></tr>
+<tr><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;XXX</td><td>X&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;XX</td><td>Aromatic</td></tr>
+<tr><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>XXX&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;XX</td><td>Positive</td></tr>
+<tr><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;X&middot;</td><td>X&middot;&middot;&middot;&middot;</td><td>&middot;&middot;XX</td><td>Negative</td></tr>
+<tr><td>&middot;&middot;&middot;&middot;&middot;</td><td>&middot;&middot;&middot;&middot;&middot;</td><td>XXXX&middot;</td><td>X&middot;&middot;&middot;&middot;</td><td>&middot;&middot;XX</td><td>Charged</td></tr>
     </table>
+    </font>
   </div>
   <p>
     <br> From Livingstone, C. D. and Barton, G. J. (1993), <br>
index 3fe08cb..6f44b3d 100755 (executable)
     <tr>
       <td width="60" nowrap>
         <div align="center">
+          <strong><a name="Jalview.2.10.1">2.10.1</a><br />
+            <em>29/11/2016</em></strong>
+        </div>
+      </td>
+      <td><div align="left">
+          <em>General</em>
+          <ul>
+            <li>
+              <!-- JAL-98 -->Improved memory usage: sparse arrays used
+              for all consensus calculations
+            </li>
+            <li>
+              <!-- JAL-2177 -->Jmol updated to version 14.6.4 (released 3rd Oct 2016)
+            </li>
+            <li>Updated Jalview's Certum code signing certificate
+              for 2016-2017</li>
+          </ul>
+          <em>Application</em>
+          <ul>
+            <li>
+              <!-- JAL-1723 -->Sequence ID tool tip presents abridged
+              set of database cross-references, sorted alphabetically
+            </li>
+            <li>
+              <!-- JAL-2282-->New replacement token for creating URLs <em>just</em>
+              from database cross references. Users with custom links
+              will receive a <a href="webServices/urllinks.html#warning">warning
+                dialog</a> asking them to update their preferences.
+            </li>
+            <li>
+              <!-- JAL-2287-->Cancel button and escape listener on
+              dialog warning user about disconnecting Jalview from a
+              Chimera session
+            </li>
+            <li>
+              <!-- JAL-2320-->Jalview's Chimera control window closes if
+              the Chimera it is connected to is shut down
+            </li>
+            <li>
+              <!-- JAL-1738-->New keystroke (B) and Select highlighted
+              columns menu item to mark columns containing
+              highlighted regions (e.g. from structure selections or results
+              of a Find operation)
+            </li>
+            <li>
+              <!-- JAL-2284-->Command line option for batch-generation
+              of HTML pages rendering alignment data with the BioJS
+              MSAviewer
+            </li>
+          </ul>
+        </div></td>
+      <td>
+        <div align="left">
+          <em>General</em>
+          <ul>
+            <li>
+              <!-- JAL-2286 -->Columns with more than one modal residue
+              are not coloured or thresholded according to percent
+              identity (first observed in Jalview 2.8.2)
+            </li>
+            <li>
+              <!-- JAL-2301 -->Threonine incorrectly reported as not
+              hydrophobic
+            </li>
+            <li>
+              <!-- JAL-2318 -->Updates to documentation pages (above PID
+              threshold, amino acid properties)
+            </li>
+            <li>
+              <!-- JAL-2292 -->Lower case residues in sequences are not
+              reported as mapped to residues in a structure file in the
+              View Mapping report
+            </li>
+            <li>
+              <!--JAL-2324 -->Identical features with non-numeric scores
+              could be added multiple times to a sequence
+            </li>
+            <li>
+              <!--JAL-2323, JAL-2333,JAL-2335,JAL-2327 -->Disulphide
+              bond features shown as two highlighted residues rather
+              than a range in linked structure views, and treated
+              correctly when selecting and computing trees from features
+            </li>
+            <li>
+              <!-- JAL-2281-->Custom URL links for database
+              cross-references are matched to database name regardless
+              of case
+            </li>
+
+          </ul>
+          <em>Application</em>
+          <ul>
+            <li>
+              <!-- JAL-2282-->Custom URL links for specific database
+              names without regular expressions also offer links from
+              Sequence ID
+            </li>
+            <li>
+              <!-- JAL-2315-->Removing a single configured link in the
+              URL links pane in Connections preferences doesn't actually
+              update Jalview configuration
+            </li>
+            <li>
+              <!-- JAL-2272-->CTRL-Click on a selected region to open
+              the alignment area popup menu doesn't work on El-Capitan
+            </li>
+            <li>
+              <!-- JAL-2280 -->Jalview doesn't offer to associate mmCIF
+              files with similarly named sequences if dropped onto the
+              alignment
+            </li>
+            <li>
+              <!-- JAL-2312 -->Additional mappings are shown for PDB
+              entries where more chains exist in the PDB accession than
+              are reported in the SIFTS file
+            </li>
+            <li>
+              <!-- JAL-2317-->Certain structures do not get mapped to
+              the structure view when displayed with Chimera
+            </li>
+            <li>
+              <!-- JAL-2317-->No chains shown in the Chimera view
+              panel's View->Show Chains submenu
+            </li>
+            <li>
+              <!--JAL-2277 -->Export as HTML with embedded SVG doesn't
+              work for wrapped alignment views
+            </li>
+            <li>
+              <!--JAL-2197 -->Rename UI components for running JPred
+              predictions from 'JNet' to 'JPred'
+            </li>
+            <li>
+              <!-- JAL-2337,JAL-2277 -->Export as PNG or SVG is
+              corrupted when annotation panel vertical scroll is not at
+              first annotation row
+            </li>
+            <li>
+              <!--JAL-2332 -->Attempting to view structure for Hen
+              lysozyme results in a PDB Client error dialog box
+            </li>
+          </ul>
+<!--           <em>New Known Issues</em>
+          <ul>
+            <li></li>
+          </ul> -->
+        </div>
+      </td>
+    </tr>
+      <td width="60" nowrap>
+        <div align="center">
           <strong><a name="Jalview.2.10.0b1">2.10.0b1</a><br />
             <em>25/10/2016</em></strong>
         </div>
               <!-- JAL-1306 -->Quality and Conservation are now shown on
               load even when Consensus calculation is disabled
             </li>
+            <li>
+              <!-- JAL-1932 -->Remove right on penultimate column of 
+              alignment does nothing
+            </li>
           </ul>
           <em>Application</em>
           <ul>
               <!-- JAL-1887 -->Incorrect start and end reported for PDB
               to sequence mapping in 'View Mappings' report
             </li>
+            <li>
+              <!-- JAL-2284 -->Unable to read old Jalview projects that
+              contain non-XML data added after Jalvew wrote project.
+            </li>
+            <li><!-- JAL-2118 -->Newly created annotation row reorders
+              after clicking on it to create new annotation for a
+              column.
+            </li>
             <!--  may exclude, this is an external service stability issue  JAL-1941 
             -- > RNA 3D structure not added via DSSR service</li> -->
           </ul>
         </ul> <em>Applet</em>
         <ul>
           <li>Split frame example added to applet examples page</li>
+        </ul><em>Build and Deployment</em>
+        <ul>
+          <li><!--  JAL-1888 -->New ant target for running Jalview's test suite</li>
         </ul></td>
       <td>
         <div align="left">
index 52220d2..83c80ba 100644 (file)
 <p>
 <p>
   <strong>Discovering Database References for Sequences</strong><br>
-  Database references are associated with a sequence are displayed as a
-  list in the tooltip shown when mousing over its sequence ID. Jalview
-  uses references for the retrieval of <a
-    href="../features/viewingpdbs.html">PDB structures</a> and <a
+  Database references associated with a sequence are displayed as an
+  abbreviated list in the tooltip shown when mousing over its sequence
+  ID, and can be viewed in full via the
+  <a href="../io/exportseqreport.html">Sequence Details</a> window. .
+  Jalview also uses references for the retrieval of
+  <a href="../features/viewingpdbs.html">PDB structures</a> and <a
     href="../features/dasfeatures.html">DAS features</a>, and for
   retrieving sequence cross-references such as the protein products of a
   DNA sequence.
index 0a4c650..088a539 100644 (file)
@@ -28,7 +28,7 @@
     and the desktop application are able to open URLs as 'popups' in
     your web browser. <br> Double-clicking on the ID of a sequence
     will open the first URL that can be generated from its sequence ID.
-    This is often the SRS site, but you can easily configure your own <a
+    This is by default the EMBL-EBI site, but you can easily configure your own <a
       href="#urllinks">sequence URL links</a>.
   </p>
   <p>
   <p>
     <strong><a name="urllinks">Configuring URL Links</a></strong> <br>URL
     links are defined in the &quot;Connections&quot; tab of the <a
-      href="../features/preferences.html">Jalview desktop
-      preferences</a>, or specified as <a
-      href="http://www.jalview.org/examples/appletParameters.html#parameters">applet
-      parameters</a>. <br> By default the item &quot;SRS&quot; is added
+    href="../features/preferences.html">Jalview desktop
+    preferences</a>, or specified as <a
+    href="http://www.jalview.org/examples/appletParameters.html#parameters">applet
+    parameters</a>. <br> By default the item &quot;EMBL-EBI Search&quot; is added
     to this link menu. This link will show a web page in your default
     browser with the selected sequence id as part of the URL.<br>
     In the preferences dialog box, click <strong>new</strong> to add a
@@ -51,9 +51,9 @@
     to remove it.<br> You can name the link, this will be displayed
     on a new menu item under the &quot;Link&quot; menu when you right
     click on a sequence id. <br> The URL string must contain a
-    token that can be replaced with a sequence ID. The simplest token is
+    token that can be replaced with a sequence ID or DB accession ID. The simplest token is
     &quot;$SEQUENCE_ID$&quot;, which will be replaced by the chosen
-    sequence id when you click on it.
+    sequence id when you click on it. 
   </p>
   <p>
     eg.<br> UniRef100 =
     Swissprot = http://www.expasy.org/uniprot/$SEQUENCE_ID$ <br> <br>
     Links will also be made for any database cross references associated
     with the sequence where the database name exactly matches a URL link
-    name. In this case, the $SEQUENCE_ID$ string will be replaced with
+    name. In this case, the $DB_ACCESSION$ string will be replaced with
     the accession string for the database cross-reference, rather than
-    the sequence ID for the sequence (<em>since Jalview 2.4</em>).
+    the sequence ID for the sequence (<em>since Jalview 2.10.1</em>).
+  </p>
+  <p>
+    <strong><a name="warning">Warning dialog about updating
+        your configured URL links</a></strong><br /> In the desktop
+    prior to Jalview 2.10.1, the only way to configure custom links for
+    a particular database cross-reference for a sequence was to give it
+    a name that
+    <em>exactly</em> matched the database source, and a regular
+    expression for filtering out any spurious matches generated when the
+    custom linked was tested against the Sequence's ID string. Since the
+    introduction of the $DB_ACCESSION$ token, however, $SEQUENCE_ID$
+    will not be used for database cross-reference accession strings, and
+    if you have custom links configured, Jalview will raise a warning
+    message so let you know that you may need to update your links to
+    use $DB_ACCESSION$.
   </p>
   <p>
     <strong>Regular Expression Substitution</strong><br> A url may
     contain a string of the form $SEQUENCE_ID=/<em>regular
-      expression</em>/=$. In this case, the regular expression will be
-    applied to the full sequence ID string and the resulting match will
+    expression</em>/=$ or $DB_ACCESSION=/<em>regular expression</em>/=$. 
+    In this case, the regular expression will be
+    applied to the full sequence ID or DB accession ID string and the resulting match will
     be inserted into the URL. Groups of parentheses can be used to
     specify which regions of the regular expression will be used to
     generate the URL:
index 448430d..1c20885 100755 (executable)
 </head>
 <body>
   <p>
-    <strong>What's new in Jalview 2.10.0b1 ?</strong>
+    <strong>What's new in Jalview 2.10.1 ?</strong>
   </p>
   <p>
-    Jalview 2.10.0b1 is a patch release for 2.10, the next major release
-    in the Jalview 2 series. Full details are in the <a
-      href="releases.html#Jalview.2.10.0b1">Jalview 2.10b1 Release
-      Notes</a>, but the highlights are below.
+    Jalview 2.10.1 was released on 24th November 2016. Full details are
+    in the <a href="releases.html#Jalview.2.10.1">Jalview 2.10.1
+      Release Notes</a>, but the highlights are below. This is also the
+    first release to include contributions from Kira Mour&atilde;o, who
+    joined Jalview's core development team in October 2016.
   </p>
   <ul>
-    <li>Drag and drop reinstated for the Jalview desktop on
-      Windows, Linux and older OSX systems.</li>
-    <li>Problems loading local PDB files have been fixed</li>
-    <li>Conservation shading can be disabled for PID and consensus
-      based colour scheme</li>
-  </ul>
-  <p><em>Major highlights of the 2.10.0 Release</em></p>
-  <ul>
-    <li><strong>Ensembl sequence fetcher</strong><br />Annotated
-      Genes, transcripts and proteins can be retrieved via Jalview's new
-      <a href="features/ensemblsequencefetcher.html">Ensembl REST
-        client</a>. Support for import of Ensembl data allows:
-      <ul>
-        <li><strong>Aligned locus view</strong><br />Transcripts
-          retrieved for a gene identifier via the Ensembl or
-          EnsemblGenomes sequence databases are automatically aligned to
-          their reference genome, and introns hidden from the view.</li>
-        <li><strong>Sequence variant data</strong><br />Jalview
-          propagates variant annotation on genomic regions onto
-          transcripts and protein products, complete with associated
-          metadata such as clinical significance.</li>
-      </ul></li>
-    <li><strong>Ensembl and ENA 'show cross-references'
-        support</strong><br />The Calculations menu's <strong>'Show
-        cross-references'</strong> now offers Ensembl as well as EMBLCDS and
-      Uniprot when CDS/Protein mapping data is available for download or
-      display. This allows variant annotation to be added directly to an
-      alignment of UniProt sequences.</li>
-    <li><strong>Working with structures</strong>
-      <ul>
-        <li><strong>More accurate structure mappings</strong><br />
-          Jalview now utilises the PDBe's SIFTS database (at EMBL-EBI)
-          to <a href="features/siftsmapping.html">match structures
-            to UniProt sequences</a>, even for structures containing
-          multiple copies of a sequence.</li>
-        <li><strong>Import structures as mmCIF</strong><br />Jalview
-          now downloads data from the EMBL-EBI's PDBe site as <a
-          href="features/mmcif.html">mmCIF</a>. This allows very large
-          structures to be imported, such as the HIV virus capsid
-          assembly.</li>
-        <li><strong>Chimera users will need to upgrade to
-            1.11.1</strong><br />If you use Chimera to view structures
-          downloaded by Jalview 2.10, you will need to make sure you are
-          running the latest version of <a href="features/chimera.html">Chimera</a>.</li>
-      </ul></li>
-    <li><strong>UniProt Free Text Search</strong><br />The new
-      search dialog for UniProt allows you to browse and retrieve
-      sequences with free-text search, or structured queries.</li>
-    <li><strong>Reference sequence alignment view</strong><br />
-      Jalview 2.9 introduced support for reference sequences. In 2.10,
-      when a reference sequence is defined for the alignment, the
-      alignment column ruler is now numbered according to the reference
-      sequence. The reference sequence for alignment views can also be
-      saved and restored from Jalview projects.</li>
+    <li><strong>More memory efficient</strong><br />We've slimmed
+      down the consensus analysis data structures used by Jalview so
+      even wider alignments can be worked with.</li>
+    <li><strong>Select highlighted region</strong><br />Press 'B'
+      or use the new menu option in the alignment window's Select menu
+      to mark columns containing highlighted regions generated from
+      structure selections, mouse-overs, or resulting from a Find
+      operation.</li>
+    <li><strong>New custom link mechanism for opening URLs
+        for database cross references.</strong><br /> If you have customised URL
+      links in your Jalview preferences, then you may already have seen
+      the <a href="#warning"> warning dialog (see below).</a></li>
+    <li><strong>New command line export option for BioJS
+        MSAviewer</strong><br />A number of small bugs with the HTML export
+      functions from the Jalview desktop were also fixed.</li>
+    <li><strong>Small but significant changes to the
+        physicochemical properties and consensus calculations</strong><br />Threonine
+      is no longer considered a non-hydrophobic residue in the protein
+      conservation calculation, and minor bugs addressed in PID and
+      consensus colouring.</li>
+    <li><strong>Correct display of disulphide bond
+        features</strong><br /> In linked structure views, Jalview would
+      highlight all residues between in addition to the two linked
+      cysteines. The 'select columns by feature' function in the feature
+      settings would also select all intermediate columns.
   </ul>
 
+  <p>
+    <strong><a name="warning">Warning dialog about updating
+        your configured URL links</a></strong><br /> In the desktop prior to Jalview
+    2.10.1, the only way to configure custom links for a particular
+    database cross-reference for a sequence was to give it a name that <em>exactly</em>
+    matched the database source, and a regular expression for filtering
+    out any spurious matches generated when the custom linked was tested
+    against the Sequence's ID string. Since the introduction of the
+    $DB_ACCESSION$ token, however, $SEQUENCE_ID$ will not be used for
+    database cross-reference accession strings, and if you have custom
+    links configured, Jalview will raise a warning message so let you
+    know that you may need to update your links to use $DB_ACCESSION$.
+  </p>
 </body>
 </html>
diff --git a/lib/Jmol-14.2.14_2015.06.11.jar b/lib/Jmol-14.2.14_2015.06.11.jar
deleted file mode 100644 (file)
index 1470745..0000000
Binary files a/lib/Jmol-14.2.14_2015.06.11.jar and /dev/null differ
diff --git a/lib/Jmol-14.6.4_2016.10.26.jar b/lib/Jmol-14.6.4_2016.10.26.jar
new file mode 100644 (file)
index 0000000..1016c3f
Binary files /dev/null and b/lib/Jmol-14.6.4_2016.10.26.jar differ
index ac1a2e3..b569f55 100644 (file)
@@ -59,8 +59,8 @@ file.reference.jalview-src=src
 file.reference.jaxrpc.jar=lib/jaxrpc.jar
 file.reference.JGoogleAnalytics_0.3.jar=lib/JGoogleAnalytics_0.3.jar
 file.reference.jhall.jar=lib/jhall.jar
-file.reference.Jmol-14.2.14_2015.06.11.jar=lib/Jmol-14.2.14_2015.06.11.jar
-file.reference.JmolApplet-14.2.14_2015.06.11.jar=appletlib/JmolApplet-14.2.14_2015.06.11.jar
+file.reference.Jmol-14.6.4_2016.10.26.jar=lib/Jmol-14.6.4_2016.10.26.jar
+file.reference.JmolApplet-14.6.4_2016.10.26.jar=appletlib/JmolApplet-14.6.4_2016.10.26.jar
 file.reference.log4j-1.2.8.jar=lib/log4j-1.2.8.jar
 file.reference.mail.jar=lib/mail.jar
 file.reference.min-jaba-client.jar=lib/min-jaba-client-2.0.jar
@@ -92,7 +92,7 @@ javac.classpath=\
     ${file.reference.jaxrpc.jar}:\
     ${file.reference.JGoogleAnalytics_0.3.jar}:\
     ${file.reference.jhall.jar}:\
-    ${file.reference.Jmol-14.2.14_2015.06.11.jar}:\
+    ${file.reference.Jmol-14.6.4_2016.10.26.jar}:\
     ${file.reference.miglayout-4.0-swing.jar}:\
     ${file.reference.log4j-1.2.8.jar}:\
     ${file.reference.mail.jar}:\
@@ -101,7 +101,7 @@ javac.classpath=\
     ${file.reference.xml-apis.jar}:\
     ${file.reference.xercesImpl.jar}:\
     ${file.reference.wsdl4j.jar}:\
-    ${file.reference.JmolApplet-14.2.14_2015.06.11.jar} \
+    ${file.reference.JmolApplet-14.6.4_2016.10.26.jar} \
     ${file.reference.varna-3.9-dev.jar}
 # Space-separated list of extra javac options
 javac.compilerargs=
index bcb07cf..3488ac6 100644 (file)
@@ -1,4 +1,4 @@
 YEAR=2016
-AUTHORS=J Procter, M Carstairs, TC Ofoegbu, AM Waterhouse, J Engelhardt, LM Lui, A Menard, D Barton, N Sherstnev, D Roldan-Martinez, M Clamp, S Searle, G Barton
-AUTHORFNAMES=Jim Procter, Mungo Carstairs, Tochukwu 'Charles' Ofoegbu, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Anne Menard, Daniel Barton, Natasha Sherstnev, David Roldan-Martinez, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton
+AUTHORS=J Procter, M Carstairs, TC Ofoegbu, K Mourao, AM Waterhouse, J Engelhardt, LM Lui, A Menard, D Barton, N Sherstnev, D Roldan-Martinez, M Clamp, S Searle, G Barton
+AUTHORFNAMES=Jim Procter, Mungo Carstairs, Tochukwu 'Charles' Ofoegbu, Kira Mourao, Andrew Waterhouse, Jan Engelhardt, Lauren Lui, Anne Menard, Daniel Barton, Natasha Sherstnev, David Roldan-Martinez, Michele Clamp, James Cuff, Steve Searle, David Martin & Geoff Barton
  
\ No newline at end of file
index 7a1f064..6360dc7 100644 (file)
@@ -125,6 +125,8 @@ action.change_font_tree_panel = Change Font (Tree Panel)
 action.colour = Colour
 action.calculate = Calculate
 action.select_all = Select all
+action.select_highlighted_columns = Select Highlighted Columns
+tooltip.select_highlighted_columns = Press B to mark highlighted columns, Ctrl-(or Cmd)-B to toggle, and Alt-B to mark all but highlighted columns 
 action.deselect_all = Deselect all
 action.invert_selection = Invert selection
 action.using_jmol = Using Jmol
@@ -382,8 +384,8 @@ label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation =
 label.translation_failed = Translation Failed
 label.error_when_translating_sequences_submit_bug_report = Unfortunately, something went wrong when translating your sequences.\nPlease take a look in the Jalview java console\nand submit a bug report including the stacktrace.
 label.implementation_error  = Implementation error:
-label.automatically_associate_pdb_files_with_sequences_same_name = Do you want to automatically associate the {0} PDB files with sequences in the alignment that have the same name?
-label.automatically_associate_pdb_files_by_name = Automatically Associate PDB files by name
+label.automatically_associate_structure_files_with_sequences_same_name = Do you want to automatically associate the {0} structure file(s) with sequences in the alignment that have the same name?
+label.automatically_associate_structure_files_by_name = Automatically Associate Structure files by name
 label.ignore_unmatched_dropped_files_info = <html>Do you want to <em>ignore</em> the {0} files whose names did not match any sequence IDs ?</html>
 label.ignore_unmatched_dropped_files = Ignore unmatched dropped files?
 label.view_name_original = Original
@@ -787,8 +789,10 @@ label.hide_columns_containing = Hide columns containing
 label.hide_columns_not_containing = Hide columns that do not contain
 option.trim_retrieved_seqs = Trim retrieved sequences
 label.trim_retrieved_sequences = When the reference sequence is longer than the sequence that you are working with, only keep the relevant subsequences.
-label.use_sequence_id_1 = Use $SEQUENCE_ID$ or $SEQUENCE_ID=/<regex>/=$
-label.use_sequence_id_2 = \nto embed sequence id in URL
+label.use_sequence_id_1 = Use $DB_ACCESSION$ or $DB_ACCESSION=/<regex>/=$
+label.use_sequence_id_2 = to embed accession id in URL
+label.use_sequence_id_3 = Use $SEQUENCE_ID$ similarly to embed sequence id
+label.use_sequence_id_4 = 
 label.ws_parameters_for = Parameters for {0}
 label.switch_server = Switch server
 label.choose_jabaws_server = Choose a server for running this service
@@ -1142,7 +1146,7 @@ warn.user_defined_width_requirements = The user defined width for the\nannotatio
 label.couldnt_create_sequence_fetcher = Couldn't create SequenceFetcher
 warn.couldnt_create_sequence_fetcher_client = Could not create the sequence fetcher client. Check error logs for details.
 warn.server_didnt_pass_validation = Service did not pass validation.\nCheck the Jalview Console for more details.
-warn.url_must_contain = Sequence URL must contain $SEQUENCE_ID$ or a regex $SEQUENCE_ID=/<regex>/=$
+warn.url_must_contain = Sequence URL must contain $SEQUENCE_ID$, $DB_ACCESSION$, or a regex
 warn.urls_not_contacted = URLs that could not be contacted
 warn.urls_no_jaba = URLs without any JABA Services
 info.validate_jabaws_server = Validate JabaWS Server ?\n(Look in console output for results)
@@ -1266,3 +1270,8 @@ status.exporting_alignment_as_x_file = Exporting alignment as {0} file
 label.column = Column
 label.cant_map_cds = Unable to map CDS to protein\nCDS missing or incomplete
 label.operation_failed = Operation failed
+label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ is no longer used for DB accessions
+label.SEQUENCE_ID_for_DB_ACCESSION1 = Please review your URL links in the 'Connections' tab of the Preferences window:
+label.SEQUENCE_ID_for_DB_ACCESSION2 = URL links using '$SEQUENCE_ID$' for DB accessions now use '$DB_ACCESSION$'.
+label.do_not_display_again = Do not display this message again
+label.output_seq_details = Output Sequence Details to list all database references
index cf36638..e5b5e27 100644 (file)
@@ -122,6 +122,8 @@ action.change_font_tree_panel = Cambiar fuente (panel del 
 action.colour = Color
 action.calculate = Calcular
 action.select_all = Seleccionar Todo
+action.select_highlighted_columns = Seleccionar columnas resaltadas
+tooltip.select_highlighted_columns = Presione B para marcar las columnas resaltadas, Ctrl (o Cmd)-B para cambiarlas, y Alt-B para marcar todas menos las columnas resaltadas
 action.deselect_all = Deseleccionar Todo
 action.invert_selection = Invertir selección
 action.using_jmol = Usar Jmol
@@ -351,8 +353,8 @@ label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation =
 label.translation_failed = Translation Failed
 label.error_when_translating_sequences_submit_bug_report = Desafortunadamente, algo fue mal a la hora de traducir tus secuencias.\nPor favor, revisa la consola Jalview java \ny presenta un informe de error que incluya el seguimiento.
 label.implementation_error  = Error de implementación:
-label.automatically_associate_pdb_files_with_sequences_same_name = Quieres asociar automáticamente los {0} ficheros PDB con las secuencias del alineamiento que tengan el mismo nombre?
-label.automatically_associate_pdb_files_by_name = Asociar los ficheros PDB por nombre automáticamente
+label.automatically_associate_structure_files_with_sequences_same_name = Quieres asociar automáticamente los {0} ficheros estructura con las secuencias del alineamiento que tengan el mismo nombre?
+label.automatically_associate_structure_files_by_name = Asociar los ficheros estructura por nombre automáticamente
 label.ignore_unmatched_dropped_files_info = Quieres <em>ignorar</em> los {0} ficheros cuyos nombres no coincidan con ningún IDs de las secuencias ?
 label.ignore_unmatched_dropped_files = Ignorar los ficheros sin coincidencias?
 label.enter_view_name = Introduzca un nombre para la vista
@@ -720,8 +722,10 @@ label.select_columns_containing = Seleccione las columnas que contengan
 label.select_columns_not_containing = Seleccione las columnas que no contengan
 option.trim_retrieved_seqs = Ajustar las secuencias recuperadas
 label.trim_retrieved_sequences = Cuando la secuencia de referencia es más larga que la secuencia con la que está trabajando, sólo se mantienen las subsecuencias relevantes.
-label.use_sequence_id_1 = Utilice $SEQUENCE_ID$ o $SEQUENCE_ID=/<regex>/=$
-label.use_sequence_id_2 = \nto para embeber el id de la secuencia en una URL
+label.use_sequence_id_1 = Utilice $DB_ACCESSION$ o $DB_ACCESSION=/<regex>/=$
+label.use_sequence_id_2 = para embeber el ID de accesión en una URL
+label.use_sequence_id_3 = Utilice $SEQUENCE_ID$ de manera similar para embeber
+label.use_sequence_id_4 = el ID de la secuencia
 label.ws_parameters_for = Parámetros para {0}
 label.switch_server = Cambiar servidor
 label.open_jabaws_web_page = Abra el página principal del servidor JABAWS en un navegador web
@@ -1068,7 +1072,7 @@ warn.user_defined_width_requirements = La anchura definida por el usuario para l
 label.couldnt_create_sequence_fetcher = No es posible crear SequenceFetcher
 warn.couldnt_create_sequence_fetcher_client = No es posible crear el cliente de recuperador de secuencias. Comprueba el fichero de log para más detalles.
 warn.server_didnt_pass_validation = El servicio no ha pasado la validaci\u00F3n.\nCompruebe la consola de Jalview para m\u00E1s detalles.
-warn.url_must_contain = La URL de la secuencia debe contener $SEQUENCE_ID$ o un regex $SEQUENCE_ID=/<regex>/=$
+warn.url_must_contain = La URL de la secuencia debe contener $SEQUENCE_ID$, $DB_ACCESSION$ o un regex
 info.validate_jabaws_server = \u00BFValidar el servidor JabaWS?\n(Consulte la consola de salida para obtener los resultados)
 label.test_server = ¿Probar servidor?
 info.you_want_jalview_to_find_uniprot_accessions = \u00BFDesea que Jalview encuentre\nUniprot Accession ids para los nombres de secuencias dados?
@@ -1267,3 +1271,8 @@ status.exporting_alignment_as_x_file = Exportando alineamiento como fichero tipo
 label.column = Columna
 label.cant_map_cds = No se pudo mapear CDS a proteína\nDatos CDS faltantes o incompletos
 label.operation_failed = Operación fallada
+label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ no se utiliza más para accesiones DB
+label.SEQUENCE_ID_for_DB_ACCESSION1 = Por favor, revise sus URLs en la pestaña 'Conexiones' de la ventana de Preferencias:
+label.SEQUENCE_ID_for_DB_ACCESSION2 = URL enlaza usando '$SEQUENCE_ID$' para accesiones DB ahora usar '$DB_ACCESSION$'.
+label.do_not_display_again = No mostrar este mensaje de nuevo
+label.output_seq_details = Seleccionar Detalles de la secuencia para ver todas
index 7774dac..783a4e2 100755 (executable)
@@ -31,6 +31,7 @@ import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ResidueProperties;
 import jalview.structure.StructureImportSettings;
 import jalview.structure.StructureMapping;
+import jalview.util.Comparison;
 
 import java.awt.Color;
 import java.util.List;
@@ -146,7 +147,9 @@ public class PDBChain
         pdbpos++;
       }
 
-      if (as.astr1.charAt(i) == as.astr2.charAt(i))
+      boolean sameResidue = Comparison.isSameResidue(as.astr1.charAt(i),
+              as.astr2.charAt(i), false);
+      if (sameResidue)
       {
         if (pdbpos >= residues.size())
         {
index 95221d2..1d57a31 100644 (file)
@@ -1,3 +1,35 @@
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions, and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions, and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   3. Redistributions must acknowledge that this software was
+ *      originally developed by the UCSF Computer Graphics Laboratory
+ *      under support by the NIH National Center for Research Resources,
+ *      grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
 package ext.edu.ucsf.rbvi.strucviz2;
 
 import java.awt.Color;
index fdcf34f..736e459 100644 (file)
@@ -1,3 +1,35 @@
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions, and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions, and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   3. Redistributions must acknowledge that this software was
+ *      originally developed by the UCSF Computer Graphics Laboratory
+ *      under support by the NIH National Center for Research Resources,
+ *      grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
 package ext.edu.ucsf.rbvi.strucviz2;
 
 import jalview.ws.HttpClientUtils;
index 7da7a48..d2f4b11 100644 (file)
@@ -1,3 +1,35 @@
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions, and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions, and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   3. Redistributions must acknowledge that this software was
+ *      originally developed by the UCSF Computer Graphics Laboratory
+ *      under support by the NIH National Center for Research Resources,
+ *      grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
 package ext.edu.ucsf.rbvi.strucviz2;
 
 import java.awt.Color;
index 6fd6340..effe556 100644 (file)
@@ -1,3 +1,35 @@
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions, and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions, and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   3. Redistributions must acknowledge that this software was
+ *      originally developed by the UCSF Computer Graphics Laboratory
+ *      under support by the NIH National Center for Research Resources,
+ *      grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
 package ext.edu.ucsf.rbvi.strucviz2;
 
 import jalview.bin.Cache;
index 08a6cb7..77c1883 100644 (file)
@@ -1,3 +1,35 @@
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions, and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions, and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   3. Redistributions must acknowledge that this software was
+ *      originally developed by the UCSF Computer Graphics Laboratory
+ *      under support by the NIH National Center for Research Resources,
+ *      grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
 package ext.edu.ucsf.rbvi.strucviz2;
 
 /**
index 2b2ce48..379097c 100644 (file)
@@ -1,3 +1,35 @@
+/* vim: set ts=2: */
+/**
+ * Copyright (c) 2006 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *   1. Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions, and the following disclaimer.
+ *   2. Redistributions in binary form must reproduce the above
+ *      copyright notice, this list of conditions, and the following
+ *      disclaimer in the documentation and/or other materials provided
+ *      with the distribution.
+ *   3. Redistributions must acknowledge that this software was
+ *      originally developed by the UCSF Computer Graphics Laboratory
+ *      under support by the NIH National Center for Research Resources,
+ *      grant P41-RR01081.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+ * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
 package ext.edu.ucsf.rbvi.strucviz2.port;
 
 import java.io.BufferedReader;
index fb49541..17874e6 100755 (executable)
@@ -24,7 +24,15 @@ import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.Profile;
+import jalview.datamodel.ProfileI;
+import jalview.datamodel.Profiles;
+import jalview.datamodel.ProfilesI;
+import jalview.datamodel.ResidueCount;
+import jalview.datamodel.ResidueCount.SymbolCounts;
 import jalview.datamodel.SequenceI;
+import jalview.ext.android.SparseIntArray;
+import jalview.util.Comparison;
 import jalview.util.Format;
 import jalview.util.MappingUtils;
 import jalview.util.QuickSort;
@@ -44,20 +52,8 @@ import java.util.List;
  */
 public class AAFrequency
 {
-  private static final int TO_UPPER_CASE = 'A' - 'a'; // -32
-
-  public static final String MAXCOUNT = "C";
-
-  public static final String MAXRESIDUE = "R";
-
-  public static final String PID_GAPS = "G";
-
-  public static final String PID_NOGAPS = "N";
-
   public static final String PROFILE = "P";
 
-  public static final String ENCODED_CHARS = "E";
-
   /*
    * Quick look-up of String value of char 'A' to 'Z'
    */
@@ -71,13 +67,13 @@ public class AAFrequency
     }
   }
 
-  public static final Hashtable[] calculate(List<SequenceI> list,
+  public static final ProfilesI calculate(List<SequenceI> list,
           int start, int end)
   {
     return calculate(list, start, end, false);
   }
 
-  public static final Hashtable[] calculate(List<SequenceI> sequences,
+  public static final ProfilesI calculate(List<SequenceI> sequences,
           int start, int end, boolean profile)
   {
     SequenceI[] seqs = new SequenceI[sequences.size()];
@@ -87,307 +83,262 @@ public class AAFrequency
       for (int i = 0; i < sequences.size(); i++)
       {
         seqs[i] = sequences.get(i);
-        if (seqs[i].getLength() > width)
+        int length = seqs[i].getLength();
+        if (length > width)
         {
-          width = seqs[i].getLength();
+          width = length;
         }
       }
 
-      Hashtable[] reply = new Hashtable[width];
-
       if (end >= width)
       {
         end = width;
       }
 
-      calculate(seqs, start, end, reply, profile);
+      ProfilesI reply = calculate(seqs, width, start, end, profile);
       return reply;
     }
   }
 
-  public static final void calculate(SequenceI[] sequences, int start,
-          int end, Hashtable[] result, boolean profile)
+  /**
+   * Calculate the consensus symbol(s) for each column in the given range.
+   * 
+   * @param sequences
+   * @param width
+   *          the full width of the alignment
+   * @param start
+   *          start column (inclusive, base zero)
+   * @param end
+   *          end column (exclusive)
+   * @param saveFullProfile
+   *          if true, store all symbol counts
+   */
+  public static final ProfilesI calculate(final SequenceI[] sequences,
+          int width, int start, int end, boolean saveFullProfile)
   {
-    Hashtable residueHash;
-    int maxCount, nongap, i, j, v;
-    int jSize = sequences.length;
-    String maxResidue;
-    char c = '-';
-    float percentage;
+    // long now = System.currentTimeMillis();
+    int seqCount = sequences.length;
+    boolean nucleotide = false;
+    int nucleotideCount = 0;
+    int peptideCount = 0;
 
-    int[] values = new int[255];
+    ProfileI[] result = new ProfileI[width];
 
-    char[] seq;
-
-    for (i = start; i < end; i++)
+    for (int column = start; column < end; column++)
     {
-      residueHash = new Hashtable();
-      maxCount = 0;
-      maxResidue = "";
-      nongap = 0;
-      values = new int[255];
+      /*
+       * Apply a heuristic to detect nucleotide data (which can
+       * be counted in more compact arrays); here we test for
+       * more than 90% nucleotide; recheck every 10 columns in case
+       * of misleading data e.g. highly conserved Alanine in peptide!
+       * Mistakenly guessing nucleotide has a small performance cost,
+       * as it will result in counting in sparse arrays.
+       * Mistakenly guessing peptide has a small space cost, 
+       * as it will use a larger than necessary array to hold counts. 
+       */
+      if (nucleotideCount > 100 && column % 10 == 0)
+      {
+        nucleotide = (9 * peptideCount < nucleotideCount);
+      }
+      ResidueCount residueCounts = new ResidueCount(nucleotide);
 
-      for (j = 0; j < jSize; j++)
+      for (int row = 0; row < seqCount; row++)
       {
-        if (sequences[j] == null)
+        if (sequences[row] == null)
         {
           System.err
                   .println("WARNING: Consensus skipping null sequence - possible race condition.");
           continue;
         }
-        seq = sequences[j].getSequence();
-        if (seq.length > i)
+        char[] seq = sequences[row].getSequence();
+        if (seq.length > column)
         {
-          c = seq[i];
-
-          if (c == '.' || c == ' ')
+          char c = seq[column];
+          residueCounts.add(c);
+          if (Comparison.isNucleotide(c))
           {
-            c = '-';
+            nucleotideCount++;
           }
-
-          if (c == '-')
-          {
-            values['-']++;
-            continue;
-          }
-          else if ('a' <= c && c <= 'z')
+          else if (!Comparison.isGap(c))
           {
-            c += TO_UPPER_CASE;
+            peptideCount++;
           }
-
-          nongap++;
-          values[c]++;
-
         }
         else
         {
-          values['-']++;
-        }
-      }
-      if (jSize == 1)
-      {
-        maxResidue = String.valueOf(c);
-        maxCount = 1;
-      }
-      else
-      {
-        for (v = 'A'; v <= 'Z'; v++)
-        {
-          // TODO why ignore values[v] == 1?
-          if (values[v] < 1 /* 2 */|| values[v] < maxCount)
-          {
-            continue;
-          }
-
-          if (values[v] > maxCount)
-          {
-            maxResidue = CHARS[v - 'A'];
-          }
-          else if (values[v] == maxCount)
-          {
-            maxResidue += CHARS[v - 'A'];
-          }
-          maxCount = values[v];
+          /*
+           * count a gap if the sequence doesn't reach this column
+           */
+          residueCounts.addGap();
         }
       }
-      if (maxResidue.length() == 0)
-      {
-        maxResidue = "-";
-      }
-      if (profile)
-      {
-        // TODO use a 1-dimensional array with jSize, nongap in [0] and [1]
-        residueHash.put(PROFILE, new int[][] { values,
-            new int[] { jSize, nongap } });
-      }
-      residueHash.put(MAXCOUNT, new Integer(maxCount));
-      residueHash.put(MAXRESIDUE, maxResidue);
 
-      percentage = ((float) maxCount * 100) / jSize;
-      residueHash.put(PID_GAPS, new Float(percentage));
+      int maxCount = residueCounts.getModalCount();
+      String maxResidue = residueCounts.getResiduesForCount(maxCount);
+      int gapCount = residueCounts.getGapCount();
+      ProfileI profile = new Profile(seqCount, gapCount, maxCount,
+              maxResidue);
 
-      if (nongap > 0)
+      if (saveFullProfile)
       {
-        // calculate for non-gapped too
-        percentage = ((float) maxCount * 100) / nongap;
+        profile.setCounts(residueCounts);
       }
-      residueHash.put(PID_NOGAPS, new Float(percentage));
 
-      result[i] = residueHash;
+      result[column] = profile;
     }
+    return new Profiles(result);
+    // long elapsed = System.currentTimeMillis() - now;
+    // System.out.println(elapsed);
   }
 
   /**
-   * Compute all or part of the annotation row from the given consensus
-   * hashtable
+   * Make an estimate of the profile size we are going to compute i.e. how many
+   * different characters may be present in it. Overestimating has a cost of
+   * using more memory than necessary. Underestimating has a cost of needing to
+   * extend the SparseIntArray holding the profile counts.
    * 
-   * @param consensus
-   *          - pre-allocated annotation row
-   * @param hconsensus
-   * @param iStart
-   * @param width
-   * @param ignoreGapsInConsensusCalculation
-   * @param includeAllConsSymbols
-   * @param nseq
+   * @param profileSizes
+   *          counts of sizes of profiles so far encountered
+   * @return
    */
-  public static void completeConsensus(AlignmentAnnotation consensus,
-          Hashtable[] hconsensus, int iStart, int width,
-          boolean ignoreGapsInConsensusCalculation,
-          boolean includeAllConsSymbols, long nseq)
+  static int estimateProfileSize(SparseIntArray profileSizes)
   {
-    completeConsensus(consensus, hconsensus, iStart, width,
-            ignoreGapsInConsensusCalculation, includeAllConsSymbols, null,
-            nseq);
+    if (profileSizes.size() == 0)
+    {
+      return 4;
+    }
+
+    /*
+     * could do a statistical heuristic here e.g. 75%ile
+     * for now just return the largest value
+     */
+    return profileSizes.keyAt(profileSizes.size() - 1);
   }
 
   /**
    * Derive the consensus annotations to be added to the alignment for display.
    * This does not recompute the raw data, but may be called on a change in
-   * display options, such as 'show logo', which may in turn result in a change
-   * in the derived values.
+   * display options, such as 'ignore gaps', which may in turn result in a
+   * change in the derived values.
    * 
    * @param consensus
    *          the annotation row to add annotations to
-   * @param hconsensus
+   * @param profiles
    *          the source consensus data
-   * @param iStart
-   *          start column
-   * @param width
-   *          end column
-   * @param ignoreGapsInConsensusCalculation
-   *          if true, use the consensus calculated ignoring gaps
-   * @param includeAllConsSymbols
+   * @param startCol
+   *          start column (inclusive)
+   * @param endCol
+   *          end column (exclusive)
+   * @param ignoreGaps
+   *          if true, normalise residue percentages ignoring gaps
+   * @param showSequenceLogo
    *          if true include all consensus symbols, else just show modal
    *          residue
-   * @param alphabet
    * @param nseq
    *          number of sequences
    */
   public static void completeConsensus(AlignmentAnnotation consensus,
-          Hashtable[] hconsensus, int iStart, int width,
-          boolean ignoreGapsInConsensusCalculation,
-          boolean includeAllConsSymbols, char[] alphabet, long nseq)
+          ProfilesI profiles, int startCol, int endCol, boolean ignoreGaps,
+          boolean showSequenceLogo, long nseq)
   {
+    // long now = System.currentTimeMillis();
     if (consensus == null || consensus.annotations == null
-            || consensus.annotations.length < width)
+            || consensus.annotations.length < endCol)
     {
-      // called with a bad alignment annotation row - wait for it to be
-      // initialised properly
+      /*
+       * called with a bad alignment annotation row 
+       * wait for it to be initialised properly
+       */
       return;
     }
 
-    final Format fmt = getPercentageFormat(nseq);
-
-    for (int i = iStart; i < width; i++)
+    for (int i = startCol; i < endCol; i++)
     {
-      Hashtable hci;
-      if (i >= hconsensus.length || ((hci = hconsensus[i]) == null))
+      ProfileI profile = profiles.get(i);
+      if (profile == null)
       {
-        // happens if sequences calculated over were shorter than alignment
-        // width
+        /*
+         * happens if sequences calculated over were 
+         * shorter than alignment width
+         */
         consensus.annotations[i] = null;
-        continue;
+        return;
       }
-      Float fv = (Float) hci
-              .get(ignoreGapsInConsensusCalculation ? PID_NOGAPS : PID_GAPS);
-      if (fv == null)
-      {
-        consensus.annotations[i] = null;
-        // data has changed below us .. give up and
-        continue;
-      }
-      float value = fv.floatValue();
-      String maxRes = hci.get(AAFrequency.MAXRESIDUE).toString();
-      StringBuilder mouseOver = new StringBuilder(64);
-      if (maxRes.length() > 1)
+
+      final int dp = getPercentageDp(nseq);
+
+      float value = profile.getPercentageIdentity(ignoreGaps);
+
+      String description = getTooltip(profile, value, showSequenceLogo,
+              ignoreGaps, dp);
+
+      String modalResidue = profile.getModalResidue();
+      if ("".equals(modalResidue))
       {
-        mouseOver.append("[").append(maxRes).append("] ");
-        maxRes = "+";
+        modalResidue = "-";
       }
-      else
+      else if (modalResidue.length() > 1)
       {
-        mouseOver.append(hci.get(AAFrequency.MAXRESIDUE) + " ");
+        modalResidue = "+";
       }
-      int[][] profile = (int[][]) hci.get(AAFrequency.PROFILE);
-      if (profile != null && includeAllConsSymbols)
-      {
-        int sequenceCount = profile[1][0];
-        int nonGappedCount = profile[1][1];
-        int normalisedBy = ignoreGapsInConsensusCalculation ? nonGappedCount
-                : sequenceCount;
-        mouseOver.setLength(0);
-        if (alphabet != null)
-        {
-          for (int c = 0; c < alphabet.length; c++)
-          {
-            float tval = profile[0][alphabet[c]] * 100f / normalisedBy;
-            mouseOver
-                    .append(((c == 0) ? "" : "; "))
-                    .append(alphabet[c])
-                    .append(" ")
-                    .append(((fmt != null) ? fmt.form(tval) : ((int) tval)))
-                    .append("%");
-          }
-        }
-        else
-        {
-          // TODO do this sort once only in calculate()?
-          // char[][] ca = new char[profile[0].length][];
-          char[] ca = new char[profile[0].length];
-          float[] vl = new float[profile[0].length];
-          for (int c = 0; c < ca.length; c++)
-          {
-            ca[c] = (char) c;
-            // ca[c] = new char[]
-            // { (char) c };
-            vl[c] = profile[0][c];
-          }
-          QuickSort.sort(vl, ca);
-          for (int p = 0, c = ca.length - 1; profile[0][ca[c]] > 0; c--)
-          {
-            final char residue = ca[c];
-            if (residue != '-')
-            {
-              float tval = profile[0][residue] * 100f / normalisedBy;
-              mouseOver
-                      .append((((p == 0) ? "" : "; ")))
-                      .append(residue)
-                      .append(" ")
-                      .append(((fmt != null) ? fmt.form(tval)
-                              : ((int) tval))).append("%");
-              p++;
-            }
-          }
-        }
-      }
-      else
-      {
-        mouseOver.append(
-                (((fmt != null) ? fmt.form(value) : ((int) value))))
-                .append("%");
-      }
-      consensus.annotations[i] = new Annotation(maxRes,
-              mouseOver.toString(), ' ', value);
+      consensus.annotations[i] = new Annotation(modalResidue, description,
+              ' ', value);
     }
+    // long elapsed = System.currentTimeMillis() - now;
+    // System.out.println(-elapsed);
   }
 
   /**
-   * Returns a Format designed to show all significant figures for profile
-   * percentages. For less than 100 sequences, returns null (the integer
-   * percentage value will be displayed). For 100-999 sequences, returns "%3.1f"
+   * Returns a tooltip showing either
+   * <ul>
+   * <li>the full profile (percentages of all residues present), if
+   * showSequenceLogo is true, or</li>
+   * <li>just the modal (most common) residue(s), if showSequenceLogo is false</li>
+   * </ul>
+   * Percentages are as a fraction of all sequence, or only ungapped sequences
+   * if ignoreGaps is true.
    * 
-   * @param nseq
+   * @param profile
+   * @param pid
+   * @param showSequenceLogo
+   * @param ignoreGaps
+   * @param dp
+   *          the number of decimal places to format percentages to
    * @return
    */
-  protected static Format getPercentageFormat(long nseq)
+  static String getTooltip(ProfileI profile, float pid,
+          boolean showSequenceLogo, boolean ignoreGaps, int dp)
   {
-    int scale = 0;
-    while (nseq >= 10)
+    ResidueCount counts = profile.getCounts();
+
+    String description = null;
+    if (counts != null && showSequenceLogo)
     {
-      scale++;
-      nseq /= 10;
+      int normaliseBy = ignoreGaps ? profile.getNonGapped() : profile
+              .getHeight();
+      description = counts.getTooltip(normaliseBy, dp);
+    }
+    else
+    {
+      StringBuilder sb = new StringBuilder(64);
+      String maxRes = profile.getModalResidue();
+      if (maxRes.length() > 1)
+      {
+        sb.append("[").append(maxRes).append("]");
+      }
+      else
+      {
+        sb.append(maxRes);
+      }
+      if (maxRes.length() > 0)
+      {
+        sb.append(" ");
+        Format.appendPercentage(sb, pid, dp);
+        sb.append("%");
+      }
+      description = sb.toString();
     }
-    return scale <= 1 ? null : new Format("%3." + (scale - 1) + "f");
+    return description;
   }
 
   /**
@@ -399,46 +350,46 @@ public class AAFrequency
    * in descending order of percentage value
    * </pre>
    * 
-   * @param hconsensus
-   *          the data table from which to extract and sort values
+   * @param profile
+   *          the data object from which to extract and sort values
    * @param ignoreGaps
    *          if true, only non-gapped values are included in percentage
    *          calculations
    * @return
    */
-  public static int[] extractProfile(Hashtable hconsensus,
+  public static int[] extractProfile(ProfileI profile,
           boolean ignoreGaps)
   {
     int[] rtnval = new int[64];
-    int[][] profile = (int[][]) hconsensus.get(AAFrequency.PROFILE);
-    if (profile == null)
+    ResidueCount counts = profile.getCounts();
+    if (counts == null)
     {
       return null;
     }
-    char[] ca = new char[profile[0].length];
-    float[] vl = new float[profile[0].length];
-    for (int c = 0; c < ca.length; c++)
-    {
-      ca[c] = (char) c;
-      vl[c] = profile[0][c];
-    }
-    QuickSort.sort(vl, ca);
+
+    SymbolCounts symbolCounts = counts.getSymbolCounts();
+    char[] symbols = symbolCounts.symbols;
+    int[] values = symbolCounts.values;
+    QuickSort.sort(values, symbols);
     int nextArrayPos = 2;
     int totalPercentage = 0;
-    int distinctValuesCount = 0;
-    final int divisor = profile[1][ignoreGaps ? 1 : 0];
-    for (int c = ca.length - 1; profile[0][ca[c]] > 0; c--)
+    final int divisor = ignoreGaps ? profile.getNonGapped() : profile
+            .getHeight();
+
+    /*
+     * traverse the arrays in reverse order (highest counts first)
+     */
+    for (int i = symbols.length - 1; i >= 0; i--)
     {
-      if (ca[c] != '-')
-      {
-        rtnval[nextArrayPos++] = ca[c];
-        final int percentage = (int) (profile[0][ca[c]] * 100f / divisor);
-        rtnval[nextArrayPos++] = percentage;
-        totalPercentage += percentage;
-        distinctValuesCount++;
-      }
+      int theChar = symbols[i];
+      int charCount = values[i];
+
+      rtnval[nextArrayPos++] = theChar;
+      final int percentage = (charCount * 100) / divisor;
+      rtnval[nextArrayPos++] = percentage;
+      totalPercentage += percentage;
     }
-    rtnval[0] = distinctValuesCount;
+    rtnval[0] = symbols.length;
     rtnval[1] = totalPercentage;
     int[] result = new int[rtnval.length + 1];
     result[0] = AlignmentAnnotation.SEQUENCE_PROFILE;
@@ -647,7 +598,7 @@ public class AAFrequency
       StringBuilder samePercent = new StringBuilder();
       String percent = null;
       String lastPercent = null;
-      Format fmt = getPercentageFormat(nseqs);
+      int percentDecPl = getPercentageDp(nseqs);
 
       for (int j = codons.length - 1; j >= 0; j--)
       {
@@ -669,7 +620,9 @@ public class AAFrequency
         final int pct = codonCount * 100 / totalCount;
         String codon = String
                 .valueOf(CodingUtils.decodeCodon(codonEncoded));
-        percent = fmt == null ? Integer.toString(pct) : fmt.form(pct);
+        StringBuilder sb = new StringBuilder();
+        Format.appendPercentage(sb, pct, percentDecPl);
+        percent = sb.toString();
         if (showProfileLogo || codonCount == modalCodonCount)
         {
           if (percent.equals(lastPercent) && j > 0)
@@ -695,4 +648,23 @@ public class AAFrequency
               mouseOver.toString(), ' ', pid);
     }
   }
+
+  /**
+   * Returns the number of decimal places to show for profile percentages. For
+   * less than 100 sequences, returns zero (the integer percentage value will be
+   * displayed). For 100-999 sequences, returns 1, for 1000-9999 returns 2, etc.
+   * 
+   * @param nseq
+   * @return
+   */
+  protected static int getPercentageDp(long nseq)
+  {
+    int scale = 0;
+    while (nseq >= 100)
+    {
+      scale++;
+      nseq /= 10;
+    }
+    return scale;
+  }
 }
index 3ad3188..86bf721 100755 (executable)
@@ -620,7 +620,10 @@ public class AlignSeq
       {
         if ((i + (j * len)) < astr1.length())
         {
-          if (astr1.charAt(i + (j * len)) == astr2.charAt(i + (j * len))
+          boolean sameChar = Comparison.isSameResidue(
+                  astr1.charAt(i + (j * len)), astr2.charAt(i + (j * len)),
+                  false);
+          if (sameChar
                   && !jalview.util.Comparison.isGap(astr1.charAt(i
                           + (j * len))))
           {
index 75dec63..7b9da46 100755 (executable)
@@ -22,24 +22,33 @@ package jalview.analysis;
 
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.ResidueCount;
+import jalview.datamodel.ResidueCount.SymbolCounts;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.schemes.ResidueProperties;
+import jalview.util.Comparison;
 
 import java.awt.Color;
-import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
 import java.util.Vector;
 
 /**
  * Calculates conservation values for a given set of sequences
- * 
- * @author $author$
- * @version $Revision$
  */
 public class Conservation
 {
+  /*
+   * need to have a minimum of 3% of sequences with a residue
+   * for it to be included in the conservation calculation
+   */
+  private static final int THRESHOLD_PERCENT = 3;
+
+  private static final int TOUPPERCASE = 'a' - 'A';
+
   SequenceI[] sequences;
 
   int start;
@@ -53,6 +62,11 @@ public class Conservation
 
   boolean seqNumsChanged = false; // updated after any change via calcSeqNum;
 
+  /*
+   * a map per column with {property, conservation} where conservation value is
+   * 1 (property is conserved), 0 (absence of property is conserved) or -1
+   * (property is not conserved i.e. column has residues with and without it)
+   */
   Map<String, Integer>[] total;
 
   boolean canonicaliseAa = true; // if true then conservation calculation will
@@ -69,6 +83,9 @@ public class Conservation
 
   private Sequence consSequence;
 
+  /*
+   * percentage of residues in a column to qualify for counting conservation
+   */
   private int threshold;
 
   private String name = "";
@@ -78,12 +95,10 @@ public class Conservation
   private String[] consSymbs;
 
   /**
-   * Creates a new Conservation object.
+   * Constructor using default threshold of 3%
    * 
    * @param name
    *          Name of conservation
-   * @param threshold
-   *          to count the residues in residueHash(). commonly used value is 3
    * @param sequences
    *          sequences to be used in calculation
    * @param start
@@ -91,6 +106,27 @@ public class Conservation
    * @param end
    *          end residue position
    */
+  public Conservation(String name, List<SequenceI> sequences, int start,
+          int end)
+  {
+    this(name, THRESHOLD_PERCENT, sequences, start, end);
+  }
+
+  /**
+   * Constructor
+   * 
+   * @param name
+   *          Name of conservation
+   * @param threshold
+   *          percentage of sequences at or below which property conservation is
+   *          ignored
+   * @param sequences
+   *          sequences to be used in calculation
+   * @param start
+   *          start column position
+   * @param end
+   *          end column position
+   */
   public Conservation(String name, int threshold,
           List<SequenceI> sequences, int start, int end)
   {
@@ -188,147 +224,187 @@ public class Conservation
    */
   public void calculate()
   {
-    int thresh, j, jSize = sequences.length;
-    int[] values; // Replaces residueHash
-    char c;
+    int height = sequences.length;
 
-    total = new Hashtable[maxLength];
+    total = new Map[maxLength];
 
-    for (int i = start; i <= end; i++)
+    for (int column = start; column <= end; column++)
     {
-      values = new int[255];
+      ResidueCount values = countResidues(column);
+
+      /*
+       * percentage count at or below which we ignore residues
+       */
+      int thresh = (threshold * height) / 100;
 
-      for (j = 0; j < jSize; j++)
+      /*
+       * check observed residues in column and record whether each 
+       * physico-chemical property is conserved (+1), absence conserved (0),
+       * or not conserved (-1)
+       * Using TreeMap means properties are displayed in alphabetical order
+       */
+      Map<String, Integer> resultHash = new TreeMap<String, Integer>();
+      SymbolCounts symbolCounts = values.getSymbolCounts();
+      char[] symbols = symbolCounts.symbols;
+      int[] counts = symbolCounts.values;
+      for (int j = 0; j < symbols.length; j++)
       {
-        if (sequences[j].getLength() > i)
+        char c = symbols[j];
+        if (counts[j] > thresh)
         {
-          c = sequences[j].getCharAt(i);
-
-          if (canonicaliseAa)
-          { // lookup the base aa code symbol
-            c = (char) ResidueProperties.aaIndex[sequences[j].getCharAt(i)];
-            if (c > 20)
-            {
-              c = '-';
-            }
-            else
-            {
-              // recover canonical aa symbol
-              c = ResidueProperties.aa[c].charAt(0);
-            }
-          }
-          else
-          {
-            // original behaviour - operate on ascii symbols directly
-            // No need to check if its a '-'
-            if (c == '.' || c == ' ')
-            {
-              c = '-';
-            }
-
-            c = toUpperCase(c);
-          }
-          values[c]++;
+          recordConservation(resultHash, String.valueOf(c));
+        }
+      }
+      if (values.getGapCount() > thresh)
+      {
+        recordConservation(resultHash, "-");
+      }
+
+      if (total.length > 0)
+      {
+        total[column - start] = resultHash;
+      }
+    }
+  }
+
+  /**
+   * Updates the conservation results for an observed residue
+   * 
+   * @param resultMap
+   *          a map of {property, conservation} where conservation value is +1
+   *          (all residues have the property), 0 (no residue has the property)
+   *          or -1 (some do, some don't)
+   * @param res
+   */
+  protected static void recordConservation(Map<String, Integer> resultMap,
+          String res)
+  {
+    res = res.toUpperCase();
+    for (Entry<String, Map<String, Integer>> property : ResidueProperties.propHash
+            .entrySet())
+    {
+      String propertyName = property.getKey();
+      Integer residuePropertyValue = property.getValue().get(res);
+
+      if (!resultMap.containsKey(propertyName))
+      {
+        /*
+         * first time we've seen this residue - note whether it has this property
+         */
+        if (residuePropertyValue != null)
+        {
+          resultMap.put(propertyName, residuePropertyValue);
         }
         else
         {
-          values['-']++;
+          /*
+           * unrecognised residue - use default value for property
+           */
+          resultMap.put(propertyName, property.getValue().get("-"));
         }
       }
+      else
+      {
+        Integer currentResult = resultMap.get(propertyName);
+        if (currentResult.intValue() != -1
+                && !currentResult.equals(residuePropertyValue))
+        {
+          /*
+           * property is unconserved - residues seen both with and without it
+           */
+          resultMap.put(propertyName, Integer.valueOf(-1));
+        }
+      }
+    }
+  }
 
-      // What is the count threshold to count the residues in residueHash()
-      thresh = (threshold * (jSize)) / 100;
+  /**
+   * Counts residues (upper-cased) and gaps in the given column
+   * 
+   * @param column
+   * @return
+   */
+  protected ResidueCount countResidues(int column)
+  {
+    ResidueCount values = new ResidueCount(false);
 
-      // loop over all the found residues
-      Hashtable<String, Integer> resultHash = new Hashtable<String, Integer>();
-      for (char v = '-'; v < 'Z'; v++)
+    for (int row = 0; row < sequences.length; row++)
+    {
+      if (sequences[row].getLength() > column)
       {
-
-        if (values[v] > thresh)
+        char c = sequences[row].getCharAt(column);
+        if (canonicaliseAa)
         {
-          String res = String.valueOf(v);
-
-          // Now loop over the properties
-          for (String type : ResidueProperties.propHash.keySet())
-          {
-            Map<String, Integer> ht = ResidueProperties.propHash.get(type);
-
-            // Have we ticked this before?
-            if (!resultHash.containsKey(type))
-            {
-              if (ht.containsKey(res))
-              {
-                resultHash.put(type, ht.get(res));
-              }
-              else
-              {
-                resultHash.put(type, ht.get("-"));
-              }
-            }
-            else if (!resultHash.get(type).equals(ht.get(res)))
-            {
-              resultHash.put(type, new Integer(-1));
-            }
-          }
+          int index = ResidueProperties.aaIndex[c];
+          c = index > 20 ? '-' : ResidueProperties.aa[index].charAt(0);
+        }
+        else
+        {
+          c = toUpperCase(c);
+        }
+        if (Comparison.isGap(c))
+        {
+          values.addGap();
+        }
+        else
+        {
+          values.add(c);
         }
       }
-
-      if (total.length > 0)
+      else
       {
-        total[i - start] = resultHash;
+        values.addGap();
       }
     }
+    return values;
   }
 
-  /*****************************************************************************
-   * count conservation for the j'th column of the alignment
+  /**
+   * Counts conservation and gaps for a column of the alignment
    * 
-   * @return { gap count, conserved residue count}
+   * @return { 1 if fully conserved, else 0, gap count }
    */
-  public int[] countConsNGaps(int j)
+  public int[] countConservationAndGaps(int column)
   {
-    int count = 0;
-    int cons = 0;
-    int nres = 0;
-    int[] r = new int[2];
-    char f = '$';
-    int i, iSize = sequences.length;
-    char c;
+    int gapCount = 0;
+    boolean fullyConserved = true;
+    int iSize = sequences.length;
 
-    for (i = 0; i < iSize; i++)
+    if (iSize == 0)
+    {
+      return new int[] { 0, 0 };
+    }
+
+    char lastRes = '0';
+    for (int i = 0; i < iSize; i++)
     {
-      if (j >= sequences[i].getLength())
+      if (column >= sequences[i].getLength())
       {
-        count++;
+        gapCount++;
         continue;
       }
 
-      c = sequences[i].getCharAt(j); // gaps do not have upper/lower case
+      char c = sequences[i].getCharAt(column); // gaps do not have upper/lower case
 
-      if (jalview.util.Comparison.isGap((c)))
+      if (Comparison.isGap((c)))
       {
-        count++;
+        gapCount++;
       }
       else
       {
         c = toUpperCase(c);
-        nres++;
-
-        if (nres == 1)
+        if (lastRes == '0')
         {
-          f = c;
-          cons++;
+          lastRes = c;
         }
-        else if (f == c)
+        if (c != lastRes)
         {
-          cons++;
+          fullyConserved = false;
         }
       }
     }
 
-    r[0] = (nres == cons) ? 1 : 0;
-    r[1] = count;
-
+    int[] r = new int[] { fullyConserved ? 1 : 0, gapCount };
     return r;
   }
 
@@ -343,7 +419,7 @@ public class Conservation
   {
     if ('a' <= c && c <= 'z')
     {
-      c -= (32); // 32 = 'a' - 'A'
+      c -= TOUPPERCASE;
     }
     return c;
   }
@@ -351,15 +427,18 @@ public class Conservation
   /**
    * Calculates the conservation sequence
    * 
-   * @param consflag
-   *          if true, positive conservation; false calculates negative
-   *          conservation
-   * @param percentageGaps
-   *          commonly used value is 25
+   * @param positiveOnly
+   *          if true, calculate positive conservation; else calculate both
+   *          positive and negative conservation
+   * @param maxPercentageGaps
+   *          the percentage of gaps in a column, at or above which no
+   *          conservation is asserted
    */
-  public void verdict(boolean consflag, float percentageGaps)
+  public void verdict(boolean positiveOnly, float maxPercentageGaps)
   {
-    StringBuffer consString = new StringBuffer();
+    // TODO call this at the end of calculate(), should not be a public method
+
+    StringBuilder consString = new StringBuilder(end);
 
     // NOTE THIS SHOULD CHECK IF THE CONSEQUENCE ALREADY
     // EXISTS AND NOT OVERWRITE WITH '-', BUT THIS CASE
@@ -371,44 +450,50 @@ public class Conservation
     consSymbs = new String[end - start + 1];
     for (int i = start; i <= end; i++)
     {
-      int[] gapcons = countConsNGaps(i);
+      int[] gapcons = countConservationAndGaps(i);
+      boolean fullyConserved = gapcons[0] == 1;
       int totGaps = gapcons[1];
-      float pgaps = ((float) totGaps * 100) / sequences.length;
-      consSymbs[i - start] = new String();
+      float pgaps = (totGaps * 100f) / sequences.length;
 
-      if (percentageGaps > pgaps)
+      if (maxPercentageGaps > pgaps)
       {
         Map<String, Integer> resultHash = total[i - start];
-        // Now find the verdict
         int count = 0;
+        StringBuilder positives = new StringBuilder(64);
+        StringBuilder negatives = new StringBuilder(32);
         for (String type : resultHash.keySet())
         {
           int result = resultHash.get(type).intValue();
-          // Do we want to count +ve conservation or +ve and -ve cons.?
-          if (consflag)
+          if (result == -1)
+          {
+            /*
+             * not conserved (present or absent)
+             */
+            continue;
+          }
+          count++;
+          if (result == 1)
           {
-            if (result == 1)
-            {
-              consSymbs[i - start] = type + " " + consSymbs[i - start];
-              count++;
-            }
+            /*
+             * positively conserved property (all residues have it)
+             */
+            positives.append(positives.length() == 0 ? "" : " ");
+            positives.append(type);
           }
-          else
+          if (result == 0 && !positiveOnly)
           {
-            if (result != -1)
-            {
-              if (result == 0)
-              {
-                consSymbs[i - start] = consSymbs[i - start] + " !" + type;
-              }
-              else
-              {
-                consSymbs[i - start] = type + " " + consSymbs[i - start];
-              }
-              count++;
-            }
+            /*
+             * absense of property is conserved (all residues lack it)
+             */
+            negatives.append(negatives.length() == 0 ? "" : " ");
+            negatives.append("!").append(type);
           }
         }
+        if (negatives.length() > 0)
+        {
+          positives.append(" ").append(negatives);
+        }
+        consSymbs[i - start] = positives.toString();
 
         if (count < 10)
         {
@@ -416,7 +501,7 @@ public class Conservation
         }
         else
         {
-          consString.append((gapcons[0] == 1) ? "*" : "+");
+          consString.append(fullyConserved ? "*" : "+");
         }
       }
       else
@@ -720,29 +805,27 @@ public class Conservation
    * 
    * @param name
    *          - name of conservation
-   * @param threshold
-   *          - minimum number of conserved residues needed to indicate
-   *          conservation (typically 3)
    * @param seqs
    * @param start
    *          first column in calculation window
    * @param end
    *          last column in calculation window
-   * @param posOrNeg
-   *          positive (true) or negative (false) conservation
-   * @param consPercGaps
+   * @param positiveOnly
+   *          calculate positive (true) or positive and negative (false)
+   *          conservation
+   * @param maxPercentGaps
    *          percentage of gaps tolerated in column
    * @param calcQuality
    *          flag indicating if alignment quality should be calculated
    * @return Conservation object ready for use in visualization
    */
   public static Conservation calculateConservation(String name,
-          int threshold, List<SequenceI> seqs, int start, int end,
-          boolean posOrNeg, int consPercGaps, boolean calcQuality)
+          List<SequenceI> seqs, int start, int end, boolean positiveOnly,
+          int maxPercentGaps, boolean calcQuality)
   {
-    Conservation cons = new Conservation(name, threshold, seqs, start, end);
+    Conservation cons = new Conservation(name, seqs, start, end);
     cons.calculate();
-    cons.verdict(posOrNeg, consPercGaps);
+    cons.verdict(positiveOnly, maxPercentGaps);
 
     if (calcQuality)
     {
@@ -751,4 +834,24 @@ public class Conservation
 
     return cons;
   }
+
+  /**
+   * Returns the computed tooltip (annotation description) for a given column.
+   * The tip is empty if the conservation score is zero, otherwise holds the
+   * conserved properties (and, optionally, properties whose absence is
+   * conserved).
+   * 
+   * @param column
+   * @return
+   */
+  String getTooltip(int column)
+  {
+    char[] sequence = getConsSequence().getSequence();
+    char val = column < sequence.length ? sequence[column] : '-';
+    boolean hasConservation = val != '-' && val != '0';
+    int consp = column - start;
+    String tip = (hasConservation && consp > -1 && consp < consSymbs.length) ? consSymbs[consp]
+            : "";
+    return tip;
+  }
 }
index 72097e0..25ee7d2 100644 (file)
 package jalview.analysis;
 
 import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SearchResultMatchI;
 import jalview.datamodel.SearchResults;
-import jalview.datamodel.Sequence;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Vector;
 
+import com.stevesoft.pat.Regex;
+
 public class Finder
 {
   /**
    * Implements the search algorithms for the Find dialog box.
    */
-  SearchResults searchResults;
+  SearchResultsI searchResults;
 
   AlignmentI alignment;
 
-  jalview.datamodel.SequenceGroup selection = null;
+  SequenceGroup selection = null;
 
-  Vector idMatch = null;
+  Vector<SequenceI> idMatch = null;
 
   boolean caseSensitive = false;
 
@@ -46,10 +53,10 @@ public class Finder
 
   boolean findAll = false;
 
-  com.stevesoft.pat.Regex regex = null;
+  Regex regex = null;
 
   /**
-   * hold's last-searched position between calles to find(false)
+   * holds last-searched position between calls to find(false)
    */
   int seqIndex = 0, resIndex = -1;
 
@@ -83,11 +90,10 @@ public class Finder
     {
       searchString = searchString.toUpperCase();
     }
-    regex = new com.stevesoft.pat.Regex(searchString);
+    regex = new Regex(searchString);
     regex.setIgnoreCase(!caseSensitive);
     searchResults = new SearchResults();
-    idMatch = new Vector();
-    Sequence seq;
+    idMatch = new Vector<SequenceI>();
     String item = null;
     boolean found = false;
     int end = alignment.getHeight();
@@ -102,10 +108,11 @@ public class Finder
         selection = null;
       }
     }
+    SearchResultMatchI lastm = null;
 
     while (!found && (seqIndex < end))
     {
-      seq = (Sequence) alignment.getSequenceAt(seqIndex);
+      SequenceI seq = alignment.getSequenceAt(seqIndex);
 
       if ((selection != null && selection.getSize() > 0)
               && !selection.getSequences(null).contains(seq))
@@ -140,7 +147,7 @@ public class Finder
         {
         }
 
-        if (regex.search(seq.getName()))
+        if (regex.search(seq.getName()) && !idMatch.contains(seq))
         {
           idMatch.addElement(seq);
           hasResults = true;
@@ -153,7 +160,8 @@ public class Finder
         }
 
         if (isIncludeDescription() && seq.getDescription() != null
-                && regex.search(seq.getDescription()))
+                && regex.search(seq.getDescription())
+                && !idMatch.contains(seq))
         {
           idMatch.addElement(seq);
           hasResults = true;
@@ -174,16 +182,16 @@ public class Finder
       }
 
       // /Shall we ignore gaps???? - JBPNote: Add Flag for forcing this or not
-      StringBuffer noGapsSB = new StringBuffer();
+      StringBuilder noGapsSB = new StringBuilder();
       int insertCount = 0;
-      Vector spaces = new Vector();
+      List<Integer> spaces = new ArrayList<Integer>();
 
       for (int j = 0; j < item.length(); j++)
       {
-        if (!jalview.util.Comparison.isGap(item.charAt(j)))
+        if (!Comparison.isGap(item.charAt(j)))
         {
           noGapsSB.append(item.charAt(j));
-          spaces.addElement(new Integer(insertCount));
+          spaces.add(Integer.valueOf(insertCount));
         }
         else
         {
@@ -192,7 +200,6 @@ public class Finder
       }
 
       String noGaps = noGapsSB.toString();
-
       for (int r = resIndex; r < noGaps.length(); r++)
       {
 
@@ -201,22 +208,22 @@ public class Finder
           resIndex = regex.matchedFrom();
 
           if ((selection != null && selection.getSize() > 0)
-                  && ((resIndex + Integer.parseInt(spaces.elementAt(
-                          resIndex).toString())) < selection.getStartRes()))
+                  && (resIndex + spaces.get(resIndex) < selection
+                          .getStartRes()))
           {
             continue;
           }
           // if invalid string used, then regex has no matched to/from
-          int sres = seq
-                  .findPosition(resIndex
-                          + Integer.parseInt(spaces.elementAt(resIndex)
-                                  .toString()));
-          int eres = seq.findPosition(regex.matchedTo()
-                  - 1
-                  + Integer.parseInt(spaces
-                          .elementAt(regex.matchedTo() - 1).toString()));
-
-          searchResults.addResult(seq, sres, eres);
+          int sres = seq.findPosition(resIndex + spaces.get(resIndex));
+          int eres = seq.findPosition(regex.matchedTo() - 1
+                  + (spaces.get(regex.matchedTo() - 1)));
+          // only add result if not contained in previous result
+          if (lastm == null
+                  || (lastm.getSequence() != seq || (!(lastm.getStart() <= sres && lastm
+                          .getEnd() >= eres))))
+          {
+            lastm = searchResults.addResult(seq, sres, eres);
+          }
           hasResults = true;
           if (!findAll)
           {
@@ -320,9 +327,12 @@ public class Finder
   }
 
   /**
-   * @return the idMatch
+   * Returns the (possibly empty) list of matching sequences (when search
+   * includes searching sequence names)
+   * 
+   * @return
    */
-  public Vector getIdMatch()
+  public Vector<SequenceI> getIdMatch()
   {
     return idMatch;
   }
@@ -338,7 +348,7 @@ public class Finder
   /**
    * @return the searchResults
    */
-  public SearchResults getSearchResults()
+  public SearchResultsI getSearchResults()
   {
     return searchResults;
   }
index 26966ba..8ed2c95 100644 (file)
@@ -97,4 +97,16 @@ public interface AlignViewControllerI
   public boolean parseFeaturesFile(String file, String protocol,
           boolean relaxedIdMatching);
 
+  /**
+   * mark columns containing highlighted regions (e.g. from search, structure
+   * highlight, or a mouse over event in another viewer)
+   * 
+   * @param invert
+   * @param extendCurrent
+   * @param toggle
+   * @return
+   */
+  boolean markHighlightedColumns(boolean invert, boolean extendCurrent,
+          boolean toggle);
+
 }
index bd7d53d..72542b3 100644 (file)
@@ -26,6 +26,8 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentView;
 import jalview.datamodel.CigarArray;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.ProfilesI;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
@@ -81,7 +83,7 @@ public interface AlignViewportI extends ViewStyleI
 
   ColumnSelection getColumnSelection();
 
-  Hashtable[] getSequenceConsensusHash();
+  ProfilesI getSequenceConsensusHash();
 
   /**
    * Get consensus data table for the cDNA complement of this alignment (if any)
@@ -144,7 +146,7 @@ public interface AlignViewportI extends ViewStyleI
    * 
    * @param hconsensus
    */
-  void setSequenceConsensusHash(Hashtable[] hconsensus);
+  void setSequenceConsensusHash(ProfilesI hconsensus);
 
   /**
    * Set the cDNA complement consensus for the viewport
@@ -422,4 +424,25 @@ public interface AlignViewportI extends ViewStyleI
    * @return true if group is defined on the alignment
    */
   boolean isSelectionDefinedGroup();
+
+  /**
+   * 
+   * @return true if there are search results on the view
+   */
+  boolean hasSearchResults();
+
+  /**
+   * set the search results for the view
+   * 
+   * @param results
+   *          - or null to clear current results
+   */
+  void setSearchResults(SearchResultsI results);
+
+  /**
+   * get search results for this view (if any)
+   * 
+   * @return search results or null
+   */
+  SearchResultsI getSearchResults();
 }
index dbc9880..f54231e 100644 (file)
@@ -132,7 +132,8 @@ public interface FeatureRenderer
   void setGroupVisibility(String group, boolean visible);
 
   /**
-   * locate features at a particular position on the given sequence
+   * Returns features at the specified position on the given sequence.
+   * Non-positional features are not included.
    * 
    * @param sequence
    * @param res
index c30fdad..0c80c37 100644 (file)
@@ -29,7 +29,6 @@ import jalview.commands.EditCommand;
 import jalview.commands.EditCommand.Action;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
@@ -59,6 +58,7 @@ import java.awt.event.ActionListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -253,122 +253,9 @@ public class APopupMenu extends java.awt.PopupMenu implements
 
     if (links != null && links.size() > 0)
     {
-      Menu linkMenu = new Menu(MessageManager.getString("action.link"));
-      for (int i = 0; i < links.size(); i++)
-      {
-        String link = links.elementAt(i);
-        UrlLink urlLink = new UrlLink(link);
-        if (!urlLink.isValid())
-        {
-          System.err.println(urlLink.getInvalidMessage());
-          continue;
-        }
-        final String target = urlLink.getTarget(); // link.substring(0,
-        // link.indexOf("|"));
-        final String label = urlLink.getLabel();
-        if (seq != null && urlLink.isDynamic())
-        {
-
-          // collect matching db-refs
-          DBRefEntry[] dbr = jalview.util.DBRefUtils.selectRefs(
-                  seq.getDBRefs(), new String[] { target });
-          // collect id string too
-          String id = seq.getName();
-          String descr = seq.getDescription();
-          if (descr != null && descr.length() < 1)
-          {
-            descr = null;
-          }
-          if (dbr != null)
-          {
-            for (int r = 0; r < dbr.length; r++)
-            {
-              if (id != null && dbr[r].getAccessionId().equals(id))
-              {
-                // suppress duplicate link creation for the bare sequence ID
-                // string with this link
-                id = null;
-              }
-              // create Bare ID link for this RUL
-              String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(),
-                      true);
-              if (urls != null)
-              {
-                for (int u = 0; u < urls.length; u += 2)
-                {
-                  addshowLink(linkMenu, label + "|" + urls[u], urls[u + 1]);
-                }
-              }
-            }
-          }
-          if (id != null)
-          {
-            // create Bare ID link for this RUL
-            String[] urls = urlLink.makeUrls(id, true);
-            if (urls != null)
-            {
-              for (int u = 0; u < urls.length; u += 2)
-              {
-                addshowLink(linkMenu, label, urls[u + 1]);
-              }
-            }
-            // addshowLink(linkMenu, target, url_pref + id + url_suff);
-          }
-          // Now construct URLs from description but only try to do it for regex
-          // URL links
-          if (descr != null && urlLink.getRegexReplace() != null)
-          {
-            // create link for this URL from description only if regex matches
-            String[] urls = urlLink.makeUrls(descr, true);
-            if (urls != null)
-            {
-              for (int u = 0; u < urls.length; u += 2)
-              {
-                addshowLink(linkMenu, label, urls[u + 1]);
-              }
-            }
-          }
-        }
-        else
-        {
-          addshowLink(linkMenu, target, urlLink.getUrl_prefix()); // link.substring(link.lastIndexOf("|")+1));
-        }
-        /*
-         * final String url;
-         * 
-         * if (link.indexOf("$SEQUENCE_ID$") > -1) { // Substitute SEQUENCE_ID
-         * string and any matching database reference accessions String url_pref
-         * = link.substring(link.indexOf("|") + 1,
-         * link.indexOf("$SEQUENCE_ID$"));
-         * 
-         * String url_suff = link.substring(link.indexOf("$SEQUENCE_ID$") + 13);
-         * // collect matching db-refs DBRefEntry[] dbr =
-         * jalview.util.DBRefUtils.selectRefs(seq.getDBRef(), new
-         * String[]{target}); // collect id string too String id =
-         * seq.getName(); if (id.indexOf("|") > -1) { id =
-         * id.substring(id.lastIndexOf("|") + 1); } if (dbr!=null) { for (int
-         * r=0;r<dbr.length; r++) { if (dbr[r].getAccessionId().equals(id)) { //
-         * suppress duplicate link creation for the bare sequence ID string with
-         * this link id = null; } addshowLink(linkMenu,
-         * dbr[r].getSource()+"|"+dbr[r].getAccessionId(), target,
-         * url_pref+dbr[r].getAccessionId()+url_suff); } } if (id!=null) { //
-         * create Bare ID link for this RUL addshowLink(linkMenu, target,
-         * url_pref + id + url_suff); } } else { addshowLink(linkMenu, target,
-         * link.substring(link.lastIndexOf("|")+1)); }
-         */
-      }
-      if (linkMenu.getItemCount() > 0)
-      {
-        if (seq != null)
-        {
-          seqMenu.add(linkMenu);
-        }
-        else
-        {
-          add(linkMenu);
-        }
-      }
+      addFeatureLinks(seq, links);
     }
+
     // TODO: add group link menu entry here
     if (seq != null)
     {
@@ -414,6 +301,71 @@ public class APopupMenu extends java.awt.PopupMenu implements
   }
 
   /**
+   * Adds a 'Link' menu item with a sub-menu item for each hyperlink provided.
+   * 
+   * @param seq
+   * @param links
+   */
+  void addFeatureLinks(final SequenceI seq, List<String> links)
+  {
+    Menu linkMenu = new Menu(MessageManager.getString("action.link"));
+    Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+
+    for (String link : links)
+    {
+      UrlLink urlLink = null;
+      try
+      {
+        urlLink = new UrlLink(link);
+      } catch (Exception foo)
+      {
+        System.err.println("Exception for URLLink '" + link + "': "
+                + foo.getMessage());
+        continue;
+      }
+
+      if (!urlLink.isValid())
+      {
+        System.err.println(urlLink.getInvalidMessage());
+        continue;
+      }
+
+      urlLink.createLinksFromSeq(seq, linkset);
+    }
+
+    addshowLinks(linkMenu, linkset.values());
+
+    // disable link menu if there are no valid entries
+    if (linkMenu.getItemCount() > 0)
+    {
+      linkMenu.setEnabled(true);
+    }
+    else
+    {
+      linkMenu.setEnabled(false);
+    }
+
+    if (seq != null)
+    {
+      seqMenu.add(linkMenu);
+    }
+    else
+    {
+      add(linkMenu);
+    }
+
+  }
+
+  private void addshowLinks(Menu linkMenu, Collection<List<String>> linkset)
+  {
+    for (List<String> linkstrset : linkset)
+    {
+      // split linkstr into label and url
+      addshowLink(linkMenu, linkstrset.get(1), linkstrset.get(3));
+    }
+  }
+
+  /**
    * Build menus for annotation types that may be shown or hidden, and for
    * 'reference annotations' that may be added to the alignment.
    */
@@ -850,7 +802,7 @@ public class APopupMenu extends java.awt.PopupMenu implements
 
     CutAndPasteTransfer cap = new CutAndPasteTransfer(false, ap.alignFrame);
 
-    StringBuffer contents = new StringBuffer();
+    StringBuilder contents = new StringBuilder(128);
     for (SequenceI seq : sequences)
     {
       contents.append(MessageManager.formatMessage(
@@ -861,7 +813,6 @@ public class APopupMenu extends java.awt.PopupMenu implements
               seq,
               true,
               true,
-              false,
               (ap.seqPanel.seqCanvas.fr != null) ? ap.seqPanel.seqCanvas.fr
                       .getMinMax() : null);
       contents.append("</p>");
@@ -892,9 +843,10 @@ public class APopupMenu extends java.awt.PopupMenu implements
 
   void addPDB()
   {
-    if (seq.getAllPDBEntries() != null)
+    Vector<PDBEntry> pdbs = seq.getAllPDBEntries();
+    if (pdbs != null&& !pdbs.isEmpty())
     {
-      PDBEntry entry = seq.getAllPDBEntries().firstElement();
+      PDBEntry entry = pdbs.firstElement();
 
       if (ap.av.applet.jmolAvailable)
       {
@@ -1206,11 +1158,10 @@ public class APopupMenu extends java.awt.PopupMenu implements
 
     if (conservationMenuItem.getState())
     {
-
-      sg.cs.setConservation(Conservation.calculateConservation("Group", 3,
-              sg.getSequences(ap.av.getHiddenRepSequences()), 0, ap.av
-                      .getAlignment().getWidth(), false, ap.av
-                      .getConsPercGaps(), false));
+      sg.cs.setConservation(Conservation.calculateConservation("Group", sg
+              .getSequences(ap.av.getHiddenRepSequences()), 0, ap.av
+              .getAlignment().getWidth(), false, ap.av.getConsPercGaps(),
+              false));
       SliderPanel.setConservationSlider(ap, sg.cs, sg.getName());
       SliderPanel.showConservationSlider();
     }
index e5178cb..4bd77b6 100644 (file)
@@ -28,6 +28,7 @@ import jalview.commands.CommandI;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
@@ -433,7 +434,7 @@ public class AlignViewport extends AlignmentViewport implements
      * there is no complement, or it is not following highlights, or no mapping
      * is found, the result will be empty.
      */
-    SearchResults sr = new SearchResults();
+    SearchResultsI sr = new SearchResults();
     int seqOffset = findComplementScrollTarget(sr);
     if (!sr.isEmpty())
     {
index 813ab84..e97c347 100644 (file)
@@ -25,7 +25,7 @@ import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
 import jalview.bin.JalviewLite;
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceI;
 import jalview.structure.StructureSelectionManager;
 
@@ -293,7 +293,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
    * Highlight the given results on the alignment.
    * 
    */
-  public void highlightSearchResults(SearchResults results)
+  public void highlightSearchResults(SearchResultsI results)
   {
     scrollToPosition(results);
     seqPanel.seqCanvas.highlightSearchResults(results);
@@ -306,7 +306,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
    * @param results
    * @return false if results were not found
    */
-  public boolean scrollToPosition(SearchResults results)
+  public boolean scrollToPosition(SearchResultsI results)
   {
     return scrollToPosition(results, true);
   }
@@ -320,10 +320,10 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
    *          - when set, the overview will be recalculated (takes longer)
    * @return false if results were not found
    */
-  public boolean scrollToPosition(SearchResults results,
+  public boolean scrollToPosition(SearchResultsI results,
           boolean redrawOverview)
   {
-    return scrollToPosition(results, redrawOverview, false);
+    return scrollToPosition(results, 0, redrawOverview, false);
   }
 
   /**
@@ -335,7 +335,8 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
    *          - when set, the overview will be recalculated (takes longer)
    * @return false if results were not found
    */
-  public boolean scrollToPosition(SearchResults results,
+  public boolean scrollToPosition(SearchResultsI results,
+          int verticalOffset,
           boolean redrawOverview, boolean centre)
   {
     // do we need to scroll the panel?
@@ -347,6 +348,10 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
       {
         return false;
       }
+      /*
+       * allow for offset of target sequence (actually scroll to one above it)
+       */
+
       SequenceI seq = alignment.getSequenceAt(seqIndex);
       int[] r = results.getResults(seq, 0, alignment.getWidth());
       if (r == null)
@@ -391,6 +396,11 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
       {
         return false;
       }
+
+      /*
+       * allow for offset of target sequence (actually scroll to one above it)
+       */
+      seqIndex = Math.max(0, seqIndex - verticalOffset);
       return scrollTo(start, end, seqIndex, false, redrawOverview);
     }
     return true;
@@ -419,6 +429,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
     {
       start = ostart;
     }
+
     if (!av.getWrapAlignment())
     {
       /*
@@ -902,14 +913,14 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
    * @param seqOffset
    *          the number of visible sequences to show above the mapped region
    */
-  protected void scrollToCentre(SearchResults sr, int seqOffset)
+  protected void scrollToCentre(SearchResultsI sr, int seqOffset)
   {
     /*
      * To avoid jumpy vertical scrolling (if some sequences are gapped or not
      * mapped), we can make the scroll-to location a sequence above the one
      * actually mapped.
      */
-    SequenceI mappedTo = sr.getResultSequence(0);
+    SequenceI mappedTo = sr.getResults().get(0).getSequence();
     List<SequenceI> seqs = av.getAlignment().getSequences();
 
     /*
@@ -931,16 +942,14 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
     {
       return; // failsafe, shouldn't happen
     }
-    sequenceIndex = Math.max(0, sequenceIndex - seqOffset);
-    sr.getResults().get(0)
-            .setSequence(av.getAlignment().getSequenceAt(sequenceIndex));
 
     /*
      * Scroll to position but centring the target residue. Also set a state flag
      * to prevent adjustmentValueChanged performing this recursively.
      */
     setFollowingComplementScroll(true);
-    scrollToPosition(sr, true, true);
+    // this should be scrollToPosition(sr,verticalOffset,
+    scrollToPosition(sr, seqOffset, true, true);
   }
 
   private void sendViewPosition()
index b925284..133cc94 100644 (file)
@@ -180,7 +180,7 @@ public class AppletJmol extends EmbmenuFrame implements
     this.ap = ap;
     jmb = new AppletJmolBinding(this, ap.getStructureSelectionManager(),
             new PDBEntry[] { pdbentry }, new SequenceI[][] { seq },
-            new String[][] { chains }, protocol);
+            protocol);
     jmb.setColourBySequence(true);
     if (pdbentry.getId() == null || pdbentry.getId().length() < 1)
     {
@@ -369,7 +369,7 @@ public class AppletJmol extends EmbmenuFrame implements
     jmb.loadInline(string);
   }
 
-  void setChainMenuItems(Vector<String> chains)
+  void setChainMenuItems(List<String> chains)
   {
     chainMenu.removeAll();
 
@@ -588,7 +588,7 @@ public class AppletJmol extends EmbmenuFrame implements
       repaint();
       return;
     }
-    setChainMenuItems(jmb.chainNames);
+    setChainMenuItems(jmb.getChainNames());
     jmb.colourBySequence(ap);
 
     setTitle(jmb.getViewerTitle());
index 6ec5b4d..684d357 100644 (file)
@@ -29,8 +29,6 @@ import jalview.structure.StructureSelectionManager;
 import java.awt.Container;
 import java.util.Map;
 
-import javajs.awt.Dimension;
-
 import org.jmol.api.JmolAppConsoleInterface;
 import org.jmol.console.AppletConsole;
 import org.jmol.java.BS;
@@ -45,9 +43,9 @@ class AppletJmolBinding extends JalviewJmolBinding
 
   public AppletJmolBinding(AppletJmol appletJmol,
           StructureSelectionManager sSm, PDBEntry[] pdbentry,
-          SequenceI[][] seq, String[][] chains, String protocol)
+          SequenceI[][] seq, String protocol)
   {
-    super(sSm, pdbentry, seq, chains, protocol);
+    super(sSm, pdbentry, seq, protocol);
     appletJmolBinding = appletJmol;
   }
 
@@ -113,12 +111,14 @@ class AppletJmolBinding extends JalviewJmolBinding
     appletJmolBinding.updateTitleAndMenus();
   }
 
+  @Override
   public void updateColours(Object source)
   {
     AlignmentPanel ap = (AlignmentPanel) source;
     colourBySequence(ap);
   }
 
+  @Override
   public void showUrl(String url)
   {
     try
@@ -143,6 +143,7 @@ class AppletJmolBinding extends JalviewJmolBinding
     // do nothing.
   }
 
+  @Override
   public void selectionChanged(BS arg0)
   {
     // TODO Auto-generated method stub
@@ -183,7 +184,7 @@ class AppletJmolBinding extends JalviewJmolBinding
   }
 
   @Override
-  public Dimension resizeInnerPanel(String data)
+  public int[] resizeInnerPanel(String data)
   {
     // TODO Auto-generated method stub
     return null;
index 929a871..5ffbaa4 100644 (file)
@@ -49,11 +49,11 @@ public class ExtJmol extends JalviewJmolBinding
   private AlignmentPanel ap;
 
   protected ExtJmol(jalview.appletgui.AlignFrame alframe,
-          PDBEntry[] pdbentry, SequenceI[][] seq, String[][] chains,
+          PDBEntry[] pdbentry, SequenceI[][] seq,
           String protocol)
   {
     super(alframe.alignPanel.getStructureSelectionManager(), pdbentry, seq,
-            chains, protocol);
+            protocol);
   }
 
   public ExtJmol(Viewer viewer, AlignmentPanel alignPanel,
@@ -64,6 +64,7 @@ public class ExtJmol extends JalviewJmolBinding
     notifyFileLoaded(null, null, null, null, 0);
   }
 
+  @Override
   public void updateColours(Object source)
   {
 
@@ -71,6 +72,7 @@ public class ExtJmol extends JalviewJmolBinding
 
   }
 
+  @Override
   public void showUrl(String arg0)
   {
     showUrl(arg0, "jmol");
@@ -126,6 +128,7 @@ public class ExtJmol extends JalviewJmolBinding
     // ignore
   }
 
+  @Override
   public void selectionChanged(BS arg0)
   {
     System.out.println(arg0);
index 82736d7..2fca07d 100644 (file)
@@ -22,6 +22,7 @@ package jalview.appletgui;
 
 import jalview.api.FeatureColourI;
 import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.io.FeaturesFile;
@@ -225,7 +226,7 @@ public class FeatureRenderer extends
             start.setText(features[index].getBegin() + "");
             end.setText(features[index].getEnd() + "");
 
-            SearchResults highlight = new SearchResults();
+            SearchResultsI highlight = new SearchResults();
             highlight.addResult(sequences[0], features[index].getBegin(),
                     features[index].getEnd());
 
index 75d9b9e..d2fe69c 100644 (file)
@@ -20,7 +20,8 @@
  */
 package jalview.appletgui;
 
-import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultMatchI;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.util.MessageManager;
@@ -50,7 +51,7 @@ public class Finder extends Panel implements ActionListener
 
   Frame frame;
 
-  SearchResults searchResults;
+  SearchResultsI searchResults;
 
   int seqIndex = 0;
 
@@ -76,6 +77,7 @@ public class Finder extends Panel implements ActionListener
     frame.repaint();
     frame.addWindowListener(new WindowAdapter()
     {
+      @Override
       public void windowClosing(WindowEvent evt)
       {
         ap.highlightSearchResults(null);
@@ -84,6 +86,7 @@ public class Finder extends Panel implements ActionListener
     textfield.requestFocus();
   }
 
+  @Override
   public void actionPerformed(ActionEvent evt)
   {
     if (evt.getSource() == textfield)
@@ -114,13 +117,15 @@ public class Finder extends Panel implements ActionListener
     SequenceFeature[] features = new SequenceFeature[searchResults
             .getSize()];
 
-    for (int i = 0; i < searchResults.getSize(); i++)
+    int i = 0;
+    for (SearchResultMatchI match : searchResults.getResults())
     {
-      seqs[i] = searchResults.getResultSequence(i);
+      seqs[i] = match.getSequence().getDatasetSequence();
 
       features[i] = new SequenceFeature(textfield.getText().trim(),
-              "Search Results", null, searchResults.getResultStart(i),
-              searchResults.getResultEnd(i), "Search Results");
+              "Search Results", null, match.getStart(), match.getEnd(),
+              "Search Results");
+      i++;
     }
 
     if (ap.seqPanel.seqCanvas.getFeatureRenderer().amendFeatures(seqs,
@@ -152,7 +157,7 @@ public class Finder extends Panel implements ActionListener
     seqIndex = finder.getSeqIndex();
     resIndex = finder.getResIndex();
     searchResults = finder.getSearchResults();
-    Vector idMatch = finder.getIdMatch();
+    Vector<SequenceI> idMatch = finder.getIdMatch();
     boolean haveResults = false;
     // set or reset the GUI
     if ((idMatch.size() > 0))
@@ -246,6 +251,7 @@ public class Finder extends Panel implements ActionListener
     textfield.setBounds(new Rectangle(40, 17, 133, 21));
     textfield.addKeyListener(new java.awt.event.KeyAdapter()
     {
+      @Override
       public void keyTyped(KeyEvent e)
       {
         textfield_keyTyped(e);
index ed96b55..182f20e 100755 (executable)
@@ -20,6 +20,9 @@
  */
 package jalview.appletgui;
 
+import static jalview.util.UrlConstants.EMBLEBI_STRING;
+import static jalview.util.UrlConstants.SRS_STRING;
+
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
@@ -82,19 +85,16 @@ public class IdPanel extends Panel implements MouseListener,
     }
     {
       // upgrade old SRS link
-      int srsPos = links
-              .indexOf("SRS|http://srs.ebi.ac.uk/srsbin/cgi-bin/wgetz?-newId+(([uniprot-all:$SEQUENCE_ID$]))+-view+SwissEntry");
+      int srsPos = links.indexOf(SRS_STRING);
       if (srsPos > -1)
       {
-        links.setElementAt(
-                "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$",
-                srsPos);
+        links.setElementAt(EMBLEBI_STRING, srsPos);
       }
     }
     if (links.size() < 1)
     {
       links = new java.util.Vector();
-      links.addElement("EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$");
+      links.addElement(EMBLEBI_STRING);
     }
   }
 
@@ -246,7 +246,14 @@ public class IdPanel extends Panel implements MouseListener,
         url = null;
         continue;
       }
-      ;
+
+      if (urlLink.usesDBAccession())
+      {
+        // this URL requires an accession id, not the name of a sequence
+        url = null;
+        continue;
+      }
+
       if (!urlLink.isValid())
       {
         System.err.println(urlLink.getInvalidMessage());
index 7216bfe..5d6bb07 100755 (executable)
@@ -21,7 +21,7 @@
 package jalview.appletgui;
 
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.renderer.ScaleRenderer;
@@ -50,8 +50,6 @@ public class SeqCanvas extends Panel
 
   AlignViewport av;
 
-  SearchResults searchResults = null;
-
   boolean fastPaint = false;
 
   int cursorX = 0;
@@ -632,9 +630,10 @@ public class SeqCanvas extends Panel
 
       // / Highlight search Results once all sequences have been drawn
       // ////////////////////////////////////////////////////////
-      if (searchResults != null)
+      if (av.hasSearchResults())
       {
-        int[] visibleResults = searchResults.getResults(nextSeq, startRes,
+        int[] visibleResults = av.getSearchResults().getResults(nextSeq,
+                startRes,
                 endRes);
         if (visibleResults != null)
         {
@@ -843,10 +842,9 @@ public class SeqCanvas extends Panel
     }
   }
 
-  public void highlightSearchResults(SearchResults results)
+  public void highlightSearchResults(SearchResultsI results)
   {
-    searchResults = results;
-
+    av.setSearchResults(results);
     repaint();
   }
 
index 6ca9499..8d6e683 100644 (file)
@@ -25,8 +25,9 @@ import jalview.commands.EditCommand;
 import jalview.commands.EditCommand.Action;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SearchResultMatchI;
 import jalview.datamodel.SearchResults;
-import jalview.datamodel.SearchResults.Match;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
@@ -458,7 +459,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
    * @param results
    * @return true if results were matched, false if not
    */
-  private boolean setStatusMessage(SearchResults results)
+  private boolean setStatusMessage(SearchResultsI results)
   {
     AlignmentI al = this.av.getAlignment();
     int sequenceIndex = al.findIndex(results);
@@ -467,7 +468,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
       return false;
     }
     SequenceI ds = al.getSequenceAt(sequenceIndex).getDatasetSequence();
-    for (Match m : results.getResults())
+    for (SearchResultMatchI m : results.getResults())
     {
       SequenceI seq = m.getSequence();
       if (seq.getDatasetSequence() != null)
@@ -559,7 +560,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
 
       if (features != null && features.length > 0)
       {
-        SearchResults highlight = new SearchResults();
+        SearchResultsI highlight = new SearchResults();
         highlight.addResult(sequence, features[0].getBegin(),
                 features[0].getEnd());
         seqCanvas.highlightSearchResults(highlight);
@@ -731,7 +732,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
   }
 
   @Override
-  public void highlightSequence(SearchResults results)
+  public void highlightSequence(SearchResultsI results)
   {
     if (av.isFollowHighlight())
     {
index 3b509e5..8292a5a 100755 (executable)
@@ -676,8 +676,8 @@ public class TreeCanvas extends Panel implements MouseListener,
       if (av.getGlobalColourScheme() != null
               && av.getGlobalColourScheme().conservationApplied())
       {
-        Conservation c = new Conservation("Group", 3,
-                sg.getSequences(null), sg.getStartRes(), sg.getEndRes());
+        Conservation c = new Conservation("Group", sg.getSequences(null),
+                sg.getStartRes(), sg.getEndRes());
 
         c.calculate();
         c.verdict(false, av.getConsPercGaps());
index 763b10b..bcb4e7b 100755 (executable)
@@ -51,6 +51,7 @@ import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.net.MalformedURLException;
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.net.URL;
 import java.security.AllPermission;
 import java.security.CodeSource;
@@ -650,10 +651,33 @@ public class Jalview
           {
             File imageFile = new File(file);
             imageName = imageFile.getName();
-            new HtmlSvgOutput(new File(file), af.alignPanel);
+            HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
+            htmlSVG.exportHTML(file);
+
             System.out.println("Creating HTML image: " + file);
             continue;
           }
+          else if (format.equalsIgnoreCase("biojsmsa"))
+          {
+            if (file == null)
+            {
+              System.err.println("The output html file must not be null");
+              return;
+            }
+            try
+            {
+              BioJsHTMLOutput
+                      .refreshVersionInfo(BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
+            } catch (URISyntaxException e)
+            {
+              e.printStackTrace();
+            }
+            BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
+            bjs.exportHTML(file);
+            System.out.println("Creating BioJS MSA Viwer HTML file: "
+                    + file);
+            continue;
+          }
           else if (format.equalsIgnoreCase("imgMap"))
           {
             af.createImageMap(new File(file), imageName);
@@ -789,6 +813,7 @@ public class Jalview
                     + "-png FILE\tCreate PNG image FILE from alignment.\n"
                     + "-svg FILE\tCreate SVG image FILE from alignment.\n"
                     + "-html FILE\tCreate HTML file from alignment.\n"
+                    + "-biojsMSA FILE\tCreate BioJS MSA Viewer HTML file from alignment.\n"
                     + "-imgMap FILE\tCreate HTML file FILE with image map of PNG image.\n"
                     + "-eps FILE\tCreate EPS file FILE from alignment.\n"
                     + "-questionnaire URL\tQueries the given URL for information about any Jalview user questionnaires.\n"
index f508bc3..e9a0dbf 100644 (file)
@@ -243,10 +243,6 @@ public class AlignViewController implements AlignViewControllerI
         SequenceFeature[] sfs = sq.getSequenceFeatures();
         if (sfs != null)
         {
-          /*
-           * check whether the feature start/end (base 1) 
-           * overlaps the selection start/end
-           */
           int ist = sq.findIndex(sq.getStart());
           int iend = sq.findIndex(sq.getEnd());
           if (iend < startPosition || ist > endPosition)
@@ -264,29 +260,54 @@ public class AlignViewController implements AlignViewControllerI
               // - findIndex wastes time by starting from first character and
               // counting
 
-              int i = sq.findIndex(sf.getBegin());
-              int j = sq.findIndex(sf.getEnd());
-              if (j < startPosition || i > endPosition)
+              int sfStartCol = sq.findIndex(sf.getBegin());
+              int sfEndCol = sq.findIndex(sf.getEnd());
+
+              if (sf.isContactFeature())
+              {
+                /*
+                 * 'contact' feature - check for 'start' or 'end'
+                 * position within the selected region
+                 */
+                if (sfStartCol >= startPosition
+                        && sfStartCol <= endPosition)
+                {
+                  bs.set(sfStartCol - 1);
+                  sequenceHasFeature = true;
+                }
+                if (sfEndCol >= startPosition && sfEndCol <= endPosition)
+                {
+                  bs.set(sfEndCol - 1);
+                  sequenceHasFeature = true;
+                }
+                continue;
+              }
+
+              /*
+               * contiguous feature - select feature positions (if any) 
+               * within the selected region
+               */
+              if (sfStartCol > endPosition || sfEndCol < startPosition)
               {
                 // feature is outside selected region
                 continue;
               }
               sequenceHasFeature = true;
-              if (i < startPosition)
+              if (sfStartCol < startPosition)
               {
-                i = startPosition;
+                sfStartCol = startPosition;
               }
-              if (i < ist)
+              if (sfStartCol < ist)
               {
-                i = ist;
+                sfStartCol = ist;
               }
-              if (j > endPosition)
+              if (sfEndCol > endPosition)
               {
-                j = endPosition;
+                sfEndCol = endPosition;
               }
-              for (; i <= j; i++)
+              for (; sfStartCol <= sfEndCol; sfStartCol++)
               {
-                bs.set(i - 1); // convert to base 0
+                bs.set(sfStartCol - 1); // convert to base 0
               }
             }
           }
@@ -381,4 +402,66 @@ public class AlignViewController implements AlignViewControllerI
     return featuresFile;
 
   }
+
+  @Override
+  public boolean markHighlightedColumns(boolean invert,
+          boolean extendCurrent, boolean toggle)
+  {
+    if (!viewport.hasSearchResults())
+    {
+      // do nothing if no selection exists
+      return false;
+    }
+    // JBPNote this routine could also mark rows, not just columns.
+    BitSet bs = new BitSet();
+    SequenceCollectionI sqcol = (viewport.getSelectionGroup() == null || extendCurrent) ? viewport
+            .getAlignment() : viewport.getSelectionGroup();
+
+    // this could be a lambda... - the remains of the method is boilerplate,
+    // except for the different messages for reporting selection.
+    int nseq = viewport.getSearchResults().markColumns(sqcol, bs);
+
+    ColumnSelection cs = viewport.getColumnSelection();
+    if (cs == null)
+    {
+      cs = new ColumnSelection();
+    }
+
+    if (bs.cardinality() > 0 || invert)
+    {
+      boolean changed = cs.markColumns(bs, sqcol.getStartRes(),
+              sqcol.getEndRes(), invert, extendCurrent, toggle);
+      if (changed)
+      {
+        viewport.setColumnSelection(cs);
+        alignPanel.paintAlignment(true);
+        int columnCount = invert ? (sqcol.getEndRes() - sqcol.getStartRes() + 1)
+                - bs.cardinality()
+                : bs.cardinality();
+        avcg.setStatus(MessageManager.formatMessage(
+                "label.view_controller_toggled_marked",
+                new String[] {
+                    toggle ? MessageManager.getString("label.toggled")
+                            : MessageManager.getString("label.marked"),
+                    String.valueOf(columnCount),
+                    invert ? MessageManager
+                            .getString("label.not_containing")
+                            : MessageManager.getString("label.containing"),
+                    "Highlight", Integer.valueOf(nseq).toString() }));
+        return true;
+      }
+    }
+    else
+    {
+      avcg.setStatus(MessageManager
+              .formatMessage("No highlighted regions marked"));
+      if (!extendCurrent)
+      {
+        cs.clear();
+        alignPanel.paintAlignment(true);
+      }
+    }
+    return false;
+  }
+
 }
index c5204eb..4fbfd62 100644 (file)
@@ -301,7 +301,7 @@ public class AlignedCodonFrame
    *          where highlighted regions go
    */
   public void markMappedRegion(SequenceI seq, int index,
-          SearchResults results)
+          SearchResultsI results)
   {
     int[] codon;
     SequenceI ds = seq.getDatasetSequence();
index 2289ac6..bd78827 100755 (executable)
@@ -661,7 +661,7 @@ public class Alignment implements AlignmentI
    * jalview.datamodel.AlignmentI#findIndex(jalview.datamodel.SearchResults)
    */
   @Override
-  public int findIndex(SearchResults results)
+  public int findIndex(SearchResultsI results)
   {
     int i = 0;
 
index 1d37fa6..7274e5f 100755 (executable)
@@ -426,7 +426,7 @@ public interface AlignmentI extends AnnotatedCollectionI
    * @param results
    * @return -1 or index of sequence in alignment
    */
-  int findIndex(SearchResults results);
+  int findIndex(SearchResultsI results);
 
   /**
    * append sequences and annotation from another alignment object to this one.
index 6a6ccd0..9c3a8e7 100755 (executable)
@@ -121,16 +121,6 @@ public class PDBEntry
   {
   }
 
-  /**
-   * Constructor given file path and PDB id.
-   * 
-   * @param filePath
-   */
-  // public PDBEntry(String filePath, String pdbId)
-  // {
-  // this.file = filePath;
-  // this.id = pdbId;
-  // }
 
   public PDBEntry(String pdbId, String chain, PDBEntry.Type type,
           String filePath)
diff --git a/src/jalview/datamodel/Profile.java b/src/jalview/datamodel/Profile.java
new file mode 100644 (file)
index 0000000..1501808
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * 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.datamodel;
+
+
+/**
+ * A profile for one column of an alignment
+ * 
+ * @author gmcarstairs
+ *
+ */
+public class Profile implements ProfileI
+{
+  /*
+   * an object holding counts of symbols in the profile
+   */
+  private ResidueCount counts;
+
+  /*
+   * the number of sequences (gapped or not) in the profile
+   */
+  private int height;
+
+  /*
+   * the number of non-gapped sequences in the profile
+   */
+  private int gapped;
+
+  /*
+   * the highest count for any residue in the profile
+   */
+  private int maxCount;
+
+  /*
+   * the residue (e.g. K) or residues (e.g. KQW) with the
+   * highest count in the profile
+   */
+  private String modalResidue;
+
+  /**
+   * Constructor which allows derived data to be stored without having to store
+   * the full profile
+   * 
+   * @param seqCount
+   *          the number of sequences in the profile
+   * @param gaps
+   *          the number of gapped sequences
+   * @param max
+   *          the highest count for any residue
+   * @param modalres
+   *          the residue (or concatenated residues) with the highest count
+   */
+  public Profile(int seqCount, int gaps, int max, String modalRes)
+  {
+    this.height = seqCount;
+    this.gapped = gaps;
+    this.maxCount = max;
+    this.modalResidue = modalRes;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#setCounts(jalview.datamodel.ResidueCount)
+   */
+  @Override
+  public void setCounts(ResidueCount residueCounts)
+  {
+    this.counts = residueCounts;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#getPercentageIdentity(boolean)
+   */
+  @Override
+  public float getPercentageIdentity(boolean ignoreGaps)
+  {
+    if (height == 0)
+    {
+      return 0f;
+    }
+    float pid = 0f;
+    if (ignoreGaps && gapped < height)
+    {
+      pid = (maxCount * 100f) / (height - gapped);
+    }
+    else
+    {
+      pid = (maxCount * 100f) / height;
+    }
+    return pid;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#getCounts()
+   */
+  @Override
+  public ResidueCount getCounts()
+  {
+    return counts;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#getHeight()
+   */
+  @Override
+  public int getHeight()
+  {
+    return height;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#getGapped()
+   */
+  @Override
+  public int getGapped()
+  {
+    return gapped;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#getMaxCount()
+   */
+  @Override
+  public int getMaxCount()
+  {
+    return maxCount;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#getModalResidue()
+   */
+  @Override
+  public String getModalResidue()
+  {
+    return modalResidue;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.datamodel.ProfileI#getNonGapped()
+   */
+  @Override
+  public int getNonGapped()
+  {
+    return height - gapped;
+  }
+}
diff --git a/src/jalview/datamodel/ProfileI.java b/src/jalview/datamodel/ProfileI.java
new file mode 100644 (file)
index 0000000..65a5c0d
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * 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.datamodel;
+
+public interface ProfileI
+{
+
+  /**
+   * Set the full profile of counts
+   * 
+   * @param residueCounts
+   */
+  public abstract void setCounts(ResidueCount residueCounts);
+
+  /**
+   * Returns the percentage identity of the profile, i.e. the highest proportion
+   * of conserved (equal) symbols. The percentage is as a fraction of all
+   * sequences, or only ungapped sequences if flag ignoreGaps is set true.
+   * 
+   * @param ignoreGaps
+   * @return
+   */
+  public abstract float getPercentageIdentity(boolean ignoreGaps);
+
+  /**
+   * Returns the full symbol counts for this profile
+   * 
+   * @return
+   */
+  public abstract ResidueCount getCounts();
+
+  /**
+   * Returns the number of sequences in the profile
+   * 
+   * @return
+   */
+  public abstract int getHeight();
+
+  /**
+   * Returns the number of sequences in the profile which had a gap character
+   * (or were too short to be included in this column's profile)
+   * 
+   * @return
+   */
+  public abstract int getGapped();
+
+  /**
+   * Returns the highest count for any symbol(s) in the profile
+   * 
+   * @return
+   */
+  public abstract int getMaxCount();
+
+  /**
+   * Returns the symbol (or concatenated symbols) which have the highest count
+   * in the profile, or an empty string if there were no symbols counted
+   * 
+   * @return
+   */
+  public abstract String getModalResidue();
+
+  /**
+   * Answers the number of non-gapped sequences in the profile
+   * 
+   * @return
+   */
+  public abstract int getNonGapped();
+
+}
\ No newline at end of file
diff --git a/src/jalview/datamodel/Profiles.java b/src/jalview/datamodel/Profiles.java
new file mode 100644 (file)
index 0000000..f65830a
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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.datamodel;
+
+public class Profiles implements ProfilesI
+{
+
+  private ProfileI[] profiles;
+
+  public Profiles(ProfileI[] p)
+  {
+    profiles = p;
+  }
+
+  /**
+   * Returns the profile for the given column, or null if none found
+   * 
+   * @param col
+   */
+  @Override
+  public ProfileI get(int col)
+  {
+    return profiles != null && col >= 0 && col < profiles.length ? profiles[col]
+            : null;
+  }
+
+  /**
+   * Returns the first column (base 0) covered by the profiles
+   */
+  @Override
+  public int getStartColumn()
+  {
+    return 0;
+  }
+
+  /**
+   * Returns the last column (base 0) covered by the profiles
+   */
+  @Override
+  public int getEndColumn()
+  {
+    return profiles == null ? 0 : profiles.length - 1;
+  }
+
+}
diff --git a/src/jalview/datamodel/ProfilesI.java b/src/jalview/datamodel/ProfilesI.java
new file mode 100644 (file)
index 0000000..82398d9
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * 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.datamodel;
+
+public interface ProfilesI
+{
+
+  ProfileI get(int i);
+
+  int getStartColumn();
+
+  int getEndColumn();
+
+}
diff --git a/src/jalview/datamodel/ResidueCount.java b/src/jalview/datamodel/ResidueCount.java
new file mode 100644 (file)
index 0000000..3e3a966
--- /dev/null
@@ -0,0 +1,641 @@
+/*
+ * 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.datamodel;
+
+import jalview.util.Comparison;
+import jalview.util.Format;
+import jalview.util.QuickSort;
+import jalview.util.SparseCount;
+
+/**
+ * A class to count occurrences of residues in a profile, optimised for speed
+ * and memory footprint.
+ * @author gmcarstairs
+ *
+ */
+public class ResidueCount
+{
+  /**
+   * A data bean to hold the results of counting symbols
+   */
+  public class SymbolCounts
+  {
+    /**
+     * the symbols seen (as char values), in no particular order
+     */
+    public final char[] symbols;
+
+    /**
+     * the counts for each symbol, in the same order as the symbols
+     */
+    public final int[] values;
+
+    SymbolCounts(char[] s, int[] v)
+    {
+      symbols = s;
+      values = v;
+    }
+  }
+
+  private static final int TOUPPERCASE = 'A' - 'a';
+
+  /*
+   * nucleotide symbols to count (including N unknown)
+   */
+  private static final String NUCS = "ACGNTU";
+
+  /*
+   * amino acid symbols to count (including X unknown)
+   * NB we also include U so as to support counting of RNA bases
+   * in the "don't know" case of nucleotide / peptide
+   */
+  private static final String AAS = "ACDEFGHIKLMNPQRSTUVWXY";
+
+  private static final int GAP_COUNT = 0;
+
+  /*
+   * fast lookup tables holding the index into our count
+   * arrays of each symbol; index 0 is reserved for gap counting
+   */
+  private static int[] NUC_INDEX = new int[26];
+
+  private static int[] AA_INDEX = new int[26];
+  static
+  {
+    for (int i = 0; i < NUCS.length(); i++)
+    {
+      NUC_INDEX[NUCS.charAt(i) - 'A'] = i + 1;
+    }
+    for (int i = 0; i < AAS.length(); i++)
+    {
+      AA_INDEX[AAS.charAt(i) - 'A'] = i + 1;
+    }
+  }
+
+  /*
+   * counts array, just big enough for the nucleotide or peptide
+   * character set (plus gap counts in position 0)
+   */
+  private short[] counts;
+
+  /*
+   * alternative array of int counts for use if any count 
+   * exceeds the maximum value of short (32767)
+   */
+  private int[] intCounts;
+
+  /*
+   * flag set if we switch from short to int counts
+   */
+  private boolean useIntCounts;
+
+  /*
+   * general-purpose counter, only for use for characters
+   * that are not in the expected alphabet
+   */
+  private SparseCount otherData;
+
+  /*
+   * keeps track of the maximum count value recorded
+   * (if this class ever allows decrements, would need to
+   * calculate this on request instead) 
+   */
+  int maxCount;
+
+  /*
+   * if we think we are counting nucleotide, can get by with smaller
+   * array to hold counts
+   */
+  private boolean isNucleotide;
+
+  /**
+   * Default constructor allocates arrays able to count either nucleotide or
+   * peptide bases. Use this constructor if not sure which the data is.
+   */
+  public ResidueCount()
+  {
+    this(false);
+  }
+
+  /**
+   * Constructor that allocates an array just big enough for the anticipated
+   * characters, plus one position to count gaps
+   */
+  public ResidueCount(boolean nucleotide)
+  {
+    isNucleotide = nucleotide;
+    int charsToCount = nucleotide ? NUCS.length() : AAS.length();
+    counts = new short[charsToCount + 1];
+  }
+
+  /**
+   * Increments the count for the given character. The supplied character may be
+   * upper or lower case but counts are for the upper case only. Gap characters
+   * (space, ., -) are all counted together.
+   * 
+   * @param c
+   * @return the new value of the count for the character
+   */
+  public int add(final char c)
+  {
+    char u = toUpperCase(c);
+    int newValue = 0;
+    int offset = getOffset(u);
+
+    /*
+     * offset 0 is reserved for gap counting, so 0 here means either
+     * an unexpected character, or a gap character passed in error
+     */
+    if (offset == 0)
+    {
+      if (Comparison.isGap(u))
+      {
+        newValue = addGap();
+      }
+      else
+      {
+        newValue = addOtherCharacter(u);
+      }
+    }
+    else
+    {
+      newValue = increment(offset);
+    }
+    return newValue;
+  }
+
+  /**
+   * Increment the count at the specified offset. If this would result in short
+   * overflow, promote to counting int values instead.
+   * 
+   * @param offset
+   * @return the new value of the count at this offset
+   */
+  int increment(int offset)
+  {
+    int newValue = 0;
+    if (useIntCounts)
+    {
+      newValue = intCounts[offset];
+      intCounts[offset] = ++newValue;
+    }
+    else
+    {
+      if (counts[offset] == Short.MAX_VALUE)
+      {
+        handleOverflow();
+        newValue = intCounts[offset];
+        intCounts[offset] = ++newValue;
+      }
+      else
+      {
+        newValue = counts[offset];
+        counts[offset] = (short) ++newValue;
+      }
+    }
+    maxCount = Math.max(maxCount, newValue);
+    return newValue;
+  }
+
+  /**
+   * Switch from counting in short to counting in int
+   */
+  synchronized void handleOverflow()
+  {
+    intCounts = new int[counts.length];
+    for (int i = 0; i < counts.length; i++)
+    {
+      intCounts[i] = counts[i];
+    }
+    counts = null;
+    useIntCounts = true;
+  }
+
+  /**
+   * Returns this character's offset in the count array
+   * 
+   * @param c
+   * @return
+   */
+  int getOffset(char c)
+  {
+    int offset = 0;
+    if ('A' <= c && c <= 'Z')
+    {
+      offset = isNucleotide ? NUC_INDEX[c - 'A'] : AA_INDEX[c - 'A'];
+    }
+    return offset;
+  }
+
+  /**
+   * @param c
+   * @return
+   */
+  protected char toUpperCase(final char c)
+  {
+    char u = c;
+    if ('a' <= c && c <= 'z')
+    {
+      u = (char) (c + TOUPPERCASE);
+    }
+    return u;
+  }
+
+  /**
+   * Increment count for some unanticipated character. The first time this
+   * called, a SparseCount is instantiated to hold these 'extra' counts.
+   * 
+   * @param c
+   * @return the new value of the count for the character
+   */
+  int addOtherCharacter(char c)
+  {
+    if (otherData == null)
+    {
+      otherData = new SparseCount();
+    }
+    int newValue = otherData.add(c, 1);
+    maxCount = Math.max(maxCount, newValue);
+    return newValue;
+  }
+
+  /**
+   * Set count for some unanticipated character. The first time this called, a
+   * SparseCount is instantiated to hold these 'extra' counts.
+   * 
+   * @param c
+   * @param value
+   */
+  void setOtherCharacter(char c, int value)
+  {
+    if (otherData == null)
+    {
+      otherData = new SparseCount();
+    }
+    otherData.put(c, value);
+  }
+
+  /**
+   * Increment count of gap characters
+   * 
+   * @return the new count of gaps
+   */
+  public int addGap()
+  {
+    int newValue;
+    if (useIntCounts)
+    {
+      newValue = ++intCounts[GAP_COUNT];
+    }
+    else
+    {
+      newValue = ++counts[GAP_COUNT];
+    }
+    return newValue;
+  }
+
+  /**
+   * Answers true if we are counting ints (only after overflow of short counts)
+   * 
+   * @return
+   */
+  boolean isCountingInts()
+  {
+    return useIntCounts;
+  }
+
+  /**
+   * Sets the count for the given character. The supplied character may be upper
+   * or lower case but counts are for the upper case only.
+   * 
+   * @param c
+   * @param count
+   */
+  public void put(char c, int count)
+  {
+    char u = toUpperCase(c);
+    int offset = getOffset(u);
+
+    /*
+     * offset 0 is reserved for gap counting, so 0 here means either
+     * an unexpected character, or a gap character passed in error
+     */
+    if (offset == 0)
+    {
+      if (Comparison.isGap(u))
+      {
+        set(0, count);
+      }
+      else
+      {
+        setOtherCharacter(u, count);
+        maxCount = Math.max(maxCount, count);
+      }
+    }
+    else
+    {
+      set(offset, count);
+      maxCount = Math.max(maxCount, count);
+    }
+  }
+
+  /**
+   * Sets the count at the specified offset. If this would result in short
+   * overflow, promote to counting int values instead.
+   * 
+   * @param offset
+   * @param value
+   */
+  void set(int offset, int value)
+  {
+    if (useIntCounts)
+    {
+      intCounts[offset] = value;
+    }
+    else
+    {
+      if (value > Short.MAX_VALUE || value < Short.MIN_VALUE)
+      {
+        handleOverflow();
+        intCounts[offset] = value;
+      }
+      else
+      {
+        counts[offset] = (short) value;
+      }
+    }
+  }
+
+  /**
+   * Returns the count for the given character, or zero if no count held
+   * 
+   * @param c
+   * @return
+   */
+  public int getCount(char c)
+  {
+    char u = toUpperCase(c);
+    int offset = getOffset(u);
+    if (offset == 0)
+    {
+      if (!Comparison.isGap(u))
+      {
+        // should have called getGapCount()
+        return otherData == null ? 0 : otherData.get(u);
+      }
+    }
+    return useIntCounts ? intCounts[offset] : counts[offset];
+  }
+
+  public int getGapCount()
+  {
+    return useIntCounts ? intCounts[0] : counts[0];
+  }
+
+  /**
+   * Answers true if this object wraps a counter for unexpected characters
+   * 
+   * @return
+   */
+  boolean isUsingOtherData()
+  {
+    return otherData != null;
+  }
+
+  /**
+   * Returns the character (or concatenated characters) for the symbol(s) with
+   * the given count in the profile. Can be used to get the modal residue by
+   * supplying the modal count value. Returns an empty string if no symbol has
+   * the given count. The symbols are in alphabetic order of standard peptide or
+   * nucleotide characters, followed by 'other' symbols if any.
+   * 
+   * @return
+   */
+  public String getResiduesForCount(int count)
+  {
+    if (count == 0)
+    {
+      return "";
+    }
+
+    /*
+     * find counts for the given value and append the
+     * corresponding symbol
+     */
+    StringBuilder modal = new StringBuilder();
+    if (useIntCounts)
+    {
+      for (int i = 1; i < intCounts.length; i++)
+      {
+        if (intCounts[i] == count)
+        {
+          modal.append(isNucleotide ? NUCS.charAt(i - 1) : AAS
+                  .charAt(i - 1));
+        }
+      }
+    }
+    else
+    {
+      for (int i = 1; i < counts.length; i++)
+      {
+        if (counts[i] == count)
+        {
+          modal.append(isNucleotide ? NUCS.charAt(i - 1) : AAS
+                  .charAt(i - 1));
+        }
+      }
+    }
+    if (otherData != null)
+    {
+      for (int i = 0; i < otherData.size(); i++)
+      {
+        if (otherData.valueAt(i) == count)
+        {
+          modal.append((char) otherData.keyAt(i));
+        }
+      }
+    }
+    return modal.toString();
+  }
+
+  /**
+   * Returns the highest count for any symbol(s) in the profile (excluding gap)
+   * 
+   * @return
+   */
+  public int getModalCount()
+  {
+    return maxCount;
+  }
+
+  /**
+   * Returns the number of distinct symbols with a non-zero count (excluding the
+   * gap symbol)
+   * 
+   * @return
+   */
+  public int size() {
+    int size = 0;
+    if (useIntCounts)
+    {
+      for (int i = 1; i < intCounts.length; i++)
+      {
+        if (intCounts[i] > 0)
+        {
+          size++;
+        }
+      }
+    }
+    else
+    {
+      for (int i = 1; i < counts.length; i++)
+      {
+        if (counts[i] > 0)
+        {
+          size++;
+        }
+      }
+    }
+
+    /*
+     * include 'other' characters recorded (even if count is zero
+     * though that would be a strange use case)
+     */
+    if (otherData != null)
+    {
+      size += otherData.size();
+    }
+
+    return size;
+  }
+
+  /**
+   * Returns a data bean holding those symbols that have a non-zero count
+   * (excluding the gap symbol), with their counts.
+   * 
+   * @return
+   */
+  public SymbolCounts getSymbolCounts()
+  {
+    int size = size();
+    char[] symbols = new char[size];
+    int[] values = new int[size];
+    int j = 0;
+
+    if (useIntCounts)
+    {
+      for (int i = 1; i < intCounts.length; i++)
+      {
+        if (intCounts[i] > 0)
+        {
+          char symbol = isNucleotide ? NUCS.charAt(i - 1) : AAS
+                  .charAt(i - 1);
+          symbols[j] = symbol;
+          values[j] = intCounts[i];
+          j++;
+        }
+      }
+    }
+    else
+    {
+      for (int i = 1; i < counts.length; i++)
+      {
+        if (counts[i] > 0)
+        {
+          char symbol = isNucleotide ? NUCS.charAt(i - 1) : AAS
+                  .charAt(i - 1);
+          symbols[j] = symbol;
+          values[j] = counts[i];
+          j++;
+        }
+      }
+    }
+    if (otherData != null)
+    {
+      for (int i = 0; i < otherData.size(); i++)
+      {
+        symbols[j] = (char) otherData.keyAt(i);
+        values[j] = otherData.valueAt(i);
+        j++;
+      }
+    }
+
+    return new SymbolCounts(symbols, values);
+  }
+
+  /**
+   * Returns a tooltip string showing residues in descending order of their
+   * percentage frequency in the profile
+   * 
+   * @param normaliseBy
+   *          the divisor for residue counts (may or may not include gapped
+   *          sequence count)
+   * @param percentageDecPl
+   *          the number of decimal places to show in percentages
+   * @return
+   */
+  public String getTooltip(int normaliseBy, int percentageDecPl)
+  {
+    SymbolCounts symbolCounts = getSymbolCounts();
+    char[] ca = symbolCounts.symbols;
+    int[] vl = symbolCounts.values;
+
+    /*
+     * sort characters into ascending order of their counts
+     */
+    QuickSort.sort(vl, ca);
+
+    /*
+     * traverse in reverse order (highest count first) to build tooltip
+     */
+    boolean first = true;
+    StringBuilder sb = new StringBuilder(64);
+    for (int c = ca.length - 1; c >= 0; c--)
+    {
+      final char residue = ca[c];
+      // TODO combine residues which share a percentage
+      // (see AAFrequency.completeCdnaConsensus)
+      float tval = (vl[c] * 100f) / normaliseBy;
+      sb.append(first ? "" : "; ").append(residue).append(" ");
+      Format.appendPercentage(sb, tval, percentageDecPl);
+      sb.append("%");
+      first = false;
+    }
+    return sb.toString();
+  }
+
+  /**
+   * Returns a string representation of the symbol counts, for debug purposes.
+   */
+  @Override
+  public String toString()
+  {
+    StringBuilder sb = new StringBuilder();
+    sb.append("[ ");
+    SymbolCounts sc = getSymbolCounts();
+    for (int i = 0; i < sc.symbols.length; i++)
+    {
+      sb.append(sc.symbols[i]).append(":").append(sc.values[i]).append(" ");
+    }
+    sb.append("]");
+    return sb.toString();
+  }
+}
diff --git a/src/jalview/datamodel/SearchResultMatchI.java b/src/jalview/datamodel/SearchResultMatchI.java
new file mode 100644 (file)
index 0000000..a47ca8b
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * 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.datamodel;
+
+/**
+ * An interface that describes one matched region of an alignment, as one
+ * contiguous portion of a single dataset sequence
+ */
+public interface SearchResultMatchI
+{
+  /**
+   * Returns the matched sequence
+   * 
+   * @return
+   */
+  SequenceI getSequence();
+
+  /**
+   * Returns the start position of the match in the sequence (base 1)
+   * 
+   * @return
+   */
+  int getStart();
+
+  /**
+   * Returns the end position of the match in the sequence (base 1)
+   * 
+   * @return
+   */
+  int getEnd();
+
+}
\ No newline at end of file
index b9db461..1bf5475 100755 (executable)
 package jalview.datamodel;
 
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.BitSet;
 import java.util.List;
 
 /**
  * Holds a list of search result matches, where each match is a contiguous
  * stretch of a single sequence.
  * 
- * @author gmcarstairs
+ * @author gmcarstairs amwaterhouse
  *
  */
-public class SearchResults
+public class SearchResults implements SearchResultsI
 {
 
-  private List<Match> matches = new ArrayList<Match>();
+  private List<SearchResultMatchI> matches = new ArrayList<SearchResultMatchI>();
 
   /**
    * One match consists of a sequence reference, start and end positions.
    * Discontiguous ranges in a sequence require two or more Match objects.
    */
-  public class Match
+  public class Match implements SearchResultMatchI
   {
     SequenceI sequence;
 
@@ -55,7 +55,10 @@ public class SearchResults
     int end;
 
     /**
-     * Constructor
+     * create a Match on a range of sequence. Match always holds region in
+     * forwards order, even if given in reverse order (such as from a mapping to
+     * a reverse strand); this avoids trouble for routines that highlight search
+     * results etc
      * 
      * @param seq
      *          a sequence
@@ -80,48 +83,54 @@ public class SearchResults
       }
       else
       {
+        // TODO: JBP could mark match as being specified in reverse direction
+        // for use
+        // by caller ? e.g. visualizing reverse strand highlight
         this.start = end;
         this.end = start;
       }
     }
 
+    /* (non-Javadoc)
+     * @see jalview.datamodel.SearchResultMatchI#getSequence()
+     */
+    @Override
     public SequenceI getSequence()
     {
       return sequence;
     }
 
+    /* (non-Javadoc)
+     * @see jalview.datamodel.SearchResultMatchI#getStart()
+     */
+    @Override
     public int getStart()
     {
       return start;
     }
 
+    /* (non-Javadoc)
+     * @see jalview.datamodel.SearchResultMatchI#getEnd()
+     */
+    @Override
     public int getEnd()
     {
       return end;
     }
 
     /**
-     * Returns the string of characters in the matched region, prefixed by the
-     * start position, e.g. "12CGT" or "208K"
+     * Returns a representation as "seqid/start-end"
      */
     @Override
     public String toString()
     {
-      final int from = Math.max(start - 1, 0);
-      String startPosition = String.valueOf(from);
-      return startPosition + getCharacters();
-    }
-
-    /**
-     * Returns the string of characters in the matched region.
-     */
-    public String getCharacters()
-    {
-      char[] chars = sequence.getSequence();
-      // convert start/end to base 0 (with bounds check)
-      final int from = Math.max(start - 1, 0);
-      final int to = Math.min(end, chars.length + 1);
-      return String.valueOf(Arrays.copyOfRange(chars, from, to));
+      StringBuilder sb = new StringBuilder();
+      if (sequence != null)
+      {
+        sb.append(sequence.getName()).append("/");
+      }
+      sb.append(start).append("-").append(end);
+      return sb.toString();
     }
 
     public void setSequence(SequenceI seq)
@@ -150,46 +159,38 @@ public class SearchResults
     @Override
     public boolean equals(Object obj)
     {
-      if (obj == null || !(obj instanceof Match))
+      if (obj == null || !(obj instanceof SearchResultMatchI))
       {
         return false;
       }
-      Match m = (Match) obj;
-      return (this.sequence == m.sequence && this.start == m.start && this.end == m.end);
+      SearchResultMatchI m = (SearchResultMatchI) obj;
+      return (sequence == m.getSequence() && start == m.getStart() && end == m
+              .getEnd());
     }
   }
 
-  /**
-   * This method replaces the old search results which merely held an alignment
-   * index of search matches. This broke when sequences were moved around the
-   * alignment
-   * 
-   * @param seq
-   *          Sequence
-   * @param start
-   *          int
-   * @param end
-   *          int
+  /* (non-Javadoc)
+   * @see jalview.datamodel.SearchResultsI#addResult(jalview.datamodel.SequenceI, int, int)
    */
-  public void addResult(SequenceI seq, int start, int end)
+  @Override
+  public SearchResultMatchI addResult(SequenceI seq, int start, int end)
   {
-    matches.add(new Match(seq, start, end));
+    Match m = new Match(seq, start, end);
+    matches.add(m);
+    return m;
   }
 
-  /**
-   * Quickly check if the given sequence is referred to in the search results
-   * 
-   * @param sequence
-   *          (specific alignment sequence or a dataset sequence)
-   * @return true if the results involve sequence
+  /* (non-Javadoc)
+   * @see jalview.datamodel.SearchResultsI#involvesSequence(jalview.datamodel.SequenceI)
    */
+  @Override
   public boolean involvesSequence(SequenceI sequence)
   {
     SequenceI ds = sequence.getDatasetSequence();
-    for (Match m : matches)
+    for (SearchResultMatchI _m : matches)
     {
-      if (m.sequence != null
-              && (m.sequence == sequence || m.sequence == ds))
+      SequenceI matched = _m.getSequence();
+      if (matched != null && (matched == sequence || matched == ds))
       {
         return true;
       }
@@ -197,11 +198,10 @@ public class SearchResults
     return false;
   }
 
-  /**
-   * This Method returns the search matches which lie between the start and end
-   * points of the sequence in question. It is optimised for returning objects
-   * for drawing on SequenceCanvas
+  /* (non-Javadoc)
+   * @see jalview.datamodel.SearchResultsI#getResults(jalview.datamodel.SequenceI, int, int)
    */
+  @Override
   public int[] getResults(SequenceI sequence, int start, int end)
   {
     if (matches.isEmpty())
@@ -213,8 +213,11 @@ public class SearchResults
     int[] tmp = null;
     int resultLength, matchStart = 0, matchEnd = 0;
     boolean mfound;
-    for (Match m : matches)
+    Match m;
+    for (SearchResultMatchI _m : matches)
     {
+      m = (Match) _m;
+
       mfound = false;
       if (m.sequence == sequence)
       {
@@ -269,97 +272,76 @@ public class SearchResults
     return result;
   }
 
-  public int getSize()
-  {
-    return matches.size();
-  }
-
-  public SequenceI getResultSequence(int index)
-  {
-    return matches.get(index).sequence;
-  }
-
-  /**
-   * Returns the start position of the i'th match in the search results.
-   * 
-   * @param i
-   * @return
-   */
-  public int getResultStart(int i)
+  @Override
+  public int markColumns(SequenceCollectionI sqcol, BitSet bs)
   {
-    return matches.get(i).start;
+    int count = 0;
+    BitSet mask = new BitSet();
+    for (SequenceI s : sqcol.getSequences())
+    {
+      int[] cols = getResults(s, sqcol.getStartRes(), sqcol.getEndRes());
+      if (cols != null)
+      {
+        for (int pair = 0; pair < cols.length; pair += 2)
+        {
+          mask.set(cols[pair], cols[pair + 1] + 1);
+        }
+      }
+    }
+    // compute columns that were newly selected
+    BitSet original = (BitSet) bs.clone();
+    original.and(mask);
+    count = mask.cardinality() - original.cardinality();
+    // and mark ranges not already marked
+    bs.or(mask);
+    return count;
   }
 
-  /**
-   * Returns the end position of the i'th match in the search results.
-   * 
-   * @param i
-   * @return
+  /* (non-Javadoc)
+   * @see jalview.datamodel.SearchResultsI#getSize()
    */
-  public int getResultEnd(int i)
+  @Override
+  public int getSize()
   {
-    return matches.get(i).end;
+    return matches.size();
   }
 
-  /**
-   * Returns true if no search result matches are held.
-   * 
-   * @return
+  /* (non-Javadoc)
+   * @see jalview.datamodel.SearchResultsI#isEmpty()
    */
+  @Override
   public boolean isEmpty()
   {
     return matches.isEmpty();
   }
 
-  /**
-   * Returns the list of matches.
-   * 
-   * @return
+  /* (non-Javadoc)
+   * @see jalview.datamodel.SearchResultsI#getResults()
    */
-  public List<Match> getResults()
+  @Override
+  public List<SearchResultMatchI> getResults()
   {
     return matches;
   }
 
   /**
-   * Return the results as a string of characters (bases) prefixed by start
-   * position(s). Meant for use when the context ensures that all matches are to
-   * regions of the same sequence (otherwise the result is meaningless).
+   * Return the results as a list of matches [seq1/from-to, seq2/from-to, ...]
    * 
    * @return
    */
   @Override
   public String toString()
   {
-    StringBuilder result = new StringBuilder(256);
-    for (Match m : matches)
-    {
-      result.append(m.toString());
-    }
-    return result.toString();
-  }
-
-  /**
-   * Return the results as a string of characters (bases). Meant for use when
-   * the context ensures that all matches are to regions of the same sequence
-   * (otherwise the result is meaningless).
-   * 
-   * @return
-   */
-  public String getCharacters()
-  {
-    StringBuilder result = new StringBuilder(256);
-    for (Match m : matches)
-    {
-      result.append(m.getCharacters());
-    }
-    return result.toString();
+    return matches == null ? "" : matches.toString();
   }
 
   /**
-   * Hashcode is has derived from the list of matches. This ensures that when
-   * two SearchResults objects satisfy the test for equals(), then they have the
+   * Hashcode is derived from the list of matches. This ensures that when two
+   * SearchResults objects satisfy the test for equals(), then they have the
    * same hashcode.
+   * 
+   * @see Match#hashCode()
+   * @see java.util.AbstractList#hashCode()
    */
   @Override
   public int hashCode()
@@ -374,11 +356,11 @@ public class SearchResults
   @Override
   public boolean equals(Object obj)
   {
-    if (obj == null || !(obj instanceof SearchResults))
+    if (obj == null || !(obj instanceof SearchResultsI))
     {
       return false;
     }
-    SearchResults sr = (SearchResults) obj;
-    return ((ArrayList<Match>) this.matches).equals(sr.matches);
+    SearchResultsI sr = (SearchResultsI) obj;
+    return matches.equals(sr.getResults());
   }
 }
diff --git a/src/jalview/datamodel/SearchResultsI.java b/src/jalview/datamodel/SearchResultsI.java
new file mode 100644 (file)
index 0000000..52a0467
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * 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.datamodel;
+
+import java.util.BitSet;
+import java.util.List;
+
+/**
+ * An interface describing the result of a search or other operation which
+ * highlights matched regions of an alignment
+ */
+public interface SearchResultsI
+{
+
+  /**
+   * Adds one region to the results
+   * 
+   * @param seq
+   *          Sequence
+   * @param start
+   *          int
+   * @param end
+   *          int
+   * @return
+   */
+  SearchResultMatchI addResult(SequenceI seq, int start, int end);
+
+  /**
+   * Answers true if the search results include the given sequence (or its
+   * dataset sequence), else false
+   * 
+   * @param sequence
+   * @return
+   */
+  boolean involvesSequence(SequenceI sequence);
+
+  /**
+   * Returns an array of [from, to, from, to..] matched columns (base 0) between
+   * the given start and end columns of the given sequence. Returns null if no
+   * matches overlap the specified region.
+   * <p>
+   * Implementations should provide an optimised method to return locations to
+   * highlight on a visible portion of an alignment.
+   * 
+   * @param sequence
+   * @param start
+   *          first column of range (base 0, inclusive)
+   * @param end
+   *          last column of range base 0, inclusive)
+   * @return int[]
+   */
+  int[] getResults(SequenceI sequence, int start, int end);
+
+  /**
+   * Returns the number of matches found
+   * 
+   * @return
+   */
+  int getSize();
+
+  /**
+   * Returns true if no search result matches are held.
+   * 
+   * @return
+   */
+  boolean isEmpty();
+
+  /**
+   * Returns the list of matches.
+   * 
+   * @return
+   */
+  List<SearchResultMatchI> getResults();
+
+  /**
+   * Set bits in a bitfield for all columns in the given sequence collection
+   * that are highlighted
+   * 
+   * @param sqcol
+   *          the set of sequences to search for highlighted regions
+   * @param bs
+   *          bitset to set
+   * @return number of bits set
+   */
+  int markColumns(SequenceCollectionI sqcol, BitSet bs);
+}
\ No newline at end of file
index c75d6f2..15f54b9 100755 (executable)
@@ -208,7 +208,9 @@ public class SequenceFeature
     }
 
     SequenceFeature sf = (SequenceFeature) o;
-    if (begin != sf.begin || end != sf.end || score != sf.score)
+    boolean sameScore = Float.isNaN(score) ? Float.isNaN(sf.score)
+            : score == sf.score;
+    if (begin != sf.begin || end != sf.end || !sameScore)
     {
       return false;
     }
@@ -530,4 +532,20 @@ public class SequenceFeature
     return s.hashCode() + getBegin() + getEnd() + (int) getScore()
             + getStrand();
   }
+
+  /**
+   * Answers true if the feature's start/end values represent two related
+   * positions, rather than ends of a range. Such features may be visualised or
+   * reported differently to features on a range.
+   */
+  public boolean isContactFeature()
+  {
+    // TODO abstract one day to a FeatureType class
+    if ("disulfide bond".equalsIgnoreCase(type)
+            || "disulphide bond".equalsIgnoreCase(type))
+    {
+      return true;
+    }
+    return false;
+  }
 }
index 9a408e3..9245761 100755 (executable)
@@ -26,10 +26,8 @@ import jalview.schemes.ColourSchemeI;
 
 import java.awt.Color;
 import java.util.ArrayList;
-import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
-import java.util.Vector;
 
 /**
  * Collects a set contiguous ranges on a set of sequences
@@ -45,8 +43,6 @@ public class SequenceGroup implements AnnotatedCollectionI
 
   Conservation conserve;
 
-  Vector aaFrequency;
-
   boolean displayBoxes = true;
 
   boolean displayText = true;
@@ -531,7 +527,7 @@ public class SequenceGroup implements AnnotatedCollectionI
     boolean upd = false;
     try
     {
-      Hashtable cnsns[] = AAFrequency.calculate(sequences, startRes,
+      ProfilesI cnsns = AAFrequency.calculate(sequences, startRes,
               endRes + 1, showSequenceLogo);
       if (consensus != null)
       {
@@ -547,8 +543,8 @@ public class SequenceGroup implements AnnotatedCollectionI
       if ((conservation != null)
               || (cs != null && cs.conservationApplied()))
       {
-        Conservation c = new Conservation(groupName, 3, sequences,
-                startRes, endRes + 1);
+        Conservation c = new Conservation(groupName, sequences, startRes,
+                endRes + 1);
         c.calculate();
         c.verdict(false, consPercGaps);
         if (conservation != null)
@@ -603,9 +599,9 @@ public class SequenceGroup implements AnnotatedCollectionI
     c.completeAnnotations(conservation, null, startRes, endRes + 1);
   }
 
-  public Hashtable[] consensusData = null;
+  public ProfilesI consensusData = null;
 
-  private void _updateConsensusRow(Hashtable[] cnsns, long nseq)
+  private void _updateConsensusRow(ProfilesI cnsns, long nseq)
   {
     if (consensus == null)
     {
diff --git a/src/jalview/ext/android/ContainerHelpers.java b/src/jalview/ext/android/ContainerHelpers.java
new file mode 100644 (file)
index 0000000..4033dcc
--- /dev/null
@@ -0,0 +1,108 @@
+package jalview.ext.android;
+
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Copied to Jalview September 2016.
+ * Only the members of this class required for SparseIntArray were copied.
+ * Method binarySearch(short[] array, int size, short value) added to support
+ * SparseShortArray.
+ */
+class ContainerHelpers
+{
+  static final boolean[] EMPTY_BOOLEANS = new boolean[0];
+
+  static final int[] EMPTY_INTS = new int[0];
+
+  static final long[] EMPTY_LONGS = new long[0];
+
+  static final Object[] EMPTY_OBJECTS = new Object[0];
+
+  // This is Arrays.binarySearch(), but doesn't do any argument validation.
+  static int binarySearch(int[] array, int size, int value)
+  {
+    int lo = 0;
+    int hi = size - 1;
+    while (lo <= hi)
+    {
+      final int mid = (lo + hi) >>> 1;
+      final int midVal = array[mid];
+      if (midVal < value)
+      {
+        lo = mid + 1;
+      }
+      else if (midVal > value)
+      {
+        hi = mid - 1;
+      }
+      else
+      {
+        return mid; // value found
+      }
+    }
+    return ~lo; // value not present
+  }
+
+  static int binarySearch(long[] array, int size, long value)
+  {
+    int lo = 0;
+    int hi = size - 1;
+    while (lo <= hi)
+    {
+      final int mid = (lo + hi) >>> 1;
+      final long midVal = array[mid];
+      if (midVal < value)
+      {
+        lo = mid + 1;
+      }
+      else if (midVal > value)
+      {
+        hi = mid - 1;
+      }
+      else
+      {
+        return mid; // value found
+      }
+    }
+    return ~lo; // value not present
+  }
+
+  // This is Arrays.binarySearch(), but doesn't do any argument validation.
+  static int binarySearch(short[] array, int size, short value)
+  {
+    int lo = 0;
+    int hi = size - 1;
+    while (lo <= hi)
+    {
+      final int mid = (lo + hi) >>> 1;
+      final short midVal = array[mid];
+      if (midVal < value)
+      {
+        lo = mid + 1;
+      }
+      else if (midVal > value)
+      {
+        hi = mid - 1;
+      }
+      else
+      {
+        return mid; // value found
+      }
+    }
+    return ~lo; // value not present
+  }
+}
diff --git a/src/jalview/ext/android/SparseIntArray.java b/src/jalview/ext/android/SparseIntArray.java
new file mode 100644 (file)
index 0000000..fcd4f1f
--- /dev/null
@@ -0,0 +1,432 @@
+package jalview.ext.android;
+
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * SparseIntArrays map integers to integers. Unlike a normal array of integers,
+ * there can be gaps in the indices. It is intended to be more memory efficient
+ * than using a HashMap to map Integers to Integers, both because it avoids
+ * auto-boxing keys and values and its data structure doesn't rely on an extra
+ * entry object for each mapping.
+ *
+ * <p>
+ * Note that this container keeps its mappings in an array data structure, using
+ * a binary search to find keys. The implementation is not intended to be
+ * appropriate for data structures that may contain large numbers of items. It
+ * is generally slower than a traditional HashMap, since lookups require a
+ * binary search and adds and removes require inserting and deleting entries in
+ * the array. For containers holding up to hundreds of items, the performance
+ * difference is not significant, less than 50%.
+ * </p>
+ *
+ * <p>
+ * It is possible to iterate over the items in this container using
+ * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
+ * <code>keyAt(int)</code> with ascending values of the index will return the
+ * keys in ascending order, or the values corresponding to the keys in ascending
+ * order in the case of <code>valueAt(int)<code>.
+ * </p>
+ */
+
+/*
+ * Imported into Jalview September 2016
+ * Change log:
+ *   Sep 2016 method add(int, int) added for more efficient increment of counts
+ *            (a single binary search, rather than one on read and one on write)
+ */
+public class SparseIntArray implements Cloneable
+{
+  private int[] mKeys;
+
+  private int[] mValues;
+
+  private int mSize;
+
+  /**
+   * Creates a new SparseIntArray containing no mappings.
+   */
+  public SparseIntArray()
+  {
+    this(10);
+  }
+
+  /**
+   * Creates a new SparseIntArray containing no mappings that will not require
+   * any additional memory allocation to store the specified number of mappings.
+   * If you supply an initial capacity of 0, the sparse array will be
+   * initialized with a light-weight representation not requiring any additional
+   * array allocations.
+   */
+  public SparseIntArray(int initialCapacity)
+  {
+    if (initialCapacity == 0)
+    {
+      mKeys = ContainerHelpers.EMPTY_INTS;
+      mValues = ContainerHelpers.EMPTY_INTS;
+    }
+    else
+    {
+      initialCapacity = idealIntArraySize(initialCapacity);
+      mKeys = new int[initialCapacity];
+      mValues = new int[initialCapacity];
+    }
+    mSize = 0;
+  }
+
+  @Override
+  public SparseIntArray clone()
+  {
+    SparseIntArray clone = null;
+    try
+    {
+      clone = (SparseIntArray) super.clone();
+      clone.mKeys = mKeys.clone();
+      clone.mValues = mValues.clone();
+    } catch (CloneNotSupportedException cnse)
+    {
+      /* ignore */
+    }
+    return clone;
+  }
+
+  /**
+   * Gets the int mapped from the specified key, or <code>0</code> if no such
+   * mapping has been made.
+   */
+  public int get(int key)
+  {
+    return get(key, 0);
+  }
+
+  /**
+   * Gets the int mapped from the specified key, or the specified value if no
+   * such mapping has been made.
+   */
+  public int get(int key, int valueIfKeyNotFound)
+  {
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+    if (i < 0)
+    {
+      return valueIfKeyNotFound;
+    }
+    else
+    {
+      return mValues[i];
+    }
+  }
+
+  /**
+   * Removes the mapping from the specified key, if there was any.
+   */
+  public void delete(int key)
+  {
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+    if (i >= 0)
+    {
+      removeAt(i);
+    }
+  }
+
+  /**
+   * Removes the mapping at the given index.
+   */
+  public void removeAt(int index)
+  {
+    System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));
+    System.arraycopy(mValues, index + 1, mValues, index, mSize
+            - (index + 1));
+    mSize--;
+  }
+
+  /**
+   * Adds a mapping from the specified key to the specified value, replacing the
+   * previous mapping from the specified key if there was one.
+   */
+  public void put(int key, int value)
+  {
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+    if (i >= 0)
+    {
+      mValues[i] = value;
+    }
+    else
+    {
+      i = ~i;
+      if (mSize >= mKeys.length)
+      {
+        int n = idealIntArraySize(mSize + 1);
+        int[] nkeys = new int[n];
+        int[] nvalues = new int[n];
+        // Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n);
+        System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+        System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+        mKeys = nkeys;
+        mValues = nvalues;
+      }
+      if (mSize - i != 0)
+      {
+        // Log.e("SparseIntArray", "move " + (mSize - i));
+        System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+        System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+      }
+      mKeys[i] = key;
+      mValues[i] = value;
+      mSize++;
+    }
+  }
+
+  /**
+   * Returns the number of key-value mappings that this SparseIntArray currently
+   * stores.
+   */
+  public int size()
+  {
+    return mSize;
+  }
+
+  /**
+   * Given an index in the range <code>0...size()-1</code>, returns the key from
+   * the <code>index</code>th key-value mapping that this SparseIntArray stores.
+   *
+   * <p>
+   * The keys corresponding to indices in ascending order are guaranteed to be
+   * in ascending order, e.g., <code>keyAt(0)</code> will return the smallest
+   * key and <code>keyAt(size()-1)</code> will return the largest key.
+   * </p>
+   */
+  public int keyAt(int index)
+  {
+    return mKeys[index];
+  }
+
+  /**
+   * Given an index in the range <code>0...size()-1</code>, returns the value
+   * from the <code>index</code>th key-value mapping that this SparseIntArray
+   * stores.
+   *
+   * <p>
+   * The values corresponding to indices in ascending order are guaranteed to be
+   * associated with keys in ascending order, e.g., <code>valueAt(0)</code> will
+   * return the value associated with the smallest key and
+   * <code>valueAt(size()-1)</code> will return the value associated with the
+   * largest key.
+   * </p>
+   */
+  public int valueAt(int index)
+  {
+    return mValues[index];
+  }
+
+  /**
+   * Returns the index for which {@link #keyAt} would return the specified key,
+   * or a negative number if the specified key is not mapped.
+   */
+  public int indexOfKey(int key)
+  {
+    return ContainerHelpers.binarySearch(mKeys, mSize, key);
+  }
+
+  /**
+   * Returns an index for which {@link #valueAt} would return the specified key,
+   * or a negative number if no keys map to the specified value. Beware that
+   * this is a linear search, unlike lookups by key, and that multiple keys can
+   * map to the same value and this will find only one of them.
+   */
+  public int indexOfValue(int value)
+  {
+    for (int i = 0; i < mSize; i++)
+    {
+      if (mValues[i] == value)
+      {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * Removes all key-value mappings from this SparseIntArray.
+   */
+  public void clear()
+  {
+    mSize = 0;
+  }
+
+  /**
+   * Puts a key/value pair into the array, optimizing for the case where the key
+   * is greater than all existing keys in the array.
+   */
+  public void append(int key, int value)
+  {
+    if (mSize != 0 && key <= mKeys[mSize - 1])
+    {
+      put(key, value);
+      return;
+    }
+    int pos = mSize;
+    if (pos >= mKeys.length)
+    {
+      int n = idealIntArraySize(pos + 1);
+      int[] nkeys = new int[n];
+      int[] nvalues = new int[n];
+      // Log.e("SparseIntArray", "grow " + mKeys.length + " to " + n);
+      System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+      System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+      mKeys = nkeys;
+      mValues = nvalues;
+    }
+    mKeys[pos] = key;
+    mValues[pos] = value;
+    mSize = pos + 1;
+  }
+
+  /**
+   * Inlined here by copying from com.android.internal.util.ArrayUtils
+   * 
+   * @param i
+   * @return
+   */
+  public static int idealIntArraySize(int need)
+  {
+    return idealByteArraySize(need * 4) / 4;
+  }
+
+  /**
+   * Inlined here by copying from com.android.internal.util.ArrayUtils
+   * 
+   * @param i
+   * @return
+   */
+  public static int idealByteArraySize(int need)
+  {
+    for (int i = 4; i < 32; i++)
+    {
+      if (need <= (1 << i) - 12)
+      {
+        return (1 << i) - 12;
+      }
+    }
+
+    return need;
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * <p>
+   * This implementation composes a string by iterating over its mappings.
+   */
+  @Override
+  public String toString()
+  {
+    if (size() <= 0)
+    {
+      return "{}";
+    }
+    StringBuilder buffer = new StringBuilder(mSize * 28);
+    buffer.append('{');
+    for (int i = 0; i < mSize; i++)
+    {
+      if (i > 0)
+      {
+        buffer.append(", ");
+      }
+      int key = keyAt(i);
+      buffer.append(key);
+      buffer.append('=');
+      int value = valueAt(i);
+      buffer.append(value);
+    }
+    buffer.append('}');
+    return buffer.toString();
+  }
+
+  /**
+   * Method (copied from put) added for Jalview to efficiently increment a key's
+   * value if present, else add it with the given value. This avoids a double
+   * binary search (once to get the value, again to put the updated value).
+   * 
+   * @param key
+   * @oparam toAdd
+   * @return the new value of the count for the key
+   * @throw ArithmeticException if the result would exceed the maximum value of
+   *        an int
+   */
+  public int add(int key, int toAdd)
+  {
+    int newValue = toAdd;
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, key);
+    if (i >= 0)
+    {
+      checkOverflow(mValues[i], toAdd);
+      mValues[i] += toAdd;
+      newValue = mValues[i];
+    }
+    else
+    {
+      i = ~i;
+      if (mSize >= mKeys.length)
+      {
+        int n = idealIntArraySize(mSize + 1);
+        int[] nkeys = new int[n];
+        int[] nvalues = new int[n];
+        System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+        System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+        mKeys = nkeys;
+        mValues = nvalues;
+      }
+      if (mSize - i != 0)
+      {
+        System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+        System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+      }
+      mKeys[i] = key;
+      mValues[i] = toAdd;
+      mSize++;
+    }
+    return newValue;
+  }
+
+  /**
+   * Throws ArithmeticException if adding addend to value would exceed the range
+   * of int
+   * 
+   * @param value
+   * @param addend
+   */
+  static void checkOverflow(int value, int addend)
+  {
+    /*
+     * test cases being careful to avoid overflow while testing!
+     */
+    if (addend > 0)
+    {
+      if (value > 0 && Integer.MAX_VALUE - value < addend)
+      {
+        throw new ArithmeticException("Integer overflow adding " + addend
+                + " to  " + value);
+      }
+    }
+    else if (addend < 0)
+    {
+      if (value < 0 && Integer.MIN_VALUE - value > addend)
+      {
+        throw new ArithmeticException("Integer underflow adding " + addend
+                + " to  " + value);
+      }
+    }
+  }
+}
diff --git a/src/jalview/ext/android/SparseShortArray.java b/src/jalview/ext/android/SparseShortArray.java
new file mode 100644 (file)
index 0000000..f961f55
--- /dev/null
@@ -0,0 +1,442 @@
+package jalview.ext.android;
+
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * SparseShortArrays map shorts to shorts. Unlike a normal array of shorts,
+ * there can be gaps in the indices. It is intended to be more memory efficient
+ * than using a HashMap to map Shorts to Shorts, both because it avoids
+ * auto-boxing keys and values and its data structure doesn't rely on an extra
+ * entry object for each mapping.
+ *
+ * <p>
+ * Note that this container keeps its mappings in an array data structure, using
+ * a binary search to find keys. The implementation is not intended to be
+ * appropriate for data structures that may contain large numbers of items. It
+ * is generally slower than a traditional HashMap, since lookups require a
+ * binary search and adds and removes require inserting and deleting entries in
+ * the array. For containers holding up to hundreds of items, the performance
+ * difference is not significant, less than 50%.
+ * </p>
+ *
+ * <p>
+ * It is possible to iterate over the items in this container using
+ * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using
+ * <code>keyAt(int)</code> with ascending values of the index will return the
+ * keys in ascending order, or the values corresponding to the keys in ascending
+ * order in the case of <code>valueAt(int)<code>.
+ * </p>
+ */
+
+/*
+ * Added to Jalview September 2016. A copy of SparseIntArray designed to store
+ * short values (to minimise space usage).
+ * <p>
+ * Note that operations append, put, add throw ArithmeticException if either the
+ * key or the resulting value overflows the range of a short. Calling code
+ * should trap and handle this, for example by switching to using a
+ * SparseIntArray instead.
+ */
+public class SparseShortArray implements Cloneable
+{
+  private short[] mKeys;
+
+  private short[] mValues;
+
+  private int mSize;
+
+  /**
+   * Creates a new SparseShortArray containing no mappings.
+   */
+  public SparseShortArray()
+  {
+    this(10);
+  }
+
+  /**
+   * Creates a new SparseShortArray containing no mappings that will not require
+   * any additional memory allocation to store the specified number of mappings.
+   * If you supply an initial capacity of 0, the sparse array will be
+   * initialized with a light-weight representation not requiring any additional
+   * array allocations.
+   */
+  public SparseShortArray(int initialCapacity)
+  {
+    if (initialCapacity == 0)
+    {
+      mKeys = new short[0];
+      mValues = new short[0];
+    }
+    else
+    {
+      initialCapacity = idealShortArraySize(initialCapacity);
+      mKeys = new short[initialCapacity];
+      mValues = new short[initialCapacity];
+    }
+    mSize = 0;
+  }
+
+  @Override
+  public SparseShortArray clone()
+  {
+    SparseShortArray clone = null;
+    try
+    {
+      clone = (SparseShortArray) super.clone();
+      clone.mKeys = mKeys.clone();
+      clone.mValues = mValues.clone();
+    } catch (CloneNotSupportedException cnse)
+    {
+      /* ignore */
+    }
+    return clone;
+  }
+
+  /**
+   * Gets the int mapped from the specified key, or <code>0</code> if no such
+   * mapping has been made.
+   */
+  public int get(int key)
+  {
+    return get(key, 0);
+  }
+
+  /**
+   * Gets the int mapped from the specified key, or the specified value if no
+   * such mapping has been made.
+   * 
+   * @throws ArithmeticException
+   *           if key is outside the range of a short value
+   */
+  public int get(int key, int valueIfKeyNotFound)
+  {
+    checkOverflow(key);
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, (short) key);
+    if (i < 0)
+    {
+      return valueIfKeyNotFound;
+    }
+    else
+    {
+      return mValues[i];
+    }
+  }
+
+  /**
+   * Removes the mapping from the specified key, if there was any.
+   * 
+   * @throws ArithmeticException
+   *           if key is outside the range of a short value
+   */
+  public void delete(int key)
+  {
+    checkOverflow(key);
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, (short) key);
+    if (i >= 0)
+    {
+      removeAt(i);
+    }
+  }
+
+  /**
+   * Removes the mapping at the given index.
+   */
+  public void removeAt(int index)
+  {
+    System.arraycopy(mKeys, index + 1, mKeys, index, mSize - (index + 1));
+    System.arraycopy(mValues, index + 1, mValues, index, mSize
+            - (index + 1));
+    mSize--;
+  }
+
+  /**
+   * Adds a mapping from the specified key to the specified value, replacing the
+   * previous mapping from the specified key if there was one.
+   * 
+   * @throws ArithmeticException
+   *           if either argument is outside the range of a short value
+   */
+  public void put(int key, int value)
+  {
+    checkOverflow(key);
+    checkOverflow(value);
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, (short) key);
+    if (i >= 0)
+    {
+      mValues[i] = (short) value;
+    }
+    else
+    {
+      i = ~i;
+      if (mSize >= mKeys.length)
+      {
+        int n = idealShortArraySize(mSize + 1);
+        short[] nkeys = new short[n];
+        short[] nvalues = new short[n];
+        // Log.e("SparseShortArray", "grow " + mKeys.length + " to " + n);
+        System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+        System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+        mKeys = nkeys;
+        mValues = nvalues;
+      }
+      if (mSize - i != 0)
+      {
+        // Log.e("SparseShortArray", "move " + (mSize - i));
+        System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+        System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+      }
+      mKeys[i] = (short) key;
+      mValues[i] = (short) value;
+      mSize++;
+    }
+  }
+
+  /**
+   * Returns the number of key-value mappings that this SparseShortArray
+   * currently stores.
+   */
+  public int size()
+  {
+    return mSize;
+  }
+
+  /**
+   * Given an index in the range <code>0...size()-1</code>, returns the key from
+   * the <code>index</code>th key-value mapping that this SparseShortArray
+   * stores.
+   *
+   * <p>
+   * The keys corresponding to indices in ascending order are guaranteed to be
+   * in ascending order, e.g., <code>keyAt(0)</code> will return the smallest
+   * key and <code>keyAt(size()-1)</code> will return the largest key.
+   * </p>
+   */
+  public short keyAt(int index)
+  {
+    return mKeys[index];
+  }
+
+  /**
+   * Given an index in the range <code>0...size()-1</code>, returns the value
+   * from the <code>index</code>th key-value mapping that this SparseShortArray
+   * stores.
+   *
+   * <p>
+   * The values corresponding to indices in ascending order are guaranteed to be
+   * associated with keys in ascending order, e.g., <code>valueAt(0)</code> will
+   * return the value associated with the smallest key and
+   * <code>valueAt(size()-1)</code> will return the value associated with the
+   * largest key.
+   * </p>
+   */
+  public short valueAt(int index)
+  {
+    return mValues[index];
+  }
+
+  /**
+   * Returns the index for which {@link #keyAt} would return the specified key,
+   * or a negative number if the specified key is not mapped.
+   * 
+   * @throws ArithmeticException
+   *           if key is outside the range of a short value
+   */
+  public int indexOfKey(int key)
+  {
+    checkOverflow(key);
+    return ContainerHelpers.binarySearch(mKeys, mSize, (short) key);
+  }
+
+  /**
+   * Returns an index for which {@link #valueAt} would return the specified key,
+   * or a negative number if no keys map to the specified value. Beware that
+   * this is a linear search, unlike lookups by key, and that multiple keys can
+   * map to the same value and this will find only one of them.
+   */
+  public int indexOfValue(int value)
+  {
+    for (int i = 0; i < mSize; i++)
+    {
+      if (mValues[i] == value)
+      {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * Removes all key-value mappings from this SparseShortArray.
+   */
+  public void clear()
+  {
+    mSize = 0;
+  }
+
+  /**
+   * Puts a key/value pair into the array, optimizing for the case where the key
+   * is greater than all existing keys in the array.
+   */
+  public void append(int key, int value)
+  {
+    if (mSize != 0 && key <= mKeys[mSize - 1])
+    {
+      put(key, value);
+      return;
+    }
+    int pos = mSize;
+    if (pos >= mKeys.length)
+    {
+      int n = idealShortArraySize(pos + 1);
+      short[] nkeys = new short[n];
+      short[] nvalues = new short[n];
+      // Log.e("SparseShortArray", "grow " + mKeys.length + " to " + n);
+      System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+      System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+      mKeys = nkeys;
+      mValues = nvalues;
+    }
+    checkOverflow(key);
+    checkOverflow(value);
+    mKeys[pos] = (short) key;
+    mValues[pos] = (short) value;
+    mSize = pos + 1;
+  }
+
+  /**
+   * Throws an exception if the value is outside the range of a short.
+   * 
+   * @param value
+   * @throws ArithmeticException
+   */
+  public static void checkOverflow(int value)
+  {
+    if (value > Short.MAX_VALUE || value < Short.MIN_VALUE)
+    {
+      throw new ArithmeticException(String.valueOf(value));
+    }
+  }
+
+  /**
+   * Inlined here by copying from com.android.internal.util.ArrayUtils
+   * 
+   * @param i
+   * @return
+   */
+  public static int idealShortArraySize(int need)
+  {
+    return idealByteArraySize(need * 2) / 2;
+  }
+
+  /**
+   * Inlined here by copying from com.android.internal.util.ArrayUtils
+   * 
+   * @param i
+   * @return
+   */
+  public static int idealByteArraySize(int need)
+  {
+    for (int i = 4; i < 32; i++)
+    {
+      if (need <= (1 << i) - 12)
+      {
+        return (1 << i) - 12;
+      }
+    }
+
+    return need;
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * <p>
+   * This implementation composes a string by iterating over its mappings.
+   */
+  @Override
+  public String toString()
+  {
+    if (size() <= 0)
+    {
+      return "{}";
+    }
+    StringBuilder buffer = new StringBuilder(mSize * 28);
+    buffer.append('{');
+    for (int i = 0; i < mSize; i++)
+    {
+      if (i > 0)
+      {
+        buffer.append(", ");
+      }
+      int key = keyAt(i);
+      buffer.append(key);
+      buffer.append('=');
+      int value = valueAt(i);
+      buffer.append(value);
+    }
+    buffer.append('}');
+    return buffer.toString();
+  }
+
+  /**
+   * Method (copied from put) added for Jalview to efficiently increment a key's
+   * value if present, else add it with the given value. This avoids a double
+   * binary search (once to get the value, again to put the updated value).
+   * 
+   * @param key
+   * @oparam toAdd
+   * @return the new value of the count for the key
+   * @throws ArithmeticException
+   *           if key, or result of adding toAdd, is outside the range of a
+   *           short value
+   */
+  public int add(int key, int toAdd)
+  {
+    int newValue = toAdd;
+    checkOverflow(key);
+    int i = ContainerHelpers.binarySearch(mKeys, mSize, (short) key);
+    if (i >= 0)
+    {
+      checkOverflow(toAdd + mValues[i]);
+      mValues[i] += (short) toAdd;
+      newValue = mValues[i];
+    }
+    else
+    {
+      checkOverflow(toAdd);
+      i = ~i;
+      if (mSize >= mKeys.length)
+      {
+        int n = idealShortArraySize(mSize + 1);
+        short[] nkeys = new short[n];
+        short[] nvalues = new short[n];
+        System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);
+        System.arraycopy(mValues, 0, nvalues, 0, mValues.length);
+        mKeys = nkeys;
+        mValues = nvalues;
+      }
+      if (mSize - i != 0)
+      {
+        System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);
+        System.arraycopy(mValues, i, mValues, i + 1, mSize - i);
+      }
+      mKeys[i] = (short) key;
+      mValues[i] = (short) toAdd;
+      mSize++;
+    }
+    return newValue;
+  }
+}
index fbac400..7a394f7 100644 (file)
@@ -49,8 +49,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Vector;
 
-import javajs.awt.Dimension;
-
 import org.jmol.adapter.smarter.SmarterJmolAdapter;
 import org.jmol.api.JmolAppConsoleInterface;
 import org.jmol.api.JmolSelectionListener;
@@ -74,7 +72,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
 
   Vector<String> atomsPicked = new Vector<String>();
 
-  public Vector<String> chainNames;
+  private List<String> chainNames;
 
   Hashtable<String, String> chainFile;
 
@@ -99,10 +97,10 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
   public Viewer viewer;
 
   public JalviewJmolBinding(StructureSelectionManager ssm,
-          PDBEntry[] pdbentry, SequenceI[][] sequenceIs, String[][] chains,
+          PDBEntry[] pdbentry, SequenceI[][] sequenceIs,
           String protocol)
   {
-    super(ssm, pdbentry, sequenceIs, chains, protocol);
+    super(ssm, pdbentry, sequenceIs, protocol);
     /*
      * viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter(),
      * "jalviewJmol", ap.av.applet .getDocumentBase(),
@@ -1083,7 +1081,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
     fileLoadingError = null;
     String[] oldmodels = modelFileNames;
     modelFileNames = null;
-    chainNames = new Vector<String>();
+    chainNames = new ArrayList<String>();
     chainFile = new Hashtable<String, String>();
     boolean notifyLoaded = false;
     String[] modelfilenames = getPdbFile();
@@ -1143,6 +1141,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
       for (int pe = 0; pe < getPdbCount(); pe++)
       {
         boolean matches = false;
+        addSequence(pe, getSequence()[pe]);
         if (fileName == null)
         {
           if (false)
@@ -1194,7 +1193,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
             String chid = new String(pdb.getId() + ":"
                     + pdb.getChains().elementAt(i).id);
             chainFile.put(chid, fileName);
-            chainNames.addElement(chid);
+            chainNames.add(chid);
           }
           notifyLoaded = true;
         }
@@ -1242,6 +1241,12 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
     setLoadingFromArchive(false);
   }
 
+  @Override
+  public List<String> getChainNames()
+  {
+    return chainNames;
+  }
+
   public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
   {
     notifyAtomPicked(iatom, strMeasure, null);
@@ -1404,7 +1409,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
   }
 
   @Override
-  public Dimension resizeInnerPanel(String data)
+  public int[] resizeInnerPanel(String data)
   {
     // Jalview doesn't honour resize panel requests
     return null;
index b2ba256..180da8f 100644 (file)
@@ -38,8 +38,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Vector;
 
-import javajs.awt.Dimension;
-
 import org.jmol.api.JmolStatusListener;
 import org.jmol.api.JmolViewer;
 import org.jmol.c.CBK;
@@ -626,7 +624,7 @@ public class JmolParser extends StructureFile implements JmolStatusListener
    * Not implemented - returns null
    */
   @Override
-  public Dimension resizeInnerPanel(String data)
+  public int[] resizeInnerPanel(String data)
   {
     return null;
   }
index 7ba9186..4a9bf5f 100644 (file)
@@ -40,6 +40,7 @@ import jalview.util.MessageManager;
 import java.awt.Color;
 import java.net.BindException;
 import java.util.ArrayList;
+import java.util.Hashtable;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -63,6 +64,9 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
 
   private static final String ALPHACARBON = "CA";
 
+  private List<String> chainNames = new ArrayList<String>();
+
+  private Hashtable<String, String> chainFile = new Hashtable<String, String>();
   /*
    * Object through which we talk to Chimera
    */
@@ -191,10 +195,9 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
    * @param protocol
    */
   public JalviewChimeraBinding(StructureSelectionManager ssm,
-          PDBEntry[] pdbentry, SequenceI[][] sequenceIs, String[][] chains,
-          String protocol)
+          PDBEntry[] pdbentry, SequenceI[][] sequenceIs, String protocol)
   {
-    super(ssm, pdbentry, sequenceIs, chains, protocol);
+    super(ssm, pdbentry, sequenceIs, protocol);
     viewer = new ChimeraManager(
             new ext.edu.ucsf.rbvi.strucviz2.StructureManager(true));
   }
@@ -244,11 +247,14 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     boolean first = true;
     for (String chain : toshow)
     {
+      int modelNumber = getModelNoForChain(chain);
+      String showChainCmd = modelNumber == -1 ? "" : modelNumber + ":."
+              + chain.split(":")[1];
       if (!first)
       {
         cmd.append(",");
       }
-      cmd.append(":.").append(chain);
+      cmd.append(showChainCmd);
       first = false;
     }
 
@@ -257,7 +263,7 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
      * window, but it looks more helpful not to (easier to relate chains to the
      * whole)
      */
-    final String command = "~display #*; ~ribbon #*; ribbon "
+    final String command = "~display #*; ~ribbon #*; ribbon :"
             + cmd.toString();
     sendChimeraCommand(command, false);
   }
@@ -758,18 +764,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
     {
       return new String[0];
     }
-    // if (modelFileNames == null)
-    // {
-    // Collection<ChimeraModel> chimodels = viewer.getChimeraModels();
-    // _modelFileNameMap = new int[chimodels.size()];
-    // int j = 0;
-    // for (ChimeraModel chimodel : chimodels)
-    // {
-    // String mdlName = chimodel.getModelName();
-    // }
-    // modelFileNames = new String[j];
-    // // System.arraycopy(mset, 0, modelFileNames, 0, j);
-    // }
 
     return chimeraMaps.keySet().toArray(
             modelFileNames = new String[chimeraMaps.size()]);
@@ -1067,28 +1061,6 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
    * 
    * @return
    */
-  public List<String> getChainNames()
-  {
-    List<String> names = new ArrayList<String>();
-    String[][] allNames = getChains();
-    if (allNames != null)
-    {
-      for (String[] chainsForPdb : allNames)
-      {
-        if (chainsForPdb != null)
-        {
-          for (String chain : chainsForPdb)
-          {
-            if (chain != null && !names.contains(chain))
-            {
-              names.add(chain);
-            }
-          }
-        }
-      }
-    }
-    return names;
-  }
 
   /**
    * Send a 'focus' command to Chimera to recentre the visible display
@@ -1125,4 +1097,31 @@ public abstract class JalviewChimeraBinding extends AAStructureBindingModel
       sm.highlightStructure(this, seq, positions);
     }
   }
+
+
+  @Override
+  public List<String> getChainNames()
+  {
+    return chainNames;
+  }
+
+  public Hashtable<String, String> getChainFile()
+  {
+    return chainFile;
+  }
+
+  public List<ChimeraModel> getChimeraModelByChain(String chain)
+  {
+    return chimeraMaps.get(chainFile.get(chain));
+  }
+
+  public int getModelNoForChain(String chain)
+  {
+    List<ChimeraModel> foundModels = getChimeraModelByChain(chain);
+    if (foundModels != null && !foundModels.isEmpty())
+    {
+      return foundModels.get(0).getModelNumber();
+    }
+    return -1;
+  }
 }
index 63620e5..6a637e3 100644 (file)
@@ -71,6 +71,7 @@ import jalview.io.JalviewFileChooser;
 import jalview.io.JalviewFileView;
 import jalview.io.JnetAnnotationMaker;
 import jalview.io.NewickFile;
+import jalview.io.StructureFile;
 import jalview.io.TCoffeeScoreFile;
 import jalview.jbgui.GAlignFrame;
 import jalview.schemes.Blosum62ColourScheme;
@@ -669,6 +670,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           toggleHiddenRegions(toggleSeqs, toggleCols);
           break;
         }
+        case KeyEvent.VK_B:
+        {
+          boolean toggleSel = evt.isControlDown() || evt.isMetaDown();
+          boolean modifyExisting = true; // always modify, don't clear
+                                         // evt.isShiftDown();
+          boolean invertHighlighted = evt.isAltDown();
+          avc.markHighlightedColumns(invertHighlighted, modifyExisting,
+                  toggleSel);
+          break;
+        }
         case KeyEvent.VK_PAGE_UP:
           if (viewport.getWrapAlignment())
           {
@@ -1340,14 +1351,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   protected void htmlMenuItem_actionPerformed(ActionEvent e)
   {
-    new HtmlSvgOutput(null, alignPanel);
+    HtmlSvgOutput htmlSVG = new HtmlSvgOutput(alignPanel);
+    htmlSVG.exportHTML(null);
   }
 
   @Override
   public void bioJSMenuItem_actionPerformed(ActionEvent e)
   {
-    BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel, this);
-    bjs.exportJalviewAlignmentAsBioJsHtmlFile();
+    BioJsHTMLOutput bjs = new BioJsHTMLOutput(alignPanel);
+    bjs.exportHTML(null);
   }
 
   public void createImageMap(File file, String image)
@@ -2907,8 +2919,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     viewport.setFollowHighlight(state);
     if (state)
     {
-      alignPanel.scrollToPosition(
-              alignPanel.getSeqPanel().seqCanvas.searchResults, false);
+      alignPanel.scrollToPosition(viewport.getSearchResults(), false);
     }
   }
 
@@ -4885,7 +4896,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               }
               if (type != null)
               {
-                if (type.equalsIgnoreCase("PDB"))
+                if (StructureFile.isStructureFile(type))
                 {
                   filesmatched.add(new Object[] { file, protocol, mtch });
                   continue;
@@ -4905,14 +4916,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                                   this,
                                   MessageManager
                                           .formatMessage(
-                                                  "label.automatically_associate_pdb_files_with_sequences_same_name",
+                                                  "label.automatically_associate_structure_files_with_sequences_same_name",
                                                   new Object[] { Integer
                                                           .valueOf(
                                                                   filesmatched
                                                                           .size())
                                                           .toString() }),
                                   MessageManager
-                                          .getString("label.automatically_associate_pdb_files_by_name"),
+                                          .getString("label.automatically_associate_structure_files_by_name"),
                                   JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)
 
           {
@@ -5930,6 +5941,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
     return false;
   }
+
+  @Override
+  protected void selectHighlightedColumns_actionPerformed(
+          ActionEvent actionEvent)
+  {
+    // include key modifier check in case user selects from menu
+    avc.markHighlightedColumns(
+            (actionEvent.getModifiers() & ActionEvent.ALT_MASK) != 0,
+            true,
+            (actionEvent.getModifiers() & (ActionEvent.META_MASK | ActionEvent.CTRL_MASK)) != 0);
+  }
 }
 
 class PrintThread extends Thread
index d0a0f11..03aee5d 100644 (file)
@@ -37,6 +37,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
@@ -1042,7 +1043,7 @@ public class AlignViewport extends AlignmentViewport implements
      * there is no complement, or it is not following highlights, or no mapping
      * is found, the result will be empty.
      */
-    SearchResults sr = new SearchResults();
+    SearchResultsI sr = new SearchResults();
     int verticalOffset = findComplementScrollTarget(sr);
     if (!sr.isEmpty())
     {
index 4db029c..e61b042 100644 (file)
@@ -25,7 +25,7 @@ import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
 import jalview.bin.Cache;
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
@@ -297,7 +297,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * Highlight the given results on the alignment.
    * 
    */
-  public void highlightSearchResults(SearchResults results)
+  public void highlightSearchResults(SearchResultsI results)
   {
     scrollToPosition(results);
     getSeqPanel().seqCanvas.highlightSearchResults(results);
@@ -309,7 +309,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * 
    * @param results
    */
-  public boolean scrollToPosition(SearchResults results)
+  public boolean scrollToPosition(SearchResultsI results)
   {
     return scrollToPosition(results, 0, true, false);
   }
@@ -322,7 +322,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * @param redrawOverview
    * @return
    */
-  public boolean scrollToPosition(SearchResults searchResults,
+  public boolean scrollToPosition(SearchResultsI searchResults,
           boolean redrawOverview)
   {
     return scrollToPosition(searchResults, 0, redrawOverview, false);
@@ -342,7 +342,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
    *          if true, try to centre the search results horizontally in the view
    * @return false if results were not found
    */
-  public boolean scrollToPosition(SearchResults results,
+  public boolean scrollToPosition(SearchResultsI results,
           int verticalOffset, boolean redrawOverview, boolean centre)
   {
     int startv, endv, starts, ends;
@@ -956,11 +956,11 @@ public class AlignmentPanel extends GAlignmentPanel implements
 
     if (av.getWrapAlignment())
     {
-      return printWrappedAlignment(pg, pwidth, pheight, pi);
+      return printWrappedAlignment(pwidth, pheight, pi, pg);
     }
     else
     {
-      return printUnwrapped(pg, pwidth, pheight, pi);
+      return printUnwrapped(pwidth, pheight, pi, pg, pg);
     }
   }
 
@@ -981,84 +981,103 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * @throws PrinterException
    *           DOCUMENT ME!
    */
-  public int printUnwrapped(Graphics pg, int pwidth, int pheight, int pi)
+  /**
+   * Draws the alignment image, including sequence ids, sequences, and
+   * annotation labels and annotations if shown, on either one or two Graphics
+   * context.
+   * 
+   * @param pageWidth
+   * @param pageHeight
+   * @param pi
+   * @param idGraphics
+   *          the graphics context for sequence ids and annotation labels
+   * @param alignmentGraphics
+   *          the graphics context for sequences and annotations (may or may not
+   *          be the same context as idGraphics)
+   * @return
+   * @throws PrinterException
+   */
+  public int printUnwrapped(int pageWidth, int pageHeight, int pi,
+          Graphics idGraphics, Graphics alignmentGraphics)
           throws PrinterException
   {
-    int idWidth = getVisibleIdWidth(false);
-    FontMetrics fm = getFontMetrics(av.getFont());
-    int scaleHeight = av.getCharHeight() + fm.getDescent();
+    final int idWidth = getVisibleIdWidth(false);
 
-    pg.setColor(Color.white);
-    pg.fillRect(0, 0, pwidth, pheight);
-    pg.setFont(av.getFont());
-
-    // //////////////////////////////////
-    // / How many sequences and residues can we fit on a printable page?
-    int totalRes = (pwidth - idWidth) / av.getCharWidth();
+    /*
+     * Get the horizontal offset to where we draw the sequences.
+     * This is idWidth if using a single Graphics context, else zero.
+     */
+    final int alignmentGraphicsOffset = idGraphics != alignmentGraphics ? 0 : idWidth;
 
-    int totalSeq = (pheight - scaleHeight) / av.getCharHeight() - 1;
+    FontMetrics fm = getFontMetrics(av.getFont());
+    int charHeight = av.getCharHeight();
+    int scaleHeight = charHeight + fm.getDescent();
 
-    int pagesWide = (av.getAlignment().getWidth() / totalRes) + 1;
+    idGraphics.setColor(Color.white);
+    idGraphics.fillRect(0, 0, pageWidth, pageHeight);
+    idGraphics.setFont(av.getFont());
 
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int startRes;
+    /*
+     * How many sequences and residues can we fit on a printable page?
+     */
+    int totalRes = (pageWidth - idWidth) / av.getCharWidth();
 
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int endRes;
+    int totalSeq = (pageHeight - scaleHeight) / charHeight - 1;
 
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int startSeq;
+    int alignmentWidth = av.getAlignment().getWidth();
+    int pagesWide = (alignmentWidth / totalRes) + 1;
 
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int endSeq;
-    startRes = (pi % pagesWide) * totalRes;
-    endRes = (startRes + totalRes) - 1;
+    final int startRes = (pi % pagesWide) * totalRes;
+    int endRes = (startRes + totalRes) - 1;
 
-    if (endRes > (av.getAlignment().getWidth() - 1))
+    if (endRes > (alignmentWidth - 1))
     {
-      endRes = av.getAlignment().getWidth() - 1;
+      endRes = alignmentWidth - 1;
     }
 
-    startSeq = (pi / pagesWide) * totalSeq;
-    endSeq = startSeq + totalSeq;
+    final int startSeq = (pi / pagesWide) * totalSeq;
+    int endSeq = startSeq + totalSeq;
 
-    if (endSeq > av.getAlignment().getHeight())
+    int alignmentHeight = av.getAlignment().getHeight();
+    if (endSeq > alignmentHeight)
     {
-      endSeq = av.getAlignment().getHeight();
+      endSeq = alignmentHeight;
     }
 
-    int pagesHigh = ((av.getAlignment().getHeight() / totalSeq) + 1)
-            * pheight;
+    int pagesHigh = ((alignmentHeight / totalSeq) + 1)
+            * pageHeight;
 
     if (av.isShowAnnotation())
     {
       pagesHigh += getAnnotationPanel().adjustPanelHeight() + 3;
     }
 
-    pagesHigh /= pheight;
+    pagesHigh /= pageHeight;
 
     if (pi >= (pagesWide * pagesHigh))
     {
       return Printable.NO_SUCH_PAGE;
     }
+    final int alignmentDrawnHeight = (endSeq - startSeq) * charHeight
+            + 3;
 
-    // draw Scale
-    pg.translate(idWidth, 0);
-    getScalePanel().drawScale(pg, startRes, endRes, pwidth - idWidth,
-            scaleHeight);
-    pg.translate(-idWidth, scaleHeight);
+    /*
+     * draw the Scale at horizontal offset, then reset to top left (0, 0)
+     */
+    alignmentGraphics.translate(alignmentGraphicsOffset, 0);
+    getScalePanel().drawScale(alignmentGraphics, startRes, endRes,
+            pageWidth - idWidth, scaleHeight);
+    alignmentGraphics.translate(-alignmentGraphicsOffset, 0);
 
-    // //////////////
-    // Draw the ids
+    /*
+     * Draw the sequence ids, offset for scale height,
+     * then reset to top left (0, 0)
+     */
+    idGraphics.translate(0, scaleHeight);
+    idGraphics.setFont(getIdPanel().getIdCanvas().getIdfont());
     Color currentColor = null;
     Color currentTextColor = null;
 
-    pg.setFont(getIdPanel().getIdCanvas().getIdfont());
-
     SequenceI seq;
     for (int i = startSeq; i < endSeq; i++)
     {
@@ -1066,6 +1085,9 @@ public class AlignmentPanel extends GAlignmentPanel implements
       if ((av.getSelectionGroup() != null)
               && av.getSelectionGroup().getSequences(null).contains(seq))
       {
+        /*
+         * gray out ids of sequences in selection group (if any)
+         */
         currentColor = Color.gray;
         currentTextColor = Color.black;
       }
@@ -1075,45 +1097,58 @@ public class AlignmentPanel extends GAlignmentPanel implements
         currentTextColor = Color.black;
       }
 
-      pg.setColor(currentColor);
-      pg.fillRect(0, (i - startSeq) * av.getCharHeight(), idWidth,
-              av.getCharHeight());
+      idGraphics.setColor(currentColor);
+      idGraphics.fillRect(0, (i - startSeq) * charHeight, idWidth,
+              charHeight);
 
-      pg.setColor(currentTextColor);
+      idGraphics.setColor(currentTextColor);
 
       int xPos = 0;
+      String displayId = seq.getDisplayId(av.getShowJVSuffix());
       if (av.isRightAlignIds())
       {
-        fm = pg.getFontMetrics();
+        fm = idGraphics.getFontMetrics();
         xPos = idWidth
-                - fm.stringWidth(seq.getDisplayId(av.getShowJVSuffix()))
+                - fm.stringWidth(displayId)
                 - 4;
       }
 
-      pg.drawString(seq.getDisplayId(av.getShowJVSuffix()), xPos,
-              (((i - startSeq) * av.getCharHeight()) + av.getCharHeight())
-                      - (av.getCharHeight() / 5));
+      idGraphics.drawString(displayId, xPos,
+              (((i - startSeq) * charHeight) + charHeight)
+                      - (charHeight / 5));
     }
+    idGraphics.setFont(av.getFont());
+    idGraphics.translate(0, -scaleHeight);
 
-    pg.setFont(av.getFont());
+    /*
+     * draw the sequences, offset for scale height, and id width (if using a
+     * single graphics context), then reset to (0, scale height)
+     */
+    alignmentGraphics.translate(alignmentGraphicsOffset, scaleHeight);
+    getSeqPanel().seqCanvas.drawPanel(alignmentGraphics, startRes, endRes,
+            startSeq, endSeq, 0);
+    alignmentGraphics.translate(-alignmentGraphicsOffset, 0);
 
-    // draw main sequence panel
-    pg.translate(idWidth, 0);
-    getSeqPanel().seqCanvas.drawPanel(pg, startRes, endRes, startSeq,
-            endSeq, 0);
-
-    if (av.isShowAnnotation() && (endSeq == av.getAlignment().getHeight()))
-    {
-      // draw annotation - need to offset for current scroll position
-      int offset = -getAlabels().getScrollOffset();
-      pg.translate(0, offset);
-      pg.translate(-idWidth - 3, (endSeq - startSeq) * av.getCharHeight()
-              + 3);
-      getAlabels().drawComponent(pg, idWidth);
-      pg.translate(idWidth + 3, 0);
+    if (av.isShowAnnotation() && (endSeq == alignmentHeight))
+    {
+      /*
+       * draw annotation labels; drawComponent() translates by
+       * getScrollOffset(), so compensate for that first;
+       * then reset to (0, scale height)
+       */
+      int offset = getAlabels().getScrollOffset();
+      idGraphics.translate(0, -offset);
+      idGraphics.translate(0, alignmentDrawnHeight);
+      getAlabels().drawComponent(idGraphics, idWidth);
+      idGraphics.translate(0, -alignmentDrawnHeight);
+
+      /*
+       * draw the annotations starting at 
+       * (idOffset, alignmentHeight) from (0, scaleHeight)
+       */
+      alignmentGraphics.translate(alignmentGraphicsOffset, alignmentDrawnHeight);
       getAnnotationPanel().renderer.drawComponent(getAnnotationPanel(), av,
-              pg, -1, startRes, endRes + 1);
-      pg.translate(0, -offset);
+              alignmentGraphics, -1, startRes, endRes + 1);
     }
 
     return Printable.PAGE_EXISTS;
@@ -1136,8 +1171,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * @throws PrinterException
    *           DOCUMENT ME!
    */
-  public int printWrappedAlignment(Graphics pg, int pwidth, int pheight,
-          int pi) throws PrinterException
+  public int printWrappedAlignment(int pwidth, int pheight, int pi,
+          Graphics pg) throws PrinterException
   {
     int annotationHeight = 0;
     AnnotationLabels labels = null;
@@ -1264,8 +1299,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
     if (onscreen
             || (idwidth = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH")) == null)
     {
-      return (getIdPanel().getWidth() > 0 ? getIdPanel().getWidth()
-              : calculateIdWidth().width + 4);
+      int w = getIdPanel().getWidth();
+      return (w > 0 ? w : calculateIdWidth().width + 4);
     }
     return idwidth.intValue() + 4;
   }
@@ -1312,21 +1347,23 @@ public class AlignmentPanel extends GAlignmentPanel implements
                 aDimension.getWidth(), aDimension.getHeight()
                         + boarderBottomOffset, file, imageTitle,
                 alignFrame, pSessionId, headless);
+        Graphics graphics = im.getGraphics();
         if (av.getWrapAlignment())
         {
-          if (im.getGraphics() != null)
+          if (graphics != null)
           {
-            printWrappedAlignment(im.getGraphics(), aDimension.getWidth(),
-                    aDimension.getHeight() + boarderBottomOffset, 0);
+            printWrappedAlignment(aDimension.getWidth(),
+                    aDimension.getHeight() + boarderBottomOffset, 0,
+                    graphics);
             im.writeImage();
           }
         }
         else
         {
-          if (im.getGraphics() != null)
+          if (graphics != null)
           {
-            printUnwrapped(im.getGraphics(), aDimension.getWidth(),
-                    aDimension.getHeight(), 0);
+            printUnwrapped(aDimension.getWidth(), aDimension.getHeight(),
+                    0, graphics, graphics);
             im.writeImage();
           }
         }
@@ -1411,7 +1448,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
 
   public void makePNGImageMap(File imgMapFile, String imageName)
   {
-    // /////ONLY WORKS WITH NONE WRAPPED ALIGNMENTS
+    // /////ONLY WORKS WITH NON WRAPPED ALIGNMENTS
     // ////////////////////////////////////////////
     int idWidth = getVisibleIdWidth(false);
     FontMetrics fm = getFontMetrics(av.getFont());
@@ -1425,7 +1462,6 @@ public class AlignmentPanel extends GAlignmentPanel implements
       {
         int s, sSize = av.getAlignment().getHeight(), res, alwidth = av
                 .getAlignment().getWidth(), g, gSize, f, fSize, sy;
-        StringBuffer text = new StringBuffer();
         PrintWriter out = new PrintWriter(new FileWriter(imgMapFile));
         out.println(jalview.io.HTMLOutput.getImageMapHTML());
         out.println("<img src=\"" + imageName
@@ -1441,7 +1477,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
           SequenceGroup[] groups = av.getAlignment().findAllGroups(seq);
           for (res = 0; res < alwidth; res++)
           {
-            text = new StringBuffer();
+            StringBuilder text = new StringBuilder();
             String triplet = null;
             if (av.getAlignment().isNucleotide())
             {
@@ -1465,18 +1501,20 @@ public class AlignmentPanel extends GAlignmentPanel implements
             {
               if (text.length() < 1)
               {
-                text.append("<area shape=\"rect\" coords=\""
-                        + (idWidth + res * av.getCharWidth()) + "," + sy
-                        + "," + (idWidth + (res + 1) * av.getCharWidth())
-                        + "," + (av.getCharHeight() + sy) + "\""
-                        + " onMouseOver=\"toolTip('" + alIndex + " "
-                        + triplet);
+                text.append("<area shape=\"rect\" coords=\"")
+                        .append((idWidth + res * av.getCharWidth()))
+                        .append(",").append(sy).append(",")
+                        .append((idWidth + (res + 1) * av.getCharWidth()))
+                        .append(",").append((av.getCharHeight() + sy))
+                        .append("\"").append(" onMouseOver=\"toolTip('")
+                        .append(alIndex).append(" ").append(triplet);
               }
 
               if (groups[g].getStartRes() < res
                       && groups[g].getEndRes() > res)
               {
-                text.append("<br><em>" + groups[g].getName() + "</em>");
+                text.append("<br><em>").append(groups[g].getName())
+                        .append("</em>");
               }
             }
 
@@ -1484,12 +1522,13 @@ public class AlignmentPanel extends GAlignmentPanel implements
             {
               if (text.length() < 1)
               {
-                text.append("<area shape=\"rect\" coords=\""
-                        + (idWidth + res * av.getCharWidth()) + "," + sy
-                        + "," + (idWidth + (res + 1) * av.getCharWidth())
-                        + "," + (av.getCharHeight() + sy) + "\""
-                        + " onMouseOver=\"toolTip('" + alIndex + " "
-                        + triplet);
+                text.append("<area shape=\"rect\" coords=\"")
+                        .append((idWidth + res * av.getCharWidth()))
+                        .append(",").append(sy).append(",")
+                        .append((idWidth + (res + 1) * av.getCharWidth()))
+                        .append(",").append((av.getCharHeight() + sy))
+                        .append("\"").append(" onMouseOver=\"toolTip('")
+                        .append(alIndex).append(" ").append(triplet);
               }
               fSize = features.length;
               for (f = 0; f < fSize; f++)
@@ -1498,15 +1537,15 @@ public class AlignmentPanel extends GAlignmentPanel implements
                 if ((features[f].getBegin() <= seq.findPosition(res))
                         && (features[f].getEnd() >= seq.findPosition(res)))
                 {
-                  if (features[f].getType().equals("disulfide bond"))
+                  if (features[f].isContactFeature())
                   {
                     if (features[f].getBegin() == seq.findPosition(res)
                             || features[f].getEnd() == seq
                                     .findPosition(res))
                     {
-                      text.append("<br>disulfide bond "
-                              + features[f].getBegin() + ":"
-                              + features[f].getEnd());
+                      text.append("<br>").append(features[f].getType())
+                              .append(" ").append(features[f].getBegin())
+                              .append(":").append(features[f].getEnd());
                     }
                   }
                   else
@@ -1517,13 +1556,13 @@ public class AlignmentPanel extends GAlignmentPanel implements
                             && !features[f].getType().equals(
                                     features[f].getDescription()))
                     {
-                      text.append(" " + features[f].getDescription());
+                      text.append(" ").append(features[f].getDescription());
                     }
 
                     if (features[f].getValue("status") != null)
                     {
-                      text.append(" (" + features[f].getValue("status")
-                              + ")");
+                      text.append(" (").append(features[f].getValue("status"))
+                              .append(")");
                     }
                   }
                 }
@@ -1788,14 +1827,14 @@ public class AlignmentPanel extends GAlignmentPanel implements
    * @param verticalOffset
    *          the number of visible sequences to show above the mapped region
    */
-  public void scrollToCentre(SearchResults sr, int verticalOffset)
+  public void scrollToCentre(SearchResultsI sr, int verticalOffset)
   {
     /*
      * To avoid jumpy vertical scrolling (if some sequences are gapped or not
      * mapped), we can make the scroll-to location a sequence above the one
      * actually mapped.
      */
-    SequenceI mappedTo = sr.getResultSequence(0);
+    SequenceI mappedTo = sr.getResults().get(0).getSequence();
     List<SequenceI> seqs = av.getAlignment().getSequences();
 
     /*
index 1c0dfe6..d7e8305 100644 (file)
@@ -50,7 +50,6 @@ import java.awt.Font;
 import java.awt.Graphics;
 import java.awt.Rectangle;
 import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
 import java.io.BufferedReader;
@@ -67,7 +66,6 @@ import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JColorChooser;
 import javax.swing.JInternalFrame;
 import javax.swing.JMenu;
-import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JSplitPane;
@@ -131,7 +129,7 @@ public class AppJmol extends StructureViewerBase
     // / TODO: check if protocol is needed to be set, and if chains are
     // autodiscovered.
     jmb = new AppJmolBinding(this, ap.getStructureSelectionManager(),
-            pdbentrys, seqs, null, null);
+            pdbentrys, seqs, null);
 
     jmb.setLoadingFromArchive(true);
     addAlignmentPanel(ap);
@@ -301,7 +299,7 @@ public class AppJmol extends StructureViewerBase
   {
     progressBar = ap.alignFrame;
     jmb = new AppJmolBinding(this, ap.getStructureSelectionManager(),
-            pdbentrys, seqs, null, null);
+            pdbentrys, seqs, null);
     addAlignmentPanel(ap);
     useAlignmentPanelForColourbyseq(ap);
     if (pdbentrys.length > 1)
@@ -394,57 +392,12 @@ public class AppJmol extends StructureViewerBase
     jmb.setFinishedInit(true);
   }
 
-  void setChainMenuItems(Vector<String> chains)
-  {
-    chainMenu.removeAll();
-    if (chains == null)
-    {
-      return;
-    }
-    JMenuItem menuItem = new JMenuItem(
-            MessageManager.getString("label.all"));
-    menuItem.addActionListener(new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent evt)
-      {
-        allChainsSelected = true;
-        for (int i = 0; i < chainMenu.getItemCount(); i++)
-        {
-          if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
-          {
-            ((JCheckBoxMenuItem) chainMenu.getItem(i)).setSelected(true);
-          }
-        }
-        centerViewer();
-        allChainsSelected = false;
-      }
-    });
-
-    chainMenu.add(menuItem);
-
-    for (String chain : chains)
-    {
-      menuItem = new JCheckBoxMenuItem(chain, true);
-      menuItem.addItemListener(new ItemListener()
-      {
-        @Override
-        public void itemStateChanged(ItemEvent evt)
-        {
-          if (!allChainsSelected)
-          {
-            centerViewer();
-          }
-        }
-      });
 
-      chainMenu.add(menuItem);
-    }
-  }
 
   boolean allChainsSelected = false;
 
-  void centerViewer()
+  @Override
+  void showSelectedChains()
   {
     Vector<String> toshow = new Vector<String>();
     for (int i = 0; i < chainMenu.getItemCount(); i++)
@@ -1075,7 +1028,7 @@ public class AppJmol extends StructureViewerBase
       repaint();
       return;
     }
-    setChainMenuItems(jmb.chainNames);
+    setChainMenuItems(jmb.getChainNames());
 
     this.setTitle(jmb.getViewerTitle());
     if (jmb.getPdbFile().length > 1 && jmb.getSequence().length > 1)
index 1c54a5e..546890e 100644 (file)
@@ -41,10 +41,9 @@ public class AppJmolBinding extends JalviewJmolBinding
   private FeatureRenderer fr = null;
 
   public AppJmolBinding(AppJmol appJmol, StructureSelectionManager sSm,
-          PDBEntry[] pdbentry, SequenceI[][] sequenceIs, String[][] chains,
-          String protocol)
+          PDBEntry[] pdbentry, SequenceI[][] sequenceIs, String protocol)
   {
-    super(sSm, pdbentry, sequenceIs, chains, protocol);
+    super(sSm, pdbentry, sequenceIs, protocol);
     appJmolWindow = appJmol;
   }
 
@@ -113,6 +112,7 @@ public class AppJmolBinding extends JalviewJmolBinding
     // appJmolWindow.repaint();
     javax.swing.SwingUtilities.invokeLater(new Runnable()
     {
+      @Override
       public void run()
       {
         appJmolWindow.updateTitleAndMenus();
@@ -121,6 +121,7 @@ public class AppJmolBinding extends JalviewJmolBinding
     });
   }
 
+  @Override
   public void updateColours(Object source)
   {
     AlignmentPanel ap = (AlignmentPanel) source;
@@ -144,6 +145,7 @@ public class AppJmolBinding extends JalviewJmolBinding
     // msWalltime);
   }
 
+  @Override
   public void showUrl(String url)
   {
     showUrl(url, "jmol");
index c30a418..fe12f40 100644 (file)
@@ -31,6 +31,7 @@ import jalview.gui.StructureViewer.ViewerType;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.JalviewFileChooser;
 import jalview.io.JalviewFileView;
+import jalview.io.StructureFile;
 import jalview.schemes.BuriedColourScheme;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.HelixColourScheme;
@@ -46,7 +47,6 @@ import jalview.util.Platform;
 import jalview.ws.dbsources.Pdb;
 
 import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
 import java.io.BufferedReader;
@@ -59,16 +59,13 @@ import java.io.InputStream;
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 import java.util.Random;
-import java.util.Set;
 import java.util.Vector;
 
 import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JColorChooser;
 import javax.swing.JInternalFrame;
 import javax.swing.JMenu;
-import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 import javax.swing.event.InternalFrameAdapter;
 import javax.swing.event.InternalFrameEvent;
@@ -196,7 +193,7 @@ public class ChimeraViewFrame extends StructureViewerBase
   public ChimeraViewFrame(PDBEntry pdbentry, SequenceI[] seq,
           String[] chains, final AlignmentPanel ap)
   {
-    super();
+    this();
     String pdbId = pdbentry.getId();
 
     /*
@@ -250,10 +247,8 @@ public class ChimeraViewFrame extends StructureViewerBase
   {
     createProgressBar();
     // FIXME extractChains needs pdbentries to match IDs to PDBEntry(s) on seqs
-    String[][] chains = extractChains(seqs);
     jmb = new JalviewChimeraBindingModel(this,
-            ap.getStructureSelectionManager(), pdbentrys, seqs, chains,
-            null);
+            ap.getStructureSelectionManager(), pdbentrys, seqs, null);
     addAlignmentPanel(ap);
     useAlignmentPanelForColourbyseq(ap);
     if (pdbentrys.length > 1)
@@ -280,41 +275,7 @@ public class ChimeraViewFrame extends StructureViewerBase
 
   }
 
-  /**
-   * Retrieve chains for sequences by inspecting their PDB refs. The hope is
-   * that the first will be to the sequence's own chain. Really need a more
-   * managed way of doing this.
-   * 
-   * @param seqs
-   * @return
-   */
-  protected String[][] extractChains(SequenceI[][] seqs)
-  {
-    String[][] chains = new String[seqs.length][];
-    for (int i = 0; i < seqs.length; i++)
-    {
-      chains[i] = new String[seqs[i].length];
-      int seqno = 0;
-      for (SequenceI seq : seqs[i])
-      {
-        String chain = null;
-        if (seq.getDatasetSequence() != null)
-        {
-          Vector<PDBEntry> pdbrefs = seq.getDatasetSequence()
-                  .getAllPDBEntries();
-          if (pdbrefs != null && pdbrefs.size() > 0)
-          {
-            // FIXME: SequenceI.PDBEntry[0] chain mapping used for
-            // ChimeraViewFrame. Is this even used ???
 
-            chain = pdbrefs.get(0).getChainCode();
-          }
-        }
-        chains[i][seqno++] = chain;
-      }
-    }
-    return chains;
-  }
 
   /**
    * Create a new viewer from saved session state data including Chimera session
@@ -333,7 +294,7 @@ public class ChimeraViewFrame extends StructureViewerBase
           SequenceI[][] seqsArray, boolean colourByChimera,
           boolean colourBySequence, String newViewId)
   {
-    super();
+    this();
     setViewId(newViewId);
     this.chimeraSessionFile = chimeraSessionFile;
     openNewChimera(alignPanel, pdbArray, seqsArray);
@@ -362,31 +323,22 @@ public class ChimeraViewFrame extends StructureViewerBase
   public ChimeraViewFrame(PDBEntry[] pe, SequenceI[][] seqs,
           AlignmentPanel ap)
   {
-    super();
+    this();
     openNewChimera(ap, pe, seqs);
   }
 
-  public ChimeraViewFrame(Map<PDBEntry, List<SequenceI>> toView,
-          AlignmentPanel alignPanel)
+  /**
+   * Default constructor
+   */
+  public ChimeraViewFrame()
   {
     super();
 
     /*
-     * Convert the map of sequences per pdb entry into the tied arrays expected
-     * by openNewChimera
-     * 
-     * TODO pass the Map down to openNewChimera and its callees instead
+     * closeViewer will decide whether or not to close this frame
+     * depending on whether user chooses to Cancel or not
      */
-    final Set<PDBEntry> pdbEntries = toView.keySet();
-    PDBEntry[] pdbs = pdbEntries.toArray(new PDBEntry[pdbEntries.size()]);
-    SequenceI[][] seqsForPdbs = new SequenceI[pdbEntries.size()][];
-    for (int i = 0; i < pdbs.length; i++)
-    {
-      final List<SequenceI> seqsForPdb = toView.get(pdbs[i]);
-      seqsForPdbs[i] = seqsForPdb.toArray(new SequenceI[seqsForPdb.size()]);
-    }
-
-    openNewChimera(alignPanel, pdbs, seqsForPdbs);
+    setDefaultCloseOperation(JInternalFrame.DO_NOTHING_ON_CLOSE);
   }
 
   /**
@@ -448,63 +400,11 @@ public class ChimeraViewFrame extends StructureViewerBase
     jmb.startChimeraListener();
   }
 
-  /**
-   * If the list is not empty, add menu items for 'All' and each individual
-   * chain to the "View | Show Chain" sub-menu. Multiple selections are allowed.
-   * 
-   * @param chainNames
-   */
-  void setChainMenuItems(List<String> chainNames)
-  {
-    chainMenu.removeAll();
-    if (chainNames == null || chainNames.isEmpty())
-    {
-      return;
-    }
-    JMenuItem menuItem = new JMenuItem(
-            MessageManager.getString("label.all"));
-    menuItem.addActionListener(new ActionListener()
-    {
-      @Override
-      public void actionPerformed(ActionEvent evt)
-      {
-        allChainsSelected = true;
-        for (int i = 0; i < chainMenu.getItemCount(); i++)
-        {
-          if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
-          {
-            ((JCheckBoxMenuItem) chainMenu.getItem(i)).setSelected(true);
-          }
-        }
-        showSelectedChains();
-        allChainsSelected = false;
-      }
-    });
-
-    chainMenu.add(menuItem);
-
-    for (String chainName : chainNames)
-    {
-      menuItem = new JCheckBoxMenuItem(chainName, true);
-      menuItem.addItemListener(new ItemListener()
-      {
-        @Override
-        public void itemStateChanged(ItemEvent evt)
-        {
-          if (!allChainsSelected)
-          {
-            showSelectedChains();
-          }
-        }
-      });
-
-      chainMenu.add(menuItem);
-    }
-  }
 
   /**
    * Show only the selected chain(s) in the viewer
    */
+  @Override
   void showSelectedChains()
   {
     List<String> toshow = new ArrayList<String>();
@@ -543,7 +443,15 @@ public class ChimeraViewFrame extends StructureViewerBase
         prompt = JvSwingUtils.wrapTooltip(true, prompt);
         int confirm = JOptionPane.showConfirmDialog(this, prompt,
                 MessageManager.getString("label.close_viewer"),
-                JOptionPane.YES_NO_OPTION);
+                JOptionPane.YES_NO_CANCEL_OPTION);
+        /*
+         * abort closure if user hits escape or Cancel
+         */
+        if (confirm == JOptionPane.CANCEL_OPTION
+                || confirm == JOptionPane.CLOSED_OPTION)
+        {
+          return;
+        }
         closeChimera = confirm == JOptionPane.YES_OPTION;
       }
       jmb.closeViewer(closeChimera);
@@ -555,6 +463,7 @@ public class ChimeraViewFrame extends StructureViewerBase
     // TODO: check for memory leaks where instance isn't finalised because jmb
     // holds a reference to the window
     jmb = null;
+    dispose();
   }
 
   /**
@@ -571,6 +480,7 @@ public class ChimeraViewFrame extends StructureViewerBase
     List<PDBEntry> filePDB = new ArrayList<PDBEntry>();
     List<Integer> filePDBpos = new ArrayList<Integer>();
     PDBEntry thePdbEntry = null;
+    StructureFile pdb = null;
     try
     {
       String[] curfiles = jmb.getPdbFile(); // files currently in viewer
@@ -679,8 +589,9 @@ public class ChimeraViewFrame extends StructureViewerBase
               stopProgressBar("", startTime);
             }
             // Explicitly map to the filename used by Chimera ;
-            jmb.getSsm().setMapping(jmb.getSequence()[pos],
+            pdb = jmb.getSsm().setMapping(jmb.getSequence()[pos],
                     jmb.getChains()[pos], pe.getFile(), protocol);
+            stashFoundChains(pdb, pe.getFile());
           } catch (OutOfMemoryError oomerror)
           {
             new OOMWarning(
@@ -696,6 +607,7 @@ public class ChimeraViewFrame extends StructureViewerBase
           }
         }
       }
+      jmb.refreshGUI();
       jmb.setFinishedInit(true);
       jmb.setLoadingFromArchive(false);
 
@@ -731,6 +643,17 @@ public class ChimeraViewFrame extends StructureViewerBase
    * @return
    * @throws Exception
    */
+
+  private void stashFoundChains(StructureFile pdb, String file)
+  {
+    for (int i = 0; i < pdb.getChains().size(); i++)
+    {
+      String chid = new String(pdb.getId() + ":"
+              + pdb.getChains().elementAt(i).id);
+      jmb.getChainNames().add(chid);
+      jmb.getChainFile().put(chid, file);
+    }
+  }
   private String fetchPdbFile(PDBEntry processingEntry) throws Exception
   {
     // FIXME: this is duplicated code with Jmol frame ?
index 3f457ea..28606f1 100644 (file)
@@ -20,6 +20,9 @@
  */
 package jalview.gui;
 
+import static jalview.util.UrlConstants.EMBLEBI_STRING;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+
 import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
 import jalview.bin.Cache;
@@ -75,6 +78,7 @@ import java.net.URL;
 import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.StringTokenizer;
 import java.util.Vector;
 import java.util.concurrent.ExecutorService;
@@ -82,9 +86,12 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.Semaphore;
 
 import javax.swing.AbstractAction;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
 import javax.swing.DefaultDesktopManager;
 import javax.swing.DesktopManager;
 import javax.swing.JButton;
+import javax.swing.JCheckBox;
 import javax.swing.JComboBox;
 import javax.swing.JComponent;
 import javax.swing.JDesktopPane;
@@ -382,6 +389,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements
 
     showNews.setVisible(false);
 
+    checkURLLinks();
+
     this.addWindowListener(new WindowAdapter()
     {
       @Override
@@ -2256,6 +2265,84 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     new Thread(jvq).start();
   }
 
+  public void checkURLLinks()
+  {
+    // Thread off the URL link checker
+    addDialogThread(new Runnable()
+    {
+      @Override
+      public void run()
+      {
+        if (Cache.getDefault("CHECKURLLINKS", true))
+        {
+          // check what the actual links are - if it's just the default don't
+          // bother with the warning
+          Vector<String> links = Preferences.sequenceURLLinks;
+
+          // only need to check links if there is one with a
+          // SEQUENCE_ID which is not the default EMBL_EBI link
+          ListIterator<String> li = links.listIterator();
+          boolean check = false;
+          List<JLabel> urls = new ArrayList<JLabel>();
+          while (li.hasNext())
+          {
+            String link = li.next();
+            if (link.contains(SEQUENCE_ID) && !link.equals(EMBLEBI_STRING))
+            {
+              check = true;
+              int barPos = link.indexOf("|");
+              String urlMsg = barPos == -1 ? link : link.substring(0,
+                      barPos) + ": " + link.substring(barPos + 1);
+              urls.add(new JLabel(urlMsg));
+            }
+          }
+          if (!check)
+          {
+            return;
+          }
+
+          // ask user to check in case URL links use old style tokens
+          // ($SEQUENCE_ID$ for sequence id _or_ accession id)
+          JPanel msgPanel = new JPanel();
+          msgPanel.setLayout(new BoxLayout(msgPanel, BoxLayout.PAGE_AXIS));
+          msgPanel.add(Box.createVerticalGlue());
+          JLabel msg = new JLabel(
+                  MessageManager
+                          .getString("label.SEQUENCE_ID_for_DB_ACCESSION1"));
+          JLabel msg2 = new JLabel(
+                  MessageManager
+                          .getString("label.SEQUENCE_ID_for_DB_ACCESSION2"));
+          msgPanel.add(msg);
+          for (JLabel url : urls)
+          {
+            msgPanel.add(url);
+          }
+          msgPanel.add(msg2);
+
+          final JCheckBox jcb = new JCheckBox(
+                  MessageManager.getString("label.do_not_display_again"));
+          jcb.addActionListener(new ActionListener()
+          {
+            @Override
+            public void actionPerformed(ActionEvent e)
+            {
+              // update Cache settings for "don't show this again"
+              boolean showWarningAgain = !jcb.isSelected();
+              Cache.setProperty("CHECKURLLINKS",
+                      Boolean.valueOf(showWarningAgain).toString());
+            }
+          });
+          msgPanel.add(jcb);
+
+          JOptionPane.showMessageDialog(Desktop.desktop, msgPanel,
+                  MessageManager
+                          .getString("label.SEQUENCE_ID_no_longer_used"),
+                  JOptionPane.WARNING_MESSAGE);
+        }
+      }
+    });
+    }
+
   /**
    * Proxy class for JDesktopPane which optionally displays the current memory
    * usage and highlights the desktop area with a red bar if free memory runs
index 426ea32..83d1612 100644 (file)
@@ -22,6 +22,7 @@ package jalview.gui;
 
 import jalview.api.FeatureColourI;
 import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.schemes.FeatureColour;
@@ -200,7 +201,7 @@ public class FeatureRenderer extends
             start.setValue(new Integer(features[index].getBegin()));
             end.setValue(new Integer(features[index].getEnd()));
 
-            SearchResults highlight = new SearchResults();
+            SearchResultsI highlight = new SearchResults();
             highlight.addResult(sequences[0], features[index].getBegin(),
                     features[index].getEnd());
 
index 6bff69a..a8dbc38 100755 (executable)
@@ -20,7 +20,8 @@
  */
 package jalview.gui;
 
-import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultMatchI;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.jbgui.GFinder;
@@ -67,7 +68,7 @@ public class Finder extends GFinder
 
   int resIndex = -1;
 
-  SearchResults searchResults;
+  SearchResultsI searchResults;
 
   /**
    * Creates a new Finder object with no associated viewport or panel.
@@ -109,6 +110,7 @@ public class Finder extends GFinder
             KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "Cancel");
     getRootPane().getActionMap().put("Cancel", new AbstractAction()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         escapeActionPerformed();
@@ -130,6 +132,7 @@ public class Finder extends GFinder
    * 
    * @param e
    */
+  @Override
   public void findNext_actionPerformed(ActionEvent e)
   {
     if (getFocusedViewport())
@@ -143,6 +146,7 @@ public class Finder extends GFinder
    * 
    * @param e
    */
+  @Override
   public void findAll_actionPerformed(ActionEvent e)
   {
     if (getFocusedViewport())
@@ -198,19 +202,22 @@ public class Finder extends GFinder
    * @param e
    *          DOCUMENT ME!
    */
+  @Override
   public void createNewGroup_actionPerformed(ActionEvent e)
   {
     SequenceI[] seqs = new SequenceI[searchResults.getSize()];
     SequenceFeature[] features = new SequenceFeature[searchResults
             .getSize()];
 
-    for (int i = 0; i < searchResults.getSize(); i++)
+    int i = 0;
+    for (SearchResultMatchI match : searchResults.getResults())
     {
-      seqs[i] = searchResults.getResultSequence(i).getDatasetSequence();
+      seqs[i] = match.getSequence().getDatasetSequence();
 
       features[i] = new SequenceFeature(textfield.getText().trim(),
-              "Search Results", null, searchResults.getResultStart(i),
-              searchResults.getResultEnd(i), "Search Results");
+              "Search Results", null, match.getStart(), match.getEnd(),
+              "Search Results");
+      i++;
     }
 
     if (ap.getSeqPanel().seqCanvas.getFeatureRenderer().amendFeatures(seqs,
@@ -256,7 +263,7 @@ public class Finder extends GFinder
 
     searchResults = finder.getSearchResults(); // find(regex,
     // caseSensitive.isSelected(), )
-    Vector idMatch = finder.getIdMatch();
+    Vector<SequenceI> idMatch = finder.getIdMatch();
     boolean haveResults = false;
     // set or reset the GUI
     if ((idMatch.size() > 0))
index a65be7b..6a20872 100755 (executable)
@@ -109,8 +109,8 @@ public class IdPanel extends JPanel implements MouseListener,
     if (seq > -1 && seq < av.getAlignment().getHeight())
     {
       SequenceI sequence = av.getAlignment().getSequenceAt(seq);
-      StringBuffer tip = new StringBuffer(64);
-      seqAnnotReport.createSequenceAnnotationReport(tip, sequence,
+      StringBuilder tip = new StringBuilder(64);
+      seqAnnotReport.createTooltipAnnotationReport(tip, sequence,
               av.isShowDBRefs(), av.isShowNPFeats(),
               sp.seqCanvas.fr.getMinMax());
       setToolTipText(JvSwingUtils.wrapTooltip(true,
@@ -225,7 +225,14 @@ public class IdPanel extends JPanel implements MouseListener,
         url = null;
         continue;
       }
-      ;
+
+      if (urlLink.usesDBAccession())
+      {
+        // this URL requires an accession id, not the name of a sequence
+        url = null;
+        continue;
+      }
+
       if (!urlLink.isValid())
       {
         jalview.bin.Cache.log.error(urlLink.getInvalidMessage());
index 1c90889..bc5e1d8 100644 (file)
@@ -3401,8 +3401,8 @@ public class Jalview2XML
         }
         if (jGroup.getConsThreshold() != 0)
         {
-          Conservation c = new Conservation("All", 3,
-                  sg.getSequences(null), 0, sg.getWidth() - 1);
+          Conservation c = new Conservation("All", sg.getSequences(null),
+                  0, sg.getWidth() - 1);
           c.calculate();
           c.verdict(false, 25);
           sg.cs.setConservation(c);
index f8a296f..3b39be7 100755 (executable)
@@ -359,8 +359,8 @@ public class Jalview2XML_V1
 
         if (groups[i].getConsThreshold() != 0)
         {
-          Conservation c = new Conservation("All", 3,
-                  sg.getSequences(null), 0, sg.getWidth() - 1);
+          Conservation c = new Conservation("All", sg.getSequences(null),
+                  0, sg.getWidth() - 1);
           c.calculate();
           c.verdict(false, 25);
           sg.cs.setConservation(c);
index 7a54732..78ab68d 100644 (file)
@@ -32,11 +32,12 @@ public class JalviewChimeraBindingModel extends JalviewChimeraBinding
 
   private FeatureRenderer fr = null;
 
+
   public JalviewChimeraBindingModel(ChimeraViewFrame chimeraViewFrame,
           StructureSelectionManager ssm, PDBEntry[] pdbentry,
-          SequenceI[][] sequenceIs, String[][] chains, String protocol)
+          SequenceI[][] sequenceIs, String protocol)
   {
-    super(ssm, pdbentry, sequenceIs, chains, protocol);
+    super(ssm, pdbentry, sequenceIs, protocol);
     cvf = chimeraViewFrame;
   }
 
@@ -72,6 +73,7 @@ public class JalviewChimeraBindingModel extends JalviewChimeraBinding
   {
     javax.swing.SwingUtilities.invokeLater(new Runnable()
     {
+      @Override
       public void run()
       {
         cvf.updateTitleAndMenus();
@@ -80,6 +82,7 @@ public class JalviewChimeraBindingModel extends JalviewChimeraBinding
     });
   }
 
+  @Override
   public void updateColours(Object source)
   {
     AlignmentPanel ap = (AlignmentPanel) source;
@@ -113,6 +116,7 @@ public class JalviewChimeraBindingModel extends JalviewChimeraBinding
    * Send an asynchronous command to Chimera, in a new thread, optionally with
    * an 'in progress' message in a progress bar somewhere
    */
+  @Override
   protected void sendAsynchronousCommand(final String command,
           final String progressMsg)
   {
@@ -135,4 +139,6 @@ public class JalviewChimeraBindingModel extends JalviewChimeraBinding
     thread.start();
 
   }
+
+
 }
index 7ab6022..5825382 100644 (file)
@@ -54,7 +54,6 @@ import jalview.schemes.TaylorColourScheme;
 import jalview.schemes.TurnColourScheme;
 import jalview.schemes.UserColourScheme;
 import jalview.schemes.ZappoColourScheme;
-import jalview.util.DBRefUtils;
 import jalview.util.GroupUrlLink;
 import jalview.util.GroupUrlLink.UrlStringTooLongException;
 import jalview.util.MessageManager;
@@ -63,8 +62,8 @@ import jalview.util.UrlLink;
 import java.awt.Color;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Hashtable;
 import java.util.LinkedHashMap;
@@ -617,7 +616,8 @@ public class PopupMenu extends JPopupMenu
   void addFeatureLinks(final SequenceI seq, List<String> links)
   {
     JMenu linkMenu = new JMenu(MessageManager.getString("action.link"));
-    List<String> linkset = new ArrayList<String>();
+    Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+
     for (String link : links)
     {
       UrlLink urlLink = null;
@@ -629,97 +629,28 @@ public class PopupMenu extends JPopupMenu
         Cache.log.error("Exception for URLLink '" + link + "'", foo);
         continue;
       }
-      ;
+
       if (!urlLink.isValid())
       {
         Cache.log.error(urlLink.getInvalidMessage());
         continue;
       }
-      final String label = urlLink.getLabel();
-      if (seq != null && urlLink.isDynamic())
-      {
 
-        // collect matching db-refs
-        DBRefEntry[] dbr = DBRefUtils.selectRefs(seq.getDBRefs(),
-                new String[] { urlLink.getTarget() });
-        // collect id string too
-        String id = seq.getName();
-        String descr = seq.getDescription();
-        if (descr != null && descr.length() < 1)
-        {
-          descr = null;
-        }
+      urlLink.createLinksFromSeq(seq, linkset);
+    }
 
-        if (dbr != null)
-        {
-          for (int r = 0; r < dbr.length; r++)
-          {
-            if (id != null && dbr[r].getAccessionId().equals(id))
-            {
-              // suppress duplicate link creation for the bare sequence ID
-              // string with this link
-              id = null;
-            }
-            // create Bare ID link for this URL
-            String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(), true);
-            if (urls != null)
-            {
-              for (int u = 0; u < urls.length; u += 2)
-              {
-                if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
-                {
-                  linkset.add(urls[u] + "|" + urls[u + 1]);
-                  addshowLink(linkMenu, label + "|" + urls[u], urls[u + 1]);
-                }
-              }
-            }
-          }
-        }
-        if (id != null)
-        {
-          // create Bare ID link for this URL
-          String[] urls = urlLink.makeUrls(id, true);
-          if (urls != null)
-          {
-            for (int u = 0; u < urls.length; u += 2)
-            {
-              if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
-              {
-                linkset.add(urls[u] + "|" + urls[u + 1]);
-                addshowLink(linkMenu, label, urls[u + 1]);
-              }
-            }
-          }
-        }
-        // Create urls from description but only for URL links which are regex
-        // links
-        if (descr != null && urlLink.getRegexReplace() != null)
-        {
-          // create link for this URL from description where regex matches
-          String[] urls = urlLink.makeUrls(descr, true);
-          if (urls != null)
-          {
-            for (int u = 0; u < urls.length; u += 2)
-            {
-              if (!linkset.contains(urls[u] + "|" + urls[u + 1]))
-              {
-                linkset.add(urls[u] + "|" + urls[u + 1]);
-                addshowLink(linkMenu, label, urls[u + 1]);
-              }
-            }
-          }
-        }
-      }
-      else
-      {
-        if (!linkset.contains(label + "|" + urlLink.getUrl_prefix()))
-        {
-          linkset.add(label + "|" + urlLink.getUrl_prefix());
-          // Add a non-dynamic link
-          addshowLink(linkMenu, label, urlLink.getUrl_prefix());
-        }
-      }
+    addshowLinks(linkMenu, linkset.values());
+
+    // disable link menu if there are no valid entries
+    if (linkMenu.getItemCount() > 0)
+    {
+      linkMenu.setEnabled(true);
     }
+    else
+    {
+      linkMenu.setEnabled(false);
+    }
+
     if (sequence != null)
     {
       sequenceMenu.add(linkMenu);
@@ -728,8 +659,11 @@ public class PopupMenu extends JPopupMenu
     {
       add(linkMenu);
     }
+
   }
 
+
+
   /**
    * Add annotation types to 'Show annotations' and/or 'Hide annotations' menus.
    * "All" is added first, followed by a separator. Then add any annotation
@@ -1004,6 +938,15 @@ public class PopupMenu extends JPopupMenu
     }
   }
 
+  private void addshowLinks(JMenu linkMenu, Collection<List<String>> linkset)
+  {
+    for (List<String> linkstrset : linkset)
+    {
+      // split linkstr into label and url
+      addshowLink(linkMenu, linkstrset.get(1), linkstrset.get(3));
+    }
+  }
+
   /**
    * add a show URL menu item to the given linkMenu
    * 
@@ -1734,7 +1677,7 @@ public class PopupMenu extends JPopupMenu
   public void createSequenceDetailsReport(SequenceI[] sequences)
   {
     CutAndPasteHtmlTransfer cap = new CutAndPasteHtmlTransfer();
-    StringBuffer contents = new StringBuffer();
+    StringBuilder contents = new StringBuilder(128);
     for (SequenceI seq : sequences)
     {
       contents.append("<p><h2>"
@@ -1749,7 +1692,6 @@ public class PopupMenu extends JPopupMenu
                       seq,
                       true,
                       true,
-                      false,
                       (ap.getSeqPanel().seqCanvas.fr != null) ? ap
                               .getSeqPanel().seqCanvas.fr.getMinMax()
                               : null);
@@ -2037,7 +1979,7 @@ public class PopupMenu extends JPopupMenu
     if (conservationMenuItem.isSelected())
     {
       // JBPNote: Conservation name shouldn't be i18n translated
-      Conservation c = new Conservation("Group", 3, sg.getSequences(ap.av
+      Conservation c = new Conservation("Group", sg.getSequences(ap.av
               .getHiddenRepSequences()), sg.getStartRes(),
               sg.getEndRes() + 1);
 
index 8dbe5e2..3bffd3a 100755 (executable)
  */
 package jalview.gui;
 
+import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.EMBLEBI_STRING;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+import static jalview.util.UrlConstants.SRS_STRING;
+
 import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
 import jalview.bin.Cache;
 import jalview.gui.Help.HelpId;
@@ -110,10 +115,7 @@ public class Preferences extends GPreferences
   public static List<String> groupURLLinks;
   static
   {
-    String string = Cache
-            .getDefault(
-                    "SEQUENCE_LINKS",
-                    "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$");
+    String string = Cache.getDefault("SEQUENCE_LINKS", EMBLEBI_STRING);
     sequenceURLLinks = new Vector<String>();
 
     try
@@ -124,7 +126,11 @@ public class Preferences extends GPreferences
         String name = st.nextToken();
         String url = st.nextToken();
         // check for '|' within a regex
-        int rxstart = url.indexOf("$SEQUENCE_ID$");
+        int rxstart = url.indexOf("$" + DB_ACCESSION + "$");
+        if (rxstart == -1)
+        {
+          rxstart = url.indexOf("$" + SEQUENCE_ID + "$");
+        }
         while (rxstart == -1 && url.indexOf("/=$") == -1)
         {
           url = url + "|" + st.nextToken();
@@ -137,14 +143,10 @@ public class Preferences extends GPreferences
     }
     {
       // upgrade old SRS link
-      int srsPos = sequenceURLLinks
-              .indexOf("SRS|http://srs.ebi.ac.uk/srsbin/cgi-bin/wgetz?-newId+(([uniprot-all:$SEQUENCE_ID$]))+-view+SwissEntry");
+      int srsPos = sequenceURLLinks.indexOf(SRS_STRING);
       if (srsPos > -1)
       {
-        sequenceURLLinks
-                .setElementAt(
-                        "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$",
-                        srsPos);
+        sequenceURLLinks.setElementAt(EMBLEBI_STRING, srsPos);
       }
     }
 
@@ -565,6 +567,7 @@ public class Preferences extends GPreferences
     else
     {
       Cache.applicationProperties.remove("SEQUENCE_LINKS");
+      sequenceURLLinks.clear();
     }
 
     Cache.applicationProperties.setProperty("USE_PROXY",
index 760ece0..d015292 100755 (executable)
@@ -21,7 +21,7 @@
 package jalview.gui;
 
 import jalview.datamodel.AlignmentI;
-import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.renderer.ScaleRenderer;
@@ -62,8 +62,6 @@ public class SeqCanvas extends JComponent
 
   AlignViewport av;
 
-  SearchResults searchResults = null;
-
   boolean fastPaint = false;
 
   int LABEL_WEST;
@@ -740,10 +738,10 @@ public class SeqCanvas extends JComponent
 
       // / Highlight search Results once all sequences have been drawn
       // ////////////////////////////////////////////////////////
-      if (searchResults != null)
+      if (av.hasSearchResults())
       {
-        int[] visibleResults = searchResults.getResults(nextSeq, startRes,
-                endRes);
+        int[] visibleResults = av.getSearchResults().getResults(nextSeq,
+                startRes, endRes);
         if (visibleResults != null)
         {
           for (int r = 0; r < visibleResults.length; r += 2)
@@ -965,11 +963,11 @@ public class SeqCanvas extends JComponent
    * @param results
    *          DOCUMENT ME!
    */
-  public void highlightSearchResults(SearchResults results)
+  public void highlightSearchResults(SearchResultsI results)
   {
     img = null;
 
-    searchResults = results;
+    av.setSearchResults(results);
 
     repaint();
   }
index 3266fab..36fb052 100644 (file)
@@ -27,8 +27,9 @@ import jalview.commands.EditCommand.Action;
 import jalview.commands.EditCommand.Edit;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SearchResultMatchI;
 import jalview.datamodel.SearchResults;
-import jalview.datamodel.SearchResults.Match;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
@@ -124,7 +125,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   private final SequenceAnnotationReport seqARep;
 
-  StringBuffer tooltipText = new StringBuffer();
+  StringBuilder tooltipText = new StringBuilder();
 
   String tmpString;
 
@@ -132,7 +133,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   StructureSelectionManager ssm;
 
-  SearchResults lastSearchResults;
+  SearchResultsI lastSearchResults;
 
   /**
    * Creates a new SeqPanel object.
@@ -676,7 +677,7 @@ public class SeqPanel extends JPanel implements MouseListener,
    * the start of the highlighted region.
    */
   @Override
-  public void highlightSequence(SearchResults results)
+  public void highlightSequence(SearchResultsI results)
   {
     if (results == null || results.equals(lastSearchResults))
     {
@@ -785,7 +786,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       seqARep.appendFeatures(tooltipText, rpos, features,
               this.ap.getSeqPanel().seqCanvas.fr.getMinMax());
     }
-    if (tooltipText.length() == 6) // <html></html>
+    if (tooltipText.length() == 6) // <html>
     {
       setToolTipText(null);
       lastTooltip = null;
@@ -910,7 +911,7 @@ public class SeqPanel extends JPanel implements MouseListener,
    * 
    * @param results
    */
-  private void setStatusMessage(SearchResults results)
+  private void setStatusMessage(SearchResultsI results)
   {
     AlignmentI al = this.av.getAlignment();
     int sequenceIndex = al.findIndex(results);
@@ -919,7 +920,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       return;
     }
     SequenceI ds = al.getSequenceAt(sequenceIndex).getDatasetSequence();
-    for (Match m : results.getResults())
+    for (SearchResultMatchI m : results.getResults())
     {
       SequenceI seq = m.getSequence();
       if (seq.getDatasetSequence() != null)
@@ -1501,7 +1502,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
       if (features != null && features.size() > 0)
       {
-        SearchResults highlight = new SearchResults();
+        SearchResultsI highlight = new SearchResults();
         highlight.addResult(sequence, features.get(0).getBegin(), features
                 .get(0).getEnd());
         seqCanvas.highlightSearchResults(highlight);
index 3350f6c..21b6e4f 100644 (file)
@@ -83,6 +83,8 @@ public class StructureChooser extends GStructureChooser implements
 
   private boolean cachedPDBExists;
 
+  private static int MAX_QLENGHT = 7820;
+
   public StructureChooser(SequenceI[] selectedSeqs, SequenceI selectedSeq,
           AlignmentPanel ap)
   {
@@ -259,7 +261,8 @@ public class StructureChooser extends GStructureChooser implements
     StringBuilder queryBuilder = new StringBuilder();
     Set<String> seqRefs = new LinkedHashSet<String>();
 
-    if (seq.getAllPDBEntries() != null)
+    if (seq.getAllPDBEntries() != null
+            && queryBuilder.length() < MAX_QLENGHT)
     {
       for (PDBEntry entry : seq.getAllPDBEntries())
       {
@@ -268,7 +271,6 @@ public class StructureChooser extends GStructureChooser implements
           queryBuilder.append("pdb_id:")
                   .append(entry.getId().toLowerCase()).append(" OR ");
           isPDBRefsFound = true;
-          // seqRefs.add(entry.getId());
         }
       }
     }
@@ -277,7 +279,8 @@ public class StructureChooser extends GStructureChooser implements
     {
       for (DBRefEntry dbRef : seq.getDBRefs())
       {
-        if (isValidSeqName(getDBRefId(dbRef)))
+        if (isValidSeqName(getDBRefId(dbRef))
+                && queryBuilder.length() < MAX_QLENGHT)
         {
           if (dbRef.getSource().equalsIgnoreCase(DBRefSource.UNIPROT))
           {
index 7df42fd..4715e48 100644 (file)
@@ -30,10 +30,15 @@ import jalview.structures.models.AAStructureBindingModel;
 import jalview.util.MessageManager;
 
 import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Vector;
 
+import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 
@@ -76,6 +81,8 @@ public abstract class StructureViewerBase extends GStructureViewer
 
   protected Thread worker = null;
 
+  protected boolean allChainsSelected = false;
+
   /**
    * 
    * @param ap2
@@ -152,6 +159,7 @@ public abstract class StructureViewerBase extends GStructureViewer
     this.ap = alp;
   }
 
+  @Override
   public AlignmentPanel[] getAllAlignmentPanels()
   {
     AlignmentPanel[] t, list = new AlignmentPanel[0];
@@ -291,6 +299,7 @@ public abstract class StructureViewerBase extends GStructureViewer
         // queue.
         new Thread(new Runnable()
         {
+          @Override
           public void run()
           {
             while (worker != null && worker.isAlive() && _started)
@@ -492,4 +501,55 @@ public abstract class StructureViewerBase extends GStructureViewer
     }
     return finished;
   }
+
+  void setChainMenuItems(List<String> chainNames)
+  {
+    chainMenu.removeAll();
+    if (chainNames == null || chainNames.isEmpty())
+    {
+      return;
+    }
+    JMenuItem menuItem = new JMenuItem(
+            MessageManager.getString("label.all"));
+    menuItem.addActionListener(new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent evt)
+      {
+        allChainsSelected = true;
+        for (int i = 0; i < chainMenu.getItemCount(); i++)
+        {
+          if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
+          {
+            ((JCheckBoxMenuItem) chainMenu.getItem(i)).setSelected(true);
+          }
+        }
+        showSelectedChains();
+        allChainsSelected = false;
+      }
+    });
+
+    chainMenu.add(menuItem);
+
+    for (String chain : chainNames)
+    {
+      menuItem = new JCheckBoxMenuItem(chain, true);
+      menuItem.addItemListener(new ItemListener()
+      {
+        @Override
+        public void itemStateChanged(ItemEvent evt)
+        {
+          if (!allChainsSelected)
+          {
+            showSelectedChains();
+          }
+        }
+      });
+
+      chainMenu.add(menuItem);
+    }
+  }
+
+  abstract void showSelectedChains();
+
 }
index 0e513f7..84fd82f 100755 (executable)
@@ -1017,8 +1017,8 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
         if (aps[a].av.getGlobalColourScheme() != null
                 && aps[a].av.getGlobalColourScheme().conservationApplied())
         {
-          Conservation c = new Conservation("Group", 3,
-                  sg.getSequences(null), sg.getStartRes(), sg.getEndRes());
+          Conservation c = new Conservation("Group", sg.getSequences(null),
+                  sg.getStartRes(), sg.getEndRes());
           c.calculate();
           c.verdict(false, aps[a].av.getConsPercGaps());
           sg.cs.setConservation(c);
index 34fdabe..61a30f8 100755 (executable)
@@ -1637,9 +1637,8 @@ public class AnnotationFile
         else if (key.equalsIgnoreCase("consThreshold"))
         {
           sg.cs.setConservationInc(Integer.parseInt(value));
-          Conservation c = new Conservation("Group", 3,
-                  sg.getSequences(null), sg.getStartRes(),
-                  sg.getEndRes() + 1);
+          Conservation c = new Conservation("Group", sg.getSequences(null),
+                  sg.getStartRes(), sg.getEndRes() + 1);
 
           c.calculate();
           c.verdict(false, 25); // TODO: refer to conservation percent threshold
index f8fa1f5..fd9c584 100644 (file)
  */
 package jalview.io;
 
-import jalview.api.AlignExportSettingI;
-import jalview.api.AlignmentViewPanel;
-import jalview.datamodel.AlignmentExportData;
 import jalview.exceptions.NoFileSelectedException;
-import jalview.gui.IProgressIndicator;
+import jalview.gui.AlignmentPanel;
 import jalview.gui.OOMWarning;
 import jalview.json.binding.biojs.BioJSReleasePojo;
 import jalview.json.binding.biojs.BioJSRepositoryPojo;
@@ -42,15 +39,8 @@ import java.net.URL;
 import java.util.Objects;
 import java.util.TreeMap;
 
-public class BioJsHTMLOutput
+public class BioJsHTMLOutput extends HTMLOutput
 {
-  private AlignmentViewPanel ap;
-
-  private long pSessionId;
-
-  private IProgressIndicator pIndicator;
-
-  private boolean headless;
 
   private static File currentBJSTemplateFile;
 
@@ -67,183 +57,41 @@ public class BioJsHTMLOutput
                   "biojs_template_git_repo",
                   "https://raw.githubusercontent.com/jalview/exporter-templates/master/biojs/package.json");
 
-  public BioJsHTMLOutput(AlignmentViewPanel ap,
-          IProgressIndicator pIndicator)
+  public BioJsHTMLOutput(AlignmentPanel ap)
   {
-    if (ap != null)
-    {
-      this.ap = ap;
-      this.pSessionId = System.currentTimeMillis();
-      this.pIndicator = pIndicator;
-      this.headless = (System.getProperty("java.awt.headless") != null && System
-              .getProperty("java.awt.headless").equals("true"));
-    }
+    super(ap);
   }
 
-  public void exportJalviewAlignmentAsBioJsHtmlFile()
+  @Override
+  public void exportHTML(String outputFile)
   {
-    String outputFile = null;
+    exportStarted();
     try
     {
-      outputFile = getOutputFile();
-      AlignExportSettingI exportSettings = new AlignExportSettingI()
+      if (outputFile == null)
       {
-        @Override
-        public boolean isExportHiddenSequences()
-        {
-          return true;
-        }
-
-        @Override
-        public boolean isExportHiddenColumns()
-        {
-          return true;
-        }
-
-        @Override
-        public boolean isExportAnnotations()
-        {
-          return true;
-        }
-
-        @Override
-        public boolean isExportFeatures()
-        {
-          return true;
-        }
-
-        @Override
-        public boolean isExportGroups()
-        {
-          return true;
-        }
-
-        @Override
-        public boolean isCancelled()
-        {
-          return false;
-        }
-
-      };
-      AlignmentExportData exportData = jalview.gui.AlignFrame
-              .getAlignmentForExport(JSONFile.FILE_DESC,
-                      ap.getAlignViewport(), exportSettings);
-      String bioJSON = new FormatAdapter(ap, exportData.getSettings())
-              .formatSequences(JSONFile.FILE_DESC, exportData
-                      .getAlignment(), exportData.getOmitHidden(),
-                      exportData.getStartEndPostions(), ap
-                              .getAlignViewport().getColumnSelection());
-
-      String bioJSTemplateString = getBioJsTemplateAsString();
-      String generatedBioJsWithJalviewAlignmentAsJson = bioJSTemplateString
-              .replaceAll("#sequenceData#", bioJSON).toString();
-
-      PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(
-              outputFile));
-      out.print(generatedBioJsWithJalviewAlignmentAsJson);
-      out.flush();
-      out.close();
-      jalview.util.BrowserLauncher.openURL("file:///" + outputFile);
-      if (pIndicator != null && !headless)
-      {
-        pIndicator.setProgressBar(MessageManager.formatMessage(
-                "status.export_complete", "BioJS"), pSessionId);
+        outputFile = getOutputFile();
       }
-    } catch (NoFileSelectedException ex)
+      generatedFile = new File(outputFile);
+    } catch (NoFileSelectedException e)
     {
-      // do noting if no file was selected
-    } catch (OutOfMemoryError err)
-    {
-      System.out.println("########################\n" + "OUT OF MEMORY "
-              + outputFile + "\n" + "########################");
-      new OOMWarning("Creating Image for " + outputFile, err);
+      setProgressMessage(MessageManager.formatMessage(
+              "status.cancelled_image_export_operation", "BioJS MSA"));
+      return;
     } catch (Exception e)
     {
-      pIndicator.setProgressBar(MessageManager.formatMessage(
-              "info.error_creating_file", "HTML"), pSessionId);
+      setProgressMessage(MessageManager.formatMessage(
+              "info.error_creating_file", "BioJS MSA"));
       e.printStackTrace();
+      return;
     }
-  }
-
-  public String getOutputFile() throws NoFileSelectedException
-  {
-    String selectedFile = null;
-    if (pIndicator != null && !headless)
-    {
-      pIndicator.setProgressBar(MessageManager.formatMessage(
-              "status.waiting_for_user_to_select_output_file", "HTML"),
-              pSessionId);
-    }
-
-    JalviewFileChooser jvFileChooser = new JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
-            new String[] { "html" }, new String[] { "HTML files" },
-            "HTML files");
-    jvFileChooser.setFileView(new JalviewFileView());
+    new Thread(this).start();
 
-    jvFileChooser.setDialogTitle(MessageManager
-            .getString("label.save_as_biojs_html"));
-    jvFileChooser.setToolTipText(MessageManager.getString("action.save"));
-
-    int fileChooserOpt = jvFileChooser.showSaveDialog(null);
-    if (fileChooserOpt == JalviewFileChooser.APPROVE_OPTION)
-    {
-      jalview.bin.Cache.setProperty("LAST_DIRECTORY", jvFileChooser
-              .getSelectedFile().getParent());
-      selectedFile = jvFileChooser.getSelectedFile().getPath();
-    }
-    else
-    {
-      pIndicator.setProgressBar(MessageManager.formatMessage(
-              "status.cancelled_image_export_operation", "BioJS"),
-              pSessionId);
-      throw new NoFileSelectedException("No file was selected.");
-    }
-    return selectedFile;
   }
 
-  public static String getBioJsTemplateAsString() throws IOException
-  {
-    InputStreamReader isReader = null;
-    BufferedReader buffReader = null;
-    StringBuilder sb = new StringBuilder();
-    Objects.requireNonNull(getCurrentBJSTemplateFile(),
-            "BioJsTemplate File not initialized!");
-    @SuppressWarnings("deprecation")
-    URL url = getCurrentBJSTemplateFile().toURL();
-    if (url != null)
-    {
-      try
-      {
-        isReader = new InputStreamReader(url.openStream());
-        buffReader = new BufferedReader(isReader);
-        String line;
-        String lineSeparator = System.getProperty("line.separator");
-        while ((line = buffReader.readLine()) != null)
-        {
-          sb.append(line).append(lineSeparator);
-        }
 
-      } catch (Exception ex)
-      {
-        ex.printStackTrace();
-      } finally
-      {
-        if (isReader != null)
-        {
-          isReader.close();
-        }
 
-        if (buffReader != null)
-        {
-          buffReader.close();
-        }
-      }
-    }
-    return sb.toString();
-  }
-
-  public static void refreshBioJSVersionsInfo(String dirName)
+  public static void refreshVersionInfo(String dirName)
           throws URISyntaxException
   {
     File directory = new File(BJS_TEMPLATES_LOCAL_DIRECTORY);
@@ -291,7 +139,7 @@ public class BioJsHTMLOutput
             BioJSRepositoryPojo release = new BioJSRepositoryPojo(
                     gitRepoPkgJson);
             syncUpdates(BJS_TEMPLATES_LOCAL_DIRECTORY, release);
-            refreshBioJSVersionsInfo(BJS_TEMPLATES_LOCAL_DIRECTORY);
+            refreshVersionInfo(BJS_TEMPLATES_LOCAL_DIRECTORY);
           }
         } catch (URISyntaxException e)
         {
@@ -412,4 +260,56 @@ public class BioJsHTMLOutput
     BioJsHTMLOutput.bioJsMSAVersions = bioJsMSAVersions;
   }
 
+  @Override
+  public boolean isEmbedData()
+  {
+    return true;
+  }
+
+  @Override
+  public boolean isLaunchInBrowserAfterExport()
+  {
+    return true;
+  }
+
+  @Override
+  public File getExportedFile()
+  {
+    return generatedFile;
+  }
+
+  @Override
+  public void run()
+  {
+    try
+    {
+      String bioJSON = getBioJSONData();
+      String bioJSTemplateString = HTMLOutput
+              .readFileAsString(getCurrentBJSTemplateFile());
+      String generatedBioJsWithJalviewAlignmentAsJson = bioJSTemplateString
+              .replaceAll("#sequenceData#", bioJSON).toString();
+
+      PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(
+              generatedFile));
+      out.print(generatedBioJsWithJalviewAlignmentAsJson);
+      out.flush();
+      out.close();
+      setProgressMessage(MessageManager.formatMessage(
+              "status.export_complete", "BioJS"));
+      exportCompleted();
+
+    } catch (OutOfMemoryError err)
+    {
+      System.out.println("########################\n" + "OUT OF MEMORY "
+              + generatedFile + "\n" + "########################");
+      new OOMWarning("Creating Image for " + generatedFile, err);
+    } catch (Exception e)
+    {
+      setProgressMessage(MessageManager.formatMessage(
+              "info.error_creating_file", "HTML"));
+      e.printStackTrace();
+    }
+
+  }
+
 }
index df0dc06..d58bd67 100755 (executable)
  */
 package jalview.io;
 
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.SequenceI;
-import jalview.gui.AlignViewport;
+import jalview.api.AlignExportSettingI;
+import jalview.datamodel.AlignmentExportData;
+import jalview.exceptions.NoFileSelectedException;
 import jalview.gui.AlignmentPanel;
-import jalview.gui.FeatureRenderer;
-import jalview.gui.SequenceRenderer;
+import jalview.gui.IProgressIndicator;
 import jalview.util.MessageManager;
 
-import java.awt.Color;
-import java.awt.Font;
-import java.io.PrintWriter;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Objects;
 
-public class HTMLOutput
+
+public abstract class HTMLOutput implements Runnable
 {
-  AlignViewport av;
+  protected AlignmentPanel ap;
 
-  SequenceRenderer sr;
+  protected long pSessionId;
 
-  jalview.renderer.seqfeatures.FeatureRenderer fr;
+  protected IProgressIndicator pIndicator;
 
-  Color color;
+  protected File generatedFile;
 
-  public HTMLOutput(AlignmentPanel ap, SequenceRenderer sr,
-          FeatureRenderer fr1)
+  public HTMLOutput(AlignmentPanel ap)
   {
-    this.av = ap.av;
-    this.sr = sr;
-
-    fr = new FeatureRenderer(ap);
-    fr.transferSettings(fr1);
-
-    JalviewFileChooser chooser = new JalviewFileChooser(
-            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
-            new String[] { "html" }, new String[] { "HTML files" },
-            "HTML files");
-
-    chooser.setFileView(new JalviewFileView());
-    chooser.setDialogTitle(MessageManager.getString("label.save_as_html"));
-    chooser.setToolTipText(MessageManager.getString("action.save"));
-
-    int value = chooser.showSaveDialog(null);
-
-    if (value == JalviewFileChooser.APPROVE_OPTION)
+    if (ap != null)
     {
-      String choice = chooser.getSelectedFile().getPath();
-      jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
-              .getSelectedFile().getParent());
-
-      try
-      {
-        PrintWriter out = new java.io.PrintWriter(new java.io.FileWriter(
-                choice));
-        out.println("<HTML>");
-        out.println("<style type=\"text/css\">");
-        out.println("<!--");
-        out.print("td {font-family: \"" + av.getFont().getFamily()
-                + "\", \"" + av.getFont().getName() + "\", mono; "
-                + "font-size: " + av.getFont().getSize() + "px; ");
-
-        if (av.getFont().getStyle() == Font.BOLD)
-        {
-          out.print("font-weight: BOLD; ");
-        }
-
-        if (av.getFont().getStyle() == Font.ITALIC)
-        {
-          out.print("font-style: italic; ");
-        }
-
-        out.println("text-align: center; }");
-
-        out.println("-->");
-        out.println("</style>");
-        out.println("<BODY>");
-
-        if (av.getWrapAlignment())
-        {
-          drawWrappedAlignment(out);
-        }
-        else
-        {
-          drawUnwrappedAlignment(out);
-        }
-
-        out.println("\n</body>\n</html>");
-        out.close();
-        jalview.util.BrowserLauncher.openURL("file:///" + choice);
-      } catch (Exception ex)
-      {
-        ex.printStackTrace();
-      }
+      this.ap = ap;
+      this.pIndicator = ap.alignFrame;
     }
   }
 
-  void drawUnwrappedAlignment(PrintWriter out)
+  public String getBioJSONData()
   {
-    out.println("<table border=\"1\"><tr><td>\n");
-    out.println("<table border=\"0\"  cellpadding=\"0\" cellspacing=\"0\">\n");
-
-    // ////////////
-    SequenceI seq;
-    AlignmentI alignment = av.getAlignment();
-
-    // draws the top row, the measure rule
-    out.println("<tr><td colspan=\"6\"></td>");
-
-    int i = 0;
+    return getBioJSONData(null);
+  }
 
-    for (i = 10; i < (alignment.getWidth() - 10); i += 10)
+  public String getBioJSONData(AlignExportSettingI exportSettings)
+  {
+    if (!isEmbedData())
     {
-      out.println("<td colspan=\"9\">" + i + "<br>|</td><td></td>");
+      return null;
     }
-
-    out.println("<td colspan=\"3\"></td><td colspan=\"3\">" + i
-            + "<br>|</td>");
-    out.println("</tr>");
-
-    for (i = 0; i < alignment.getHeight(); i++)
+    if (exportSettings == null)
     {
-      seq = alignment.getSequenceAt(i);
-
-      String id = seq.getDisplayId(av.getShowJVSuffix());
-
-      out.println("<tr><td nowrap>" + id + "&nbsp;&nbsp;</td>");
-
-      for (int res = 0; res < seq.getLength(); res++)
+      exportSettings = new AlignExportSettingI()
       {
-        if (!jalview.util.Comparison.isGap(seq.getCharAt(res)))
+        @Override
+        public boolean isExportHiddenSequences()
         {
-          color = sr.getResidueBoxColour(seq, res);
+          return true;
+        }
 
-          color = fr.findFeatureColour(color, seq, res);
+        @Override
+        public boolean isExportHiddenColumns()
+        {
+          return true;
         }
-        else
+
+        @Override
+        public boolean isExportAnnotations()
         {
-          color = Color.white;
+          return true;
         }
 
-        if (color.getRGB() < -1)
+        @Override
+        public boolean isExportFeatures()
         {
-          out.println("<td bgcolor=\"#"
-                  + jalview.util.Format.getHexString(color) + "\">"
-                  + seq.getCharAt(res) + "</td>");
+          return true;
         }
-        else
+
+        @Override
+        public boolean isExportGroups()
         {
-          out.println("<td>" + seq.getCharAt(res) + "</td>");
+          return true;
         }
-      }
 
-      out.println("</tr>");
+        @Override
+        public boolean isCancelled()
+        {
+          return false;
+        }
+      };
     }
-
-    // ////////////
-    out.println("</table>");
-    out.println("</td></tr></table>");
+    AlignmentExportData exportData = jalview.gui.AlignFrame
+            .getAlignmentForExport(JSONFile.FILE_DESC,
+                    ap.getAlignViewport(), exportSettings);
+    String bioJSON = new FormatAdapter(ap, exportData.getSettings())
+            .formatSequences(JSONFile.FILE_DESC, exportData.getAlignment(),
+                    exportData.getOmitHidden(), exportData
+                            .getStartEndPostions(), ap.getAlignViewport()
+                            .getColumnSelection());
+    return bioJSON;
   }
 
-  void drawWrappedAlignment(PrintWriter out)
+  /**
+   * Read a template file content as string
+   * 
+   * @param file
+   *          - the file to be read
+   * @return File content as String
+   * @throws IOException
+   */
+  public static String readFileAsString(File file) throws IOException
   {
-    // //////////////////////////////////
-    // / How many sequences and residues can we fit on a printable page?
-    AlignmentI al = av.getAlignment();
-    SequenceI seq;
-    String r;
-    String g;
-    String b;
-
-    out.println("<table border=\"1\"><tr><td>\n");
-    out.println("<table border=\"0\"  cellpadding=\"0\" cellspacing=\"0\">\n");
-
-    for (int startRes = 0; startRes < al.getWidth(); startRes += av
-            .getWrappedWidth())
+    InputStreamReader isReader = null;
+    BufferedReader buffReader = null;
+    StringBuilder sb = new StringBuilder();
+    Objects.requireNonNull(file, "File must not be null!");
+    @SuppressWarnings("deprecation")
+    URL url = file.toURL();
+    if (url != null)
     {
-      int endRes = startRes + av.getWrappedWidth();
-
-      if (endRes > al.getWidth())
-      {
-        endRes = al.getWidth();
-      }
-
-      if (av.getScaleAboveWrapped())
+      try
       {
-        out.println("<tr>");
-
-        if (av.getScaleLeftWrapped())
-        {
-          out.println("<td colspan=\"7\">&nbsp;</td>");
-        }
-        else
+        isReader = new InputStreamReader(url.openStream());
+        buffReader = new BufferedReader(isReader);
+        String line;
+        String lineSeparator = System.getProperty("line.separator");
+        while ((line = buffReader.readLine()) != null)
         {
-          out.println("<td colspan=\"6\">&nbsp;</td>");
+          sb.append(line).append(lineSeparator);
         }
-
-        for (int i = startRes + 10; i < endRes; i += 10)
-        {
-          out.println("<td colspan=\"9\">" + i + "<br>|</td><td></td>");
-        }
-
-        out.println("</tr>");
-      }
-
-      int startPos, endPos;
-      for (int s = 0; s < al.getHeight(); s++)
+  
+      } catch (Exception ex)
       {
-        out.println("<tr>");
-        seq = al.getSequenceAt(s);
-
-        startPos = seq.findPosition(startRes);
-        endPos = seq.findPosition(endRes) - 1;
-
-        String id = seq.getDisplayId(av.getShowJVSuffix());
-
-        out.println("<td nowrap>" + id + "&nbsp;&nbsp;</td>");
-
-        if (av.getScaleLeftWrapped())
-        {
-          if (startPos > seq.getEnd() || endPos == 0)
-          {
-            out.println("<td nowrap>&nbsp;</td>");
-          }
-          else
-          {
-            out.println("<td nowrap>" + startPos + "&nbsp;&nbsp;</td>");
-          }
-        }
-
-        for (int res = startRes; res < endRes; res++)
-        {
-          if (!jalview.util.Comparison.isGap(seq.getCharAt(res)))
-          {
-            color = sr.getResidueBoxColour(seq, res);
-
-            color = fr.findFeatureColour(color, seq, res);
-          }
-          else
-          {
-            color = Color.white;
-          }
-
-          if (color.getRGB() < -1)
-          {
-            out.println("<td bgcolor=\"#"
-                    + jalview.util.Format.getHexString(color) + "\">"
-                    + seq.getCharAt(res) + "</td>");
-          }
-          else
-          {
-            out.println("<td>" + seq.getCharAt(res) + "</td>");
-          }
-
-        }
-
-        if (av.getScaleRightWrapped()
-                && endRes < startRes + av.getWrappedWidth())
+        ex.printStackTrace();
+      } finally
+      {
+        if (isReader != null)
         {
-          out.println("<td colspan=\""
-                  + (startRes + av.getWrappedWidth() - endRes) + "\">"
-                  + "&nbsp;&nbsp;</td>");
+          isReader.close();
         }
-
-        if (av.getScaleRightWrapped() && startPos < endPos)
+  
+        if (buffReader != null)
         {
-          out.println("<td nowrap>&nbsp;" + endPos + "&nbsp;&nbsp;</td>");
+          buffReader.close();
         }
-
-        out.println("</tr>");
-      }
-
-      if (endRes < al.getWidth())
-      {
-        out.println("<tr><td height=\"5\"></td></tr>");
       }
     }
-
-    out.println("</table>");
-    out.println("</table>");
+    return sb.toString();
   }
 
   public static String getImageMapHTML()
@@ -386,4 +252,122 @@ public class HTMLOutput
                     + "initToolTips(); //--></script>\n");
 
   }
+
+  public String getOutputFile() throws NoFileSelectedException
+  {
+    String selectedFile = null;
+    if (pIndicator != null && !isHeadless())
+    {
+      pIndicator.setProgressBar(MessageManager.formatMessage(
+              "status.waiting_for_user_to_select_output_file", "HTML"),
+              pSessionId);
+    }
+
+    JalviewFileChooser jvFileChooser = new JalviewFileChooser(
+            jalview.bin.Cache.getProperty("LAST_DIRECTORY"),
+            new String[] { "html" }, new String[] { "HTML files" },
+            "HTML files");
+    jvFileChooser.setFileView(new JalviewFileView());
+
+    jvFileChooser.setDialogTitle(MessageManager
+            .getString("label.save_as_html"));
+    jvFileChooser.setToolTipText(MessageManager.getString("action.save"));
+
+    int fileChooserOpt = jvFileChooser.showSaveDialog(null);
+    if (fileChooserOpt == JalviewFileChooser.APPROVE_OPTION)
+    {
+      jalview.bin.Cache.setProperty("LAST_DIRECTORY", jvFileChooser
+              .getSelectedFile().getParent());
+      selectedFile = jvFileChooser.getSelectedFile().getPath();
+    }
+    else
+    {
+      throw new NoFileSelectedException("No file was selected.");
+    }
+    return selectedFile;
+  }
+
+  protected void setProgressMessage(String message)
+  {
+    if (pIndicator != null && !isHeadless())
+    {
+      pIndicator.setProgressBar(message, pSessionId);
+    }
+    else
+    {
+      System.out.println(message);
+    }
+  }
+
+  /**
+   * Answers true if HTML export is invoke in headless mode or false otherwise
+   * 
+   * @return
+   */
+  protected boolean isHeadless()
+  {
+    return System.getProperty("java.awt.headless") != null
+            && System.getProperty("java.awt.headless").equals("true");
+  }
+
+  /**
+   * This method provides implementation of consistent behaviour which should
+   * occur before a HTML file export. It MUST be called at the start of the
+   * exportHTML() method implementation.
+   */
+  protected void exportStarted()
+  {
+    pSessionId = System.currentTimeMillis();
+  }
+
+  /**
+   * This method provides implementation of consistent behaviour which should
+   * occur after a HTML file export. It MUST be called at the end of the
+   * exportHTML() method implementation.
+   */
+  protected void exportCompleted()
+  {
+    if (isLaunchInBrowserAfterExport() && !isHeadless())
+    {
+      try
+      {
+        jalview.util.BrowserLauncher
+                .openURL("file:///" + getExportedFile());
+      } catch (IOException e)
+      {
+        e.printStackTrace();
+      }
+    }
+  }
+
+  /**
+   * if this answers true then BioJSON data will be embedded to the exported
+   * HTML file otherwise it won't be embedded.
+   * 
+   * @return
+   */
+  public abstract boolean isEmbedData();
+
+  /**
+   * if this answers true then the generated HTML file is opened for viewing in
+   * a browser after its generation otherwise it won't be opened in a browser
+   * 
+   * @return
+   */
+  public abstract boolean isLaunchInBrowserAfterExport();
+
+  /**
+   * handle to the generated HTML file
+   * 
+   * @return
+   */
+  public abstract File getExportedFile();
+
+  /**
+   * This is the main method to handle the HTML generation.
+   * 
+   * @param outputFile
+   *          the file path of the generated HTML
+   */
+  public abstract void exportHTML(String outputFile);
 }
index 68173ff..1ec3a4e 100644 (file)
  */
 package jalview.io;
 
-import jalview.api.AlignExportSettingI;
-import jalview.api.FeatureRenderer;
-import jalview.datamodel.AlignmentExportData;
-import jalview.datamodel.SequenceI;
-import jalview.gui.AlignViewport;
+import jalview.exceptions.NoFileSelectedException;
 import jalview.gui.AlignmentPanel;
 import jalview.gui.HTMLOptions;
-import jalview.gui.IProgressIndicator;
 import jalview.gui.OOMWarning;
 import jalview.math.AlignmentDimension;
 import jalview.util.MessageManager;
 
-import java.awt.Color;
-import java.awt.FontMetrics;
 import java.awt.Graphics;
-import java.awt.print.Printable;
 import java.awt.print.PrinterException;
 import java.io.File;
 import java.io.FileOutputStream;
+import java.io.IOException;
 
 import org.jfree.graphics2d.svg.SVGGraphics2D;
 import org.jfree.graphics2d.svg.SVGHints;
 
-public class HtmlSvgOutput
+public class HtmlSvgOutput extends HTMLOutput
 {
-  AlignViewport av;
 
-  FeatureRenderer fr;
 
-  AlignmentPanel ap;
-
-  private IProgressIndicator pIndicator;
-
-  private long pSessionId;
-
-  private boolean headless;
-
-  public HtmlSvgOutput(File file, AlignmentPanel ap)
+  public HtmlSvgOutput(AlignmentPanel ap)
   {
-    this.av = ap.av;
-    this.ap = ap;
-    fr = ap.cloneFeatureRenderer();
-    generateHtmlSvgOutput(file);
+    super(ap);
   }
 
-  public void generateHtmlSvgOutput(File file)
+  @Override
+  public void exportHTML(String outputFile)
   {
-    pIndicator = ap.alignFrame;
-    pSessionId = System.currentTimeMillis();
+    exportStarted();
     try
     {
-      headless = (System.getProperty("java.awt.headless") != null && System
-              .getProperty("java.awt.headless").equals("true"));
-      if (file == null)
+      if (outputFile == null)
       {
-        setProgressMessage(MessageManager.formatMessage(
-                "status.waiting_for_user_to_select_output_file", "HTML"));
-        JalviewFileChooser chooser = getHTMLChooser();
-        chooser.setFileView(new jalview.io.JalviewFileView());
-        chooser.setDialogTitle(ap.alignFrame.getTitle());
-        chooser.setToolTipText(MessageManager.getString("action.save"));
-        int value = chooser.showSaveDialog(ap.alignFrame);
-
-        if (value == jalview.io.JalviewFileChooser.APPROVE_OPTION)
-        {
-          jalview.bin.Cache.setProperty("LAST_DIRECTORY", chooser
-                  .getSelectedFile().getParent());
-          file = chooser.getSelectedFile();
-          ap.alignFrame.repaint();
-        }
-        else
-        {
-          setProgressMessage(MessageManager.formatMessage(
-                  "status.cancelled_image_export_operation", "HTML"));
-          return;
-        }
+        outputFile = getOutputFile();
       }
+      generatedFile = new File(outputFile);
+    } catch (NoFileSelectedException e)
+    {
+      setProgressMessage(MessageManager.formatMessage(
+              "status.cancelled_image_export_operation", "HTML"));
+      return;
     } catch (Exception e)
     {
-      pIndicator.setProgressBar(MessageManager.formatMessage(
-              "info.error_creating_file", "HTML"), pSessionId);
+      setProgressMessage(MessageManager.formatMessage(
+              "info.error_creating_file", "HTML"));
       e.printStackTrace();
       return;
     }
-    final File fileX = file;
-    new Thread()
-    {
-      @Override
-      public void run()
-      {
-        try
-        {
-          setProgressMessage(null);
-          setProgressMessage(MessageManager.formatMessage(
-                  "status.exporting_alignment_as_x_file", "HTML"));
-          AlignmentDimension aDimension = ap.getAlignmentDimension();
-          SVGGraphics2D g1 = new SVGGraphics2D(aDimension.getWidth(),
-                  aDimension.getHeight());
-          SVGGraphics2D g2 = new SVGGraphics2D(aDimension.getWidth(),
-                  aDimension.getHeight());
-
-          String renderStyle = jalview.bin.Cache.getDefault(
-                  "HTML_RENDERING", "Prompt each time");
-
-          // If we need to prompt, and if the GUI is visible then
-          // Prompt for rendering style
-          if (renderStyle.equalsIgnoreCase("Prompt each time")
-                  && !(System.getProperty("java.awt.headless") != null && System
-                          .getProperty("java.awt.headless").equals("true")))
-          {
-            HTMLOptions svgOption = new HTMLOptions();
-            renderStyle = svgOption.getValue();
-
-            if (renderStyle == null || svgOption.cancelled)
-            {
-              setProgressMessage(MessageManager.formatMessage(
-                      "status.cancelled_image_export_operation", "HTML"));
-              return;
-            }
-          }
-
-          if (renderStyle.equalsIgnoreCase("Lineart"))
-          {
-            g1.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
-                    SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
-            g2.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
-                    SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
-          }
-          printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
-                  g1, g2);
-
-          String titleSvgData = g1.getSVGDocument();
-          String alignSvgData = g2.getSVGDocument();
-          String jsonData = null;
-          boolean isEmbbedBioJSON = Boolean.valueOf(jalview.bin.Cache
-                  .getDefault("EXPORT_EMBBED_BIOJSON", "true"));
-          if (isEmbbedBioJSON)
-          {
-            AlignExportSettingI exportSettings = new AlignExportSettingI()
-            {
-              @Override
-              public boolean isExportHiddenSequences()
-              {
-                return true;
-              }
-
-              @Override
-              public boolean isExportHiddenColumns()
-              {
-                return true;
-              }
-
-              @Override
-              public boolean isExportAnnotations()
-              {
-                return true;
-              }
-
-              @Override
-              public boolean isExportFeatures()
-              {
-                return true;
-              }
-
-              @Override
-              public boolean isExportGroups()
-              {
-                return true;
-              }
-
-              @Override
-              public boolean isCancelled()
-              {
-                return false;
-              }
-
-            };
-            AlignmentExportData exportData = jalview.gui.AlignFrame
-                    .getAlignmentForExport(JSONFile.FILE_DESC, av,
-                            exportSettings);
-            jsonData = new FormatAdapter(ap, exportData.getSettings())
-                    .formatSequences(JSONFile.FILE_DESC,
-                            exportData.getAlignment(),
-                            exportData.getOmitHidden(),
-                            exportData.getStartEndPostions(),
-                            av.getColumnSelection());
-          }
-          String htmlData = getHtml(titleSvgData, alignSvgData, jsonData);
-          FileOutputStream out = new FileOutputStream(fileX);
-          out.write(htmlData.getBytes());
-          out.flush();
-          out.close();
-          if (!(System.getProperty("java.awt.headless") != null && System
-                  .getProperty("java.awt.headless").equals("true")))
-          {
-            jalview.util.BrowserLauncher.openURL("file:///" + fileX);
-          }
-        } catch (OutOfMemoryError err)
-        {
-          System.out.println("########################\n"
-                  + "OUT OF MEMORY " + fileX + "\n"
-                  + "########################");
-          new OOMWarning("Creating Image for " + fileX, err);
-        } catch (Exception e)
-        {
-          e.printStackTrace();
-          pIndicator.setProgressBar(MessageManager.formatMessage(
-                  "info.error_creating_file", "HTML"), pSessionId);
-        }
-        setProgressMessage(MessageManager.formatMessage(
-                "status.export_complete", "HTML"));
-      }
-    }.start();
-
+    new Thread(this).start();
   }
 
-  private void setProgressMessage(String message)
-  {
-    if (pIndicator != null && !headless)
-    {
-      pIndicator.setProgressBar(message, pSessionId);
-    }
-    else
-    {
-      System.out.println(message);
-    }
-  }
 
   static JalviewFileChooser getHTMLChooser()
   {
@@ -257,139 +81,22 @@ public class HtmlSvgOutput
             "Hypertext Markup Language");
   }
 
-  public int printUnwrapped(int pwidth, int pheight, int pi, Graphics... pg)
+  public int printUnwrapped(int pwidth, int pheight, int pi,
+          Graphics idGraphics, Graphics alignmentGraphics)
           throws PrinterException
   {
-    int idWidth = ap.getVisibleIdWidth(false);
-    FontMetrics fm = ap.getFontMetrics(av.getFont());
-    int scaleHeight = av.getCharHeight() + fm.getDescent();
-
-    pg[0].setColor(Color.white);
-    pg[0].fillRect(0, 0, pwidth, pheight);
-    pg[0].setFont(av.getFont());
-
-    // //////////////////////////////////
-    // / How many sequences and residues can we fit on a printable page?
-    int totalRes = (pwidth - idWidth) / av.getCharWidth();
-    int totalSeq = (pheight - scaleHeight) / av.getCharHeight() - 1;
-    int pagesWide = (av.getAlignment().getWidth() / totalRes) + 1;
-
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int startRes;
-
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int endRes;
-
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int startSeq;
-
-    // ///////////////////////////
-    // / Only print these sequences and residues on this page
-    int endSeq;
-    startRes = (pi % pagesWide) * totalRes;
-    endRes = (startRes + totalRes) - 1;
-
-    if (endRes > (av.getAlignment().getWidth() - 1))
-    {
-      endRes = av.getAlignment().getWidth() - 1;
-    }
-    startSeq = (pi / pagesWide) * totalSeq;
-    endSeq = startSeq + totalSeq;
-    if (endSeq > av.getAlignment().getHeight())
-    {
-      endSeq = av.getAlignment().getHeight();
-    }
-    int pagesHigh = ((av.getAlignment().getHeight() / totalSeq) + 1)
-            * pheight;
-    if (av.isShowAnnotation())
-    {
-      pagesHigh += ap.getAnnotationPanel().adjustPanelHeight() + 3;
-    }
-    pagesHigh /= pheight;
-    if (pi >= (pagesWide * pagesHigh))
-    {
-      return Printable.NO_SUCH_PAGE;
-    }
-
-    // draw Scale
-    pg[1].translate(0, 0);
-    ap.getScalePanel().drawScale(pg[1], startRes, endRes, pwidth - idWidth,
-            scaleHeight);
-    pg[1].translate(-idWidth, scaleHeight);
-
-    // //////////////
-    // Draw the ids
-    Color currentColor = null;
-    Color currentTextColor = null;
-    pg[0].translate(0, scaleHeight);
-    pg[0].setFont(ap.getIdPanel().getIdCanvas().getIdfont());
-    SequenceI seq;
-    for (int i = startSeq; i < endSeq; i++)
-    {
-      seq = av.getAlignment().getSequenceAt(i);
-      if ((av.getSelectionGroup() != null)
-              && av.getSelectionGroup().getSequences(null).contains(seq))
-      {
-        currentColor = Color.gray;
-        currentTextColor = Color.black;
-      }
-      else
-      {
-        currentColor = av.getSequenceColour(seq);
-        currentTextColor = Color.black;
-      }
-      pg[0].setColor(currentColor);
-      pg[0].fillRect(0, (i - startSeq) * av.getCharHeight(), idWidth,
-              av.getCharHeight());
-      pg[0].setColor(currentTextColor);
-      int xPos = 0;
-      if (av.isRightAlignIds())
-      {
-        fm = pg[0].getFontMetrics();
-        xPos = idWidth
-                - fm.stringWidth(seq.getDisplayId(av.getShowJVSuffix()))
-                - 4;
-      }
-      pg[0].drawString(seq.getDisplayId(av.getShowJVSuffix()), xPos,
-              (((i - startSeq) * av.getCharHeight()) + av.getCharHeight())
-                      - (av.getCharHeight() / 5));
-    }
-    pg[0].setFont(av.getFont());
-    pg[0].translate(idWidth, 0);
-
-    // draw main sequence panel
-    pg[1].translate(idWidth, 0);
-    ap.getSeqPanel().seqCanvas.drawPanel(pg[1], startRes, endRes, startSeq,
-            endSeq, 0);
-    if (av.isShowAnnotation() && (endSeq == av.getAlignment().getHeight()))
-    {
-      // draw annotation label - need to offset for current scroll position
-      int offset = -ap.getAlabels().getScrollOffset();
-      pg[0].translate(0, offset);
-      pg[0].translate(-idWidth - 3,
-              (endSeq - startSeq) * av.getCharHeight() + 3);
-      ap.getAlabels().drawComponent(pg[0], idWidth);
-      pg[0].translate(idWidth + 3, 0);
-      pg[0].translate(0, -offset);
-
-      // draw annotation - need to offset for current scroll position
-      pg[1].translate(0, offset);
-      pg[1].translate(-idWidth - 3,
-              (endSeq - startSeq) * av.getCharHeight() + 3);
-      pg[1].translate(idWidth + 3, 0);
-      ap.getAnnotationPanel().renderer.drawComponent(
-              ap.getAnnotationPanel(), av, pg[1], -1, startRes, endRes + 1);
-      pg[1].translate(0, -offset);
-    }
+    return ap.printUnwrapped(pwidth, pheight, pi, idGraphics,
+            alignmentGraphics);
+  }
 
-    return Printable.PAGE_EXISTS;
+  public int printWrapped(int pwidth, int pheight, int pi, Graphics... pg)
+          throws PrinterException
+  {
+    return ap.printWrappedAlignment(pwidth, pheight, pi, pg[0]);
   }
 
   private String getHtml(String titleSvg, String alignmentSvg,
-          String jsonData)
+          String jsonData, boolean wrapped)
   {
     StringBuilder htmlSvg = new StringBuilder();
     htmlSvg.append("<html>\n");
@@ -429,8 +136,9 @@ public class HtmlSvgOutput
               + ".facebox_hide { z-index:-100; }\n"
               + ".facebox_overlayBG { background-color: #000;  z-index: 99;  }");
     }
-
     htmlSvg.append("</style>");
+    if (!wrapped)
+    {
     htmlSvg.append("<div class=\"main-container\" \n>");
     htmlSvg.append("<div class=\"titlex\">\n");
     htmlSvg.append("<div class=\"sub-category-container\"> \n");
@@ -451,9 +159,16 @@ public class HtmlSvgOutput
             + "subCatContainer.scrollTop($(this).scrollTop());\n});\n");
 
     htmlSvg.append("</script>\n");
+    }
+    else
+    {
+      htmlSvg.append("<div>\n")
+              .append(alignmentSvg).append("</div>");
+      htmlSvg.append("<script language=\"JavaScript\" type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js\"></script>\n"
+              + "<script language=\"JavaScript\" type=\"text/javascript\"  src=\"http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.2/jquery-ui.min.js\"></script>\n");
+    }
 
     // javascript for launching file in Jalview
-
     htmlSvg.append("<script language=\"JavaScript\">\n");
     htmlSvg.append("function openJalviewUsingCurrentUrl(){\n");
     htmlSvg.append("    var json = JSON.parse(document.getElementById(\"seqData\").innerHTML);\n");
@@ -478,269 +193,115 @@ public class HtmlSvgOutput
     htmlSvg.append("    document.body.removeChild(myForm);\n");
     htmlSvg.append("}\n");
 
-    // jquery facebox for displaying raw BioJSON data");
     if (jsonData != null)
     {
-      htmlSvg.append("/* Facebox (for jQuery)\n");
-      htmlSvg.append("* version: 1.3\n");
-      htmlSvg.append(" * @requires jQuery v1.2 or later\n");
-      htmlSvg.append(" * @homepage https://github.com/defunkt/facebox\n");
-      htmlSvg.append(" * Licensed under the MIT:\n");
-      htmlSvg.append(" *   http://www.opensource.org/licenses/mit-license.php\n");
-      htmlSvg.append(" * Copyright Forever Chris Wanstrath, Kyle Neath\n");
-      htmlSvg.append(" * Usage:\n");
-      htmlSvg.append(" *  jQuery(document).ready(function() {\n");
-      htmlSvg.append(" *    jQuery('a[rel*=facebox]').facebox()\n");
-      htmlSvg.append(" *  })\n");
-      htmlSvg.append(" *  <a href=\"#terms\" rel=\"facebox\">Terms</a>\n");
-      htmlSvg.append(" *    Loads the #terms div in the box\n");
-      htmlSvg.append(" *  <a href=\"terms.html\" rel=\"facebox\">Terms</a>\n");
-      htmlSvg.append(" *    Loads the terms.html page in the box\n");
-      htmlSvg.append(" *  <a href=\"terms.png\" rel=\"facebox\">Terms</a>\n");
-      htmlSvg.append(" *    Loads the terms.png image in the box\n");
-      htmlSvg.append(" *  You can also use it programmatically:\n");
-      htmlSvg.append(" *    jQuery.facebox('some html')\n");
-      htmlSvg.append(" *    jQuery.facebox('some html', 'my-groovy-style')\n");
-      htmlSvg.append(" *  The above will open a facebox with \"some html\" as the content.\n");
-      htmlSvg.append(" *    jQuery.facebox(function($) {\n");
-      htmlSvg.append(" *      $.get('blah.html', function(data) { $.facebox(data) })\n");
-      htmlSvg.append(" *    })\n");
-      htmlSvg.append(" *  The above will show a loading screen before the passed function is called,\n");
-      htmlSvg.append(" *  allowing for a better ajaxy experience.\n");
-      htmlSvg.append(" *  The facebox function can also display an ajax page, an image, or the contents of a div:\n");
-      htmlSvg.append(" *    jQuery.facebox({ ajax: 'remote.html' })\n");
-      htmlSvg.append(" *    jQuery.facebox({ ajax: 'remote.html' }, 'my-groovy-style')\n");
-      htmlSvg.append(" *    jQuery.facebox({ image: 'stairs.jpg' })\n");
-      htmlSvg.append(" *    jQuery.facebox({ image: 'stairs.jpg' }, 'my-groovy-style')\n");
-      htmlSvg.append(" *    jQuery.facebox({ div: '#box' })\n");
-      htmlSvg.append(" *    jQuery.facebox({ div: '#box' }, 'my-groovy-style')\n");
-      htmlSvg.append(" *    Want to close the facebox?  Trigger the 'close.facebox' document event:\n");
-      htmlSvg.append(" *    jQuery(document).trigger('close.facebox')\n");
-      htmlSvg.append(" *  Facebox also has a bunch of other hooks:\n");
-      htmlSvg.append(" *    loading.facebox\n");
-      htmlSvg.append(" *    beforeReveal.facebox\n");
-      htmlSvg.append(" *    reveal.facebox (aliased as 'afterReveal.facebox')\n");
-      htmlSvg.append(" *    init.facebox\n");
-      htmlSvg.append(" *    afterClose.facebox\n");
-      htmlSvg.append(" *  Simply bind a function to any of these hooks:\n");
-      htmlSvg.append(" *   $(document).bind('reveal.facebox', function() { ...stuff to do after the facebox and contents are revealed... })\n");
-      htmlSvg.append(" *\n");
-      htmlSvg.append(" */\n");
-      htmlSvg.append("(function($) {\n");
-      htmlSvg.append("  $.facebox = function(data, klass) {\n");
-      htmlSvg.append("    $.facebox.loading()\n");
-      htmlSvg.append("    if (data.ajax) fillFaceboxFromAjax(data.ajax, klass)\n");
-      htmlSvg.append("    else if (data.image) fillFaceboxFromImage(data.image, klass)\n");
-      htmlSvg.append("    else if (data.div) fillFaceboxFromHref(data.div, klass)\n");
-      htmlSvg.append("    else if ($.isFunction(data)) data.call($)\n");
-      htmlSvg.append("    else $.facebox.reveal(data, klass)\n");
-      htmlSvg.append("  }\n");
-
-      htmlSvg.append("  $.extend($.facebox, {\n");
-      htmlSvg.append("    settings: {\n");
-      htmlSvg.append("      opacity      : 0.2,\n");
-      htmlSvg.append("      overlay      : true,\n");
-      htmlSvg.append("      loadingImage : 'https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/loading.gif',\n");
-      htmlSvg.append("      closeImage   : 'https://raw.githubusercontent.com/jalview/biojson/gh-pages/images/cancel.png',\n");
-      htmlSvg.append("      imageTypes   : [ 'png', 'jpg', 'jpeg', 'gif' ],\n");
-      htmlSvg.append("      faceboxHtml  : '<div  id=\"facebox\" style=\"display:none; width: 95%; height: 85%; overflow: auto;\"> ");
-      htmlSvg.append("      <div class=\"popup\"> ");
-      htmlSvg.append("        <div class=\"content\"> ");
-      htmlSvg.append("        </div> ");
-      htmlSvg.append("        <a href=\"#\" class=\"close\"></a> ");
-      htmlSvg.append("      </div> ");
-      htmlSvg.append("    </div>'\n");
-      htmlSvg.append("    },      \n");
-      htmlSvg.append("    loading: function() {\n");
-      htmlSvg.append("      init()\n");
-      htmlSvg.append("      if ($('#facebox .loading').length == 1) return true\n");
-      htmlSvg.append("      showOverlay()      \n");
-      htmlSvg.append("      $('#facebox .content').empty().\n");
-      htmlSvg.append("        append('<div class=\"loading\"><img src=\"'+$.facebox.settings.loadingImage+'\"/></div>')\n");
-      htmlSvg.append("      $('#facebox').show().css({\n");
-      htmlSvg.append("        top:    getPageScroll()[1] + (getPageHeight() / 10),\n");
-      htmlSvg.append("        left:    $(window).width() / 2 - ($('#facebox .popup').outerWidth() / 2)\n");
-      htmlSvg.append("      })      \n");
-      htmlSvg.append("      $(document).bind('keydown.facebox', function(e) {\n");
-      htmlSvg.append("       if (e.keyCode == 27) $.facebox.close()\n");
-      htmlSvg.append("        return true\n");
-      htmlSvg.append("      })\n");
-      htmlSvg.append("      $(document).trigger('loading.facebox')\n");
-      htmlSvg.append("    },\n");
-      htmlSvg.append("    reveal: function(data, klass) {\n");
-      htmlSvg.append("      $(document).trigger('beforeReveal.facebox')\n");
-      htmlSvg.append("      if (klass) $('#facebox .content').addClass(klass)\n");
-      htmlSvg.append("      $('#facebox .content').empty().append('<pre><code>'+JSON.stringify(JSON.parse(data),null,4)+'</pre></code>')\n");
-      htmlSvg.append("      $('#facebox .popup').children().fadeIn('normal')\n");
-      htmlSvg.append("      $('#facebox').css('left', $(window).width() / 2 - ($('#facebox .popup').outerWidth() / 2))\n");
-      htmlSvg.append("      $(document).trigger('reveal.facebox').trigger('afterReveal.facebox')\n");
-      htmlSvg.append("    },      \n");
-      htmlSvg.append("    close: function() {\n");
-      htmlSvg.append("      $(document).trigger('close.facebox')\n");
-      htmlSvg.append("      return false\n");
-      htmlSvg.append("    }\n");
-      htmlSvg.append("  })\n");
-      htmlSvg.append("  $.fn.facebox = function(settings) {\n");
-      htmlSvg.append("    if ($(this).length == 0) return    \n");
-      htmlSvg.append("    init(settings)      \n");
-      htmlSvg.append("    function clickHandler() {\n");
-      htmlSvg.append("      $.facebox.loading(true)      \n");
-      htmlSvg.append("      // support for rel=\"facebox.inline_popup\" syntax, to add a class\n");
-      htmlSvg.append("      // also supports deprecated \"facebox[.inline_popup]\" syntax\n");
-      htmlSvg.append("      var klass = this.rel.match(/facebox\\[?\\.(\\w+)\\]?/)\n");
-      htmlSvg.append("      if (klass) klass = klass[1]\n");
-      htmlSvg.append("      fillFaceboxFromHref(this.href, klass)\n");
-      htmlSvg.append("      return false\n");
-      htmlSvg.append("    }      \n");
-      htmlSvg.append("    return this.bind('click.facebox', clickHandler)\n");
-      htmlSvg.append("  }\n");
-      htmlSvg.append("  // called one time to setup facebox on this page\n");
-      htmlSvg.append("  function init(settings) {\n");
-      htmlSvg.append("    if ($.facebox.settings.inited) return true\n");
-      htmlSvg.append("    else $.facebox.settings.inited = true\n");
-      htmlSvg.append("    $(document).trigger('init.facebox')\n");
-      htmlSvg.append("    makeCompatible()\n");
-      htmlSvg.append("    var imageTypes = $.facebox.settings.imageTypes.join('|')\n");
-      htmlSvg.append("    $.facebox.settings.imageTypesRegexp = new RegExp('\\\\.(' + imageTypes + ')(\\\\?.*)?$', 'i')\n");
-
-      htmlSvg.append("    if (settings) $.extend($.facebox.settings, settings)\n");
-      htmlSvg.append("    $('body').append($.facebox.settings.faceboxHtml)\n");
-
-      htmlSvg.append("    var preload = [ new Image(), new Image() ]\n");
-      htmlSvg.append("    preload[0].src = $.facebox.settings.closeImage\n");
-      htmlSvg.append("    preload[1].src = $.facebox.settings.loadingImage\n");
-
-      htmlSvg.append("    $('#facebox').find('.b:first, .bl').each(function() {\n");
-      htmlSvg.append("      preload.push(new Image())\n");
-      htmlSvg.append("      preload.slice(-1).src = $(this).css('background-image').replace(/url\\((.+)\\)/, '$1')\n");
-      htmlSvg.append("    })\n");
-
-      htmlSvg.append("    $('#facebox .close')\n");
-      htmlSvg.append("      .click($.facebox.close)\n");
-      htmlSvg.append("      .append('<img src=\"'\n");
-      htmlSvg.append("              + $.facebox.settings.closeImage\n");
-      htmlSvg.append("              + '\" class=\"close_image\" title=\"close\">')\n");
-      htmlSvg.append("  }\n");
-
-      htmlSvg.append("  // getPageScroll() by quirksmode.com\n");
-      htmlSvg.append("  function getPageScroll() {\n");
-      htmlSvg.append("    var xScroll, yScroll;\n");
-      htmlSvg.append("    if (self.pageYOffset) {\n");
-      htmlSvg.append("      yScroll = self.pageYOffset;\n");
-      htmlSvg.append("      xScroll = self.pageXOffset;\n");
-      htmlSvg.append("    } else if (document.documentElement && document.documentElement.scrollTop) {     // Explorer 6 Strict\n");
-      htmlSvg.append("      yScroll = document.documentElement.scrollTop;\n");
-      htmlSvg.append("      xScroll = document.documentElement.scrollLeft;\n");
-      htmlSvg.append("    } else if (document.body) {// all other Explorers\n");
-      htmlSvg.append("      yScroll = document.body.scrollTop;\n");
-      htmlSvg.append("      xScroll = document.body.scrollLeft;\n");
-      htmlSvg.append("    }\n");
-      htmlSvg.append("    return new Array(xScroll,yScroll)\n");
-      htmlSvg.append("  }\n");
-
-      // Adapted from getPageSize() by quirksmode.com");
-      htmlSvg.append("  function getPageHeight() {\n");
-      htmlSvg.append("    var windowHeight\n");
-      htmlSvg.append("    if (self.innerHeight) {    // all except Explorer\n");
-      htmlSvg.append("      windowHeight = self.innerHeight;\n");
-      htmlSvg.append("    } else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode\n");
-      htmlSvg.append("      windowHeight = document.documentElement.clientHeight;\n");
-      htmlSvg.append("    } else if (document.body) { // other Explorers\n");
-      htmlSvg.append("      windowHeight = document.body.clientHeight;\n");
-      htmlSvg.append("    }\n");
-      htmlSvg.append("    return windowHeight\n");
-      htmlSvg.append("  }\n");
-
-      htmlSvg.append("  // Backwards compatibility\n");
-      htmlSvg.append("  function makeCompatible() {\n");
-      htmlSvg.append("    var $s = $.facebox.settings      \n");
-      htmlSvg.append("    $s.loadingImage = $s.loading_image || $s.loadingImage\n");
-      htmlSvg.append("    $s.closeImage = $s.close_image || $s.closeImage\n");
-      htmlSvg.append("    $s.imageTypes = $s.image_types || $s.imageTypes\n");
-      htmlSvg.append("    $s.faceboxHtml = $s.facebox_html || $s.faceboxHtml\n");
-      htmlSvg.append("  }\n");
-
-      htmlSvg.append("  // Figures out what you want to display and displays it\n");
-      htmlSvg.append("  // formats are:\n");
-      htmlSvg.append("  //     div: #id\n");
-      htmlSvg.append("  //   image: blah.extension\n");
-      htmlSvg.append("  //    ajax: anything else\n");
-      htmlSvg.append("  function fillFaceboxFromHref(href, klass) {\n");
-      htmlSvg.append("    // div\n");
-      htmlSvg.append("    if (href.match(/#/)) {\n");
-      htmlSvg.append("      var url    = window.location.href.split('#')[0]\n");
-      htmlSvg.append("      var target = href.replace(url,'')\n");
-      htmlSvg.append("      if (target == '#') return\n");
-      htmlSvg.append("      $.facebox.reveal($(target).html(), klass)\n");
-
-      htmlSvg.append("    // image\n");
-      htmlSvg.append("    } else if (href.match($.facebox.settings.imageTypesRegexp)) {\n");
-      htmlSvg.append("      fillFaceboxFromImage(href, klass)\n");
-      htmlSvg.append("    // ajax\n");
-      htmlSvg.append("    } else {\n");
-      htmlSvg.append("      fillFaceboxFromAjax(href, klass)\n");
-      htmlSvg.append("    }\n");
-      htmlSvg.append("  }\n");
-
-      htmlSvg.append("  function fillFaceboxFromImage(href, klass) {\n");
-      htmlSvg.append("    var image = new Image()\n");
-      htmlSvg.append("    image.onload = function() {\n");
-      htmlSvg.append("      $.facebox.reveal('<div class=\"image\"><img src=\"' + image.src + '\" /></div>', klass)\n");
-      htmlSvg.append("    }\n");
-      htmlSvg.append("    image.src = href\n");
-      htmlSvg.append("   }\n");
-
-      htmlSvg.append("  function fillFaceboxFromAjax(href, klass) {\n");
-      htmlSvg.append("    $.facebox.jqxhr = $.get(href, function(data) { $.facebox.reveal(data, klass) })\n");
-      htmlSvg.append("  }\n");
+      // JQuery FaceBox for displaying raw BioJSON data");
+      File faceBoxJsFile = new File("examples/javascript/facebox-1.3.js");
+      try
+      {
+        htmlSvg.append(HTMLOutput.readFileAsString(faceBoxJsFile));
+      } catch (IOException e)
+      {
+        e.printStackTrace();
+      }
+    }
 
-      htmlSvg.append("  function skipOverlay() {\n");
-      htmlSvg.append("    return $.facebox.settings.overlay == false || $.facebox.settings.opacity === null\n");
-      htmlSvg.append("  }\n");
+    htmlSvg.append("</script>\n");
+    htmlSvg.append("</html>");
+    return htmlSvg.toString();
+  }
 
-      htmlSvg.append("  function showOverlay() {\n");
-      htmlSvg.append("    if (skipOverlay()) return\n");
+  @Override
+  public boolean isEmbedData()
+  {
+    return Boolean.valueOf(jalview.bin.Cache.getDefault(
+            "EXPORT_EMBBED_BIOJSON", "true"));
+  }
 
-      htmlSvg.append("    if ($('#facebox_overlay').length == 0)\n");
-      htmlSvg.append("      $(\"body\").append('<div id=\"facebox_overlay\" class=\"facebox_hide\"></div>')\n");
+  @Override
+  public boolean isLaunchInBrowserAfterExport()
+  {
+    return true;
+  }
 
-      htmlSvg.append("    $('#facebox_overlay').hide().addClass(\"facebox_overlayBG\")\n");
-      htmlSvg.append("      .css('opacity', $.facebox.settings.opacity)\n");
-      htmlSvg.append("      .click(function() { $(document).trigger('close.facebox') })\n");
-      htmlSvg.append("       .fadeIn(200)\n");
-      htmlSvg.append("    return false\n");
-      htmlSvg.append("  }\n");
+  @Override
+  public File getExportedFile()
+  {
+    return generatedFile;
+  }
 
-      htmlSvg.append("  function hideOverlay() {\n");
-      htmlSvg.append("    if (skipOverlay()) return      \n");
-      htmlSvg.append("    $('#facebox_overlay').fadeOut(200, function(){\n");
-      htmlSvg.append("      $(\"#facebox_overlay\").removeClass(\"facebox_overlayBG\")\n");
-      htmlSvg.append("      $(\"#facebox_overlay\").addClass(\"facebox_hide\")\n");
-      htmlSvg.append("      $(\"#facebox_overlay\").remove()\n");
-      htmlSvg.append("    })      \n");
-      htmlSvg.append("    return false\n");
-      htmlSvg.append("  }\n");
+  @Override
+  public void run()
+  {
+    try
+    {
+      setProgressMessage(null);
+      setProgressMessage(MessageManager.formatMessage(
+              "status.exporting_alignment_as_x_file", "HTML"));
+      AlignmentDimension aDimension = ap.getAlignmentDimension();
+      SVGGraphics2D idPanelGraphics = new SVGGraphics2D(
+              aDimension.getWidth(), aDimension.getHeight());
+      SVGGraphics2D alignPanelGraphics = new SVGGraphics2D(
+              aDimension.getWidth(), aDimension.getHeight());
+
+      String renderStyle = jalview.bin.Cache.getDefault("HTML_RENDERING",
+              "Prompt each time");
+
+      // If we need to prompt, and if the GUI is visible then
+      // Prompt for rendering style
+      if (renderStyle.equalsIgnoreCase("Prompt each time") && !isHeadless())
+      {
+        HTMLOptions svgOption = new HTMLOptions();
+        renderStyle = svgOption.getValue();
 
-      htmlSvg.append("  $(document).bind('close.facebox', function() {\n");
-      htmlSvg.append("    if ($.facebox.jqxhr) {\n");
-      htmlSvg.append("      $.facebox.jqxhr.abort()\n");
-      htmlSvg.append("      $.facebox.jqxhr = null\n");
-      htmlSvg.append("    }\n");
-      htmlSvg.append("    $(document).unbind('keydown.facebox')\n");
-      htmlSvg.append("    $('#facebox').fadeOut(function() {\n");
-      htmlSvg.append("      $('#facebox .content').removeClass().addClass('content')\n");
-      htmlSvg.append("      $('#facebox .loading').remove()\n");
-      htmlSvg.append("      $(document).trigger('afterClose.facebox')\n");
-      htmlSvg.append("    })\n");
-      htmlSvg.append("    hideOverlay()\n");
-      htmlSvg.append("  })\n");
+        if (renderStyle == null || svgOption.cancelled)
+        {
+          setProgressMessage(MessageManager.formatMessage(
+                  "status.cancelled_image_export_operation", "HTML"));
+          return;
+        }
+      }
 
-      htmlSvg.append("})(jQuery);\n");
+      if (renderStyle.equalsIgnoreCase("Lineart"))
+      {
+        idPanelGraphics.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
+                SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
+        alignPanelGraphics.setRenderingHint(SVGHints.KEY_DRAW_STRING_TYPE,
+                SVGHints.VALUE_DRAW_STRING_TYPE_VECTOR);
+      }
+      if (ap.av.getWrapAlignment())
+      {
+        printWrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
+                alignPanelGraphics);
+      }
+      else
+      {
+        printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0,
+                idPanelGraphics, alignPanelGraphics);
+      }
 
+      String idPanelSvgData = idPanelGraphics.getSVGDocument();
+      String alignPanelSvgData = alignPanelGraphics.getSVGDocument();
+      String jsonData = getBioJSONData();
+      String htmlData = getHtml(idPanelSvgData, alignPanelSvgData,
+              jsonData, ap.av.getWrapAlignment());
+      FileOutputStream out = new FileOutputStream(generatedFile);
+      out.write(htmlData.getBytes());
+      out.flush();
+      out.close();
+      setProgressMessage(MessageManager.formatMessage(
+              "status.export_complete", "HTML"));
+      exportCompleted();
+    } catch (OutOfMemoryError err)
+    {
+      System.out.println("########################\n" + "OUT OF MEMORY "
+              + generatedFile + "\n" + "########################");
+      new OOMWarning("Creating Image for " + generatedFile, err);
+    } catch (Exception e)
+    {
+      e.printStackTrace();
+      setProgressMessage(MessageManager.formatMessage(
+              "info.error_creating_file", "HTML"));
     }
-
-    htmlSvg.append("</script>\n");
-    htmlSvg.append("</html>");
-    return htmlSvg.toString();
   }
 }
index d5593e3..3feae5d 100755 (executable)
@@ -192,13 +192,13 @@ public class JnetAnnotationMaker
           if (id.equals("JNETCONF"))
           {
             annot = new AlignmentAnnotation(preds[i].getName(),
-                    "JNet Output", annotations, 0f, 10f,
+                    "JPred Output", annotations, 0f, 10f,
                     AlignmentAnnotation.BAR_GRAPH);
           }
           else
           {
             annot = new AlignmentAnnotation(preds[i].getName(),
-                    "JNet Output", annotations);
+                    "JPred Output", annotations);
           }
 
           if (seqRef != null)
index 07b88bf..6c8f40f 100644 (file)
 package jalview.io;
 
 import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.io.gff.GffConstants;
-import jalview.util.DBRefUtils;
+import jalview.util.MessageManager;
 import jalview.util.UrlLink;
 
-import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -38,8 +42,69 @@ import java.util.Map;
  */
 public class SequenceAnnotationReport
 {
+  private static final String COMMA = ",";
+
+  private static final String ELLIPSIS = "...";
+
+  private static final int MAX_REFS_PER_SOURCE = 4;
+
+  private static final int MAX_SOURCES = 40;
+
+  private static final String[][] PRIMARY_SOURCES = new String[][] {
+      DBRefSource.CODINGDBS, DBRefSource.DNACODINGDBS,
+      DBRefSource.PROTEINDBS };
+
   final String linkImageURL;
 
+  /*
+   * Comparator to order DBRefEntry by Source + accession id (case-insensitive)
+   */
+  private static Comparator<DBRefEntry> comparator = new Comparator<DBRefEntry>()
+  {
+
+    @Override
+    public int compare(DBRefEntry ref1, DBRefEntry ref2)
+    {
+      String s1 = ref1.getSource();
+      String s2 = ref2.getSource();
+      boolean s1Primary = isPrimarySource(s1);
+      boolean s2Primary = isPrimarySource(s2);
+      if (s1Primary && !s2Primary)
+      {
+        return -1;
+      }
+      if (!s1Primary && s2Primary)
+      {
+        return 1;
+      }
+      int comp = s1 == null ? -1 : (s2 == null ? 1 : s1
+              .compareToIgnoreCase(s2));
+      if (comp == 0)
+      {
+        String a1 = ref1.getAccessionId();
+        String a2 = ref2.getAccessionId();
+        comp = a1 == null ? -1 : (a2 == null ? 1 : a1
+                .compareToIgnoreCase(a2));
+      }
+      return comp;
+    }
+
+    private boolean isPrimarySource(String source)
+    {
+      for (String[] primary : PRIMARY_SOURCES)
+      {
+        for (String s : primary)
+        {
+          if (source.equals(s))
+          {
+            return true;
+          }
+        }
+      }
+      return false;
+    }
+  };
+
   public SequenceAnnotationReport(String linkImageURL)
   {
     this.linkImageURL = linkImageURL;
@@ -48,37 +113,35 @@ public class SequenceAnnotationReport
   /**
    * Append text for the list of features to the tooltip
    * 
-   * @param tooltipText2
+   * @param sb
    * @param rpos
    * @param features
    * @param minmax
    */
-  public void appendFeatures(final StringBuffer tooltipText2, int rpos,
+  public void appendFeatures(final StringBuilder sb, int rpos,
           List<SequenceFeature> features, Map<String, float[][]> minmax)
   {
     if (features != null)
     {
       for (SequenceFeature feature : features)
       {
-        appendFeature(tooltipText2, rpos, minmax, feature);
+        appendFeature(sb, rpos, minmax, feature);
       }
     }
   }
 
   /**
-   * Appends text for one sequence feature to the string buffer
+   * Appends the feature at rpos to the given buffer
    * 
    * @param sb
    * @param rpos
    * @param minmax
-   *          {{min, max}, {min, max}} positional and non-positional feature
-   *          scores for this type
    * @param feature
    */
-  void appendFeature(final StringBuffer sb, int rpos,
+  void appendFeature(final StringBuilder sb, int rpos,
           Map<String, float[][]> minmax, SequenceFeature feature)
   {
-    if ("disulfide bond".equals(feature.getType()))
+    if (feature.isContactFeature())
     {
       if (feature.getBegin() == rpos || feature.getEnd() == rpos)
       {
@@ -86,7 +149,8 @@ public class SequenceAnnotationReport
         {
           sb.append("<br>");
         }
-        sb.append("disulfide bond ").append(feature.getBegin()).append(":")
+        sb.append(feature.getType()).append(" ").append(feature.getBegin())
+                .append(":")
                 .append(feature.getEnd());
       }
     }
@@ -108,7 +172,7 @@ public class SequenceAnnotationReport
         }
         if (feature.begin != feature.end)
         {
-          sb.append(" " + feature.end);
+          sb.append(" ").append(feature.end);
         }
 
         if (feature.getDescription() != null
@@ -116,13 +180,12 @@ public class SequenceAnnotationReport
         {
           String tmpString = feature.getDescription();
           String tmp2up = tmpString.toUpperCase();
-          final int startTag = tmp2up.indexOf("<HTML>");
+          int startTag = tmp2up.indexOf("<HTML>");
           if (startTag > -1)
           {
             tmpString = tmpString.substring(startTag + 6);
             tmp2up = tmp2up.substring(startTag + 6);
           }
-          // TODO strips off </body> but not <body> - is that intended?
           int endTag = tmp2up.indexOf("</BODY>");
           if (endTag > -1)
           {
@@ -147,7 +210,9 @@ public class SequenceAnnotationReport
               // be used, so we must remove < > symbols
               tmpString = tmpString.replaceAll("<", "&lt;");
               tmpString = tmpString.replaceAll(">", "&gt;");
-              sb.append("; ").append(tmpString);
+
+              sb.append("; ");
+              sb.append(tmpString);
             }
             else
             {
@@ -155,11 +220,7 @@ public class SequenceAnnotationReport
             }
           }
         }
-
-        /*
-         * score should be shown if there is one, and min != max
-         * for this feature type (e.g. not all 0)
-         */
+        // check score should be shown
         if (!Float.isNaN(feature.getScore()))
         {
           float[][] rng = (minmax == null) ? null : minmax.get(feature
@@ -182,7 +243,6 @@ public class SequenceAnnotationReport
         }
       }
     }
-    appendLinks(sb, feature);
   }
 
   /**
@@ -206,16 +266,17 @@ public class SequenceAnnotationReport
         {
           try
           {
-            for (String[] urllink : createLinksFrom(null, urlstring))
+            for (List<String> urllink : createLinksFrom(null, urlstring))
             {
               sb.append("<br/> <a href=\""
-                      + urllink[3]
+                      + urllink.get(3)
                       + "\" target=\""
-                      + urllink[0]
+                      + urllink.get(0)
                       + "\">"
-                      + (urllink[0].toLowerCase().equals(
-                              urllink[1].toLowerCase()) ? urllink[0]
-                              : (urllink[0] + ":" + urllink[1]))
+                      + (urllink.get(0).toLowerCase()
+                              .equals(urllink.get(1).toLowerCase()) ? urllink
+                              .get(0) : (urllink.get(0) + ":" + urllink
+                              .get(1)))
                       + "</a></br>");
             }
           } catch (Exception x)
@@ -234,146 +295,60 @@ public class SequenceAnnotationReport
    * 
    * @param seq
    * @param link
-   * @return String[][] { String[] { link target, link label, dynamic component
-   *         inserted (if any), url }}
+   * @return Collection< List<String> > { List<String> { link target, link
+   *         label, dynamic component inserted (if any), url }}
    */
-  String[][] createLinksFrom(SequenceI seq, String link)
+  Collection<List<String>> createLinksFrom(SequenceI seq, String link)
   {
-    List<String[]> urlSets = new ArrayList<String[]>();
-    List<String> uniques = new ArrayList<String>();
+    Map<String, List<String>> urlSets = new LinkedHashMap<String, List<String>>();
     UrlLink urlLink = new UrlLink(link);
     if (!urlLink.isValid())
     {
       System.err.println(urlLink.getInvalidMessage());
       return null;
     }
-    if (seq != null && urlLink.isDynamic())
-    {
-      urlSets.addAll(createDynamicLinks(seq, urlLink, uniques));
-    }
-    else
-    {
-      String target = urlLink.getTarget();
-      String label = urlLink.getLabel();
-      String unq = label + "|" + urlLink.getUrl_prefix();
-      if (!uniques.contains(unq))
-      {
-        uniques.add(unq);
-        urlSets.add(new String[] { target, label, null,
-            urlLink.getUrl_prefix() });
-      }
-    }
 
-    return urlSets.toArray(new String[][] {});
-  }
+    urlLink.createLinksFromSeq(seq, urlSets);
 
-  /**
-   * Formats and returns a list of dynamic href links
-   * 
-   * @param seq
-   * @param urlLink
-   * @param uniques
-   */
-  List<String[]> createDynamicLinks(SequenceI seq, UrlLink urlLink,
-          List<String> uniques)
-  {
-    List<String[]> result = new ArrayList<String[]>();
-    final String target = urlLink.getTarget();
-    final String label = urlLink.getLabel();
-
-    // collect matching db-refs
-    DBRefEntry[] dbr = DBRefUtils.selectRefs(seq.getDBRefs(),
-            new String[] { target });
-    // collect id string too
-    String id = seq.getName();
-    String descr = seq.getDescription();
-    if (descr != null && descr.length() < 1)
-    {
-      descr = null;
-    }
-    if (dbr != null)
-    {
-      for (int r = 0; r < dbr.length; r++)
-      {
-        if (id != null && dbr[r].getAccessionId().equals(id))
-        {
-          // suppress duplicate link creation for the bare sequence ID
-          // string with this link
-          id = null;
-        }
-        // create Bare ID link for this URL
-        String[] urls = urlLink.makeUrls(dbr[r].getAccessionId(), true);
-        if (urls != null)
-        {
-          for (int u = 0; u < urls.length; u += 2)
-          {
-            String unq = urls[u] + "|" + urls[u + 1];
-            if (!uniques.contains(unq))
-            {
-              result.add(new String[] { target, label, urls[u], urls[u + 1] });
-              uniques.add(unq);
-            }
-          }
-        }
-      }
-    }
-    if (id != null)
-    {
-      // create Bare ID link for this URL
-      String[] urls = urlLink.makeUrls(id, true);
-      if (urls != null)
-      {
-        for (int u = 0; u < urls.length; u += 2)
-        {
-          String unq = urls[u] + "|" + urls[u + 1];
-          if (!uniques.contains(unq))
-          {
-            result.add(new String[] { target, label, urls[u], urls[u + 1] });
-            uniques.add(unq);
-          }
-        }
-      }
-    }
-    if (descr != null && urlLink.getRegexReplace() != null)
-    {
-      // create link for this URL from description only if regex matches
-      String[] urls = urlLink.makeUrls(descr, true);
-      if (urls != null)
-      {
-        for (int u = 0; u < urls.length; u += 2)
-        {
-          String unq = urls[u] + "|" + urls[u + 1];
-          if (!uniques.contains(unq))
-          {
-            result.add(new String[] { target, label, urls[u], urls[u + 1] });
-            uniques.add(unq);
-          }
-        }
-      }
-    }
-    return result;
+    return urlSets.values();
   }
 
-  public void createSequenceAnnotationReport(final StringBuffer tip,
+  public void createSequenceAnnotationReport(final StringBuilder tip,
           SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
           Map<String, float[][]> minmax)
   {
     createSequenceAnnotationReport(tip, sequence, showDbRefs, showNpFeats,
-            true, minmax);
+            minmax, false);
   }
 
-  public void createSequenceAnnotationReport(final StringBuffer tip,
+  /**
+   * Builds an html formatted report of sequence details and appends it to the
+   * provided buffer.
+   * 
+   * @param sb
+   *          buffer to append report to
+   * @param sequence
+   *          the sequence the report is for
+   * @param showDbRefs
+   *          whether to include database references for the sequence
+   * @param showNpFeats
+   *          whether to include non-positional sequence features
+   * @param minmax
+   * @param summary
+   * @return
+   */
+  int createSequenceAnnotationReport(final StringBuilder sb,
           SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
-          boolean tableWrap, Map<String, float[][]> minmax)
+          Map<String, float[][]> minmax, boolean summary)
   {
     String tmp;
-    tip.append("<i>");
+    sb.append("<i>");
 
     int maxWidth = 0;
     if (sequence.getDescription() != null)
     {
       tmp = sequence.getDescription();
-      tip.append("<br>" + tmp);
+      sb.append("<br>").append(tmp);
       maxWidth = Math.max(maxWidth, tmp.length());
     }
     SequenceI ds = sequence;
@@ -384,16 +359,81 @@ public class SequenceAnnotationReport
     DBRefEntry[] dbrefs = ds.getDBRefs();
     if (showDbRefs && dbrefs != null)
     {
-      for (int i = 0; i < dbrefs.length; i++)
+      // note this sorts the refs held on the sequence!
+      Arrays.sort(dbrefs, comparator);
+      boolean ellipsis = false;
+      String source = null;
+      String lastSource = null;
+      int countForSource = 0;
+      int sourceCount = 0;
+      boolean moreSources = false;
+      int lineLength = 0;
+
+      for (DBRefEntry ref : dbrefs)
+      {
+        source = ref.getSource();
+        if (source == null)
+        {
+          // shouldn't happen
+          continue;
+        }
+        boolean sourceChanged = !source.equals(lastSource);
+        if (sourceChanged)
+        {
+          lineLength = 0;
+          countForSource = 0;
+          sourceCount++;
+        }
+        if (sourceCount > MAX_SOURCES && summary)
+        {
+          ellipsis = true;
+          moreSources = true;
+          break;
+        }
+        lastSource = source;
+        countForSource++;
+        if (countForSource == 1 || !summary)
+        {
+          sb.append("<br>");
+        }
+        if (countForSource <= MAX_REFS_PER_SOURCE || !summary)
+        {
+          String accessionId = ref.getAccessionId();
+          lineLength += accessionId.length() + 1;
+          if (countForSource > 1 && summary)
+          {
+            sb.append(", ").append(accessionId);
+            lineLength++;
+          }
+          else
+          {
+            sb.append(source).append(" ").append(accessionId);
+            lineLength += source.length();
+          }
+          maxWidth = Math.max(maxWidth, lineLength);
+        }
+        if (countForSource == MAX_REFS_PER_SOURCE && summary)
+        {
+          sb.append(COMMA).append(ELLIPSIS);
+          ellipsis = true;
+        }
+      }
+      if (moreSources)
+      {
+        sb.append("<br>").append(ELLIPSIS).append(COMMA).append(source)
+                .append(COMMA).append(ELLIPSIS);
+      }
+      if (ellipsis)
       {
-        tip.append("<br>");
-        tmp = dbrefs[i].getSource() + " " + dbrefs[i].getAccessionId();
-        tip.append(tmp);
-        maxWidth = Math.max(maxWidth, tmp.length());
+        sb.append("<br>(");
+        sb.append(MessageManager.getString("label.output_seq_details"));
+        sb.append(")");
       }
     }
 
-    // ADD NON POSITIONAL SEQUENCE INFO
+    /*
+     * add non-positional features if wanted
+     */
     SequenceFeature[] features = sequence.getSequenceFeatures();
     if (showNpFeats && features != null)
     {
@@ -401,21 +441,29 @@ public class SequenceAnnotationReport
       {
         if (features[i].begin == 0 && features[i].end == 0)
         {
-          int sz = -tip.length();
-          List<SequenceFeature> tfeat = new ArrayList<SequenceFeature>();
-          tfeat.add(features[i]);
-          appendFeatures(tip, 0, tfeat, minmax);
-          sz += tip.length();
+          int sz = -sb.length();
+          appendFeature(sb, 0, minmax, features[i]);
+          sz += sb.length();
           maxWidth = Math.max(maxWidth, sz);
         }
       }
     }
+    sb.append("</i>");
+    return maxWidth;
+  }
+
+  public void createTooltipAnnotationReport(final StringBuilder tip,
+          SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
+          Map<String, float[][]> minmax)
+  {
+    int maxWidth = createSequenceAnnotationReport(tip, sequence,
+            showDbRefs, showNpFeats, minmax, true);
 
-    if (tableWrap && maxWidth > 60)
+    if (maxWidth > 60)
     {
-      tip.insert(0, "<table width=350 border=0><tr><td><i>");
-      tip.append("</i></td></tr></table>");
+      // ? not sure this serves any useful purpose
+      // tip.insert(0, "<table width=350 border=0><tr><td>");
+      // tip.append("</td></tr></table>");
     }
-
   }
 }
index 26c202c..97b246f 100644 (file)
@@ -45,6 +45,11 @@ public abstract class StructureFile extends AlignFile
 
   private String id;
 
+  public enum StructureFileType
+  {
+    PDB, MMCIF, MMTF
+  };
+
   private PDBEntry.Type dbRefType;
 
   /**
@@ -484,4 +489,20 @@ public abstract class StructureFile extends AlignFile
   {
     this.pdbIdAvailable = pdbIdAvailable;
   }
+
+  public static boolean isStructureFile(String fileType)
+  {
+    if (fileType == null)
+    {
+      return false;
+    }
+    for (StructureFileType sfType : StructureFileType.values())
+    {
+      if (sfType.name().equalsIgnoreCase(fileType))
+      {
+        return true;
+      }
+    }
+    return false;
+  }
 }
index 6b94559..af8a172 100755 (executable)
@@ -2181,6 +2181,19 @@ public class GAlignFrame extends JInternalFrame
         alignmentProperties();
       }
     });
+    JMenuItem selectHighlighted = new JMenuItem(
+            MessageManager.getString("action.select_highlighted_columns"));
+    selectHighlighted.setToolTipText(MessageManager
+            .getString("tooltip.select_highlighted_columns"));
+    al = new ActionListener()
+    {
+      @Override
+      public void actionPerformed(ActionEvent actionEvent)
+      {
+        selectHighlightedColumns_actionPerformed(actionEvent);
+      }
+    };
+    selectHighlighted.addActionListener(al);
     JMenu tooltipSettingsMenu = new JMenu(
             MessageManager.getString("label.sequence_id_tooltip"));
     JMenu autoAnnMenu = new JMenu(
@@ -2382,12 +2395,20 @@ public class GAlignFrame extends JInternalFrame
     selectMenu.add(grpsFromSelection);
     selectMenu.add(deleteGroups);
     selectMenu.add(annotationColumn);
+    selectMenu.add(selectHighlighted);
     // TODO - determine if the listenToViewSelections button is needed : see bug
     // JAL-574
     // selectMenu.addSeparator();
     // selectMenu.add(listenToViewSelections);
   }
 
+  protected void selectHighlightedColumns_actionPerformed(
+          ActionEvent actionEvent)
+  {
+    // TODO Auto-generated method stub
+
+  }
+
   /**
    * Generate the reverse sequence (or reverse complement if the flag is true)
    * and add it to the alignment
index 46580a2..2689946 100755 (executable)
@@ -60,16 +60,18 @@ public class GSequenceLink extends Panel
     nameTB.setBounds(new Rectangle(77, 10, 310, 23));
     nameTB.addKeyListener(new KeyAdapter()
     {
+      @Override
       public void keyTyped(KeyEvent e)
       {
         nameTB_keyTyped(e);
       }
     });
     urlTB.setFont(JvSwingUtils.getLabelFont());
-    urlTB.setText("http://www.");
+    urlTB.setText("http://");
     urlTB.setBounds(new Rectangle(78, 40, 309, 23));
     urlTB.addKeyListener(new KeyAdapter()
     {
+      @Override
       public void keyTyped(KeyEvent e)
       {
         urlTB_keyTyped(e);
@@ -88,7 +90,20 @@ public class GSequenceLink extends Panel
     jLabel3.setBounds(new Rectangle(21, 72, 351, 15));
     jLabel4.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
     jLabel4.setText(MessageManager.getString("label.use_sequence_id_2"));
-    jLabel4.setBounds(new Rectangle(21, 93, 351, 15));
+    jLabel4.setBounds(new Rectangle(21, 88, 351, 15));
+    jLabel5.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
+    jLabel5.setText(MessageManager.getString("label.use_sequence_id_3"));
+    jLabel5.setBounds(new Rectangle(21, 106, 351, 15));
+
+    String lastLabel = MessageManager.getString("label.use_sequence_id_4");
+    if (lastLabel.length() > 0)
+    {
+      // e.g. Spanish version has longer text
+      jLabel6.setFont(new java.awt.Font("Verdana", Font.ITALIC, 11));
+      jLabel6.setText(lastLabel);
+      jLabel6.setBounds(new Rectangle(21, 122, 351, 15));
+    }
+
     jPanel1.setBorder(BorderFactory.createEtchedBorder());
     jPanel1.setLayout(null);
     jPanel1.add(jLabel1);
@@ -97,11 +112,21 @@ public class GSequenceLink extends Panel
     jPanel1.add(jLabel2);
     jPanel1.add(jLabel3);
     jPanel1.add(jLabel4);
+    jPanel1.add(jLabel5);
+
+    int height = 130;
+    if (lastLabel.length() > 0)
+    {
+      jPanel1.add(jLabel6);
+      height = 146;
+    }
+
     this.add(jPanel1, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0,
             GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(
-                    5, 4, 6, 5), 390, 130));
+                    5, 4, 6, 5), 390, height));
   }
 
+  @Override
   public void setName(String name)
   {
     nameTB.setText(name);
@@ -112,6 +137,7 @@ public class GSequenceLink extends Panel
     urlTB.setText(url);
   }
 
+  @Override
   public String getName()
   {
     return nameTB.getText();
@@ -149,6 +175,10 @@ public class GSequenceLink extends Panel
 
   JLabel jLabel4 = new JLabel();
 
+  JLabel jLabel5 = new JLabel();
+
+  JLabel jLabel6 = new JLabel();
+
   JPanel jPanel1 = new JPanel();
 
   GridBagLayout gridBagLayout1 = new GridBagLayout();
index 3fdcb3b..a0e530c 100644 (file)
@@ -28,6 +28,7 @@ import jalview.api.AlignViewportI;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.ProfilesI;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ResidueProperties;
 import jalview.util.Platform;
@@ -73,7 +74,7 @@ public class AnnotationRenderer
 
   private ColumnSelection columnSelection;
 
-  private Hashtable[] hconsensus;
+  private ProfilesI hconsensus;
 
   private Hashtable[] complementConsensus;
 
@@ -351,7 +352,7 @@ public class AnnotationRenderer
       {
         // TODO? group consensus for cDNA complement
         return AAFrequency.extractProfile(
-                aa.groupRef.consensusData[column],
+                aa.groupRef.consensusData.get(column),
                 aa.groupRef.getIgnoreGapsConsensus());
       }
       // TODO extend annotation row to enable dynamic and static profile data to
@@ -365,7 +366,8 @@ public class AnnotationRenderer
         }
         else
         {
-          return AAFrequency.extractProfile(hconsensus[column],
+          return AAFrequency.extractProfile(
+hconsensus.get(column),
                   av_ignoreGapsConsensus);
         }
       }
index b007365..9e0089f 100644 (file)
@@ -188,15 +188,20 @@ public class FeatureRenderer extends FeatureRendererModel
   }
 
   /**
-   * This is used by the Molecule Viewer and Overview to get the accurate colour
-   * of the rendered sequence
+   * This is used by Structure Viewers and the Overview Window to get the
+   * feature colour of the rendered sequence, returned as an RGB value
+   * 
+   * @param defaultColour
+   * @param seq
+   * @param column
+   * @return
    */
-  public synchronized int findFeatureColour(int initialCol,
+  public synchronized int findFeatureColour(int defaultColour,
           final SequenceI seq, int column)
   {
     if (!av.isShowSequenceFeatures())
     {
-      return initialCol;
+      return defaultColour;
     }
 
     SequenceFeature[] sequenceFeatures = seq.getSequenceFeatures();
@@ -223,7 +228,7 @@ public class FeatureRenderer extends FeatureRendererModel
 
     if (lastSequenceFeatures == null || sfSize == 0)
     {
-      return initialCol;
+      return defaultColour;
     }
 
     if (jalview.util.Comparison.isGap(lastSeq.getCharAt(column)))
@@ -244,7 +249,7 @@ public class FeatureRenderer extends FeatureRendererModel
 
     if (offscreenImage != null)
     {
-      offscreenImage.setRGB(0, 0, initialCol);
+      offscreenImage.setRGB(0, 0, defaultColour);
       drawSequence(offscreenImage.getGraphics(), lastSeq, column, column, 0);
 
       return offscreenImage.getRGB(0, 0);
@@ -255,7 +260,7 @@ public class FeatureRenderer extends FeatureRendererModel
 
       if (currentColour == null)
       {
-        return initialCol;
+        return defaultColour;
       }
       else
       {
@@ -275,6 +280,19 @@ public class FeatureRenderer extends FeatureRendererModel
 
   int epos;
 
+  /**
+   * Draws the sequence on the graphics context, or just determines the colour
+   * that would be drawn (if flag offscreenrender is true).
+   * 
+   * @param g
+   * @param seq
+   * @param start
+   *          start column (or sequence position in offscreenrender mode)
+   * @param end
+   *          end column (not used in offscreenrender mode)
+   * @param y1
+   *          vertical offset at which to draw on the graphics
+   */
   public synchronized void drawSequence(Graphics g, final SequenceI seq,
           int start, int end, int y1)
   {
@@ -312,12 +330,10 @@ public class FeatureRenderer extends FeatureRendererModel
     }
 
     sfSize = lastSequenceFeatures.length;
-    String type;
     for (int renderIndex = 0; renderIndex < renderOrder.length; renderIndex++)
     {
-      type = renderOrder[renderIndex];
-
-      if (type == null || !showFeatureOfType(type))
+      String type = renderOrder[renderIndex];
+      if (!showFeatureOfType(type))
       {
         continue;
       }
@@ -332,16 +348,16 @@ public class FeatureRenderer extends FeatureRendererModel
           continue;
         }
 
-        if (featureGroups != null
-                && sequenceFeature.featureGroup != null
-                && sequenceFeature.featureGroup.length() != 0
-                && featureGroups.containsKey(sequenceFeature.featureGroup)
-                && !featureGroups.get(sequenceFeature.featureGroup)
-                        .booleanValue())
+        if (featureGroupNotShown(sequenceFeature))
         {
           continue;
         }
 
+        /*
+         * check feature overlaps the visible part of the alignment, 
+         * unless doing offscreenRender (to the Overview window or a 
+         * structure viewer) which is not limited 
+         */
         if (!offscreenRender
                 && (sequenceFeature.getBegin() > epos || sequenceFeature
                         .getEnd() < spos))
@@ -349,35 +365,43 @@ public class FeatureRenderer extends FeatureRendererModel
           continue;
         }
 
+        Color featureColour = getColour(sequenceFeature);
+        boolean isContactFeature = sequenceFeature.isContactFeature();
+
         if (offscreenRender && offscreenImage == null)
         {
-          if (sequenceFeature.begin <= start
-                  && sequenceFeature.end >= start)
+          /*
+           * offscreen mode with no image (image is only needed if transparency 
+           * is applied to feature colours) - just check feature is rendered at 
+           * the requested position (start == sequence position in this mode)
+           */
+          boolean featureIsAtPosition = sequenceFeature.begin <= start
+                  && sequenceFeature.end >= start;
+          if (isContactFeature)
+          {
+            featureIsAtPosition = sequenceFeature.begin == start
+                    || sequenceFeature.end == start;
+          }
+          if (featureIsAtPosition)
           {
             // this is passed out to the overview and other sequence renderers
             // (e.g. molecule viewer) to get displayed colour for rendered
             // sequence
-            currentColour = new Integer(getColour(sequenceFeature).getRGB());
+            currentColour = new Integer(featureColour.getRGB());
             // used to be retreived from av.featuresDisplayed
             // currentColour = av.featuresDisplayed
             // .get(sequenceFeatures[sfindex].type);
 
           }
         }
-        else if (sequenceFeature.type.equals("disulfide bond"))
+        else if (isContactFeature)
         {
           renderFeature(g, seq, seq.findIndex(sequenceFeature.begin) - 1,
-                  seq.findIndex(sequenceFeature.begin) - 1,
-                  getColour(sequenceFeature)
-                  // new Color(((Integer) av.featuresDisplayed
-                  // .get(sequenceFeatures[sfindex].type)).intValue())
-                  , start, end, y1);
+                  seq.findIndex(sequenceFeature.begin) - 1, featureColour,
+                  start, end, y1);
           renderFeature(g, seq, seq.findIndex(sequenceFeature.end) - 1,
-                  seq.findIndex(sequenceFeature.end) - 1,
-                  getColour(sequenceFeature)
-                  // new Color(((Integer) av.featuresDisplayed
-                  // .get(sequenceFeatures[sfindex].type)).intValue())
-                  , start, end, y1);
+                  seq.findIndex(sequenceFeature.end) - 1, featureColour,
+                  start, end, y1);
 
         }
         else if (showFeature(sequenceFeature))
@@ -388,19 +412,17 @@ public class FeatureRenderer extends FeatureRendererModel
             renderScoreFeature(g, seq,
                     seq.findIndex(sequenceFeature.begin) - 1,
                     seq.findIndex(sequenceFeature.end) - 1,
-                    getColour(sequenceFeature), start, end, y1,
+                    featureColour, start, end, y1,
                     normaliseScore(sequenceFeature));
           }
           else
           {
             renderFeature(g, seq, seq.findIndex(sequenceFeature.begin) - 1,
                     seq.findIndex(sequenceFeature.end) - 1,
-                    getColour(sequenceFeature), start, end, y1);
+                    featureColour, start, end, y1);
           }
         }
-
       }
-
     }
 
     if (transparency != 1.0f && g != null)
@@ -412,6 +434,24 @@ public class FeatureRenderer extends FeatureRendererModel
   }
 
   /**
+   * Answers true if the feature belongs to a feature group which is not
+   * currently displayed, else false
+   * 
+   * @param sequenceFeature
+   * @return
+   */
+  protected boolean featureGroupNotShown(
+          final SequenceFeature sequenceFeature)
+  {
+    return featureGroups != null
+            && sequenceFeature.featureGroup != null
+            && sequenceFeature.featureGroup.length() != 0
+            && featureGroups.containsKey(sequenceFeature.featureGroup)
+            && !featureGroups.get(sequenceFeature.featureGroup)
+                    .booleanValue();
+  }
+
+  /**
    * Called when alignment in associated view has new/modified features to
    * discover and display.
    * 
index 9d09259..c47f171 100755 (executable)
  */
 package jalview.schemes;
 
-import jalview.analysis.AAFrequency;
 import jalview.datamodel.AnnotatedCollectionI;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
 
 import java.awt.Color;
 import java.util.Map;
 
 public class Blosum62ColourScheme extends ResidueColourScheme
 {
+  private static final Color LIGHT_BLUE = new Color(204, 204, 255);
+  private static final Color DARK_BLUE = new Color(154, 154, 255);
+
   public Blosum62ColourScheme()
   {
     super();
@@ -44,7 +47,7 @@ public class Blosum62ColourScheme extends ResidueColourScheme
       res -= ('a' - 'A');
     }
 
-    if (consensus == null || j >= consensus.length || consensus[j] == null
+    if (consensus == null || consensus.get(j) == null
             || (threshold != 0 && !aboveThreshold(res, j)))
     {
       return Color.white;
@@ -52,14 +55,16 @@ public class Blosum62ColourScheme extends ResidueColourScheme
 
     Color currentColour;
 
-    if (!jalview.util.Comparison.isGap(res))
+    if (!Comparison.isGap(res))
     {
-      String max = (String) consensus[j].get(AAFrequency.MAXRESIDUE);
+      /*
+       * test if this is the consensus (or joint consensus) residue
+       */
+      String max = consensus.get(j).getModalResidue();
 
       if (max.indexOf(res) > -1)
       {
-        // TODO use a constant here?
-        currentColour = new Color(154, 154, 255);
+        currentColour = DARK_BLUE;
       }
       else
       {
@@ -74,8 +79,7 @@ public class Blosum62ColourScheme extends ResidueColourScheme
 
         if (c > 0)
         {
-          // TODO use a constant here?
-          currentColour = new Color(204, 204, 255);
+          currentColour = LIGHT_BLUE;
         }
         else
         {
index effdf59..da99a4a 100755 (executable)
@@ -21,6 +21,7 @@
 package jalview.schemes;
 
 import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceI;
 
@@ -52,7 +53,7 @@ public interface ColourSchemeI
   /**
    * assign the given consensus profile for the colourscheme
    */
-  public void setConsensus(java.util.Hashtable[] h);
+  public void setConsensus(ProfilesI hconsensus);
 
   /**
    * assign the given conservation to the colourscheme
index eac467a..35be31b 100644 (file)
@@ -21,8 +21,7 @@
 package jalview.schemes;
 
 import jalview.analysis.Conservation;
-
-import java.util.Hashtable;
+import jalview.datamodel.ProfilesI;
 
 /**
  * Colourscheme that takes its colours from some other colourscheme
@@ -41,7 +40,7 @@ public class FollowerColourScheme extends ResidueColourScheme
   }
 
   @Override
-  public void setConsensus(Hashtable[] consensus)
+  public void setConsensus(ProfilesI consensus)
   {
     if (colourScheme != null)
     {
index 9dd763d..0ad5b5c 100755 (executable)
  */
 package jalview.schemes;
 
-import jalview.analysis.AAFrequency;
+import jalview.datamodel.ProfileI;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
 
 import java.awt.Color;
 
@@ -48,7 +49,7 @@ public class PIDColourScheme extends ResidueColourScheme
       c -= ('a' - 'A');
     }
 
-    if (consensus == null || j >= consensus.length || consensus[j] == null)
+    if (consensus == null || consensus.get(j) == null)
     {
       return Color.white;
     }
@@ -62,25 +63,24 @@ public class PIDColourScheme extends ResidueColourScheme
 
     double sc = 0;
 
-    if (consensus.length <= j)
-    {
-      return Color.white;
-    }
 
-    if ((Integer
-            .parseInt(consensus[j].get(AAFrequency.MAXCOUNT).toString()) != -1)
-            && consensus[j].contains(String.valueOf(c)))
+    /*
+     * test whether this is the consensus (or joint consensus) residue
+     */
+    ProfileI profile = consensus.get(j);
+    boolean matchesConsensus = profile.getModalResidue().contains(
+            String.valueOf(c));
+    if (matchesConsensus)
     {
-      sc = ((Float) consensus[j].get(ignoreGaps)).floatValue();
+      sc = profile.getPercentageIdentity(ignoreGaps);
 
-      if (!jalview.util.Comparison.isGap(c))
+      if (!Comparison.isGap(c))
       {
         for (int i = 0; i < thresholds.length; i++)
         {
           if (sc > thresholds[i])
           {
             currentColour = pidColours[i];
-
             break;
           }
         }
index bca98cf..f6b7c5e 100755 (executable)
  */
 package jalview.schemes;
 
-import jalview.analysis.AAFrequency;
 import jalview.analysis.Conservation;
 import jalview.datamodel.AnnotatedCollectionI;
+import jalview.datamodel.ProfileI;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceI;
+import jalview.util.ColorUtils;
+import jalview.util.Comparison;
 import jalview.util.MessageManager;
 
 import java.awt.Color;
-import java.util.Hashtable;
 import java.util.Map;
 
 /**
@@ -48,17 +50,21 @@ public class ResidueColourScheme implements ColourSchemeI
   int threshold = 0;
 
   /* Set when threshold colouring to either pid_gaps or pid_nogaps */
-  protected String ignoreGaps = AAFrequency.PID_GAPS;
+  protected boolean ignoreGaps = false;
 
-  /** Consenus as a hashtable array */
-  Hashtable[] consensus;
+  /*
+   * Consensus data indexed by column
+   */
+  ProfilesI consensus;
 
-  /** Conservation string as a char array */
+  /*
+   * Conservation string as a char array 
+   */
   char[] conservation;
 
-  int conservationLength = 0;
-
-  /** DOCUMENT ME!! */
+  /*
+   * The conservation slider percentage setting 
+   */
   int inc = 30;
 
   /**
@@ -100,6 +106,7 @@ public class ResidueColourScheme implements ColourSchemeI
   /**
    * Find a colour without an index in a sequence
    */
+  @Override
   public Color findColour(char c)
   {
     return colors == null ? Color.white : colors[symbolIndex[c]];
@@ -133,58 +140,63 @@ public class ResidueColourScheme implements ColourSchemeI
    * 
    * @return Returns the percentage threshold
    */
+  @Override
   public int getThreshold()
   {
     return threshold;
   }
 
   /**
-   * DOCUMENT ME!
+   * Sets the percentage consensus threshold value, and whether gaps are ignored
+   * in percentage identity calculation
    * 
-   * @param ct
-   *          DOCUMENT ME!
+   * @param consensusThreshold
+   * @param ignoreGaps
    */
-  public void setThreshold(int ct, boolean ignoreGaps)
+  @Override
+  public void setThreshold(int consensusThreshold, boolean ignoreGaps)
   {
-    threshold = ct;
-    if (ignoreGaps)
-    {
-      this.ignoreGaps = AAFrequency.PID_NOGAPS;
-    }
-    else
-    {
-      this.ignoreGaps = AAFrequency.PID_GAPS;
-    }
+    threshold = consensusThreshold;
+    this.ignoreGaps = ignoreGaps;
   }
 
   /**
-   * DOCUMENT ME!
+   * Answers true if there is a consensus profile for the specified column, and
+   * the given residue matches the consensus (or joint consensus) residue for
+   * the column, and the percentage identity for the profile is equal to or
+   * greater than the current threshold; else answers false. The percentage
+   * calculation depends on whether or not we are ignoring gapped sequences.
    * 
-   * @param s
-   *          DOCUMENT ME!
-   * @param j
-   *          DOCUMENT ME!
+   * @param residue
+   * @param column
+   *          (index into consensus profiles)
    * 
-   * @return DOCUMENT ME!
+   * @return
+   * @see #setThreshold(int, boolean)
    */
-  public boolean aboveThreshold(char c, int j)
+  public boolean aboveThreshold(char residue, int column)
   {
-    if ('a' <= c && c <= 'z')
+    if ('a' <= residue && residue <= 'z')
     {
       // TO UPPERCASE !!!
       // Faster than toUpperCase
-      c -= ('a' - 'A');
+      residue -= ('a' - 'A');
     }
 
-    if (consensus == null || consensus.length < j || consensus[j] == null)
+    if (consensus == null)
     {
       return false;
     }
 
-    if ((((Integer) consensus[j].get(AAFrequency.MAXCOUNT)).intValue() != -1)
-            && consensus[j].contains(String.valueOf(c)))
+    ProfileI profile = consensus.get(column);
+
+    /*
+     * test whether this is the consensus (or joint consensus) residue
+     */
+    if (profile != null
+            && profile.getModalResidue().contains(String.valueOf(residue)))
     {
-      if (((Float) consensus[j].get(ignoreGaps)).floatValue() >= threshold)
+      if (profile.getPercentageIdentity(ignoreGaps) >= threshold)
       {
         return true;
       }
@@ -193,6 +205,7 @@ public class ResidueColourScheme implements ColourSchemeI
     return false;
   }
 
+  @Override
   public boolean conservationApplied()
   {
     return conservationColouring;
@@ -204,11 +217,13 @@ public class ResidueColourScheme implements ColourSchemeI
     conservationColouring = conservationApplied;
   }
 
+  @Override
   public void setConservationInc(int i)
   {
     inc = i;
   }
 
+  @Override
   public int getConservationInc()
   {
     return inc;
@@ -220,7 +235,8 @@ public class ResidueColourScheme implements ColourSchemeI
    * @param consensus
    *          DOCUMENT ME!
    */
-  public void setConsensus(Hashtable[] consensus)
+  @Override
+  public void setConsensus(ProfilesI consensus)
   {
     if (consensus == null)
     {
@@ -230,6 +246,7 @@ public class ResidueColourScheme implements ColourSchemeI
     this.consensus = consensus;
   }
 
+  @Override
   public void setConservation(Conservation cons)
   {
     if (cons == null)
@@ -240,73 +257,70 @@ public class ResidueColourScheme implements ColourSchemeI
     else
     {
       conservationColouring = true;
-      int i, iSize = cons.getConsSequence().getLength();
+      int iSize = cons.getConsSequence().getLength();
       conservation = new char[iSize];
-      for (i = 0; i < iSize; i++)
+      for (int i = 0; i < iSize; i++)
       {
         conservation[i] = cons.getConsSequence().getCharAt(i);
       }
-      conservationLength = conservation.length;
     }
 
   }
 
   /**
-   * DOCUMENT ME!
+   * Applies a combination of column conservation score, and conservation
+   * percentage slider, to 'bleach' out the residue colours towards white.
+   * <p>
+   * If a column is fully conserved (identical residues, conservation score 11,
+   * shown as *), or all 10 physico-chemical properties are conserved
+   * (conservation score 10, shown as +), then the colour is left unchanged.
+   * <p>
+   * Otherwise a 'bleaching' factor is computed and applied to the colour. This
+   * is designed to fade colours for scores of 0-9 completely to white at slider
+   * positions ranging from 18% - 100% respectively.
    * 
-   * @param s
-   *          DOCUMENT ME!
-   * @param i
-   *          DOCUMENT ME!
+   * @param currentColour
+   * @param column
    * 
-   * @return DOCUMENT ME!
+   * @return bleached (or unmodified) colour
    */
-
-  Color applyConservation(Color currentColour, int i)
+  Color applyConservation(Color currentColour, int column)
   {
+    if (conservation == null || conservation.length <= column)
+    {
+      return currentColour;
+    }
+    char conservationScore = conservation[column];
+
+    /*
+     * if residues are fully conserved (* or 11), or all properties
+     * are conserved (+ or 10), leave colour unchanged
+     */
+    if (conservationScore == '*' || conservationScore == '+'
+            || conservationScore == (char) 10
+            || conservationScore == (char) 11)
+    {
+      return currentColour;
+    }
 
-    if ((conservationLength > i) && (conservation[i] != '*')
-            && (conservation[i] != '+'))
+    if (Comparison.isGap(conservationScore))
     {
-      if (jalview.util.Comparison.isGap(conservation[i]))
-      {
-        currentColour = Color.white;
-      }
-      else
-      {
-        float t = 11 - (conservation[i] - '0');
-        if (t == 0)
-        {
-          return Color.white;
-        }
-
-        int red = currentColour.getRed();
-        int green = currentColour.getGreen();
-        int blue = currentColour.getBlue();
-
-        int dr = 255 - red;
-        int dg = 255 - green;
-        int db = 255 - blue;
-
-        dr *= t / 10f;
-        dg *= t / 10f;
-        db *= t / 10f;
-
-        red += (inc / 20f) * dr;
-        green += (inc / 20f) * dg;
-        blue += (inc / 20f) * db;
-
-        if (red > 255 || green > 255 || blue > 255)
-        {
-          currentColour = Color.white;
-        }
-        else
-        {
-          currentColour = new Color(red, green, blue);
-        }
-      }
+      return Color.white;
     }
-    return currentColour;
+
+    /*
+     * convert score 0-9 to a bleaching factor 1.1 - 0.2
+     */
+    float bleachFactor = (11 - (conservationScore - '0')) / 10f;
+
+    /*
+     * scale this up by 0-5 (percentage slider / 20)
+     * as a result, scores of:         0  1  2  3  4  5  6  7  8  9
+     * fade to white at slider value: 18 20 22 25 29 33 40 50 67 100%
+     */
+    bleachFactor *= (inc / 20f);
+
+    return ColorUtils.bleachColour(currentColour, bleachFactor);
   }
 
   @Override
index 90a7952..4d46279 100755 (executable)
@@ -222,10 +222,14 @@ public class ResidueProperties
     purinepyrimidineIndex['n'] = 2;
   }
 
+  private static final Integer ONE = Integer.valueOf(1);
+
+  private static final Integer ZERO = Integer.valueOf(0);
+
   static
   {
-    aa3Hash.put("ALA", Integer.valueOf(0));
-    aa3Hash.put("ARG", Integer.valueOf(1));
+    aa3Hash.put("ALA", ZERO);
+    aa3Hash.put("ARG", ONE);
     aa3Hash.put("ASN", Integer.valueOf(2));
     aa3Hash.put("ASP", Integer.valueOf(3)); // D
     aa3Hash.put("CYS", Integer.valueOf(4));
@@ -910,267 +914,267 @@ public class ResidueProperties
 
   static
   {
-    hydrophobic.put("I", Integer.valueOf(1));
-    hydrophobic.put("L", Integer.valueOf(1));
-    hydrophobic.put("V", Integer.valueOf(1));
-    hydrophobic.put("C", Integer.valueOf(1));
-    hydrophobic.put("A", Integer.valueOf(1));
-    hydrophobic.put("G", Integer.valueOf(1));
-    hydrophobic.put("M", Integer.valueOf(1));
-    hydrophobic.put("F", Integer.valueOf(1));
-    hydrophobic.put("Y", Integer.valueOf(1));
-    hydrophobic.put("W", Integer.valueOf(1));
-    hydrophobic.put("H", Integer.valueOf(1));
-    hydrophobic.put("K", Integer.valueOf(1));
-    hydrophobic.put("X", Integer.valueOf(1));
-    hydrophobic.put("-", Integer.valueOf(1));
-    hydrophobic.put("*", Integer.valueOf(1));
-    hydrophobic.put("R", Integer.valueOf(0));
-    hydrophobic.put("E", Integer.valueOf(0));
-    hydrophobic.put("Q", Integer.valueOf(0));
-    hydrophobic.put("D", Integer.valueOf(0));
-    hydrophobic.put("N", Integer.valueOf(0));
-    hydrophobic.put("S", Integer.valueOf(0));
-    hydrophobic.put("T", Integer.valueOf(0));
-    hydrophobic.put("P", Integer.valueOf(0));
+    hydrophobic.put("I", ONE);
+    hydrophobic.put("L", ONE);
+    hydrophobic.put("V", ONE);
+    hydrophobic.put("C", ONE);
+    hydrophobic.put("A", ONE);
+    hydrophobic.put("G", ONE);
+    hydrophobic.put("M", ONE);
+    hydrophobic.put("F", ONE);
+    hydrophobic.put("Y", ONE);
+    hydrophobic.put("W", ONE);
+    hydrophobic.put("H", ONE);
+    hydrophobic.put("K", ONE);
+    hydrophobic.put("X", ONE);
+    hydrophobic.put("-", ONE);
+    hydrophobic.put("*", ONE);
+    hydrophobic.put("R", ZERO);
+    hydrophobic.put("E", ZERO);
+    hydrophobic.put("Q", ZERO);
+    hydrophobic.put("D", ZERO);
+    hydrophobic.put("N", ZERO);
+    hydrophobic.put("S", ZERO);
+    hydrophobic.put("T", ONE);
+    hydrophobic.put("P", ZERO);
   }
 
   static
   {
-    polar.put("Y", Integer.valueOf(1));
-    polar.put("W", Integer.valueOf(1));
-    polar.put("H", Integer.valueOf(1));
-    polar.put("K", Integer.valueOf(1));
-    polar.put("R", Integer.valueOf(1));
-    polar.put("E", Integer.valueOf(1));
-    polar.put("Q", Integer.valueOf(1));
-    polar.put("D", Integer.valueOf(1));
-    polar.put("N", Integer.valueOf(1));
-    polar.put("S", Integer.valueOf(1));
-    polar.put("T", Integer.valueOf(1));
-    polar.put("X", Integer.valueOf(1));
-    polar.put("-", Integer.valueOf(1));
-    polar.put("*", Integer.valueOf(1));
-    polar.put("I", Integer.valueOf(0));
-    polar.put("L", Integer.valueOf(0));
-    polar.put("V", Integer.valueOf(0));
-    polar.put("C", Integer.valueOf(0));
-    polar.put("A", Integer.valueOf(0));
-    polar.put("G", Integer.valueOf(0));
-    polar.put("M", Integer.valueOf(0));
-    polar.put("F", Integer.valueOf(0));
-    polar.put("P", Integer.valueOf(0));
+    polar.put("Y", ONE);
+    polar.put("W", ONE);
+    polar.put("H", ONE);
+    polar.put("K", ONE);
+    polar.put("R", ONE);
+    polar.put("E", ONE);
+    polar.put("Q", ONE);
+    polar.put("D", ONE);
+    polar.put("N", ONE);
+    polar.put("S", ONE);
+    polar.put("T", ONE);
+    polar.put("X", ONE);
+    polar.put("-", ONE);
+    polar.put("*", ONE);
+    polar.put("I", ZERO);
+    polar.put("L", ZERO);
+    polar.put("V", ZERO);
+    polar.put("C", ZERO);
+    polar.put("A", ZERO);
+    polar.put("G", ZERO);
+    polar.put("M", ZERO);
+    polar.put("F", ZERO);
+    polar.put("P", ZERO);
   }
 
   static
   {
-    small.put("I", Integer.valueOf(0));
-    small.put("L", Integer.valueOf(0));
-    small.put("V", Integer.valueOf(1));
-    small.put("C", Integer.valueOf(1));
-    small.put("A", Integer.valueOf(1));
-    small.put("G", Integer.valueOf(1));
-    small.put("M", Integer.valueOf(0));
-    small.put("F", Integer.valueOf(0));
-    small.put("Y", Integer.valueOf(0));
-    small.put("W", Integer.valueOf(0));
-    small.put("H", Integer.valueOf(0));
-    small.put("K", Integer.valueOf(0));
-    small.put("R", Integer.valueOf(0));
-    small.put("E", Integer.valueOf(0));
-    small.put("Q", Integer.valueOf(0));
-    small.put("D", Integer.valueOf(1));
-    small.put("N", Integer.valueOf(1));
-    small.put("S", Integer.valueOf(1));
-    small.put("T", Integer.valueOf(1));
-    small.put("P", Integer.valueOf(1));
-    small.put("-", Integer.valueOf(1));
-    small.put("*", Integer.valueOf(1));
+    small.put("I", ZERO);
+    small.put("L", ZERO);
+    small.put("V", ONE);
+    small.put("C", ONE);
+    small.put("A", ONE);
+    small.put("G", ONE);
+    small.put("M", ZERO);
+    small.put("F", ZERO);
+    small.put("Y", ZERO);
+    small.put("W", ZERO);
+    small.put("H", ZERO);
+    small.put("K", ZERO);
+    small.put("R", ZERO);
+    small.put("E", ZERO);
+    small.put("Q", ZERO);
+    small.put("D", ONE);
+    small.put("N", ONE);
+    small.put("S", ONE);
+    small.put("T", ONE);
+    small.put("P", ONE);
+    small.put("-", ONE);
+    small.put("*", ONE);
   }
 
   static
   {
-    positive.put("I", Integer.valueOf(0));
-    positive.put("L", Integer.valueOf(0));
-    positive.put("V", Integer.valueOf(0));
-    positive.put("C", Integer.valueOf(0));
-    positive.put("A", Integer.valueOf(0));
-    positive.put("G", Integer.valueOf(0));
-    positive.put("M", Integer.valueOf(0));
-    positive.put("F", Integer.valueOf(0));
-    positive.put("Y", Integer.valueOf(0));
-    positive.put("W", Integer.valueOf(0));
-    positive.put("H", Integer.valueOf(1));
-    positive.put("K", Integer.valueOf(1));
-    positive.put("R", Integer.valueOf(1));
-    positive.put("E", Integer.valueOf(0));
-    positive.put("Q", Integer.valueOf(0));
-    positive.put("D", Integer.valueOf(0));
-    positive.put("N", Integer.valueOf(0));
-    positive.put("S", Integer.valueOf(0));
-    positive.put("T", Integer.valueOf(0));
-    positive.put("P", Integer.valueOf(0));
-    positive.put("-", Integer.valueOf(1));
-    positive.put("*", Integer.valueOf(1));
+    positive.put("I", ZERO);
+    positive.put("L", ZERO);
+    positive.put("V", ZERO);
+    positive.put("C", ZERO);
+    positive.put("A", ZERO);
+    positive.put("G", ZERO);
+    positive.put("M", ZERO);
+    positive.put("F", ZERO);
+    positive.put("Y", ZERO);
+    positive.put("W", ZERO);
+    positive.put("H", ONE);
+    positive.put("K", ONE);
+    positive.put("R", ONE);
+    positive.put("E", ZERO);
+    positive.put("Q", ZERO);
+    positive.put("D", ZERO);
+    positive.put("N", ZERO);
+    positive.put("S", ZERO);
+    positive.put("T", ZERO);
+    positive.put("P", ZERO);
+    positive.put("-", ONE);
+    positive.put("*", ONE);
   }
 
   static
   {
-    negative.put("I", Integer.valueOf(0));
-    negative.put("L", Integer.valueOf(0));
-    negative.put("V", Integer.valueOf(0));
-    negative.put("C", Integer.valueOf(0));
-    negative.put("A", Integer.valueOf(0));
-    negative.put("G", Integer.valueOf(0));
-    negative.put("M", Integer.valueOf(0));
-    negative.put("F", Integer.valueOf(0));
-    negative.put("Y", Integer.valueOf(0));
-    negative.put("W", Integer.valueOf(0));
-    negative.put("H", Integer.valueOf(0));
-    negative.put("K", Integer.valueOf(0));
-    negative.put("R", Integer.valueOf(0));
-    negative.put("E", Integer.valueOf(1));
-    negative.put("Q", Integer.valueOf(0));
-    negative.put("D", Integer.valueOf(1));
-    negative.put("N", Integer.valueOf(0));
-    negative.put("S", Integer.valueOf(0));
-    negative.put("T", Integer.valueOf(0));
-    negative.put("P", Integer.valueOf(0));
-    negative.put("-", Integer.valueOf(1));
-    negative.put("*", Integer.valueOf(1));
+    negative.put("I", ZERO);
+    negative.put("L", ZERO);
+    negative.put("V", ZERO);
+    negative.put("C", ZERO);
+    negative.put("A", ZERO);
+    negative.put("G", ZERO);
+    negative.put("M", ZERO);
+    negative.put("F", ZERO);
+    negative.put("Y", ZERO);
+    negative.put("W", ZERO);
+    negative.put("H", ZERO);
+    negative.put("K", ZERO);
+    negative.put("R", ZERO);
+    negative.put("E", ONE);
+    negative.put("Q", ZERO);
+    negative.put("D", ONE);
+    negative.put("N", ZERO);
+    negative.put("S", ZERO);
+    negative.put("T", ZERO);
+    negative.put("P", ZERO);
+    negative.put("-", ONE);
+    negative.put("*", ONE);
   }
 
   static
   {
-    charged.put("I", Integer.valueOf(0));
-    charged.put("L", Integer.valueOf(0));
-    charged.put("V", Integer.valueOf(0));
-    charged.put("C", Integer.valueOf(0));
-    charged.put("A", Integer.valueOf(0));
-    charged.put("G", Integer.valueOf(0));
-    charged.put("M", Integer.valueOf(0));
-    charged.put("F", Integer.valueOf(0));
-    charged.put("Y", Integer.valueOf(0));
-    charged.put("W", Integer.valueOf(0));
-    charged.put("H", Integer.valueOf(1));
-    charged.put("K", Integer.valueOf(1));
-    charged.put("R", Integer.valueOf(1));
-    charged.put("E", Integer.valueOf(1));
-    charged.put("Q", Integer.valueOf(0));
-    charged.put("D", Integer.valueOf(1));
-    charged.put("N", Integer.valueOf(0)); // Asparagine is polar but not
+    charged.put("I", ZERO);
+    charged.put("L", ZERO);
+    charged.put("V", ZERO);
+    charged.put("C", ZERO);
+    charged.put("A", ZERO);
+    charged.put("G", ZERO);
+    charged.put("M", ZERO);
+    charged.put("F", ZERO);
+    charged.put("Y", ZERO);
+    charged.put("W", ZERO);
+    charged.put("H", ONE);
+    charged.put("K", ONE);
+    charged.put("R", ONE);
+    charged.put("E", ONE);
+    charged.put("Q", ZERO);
+    charged.put("D", ONE);
+    charged.put("N", ZERO); // Asparagine is polar but not
                                           // charged.
     // Alternative would be charged and
     // negative (in basic form)?
-    charged.put("S", Integer.valueOf(0));
-    charged.put("T", Integer.valueOf(0));
-    charged.put("P", Integer.valueOf(0));
-    charged.put("-", Integer.valueOf(1));
-    charged.put("*", Integer.valueOf(1));
+    charged.put("S", ZERO);
+    charged.put("T", ZERO);
+    charged.put("P", ZERO);
+    charged.put("-", ONE);
+    charged.put("*", ONE);
   }
 
   static
   {
-    aromatic.put("I", Integer.valueOf(0));
-    aromatic.put("L", Integer.valueOf(0));
-    aromatic.put("V", Integer.valueOf(0));
-    aromatic.put("C", Integer.valueOf(0));
-    aromatic.put("A", Integer.valueOf(0));
-    aromatic.put("G", Integer.valueOf(0));
-    aromatic.put("M", Integer.valueOf(0));
-    aromatic.put("F", Integer.valueOf(1));
-    aromatic.put("Y", Integer.valueOf(1));
-    aromatic.put("W", Integer.valueOf(1));
-    aromatic.put("H", Integer.valueOf(1));
-    aromatic.put("K", Integer.valueOf(0));
-    aromatic.put("R", Integer.valueOf(0));
-    aromatic.put("E", Integer.valueOf(0));
-    aromatic.put("Q", Integer.valueOf(0));
-    aromatic.put("D", Integer.valueOf(0));
-    aromatic.put("N", Integer.valueOf(0));
-    aromatic.put("S", Integer.valueOf(0));
-    aromatic.put("T", Integer.valueOf(0));
-    aromatic.put("P", Integer.valueOf(0));
-    aromatic.put("-", Integer.valueOf(1));
-    aromatic.put("*", Integer.valueOf(1));
+    aromatic.put("I", ZERO);
+    aromatic.put("L", ZERO);
+    aromatic.put("V", ZERO);
+    aromatic.put("C", ZERO);
+    aromatic.put("A", ZERO);
+    aromatic.put("G", ZERO);
+    aromatic.put("M", ZERO);
+    aromatic.put("F", ONE);
+    aromatic.put("Y", ONE);
+    aromatic.put("W", ONE);
+    aromatic.put("H", ONE);
+    aromatic.put("K", ZERO);
+    aromatic.put("R", ZERO);
+    aromatic.put("E", ZERO);
+    aromatic.put("Q", ZERO);
+    aromatic.put("D", ZERO);
+    aromatic.put("N", ZERO);
+    aromatic.put("S", ZERO);
+    aromatic.put("T", ZERO);
+    aromatic.put("P", ZERO);
+    aromatic.put("-", ONE);
+    aromatic.put("*", ONE);
   }
 
   static
   {
-    aliphatic.put("I", Integer.valueOf(1));
-    aliphatic.put("L", Integer.valueOf(1));
-    aliphatic.put("V", Integer.valueOf(1));
-    aliphatic.put("C", Integer.valueOf(0));
-    aliphatic.put("A", Integer.valueOf(0));
-    aliphatic.put("G", Integer.valueOf(0));
-    aliphatic.put("M", Integer.valueOf(0));
-    aliphatic.put("F", Integer.valueOf(0));
-    aliphatic.put("Y", Integer.valueOf(0));
-    aliphatic.put("W", Integer.valueOf(0));
-    aliphatic.put("H", Integer.valueOf(0));
-    aliphatic.put("K", Integer.valueOf(0));
-    aliphatic.put("R", Integer.valueOf(0));
-    aliphatic.put("E", Integer.valueOf(0));
-    aliphatic.put("Q", Integer.valueOf(0));
-    aliphatic.put("D", Integer.valueOf(0));
-    aliphatic.put("N", Integer.valueOf(0));
-    aliphatic.put("S", Integer.valueOf(0));
-    aliphatic.put("T", Integer.valueOf(0));
-    aliphatic.put("P", Integer.valueOf(0));
-    aliphatic.put("-", Integer.valueOf(1));
-    aliphatic.put("*", Integer.valueOf(1));
+    aliphatic.put("I", ONE);
+    aliphatic.put("L", ONE);
+    aliphatic.put("V", ONE);
+    aliphatic.put("C", ZERO);
+    aliphatic.put("A", ZERO);
+    aliphatic.put("G", ZERO);
+    aliphatic.put("M", ZERO);
+    aliphatic.put("F", ZERO);
+    aliphatic.put("Y", ZERO);
+    aliphatic.put("W", ZERO);
+    aliphatic.put("H", ZERO);
+    aliphatic.put("K", ZERO);
+    aliphatic.put("R", ZERO);
+    aliphatic.put("E", ZERO);
+    aliphatic.put("Q", ZERO);
+    aliphatic.put("D", ZERO);
+    aliphatic.put("N", ZERO);
+    aliphatic.put("S", ZERO);
+    aliphatic.put("T", ZERO);
+    aliphatic.put("P", ZERO);
+    aliphatic.put("-", ONE);
+    aliphatic.put("*", ONE);
   }
 
   static
   {
-    tiny.put("I", Integer.valueOf(0));
-    tiny.put("L", Integer.valueOf(0));
-    tiny.put("V", Integer.valueOf(0));
-    tiny.put("C", Integer.valueOf(0));
-    tiny.put("A", Integer.valueOf(1));
-    tiny.put("G", Integer.valueOf(1));
-    tiny.put("M", Integer.valueOf(0));
-    tiny.put("F", Integer.valueOf(0));
-    tiny.put("Y", Integer.valueOf(0));
-    tiny.put("W", Integer.valueOf(0));
-    tiny.put("H", Integer.valueOf(0));
-    tiny.put("K", Integer.valueOf(0));
-    tiny.put("R", Integer.valueOf(0));
-    tiny.put("E", Integer.valueOf(0));
-    tiny.put("Q", Integer.valueOf(0));
-    tiny.put("D", Integer.valueOf(0));
-    tiny.put("N", Integer.valueOf(0));
-    tiny.put("S", Integer.valueOf(1));
-    tiny.put("T", Integer.valueOf(0));
-    tiny.put("P", Integer.valueOf(0));
-    tiny.put("-", Integer.valueOf(1));
-    tiny.put("*", Integer.valueOf(1));
+    tiny.put("I", ZERO);
+    tiny.put("L", ZERO);
+    tiny.put("V", ZERO);
+    tiny.put("C", ZERO);
+    tiny.put("A", ONE);
+    tiny.put("G", ONE);
+    tiny.put("M", ZERO);
+    tiny.put("F", ZERO);
+    tiny.put("Y", ZERO);
+    tiny.put("W", ZERO);
+    tiny.put("H", ZERO);
+    tiny.put("K", ZERO);
+    tiny.put("R", ZERO);
+    tiny.put("E", ZERO);
+    tiny.put("Q", ZERO);
+    tiny.put("D", ZERO);
+    tiny.put("N", ZERO);
+    tiny.put("S", ONE);
+    tiny.put("T", ZERO);
+    tiny.put("P", ZERO);
+    tiny.put("-", ONE);
+    tiny.put("*", ONE);
   }
 
   static
   {
-    proline.put("I", Integer.valueOf(0));
-    proline.put("L", Integer.valueOf(0));
-    proline.put("V", Integer.valueOf(0));
-    proline.put("C", Integer.valueOf(0));
-    proline.put("A", Integer.valueOf(0));
-    proline.put("G", Integer.valueOf(0));
-    proline.put("M", Integer.valueOf(0));
-    proline.put("F", Integer.valueOf(0));
-    proline.put("Y", Integer.valueOf(0));
-    proline.put("W", Integer.valueOf(0));
-    proline.put("H", Integer.valueOf(0));
-    proline.put("K", Integer.valueOf(0));
-    proline.put("R", Integer.valueOf(0));
-    proline.put("E", Integer.valueOf(0));
-    proline.put("Q", Integer.valueOf(0));
-    proline.put("D", Integer.valueOf(0));
-    proline.put("N", Integer.valueOf(0));
-    proline.put("S", Integer.valueOf(0));
-    proline.put("T", Integer.valueOf(0));
-    proline.put("P", Integer.valueOf(1));
-    proline.put("-", Integer.valueOf(1));
-    proline.put("*", Integer.valueOf(1));
+    proline.put("I", ZERO);
+    proline.put("L", ZERO);
+    proline.put("V", ZERO);
+    proline.put("C", ZERO);
+    proline.put("A", ZERO);
+    proline.put("G", ZERO);
+    proline.put("M", ZERO);
+    proline.put("F", ZERO);
+    proline.put("Y", ZERO);
+    proline.put("W", ZERO);
+    proline.put("H", ZERO);
+    proline.put("K", ZERO);
+    proline.put("R", ZERO);
+    proline.put("E", ZERO);
+    proline.put("Q", ZERO);
+    proline.put("D", ZERO);
+    proline.put("N", ZERO);
+    proline.put("S", ZERO);
+    proline.put("T", ZERO);
+    proline.put("P", ONE);
+    proline.put("-", ONE);
+    proline.put("*", ONE);
   }
 
   static
index 771b8a0..81ff739 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.structure;
 
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceI;
 
 public interface SequenceListener
@@ -27,7 +28,7 @@ public interface SequenceListener
   // TODO remove this? never called on SequenceListener type
   public void mouseOverSequence(SequenceI sequence, int index, int pos);
 
-  public void highlightSequence(jalview.datamodel.SearchResults results);
+  public void highlightSequence(SearchResultsI results);
 
   // TODO remove this? never called
   public void updateColours(SequenceI sequence, int index);
index 7e691be..b3968a3 100644 (file)
@@ -31,6 +31,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.SequenceI;
 import jalview.ext.jmol.JmolParser;
 import jalview.gui.IProgressIndicator;
@@ -391,7 +392,7 @@ public class StructureSelectionManager
         registerPDBFile(pdb.getId().trim(), pdbFile);
       }
       // if PDBId is unavailable then skip SIFTS mapping execution path
-      isMapUsingSIFTs = pdb.isPPDBIdAvailable();
+      isMapUsingSIFTs = isMapUsingSIFTs && pdb.isPPDBIdAvailable();
 
     } catch (Exception ex)
     {
@@ -805,7 +806,7 @@ public class StructureSelectionManager
       return;
     }
 
-    SearchResults results = new SearchResults();
+    SearchResultsI results = new SearchResults();
     for (AtomSpec atom : atoms)
     {
       SequenceI lastseq = null;
@@ -855,7 +856,7 @@ public class StructureSelectionManager
   {
     boolean hasSequenceListeners = handlingVamsasMo
             || !seqmappings.isEmpty();
-    SearchResults results = null;
+    SearchResultsI results = null;
     if (seqPos == -1)
     {
       seqPos = seq.findPosition(indexpos);
index b00f1bc..5dc3465 100644 (file)
@@ -135,19 +135,14 @@ public abstract class AAStructureBindingModel extends
    * @param protocol
    */
   public AAStructureBindingModel(StructureSelectionManager ssm,
-          PDBEntry[] pdbentry, SequenceI[][] sequenceIs, String[][] chains,
+          PDBEntry[] pdbentry, SequenceI[][] sequenceIs,
           String protocol)
   {
     this.ssm = ssm;
     this.sequence = sequenceIs;
     this.nucleotide = Comparison.isNucleotide(sequenceIs);
-    this.chains = chains;
     this.pdbEntry = pdbentry;
     this.protocol = protocol;
-    if (chains == null)
-    {
-      this.chains = new String[pdbentry.length][];
-    }
   }
 
   public StructureSelectionManager getSsm()
@@ -674,4 +669,12 @@ public abstract class AAStructureBindingModel extends
   {
     this.finishedInit = fi;
   }
+
+  /**
+   * Returns a list of chains mapped in this viewer.
+   * 
+   * @return
+   */
+  public abstract List<String> getChainNames();
+
 }
index 31d1ded..525bfdb 100644 (file)
@@ -142,4 +142,53 @@ public class ColorUtils
             * (maxColour.getBlue() - minColour.getBlue());
     return new Color(r / 255, g / 255, b / 255);
   }
+
+  /**
+   * 'Fades' the given colour towards white by the specified proportion. A
+   * factor of 1 or more results in White, a factor of 0 leaves the colour
+   * unchanged, and a factor between 0 and 1 results in a proportionate change
+   * of RGB values towards (255, 255, 255).
+   * <p>
+   * A negative bleachFactor can be specified to darken the colour towards Black
+   * (0, 0, 0).
+   * 
+   * @param colour
+   * @param bleachFactor
+   * @return
+   */
+  public static Color bleachColour(Color colour, float bleachFactor)
+  {
+    if (bleachFactor >= 1f)
+    {
+      return Color.WHITE;
+    }
+    if (bleachFactor <= -1f)
+    {
+      return Color.BLACK;
+    }
+    if (bleachFactor == 0f)
+    {
+      return colour;
+    }
+
+    int red = colour.getRed();
+    int green = colour.getGreen();
+    int blue = colour.getBlue();
+
+    if (bleachFactor > 0)
+    {
+      red += (255 - red) * bleachFactor;
+      green += (255 - green) * bleachFactor;
+      blue += (255 - blue) * bleachFactor;
+      return new Color(red, green, blue);
+    }
+    else
+    {
+      float factor = 1 + bleachFactor;
+      red *= factor;
+      green *= factor;
+      blue *= factor;
+      return new Color(red, green, blue);
+    }
+  }
 }
index 0beb45b..1326647 100644 (file)
@@ -415,4 +415,29 @@ public class Comparison
             .size()]);
     return isNucleotide(oneDArray);
   }
+
+  /**
+   * Compares two residues either case sensitively or case insensitively
+   * depending on the caseSensitive flag
+   * 
+   * @param c1
+   *          first char
+   * @param c2
+   *          second char to compare with
+   * @param caseSensitive
+   *          if true comparison will be case sensitive otherwise its not
+   * @return
+   */
+  public static boolean isSameResidue(char c1, char c2,
+          boolean caseSensitive)
+  {
+    if (caseSensitive)
+    {
+      return (c1 == c2);
+    }
+    else
+    {
+      return Character.toUpperCase(c1) == Character.toUpperCase(c2);
+    }
+  }
 }
index e6aa472..04cb75e 100755 (executable)
@@ -100,14 +100,14 @@ public class DBRefUtils
     HashSet<String> srcs = new HashSet<String>();
     for (String src : sources)
     {
-      srcs.add(src);
+      srcs.add(src.toUpperCase());
     }
 
     List<DBRefEntry> res = new ArrayList<DBRefEntry>();
     for (DBRefEntry dbr : dbrefs)
     {
       String source = getCanonicalName(dbr.getSource());
-      if (srcs.contains(source))
+      if (srcs.contains(source.toUpperCase()))
       {
         res.add(dbr);
       }
index d14e4ad..389afcd 100755 (executable)
@@ -26,6 +26,8 @@
  */
 package jalview.util;
 
+import java.util.Arrays;
+
 /**
  * DOCUMENT ME!
  * 
@@ -664,30 +666,22 @@ public class Format
   }
 
   /**
-   * DOCUMENT ME!
+   * Returns a string consisting of n repeats of character c
    * 
    * @param c
-   *          DOCUMENT ME!
    * @param n
-   *          DOCUMENT ME!
    * 
-   * @return DOCUMENT ME!
+   * @return
    */
-  private static String repeat(char c, int n)
+  static String repeat(char c, int n)
   {
     if (n <= 0)
     {
       return "";
     }
-
-    StringBuffer s = new StringBuffer(n);
-
-    for (int i = 0; i < n; i++)
-    {
-      s.append(c);
-    }
-
-    return s.toString();
+    char[] chars = new char[n];
+    Arrays.fill(chars, c);
+    return new String(chars);
   }
 
   /**
@@ -947,4 +941,49 @@ public class Format
   {
     return formatString;
   }
+
+  /**
+   * Bespoke method to format percentage float value to the specified number of
+   * decimal places. Avoids use of general-purpose format parsers as a
+   * processing hotspot.
+   * 
+   * @param sb
+   * @param value
+   * @param dp
+   */
+  public static void appendPercentage(StringBuilder sb, float value, int dp)
+  {
+    /*
+     * rounding first
+     */
+    double d = value;
+    long factor = 1L;
+    for (int i = 0; i < dp; i++)
+    {
+      factor *= 10;
+    }
+    d *= factor;
+    d += 0.5;
+
+    /*
+     * integer part
+     */
+    value = (float) (d / factor);
+    sb.append((long) value);
+
+    /*
+     * decimal places
+     */
+    if (dp > 0)
+    {
+      sb.append(".");
+      while (dp > 0)
+      {
+        value = value - (int) value;
+        value *= 10;
+        sb.append((int) value);
+        dp--;
+      }
+    }
+  }
 }
index 1fe452d..f35339c 100644 (file)
@@ -31,8 +31,9 @@ import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentOrder;
 import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SearchResultMatchI;
 import jalview.datamodel.SearchResults;
-import jalview.datamodel.SearchResults.Match;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
@@ -194,7 +195,7 @@ public final class MappingUtils
       /*
        * Determine all mappings from this position to mapped sequences.
        */
-      SearchResults sr = buildSearchResults(seq, seqpos, mappings);
+      SearchResultsI sr = buildSearchResults(seq, seqpos, mappings);
 
       if (!sr.isEmpty())
       {
@@ -266,10 +267,10 @@ public final class MappingUtils
    * @param seqmappings
    * @return
    */
-  public static SearchResults buildSearchResults(SequenceI seq, int index,
+  public static SearchResultsI buildSearchResults(SequenceI seq, int index,
           List<AlignedCodonFrame> seqmappings)
   {
-    SearchResults results = new SearchResults();
+    SearchResultsI results = new SearchResults();
     addSearchResults(results, seq, index, seqmappings);
     return results;
   }
@@ -283,7 +284,7 @@ public final class MappingUtils
    * @param index
    * @param seqmappings
    */
-  public static void addSearchResults(SearchResults results, SequenceI seq,
+  public static void addSearchResults(SearchResultsI results, SequenceI seq,
           int index, List<AlignedCodonFrame> seqmappings)
   {
     if (index >= seq.getStart() && index <= seq.getEnd())
@@ -376,15 +377,15 @@ public final class MappingUtils
                */
               List<AlignedCodonFrame> mapping = Arrays
                       .asList(new AlignedCodonFrame[] { acf });
-              SearchResults sr = buildSearchResults(selected,
+              SearchResultsI sr = buildSearchResults(selected,
                       startResiduePos, mapping);
-              for (Match m : sr.getResults())
+              for (SearchResultMatchI m : sr.getResults())
               {
                 mappedStartResidue = m.getStart();
                 mappedEndResidue = m.getEnd();
               }
               sr = buildSearchResults(selected, endResiduePos, mapping);
-              for (Match m : sr.getResults())
+              for (SearchResultMatchI m : sr.getResults())
               {
                 mappedStartResidue = Math.min(mappedStartResidue,
                         m.getStart());
@@ -647,8 +648,8 @@ public final class MappingUtils
        * 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())
+      SearchResultsI sr = buildSearchResults(fromSeq, residuePos, mappings);
+      for (SearchResultMatchI m : sr.getResults())
       {
         int mappedStartResidue = m.getStart();
         int mappedEndResidue = m.getEnd();
index 3fb384f..49dc7ff 100644 (file)
@@ -30,6 +30,10 @@ import java.awt.event.MouseEvent;
  */
 public class Platform
 {
+  private static Boolean isAMac = null;
+
+  private static Boolean isHeadless = null;
+
   /**
    * sorry folks - Macs really are different
    * 
@@ -37,15 +41,21 @@ public class Platform
    */
   public static boolean isAMac()
   {
-    return java.lang.System.getProperty("os.name").indexOf("Mac") > -1;
+    if (isAMac == null)
+    {
+      isAMac = System.getProperty("os.name").indexOf("Mac") > -1;
+    }
+    return isAMac.booleanValue();
 
   }
 
   public static boolean isHeadless()
   {
-    String hdls = java.lang.System.getProperty("java.awt.headless");
-
-    return hdls != null && hdls.equals("true");
+    if (isHeadless == null)
+    {
+      isHeadless = "true".equals(System.getProperty("java.awt.headless"));
+    }
+    return isHeadless;
   }
 
   /**
@@ -89,8 +99,28 @@ public class Platform
    */
   public static boolean isControlDown(MouseEvent e)
   {
-    if (isAMac())
+    boolean aMac = isAMac();
+    return isControlDown(e, aMac);
+  }
+
+  /**
+   * Overloaded version of method (to allow unit testing)
+   * 
+   * @param e
+   * @param aMac
+   * @return
+   */
+  protected static boolean isControlDown(MouseEvent e, boolean aMac)
+  {
+    if (aMac)
     {
+      /*
+       * answer false for right mouse button
+       */
+      if (e.isPopupTrigger())
+      {
+        return false;
+      }
       return (Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() & e
               .getModifiers()) != 0;
       // could we use e.isMetaDown() here?
diff --git a/src/jalview/util/SparseCount.java b/src/jalview/util/SparseCount.java
new file mode 100644 (file)
index 0000000..7fd9792
--- /dev/null
@@ -0,0 +1,174 @@
+/*
+ * 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.util;
+
+import jalview.ext.android.SparseIntArray;
+import jalview.ext.android.SparseShortArray;
+
+/**
+ * A class to count occurrences of characters with minimal memory footprint.
+ * Sparse arrays of short values are used to hold the counts, with automatic
+ * promotion to arrays of int if any count exceeds the maximum value for a
+ * short.
+ * 
+ * @author gmcarstairs
+ *
+ */
+public class SparseCount
+{
+  private static final int DEFAULT_PROFILE_SIZE = 2;
+
+  /*
+   * array of keys (chars) and values (counts)
+   * held either as shorts or (if shorts overflow) as ints 
+   */
+  private SparseShortArray shortProfile;
+
+  private SparseIntArray intProfile;
+
+  /*
+   * flag is set true after short overflow occurs
+   */
+  private boolean useInts;
+
+  /**
+   * Constructor which initially creates a new sparse array of short values to
+   * hold counts.
+   * 
+   * @param profileSize
+   */
+  public SparseCount(int profileSize)
+  {
+    this.shortProfile = new SparseShortArray(profileSize);
+  }
+
+  /**
+   * Constructor which allocates an initial count array for only two distinct
+   * values (the array will grow if needed)
+   */
+  public SparseCount()
+  {
+    this(DEFAULT_PROFILE_SIZE);
+  }
+
+  /**
+   * Adds the given value for the given key (or sets the initial value), and
+   * returns the new value
+   * 
+   * @param key
+   * @param value
+   */
+  public int add(int key, int value)
+  {
+    int newValue = 0;
+    if (useInts)
+    {
+      newValue = intProfile.add(key, value);
+    }
+    else
+    {
+      try {
+        newValue = shortProfile.add(key, value);
+      } catch (ArithmeticException e) {
+        handleOverflow();
+        newValue = intProfile.add(key, value);
+      }
+    }
+    return newValue;
+  }
+
+  /**
+   * Switch from counting shorts to counting ints
+   */
+  synchronized void handleOverflow()
+  {
+    int size = shortProfile.size();
+    intProfile = new SparseIntArray(size);
+    for (int i = 0; i < size; i++)
+    {
+      short key = shortProfile.keyAt(i);
+      short value = shortProfile.valueAt(i);
+      intProfile.put(key, value);
+    }
+    shortProfile = null;
+    useInts = true;
+  }
+
+  /**
+   * Returns the size of the profile (number of distinct items counted)
+   * 
+   * @return
+   */
+  public int size()
+  {
+    return useInts ? intProfile.size() : shortProfile.size();
+  }
+
+  /**
+   * Returns the value for the key (zero if no such key)
+   * 
+   * @param key
+   * @return
+   */
+  public int get(int key)
+  {
+    return useInts ? intProfile.get(key) : shortProfile.get(key);
+  }
+
+  /**
+   * Sets the value for the given key
+   * 
+   * @param key
+   * @param value
+   */
+  public void put(int key, int value)
+  {
+    if (useInts)
+    {
+      intProfile.put(key, value);
+    }
+    else
+    {
+      shortProfile.put(key, value);
+    }
+  }
+
+  public int keyAt(int k)
+  {
+    return useInts ? intProfile.keyAt(k) : shortProfile.keyAt(k);
+  }
+
+  public int valueAt(int k)
+  {
+    return useInts ? intProfile.valueAt(k) : shortProfile.valueAt(k);
+  }
+
+  /**
+   * Answers true if this object wraps arrays of int values, false if using
+   * short values
+   * 
+   * @return
+   */
+  boolean isUsingInt()
+  {
+    return useInts;
+  }
+}
diff --git a/src/jalview/util/UrlConstants.java b/src/jalview/util/UrlConstants.java
new file mode 100644 (file)
index 0000000..1910bff
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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.util;
+
+/**
+ * A class to hold constants relating to Url links used in Jalview
+ */
+public class UrlConstants
+{
+
+  /*
+   * Sequence ID string
+   */
+  public static final String DB_ACCESSION = "DB_ACCESSION";
+
+  /*
+   * Sequence Name string
+   */
+  public static final String SEQUENCE_ID = "SEQUENCE_ID";
+
+  /*
+   * Default sequence URL link string for EMBL-EBI search
+   */
+  public static final String EMBLEBI_STRING = "EMBL-EBI Search|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$";
+
+  /*
+   * Default sequence URL link string for SRS 
+   */
+  public static final String SRS_STRING = "SRS|http://srs.ebi.ac.uk/srsbin/cgi-bin/wgetz?-newId+(([uniprot-all:$SEQUENCE_ID$]))+-view+SwissEntry";
+
+  /*
+   * not instantiable
+   */
+  private UrlConstants()
+  {
+  }
+}
index 4297090..3ee6432 100644 (file)
  */
 package jalview.util;
 
+import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.SequenceI;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
 import java.util.Vector;
 
 public class UrlLink
@@ -30,17 +39,33 @@ public class UrlLink
    * Jalview 2.4 extension allows regular expressions to be used to parse ID
    * strings and replace the result in the URL. Regex's operate on the whole ID
    * string given to the matchURL method, if no regex is supplied, then only
-   * text following the first pipe symbol will be susbstituted. Usage
+   * text following the first pipe symbol will be substituted. Usage
    * documentation todo.
    */
-  private String url_suffix, url_prefix, target, label, regexReplace;
+
+  // Internal constants
+  private static final String SEP = "|";
+
+  private static final String DELIM = "$";
+
+  private String urlSuffix;
+
+  private String urlPrefix;
+
+  private String target;
+
+  private String label;
+
+  private String regexReplace;
 
   private boolean dynamic = false;
 
+  private boolean usesDBaccession = false;
+
   private String invalidMessage = null;
 
   /**
-   * parse the given linkString of the form '<label>|<url>' into parts url may
+   * parse the given linkString of the form '<label>SEP<url>' into parts url may
    * contain a string $SEQUENCE_ID<=optional regex=>$ where <=optional regex=>
    * must be of the form =/<perl style regex>/=$
    * 
@@ -48,81 +73,37 @@ public class UrlLink
    */
   public UrlLink(String link)
   {
-    int sep = link.indexOf("|"), psqid = link.indexOf("$SEQUENCE_ID");
+    int sep = link.indexOf(SEP);
+    int psqid = link.indexOf(DELIM + DB_ACCESSION);
+    int nsqid = link.indexOf(DELIM + SEQUENCE_ID);
     if (psqid > -1)
     {
       dynamic = true;
-      int p = sep;
-      do
-      {
-        sep = p;
-        p = link.indexOf("|", sep + 1);
-      } while (p > sep && p < psqid);
-      // Assuming that the URL itself does not contain any '|' symbols
-      // sep now contains last pipe symbol position prior to any regex symbols
-      label = link.substring(0, sep);
-      if (label.indexOf("|") > -1)
-      {
-        // | terminated database name / www target at start of Label
-        target = label.substring(0, label.indexOf("|"));
-      }
-      else if (label.indexOf(" ") > 2)
-      {
-        // space separated Label - matches database name
-        target = label.substring(0, label.indexOf(" "));
-      }
-      else
-      {
-        target = label;
-      }
-      // Parse URL : Whole URL string first
-      url_prefix = link.substring(sep + 1, psqid);
-      if (link.indexOf("$SEQUENCE_ID=/") == psqid
-              && (p = link.indexOf("/=$", psqid + 14)) > psqid + 14)
-      {
-        // Extract Regex and suffix
-        url_suffix = link.substring(p + 3);
-        regexReplace = link.substring(psqid + 14, p);
-        try
-        {
-          com.stevesoft.pat.Regex rg = com.stevesoft.pat.Regex.perlCode("/"
-                  + regexReplace + "/");
-          if (rg == null)
-          {
-            invalidMessage = "Invalid Regular Expression : '"
-                    + regexReplace + "'\n";
-          }
-        } catch (Exception e)
-        {
-          invalidMessage = "Invalid Regular Expression : '" + regexReplace
-                  + "'\n";
-        }
-      }
-      else
-      {
-        regexReplace = null;
-        // verify format is really correct.
-        if (link.indexOf("$SEQUENCE_ID$") == psqid)
-        {
-          url_suffix = link.substring(psqid + 13);
-          regexReplace = null;
-        }
-        else
-        {
-          invalidMessage = "Warning: invalid regex structure for URL link : "
-                  + link;
-        }
-      }
+      usesDBaccession = true;
+
+      sep = parseTargetAndLabel(sep, psqid, link);
+
+      parseUrl(link, DB_ACCESSION, psqid, sep);
+    }
+    else if (nsqid > -1)
+    {
+      dynamic = true;
+      sep = parseTargetAndLabel(sep, nsqid, link);
+
+      parseUrl(link, SEQUENCE_ID, nsqid, sep);
     }
     else
     {
       target = link.substring(0, sep);
-      label = link.substring(0, sep = link.lastIndexOf("|"));
-      url_prefix = link.substring(sep + 1);
+      sep = link.lastIndexOf(SEP);
+      label = link.substring(0, sep);
+      urlPrefix = link.substring(sep + 1).trim();
       regexReplace = null; // implies we trim any prefix if necessary //
-      // regexReplace=".*\\|?(.*)";
-      url_suffix = null;
+      urlSuffix = null;
     }
+
+    label = label.trim();
+    target = target.trim();
   }
 
   /**
@@ -130,7 +111,7 @@ public class UrlLink
    */
   public String getUrl_suffix()
   {
-    return url_suffix;
+    return urlSuffix;
   }
 
   /**
@@ -138,7 +119,7 @@ public class UrlLink
    */
   public String getUrl_prefix()
   {
-    return url_prefix;
+    return urlPrefix;
   }
 
   /**
@@ -185,6 +166,34 @@ public class UrlLink
   }
 
   /**
+   * 
+   * @return whether link is dynamic
+   */
+  public boolean isDynamic()
+  {
+    return dynamic;
+  }
+
+  /**
+   * 
+   * @return whether link uses DB Accession id
+   */
+  public boolean usesDBAccession()
+  {
+    return usesDBaccession;
+  }
+
+  /**
+   * Set the label
+   * 
+   * @param newlabel
+   */
+  public void setLabel(String newlabel)
+  {
+    this.label = newlabel;
+  }
+
+  /**
    * return one or more URL strings by applying regex to the given idstring
    * 
    * @param idstring
@@ -209,7 +218,7 @@ public class UrlLink
           {
             // take whole regex
             return new String[] { rg.stringMatched(),
-                url_prefix + rg.stringMatched() + url_suffix };
+                urlPrefix + rg.stringMatched() + urlSuffix };
           } /*
              * else if (ns==1) { // take only subgroup match return new String[]
              * { rg.stringMatched(1), url_prefix+rg.stringMatched(1)+url_suffix
@@ -250,7 +259,7 @@ public class UrlLink
                 if (mtch.length() > 0)
                 {
                   subs.addElement(mtch);
-                  subs.addElement(url_prefix + mtch + url_suffix);
+                  subs.addElement(urlPrefix + mtch + urlSuffix);
                 }
                 s = r;
               }
@@ -259,8 +268,8 @@ public class UrlLink
                 if (rg.matchedFrom(s) > -1)
                 {
                   subs.addElement(rg.stringMatched(s));
-                  subs.addElement(url_prefix + rg.stringMatched(s)
-                          + url_suffix);
+                  subs.addElement(urlPrefix + rg.stringMatched(s)
+                          + urlSuffix);
                 }
                 s++;
               }
@@ -281,29 +290,254 @@ public class UrlLink
         }
       }
       /* Otherwise - trim off any 'prefix' - pre 2.4 Jalview behaviour */
-      if (idstring.indexOf("|") > -1)
+      if (idstring.indexOf(SEP) > -1)
       {
-        idstring = idstring.substring(idstring.lastIndexOf("|") + 1);
+        idstring = idstring.substring(idstring.lastIndexOf(SEP) + 1);
       }
 
       // just return simple url substitution.
-      return new String[] { idstring, url_prefix + idstring + url_suffix };
+      return new String[] { idstring, urlPrefix + idstring + urlSuffix };
     }
     else
     {
-      return new String[] { "", url_prefix };
+      return new String[] { "", urlPrefix };
     }
   }
 
+  @Override
   public String toString()
   {
+    String var = (usesDBaccession ? DB_ACCESSION : SEQUENCE_ID);
+
     return label
-            + "|"
-            + url_prefix
-            + (dynamic ? ("$SEQUENCE_ID" + ((regexReplace != null) ? "="
-                    + regexReplace + "=$" : "$")) : "")
-            + ((url_suffix == null) ? "" : url_suffix);
+            + SEP
+            + urlPrefix
+            + (dynamic ? (DELIM + var + ((regexReplace != null) ? "="
+                    + regexReplace + "=" + DELIM : DELIM)) : "")
+            + ((urlSuffix == null) ? "" : urlSuffix);
+  }
+
+  /**
+   * 
+   * @param firstSep
+   *          Location of first occurrence of separator in link string
+   * @param psqid
+   *          Position of sequence id or name in link string
+   * @param link
+   *          Link string containing database name and url
+   * @return Position of last separator symbol prior to any regex symbols
+   */
+  protected int parseTargetAndLabel(int firstSep, int psqid, String link)
+  {
+    int p = firstSep;
+    int sep = firstSep;
+    do
+    {
+      sep = p;
+      p = link.indexOf(SEP, sep + 1);
+    } while (p > sep && p < psqid);
+    // Assuming that the URL itself does not contain any SEP symbols
+    // sep now contains last pipe symbol position prior to any regex symbols
+    label = link.substring(0, sep);
+    if (label.indexOf(SEP) > -1)
+    {
+      // SEP terminated database name / www target at start of Label
+      target = label.substring(0, label.indexOf(SEP));
+    }
+    else if (label.indexOf(" ") > 2)
+    {
+      // space separated Label - matches database name
+      target = label.substring(0, label.indexOf(" "));
+    }
+    else
+    {
+      target = label;
+    }
+    return sep;
+  }
+
+  /**
+   * Parse the URL part of the link string
+   * 
+   * @param link
+   *          Link string containing database name and url
+   * @param varName
+   *          Name of variable in url string (e.g. SEQUENCE_ID, SEQUENCE_NAME)
+   * @param sqidPos
+   *          Position of id or name in link string
+   * @param sep
+   *          Position of separator in link string
+   */
+  protected void parseUrl(String link, String varName, int sqidPos, int sep)
+  {
+    urlPrefix = link.substring(sep + 1, sqidPos).trim();
+
+    // delimiter at start of regex: e.g. $SEQUENCE_ID=/
+    String startDelimiter = DELIM + varName + "=/";
+
+    // delimiter at end of regex: /=$
+    String endDelimiter = "/=" + DELIM;
+
+    int startLength = startDelimiter.length();
+
+    // Parse URL : Whole URL string first
+    int p = link.indexOf(endDelimiter, sqidPos + startLength);
+
+    if (link.indexOf(startDelimiter) == sqidPos
+            && (p > sqidPos + startLength))
+    {
+      // Extract Regex and suffix
+      urlSuffix = link.substring(p + endDelimiter.length());
+      regexReplace = link.substring(sqidPos + startLength, p);
+      try
+      {
+        com.stevesoft.pat.Regex rg = com.stevesoft.pat.Regex.perlCode("/"
+                + regexReplace + "/");
+        if (rg == null)
+        {
+          invalidMessage = "Invalid Regular Expression : '" + regexReplace
+                  + "'\n";
+        }
+      } catch (Exception e)
+      {
+        invalidMessage = "Invalid Regular Expression : '" + regexReplace
+                + "'\n";
+      }
+    }
+    else
+    {
+      // no regex
+      regexReplace = null;
+      // verify format is really correct.
+      if (link.indexOf(DELIM + varName + DELIM) == sqidPos)
+      {
+        urlSuffix = link.substring(sqidPos + startLength - 1);
+        regexReplace = null;
+      }
+      else
+      {
+        invalidMessage = "Warning: invalid regex structure for URL link : "
+                + link;
+      }
+    }
+  }
+
+  /**
+   * Create a set of URL links for a sequence
+   * 
+   * @param seq
+   *          The sequence to create links for
+   * @param linkset
+   *          Map of links: key = id + SEP + link, value = [target, label, id,
+   *          link]
+   */
+  public void createLinksFromSeq(final SequenceI seq,
+          Map<String, List<String>> linkset)
+  {
+    if (seq != null && dynamic)
+    {
+      createDynamicLinks(seq, linkset);
+    }
+    else
+    {
+      createStaticLink(linkset);
+    }
+  }
+
+  /**
+   * Create a static URL link
+   * 
+   * @param linkset
+   *          Map of links: key = id + SEP + link, value = [target, label, id,
+   *          link]
+   */
+  protected void createStaticLink(Map<String, List<String>> linkset)
+  {
+    if (!linkset.containsKey(label + SEP + getUrl_prefix()))
+    {
+      // Add a non-dynamic link
+      linkset.put(label + SEP + getUrl_prefix(),
+              Arrays.asList(target, label, null, getUrl_prefix()));
+    }
+  }
+
+  /**
+   * Create dynamic URL links
+   * 
+   * @param seq
+   *          The sequence to create links for
+   * @param linkset
+   *          Map of links: key = id + SEP + link, value = [target, label, id,
+   *          link]
+   */
+  protected void createDynamicLinks(final SequenceI seq,
+          Map<String, List<String>> linkset)
+  {
+    // collect id string too
+    String id = seq.getName();
+    String descr = seq.getDescription();
+    if (descr != null && descr.length() < 1)
+    {
+      descr = null;
+    }
+
+    if (usesDBAccession()) // link is ID
+    {
+      // collect matching db-refs
+      DBRefEntry[] dbr = DBRefUtils.selectRefs(seq.getDBRefs(),
+              new String[] { target });
+
+      // if there are any dbrefs which match up with the link
+      if (dbr != null)
+      {
+        for (int r = 0; r < dbr.length; r++)
+        {
+          // create Bare ID link for this URL
+          createBareURLLink(dbr[r].getAccessionId(), true, linkset);
+        }
+      }
+    }
+    else if (!usesDBAccession() && id != null) // link is name
+    {
+      // create Bare ID link for this URL
+      createBareURLLink(id, false, linkset);
+    }
+
+    // Create urls from description but only for URL links which are regex
+    // links
+    if (descr != null && getRegexReplace() != null)
+    {
+      // create link for this URL from description where regex matches
+      createBareURLLink(descr, false, linkset);
+    }
+  }
 
+  /*
+   * Create a bare URL Link
+   * Returns map where key = id + SEP + link, and value = [target, label, id, link]
+   */
+  protected void createBareURLLink(String id, Boolean combineLabel,
+          Map<String, List<String>> linkset)
+  {
+    String[] urls = makeUrls(id, true);
+    if (urls != null)
+    {
+      for (int u = 0; u < urls.length; u += 2)
+      {
+        if (!linkset.containsKey(urls[u] + SEP + urls[u + 1]))
+        {
+          String thisLabel = label;
+          if (combineLabel)
+          {
+            // incorporate label with idstring
+            thisLabel = label + SEP + urls[u];
+          }
+
+          linkset.put(urls[u] + SEP + urls[u + 1],
+                  Arrays.asList(target, thisLabel, urls[u], urls[u + 1]));
+        }
+      }
+    }
   }
 
   private static void testUrls(UrlLink ul, String idstring, String[] urls)
@@ -341,7 +575,8 @@ public class UrlLink
      * "PF3|http://us.expasy.org/cgi-bin/niceprot.pl?$SEQUENCE_ID=/PFAM:(.+)/=$"
      * , "NOTFER|http://notfer.org/$SEQUENCE_ID=/(?<!\\s)(.+)/=$",
      */
-    "NESTED|http://nested/$SEQUENCE_ID=/^(?:Label:)?(?:(?:gi\\|(\\d+))|([^:]+))/=$/nested" };
+    "NESTED|http://nested/$" + DB_ACCESSION
+            + "=/^(?:Label:)?(?:(?:gi\\|(\\d+))|([^:]+))/=$/nested" };
     String[] idstrings = new String[] {
     /*
      * //"LGUL_human", //"QWIQW_123123", "uniprot|why_do+_12313_foo",
@@ -382,15 +617,4 @@ public class UrlLink
       }
     }
   }
-
-  public boolean isDynamic()
-  {
-    // TODO Auto-generated method stub
-    return dynamic;
-  }
-
-  public void setLabel(String newlabel)
-  {
-    this.label = newlabel;
-  }
 }
index c1c88c1..fecccb0 100644 (file)
@@ -36,7 +36,8 @@ import jalview.datamodel.Annotation;
 import jalview.datamodel.CigarArray;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.HiddenSequences;
-import jalview.datamodel.SearchResults;
+import jalview.datamodel.ProfilesI;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceGroup;
@@ -700,7 +701,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   /**
    * results of alignment consensus analysis for visible portion of view
    */
-  protected Hashtable[] hconsensus = null;
+  protected ProfilesI hconsensus = null;
 
   /**
    * results of cDNA complement consensus visible portion of view
@@ -734,7 +735,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   }
 
   @Override
-  public void setSequenceConsensusHash(Hashtable[] hconsensus)
+  public void setSequenceConsensusHash(ProfilesI hconsensus)
   {
     this.hconsensus = hconsensus;
   }
@@ -746,7 +747,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   }
 
   @Override
-  public Hashtable[] getSequenceConsensusHash()
+  public ProfilesI getSequenceConsensusHash()
   {
     return hconsensus;
   }
@@ -939,7 +940,9 @@ public abstract class AlignmentViewport implements AlignViewportI,
     groupConservation = null;
     hconsensus = null;
     hcomplementConsensus = null;
-    // TODO removed listeners from changeSupport?
+    // colour scheme may hold reference to consensus
+    globalColourScheme = null;
+    // TODO remove listeners from changeSupport?
     changeSupport = null;
     setAlignment(null);
   }
@@ -1864,7 +1867,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
       cs.setConsensus(hconsensus);
       if (cs.conservationApplied())
       {
-        cs.setConservation(Conservation.calculateConservation("All", 3,
+        cs.setConservation(Conservation.calculateConservation("All",
                 alignment.getSequences(), 0, alignment.getWidth(), false,
                 getConsPercGaps(), false));
       }
@@ -2715,7 +2718,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    *          the SearchResults to add to
    * @return the offset (below top of visible region) of the matched sequence
    */
-  protected int findComplementScrollTarget(SearchResults sr)
+  protected int findComplementScrollTarget(SearchResultsI sr)
   {
     final AlignViewportI complement = getCodingComplement();
     if (complement == null || !complement.isFollowHighlight())
@@ -2822,6 +2825,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
    */
   private boolean selectionIsDefinedGroup = false;
 
+
   @Override
   public boolean isSelectionDefinedGroup()
   {
@@ -2845,4 +2849,27 @@ public abstract class AlignmentViewport implements AlignViewportI,
     return selectionGroup.getContext() == alignment
             || selectionIsDefinedGroup;
   }
+
+  /**
+   * null, or currently highlighted results on this view
+   */
+  private SearchResultsI searchResults = null;
+
+  @Override
+  public boolean hasSearchResults()
+  {
+    return searchResults != null;
+  }
+
+  @Override
+  public void setSearchResults(SearchResultsI results)
+  {
+    searchResults = results;
+  }
+
+  @Override
+  public SearchResultsI getSearchResults()
+  {
+    return searchResults;
+  }
 }
index 4ac4804..c1ad465 100644 (file)
@@ -288,8 +288,12 @@ public abstract class FeatureRendererModel implements
           continue;
         }
 
-        if ((features[i].getBegin() <= res)
-                && (features[i].getEnd() >= res))
+        // check if start/end are at res, and if not a contact feature, that res
+        // lies between start and end
+        if ((features[i].getBegin() == res || features[i].getEnd() == res)
+                || (!features[i].isContactFeature()
+                        && (features[i].getBegin() < res) && (features[i]
+                        .getEnd() >= res)))
         {
           tmp.add(features[i]);
         }
@@ -564,9 +568,16 @@ public abstract class FeatureRendererModel implements
     return fc.isColored(sequenceFeature);
   }
 
+  /**
+   * Answers true if the feature type is currently selected to be displayed,
+   * else false
+   * 
+   * @param type
+   * @return
+   */
   protected boolean showFeatureOfType(String type)
   {
-    return av.getFeaturesDisplayed().isVisible(type);
+    return type == null ? false : av.getFeaturesDisplayed().isVisible(type);
   }
 
   @Override
index 529df6f..431fbec 100644 (file)
@@ -96,7 +96,6 @@ public class ComplementConsensusThread extends ConsensusThread
    * @param consensusData
    *          the computed consensus data
    */
-  @Override
   protected void deriveConsensus(AlignmentAnnotation consensusAnnotation,
           Hashtable[] consensusData)
   {
@@ -104,4 +103,16 @@ public class ComplementConsensusThread extends ConsensusThread
             alignViewport.isShowSequenceLogo(), getSequences().length);
   }
 
+  @Override
+  public void updateResultAnnotation(boolean immediate)
+  {
+    AlignmentAnnotation consensus = getConsensusAnnotation();
+    Hashtable[] hconsensus = getViewportConsensus();
+    if (immediate || !calcMan.isWorking(this) && consensus != null
+            && hconsensus != null)
+    {
+      deriveConsensus(consensus, hconsensus);
+    }
+  }
+
 }
index 5f0ec84..debe45d 100644 (file)
@@ -26,11 +26,10 @@ import jalview.api.AlignmentViewPanel;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.SequenceI;
 import jalview.schemes.ColourSchemeI;
 
-import java.util.Hashtable;
-
 public class ConsensusThread extends AlignCalcWorker
 {
   public ConsensusThread(AlignViewportI alignViewport,
@@ -125,10 +124,11 @@ public class ConsensusThread extends AlignCalcWorker
    */
   protected void computeConsensus(AlignmentI alignment)
   {
-    Hashtable[] hconsensus = new Hashtable[alignment.getWidth()];
 
     SequenceI[] aseqs = getSequences();
-    AAFrequency.calculate(aseqs, 0, alignment.getWidth(), hconsensus, true);
+    int width = alignment.getWidth();
+    ProfilesI hconsensus = AAFrequency.calculate(aseqs, width, 0,
+            width, true);
 
     alignViewport.setSequenceConsensusHash(hconsensus);
     setColourSchemeConsensus(hconsensus);
@@ -145,7 +145,7 @@ public class ConsensusThread extends AlignCalcWorker
   /**
    * @param hconsensus
    */
-  protected void setColourSchemeConsensus(Hashtable[] hconsensus)
+  protected void setColourSchemeConsensus(ProfilesI hconsensus)
   {
     ColourSchemeI globalColourScheme = alignViewport
             .getGlobalColourScheme();
@@ -178,7 +178,7 @@ public class ConsensusThread extends AlignCalcWorker
   public void updateResultAnnotation(boolean immediate)
   {
     AlignmentAnnotation consensus = getConsensusAnnotation();
-    Hashtable[] hconsensus = getViewportConsensus();
+    ProfilesI hconsensus = (ProfilesI) getViewportConsensus();
     if (immediate || !calcMan.isWorking(this) && consensus != null
             && hconsensus != null)
     {
@@ -192,15 +192,18 @@ public class ConsensusThread extends AlignCalcWorker
    * 
    * @param consensusAnnotation
    *          the annotation to be populated
-   * @param consensusData
+   * @param hconsensus
    *          the computed consensus data
    */
   protected void deriveConsensus(AlignmentAnnotation consensusAnnotation,
-          Hashtable[] consensusData)
+          ProfilesI hconsensus)
   {
+
     long nseq = getSequences().length;
-    AAFrequency.completeConsensus(consensusAnnotation, consensusData, 0,
-            consensusData.length, alignViewport.isIgnoreGapsConsensus(),
+    AAFrequency.completeConsensus(consensusAnnotation, hconsensus,
+            hconsensus.getStartColumn(),
+            hconsensus.getEndColumn() + 1,
+            alignViewport.isIgnoreGapsConsensus(),
             alignViewport.isShowSequenceLogo(), nseq);
   }
 
@@ -209,8 +212,9 @@ public class ConsensusThread extends AlignCalcWorker
    * 
    * @return
    */
-  protected Hashtable[] getViewportConsensus()
+  protected Object getViewportConsensus()
   {
+    // TODO convert ComplementConsensusThread to use Profile
     return alignViewport.getSequenceConsensusHash();
   }
 }
index 11ec521..e71c4f5 100644 (file)
@@ -94,7 +94,7 @@ public class ConservationThread extends AlignCalcWorker
       }
       try
       {
-        cons = Conservation.calculateConservation("All", 3,
+        cons = Conservation.calculateConservation("All",
                 alignment.getSequences(), 0, alWidth - 1, false,
                 ConsPercGaps, quality != null);
       } catch (IndexOutOfBoundsException x)
index acca50f..27db604 100644 (file)
@@ -29,6 +29,7 @@ import jalview.datamodel.SequenceI;
 import jalview.io.StructureFile;
 import jalview.schemes.ResidueProperties;
 import jalview.structure.StructureMapping;
+import jalview.util.Comparison;
 import jalview.util.DBRefUtils;
 import jalview.util.Format;
 import jalview.xml.binding.sifts.Entry;
@@ -510,13 +511,13 @@ public class SiftsClient implements SiftsClientI
     if (os != null)
     {
       MappingOutputPojo mop = new MappingOutputPojo();
-      mop.setSeqStart(pdbStart);
-      mop.setSeqEnd(pdbEnd);
+      mop.setSeqStart(seqStart);
+      mop.setSeqEnd(seqEnd);
       mop.setSeqName(seq.getName());
       mop.setSeqResidue(matchedSeq);
 
-      mop.setStrStart(seqStart);
-      mop.setStrEnd(seqEnd);
+      mop.setStrStart(pdbStart);
+      mop.setStrEnd(pdbEnd);
       mop.setStrName(structId);
       mop.setStrResidue(targetStrucSeqs.toString());
 
@@ -826,6 +827,10 @@ public class SiftsClient implements SiftsClientI
 
     if (sPojo[0].entityId != null)
     {
+      if (sPojo[0].pid < 1)
+      {
+        return null;
+      }
       for (Entity entity : entities)
       {
         if (!entity.getEntityId().equalsIgnoreCase(sPojo[0].entityId))
@@ -1000,8 +1005,10 @@ public class SiftsClient implements SiftsClientI
         {
           if ((i + (j * len)) < seqRes.length())
           {
-            if (seqRes.charAt(i + (j * len)) == strRes
-                    .charAt(i + (j * len))
+            boolean sameChar = Comparison.isSameResidue(
+                    seqRes.charAt(i + (j * len)),
+                    strRes.charAt(i + (j * len)), false);
+            if (sameChar
                     && !jalview.util.Comparison.isGap(seqRes.charAt(i
                             + (j * len))))
             {
index eff6bbf..58601a9 100644 (file)
@@ -23,65 +23,64 @@ package jalview.analysis;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNull;
 
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.ProfileI;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 
-import java.util.Hashtable;
-
 import org.testng.annotations.Test;
 
 public class AAFrequencyTest
 {
-  private static final String C = AAFrequency.MAXCOUNT;
-
-  private static final String R = AAFrequency.MAXRESIDUE;
-
-  private static final String G = AAFrequency.PID_GAPS;
-
-  private static final String N = AAFrequency.PID_NOGAPS;
-
-  private static final String P = AAFrequency.PROFILE;
-
   @Test(groups = { "Functional" })
   public void testCalculate_noProfile()
   {
-    SequenceI seq1 = new Sequence("Seq1", "CAGT");
-    SequenceI seq2 = new Sequence("Seq2", "CACT");
-    SequenceI seq3 = new Sequence("Seq3", "C--G");
-    SequenceI seq4 = new Sequence("Seq4", "CA-t");
+    SequenceI seq1 = new Sequence("Seq1", "CAG-T");
+    SequenceI seq2 = new Sequence("Seq2", "CAC-T");
+    SequenceI seq3 = new Sequence("Seq3", "C---G");
+    SequenceI seq4 = new Sequence("Seq4", "CA--t");
     SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
-    Hashtable[] result = new Hashtable[seq1.getLength()];
-
-    AAFrequency.calculate(seqs, 0, seq1.getLength(), result, false);
+    int width = seq1.getLength();
+    ProfilesI result = AAFrequency.calculate(seqs, width, 0, width,
+            false);
 
     // col 0 is 100% C
-    Hashtable col = result[0];
-    assertEquals(100f, (Float) col.get(G), 0.0001f);
-    assertEquals(100f, (Float) col.get(N), 0.0001f);
-    assertEquals(4, col.get(C));
-    assertEquals("C", col.get(R));
-    assertNull(col.get(P));
+    ProfileI col = result.get(0);
+    assertEquals(100f, col.getPercentageIdentity(false));
+    assertEquals(100f, col.getPercentageIdentity(true));
+    assertEquals(4, col.getMaxCount());
+    assertEquals("C", col.getModalResidue());
+    assertNull(col.getCounts());
 
     // col 1 is 75% A
-    col = result[1];
-    assertEquals(75f, (Float) col.get(G), 0.0001f);
-    assertEquals(100f, (Float) col.get(N), 0.0001f);
-    assertEquals(3, col.get(C));
-    assertEquals("A", col.get(R));
+    col = result.get(1);
+    assertEquals(75f, col.getPercentageIdentity(false));
+    assertEquals(100f, col.getPercentageIdentity(true));
+    assertEquals(3, col.getMaxCount());
+    assertEquals("A", col.getModalResidue());
 
     // col 2 is 50% G 50% C or 25/25 counting gaps
-    col = result[2];
-    assertEquals(25f, (Float) col.get(G), 0.0001f);
-    assertEquals(50f, (Float) col.get(N), 0.0001f);
-    assertEquals(1, col.get(C));
-    assertEquals("CG", col.get(R));
-
-    // col 3 is 75% T 25% G
-    col = result[3];
-    assertEquals(75f, (Float) col.get(G), 0.0001f);
-    assertEquals(75f, (Float) col.get(N), 0.0001f);
-    assertEquals(3, col.get(C));
-    assertEquals("T", col.get(R));
+    col = result.get(2);
+    assertEquals(25f, col.getPercentageIdentity(false));
+    assertEquals(50f, col.getPercentageIdentity(true));
+    assertEquals(1, col.getMaxCount());
+    assertEquals("CG", col.getModalResidue());
+
+    // col 3 is all gaps
+    col = result.get(3);
+    assertEquals(0f, col.getPercentageIdentity(false));
+    assertEquals(0f, col.getPercentageIdentity(true));
+    assertEquals(0, col.getMaxCount());
+    assertEquals("", col.getModalResidue());
+
+    // col 4 is 75% T 25% G
+    col = result.get(4);
+    assertEquals(75f, col.getPercentageIdentity(false));
+    assertEquals(75f, col.getPercentageIdentity(true));
+    assertEquals(3, col.getMaxCount());
+    assertEquals("T", col.getModalResidue());
   }
 
   @Test(groups = { "Functional" })
@@ -92,33 +91,34 @@ public class AAFrequencyTest
     SequenceI seq3 = new Sequence("Seq3", "C--G");
     SequenceI seq4 = new Sequence("Seq4", "CA-t");
     SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
-    Hashtable[] result = new Hashtable[seq1.getLength()];
-
-    AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true);
-    int[][] profile = (int[][]) result[0].get(P);
-    assertEquals(4, profile[0]['C']);
-    assertEquals(4, profile[1][0]); // no of seqs
-    assertEquals(4, profile[1][1]); // nongapped in column
-
-    profile = (int[][]) result[1].get(P);
-    assertEquals(3, profile[0]['A']);
-    assertEquals(4, profile[1][0]);
-    assertEquals(3, profile[1][1]);
-
-    profile = (int[][]) result[2].get(P);
-    assertEquals(1, profile[0]['G']);
-    assertEquals(1, profile[0]['C']);
-    assertEquals(4, profile[1][0]);
-    assertEquals(2, profile[1][1]);
-
-    profile = (int[][]) result[3].get(P);
-    assertEquals(3, profile[0]['T']);
-    assertEquals(1, profile[0]['G']);
-    assertEquals(4, profile[1][0]);
-    assertEquals(4, profile[1][1]);
+    int width = seq1.getLength();
+    ProfilesI result = AAFrequency.calculate(seqs, width, 0, width,
+            true);
+
+    ProfileI profile = result.get(0);
+    assertEquals(4, profile.getCounts().getCount('C'));
+    assertEquals(4, profile.getHeight());
+    assertEquals(4, profile.getNonGapped());
+
+    profile = result.get(1);
+    assertEquals(3, profile.getCounts().getCount('A'));
+    assertEquals(4, profile.getHeight());
+    assertEquals(3, profile.getNonGapped());
+
+    profile = result.get(2);
+    assertEquals(1, profile.getCounts().getCount('C'));
+    assertEquals(1, profile.getCounts().getCount('G'));
+    assertEquals(4, profile.getHeight());
+    assertEquals(2, profile.getNonGapped());
+
+    profile = result.get(3);
+    assertEquals(3, profile.getCounts().getCount('T'));
+    assertEquals(1, profile.getCounts().getCount('G'));
+    assertEquals(4, profile.getHeight());
+    assertEquals(4, profile.getNonGapped());
   }
 
-  @Test(groups = { "Functional" })
+  @Test(groups = { "Functional" }, enabled = false)
   public void testCalculate_withProfileTiming()
   {
     SequenceI seq1 = new Sequence("Seq1", "CAGT");
@@ -126,27 +126,100 @@ public class AAFrequencyTest
     SequenceI seq3 = new Sequence("Seq3", "C--G");
     SequenceI seq4 = new Sequence("Seq4", "CA-t");
     SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
-    Hashtable[] result = new Hashtable[seq1.getLength()];
 
-    // ensure class loaded and initialized
-    AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true);
+    // ensure class loaded and initialised
+    int width = seq1.getLength();
+    AAFrequency.calculate(seqs, width, 0, width, true);
+
     int reps = 100000;
     long start = System.currentTimeMillis();
     for (int i = 0; i < reps; i++)
     {
-      AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true);
+      AAFrequency.calculate(seqs, width, 0, width, true);
     }
     System.out.println(System.currentTimeMillis() - start);
   }
 
+  /**
+   * Test generation of consensus annotation with options 'include gaps'
+   * (profile percentages are of all sequences, whether gapped or not), and
+   * 'show logo' (the full profile with all residue percentages is reported in
+   * the description for the tooltip)
+   */
   @Test(groups = { "Functional" })
-  public void testGetPercentageFormat()
+  public void testCompleteConsensus_includeGaps_showLogo()
   {
-    assertNull(AAFrequency.getPercentageFormat(0));
-    assertNull(AAFrequency.getPercentageFormat(99));
-    assertEquals("%3.1f", AAFrequency.getPercentageFormat(100).toString());
-    assertEquals("%3.1f", AAFrequency.getPercentageFormat(999).toString());
-    assertEquals("%3.2f", AAFrequency.getPercentageFormat(1000).toString());
-    assertEquals("%3.2f", AAFrequency.getPercentageFormat(9999).toString());
+    /*
+     * first compute the profiles
+     */
+    SequenceI seq1 = new Sequence("Seq1", "CAG-T");
+    SequenceI seq2 = new Sequence("Seq2", "CAC-T");
+    SequenceI seq3 = new Sequence("Seq3", "C---G");
+    SequenceI seq4 = new Sequence("Seq4", "CA--t");
+    SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
+    int width = seq1.getLength();
+    ProfilesI profiles = AAFrequency.calculate(seqs, width, 0, width, true);
+
+    AlignmentAnnotation consensus = new AlignmentAnnotation("Consensus",
+            "PID", new Annotation[width]);
+    AAFrequency
+            .completeConsensus(consensus, profiles, 0, 5, false, true, 4);
+
+    Annotation ann = consensus.annotations[0];
+    assertEquals("C 100%", ann.description);
+    assertEquals("C", ann.displayCharacter);
+    ann = consensus.annotations[1];
+    assertEquals("A 75%", ann.description);
+    assertEquals("A", ann.displayCharacter);
+    ann = consensus.annotations[2];
+    assertEquals("C 25%; G 25%", ann.description);
+    assertEquals("+", ann.displayCharacter);
+    ann = consensus.annotations[3];
+    assertEquals("", ann.description);
+    assertEquals("-", ann.displayCharacter);
+    ann = consensus.annotations[4];
+    assertEquals("T 75%; G 25%", ann.description);
+    assertEquals("T", ann.displayCharacter);
+  }
+
+  /**
+   * Test generation of consensus annotation with options 'ignore gaps' (profile
+   * percentages are of the non-gapped sequences) and 'no logo' (only the modal
+   * residue[s] percentage is reported in the description for the tooltip)
+   */
+  @Test(groups = { "Functional" })
+  public void testCompleteConsensus_ignoreGaps_noLogo()
+  {
+    /*
+     * first compute the profiles
+     */
+    SequenceI seq1 = new Sequence("Seq1", "CAG-T");
+    SequenceI seq2 = new Sequence("Seq2", "CAC-T");
+    SequenceI seq3 = new Sequence("Seq3", "C---G");
+    SequenceI seq4 = new Sequence("Seq4", "CA--t");
+    SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
+    int width = seq1.getLength();
+    ProfilesI profiles = AAFrequency.calculate(seqs, width, 0, width, true);
+  
+    AlignmentAnnotation consensus = new AlignmentAnnotation("Consensus",
+            "PID", new Annotation[width]);
+    AAFrequency
+            .completeConsensus(consensus, profiles, 0, 5, true, false, 4);
+  
+    Annotation ann = consensus.annotations[0];
+    assertEquals("C 100%", ann.description);
+    assertEquals("C", ann.displayCharacter);
+    ann = consensus.annotations[1];
+    assertEquals("A 100%", ann.description);
+    assertEquals("A", ann.displayCharacter);
+    ann = consensus.annotations[2];
+    assertEquals("[CG] 50%", ann.description);
+    assertEquals("+", ann.displayCharacter);
+    ann = consensus.annotations[3];
+    assertEquals("", ann.description);
+    assertEquals("-", ann.displayCharacter);
+    ann = consensus.annotations[4];
+    assertEquals("T 75%", ann.description);
+    assertEquals("T", ann.displayCharacter);
   }
 }
index 4aed7e7..449514a 100644 (file)
@@ -35,8 +35,8 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.Mapping;
-import jalview.datamodel.SearchResults;
-import jalview.datamodel.SearchResults.Match;
+import jalview.datamodel.SearchResultMatchI;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
@@ -1119,9 +1119,9 @@ public class AlignmentUtilsTests
     assertEquals(1, mappings.size());
 
     // map G to GGG
-    SearchResults sr = MappingUtils.buildSearchResults(pep1, 1, mappings);
+    SearchResultsI sr = MappingUtils.buildSearchResults(pep1, 1, mappings);
     assertEquals(1, sr.getResults().size());
-    Match m = sr.getResults().get(0);
+    SearchResultMatchI m = sr.getResults().get(0);
     assertSame(cds1Dss, m.getSequence());
     assertEquals(1, m.getStart());
     assertEquals(3, m.getEnd());
@@ -1650,10 +1650,10 @@ public class AlignmentUtilsTests
     List<AlignedCodonFrame> pep1CdsMappings = MappingUtils
             .findMappingsForSequence(cds.getSequenceAt(0), pep1Mappings);
     assertEquals(1, pep1CdsMappings.size());
-    SearchResults sr = MappingUtils.buildSearchResults(pep1, 1,
+    SearchResultsI sr = MappingUtils.buildSearchResults(pep1, 1,
             pep1CdsMappings);
     assertEquals(1, sr.getResults().size());
-    Match m = sr.getResults().get(0);
+    SearchResultMatchI m = sr.getResults().get(0);
     assertEquals(cds.getSequenceAt(0).getDatasetSequence(), m.getSequence());
     assertEquals(1, m.getStart());
     assertEquals(3, m.getEnd());
@@ -2388,9 +2388,9 @@ public class AlignmentUtilsTests
     assertEquals(1, mappings.size());
 
     // map G to GGG
-    SearchResults sr = MappingUtils.buildSearchResults(pep3, 1, mappings);
+    SearchResultsI sr = MappingUtils.buildSearchResults(pep3, 1, mappings);
     assertEquals(1, sr.getResults().size());
-    Match m = sr.getResults().get(0);
+    SearchResultMatchI m = sr.getResults().get(0);
     assertSame(cds.getSequenceAt(0).getDatasetSequence(), m.getSequence());
     assertEquals(1, m.getStart());
     assertEquals(3, m.getEnd());
diff --git a/test/jalview/analysis/ConservationTest.java b/test/jalview/analysis/ConservationTest.java
new file mode 100644 (file)
index 0000000..39eb309
--- /dev/null
@@ -0,0 +1,336 @@
+/*
+ * 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.analysis;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.Test;
+
+public class ConservationTest
+{
+  @Test(groups = "Functional")
+  public void testRecordConservation()
+  {
+    Map<String, Integer> resultMap = new HashMap<String, Integer>();
+
+    // V is hydrophobic, aliphatic, small
+    Conservation.recordConservation(resultMap, "V");
+    assertEquals(resultMap.get("hydrophobic").intValue(), 1);
+    assertEquals(resultMap.get("aliphatic").intValue(), 1);
+    assertEquals(resultMap.get("small").intValue(), 1);
+    assertEquals(resultMap.get("tiny").intValue(), 0);
+    assertEquals(resultMap.get("polar").intValue(), 0);
+    assertEquals(resultMap.get("charged").intValue(), 0);
+
+    // now add S: not hydrophobic, small, tiny, polar, not aliphatic
+    Conservation.recordConservation(resultMap, "s");
+    assertEquals(resultMap.get("hydrophobic").intValue(), -1);
+    assertEquals(resultMap.get("aliphatic").intValue(), -1);
+    assertEquals(resultMap.get("small").intValue(), 1);
+    assertEquals(resultMap.get("tiny").intValue(), -1);
+    assertEquals(resultMap.get("polar").intValue(), -1);
+    assertEquals(resultMap.get("charged").intValue(), 0);
+  }
+
+  @Test(groups = "Functional")
+  public void testCountConservationAndGaps()
+  {
+    List<SequenceI> seqs = new ArrayList<SequenceI>();
+    seqs.add(new Sequence("seq1", "VGnY")); // not case sensitive
+    seqs.add(new Sequence("seq2", "-G-y"));
+    seqs.add(new Sequence("seq3", "VG-Y"));
+    seqs.add(new Sequence("seq4", "VGNW"));
+
+    Conservation cons = new Conservation("", seqs, 0, 50);
+    int[] counts = cons.countConservationAndGaps(0);
+    assertEquals(counts[0], 1); // conserved
+    assertEquals(counts[1], 1); // gap count
+    counts = cons.countConservationAndGaps(1);
+    assertEquals(counts[0], 1);
+    assertEquals(counts[1], 0);
+    counts = cons.countConservationAndGaps(2);
+    assertEquals(counts[0], 1);
+    assertEquals(counts[1], 2);
+    counts = cons.countConservationAndGaps(3);
+    assertEquals(counts[0], 0); // not conserved
+    assertEquals(counts[1], 0);
+  }
+
+  @Test(groups = "Functional")
+  public void testCalculate_noThreshold()
+  {
+    List<SequenceI> seqs = new ArrayList<SequenceI>();
+    seqs.add(new Sequence("seq1", "VGIV-N"));
+    seqs.add(new Sequence("seq2", "V-iL-N")); // not case sensitive
+    seqs.add(new Sequence("seq3", "V-IW-N"));
+    seqs.add(new Sequence("seq4", "VGLH-L"));
+
+    Conservation cons = new Conservation("", 0, seqs, 0, 5);
+    cons.calculate();
+
+    /*
+     * column 0: all V (hydrophobic/aliphatic/small)
+     */
+    Map<String, Integer> colCons = cons.total[0];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), 1);
+    assertEquals(colCons.get("small").intValue(), 1);
+    assertEquals(colCons.get("tiny").intValue(), 0);
+    assertEquals(colCons.get("proline").intValue(), 0);
+    assertEquals(colCons.get("charged").intValue(), 0);
+    assertEquals(colCons.get("negative").intValue(), 0);
+    assertEquals(colCons.get("polar").intValue(), 0);
+    assertEquals(colCons.get("positive").intValue(), 0);
+    assertEquals(colCons.get("aromatic").intValue(), 0);
+
+    /*
+     * column 1: all G (hydrophobic/small/tiny)
+     * gaps take default value of property present
+     */
+    colCons = cons.total[1];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), -1);
+    assertEquals(colCons.get("small").intValue(), 1);
+    assertEquals(colCons.get("tiny").intValue(), 1);
+    assertEquals(colCons.get("proline").intValue(), -1);
+    assertEquals(colCons.get("charged").intValue(), -1);
+    assertEquals(colCons.get("negative").intValue(), -1);
+    assertEquals(colCons.get("polar").intValue(), -1);
+    assertEquals(colCons.get("positive").intValue(), -1);
+    assertEquals(colCons.get("aromatic").intValue(), -1);
+
+    /*
+     * column 2: I/L (aliphatic/hydrophobic), all others negatively conserved
+     */
+    colCons = cons.total[2];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), 1);
+    assertEquals(colCons.get("small").intValue(), 0);
+    assertEquals(colCons.get("tiny").intValue(), 0);
+    assertEquals(colCons.get("proline").intValue(), 0);
+    assertEquals(colCons.get("charged").intValue(), 0);
+    assertEquals(colCons.get("negative").intValue(), 0);
+    assertEquals(colCons.get("polar").intValue(), 0);
+    assertEquals(colCons.get("positive").intValue(), 0);
+    assertEquals(colCons.get("aromatic").intValue(), 0);
+
+    /*
+     * column 3: VLWH all hydrophobic, none is tiny, negative or proline
+     */
+    colCons = cons.total[3];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), -1);
+    assertEquals(colCons.get("small").intValue(), -1);
+    assertEquals(colCons.get("tiny").intValue(), 0);
+    assertEquals(colCons.get("proline").intValue(), 0);
+    assertEquals(colCons.get("charged").intValue(), -1);
+    assertEquals(colCons.get("negative").intValue(), 0);
+    assertEquals(colCons.get("polar").intValue(), -1);
+    assertEquals(colCons.get("positive").intValue(), -1);
+    assertEquals(colCons.get("aromatic").intValue(), -1);
+
+    /*
+     * column 4: all gaps - counted as having all properties
+     */
+    colCons = cons.total[4];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), 1);
+    assertEquals(colCons.get("small").intValue(), 1);
+    assertEquals(colCons.get("tiny").intValue(), 1);
+    assertEquals(colCons.get("proline").intValue(), 1);
+    assertEquals(colCons.get("charged").intValue(), 1);
+    assertEquals(colCons.get("negative").intValue(), 1);
+    assertEquals(colCons.get("polar").intValue(), 1);
+    assertEquals(colCons.get("positive").intValue(), 1);
+    assertEquals(colCons.get("aromatic").intValue(), 1);
+
+    /*
+     * column 5: N (small polar) and L (aliphatic hydrophobic) 
+     * have nothing in common!
+     */
+    colCons = cons.total[5];
+    assertEquals(colCons.get("hydrophobic").intValue(), -1);
+    assertEquals(colCons.get("aliphatic").intValue(), -1);
+    assertEquals(colCons.get("small").intValue(), -1);
+    assertEquals(colCons.get("tiny").intValue(), 0);
+    assertEquals(colCons.get("proline").intValue(), 0);
+    assertEquals(colCons.get("charged").intValue(), 0);
+    assertEquals(colCons.get("negative").intValue(), 0);
+    assertEquals(colCons.get("polar").intValue(), -1);
+    assertEquals(colCons.get("positive").intValue(), 0);
+    assertEquals(colCons.get("aromatic").intValue(), 0);
+  }
+
+  /**
+   * Test for the case whether the number of non-gapped sequences in a column
+   * has to be above a threshold
+   */
+  @Test(groups = "Functional")
+  public void testCalculate_threshold()
+  {
+    List<SequenceI> seqs = new ArrayList<SequenceI>();
+    seqs.add(new Sequence("seq1", "VGIV-"));
+    seqs.add(new Sequence("seq2", "V-iL-")); // not case sensitive
+    seqs.add(new Sequence("seq3", "V-IW-"));
+    seqs.add(new Sequence("seq4", "VGLH-"));
+    seqs.add(new Sequence("seq5", "VGLH-"));
+  
+    /*
+     * threshold 50% means a residue has to occur 3 or more times
+     * in a column to be counted for conservation
+     */
+    // TODO: ConservationThread uses a value of 3
+    // calculateConservation states it is the minimum number of sequences
+    // but it is treated as percentage threshold in calculate() ?
+    Conservation cons = new Conservation("", 50, seqs, 0, 4);
+    cons.calculate();
+  
+    /*
+     * column 0: all V (hydrophobic/aliphatic/small)
+     */
+    Map<String, Integer> colCons = cons.total[0];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), 1);
+    assertEquals(colCons.get("small").intValue(), 1);
+    assertEquals(colCons.get("tiny").intValue(), 0);
+    assertEquals(colCons.get("proline").intValue(), 0);
+    assertEquals(colCons.get("charged").intValue(), 0);
+    assertEquals(colCons.get("negative").intValue(), 0);
+    assertEquals(colCons.get("polar").intValue(), 0);
+    assertEquals(colCons.get("positive").intValue(), 0);
+    assertEquals(colCons.get("aromatic").intValue(), 0);
+  
+    /*
+     * column 1: all G (hydrophobic/small/tiny)
+     * gaps are ignored as not above threshold
+     */
+    colCons = cons.total[1];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), 0);
+    assertEquals(colCons.get("small").intValue(), 1);
+    assertEquals(colCons.get("tiny").intValue(), 1);
+    assertEquals(colCons.get("proline").intValue(), 0);
+    assertEquals(colCons.get("charged").intValue(), 0);
+    assertEquals(colCons.get("negative").intValue(), 0);
+    assertEquals(colCons.get("polar").intValue(), 0);
+    assertEquals(colCons.get("positive").intValue(), 0);
+    assertEquals(colCons.get("aromatic").intValue(), 0);
+  
+    /*
+     * column 2: I/L (aliphatic/hydrophobic), all others negatively conserved
+     */
+    colCons = cons.total[2];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), 1);
+    assertEquals(colCons.get("small").intValue(), 0);
+    assertEquals(colCons.get("tiny").intValue(), 0);
+    assertEquals(colCons.get("proline").intValue(), 0);
+    assertEquals(colCons.get("charged").intValue(), 0);
+    assertEquals(colCons.get("negative").intValue(), 0);
+    assertEquals(colCons.get("polar").intValue(), 0);
+    assertEquals(colCons.get("positive").intValue(), 0);
+    assertEquals(colCons.get("aromatic").intValue(), 0);
+  
+    /*
+     * column 3: nothing above threshold
+     */
+    colCons = cons.total[3];
+    assertTrue(colCons.isEmpty());
+  
+    /*
+     * column 4: all gaps - counted as having all properties
+     */
+    colCons = cons.total[4];
+    assertEquals(colCons.get("hydrophobic").intValue(), 1);
+    assertEquals(colCons.get("aliphatic").intValue(), 1);
+    assertEquals(colCons.get("small").intValue(), 1);
+    assertEquals(colCons.get("tiny").intValue(), 1);
+    assertEquals(colCons.get("proline").intValue(), 1);
+    assertEquals(colCons.get("charged").intValue(), 1);
+    assertEquals(colCons.get("negative").intValue(), 1);
+    assertEquals(colCons.get("polar").intValue(), 1);
+    assertEquals(colCons.get("positive").intValue(), 1);
+    assertEquals(colCons.get("aromatic").intValue(), 1);
+  }
+
+  /**
+   * Test the method that derives the conservation 'sequence' and the mouseover
+   * tooltips from the computed conservation
+   */
+  @Test(groups = "Functional")
+  public void testVerdict()
+  {
+    List<SequenceI> seqs = new ArrayList<SequenceI>();
+    seqs.add(new Sequence("seq1", "VGIVV-H"));
+    seqs.add(new Sequence("seq2", "VGILL-H"));
+    seqs.add(new Sequence("seq3", "VGIW--R"));
+    seqs.add(new Sequence("seq4", "VGLHH--"));
+    seqs.add(new Sequence("seq5", "VGLHH-R"));
+    seqs.add(new Sequence("seq6", "VGLHH--"));
+    seqs.add(new Sequence("seq7", "VGLHH-R"));
+    seqs.add(new Sequence("seq8", "VGLHH-R"));
+
+    // calculate with no threshold
+    Conservation cons = new Conservation("", 0, seqs, 0, 6);
+    cons.calculate();
+    // positive and negative conservation where <25% gaps in columns
+    cons.verdict(false, 25);
+
+    /*
+     * verify conservation 'sequence'
+     * cols 0 fully conserved and above threshold (*)
+     * col 2 properties fully conserved (+)
+     * col 3 VLWH 1 positively and 3 negatively conserved properties
+     * col 4 has 1 positively conserved property, but because gap contributes a
+     * 'positive' for all properties, no negative conservation is counted
+     * col 5 is all gaps
+     * col 6 has 25% gaps so fails threshold test
+     */
+    assertEquals(cons.getConsSequence().getSequenceAsString(), "**+41--");
+
+    /*
+     * verify tooltips; conserved properties are sorted alphabetically within
+     * positive followed by negative
+     */
+    assertEquals(
+            cons.getTooltip(0),
+            "aliphatic hydrophobic small !aromatic !charged !negative !polar !positive !proline !tiny");
+    assertEquals(
+            cons.getTooltip(1),
+            "hydrophobic small tiny !aliphatic !aromatic !charged !negative !polar !positive !proline");
+    assertEquals(
+            cons.getTooltip(2),
+            "aliphatic hydrophobic !aromatic !charged !negative !polar !positive !proline !small !tiny");
+    assertEquals(cons.getTooltip(3), "hydrophobic !negative !proline !tiny");
+    assertEquals(cons.getTooltip(4), "hydrophobic");
+    assertEquals(cons.getTooltip(5), "");
+    assertEquals(cons.getTooltip(6), "");
+  }
+}
diff --git a/test/jalview/analysis/FinderTest.java b/test/jalview/analysis/FinderTest.java
new file mode 100644 (file)
index 0000000..91ceb82
--- /dev/null
@@ -0,0 +1,309 @@
+/*
+ * 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.analysis;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SearchResultMatchI;
+import jalview.datamodel.SearchResultsI;
+import jalview.datamodel.Sequence;
+import jalview.gui.AlignFrame;
+import jalview.io.FileLoader;
+import jalview.io.FormatAdapter;
+
+import java.util.List;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class FinderTest
+{
+  private AlignFrame af;
+
+  private AlignmentI al;
+
+  @BeforeClass(groups = "Functional")
+  public void setUp()
+  {
+    String seqData = "seq1 ABCD--EF-GHI\n" + "seq2 A--BCDefHI\n"
+            + "seq3 --bcdEFH\n" + "seq4 aa---aMMMMMaaa\n";
+    af = new FileLoader().LoadFileWaitTillLoaded(seqData,
+            FormatAdapter.PASTE);
+    al = af.getViewport().getAlignment();
+  }
+
+  /**
+   * Test for find all matches of a regular expression
+   */
+  @Test(groups = "Functional")
+  public void testFindAll_regex()
+  {
+    Finder f = new Finder(al, null);
+    f.setFindAll(true);
+    f.find("E.H"); // 'E, any character, H'
+
+    // should match seq2 efH and seq3 EFH
+    SearchResultsI sr = f.getSearchResults();
+    assertEquals(sr.getSize(), 2);
+    List<SearchResultMatchI> matches = sr.getResults();
+    assertSame(al.getSequenceAt(1), matches.get(0).getSequence());
+    assertSame(al.getSequenceAt(2), matches.get(1).getSequence());
+    assertEquals(matches.get(0).getStart(), 5);
+    assertEquals(matches.get(0).getEnd(), 7);
+    assertEquals(matches.get(1).getStart(), 4);
+    assertEquals(matches.get(1).getEnd(), 6);
+  }
+
+  /**
+   * Test for (undocumented) find residue by position
+   */
+  @Test(groups = "Functional")
+  public void testFind_residueNumber()
+  {
+    Finder f = new Finder(al, null);
+    f.setFindAll(true);
+    f.find("9");
+
+    // seq1 and seq4 have 9 residues; no match in other sequences
+    SearchResultsI sr = f.getSearchResults();
+    assertEquals(sr.getSize(), 2);
+    List<SearchResultMatchI> matches = sr.getResults();
+    assertSame(al.getSequenceAt(0), matches.get(0).getSequence());
+    assertSame(al.getSequenceAt(3), matches.get(1).getSequence());
+    assertEquals(matches.get(0).getStart(), 9);
+    assertEquals(matches.get(0).getEnd(), 9);
+    assertEquals(matches.get(1).getStart(), 9);
+    assertEquals(matches.get(1).getEnd(), 9);
+  }
+
+  /**
+   * Test for find next action
+   */
+  @Test(groups = "Functional")
+  public void testFindNext()
+  {
+    /*
+     * start at second sequence; resIndex of -1
+     * means sequence id / description is searched
+     */
+    Finder f = new Finder(al, null, 1, -1);
+    f.find("e"); // matches id
+
+    assertTrue(f.getSearchResults().isEmpty());
+    assertEquals(f.getIdMatch().size(), 1);
+    assertSame(f.getIdMatch().get(0), al.getSequenceAt(1));
+
+    // resIndex is now 0 - for use in next find next
+    assertEquals(f.getResIndex(), 0);
+    f = new Finder(al, null, 1, 0);
+    f.find("e"); // matches in sequence
+    assertTrue(f.getIdMatch().isEmpty());
+    assertEquals(f.getSearchResults().getSize(), 1);
+    List<SearchResultMatchI> matches = f.getSearchResults().getResults();
+    assertEquals(matches.get(0).getStart(), 5);
+    assertEquals(matches.get(0).getEnd(), 5);
+    assertSame(matches.get(0).getSequence(), al.getSequenceAt(1));
+    // still in the second sequence
+    assertEquals(f.getSeqIndex(), 1);
+    // next residue position to search from is 5
+    // (used as base 0 by RegEx so the same as 6 if base 1)
+    assertEquals(f.getResIndex(), 5);
+
+    // find next from end of sequence - finds next sequence id
+    f = new Finder(al, null, 1, 5);
+    f.find("e");
+    assertEquals(f.getIdMatch().size(), 1);
+    assertSame(f.getIdMatch().get(0), al.getSequenceAt(2));
+  }
+
+  /**
+   * Test for matching within sequence descriptions
+   */
+  @Test(groups = "Functional")
+  public void testFindAll_inDescription()
+  {
+    AlignmentI al2 = new Alignment(al);
+    al2.getSequenceAt(0).setDescription("BRAF");
+    al2.getSequenceAt(1).setDescription("braf");
+    Finder f = new Finder(al2, null);
+    f.setFindAll(true);
+    f.setIncludeDescription(true);
+
+    f.find("rAF");
+    assertEquals(f.getIdMatch().size(), 2);
+    assertSame(f.getIdMatch().get(0), al2.getSequenceAt(0));
+    assertSame(f.getIdMatch().get(1), al2.getSequenceAt(1));
+    assertTrue(f.getSearchResults().isEmpty());
+
+    /*
+     * case sensitive
+     */
+    f = new Finder(al2, null);
+    f.setFindAll(true);
+    f.setCaseSensitive(true);
+    f.setIncludeDescription(true);
+
+    f.find("RAF");
+    assertEquals(f.getIdMatch().size(), 1);
+    assertSame(f.getIdMatch().get(0), al2.getSequenceAt(0));
+    assertTrue(f.getSearchResults().isEmpty());
+
+    /*
+     * match sequence id, description and sequence!
+     */
+    al2.getSequenceAt(0).setDescription("the efh sequence");
+    al2.getSequenceAt(0).setName("mouseEFHkinase");
+    al2.getSequenceAt(1).setName("humanEFHkinase");
+    f = new Finder(al2, null);
+    f.setFindAll(true);
+    f.setIncludeDescription(true);
+
+    /*
+     * sequence matches should have no duplicates
+     */
+    f.find("EFH");
+    assertEquals(f.getIdMatch().size(), 2);
+    assertSame(f.getIdMatch().get(0), al2.getSequenceAt(0));
+    assertSame(f.getIdMatch().get(1), al2.getSequenceAt(1));
+
+    assertEquals(f.getSearchResults().getSize(), 2);
+    SearchResultMatchI match = f.getSearchResults().getResults().get(0);
+    assertSame(al2.getSequenceAt(1), match.getSequence());
+    assertEquals(5, match.getStart());
+    assertEquals(7, match.getEnd());
+    match = f.getSearchResults().getResults().get(1);
+    assertSame(al2.getSequenceAt(2), match.getSequence());
+    assertEquals(4, match.getStart());
+    assertEquals(6, match.getEnd());
+  }
+
+  /**
+   * Test for matching within sequence ids
+   */
+  @Test(groups = "Functional")
+  public void testFindAll_sequenceIds()
+  {
+    Finder f = new Finder(al, null);
+    f.setFindAll(true);
+
+    /*
+     * case insensitive
+     */
+    f.find("SEQ1");
+    assertEquals(f.getIdMatch().size(), 1);
+    assertSame(f.getIdMatch().get(0), al.getSequenceAt(0));
+    assertTrue(f.getSearchResults().isEmpty());
+
+    /*
+     * case sensitive
+     */
+    f = new Finder(al, null);
+    f.setFindAll(true);
+    f.setCaseSensitive(true);
+    f.find("SEQ1");
+    assertTrue(f.getSearchResults().isEmpty());
+
+    /*
+     * match both sequence id and sequence
+     */
+    AlignmentI al2 = new Alignment(al);
+    al2.addSequence(new Sequence("aBz", "xyzabZpqrAbZ"));
+    f = new Finder(al2, null);
+    f.setFindAll(true);
+    f.find("ABZ");
+    assertEquals(f.getIdMatch().size(), 1);
+    assertSame(f.getIdMatch().get(0), al2.getSequenceAt(4));
+    assertEquals(f.getSearchResults().getSize(), 2);
+    SearchResultMatchI match = f.getSearchResults().getResults().get(0);
+    assertSame(al2.getSequenceAt(4), match.getSequence());
+    assertEquals(4, match.getStart());
+    assertEquals(6, match.getEnd());
+    match = f.getSearchResults().getResults().get(1);
+    assertSame(al2.getSequenceAt(4), match.getSequence());
+    assertEquals(10, match.getStart());
+    assertEquals(12, match.getEnd());
+  }
+
+  /**
+   * Test finding all matches of a sequence pattern in an alignment
+   */
+  @Test(groups = "Functional")
+  public void testFindAll_simpleMatch()
+  {
+    Finder f = new Finder(al, null);
+    f.setFindAll(true);
+
+    /*
+     * case insensitive first
+     */
+    f.find("EfH");
+    SearchResultsI searchResults = f.getSearchResults();
+    assertEquals(searchResults.getSize(), 2);
+    SearchResultMatchI match = searchResults.getResults().get(0);
+    assertSame(al.getSequenceAt(1), match.getSequence());
+    assertEquals(5, match.getStart());
+    assertEquals(7, match.getEnd());
+    match = searchResults.getResults().get(1);
+    assertSame(al.getSequenceAt(2), match.getSequence());
+    assertEquals(4, match.getStart());
+    assertEquals(6, match.getEnd());
+
+    /*
+     * case sensitive
+     */
+    f = new Finder(al, null);
+    f.setFindAll(true);
+    f.setCaseSensitive(true);
+    f.find("BC");
+    searchResults = f.getSearchResults();
+    assertEquals(searchResults.getSize(), 2);
+    match = searchResults.getResults().get(0);
+    assertSame(al.getSequenceAt(0), match.getSequence());
+    assertEquals(2, match.getStart());
+    assertEquals(3, match.getEnd());
+    match = searchResults.getResults().get(1);
+    assertSame(al.getSequenceAt(1), match.getSequence());
+    assertEquals(2, match.getStart());
+    assertEquals(3, match.getEnd());
+  }
+
+  /**
+   * Test for JAL-2302 to verify that sub-matches are not included in a find all
+   * result
+   */
+  @Test(groups = "Functional")
+  public void testFind_maximalResultOnly()
+  {
+    Finder f = new Finder(al, null);
+    f.setFindAll(true);
+    f.find("M+");
+    SearchResultsI searchResults = f.getSearchResults();
+    assertEquals(searchResults.getSize(), 1);
+    SearchResultMatchI match = searchResults.getResults().get(0);
+    assertSame(al.getSequenceAt(3), match.getSequence());
+    assertEquals(4, match.getStart()); // dataset sequence positions
+    assertEquals(8, match.getEnd()); // base 1
+  }
+}
index 309790f..292b576 100644 (file)
@@ -27,6 +27,8 @@ import jalview.gui.AlignFrame;
 import jalview.io.FileLoader;
 import jalview.io.FormatAdapter;
 
+import java.util.Arrays;
+
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -137,4 +139,45 @@ public class FeatureScoreModelTest
               + "(" + s + ") should still be distinct from FER1_MAIZE (3)");
     }
   }
+
+  /**
+   * Check findFeatureAt doesn't return contact features except at contact
+   * points TODO:move to under the FeatureRendererModel test suite
+   */
+  @Test(groups = { "Functional" })
+  public void testFindFeatureAt_PointFeature() throws Exception
+  {
+    String alignment = "a CCCCCCGGGGGGCCCCCC\n" + "b CCCCCCGGGGGGCCCCCC\n"
+            + "c CCCCCCGGGGGGCCCCCC\n";
+    AlignFrame af = new jalview.io.FileLoader(false)
+            .LoadFileWaitTillLoaded(alignment, FormatAdapter.PASTE);
+    SequenceI aseq = af.getViewport().getAlignment().getSequenceAt(0);
+    SequenceFeature sf = null;
+    sf = new SequenceFeature("disulphide bond", "", 2, 5, Float.NaN, "");
+    aseq.addSequenceFeature(sf);
+    Assert.assertTrue(sf.isContactFeature());
+    af.refreshFeatureUI(true);
+    af.getFeatureRenderer().setAllVisible(Arrays.asList("disulphide bond"));
+    Assert.assertEquals(af.getFeatureRenderer().getDisplayedFeatureTypes()
+            .size(), 1, "Should be just one feature type displayed");
+    // step through and check for pointwise feature presence/absence
+    Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 1)
+            .size(), 0);
+    // step through and check for pointwise feature presence/absence
+    Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 2)
+            .size(), 1);
+    // step through and check for pointwise feature presence/absence
+    Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 3)
+            .size(), 0);
+    // step through and check for pointwise feature presence/absence
+    Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 4)
+            .size(), 0);
+    // step through and check for pointwise feature presence/absence
+    Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 5)
+            .size(), 1);
+    // step through and check for pointwise feature presence/absence
+    Assert.assertEquals(af.getFeatureRenderer().findFeaturesAtRes(aseq, 6)
+            .size(), 0);
+  }
+
 }
index b85536e..c79a043 100644 (file)
@@ -34,6 +34,15 @@ import org.testng.annotations.Test;
 
 public class CommandLineOperations
 {
+  private static final int TEST_TIMEOUT = 4500; // Note longer timeout needed on
+                                                // full test run than on
+                                                // individual tests
+
+  private static final int SETUP_TIMEOUT = 9000;
+
+  private static final int MINFILESIZE_SMALL = 2096;
+
+  private static final int MINFILESIZE_BIG = 4096;
 
   private ArrayList<String> successfulCMDs = new ArrayList<String>();
 
@@ -60,6 +69,7 @@ public class CommandLineOperations
       this.process = process;
     }
 
+    @Override
     public void run()
     {
       try
@@ -142,7 +152,7 @@ public class CommandLineOperations
     String cmds = "nodisplay -open examples/uniref50.fa -sortbytree -props FILE -colour zappo "
             + "-jabaws http://www.compbio.dundee.ac.uk/jabaws -nosortbytree -dasserver nickname=www.test.com "
             + "-features examples/testdata/plantfdx.features -annotations examples/testdata/plantfdx.annotations -tree examples/testdata/uniref50_test_tree";
-    Worker worker = jalviewDesktopRunner(true, cmds, 9000);
+    Worker worker = jalviewDesktopRunner(true, cmds, SETUP_TIMEOUT);
     String ln = null;
     while ((ln = worker.getOutputReader().readLine()) != null)
     {
@@ -155,7 +165,7 @@ public class CommandLineOperations
   public void setUpForCommandLineInputOperations() throws IOException
   {
     String cmds = "-open examples/uniref50.fa -noquestionnaire -nousagestats";
-    Worker worker = jalviewDesktopRunner(false, cmds, 9000);
+    Worker worker = jalviewDesktopRunner(false, cmds, SETUP_TIMEOUT);
     String ln = null;
     int count = 0;
     while ((ln = worker.getErrorReader().readLine()) != null)
@@ -204,7 +214,8 @@ public class CommandLineOperations
       worker.process.destroy();
       Assert.fail("Jalview did not exit after "
               + type
-              + " generation (try running test again to verify - timeout at 9000ms). ["
+              + " generation (try running test again to verify - timeout at "
+              + SETUP_TIMEOUT + "ms). ["
               + harg + "]");
     }
     new File(fileName).delete();
@@ -252,36 +263,36 @@ public class CommandLineOperations
   {
     return new Object[][] {
         { "nodisplay -open examples/uniref50.fa", " -eps",
-            "test_uniref50_out.eps", true, 4096, 4000 },
+            "test_uniref50_out.eps", true, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "nodisplay -open examples/uniref50.fa", " -eps",
-            "test_uniref50_out.eps", false, 4096, 4000 },
+            "test_uniref50_out.eps", false, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "nogui -open examples/uniref50.fa", " -eps",
-            "test_uniref50_out.eps", true, 4096, 4000 },
+            "test_uniref50_out.eps", true, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "nogui -open examples/uniref50.fa", " -eps",
-            "test_uniref50_out.eps", false, 4096, 4000 },
+            "test_uniref50_out.eps", false, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -eps",
-            "test_uniref50_out.eps", true, 4096, 4000 },
+            "test_uniref50_out.eps", true, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -svg",
-            "test_uniref50_out.svg", false, 4096, 3000 },
+            "test_uniref50_out.svg", false, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -png",
-            "test_uniref50_out.png", true, 4096, 3000 },
+            "test_uniref50_out.png", true, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -html",
-            "test_uniref50_out.html", true, 4096, 3000 },
+            "test_uniref50_out.html", true, MINFILESIZE_BIG, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -fasta",
-            "test_uniref50_out.mfa", true, 2096, 3000 },
+            "test_uniref50_out.mfa", true, MINFILESIZE_SMALL, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -clustal",
-            "test_uniref50_out.aln", true, 2096, 3000 },
+            "test_uniref50_out.aln", true, MINFILESIZE_SMALL, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -msf",
-            "test_uniref50_out.msf", true, 2096, 3000 },
+            "test_uniref50_out.msf", true, MINFILESIZE_SMALL, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -pileup",
-            "test_uniref50_out.aln", true, 2096, 3000 },
+            "test_uniref50_out.aln", true, MINFILESIZE_SMALL, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -pir",
-            "test_uniref50_out.pir", true, 2096, 3000 },
+            "test_uniref50_out.pir", true, MINFILESIZE_SMALL, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -pfam",
-            "test_uniref50_out.pfam", true, 2096, 3000 },
+            "test_uniref50_out.pfam", true, MINFILESIZE_SMALL, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -blc",
-            "test_uniref50_out.blc", true, 2096, 3000 },
+            "test_uniref50_out.blc", true, MINFILESIZE_SMALL, TEST_TIMEOUT },
         { "headless -open examples/uniref50.fa", " -jalview",
-            "test_uniref50_out.jvp", true, 2096, 3000 }, };
+            "test_uniref50_out.jvp", true, MINFILESIZE_SMALL, TEST_TIMEOUT }, };
   }
 }
index 7fd8965..e2c2130 100644 (file)
@@ -23,11 +23,19 @@ package jalview.controller;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.analysis.Finder;
+import jalview.api.AlignViewControllerI;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.io.FileLoader;
+import jalview.io.FormatAdapter;
 
+import java.util.Arrays;
 import java.util.BitSet;
 
 import org.testng.annotations.Test;
@@ -37,10 +45,10 @@ public class AlignViewControllerTest
   @Test(groups = "Functional")
   public void testFindColumnsWithFeature()
   {
-    SequenceI seq1 = new Sequence("seq1", "aMMMaaaaaaaaaaaaaaaa");
-    SequenceI seq2 = new Sequence("seq2", "aaaMMMMMMMaaaaaaaaaa");
-    SequenceI seq3 = new Sequence("seq3", "aaaaaaaaaaMMMMMaaaaa");
-    SequenceI seq4 = new Sequence("seq3", "aaaaaaaaaaaaaaaaaaaa");
+    SequenceI seq1 = new Sequence("seq1", "-a-MMMaaaaaaaaaaaaaaaa");
+    SequenceI seq2 = new Sequence("seq2", "aa--aMM-MMMMMaaaaaaaaaa");
+    SequenceI seq3 = new Sequence("seq3", "abcab-caD-aaMMMMMaaaaa");
+    SequenceI seq4 = new Sequence("seq4", "abc--abcaaaaaaaaaaaaaa");
 
     /*
      * features start/end are base 1
@@ -53,13 +61,16 @@ public class AlignViewControllerTest
             null));
     seq3.addSequenceFeature(new SequenceFeature("Metal", "desc", 11, 15,
             0f, null));
+    // disulfide bond is a 'contact feature' - only select its 'start' and 'end'
+    seq3.addSequenceFeature(new SequenceFeature("disulfide bond", "desc", 8, 12,
+            0f, null));
 
     /*
-     * select the first three columns --> Metal in seq1 2-3
+     * select the first five columns --> Metal in seq1 cols 4-5
      */
     SequenceGroup sg = new SequenceGroup();
     sg.setStartRes(0); // base 0
-    sg.setEndRes(2);
+    sg.setEndRes(4);
     sg.addSequence(seq1, false);
     sg.addSequence(seq2, false);
     sg.addSequence(seq3, false);
@@ -70,36 +81,37 @@ public class AlignViewControllerTest
             bs);
     assertEquals(1, seqCount);
     assertEquals(2, bs.cardinality());
-    assertTrue(bs.get(1));
-    assertTrue(bs.get(2));
+    assertTrue(bs.get(3)); // base 0
+    assertTrue(bs.get(4));
 
     /*
-     * select the first four columns: Metal in seq1 2:4, seq2 4:4
+     * select the first seven columns: Metal in seq1 cols 4-6, seq2 cols 6-7 
      */
-    sg.setEndRes(3);
+    sg.setEndRes(6);
     bs.clear();
     seqCount = AlignViewController.findColumnsWithFeature("Metal", sg, bs);
     assertEquals(2, seqCount);
-    assertEquals(3, bs.cardinality());
-    assertTrue(bs.get(1));
-    assertTrue(bs.get(2));
+    assertEquals(4, bs.cardinality());
     assertTrue(bs.get(3));
+    assertTrue(bs.get(4));
+    assertTrue(bs.get(5));
+    assertTrue(bs.get(6));
 
     /*
-     * select column 11: Metal in seq3 only
+     * select column 14: Metal in seq3 only
      */
-    sg.setStartRes(10);
-    sg.setEndRes(10);
+    sg.setStartRes(13);
+    sg.setEndRes(13);
     bs.clear();
     seqCount = AlignViewController.findColumnsWithFeature("Metal", sg, bs);
     assertEquals(1, seqCount);
     assertEquals(1, bs.cardinality());
-    assertTrue(bs.get(10));
+    assertTrue(bs.get(13));
 
     /*
-     * select columns 16-20: no Metal feature
+     * select columns 18-20: no Metal feature
      */
-    sg.setStartRes(15);
+    sg.setStartRes(17);
     sg.setEndRes(19);
     bs.clear();
     seqCount = AlignViewController.findColumnsWithFeature("Metal", sg, bs);
@@ -107,6 +119,30 @@ public class AlignViewControllerTest
     assertEquals(0, bs.cardinality());
 
     /*
+     * columns 11-13 should not match disulfide bond at 8/12
+     */
+    sg.setStartRes(10);
+    sg.setEndRes(12);
+    bs.clear();
+    seqCount = AlignViewController.findColumnsWithFeature("disulfide bond",
+            sg, bs);
+    assertEquals(0, seqCount);
+    assertEquals(0, bs.cardinality());
+
+    /*
+     * columns 6-18 should match disulfide bond at columns 9, 14
+     */
+    sg.setStartRes(5);
+    sg.setEndRes(17);
+    bs.clear();
+    seqCount = AlignViewController.findColumnsWithFeature("disulfide bond",
+            sg, bs);
+    assertEquals(1, seqCount);
+    assertEquals(2, bs.cardinality());
+    assertTrue(bs.get(8));
+    assertTrue(bs.get(13));
+
+    /*
      * look for a feature that isn't there
      */
     sg.setStartRes(0);
@@ -116,4 +152,53 @@ public class AlignViewControllerTest
     assertEquals(0, seqCount);
     assertEquals(0, bs.cardinality());
   }
+
+  /**
+   * shameless copy of test data from findFeature for testing mark columns from
+   * highlight
+   */
+  @Test(groups = "Functional")
+  public void testSelectColumnsWithHighlight()
+  {
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            "seq1 aMMMaaaaaaaaaaaaaaaa\n" + "seq2 aaaMMMMMMMaaaaaaaaaa\n"
+                    + "seq3 aaaaaaaaaaMMMMMaaaaa\n"
+                    + "seq4 aaaaaaaaaaaaaaaaaaaa\n", FormatAdapter.PASTE);
+
+    SearchResultsI sr = new SearchResults();
+    SequenceI[] sqs = af.getViewport().getAlignment().getSequencesArray();
+    SequenceI seq1 = sqs[0];
+    SequenceI seq2 = sqs[1];
+    SequenceI seq3 = sqs[2];
+    SequenceI seq4 = sqs[3];
+
+    /*
+     * features start/end are base 1
+     */
+    sr.addResult(seq1, 2, 4);
+    sr.addResult(seq2, 4, 10);
+    sr.addResult(seq3, 11, 15);
+
+    /*
+     *  test Match/Find works first
+     */
+    Finder f = new Finder(af.getViewport().getAlignment(), null);
+    f.setFindAll(true);
+    f.setCaseSensitive(true);
+    f.find("M+");
+    assertEquals(
+            "Finder found different set of results to manually created SearchResults",
+            sr, f.getSearchResults());
+
+    /*
+     * now check simple mark columns from find operation
+     */
+    af.getViewport().setSearchResults(sr);
+    AlignViewControllerI avc = af.avc;
+
+    avc.markHighlightedColumns(false, false, false);
+    assertTrue("Didn't select highlighted columns", Arrays.deepEquals(af
+            .getViewport().getColumnSelection().getSelectedRanges()
+            .toArray(), new int[][] { { 1, 14 } }));
+  }
 }
index 6f3c7a9..95764d0 100644 (file)
@@ -24,8 +24,6 @@ import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertTrue;
 
-import jalview.datamodel.SearchResults.Match;
-
 import org.testng.annotations.Test;
 
 public class MatchTest
@@ -34,17 +32,9 @@ public class MatchTest
   @Test(groups = { "Functional" })
   public void testToString()
   {
-    SequenceI seq = new Sequence("", "abcdefghijklm");
-    Match m = new SearchResults().new Match(seq, 3, 5);
-    assertEquals("2cde", m.toString());
-  }
-
-  @Test(groups = { "Functional" })
-  public void testGetCharacters()
-  {
-    SequenceI seq = new Sequence("", "abcdefghijklm");
-    Match m = new SearchResults().new Match(seq, 3, 5);
-    assertEquals("cde", m.getCharacters());
+    SequenceI seq = new Sequence("Seq1", "abcdefghijklm");
+    SearchResultMatchI m = new SearchResults().new Match(seq, 3, 5);
+    assertEquals("Seq1/3-5", m.toString());
   }
 
   @Test(groups = { "Functional" })
@@ -52,8 +42,8 @@ public class MatchTest
   {
     SequenceI seq1 = new Sequence("", "abcdefghijklm");
     SequenceI seq2 = new Sequence("", "abcdefghijklm");
-    SearchResults sr1 = new SearchResults();
-    SearchResults sr2 = new SearchResults();
+    SearchResultsI sr1 = new SearchResults();
+    SearchResultsI sr2 = new SearchResults();
 
     assertFalse(sr1.equals(null));
     assertFalse(sr1.equals(seq1));
@@ -72,7 +62,7 @@ public class MatchTest
     /*
      * same match but on different sequences - not equal
      */
-    SearchResults sr3 = new SearchResults();
+    SearchResultsI sr3 = new SearchResults();
     sr3.addResult(seq2, 1, 1);
     assertFalse(sr1.equals(sr3));
     assertFalse(sr3.equals(sr1));
diff --git a/test/jalview/datamodel/ResidueCountTest.java b/test/jalview/datamodel/ResidueCountTest.java
new file mode 100644 (file)
index 0000000..6c6e36a
--- /dev/null
@@ -0,0 +1,432 @@
+/*
+ * 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.datamodel;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import jalview.datamodel.ResidueCount.SymbolCounts;
+
+import org.junit.Assert;
+import org.testng.annotations.Test;
+
+public class ResidueCountTest
+{
+  /**
+   * Test a mix of add and put for nucleotide counting
+   */
+  @Test(groups = "Functional")
+  public void test_countNucleotide()
+  {
+    ResidueCount rc = new ResidueCount(true);
+    assertEquals(rc.getCount('A'), 0);
+    assertEquals(rc.getGapCount(), 0);
+    // add then add
+    assertEquals(rc.add('A'), 1);
+    assertEquals(rc.add('a'), 2);
+    // put then add
+    rc.put('g', 3);
+    assertEquals(rc.add('G'), 4);
+    // add then put
+    assertEquals(rc.add('c'), 1);
+    rc.put('C', 4);
+    assertEquals(rc.add('N'), 1);
+
+    assertEquals(rc.getCount('a'), 2);
+    assertEquals(rc.getCount('A'), 2);
+    assertEquals(rc.getCount('G'), 4);
+    assertEquals(rc.getCount('c'), 4);
+    assertEquals(rc.getCount('T'), 0); // never seen
+    assertEquals(rc.getCount('N'), 1);
+    assertEquals(rc.getCount('?'), 0);
+    assertEquals(rc.getCount('-'), 0);
+
+    assertFalse(rc.isCountingInts());
+    assertFalse(rc.isUsingOtherData());
+  }
+
+  /**
+   * Test adding to gap count (either using addGap or add)
+   */
+  @Test(groups = "Functional")
+  public void testAddGap()
+  {
+    ResidueCount rc = new ResidueCount(true);
+    rc.addGap();
+    rc.add('-');
+    rc.add('.');
+    rc.add(' ');
+    
+    assertEquals(rc.getGapCount(), 4);
+    assertEquals(rc.getCount(' '), 4);
+    assertEquals(rc.getCount('-'), 4);
+    assertEquals(rc.getCount('.'), 4);
+    assertFalse(rc.isUsingOtherData());
+    assertFalse(rc.isCountingInts());
+  }
+
+  @Test(groups = "Functional")
+  public void testOverflow()
+  {
+    /*
+     * overflow from add
+     */
+    ResidueCount rc = new ResidueCount(true);
+    rc.addGap();
+    rc.put('A', Short.MAX_VALUE - 1);
+    assertFalse(rc.isCountingInts());
+    rc.add('A');
+    assertFalse(rc.isCountingInts());
+    rc.add('A');
+    assertTrue(rc.isCountingInts());
+    assertEquals(rc.getCount('a'), Short.MAX_VALUE + 1);
+    rc.add('A');
+    assertTrue(rc.isCountingInts());
+    assertEquals(rc.getCount('a'), Short.MAX_VALUE + 2);
+    assertEquals(rc.getGapCount(), 1);
+    rc.addGap();
+    assertEquals(rc.getGapCount(), 2);
+
+    /*
+     * overflow from put
+     */
+    rc = new ResidueCount(true);
+    rc.put('G', Short.MAX_VALUE + 1);
+    assertTrue(rc.isCountingInts());
+    assertEquals(rc.getCount('g'), Short.MAX_VALUE + 1);
+    rc.put('G', 1);
+    assertTrue(rc.isCountingInts());
+    assertEquals(rc.getCount('g'), 1);
+
+    /*
+     * underflow from put
+     */
+    rc = new ResidueCount(true);
+    rc.put('G', Short.MIN_VALUE - 1);
+    assertTrue(rc.isCountingInts());
+    assertEquals(rc.getCount('g'), Short.MIN_VALUE - 1);
+  }
+
+  /**
+   * Test a mix of add and put for peptide counting
+   */
+  @Test(groups = "Functional")
+  public void test_countPeptide()
+  {
+    ResidueCount rc = new ResidueCount(false);
+    rc.put('q', 4);
+    rc.add('Q');
+    rc.add('X');
+    rc.add('x');
+    rc.add('W');
+    rc.put('w', 7);
+    rc.put('m', 12);
+    rc.put('M', 13);
+
+    assertEquals(rc.getCount('q'), 5);
+    assertEquals(rc.getCount('X'), 2);
+    assertEquals(rc.getCount('W'), 7);
+    assertEquals(rc.getCount('m'), 13);
+    assertEquals(rc.getCount('G'), 0);
+    assertEquals(rc.getCount('-'), 0);
+
+    assertFalse(rc.isCountingInts());
+    assertFalse(rc.isUsingOtherData());
+  }
+
+  @Test(groups = "Functional")
+  public void test_unexpectedPeptide()
+  {
+    ResidueCount rc = new ResidueCount(false);
+    // expected characters (upper or lower case):
+    String aas = "ACDEFGHIKLMNPQRSTVWXY";
+    String lower = aas.toLowerCase();
+    for (int i = 0; i < aas.length(); i++)
+    {
+      rc.put(aas.charAt(i), i);
+      rc.add(lower.charAt(i));
+    }
+    for (int i = 0; i < aas.length(); i++)
+    {
+      assertEquals(rc.getCount(aas.charAt(i)), i + 1);
+    }
+    assertFalse(rc.isUsingOtherData());
+
+    rc.put('J', 4);
+    assertTrue(rc.isUsingOtherData());
+    assertEquals(rc.getCount('J'), 4);
+    rc.add('j');
+    assertEquals(rc.getCount('J'), 5);
+  }
+
+  @Test(groups = "Functional")
+  public void test_unexpectedNucleotide()
+  {
+    ResidueCount rc = new ResidueCount(true);
+    // expected characters (upper or lower case):
+    String nucs = "ACGTUN";
+    String lower = nucs.toLowerCase();
+    for (int i = 0; i < nucs.length(); i++)
+    {
+      rc.put(nucs.charAt(i), i);
+      rc.add(lower.charAt(i));
+    }
+    for (int i = 0; i < nucs.length(); i++)
+    {
+      assertEquals(rc.getCount(nucs.charAt(i)), i + 1);
+    }
+    assertFalse(rc.isUsingOtherData());
+
+    rc.add('J');
+    assertTrue(rc.isUsingOtherData());
+  }
+
+  @Test(groups = "Functional")
+  public void testGetModalCount()
+  {
+    ResidueCount rc = new ResidueCount(true);
+    rc.add('c');
+    rc.add('g');
+    rc.add('c');
+    assertEquals(rc.getModalCount(), 2);
+
+    // modal count is in the 'short overflow' counts
+    rc = new ResidueCount();
+    rc.add('c');
+    rc.put('g', Short.MAX_VALUE);
+    rc.add('G');
+    assertEquals(rc.getModalCount(), Short.MAX_VALUE + 1);
+
+    // modal count is in the 'other data' counts
+    rc = new ResidueCount(false);
+    rc.add('Q');
+    rc.add('{');
+    rc.add('{');
+    assertEquals(rc.getModalCount(), 2);
+
+    // verify modal count excludes gap
+    rc = new ResidueCount();
+    rc.add('Q');
+    rc.add('P');
+    rc.add('Q');
+    rc.addGap();
+    rc.addGap();
+    rc.addGap();
+    assertEquals(rc.getModalCount(), 2);
+  }
+
+  @Test(groups = "Functional")
+  public void testGetResiduesForCount()
+  {
+    ResidueCount rc = new ResidueCount(true);
+    rc.add('c');
+    rc.add('g');
+    rc.add('c');
+    assertEquals(rc.getResiduesForCount(2), "C");
+    assertEquals(rc.getResiduesForCount(1), "G");
+    assertEquals(rc.getResiduesForCount(3), "");
+    assertEquals(rc.getResiduesForCount(0), "");
+    assertEquals(rc.getResiduesForCount(-1), "");
+
+    // modal count is in the 'short overflow' counts
+    rc = new ResidueCount(true);
+    rc.add('c');
+    rc.put('g', Short.MAX_VALUE);
+    rc.add('G');
+    assertEquals(rc.getResiduesForCount(Short.MAX_VALUE + 1), "G");
+    assertEquals(rc.getResiduesForCount(1), "C");
+
+    // peptide modal count is in the 'short overflow' counts
+    rc = new ResidueCount(false);
+    rc.add('c');
+    rc.put('p', Short.MAX_VALUE);
+    rc.add('P');
+    assertEquals(rc.getResiduesForCount(Short.MAX_VALUE + 1), "P");
+    assertEquals(rc.getResiduesForCount(1), "C");
+  
+    // modal count is in the 'other data' counts
+    rc = new ResidueCount();
+    rc.add('Q');
+    rc.add('{');
+    rc.add('{');
+    assertEquals(rc.getResiduesForCount(1), "Q");
+    assertEquals(rc.getResiduesForCount(2), "{");
+
+    // residues share modal count
+    rc = new ResidueCount();
+    rc.add('G');
+    rc.add('G');
+    rc.add('c');
+    rc.add('C');
+    rc.add('U');
+    assertEquals(rc.getResiduesForCount(1), "U");
+    assertEquals(rc.getResiduesForCount(2), "CG");
+
+    // expected and unexpected symbols share modal count
+    rc = new ResidueCount();
+    rc.add('G');
+    rc.add('t');
+    rc.add('[');
+    rc.add('[');
+    rc.add('t');
+    rc.add('G');
+    rc.add('c');
+    rc.add('C');
+    rc.add('U');
+    assertEquals(rc.getResiduesForCount(1), "U");
+    assertEquals(rc.getResiduesForCount(2), "CGT[");
+  }
+
+  @Test(groups = "Functional")
+  public void testGetSymbolCounts_nucleotide()
+  {
+    ResidueCount rc = new ResidueCount(true);
+    rc.add('g');
+    rc.add('c');
+    rc.add('G');
+    rc.add('J'); // 'otherData'
+    rc.add('g');
+    rc.add('N');
+    rc.put('[', 0); // 'otherdata'
+
+    SymbolCounts sc = rc.getSymbolCounts();
+    Assert.assertArrayEquals(new char[] { 'C', 'G', 'N', 'J', '[' },
+            sc.symbols);
+    Assert.assertArrayEquals(new int[] { 1, 3, 1, 1, 0 }, sc.values);
+
+    // now with overflow to int counts
+    rc.put('U', Short.MAX_VALUE);
+    rc.add('u');
+    sc = rc.getSymbolCounts();
+    Assert.assertArrayEquals(new char[] { 'C', 'G', 'N', 'U', 'J', '[' },
+            sc.symbols);
+    Assert.assertArrayEquals(new int[] { 1, 3, 1, 32768, 1, 0 }, sc.values);
+  }
+
+  @Test(groups = "Functional")
+  public void testGetSymbolCounts_peptide()
+  {
+    ResidueCount rc = new ResidueCount(false);
+    rc.add('W');
+    rc.add('q');
+    rc.add('W');
+    rc.add('Z'); // 'otherData'
+    rc.add('w');
+    rc.add('L');
+
+    SymbolCounts sc = rc.getSymbolCounts();
+    Assert.assertArrayEquals(new char[] { 'L', 'Q', 'W', 'Z' }, sc.symbols);
+    Assert.assertArrayEquals(new int[] { 1, 1, 3, 1 }, sc.values);
+
+    // now with overflow to int counts
+    rc.put('W', Short.MAX_VALUE);
+    rc.add('W');
+    sc = rc.getSymbolCounts();
+    Assert.assertArrayEquals(new char[] { 'L', 'Q', 'W', 'Z' }, sc.symbols);
+    Assert.assertArrayEquals(new int[] { 1, 1, 32768, 1 }, sc.values);
+  }
+
+  @Test(groups = "Functional")
+  public void testToString()
+  {
+    ResidueCount rc = new ResidueCount();
+    rc.add('q');
+    rc.add('c');
+    rc.add('Q');
+    assertEquals(rc.toString(), "[ C:1 Q:2 ]");
+
+    // add 'other data'
+    rc.add('{');
+    assertEquals(rc.toString(), "[ C:1 Q:2 {:1 ]");
+
+    // switch from short to int counting:
+    rc.put('G', Short.MAX_VALUE);
+    rc.add('g');
+    assertEquals(rc.toString(), "[ C:1 G:32768 Q:2 {:1 ]");
+  }
+
+  @Test(groups = "Functional")
+  public void testGetTooltip()
+  {
+    ResidueCount rc = new ResidueCount();
+
+    // no counts!
+    assertEquals(rc.getTooltip(20, 1), "");
+
+    /*
+     * count 7 C, 6 K, 7 Q, 10 P, 9 W, 1 F (total 40)
+     */
+    for (int i = 0; i < 7; i++)
+    {
+      rc.add('c');
+      rc.add('q');
+    }
+    for (int i = 0; i < 10; i++)
+    {
+      rc.add('p');
+    }
+    for (int i = 0; i < 9; i++)
+    {
+      rc.add('W');
+    }
+    for (int i = 0; i < 6; i++)
+    {
+      rc.add('K');
+    }
+    rc.add('F');
+    
+    /*
+     * percentages are rounded (0.5 rounded up)
+     * 10/40 9/40 7/40 6/40 1/40
+     */
+    assertEquals(rc.getTooltip(40, 0),
+            "P 25%; W 23%; C 18%; Q 18%; K 15%; F 3%");
+
+    rc.add('Q');
+    /*
+     * 10/30 9/30 8/30 7/30 6/30 1/30
+     */
+    assertEquals(rc.getTooltip(30, 1),
+            "P 33.3%; W 30.0%; Q 26.7%; C 23.3%; K 20.0%; F 3.3%");
+  }
+
+  @Test(groups = "Functional")
+  public void testPut()
+  {
+    ResidueCount rc = new ResidueCount();
+    rc.put('q', 3);
+    assertEquals(rc.getCount('Q'), 3);
+    rc.put(' ', 4);
+    assertEquals(rc.getGapCount(), 4);
+    rc.put('.', 5);
+    assertEquals(rc.getGapCount(), 5);
+    rc.put('-', 6);
+    assertEquals(rc.getGapCount(), 6);
+
+    rc.put('?', 5);
+    assertEquals(rc.getCount('?'), 5);
+    rc.put('?', 6);
+    rc.put('!', 7);
+    assertEquals(rc.getCount('?'), 6);
+    assertEquals(rc.getCount('!'), 7);
+  }
+}
index f9a0a4f..19e89d2 100644 (file)
@@ -25,8 +25,9 @@ import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
 
-import jalview.datamodel.SearchResults.Match;
+import java.util.BitSet;
 
+import org.junit.Assert;
 import org.testng.annotations.Test;
 
 public class SearchResultsTest
@@ -35,39 +36,24 @@ public class SearchResultsTest
   @Test(groups = { "Functional" })
   public void testToString()
   {
-    SequenceI seq = new Sequence("", "abcdefghijklm");
-    SearchResults sr = new SearchResults();
+    SequenceI seq = new Sequence("Seq1", "abcdefghijklm");
+    SearchResultsI sr = new SearchResults();
     sr.addResult(seq, 1, 1);
-    assertEquals("0a", sr.toString());
+    assertEquals("[Seq1/1-1]", sr.toString());
     sr.addResult(seq, 3, 5);
-    assertEquals("0a2cde", sr.toString());
+    assertEquals("[Seq1/1-1, Seq1/3-5]", sr.toString());
 
-    seq = new Sequence("", "pqrstuvwxy");
+    seq = new Sequence("Seq2", "pqrstuvwxy");
     sr.addResult(seq, 6, 7);
-    assertEquals("0a2cde5uv", sr.toString());
-  }
-
-  @Test(groups = { "Functional" })
-  public void testGetCharacters()
-  {
-    SequenceI seq = new Sequence("", "abcdefghijklm");
-    SearchResults sr = new SearchResults();
-    sr.addResult(seq, 1, 1);
-    assertEquals("a", sr.getCharacters());
-    sr.addResult(seq, 3, 5);
-    assertEquals("acde", sr.getCharacters());
-
-    seq = new Sequence("", "pqrstuvwxy");
-    sr.addResult(seq, 6, 7);
-    assertEquals("acdeuv", sr.getCharacters());
+    assertEquals("[Seq1/1-1, Seq1/3-5, Seq2/6-7]", sr.toString());
   }
 
   @Test(groups = { "Functional" })
   public void testEquals()
   {
     SequenceI seq1 = new Sequence("", "abcdefghijklm");
-    SearchResults sr1 = new SearchResults();
-    SearchResults sr2 = new SearchResults();
+    SearchResultsI sr1 = new SearchResults();
+    SearchResultsI sr2 = new SearchResults();
 
     assertFalse(sr1.equals(null)); // null object
     assertFalse(sr1.equals(seq1)); // wrong type
@@ -76,7 +62,7 @@ public class SearchResultsTest
     assertTrue(sr2.equals(sr1)); // reflexive
 
     /*
-     * only one result is not empty
+     * if only one result is not empty
      */
     sr1.addResult(seq1, 1, 1);
     assertTrue(sr1.equals(sr1));
@@ -111,8 +97,8 @@ public class SearchResultsTest
   {
     SequenceI seq1 = new Sequence("", "abcdefghijklm");
     SequenceI seq2 = new Sequence("", "abcdefghijklm");
-    SearchResults sr1 = new SearchResults();
-    SearchResults sr2 = new SearchResults();
+    SearchResultsI sr1 = new SearchResults();
+    SearchResultsI sr2 = new SearchResults();
 
     sr1.addResult(seq1, 1, 1);
     sr2.addResult(seq2, 1, 1);
@@ -127,8 +113,8 @@ public class SearchResultsTest
   public void testEquals_orderDiffers()
   {
     SequenceI seq1 = new Sequence("", "abcdefghijklm");
-    SearchResults sr1 = new SearchResults();
-    SearchResults sr2 = new SearchResults();
+    SearchResultsI sr1 = new SearchResults();
+    SearchResultsI sr2 = new SearchResults();
 
     sr1.addResult(seq1, 1, 1);
     sr1.addResult(seq1, 2, 2);
@@ -145,8 +131,8 @@ public class SearchResultsTest
   public void testHashcode()
   {
     SequenceI seq1 = new Sequence("", "abcdefghijklm");
-    SearchResults sr1 = new SearchResults();
-    SearchResults sr2 = new SearchResults();
+    SearchResultsI sr1 = new SearchResults();
+    SearchResultsI sr2 = new SearchResults();
 
     /*
      * both empty
@@ -178,7 +164,7 @@ public class SearchResultsTest
   public void testMatchConstructor()
   {
     SequenceI seq1 = new Sequence("", "abcdefghijklm");
-    Match m = new SearchResults().new Match(seq1, 2, 5);
+    SearchResultMatchI m = new SearchResults().new Match(seq1, 2, 5);
     assertSame(seq1, m.getSequence());
     assertEquals(2, m.getStart());
     assertEquals(5, m.getEnd());
@@ -189,4 +175,87 @@ public class SearchResultsTest
     assertEquals(2, m.getStart());
     assertEquals(5, m.getEnd());
   }
+
+  /**
+   * test markColumns for creating column selections
+   */
+  @Test(groups = { "Functional" })
+  public void testMarkColumns()
+  {
+    int marked = 0;
+    SequenceI seq1 = new Sequence("", "abcdefghijklm");
+    SequenceI seq2 = new Sequence("", "abcdefghijklm");
+    SequenceGroup s1g=new SequenceGroup(), s2g=new SequenceGroup(), sallg=new SequenceGroup();
+    s1g.addSequence(seq1, false);
+    s2g.addSequence(seq2, false);
+    sallg.addSequence(seq1, false);
+    sallg.addSequence(seq2, false);
+    
+    SearchResultsI sr = new SearchResults();
+    BitSet bs = new BitSet();
+    
+    SearchResultMatchI srm = null;
+    srm = sr.addResult(seq1, 1, 1);
+    Assert.assertNotNull("addResult didn't return Match", srm);
+    srm = sr.addResult(seq2, 1, 2);
+    assertEquals("Sequence reference not set", seq2, srm.getSequence());
+    assertEquals("match start incorrect", 1, srm.getStart());
+    assertEquals("match end incorrect", 2, srm.getEnd());
+    
+    // set start/end range for groups to cover matches
+
+    s1g.setStartRes(0);
+    s1g.setEndRes(5);
+    s2g.setStartRes(0);
+    s2g.setEndRes(5);
+    sallg.setStartRes(0);
+    sallg.setEndRes(5);
+
+    /*
+     * just seq1
+     */
+    marked = sr.markColumns(s1g, bs);
+    // check the bitset cardinality before checking the return value
+    assertEquals("Didn't mark expected number", 1, bs.cardinality());
+    assertEquals("Didn't return count of number of bits marked", 1, marked);
+    assertTrue("Didn't mark expected position", bs.get(0));
+    // now check return value for marking the same again
+    assertEquals(
+            "Didn't count number of bits marked for existing marked set",
+            0,
+            sr.markColumns(s1g, bs));
+    bs.clear();
+    
+    /*
+     * just seq2
+     */
+    marked = sr.markColumns(s2g, bs);
+    assertEquals("Didn't mark expected number", 2, bs.cardinality());
+    assertEquals("Didn't return count of number of bits marked", 2, marked);
+    assertTrue("Didn't mark expected position (1)", bs.get(0));
+    assertTrue("Didn't mark expected position (2)", bs.get(1));
+    
+    /*
+     * both seq1 and seq2 
+     * should be same as seq2
+     */
+    BitSet allbs = new BitSet();
+    assertEquals(2, sr.markColumns(sallg, allbs));
+    assertEquals(bs, allbs);
+
+    // now check range selection
+
+    /*
+     * limit s2g to just the second column, sallg to the first column
+     */
+    s2g.setStartRes(1);
+    s2g.setEndRes(1);
+    sallg.setEndRes(0);
+    BitSet tbs = new BitSet();
+    assertEquals("Group start/end didn't select columns to mark",1, sr.markColumns(s2g, tbs));
+    assertEquals("Group start/end didn't select columns to mark", 1, sr.markColumns(sallg, tbs));
+    assertEquals(
+            "Didn't set expected number of columns in total for two successive marks",
+            2, tbs.cardinality());
+  }
 }
index 2ec824d..23812ea 100644 (file)
@@ -112,56 +112,83 @@ public class SequenceFeatureTest
     assertEquals(sf1.hashCode(), sf2.hashCode());
 
     // changing type breaks equals:
+    String restores = sf2.getType();
     sf2.setType("Type");
     assertFalse(sf1.equals(sf2));
+    sf2.setType(restores);
 
     // changing description breaks equals:
-    sf2.setType("type");
+    restores = sf2.getDescription();
     sf2.setDescription("Desc");
     assertFalse(sf1.equals(sf2));
+    sf2.setDescription(restores);
+
+    // changing score breaks equals:
+    float restoref = sf2.getScore();
+    sf2.setScore(12.4f);
+    assertFalse(sf1.equals(sf2));
+    sf2.setScore(restoref);
+
+    // NaN doesn't match a number
+    restoref = sf2.getScore();
+    sf2.setScore(Float.NaN);
+    assertFalse(sf1.equals(sf2));
+
+    // NaN matches NaN
+    sf1.setScore(Float.NaN);
+    assertTrue(sf1.equals(sf2));
+    sf1.setScore(restoref);
+    sf2.setScore(restoref);
 
     // changing start position breaks equals:
-    sf2.setDescription("desc");
+    int restorei = sf2.getBegin();
     sf2.setBegin(21);
     assertFalse(sf1.equals(sf2));
+    sf2.setBegin(restorei);
 
     // changing end position breaks equals:
-    sf2.setBegin(22);
+    restorei = sf2.getEnd();
     sf2.setEnd(32);
     assertFalse(sf1.equals(sf2));
+    sf2.setEnd(restorei);
 
     // changing feature group breaks equals:
-    sf2.setEnd(33);
+    restores = sf2.getFeatureGroup();
     sf2.setFeatureGroup("Group");
     assertFalse(sf1.equals(sf2));
+    sf2.setFeatureGroup(restores);
 
     // changing ID breaks equals:
-    sf2.setFeatureGroup("group");
+    restores = (String) sf2.getValue("ID");
     sf2.setValue("ID", "id2");
     assertFalse(sf1.equals(sf2));
+    sf2.setValue("ID", restores);
 
     // changing Name breaks equals:
-    sf2.setValue("ID", "id");
+    restores = (String) sf2.getValue("Name");
     sf2.setValue("Name", "Name");
     assertFalse(sf1.equals(sf2));
+    sf2.setValue("Name", restores);
 
     // changing Parent breaks equals:
-    sf2.setValue("Name", "name");
+    restores = (String) sf1.getValue("Parent");
     sf1.setValue("Parent", "Parent");
     assertFalse(sf1.equals(sf2));
+    sf1.setValue("Parent", restores);
 
     // changing strand breaks equals:
-    sf1.setValue("Parent", "parent");
+    restorei = sf2.getStrand();
     sf2.setStrand("-");
     assertFalse(sf1.equals(sf2));
+    sf2.setStrand(restorei == 1 ? "+" : "-");
 
     // changing phase breaks equals:
-    sf2.setStrand("+");
+    restores = sf1.getPhase();
     sf1.setPhase("2");
     assertFalse(sf1.equals(sf2));
+    sf1.setPhase(restores);
 
     // restore equality as sanity check:
-    sf1.setPhase("1");
     assertTrue(sf1.equals(sf2));
     assertTrue(sf2.equals(sf1));
     assertEquals(sf1.hashCode(), sf2.hashCode());
@@ -170,4 +197,24 @@ public class SequenceFeatureTest
     sf1.setStatus("new");
     assertTrue(sf1.equals(sf2));
   }
+
+  @Test(groups = { "Functional" })
+  public void testIsContactFeature()
+  {
+    SequenceFeature sf = new SequenceFeature("type", "desc", 22, 33, 12.5f,
+            "group");
+    assertFalse(sf.isContactFeature());
+    sf.setType("");
+    assertFalse(sf.isContactFeature());
+    sf.setType(null);
+    assertFalse(sf.isContactFeature());
+    sf.setType("Disulfide Bond");
+    assertTrue(sf.isContactFeature());
+    sf.setType("disulfide bond");
+    assertTrue(sf.isContactFeature());
+    sf.setType("Disulphide Bond");
+    assertTrue(sf.isContactFeature());
+    sf.setType("disulphide bond");
+    assertTrue(sf.isContactFeature());
+  }
 }
diff --git a/test/jalview/ext/android/SparseIntArrayTest.java b/test/jalview/ext/android/SparseIntArrayTest.java
new file mode 100644 (file)
index 0000000..be95d6e
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * 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.ext.android;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import org.testng.annotations.Test;
+
+/*
+ * Tests for SparseIntArray. Unlike SparseShortArray, SparseIntArray does not throw
+ * any exception for overflow.
+ */
+public class SparseIntArrayTest
+{
+  @Test(groups = "Functional")
+  public void testPut()
+  {
+    SparseIntArray counter = new SparseIntArray();
+
+    /*
+     * either key or value may be in the range of int
+     */
+    counter.put(Integer.MAX_VALUE, Integer.MIN_VALUE);
+    counter.put(Integer.MIN_VALUE, Integer.MAX_VALUE);
+    assertEquals(counter.get(Integer.MAX_VALUE), Integer.MIN_VALUE);
+    assertEquals(counter.get(Integer.MIN_VALUE), Integer.MAX_VALUE);
+  }
+
+  @Test(groups = "Functional")
+  public void testAdd()
+  {
+    SparseIntArray counter = new SparseIntArray();
+  
+    assertEquals(counter.add('P', 2), 2);
+    assertEquals(counter.add('P', 3), 5);
+    counter.put('Q', 7);
+    assertEquals(counter.add('Q', 4), 11);
+
+    counter.put('x', Integer.MAX_VALUE);
+    try
+    {
+      counter.add('x', 1);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+  
+    counter.put('y', Integer.MIN_VALUE);
+    try
+    {
+      counter.add('y', -1);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+  }
+
+  @Test(groups = "Functional")
+  public void testCheckOverflow()
+  {
+    // things that don't overflow:
+    SparseIntArray.checkOverflow(Integer.MAX_VALUE, 0);
+    SparseIntArray.checkOverflow(Integer.MAX_VALUE, -1);
+    SparseIntArray.checkOverflow(Integer.MAX_VALUE, Integer.MIN_VALUE);
+    SparseIntArray.checkOverflow(Integer.MAX_VALUE, -Integer.MAX_VALUE);
+    SparseIntArray.checkOverflow(0, -Integer.MAX_VALUE);
+    SparseIntArray.checkOverflow(0, Integer.MIN_VALUE);
+    SparseIntArray.checkOverflow(Integer.MIN_VALUE, 0);
+    SparseIntArray.checkOverflow(Integer.MIN_VALUE, 1);
+    SparseIntArray.checkOverflow(Integer.MIN_VALUE, Integer.MAX_VALUE);
+
+    // and some that do
+    try
+    {
+      SparseIntArray.checkOverflow(Integer.MAX_VALUE, 1);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+    try
+    {
+      SparseIntArray.checkOverflow(Integer.MAX_VALUE - 1, 2);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+    try
+    {
+      SparseIntArray.checkOverflow(1, Integer.MAX_VALUE);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+    try
+    {
+      SparseIntArray.checkOverflow(Integer.MIN_VALUE, -1);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+    try
+    {
+      SparseIntArray.checkOverflow(Integer.MIN_VALUE + 1, -2);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+    try
+    {
+      SparseIntArray.checkOverflow(-1, Integer.MIN_VALUE);
+      fail("expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected
+    }
+  }
+
+}
diff --git a/test/jalview/ext/android/SparseShortArrayTest.java b/test/jalview/ext/android/SparseShortArrayTest.java
new file mode 100644 (file)
index 0000000..df161b7
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * 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.ext.android;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import org.testng.annotations.Test;
+
+public class SparseShortArrayTest
+{
+  @Test(groups = "Functional")
+  public void testPut()
+  {
+    SparseShortArray counter = new SparseShortArray();
+
+    /*
+     * either key or value may be in the range of short
+     */
+    counter.put(Short.MAX_VALUE, Short.MIN_VALUE);
+    counter.put(Short.MIN_VALUE, Short.MAX_VALUE);
+
+    // put a too large value
+    try
+    {
+      counter.put(0, Short.MAX_VALUE + 1);
+      fail("Expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected;
+    }
+
+    // put a too small value
+    try
+    {
+      counter.put(1, Short.MIN_VALUE - 1);
+      fail("Expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected;
+    }
+
+    // put a too large key
+    try
+    {
+      counter.put(Short.MAX_VALUE + 1, 0);
+      fail("Expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected;
+    }
+
+    // put a too small key
+    try
+    {
+      counter.put(Short.MIN_VALUE - 1, 2);
+      fail("Expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected;
+    }
+  }
+
+  @Test(groups = "Functional")
+  public void testAdd()
+  {
+    SparseShortArray counter = new SparseShortArray();
+  
+    assertEquals(counter.add('P', 2), 2);
+    assertEquals(counter.add('P', 3), 5);
+    counter.put('Q', 7);
+    assertEquals(counter.add('Q', 4), 11);
+
+    // increment giving overflow
+    counter.put('x', Short.MAX_VALUE);
+    try
+    {
+      counter.add('x', 1);
+      fail("Expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected;
+    }
+  
+    // decrement giving underflow
+    counter.put('y', Short.MIN_VALUE);
+    try
+    {
+      counter.add('y', -1);
+      fail("Expected exception");
+    } catch (ArithmeticException e)
+    {
+      // expected;
+    }
+  }
+}
index f8c53b0..bdc14db 100644 (file)
@@ -33,7 +33,7 @@ import org.testng.annotations.Test;
  */
 public class TestHtsContigDb
 {
-  @Test
+  @Test(groups = "Functional")
   public final void testHTSReferenceSequence() throws Exception
   {
     HtsContigDb remmadb = new HtsContigDb("REEMADB", new File(
index 316d9af..b2ef3f7 100644 (file)
@@ -37,7 +37,7 @@ import org.testng.annotations.Test;
 public class AlignFrameTest
 {
 
-  @Test
+  @Test(groups = "Functional")
   public void testHideFeatureColumns()
   {
     SequenceI seq1 = new Sequence("Seq1", "ABCDEFGHIJ");
index 00c52ed..dfe0e68 100644 (file)
@@ -35,6 +35,8 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.PDBEntry.Type;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.io.FileLoader;
@@ -347,4 +349,28 @@ public class AlignViewportTest
     af.getViewport().setGlobalColourScheme(cs);
     assertFalse(cs.conservationApplied());
   }
+
+  @Test(groups = { "Functional" })
+  public void testSetGetHasSearchResults()
+  {
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            "examples/uniref50.fa", FormatAdapter.FILE);
+    SearchResultsI sr = new SearchResults();
+    SequenceI s1 = af.getViewport().getAlignment().getSequenceAt(0);
+
+    // create arbitrary range on first sequence
+    sr.addResult(s1, s1.getStart() + 10, s1.getStart() + 15);
+
+    // test set
+    af.getViewport().setSearchResults(sr);
+    // has -> true
+    assertTrue(af.getViewport().hasSearchResults());
+    // get == original
+    assertEquals(sr, af.getViewport().getSearchResults());
+
+    // set(null) results in has -> false
+
+    af.getViewport().setSearchResults(null);
+    assertFalse(af.getViewport().hasSearchResults());
+  }
 }
index 5bc0ddf..92770d5 100644 (file)
@@ -28,7 +28,7 @@ import org.testng.annotations.Test;
 
 public class AppVarnaTest
 {
-  @Test
+  @Test(groups = "Functional")
   public void testReplaceOddGaps()
   {
     String struct = "{(<]}>)";
index edf3202..14354ff 100644 (file)
@@ -20,6 +20,8 @@
  */
 package jalview.gui;
 
+import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
 import static org.testng.AssertJUnit.assertTrue;
@@ -27,6 +29,9 @@ import static org.testng.AssertJUnit.assertTrue;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.FormatAdapter;
@@ -440,4 +445,105 @@ public class PopupMenuTest
     assertEquals(JSeparator.HORIZONTAL,
             ((JSeparator) hideOptions[1]).getOrientation());
   }
+
+  /**
+   * Test for adding feature links
+   */
+  @Test(groups = { "Functional" })
+  public void testAddFeatureLinks()
+  {
+    // sequences from the alignment
+    List<SequenceI> seqs = parentPanel.getAlignment().getSequences();
+
+    // create list of links and list of DBRefs
+    List<String> links = new ArrayList<String>();
+    List<DBRefEntry> refs = new ArrayList<DBRefEntry>();
+
+    // links as might be added into Preferences | Connections dialog
+    links.add("EMBL-EBI Search | http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$"
+            + SEQUENCE_ID + "$");
+    links.add("UNIPROT | http://www.uniprot.org/uniprot/$" + DB_ACCESSION
+            + "$");
+    links.add("INTERPRO | http://www.ebi.ac.uk/interpro/entry/$"
+            + DB_ACCESSION + "$");
+    // Gene3D entry tests for case (in)sensitivity
+    links.add("Gene3D | http://gene3d.biochem.ucl.ac.uk/Gene3D/search?sterm=$"
+            + DB_ACCESSION + "$&mode=protein");
+
+    // make seq0 dbrefs
+    refs.add(new DBRefEntry(DBRefSource.UNIPROT, "1", "P83527"));
+    refs.add(new DBRefEntry("INTERPRO", "1", "IPR001041"));
+    refs.add(new DBRefEntry("INTERPRO", "1", "IPR006058"));
+    refs.add(new DBRefEntry("INTERPRO", "1", "IPR012675"));
+    
+    // make seq1 dbrefs
+    refs.add(new DBRefEntry(DBRefSource.UNIPROT, "1", "Q9ZTS2"));
+    refs.add(new DBRefEntry("GENE3D", "1", "3.10.20.30"));
+
+    // add all the dbrefs to the sequences: Uniprot 1 each, Interpro all 3 to
+    // seq0, Gene3D to seq1
+    seqs.get(0).addDBRef(refs.get(0));
+
+    seqs.get(0).addDBRef(refs.get(1));
+    seqs.get(0).addDBRef(refs.get(2));
+    seqs.get(0).addDBRef(refs.get(3));
+    
+    seqs.get(1).addDBRef(refs.get(4));
+    seqs.get(1).addDBRef(refs.get(5));
+    
+    // get the Popup Menu for first sequence
+    testee = new PopupMenu(parentPanel, (Sequence) seqs.get(0), links);
+    Component[] seqItems = testee.sequenceMenu.getMenuComponents();
+    JMenu linkMenu = (JMenu) seqItems[6];
+    Component[] linkItems = linkMenu.getMenuComponents();
+    
+    // check the number of links are the expected number
+    assertEquals(5, linkItems.length);
+
+    // first entry is EMBL-EBI which just uses sequence id not accession id?
+    assertEquals("EMBL-EBI Search", ((JMenuItem) linkItems[0]).getText());
+
+    // sequence id for each link should match corresponding DB accession id
+    for (int i = 1; i < 4; i++)
+    {
+      assertEquals(refs.get(i - 1).getSource(), ((JMenuItem) linkItems[i])
+              .getText().split("\\|")[0]);
+      assertEquals(refs.get(i - 1).getAccessionId(),
+              ((JMenuItem) linkItems[i])
+              .getText().split("\\|")[1]);
+    }
+
+    // get the Popup Menu for second sequence
+    testee = new PopupMenu(parentPanel, (Sequence) seqs.get(1), links);
+    seqItems = testee.sequenceMenu.getMenuComponents();
+    linkMenu = (JMenu) seqItems[6];
+    linkItems = linkMenu.getMenuComponents();
+    
+    // check the number of links are the expected number
+    assertEquals(3, linkItems.length);
+
+    // first entry is EMBL-EBI which just uses sequence id not accession id?
+    assertEquals("EMBL-EBI Search", ((JMenuItem) linkItems[0]).getText());
+
+    // sequence id for each link should match corresponding DB accession id
+    for (int i = 1; i < 3; i++)
+    {
+      assertEquals(refs.get(i + 3).getSource(), ((JMenuItem) linkItems[i])
+              .getText().split("\\|")[0].toUpperCase());
+      assertEquals(refs.get(i + 3).getAccessionId(),
+              ((JMenuItem) linkItems[i]).getText().split("\\|")[1]);
+    }
+
+    // if there are no valid links the Links submenu is disabled
+    List<String> nomatchlinks = new ArrayList<String>();
+    nomatchlinks.add("NOMATCH | http://www.uniprot.org/uniprot/$"
+            + DB_ACCESSION + "$");
+
+    testee = new PopupMenu(parentPanel, (Sequence) seqs.get(0),
+            nomatchlinks);
+    seqItems = testee.sequenceMenu.getMenuComponents();
+    linkMenu = (JMenu) seqItems[6];
+    assertFalse(linkMenu.isEnabled());
+
+  }
 }
diff --git a/test/jalview/io/3ucu.cif b/test/jalview/io/3ucu.cif
new file mode 100644 (file)
index 0000000..5255f53
--- /dev/null
@@ -0,0 +1,4828 @@
+data_3UCU
+#
+_entry.id       3UCU
+#
+_citation.id                            primary
+_citation.title                         "Structural and biochemical characterization of linear dinucleotide analogues bound to the c-di-GMP-I aptamer."
+_citation.journal_abbrev                Biochemistry
+_citation.journal_volume                51
+_citation.page_first                    425
+_citation.page_last                     432
+_citation.year                          2012
+_citation.journal_id_ASTM               BICHAW
+_citation.country                       US
+_citation.journal_id_ISSN               0006-2960
+_citation.journal_id_CSD                0033
+_citation.book_publisher                ?
+_citation.pdbx_database_id_PubMed       22148472
+_citation.pdbx_database_id_DOI          10.1021/bi2016662
+#
+loop_
+_citation_author.citation_id       
+_citation_author.name              
+_citation_author.ordinal           
+primary "Smith, K.D." 1
+primary "Lipchock, S.V." 2
+primary "Strobel, S.A." 3
+#
+_cell.entry_id               3UCU
+_cell.length_a               49.088
+_cell.length_b               45.350
+_cell.length_c               77.243
+_cell.angle_alpha            90.00
+_cell.angle_beta             96.24
+_cell.angle_gamma            90.00
+_cell.Z_PDB                  2
+_cell.pdbx_unique_axis       ?
+_cell.length_a_esd           ?
+_cell.length_b_esd           ?
+_cell.length_c_esd           ?
+_cell.angle_alpha_esd        ?
+_cell.angle_beta_esd         ?
+_cell.angle_gamma_esd        ?
+#
+_symmetry.entry_id                             3UCU
+_symmetry.space_group_name_H-M                 "P 1 21 1"
+_symmetry.pdbx_full_space_group_name_H-M       ?
+_symmetry.cell_setting                         ?
+_symmetry.Int_Tables_number                    ?
+_symmetry.space_group_name_Hall                ?
+#
+loop_
+_entity.id                             
+_entity.type                           
+_entity.src_method                     
+_entity.pdbx_description               
+_entity.formula_weight                 
+_entity.pdbx_number_of_molecules       
+_entity.details                        
+_entity.pdbx_mutation                  
+_entity.pdbx_fragment                  
+_entity.pdbx_ec                        
+1 polymer man "U1 small nuclear ribonucleoprotein A" 11340.407 1 ? "Y31H, Q36R" "RNA binding domain, UNP residues 1-98" ?
+2 polymer syn "RNA (92-MER)" 29942.965 1 "c-di-GMP-I riboswitch" ? ? ?
+3 polymer syn "diguanosine monophosphate" 645.458 1 ? ? ? ?
+4 non-polymer syn "MAGNESIUM ION" 24.305 1 ? ? ? ?
+5 water nat water 18.015 14 ? ? ? ?
+#
+loop_
+_entity_keywords.entity_id       
+_entity_keywords.text            
+1 ?
+2 ?
+3 ?
+4 ?
+5 ?
+#
+loop_
+_entity_name_com.entity_id       
+_entity_name_com.name            
+1 "U1 snRNP A, U1-A, U1A"
+2 ?
+3 ?
+4 ?
+5 ?
+#
+loop_
+_entity_poly.entity_id                          
+_entity_poly.type                               
+_entity_poly.nstd_linkage                       
+_entity_poly.nstd_monomer                       
+_entity_poly.pdbx_seq_one_letter_code           
+_entity_poly.pdbx_seq_one_letter_code_can       
+_entity_poly.pdbx_strand_id                     
+1 polypeptide(L) no no 
+;MAVPETRPNHTIYINNLNEKIKKDELKKSLHAIFSRFGQILDILVSRSLKMRGQAFVIFKEVSSATNALRSMQGFPFYDK
+PMRIQYAKTDSDIIAKMK
+;
+;MAVPETRPNHTIYINNLNEKIKKDELKKSLHAIFSRFGQILDILVSRSLKMRGQAFVIFKEVSSATNALRSMQGFPFYDK
+PMRIQYAKTDSDIIAKMK
+;
+ P
+2 polyribonucleotide no yes 
+;(GTP)GUCACGCACAGGGCAAACCAUUCGAAAGAGUGGGACGCAAAGCCUCCGGCCUAAACCAUUGCACUCCGGUAGGUA
+GCGGGGUUACCGAUGG
+;
+;GGUCACGCACAGGGCAAACCAUUCGAAAGAGUGGGACGCAAAGCCUCCGGCCUAAACCAUUGCACUCCGGUAGGUAGCGG
+GGUUACCGAUGG
+;
+ R
+3 polyribonucleotide no no GG GG A
+#
+loop_
+_entity_poly_seq.entity_id       
+_entity_poly_seq.num             
+_entity_poly_seq.mon_id          
+_entity_poly_seq.hetero          
+1 1 MET n
+1 2 ALA n
+1 3 VAL n
+1 4 PRO n
+1 5 GLU n
+1 6 THR n
+1 7 ARG n
+1 8 PRO n
+1 9 ASN n
+1 10 HIS n
+1 11 THR n
+1 12 ILE n
+1 13 TYR n
+1 14 ILE n
+1 15 ASN n
+1 16 ASN n
+1 17 LEU n
+1 18 ASN n
+1 19 GLU n
+1 20 LYS n
+1 21 ILE n
+1 22 LYS n
+1 23 LYS n
+1 24 ASP n
+1 25 GLU n
+1 26 LEU n
+1 27 LYS n
+1 28 LYS n
+1 29 SER n
+1 30 LEU n
+1 31 HIS n
+1 32 ALA n
+1 33 ILE n
+1 34 PHE n
+1 35 SER n
+1 36 ARG n
+1 37 PHE n
+1 38 GLY n
+1 39 GLN n
+1 40 ILE n
+1 41 LEU n
+1 42 ASP n
+1 43 ILE n
+1 44 LEU n
+1 45 VAL n
+1 46 SER n
+1 47 ARG n
+1 48 SER n
+1 49 LEU n
+1 50 LYS n
+1 51 MET n
+1 52 ARG n
+1 53 GLY n
+1 54 GLN n
+1 55 ALA n
+1 56 PHE n
+1 57 VAL n
+1 58 ILE n
+1 59 PHE n
+1 60 LYS n
+1 61 GLU n
+1 62 VAL n
+1 63 SER n
+1 64 SER n
+1 65 ALA n
+1 66 THR n
+1 67 ASN n
+1 68 ALA n
+1 69 LEU n
+1 70 ARG n
+1 71 SER n
+1 72 MET n
+1 73 GLN n
+1 74 GLY n
+1 75 PHE n
+1 76 PRO n
+1 77 PHE n
+1 78 TYR n
+1 79 ASP n
+1 80 LYS n
+1 81 PRO n
+1 82 MET n
+1 83 ARG n
+1 84 ILE n
+1 85 GLN n
+1 86 TYR n
+1 87 ALA n
+1 88 LYS n
+1 89 THR n
+1 90 ASP n
+1 91 SER n
+1 92 ASP n
+1 93 ILE n
+1 94 ILE n
+1 95 ALA n
+1 96 LYS n
+1 97 MET n
+1 98 LYS n
+2 1 GTP n
+2 2 G n
+2 3 U n
+2 4 C n
+2 5 A n
+2 6 C n
+2 7 G n
+2 8 C n
+2 9 A n
+2 10 C n
+2 11 A n
+2 12 G n
+2 13 G n
+2 14 G n
+2 15 C n
+2 16 A n
+2 17 A n
+2 18 A n
+2 19 C n
+2 20 C n
+2 21 A n
+2 22 U n
+2 23 U n
+2 24 C n
+2 25 G n
+2 26 A n
+2 27 A n
+2 28 A n
+2 29 G n
+2 30 A n
+2 31 G n
+2 32 U n
+2 33 G n
+2 34 G n
+2 35 G n
+2 36 A n
+2 37 C n
+2 38 G n
+2 39 C n
+2 40 A n
+2 41 A n
+2 42 A n
+2 43 G n
+2 44 C n
+2 45 C n
+2 46 U n
+2 47 C n
+2 48 C n
+2 49 G n
+2 50 G n
+2 51 C n
+2 52 C n
+2 53 U n
+2 54 A n
+2 55 A n
+2 56 A n
+2 57 C n
+2 58 C n
+2 59 A n
+2 60 U n
+2 61 U n
+2 62 G n
+2 63 C n
+2 64 A n
+2 65 C n
+2 66 U n
+2 67 C n
+2 68 C n
+2 69 G n
+2 70 G n
+2 71 U n
+2 72 A n
+2 73 G n
+2 74 G n
+2 75 U n
+2 76 A n
+2 77 G n
+2 78 C n
+2 79 G n
+2 80 G n
+2 81 G n
+2 82 G n
+2 83 U n
+2 84 U n
+2 85 A n
+2 86 C n
+2 87 C n
+2 88 G n
+2 89 A n
+2 90 U n
+2 91 G n
+2 92 G n
+3 1 G n
+3 2 G n
+#
+_entity_src_gen.entity_id                              1
+_entity_src_gen.gene_src_common_name                   human
+_entity_src_gen.gene_src_genus                         ?
+_entity_src_gen.pdbx_gene_src_gene                     SNRPA
+_entity_src_gen.gene_src_species                       ?
+_entity_src_gen.gene_src_strain                        ?
+_entity_src_gen.gene_src_tissue                        ?
+_entity_src_gen.gene_src_tissue_fraction               ?
+_entity_src_gen.gene_src_details                       ?
+_entity_src_gen.pdbx_gene_src_fragment                 ?
+_entity_src_gen.pdbx_gene_src_scientific_name          "Homo sapiens"
+_entity_src_gen.pdbx_gene_src_ncbi_taxonomy_id         9606
+_entity_src_gen.pdbx_gene_src_variant                  ?
+_entity_src_gen.pdbx_gene_src_cell_line                ?
+_entity_src_gen.pdbx_gene_src_atcc                     ?
+_entity_src_gen.pdbx_gene_src_organ                    ?
+_entity_src_gen.pdbx_gene_src_organelle                ?
+_entity_src_gen.pdbx_gene_src_cell                     ?
+_entity_src_gen.pdbx_gene_src_cellular_location        ?
+_entity_src_gen.host_org_common_name                   ?
+_entity_src_gen.pdbx_host_org_scientific_name          "Escherichia coli"
+_entity_src_gen.pdbx_host_org_ncbi_taxonomy_id         511693
+_entity_src_gen.host_org_genus                         ?
+_entity_src_gen.pdbx_host_org_gene                     ?
+_entity_src_gen.pdbx_host_org_organ                    ?
+_entity_src_gen.host_org_species                       ?
+_entity_src_gen.pdbx_host_org_tissue                   ?
+_entity_src_gen.pdbx_host_org_tissue_fraction          ?
+_entity_src_gen.pdbx_host_org_strain                   BL21
+_entity_src_gen.pdbx_host_org_variant                  ?
+_entity_src_gen.pdbx_host_org_cell_line                ?
+_entity_src_gen.pdbx_host_org_atcc                     ?
+_entity_src_gen.pdbx_host_org_culture_collection       ?
+_entity_src_gen.pdbx_host_org_cell                     ?
+_entity_src_gen.pdbx_host_org_organelle                ?
+_entity_src_gen.pdbx_host_org_cellular_location        ?
+_entity_src_gen.pdbx_host_org_vector_type              plasmid
+_entity_src_gen.pdbx_host_org_vector                   ?
+_entity_src_gen.plasmid_name                           pET11
+_entity_src_gen.plasmid_details                        ?
+_entity_src_gen.pdbx_description                       ?
+#
+_pdbx_entity_src_syn.entity_id                  2
+_pdbx_entity_src_syn.organism_scientific        ?
+_pdbx_entity_src_syn.organism_common_name       ?
+_pdbx_entity_src_syn.ncbi_taxonomy_id           ?
+_pdbx_entity_src_syn.details                    "in vitro transcribed RNA transcript"
+#
+loop_
+_struct_ref.id                             
+_struct_ref.db_name                        
+_struct_ref.db_code                        
+_struct_ref.pdbx_db_accession              
+_struct_ref.entity_id                      
+_struct_ref.pdbx_seq_one_letter_code       
+_struct_ref.pdbx_align_begin               
+_struct_ref.biol_id                        
+1 UNP SNRPA_HUMAN P09012 1 
+;MAVPETRPNHTIYINNLNEKIKKDELKKSLYAIFSQFGQILDILVSRSLKMRGQAFVIFK 
+EVSSATNALRSMQGFPFYDKPMRIQYAKTDSDIIAKMK
+;
+ 1 .
+2 PDB 3UCU 3UCU 2 ? ? .
+3 PDB 3UCU 3UCU 3 ? ? .
+#
+loop_
+_struct_ref_seq.align_id                          
+_struct_ref_seq.ref_id                            
+_struct_ref_seq.pdbx_PDB_id_code                  
+_struct_ref_seq.pdbx_strand_id                    
+_struct_ref_seq.seq_align_beg                     
+_struct_ref_seq.pdbx_seq_align_beg_ins_code       
+_struct_ref_seq.seq_align_end                     
+_struct_ref_seq.pdbx_seq_align_end_ins_code       
+_struct_ref_seq.pdbx_db_accession                 
+_struct_ref_seq.db_align_beg                      
+_struct_ref_seq.db_align_end                      
+_struct_ref_seq.pdbx_auth_seq_align_beg           
+_struct_ref_seq.pdbx_auth_seq_align_end           
+1 1 3UCU P 1 ? 98 ? P09012 1 98 1 98
+2 2 3UCU R 1 ? 92 ? 3UCU 8 98 8 98
+3 3 3UCU A 1 ? 2 ? 3UCU 1 2 1 2
+#
+loop_
+_struct_ref_seq_dif.align_id                         
+_struct_ref_seq_dif.pdbx_pdb_id_code                 
+_struct_ref_seq_dif.mon_id                           
+_struct_ref_seq_dif.pdbx_pdb_strand_id               
+_struct_ref_seq_dif.seq_num                          
+_struct_ref_seq_dif.pdbx_pdb_ins_code                
+_struct_ref_seq_dif.pdbx_seq_db_name                 
+_struct_ref_seq_dif.pdbx_seq_db_accession_code       
+_struct_ref_seq_dif.db_mon_id                        
+_struct_ref_seq_dif.pdbx_seq_db_seq_num              
+_struct_ref_seq_dif.details                          
+_struct_ref_seq_dif.pdbx_auth_seq_num                
+_struct_ref_seq_dif.pdbx_ordinal                     
+1 3UCU HIS P 31 ? UNP P09012 TYR 31 "Engineered mutation" 31 1
+1 3UCU ARG P 36 ? UNP P09012 GLN 36 "Engineered mutation" 36 2
+#
+loop_
+_chem_comp.id                   
+_chem_comp.type                 
+_chem_comp.mon_nstd_flag        
+_chem_comp.name                 
+_chem_comp.pdbx_synonyms        
+_chem_comp.formula              
+_chem_comp.formula_weight       
+ARG "L-peptide linking" y ARGININE ? "C6 H15 N4 O2 1" 175.210
+PRO "L-peptide linking" y PROLINE ? "C5 H9 N O2" 115.132
+ASN "L-peptide linking" y ASPARAGINE ? "C4 H8 N2 O3" 132.119
+HIS "L-peptide linking" y HISTIDINE ? "C6 H10 N3 O2 1" 156.164
+THR "L-peptide linking" y THREONINE ? "C4 H9 N O3" 119.120
+ILE "L-peptide linking" y ISOLEUCINE ? "C6 H13 N O2" 131.174
+TYR "L-peptide linking" y TYROSINE ? "C9 H11 N O3" 181.191
+LEU "L-peptide linking" y LEUCINE ? "C6 H13 N O2" 131.174
+GLU "L-peptide linking" y "GLUTAMIC ACID" ? "C5 H9 N O4" 147.130
+LYS "L-peptide linking" y LYSINE ? "C6 H15 N2 O2 1" 147.197
+ASP "L-peptide linking" y "ASPARTIC ACID" ? "C4 H7 N O4" 133.104
+SER "L-peptide linking" y SERINE ? "C3 H7 N O3" 105.093
+ALA "L-peptide linking" y ALANINE ? "C3 H7 N O2" 89.094
+PHE "L-peptide linking" y PHENYLALANINE ? "C9 H11 N O2" 165.191
+GLY "PEPTIDE LINKING" y GLYCINE ? "C2 H5 N O2" 75.067
+GLN "L-peptide linking" y GLUTAMINE ? "C5 H10 N2 O3" 146.146
+VAL "L-peptide linking" y VALINE ? "C5 H11 N O2" 117.147
+MET "L-peptide linking" y METHIONINE ? "C5 H11 N O2 S" 149.207
+GTP "RNA linking" n "GUANOSINE-5'-TRIPHOSPHATE" ? "C10 H16 N5 O14 P3" 523.183
+G "RNA linking" y "GUANOSINE-5'-MONOPHOSPHATE" ? "C10 H14 N5 O8 P" 363.223
+U "RNA linking" y "URIDINE-5'-MONOPHOSPHATE" ? "C9 H13 N2 O9 P" 324.183
+C "RNA linking" y "CYTIDINE-5'-MONOPHOSPHATE" ? "C9 H14 N3 O8 P" 323.199
+A "RNA linking" y "ADENOSINE-5'-MONOPHOSPHATE" ? "C10 H14 N5 O7 P" 347.224
+MG NON-POLYMER . "MAGNESIUM ION" ? "MG 2" 24.305
+HOH NON-POLYMER . WATER ? "H2 O" 18.015
+#
+_exptl.entry_id              3UCU
+_exptl.method                "X-ray diffraction"
+_exptl.crystals_number       1
+#
+_exptl_crystal.id                        1
+_exptl_crystal.density_meas              ?
+_exptl_crystal.density_Matthews          2.04
+_exptl_crystal.density_percent_sol       39.66
+_exptl_crystal.description               ?
+_exptl_crystal.F_000                     ?
+_exptl_crystal.preparation               ?
+#
+_exptl_crystal_grow.crystal_id          1
+_exptl_crystal_grow.method              "VAPOR DIFFUSION, HANGING DROP"
+_exptl_crystal_grow.temp                298
+_exptl_crystal_grow.temp_details        ?
+_exptl_crystal_grow.pH                  6
+_exptl_crystal_grow.pdbx_details        "24% PEG550mme, 50 mM MES, pH 6.0, 5 mM MgSO4, 300 mM NaCl, VAPOR DIFFUSION, HANGING DROP, temperature 298K"
+_exptl_crystal_grow.pdbx_pH_range       ?
+#
+_diffrn.id                         1
+_diffrn.ambient_temp               100
+_diffrn.ambient_temp_details       ?
+_diffrn.crystal_id                 1
+#
+_diffrn_detector.diffrn_id                  1
+_diffrn_detector.detector                   CCD
+_diffrn_detector.type                       "ADSC QUANTUM 315"
+_diffrn_detector.pdbx_collection_date       2009-10-01
+_diffrn_detector.details                    ?
+#
+_diffrn_radiation.diffrn_id                            1
+_diffrn_radiation.wavelength_id                        1
+_diffrn_radiation.pdbx_monochromatic_or_laue_m_l       M
+_diffrn_radiation.monochromator                        Si(111)
+_diffrn_radiation.pdbx_diffrn_protocol                 "Single wavelength"
+_diffrn_radiation.pdbx_scattering_type                 x-ray
+#
+_diffrn_radiation_wavelength.id               1
+_diffrn_radiation_wavelength.wavelength       1.1
+_diffrn_radiation_wavelength.wt               1.0
+#
+_diffrn_source.diffrn_id                       1
+_diffrn_source.source                          Synchrotron
+_diffrn_source.type                            "NSLS BEAMLINE X25"
+_diffrn_source.pdbx_synchrotron_site           NSLS
+_diffrn_source.pdbx_synchrotron_beamline       X25
+_diffrn_source.pdbx_wavelength                 ?
+_diffrn_source.pdbx_wavelength_list            1.1
+#
+_reflns.entry_id                         3UCU
+_reflns.observed_criterion_sigma_I       2.0
+_reflns.observed_criterion_sigma_F       2.0
+_reflns.d_resolution_low                 50
+_reflns.d_resolution_high                2.8
+_reflns.number_obs                       8584
+_reflns.number_all                       8612
+_reflns.percent_possible_obs             99.7
+_reflns.pdbx_Rmerge_I_obs                0.086
+_reflns.pdbx_Rsym_value                  ?
+_reflns.pdbx_netI_over_sigmaI            21.8
+_reflns.B_iso_Wilson_estimate            ?
+_reflns.pdbx_redundancy                  7.0
+_reflns.R_free_details                   ?
+_reflns.limit_h_max                      ?
+_reflns.limit_h_min                      ?
+_reflns.limit_k_max                      ?
+_reflns.limit_k_min                      ?
+_reflns.limit_l_max                      ?
+_reflns.limit_l_min                      ?
+_reflns.observed_criterion_F_max         ?
+_reflns.observed_criterion_F_min         ?
+_reflns.pdbx_chi_squared                 ?
+_reflns.pdbx_scaling_rejects             ?
+_reflns.pdbx_ordinal                     1
+_reflns.pdbx_diffrn_id                   1
+#
+_reflns_shell.d_res_high                 2.80
+_reflns_shell.d_res_low                  2.85
+_reflns_shell.percent_possible_all       99.8
+_reflns_shell.Rmerge_I_obs               0.85
+_reflns_shell.pdbx_Rsym_value            ?
+_reflns_shell.meanI_over_sigI_obs        2.3
+_reflns_shell.pdbx_redundancy            6.6
+_reflns_shell.percent_possible_obs       ?
+_reflns_shell.number_unique_all          ?
+_reflns_shell.number_measured_all        ?
+_reflns_shell.number_measured_obs        ?
+_reflns_shell.number_unique_obs          ?
+_reflns_shell.pdbx_chi_squared           ?
+_reflns_shell.pdbx_ordinal               1
+_reflns_shell.pdbx_diffrn_id             1
+#
+_computing.entry_id                               3UCU
+_computing.pdbx_data_reduction_ii                 HKL-2000
+_computing.pdbx_data_reduction_ds                 HKL-2000
+_computing.data_collection                        CBASS
+_computing.structure_solution                     Phaser
+_computing.structure_refinement                   REFMAC5
+_computing.pdbx_structure_refinement_method       ?
+#
+_refine.entry_id                                   3UCU
+_refine.ls_number_reflns_obs                       8150
+_refine.ls_number_reflns_all                       8150
+_refine.pdbx_ls_sigma_I                            ?
+_refine.pdbx_ls_sigma_F                            ?
+_refine.pdbx_data_cutoff_high_absF                 ?
+_refine.pdbx_data_cutoff_low_absF                  ?
+_refine.pdbx_data_cutoff_high_rms_absF             ?
+_refine.ls_d_res_low                               ?
+_refine.ls_d_res_high                              2.8
+_refine.ls_percent_reflns_obs                      98.73
+_refine.ls_R_factor_obs                            0.21709
+_refine.ls_R_factor_all                            0.21709
+_refine.ls_R_factor_R_work                         0.21486
+_refine.ls_R_factor_R_free                         0.26208
+_refine.ls_R_factor_R_free_error                   ?
+_refine.ls_R_factor_R_free_error_details           ?
+_refine.ls_percent_reflns_R_free                   4.7
+_refine.ls_number_reflns_R_free                    406
+_refine.ls_number_parameters                       ?
+_refine.ls_number_restraints                       ?
+_refine.occupancy_min                              ?
+_refine.occupancy_max                              ?
+_refine.correlation_coeff_Fo_to_Fc                 0.942
+_refine.correlation_coeff_Fo_to_Fc_free            0.911
+_refine.B_iso_mean                                 62.151
+_refine.aniso_B[1][1]                              2.72
+_refine.aniso_B[2][2]                              -5.60
+_refine.aniso_B[3][3]                              3.88
+_refine.aniso_B[1][2]                              0.00
+_refine.aniso_B[1][3]                              4.57
+_refine.aniso_B[2][3]                              -0.00
+_refine.solvent_model_details                      MASK
+_refine.solvent_model_param_ksol                   ?
+_refine.solvent_model_param_bsol                   ?
+_refine.pdbx_solvent_vdw_probe_radii               1.40
+_refine.pdbx_solvent_ion_probe_radii               0.80
+_refine.pdbx_solvent_shrinkage_radii               0.80
+_refine.pdbx_ls_cross_valid_method                 THROUGHOUT
+_refine.details                                    "HYDROGENS HAVE BEEN ADDED IN THE RIDING POSITIONS"
+_refine.pdbx_starting_model                        ?
+_refine.pdbx_method_to_determine_struct            "MOLECULAR REPLACEMENT"
+_refine.pdbx_isotropic_thermal_model               ?
+_refine.pdbx_stereochemistry_target_values         "MAXIMUM LIKELIHOOD"
+_refine.pdbx_stereochem_target_val_spec_case       ?
+_refine.pdbx_R_Free_selection_details              RANDOM
+_refine.pdbx_overall_ESU_R_Free                    0.433
+_refine.overall_SU_ML                              0.380
+_refine.pdbx_overall_phase_error                   ?
+_refine.overall_SU_B                               19.510
+_refine.overall_SU_R_Cruickshank_DPI               ?
+_refine.ls_redundancy_reflns_obs                   ?
+_refine.B_iso_min                                  ?
+_refine.B_iso_max                                  ?
+_refine.overall_SU_R_free                          ?
+_refine.ls_wR_factor_R_free                        ?
+_refine.ls_wR_factor_R_work                        ?
+_refine.overall_FOM_free_R_set                     ?
+_refine.overall_FOM_work_R_set                     ?
+_refine.pdbx_diffrn_id                             1
+_refine.pdbx_refine_id                             "X-ray diffraction"
+_refine.pdbx_overall_ESU_R                         ?
+#
+_refine_hist.pdbx_refine_id                       "X-ray diffraction"
+_refine_hist.cycle_id                             LAST
+_refine_hist.pdbx_number_atoms_protein            712
+_refine_hist.pdbx_number_atoms_nucleic_acid       2031
+_refine_hist.pdbx_number_atoms_ligand             1
+_refine_hist.number_atoms_solvent                 14
+_refine_hist.number_atoms_total                   2758
+_refine_hist.d_res_high                           2.8
+_refine_hist.d_res_low                            .
+#
+loop_
+_refine_ls_restr.type                          
+_refine_ls_restr.dev_ideal                     
+_refine_ls_restr.dev_ideal_target              
+_refine_ls_restr.weight                        
+_refine_ls_restr.number                        
+_refine_ls_restr.pdbx_restraint_function       
+_refine_ls_restr.pdbx_refine_id                
+r_bond_refined_d 0.006 0.021 ? 3002 ? "X-ray diffraction"
+r_angle_refined_deg 1.038 2.775 ? 4526 ? "X-ray diffraction"
+r_dihedral_angle_1_deg 4.492 5.000 ? 86 ? "X-ray diffraction"
+r_dihedral_angle_2_deg 33.872 23.235 ? 34 ? "X-ray diffraction"
+r_dihedral_angle_3_deg 15.786 15.000 ? 144 ? "X-ray diffraction"
+r_dihedral_angle_4_deg 14.062 15.000 ? 6 ? "X-ray diffraction"
+r_chiral_restr 0.055 0.200 ? 575 ? "X-ray diffraction"
+r_gen_planes_refined 0.002 0.020 ? 1519 ? "X-ray diffraction"
+r_mcbond_it 1.210 6.000 ? 434 ? "X-ray diffraction"
+r_mcangle_it 2.149 8.000 ? 703 ? "X-ray diffraction"
+r_scbond_it 1.331 6.000 ? 2568 ? "X-ray diffraction"
+r_scangle_it 2.184 8.000 ? 3822 ? "X-ray diffraction"
+#
+_refine_ls_shell.pdbx_total_number_of_bins_used       20
+_refine_ls_shell.d_res_high                           2.785
+_refine_ls_shell.d_res_low                            2.857
+_refine_ls_shell.number_reflns_R_work                 530
+_refine_ls_shell.R_factor_R_work                      0.420
+_refine_ls_shell.percent_reflns_obs                   88.80
+_refine_ls_shell.R_factor_R_free                      0.444
+_refine_ls_shell.R_factor_R_free_error                ?
+_refine_ls_shell.percent_reflns_R_free                ?
+_refine_ls_shell.number_reflns_R_free                 33
+_refine_ls_shell.number_reflns_all                    ?
+_refine_ls_shell.R_factor_all                         ?
+_refine_ls_shell.number_reflns_obs                    566
+_refine_ls_shell.redundancy_reflns_obs                ?
+_refine_ls_shell.pdbx_refine_id                       "X-ray diffraction"
+#
+_struct.entry_id                      3UCU
+_struct.title                         "The c-di-GMP-I riboswitch bound to pGpG"
+_struct.pdbx_descriptor               "U1 small nuclear ribonucleoprotein A/RNA"
+_struct.pdbx_model_details            ?
+_struct.pdbx_CASP_flag                ?
+_struct.pdbx_model_type_details       ?
+#
+_struct_keywords.entry_id            3UCU
+_struct_keywords.pdbx_keywords       "SIGNALING PROTEIN/RNA"
+_struct_keywords.text                "riboswitch, SIGNALING PROTEIN-RNA complex"
+#
+loop_
+_struct_asym.id                                
+_struct_asym.pdbx_blank_PDB_chainid_flag       
+_struct_asym.pdbx_modified                     
+_struct_asym.entity_id                         
+_struct_asym.details                           
+A N N 1 ?
+B N N 2 ?
+C N N 3 ?
+D N N 4 ?
+E N N 5 ?
+F N N 5 ?
+G N N 5 ?
+#
+_struct_biol.id            1
+_struct_biol.details       "THE PROTEIN IS NOT BIOLOGICALLY RELEVANT AND HAS BEEN USED AS A CRYSTALLIZATION CHAPERONE."
+#
+loop_
+_struct_conf.conf_type_id                
+_struct_conf.id                          
+_struct_conf.pdbx_PDB_helix_id           
+_struct_conf.beg_label_comp_id           
+_struct_conf.beg_label_asym_id           
+_struct_conf.beg_label_seq_id            
+_struct_conf.pdbx_beg_PDB_ins_code       
+_struct_conf.end_label_comp_id           
+_struct_conf.end_label_asym_id           
+_struct_conf.end_label_seq_id            
+_struct_conf.pdbx_end_PDB_ins_code       
+_struct_conf.beg_auth_comp_id            
+_struct_conf.beg_auth_asym_id            
+_struct_conf.beg_auth_seq_id             
+_struct_conf.end_auth_comp_id            
+_struct_conf.end_auth_asym_id            
+_struct_conf.end_auth_seq_id             
+_struct_conf.pdbx_PDB_helix_class        
+_struct_conf.details                     
+_struct_conf.pdbx_PDB_helix_length       
+HELX_P HELX_P1 1 LYS A 22 ? SER A 35 ? LYS P 22 SER P 35 1 ? 14
+HELX_P HELX_P2 2 GLU A 61 ? GLN A 73 ? GLU P 61 GLN P 73 1 ? 13
+#
+_struct_conf_type.id              HELX_P
+_struct_conf_type.criteria        ?
+_struct_conf_type.reference       ?
+#
+loop_
+_struct_conn.id                                
+_struct_conn.conn_type_id                      
+_struct_conn.pdbx_PDB_id                       
+_struct_conn.ptnr1_label_asym_id               
+_struct_conn.ptnr1_label_comp_id               
+_struct_conn.ptnr1_label_seq_id                
+_struct_conn.ptnr1_label_atom_id               
+_struct_conn.pdbx_ptnr1_label_alt_id           
+_struct_conn.pdbx_ptnr1_PDB_ins_code           
+_struct_conn.pdbx_ptnr1_standard_comp_id       
+_struct_conn.ptnr1_symmetry                    
+_struct_conn.ptnr2_label_asym_id               
+_struct_conn.ptnr2_label_comp_id               
+_struct_conn.ptnr2_label_seq_id                
+_struct_conn.ptnr2_label_atom_id               
+_struct_conn.pdbx_ptnr2_label_alt_id           
+_struct_conn.pdbx_ptnr2_PDB_ins_code           
+_struct_conn.ptnr1_auth_asym_id                
+_struct_conn.ptnr1_auth_comp_id                
+_struct_conn.ptnr1_auth_seq_id                 
+_struct_conn.ptnr2_auth_asym_id                
+_struct_conn.ptnr2_auth_comp_id                
+_struct_conn.ptnr2_auth_seq_id                 
+_struct_conn.ptnr2_symmetry                    
+_struct_conn.pdbx_ptnr3_label_atom_id          
+_struct_conn.pdbx_ptnr3_label_seq_id           
+_struct_conn.pdbx_ptnr3_label_comp_id          
+_struct_conn.pdbx_ptnr3_label_asym_id          
+_struct_conn.pdbx_ptnr3_label_alt_id           
+_struct_conn.pdbx_ptnr3_PDB_ins_code           
+_struct_conn.details                           
+_struct_conn.pdbx_dist_value                   
+_struct_conn.pdbx_value_order                  
+covale1 covale ? B GTP 1 "O3'" ? ? ? 1_555 B G 2 P ? ? R GTP 8 R G 9 1_555 ? ? ? ? ? ? ? 1.600 ?
+covale2 covale ? B C 58 "O3'" ? ? ? 1_555 B A 59 P ? ? R C 65 R A 660 1_555 ? ? ? ? ? ? ? 1.605 ?
+metalc1 metalc ? D MG . MG ? ? ? 1_555 G HOH . O ? ? R MG 1 A HOH 3 1_555 ? ? ? ? ? ? ? 2.176 ?
+metalc2 metalc ? D MG . MG ? ? ? 1_555 F HOH . O ? ? R MG 1 R HOH 676 1_555 ? ? ? ? ? ? ? 2.179 ?
+metalc3 metalc ? D MG . MG ? ? ? 1_555 F HOH . O ? ? R MG 1 R HOH 673 1_555 ? ? ? ? ? ? ? 2.179 ?
+metalc4 metalc ? D MG . MG ? ? ? 1_555 F HOH . O ? ? R MG 1 R HOH 674 1_555 ? ? ? ? ? ? ? 2.180 ?
+metalc5 metalc ? D MG . MG ? ? ? 1_555 F HOH . O ? ? R MG 1 R HOH 675 1_555 ? ? ? ? ? ? ? 2.182 ?
+mismat1 mismat ? B A 5 ? ? ? ? 1_555 B G 91 ? ? ? R A 12 R G 97 1_555 ? ? ? ? ? ? ? ? ?
+mismat2 mismat ? B G 7 ? ? ? ? 1_555 B A 9 ? ? ? R G 14 R A 16 1_555 ? ? ? ? ? ? ? ? ?
+mismat3 mismat ? B A 9 ? ? ? ? 1_555 B C 87 ? ? ? R A 16 R C 93 1_555 ? ? ? ? ? ? ? ? ?
+mismat4 mismat ? B C 10 ? ? ? ? 1_555 B C 87 ? ? ? R C 17 R C 93 1_555 ? ? ? ? ? ? ? ? ?
+mismat5 mismat ? B G 12 ? ? ? ? 1_555 B A 40 ? ? ? R G 19 R A 47 1_555 ? ? ? ? ? ? ? ? ?
+mismat6 mismat ? B G 13 ? ? ? ? 1_555 C G 1 ? ? ? R G 20 A G 1 1_555 ? ? ? ? ? ? ? ? ?
+mismat7 mismat ? B A 16 ? ? ? ? 1_555 B C 37 ? ? ? R A 23 R C 44 1_555 ? ? ? ? ? ? ? ? ?
+mismat8 mismat ? B A 18 ? ? ? ? 1_555 B G 35 ? ? ? R A 25 R G 42 1_555 ? ? ? ? ? ? ? ? ?
+mismat9 mismat ? B U 22 ? ? ? ? 1_555 B G 31 ? ? ? R U 29 R G 38 1_555 ? ? ? ? ? ? ? ? ?
+mismat10 mismat ? B G 25 ? ? ? ? 1_555 B A 28 ? ? ? R G 32 R A 35 1_555 ? ? ? ? ? ? ? ? ?
+mismat11 mismat ? B A 28 ? ? ? ? 1_555 B G 73 ? ? ? R A 35 R G 79 1_555 ? ? ? ? ? ? ? ? ?
+mismat12 mismat ? B G 38 ? ? ? ? 1_555 B A 42 ? ? ? R G 45 R A 49 1_555 ? ? ? ? ? ? ? ? ?
+mismat13 mismat ? B G 43 ? ? ? ? 1_555 B U 83 ? ? ? R G 50 R U 89 1_555 ? ? ? ? ? ? ? ? ?
+mismat14 mismat ? B U 46 ? ? ? ? 1_555 B C 48 ? ? ? R U 53 R C 55 1_555 ? ? ? ? ? ? ? ? ?
+mismat15 mismat ? B C 47 ? ? ? ? 1_555 B A 76 ? ? ? R C 54 R A 82 1_555 ? ? ? ? ? ? ? ? ?
+mismat16 mismat ? B G 50 ? ? ? ? 1_555 B U 75 ? ? ? R G 57 R U 81 1_555 ? ? ? ? ? ? ? ? ?
+mismat17 mismat ? B A 54 ? ? ? ? 1_555 B A 55 ? ? ? R A 61 R A 62 1_555 ? ? ? ? ? ? ? ? ?
+mismat18 mismat ? B G 88 ? ? ? ? 1_555 B A 89 ? ? ? R G 94 R A 95 1_555 ? ? ? ? ? ? ? ? ?
+hydrog1 hydrog ? B C 4 N3 ? ? ? 1_555 B G 92 N1 ? ? R C 11 R G 98 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog2 hydrog ? B C 4 N4 ? ? ? 1_555 B G 92 O6 ? ? R C 11 R G 98 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog3 hydrog ? B C 4 O2 ? ? ? 1_555 B G 92 N2 ? ? R C 11 R G 98 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog4 hydrog ? B A 5 N1 ? ? ? 1_555 B G 91 N1 ? ? R A 12 R G 97 1_555 ? ? ? ? ? ? TYPE_8_PAIR ? ?
+hydrog5 hydrog ? B A 5 N6 ? ? ? 1_555 B G 91 O6 ? ? R A 12 R G 97 1_555 ? ? ? ? ? ? TYPE_8_PAIR ? ?
+hydrog6 hydrog ? B C 6 N3 ? ? ? 1_555 B G 88 N1 ? ? R C 13 R G 94 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog7 hydrog ? B C 6 N4 ? ? ? 1_555 B G 88 O6 ? ? R C 13 R G 94 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog8 hydrog ? B C 6 O2 ? ? ? 1_555 B G 88 N2 ? ? R C 13 R G 94 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog9 hydrog ? B G 7 N2 ? ? ? 1_555 B A 9 N7 ? ? R G 14 R A 16 1_555 ? ? ? ? ? ? "G-A MISPAIR" ? ?
+hydrog10 hydrog ? B G 7 N1 ? ? ? 1_555 B C 87 N3 ? ? R G 14 R C 93 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog11 hydrog ? B G 7 N2 ? ? ? 1_555 B C 87 O2 ? ? R G 14 R C 93 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog12 hydrog ? B G 7 O6 ? ? ? 1_555 B C 87 N4 ? ? R G 14 R C 93 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog13 hydrog ? B A 9 N6 ? ? ? 1_555 B C 87 O2 ? ? R A 16 R C 93 1_555 ? ? ? ? ? ? "A-C MISPAIR" ? ?
+hydrog14 hydrog ? B C 10 N4 ? ? ? 1_555 B C 87 O2 ? ? R C 17 R C 93 1_555 ? ? ? ? ? ? "C-C MISPAIR" ? ?
+hydrog15 hydrog ? B C 10 N4 ? ? ? 1_555 C G 2 N3 ? ? R C 17 A G 2 1_555 ? ? ? ? ? ? "C-G PAIR" ? ?
+hydrog16 hydrog ? B G 12 O6 ? ? ? 1_555 B A 40 N6 ? ? R G 19 R A 47 1_555 ? ? ? ? ? ? "G-A MISPAIR" ? ?
+hydrog17 hydrog ? B G 13 N1 ? ? ? 1_555 C G 1 N7 ? ? R G 20 A G 1 1_555 ? ? ? ? ? ? TYPE_7_PAIR ? ?
+hydrog18 hydrog ? B G 13 N2 ? ? ? 1_555 C G 1 O6 ? ? R G 20 A G 1 1_555 ? ? ? ? ? ? TYPE_7_PAIR ? ?
+hydrog19 hydrog ? B G 14 N1 ? ? ? 1_555 B C 39 N3 ? ? R G 21 R C 46 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog20 hydrog ? B G 14 N2 ? ? ? 1_555 B C 39 O2 ? ? R G 21 R C 46 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog21 hydrog ? B G 14 O6 ? ? ? 1_555 B C 39 N4 ? ? R G 21 R C 46 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog22 hydrog ? B C 15 N3 ? ? ? 1_555 B G 38 N1 ? ? R C 22 R G 45 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog23 hydrog ? B C 15 N4 ? ? ? 1_555 B G 38 O6 ? ? R C 22 R G 45 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog24 hydrog ? B C 15 O2 ? ? ? 1_555 B G 38 N2 ? ? R C 22 R G 45 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog25 hydrog ? B A 16 N3 ? ? ? 1_555 B C 37 N4 ? ? R A 23 R C 44 1_555 ? ? ? ? ? ? "A-C MISPAIR" ? ?
+hydrog26 hydrog ? B A 18 N6 ? ? ? 1_555 B G 35 N3 ? ? R A 25 R G 42 1_555 ? ? ? ? ? ? TYPE_11_PAIR ? ?
+hydrog27 hydrog ? B A 18 N7 ? ? ? 1_555 B G 35 N2 ? ? R A 25 R G 42 1_555 ? ? ? ? ? ? TYPE_11_PAIR ? ?
+hydrog28 hydrog ? B C 19 N3 ? ? ? 1_555 B G 34 N1 ? ? R C 26 R G 41 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog29 hydrog ? B C 19 N4 ? ? ? 1_555 B G 34 O6 ? ? R C 26 R G 41 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog30 hydrog ? B C 19 O2 ? ? ? 1_555 B G 34 N2 ? ? R C 26 R G 41 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog31 hydrog ? B C 20 N3 ? ? ? 1_555 B G 33 N1 ? ? R C 27 R G 40 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog32 hydrog ? B C 20 N4 ? ? ? 1_555 B G 33 O6 ? ? R C 27 R G 40 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog33 hydrog ? B C 20 O2 ? ? ? 1_555 B G 33 N2 ? ? R C 27 R G 40 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog34 hydrog ? B A 21 N1 ? ? ? 1_555 B U 32 N3 ? ? R A 28 R U 39 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog35 hydrog ? B A 21 N6 ? ? ? 1_555 B U 32 O4 ? ? R A 28 R U 39 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog36 hydrog ? B U 22 N3 ? ? ? 1_555 B G 31 O6 ? ? R U 29 R G 38 1_555 ? ? ? ? ? ? TYPE_28_PAIR ? ?
+hydrog37 hydrog ? B U 22 O2 ? ? ? 1_555 B G 31 N1 ? ? R U 29 R G 38 1_555 ? ? ? ? ? ? TYPE_28_PAIR ? ?
+hydrog38 hydrog ? B U 23 N3 ? ? ? 1_555 B A 30 N1 ? ? R U 30 R A 37 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog39 hydrog ? B U 23 O4 ? ? ? 1_555 B A 30 N6 ? ? R U 30 R A 37 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog40 hydrog ? B C 24 N3 ? ? ? 1_555 B G 29 N1 ? ? R C 31 R G 36 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog41 hydrog ? B C 24 N4 ? ? ? 1_555 B G 29 O6 ? ? R C 31 R G 36 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog42 hydrog ? B C 24 O2 ? ? ? 1_555 B G 29 N2 ? ? R C 31 R G 36 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog43 hydrog ? B G 25 N2 ? ? ? 1_555 B A 28 N7 ? ? R G 32 R A 35 1_555 ? ? ? ? ? ? "G-A MISPAIR" ? ?
+hydrog44 hydrog ? B A 28 N3 ? ? ? 1_555 B G 73 N2 ? ? R A 35 R G 79 1_555 ? ? ? ? ? ? "A-G MISPAIR" ? ?
+hydrog45 hydrog ? B C 37 N3 ? ? ? 1_555 B G 77 N1 ? ? R C 44 R G 83 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog46 hydrog ? B C 37 N4 ? ? ? 1_555 B G 77 O6 ? ? R C 44 R G 83 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog47 hydrog ? B C 37 O2 ? ? ? 1_555 B G 77 N2 ? ? R C 44 R G 83 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog48 hydrog ? B G 38 N2 ? ? ? 1_555 B A 42 N3 ? ? R G 45 R A 49 1_555 ? ? ? ? ? ? "G-A MISPAIR" ? ?
+hydrog49 hydrog ? B A 41 N6 ? ? ? 1_555 B U 84 O2 ? ? R A 48 R U 90 1_555 ? ? ? ? ? ? "REVERSED HOOGSTEEN" ? ?
+hydrog50 hydrog ? B A 41 N7 ? ? ? 1_555 B U 84 N3 ? ? R A 48 R U 90 1_555 ? ? ? ? ? ? "REVERSED HOOGSTEEN" ? ?
+hydrog51 hydrog ? B G 43 N1 ? ? ? 1_555 B U 83 O2 ? ? R G 50 R U 89 1_555 ? ? ? ? ? ? TYPE_28_PAIR ? ?
+hydrog52 hydrog ? B G 43 O6 ? ? ? 1_555 B U 83 N3 ? ? R G 50 R U 89 1_555 ? ? ? ? ? ? TYPE_28_PAIR ? ?
+hydrog53 hydrog ? B C 44 N3 ? ? ? 1_555 B G 82 N1 ? ? R C 51 R G 88 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog54 hydrog ? B C 44 N4 ? ? ? 1_555 B G 82 O6 ? ? R C 51 R G 88 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog55 hydrog ? B C 44 O2 ? ? ? 1_555 B G 82 N2 ? ? R C 51 R G 88 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog56 hydrog ? B C 45 N3 ? ? ? 1_555 B G 81 N1 ? ? R C 52 R G 87 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog57 hydrog ? B C 45 N4 ? ? ? 1_555 B G 81 O6 ? ? R C 52 R G 87 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog58 hydrog ? B C 45 O2 ? ? ? 1_555 B G 81 N2 ? ? R C 52 R G 87 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog59 hydrog ? B U 46 O2 ? ? ? 1_555 B C 48 N4 ? ? R U 53 R C 55 1_555 ? ? ? ? ? ? "U-C MISPAIR" ? ?
+hydrog60 hydrog ? B C 47 N4 ? ? ? 1_555 B A 76 N1 ? ? R C 54 R A 82 1_555 ? ? ? ? ? ? "C-A MISPAIR" ? ?
+hydrog61 hydrog ? B C 47 N3 ? ? ? 1_555 B G 80 N1 ? ? R C 54 R G 86 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog62 hydrog ? B C 47 N4 ? ? ? 1_555 B G 80 O6 ? ? R C 54 R G 86 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog63 hydrog ? B C 47 O2 ? ? ? 1_555 B G 80 N2 ? ? R C 54 R G 86 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog64 hydrog ? B C 48 N3 ? ? ? 1_555 B G 79 N1 ? ? R C 55 R G 85 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog65 hydrog ? B C 48 N4 ? ? ? 1_555 B G 79 O6 ? ? R C 55 R G 85 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog66 hydrog ? B C 48 O2 ? ? ? 1_555 B G 79 N2 ? ? R C 55 R G 85 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog67 hydrog ? B G 49 N1 ? ? ? 1_555 B C 78 N3 ? ? R G 56 R C 84 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog68 hydrog ? B G 49 N2 ? ? ? 1_555 B C 78 O2 ? ? R G 56 R C 84 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog69 hydrog ? B G 49 O6 ? ? ? 1_555 B C 78 N4 ? ? R G 56 R C 84 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog70 hydrog ? B G 50 N1 ? ? ? 1_555 B U 75 O2 ? ? R G 57 R U 81 1_555 ? ? ? ? ? ? TYPE_28_PAIR ? ?
+hydrog71 hydrog ? B G 50 O6 ? ? ? 1_555 B U 75 N3 ? ? R G 57 R U 81 1_555 ? ? ? ? ? ? TYPE_28_PAIR ? ?
+hydrog72 hydrog ? B C 51 N3 ? ? ? 1_555 B G 74 N1 ? ? R C 58 R G 80 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog73 hydrog ? B C 51 N4 ? ? ? 1_555 B G 74 O6 ? ? R C 58 R G 80 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog74 hydrog ? B C 51 O2 ? ? ? 1_555 B G 74 N2 ? ? R C 58 R G 80 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog75 hydrog ? B C 52 N3 ? ? ? 1_555 B G 73 N1 ? ? R C 59 R G 79 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog76 hydrog ? B C 52 N4 ? ? ? 1_555 B G 73 O6 ? ? R C 59 R G 79 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog77 hydrog ? B C 52 O2 ? ? ? 1_555 B G 73 N2 ? ? R C 59 R G 79 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog78 hydrog ? B U 53 N3 ? ? ? 1_555 B A 72 N1 ? ? R U 60 R A 78 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog79 hydrog ? B U 53 O4 ? ? ? 1_555 B A 72 N6 ? ? R U 60 R A 78 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog80 hydrog ? B A 54 N3 ? ? ? 1_555 B A 55 N6 ? ? R A 61 R A 62 1_555 ? ? ? ? ? ? "A-A MISPAIR" ? ?
+hydrog81 hydrog ? B A 54 N1 ? ? ? 1_555 B U 71 N3 ? ? R A 61 R U 77 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog82 hydrog ? B A 54 N6 ? ? ? 1_555 B U 71 O4 ? ? R A 61 R U 77 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog83 hydrog ? B A 56 N6 ? ? ? 1_555 B U 71 O2 ? ? R A 63 R U 77 1_555 ? ? ? ? ? ? "A-U PAIR" ? ?
+hydrog84 hydrog ? B C 57 N3 ? ? ? 1_555 B G 70 N1 ? ? R C 64 R G 76 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog85 hydrog ? B C 57 N4 ? ? ? 1_555 B G 70 O6 ? ? R C 64 R G 76 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog86 hydrog ? B C 57 O2 ? ? ? 1_555 B G 70 N2 ? ? R C 64 R G 76 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog87 hydrog ? B C 58 N3 ? ? ? 1_555 B G 69 N1 ? ? R C 65 R G 75 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog88 hydrog ? B C 58 N4 ? ? ? 1_555 B G 69 O6 ? ? R C 65 R G 75 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog89 hydrog ? B C 58 O2 ? ? ? 1_555 B G 69 N2 ? ? R C 65 R G 75 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog90 hydrog ? B C 86 N3 ? ? ? 1_555 C G 2 N1 ? ? R C 92 A G 2 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog91 hydrog ? B C 86 N4 ? ? ? 1_555 C G 2 O6 ? ? R C 92 A G 2 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog92 hydrog ? B C 86 O2 ? ? ? 1_555 C G 2 N2 ? ? R C 92 A G 2 1_555 ? ? ? ? ? ? WATSON-CRICK ? ?
+hydrog93 hydrog ? B G 88 N2 ? ? ? 1_555 B A 89 N1 ? ? R G 94 R A 95 1_555 ? ? ? ? ? ? "G-A MISPAIR" ? ?
+#
+loop_
+_struct_conn_type.id              
+_struct_conn_type.criteria        
+_struct_conn_type.reference       
+covale ? ?
+metalc ? ?
+hydrog "For hydrogen bonding between nucleic acid bases, donor to acceptor distance of 2.2 -3.5 Angstroms was used." ?
+mismat ? ?
+#
+_struct_sheet.id                   A
+_struct_sheet.type                 ?
+_struct_sheet.number_strands       4
+_struct_sheet.details              ?
+#
+loop_
+_struct_sheet_order.sheet_id         
+_struct_sheet_order.range_id_1       
+_struct_sheet_order.range_id_2       
+_struct_sheet_order.offset           
+_struct_sheet_order.sense            
+A 1 2 ? anti-parallel
+A 2 3 ? anti-parallel
+A 3 4 ? anti-parallel
+#
+loop_
+_struct_sheet_range.sheet_id                    
+_struct_sheet_range.id                          
+_struct_sheet_range.beg_label_comp_id           
+_struct_sheet_range.beg_label_asym_id           
+_struct_sheet_range.beg_label_seq_id            
+_struct_sheet_range.pdbx_beg_PDB_ins_code       
+_struct_sheet_range.end_label_comp_id           
+_struct_sheet_range.end_label_asym_id           
+_struct_sheet_range.end_label_seq_id            
+_struct_sheet_range.pdbx_end_PDB_ins_code       
+_struct_sheet_range.symmetry                    
+_struct_sheet_range.beg_auth_comp_id            
+_struct_sheet_range.beg_auth_asym_id            
+_struct_sheet_range.beg_auth_seq_id             
+_struct_sheet_range.end_auth_comp_id            
+_struct_sheet_range.end_auth_asym_id            
+_struct_sheet_range.end_auth_seq_id             
+A 1 ILE A 40 ? LEU A 44 ? ? ILE P 40 LEU P 44
+A 2 ALA A 55 ? PHE A 59 ? ? ALA P 55 PHE P 59
+A 3 THR A 11 ? ASN A 15 ? ? THR P 11 ASN P 15
+A 4 ARG A 83 ? TYR A 86 ? ? ARG P 83 TYR P 86
+#
+loop_
+_pdbx_struct_sheet_hbond.sheet_id                    
+_pdbx_struct_sheet_hbond.range_id_1                  
+_pdbx_struct_sheet_hbond.range_id_2                  
+_pdbx_struct_sheet_hbond.range_1_label_atom_id       
+_pdbx_struct_sheet_hbond.range_1_label_comp_id       
+_pdbx_struct_sheet_hbond.range_1_label_asym_id       
+_pdbx_struct_sheet_hbond.range_1_label_seq_id        
+_pdbx_struct_sheet_hbond.range_1_PDB_ins_code        
+_pdbx_struct_sheet_hbond.range_1_auth_atom_id        
+_pdbx_struct_sheet_hbond.range_1_auth_comp_id        
+_pdbx_struct_sheet_hbond.range_1_auth_asym_id        
+_pdbx_struct_sheet_hbond.range_1_auth_seq_id         
+_pdbx_struct_sheet_hbond.range_2_label_atom_id       
+_pdbx_struct_sheet_hbond.range_2_label_comp_id       
+_pdbx_struct_sheet_hbond.range_2_label_asym_id       
+_pdbx_struct_sheet_hbond.range_2_label_seq_id        
+_pdbx_struct_sheet_hbond.range_2_PDB_ins_code        
+_pdbx_struct_sheet_hbond.range_2_auth_atom_id        
+_pdbx_struct_sheet_hbond.range_2_auth_comp_id        
+_pdbx_struct_sheet_hbond.range_2_auth_asym_id        
+_pdbx_struct_sheet_hbond.range_2_auth_seq_id         
+A 1 2 N LEU A 44 ? N LEU P 44 O PHE A 56 ? O PHE P 56
+A 2 3 O ALA A 55 ? O ALA P 55 N ILE A 14 ? N ILE P 14
+A 3 4 N TYR A 13 ? N TYR P 13 O GLN A 85 ? O GLN P 85
+#
+_struct_site.id                       AC1
+_struct_site.details                  "BINDING SITE FOR RESIDUE MG R 1"
+_struct_site.pdbx_evidence_code       SOFTWARE
+#
+loop_
+_struct_site_gen.id                       
+_struct_site_gen.site_id                  
+_struct_site_gen.pdbx_num_res             
+_struct_site_gen.label_comp_id            
+_struct_site_gen.label_asym_id            
+_struct_site_gen.label_seq_id             
+_struct_site_gen.pdbx_auth_ins_code       
+_struct_site_gen.auth_comp_id             
+_struct_site_gen.auth_asym_id             
+_struct_site_gen.auth_seq_id              
+_struct_site_gen.label_atom_id            
+_struct_site_gen.label_alt_id             
+_struct_site_gen.symmetry                 
+_struct_site_gen.details                  
+1 AC1 7 HOH G . ? HOH A 3 . . 1_555 ?
+2 AC1 7 A B 40 ? A R 47 . . 1_555 ?
+3 AC1 7 A B 41 ? A R 48 . . 1_555 ?
+4 AC1 7 HOH F . ? HOH R 673 . . 1_555 ?
+5 AC1 7 HOH F . ? HOH R 674 . . 1_555 ?
+6 AC1 7 HOH F . ? HOH R 675 . . 1_555 ?
+7 AC1 7 HOH F . ? HOH R 676 . . 1_555 ?
+#
+_atom_sites.entry_id                        3UCU
+_atom_sites.Cartn_transform_axes            ?
+_atom_sites.fract_transf_matrix[1][1]       0.020372
+_atom_sites.fract_transf_matrix[1][2]       0.000000
+_atom_sites.fract_transf_matrix[1][3]       0.002227
+_atom_sites.fract_transf_matrix[2][1]       -0.000000
+_atom_sites.fract_transf_matrix[2][2]       0.022051
+_atom_sites.fract_transf_matrix[2][3]       0.000000
+_atom_sites.fract_transf_matrix[3][1]       0.000000
+_atom_sites.fract_transf_matrix[3][2]       -0.000000
+_atom_sites.fract_transf_matrix[3][3]       0.013023
+_atom_sites.fract_transf_vector[1]          0.00000
+_atom_sites.fract_transf_vector[2]          0.00000
+_atom_sites.fract_transf_vector[3]          0.00000
+#
+loop_
+_atom_type.symbol       
+N
+C
+O
+S
+P
+MG
+#
+loop_
+_atom_site.group_PDB                
+_atom_site.id                       
+_atom_site.type_symbol              
+_atom_site.label_atom_id            
+_atom_site.label_alt_id             
+_atom_site.label_comp_id            
+_atom_site.label_asym_id            
+_atom_site.label_entity_id          
+_atom_site.label_seq_id             
+_atom_site.pdbx_PDB_ins_code        
+_atom_site.Cartn_x                  
+_atom_site.Cartn_y                  
+_atom_site.Cartn_z                  
+_atom_site.occupancy                
+_atom_site.B_iso_or_equiv           
+_atom_site.Cartn_x_esd              
+_atom_site.Cartn_y_esd              
+_atom_site.Cartn_z_esd              
+_atom_site.occupancy_esd            
+_atom_site.B_iso_or_equiv_esd       
+_atom_site.pdbx_formal_charge       
+_atom_site.auth_seq_id              
+_atom_site.auth_comp_id             
+_atom_site.auth_asym_id             
+_atom_site.auth_atom_id             
+_atom_site.pdbx_PDB_model_num       
+_atom_site.pdbe_label_seq_id        
+ATOM 1 N N . ARG A 1 7 ? 3.282 29.355 -6.805 1.00 77.39 ? ? ? ? ? ? 7 ARG P N 1 7
+ATOM 2 C CA . ARG A 1 7 ? 3.842 27.969 -6.824 1.00 76.12 ? ? ? ? ? ? 7 ARG P CA 1 7
+ATOM 3 C C . ARG A 1 7 ? 5.170 27.792 -6.062 1.00 74.61 ? ? ? ? ? ? 7 ARG P C 1 7
+ATOM 4 O O . ARG A 1 7 ? 5.300 26.839 -5.293 1.00 74.64 ? ? ? ? ? ? 7 ARG P O 1 7
+ATOM 5 C CB . ARG A 1 7 ? 3.967 27.446 -8.260 1.00 76.94 ? ? ? ? ? ? 7 ARG P CB 1 7
+ATOM 6 C CG . ARG A 1 7 ? 2.734 26.712 -8.767 1.00 77.92 ? ? ? ? ? ? 7 ARG P CG 1 7
+ATOM 7 C CD . ARG A 1 7 ? 3.102 25.692 -9.840 1.00 78.78 ? ? ? ? ? ? 7 ARG P CD 1 7
+ATOM 8 N NE . ARG A 1 7 ? 4.202 24.827 -9.411 1.00 79.23 ? ? ? ? ? ? 7 ARG P NE 1 7
+ATOM 9 C CZ . ARG A 1 7 ? 4.780 23.898 -10.169 1.00 80.34 ? ? ? ? ? ? 7 ARG P CZ 1 7
+ATOM 10 N NH1 . ARG A 1 7 ? 4.370 23.689 -11.415 1.00 80.85 ? ? ? ? ? ? 7 ARG P NH1 1 7
+ATOM 11 N NH2 . ARG A 1 7 ? 5.774 23.173 -9.676 1.00 80.08 ? ? ? ? ? ? 7 ARG P NH2 1 7
+ATOM 12 N N . PRO A 1 8 ? 6.156 28.698 -6.267 1.00 73.28 ? ? ? ? ? ? 8 PRO P N 1 8
+ATOM 13 C CA . PRO A 1 8 ? 7.454 28.531 -5.598 1.00 72.17 ? ? ? ? ? ? 8 PRO P CA 1 8
+ATOM 14 C C . PRO A 1 8 ? 7.404 28.719 -4.080 1.00 71.22 ? ? ? ? ? ? 8 PRO P C 1 8
+ATOM 15 O O . PRO A 1 8 ? 6.475 29.336 -3.559 1.00 71.67 ? ? ? ? ? ? 8 PRO P O 1 8
+ATOM 16 C CB . PRO A 1 8 ? 8.317 29.623 -6.235 1.00 72.40 ? ? ? ? ? ? 8 PRO P CB 1 8
+ATOM 17 C CG . PRO A 1 8 ? 7.351 30.654 -6.669 1.00 73.06 ? ? ? ? ? ? 8 PRO P CG 1 8
+ATOM 18 C CD . PRO A 1 8 ? 6.155 29.890 -7.137 1.00 73.11 ? ? ? ? ? ? 8 PRO P CD 1 8
+ATOM 19 N N . ASN A 1 9 ? 8.414 28.190 -3.391 1.00 70.44 ? ? ? ? ? ? 9 ASN P N 1 9
+ATOM 20 C CA . ASN A 1 9 ? 8.463 28.184 -1.929 1.00 69.18 ? ? ? ? ? ? 9 ASN P CA 1 9
+ATOM 21 C C . ASN A 1 9 ? 9.904 28.146 -1.414 1.00 68.38 ? ? ? ? ? ? 9 ASN P C 1 9
+ATOM 22 O O . ASN A 1 9 ? 10.807 27.696 -2.122 1.00 69.28 ? ? ? ? ? ? 9 ASN P O 1 9
+ATOM 23 C CB . ASN A 1 9 ? 7.688 26.974 -1.393 1.00 69.51 ? ? ? ? ? ? 9 ASN P CB 1 9
+ATOM 24 C CG . ASN A 1 9 ? 7.174 27.177 0.021 1.00 69.76 ? ? ? ? ? ? 9 ASN P CG 1 9
+ATOM 25 O OD1 . ASN A 1 9 ? 7.804 27.848 0.839 1.00 71.77 ? ? ? ? ? ? 9 ASN P OD1 1 9
+ATOM 26 N ND2 . ASN A 1 9 ? 6.020 26.590 0.315 1.00 68.93 ? ? ? ? ? ? 9 ASN P ND2 1 9
+ATOM 27 N N . HIS A 1 10 ? 10.109 28.617 -0.184 1.00 66.82 ? ? ? ? ? ? 10 HIS P N 1 10
+ATOM 28 C CA . HIS A 1 10 ? 11.412 28.538 0.486 1.00 66.08 ? ? ? ? ? ? 10 HIS P CA 1 10
+ATOM 29 C C . HIS A 1 10 ? 11.863 27.090 0.668 1.00 65.03 ? ? ? ? ? ? 10 HIS P C 1 10
+ATOM 30 O O . HIS A 1 10 ? 13.062 26.797 0.685 1.00 64.70 ? ? ? ? ? ? 10 HIS P O 1 10
+ATOM 31 C CB . HIS A 1 10 ? 11.351 29.199 1.865 1.00 67.33 ? ? ? ? ? ? 10 HIS P CB 1 10
+ATOM 32 C CG . HIS A 1 10 ? 11.091 30.670 1.825 1.00 67.56 ? ? ? ? ? ? 10 HIS P CG 1 10
+ATOM 33 N ND1 . HIS A 1 10 ? 12.103 31.603 1.849 1.00 68.36 ? ? ? ? ? ? 10 HIS P ND1 1 10
+ATOM 34 C CD2 . HIS A 1 10 ? 9.933 31.370 1.779 1.00 68.42 ? ? ? ? ? ? 10 HIS P CD2 1 10
+ATOM 35 C CE1 . HIS A 1 10 ? 11.581 32.816 1.812 1.00 68.48 ? ? ? ? ? ? 10 HIS P CE1 1 10
+ATOM 36 N NE2 . HIS A 1 10 ? 10.267 32.703 1.768 1.00 68.45 ? ? ? ? ? ? 10 HIS P NE2 1 10
+ATOM 37 N N . THR A 1 11 ? 10.887 26.198 0.814 1.00 63.00 ? ? ? ? ? ? 11 THR P N 1 11
+ATOM 38 C CA . THR A 1 11 ? 11.134 24.790 1.084 1.00 60.82 ? ? ? ? ? ? 11 THR P CA 1 11
+ATOM 39 C C . THR A 1 11 ? 10.971 23.958 -0.184 1.00 59.43 ? ? ? ? ? ? 11 THR P C 1 11
+ATOM 40 O O . THR A 1 11 ? 10.107 24.239 -1.015 1.00 60.52 ? ? ? ? ? ? 11 THR P O 1 11
+ATOM 41 C CB . THR A 1 11 ? 10.176 24.268 2.176 1.00 61.19 ? ? ? ? ? ? 11 THR P CB 1 11
+ATOM 42 O OG1 . THR A 1 11 ? 10.174 25.178 3.283 1.00 61.69 ? ? ? ? ? ? 11 THR P OG1 1 11
+ATOM 43 C CG2 . THR A 1 11 ? 10.598 22.888 2.666 1.00 61.40 ? ? ? ? ? ? 11 THR P CG2 1 11
+ATOM 44 N N . ILE A 1 12 ? 11.819 22.943 -0.327 1.00 57.83 ? ? ? ? ? ? 12 ILE P N 1 12
+ATOM 45 C CA . ILE A 1 12 ? 11.712 21.984 -1.424 1.00 55.69 ? ? ? ? ? ? 12 ILE P CA 1 12
+ATOM 46 C C . ILE A 1 12 ? 11.417 20.580 -0.902 1.00 55.32 ? ? ? ? ? ? 12 ILE P C 1 12
+ATOM 47 O O . ILE A 1 12 ? 11.992 20.134 0.097 1.00 54.83 ? ? ? ? ? ? 12 ILE P O 1 12
+ATOM 48 C CB . ILE A 1 12 ? 12.966 21.974 -2.332 1.00 55.89 ? ? ? ? ? ? 12 ILE P CB 1 12
+ATOM 49 C CG1 . ILE A 1 12 ? 14.249 21.850 -1.499 1.00 55.80 ? ? ? ? ? ? 12 ILE P CG1 1 12
+ATOM 50 C CG2 . ILE A 1 12 ? 12.995 23.227 -3.206 1.00 55.63 ? ? ? ? ? ? 12 ILE P CG2 1 12
+ATOM 51 C CD1 . ILE A 1 12 ? 15.436 21.305 -2.266 1.00 56.47 ? ? ? ? ? ? 12 ILE P CD1 1 12
+ATOM 52 N N . TYR A 1 13 ? 10.503 19.900 -1.586 1.00 53.47 ? ? ? ? ? ? 13 TYR P N 1 13
+ATOM 53 C CA . TYR A 1 13 ? 10.067 18.570 -1.201 1.00 51.15 ? ? ? ? ? ? 13 TYR P CA 1 13
+ATOM 54 C C . TYR A 1 13 ? 10.810 17.526 -2.014 1.00 51.67 ? ? ? ? ? ? 13 TYR P C 1 13
+ATOM 55 O O . TYR A 1 13 ? 10.506 17.307 -3.189 1.00 52.90 ? ? ? ? ? ? 13 TYR P O 1 13
+ATOM 56 C CB . TYR A 1 13 ? 8.559 18.430 -1.407 1.00 50.24 ? ? ? ? ? ? 13 TYR P CB 1 13
+ATOM 57 C CG . TYR A 1 13 ? 7.995 17.085 -1.013 1.00 48.48 ? ? ? ? ? ? 13 TYR P CG 1 13
+ATOM 58 C CD1 . TYR A 1 13 ? 7.675 16.810 0.310 1.00 48.54 ? ? ? ? ? ? 13 TYR P CD1 1 13
+ATOM 59 C CD2 . TYR A 1 13 ? 7.772 16.095 -1.965 1.00 49.30 ? ? ? ? ? ? 13 TYR P CD2 1 13
+ATOM 60 C CE1 . TYR A 1 13 ? 7.156 15.581 0.683 1.00 50.28 ? ? ? ? ? ? 13 TYR P CE1 1 13
+ATOM 61 C CE2 . TYR A 1 13 ? 7.251 14.859 -1.605 1.00 50.24 ? ? ? ? ? ? 13 TYR P CE2 1 13
+ATOM 62 C CZ . TYR A 1 13 ? 6.943 14.610 -0.278 1.00 50.26 ? ? ? ? ? ? 13 TYR P CZ 1 13
+ATOM 63 O OH . TYR A 1 13 ? 6.426 13.392 0.097 1.00 51.27 ? ? ? ? ? ? 13 TYR P OH 1 13
+ATOM 64 N N . ILE A 1 14 ? 11.790 16.891 -1.380 1.00 52.72 ? ? ? ? ? ? 14 ILE P N 1 14
+ATOM 65 C CA . ILE A 1 14 ? 12.554 15.824 -2.020 1.00 53.08 ? ? ? ? ? ? 14 ILE P CA 1 14
+ATOM 66 C C . ILE A 1 14 ? 11.854 14.493 -1.781 1.00 54.93 ? ? ? ? ? ? 14 ILE P C 1 14
+ATOM 67 O O . ILE A 1 14 ? 11.422 14.189 -0.665 1.00 54.75 ? ? ? ? ? ? 14 ILE P O 1 14
+ATOM 68 C CB . ILE A 1 14 ? 14.018 15.793 -1.539 1.00 50.75 ? ? ? ? ? ? 14 ILE P CB 1 14
+ATOM 69 C CG1 . ILE A 1 14 ? 14.691 17.129 -1.849 1.00 49.83 ? ? ? ? ? ? 14 ILE P CG1 1 14
+ATOM 70 C CG2 . ILE A 1 14 ? 14.786 14.670 -2.221 1.00 50.96 ? ? ? ? ? ? 14 ILE P CG2 1 14
+ATOM 71 C CD1 . ILE A 1 14 ? 15.762 17.515 -0.872 1.00 51.18 ? ? ? ? ? ? 14 ILE P CD1 1 14
+ATOM 72 N N . ASN A 1 15 ? 11.749 13.714 -2.851 1.00 56.95 ? ? ? ? ? ? 15 ASN P N 1 15
+ATOM 73 C CA . ASN A 1 15 ? 10.951 12.501 -2.872 1.00 60.17 ? ? ? ? ? ? 15 ASN P CA 1 15
+ATOM 74 C C . ASN A 1 15 ? 11.800 11.318 -3.327 1.00 60.77 ? ? ? ? ? ? 15 ASN P C 1 15
+ATOM 75 O O . ASN A 1 15 ? 12.890 11.509 -3.876 1.00 62.14 ? ? ? ? ? ? 15 ASN P O 1 15
+ATOM 76 C CB . ASN A 1 15 ? 9.773 12.710 -3.831 1.00 63.33 ? ? ? ? ? ? 15 ASN P CB 1 15
+ATOM 77 C CG . ASN A 1 15 ? 8.558 11.882 -3.469 1.00 66.30 ? ? ? ? ? ? 15 ASN P CG 1 15
+ATOM 78 O OD1 . ASN A 1 15 ? 7.895 11.324 -4.348 1.00 68.07 ? ? ? ? ? ? 15 ASN P OD1 1 15
+ATOM 79 N ND2 . ASN A 1 15 ? 8.248 11.806 -2.178 1.00 66.31 ? ? ? ? ? ? 15 ASN P ND2 1 15
+ATOM 80 N N . ASN A 1 16 ? 11.303 10.104 -3.092 1.00 59.64 ? ? ? ? ? ? 16 ASN P N 1 16
+ATOM 81 C CA . ASN A 1 16 ? 11.931 8.883 -3.602 1.00 60.22 ? ? ? ? ? ? 16 ASN P CA 1 16
+ATOM 82 C C . ASN A 1 16 ? 13.369 8.685 -3.083 1.00 60.60 ? ? ? ? ? ? 16 ASN P C 1 16
+ATOM 83 O O . ASN A 1 16 ? 14.333 8.496 -3.867 1.00 62.95 ? ? ? ? ? ? 16 ASN P O 1 16
+ATOM 84 C CB . ASN A 1 16 ? 11.875 8.863 -5.143 1.00 59.98 ? ? ? ? ? ? 16 ASN P CB 1 16
+ATOM 85 C CG . ASN A 1 16 ? 12.281 7.527 -5.734 1.00 59.13 ? ? ? ? ? ? 16 ASN P CG 1 16
+ATOM 86 O OD1 . ASN A 1 16 ? 11.670 6.497 -5.452 1.00 58.94 ? ? ? ? ? ? 16 ASN P OD1 1 16
+ATOM 87 N ND2 . ASN A 1 16 ? 13.318 7.540 -6.566 1.00 58.95 ? ? ? ? ? ? 16 ASN P ND2 1 16
+ATOM 88 N N . LEU A 1 17 ? 13.500 8.729 -1.751 1.00 59.36 ? ? ? ? ? ? 17 LEU P N 1 17
+ATOM 89 C CA . LEU A 1 17 ? 14.815 8.588 -1.120 1.00 57.68 ? ? ? ? ? ? 17 LEU P CA 1 17
+ATOM 90 C C . LEU A 1 17 ? 15.016 7.195 -0.544 1.00 58.55 ? ? ? ? ? ? 17 LEU P C 1 17
+ATOM 91 O O . LEU A 1 17 ? 14.056 6.541 -0.131 1.00 58.44 ? ? ? ? ? ? 17 LEU P O 1 17
+ATOM 92 C CB . LEU A 1 17 ? 14.993 9.624 -0.009 1.00 54.86 ? ? ? ? ? ? 17 LEU P CB 1 17
+ATOM 93 C CG . LEU A 1 17 ? 15.024 11.105 -0.383 1.00 54.27 ? ? ? ? ? ? 17 LEU P CG 1 17
+ATOM 94 C CD1 . LEU A 1 17 ? 14.809 11.960 0.857 1.00 53.68 ? ? ? ? ? ? 17 LEU P CD1 1 17
+ATOM 95 C CD2 . LEU A 1 17 ? 16.327 11.467 -1.075 1.00 53.69 ? ? ? ? ? ? 17 LEU P CD2 1 17
+ATOM 96 N N . ASN A 1 18 ? 16.272 6.752 -0.523 1.00 59.90 ? ? ? ? ? ? 18 ASN P N 1 18
+ATOM 97 C CA . ASN A 1 18 ? 16.646 5.501 0.123 1.00 60.60 ? ? ? ? ? ? 18 ASN P CA 1 18
+ATOM 98 C C . ASN A 1 18 ? 16.255 5.552 1.595 1.00 62.35 ? ? ? ? ? ? 18 ASN P C 1 18
+ATOM 99 O O . ASN A 1 18 ? 16.767 6.371 2.362 1.00 62.63 ? ? ? ? ? ? 18 ASN P O 1 18
+ATOM 100 C CB . ASN A 1 18 ? 18.149 5.251 -0.034 1.00 61.17 ? ? ? ? ? ? 18 ASN P CB 1 18
+ATOM 101 C CG . ASN A 1 18 ? 18.556 3.824 0.318 1.00 61.79 ? ? ? ? ? ? 18 ASN P CG 1 18
+ATOM 102 O OD1 . ASN A 1 18 ? 17.827 3.093 0.995 1.00 62.04 ? ? ? ? ? ? 18 ASN P OD1 1 18
+ATOM 103 N ND2 . ASN A 1 18 ? 19.738 3.425 -0.141 1.00 61.43 ? ? ? ? ? ? 18 ASN P ND2 1 18
+ATOM 104 N N . GLU A 1 19 ? 15.333 4.675 1.976 1.00 64.29 ? ? ? ? ? ? 19 GLU P N 1 19
+ATOM 105 C CA . GLU A 1 19 ? 14.754 4.686 3.317 1.00 64.71 ? ? ? ? ? ? 19 GLU P CA 1 19
+ATOM 106 C C . GLU A 1 19 ? 15.668 4.026 4.346 1.00 65.51 ? ? ? ? ? ? 19 GLU P C 1 19
+ATOM 107 O O . GLU A 1 19 ? 15.414 4.101 5.552 1.00 66.45 ? ? ? ? ? ? 19 GLU P O 1 19
+ATOM 108 C CB . GLU A 1 19 ? 13.382 4.011 3.302 1.00 64.85 ? ? ? ? ? ? 19 GLU P CB 1 19
+ATOM 109 C CG . GLU A 1 19 ? 12.405 4.625 2.305 1.00 66.67 ? ? ? ? ? ? 19 GLU P CG 1 19
+ATOM 110 C CD . GLU A 1 19 ? 11.296 3.672 1.902 1.00 68.11 ? ? ? ? ? ? 19 GLU P CD 1 19
+ATOM 111 O OE1 . GLU A 1 19 ? 10.483 3.295 2.773 1.00 68.88 ? ? ? ? ? ? 19 GLU P OE1 1 19
+ATOM 112 O OE2 . GLU A 1 19 ? 11.233 3.305 0.709 1.00 69.92 ? ? ? ? ? ? 19 GLU P OE2 1 19
+ATOM 113 N N . LYS A 1 20 ? 16.737 3.395 3.864 1.00 66.19 ? ? ? ? ? ? 20 LYS P N 1 20
+ATOM 114 C CA . LYS A 1 20 ? 17.672 2.671 4.726 1.00 66.48 ? ? ? ? ? ? 20 LYS P CA 1 20
+ATOM 115 C C . LYS A 1 20 ? 18.696 3.579 5.407 1.00 66.60 ? ? ? ? ? ? 20 LYS P C 1 20
+ATOM 116 O O . LYS A 1 20 ? 19.346 3.172 6.373 1.00 66.83 ? ? ? ? ? ? 20 LYS P O 1 20
+ATOM 117 C CB . LYS A 1 20 ? 18.375 1.557 3.945 1.00 66.85 ? ? ? ? ? ? 20 LYS P CB 1 20
+ATOM 118 C CG . LYS A 1 20 ? 17.452 0.418 3.544 1.00 69.82 ? ? ? ? ? ? 20 LYS P CG 1 20
+ATOM 119 C CD . LYS A 1 20 ? 18.193 -0.907 3.474 1.00 72.14 ? ? ? ? ? ? 20 LYS P CD 1 20
+ATOM 120 C CE . LYS A 1 20 ? 17.218 -2.078 3.535 1.00 73.89 ? ? ? ? ? ? 20 LYS P CE 1 20
+ATOM 121 N NZ . LYS A 1 20 ? 17.905 -3.370 3.828 1.00 74.59 ? ? ? ? ? ? 20 LYS P NZ 1 20
+ATOM 122 N N . ILE A 1 21 ? 18.826 4.806 4.908 1.00 66.63 ? ? ? ? ? ? 21 ILE P N 1 21
+ATOM 123 C CA . ILE A 1 21 ? 19.771 5.776 5.463 1.00 67.18 ? ? ? ? ? ? 21 ILE P CA 1 21
+ATOM 124 C C . ILE A 1 21 ? 19.315 6.224 6.848 1.00 67.73 ? ? ? ? ? ? 21 ILE P C 1 21
+ATOM 125 O O . ILE A 1 21 ? 18.141 6.538 7.050 1.00 67.09 ? ? ? ? ? ? 21 ILE P O 1 21
+ATOM 126 C CB . ILE A 1 21 ? 19.937 7.035 4.553 1.00 66.89 ? ? ? ? ? ? 21 ILE P CB 1 21
+ATOM 127 C CG1 . ILE A 1 21 ? 19.962 6.669 3.061 1.00 66.21 ? ? ? ? ? ? 21 ILE P CG1 1 21
+ATOM 128 C CG2 . ILE A 1 21 ? 21.169 7.851 4.959 1.00 67.31 ? ? ? ? ? ? 21 ILE P CG2 1 21
+ATOM 129 C CD1 . ILE A 1 21 ? 21.055 5.705 2.649 1.00 67.59 ? ? ? ? ? ? 21 ILE P CD1 1 21
+ATOM 130 N N . LYS A 1 22 ? 20.246 6.244 7.797 1.00 70.10 ? ? ? ? ? ? 22 LYS P N 1 22
+ATOM 131 C CA . LYS A 1 22 ? 19.963 6.749 9.136 1.00 72.14 ? ? ? ? ? ? 22 LYS P CA 1 22
+ATOM 132 C C . LYS A 1 22 ? 19.669 8.247 9.097 1.00 72.02 ? ? ? ? ? ? 22 LYS P C 1 22
+ATOM 133 O O . LYS A 1 22 ? 20.360 9.011 8.414 1.00 72.88 ? ? ? ? ? ? 22 LYS P O 1 22
+ATOM 134 C CB . LYS A 1 22 ? 21.121 6.452 10.095 1.00 73.72 ? ? ? ? ? ? 22 LYS P CB 1 22
+ATOM 135 C CG . LYS A 1 22 ? 21.105 5.048 10.685 1.00 75.74 ? ? ? ? ? ? 22 LYS P CG 1 22
+ATOM 136 C CD . LYS A 1 22 ? 21.957 4.974 11.948 1.00 77.58 ? ? ? ? ? ? 22 LYS P CD 1 22
+ATOM 137 C CE . LYS A 1 22 ? 21.768 3.651 12.675 1.00 78.80 ? ? ? ? ? ? 22 LYS P CE 1 22
+ATOM 138 N NZ . LYS A 1 22 ? 22.372 3.667 14.040 1.00 79.25 ? ? ? ? ? ? 22 LYS P NZ 1 22
+ATOM 139 N N . LYS A 1 23 ? 18.632 8.646 9.831 1.00 71.68 ? ? ? ? ? ? 23 LYS P N 1 23
+ATOM 140 C CA . LYS A 1 23 ? 18.194 10.041 9.936 1.00 71.22 ? ? ? ? ? ? 23 LYS P CA 1 23
+ATOM 141 C C . LYS A 1 23 ? 19.358 11.042 10.014 1.00 70.30 ? ? ? ? ? ? 23 LYS P C 1 23
+ATOM 142 O O . LYS A 1 23 ? 19.318 12.117 9.383 1.00 70.36 ? ? ? ? ? ? 23 LYS P O 1 23
+ATOM 143 C CB . LYS A 1 23 ? 17.264 10.196 11.149 1.00 72.38 ? ? ? ? ? ? 23 LYS P CB 1 23
+ATOM 144 C CG . LYS A 1 23 ? 16.655 11.578 11.342 1.00 73.48 ? ? ? ? ? ? 23 LYS P CG 1 23
+ATOM 145 C CD . LYS A 1 23 ? 15.606 11.566 12.447 1.00 74.43 ? ? ? ? ? ? 23 LYS P CD 1 23
+ATOM 146 C CE . LYS A 1 23 ? 15.165 12.983 12.792 1.00 75.99 ? ? ? ? ? ? 23 LYS P CE 1 23
+ATOM 147 N NZ . LYS A 1 23 ? 13.907 13.014 13.592 1.00 75.30 ? ? ? ? ? ? 23 LYS P NZ 1 23
+ATOM 148 N N . ASP A 1 24 ? 20.391 10.672 10.780 1.00 69.62 ? ? ? ? ? ? 24 ASP P N 1 24
+ATOM 149 C CA . ASP A 1 24 ? 21.549 11.539 11.002 1.00 68.79 ? ? ? ? ? ? 24 ASP P CA 1 24
+ATOM 150 C C . ASP A 1 24 ? 22.321 11.767 9.710 1.00 67.58 ? ? ? ? ? ? 24 ASP P C 1 24
+ATOM 151 O O . ASP A 1 24 ? 22.617 12.908 9.356 1.00 66.30 ? ? ? ? ? ? 24 ASP P O 1 24
+ATOM 152 C CB . ASP A 1 24 ? 22.481 10.937 12.062 1.00 70.00 ? ? ? ? ? ? 24 ASP P CB 1 24
+ATOM 153 C CG . ASP A 1 24 ? 21.732 10.415 13.272 1.00 70.21 ? ? ? ? ? ? 24 ASP P CG 1 24
+ATOM 154 O OD1 . ASP A 1 24 ? 21.278 11.236 14.097 1.00 69.90 ? ? ? ? ? ? 24 ASP P OD1 1 24
+ATOM 155 O OD2 . ASP A 1 24 ? 21.602 9.178 13.398 1.00 71.39 ? ? ? ? ? ? 24 ASP P OD2 1 24
+ATOM 156 N N . GLU A 1 25 ? 22.637 10.675 9.016 1.00 66.70 ? ? ? ? ? ? 25 GLU P N 1 25
+ATOM 157 C CA . GLU A 1 25 ? 23.394 10.734 7.769 1.00 67.02 ? ? ? ? ? ? 25 GLU P CA 1 25
+ATOM 158 C C . GLU A 1 25 ? 22.588 11.404 6.661 1.00 65.66 ? ? ? ? ? ? 25 GLU P C 1 25
+ATOM 159 O O . GLU A 1 25 ? 23.133 12.180 5.873 1.00 63.20 ? ? ? ? ? ? 25 GLU P O 1 25
+ATOM 160 C CB . GLU A 1 25 ? 23.836 9.334 7.330 1.00 70.58 ? ? ? ? ? ? 25 GLU P CB 1 25
+ATOM 161 C CG . GLU A 1 25 ? 24.819 8.646 8.277 1.00 75.58 ? ? ? ? ? ? 25 GLU P CG 1 25
+ATOM 162 C CD . GLU A 1 25 ? 26.128 9.411 8.450 1.00 78.43 ? ? ? ? ? ? 25 GLU P CD 1 25
+ATOM 163 O OE1 . GLU A 1 25 ? 26.717 9.841 7.433 1.00 79.52 ? ? ? ? ? ? 25 GLU P OE1 1 25
+ATOM 164 O OE2 . GLU A 1 25 ? 26.572 9.575 9.608 1.00 80.01 ? ? ? ? ? ? 25 GLU P OE2 1 25
+ATOM 165 N N . LEU A 1 26 ? 21.290 11.106 6.620 1.00 64.01 ? ? ? ? ? ? 26 LEU P N 1 26
+ATOM 166 C CA . LEU A 1 26 ? 20.392 11.665 5.615 1.00 63.38 ? ? ? ? ? ? 26 LEU P CA 1 26
+ATOM 167 C C . LEU A 1 26 ? 20.417 13.198 5.622 1.00 63.82 ? ? ? ? ? ? 26 LEU P C 1 26
+ATOM 168 O O . LEU A 1 26 ? 20.719 13.815 4.598 1.00 62.41 ? ? ? ? ? ? 26 LEU P O 1 26
+ATOM 169 C CB . LEU A 1 26 ? 18.969 11.115 5.796 1.00 62.60 ? ? ? ? ? ? 26 LEU P CB 1 26
+ATOM 170 C CG . LEU A 1 26 ? 17.858 11.397 4.770 1.00 61.96 ? ? ? ? ? ? 26 LEU P CG 1 26
+ATOM 171 C CD1 . LEU A 1 26 ? 18.338 11.310 3.321 1.00 61.38 ? ? ? ? ? ? 26 LEU P CD1 1 26
+ATOM 172 C CD2 . LEU A 1 26 ? 16.693 10.441 4.996 1.00 61.28 ? ? ? ? ? ? 26 LEU P CD2 1 26
+ATOM 173 N N . LYS A 1 27 ? 20.127 13.802 6.775 1.00 64.51 ? ? ? ? ? ? 27 LYS P N 1 27
+ATOM 174 C CA . LYS A 1 27 ? 20.209 15.258 6.925 1.00 66.21 ? ? ? ? ? ? 27 LYS P CA 1 27
+ATOM 175 C C . LYS A 1 27 ? 21.602 15.751 6.537 1.00 67.46 ? ? ? ? ? ? 27 LYS P C 1 27
+ATOM 176 O O . LYS A 1 27 ? 21.742 16.634 5.684 1.00 67.87 ? ? ? ? ? ? 27 LYS P O 1 27
+ATOM 177 C CB . LYS A 1 27 ? 19.886 15.694 8.359 1.00 66.81 ? ? ? ? ? ? 27 LYS P CB 1 27
+ATOM 178 C CG . LYS A 1 27 ? 18.460 15.421 8.808 1.00 68.72 ? ? ? ? ? ? 27 LYS P CG 1 27
+ATOM 179 C CD . LYS A 1 27 ? 18.100 16.247 10.033 1.00 69.14 ? ? ? ? ? ? 27 LYS P CD 1 27
+ATOM 180 C CE . LYS A 1 27 ? 16.707 15.901 10.539 1.00 70.46 ? ? ? ? ? ? 27 LYS P CE 1 27
+ATOM 181 N NZ . LYS A 1 27 ? 16.140 16.984 11.392 1.00 70.41 ? ? ? ? ? ? 27 LYS P NZ 1 27
+ATOM 182 N N . LYS A 1 28 ? 22.617 15.148 7.160 1.00 67.07 ? ? ? ? ? ? 28 LYS P N 1 28
+ATOM 183 C CA . LYS A 1 28 ? 24.022 15.482 6.944 1.00 65.95 ? ? ? ? ? ? 28 LYS P CA 1 28
+ATOM 184 C C . LYS A 1 28 ? 24.361 15.546 5.452 1.00 63.96 ? ? ? ? ? ? 28 LYS P C 1 28
+ATOM 185 O O . LYS A 1 28 ? 24.862 16.563 4.970 1.00 62.21 ? ? ? ? ? ? 28 LYS P O 1 28
+ATOM 186 C CB . LYS A 1 28 ? 24.910 14.456 7.657 1.00 68.03 ? ? ? ? ? ? 28 LYS P CB 1 28
+ATOM 187 C CG . LYS A 1 28 ? 26.276 14.965 8.094 1.00 69.74 ? ? ? ? ? ? 28 LYS P CG 1 28
+ATOM 188 C CD . LYS A 1 28 ? 27.231 13.799 8.328 1.00 71.03 ? ? ? ? ? ? 28 LYS P CD 1 28
+ATOM 189 C CE . LYS A 1 28 ? 28.535 14.239 8.983 1.00 71.65 ? ? ? ? ? ? 28 LYS P CE 1 28
+ATOM 190 N NZ . LYS A 1 28 ? 28.434 14.278 10.470 1.00 71.45 ? ? ? ? ? ? 28 LYS P NZ 1 28
+ATOM 191 N N . SER A 1 29 ? 24.062 14.465 4.732 1.00 62.97 ? ? ? ? ? ? 29 SER P N 1 29
+ATOM 192 C CA . SER A 1 29 ? 24.323 14.378 3.292 1.00 62.46 ? ? ? ? ? ? 29 SER P CA 1 29
+ATOM 193 C C . SER A 1 29 ? 23.541 15.422 2.495 1.00 63.18 ? ? ? ? ? ? 29 SER P C 1 29
+ATOM 194 O O . SER A 1 29 ? 24.109 16.091 1.634 1.00 65.29 ? ? ? ? ? ? 29 SER P O 1 29
+ATOM 195 C CB . SER A 1 29 ? 24.013 12.978 2.765 1.00 61.42 ? ? ? ? ? ? 29 SER P CB 1 29
+ATOM 196 O OG . SER A 1 29 ? 24.614 11.985 3.572 1.00 61.08 ? ? ? ? ? ? 29 SER P OG 1 29
+ATOM 197 N N . LEU A 1 30 ? 22.248 15.563 2.787 1.00 62.10 ? ? ? ? ? ? 30 LEU P N 1 30
+ATOM 198 C CA . LEU A 1 30 ? 21.409 16.567 2.125 1.00 60.90 ? ? ? ? ? ? 30 LEU P CA 1 30
+ATOM 199 C C . LEU A 1 30 ? 21.945 17.979 2.342 1.00 61.95 ? ? ? ? ? ? 30 LEU P C 1 30
+ATOM 200 O O . LEU A 1 30 ? 21.902 18.811 1.435 1.00 60.80 ? ? ? ? ? ? 30 LEU P O 1 30
+ATOM 201 C CB . LEU A 1 30 ? 19.957 16.473 2.603 1.00 57.93 ? ? ? ? ? ? 30 LEU P CB 1 30
+ATOM 202 C CG . LEU A 1 30 ? 19.133 15.272 2.128 1.00 55.91 ? ? ? ? ? ? 30 LEU P CG 1 30
+ATOM 203 C CD1 . LEU A 1 30 ? 17.927 15.085 3.022 1.00 56.03 ? ? ? ? ? ? 30 LEU P CD1 1 30
+ATOM 204 C CD2 . LEU A 1 30 ? 18.708 15.406 0.675 1.00 54.70 ? ? ? ? ? ? 30 LEU P CD2 1 30
+ATOM 205 N N . HIS A 1 31 ? 22.454 18.234 3.544 1.00 64.40 ? ? ? ? ? ? 31 HIS P N 1 31
+ATOM 206 C CA . HIS A 1 31 ? 23.106 19.499 3.862 1.00 66.73 ? ? ? ? ? ? 31 HIS P CA 1 31
+ATOM 207 C C . HIS A 1 31 ? 24.406 19.639 3.078 1.00 67.17 ? ? ? ? ? ? 31 HIS P C 1 31
+ATOM 208 O O . HIS A 1 31 ? 24.723 20.717 2.572 1.00 67.39 ? ? ? ? ? ? 31 HIS P O 1 31
+ATOM 209 C CB . HIS A 1 31 ? 23.382 19.600 5.364 1.00 68.23 ? ? ? ? ? ? 31 HIS P CB 1 31
+ATOM 210 C CG . HIS A 1 31 ? 23.744 20.978 5.820 1.00 70.27 ? ? ? ? ? ? 31 HIS P CG 1 31
+ATOM 211 N ND1 . HIS A 1 31 ? 22.812 21.870 6.306 1.00 71.21 ? ? ? ? ? ? 31 HIS P ND1 1 31
+ATOM 212 C CD2 . HIS A 1 31 ? 24.936 21.620 5.862 1.00 71.57 ? ? ? ? ? ? 31 HIS P CD2 1 31
+ATOM 213 C CE1 . HIS A 1 31 ? 23.413 23.002 6.626 1.00 72.11 ? ? ? ? ? ? 31 HIS P CE1 1 31
+ATOM 214 N NE2 . HIS A 1 31 ? 24.703 22.876 6.367 1.00 72.30 ? ? ? ? ? ? 31 HIS P NE2 1 31
+ATOM 215 N N . ALA A 1 32 ? 25.144 18.537 2.969 1.00 66.61 ? ? ? ? ? ? 32 ALA P N 1 32
+ATOM 216 C CA . ALA A 1 32 ? 26.419 18.518 2.258 1.00 67.14 ? ? ? ? ? ? 32 ALA P CA 1 32
+ATOM 217 C C . ALA A 1 32 ? 26.266 18.676 0.740 1.00 67.12 ? ? ? ? ? ? 32 ALA P C 1 32
+ATOM 218 O O . ALA A 1 32 ? 27.247 18.914 0.036 1.00 68.42 ? ? ? ? ? ? 32 ALA P O 1 32
+ATOM 219 C CB . ALA A 1 32 ? 27.182 17.242 2.587 1.00 67.01 ? ? ? ? ? ? 32 ALA P CB 1 32
+ATOM 220 N N . ILE A 1 33 ? 25.038 18.551 0.245 1.00 66.22 ? ? ? ? ? ? 33 ILE P N 1 33
+ATOM 221 C CA . ILE A 1 33 ? 24.779 18.577 -1.192 1.00 66.21 ? ? ? ? ? ? 33 ILE P CA 1 33
+ATOM 222 C C . ILE A 1 33 ? 24.008 19.825 -1.634 1.00 65.72 ? ? ? ? ? ? 33 ILE P C 1 33
+ATOM 223 O O . ILE A 1 33 ? 24.216 20.325 -2.741 1.00 65.62 ? ? ? ? ? ? 33 ILE P O 1 33
+ATOM 224 C CB . ILE A 1 33 ? 24.048 17.279 -1.653 1.00 67.78 ? ? ? ? ? ? 33 ILE P CB 1 33
+ATOM 225 C CG1 . ILE A 1 33 ? 24.893 16.028 -1.351 1.00 69.97 ? ? ? ? ? ? 33 ILE P CG1 1 33
+ATOM 226 C CG2 . ILE A 1 33 ? 23.676 17.329 -3.132 1.00 67.72 ? ? ? ? ? ? 33 ILE P CG2 1 33
+ATOM 227 C CD1 . ILE A 1 33 ? 26.364 16.077 -1.816 1.00 72.17 ? ? ? ? ? ? 33 ILE P CD1 1 33
+ATOM 228 N N . PHE A 1 34 ? 23.136 20.329 -0.764 1.00 65.46 ? ? ? ? ? ? 34 PHE P N 1 34
+ATOM 229 C CA . PHE A 1 34 ? 22.262 21.453 -1.108 1.00 64.57 ? ? ? ? ? ? 34 PHE P CA 1 34
+ATOM 230 C C . PHE A 1 34 ? 22.737 22.822 -0.613 1.00 65.26 ? ? ? ? ? ? 34 PHE P C 1 34
+ATOM 231 O O . PHE A 1 34 ? 22.223 23.850 -1.063 1.00 65.25 ? ? ? ? ? ? 34 PHE P O 1 34
+ATOM 232 C CB . PHE A 1 34 ? 20.830 21.192 -0.622 1.00 62.75 ? ? ? ? ? ? 34 PHE P CB 1 34
+ATOM 233 C CG . PHE A 1 34 ? 20.070 20.209 -1.468 1.00 60.53 ? ? ? ? ? ? 34 PHE P CG 1 34
+ATOM 234 C CD1 . PHE A 1 34 ? 19.527 20.596 -2.691 1.00 59.24 ? ? ? ? ? ? 34 PHE P CD1 1 34
+ATOM 235 C CD2 . PHE A 1 34 ? 19.892 18.899 -1.041 1.00 59.15 ? ? ? ? ? ? 34 PHE P CD2 1 34
+ATOM 236 C CE1 . PHE A 1 34 ? 18.825 19.691 -3.479 1.00 57.79 ? ? ? ? ? ? 34 PHE P CE1 1 34
+ATOM 237 C CE2 . PHE A 1 34 ? 19.189 17.987 -1.823 1.00 58.66 ? ? ? ? ? ? 34 PHE P CE2 1 34
+ATOM 238 C CZ . PHE A 1 34 ? 18.654 18.385 -3.044 1.00 57.78 ? ? ? ? ? ? 34 PHE P CZ 1 34
+ATOM 239 N N . SER A 1 35 ? 23.711 22.838 0.298 1.00 66.13 ? ? ? ? ? ? 35 SER P N 1 35
+ATOM 240 C CA . SER A 1 35 ? 24.194 24.093 0.898 1.00 67.08 ? ? ? ? ? ? 35 SER P CA 1 35
+ATOM 241 C C . SER A 1 35 ? 24.891 25.020 -0.097 1.00 65.70 ? ? ? ? ? ? 35 SER P C 1 35
+ATOM 242 O O . SER A 1 35 ? 25.042 26.215 0.164 1.00 66.47 ? ? ? ? ? ? 35 SER P O 1 35
+ATOM 243 C CB . SER A 1 35 ? 25.109 23.824 2.099 1.00 68.50 ? ? ? ? ? ? 35 SER P CB 1 35
+ATOM 244 O OG . SER A 1 35 ? 26.304 23.176 1.701 1.00 71.12 ? ? ? ? ? ? 35 SER P OG 1 35
+ATOM 245 N N . ARG A 1 36 ? 25.302 24.467 -1.236 1.00 64.91 ? ? ? ? ? ? 36 ARG P N 1 36
+ATOM 246 C CA . ARG A 1 36 ? 25.956 25.244 -2.286 1.00 64.08 ? ? ? ? ? ? 36 ARG P CA 1 36
+ATOM 247 C C . ARG A 1 36 ? 24.983 26.130 -3.070 1.00 63.63 ? ? ? ? ? ? 36 ARG P C 1 36
+ATOM 248 O O . ARG A 1 36 ? 25.395 26.887 -3.952 1.00 64.13 ? ? ? ? ? ? 36 ARG P O 1 36
+ATOM 249 C CB . ARG A 1 36 ? 26.751 24.332 -3.232 1.00 65.69 ? ? ? ? ? ? 36 ARG P CB 1 36
+ATOM 250 C CG . ARG A 1 36 ? 25.968 23.181 -3.854 1.00 67.06 ? ? ? ? ? ? 36 ARG P CG 1 36
+ATOM 251 C CD . ARG A 1 36 ? 26.789 22.490 -4.938 1.00 68.94 ? ? ? ? ? ? 36 ARG P CD 1 36
+ATOM 252 N NE . ARG A 1 36 ? 26.791 23.249 -6.190 1.00 70.61 ? ? ? ? ? ? 36 ARG P NE 1 36
+ATOM 253 C CZ . ARG A 1 36 ? 26.169 22.870 -7.306 1.00 71.80 ? ? ? ? ? ? 36 ARG P CZ 1 36
+ATOM 254 N NH1 . ARG A 1 36 ? 26.229 23.632 -8.390 1.00 71.50 ? ? ? ? ? ? 36 ARG P NH1 1 36
+ATOM 255 N NH2 . ARG A 1 36 ? 25.495 21.728 -7.350 1.00 72.57 ? ? ? ? ? ? 36 ARG P NH2 1 36
+ATOM 256 N N . PHE A 1 37 ? 23.697 26.033 -2.744 1.00 62.13 ? ? ? ? ? ? 37 PHE P N 1 37
+ATOM 257 C CA . PHE A 1 37 ? 22.666 26.814 -3.422 1.00 60.59 ? ? ? ? ? ? 37 PHE P CA 1 37
+ATOM 258 C C . PHE A 1 37 ? 22.213 28.016 -2.599 1.00 62.21 ? ? ? ? ? ? 37 PHE P C 1 37
+ATOM 259 O O . PHE A 1 37 ? 21.757 29.017 -3.154 1.00 62.93 ? ? ? ? ? ? 37 PHE P O 1 37
+ATOM 260 C CB . PHE A 1 37 ? 21.470 25.929 -3.775 1.00 57.92 ? ? ? ? ? ? 37 PHE P CB 1 37
+ATOM 261 C CG . PHE A 1 37 ? 21.791 24.843 -4.759 1.00 56.27 ? ? ? ? ? ? 37 PHE P CG 1 37
+ATOM 262 C CD1 . PHE A 1 37 ? 21.945 25.133 -6.110 1.00 55.82 ? ? ? ? ? ? 37 PHE P CD1 1 37
+ATOM 263 C CD2 . PHE A 1 37 ? 21.939 23.527 -4.337 1.00 55.93 ? ? ? ? ? ? 37 PHE P CD2 1 37
+ATOM 264 C CE1 . PHE A 1 37 ? 22.242 24.130 -7.023 1.00 55.73 ? ? ? ? ? ? 37 PHE P CE1 1 37
+ATOM 265 C CE2 . PHE A 1 37 ? 22.234 22.515 -5.246 1.00 55.14 ? ? ? ? ? ? 37 PHE P CE2 1 37
+ATOM 266 C CZ . PHE A 1 37 ? 22.386 22.818 -6.590 1.00 55.40 ? ? ? ? ? ? 37 PHE P CZ 1 37
+ATOM 267 N N . GLY A 1 38 ? 22.351 27.911 -1.279 1.00 63.47 ? ? ? ? ? ? 38 GLY P N 1 38
+ATOM 268 C CA . GLY A 1 38 ? 21.933 28.963 -0.356 1.00 64.83 ? ? ? ? ? ? 38 GLY P CA 1 38
+ATOM 269 C C . GLY A 1 38 ? 21.995 28.505 1.087 1.00 66.45 ? ? ? ? ? ? 38 GLY P C 1 38
+ATOM 270 O O . GLY A 1 38 ? 22.129 27.311 1.364 1.00 66.85 ? ? ? ? ? ? 38 GLY P O 1 38
+ATOM 271 N N . GLN A 1 39 ? 21.897 29.460 2.007 1.00 68.03 ? ? ? ? ? ? 39 GLN P N 1 39
+ATOM 272 C CA . GLN A 1 39 ? 21.910 29.174 3.442 1.00 69.07 ? ? ? ? ? ? 39 GLN P CA 1 39
+ATOM 273 C C . GLN A 1 39 ? 20.644 28.413 3.830 1.00 68.49 ? ? ? ? ? ? 39 GLN P C 1 39
+ATOM 274 O O . GLN A 1 39 ? 19.545 28.752 3.383 1.00 69.87 ? ? ? ? ? ? 39 GLN P O 1 39
+ATOM 275 C CB . GLN A 1 39 ? 22.028 30.471 4.252 1.00 70.75 ? ? ? ? ? ? 39 GLN P CB 1 39
+ATOM 276 C CG . GLN A 1 39 ? 23.298 31.299 3.975 1.00 74.26 ? ? ? ? ? ? 39 GLN P CG 1 39
+ATOM 277 C CD . GLN A 1 39 ? 23.243 32.107 2.670 1.00 74.93 ? ? ? ? ? ? 39 GLN P CD 1 39
+ATOM 278 O OE1 . GLN A 1 39 ? 22.190 32.250 2.044 1.00 75.34 ? ? ? ? ? ? 39 GLN P OE1 1 39
+ATOM 279 N NE2 . GLN A 1 39 ? 24.389 32.640 2.266 1.00 75.22 ? ? ? ? ? ? 39 GLN P NE2 1 39
+ATOM 280 N N . ILE A 1 40 ? 20.804 27.380 4.650 1.00 65.88 ? ? ? ? ? ? 40 ILE P N 1 40
+ATOM 281 C CA . ILE A 1 40 ? 19.679 26.533 5.034 1.00 65.76 ? ? ? ? ? ? 40 ILE P CA 1 40
+ATOM 282 C C . ILE A 1 40 ? 19.252 26.794 6.475 1.00 67.11 ? ? ? ? ? ? 40 ILE P C 1 40
+ATOM 283 O O . ILE A 1 40 ? 20.080 26.790 7.389 1.00 67.67 ? ? ? ? ? ? 40 ILE P O 1 40
+ATOM 284 C CB . ILE A 1 40 ? 19.998 25.032 4.816 1.00 64.90 ? ? ? ? ? ? 40 ILE P CB 1 40
+ATOM 285 C CG1 . ILE A 1 40 ? 20.232 24.754 3.326 1.00 64.01 ? ? ? ? ? ? 40 ILE P CG1 1 40
+ATOM 286 C CG2 . ILE A 1 40 ? 18.876 24.143 5.364 1.00 63.92 ? ? ? ? ? ? 40 ILE P CG2 1 40
+ATOM 287 C CD1 . ILE A 1 40 ? 21.022 23.496 3.039 1.00 63.60 ? ? ? ? ? ? 40 ILE P CD1 1 40
+ATOM 288 N N . LEU A 1 41 ? 17.955 27.030 6.661 1.00 68.35 ? ? ? ? ? ? 41 LEU P N 1 41
+ATOM 289 C CA . LEU A 1 41 ? 17.369 27.212 7.987 1.00 70.51 ? ? ? ? ? ? 41 LEU P CA 1 41
+ATOM 290 C C . LEU A 1 41 ? 17.447 25.908 8.782 1.00 71.19 ? ? ? ? ? ? 41 LEU P C 1 41
+ATOM 291 O O . LEU A 1 41 ? 18.153 25.826 9.789 1.00 72.12 ? ? ? ? ? ? 41 LEU P O 1 41
+ATOM 292 C CB . LEU A 1 41 ? 15.913 27.684 7.872 1.00 71.76 ? ? ? ? ? ? 41 LEU P CB 1 41
+ATOM 293 C CG . LEU A 1 41 ? 15.569 29.180 7.807 1.00 72.63 ? ? ? ? ? ? 41 LEU P CG 1 41
+ATOM 294 C CD1 . LEU A 1 41 ? 16.293 29.912 6.691 1.00 72.37 ? ? ? ? ? ? 41 LEU P CD1 1 41
+ATOM 295 C CD2 . LEU A 1 41 ? 14.063 29.363 7.656 1.00 73.26 ? ? ? ? ? ? 41 LEU P CD2 1 41
+ATOM 296 N N . ASP A 1 42 ? 16.721 24.896 8.314 1.00 70.65 ? ? ? ? ? ? 42 ASP P N 1 42
+ATOM 297 C CA . ASP A 1 42 ? 16.770 23.559 8.891 1.00 70.54 ? ? ? ? ? ? 42 ASP P CA 1 42
+ATOM 298 C C . ASP A 1 42 ? 16.354 22.551 7.830 1.00 69.26 ? ? ? ? ? ? 42 ASP P C 1 42
+ATOM 299 O O . ASP A 1 42 ? 15.696 22.907 6.852 1.00 69.42 ? ? ? ? ? ? 42 ASP P O 1 42
+ATOM 300 C CB . ASP A 1 42 ? 15.847 23.459 10.115 1.00 72.25 ? ? ? ? ? ? 42 ASP P CB 1 42
+ATOM 301 C CG . ASP A 1 42 ? 16.182 22.270 11.017 1.00 73.64 ? ? ? ? ? ? 42 ASP P CG 1 42
+ATOM 302 O OD1 . ASP A 1 42 ? 17.379 22.044 11.311 1.00 74.48 ? ? ? ? ? ? 42 ASP P OD1 1 42
+ATOM 303 O OD2 . ASP A 1 42 ? 15.240 21.566 11.443 1.00 72.67 ? ? ? ? ? ? 42 ASP P OD2 1 42
+ATOM 304 N N . ILE A 1 43 ? 16.755 21.297 8.015 1.00 67.83 ? ? ? ? ? ? 43 ILE P N 1 43
+ATOM 305 C CA . ILE A 1 43 ? 16.316 20.217 7.143 1.00 66.49 ? ? ? ? ? ? 43 ILE P CA 1 43
+ATOM 306 C C . ILE A 1 43 ? 15.410 19.268 7.923 1.00 66.22 ? ? ? ? ? ? 43 ILE P C 1 43
+ATOM 307 O O . ILE A 1 43 ? 15.827 18.669 8.916 1.00 66.44 ? ? ? ? ? ? 43 ILE P O 1 43
+ATOM 308 C CB . ILE A 1 43 ? 17.506 19.458 6.509 1.00 66.63 ? ? ? ? ? ? 43 ILE P CB 1 43
+ATOM 309 C CG1 . ILE A 1 43 ? 18.313 20.399 5.609 1.00 66.94 ? ? ? ? ? ? 43 ILE P CG1 1 43
+ATOM 310 C CG2 . ILE A 1 43 ? 17.013 18.246 5.718 1.00 66.60 ? ? ? ? ? ? 43 ILE P CG2 1 43
+ATOM 311 C CD1 . ILE A 1 43 ? 19.555 19.774 4.999 1.00 67.64 ? ? ? ? ? ? 43 ILE P CD1 1 43
+ATOM 312 N N . LEU A 1 44 ? 14.166 19.151 7.470 1.00 66.04 ? ? ? ? ? ? 44 LEU P N 1 44
+ATOM 313 C CA . LEU A 1 44 ? 13.185 18.297 8.122 1.00 66.09 ? ? ? ? ? ? 44 LEU P CA 1 44
+ATOM 314 C C . LEU A 1 44 ? 13.199 16.900 7.517 1.00 65.09 ? ? ? ? ? ? 44 LEU P C 1 44
+ATOM 315 O O . LEU A 1 44 ? 12.866 16.717 6.346 1.00 65.42 ? ? ? ? ? ? 44 LEU P O 1 44
+ATOM 316 C CB . LEU A 1 44 ? 11.781 18.910 8.023 1.00 68.08 ? ? ? ? ? ? 44 LEU P CB 1 44
+ATOM 317 C CG . LEU A 1 44 ? 11.299 19.984 9.013 1.00 69.60 ? ? ? ? ? ? 44 LEU P CG 1 44
+ATOM 318 C CD1 . LEU A 1 44 ? 11.063 19.395 10.405 1.00 71.01 ? ? ? ? ? ? 44 LEU P CD1 1 44
+ATOM 319 C CD2 . LEU A 1 44 ? 12.223 21.203 9.084 1.00 69.42 ? ? ? ? ? ? 44 LEU P CD2 1 44
+ATOM 320 N N . VAL A 1 45 ? 13.601 15.923 8.324 1.00 63.60 ? ? ? ? ? ? 45 VAL P N 1 45
+ATOM 321 C CA . VAL A 1 45 ? 13.624 14.522 7.916 1.00 62.92 ? ? ? ? ? ? 45 VAL P CA 1 45
+ATOM 322 C C . VAL A 1 45 ? 13.030 13.667 9.032 1.00 63.65 ? ? ? ? ? ? 45 VAL P C 1 45
+ATOM 323 O O . VAL A 1 45 ? 13.415 13.797 10.193 1.00 65.60 ? ? ? ? ? ? 45 VAL P O 1 45
+ATOM 324 C CB . VAL A 1 45 ? 15.067 14.041 7.588 1.00 61.93 ? ? ? ? ? ? 45 VAL P CB 1 45
+ATOM 325 C CG1 . VAL A 1 45 ? 15.094 12.549 7.326 1.00 61.28 ? ? ? ? ? ? 45 VAL P CG1 1 45
+ATOM 326 C CG2 . VAL A 1 45 ? 15.631 14.786 6.391 1.00 61.76 ? ? ? ? ? ? 45 VAL P CG2 1 45
+ATOM 327 N N . SER A 1 46 ? 12.083 12.804 8.677 1.00 64.18 ? ? ? ? ? ? 46 SER P N 1 46
+ATOM 328 C CA . SER A 1 46 ? 11.467 11.892 9.636 1.00 64.69 ? ? ? ? ? ? 46 SER P CA 1 46
+ATOM 329 C C . SER A 1 46 ? 11.265 10.524 8.994 1.00 65.06 ? ? ? ? ? ? 46 SER P C 1 46
+ATOM 330 O O . SER A 1 46 ? 11.017 10.431 7.791 1.00 65.32 ? ? ? ? ? ? 46 SER P O 1 46
+ATOM 331 C CB . SER A 1 46 ? 10.138 12.459 10.132 1.00 65.49 ? ? ? ? ? ? 46 SER P CB 1 46
+ATOM 332 O OG . SER A 1 46 ? 9.620 11.684 11.196 1.00 66.95 ? ? ? ? ? ? 46 SER P OG 1 46
+ATOM 333 N N . ARG A 1 47 ? 11.372 9.468 9.795 1.00 66.39 ? ? ? ? ? ? 47 ARG P N 1 47
+ATOM 334 C CA . ARG A 1 47 ? 11.339 8.099 9.267 1.00 67.79 ? ? ? ? ? ? 47 ARG P CA 1 47
+ATOM 335 C C . ARG A 1 47 ? 10.098 7.293 9.660 1.00 68.16 ? ? ? ? ? ? 47 ARG P C 1 47
+ATOM 336 O O . ARG A 1 47 ? 10.147 6.061 9.729 1.00 69.44 ? ? ? ? ? ? 47 ARG P O 1 47
+ATOM 337 C CB . ARG A 1 47 ? 12.621 7.346 9.641 1.00 68.54 ? ? ? ? ? ? 47 ARG P CB 1 47
+ATOM 338 C CG . ARG A 1 47 ? 13.850 7.809 8.870 1.00 70.75 ? ? ? ? ? ? 47 ARG P CG 1 47
+ATOM 339 C CD . ARG A 1 47 ? 15.100 7.063 9.303 1.00 71.97 ? ? ? ? ? ? 47 ARG P CD 1 47
+ATOM 340 N NE . ARG A 1 47 ? 15.141 5.702 8.772 1.00 73.06 ? ? ? ? ? ? 47 ARG P NE 1 47
+ATOM 341 C CZ . ARG A 1 47 ? 16.059 4.796 9.094 1.00 74.07 ? ? ? ? ? ? 47 ARG P CZ 1 47
+ATOM 342 N NH1 . ARG A 1 47 ? 17.026 5.093 9.956 1.00 74.03 ? ? ? ? ? ? 47 ARG P NH1 1 47
+ATOM 343 N NH2 . ARG A 1 47 ? 16.010 3.585 8.552 1.00 74.22 ? ? ? ? ? ? 47 ARG P NH2 1 47
+ATOM 344 N N . SER A 1 48 ? 8.990 7.987 9.905 1.00 67.76 ? ? ? ? ? ? 48 SER P N 1 48
+ATOM 345 C CA . SER A 1 48 ? 7.708 7.329 10.147 1.00 66.74 ? ? ? ? ? ? 48 SER P CA 1 48
+ATOM 346 C C . SER A 1 48 ? 7.106 6.881 8.820 1.00 67.60 ? ? ? ? ? ? 48 SER P C 1 48
+ATOM 347 O O . SER A 1 48 ? 7.478 7.395 7.766 1.00 68.37 ? ? ? ? ? ? 48 SER P O 1 48
+ATOM 348 C CB . SER A 1 48 ? 6.749 8.262 10.891 1.00 66.41 ? ? ? ? ? ? 48 SER P CB 1 48
+ATOM 349 O OG . SER A 1 48 ? 6.604 9.499 10.219 1.00 64.76 ? ? ? ? ? ? 48 SER P OG 1 48
+ATOM 350 N N . LEU A 1 49 ? 6.178 5.926 8.878 1.00 68.66 ? ? ? ? ? ? 49 LEU P N 1 49
+ATOM 351 C CA . LEU A 1 49 ? 5.533 5.365 7.682 1.00 68.33 ? ? ? ? ? ? 49 LEU P CA 1 49
+ATOM 352 C C . LEU A 1 49 ? 5.019 6.444 6.726 1.00 68.08 ? ? ? ? ? ? 49 LEU P C 1 49
+ATOM 353 O O . LEU A 1 49 ? 5.067 6.285 5.507 1.00 67.25 ? ? ? ? ? ? 49 LEU P O 1 49
+ATOM 354 C CB . LEU A 1 49 ? 4.383 4.439 8.090 1.00 68.60 ? ? ? ? ? ? 49 LEU P CB 1 49
+ATOM 355 C CG . LEU A 1 49 ? 3.707 3.606 6.996 1.00 69.29 ? ? ? ? ? ? 49 LEU P CG 1 49
+ATOM 356 C CD1 . LEU A 1 49 ? 4.452 2.304 6.765 1.00 69.11 ? ? ? ? ? ? 49 LEU P CD1 1 49
+ATOM 357 C CD2 . LEU A 1 49 ? 2.254 3.329 7.353 1.00 70.29 ? ? ? ? ? ? 49 LEU P CD2 1 49
+ATOM 358 N N . LYS A 1 50 ? 4.539 7.539 7.303 1.00 69.37 ? ? ? ? ? ? 50 LYS P N 1 50
+ATOM 359 C CA . LYS A 1 50 ? 3.982 8.657 6.556 1.00 70.58 ? ? ? ? ? ? 50 LYS P CA 1 50
+ATOM 360 C C . LYS A 1 50 ? 5.077 9.592 6.033 1.00 69.87 ? ? ? ? ? ? 50 LYS P C 1 50
+ATOM 361 O O . LYS A 1 50 ? 4.845 10.381 5.116 1.00 69.14 ? ? ? ? ? ? 50 LYS P O 1 50
+ATOM 362 C CB . LYS A 1 50 ? 3.025 9.433 7.468 1.00 72.95 ? ? ? ? ? ? 50 LYS P CB 1 50
+ATOM 363 C CG . LYS A 1 50 ? 1.919 10.186 6.754 1.00 75.40 ? ? ? ? ? ? 50 LYS P CG 1 50
+ATOM 364 C CD . LYS A 1 50 ? 1.063 10.945 7.753 1.00 76.49 ? ? ? ? ? ? 50 LYS P CD 1 50
+ATOM 365 C CE . LYS A 1 50 ? -0.052 11.706 7.059 1.00 77.39 ? ? ? ? ? ? 50 LYS P CE 1 50
+ATOM 366 N NZ . LYS A 1 50 ? -0.787 12.572 8.019 1.00 78.07 ? ? ? ? ? ? 50 LYS P NZ 1 50
+ATOM 367 N N . MET A 1 51 ? 6.270 9.495 6.614 1.00 68.96 ? ? ? ? ? ? 51 MET P N 1 51
+ATOM 368 C CA . MET A 1 51 ? 7.346 10.447 6.331 1.00 69.07 ? ? ? ? ? ? 51 MET P CA 1 51
+ATOM 369 C C . MET A 1 51 ? 8.580 9.842 5.655 1.00 68.01 ? ? ? ? ? ? 51 MET P C 1 51
+ATOM 370 O O . MET A 1 51 ? 9.479 10.574 5.239 1.00 68.98 ? ? ? ? ? ? 51 MET P O 1 51
+ATOM 371 C CB . MET A 1 51 ? 7.755 11.167 7.617 1.00 70.99 ? ? ? ? ? ? 51 MET P CB 1 51
+ATOM 372 C CG . MET A 1 51 ? 6.684 12.088 8.186 1.00 72.46 ? ? ? ? ? ? 51 MET P CG 1 51
+ATOM 373 S SD . MET A 1 51 ? 6.282 13.463 7.091 1.00 75.65 ? ? ? ? ? ? 51 MET P SD 1 51
+ATOM 374 C CE . MET A 1 51 ? 7.805 14.414 7.159 1.00 74.62 ? ? ? ? ? ? 51 MET P CE 1 51
+ATOM 375 N N . ARG A 1 52 ? 8.606 8.515 5.538 1.00 65.85 ? ? ? ? ? ? 52 ARG P N 1 52
+ATOM 376 C CA . ARG A 1 52 ? 9.739 7.783 4.964 1.00 63.78 ? ? ? ? ? ? 52 ARG P CA 1 52
+ATOM 377 C C . ARG A 1 52 ? 10.053 8.171 3.523 1.00 62.25 ? ? ? ? ? ? 52 ARG P C 1 52
+ATOM 378 O O . ARG A 1 52 ? 9.146 8.426 2.730 1.00 63.55 ? ? ? ? ? ? 52 ARG P O 1 52
+ATOM 379 C CB . ARG A 1 52 ? 9.489 6.277 5.051 1.00 65.46 ? ? ? ? ? ? 52 ARG P CB 1 52
+ATOM 380 C CG . ARG A 1 52 ? 9.761 5.709 6.425 1.00 68.07 ? ? ? ? ? ? 52 ARG P CG 1 52
+ATOM 381 C CD . ARG A 1 52 ? 9.093 4.366 6.656 1.00 68.80 ? ? ? ? ? ? 52 ARG P CD 1 52
+ATOM 382 N NE . ARG A 1 52 ? 9.089 4.040 8.082 1.00 69.38 ? ? ? ? ? ? 52 ARG P NE 1 52
+ATOM 383 C CZ . ARG A 1 52 ? 8.948 2.818 8.586 1.00 69.95 ? ? ? ? ? ? 52 ARG P CZ 1 52
+ATOM 384 N NH1 . ARG A 1 52 ? 8.797 1.769 7.787 1.00 70.80 ? ? ? ? ? ? 52 ARG P NH1 1 52
+ATOM 385 N NH2 . ARG A 1 52 ? 8.962 2.643 9.900 1.00 71.50 ? ? ? ? ? ? 52 ARG P NH2 1 52
+ATOM 386 N N . GLY A 1 53 ? 11.345 8.216 3.203 1.00 59.84 ? ? ? ? ? ? 53 GLY P N 1 53
+ATOM 387 C CA . GLY A 1 53 ? 11.820 8.506 1.846 1.00 57.52 ? ? ? ? ? ? 53 GLY P CA 1 53
+ATOM 388 C C . GLY A 1 53 ? 11.596 9.933 1.380 1.00 55.96 ? ? ? ? ? ? 53 GLY P C 1 53
+ATOM 389 O O . GLY A 1 53 ? 11.617 10.211 0.182 1.00 56.35 ? ? ? ? ? ? 53 GLY P O 1 53
+ATOM 390 N N . GLN A 1 54 ? 11.395 10.841 2.331 1.00 55.63 ? ? ? ? ? ? 54 GLN P N 1 54
+ATOM 391 C CA . GLN A 1 54 ? 11.038 12.225 2.026 1.00 55.28 ? ? ? ? ? ? 54 GLN P CA 1 54
+ATOM 392 C C . GLN A 1 54 ? 11.924 13.212 2.780 1.00 53.06 ? ? ? ? ? ? 54 GLN P C 1 54
+ATOM 393 O O . GLN A 1 54 ? 12.485 12.875 3.823 1.00 51.99 ? ? ? ? ? ? 54 GLN P O 1 54
+ATOM 394 C CB . GLN A 1 54 ? 9.564 12.472 2.368 1.00 56.99 ? ? ? ? ? ? 54 GLN P CB 1 54
+ATOM 395 C CG . GLN A 1 54 ? 8.597 11.512 1.686 1.00 58.64 ? ? ? ? ? ? 54 GLN P CG 1 54
+ATOM 396 C CD . GLN A 1 54 ? 7.285 11.371 2.427 1.00 60.02 ? ? ? ? ? ? 54 GLN P CD 1 54
+ATOM 397 O OE1 . GLN A 1 54 ? 6.492 12.312 2.499 1.00 62.25 ? ? ? ? ? ? 54 GLN P OE1 1 54
+ATOM 398 N NE2 . GLN A 1 54 ? 7.041 10.186 2.973 1.00 59.54 ? ? ? ? ? ? 54 GLN P NE2 1 54
+ATOM 399 N N . ALA A 1 55 ? 12.043 14.428 2.248 1.00 51.60 ? ? ? ? ? ? 55 ALA P N 1 55
+ATOM 400 C CA . ALA A 1 55 ? 12.855 15.476 2.874 1.00 50.86 ? ? ? ? ? ? 55 ALA P CA 1 55
+ATOM 401 C C . ALA A 1 55 ? 12.371 16.890 2.566 1.00 51.02 ? ? ? ? ? ? 55 ALA P C 1 55
+ATOM 402 O O . ALA A 1 55 ? 12.000 17.207 1.434 1.00 51.77 ? ? ? ? ? ? 55 ALA P O 1 55
+ATOM 403 C CB . ALA A 1 55 ? 14.317 15.328 2.479 1.00 50.85 ? ? ? ? ? ? 55 ALA P CB 1 55
+ATOM 404 N N . PHE A 1 56 ? 12.394 17.736 3.592 1.00 51.48 ? ? ? ? ? ? 56 PHE P N 1 56
+ATOM 405 C CA . PHE A 1 56 ? 12.088 19.151 3.449 1.00 52.22 ? ? ? ? ? ? 56 PHE P CA 1 56
+ATOM 406 C C . PHE A 1 56 ? 13.344 19.973 3.710 1.00 51.54 ? ? ? ? ? ? 56 PHE P C 1 56
+ATOM 407 O O . PHE A 1 56 ? 13.870 19.971 4.825 1.00 53.03 ? ? ? ? ? ? 56 PHE P O 1 56
+ATOM 408 C CB . PHE A 1 56 ? 10.980 19.565 4.424 1.00 53.24 ? ? ? ? ? ? 56 PHE P CB 1 56
+ATOM 409 C CG . PHE A 1 56 ? 9.632 18.989 4.094 1.00 55.48 ? ? ? ? ? ? 56 PHE P CG 1 56
+ATOM 410 C CD1 . PHE A 1 56 ? 9.241 17.754 4.609 1.00 56.61 ? ? ? ? ? ? 56 PHE P CD1 1 56
+ATOM 411 C CD2 . PHE A 1 56 ? 8.748 19.685 3.275 1.00 55.66 ? ? ? ? ? ? 56 PHE P CD2 1 56
+ATOM 412 C CE1 . PHE A 1 56 ? 7.992 17.216 4.304 1.00 56.49 ? ? ? ? ? ? 56 PHE P CE1 1 56
+ATOM 413 C CE2 . PHE A 1 56 ? 7.498 19.158 2.964 1.00 55.83 ? ? ? ? ? ? 56 PHE P CE2 1 56
+ATOM 414 C CZ . PHE A 1 56 ? 7.119 17.920 3.482 1.00 56.89 ? ? ? ? ? ? 56 PHE P CZ 1 56
+ATOM 415 N N . VAL A 1 57 ? 13.829 20.660 2.678 1.00 49.70 ? ? ? ? ? ? 57 VAL P N 1 57
+ATOM 416 C CA . VAL A 1 57 ? 14.964 21.566 2.821 1.00 49.92 ? ? ? ? ? ? 57 VAL P CA 1 57
+ATOM 417 C C . VAL A 1 57 ? 14.473 23.008 2.748 1.00 51.04 ? ? ? ? ? ? 57 VAL P C 1 57
+ATOM 418 O O . VAL A 1 57 ? 14.019 23.462 1.696 1.00 50.95 ? ? ? ? ? ? 57 VAL P O 1 57
+ATOM 419 C CB . VAL A 1 57 ? 16.049 21.320 1.745 1.00 49.85 ? ? ? ? ? ? 57 VAL P CB 1 57
+ATOM 420 C CG1 . VAL A 1 57 ? 17.189 22.317 1.895 1.00 50.58 ? ? ? ? ? ? 57 VAL P CG1 1 57
+ATOM 421 C CG2 . VAL A 1 57 ? 16.586 19.904 1.840 1.00 49.81 ? ? ? ? ? ? 57 VAL P CG2 1 57
+ATOM 422 N N . ILE A 1 58 ? 14.564 23.717 3.871 1.00 51.65 ? ? ? ? ? ? 58 ILE P N 1 58
+ATOM 423 C CA . ILE A 1 58 ? 14.102 25.102 3.954 1.00 52.28 ? ? ? ? ? ? 58 ILE P CA 1 58
+ATOM 424 C C . ILE A 1 58 ? 15.261 26.072 3.744 1.00 53.40 ? ? ? ? ? ? 58 ILE P C 1 58
+ATOM 425 O O . ILE A 1 58 ? 16.260 26.027 4.463 1.00 55.73 ? ? ? ? ? ? 58 ILE P O 1 58
+ATOM 426 C CB . ILE A 1 58 ? 13.404 25.408 5.304 1.00 51.18 ? ? ? ? ? ? 58 ILE P CB 1 58
+ATOM 427 C CG1 . ILE A 1 58 ? 12.446 24.278 5.697 1.00 50.88 ? ? ? ? ? ? 58 ILE P CG1 1 58
+ATOM 428 C CG2 . ILE A 1 58 ? 12.662 26.741 5.230 1.00 52.22 ? ? ? ? ? ? 58 ILE P CG2 1 58
+ATOM 429 C CD1 . ILE A 1 58 ? 11.880 24.403 7.103 1.00 51.34 ? ? ? ? ? ? 58 ILE P CD1 1 58
+ATOM 430 N N . PHE A 1 59 ? 15.116 26.948 2.756 1.00 55.12 ? ? ? ? ? ? 59 PHE P N 1 59
+ATOM 431 C CA . PHE A 1 59 ? 16.137 27.943 2.443 1.00 57.70 ? ? ? ? ? ? 59 PHE P CA 1 59
+ATOM 432 C C . PHE A 1 59 ? 15.776 29.311 3.011 1.00 59.81 ? ? ? ? ? ? 59 PHE P C 1 59
+ATOM 433 O O . PHE A 1 59 ? 14.606 29.583 3.290 1.00 59.92 ? ? ? ? ? ? 59 PHE P O 1 59
+ATOM 434 C CB . PHE A 1 59 ? 16.315 28.059 0.927 1.00 56.34 ? ? ? ? ? ? 59 PHE P CB 1 59
+ATOM 435 C CG . PHE A 1 59 ? 16.958 26.859 0.293 1.00 55.66 ? ? ? ? ? ? 59 PHE P CG 1 59
+ATOM 436 C CD1 . PHE A 1 59 ? 18.343 26.772 0.185 1.00 55.51 ? ? ? ? ? ? 59 PHE P CD1 1 59
+ATOM 437 C CD2 . PHE A 1 59 ? 16.181 25.822 -0.210 1.00 55.01 ? ? ? ? ? ? 59 PHE P CD2 1 59
+ATOM 438 C CE1 . PHE A 1 59 ? 18.945 25.663 -0.408 1.00 55.30 ? ? ? ? ? ? 59 PHE P CE1 1 59
+ATOM 439 C CE2 . PHE A 1 59 ? 16.771 24.712 -0.808 1.00 55.15 ? ? ? ? ? ? 59 PHE P CE2 1 59
+ATOM 440 C CZ . PHE A 1 59 ? 18.157 24.631 -0.905 1.00 54.59 ? ? ? ? ? ? 59 PHE P CZ 1 59
+ATOM 441 N N . LYS A 1 60 ? 16.786 30.166 3.181 1.00 62.92 ? ? ? ? ? ? 60 LYS P N 1 60
+ATOM 442 C CA . LYS A 1 60 ? 16.564 31.576 3.498 1.00 64.82 ? ? ? ? ? ? 60 LYS P CA 1 60
+ATOM 443 C C . LYS A 1 60 ? 15.810 32.248 2.362 1.00 65.30 ? ? ? ? ? ? 60 LYS P C 1 60
+ATOM 444 O O . LYS A 1 60 ? 14.854 32.985 2.593 1.00 65.12 ? ? ? ? ? ? 60 LYS P O 1 60
+ATOM 445 C CB . LYS A 1 60 ? 17.887 32.312 3.729 1.00 67.05 ? ? ? ? ? ? 60 LYS P CB 1 60
+ATOM 446 C CG . LYS A 1 60 ? 18.379 32.322 5.167 1.00 68.90 ? ? ? ? ? ? 60 LYS P CG 1 60
+ATOM 447 C CD . LYS A 1 60 ? 19.448 33.392 5.363 1.00 71.74 ? ? ? ? ? ? 60 LYS P CD 1 60
+ATOM 448 C CE . LYS A 1 60 ? 20.033 33.373 6.776 1.00 73.73 ? ? ? ? ? ? 60 LYS P CE 1 60
+ATOM 449 N NZ . LYS A 1 60 ? 21.063 32.308 6.968 1.00 74.60 ? ? ? ? ? ? 60 LYS P NZ 1 60
+ATOM 450 N N . GLU A 1 61 ? 16.239 31.971 1.134 1.00 66.25 ? ? ? ? ? ? 61 GLU P N 1 61
+ATOM 451 C CA . GLU A 1 61 ? 15.692 32.627 -0.047 1.00 66.70 ? ? ? ? ? ? 61 GLU P CA 1 61
+ATOM 452 C C . GLU A 1 61 ? 15.037 31.640 -1.006 1.00 66.84 ? ? ? ? ? ? 61 GLU P C 1 61
+ATOM 453 O O . GLU A 1 61 ? 15.579 30.564 -1.267 1.00 67.07 ? ? ? ? ? ? 61 GLU P O 1 61
+ATOM 454 C CB . GLU A 1 61 ? 16.794 33.409 -0.758 1.00 67.58 ? ? ? ? ? ? 61 GLU P CB 1 61
+ATOM 455 C CG . GLU A 1 61 ? 17.429 34.489 0.112 1.00 69.78 ? ? ? ? ? ? 61 GLU P CG 1 61
+ATOM 456 C CD . GLU A 1 61 ? 18.677 35.086 -0.502 1.00 70.73 ? ? ? ? ? ? 61 GLU P CD 1 61
+ATOM 457 O OE1 . GLU A 1 61 ? 19.654 35.309 0.246 1.00 71.11 ? ? ? ? ? ? 61 GLU P OE1 1 61
+ATOM 458 O OE2 . GLU A 1 61 ? 18.683 35.328 -1.729 1.00 71.63 ? ? ? ? ? ? 61 GLU P OE2 1 61
+ATOM 459 N N . VAL A 1 62 ? 13.869 32.021 -1.523 1.00 67.50 ? ? ? ? ? ? 62 VAL P N 1 62
+ATOM 460 C CA . VAL A 1 62 ? 13.124 31.217 -2.504 1.00 68.34 ? ? ? ? ? ? 62 VAL P CA 1 62
+ATOM 461 C C . VAL A 1 62 ? 13.938 31.014 -3.785 1.00 69.51 ? ? ? ? ? ? 62 VAL P C 1 62
+ATOM 462 O O . VAL A 1 62 ? 13.882 29.949 -4.401 1.00 69.69 ? ? ? ? ? ? 62 VAL P O 1 62
+ATOM 463 C CB . VAL A 1 62 ? 11.750 31.861 -2.859 1.00 67.33 ? ? ? ? ? ? 62 VAL P CB 1 62
+ATOM 464 C CG1 . VAL A 1 62 ? 10.998 31.023 -3.892 1.00 66.61 ? ? ? ? ? ? 62 VAL P CG1 1 62
+ATOM 465 C CG2 . VAL A 1 62 ? 10.899 32.049 -1.615 1.00 65.99 ? ? ? ? ? ? 62 VAL P CG2 1 62
+ATOM 466 N N . SER A 1 63 ? 14.691 32.040 -4.174 1.00 70.80 ? ? ? ? ? ? 63 SER P N 1 63
+ATOM 467 C CA . SER A 1 63 ? 15.532 31.980 -5.366 1.00 72.94 ? ? ? ? ? ? 63 SER P CA 1 63
+ATOM 468 C C . SER A 1 63 ? 16.560 30.851 -5.278 1.00 73.51 ? ? ? ? ? ? 63 SER P C 1 63
+ATOM 469 O O . SER A 1 63 ? 16.797 30.148 -6.261 1.00 74.86 ? ? ? ? ? ? 63 SER P O 1 63
+ATOM 470 C CB . SER A 1 63 ? 16.226 33.323 -5.601 1.00 73.36 ? ? ? ? ? ? 63 SER P CB 1 63
+ATOM 471 O OG . SER A 1 63 ? 16.988 33.704 -4.470 1.00 75.33 ? ? ? ? ? ? 63 SER P OG 1 63
+ATOM 472 N N . SER A 1 64 ? 17.153 30.678 -4.097 1.00 73.28 ? ? ? ? ? ? 64 SER P N 1 64
+ATOM 473 C CA . SER A 1 64 ? 18.118 29.607 -3.863 1.00 73.78 ? ? ? ? ? ? 64 SER P CA 1 64
+ATOM 474 C C . SER A 1 64 ? 17.442 28.233 -3.872 1.00 74.09 ? ? ? ? ? ? 64 SER P C 1 64
+ATOM 475 O O . SER A 1 64 ? 18.055 27.233 -4.255 1.00 74.55 ? ? ? ? ? ? 64 SER P O 1 64
+ATOM 476 C CB . SER A 1 64 ? 18.878 29.833 -2.553 1.00 74.22 ? ? ? ? ? ? 64 SER P CB 1 64
+ATOM 477 O OG . SER A 1 64 ? 18.035 29.680 -1.428 1.00 76.33 ? ? ? ? ? ? 64 SER P OG 1 64
+ATOM 478 N N . ALA A 1 65 ? 16.179 28.194 -3.450 1.00 73.75 ? ? ? ? ? ? 65 ALA P N 1 65
+ATOM 479 C CA . ALA A 1 65 ? 15.363 26.983 -3.538 1.00 72.77 ? ? ? ? ? ? 65 ALA P CA 1 65
+ATOM 480 C C . ALA A 1 65 ? 15.023 26.666 -4.991 1.00 72.62 ? ? ? ? ? ? 65 ALA P C 1 65
+ATOM 481 O O . ALA A 1 65 ? 14.969 25.499 -5.379 1.00 73.18 ? ? ? ? ? ? 65 ALA P O 1 65
+ATOM 482 C CB . ALA A 1 65 ? 14.090 27.137 -2.721 1.00 71.97 ? ? ? ? ? ? 65 ALA P CB 1 65
+ATOM 483 N N . THR A 1 66 ? 14.800 27.716 -5.780 1.00 72.37 ? ? ? ? ? ? 66 THR P N 1 66
+ATOM 484 C CA . THR A 1 66 ? 14.475 27.594 -7.201 1.00 71.59 ? ? ? ? ? ? 66 THR P CA 1 66
+ATOM 485 C C . THR A 1 66 ? 15.646 27.000 -7.979 1.00 70.84 ? ? ? ? ? ? 66 THR P C 1 66
+ATOM 486 O O . THR A 1 66 ? 15.458 26.130 -8.831 1.00 69.83 ? ? ? ? ? ? 66 THR P O 1 66
+ATOM 487 C CB . THR A 1 66 ? 14.083 28.966 -7.804 1.00 72.05 ? ? ? ? ? ? 66 THR P CB 1 66
+ATOM 488 O OG1 . THR A 1 66 ? 13.075 29.579 -6.991 1.00 72.70 ? ? ? ? ? ? 66 THR P OG1 1 66
+ATOM 489 C CG2 . THR A 1 66 ? 13.555 28.812 -9.229 1.00 71.59 ? ? ? ? ? ? 66 THR P CG2 1 66
+ATOM 490 N N . ASN A 1 67 ? 16.852 27.471 -7.672 1.00 70.47 ? ? ? ? ? ? 67 ASN P N 1 67
+ATOM 491 C CA . ASN A 1 67 ? 18.058 26.971 -8.319 1.00 70.79 ? ? ? ? ? ? 67 ASN P CA 1 67
+ATOM 492 C C . ASN A 1 67 ? 18.331 25.519 -7.955 1.00 69.83 ? ? ? ? ? ? 67 ASN P C 1 67
+ATOM 493 O O . ASN A 1 67 ? 18.590 24.702 -8.834 1.00 70.19 ? ? ? ? ? ? 67 ASN P O 1 67
+ATOM 494 C CB . ASN A 1 67 ? 19.262 27.854 -7.983 1.00 71.93 ? ? ? ? ? ? 67 ASN P CB 1 67
+ATOM 495 C CG . ASN A 1 67 ? 19.121 29.272 -8.523 1.00 73.48 ? ? ? ? ? ? 67 ASN P CG 1 67
+ATOM 496 O OD1 . ASN A 1 67 ? 18.128 29.618 -9.170 1.00 72.43 ? ? ? ? ? ? 67 ASN P OD1 1 67
+ATOM 497 N ND2 . ASN A 1 67 ? 20.123 30.103 -8.253 1.00 75.22 ? ? ? ? ? ? 67 ASN P ND2 1 67
+ATOM 498 N N . ALA A 1 68 ? 18.239 25.207 -6.662 1.00 69.11 ? ? ? ? ? ? 68 ALA P N 1 68
+ATOM 499 C CA . ALA A 1 68 ? 18.466 23.854 -6.140 1.00 68.14 ? ? ? ? ? ? 68 ALA P CA 1 68
+ATOM 500 C C . ALA A 1 68 ? 17.574 22.801 -6.797 1.00 68.29 ? ? ? ? ? ? 68 ALA P C 1 68
+ATOM 501 O O . ALA A 1 68 ? 18.025 21.692 -7.086 1.00 67.81 ? ? ? ? ? ? 68 ALA P O 1 68
+ATOM 502 C CB . ALA A 1 68 ? 18.282 23.836 -4.629 1.00 67.95 ? ? ? ? ? ? 68 ALA P CB 1 68
+ATOM 503 N N . LEU A 1 69 ? 16.312 23.160 -7.026 1.00 69.27 ? ? ? ? ? ? 69 LEU P N 1 69
+ATOM 504 C CA . LEU A 1 69 ? 15.340 22.281 -7.674 1.00 69.95 ? ? ? ? ? ? 69 LEU P CA 1 69
+ATOM 505 C C . LEU A 1 69 ? 15.719 22.050 -9.130 1.00 71.53 ? ? ? ? ? ? 69 LEU P C 1 69
+ATOM 506 O O . LEU A 1 69 ? 15.865 20.909 -9.568 1.00 72.31 ? ? ? ? ? ? 69 LEU P O 1 69
+ATOM 507 C CB . LEU A 1 69 ? 13.930 22.886 -7.578 1.00 68.95 ? ? ? ? ? ? 69 LEU P CB 1 69
+ATOM 508 C CG . LEU A 1 69 ? 12.708 22.127 -8.115 1.00 68.62 ? ? ? ? ? ? 69 LEU P CG 1 69
+ATOM 509 C CD1 . LEU A 1 69 ? 11.455 22.552 -7.366 1.00 68.96 ? ? ? ? ? ? 69 LEU P CD1 1 69
+ATOM 510 C CD2 . LEU A 1 69 ? 12.511 22.311 -9.617 1.00 68.65 ? ? ? ? ? ? 69 LEU P CD2 1 69
+ATOM 511 N N . ARG A 1 70 ? 15.876 23.145 -9.870 1.00 73.08 ? ? ? ? ? ? 70 ARG P N 1 70
+ATOM 512 C CA . ARG A 1 70 ? 16.155 23.088 -11.298 1.00 74.41 ? ? ? ? ? ? 70 ARG P CA 1 70
+ATOM 513 C C . ARG A 1 70 ? 17.530 22.486 -11.599 1.00 75.37 ? ? ? ? ? ? 70 ARG P C 1 70
+ATOM 514 O O . ARG A 1 70 ? 17.700 21.795 -12.607 1.00 75.39 ? ? ? ? ? ? 70 ARG P O 1 70
+ATOM 515 C CB . ARG A 1 70 ? 15.986 24.477 -11.931 1.00 75.27 ? ? ? ? ? ? 70 ARG P CB 1 70
+ATOM 516 C CG . ARG A 1 70 ? 14.540 24.779 -12.343 1.00 76.61 ? ? ? ? ? ? 70 ARG P CG 1 70
+ATOM 517 C CD . ARG A 1 70 ? 14.132 26.241 -12.128 1.00 78.28 ? ? ? ? ? ? 70 ARG P CD 1 70
+ATOM 518 N NE . ARG A 1 70 ? 14.722 27.167 -13.100 1.00 79.62 ? ? ? ? ? ? 70 ARG P NE 1 70
+ATOM 519 C CZ . ARG A 1 70 ? 14.294 28.411 -13.320 1.00 79.79 ? ? ? ? ? ? 70 ARG P CZ 1 70
+ATOM 520 N NH1 . ARG A 1 70 ? 13.256 28.901 -12.652 1.00 80.16 ? ? ? ? ? ? 70 ARG P NH1 1 70
+ATOM 521 N NH2 . ARG A 1 70 ? 14.902 29.170 -14.221 1.00 80.30 ? ? ? ? ? ? 70 ARG P NH2 1 70
+ATOM 522 N N . SER A 1 71 ? 18.491 22.722 -10.705 1.00 75.79 ? ? ? ? ? ? 71 SER P N 1 71
+ATOM 523 C CA . SER A 1 71 ? 19.872 22.276 -10.908 1.00 76.68 ? ? ? ? ? ? 71 SER P CA 1 71
+ATOM 524 C C . SER A 1 71 ? 20.121 20.816 -10.532 1.00 77.22 ? ? ? ? ? ? 71 SER P C 1 71
+ATOM 525 O O . SER A 1 71 ? 21.059 20.199 -11.042 1.00 78.31 ? ? ? ? ? ? 71 SER P O 1 71
+ATOM 526 C CB . SER A 1 71 ? 20.852 23.173 -10.147 1.00 76.18 ? ? ? ? ? ? 71 SER P CB 1 71
+ATOM 527 O OG . SER A 1 71 ? 20.682 24.535 -10.506 1.00 77.09 ? ? ? ? ? ? 71 SER P OG 1 71
+ATOM 528 N N . MET A 1 72 ? 19.292 20.264 -9.649 1.00 77.19 ? ? ? ? ? ? 72 MET P N 1 72
+ATOM 529 C CA . MET A 1 72 ? 19.538 18.914 -9.136 1.00 76.71 ? ? ? ? ? ? 72 MET P CA 1 72
+ATOM 530 C C . MET A 1 72 ? 18.343 17.947 -9.154 1.00 76.58 ? ? ? ? ? ? 72 MET P C 1 72
+ATOM 531 O O . MET A 1 72 ? 18.313 16.933 -8.359 1.00 75.50 ? ? ? ? ? ? 72 MET P O 1 72
+ATOM 532 C CB . MET A 1 72 ? 20.158 18.976 -7.739 1.00 77.03 ? ? ? ? ? ? 72 MET P CB 1 72
+ATOM 533 C CG . MET A 1 72 ? 21.659 19.136 -7.768 1.00 78.13 ? ? ? ? ? ? 72 MET P CG 1 72
+ATOM 534 S SD . MET A 1 72 ? 22.386 18.963 -6.138 1.00 80.36 ? ? ? ? ? ? 72 MET P SD 1 72
+ATOM 535 C CE . MET A 1 72 ? 24.116 18.765 -6.562 1.00 81.61 ? ? ? ? ? ? 72 MET P CE 1 72
+ATOM 536 N N . GLN A 1 73 ? 17.377 18.244 -10.069 1.00 77.39 ? ? ? ? ? ? 73 GLN P N 1 73
+ATOM 537 C CA . GLN A 1 73 ? 16.236 17.333 -10.223 1.00 78.05 ? ? ? ? ? ? 73 GLN P CA 1 73
+ATOM 538 C C . GLN A 1 73 ? 16.685 16.089 -10.985 1.00 78.05 ? ? ? ? ? ? 73 GLN P C 1 73
+ATOM 539 O O . GLN A 1 73 ? 17.300 16.195 -12.048 1.00 77.97 ? ? ? ? ? ? 73 GLN P O 1 73
+ATOM 540 C CB . GLN A 1 73 ? 15.086 18.020 -10.964 1.00 78.23 ? ? ? ? ? ? 73 GLN P CB 1 73
+ATOM 541 C CG . GLN A 1 73 ? 13.720 17.913 -10.273 1.00 79.31 ? ? ? ? ? ? 73 GLN P CG 1 73
+ATOM 542 C CD . GLN A 1 73 ? 13.085 16.525 -10.335 1.00 79.89 ? ? ? ? ? ? 73 GLN P CD 1 73
+ATOM 543 O OE1 . GLN A 1 73 ? 13.680 15.564 -10.825 1.00 80.91 ? ? ? ? ? ? 73 GLN P OE1 1 73
+ATOM 544 N NE2 . GLN A 1 73 ? 11.861 16.424 -9.833 1.00 80.00 ? ? ? ? ? ? 73 GLN P NE2 1 73
+ATOM 545 N N . GLY A 1 74 ? 16.390 14.916 -10.427 1.00 78.16 ? ? ? ? ? ? 74 GLY P N 1 74
+ATOM 546 C CA . GLY A 1 74 ? 16.762 13.639 -11.042 1.00 78.21 ? ? ? ? ? ? 74 GLY P CA 1 74
+ATOM 547 C C . GLY A 1 74 ? 18.062 13.044 -10.523 1.00 77.68 ? ? ? ? ? ? 74 GLY P C 1 74
+ATOM 548 O O . GLY A 1 74 ? 18.272 11.834 -10.615 1.00 78.32 ? ? ? ? ? ? 74 GLY P O 1 74
+ATOM 549 N N . PHE A 1 75 ? 18.925 13.903 -9.980 1.00 76.74 ? ? ? ? ? ? 75 PHE P N 1 75
+ATOM 550 C CA . PHE A 1 75 ? 20.240 13.526 -9.446 1.00 77.20 ? ? ? ? ? ? 75 PHE P CA 1 75
+ATOM 551 C C . PHE A 1 75 ? 20.203 12.243 -8.600 1.00 76.71 ? ? ? ? ? ? 75 PHE P C 1 75
+ATOM 552 O O . PHE A 1 75 ? 19.464 12.170 -7.614 1.00 75.98 ? ? ? ? ? ? 75 PHE P O 1 75
+ATOM 553 C CB . PHE A 1 75 ? 20.806 14.692 -8.622 1.00 77.88 ? ? ? ? ? ? 75 PHE P CB 1 75
+ATOM 554 C CG . PHE A 1 75 ? 22.297 14.643 -8.417 1.00 79.00 ? ? ? ? ? ? 75 PHE P CG 1 75
+ATOM 555 C CD1 . PHE A 1 75 ? 23.151 15.331 -9.276 1.00 79.61 ? ? ? ? ? ? 75 PHE P CD1 1 75
+ATOM 556 C CD2 . PHE A 1 75 ? 22.848 13.938 -7.349 1.00 79.27 ? ? ? ? ? ? 75 PHE P CD2 1 75
+ATOM 557 C CE1 . PHE A 1 75 ? 24.534 15.303 -9.084 1.00 80.20 ? ? ? ? ? ? 75 PHE P CE1 1 75
+ATOM 558 C CE2 . PHE A 1 75 ? 24.229 13.900 -7.150 1.00 79.39 ? ? ? ? ? ? 75 PHE P CE2 1 75
+ATOM 559 C CZ . PHE A 1 75 ? 25.073 14.585 -8.017 1.00 79.98 ? ? ? ? ? ? 75 PHE P CZ 1 75
+ATOM 560 N N . PRO A 1 76 ? 20.990 11.222 -8.999 1.00 76.70 ? ? ? ? ? ? 76 PRO P N 1 76
+ATOM 561 C CA . PRO A 1 76 ? 21.116 9.972 -8.246 1.00 76.59 ? ? ? ? ? ? 76 PRO P CA 1 76
+ATOM 562 C C . PRO A 1 76 ? 21.790 10.183 -6.891 1.00 75.90 ? ? ? ? ? ? 76 PRO P C 1 76
+ATOM 563 O O . PRO A 1 76 ? 22.881 10.757 -6.815 1.00 75.94 ? ? ? ? ? ? 76 PRO P O 1 76
+ATOM 564 C CB . PRO A 1 76 ? 21.990 9.097 -9.153 1.00 76.82 ? ? ? ? ? ? 76 PRO P CB 1 76
+ATOM 565 C CG . PRO A 1 76 ? 21.821 9.672 -10.511 1.00 77.27 ? ? ? ? ? ? 76 PRO P CG 1 76
+ATOM 566 C CD . PRO A 1 76 ? 21.701 11.145 -10.288 1.00 77.15 ? ? ? ? ? ? 76 PRO P CD 1 76
+ATOM 567 N N . PHE A 1 77 ? 21.129 9.700 -5.841 1.00 74.72 ? ? ? ? ? ? 77 PHE P N 1 77
+ATOM 568 C CA . PHE A 1 77 ? 21.515 9.960 -4.458 1.00 72.57 ? ? ? ? ? ? 77 PHE P CA 1 77
+ATOM 569 C C . PHE A 1 77 ? 21.297 8.693 -3.629 1.00 71.11 ? ? ? ? ? ? 77 PHE P C 1 77
+ATOM 570 O O . PHE A 1 77 ? 20.155 8.282 -3.395 1.00 68.54 ? ? ? ? ? ? 77 PHE P O 1 77
+ATOM 571 C CB . PHE A 1 77 ? 20.676 11.120 -3.918 1.00 72.34 ? ? ? ? ? ? 77 PHE P CB 1 77
+ATOM 572 C CG . PHE A 1 77 ? 21.122 11.635 -2.586 1.00 72.37 ? ? ? ? ? ? 77 PHE P CG 1 77
+ATOM 573 C CD1 . PHE A 1 77 ? 22.336 12.300 -2.451 1.00 72.45 ? ? ? ? ? ? 77 PHE P CD1 1 77
+ATOM 574 C CD2 . PHE A 1 77 ? 20.310 11.486 -1.468 1.00 72.33 ? ? ? ? ? ? 77 PHE P CD2 1 77
+ATOM 575 C CE1 . PHE A 1 77 ? 22.745 12.788 -1.217 1.00 73.06 ? ? ? ? ? ? 77 PHE P CE1 1 77
+ATOM 576 C CE2 . PHE A 1 77 ? 20.707 11.975 -0.231 1.00 73.27 ? ? ? ? ? ? 77 PHE P CE2 1 77
+ATOM 577 C CZ . PHE A 1 77 ? 21.929 12.627 -0.105 1.00 73.40 ? ? ? ? ? ? 77 PHE P CZ 1 77
+ATOM 578 N N . TYR A 1 78 ? 22.401 8.088 -3.190 1.00 69.87 ? ? ? ? ? ? 78 TYR P N 1 78
+ATOM 579 C CA . TYR A 1 78 ? 22.399 6.757 -2.575 1.00 69.55 ? ? ? ? ? ? 78 TYR P CA 1 78
+ATOM 580 C C . TYR A 1 78 ? 21.743 5.741 -3.510 1.00 71.10 ? ? ? ? ? ? 78 TYR P C 1 78
+ATOM 581 O O . TYR A 1 78 ? 20.803 5.042 -3.121 1.00 70.76 ? ? ? ? ? ? 78 TYR P O 1 78
+ATOM 582 C CB . TYR A 1 78 ? 21.700 6.758 -1.209 1.00 67.92 ? ? ? ? ? ? 78 TYR P CB 1 78
+ATOM 583 C CG . TYR A 1 78 ? 22.436 7.489 -0.110 1.00 66.15 ? ? ? ? ? ? 78 TYR P CG 1 78
+ATOM 584 C CD1 . TYR A 1 78 ? 23.514 6.900 0.547 1.00 65.85 ? ? ? ? ? ? 78 TYR P CD1 1 78
+ATOM 585 C CD2 . TYR A 1 78 ? 22.039 8.761 0.291 1.00 65.44 ? ? ? ? ? ? 78 TYR P CD2 1 78
+ATOM 586 C CE1 . TYR A 1 78 ? 24.183 7.566 1.568 1.00 65.00 ? ? ? ? ? ? 78 TYR P CE1 1 78
+ATOM 587 C CE2 . TYR A 1 78 ? 22.706 9.436 1.308 1.00 65.15 ? ? ? ? ? ? 78 TYR P CE2 1 78
+ATOM 588 C CZ . TYR A 1 78 ? 23.777 8.832 1.941 1.00 64.50 ? ? ? ? ? ? 78 TYR P CZ 1 78
+ATOM 589 O OH . TYR A 1 78 ? 24.438 9.492 2.950 1.00 63.15 ? ? ? ? ? ? 78 TYR P OH 1 78
+ATOM 590 N N . ASP A 1 79 ? 22.242 5.689 -4.747 1.00 73.33 ? ? ? ? ? ? 79 ASP P N 1 79
+ATOM 591 C CA . ASP A 1 79 ? 21.730 4.804 -5.808 1.00 74.53 ? ? ? ? ? ? 79 ASP P CA 1 79
+ATOM 592 C C . ASP A 1 79 ? 20.236 5.014 -6.150 1.00 73.85 ? ? ? ? ? ? 79 ASP P C 1 79
+ATOM 593 O O . ASP A 1 79 ? 19.592 4.131 -6.724 1.00 73.76 ? ? ? ? ? ? 79 ASP P O 1 79
+ATOM 594 C CB . ASP A 1 79 ? 22.039 3.328 -5.488 1.00 75.93 ? ? ? ? ? ? 79 ASP P CB 1 79
+ATOM 595 C CG . ASP A 1 79 ? 22.074 2.443 -6.732 1.00 77.34 ? ? ? ? ? ? 79 ASP P CG 1 79
+ATOM 596 O OD1 . ASP A 1 79 ? 22.408 2.944 -7.831 1.00 77.86 ? ? ? ? ? ? 79 ASP P OD1 1 79
+ATOM 597 O OD2 . ASP A 1 79 ? 21.771 1.236 -6.605 1.00 77.54 ? ? ? ? ? ? 79 ASP P OD2 1 79
+ATOM 598 N N . LYS A 1 80 ? 19.696 6.182 -5.803 1.00 73.73 ? ? ? ? ? ? 80 LYS P N 1 80
+ATOM 599 C CA . LYS A 1 80 ? 18.301 6.518 -6.110 1.00 73.49 ? ? ? ? ? ? 80 LYS P CA 1 80
+ATOM 600 C C . LYS A 1 80 ? 18.146 7.961 -6.599 1.00 74.26 ? ? ? ? ? ? 80 LYS P C 1 80
+ATOM 601 O O . LYS A 1 80 ? 18.685 8.886 -5.985 1.00 73.92 ? ? ? ? ? ? 80 LYS P O 1 80
+ATOM 602 C CB . LYS A 1 80 ? 17.389 6.271 -4.903 1.00 72.16 ? ? ? ? ? ? 80 LYS P CB 1 80
+ATOM 603 C CG . LYS A 1 80 ? 16.982 4.816 -4.711 1.00 72.11 ? ? ? ? ? ? 80 LYS P CG 1 80
+ATOM 604 C CD . LYS A 1 80 ? 15.839 4.673 -3.718 1.00 71.48 ? ? ? ? ? ? 80 LYS P CD 1 80
+ATOM 605 C CE . LYS A 1 80 ? 14.502 5.031 -4.348 1.00 71.99 ? ? ? ? ? ? 80 LYS P CE 1 80
+ATOM 606 N NZ . LYS A 1 80 ? 13.403 5.043 -3.345 1.00 73.15 ? ? ? ? ? ? 80 LYS P NZ 1 80
+ATOM 607 N N . PRO A 1 81 ? 17.397 8.156 -7.704 1.00 74.32 ? ? ? ? ? ? 81 PRO P N 1 81
+ATOM 608 C CA . PRO A 1 81 ? 17.201 9.495 -8.254 1.00 73.20 ? ? ? ? ? ? 81 PRO P CA 1 81
+ATOM 609 C C . PRO A 1 81 ? 16.276 10.331 -7.376 1.00 72.45 ? ? ? ? ? ? 81 PRO P C 1 81
+ATOM 610 O O . PRO A 1 81 ? 15.177 9.889 -7.029 1.00 71.86 ? ? ? ? ? ? 81 PRO P O 1 81
+ATOM 611 C CB . PRO A 1 81 ? 16.554 9.225 -9.615 1.00 73.27 ? ? ? ? ? ? 81 PRO P CB 1 81
+ATOM 612 C CG . PRO A 1 81 ? 15.848 7.926 -9.447 1.00 73.64 ? ? ? ? ? ? 81 PRO P CG 1 81
+ATOM 613 C CD . PRO A 1 81 ? 16.650 7.130 -8.459 1.00 74.15 ? ? ? ? ? ? 81 PRO P CD 1 81
+ATOM 614 N N . MET A 1 82 ? 16.734 11.523 -7.009 1.00 72.19 ? ? ? ? ? ? 82 MET P N 1 82
+ATOM 615 C CA . MET A 1 82 ? 15.919 12.453 -6.239 1.00 72.11 ? ? ? ? ? ? 82 MET P CA 1 82
+ATOM 616 C C . MET A 1 82 ? 14.759 12.967 -7.083 1.00 72.34 ? ? ? ? ? ? 82 MET P C 1 82
+ATOM 617 O O . MET A 1 82 ? 14.875 13.085 -8.305 1.00 72.60 ? ? ? ? ? ? 82 MET P O 1 82
+ATOM 618 C CB . MET A 1 82 ? 16.769 13.620 -5.733 1.00 71.74 ? ? ? ? ? ? 82 MET P CB 1 82
+ATOM 619 C CG . MET A 1 82 ? 17.663 13.272 -4.551 1.00 71.59 ? ? ? ? ? ? 82 MET P CG 1 82
+ATOM 620 S SD . MET A 1 82 ? 18.623 14.674 -3.937 1.00 71.26 ? ? ? ? ? ? 82 MET P SD 1 82
+ATOM 621 C CE . MET A 1 82 ? 20.010 14.674 -5.066 1.00 71.25 ? ? ? ? ? ? 82 MET P CE 1 82
+ATOM 622 N N . ARG A 1 83 ? 13.635 13.249 -6.430 1.00 72.88 ? ? ? ? ? ? 83 ARG P N 1 83
+ATOM 623 C CA . ARG A 1 83 ? 12.481 13.836 -7.103 1.00 74.28 ? ? ? ? ? ? 83 ARG P CA 1 83
+ATOM 624 C C . ARG A 1 83 ? 12.070 15.115 -6.384 1.00 73.25 ? ? ? ? ? ? 83 ARG P C 1 83
+ATOM 625 O O . ARG A 1 83 ? 11.290 15.089 -5.429 1.00 74.77 ? ? ? ? ? ? 83 ARG P O 1 83
+ATOM 626 C CB . ARG A 1 83 ? 11.314 12.840 -7.184 1.00 77.26 ? ? ? ? ? ? 83 ARG P CB 1 83
+ATOM 627 C CG . ARG A 1 83 ? 11.616 11.564 -7.975 1.00 80.64 ? ? ? ? ? ? 83 ARG P CG 1 83
+ATOM 628 C CD . ARG A 1 83 ? 11.611 11.798 -9.487 1.00 82.60 ? ? ? ? ? ? 83 ARG P CD 1 83
+ATOM 629 N NE . ARG A 1 83 ? 12.506 10.879 -10.193 1.00 84.36 ? ? ? ? ? ? 83 ARG P NE 1 83
+ATOM 630 C CZ . ARG A 1 83 ? 12.192 9.637 -10.559 1.00 85.59 ? ? ? ? ? ? 83 ARG P CZ 1 83
+ATOM 631 N NH1 . ARG A 1 83 ? 10.994 9.129 -10.292 1.00 85.97 ? ? ? ? ? ? 83 ARG P NH1 1 83
+ATOM 632 N NH2 . ARG A 1 83 ? 13.087 8.893 -11.197 1.00 85.96 ? ? ? ? ? ? 83 ARG P NH2 1 83
+ATOM 633 N N . ILE A 1 84 ? 12.614 16.234 -6.848 1.00 70.68 ? ? ? ? ? ? 84 ILE P N 1 84
+ATOM 634 C CA . ILE A 1 84 ? 12.389 17.524 -6.207 1.00 68.59 ? ? ? ? ? ? 84 ILE P CA 1 84
+ATOM 635 C C . ILE A 1 84 ? 11.180 18.243 -6.802 1.00 68.25 ? ? ? ? ? ? 84 ILE P C 1 84
+ATOM 636 O O . ILE A 1 84 ? 11.027 18.329 -8.021 1.00 68.71 ? ? ? ? ? ? 84 ILE P O 1 84
+ATOM 637 C CB . ILE A 1 84 ? 13.643 18.437 -6.297 1.00 68.14 ? ? ? ? ? ? 84 ILE P CB 1 84
+ATOM 638 C CG1 . ILE A 1 84 ? 14.920 17.630 -6.026 1.00 67.86 ? ? ? ? ? ? 84 ILE P CG1 1 84
+ATOM 639 C CG2 . ILE A 1 84 ? 13.520 19.619 -5.329 1.00 68.05 ? ? ? ? ? ? 84 ILE P CG2 1 84
+ATOM 640 C CD1 . ILE A 1 84 ? 16.214 18.332 -6.419 1.00 67.21 ? ? ? ? ? ? 84 ILE P CD1 1 84
+ATOM 641 N N . GLN A 1 85 ? 10.319 18.734 -5.919 1.00 68.10 ? ? ? ? ? ? 85 GLN P N 1 85
+ATOM 642 C CA . GLN A 1 85 ? 9.235 19.639 -6.281 1.00 69.41 ? ? ? ? ? ? 85 GLN P CA 1 85
+ATOM 643 C C . GLN A 1 85 ? 9.021 20.614 -5.123 1.00 70.51 ? ? ? ? ? ? 85 GLN P C 1 85
+ATOM 644 O O . GLN A 1 85 ? 9.499 20.373 -4.015 1.00 71.01 ? ? ? ? ? ? 85 GLN P O 1 85
+ATOM 645 C CB . GLN A 1 85 ? 7.950 18.867 -6.612 1.00 69.26 ? ? ? ? ? ? 85 GLN P CB 1 85
+ATOM 646 C CG . GLN A 1 85 ? 7.436 17.958 -5.495 1.00 69.64 ? ? ? ? ? ? 85 GLN P CG 1 85
+ATOM 647 C CD . GLN A 1 85 ? 6.210 17.141 -5.888 1.00 68.19 ? ? ? ? ? ? 85 GLN P CD 1 85
+ATOM 648 O OE1 . GLN A 1 85 ? 5.755 16.289 -5.123 1.00 66.95 ? ? ? ? ? ? 85 GLN P OE1 1 85
+ATOM 649 N NE2 . GLN A 1 85 ? 5.671 17.398 -7.074 1.00 67.51 ? ? ? ? ? ? 85 GLN P NE2 1 85
+ATOM 650 N N . TYR A 1 86 ? 8.322 21.716 -5.380 1.00 71.54 ? ? ? ? ? ? 86 TYR P N 1 86
+ATOM 651 C CA . TYR A 1 86 ? 8.063 22.717 -4.347 1.00 72.64 ? ? ? ? ? ? 86 TYR P CA 1 86
+ATOM 652 C C . TYR A 1 86 ? 7.132 22.208 -3.252 1.00 73.71 ? ? ? ? ? ? 86 TYR P C 1 86
+ATOM 653 O O . TYR A 1 86 ? 6.305 21.319 -3.484 1.00 73.77 ? ? ? ? ? ? 86 TYR P O 1 86
+ATOM 654 C CB . TYR A 1 86 ? 7.464 23.985 -4.959 1.00 74.07 ? ? ? ? ? ? 86 TYR P CB 1 86
+ATOM 655 C CG . TYR A 1 86 ? 8.466 24.894 -5.629 1.00 74.93 ? ? ? ? ? ? 86 TYR P CG 1 86
+ATOM 656 C CD1 . TYR A 1 86 ? 9.476 25.515 -4.893 1.00 75.09 ? ? ? ? ? ? 86 TYR P CD1 1 86
+ATOM 657 C CD2 . TYR A 1 86 ? 8.393 25.150 -6.997 1.00 75.01 ? ? ? ? ? ? 86 TYR P CD2 1 86
+ATOM 658 C CE1 . TYR A 1 86 ? 10.394 26.355 -5.503 1.00 75.42 ? ? ? ? ? ? 86 TYR P CE1 1 86
+ATOM 659 C CE2 . TYR A 1 86 ? 9.305 25.988 -7.617 1.00 76.04 ? ? ? ? ? ? 86 TYR P CE2 1 86
+ATOM 660 C CZ . TYR A 1 86 ? 10.302 26.587 -6.864 1.00 76.45 ? ? ? ? ? ? 86 TYR P CZ 1 86
+ATOM 661 O OH . TYR A 1 86 ? 11.207 27.420 -7.474 1.00 77.07 ? ? ? ? ? ? 86 TYR P OH 1 86
+ATOM 662 N N . ALA A 1 87 ? 7.278 22.779 -2.059 1.00 73.67 ? ? ? ? ? ? 87 ALA P N 1 87
+ATOM 663 C CA . ALA A 1 87 ? 6.354 22.531 -0.962 1.00 74.48 ? ? ? ? ? ? 87 ALA P CA 1 87
+ATOM 664 C C . ALA A 1 87 ? 5.014 23.200 -1.264 1.00 75.95 ? ? ? ? ? ? 87 ALA P C 1 87
+ATOM 665 O O . ALA A 1 87 ? 4.978 24.268 -1.889 1.00 76.31 ? ? ? ? ? ? 87 ALA P O 1 87
+ATOM 666 C CB . ALA A 1 87 ? 6.931 23.055 0.342 1.00 74.00 ? ? ? ? ? ? 87 ALA P CB 1 87
+ATOM 667 N N . LYS A 1 88 ? 3.919 22.560 -0.828 1.00 78.69 ? ? ? ? ? ? 88 LYS P N 1 88
+ATOM 668 C CA . LYS A 1 88 ? 2.572 23.092 -1.037 1.00 80.61 ? ? ? ? ? ? 88 LYS P CA 1 88
+ATOM 669 C C . LYS A 1 88 ? 2.330 24.286 -0.122 1.00 82.43 ? ? ? ? ? ? 88 LYS P C 1 88
+ATOM 670 O O . LYS A 1 88 ? 1.979 25.389 -0.583 1.00 81.29 ? ? ? ? ? ? 88 LYS P O 1 88
+ATOM 671 C CB . LYS A 1 88 ? 1.525 22.013 -0.748 1.00 81.34 ? ? ? ? ? ? 88 LYS P CB 1 88
+ATOM 672 C CG . LYS A 1 88 ? 1.591 20.802 -1.669 1.00 82.53 ? ? ? ? ? ? 88 LYS P CG 1 88
+ATOM 673 C CD . LYS A 1 88 ? 0.630 19.716 -1.206 1.00 82.77 ? ? ? ? ? ? 88 LYS P CD 1 88
+ATOM 674 C CE . LYS A 1 88 ? 0.687 18.501 -2.122 1.00 83.16 ? ? ? ? ? ? 88 LYS P CE 1 88
+ATOM 675 N NZ . LYS A 1 88 ? -0.109 17.366 -1.577 1.00 83.03 ? ? ? ? ? ? 88 LYS P NZ 1 88
+ATOM 676 N N . THR A 1 89 ? 2.532 24.035 1.184 1.00 86.65 ? ? ? ? ? ? 89 THR P N 1 89
+ATOM 677 C CA . THR A 1 89 ? 2.326 25.040 2.223 1.00 91.29 ? ? ? ? ? ? 89 THR P CA 1 89
+ATOM 678 C C . THR A 1 89 ? 3.624 25.012 3.064 1.00 93.56 ? ? ? ? ? ? 89 THR P C 1 89
+ATOM 679 O O . THR A 1 89 ? 4.263 23.915 3.201 1.00 95.63 ? ? ? ? ? ? 89 THR P O 1 89
+ATOM 680 C CB . THR A 1 89 ? 1.170 24.605 3.188 1.00 91.85 ? ? ? ? ? ? 89 THR P CB 1 89
+ATOM 681 O OG1 . THR A 1 89 ? 1.659 23.561 4.098 1.00 92.96 ? ? ? ? ? ? 89 THR P OG1 1 89
+ATOM 682 C CG2 . THR A 1 89 ? -0.048 24.085 2.409 1.00 91.80 ? ? ? ? ? ? 89 THR P CG2 1 89
+ATOM 683 N N . ASP A 1 90 ? 4.015 26.200 3.638 1.00 94.83 ? ? ? ? ? ? 90 ASP P N 1 90
+ATOM 684 C CA . ASP A 1 90 ? 5.263 26.232 4.415 1.00 96.77 ? ? ? ? ? ? 90 ASP P CA 1 90
+ATOM 685 C C . ASP A 1 90 ? 5.010 26.968 5.761 1.00 96.82 ? ? ? ? ? ? 90 ASP P C 1 90
+ATOM 686 O O . ASP A 1 90 ? 4.706 28.166 5.811 1.00 97.65 ? ? ? ? ? ? 90 ASP P O 1 90
+ATOM 687 C CB . ASP A 1 90 ? 6.318 27.053 3.601 1.00 98.64 ? ? ? ? ? ? 90 ASP P CB 1 90
+ATOM 688 C CG . ASP A 1 90 ? 7.490 27.588 4.452 1.00 100.17 ? ? ? ? ? ? 90 ASP P CG 1 90
+ATOM 689 O OD1 . ASP A 1 90 ? 8.159 26.774 5.157 1.00 100.67 ? ? ? ? ? ? 90 ASP P OD1 1 90
+ATOM 690 O OD2 . ASP A 1 90 ? 7.750 28.827 4.396 1.00 101.43 ? ? ? ? ? ? 90 ASP P OD2 1 90
+ATOM 691 N N . SER A 1 91 ? 5.112 26.167 6.846 1.00 96.55 ? ? ? ? ? ? 91 SER P N 1 91
+ATOM 692 C CA . SER A 1 91 ? 5.073 26.712 8.219 1.00 96.88 ? ? ? ? ? ? 91 SER P CA 1 91
+ATOM 693 C C . SER A 1 91 ? 6.514 27.054 8.624 1.00 96.62 ? ? ? ? ? ? 91 SER P C 1 91
+ATOM 694 O O . SER A 1 91 ? 7.505 26.742 7.859 1.00 96.50 ? ? ? ? ? ? 91 SER P O 1 91
+ATOM 695 C CB . SER A 1 91 ? 4.458 25.701 9.201 1.00 97.01 ? ? ? ? ? ? 91 SER P CB 1 91
+ATOM 696 O OG . SER A 1 91 ? 4.501 26.191 10.550 1.00 96.14 ? ? ? ? ? ? 91 SER P OG 1 91
+ATOM 697 N N . ASP A 1 92 ? 6.617 27.687 9.827 1.00 96.09 ? ? ? ? ? ? 92 ASP P N 1 92
+ATOM 698 C CA . ASP A 1 92 ? 7.916 28.243 10.265 1.00 96.41 ? ? ? ? ? ? 92 ASP P CA 1 92
+ATOM 699 C C . ASP A 1 92 ? 8.195 29.522 9.462 1.00 97.21 ? ? ? ? ? ? 92 ASP P C 1 92
+ATOM 700 O O . ASP A 1 92 ? 7.266 30.141 8.927 1.00 97.34 ? ? ? ? ? ? 92 ASP P O 1 92
+ATOM 701 C CB . ASP A 1 92 ? 9.045 27.210 10.088 1.00 96.12 ? ? ? ? ? ? 92 ASP P CB 1 92
+ATOM 702 C CG . ASP A 1 92 ? 10.218 27.458 11.014 1.00 96.39 ? ? ? ? ? ? 92 ASP P CG 1 92
+ATOM 703 O OD1 . ASP A 1 92 ? 10.147 27.037 12.188 1.00 96.84 ? ? ? ? ? ? 92 ASP P OD1 1 92
+ATOM 704 O OD2 . ASP A 1 92 ? 11.215 28.064 10.564 1.00 96.10 ? ? ? ? ? ? 92 ASP P OD2 1 92
+ATOM 705 N N . ILE A 1 93 ? 9.465 29.912 9.378 1.00 97.36 ? ? ? ? ? ? 93 ILE P N 1 93
+ATOM 706 C CA . ILE A 1 93 ? 9.858 31.124 8.662 1.00 97.66 ? ? ? ? ? ? 93 ILE P CA 1 93
+ATOM 707 C C . ILE A 1 93 ? 10.452 30.788 7.287 1.00 96.98 ? ? ? ? ? ? 93 ILE P C 1 93
+ATOM 708 O O . ILE A 1 93 ? 9.720 30.563 6.320 1.00 94.99 ? ? ? ? ? ? 93 ILE P O 1 93
+ATOM 709 C CB . ILE A 1 93 ? 10.845 31.970 9.507 1.00 98.20 ? ? ? ? ? ? 93 ILE P CB 1 93
+ATOM 710 C CG1 . ILE A 1 93 ? 10.111 32.605 10.695 1.00 98.87 ? ? ? ? ? ? 93 ILE P CG1 1 93
+ATOM 711 C CG2 . ILE A 1 93 ? 11.518 33.037 8.657 1.00 97.94 ? ? ? ? ? ? 93 ILE P CG2 1 93
+ATOM 712 C CD1 . ILE A 1 93 ? 11.016 33.035 11.843 1.00 99.64 ? ? ? ? ? ? 93 ILE P CD1 1 93
+ATOM 713 P PG . GTP B 2 1 ? 0.140 -8.175 68.585 1.00 101.58 ? ? ? ? ? ? 8 GTP R PG 1 1
+ATOM 714 O O1G . GTP B 2 1 ? 0.190 -6.803 67.948 1.00 101.50 ? ? ? ? ? ? 8 GTP R O1G 1 1
+ATOM 715 O O2G . GTP B 2 1 ? 1.348 -8.374 69.479 1.00 101.57 ? ? ? ? ? ? 8 GTP R O2G 1 1
+ATOM 716 O O3G . GTP B 2 1 ? -1.133 -8.320 69.389 1.00 101.02 ? ? ? ? ? ? 8 GTP R O3G 1 1
+ATOM 717 O O3B . GTP B 2 1 ? 0.173 -9.259 67.393 1.00 99.61 ? ? ? ? ? ? 8 GTP R O3B 1 1
+ATOM 718 P PB . GTP B 2 1 ? -0.723 -10.597 67.460 1.00 98.43 ? ? ? ? ? ? 8 GTP R PB 1 1
+ATOM 719 O O1B . GTP B 2 1 ? -2.146 -10.275 67.056 1.00 97.77 ? ? ? ? ? ? 8 GTP R O1B 1 1
+ATOM 720 O O2B . GTP B 2 1 ? -0.672 -11.233 68.832 1.00 98.31 ? ? ? ? ? ? 8 GTP R O2B 1 1
+ATOM 721 O O3A . GTP B 2 1 ? -0.024 -11.546 66.359 1.00 94.67 ? ? ? ? ? ? 8 GTP R O3A 1 1
+ATOM 722 P PA . GTP B 2 1 ? 1.557 -11.859 66.400 1.00 90.76 ? ? ? ? ? ? 8 GTP R PA 1 1
+ATOM 723 O O1A . GTP B 2 1 ? 2.175 -11.300 67.662 1.00 90.52 ? ? ? ? ? ? 8 GTP R O1A 1 1
+ATOM 724 O O2A . GTP B 2 1 ? 2.255 -11.317 65.173 1.00 90.62 ? ? ? ? ? ? 8 GTP R O2A 1 1
+ATOM 725 O "O5'" . GTP B 2 1 ? 1.598 -13.469 66.440 1.00 86.77 ? ? ? ? ? ? 8 GTP R "O5'" 1 1
+ATOM 726 C "C5'" . GTP B 2 1 ? 1.644 -14.206 65.241 1.00 80.20 ? ? ? ? ? ? 8 GTP R "C5'" 1 1
+ATOM 727 C "C4'" . GTP B 2 1 ? 0.775 -15.458 65.309 1.00 75.66 ? ? ? ? ? ? 8 GTP R "C4'" 1 1
+ATOM 728 O "O4'" . GTP B 2 1 ? -0.224 -15.412 66.315 1.00 73.25 ? ? ? ? ? ? 8 GTP R "O4'" 1 1
+ATOM 729 C "C3'" . GTP B 2 1 ? 0.001 -15.623 64.018 1.00 73.91 ? ? ? ? ? ? 8 GTP R "C3'" 1 1
+ATOM 730 O "O3'" . GTP B 2 1 ? 0.769 -16.223 63.006 1.00 72.21 ? ? ? ? ? ? 8 GTP R "O3'" 1 1
+ATOM 731 C "C2'" . GTP B 2 1 ? -1.219 -16.416 64.424 1.00 72.23 ? ? ? ? ? ? 8 GTP R "C2'" 1 1
+ATOM 732 O "O2'" . GTP B 2 1 ? -0.928 -17.795 64.430 1.00 72.32 ? ? ? ? ? ? 8 GTP R "O2'" 1 1
+ATOM 733 C "C1'" . GTP B 2 1 ? -1.470 -15.916 65.840 1.00 69.93 ? ? ? ? ? ? 8 GTP R "C1'" 1 1
+ATOM 734 N N9 . GTP B 2 1 ? -2.500 -14.842 65.861 1.00 65.33 ? ? ? ? ? ? 8 GTP R N9 1 1
+ATOM 735 C C8 . GTP B 2 1 ? -2.371 -13.634 66.502 1.00 64.07 ? ? ? ? ? ? 8 GTP R C8 1 1
+ATOM 736 N N7 . GTP B 2 1 ? -3.492 -12.901 66.320 1.00 60.73 ? ? ? ? ? ? 8 GTP R N7 1 1
+ATOM 737 C C5 . GTP B 2 1 ? -4.351 -13.619 65.569 1.00 59.04 ? ? ? ? ? ? 8 GTP R C5 1 1
+ATOM 738 C C6 . GTP B 2 1 ? -5.628 -13.335 65.099 1.00 56.79 ? ? ? ? ? ? 8 GTP R C6 1 1
+ATOM 739 O O6 . GTP B 2 1 ? -6.156 -12.258 65.364 1.00 55.11 ? ? ? ? ? ? 8 GTP R O6 1 1
+ATOM 740 N N1 . GTP B 2 1 ? -6.300 -14.269 64.337 1.00 55.42 ? ? ? ? ? ? 8 GTP R N1 1 1
+ATOM 741 C C2 . GTP B 2 1 ? -5.696 -15.476 64.046 1.00 56.18 ? ? ? ? ? ? 8 GTP R C2 1 1
+ATOM 742 N N2 . GTP B 2 1 ? -6.339 -16.375 63.311 1.00 54.79 ? ? ? ? ? ? 8 GTP R N2 1 1
+ATOM 743 N N3 . GTP B 2 1 ? -4.423 -15.752 64.517 1.00 58.75 ? ? ? ? ? ? 8 GTP R N3 1 1
+ATOM 744 C C4 . GTP B 2 1 ? -3.751 -14.841 65.272 1.00 61.17 ? ? ? ? ? ? 8 GTP R C4 1 1
+ATOM 745 P P . G B 2 2 ? 1.092 -15.405 61.669 1.00 71.32 ? ? ? ? ? ? 9 G R P 1 2
+ATOM 746 O OP1 . G B 2 2 ? 2.304 -16.004 61.050 1.00 71.77 ? ? ? ? ? ? 9 G R OP1 1 2
+ATOM 747 O OP2 . G B 2 2 ? 1.080 -13.952 62.005 1.00 70.00 ? ? ? ? ? ? 9 G R OP2 1 2
+ATOM 748 O "O5'" . G B 2 2 ? -0.185 -15.699 60.753 1.00 68.84 ? ? ? ? ? ? 9 G R "O5'" 1 2
+ATOM 749 C "C5'" . G B 2 2 ? -0.533 -17.036 60.402 1.00 66.18 ? ? ? ? ? ? 9 G R "C5'" 1 2
+ATOM 750 C "C4'" . G B 2 2 ? -1.948 -17.101 59.859 1.00 63.74 ? ? ? ? ? ? 9 G R "C4'" 1 2
+ATOM 751 O "O4'" . G B 2 2 ? -2.894 -16.771 60.907 1.00 62.47 ? ? ? ? ? ? 9 G R "O4'" 1 2
+ATOM 752 C "C3'" . G B 2 2 ? -2.285 -16.078 58.784 1.00 62.80 ? ? ? ? ? ? 9 G R "C3'" 1 2
+ATOM 753 O "O3'" . G B 2 2 ? -1.756 -16.429 57.509 1.00 61.79 ? ? ? ? ? ? 9 G R "O3'" 1 2
+ATOM 754 C "C2'" . G B 2 2 ? -3.807 -16.126 58.818 1.00 61.27 ? ? ? ? ? ? 9 G R "C2'" 1 2
+ATOM 755 O "O2'" . G B 2 2 ? -4.345 -17.255 58.154 1.00 62.11 ? ? ? ? ? ? 9 G R "O2'" 1 2
+ATOM 756 C "C1'" . G B 2 2 ? -4.058 -16.199 60.324 1.00 59.67 ? ? ? ? ? ? 9 G R "C1'" 1 2
+ATOM 757 N N9 . G B 2 2 ? -4.368 -14.890 60.915 1.00 55.85 ? ? ? ? ? ? 9 G R N9 1 2
+ATOM 758 C C8 . G B 2 2 ? -3.600 -14.131 61.770 1.00 54.67 ? ? ? ? ? ? 9 G R C8 1 2
+ATOM 759 N N7 . G B 2 2 ? -4.161 -13.003 62.124 1.00 52.55 ? ? ? ? ? ? 9 G R N7 1 2
+ATOM 760 C C5 . G B 2 2 ? -5.381 -13.006 61.462 1.00 52.49 ? ? ? ? ? ? 9 G R C5 1 2
+ATOM 761 C C6 . G B 2 2 ? -6.431 -12.048 61.449 1.00 52.41 ? ? ? ? ? ? 9 G R C6 1 2
+ATOM 762 O O6 . G B 2 2 ? -6.502 -10.961 62.040 1.00 52.44 ? ? ? ? ? ? 9 G R O6 1 2
+ATOM 763 N N1 . G B 2 2 ? -7.495 -12.447 60.641 1.00 53.56 ? ? ? ? ? ? 9 G R N1 1 2
+ATOM 764 C C2 . G B 2 2 ? -7.543 -13.626 59.928 1.00 53.90 ? ? ? ? ? ? 9 G R C2 1 2
+ATOM 765 N N2 . G B 2 2 ? -8.649 -13.846 59.200 1.00 54.28 ? ? ? ? ? ? 9 G R N2 1 2
+ATOM 766 N N3 . G B 2 2 ? -6.570 -14.531 59.932 1.00 53.24 ? ? ? ? ? ? 9 G R N3 1 2
+ATOM 767 C C4 . G B 2 2 ? -5.522 -14.160 60.716 1.00 54.04 ? ? ? ? ? ? 9 G R C4 1 2
+ATOM 768 P P . U B 2 3 ? -1.279 -15.272 56.506 1.00 62.06 ? ? ? ? ? ? 10 U R P 1 3
+ATOM 769 O OP1 . U B 2 3 ? -0.780 -15.928 55.276 1.00 62.31 ? ? ? ? ? ? 10 U R OP1 1 3
+ATOM 770 O OP2 . U B 2 3 ? -0.389 -14.352 57.253 1.00 60.55 ? ? ? ? ? ? 10 U R OP2 1 3
+ATOM 771 O "O5'" . U B 2 3 ? -2.635 -14.489 56.154 1.00 59.94 ? ? ? ? ? ? 10 U R "O5'" 1 3
+ATOM 772 C "C5'" . U B 2 3 ? -3.637 -15.118 55.355 1.00 57.27 ? ? ? ? ? ? 10 U R "C5'" 1 3
+ATOM 773 C "C4'" . U B 2 3 ? -4.939 -14.343 55.380 1.00 56.27 ? ? ? ? ? ? 10 U R "C4'" 1 3
+ATOM 774 O "O4'" . U B 2 3 ? -5.333 -14.033 56.736 1.00 55.10 ? ? ? ? ? ? 10 U R "O4'" 1 3
+ATOM 775 C "C3'" . U B 2 3 ? -4.857 -12.979 54.725 1.00 57.13 ? ? ? ? ? ? 10 U R "C3'" 1 3
+ATOM 776 O "O3'" . U B 2 3 ? -4.968 -13.123 53.326 1.00 59.57 ? ? ? ? ? ? 10 U R "O3'" 1 3
+ATOM 777 C "C2'" . U B 2 3 ? -6.042 -12.242 55.344 1.00 55.44 ? ? ? ? ? ? 10 U R "C2'" 1 3
+ATOM 778 O "O2'" . U B 2 3 ? -7.281 -12.463 54.696 1.00 53.73 ? ? ? ? ? ? 10 U R "O2'" 1 3
+ATOM 779 C "C1'" . U B 2 3 ? -6.059 -12.812 56.759 1.00 53.94 ? ? ? ? ? ? 10 U R "C1'" 1 3
+ATOM 780 N N1 . U B 2 3 ? -5.456 -11.869 57.759 1.00 52.28 ? ? ? ? ? ? 10 U R N1 1 3
+ATOM 781 C C2 . U B 2 3 ? -6.149 -10.727 58.134 1.00 52.45 ? ? ? ? ? ? 10 U R C2 1 3
+ATOM 782 O O2 . U B 2 3 ? -7.251 -10.412 57.707 1.00 52.60 ? ? ? ? ? ? 10 U R O2 1 3
+ATOM 783 N N3 . U B 2 3 ? -5.493 -9.942 59.053 1.00 53.37 ? ? ? ? ? ? 10 U R N3 1 3
+ATOM 784 C C4 . U B 2 3 ? -4.249 -10.164 59.625 1.00 52.82 ? ? ? ? ? ? 10 U R C4 1 3
+ATOM 785 O O4 . U B 2 3 ? -3.807 -9.356 60.435 1.00 53.67 ? ? ? ? ? ? 10 U R O4 1 3
+ATOM 786 C C5 . U B 2 3 ? -3.584 -11.365 59.185 1.00 52.33 ? ? ? ? ? ? 10 U R C5 1 3
+ATOM 787 C C6 . U B 2 3 ? -4.203 -12.150 58.290 1.00 52.89 ? ? ? ? ? ? 10 U R C6 1 3
+ATOM 788 P P . C B 2 4 ? -4.133 -12.159 52.363 1.00 60.71 ? ? ? ? ? ? 11 C R P 1 4
+ATOM 789 O OP1 . C B 2 4 ? -4.286 -12.712 50.998 1.00 62.71 ? ? ? ? ? ? 11 C R OP1 1 4
+ATOM 790 O OP2 . C B 2 4 ? -2.776 -11.967 52.927 1.00 60.68 ? ? ? ? ? ? 11 C R OP2 1 4
+ATOM 791 O "O5'" . C B 2 4 ? -4.924 -10.770 52.473 1.00 60.32 ? ? ? ? ? ? 11 C R "O5'" 1 4
+ATOM 792 C "C5'" . C B 2 4 ? -6.256 -10.666 51.967 1.00 61.90 ? ? ? ? ? ? 11 C R "C5'" 1 4
+ATOM 793 C "C4'" . C B 2 4 ? -6.934 -9.390 52.428 1.00 62.56 ? ? ? ? ? ? 11 C R "C4'" 1 4
+ATOM 794 O "O4'" . C B 2 4 ? -7.099 -9.397 53.869 1.00 63.94 ? ? ? ? ? ? 11 C R "O4'" 1 4
+ATOM 795 C "C3'" . C B 2 4 ? -6.141 -8.119 52.178 1.00 63.04 ? ? ? ? ? ? 11 C R "C3'" 1 4
+ATOM 796 O "O3'" . C B 2 4 ? -6.256 -7.704 50.829 1.00 63.93 ? ? ? ? ? ? 11 C R "O3'" 1 4
+ATOM 797 C "C2'" . C B 2 4 ? -6.797 -7.155 53.162 1.00 62.84 ? ? ? ? ? ? 11 C R "C2'" 1 4
+ATOM 798 O "O2'" . C B 2 4 ? -8.042 -6.646 52.723 1.00 63.83 ? ? ? ? ? ? 11 C R "O2'" 1 4
+ATOM 799 C "C1'" . C B 2 4 ? -6.997 -8.068 54.368 1.00 62.60 ? ? ? ? ? ? 11 C R "C1'" 1 4
+ATOM 800 N N1 . C B 2 4 ? -5.895 -7.954 55.398 1.00 60.84 ? ? ? ? ? ? 11 C R N1 1 4
+ATOM 801 C C2 . C B 2 4 ? -5.949 -6.942 56.380 1.00 60.62 ? ? ? ? ? ? 11 C R C2 1 4
+ATOM 802 O O2 . C B 2 4 ? -6.898 -6.143 56.400 1.00 59.51 ? ? ? ? ? ? 11 C R O2 1 4
+ATOM 803 N N3 . C B 2 4 ? -4.944 -6.861 57.296 1.00 59.87 ? ? ? ? ? ? 11 C R N3 1 4
+ATOM 804 C C4 . C B 2 4 ? -3.924 -7.728 57.258 1.00 59.87 ? ? ? ? ? ? 11 C R C4 1 4
+ATOM 805 N N4 . C B 2 4 ? -2.961 -7.608 58.177 1.00 59.50 ? ? ? ? ? ? 11 C R N4 1 4
+ATOM 806 C C5 . C B 2 4 ? -3.846 -8.758 56.273 1.00 60.06 ? ? ? ? ? ? 11 C R C5 1 4
+ATOM 807 C C6 . C B 2 4 ? -4.840 -8.831 55.377 1.00 59.96 ? ? ? ? ? ? 11 C R C6 1 4
+ATOM 808 P P . A B 2 5 ? -5.012 -7.004 50.105 1.00 64.89 ? ? ? ? ? ? 12 A R P 1 5
+ATOM 809 O OP1 . A B 2 5 ? -5.176 -7.271 48.659 1.00 65.68 ? ? ? ? ? ? 12 A R OP1 1 5
+ATOM 810 O OP2 . A B 2 5 ? -3.751 -7.410 50.776 1.00 63.68 ? ? ? ? ? ? 12 A R OP2 1 5
+ATOM 811 O "O5'" . A B 2 5 ? -5.276 -5.446 50.393 1.00 63.76 ? ? ? ? ? ? 12 A R "O5'" 1 5
+ATOM 812 C "C5'" . A B 2 5 ? -4.347 -4.657 51.146 1.00 62.34 ? ? ? ? ? ? 12 A R "C5'" 1 5
+ATOM 813 C "C4'" . A B 2 5 ? -5.064 -3.579 51.943 1.00 61.88 ? ? ? ? ? ? 12 A R "C4'" 1 5
+ATOM 814 O "O4'" . A B 2 5 ? -5.574 -4.128 53.190 1.00 60.71 ? ? ? ? ? ? 12 A R "O4'" 1 5
+ATOM 815 C "C3'" . A B 2 5 ? -4.192 -2.402 52.357 1.00 61.61 ? ? ? ? ? ? 12 A R "C3'" 1 5
+ATOM 816 O "O3'" . A B 2 5 ? -4.270 -1.384 51.377 1.00 63.11 ? ? ? ? ? ? 12 A R "O3'" 1 5
+ATOM 817 C "C2'" . A B 2 5 ? -4.844 -1.962 53.664 1.00 61.04 ? ? ? ? ? ? 12 A R "C2'" 1 5
+ATOM 818 O "O2'" . A B 2 5 ? -6.018 -1.200 53.455 1.00 62.36 ? ? ? ? ? ? 12 A R "O2'" 1 5
+ATOM 819 C "C1'" . A B 2 5 ? -5.202 -3.306 54.285 1.00 58.98 ? ? ? ? ? ? 12 A R "C1'" 1 5
+ATOM 820 N N9 . A B 2 5 ? -4.097 -3.929 55.022 1.00 56.09 ? ? ? ? ? ? 12 A R N9 1 5
+ATOM 821 C C8 . A B 2 5 ? -3.455 -5.097 54.707 1.00 54.04 ? ? ? ? ? ? 12 A R C8 1 5
+ATOM 822 N N7 . A B 2 5 ? -2.496 -5.424 55.538 1.00 53.37 ? ? ? ? ? ? 12 A R N7 1 5
+ATOM 823 C C5 . A B 2 5 ? -2.501 -4.402 56.470 1.00 52.28 ? ? ? ? ? ? 12 A R C5 1 5
+ATOM 824 C C6 . A B 2 5 ? -1.714 -4.160 57.618 1.00 50.30 ? ? ? ? ? ? 12 A R C6 1 5
+ATOM 825 N N6 . A B 2 5 ? -0.736 -4.976 58.021 1.00 49.01 ? ? ? ? ? ? 12 A R N6 1 5
+ATOM 826 N N1 . A B 2 5 ? -1.971 -3.044 58.336 1.00 50.10 ? ? ? ? ? ? 12 A R N1 1 5
+ATOM 827 C C2 . A B 2 5 ? -2.952 -2.224 57.931 1.00 51.14 ? ? ? ? ? ? 12 A R C2 1 5
+ATOM 828 N N3 . A B 2 5 ? -3.758 -2.348 56.870 1.00 53.09 ? ? ? ? ? ? 12 A R N3 1 5
+ATOM 829 C C4 . A B 2 5 ? -3.482 -3.469 56.171 1.00 54.10 ? ? ? ? ? ? 12 A R C4 1 5
+ATOM 830 P P . C B 2 6 ? -2.972 -0.548 50.953 1.00 64.68 ? ? ? ? ? ? 13 C R P 1 6
+ATOM 831 O OP1 . C B 2 6 ? -3.427 0.475 49.985 1.00 65.38 ? ? ? ? ? ? 13 C R OP1 1 6
+ATOM 832 O OP2 . C B 2 6 ? -1.909 -1.502 50.562 1.00 64.52 ? ? ? ? ? ? 13 C R OP2 1 6
+ATOM 833 O "O5'" . C B 2 6 ? -2.505 0.167 52.307 1.00 62.85 ? ? ? ? ? ? 13 C R "O5'" 1 6
+ATOM 834 C "C5'" . C B 2 6 ? -3.252 1.244 52.868 1.00 61.05 ? ? ? ? ? ? 13 C R "C5'" 1 6
+ATOM 835 C "C4'" . C B 2 6 ? -2.678 1.621 54.220 1.00 60.77 ? ? ? ? ? ? 13 C R "C4'" 1 6
+ATOM 836 O "O4'" . C B 2 6 ? -2.723 0.482 55.116 1.00 59.20 ? ? ? ? ? ? 13 C R "O4'" 1 6
+ATOM 837 C "C3'" . C B 2 6 ? -1.206 1.997 54.193 1.00 60.65 ? ? ? ? ? ? 13 C R "C3'" 1 6
+ATOM 838 O "O3'" . C B 2 6 ? -1.059 3.351 53.815 1.00 62.13 ? ? ? ? ? ? 13 C R "O3'" 1 6
+ATOM 839 C "C2'" . C B 2 6 ? -0.783 1.746 55.636 1.00 59.30 ? ? ? ? ? ? 13 C R "C2'" 1 6
+ATOM 840 O "O2'" . C B 2 6 ? -1.145 2.793 56.518 1.00 60.09 ? ? ? ? ? ? 13 C R "O2'" 1 6
+ATOM 841 C "C1'" . C B 2 6 ? -1.582 0.489 55.959 1.00 56.30 ? ? ? ? ? ? 13 C R "C1'" 1 6
+ATOM 842 N N1 . C B 2 6 ? -0.809 -0.774 55.761 1.00 53.47 ? ? ? ? ? ? 13 C R N1 1 6
+ATOM 843 C C2 . C B 2 6 ? 0.156 -1.167 56.708 1.00 52.41 ? ? ? ? ? ? 13 C R C2 1 6
+ATOM 844 O O2 . C B 2 6 ? 0.369 -0.463 57.704 1.00 52.00 ? ? ? ? ? ? 13 C R O2 1 6
+ATOM 845 N N3 . C B 2 6 ? 0.839 -2.327 56.501 1.00 50.59 ? ? ? ? ? ? 13 C R N3 1 6
+ATOM 846 C C4 . C B 2 6 ? 0.591 -3.069 55.414 1.00 49.69 ? ? ? ? ? ? 13 C R C4 1 6
+ATOM 847 N N4 . C B 2 6 ? 1.286 -4.194 55.256 1.00 48.88 ? ? ? ? ? ? 13 C R N4 1 6
+ATOM 848 C C5 . C B 2 6 ? -0.382 -2.695 54.439 1.00 50.63 ? ? ? ? ? ? 13 C R C5 1 6
+ATOM 849 C C6 . C B 2 6 ? -1.048 -1.553 54.655 1.00 53.49 ? ? ? ? ? ? 13 C R C6 1 6
+ATOM 850 P P . G B 2 7 ? 0.258 3.812 53.042 1.00 63.38 ? ? ? ? ? ? 14 G R P 1 7
+ATOM 851 O OP1 . G B 2 7 ? -0.023 5.157 52.492 1.00 64.31 ? ? ? ? ? ? 14 G R OP1 1 7
+ATOM 852 O OP2 . G B 2 7 ? 0.701 2.724 52.141 1.00 63.46 ? ? ? ? ? ? 14 G R OP2 1 7
+ATOM 853 O "O5'" . G B 2 7 ? 1.338 3.926 54.216 1.00 63.49 ? ? ? ? ? ? 14 G R "O5'" 1 7
+ATOM 854 C "C5'" . G B 2 7 ? 1.260 4.992 55.158 1.00 64.52 ? ? ? ? ? ? 14 G R "C5'" 1 7
+ATOM 855 C "C4'" . G B 2 7 ? 2.336 4.838 56.216 1.00 64.74 ? ? ? ? ? ? 14 G R "C4'" 1 7
+ATOM 856 O "O4'" . G B 2 7 ? 2.379 3.456 56.656 1.00 63.78 ? ? ? ? ? ? 14 G R "O4'" 1 7
+ATOM 857 C "C3'" . G B 2 7 ? 3.749 5.197 55.766 1.00 66.62 ? ? ? ? ? ? 14 G R "C3'" 1 7
+ATOM 858 O "O3'" . G B 2 7 ? 4.409 5.948 56.790 1.00 71.46 ? ? ? ? ? ? 14 G R "O3'" 1 7
+ATOM 859 C "C2'" . G B 2 7 ? 4.413 3.839 55.521 1.00 64.82 ? ? ? ? ? ? 14 G R "C2'" 1 7
+ATOM 860 O "O2'" . G B 2 7 ? 5.802 3.826 55.801 1.00 67.05 ? ? ? ? ? ? 14 G R "O2'" 1 7
+ATOM 861 C "C1'" . G B 2 7 ? 3.678 2.922 56.495 1.00 61.77 ? ? ? ? ? ? 14 G R "C1'" 1 7
+ATOM 862 N N9 . G B 2 7 ? 3.560 1.545 56.015 1.00 57.07 ? ? ? ? ? ? 14 G R N9 1 7
+ATOM 863 C C8 . G B 2 7 ? 2.768 1.094 54.984 1.00 55.11 ? ? ? ? ? ? 14 G R C8 1 7
+ATOM 864 N N7 . G B 2 7 ? 2.865 -0.189 54.772 1.00 52.35 ? ? ? ? ? ? 14 G R N7 1 7
+ATOM 865 C C5 . G B 2 7 ? 3.779 -0.619 55.723 1.00 51.71 ? ? ? ? ? ? 14 G R C5 1 7
+ATOM 866 C C6 . G B 2 7 ? 4.283 -1.916 55.982 1.00 50.53 ? ? ? ? ? ? 14 G R C6 1 7
+ATOM 867 O O6 . G B 2 7 ? 4.013 -2.973 55.404 1.00 50.94 ? ? ? ? ? ? 14 G R O6 1 7
+ATOM 868 N N1 . G B 2 7 ? 5.193 -1.930 57.035 1.00 50.87 ? ? ? ? ? ? 14 G R N1 1 7
+ATOM 869 C C2 . G B 2 7 ? 5.571 -0.824 57.756 1.00 51.10 ? ? ? ? ? ? 14 G R C2 1 7
+ATOM 870 N N2 . G B 2 7 ? 6.463 -1.038 58.734 1.00 50.12 ? ? ? ? ? ? 14 G R N2 1 7
+ATOM 871 N N3 . G B 2 7 ? 5.107 0.401 57.523 1.00 52.48 ? ? ? ? ? ? 14 G R N3 1 7
+ATOM 872 C C4 . G B 2 7 ? 4.218 0.433 56.497 1.00 53.49 ? ? ? ? ? ? 14 G R C4 1 7
+ATOM 873 P P . C B 2 8 ? 4.504 7.550 56.750 1.00 74.77 ? ? ? ? ? ? 15 C R P 1 8
+ATOM 874 O OP1 . C B 2 8 ? 3.298 8.092 57.417 1.00 72.78 ? ? ? ? ? ? 15 C R OP1 1 8
+ATOM 875 O OP2 . C B 2 8 ? 4.830 7.991 55.373 1.00 74.51 ? ? ? ? ? ? 15 C R OP2 1 8
+ATOM 876 O "O5'" . C B 2 8 ? 5.802 7.805 57.658 1.00 75.53 ? ? ? ? ? ? 15 C R "O5'" 1 8
+ATOM 877 C "C5'" . C B 2 8 ? 5.926 8.978 58.464 1.00 78.77 ? ? ? ? ? ? 15 C R "C5'" 1 8
+ATOM 878 C "C4'" . C B 2 8 ? 6.004 8.652 59.950 1.00 80.45 ? ? ? ? ? ? 15 C R "C4'" 1 8
+ATOM 879 O "O4'" . C B 2 8 ? 4.666 8.490 60.476 1.00 81.15 ? ? ? ? ? ? 15 C R "O4'" 1 8
+ATOM 880 C "C3'" . C B 2 8 ? 6.740 7.368 60.316 1.00 81.19 ? ? ? ? ? ? 15 C R "C3'" 1 8
+ATOM 881 O "O3'" . C B 2 8 ? 8.103 7.650 60.564 1.00 81.63 ? ? ? ? ? ? 15 C R "O3'" 1 8
+ATOM 882 C "C2'" . C B 2 8 ? 6.059 6.904 61.598 1.00 81.69 ? ? ? ? ? ? 15 C R "C2'" 1 8
+ATOM 883 O "O2'" . C B 2 8 ? 6.754 7.330 62.754 1.00 81.39 ? ? ? ? ? ? 15 C R "O2'" 1 8
+ATOM 884 C "C1'" . C B 2 8 ? 4.671 7.545 61.529 1.00 82.56 ? ? ? ? ? ? 15 C R "C1'" 1 8
+ATOM 885 N N1 . C B 2 8 ? 3.565 6.550 61.303 1.00 84.70 ? ? ? ? ? ? 15 C R N1 1 8
+ATOM 886 C C2 . C B 2 8 ? 2.796 6.086 62.390 1.00 85.70 ? ? ? ? ? ? 15 C R C2 1 8
+ATOM 887 O O2 . C B 2 8 ? 3.027 6.496 63.536 1.00 85.87 ? ? ? ? ? ? 15 C R O2 1 8
+ATOM 888 N N3 . C B 2 8 ? 1.804 5.183 62.153 1.00 85.99 ? ? ? ? ? ? 15 C R N3 1 8
+ATOM 889 C C4 . C B 2 8 ? 1.568 4.750 60.910 1.00 85.66 ? ? ? ? ? ? 15 C R C4 1 8
+ATOM 890 N N4 . C B 2 8 ? 0.586 3.866 60.725 1.00 85.80 ? ? ? ? ? ? 15 C R N4 1 8
+ATOM 891 C C5 . C B 2 8 ? 2.332 5.208 59.795 1.00 85.77 ? ? ? ? ? ? 15 C R C5 1 8
+ATOM 892 C C6 . C B 2 8 ? 3.308 6.094 60.036 1.00 85.16 ? ? ? ? ? ? 15 C R C6 1 8
+ATOM 893 P P . A B 2 9 ? 9.197 7.523 59.408 1.00 81.98 ? ? ? ? ? ? 16 A R P 1 9
+ATOM 894 O OP1 . A B 2 9 ? 9.696 8.891 59.140 1.00 82.37 ? ? ? ? ? ? 16 A R OP1 1 9
+ATOM 895 O OP2 . A B 2 9 ? 8.630 6.726 58.298 1.00 82.89 ? ? ? ? ? ? 16 A R OP2 1 9
+ATOM 896 O "O5'" . A B 2 9 ? 10.350 6.664 60.115 1.00 83.24 ? ? ? ? ? ? 16 A R "O5'" 1 9
+ATOM 897 C "C5'" . A B 2 9 ? 10.122 5.307 60.481 1.00 86.50 ? ? ? ? ? ? 16 A R "C5'" 1 9
+ATOM 898 C "C4'" . A B 2 9 ? 10.025 5.146 61.988 1.00 89.36 ? ? ? ? ? ? 16 A R "C4'" 1 9
+ATOM 899 O "O4'" . A B 2 9 ? 8.672 4.755 62.345 1.00 90.33 ? ? ? ? ? ? 16 A R "O4'" 1 9
+ATOM 900 C "C3'" . A B 2 9 ? 10.926 4.065 62.574 1.00 90.38 ? ? ? ? ? ? 16 A R "C3'" 1 9
+ATOM 901 O "O3'" . A B 2 9 ? 12.203 4.596 62.932 1.00 91.82 ? ? ? ? ? ? 16 A R "O3'" 1 9
+ATOM 902 C "C2'" . A B 2 9 ? 10.139 3.609 63.800 1.00 91.00 ? ? ? ? ? ? 16 A R "C2'" 1 9
+ATOM 903 O "O2'" . A B 2 9 ? 10.348 4.429 64.935 1.00 91.41 ? ? ? ? ? ? 16 A R "O2'" 1 9
+ATOM 904 C "C1'" . A B 2 9 ? 8.696 3.719 63.315 1.00 91.59 ? ? ? ? ? ? 16 A R "C1'" 1 9
+ATOM 905 N N9 . A B 2 9 ? 8.165 2.471 62.747 1.00 92.84 ? ? ? ? ? ? 16 A R N9 1 9
+ATOM 906 C C8 . A B 2 9 ? 7.752 2.263 61.458 1.00 93.05 ? ? ? ? ? ? 16 A R C8 1 9
+ATOM 907 N N7 . A B 2 9 ? 7.322 1.047 61.220 1.00 92.93 ? ? ? ? ? ? 16 A R N7 1 9
+ATOM 908 C C5 . A B 2 9 ? 7.459 0.403 62.436 1.00 93.48 ? ? ? ? ? ? 16 A R C5 1 9
+ATOM 909 C C6 . A B 2 9 ? 7.176 -0.918 62.853 1.00 93.99 ? ? ? ? ? ? 16 A R C6 1 9
+ATOM 910 N N6 . A B 2 9 ? 6.673 -1.849 62.038 1.00 94.91 ? ? ? ? ? ? 16 A R N6 1 9
+ATOM 911 N N1 . A B 2 9 ? 7.429 -1.249 64.140 1.00 94.14 ? ? ? ? ? ? 16 A R N1 1 9
+ATOM 912 C C2 . A B 2 9 ? 7.932 -0.314 64.958 1.00 94.09 ? ? ? ? ? ? 16 A R C2 1 9
+ATOM 913 N N3 . A B 2 9 ? 8.239 0.956 64.679 1.00 94.11 ? ? ? ? ? ? 16 A R N3 1 9
+ATOM 914 C C4 . A B 2 9 ? 7.977 1.262 63.391 1.00 93.52 ? ? ? ? ? ? 16 A R C4 1 9
+ATOM 915 P P . C B 2 10 ? 13.534 3.706 62.814 1.00 93.25 ? ? ? ? ? ? 17 C R P 1 10
+ATOM 916 O OP1 . C B 2 10 ? 14.662 4.503 63.349 1.00 93.31 ? ? ? ? ? ? 17 C R OP1 1 10
+ATOM 917 O OP2 . C B 2 10 ? 13.610 3.188 61.430 1.00 92.50 ? ? ? ? ? ? 17 C R OP2 1 10
+ATOM 918 O "O5'" . C B 2 10 ? 13.259 2.455 63.783 1.00 95.03 ? ? ? ? ? ? 17 C R "O5'" 1 10
+ATOM 919 C "C5'" . C B 2 10 ? 13.312 2.558 65.212 1.00 97.15 ? ? ? ? ? ? 17 C R "C5'" 1 10
+ATOM 920 C "C4'" . C B 2 10 ? 12.938 1.241 65.875 1.00 98.38 ? ? ? ? ? ? 17 C R "C4'" 1 10
+ATOM 921 O "O4'" . C B 2 10 ? 11.607 0.833 65.468 1.00 98.65 ? ? ? ? ? ? 17 C R "O4'" 1 10
+ATOM 922 C "C3'" . C B 2 10 ? 13.838 0.074 65.499 1.00 99.25 ? ? ? ? ? ? 17 C R "C3'" 1 10
+ATOM 923 O "O3'" . C B 2 10 ? 14.931 0.008 66.393 1.00 100.43 ? ? ? ? ? ? 17 C R "O3'" 1 10
+ATOM 924 C "C2'" . C B 2 10 ? 12.934 -1.150 65.613 1.00 99.34 ? ? ? ? ? ? 17 C R "C2'" 1 10
+ATOM 925 O "O2'" . C B 2 10 ? 12.943 -1.730 66.903 1.00 98.94 ? ? ? ? ? ? 17 C R "O2'" 1 10
+ATOM 926 C "C1'" . C B 2 10 ? 11.557 -0.573 65.277 1.00 99.35 ? ? ? ? ? ? 17 C R "C1'" 1 10
+ATOM 927 N N1 . C B 2 10 ? 11.109 -0.885 63.870 1.00 99.84 ? ? ? ? ? ? 17 C R N1 1 10
+ATOM 928 C C2 . C B 2 10 ? 10.585 -2.154 63.548 1.00 99.68 ? ? ? ? ? ? 17 C R C2 1 10
+ATOM 929 O O2 . C B 2 10 ? 10.480 -3.031 64.414 1.00 99.42 ? ? ? ? ? ? 17 C R O2 1 10
+ATOM 930 N N3 . C B 2 10 ? 10.195 -2.398 62.269 1.00 100.14 ? ? ? ? ? ? 17 C R N3 1 10
+ATOM 931 C C4 . C B 2 10 ? 10.309 -1.449 61.335 1.00 100.55 ? ? ? ? ? ? 17 C R C4 1 10
+ATOM 932 N N4 . C B 2 10 ? 9.910 -1.742 60.093 1.00 101.27 ? ? ? ? ? ? 17 C R N4 1 10
+ATOM 933 C C5 . C B 2 10 ? 10.838 -0.158 61.636 1.00 100.21 ? ? ? ? ? ? 17 C R C5 1 10
+ATOM 934 C C6 . C B 2 10 ? 11.220 0.073 62.897 1.00 99.81 ? ? ? ? ? ? 17 C R C6 1 10
+ATOM 935 P P . A B 2 11 ? 16.406 -0.067 65.791 1.00 101.72 ? ? ? ? ? ? 18 A R P 1 11
+ATOM 936 O OP1 . A B 2 11 ? 17.355 0.159 66.908 1.00 101.76 ? ? ? ? ? ? 18 A R OP1 1 11
+ATOM 937 O OP2 . A B 2 11 ? 16.456 0.812 64.600 1.00 101.60 ? ? ? ? ? ? 18 A R OP2 1 11
+ATOM 938 O "O5'" . A B 2 11 ? 16.506 -1.585 65.289 1.00 101.21 ? ? ? ? ? ? 18 A R "O5'" 1 11
+ATOM 939 C "C5'" . A B 2 11 ? 16.893 -2.607 66.200 1.00 101.02 ? ? ? ? ? ? 18 A R "C5'" 1 11
+ATOM 940 C "C4'" . A B 2 11 ? 16.603 -3.987 65.646 1.00 100.63 ? ? ? ? ? ? 18 A R "C4'" 1 11
+ATOM 941 O "O4'" . A B 2 11 ? 15.218 -4.088 65.235 1.00 101.37 ? ? ? ? ? ? 18 A R "O4'" 1 11
+ATOM 942 C "C3'" . A B 2 11 ? 17.367 -4.358 64.387 1.00 100.17 ? ? ? ? ? ? 18 A R "C3'" 1 11
+ATOM 943 O "O3'" . A B 2 11 ? 18.709 -4.721 64.689 1.00 98.50 ? ? ? ? ? ? 18 A R "O3'" 1 11
+ATOM 944 C "C2'" . A B 2 11 ? 16.532 -5.530 63.879 1.00 100.89 ? ? ? ? ? ? 18 A R "C2'" 1 11
+ATOM 945 O "O2'" . A B 2 11 ? 16.819 -6.758 64.523 1.00 99.68 ? ? ? ? ? ? 18 A R "O2'" 1 11
+ATOM 946 C "C1'" . A B 2 11 ? 15.116 -5.056 64.204 1.00 102.34 ? ? ? ? ? ? 18 A R "C1'" 1 11
+ATOM 947 N N9 . A B 2 11 ? 14.471 -4.455 63.038 1.00 104.57 ? ? ? ? ? ? 18 A R N9 1 11
+ATOM 948 C C8 . A B 2 11 ? 14.257 -3.123 62.812 1.00 105.36 ? ? ? ? ? ? 18 A R C8 1 11
+ATOM 949 N N7 . A B 2 11 ? 13.660 -2.866 61.673 1.00 105.81 ? ? ? ? ? ? 18 A R N7 1 11
+ATOM 950 C C5 . A B 2 11 ? 13.475 -4.116 61.108 1.00 105.43 ? ? ? ? ? ? 18 A R C5 1 11
+ATOM 951 C C6 . A B 2 11 ? 12.891 -4.532 59.893 1.00 105.84 ? ? ? ? ? ? 18 A R C6 1 11
+ATOM 952 N N6 . A B 2 11 ? 12.377 -3.674 59.005 1.00 105.59 ? ? ? ? ? ? 18 A R N6 1 11
+ATOM 953 N N1 . A B 2 11 ? 12.864 -5.859 59.623 1.00 106.12 ? ? ? ? ? ? 18 A R N1 1 11
+ATOM 954 C C2 . A B 2 11 ? 13.383 -6.714 60.519 1.00 105.77 ? ? ? ? ? ? 18 A R C2 1 11
+ATOM 955 N N3 . A B 2 11 ? 13.954 -6.438 61.694 1.00 105.31 ? ? ? ? ? ? 18 A R N3 1 11
+ATOM 956 C C4 . A B 2 11 ? 13.970 -5.112 61.933 1.00 105.07 ? ? ? ? ? ? 18 A R C4 1 11
+ATOM 957 P P . G B 2 12 ? 19.864 -4.498 63.600 1.00 96.97 ? ? ? ? ? ? 19 G R P 1 12
+ATOM 958 O OP1 . G B 2 12 ? 21.168 -4.712 64.267 1.00 97.32 ? ? ? ? ? ? 19 G R OP1 1 12
+ATOM 959 O OP2 . G B 2 12 ? 19.602 -3.219 62.899 1.00 97.07 ? ? ? ? ? ? 19 G R OP2 1 12
+ATOM 960 O "O5'" . G B 2 12 ? 19.612 -5.686 62.565 1.00 93.61 ? ? ? ? ? ? 19 G R "O5'" 1 12
+ATOM 961 C "C5'" . G B 2 12 ? 19.789 -7.031 62.976 1.00 91.14 ? ? ? ? ? ? 19 G R "C5'" 1 12
+ATOM 962 C "C4'" . G B 2 12 ? 19.351 -7.959 61.867 1.00 89.62 ? ? ? ? ? ? 19 G R "C4'" 1 12
+ATOM 963 O "O4'" . G B 2 12 ? 17.934 -7.764 61.633 1.00 89.19 ? ? ? ? ? ? 19 G R "O4'" 1 12
+ATOM 964 C "C3'" . G B 2 12 ? 19.970 -7.674 60.506 1.00 89.18 ? ? ? ? ? ? 19 G R "C3'" 1 12
+ATOM 965 O "O3'" . G B 2 12 ? 21.299 -8.187 60.375 1.00 87.87 ? ? ? ? ? ? 19 G R "O3'" 1 12
+ATOM 966 C "C2'" . G B 2 12 ? 18.951 -8.316 59.567 1.00 89.10 ? ? ? ? ? ? 19 G R "C2'" 1 12
+ATOM 967 O "O2'" . G B 2 12 ? 19.051 -9.727 59.492 1.00 89.19 ? ? ? ? ? ? 19 G R "O2'" 1 12
+ATOM 968 C "C1'" . G B 2 12 ? 17.652 -7.886 60.248 1.00 88.55 ? ? ? ? ? ? 19 G R "C1'" 1 12
+ATOM 969 N N9 . G B 2 12 ? 17.128 -6.614 59.739 1.00 87.43 ? ? ? ? ? ? 19 G R N9 1 12
+ATOM 970 C C8 . G B 2 12 ? 17.424 -5.346 60.187 1.00 87.12 ? ? ? ? ? ? 19 G R C8 1 12
+ATOM 971 N N7 . G B 2 12 ? 16.808 -4.400 59.536 1.00 86.74 ? ? ? ? ? ? 19 G R N7 1 12
+ATOM 972 C C5 . G B 2 12 ? 16.050 -5.080 58.591 1.00 86.12 ? ? ? ? ? ? 19 G R C5 1 12
+ATOM 973 C C6 . G B 2 12 ? 15.173 -4.584 57.592 1.00 85.60 ? ? ? ? ? ? 19 G R C6 1 12
+ATOM 974 O O6 . G B 2 12 ? 14.882 -3.405 57.346 1.00 85.10 ? ? ? ? ? ? 19 G R O6 1 12
+ATOM 975 N N1 . G B 2 12 ? 14.600 -5.609 56.838 1.00 85.56 ? ? ? ? ? ? 19 G R N1 1 12
+ATOM 976 C C2 . G B 2 12 ? 14.849 -6.951 57.023 1.00 85.36 ? ? ? ? ? ? 19 G R C2 1 12
+ATOM 977 N N2 . G B 2 12 ? 14.210 -7.797 56.202 1.00 84.65 ? ? ? ? ? ? 19 G R N2 1 12
+ATOM 978 N N3 . G B 2 12 ? 15.671 -7.427 57.953 1.00 85.52 ? ? ? ? ? ? 19 G R N3 1 12
+ATOM 979 C C4 . G B 2 12 ? 16.238 -6.442 58.700 1.00 86.32 ? ? ? ? ? ? 19 G R C4 1 12
+ATOM 980 P P . G B 2 13 ? 22.572 -7.212 60.503 1.00 87.08 ? ? ? ? ? ? 20 G R P 1 13
+ATOM 981 O OP1 . G B 2 13 ? 23.679 -8.042 61.028 1.00 87.37 ? ? ? ? ? ? 20 G R OP1 1 13
+ATOM 982 O OP2 . G B 2 13 ? 22.190 -5.964 61.211 1.00 86.12 ? ? ? ? ? ? 20 G R OP2 1 13
+ATOM 983 O "O5'" . G B 2 13 ? 22.918 -6.816 58.994 1.00 83.80 ? ? ? ? ? ? 20 G R "O5'" 1 13
+ATOM 984 C "C5'" . G B 2 13 ? 22.315 -5.683 58.380 1.00 79.73 ? ? ? ? ? ? 20 G R "C5'" 1 13
+ATOM 985 C "C4'" . G B 2 13 ? 21.161 -6.153 57.518 1.00 76.53 ? ? ? ? ? ? 20 G R "C4'" 1 13
+ATOM 986 O "O4'" . G B 2 13 ? 19.916 -5.538 57.930 1.00 76.27 ? ? ? ? ? ? 20 G R "O4'" 1 13
+ATOM 987 C "C3'" . G B 2 13 ? 21.263 -5.858 56.034 1.00 73.78 ? ? ? ? ? ? 20 G R "C3'" 1 13
+ATOM 988 O "O3'" . G B 2 13 ? 22.152 -6.799 55.427 1.00 69.26 ? ? ? ? ? ? 20 G R "O3'" 1 13
+ATOM 989 C "C2'" . G B 2 13 ? 19.803 -6.053 55.631 1.00 74.20 ? ? ? ? ? ? 20 G R "C2'" 1 13
+ATOM 990 O "O2'" . G B 2 13 ? 19.439 -7.416 55.520 1.00 73.18 ? ? ? ? ? ? 20 G R "O2'" 1 13
+ATOM 991 C "C1'" . G B 2 13 ? 19.071 -5.410 56.803 1.00 75.04 ? ? ? ? ? ? 20 G R "C1'" 1 13
+ATOM 992 N N9 . G B 2 13 ? 18.769 -3.992 56.609 1.00 75.64 ? ? ? ? ? ? 20 G R N9 1 13
+ATOM 993 C C8 . G B 2 13 ? 19.372 -2.929 57.241 1.00 76.41 ? ? ? ? ? ? 20 G R C8 1 13
+ATOM 994 N N7 . G B 2 13 ? 18.903 -1.768 56.879 1.00 76.65 ? ? ? ? ? ? 20 G R N7 1 13
+ATOM 995 C C5 . G B 2 13 ? 17.923 -2.078 55.946 1.00 76.09 ? ? ? ? ? ? 20 G R C5 1 13
+ATOM 996 C C6 . G B 2 13 ? 17.069 -1.220 55.206 1.00 76.26 ? ? ? ? ? ? 20 G R C6 1 13
+ATOM 997 O O6 . G B 2 13 ? 17.019 0.020 55.239 1.00 75.92 ? ? ? ? ? ? 20 G R O6 1 13
+ATOM 998 N N1 . G B 2 13 ? 16.217 -1.939 54.362 1.00 75.80 ? ? ? ? ? ? 20 G R N1 1 13
+ATOM 999 C C2 . G B 2 13 ? 16.196 -3.314 54.251 1.00 74.64 ? ? ? ? ? ? 20 G R C2 1 13
+ATOM 1000 N N2 . G B 2 13 ? 15.308 -3.829 53.391 1.00 74.53 ? ? ? ? ? ? 20 G R N2 1 13
+ATOM 1001 N N3 . G B 2 13 ? 16.990 -4.126 54.939 1.00 74.10 ? ? ? ? ? ? 20 G R N3 1 13
+ATOM 1002 C C4 . G B 2 13 ? 17.827 -3.444 55.765 1.00 75.33 ? ? ? ? ? ? 20 G R C4 1 13
+ATOM 1003 P P . G B 2 14 ? 22.496 -6.740 53.864 1.00 65.21 ? ? ? ? ? ? 21 G R P 1 14
+ATOM 1004 O OP1 . G B 2 14 ? 23.510 -7.779 53.568 1.00 64.77 ? ? ? ? ? ? 21 G R OP1 1 14
+ATOM 1005 O OP2 . G B 2 14 ? 22.744 -5.329 53.482 1.00 65.68 ? ? ? ? ? ? 21 G R OP2 1 14
+ATOM 1006 O "O5'" . G B 2 14 ? 21.095 -7.180 53.240 1.00 61.98 ? ? ? ? ? ? 21 G R "O5'" 1 14
+ATOM 1007 C "C5'" . G B 2 14 ? 21.026 -7.844 52.009 1.00 57.17 ? ? ? ? ? ? 21 G R "C5'" 1 14
+ATOM 1008 C "C4'" . G B 2 14 ? 19.720 -7.523 51.321 1.00 54.12 ? ? ? ? ? ? 21 G R "C4'" 1 14
+ATOM 1009 O "O4'" . G B 2 14 ? 18.891 -6.638 52.109 1.00 53.25 ? ? ? ? ? ? 21 G R "O4'" 1 14
+ATOM 1010 C "C3'" . G B 2 14 ? 19.920 -6.725 50.060 1.00 52.50 ? ? ? ? ? ? 21 G R "C3'" 1 14
+ATOM 1011 O "O3'" . G B 2 14 ? 20.398 -7.592 49.063 1.00 52.31 ? ? ? ? ? ? 21 G R "O3'" 1 14
+ATOM 1012 C "C2'" . G B 2 14 ? 18.517 -6.195 49.809 1.00 51.43 ? ? ? ? ? ? 21 G R "C2'" 1 14
+ATOM 1013 O "O2'" . G B 2 14 ? 17.639 -7.159 49.261 1.00 48.28 ? ? ? ? ? ? 21 G R "O2'" 1 14
+ATOM 1014 C "C1'" . G B 2 14 ? 18.119 -5.825 51.238 1.00 51.47 ? ? ? ? ? ? 21 G R "C1'" 1 14
+ATOM 1015 N N9 . G B 2 14 ? 18.354 -4.423 51.593 1.00 50.42 ? ? ? ? ? ? 21 G R N9 1 14
+ATOM 1016 C C8 . G B 2 14 ? 19.201 -3.963 52.574 1.00 50.69 ? ? ? ? ? ? 21 G R C8 1 14
+ATOM 1017 N N7 . G B 2 14 ? 19.221 -2.665 52.689 1.00 50.57 ? ? ? ? ? ? 21 G R N7 1 14
+ATOM 1018 C C5 . G B 2 14 ? 18.329 -2.225 51.723 1.00 49.87 ? ? ? ? ? ? 21 G R C5 1 14
+ATOM 1019 C C6 . G B 2 14 ? 17.939 -0.902 51.382 1.00 51.06 ? ? ? ? ? ? 21 G R C6 1 14
+ATOM 1020 O O6 . G B 2 14 ? 18.330 0.162 51.897 1.00 50.76 ? ? ? ? ? ? 21 G R O6 1 14
+ATOM 1021 N N1 . G B 2 14 ? 17.007 -0.884 50.334 1.00 49.85 ? ? ? ? ? ? 21 G R N1 1 14
+ATOM 1022 C C2 . G B 2 14 ? 16.516 -2.015 49.706 1.00 48.94 ? ? ? ? ? ? 21 G R C2 1 14
+ATOM 1023 N N2 . G B 2 14 ? 15.625 -1.819 48.723 1.00 47.46 ? ? ? ? ? ? 21 G R N2 1 14
+ATOM 1024 N N3 . G B 2 14 ? 16.875 -3.258 50.023 1.00 47.98 ? ? ? ? ? ? 21 G R N3 1 14
+ATOM 1025 C C4 . G B 2 14 ? 17.783 -3.295 51.036 1.00 49.64 ? ? ? ? ? ? 21 G R C4 1 14
+ATOM 1026 P P . C B 2 15 ? 21.706 -7.130 48.274 1.00 50.29 ? ? ? ? ? ? 22 C R P 1 15
+ATOM 1027 O OP1 . C B 2 15 ? 22.378 -8.329 47.735 1.00 48.95 ? ? ? ? ? ? 22 C R OP1 1 15
+ATOM 1028 O OP2 . C B 2 15 ? 22.458 -6.195 49.141 1.00 51.24 ? ? ? ? ? ? 22 C R OP2 1 15
+ATOM 1029 O "O5'" . C B 2 15 ? 21.047 -6.302 47.076 1.00 50.36 ? ? ? ? ? ? 22 C R "O5'" 1 15
+ATOM 1030 C "C5'" . C B 2 15 ? 19.948 -6.853 46.341 1.00 47.32 ? ? ? ? ? ? 22 C R "C5'" 1 15
+ATOM 1031 C "C4'" . C B 2 15 ? 19.100 -5.745 45.754 1.00 47.19 ? ? ? ? ? ? 22 C R "C4'" 1 15
+ATOM 1032 O "O4'" . C B 2 15 ? 18.560 -4.915 46.812 1.00 47.51 ? ? ? ? ? ? 22 C R "O4'" 1 15
+ATOM 1033 C "C3'" . C B 2 15 ? 19.857 -4.761 44.879 1.00 46.49 ? ? ? ? ? ? 22 C R "C3'" 1 15
+ATOM 1034 O "O3'" . C B 2 15 ? 19.985 -5.287 43.572 1.00 46.54 ? ? ? ? ? ? 22 C R "O3'" 1 15
+ATOM 1035 C "C2'" . C B 2 15 ? 18.934 -3.552 44.912 1.00 46.86 ? ? ? ? ? ? 22 C R "C2'" 1 15
+ATOM 1036 O "O2'" . C B 2 15 ? 17.853 -3.638 44.004 1.00 49.26 ? ? ? ? ? ? 22 C R "O2'" 1 15
+ATOM 1037 C "C1'" . C B 2 15 ? 18.393 -3.590 46.336 1.00 45.86 ? ? ? ? ? ? 22 C R "C1'" 1 15
+ATOM 1038 N N1 . C B 2 15 ? 19.057 -2.602 47.243 1.00 44.65 ? ? ? ? ? ? 22 C R N1 1 15
+ATOM 1039 C C2 . C B 2 15 ? 18.775 -1.230 47.099 1.00 46.56 ? ? ? ? ? ? 22 C R C2 1 15
+ATOM 1040 O O2 . C B 2 15 ? 17.985 -0.849 46.221 1.00 46.87 ? ? ? ? ? ? 22 C R O2 1 15
+ATOM 1041 N N3 . C B 2 15 ? 19.384 -0.343 47.935 1.00 46.85 ? ? ? ? ? ? 22 C R N3 1 15
+ATOM 1042 C C4 . C B 2 15 ? 20.234 -0.778 48.874 1.00 45.89 ? ? ? ? ? ? 22 C R C4 1 15
+ATOM 1043 N N4 . C B 2 15 ? 20.802 0.134 49.669 1.00 45.82 ? ? ? ? ? ? 22 C R N4 1 15
+ATOM 1044 C C5 . C B 2 15 ? 20.534 -2.165 49.038 1.00 44.92 ? ? ? ? ? ? 22 C R C5 1 15
+ATOM 1045 C C6 . C B 2 15 ? 19.929 -3.030 48.210 1.00 44.89 ? ? ? ? ? ? 22 C R C6 1 15
+ATOM 1046 P P . A B 2 16 ? 21.343 -5.149 42.731 1.00 48.48 ? ? ? ? ? ? 23 A R P 1 16
+ATOM 1047 O OP1 . A B 2 16 ? 21.164 -5.965 41.507 1.00 46.89 ? ? ? ? ? ? 23 A R OP1 1 16
+ATOM 1048 O OP2 . A B 2 16 ? 22.500 -5.387 43.633 1.00 44.61 ? ? ? ? ? ? 23 A R OP2 1 16
+ATOM 1049 O "O5'" . A B 2 16 ? 21.373 -3.607 42.310 1.00 46.09 ? ? ? ? ? ? 23 A R "O5'" 1 16
+ATOM 1050 C "C5'" . A B 2 16 ? 20.287 -2.976 41.638 1.00 46.26 ? ? ? ? ? ? 23 A R "C5'" 1 16
+ATOM 1051 C "C4'" . A B 2 16 ? 20.423 -1.469 41.779 1.00 47.11 ? ? ? ? ? ? 23 A R "C4'" 1 16
+ATOM 1052 O "O4'" . A B 2 16 ? 20.405 -1.097 43.184 1.00 46.84 ? ? ? ? ? ? 23 A R "O4'" 1 16
+ATOM 1053 C "C3'" . A B 2 16 ? 21.729 -0.940 41.199 1.00 47.34 ? ? ? ? ? ? 23 A R "C3'" 1 16
+ATOM 1054 O "O3'" . A B 2 16 ? 21.480 0.182 40.378 1.00 47.33 ? ? ? ? ? ? 23 A R "O3'" 1 16
+ATOM 1055 C "C2'" . A B 2 16 ? 22.571 -0.585 42.423 1.00 48.10 ? ? ? ? ? ? 23 A R "C2'" 1 16
+ATOM 1056 O "O2'" . A B 2 16 ? 23.439 0.518 42.227 1.00 49.12 ? ? ? ? ? ? 23 A R "O2'" 1 16
+ATOM 1057 C "C1'" . A B 2 16 ? 21.510 -0.268 43.473 1.00 47.02 ? ? ? ? ? ? 23 A R "C1'" 1 16
+ATOM 1058 N N9 . A B 2 16 ? 22.052 -0.541 44.799 1.00 46.26 ? ? ? ? ? ? 23 A R N9 1 16
+ATOM 1059 C C8 . A B 2 16 ? 22.416 -1.753 45.317 1.00 46.49 ? ? ? ? ? ? 23 A R C8 1 16
+ATOM 1060 N N7 . A B 2 16 ? 22.904 -1.687 46.534 1.00 47.15 ? ? ? ? ? ? 23 A R N7 1 16
+ATOM 1061 C C5 . A B 2 16 ? 22.869 -0.336 46.832 1.00 47.56 ? ? ? ? ? ? 23 A R C5 1 16
+ATOM 1062 C C6 . A B 2 16 ? 23.253 0.406 47.970 1.00 47.67 ? ? ? ? ? ? 23 A R C6 1 16
+ATOM 1063 N N6 . A B 2 16 ? 23.764 -0.152 49.069 1.00 50.08 ? ? ? ? ? ? 23 A R N6 1 16
+ATOM 1064 N N1 . A B 2 16 ? 23.082 1.746 47.950 1.00 47.35 ? ? ? ? ? ? 23 A R N1 1 16
+ATOM 1065 C C2 . A B 2 16 ? 22.571 2.309 46.848 1.00 47.69 ? ? ? ? ? ? 23 A R C2 1 16
+ATOM 1066 N N3 . A B 2 16 ? 22.175 1.719 45.718 1.00 47.86 ? ? ? ? ? ? 23 A R N3 1 16
+ATOM 1067 C C4 . A B 2 16 ? 22.351 0.385 45.771 1.00 47.38 ? ? ? ? ? ? 23 A R C4 1 16
+ATOM 1068 P P . A B 2 17 ? 22.147 0.226 38.926 1.00 48.21 ? ? ? ? ? ? 24 A R P 1 17
+ATOM 1069 O OP1 . A B 2 17 ? 21.428 -0.731 38.055 1.00 47.98 ? ? ? ? ? ? 24 A R OP1 1 17
+ATOM 1070 O OP2 . A B 2 17 ? 23.618 0.143 39.097 1.00 44.91 ? ? ? ? ? ? 24 A R OP2 1 17
+ATOM 1071 O "O5'" . A B 2 17 ? 21.760 1.695 38.436 1.00 47.93 ? ? ? ? ? ? 24 A R "O5'" 1 17
+ATOM 1072 C "C5'" . A B 2 17 ? 20.397 2.030 38.201 1.00 46.67 ? ? ? ? ? ? 24 A R "C5'" 1 17
+ATOM 1073 C "C4'" . A B 2 17 ? 20.193 3.531 38.277 1.00 47.53 ? ? ? ? ? ? 24 A R "C4'" 1 17
+ATOM 1074 O "O4'" . A B 2 17 ? 20.319 3.997 39.645 1.00 47.25 ? ? ? ? ? ? 24 A R "O4'" 1 17
+ATOM 1075 C "C3'" . A B 2 17 ? 21.223 4.368 37.536 1.00 47.99 ? ? ? ? ? ? 24 A R "C3'" 1 17
+ATOM 1076 O "O3'" . A B 2 17 ? 20.939 4.374 36.152 1.00 49.41 ? ? ? ? ? ? 24 A R "O3'" 1 17
+ATOM 1077 C "C2'" . A B 2 17 ? 20.995 5.728 38.183 1.00 47.92 ? ? ? ? ? ? 24 A R "C2'" 1 17
+ATOM 1078 O "O2'" . A B 2 17 ? 19.850 6.397 37.695 1.00 48.99 ? ? ? ? ? ? 24 A R "O2'" 1 17
+ATOM 1079 C "C1'" . A B 2 17 ? 20.795 5.334 39.646 1.00 46.09 ? ? ? ? ? ? 24 A R "C1'" 1 17
+ATOM 1080 N N9 . A B 2 17 ? 22.032 5.417 40.424 1.00 43.36 ? ? ? ? ? ? 24 A R N9 1 17
+ATOM 1081 C C8 . A B 2 17 ? 22.684 4.393 41.055 1.00 43.62 ? ? ? ? ? ? 24 A R C8 1 17
+ATOM 1082 N N7 . A B 2 17 ? 23.781 4.759 41.675 1.00 43.25 ? ? ? ? ? ? 24 A R N7 1 17
+ATOM 1083 C C5 . A B 2 17 ? 23.855 6.119 41.434 1.00 42.22 ? ? ? ? ? ? 24 A R C5 1 17
+ATOM 1084 C C6 . A B 2 17 ? 24.791 7.101 41.818 1.00 43.42 ? ? ? ? ? ? 24 A R C6 1 17
+ATOM 1085 N N6 . A B 2 17 ? 25.871 6.833 42.561 1.00 45.49 ? ? ? ? ? ? 24 A R N6 1 17
+ATOM 1086 N N1 . A B 2 17 ? 24.576 8.375 41.413 1.00 44.01 ? ? ? ? ? ? 24 A R N1 1 17
+ATOM 1087 C C2 . A B 2 17 ? 23.497 8.643 40.664 1.00 42.83 ? ? ? ? ? ? 24 A R C2 1 17
+ATOM 1088 N N3 . A B 2 17 ? 22.552 7.800 40.241 1.00 42.38 ? ? ? ? ? ? 24 A R N3 1 17
+ATOM 1089 C C4 . A B 2 17 ? 22.788 6.544 40.665 1.00 42.02 ? ? ? ? ? ? 24 A R C4 1 17
+ATOM 1090 P P . A B 2 18 ? 22.089 4.110 35.069 1.00 51.29 ? ? ? ? ? ? 25 A R P 1 18
+ATOM 1091 O OP1 . A B 2 18 ? 21.412 4.070 33.752 1.00 51.01 ? ? ? ? ? ? 25 A R OP1 1 18
+ATOM 1092 O OP2 . A B 2 18 ? 22.956 2.990 35.506 1.00 49.03 ? ? ? ? ? ? 25 A R OP2 1 18
+ATOM 1093 O "O5'" . A B 2 18 ? 22.962 5.443 35.158 1.00 50.98 ? ? ? ? ? ? 25 A R "O5'" 1 18
+ATOM 1094 C "C5'" . A B 2 18 ? 22.414 6.692 34.749 1.00 47.94 ? ? ? ? ? ? 25 A R "C5'" 1 18
+ATOM 1095 C "C4'" . A B 2 18 ? 23.255 7.822 35.304 1.00 45.90 ? ? ? ? ? ? 25 A R "C4'" 1 18
+ATOM 1096 O "O4'" . A B 2 18 ? 23.315 7.712 36.744 1.00 43.54 ? ? ? ? ? ? 25 A R "O4'" 1 18
+ATOM 1097 C "C3'" . A B 2 18 ? 24.714 7.797 34.880 1.00 45.50 ? ? ? ? ? ? 25 A R "C3'" 1 18
+ATOM 1098 O "O3'" . A B 2 18 ? 24.878 8.394 33.604 1.00 44.28 ? ? ? ? ? ? 25 A R "O3'" 1 18
+ATOM 1099 C "C2'" . A B 2 18 ? 25.344 8.643 35.974 1.00 45.71 ? ? ? ? ? ? 25 A R "C2'" 1 18
+ATOM 1100 O "O2'" . A B 2 18 ? 25.135 10.027 35.764 1.00 49.08 ? ? ? ? ? ? 25 A R "O2'" 1 18
+ATOM 1101 C "C1'" . A B 2 18 ? 24.571 8.169 37.200 1.00 43.36 ? ? ? ? ? ? 25 A R "C1'" 1 18
+ATOM 1102 N N9 . A B 2 18 ? 25.240 7.106 37.950 1.00 42.28 ? ? ? ? ? ? 25 A R N9 1 18
+ATOM 1103 C C8 . A B 2 18 ? 24.838 5.805 38.108 1.00 41.66 ? ? ? ? ? ? 25 A R C8 1 18
+ATOM 1104 N N7 . A B 2 18 ? 25.647 5.081 38.853 1.00 40.50 ? ? ? ? ? ? 25 A R N7 1 18
+ATOM 1105 C C5 . A B 2 18 ? 26.652 5.967 39.208 1.00 42.42 ? ? ? ? ? ? 25 A R C5 1 18
+ATOM 1106 C C6 . A B 2 18 ? 27.822 5.834 39.995 1.00 43.38 ? ? ? ? ? ? 25 A R C6 1 18
+ATOM 1107 N N6 . A B 2 18 ? 28.192 4.693 40.587 1.00 44.62 ? ? ? ? ? ? 25 A R N6 1 18
+ATOM 1108 N N1 . A B 2 18 ? 28.613 6.919 40.149 1.00 42.85 ? ? ? ? ? ? 25 A R N1 1 18
+ATOM 1109 C C2 . A B 2 18 ? 28.251 8.066 39.560 1.00 42.93 ? ? ? ? ? ? 25 A R C2 1 18
+ATOM 1110 N N3 . A B 2 18 ? 27.178 8.315 38.804 1.00 41.24 ? ? ? ? ? ? 25 A R N3 1 18
+ATOM 1111 C C4 . A B 2 18 ? 26.413 7.219 38.663 1.00 41.86 ? ? ? ? ? ? 25 A R C4 1 18
+ATOM 1112 P P . C B 2 19 ? 25.881 7.756 32.535 1.00 43.87 ? ? ? ? ? ? 26 C R P 1 19
+ATOM 1113 O OP1 . C B 2 19 ? 25.924 8.672 31.372 1.00 45.22 ? ? ? ? ? ? 26 C R OP1 1 19
+ATOM 1114 O OP2 . C B 2 19 ? 25.530 6.337 32.323 1.00 43.11 ? ? ? ? ? ? 26 C R OP2 1 19
+ATOM 1115 O "O5'" . C B 2 19 ? 27.280 7.766 33.302 1.00 42.41 ? ? ? ? ? ? 26 C R "O5'" 1 19
+ATOM 1116 C "C5'" . C B 2 19 ? 28.029 8.954 33.428 1.00 42.47 ? ? ? ? ? ? 26 C R "C5'" 1 19
+ATOM 1117 C "C4'" . C B 2 19 ? 29.199 8.688 34.344 1.00 42.95 ? ? ? ? ? ? 26 C R "C4'" 1 19
+ATOM 1118 O "O4'" . C B 2 19 ? 28.701 8.197 35.611 1.00 44.10 ? ? ? ? ? ? 26 C R "O4'" 1 19
+ATOM 1119 C "C3'" . C B 2 19 ? 30.122 7.583 33.870 1.00 43.32 ? ? ? ? ? ? 26 C R "C3'" 1 19
+ATOM 1120 O "O3'" . C B 2 19 ? 31.055 8.076 32.906 1.00 42.98 ? ? ? ? ? ? 26 C R "O3'" 1 19
+ATOM 1121 C "C2'" . C B 2 19 ? 30.780 7.169 35.180 1.00 44.14 ? ? ? ? ? ? 26 C R "C2'" 1 19
+ATOM 1122 O "O2'" . C B 2 19 ? 31.797 8.067 35.579 1.00 45.74 ? ? ? ? ? ? 26 C R "O2'" 1 19
+ATOM 1123 C "C1'" . C B 2 19 ? 29.596 7.233 36.141 1.00 44.24 ? ? ? ? ? ? 26 C R "C1'" 1 19
+ATOM 1124 N N1 . C B 2 19 ? 28.882 5.914 36.346 1.00 44.11 ? ? ? ? ? ? 26 C R N1 1 19
+ATOM 1125 C C2 . C B 2 19 ? 29.416 4.951 37.225 1.00 44.20 ? ? ? ? ? ? 26 C R C2 1 19
+ATOM 1126 O O2 . C B 2 19 ? 30.471 5.186 37.825 1.00 45.68 ? ? ? ? ? ? 26 C R O2 1 19
+ATOM 1127 N N3 . C B 2 19 ? 28.759 3.771 37.398 1.00 43.48 ? ? ? ? ? ? 26 C R N3 1 19
+ATOM 1128 C C4 . C B 2 19 ? 27.623 3.534 36.735 1.00 43.64 ? ? ? ? ? ? 26 C R C4 1 19
+ATOM 1129 N N4 . C B 2 19 ? 27.013 2.364 36.935 1.00 43.97 ? ? ? ? ? ? 26 C R N4 1 19
+ATOM 1130 C C5 . C B 2 19 ? 27.060 4.491 35.835 1.00 43.52 ? ? ? ? ? ? 26 C R C5 1 19
+ATOM 1131 C C6 . C B 2 19 ? 27.714 5.650 35.678 1.00 43.68 ? ? ? ? ? ? 26 C R C6 1 19
+ATOM 1132 P P . C B 2 20 ? 31.556 7.144 31.693 1.00 39.78 ? ? ? ? ? ? 27 C R P 1 20
+ATOM 1133 O OP1 . C B 2 20 ? 32.323 8.022 30.791 1.00 39.80 ? ? ? ? ? ? 27 C R OP1 1 20
+ATOM 1134 O OP2 . C B 2 20 ? 30.417 6.356 31.160 1.00 36.35 ? ? ? ? ? ? 27 C R OP2 1 20
+ATOM 1135 O "O5'" . C B 2 20 ? 32.572 6.148 32.419 1.00 38.07 ? ? ? ? ? ? 27 C R "O5'" 1 20
+ATOM 1136 C "C5'" . C B 2 20 ? 33.723 6.671 33.085 1.00 39.59 ? ? ? ? ? ? 27 C R "C5'" 1 20
+ATOM 1137 C "C4'" . C B 2 20 ? 34.404 5.601 33.916 1.00 40.17 ? ? ? ? ? ? 27 C R "C4'" 1 20
+ATOM 1138 O "O4'" . C B 2 20 ? 33.530 5.176 34.989 1.00 41.08 ? ? ? ? ? ? 27 C R "O4'" 1 20
+ATOM 1139 C "C3'" . C B 2 20 ? 34.684 4.298 33.189 1.00 41.06 ? ? ? ? ? ? 27 C R "C3'" 1 20
+ATOM 1140 O "O3'" . C B 2 20 ? 35.819 4.403 32.341 1.00 41.21 ? ? ? ? ? ? 27 C R "O3'" 1 20
+ATOM 1141 C "C2'" . C B 2 20 ? 34.907 3.363 34.373 1.00 41.83 ? ? ? ? ? ? 27 C R "C2'" 1 20
+ATOM 1142 O "O2'" . C B 2 20 ? 36.171 3.525 34.987 1.00 44.59 ? ? ? ? ? ? 27 C R "O2'" 1 20
+ATOM 1143 C "C1'" . C B 2 20 ? 33.805 3.823 35.319 1.00 40.05 ? ? ? ? ? ? 27 C R "C1'" 1 20
+ATOM 1144 N N1 . C B 2 20 ? 32.559 2.968 35.259 1.00 38.33 ? ? ? ? ? ? 27 C R N1 1 20
+ATOM 1145 C C2 . C B 2 20 ? 32.548 1.722 35.912 1.00 38.95 ? ? ? ? ? ? 27 C R C2 1 20
+ATOM 1146 O O2 . C B 2 20 ? 33.554 1.340 36.520 1.00 40.74 ? ? ? ? ? ? 27 C R O2 1 20
+ATOM 1147 N N3 . C B 2 20 ? 31.428 0.953 35.864 1.00 38.42 ? ? ? ? ? ? 27 C R N3 1 20
+ATOM 1148 C C4 . C B 2 20 ? 30.351 1.380 35.200 1.00 37.42 ? ? ? ? ? ? 27 C R C4 1 20
+ATOM 1149 N N4 . C B 2 20 ? 29.283 0.579 35.186 1.00 37.14 ? ? ? ? ? ? 27 C R N4 1 20
+ATOM 1150 C C5 . C B 2 20 ? 30.331 2.642 34.527 1.00 36.89 ? ? ? ? ? ? 27 C R C5 1 20
+ATOM 1151 C C6 . C B 2 20 ? 31.443 3.391 34.584 1.00 37.84 ? ? ? ? ? ? 27 C R C6 1 20
+ATOM 1152 P P . A B 2 21 ? 35.931 3.458 31.055 1.00 43.40 ? ? ? ? ? ? 28 A R P 1 21
+ATOM 1153 O OP1 . A B 2 21 ? 37.136 3.860 30.290 1.00 41.89 ? ? ? ? ? ? 28 A R OP1 1 21
+ATOM 1154 O OP2 . A B 2 21 ? 34.605 3.427 30.388 1.00 41.02 ? ? ? ? ? ? 28 A R OP2 1 21
+ATOM 1155 O "O5'" . A B 2 21 ? 36.179 2.017 31.702 1.00 43.30 ? ? ? ? ? ? 28 A R "O5'" 1 21
+ATOM 1156 C "C5'" . A B 2 21 ? 37.436 1.648 32.245 1.00 45.08 ? ? ? ? ? ? 28 A R "C5'" 1 21
+ATOM 1157 C "C4'" . A B 2 21 ? 37.394 0.197 32.687 1.00 47.78 ? ? ? ? ? ? 28 A R "C4'" 1 21
+ATOM 1158 O "O4'" . A B 2 21 ? 36.372 0.060 33.704 1.00 48.75 ? ? ? ? ? ? 28 A R "O4'" 1 21
+ATOM 1159 C "C3'" . A B 2 21 ? 36.970 -0.821 31.636 1.00 49.28 ? ? ? ? ? ? 28 A R "C3'" 1 21
+ATOM 1160 O "O3'" . A B 2 21 ? 38.037 -1.180 30.768 1.00 50.48 ? ? ? ? ? ? 28 A R "O3'" 1 21
+ATOM 1161 C "C2'" . A B 2 21 ? 36.530 -1.977 32.528 1.00 50.10 ? ? ? ? ? ? 28 A R "C2'" 1 21
+ATOM 1162 O "O2'" . A B 2 21 ? 37.603 -2.745 33.037 1.00 51.40 ? ? ? ? ? ? 28 A R "O2'" 1 21
+ATOM 1163 C "C1'" . A B 2 21 ? 35.816 -1.239 33.655 1.00 49.12 ? ? ? ? ? ? 28 A R "C1'" 1 21
+ATOM 1164 N N9 . A B 2 21 ? 34.381 -1.148 33.405 1.00 49.16 ? ? ? ? ? ? 28 A R N9 1 21
+ATOM 1165 C C8 . A B 2 21 ? 33.703 -0.130 32.793 1.00 49.52 ? ? ? ? ? ? 28 A R C8 1 21
+ATOM 1166 N N7 . A B 2 21 ? 32.410 -0.333 32.696 1.00 50.33 ? ? ? ? ? ? 28 A R N7 1 21
+ATOM 1167 C C5 . A B 2 21 ? 32.229 -1.574 33.280 1.00 49.47 ? ? ? ? ? ? 28 A R C5 1 21
+ATOM 1168 C C6 . A B 2 21 ? 31.082 -2.366 33.495 1.00 49.83 ? ? ? ? ? ? 28 A R C6 1 21
+ATOM 1169 N N6 . A B 2 21 ? 29.853 -1.996 33.122 1.00 49.71 ? ? ? ? ? ? 28 A R N6 1 21
+ATOM 1170 N N1 . A B 2 21 ? 31.250 -3.562 34.102 1.00 50.49 ? ? ? ? ? ? 28 A R N1 1 21
+ATOM 1171 C C2 . A B 2 21 ? 32.482 -3.938 34.473 1.00 49.24 ? ? ? ? ? ? 28 A R C2 1 21
+ATOM 1172 N N3 . A B 2 21 ? 33.631 -3.277 34.327 1.00 48.13 ? ? ? ? ? ? 28 A R N3 1 21
+ATOM 1173 C C4 . A B 2 21 ? 33.434 -2.095 33.718 1.00 49.09 ? ? ? ? ? ? 28 A R C4 1 21
+ATOM 1174 P P . U B 2 22 ? 37.749 -1.562 29.235 1.00 51.88 ? ? ? ? ? ? 29 U R P 1 22
+ATOM 1175 O OP1 . U B 2 22 ? 39.065 -1.714 28.578 1.00 52.03 ? ? ? ? ? ? 29 U R OP1 1 22
+ATOM 1176 O OP2 . U B 2 22 ? 36.747 -0.632 28.667 1.00 50.95 ? ? ? ? ? ? 29 U R OP2 1 22
+ATOM 1177 O "O5'" . U B 2 22 ? 37.032 -2.985 29.327 1.00 52.23 ? ? ? ? ? ? 29 U R "O5'" 1 22
+ATOM 1178 C "C5'" . U B 2 22 ? 37.724 -4.155 29.742 1.00 51.27 ? ? ? ? ? ? 29 U R "C5'" 1 22
+ATOM 1179 C "C4'" . U B 2 22 ? 36.710 -5.241 30.046 1.00 51.64 ? ? ? ? ? ? 29 U R "C4'" 1 22
+ATOM 1180 O "O4'" . U B 2 22 ? 35.768 -4.729 31.021 1.00 51.20 ? ? ? ? ? ? 29 U R "O4'" 1 22
+ATOM 1181 C "C3'" . U B 2 22 ? 35.803 -5.623 28.888 1.00 51.62 ? ? ? ? ? ? 29 U R "C3'" 1 22
+ATOM 1182 O "O3'" . U B 2 22 ? 36.436 -6.515 27.977 1.00 53.54 ? ? ? ? ? ? 29 U R "O3'" 1 22
+ATOM 1183 C "C2'" . U B 2 22 ? 34.636 -6.260 29.639 1.00 50.64 ? ? ? ? ? ? 29 U R "C2'" 1 22
+ATOM 1184 O "O2'" . U B 2 22 ? 34.909 -7.570 30.098 1.00 48.36 ? ? ? ? ? ? 29 U R "O2'" 1 22
+ATOM 1185 C "C1'" . U B 2 22 ? 34.487 -5.298 30.814 1.00 49.41 ? ? ? ? ? ? 29 U R "C1'" 1 22
+ATOM 1186 N N1 . U B 2 22 ? 33.449 -4.230 30.577 1.00 49.14 ? ? ? ? ? ? 29 U R N1 1 22
+ATOM 1187 C C2 . U B 2 22 ? 32.119 -4.509 30.860 1.00 48.59 ? ? ? ? ? ? 29 U R C2 1 22
+ATOM 1188 O O2 . U B 2 22 ? 31.733 -5.578 31.298 1.00 47.71 ? ? ? ? ? ? 29 U R O2 1 22
+ATOM 1189 N N3 . U B 2 22 ? 31.237 -3.482 30.606 1.00 47.53 ? ? ? ? ? ? 29 U R N3 1 22
+ATOM 1190 C C4 . U B 2 22 ? 31.542 -2.224 30.111 1.00 48.35 ? ? ? ? ? ? 29 U R C4 1 22
+ATOM 1191 O O4 . U B 2 22 ? 30.646 -1.401 29.941 1.00 49.31 ? ? ? ? ? ? 29 U R O4 1 22
+ATOM 1192 C C5 . U B 2 22 ? 32.942 -2.002 29.841 1.00 48.45 ? ? ? ? ? ? 29 U R C5 1 22
+ATOM 1193 C C6 . U B 2 22 ? 33.819 -2.989 30.078 1.00 48.88 ? ? ? ? ? ? 29 U R C6 1 22
+ATOM 1194 P P . U B 2 23 ? 35.891 -6.612 26.473 1.00 55.92 ? ? ? ? ? ? 30 U R P 1 23
+ATOM 1195 O OP1 . U B 2 23 ? 36.885 -7.370 25.685 1.00 56.79 ? ? ? ? ? ? 30 U R OP1 1 23
+ATOM 1196 O OP2 . U B 2 23 ? 35.472 -5.266 26.026 1.00 56.02 ? ? ? ? ? ? 30 U R OP2 1 23
+ATOM 1197 O "O5'" . U B 2 23 ? 34.562 -7.489 26.615 1.00 55.88 ? ? ? ? ? ? 30 U R "O5'" 1 23
+ATOM 1198 C "C5'" . U B 2 23 ? 34.646 -8.880 26.907 1.00 54.03 ? ? ? ? ? ? 30 U R "C5'" 1 23
+ATOM 1199 C "C4'" . U B 2 23 ? 33.261 -9.453 27.111 1.00 52.65 ? ? ? ? ? ? 30 U R "C4'" 1 23
+ATOM 1200 O "O4'" . U B 2 23 ? 32.604 -8.723 28.174 1.00 53.98 ? ? ? ? ? ? 30 U R "O4'" 1 23
+ATOM 1201 C "C3'" . U B 2 23 ? 32.326 -9.267 25.931 1.00 52.84 ? ? ? ? ? ? 30 U R "C3'" 1 23
+ATOM 1202 O "O3'" . U B 2 23 ? 32.533 -10.276 24.969 1.00 53.35 ? ? ? ? ? ? 30 U R "O3'" 1 23
+ATOM 1203 C "C2'" . U B 2 23 ? 30.964 -9.386 26.601 1.00 53.57 ? ? ? ? ? ? 30 U R "C2'" 1 23
+ATOM 1204 O "O2'" . U B 2 23 ? 30.578 -10.727 26.842 1.00 53.89 ? ? ? ? ? ? 30 U R "O2'" 1 23
+ATOM 1205 C "C1'" . U B 2 23 ? 31.212 -8.649 27.915 1.00 53.68 ? ? ? ? ? ? 30 U R "C1'" 1 23
+ATOM 1206 N N1 . U B 2 23 ? 30.749 -7.219 27.876 1.00 53.17 ? ? ? ? ? ? 30 U R N1 1 23
+ATOM 1207 C C2 . U B 2 23 ? 29.401 -6.947 28.060 1.00 53.95 ? ? ? ? ? ? 30 U R C2 1 23
+ATOM 1208 O O2 . U B 2 23 ? 28.556 -7.801 28.260 1.00 53.72 ? ? ? ? ? ? 30 U R O2 1 23
+ATOM 1209 N N3 . U B 2 23 ? 29.064 -5.616 28.007 1.00 55.46 ? ? ? ? ? ? 30 U R N3 1 23
+ATOM 1210 C C4 . U B 2 23 ? 29.917 -4.547 27.788 1.00 55.95 ? ? ? ? ? ? 30 U R C4 1 23
+ATOM 1211 O O4 . U B 2 23 ? 29.461 -3.405 27.769 1.00 57.24 ? ? ? ? ? ? 30 U R O4 1 23
+ATOM 1212 C C5 . U B 2 23 ? 31.304 -4.906 27.600 1.00 54.11 ? ? ? ? ? ? 30 U R C5 1 23
+ATOM 1213 C C6 . U B 2 23 ? 31.658 -6.198 27.651 1.00 52.33 ? ? ? ? ? ? 30 U R C6 1 23
+ATOM 1214 P P . C B 2 24 ? 32.283 -9.967 23.422 1.00 52.17 ? ? ? ? ? ? 31 C R P 1 24
+ATOM 1215 O OP1 . C B 2 24 ? 32.848 -11.102 22.662 1.00 53.59 ? ? ? ? ? ? 31 C R OP1 1 24
+ATOM 1216 O OP2 . C B 2 24 ? 32.747 -8.594 23.131 1.00 54.12 ? ? ? ? ? ? 31 C R OP2 1 24
+ATOM 1217 O "O5'" . C B 2 24 ? 30.687 -9.957 23.300 1.00 52.70 ? ? ? ? ? ? 31 C R "O5'" 1 24
+ATOM 1218 C "C5'" . C B 2 24 ? 29.932 -11.153 23.477 1.00 53.71 ? ? ? ? ? ? 31 C R "C5'" 1 24
+ATOM 1219 C "C4'" . C B 2 24 ? 28.450 -10.857 23.618 1.00 53.63 ? ? ? ? ? ? 31 C R "C4'" 1 24
+ATOM 1220 O "O4'" . C B 2 24 ? 28.230 -9.974 24.745 1.00 54.03 ? ? ? ? ? ? 31 C R "O4'" 1 24
+ATOM 1221 C "C3'" . C B 2 24 ? 27.817 -10.070 22.484 1.00 54.65 ? ? ? ? ? ? 31 C R "C3'" 1 24
+ATOM 1222 O "O3'" . C B 2 24 ? 27.605 -10.864 21.320 1.00 56.43 ? ? ? ? ? ? 31 C R "O3'" 1 24
+ATOM 1223 C "C2'" . C B 2 24 ? 26.527 -9.592 23.151 1.00 54.06 ? ? ? ? ? ? 31 C R "C2'" 1 24
+ATOM 1224 O "O2'" . C B 2 24 ? 25.530 -10.586 23.275 1.00 53.49 ? ? ? ? ? ? 31 C R "O2'" 1 24
+ATOM 1225 C "C1'" . C B 2 24 ? 27.053 -9.208 24.529 1.00 53.46 ? ? ? ? ? ? 31 C R "C1'" 1 24
+ATOM 1226 N N1 . C B 2 24 ? 27.340 -7.732 24.675 1.00 53.11 ? ? ? ? ? ? 31 C R N1 1 24
+ATOM 1227 C C2 . C B 2 24 ? 26.282 -6.835 24.929 1.00 53.12 ? ? ? ? ? ? 31 C R C2 1 24
+ATOM 1228 O O2 . C B 2 24 ? 25.121 -7.255 25.028 1.00 52.24 ? ? ? ? ? ? 31 C R O2 1 24
+ATOM 1229 N N3 . C B 2 24 ? 26.559 -5.511 25.059 1.00 53.11 ? ? ? ? ? ? 31 C R N3 1 24
+ATOM 1230 C C4 . C B 2 24 ? 27.817 -5.073 24.947 1.00 53.09 ? ? ? ? ? ? 31 C R C4 1 24
+ATOM 1231 N N4 . C B 2 24 ? 28.030 -3.762 25.087 1.00 53.24 ? ? ? ? ? ? 31 C R N4 1 24
+ATOM 1232 C C5 . C B 2 24 ? 28.908 -5.959 24.691 1.00 52.72 ? ? ? ? ? ? 31 C R C5 1 24
+ATOM 1233 C C6 . C B 2 24 ? 28.625 -7.264 24.566 1.00 52.42 ? ? ? ? ? ? 31 C R C6 1 24
+ATOM 1234 P P . G B 2 25 ? 27.805 -10.204 19.869 1.00 57.68 ? ? ? ? ? ? 32 G R P 1 25
+ATOM 1235 O OP1 . G B 2 25 ? 27.654 -11.275 18.856 1.00 57.60 ? ? ? ? ? ? 32 G R OP1 1 25
+ATOM 1236 O OP2 . G B 2 25 ? 29.032 -9.374 19.887 1.00 55.05 ? ? ? ? ? ? 32 G R OP2 1 25
+ATOM 1237 O "O5'" . G B 2 25 ? 26.552 -9.219 19.755 1.00 56.53 ? ? ? ? ? ? 32 G R "O5'" 1 25
+ATOM 1238 C "C5'" . G B 2 25 ? 25.214 -9.713 19.775 1.00 56.44 ? ? ? ? ? ? 32 G R "C5'" 1 25
+ATOM 1239 C "C4'" . G B 2 25 ? 24.243 -8.552 19.860 1.00 57.18 ? ? ? ? ? ? 32 G R "C4'" 1 25
+ATOM 1240 O "O4'" . G B 2 25 ? 24.377 -7.870 21.133 1.00 57.36 ? ? ? ? ? ? 32 G R "O4'" 1 25
+ATOM 1241 C "C3'" . G B 2 25 ? 24.526 -7.412 18.899 1.00 58.50 ? ? ? ? ? ? 32 G R "C3'" 1 25
+ATOM 1242 O "O3'" . G B 2 25 ? 24.232 -7.740 17.545 1.00 60.15 ? ? ? ? ? ? 32 G R "O3'" 1 25
+ATOM 1243 C "C2'" . G B 2 25 ? 23.668 -6.311 19.510 1.00 57.04 ? ? ? ? ? ? 32 G R "C2'" 1 25
+ATOM 1244 O "O2'" . G B 2 25 ? 22.280 -6.522 19.345 1.00 59.42 ? ? ? ? ? ? 32 G R "O2'" 1 25
+ATOM 1245 C "C1'" . G B 2 25 ? 24.075 -6.490 20.971 1.00 55.51 ? ? ? ? ? ? 32 G R "C1'" 1 25
+ATOM 1246 N N9 . G B 2 25 ? 25.235 -5.664 21.304 1.00 53.55 ? ? ? ? ? ? 32 G R N9 1 25
+ATOM 1247 C C8 . G B 2 25 ? 26.554 -6.052 21.347 1.00 53.69 ? ? ? ? ? ? 32 G R C8 1 25
+ATOM 1248 N N7 . G B 2 25 ? 27.377 -5.089 21.658 1.00 53.73 ? ? ? ? ? ? 32 G R N7 1 25
+ATOM 1249 C C5 . G B 2 25 ? 26.554 -3.985 21.829 1.00 53.84 ? ? ? ? ? ? 32 G R C5 1 25
+ATOM 1250 C C6 . G B 2 25 ? 26.881 -2.650 22.174 1.00 54.54 ? ? ? ? ? ? 32 G R C6 1 25
+ATOM 1251 O O6 . G B 2 25 ? 28.007 -2.181 22.400 1.00 56.21 ? ? ? ? ? ? 32 G R O6 1 25
+ATOM 1252 N N1 . G B 2 25 ? 25.752 -1.829 22.248 1.00 52.91 ? ? ? ? ? ? 32 G R N1 1 25
+ATOM 1253 C C2 . G B 2 25 ? 24.465 -2.258 22.013 1.00 52.70 ? ? ? ? ? ? 32 G R C2 1 25
+ATOM 1254 N N2 . G B 2 25 ? 23.496 -1.339 22.126 1.00 53.64 ? ? ? ? ? ? 32 G R N2 1 25
+ATOM 1255 N N3 . G B 2 25 ? 24.147 -3.507 21.689 1.00 52.97 ? ? ? ? ? ? 32 G R N3 1 25
+ATOM 1256 C C4 . G B 2 25 ? 25.234 -4.319 21.614 1.00 53.66 ? ? ? ? ? ? 32 G R C4 1 25
+ATOM 1257 P P . A B 2 26 ? 25.364 -7.422 16.452 1.00 61.56 ? ? ? ? ? ? 33 A R P 1 26
+ATOM 1258 O OP1 . A B 2 26 ? 25.209 -8.395 15.347 1.00 60.83 ? ? ? ? ? ? 33 A R OP1 1 26
+ATOM 1259 O OP2 . A B 2 26 ? 26.673 -7.287 17.141 1.00 59.56 ? ? ? ? ? ? 33 A R OP2 1 26
+ATOM 1260 O "O5'" . A B 2 26 ? 24.923 -5.972 15.940 1.00 59.89 ? ? ? ? ? ? 33 A R "O5'" 1 26
+ATOM 1261 C "C5'" . A B 2 26 ? 25.897 -5.006 15.557 1.00 58.91 ? ? ? ? ? ? 33 A R "C5'" 1 26
+ATOM 1262 C "C4'" . A B 2 26 ? 25.212 -3.749 15.057 1.00 57.67 ? ? ? ? ? ? 33 A R "C4'" 1 26
+ATOM 1263 O "O4'" . A B 2 26 ? 24.090 -4.120 14.217 1.00 57.15 ? ? ? ? ? ? 33 A R "O4'" 1 26
+ATOM 1264 C "C3'" . A B 2 26 ? 24.622 -2.871 16.147 1.00 56.29 ? ? ? ? ? ? 33 A R "C3'" 1 26
+ATOM 1265 O "O3'" . A B 2 26 ? 25.604 -1.932 16.570 1.00 56.61 ? ? ? ? ? ? 33 A R "O3'" 1 26
+ATOM 1266 C "C2'" . A B 2 26 ? 23.457 -2.197 15.434 1.00 55.61 ? ? ? ? ? ? 33 A R "C2'" 1 26
+ATOM 1267 O "O2'" . A B 2 26 ? 23.855 -1.055 14.695 1.00 55.44 ? ? ? ? ? ? 33 A R "O2'" 1 26
+ATOM 1268 C "C1'" . A B 2 26 ? 22.981 -3.284 14.474 1.00 55.30 ? ? ? ? ? ? 33 A R "C1'" 1 26
+ATOM 1269 N N9 . A B 2 26 ? 21.864 -4.121 14.930 1.00 55.07 ? ? ? ? ? ? 33 A R N9 1 26
+ATOM 1270 C C8 . A B 2 26 ? 21.863 -5.482 15.079 1.00 54.80 ? ? ? ? ? ? 33 A R C8 1 26
+ATOM 1271 N N7 . A B 2 26 ? 20.720 -5.978 15.491 1.00 54.47 ? ? ? ? ? ? 33 A R N7 1 26
+ATOM 1272 C C5 . A B 2 26 ? 19.907 -4.868 15.616 1.00 54.13 ? ? ? ? ? ? 33 A R C5 1 26
+ATOM 1273 C C6 . A B 2 26 ? 18.564 -4.713 16.014 1.00 54.74 ? ? ? ? ? ? 33 A R C6 1 26
+ATOM 1274 N N6 . A B 2 26 ? 17.779 -5.732 16.372 1.00 55.74 ? ? ? ? ? ? 33 A R N6 1 26
+ATOM 1275 N N1 . A B 2 26 ? 18.047 -3.466 16.028 1.00 55.08 ? ? ? ? ? ? 33 A R N1 1 26
+ATOM 1276 C C2 . A B 2 26 ? 18.830 -2.439 15.671 1.00 55.44 ? ? ? ? ? ? 33 A R C2 1 26
+ATOM 1277 N N3 . A B 2 26 ? 20.104 -2.458 15.280 1.00 55.35 ? ? ? ? ? ? 33 A R N3 1 26
+ATOM 1278 C C4 . A B 2 26 ? 20.592 -3.714 15.273 1.00 54.75 ? ? ? ? ? ? 33 A R C4 1 26
+ATOM 1279 P P . A B 2 27 ? 25.899 -1.729 18.128 1.00 55.74 ? ? ? ? ? ? 34 A R P 1 27
+ATOM 1280 O OP1 . A B 2 27 ? 27.156 -0.961 18.279 1.00 54.88 ? ? ? ? ? ? 34 A R OP1 1 27
+ATOM 1281 O OP2 . A B 2 27 ? 25.781 -3.059 18.763 1.00 57.39 ? ? ? ? ? ? 34 A R OP2 1 27
+ATOM 1282 O "O5'" . A B 2 27 ? 24.665 -0.832 18.614 1.00 54.02 ? ? ? ? ? ? 34 A R "O5'" 1 27
+ATOM 1283 C "C5'" . A B 2 27 ? 24.456 0.481 18.090 1.00 52.80 ? ? ? ? ? ? 34 A R "C5'" 1 27
+ATOM 1284 C "C4'" . A B 2 27 ? 22.992 0.875 18.185 1.00 52.89 ? ? ? ? ? ? 34 A R "C4'" 1 27
+ATOM 1285 O "O4'" . A B 2 27 ? 22.172 -0.161 17.588 1.00 52.10 ? ? ? ? ? ? 34 A R "O4'" 1 27
+ATOM 1286 C "C3'" . A B 2 27 ? 22.445 1.015 19.600 1.00 53.41 ? ? ? ? ? ? 34 A R "C3'" 1 27
+ATOM 1287 O "O3'" . A B 2 27 ? 22.684 2.325 20.108 1.00 53.18 ? ? ? ? ? ? 34 A R "O3'" 1 27
+ATOM 1288 C "C2'" . A B 2 27 ? 20.954 0.743 19.413 1.00 53.05 ? ? ? ? ? ? 34 A R "C2'" 1 27
+ATOM 1289 O "O2'" . A B 2 27 ? 20.243 1.896 19.006 1.00 54.41 ? ? ? ? ? ? 34 A R "O2'" 1 27
+ATOM 1290 C "C1'" . A B 2 27 ? 20.940 -0.277 18.282 1.00 51.91 ? ? ? ? ? ? 34 A R "C1'" 1 27
+ATOM 1291 N N9 . A B 2 27 ? 20.731 -1.672 18.685 1.00 50.62 ? ? ? ? ? ? 34 A R N9 1 27
+ATOM 1292 C C8 . A B 2 27 ? 21.693 -2.623 18.898 1.00 51.25 ? ? ? ? ? ? 34 A R C8 1 27
+ATOM 1293 N N7 . A B 2 27 ? 21.222 -3.801 19.236 1.00 49.82 ? ? ? ? ? ? 34 A R N7 1 27
+ATOM 1294 C C5 . A B 2 27 ? 19.852 -3.617 19.243 1.00 49.76 ? ? ? ? ? ? 34 A R C5 1 27
+ATOM 1295 C C6 . A B 2 27 ? 18.774 -4.490 19.521 1.00 49.94 ? ? ? ? ? ? 34 A R C6 1 27
+ATOM 1296 N N6 . A B 2 27 ? 18.940 -5.773 19.859 1.00 49.41 ? ? ? ? ? ? 34 A R N6 1 27
+ATOM 1297 N N1 . A B 2 27 ? 17.515 -3.998 19.441 1.00 49.13 ? ? ? ? ? ? 34 A R N1 1 27
+ATOM 1298 C C2 . A B 2 27 ? 17.354 -2.711 19.106 1.00 49.13 ? ? ? ? ? ? 34 A R C2 1 27
+ATOM 1299 N N3 . A B 2 27 ? 18.290 -1.800 18.822 1.00 49.72 ? ? ? ? ? ? 34 A R N3 1 27
+ATOM 1300 C C4 . A B 2 27 ? 19.531 -2.314 18.908 1.00 49.62 ? ? ? ? ? ? 34 A R C4 1 27
+ATOM 1301 P P . A B 2 28 ? 22.801 2.583 21.687 1.00 53.86 ? ? ? ? ? ? 35 A R P 1 28
+ATOM 1302 O OP1 . A B 2 28 ? 23.178 4.002 21.865 1.00 53.79 ? ? ? ? ? ? 35 A R OP1 1 28
+ATOM 1303 O OP2 . A B 2 28 ? 23.645 1.520 22.280 1.00 53.01 ? ? ? ? ? ? 35 A R OP2 1 28
+ATOM 1304 O "O5'" . A B 2 28 ? 21.308 2.352 22.218 1.00 53.14 ? ? ? ? ? ? 35 A R "O5'" 1 28
+ATOM 1305 C "C5'" . A B 2 28 ? 20.402 3.437 22.382 1.00 52.47 ? ? ? ? ? ? 35 A R "C5'" 1 28
+ATOM 1306 C "C4'" . A B 2 28 ? 18.998 2.929 22.666 1.00 52.85 ? ? ? ? ? ? 35 A R "C4'" 1 28
+ATOM 1307 O "O4'" . A B 2 28 ? 18.675 1.828 21.776 1.00 51.59 ? ? ? ? ? ? 35 A R "O4'" 1 28
+ATOM 1308 C "C3'" . A B 2 28 ? 18.780 2.345 24.053 1.00 53.08 ? ? ? ? ? ? 35 A R "C3'" 1 28
+ATOM 1309 O "O3'" . A B 2 28 ? 18.546 3.363 25.014 1.00 55.52 ? ? ? ? ? ? 35 A R "O3'" 1 28
+ATOM 1310 C "C2'" . A B 2 28 ? 17.554 1.462 23.825 1.00 51.88 ? ? ? ? ? ? 35 A R "C2'" 1 28
+ATOM 1311 O "O2'" . A B 2 28 ? 16.329 2.169 23.769 1.00 50.77 ? ? ? ? ? ? 35 A R "O2'" 1 28
+ATOM 1312 C "C1'" . A B 2 28 ? 17.890 0.869 22.461 1.00 50.48 ? ? ? ? ? ? 35 A R "C1'" 1 28
+ATOM 1313 N N9 . A B 2 28 ? 18.635 -0.384 22.559 1.00 48.64 ? ? ? ? ? ? 35 A R N9 1 28
+ATOM 1314 C C8 . A B 2 28 ? 19.995 -0.546 22.610 1.00 49.70 ? ? ? ? ? ? 35 A R C8 1 28
+ATOM 1315 N N7 . A B 2 28 ? 20.384 -1.798 22.699 1.00 48.97 ? ? ? ? ? ? 35 A R N7 1 28
+ATOM 1316 C C5 . A B 2 28 ? 19.192 -2.508 22.711 1.00 46.90 ? ? ? ? ? ? 35 A R C5 1 28
+ATOM 1317 C C6 . A B 2 28 ? 18.911 -3.888 22.795 1.00 46.04 ? ? ? ? ? ? 35 A R C6 1 28
+ATOM 1318 N N6 . A B 2 28 ? 19.859 -4.832 22.882 1.00 46.58 ? ? ? ? ? ? 35 A R N6 1 28
+ATOM 1319 N N1 . A B 2 28 ? 17.612 -4.262 22.779 1.00 45.17 ? ? ? ? ? ? 35 A R N1 1 28
+ATOM 1320 C C2 . A B 2 28 ? 16.664 -3.315 22.691 1.00 45.35 ? ? ? ? ? ? 35 A R C2 1 28
+ATOM 1321 N N3 . A B 2 28 ? 16.805 -1.992 22.613 1.00 45.86 ? ? ? ? ? ? 35 A R N3 1 28
+ATOM 1322 C C4 . A B 2 28 ? 18.105 -1.650 22.628 1.00 46.96 ? ? ? ? ? ? 35 A R C4 1 28
+ATOM 1323 P P . G B 2 29 ? 19.511 3.530 26.284 1.00 58.20 ? ? ? ? ? ? 36 G R P 1 29
+ATOM 1324 O OP1 . G B 2 29 ? 18.775 4.376 27.253 1.00 57.99 ? ? ? ? ? ? 36 G R OP1 1 29
+ATOM 1325 O OP2 . G B 2 29 ? 20.855 3.939 25.807 1.00 55.69 ? ? ? ? ? ? 36 G R OP2 1 29
+ATOM 1326 O "O5'" . G B 2 29 ? 19.655 2.050 26.878 1.00 57.97 ? ? ? ? ? ? 36 G R "O5'" 1 29
+ATOM 1327 C "C5'" . G B 2 29 ? 18.560 1.412 27.534 1.00 57.83 ? ? ? ? ? ? 36 G R "C5'" 1 29
+ATOM 1328 C "C4'" . G B 2 29 ? 18.527 -0.076 27.225 1.00 57.14 ? ? ? ? ? ? 36 G R "C4'" 1 29
+ATOM 1329 O "O4'" . G B 2 29 ? 19.195 -0.379 25.969 1.00 56.01 ? ? ? ? ? ? 36 G R "O4'" 1 29
+ATOM 1330 C "C3'" . G B 2 29 ? 19.252 -0.970 28.216 1.00 56.29 ? ? ? ? ? ? 36 G R "C3'" 1 29
+ATOM 1331 O "O3'" . G B 2 29 ? 18.497 -1.147 29.413 1.00 54.08 ? ? ? ? ? ? 36 G R "O3'" 1 29
+ATOM 1332 C "C2'" . G B 2 29 ? 19.365 -2.246 27.386 1.00 56.82 ? ? ? ? ? ? 36 G R "C2'" 1 29
+ATOM 1333 O "O2'" . G B 2 29 ? 18.134 -2.940 27.256 1.00 58.92 ? ? ? ? ? ? 36 G R "O2'" 1 29
+ATOM 1334 C "C1'" . G B 2 29 ? 19.789 -1.662 26.038 1.00 53.98 ? ? ? ? ? ? 36 G R "C1'" 1 29
+ATOM 1335 N N9 . G B 2 29 ? 21.240 -1.527 25.870 1.00 51.24 ? ? ? ? ? ? 36 G R N9 1 29
+ATOM 1336 C C8 . G B 2 29 ? 21.969 -0.360 25.841 1.00 50.73 ? ? ? ? ? ? 36 G R C8 1 29
+ATOM 1337 N N7 . G B 2 29 ? 23.253 -0.536 25.681 1.00 48.03 ? ? ? ? ? ? 36 G R N7 1 29
+ATOM 1338 C C5 . G B 2 29 ? 23.393 -1.914 25.600 1.00 47.67 ? ? ? ? ? ? 36 G R C5 1 29
+ATOM 1339 C C6 . G B 2 29 ? 24.558 -2.703 25.430 1.00 46.74 ? ? ? ? ? ? 36 G R C6 1 29
+ATOM 1340 O O6 . G B 2 29 ? 25.729 -2.322 25.314 1.00 45.80 ? ? ? ? ? ? 36 G R O6 1 29
+ATOM 1341 N N1 . G B 2 29 ? 24.269 -4.067 25.399 1.00 46.80 ? ? ? ? ? ? 36 G R N1 1 29
+ATOM 1342 C C2 . G B 2 29 ? 23.003 -4.598 25.520 1.00 48.59 ? ? ? ? ? ? 36 G R C2 1 29
+ATOM 1343 N N2 . G B 2 29 ? 22.910 -5.934 25.471 1.00 48.06 ? ? ? ? ? ? 36 G R N2 1 29
+ATOM 1344 N N3 . G B 2 29 ? 21.900 -3.870 25.682 1.00 48.76 ? ? ? ? ? ? 36 G R N3 1 29
+ATOM 1345 C C4 . G B 2 29 ? 22.165 -2.538 25.714 1.00 49.31 ? ? ? ? ? ? 36 G R C4 1 29
+ATOM 1346 P P . A B 2 30 ? 19.268 -1.223 30.816 1.00 52.19 ? ? ? ? ? ? 37 A R P 1 30
+ATOM 1347 O OP1 . A B 2 30 ? 18.287 -1.000 31.901 1.00 52.56 ? ? ? ? ? ? 37 A R OP1 1 30
+ATOM 1348 O OP2 . A B 2 30 ? 20.468 -0.356 30.739 1.00 53.44 ? ? ? ? ? ? 37 A R OP2 1 30
+ATOM 1349 O "O5'" . A B 2 30 ? 19.758 -2.747 30.849 1.00 50.68 ? ? ? ? ? ? 37 A R "O5'" 1 30
+ATOM 1350 C "C5'" . A B 2 30 ? 18.810 -3.814 30.923 1.00 47.96 ? ? ? ? ? ? 37 A R "C5'" 1 30
+ATOM 1351 C "C4'" . A B 2 30 ? 19.407 -5.142 30.487 1.00 45.30 ? ? ? ? ? ? 37 A R "C4'" 1 30
+ATOM 1352 O "O4'" . A B 2 30 ? 20.061 -5.001 29.198 1.00 43.97 ? ? ? ? ? ? 37 A R "O4'" 1 30
+ATOM 1353 C "C3'" . A B 2 30 ? 20.502 -5.691 31.389 1.00 43.93 ? ? ? ? ? ? 37 A R "C3'" 1 30
+ATOM 1354 O "O3'" . A B 2 30 ? 19.963 -6.389 32.497 1.00 43.64 ? ? ? ? ? ? 37 A R "O3'" 1 30
+ATOM 1355 C "C2'" . A B 2 30 ? 21.231 -6.628 30.436 1.00 43.05 ? ? ? ? ? ? 37 A R "C2'" 1 30
+ATOM 1356 O "O2'" . A B 2 30 ? 20.541 -7.846 30.248 1.00 44.55 ? ? ? ? ? ? 37 A R "O2'" 1 30
+ATOM 1357 C "C1'" . A B 2 30 ? 21.228 -5.807 29.152 1.00 42.24 ? ? ? ? ? ? 37 A R "C1'" 1 30
+ATOM 1358 N N9 . A B 2 30 ? 22.415 -4.959 28.993 1.00 41.12 ? ? ? ? ? ? 37 A R N9 1 30
+ATOM 1359 C C8 . A B 2 30 ? 22.462 -3.591 29.039 1.00 41.53 ? ? ? ? ? ? 37 A R C8 1 30
+ATOM 1360 N N7 . A B 2 30 ? 23.662 -3.085 28.864 1.00 40.53 ? ? ? ? ? ? 37 A R N7 1 30
+ATOM 1361 C C5 . A B 2 30 ? 24.463 -4.195 28.689 1.00 39.80 ? ? ? ? ? ? 37 A R C5 1 30
+ATOM 1362 C C6 . A B 2 30 ? 25.847 -4.333 28.455 1.00 40.58 ? ? ? ? ? ? 37 A R C6 1 30
+ATOM 1363 N N6 . A B 2 30 ? 26.675 -3.287 28.360 1.00 39.26 ? ? ? ? ? ? 37 A R N6 1 30
+ATOM 1364 N N1 . A B 2 30 ? 26.346 -5.585 28.321 1.00 39.87 ? ? ? ? ? ? 37 A R N1 1 30
+ATOM 1365 C C2 . A B 2 30 ? 25.502 -6.622 28.415 1.00 41.00 ? ? ? ? ? ? 37 A R C2 1 30
+ATOM 1366 N N3 . A B 2 30 ? 24.183 -6.615 28.634 1.00 40.26 ? ? ? ? ? ? 37 A R N3 1 30
+ATOM 1367 C C4 . A B 2 30 ? 23.716 -5.360 28.764 1.00 40.22 ? ? ? ? ? ? 37 A R C4 1 30
+ATOM 1368 P P . G B 2 31 ? 20.801 -6.465 33.861 1.00 44.19 ? ? ? ? ? ? 38 G R P 1 31
+ATOM 1369 O OP1 . G B 2 31 ? 19.904 -7.043 34.886 1.00 44.89 ? ? ? ? ? ? 38 G R OP1 1 31
+ATOM 1370 O OP2 . G B 2 31 ? 21.425 -5.149 34.106 1.00 43.62 ? ? ? ? ? ? 38 G R OP2 1 31
+ATOM 1371 O "O5'" . G B 2 31 ? 21.993 -7.478 33.532 1.00 42.81 ? ? ? ? ? ? 38 G R "O5'" 1 31
+ATOM 1372 C "C5'" . G B 2 31 ? 21.780 -8.880 33.459 1.00 41.49 ? ? ? ? ? ? 38 G R "C5'" 1 31
+ATOM 1373 C "C4'" . G B 2 31 ? 23.070 -9.592 33.091 1.00 43.18 ? ? ? ? ? ? 38 G R "C4'" 1 31
+ATOM 1374 O "O4'" . G B 2 31 ? 23.612 -9.055 31.860 1.00 42.94 ? ? ? ? ? ? 38 G R "O4'" 1 31
+ATOM 1375 C "C3'" . G B 2 31 ? 24.221 -9.425 34.071 1.00 43.20 ? ? ? ? ? ? 38 G R "C3'" 1 31
+ATOM 1376 O "O3'" . G B 2 31 ? 24.055 -10.299 35.164 1.00 43.73 ? ? ? ? ? ? 38 G R "O3'" 1 31
+ATOM 1377 C "C2'" . G B 2 31 ? 25.407 -9.815 33.205 1.00 41.94 ? ? ? ? ? ? 38 G R "C2'" 1 31
+ATOM 1378 O "O2'" . G B 2 31 ? 25.520 -11.212 33.024 1.00 41.94 ? ? ? ? ? ? 38 G R "O2'" 1 31
+ATOM 1379 C "C1'" . G B 2 31 ? 25.026 -9.143 31.889 1.00 43.10 ? ? ? ? ? ? 38 G R "C1'" 1 31
+ATOM 1380 N N9 . G B 2 31 ? 25.602 -7.807 31.746 1.00 44.86 ? ? ? ? ? ? 38 G R N9 1 31
+ATOM 1381 C C8 . G B 2 31 ? 24.936 -6.604 31.741 1.00 45.13 ? ? ? ? ? ? 38 G R C8 1 31
+ATOM 1382 N N7 . G B 2 31 ? 25.720 -5.571 31.599 1.00 44.89 ? ? ? ? ? ? 38 G R N7 1 31
+ATOM 1383 C C5 . G B 2 31 ? 26.988 -6.123 31.511 1.00 45.32 ? ? ? ? ? ? 38 G R C5 1 31
+ATOM 1384 C C6 . G B 2 31 ? 28.243 -5.495 31.349 1.00 46.89 ? ? ? ? ? ? 38 G R C6 1 31
+ATOM 1385 O O6 . G B 2 31 ? 28.487 -4.287 31.253 1.00 50.65 ? ? ? ? ? ? 38 G R O6 1 31
+ATOM 1386 N N1 . G B 2 31 ? 29.288 -6.412 31.307 1.00 47.83 ? ? ? ? ? ? 38 G R N1 1 31
+ATOM 1387 C C2 . G B 2 31 ? 29.143 -7.776 31.406 1.00 47.49 ? ? ? ? ? ? 38 G R C2 1 31
+ATOM 1388 N N2 . G B 2 31 ? 30.275 -8.493 31.341 1.00 47.67 ? ? ? ? ? ? 38 G R N2 1 31
+ATOM 1389 N N3 . G B 2 31 ? 27.970 -8.384 31.552 1.00 45.77 ? ? ? ? ? ? 38 G R N3 1 31
+ATOM 1390 C C4 . G B 2 31 ? 26.938 -7.498 31.599 1.00 45.82 ? ? ? ? ? ? 38 G R C4 1 31
+ATOM 1391 P P . U B 2 32 ? 24.162 -9.740 36.657 1.00 44.51 ? ? ? ? ? ? 39 U R P 1 32
+ATOM 1392 O OP1 . U B 2 32 ? 23.503 -10.743 37.528 1.00 43.82 ? ? ? ? ? ? 39 U R OP1 1 32
+ATOM 1393 O OP2 . U B 2 32 ? 23.692 -8.336 36.680 1.00 44.11 ? ? ? ? ? ? 39 U R OP2 1 32
+ATOM 1394 O "O5'" . U B 2 32 ? 25.740 -9.730 36.933 1.00 42.60 ? ? ? ? ? ? 39 U R "O5'" 1 32
+ATOM 1395 C "C5'" . U B 2 32 ? 26.491 -10.927 36.778 1.00 43.07 ? ? ? ? ? ? 39 U R "C5'" 1 32
+ATOM 1396 C "C4'" . U B 2 32 ? 27.958 -10.640 36.533 1.00 44.22 ? ? ? ? ? ? 39 U R "C4'" 1 32
+ATOM 1397 O "O4'" . U B 2 32 ? 28.141 -9.947 35.275 1.00 43.57 ? ? ? ? ? ? 39 U R "O4'" 1 32
+ATOM 1398 C "C3'" . U B 2 32 ? 28.603 -9.687 37.523 1.00 46.48 ? ? ? ? ? ? 39 U R "C3'" 1 32
+ATOM 1399 O "O3'" . U B 2 32 ? 28.866 -10.319 38.765 1.00 46.94 ? ? ? ? ? ? 39 U R "O3'" 1 32
+ATOM 1400 C "C2'" . U B 2 32 ? 29.858 -9.288 36.758 1.00 45.68 ? ? ? ? ? ? 39 U R "C2'" 1 32
+ATOM 1401 O "O2'" . U B 2 32 ? 30.836 -10.311 36.728 1.00 46.72 ? ? ? ? ? ? 39 U R "O2'" 1 32
+ATOM 1402 C "C1'" . U B 2 32 ? 29.259 -9.079 35.370 1.00 44.61 ? ? ? ? ? ? 39 U R "C1'" 1 32
+ATOM 1403 N N1 . U B 2 32 ? 28.846 -7.656 35.102 1.00 45.89 ? ? ? ? ? ? 39 U R N1 1 32
+ATOM 1404 C C2 . U B 2 32 ? 29.813 -6.712 34.788 1.00 47.86 ? ? ? ? ? ? 39 U R C2 1 32
+ATOM 1405 O O2 . U B 2 32 ? 31.004 -6.959 34.716 1.00 48.89 ? ? ? ? ? ? 39 U R O2 1 32
+ATOM 1406 N N3 . U B 2 32 ? 29.338 -5.439 34.562 1.00 48.50 ? ? ? ? ? ? 39 U R N3 1 32
+ATOM 1407 C C4 . U B 2 32 ? 28.021 -5.019 34.612 1.00 48.94 ? ? ? ? ? ? 39 U R C4 1 32
+ATOM 1408 O O4 . U B 2 32 ? 27.750 -3.845 34.385 1.00 50.10 ? ? ? ? ? ? 39 U R O4 1 32
+ATOM 1409 C C5 . U B 2 32 ? 27.069 -6.052 34.940 1.00 48.62 ? ? ? ? ? ? 39 U R C5 1 32
+ATOM 1410 C C6 . U B 2 32 ? 27.508 -7.299 35.166 1.00 47.17 ? ? ? ? ? ? 39 U R C6 1 32
+ATOM 1411 P P . G B 2 33 ? 28.661 -9.463 40.100 1.00 46.70 ? ? ? ? ? ? 40 G R P 1 33
+ATOM 1412 O OP1 . G B 2 33 ? 28.707 -10.400 41.245 1.00 48.42 ? ? ? ? ? ? 40 G R OP1 1 33
+ATOM 1413 O OP2 . G B 2 33 ? 27.484 -8.579 39.938 1.00 45.90 ? ? ? ? ? ? 40 G R OP2 1 33
+ATOM 1414 O "O5'" . G B 2 33 ? 29.970 -8.542 40.100 1.00 48.32 ? ? ? ? ? ? 40 G R "O5'" 1 33
+ATOM 1415 C "C5'" . G B 2 33 ? 31.266 -9.105 40.315 1.00 48.50 ? ? ? ? ? ? 40 G R "C5'" 1 33
+ATOM 1416 C "C4'" . G B 2 33 ? 32.356 -8.056 40.164 1.00 49.16 ? ? ? ? ? ? 40 G R "C4'" 1 33
+ATOM 1417 O "O4'" . G B 2 33 ? 32.432 -7.604 38.786 1.00 49.52 ? ? ? ? ? ? 40 G R "O4'" 1 33
+ATOM 1418 C "C3'" . G B 2 33 ? 32.154 -6.765 40.944 1.00 48.95 ? ? ? ? ? ? 40 G R "C3'" 1 33
+ATOM 1419 O "O3'" . G B 2 33 ? 32.509 -6.919 42.303 1.00 50.51 ? ? ? ? ? ? 40 G R "O3'" 1 33
+ATOM 1420 C "C2'" . G B 2 33 ? 33.104 -5.839 40.195 1.00 48.68 ? ? ? ? ? ? 40 G R "C2'" 1 33
+ATOM 1421 O "O2'" . G B 2 33 ? 34.470 -6.059 40.491 1.00 48.19 ? ? ? ? ? ? 40 G R "O2'" 1 33
+ATOM 1422 C "C1'" . G B 2 33 ? 32.784 -6.231 38.758 1.00 48.39 ? ? ? ? ? ? 40 G R "C1'" 1 33
+ATOM 1423 N N9 . G B 2 33 ? 31.682 -5.434 38.216 1.00 48.51 ? ? ? ? ? ? 40 G R N9 1 33
+ATOM 1424 C C8 . G B 2 33 ? 30.376 -5.822 38.028 1.00 47.85 ? ? ? ? ? ? 40 G R C8 1 33
+ATOM 1425 N N7 . G B 2 33 ? 29.621 -4.883 37.528 1.00 48.63 ? ? ? ? ? ? 40 G R N7 1 33
+ATOM 1426 C C5 . G B 2 33 ? 30.475 -3.797 37.376 1.00 48.23 ? ? ? ? ? ? 40 G R C5 1 33
+ATOM 1427 C C6 . G B 2 33 ? 30.225 -2.489 36.882 1.00 48.37 ? ? ? ? ? ? 40 G R C6 1 33
+ATOM 1428 O O6 . G B 2 33 ? 29.156 -2.019 36.462 1.00 48.86 ? ? ? ? ? ? 40 G R O6 1 33
+ATOM 1429 N N1 . G B 2 33 ? 31.373 -1.694 36.900 1.00 47.02 ? ? ? ? ? ? 40 G R N1 1 33
+ATOM 1430 C C2 . G B 2 33 ? 32.606 -2.111 37.342 1.00 46.42 ? ? ? ? ? ? 40 G R C2 1 33
+ATOM 1431 N N2 . G B 2 33 ? 33.599 -1.216 37.286 1.00 46.60 ? ? ? ? ? ? 40 G R N2 1 33
+ATOM 1432 N N3 . G B 2 33 ? 32.852 -3.328 37.807 1.00 46.58 ? ? ? ? ? ? 40 G R N3 1 33
+ATOM 1433 C C4 . G B 2 33 ? 31.747 -4.119 37.800 1.00 48.20 ? ? ? ? ? ? 40 G R C4 1 33
+ATOM 1434 P P . G B 2 34 ? 31.803 -6.020 43.428 1.00 51.79 ? ? ? ? ? ? 41 G R P 1 34
+ATOM 1435 O OP1 . G B 2 34 ? 32.238 -6.556 44.736 1.00 50.89 ? ? ? ? ? ? 41 G R OP1 1 34
+ATOM 1436 O OP2 . G B 2 34 ? 30.356 -5.903 43.125 1.00 49.31 ? ? ? ? ? ? 41 G R OP2 1 34
+ATOM 1437 O "O5'" . G B 2 34 ? 32.464 -4.579 43.213 1.00 50.20 ? ? ? ? ? ? 41 G R "O5'" 1 34
+ATOM 1438 C "C5'" . G B 2 34 ? 33.840 -4.359 43.502 1.00 50.09 ? ? ? ? ? ? 41 G R "C5'" 1 34
+ATOM 1439 C "C4'" . G B 2 34 ? 34.306 -3.012 42.972 1.00 49.58 ? ? ? ? ? ? 41 G R "C4'" 1 34
+ATOM 1440 O "O4'" . G B 2 34 ? 34.019 -2.884 41.553 1.00 49.09 ? ? ? ? ? ? 41 G R "O4'" 1 34
+ATOM 1441 C "C3'" . G B 2 34 ? 33.620 -1.787 43.554 1.00 49.25 ? ? ? ? ? ? 41 G R "C3'" 1 34
+ATOM 1442 O "O3'" . G B 2 34 ? 34.098 -1.482 44.854 1.00 49.30 ? ? ? ? ? ? 41 G R "O3'" 1 34
+ATOM 1443 C "C2'" . G B 2 34 ? 34.043 -0.744 42.525 1.00 48.28 ? ? ? ? ? ? 41 G R "C2'" 1 34
+ATOM 1444 O "O2'" . G B 2 34 ? 35.415 -0.410 42.617 1.00 48.44 ? ? ? ? ? ? 41 G R "O2'" 1 34
+ATOM 1445 C "C1'" . G B 2 34 ? 33.779 -1.519 41.242 1.00 46.85 ? ? ? ? ? ? 41 G R "C1'" 1 34
+ATOM 1446 N N9 . G B 2 34 ? 32.419 -1.360 40.725 1.00 45.11 ? ? ? ? ? ? 41 G R N9 1 34
+ATOM 1447 C C8 . G B 2 34 ? 31.414 -2.297 40.746 1.00 44.97 ? ? ? ? ? ? 41 G R C8 1 34
+ATOM 1448 N N7 . G B 2 34 ? 30.299 -1.887 40.208 1.00 45.13 ? ? ? ? ? ? 41 G R N7 1 34
+ATOM 1449 C C5 . G B 2 34 ? 30.577 -0.591 39.798 1.00 44.76 ? ? ? ? ? ? 41 G R C5 1 34
+ATOM 1450 C C6 . G B 2 34 ? 29.745 0.356 39.145 1.00 45.41 ? ? ? ? ? ? 41 G R C6 1 34
+ATOM 1451 O O6 . G B 2 34 ? 28.562 0.230 38.792 1.00 45.47 ? ? ? ? ? ? 41 G R O6 1 34
+ATOM 1452 N N1 . G B 2 34 ? 30.412 1.556 38.903 1.00 44.98 ? ? ? ? ? ? 41 G R N1 1 34
+ATOM 1453 C C2 . G B 2 34 ? 31.720 1.805 39.249 1.00 44.31 ? ? ? ? ? ? 41 G R C2 1 34
+ATOM 1454 N N2 . G B 2 34 ? 32.189 3.020 38.933 1.00 44.23 ? ? ? ? ? ? 41 G R N2 1 34
+ATOM 1455 N N3 . G B 2 34 ? 32.511 0.925 39.859 1.00 43.72 ? ? ? ? ? ? 41 G R N3 1 34
+ATOM 1456 C C4 . G B 2 34 ? 31.878 -0.250 40.107 1.00 44.73 ? ? ? ? ? ? 41 G R C4 1 34
+ATOM 1457 P P . G B 2 35 ? 33.143 -0.770 45.924 1.00 51.11 ? ? ? ? ? ? 42 G R P 1 35
+ATOM 1458 O OP1 . G B 2 35 ? 34.010 -0.259 47.009 1.00 51.05 ? ? ? ? ? ? 42 G R OP1 1 35
+ATOM 1459 O OP2 . G B 2 35 ? 32.031 -1.698 46.228 1.00 51.32 ? ? ? ? ? ? 42 G R OP2 1 35
+ATOM 1460 O "O5'" . G B 2 35 ? 32.483 0.459 45.142 1.00 50.76 ? ? ? ? ? ? 42 G R "O5'" 1 35
+ATOM 1461 C "C5'" . G B 2 35 ? 33.118 1.726 45.039 1.00 50.33 ? ? ? ? ? ? 42 G R "C5'" 1 35
+ATOM 1462 C "C4'" . G B 2 35 ? 32.195 2.676 44.298 1.00 50.72 ? ? ? ? ? ? 42 G R "C4'" 1 35
+ATOM 1463 O "O4'" . G B 2 35 ? 31.640 2.016 43.131 1.00 48.78 ? ? ? ? ? ? 42 G R "O4'" 1 35
+ATOM 1464 C "C3'" . G B 2 35 ? 30.989 3.122 45.107 1.00 50.26 ? ? ? ? ? ? 42 G R "C3'" 1 35
+ATOM 1465 O "O3'" . G B 2 35 ? 31.354 4.266 45.871 1.00 51.31 ? ? ? ? ? ? 42 G R "O3'" 1 35
+ATOM 1466 C "C2'" . G B 2 35 ? 29.963 3.436 44.019 1.00 49.86 ? ? ? ? ? ? 42 G R "C2'" 1 35
+ATOM 1467 O "O2'" . G B 2 35 ? 30.077 4.753 43.515 1.00 51.59 ? ? ? ? ? ? 42 G R "O2'" 1 35
+ATOM 1468 C "C1'" . G B 2 35 ? 30.307 2.435 42.919 1.00 47.89 ? ? ? ? ? ? 42 G R "C1'" 1 35
+ATOM 1469 N N9 . G B 2 35 ? 29.436 1.259 42.894 1.00 45.85 ? ? ? ? ? ? 42 G R N9 1 35
+ATOM 1470 C C8 . G B 2 35 ? 29.644 0.068 43.546 1.00 45.91 ? ? ? ? ? ? 42 G R C8 1 35
+ATOM 1471 N N7 . G B 2 35 ? 28.701 -0.809 43.340 1.00 45.51 ? ? ? ? ? ? 42 G R N7 1 35
+ATOM 1472 C C5 . G B 2 35 ? 27.806 -0.163 42.499 1.00 43.67 ? ? ? ? ? ? 42 G R C5 1 35
+ATOM 1473 C C6 . G B 2 35 ? 26.584 -0.620 41.937 1.00 44.02 ? ? ? ? ? ? 42 G R C6 1 35
+ATOM 1474 O O6 . G B 2 35 ? 26.033 -1.723 42.075 1.00 43.11 ? ? ? ? ? ? 42 G R O6 1 35
+ATOM 1475 N N1 . G B 2 35 ? 25.986 0.349 41.135 1.00 43.67 ? ? ? ? ? ? 42 G R N1 1 35
+ATOM 1476 C C2 . G B 2 35 ? 26.507 1.603 40.910 1.00 43.58 ? ? ? ? ? ? 42 G R C2 1 35
+ATOM 1477 N N2 . G B 2 35 ? 25.791 2.408 40.110 1.00 44.89 ? ? ? ? ? ? 42 G R N2 1 35
+ATOM 1478 N N3 . G B 2 35 ? 27.647 2.038 41.433 1.00 41.86 ? ? ? ? ? ? 42 G R N3 1 35
+ATOM 1479 C C4 . G B 2 35 ? 28.245 1.111 42.216 1.00 42.98 ? ? ? ? ? ? 42 G R C4 1 35
+ATOM 1480 P P . A B 2 36 ? 30.465 4.786 47.100 1.00 52.33 ? ? ? ? ? ? 43 A R P 1 36
+ATOM 1481 O OP1 . A B 2 36 ? 31.357 5.592 47.961 1.00 53.58 ? ? ? ? ? ? 43 A R OP1 1 36
+ATOM 1482 O OP2 . A B 2 36 ? 29.712 3.644 47.664 1.00 52.58 ? ? ? ? ? ? 43 A R OP2 1 36
+ATOM 1483 O "O5'" . A B 2 36 ? 29.419 5.771 46.416 1.00 51.77 ? ? ? ? ? ? 43 A R "O5'" 1 36
+ATOM 1484 C "C5'" . A B 2 36 ? 28.291 6.189 47.152 1.00 52.46 ? ? ? ? ? ? 43 A R "C5'" 1 36
+ATOM 1485 C "C4'" . A B 2 36 ? 27.107 6.418 46.229 1.00 52.39 ? ? ? ? ? ? 43 A R "C4'" 1 36
+ATOM 1486 O "O4'" . A B 2 36 ? 26.932 5.274 45.353 1.00 50.60 ? ? ? ? ? ? 43 A R "O4'" 1 36
+ATOM 1487 C "C3'" . A B 2 36 ? 25.786 6.619 46.960 1.00 52.71 ? ? ? ? ? ? 43 A R "C3'" 1 36
+ATOM 1488 O "O3'" . A B 2 36 ? 25.046 7.652 46.335 1.00 55.18 ? ? ? ? ? ? 43 A R "O3'" 1 36
+ATOM 1489 C "C2'" . A B 2 36 ? 25.077 5.277 46.795 1.00 53.30 ? ? ? ? ? ? 43 A R "C2'" 1 36
+ATOM 1490 O "O2'" . A B 2 36 ? 23.668 5.412 46.769 1.00 54.56 ? ? ? ? ? ? 43 A R "O2'" 1 36
+ATOM 1491 C "C1'" . A B 2 36 ? 25.595 4.819 45.434 1.00 51.94 ? ? ? ? ? ? 43 A R "C1'" 1 36
+ATOM 1492 N N9 . A B 2 36 ? 25.561 3.371 45.210 1.00 50.70 ? ? ? ? ? ? 43 A R N9 1 36
+ATOM 1493 C C8 . A B 2 36 ? 24.875 2.734 44.212 1.00 50.32 ? ? ? ? ? ? 43 A R C8 1 36
+ATOM 1494 N N7 . A B 2 36 ? 25.004 1.430 44.217 1.00 49.68 ? ? ? ? ? ? 43 A R N7 1 36
+ATOM 1495 C C5 . A B 2 36 ? 25.836 1.189 45.295 1.00 50.21 ? ? ? ? ? ? 43 A R C5 1 36
+ATOM 1496 C C6 . A B 2 36 ? 26.363 -0.004 45.837 1.00 50.79 ? ? ? ? ? ? 43 A R C6 1 36
+ATOM 1497 N N6 . A B 2 36 ? 26.095 -1.208 45.326 1.00 49.84 ? ? ? ? ? ? 43 A R N6 1 36
+ATOM 1498 N N1 . A B 2 36 ? 27.174 0.088 46.920 1.00 52.32 ? ? ? ? ? ? 43 A R N1 1 36
+ATOM 1499 C C2 . A B 2 36 ? 27.437 1.304 47.428 1.00 51.59 ? ? ? ? ? ? 43 A R C2 1 36
+ATOM 1500 N N3 . A B 2 36 ? 26.996 2.494 47.001 1.00 51.17 ? ? ? ? ? ? 43 A R N3 1 36
+ATOM 1501 C C4 . A B 2 36 ? 26.194 2.372 45.922 1.00 50.16 ? ? ? ? ? ? 43 A R C4 1 36
+ATOM 1502 P P . C B 2 37 ? 25.237 9.201 46.692 1.00 57.03 ? ? ? ? ? ? 44 C R P 1 37
+ATOM 1503 O OP1 . C B 2 37 ? 26.222 9.752 45.727 1.00 56.12 ? ? ? ? ? ? 44 C R OP1 1 37
+ATOM 1504 O OP2 . C B 2 37 ? 25.474 9.358 48.148 1.00 56.22 ? ? ? ? ? ? 44 C R OP2 1 37
+ATOM 1505 O "O5'" . C B 2 37 ? 23.757 9.735 46.387 1.00 52.44 ? ? ? ? ? ? 44 C R "O5'" 1 37
+ATOM 1506 C "C5'" . C B 2 37 ? 23.516 10.797 45.483 1.00 48.40 ? ? ? ? ? ? 44 C R "C5'" 1 37
+ATOM 1507 C "C4'" . C B 2 37 ? 22.333 10.492 44.584 1.00 44.93 ? ? ? ? ? ? 44 C R "C4'" 1 37
+ATOM 1508 O "O4'" . C B 2 37 ? 22.527 9.245 43.881 1.00 44.65 ? ? ? ? ? ? 44 C R "O4'" 1 37
+ATOM 1509 C "C3'" . C B 2 37 ? 21.002 10.214 45.256 1.00 44.11 ? ? ? ? ? ? 44 C R "C3'" 1 37
+ATOM 1510 O "O3'" . C B 2 37 ? 20.425 11.371 45.832 1.00 44.49 ? ? ? ? ? ? 44 C R "O3'" 1 37
+ATOM 1511 C "C2'" . C B 2 37 ? 20.219 9.714 44.049 1.00 44.48 ? ? ? ? ? ? 44 C R "C2'" 1 37
+ATOM 1512 O "O2'" . C B 2 37 ? 19.804 10.730 43.161 1.00 45.65 ? ? ? ? ? ? 44 C R "O2'" 1 37
+ATOM 1513 C "C1'" . C B 2 37 ? 21.265 8.852 43.354 1.00 44.25 ? ? ? ? ? ? 44 C R "C1'" 1 37
+ATOM 1514 N N1 . C B 2 37 ? 21.016 7.375 43.529 1.00 43.78 ? ? ? ? ? ? 44 C R N1 1 37
+ATOM 1515 C C2 . C B 2 37 ? 19.950 6.749 42.847 1.00 42.83 ? ? ? ? ? ? 44 C R C2 1 37
+ATOM 1516 O O2 . C B 2 37 ? 19.214 7.405 42.099 1.00 41.60 ? ? ? ? ? ? 44 C R O2 1 37
+ATOM 1517 N N3 . C B 2 37 ? 19.746 5.418 43.026 1.00 42.89 ? ? ? ? ? ? 44 C R N3 1 37
+ATOM 1518 C C4 . C B 2 37 ? 20.551 4.718 43.833 1.00 43.67 ? ? ? ? ? ? 44 C R C4 1 37
+ATOM 1519 N N4 . C B 2 37 ? 20.313 3.410 43.972 1.00 44.22 ? ? ? ? ? ? 44 C R N4 1 37
+ATOM 1520 C C5 . C B 2 37 ? 21.637 5.328 44.536 1.00 43.51 ? ? ? ? ? ? 44 C R C5 1 37
+ATOM 1521 C C6 . C B 2 37 ? 21.829 6.642 44.358 1.00 43.72 ? ? ? ? ? ? 44 C R C6 1 37
+ATOM 1522 P P . G B 2 38 ? 19.380 11.223 47.042 1.00 45.07 ? ? ? ? ? ? 45 G R P 1 38
+ATOM 1523 O OP1 . G B 2 38 ? 19.337 12.529 47.735 1.00 41.50 ? ? ? ? ? ? 45 G R OP1 1 38
+ATOM 1524 O OP2 . G B 2 38 ? 19.689 9.972 47.783 1.00 43.11 ? ? ? ? ? ? 45 G R OP2 1 38
+ATOM 1525 O "O5'" . G B 2 38 ? 17.977 11.024 46.304 1.00 43.44 ? ? ? ? ? ? 45 G R "O5'" 1 38
+ATOM 1526 C "C5'" . G B 2 38 ? 16.994 10.169 46.858 1.00 43.41 ? ? ? ? ? ? 45 G R "C5'" 1 38
+ATOM 1527 C "C4'" . G B 2 38 ? 16.637 9.089 45.854 1.00 44.48 ? ? ? ? ? ? 45 G R "C4'" 1 38
+ATOM 1528 O "O4'" . G B 2 38 ? 17.831 8.359 45.475 1.00 44.34 ? ? ? ? ? ? 45 G R "O4'" 1 38
+ATOM 1529 C "C3'" . G B 2 38 ? 15.686 8.032 46.387 1.00 43.37 ? ? ? ? ? ? 45 G R "C3'" 1 38
+ATOM 1530 O "O3'" . G B 2 38 ? 14.328 8.451 46.218 1.00 42.53 ? ? ? ? ? ? 45 G R "O3'" 1 38
+ATOM 1531 C "C2'" . G B 2 38 ? 16.048 6.823 45.535 1.00 42.65 ? ? ? ? ? ? 45 G R "C2'" 1 38
+ATOM 1532 O "O2'" . G B 2 38 ? 15.456 6.887 44.256 1.00 42.86 ? ? ? ? ? ? 45 G R "O2'" 1 38
+ATOM 1533 C "C1'" . G B 2 38 ? 17.561 6.970 45.399 1.00 43.55 ? ? ? ? ? ? 45 G R "C1'" 1 38
+ATOM 1534 N N9 . G B 2 38 ? 18.374 6.268 46.403 1.00 44.12 ? ? ? ? ? ? 45 G R N9 1 38
+ATOM 1535 C C8 . G B 2 38 ? 19.247 6.824 47.314 1.00 43.89 ? ? ? ? ? ? 45 G R C8 1 38
+ATOM 1536 N N7 . G B 2 38 ? 19.846 5.956 48.083 1.00 42.13 ? ? ? ? ? ? 45 G R N7 1 38
+ATOM 1537 C C5 . G B 2 38 ? 19.341 4.740 47.653 1.00 42.81 ? ? ? ? ? ? 45 G R C5 1 38
+ATOM 1538 C C6 . G B 2 38 ? 19.618 3.431 48.112 1.00 44.14 ? ? ? ? ? ? 45 G R C6 1 38
+ATOM 1539 O O6 . G B 2 38 ? 20.391 3.095 49.024 1.00 45.94 ? ? ? ? ? ? 45 G R O6 1 38
+ATOM 1540 N N1 . G B 2 38 ? 18.898 2.464 47.403 1.00 44.37 ? ? ? ? ? ? 45 G R N1 1 38
+ATOM 1541 C C2 . G B 2 38 ? 18.012 2.738 46.383 1.00 44.72 ? ? ? ? ? ? 45 G R C2 1 38
+ATOM 1542 N N2 . G B 2 38 ? 17.398 1.695 45.808 1.00 44.15 ? ? ? ? ? ? 45 G R N2 1 38
+ATOM 1543 N N3 . G B 2 38 ? 17.745 3.963 45.948 1.00 44.64 ? ? ? ? ? ? 45 G R N3 1 38
+ATOM 1544 C C4 . G B 2 38 ? 18.442 4.911 46.622 1.00 43.43 ? ? ? ? ? ? 45 G R C4 1 38
+ATOM 1545 P P . C B 2 39 ? 13.264 8.018 47.333 1.00 42.35 ? ? ? ? ? ? 46 C R P 1 39
+ATOM 1546 O OP1 . C B 2 39 ? 11.995 8.754 47.122 1.00 38.48 ? ? ? ? ? ? 46 C R OP1 1 39
+ATOM 1547 O OP2 . C B 2 39 ? 13.968 8.074 48.638 1.00 42.04 ? ? ? ? ? ? 46 C R OP2 1 39
+ATOM 1548 O "O5'" . C B 2 39 ? 13.038 6.474 46.998 1.00 42.35 ? ? ? ? ? ? 46 C R "O5'" 1 39
+ATOM 1549 C "C5'" . C B 2 39 ? 12.257 6.057 45.884 1.00 42.72 ? ? ? ? ? ? 46 C R "C5'" 1 39
+ATOM 1550 C "C4'" . C B 2 39 ? 12.267 4.541 45.826 1.00 43.56 ? ? ? ? ? ? 46 C R "C4'" 1 39
+ATOM 1551 O "O4'" . C B 2 39 ? 13.642 4.107 45.882 1.00 43.58 ? ? ? ? ? ? 46 C R "O4'" 1 39
+ATOM 1552 C "C3'" . C B 2 39 ? 11.637 3.825 47.011 1.00 43.82 ? ? ? ? ? ? 46 C R "C3'" 1 39
+ATOM 1553 O "O3'" . C B 2 39 ? 10.237 3.694 46.849 1.00 44.65 ? ? ? ? ? ? 46 C R "O3'" 1 39
+ATOM 1554 C "C2'" . C B 2 39 ? 12.327 2.470 46.977 1.00 43.64 ? ? ? ? ? ? 46 C R "C2'" 1 39
+ATOM 1555 O "O2'" . C B 2 39 ? 11.742 1.570 46.058 1.00 46.61 ? ? ? ? ? ? 46 C R "O2'" 1 39
+ATOM 1556 C "C1'" . C B 2 39 ? 13.730 2.844 46.514 1.00 43.43 ? ? ? ? ? ? 46 C R "C1'" 1 39
+ATOM 1557 N N1 . C B 2 39 ? 14.734 2.898 47.622 1.00 41.58 ? ? ? ? ? ? 46 C R N1 1 39
+ATOM 1558 C C2 . C B 2 39 ? 15.249 1.701 48.143 1.00 42.96 ? ? ? ? ? ? 46 C R C2 1 39
+ATOM 1559 O O2 . C B 2 39 ? 14.870 0.617 47.677 1.00 43.48 ? ? ? ? ? ? 46 C R O2 1 39
+ATOM 1560 N N3 . C B 2 39 ? 16.159 1.760 49.152 1.00 43.65 ? ? ? ? ? ? 46 C R N3 1 39
+ATOM 1561 C C4 . C B 2 39 ? 16.546 2.943 49.633 1.00 43.09 ? ? ? ? ? ? 46 C R C4 1 39
+ATOM 1562 N N4 . C B 2 39 ? 17.441 2.953 50.626 1.00 43.69 ? ? ? ? ? ? 46 C R N4 1 39
+ATOM 1563 C C5 . C B 2 39 ? 16.030 4.170 49.113 1.00 43.36 ? ? ? ? ? ? 46 C R C5 1 39
+ATOM 1564 C C6 . C B 2 39 ? 15.136 4.101 48.121 1.00 41.05 ? ? ? ? ? ? 46 C R C6 1 39
+ATOM 1565 P P . A B 2 40 ? 9.259 4.280 47.969 1.00 44.44 ? ? ? ? ? ? 47 A R P 1 40
+ATOM 1566 O OP1 . A B 2 40 ? 8.289 5.159 47.280 1.00 43.91 ? ? ? ? ? ? 47 A R OP1 1 40
+ATOM 1567 O OP2 . A B 2 40 ? 10.102 4.809 49.066 1.00 43.82 ? ? ? ? ? ? 47 A R OP2 1 40
+ATOM 1568 O "O5'" . A B 2 40 ? 8.477 2.990 48.507 1.00 45.10 ? ? ? ? ? ? 47 A R "O5'" 1 40
+ATOM 1569 C "C5'" . A B 2 40 ? 9.176 1.947 49.190 1.00 46.36 ? ? ? ? ? ? 47 A R "C5'" 1 40
+ATOM 1570 C "C4'" . A B 2 40 ? 8.270 0.766 49.515 1.00 47.32 ? ? ? ? ? ? 47 A R "C4'" 1 40
+ATOM 1571 O "O4'" . A B 2 40 ? 8.989 -0.183 50.342 1.00 47.90 ? ? ? ? ? ? 47 A R "O4'" 1 40
+ATOM 1572 C "C3'" . A B 2 40 ? 7.010 1.057 50.317 1.00 47.66 ? ? ? ? ? ? 47 A R "C3'" 1 40
+ATOM 1573 O "O3'" . A B 2 40 ? 6.108 -0.014 50.173 1.00 48.86 ? ? ? ? ? ? 47 A R "O3'" 1 40
+ATOM 1574 C "C2'" . A B 2 40 ? 7.550 1.018 51.735 1.00 47.93 ? ? ? ? ? ? 47 A R "C2'" 1 40
+ATOM 1575 O "O2'" . A B 2 40 ? 6.521 0.826 52.682 1.00 49.51 ? ? ? ? ? ? 47 A R "O2'" 1 40
+ATOM 1576 C "C1'" . A B 2 40 ? 8.435 -0.222 51.646 1.00 47.50 ? ? ? ? ? ? 47 A R "C1'" 1 40
+ATOM 1577 N N9 . A B 2 40 ? 9.542 -0.298 52.602 1.00 47.73 ? ? ? ? ? ? 47 A R N9 1 40
+ATOM 1578 C C8 . A B 2 40 ? 10.145 0.737 53.264 1.00 47.31 ? ? ? ? ? ? 47 A R C8 1 40
+ATOM 1579 N N7 . A B 2 40 ? 11.122 0.359 54.054 1.00 48.47 ? ? ? ? ? ? 47 A R N7 1 40
+ATOM 1580 C C5 . A B 2 40 ? 11.166 -1.014 53.906 1.00 45.96 ? ? ? ? ? ? 47 A R C5 1 40
+ATOM 1581 C C6 . A B 2 40 ? 11.986 -2.006 54.482 1.00 46.35 ? ? ? ? ? ? 47 A R C6 1 40
+ATOM 1582 N N6 . A B 2 40 ? 12.957 -1.735 55.360 1.00 46.71 ? ? ? ? ? ? 47 A R N6 1 40
+ATOM 1583 N N1 . A B 2 40 ? 11.772 -3.292 54.123 1.00 47.25 ? ? ? ? ? ? 47 A R N1 1 40
+ATOM 1584 C C2 . A B 2 40 ? 10.796 -3.560 53.242 1.00 47.77 ? ? ? ? ? ? 47 A R C2 1 40
+ATOM 1585 N N3 . A B 2 40 ? 9.962 -2.710 52.636 1.00 47.19 ? ? ? ? ? ? 47 A R N3 1 40
+ATOM 1586 C C4 . A B 2 40 ? 10.202 -1.439 53.012 1.00 46.72 ? ? ? ? ? ? 47 A R C4 1 40
+ATOM 1587 P P . A B 2 41 ? 4.955 -0.091 49.076 1.00 51.51 ? ? ? ? ? ? 48 A R P 1 41
+ATOM 1588 O OP1 . A B 2 41 ? 5.265 0.820 47.948 1.00 51.90 ? ? ? ? ? ? 48 A R OP1 1 41
+ATOM 1589 O OP2 . A B 2 41 ? 3.646 0.007 49.757 1.00 52.49 ? ? ? ? ? ? 48 A R OP2 1 41
+ATOM 1590 O "O5'" . A B 2 41 ? 5.117 -1.628 48.662 1.00 51.05 ? ? ? ? ? ? 48 A R "O5'" 1 41
+ATOM 1591 C "C5'" . A B 2 41 ? 5.581 -2.012 47.387 1.00 48.96 ? ? ? ? ? ? 48 A R "C5'" 1 41
+ATOM 1592 C "C4'" . A B 2 41 ? 7.076 -2.256 47.406 1.00 47.63 ? ? ? ? ? ? 48 A R "C4'" 1 41
+ATOM 1593 O "O4'" . A B 2 41 ? 7.366 -3.557 47.994 1.00 47.54 ? ? ? ? ? ? 48 A R "O4'" 1 41
+ATOM 1594 C "C3'" . A B 2 41 ? 7.670 -2.294 46.000 1.00 48.38 ? ? ? ? ? ? 48 A R "C3'" 1 41
+ATOM 1595 O "O3'" . A B 2 41 ? 8.953 -1.683 45.942 1.00 47.50 ? ? ? ? ? ? 48 A R "O3'" 1 41
+ATOM 1596 C "C2'" . A B 2 41 ? 7.764 -3.785 45.722 1.00 47.48 ? ? ? ? ? ? 48 A R "C2'" 1 41
+ATOM 1597 O "O2'" . A B 2 41 ? 8.712 -4.111 44.727 1.00 47.73 ? ? ? ? ? ? 48 A R "O2'" 1 41
+ATOM 1598 C "C1'" . A B 2 41 ? 8.217 -4.251 47.099 1.00 46.30 ? ? ? ? ? ? 48 A R "C1'" 1 41
+ATOM 1599 N N9 . A B 2 41 ? 8.131 -5.703 47.214 1.00 44.07 ? ? ? ? ? ? 48 A R N9 1 41
+ATOM 1600 C C8 . A B 2 41 ? 7.038 -6.496 46.986 1.00 43.97 ? ? ? ? ? ? 48 A R C8 1 41
+ATOM 1601 N N7 . A B 2 41 ? 7.279 -7.776 47.136 1.00 43.91 ? ? ? ? ? ? 48 A R N7 1 41
+ATOM 1602 C C5 . A B 2 41 ? 8.622 -7.823 47.479 1.00 41.25 ? ? ? ? ? ? 48 A R C5 1 41
+ATOM 1603 C C6 . A B 2 41 ? 9.493 -8.888 47.778 1.00 40.57 ? ? ? ? ? ? 48 A R C6 1 41
+ATOM 1604 N N6 . A B 2 41 ? 9.103 -10.165 47.777 1.00 41.36 ? ? ? ? ? ? 48 A R N6 1 41
+ATOM 1605 N N1 . A B 2 41 ? 10.780 -8.596 48.082 1.00 41.01 ? ? ? ? ? ? 48 A R N1 1 41
+ATOM 1606 C C2 . A B 2 41 ? 11.169 -7.314 48.087 1.00 40.88 ? ? ? ? ? ? 48 A R C2 1 41
+ATOM 1607 N N3 . A B 2 41 ? 10.439 -6.228 47.823 1.00 41.29 ? ? ? ? ? ? 48 A R N3 1 41
+ATOM 1608 C C4 . A B 2 41 ? 9.166 -6.554 47.527 1.00 41.82 ? ? ? ? ? ? 48 A R C4 1 41
+ATOM 1609 P P . A B 2 42 ? 9.244 -0.667 44.749 1.00 47.34 ? ? ? ? ? ? 49 A R P 1 42
+ATOM 1610 O OP1 . A B 2 42 ? 9.187 0.705 45.299 1.00 47.04 ? ? ? ? ? ? 49 A R OP1 1 42
+ATOM 1611 O OP2 . A B 2 42 ? 8.388 -1.041 43.595 1.00 47.35 ? ? ? ? ? ? 49 A R OP2 1 42
+ATOM 1612 O "O5'" . A B 2 42 ? 10.757 -1.007 44.375 1.00 47.41 ? ? ? ? ? ? 49 A R "O5'" 1 42
+ATOM 1613 C "C5'" . A B 2 42 ? 11.069 -2.228 43.707 1.00 46.93 ? ? ? ? ? ? 49 A R "C5'" 1 42
+ATOM 1614 C "C4'" . A B 2 42 ? 12.558 -2.330 43.426 1.00 45.41 ? ? ? ? ? ? 49 A R "C4'" 1 42
+ATOM 1615 O "O4'" . A B 2 42 ? 12.939 -1.251 42.542 1.00 45.25 ? ? ? ? ? ? 49 A R "O4'" 1 42
+ATOM 1616 C "C3'" . A B 2 42 ? 13.487 -2.228 44.632 1.00 45.51 ? ? ? ? ? ? 49 A R "C3'" 1 42
+ATOM 1617 O "O3'" . A B 2 42 ? 14.614 -3.079 44.421 1.00 46.52 ? ? ? ? ? ? 49 A R "O3'" 1 42
+ATOM 1618 C "C2'" . A B 2 42 ? 13.887 -0.751 44.666 1.00 44.48 ? ? ? ? ? ? 49 A R "C2'" 1 42
+ATOM 1619 O "O2'" . A B 2 42 ? 15.206 -0.573 45.143 1.00 44.52 ? ? ? ? ? ? 49 A R "O2'" 1 42
+ATOM 1620 C "C1'" . A B 2 42 ? 13.820 -0.356 43.193 1.00 43.80 ? ? ? ? ? ? 49 A R "C1'" 1 42
+ATOM 1621 N N9 . A B 2 42 ? 13.351 0.999 42.903 1.00 42.51 ? ? ? ? ? ? 49 A R N9 1 42
+ATOM 1622 C C8 . A B 2 42 ? 12.136 1.356 42.382 1.00 42.71 ? ? ? ? ? ? 49 A R C8 1 42
+ATOM 1623 N N7 . A B 2 42 ? 11.991 2.649 42.202 1.00 41.67 ? ? ? ? ? ? 49 A R N7 1 42
+ATOM 1624 C C5 . A B 2 42 ? 13.195 3.175 42.631 1.00 40.69 ? ? ? ? ? ? 49 A R C5 1 42
+ATOM 1625 C C6 . A B 2 42 ? 13.685 4.495 42.700 1.00 40.78 ? ? ? ? ? ? 49 A R C6 1 42
+ATOM 1626 N N6 . A B 2 42 ? 12.985 5.567 42.328 1.00 41.62 ? ? ? ? ? ? 49 A R N6 1 42
+ATOM 1627 N N1 . A B 2 42 ? 14.931 4.682 43.177 1.00 41.13 ? ? ? ? ? ? 49 A R N1 1 42
+ATOM 1628 C C2 . A B 2 42 ? 15.643 3.613 43.564 1.00 42.39 ? ? ? ? ? ? 49 A R C2 1 42
+ATOM 1629 N N3 . A B 2 42 ? 15.294 2.325 43.544 1.00 41.56 ? ? ? ? ? ? 49 A R N3 1 42
+ATOM 1630 C C4 . A B 2 42 ? 14.047 2.172 43.061 1.00 41.16 ? ? ? ? ? ? 49 A R C4 1 42
+ATOM 1631 P P . G B 2 43 ? 14.830 -4.432 45.254 1.00 46.95 ? ? ? ? ? ? 50 G R P 1 43
+ATOM 1632 O OP1 . G B 2 43 ? 14.915 -4.082 46.690 1.00 47.70 ? ? ? ? ? ? 50 G R OP1 1 43
+ATOM 1633 O OP2 . G B 2 43 ? 15.952 -5.166 44.622 1.00 45.67 ? ? ? ? ? ? 50 G R OP2 1 43
+ATOM 1634 O "O5'" . G B 2 43 ? 13.472 -5.244 44.996 1.00 44.47 ? ? ? ? ? ? 50 G R "O5'" 1 43
+ATOM 1635 C "C5'" . G B 2 43 ? 13.208 -5.853 43.740 1.00 43.48 ? ? ? ? ? ? 50 G R "C5'" 1 43
+ATOM 1636 C "C4'" . G B 2 43 ? 13.210 -7.362 43.866 1.00 43.27 ? ? ? ? ? ? 50 G R "C4'" 1 43
+ATOM 1637 O "O4'" . G B 2 43 ? 12.263 -7.755 44.893 1.00 42.53 ? ? ? ? ? ? 50 G R "O4'" 1 43
+ATOM 1638 C "C3'" . G B 2 43 ? 12.767 -8.102 42.612 1.00 43.46 ? ? ? ? ? ? 50 G R "C3'" 1 43
+ATOM 1639 O "O3'" . G B 2 43 ? 13.883 -8.375 41.771 1.00 44.99 ? ? ? ? ? ? 50 G R "O3'" 1 43
+ATOM 1640 C "C2'" . G B 2 43 ? 12.169 -9.379 43.192 1.00 42.91 ? ? ? ? ? ? 50 G R "C2'" 1 43
+ATOM 1641 O "O2'" . G B 2 43 ? 13.156 -10.333 43.534 1.00 44.03 ? ? ? ? ? ? 50 G R "O2'" 1 43
+ATOM 1642 C "C1'" . G B 2 43 ? 11.483 -8.853 44.452 1.00 41.18 ? ? ? ? ? ? 50 G R "C1'" 1 43
+ATOM 1643 N N9 . G B 2 43 ? 10.107 -8.406 44.233 1.00 38.70 ? ? ? ? ? ? 50 G R N9 1 43
+ATOM 1644 C C8 . G B 2 43 ? 9.642 -7.114 44.307 1.00 37.65 ? ? ? ? ? ? 50 G R C8 1 43
+ATOM 1645 N N7 . G B 2 43 ? 8.365 -7.003 44.066 1.00 37.68 ? ? ? ? ? ? 50 G R N7 1 43
+ATOM 1646 C C5 . G B 2 43 ? 7.953 -8.303 43.810 1.00 36.40 ? ? ? ? ? ? 50 G R C5 1 43
+ATOM 1647 C C6 . G B 2 43 ? 6.671 -8.804 43.477 1.00 37.05 ? ? ? ? ? ? 50 G R C6 1 43
+ATOM 1648 O O6 . G B 2 43 ? 5.614 -8.173 43.342 1.00 37.59 ? ? ? ? ? ? 50 G R O6 1 43
+ATOM 1649 N N1 . G B 2 43 ? 6.674 -10.185 43.290 1.00 37.48 ? ? ? ? ? ? 50 G R N1 1 43
+ATOM 1650 C C2 . G B 2 43 ? 7.787 -10.980 43.413 1.00 38.03 ? ? ? ? ? ? 50 G R C2 1 43
+ATOM 1651 N N2 . G B 2 43 ? 7.598 -12.288 43.199 1.00 40.53 ? ? ? ? ? ? 50 G R N2 1 43
+ATOM 1652 N N3 . G B 2 43 ? 8.997 -10.524 43.721 1.00 37.80 ? ? ? ? ? ? 50 G R N3 1 43
+ATOM 1653 C C4 . G B 2 43 ? 9.012 -9.179 43.906 1.00 37.29 ? ? ? ? ? ? 50 G R C4 1 43
+ATOM 1654 P P . C B 2 44 ? 13.818 -8.093 40.194 1.00 45.41 ? ? ? ? ? ? 51 C R P 1 44
+ATOM 1655 O OP1 . C B 2 44 ? 15.136 -8.458 39.632 1.00 45.51 ? ? ? ? ? ? 51 C R OP1 1 44
+ATOM 1656 O OP2 . C B 2 44 ? 13.300 -6.720 40.000 1.00 47.90 ? ? ? ? ? ? 51 C R OP2 1 44
+ATOM 1657 O "O5'" . C B 2 44 ? 12.698 -9.100 39.649 1.00 44.83 ? ? ? ? ? ? 51 C R "O5'" 1 44
+ATOM 1658 C "C5'" . C B 2 44 ? 12.918 -10.507 39.627 1.00 45.29 ? ? ? ? ? ? 51 C R "C5'" 1 44
+ATOM 1659 C "C4'" . C B 2 44 ? 11.613 -11.268 39.472 1.00 45.75 ? ? ? ? ? ? 51 C R "C4'" 1 44
+ATOM 1660 O "O4'" . C B 2 44 ? 10.687 -10.934 40.536 1.00 46.23 ? ? ? ? ? ? 51 C R "O4'" 1 44
+ATOM 1661 C "C3'" . C B 2 44 ? 10.806 -10.940 38.227 1.00 46.47 ? ? ? ? ? ? 51 C R "C3'" 1 44
+ATOM 1662 O "O3'" . C B 2 44 ? 11.348 -11.575 37.091 1.00 46.60 ? ? ? ? ? ? 51 C R "O3'" 1 44
+ATOM 1663 C "C2'" . C B 2 44 ? 9.444 -11.508 38.603 1.00 46.63 ? ? ? ? ? ? 51 C R "C2'" 1 44
+ATOM 1664 O "O2'" . C B 2 44 ? 9.388 -12.921 38.525 1.00 49.14 ? ? ? ? ? ? 51 C R "O2'" 1 44
+ATOM 1665 C "C1'" . C B 2 44 ? 9.353 -11.058 40.056 1.00 45.84 ? ? ? ? ? ? 51 C R "C1'" 1 44
+ATOM 1666 N N1 . C B 2 44 ? 8.611 -9.763 40.221 1.00 45.10 ? ? ? ? ? ? 51 C R N1 1 44
+ATOM 1667 C C2 . C B 2 44 ? 7.210 -9.732 40.100 1.00 45.06 ? ? ? ? ? ? 51 C R C2 1 44
+ATOM 1668 O O2 . C B 2 44 ? 6.581 -10.768 39.859 1.00 43.14 ? ? ? ? ? ? 51 C R O2 1 44
+ATOM 1669 N N3 . C B 2 44 ? 6.567 -8.545 40.255 1.00 45.68 ? ? ? ? ? ? 51 C R N3 1 44
+ATOM 1670 C C4 . C B 2 44 ? 7.255 -7.430 40.520 1.00 44.03 ? ? ? ? ? ? 51 C R C4 1 44
+ATOM 1671 N N4 . C B 2 44 ? 6.568 -6.295 40.666 1.00 44.60 ? ? ? ? ? ? 51 C R N4 1 44
+ATOM 1672 C C5 . C B 2 44 ? 8.674 -7.434 40.648 1.00 43.53 ? ? ? ? ? ? 51 C R C5 1 44
+ATOM 1673 C C6 . C B 2 44 ? 9.299 -8.608 40.492 1.00 44.83 ? ? ? ? ? ? 51 C R C6 1 44
+ATOM 1674 P P . C B 2 45 ? 11.224 -10.860 35.670 1.00 47.31 ? ? ? ? ? ? 52 C R P 1 45
+ATOM 1675 O OP1 . C B 2 45 ? 12.072 -11.630 34.730 1.00 46.90 ? ? ? ? ? ? 52 C R OP1 1 45
+ATOM 1676 O OP2 . C B 2 45 ? 11.449 -9.404 35.844 1.00 45.44 ? ? ? ? ? ? 52 C R OP2 1 45
+ATOM 1677 O "O5'" . C B 2 45 ? 9.679 -11.078 35.300 1.00 46.82 ? ? ? ? ? ? 52 C R "O5'" 1 45
+ATOM 1678 C "C5'" . C B 2 45 ? 9.287 -12.186 34.497 1.00 46.25 ? ? ? ? ? ? 52 C R "C5'" 1 45
+ATOM 1679 C "C4'" . C B 2 45 ? 7.780 -12.268 34.376 1.00 45.47 ? ? ? ? ? ? 52 C R "C4'" 1 45
+ATOM 1680 O "O4'" . C B 2 45 ? 7.159 -11.805 35.606 1.00 43.62 ? ? ? ? ? ? 52 C R "O4'" 1 45
+ATOM 1681 C "C3'" . C B 2 45 ? 7.188 -11.377 33.298 1.00 46.15 ? ? ? ? ? ? 52 C R "C3'" 1 45
+ATOM 1682 O "O3'" . C B 2 45 ? 7.304 -11.973 32.000 1.00 47.35 ? ? ? ? ? ? 52 C R "O3'" 1 45
+ATOM 1683 C "C2'" . C B 2 45 ? 5.746 -11.267 33.781 1.00 44.90 ? ? ? ? ? ? 52 C R "C2'" 1 45
+ATOM 1684 O "O2'" . C B 2 45 ? 4.977 -12.401 33.430 1.00 43.53 ? ? ? ? ? ? 52 C R "O2'" 1 45
+ATOM 1685 C "C1'" . C B 2 45 ? 5.929 -11.169 35.302 1.00 43.74 ? ? ? ? ? ? 52 C R "C1'" 1 45
+ATOM 1686 N N1 . C B 2 45 ? 5.951 -9.755 35.839 1.00 42.95 ? ? ? ? ? ? 52 C R N1 1 45
+ATOM 1687 C C2 . C B 2 45 ? 4.769 -8.993 35.949 1.00 43.00 ? ? ? ? ? ? 52 C R C2 1 45
+ATOM 1688 O O2 . C B 2 45 ? 3.681 -9.470 35.612 1.00 44.02 ? ? ? ? ? ? 52 C R O2 1 45
+ATOM 1689 N N3 . C B 2 45 ? 4.840 -7.724 36.433 1.00 42.38 ? ? ? ? ? ? 52 C R N3 1 45
+ATOM 1690 C C4 . C B 2 45 ? 6.014 -7.206 36.804 1.00 42.74 ? ? ? ? ? ? 52 C R C4 1 45
+ATOM 1691 N N4 . C B 2 45 ? 6.030 -5.955 37.278 1.00 43.12 ? ? ? ? ? ? 52 C R N4 1 45
+ATOM 1692 C C5 . C B 2 45 ? 7.225 -7.954 36.708 1.00 42.43 ? ? ? ? ? ? 52 C R C5 1 45
+ATOM 1693 C C6 . C B 2 45 ? 7.144 -9.202 36.226 1.00 43.56 ? ? ? ? ? ? 52 C R C6 1 45
+ATOM 1694 P P . U B 2 46 ? 8.138 -11.249 30.828 1.00 48.68 ? ? ? ? ? ? 53 U R P 1 46
+ATOM 1695 O OP1 . U B 2 46 ? 8.489 -12.289 29.839 1.00 47.12 ? ? ? ? ? ? 53 U R OP1 1 46
+ATOM 1696 O OP2 . U B 2 46 ? 9.230 -10.441 31.421 1.00 48.44 ? ? ? ? ? ? 53 U R OP2 1 46
+ATOM 1697 O "O5'" . U B 2 46 ? 7.083 -10.220 30.199 1.00 49.66 ? ? ? ? ? ? 53 U R "O5'" 1 46
+ATOM 1698 C "C5'" . U B 2 46 ? 5.921 -10.671 29.502 1.00 54.40 ? ? ? ? ? ? 53 U R "C5'" 1 46
+ATOM 1699 C "C4'" . U B 2 46 ? 4.963 -9.523 29.198 1.00 57.53 ? ? ? ? ? ? 53 U R "C4'" 1 46
+ATOM 1700 O "O4'" . U B 2 46 ? 5.287 -8.340 29.980 1.00 58.88 ? ? ? ? ? ? 53 U R "O4'" 1 46
+ATOM 1701 C "C3'" . U B 2 46 ? 4.914 -9.062 27.740 1.00 59.19 ? ? ? ? ? ? 53 U R "C3'" 1 46
+ATOM 1702 O "O3'" . U B 2 46 ? 3.560 -8.799 27.368 1.00 61.47 ? ? ? ? ? ? 53 U R "O3'" 1 46
+ATOM 1703 C "C2'" . U B 2 46 ? 5.745 -7.780 27.752 1.00 59.32 ? ? ? ? ? ? 53 U R "C2'" 1 46
+ATOM 1704 O "O2'" . U B 2 46 ? 5.377 -6.857 26.745 1.00 57.74 ? ? ? ? ? ? 53 U R "O2'" 1 46
+ATOM 1705 C "C1'" . U B 2 46 ? 5.371 -7.220 29.121 1.00 59.06 ? ? ? ? ? ? 53 U R "C1'" 1 46
+ATOM 1706 N N1 . U B 2 46 ? 6.340 -6.249 29.712 1.00 58.09 ? ? ? ? ? ? 53 U R N1 1 46
+ATOM 1707 C C2 . U B 2 46 ? 5.859 -5.056 30.218 1.00 58.80 ? ? ? ? ? ? 53 U R C2 1 46
+ATOM 1708 O O2 . U B 2 46 ? 4.677 -4.755 30.201 1.00 58.05 ? ? ? ? ? ? 53 U R O2 1 46
+ATOM 1709 N N3 . U B 2 46 ? 6.820 -4.221 30.752 1.00 59.01 ? ? ? ? ? ? 53 U R N3 1 46
+ATOM 1710 C C4 . U B 2 46 ? 8.187 -4.464 30.825 1.00 60.61 ? ? ? ? ? ? 53 U R C4 1 46
+ATOM 1711 O O4 . U B 2 46 ? 8.943 -3.633 31.329 1.00 61.27 ? ? ? ? ? ? 53 U R O4 1 46
+ATOM 1712 C C5 . U B 2 46 ? 8.606 -5.731 30.274 1.00 60.10 ? ? ? ? ? ? 53 U R C5 1 46
+ATOM 1713 C C6 . U B 2 46 ? 7.688 -6.556 29.750 1.00 58.38 ? ? ? ? ? ? 53 U R C6 1 46
+ATOM 1714 P P . C B 2 47 ? 2.584 -9.951 26.828 1.00 64.91 ? ? ? ? ? ? 54 C R P 1 47
+ATOM 1715 O OP1 . C B 2 47 ? 2.979 -11.258 27.407 1.00 63.17 ? ? ? ? ? ? 54 C R OP1 1 47
+ATOM 1716 O OP2 . C B 2 47 ? 2.483 -9.798 25.359 1.00 65.09 ? ? ? ? ? ? 54 C R OP2 1 47
+ATOM 1717 O "O5'" . C B 2 47 ? 1.185 -9.501 27.460 1.00 65.30 ? ? ? ? ? ? 54 C R "O5'" 1 47
+ATOM 1718 C "C5'" . C B 2 47 ? 0.024 -10.322 27.343 1.00 66.07 ? ? ? ? ? ? 54 C R "C5'" 1 47
+ATOM 1719 C "C4'" . C B 2 47 ? -1.185 -9.644 27.967 1.00 66.39 ? ? ? ? ? ? 54 C R "C4'" 1 47
+ATOM 1720 O "O4'" . C B 2 47 ? -1.087 -9.717 29.411 1.00 65.78 ? ? ? ? ? ? 54 C R "O4'" 1 47
+ATOM 1721 C "C3'" . C B 2 47 ? -1.312 -8.159 27.662 1.00 66.72 ? ? ? ? ? ? 54 C R "C3'" 1 47
+ATOM 1722 O "O3'" . C B 2 47 ? -2.036 -7.964 26.455 1.00 67.66 ? ? ? ? ? ? 54 C R "O3'" 1 47
+ATOM 1723 C "C2'" . C B 2 47 ? -2.044 -7.617 28.886 1.00 66.13 ? ? ? ? ? ? 54 C R "C2'" 1 47
+ATOM 1724 O "O2'" . C B 2 47 ? -3.449 -7.770 28.809 1.00 66.82 ? ? ? ? ? ? 54 C R "O2'" 1 47
+ATOM 1725 C "C1'" . C B 2 47 ? -1.474 -8.487 30.002 1.00 65.57 ? ? ? ? ? ? 54 C R "C1'" 1 47
+ATOM 1726 N N1 . C B 2 47 ? -0.310 -7.864 30.746 1.00 65.06 ? ? ? ? ? ? 54 C R N1 1 47
+ATOM 1727 C C2 . C B 2 47 ? -0.545 -6.896 31.745 1.00 64.59 ? ? ? ? ? ? 54 C R C2 1 47
+ATOM 1728 O O2 . C B 2 47 ? -1.699 -6.547 32.019 1.00 64.26 ? ? ? ? ? ? 54 C R O2 1 47
+ATOM 1729 N N3 . C B 2 47 ? 0.512 -6.352 32.401 1.00 64.26 ? ? ? ? ? ? 54 C R N3 1 47
+ATOM 1730 C C4 . C B 2 47 ? 1.757 -6.733 32.100 1.00 64.92 ? ? ? ? ? ? 54 C R C4 1 47
+ATOM 1731 N N4 . C B 2 47 ? 2.760 -6.164 32.775 1.00 64.83 ? ? ? ? ? ? 54 C R N4 1 47
+ATOM 1732 C C5 . C B 2 47 ? 2.024 -7.713 31.093 1.00 64.53 ? ? ? ? ? ? 54 C R C5 1 47
+ATOM 1733 C C6 . C B 2 47 ? 0.975 -8.243 30.454 1.00 63.98 ? ? ? ? ? ? 54 C R C6 1 47
+ATOM 1734 P P . C B 2 48 ? -1.674 -6.723 25.517 1.00 68.81 ? ? ? ? ? ? 55 C R P 1 48
+ATOM 1735 O OP1 . C B 2 48 ? -2.447 -6.864 24.261 1.00 69.41 ? ? ? ? ? ? 55 C R OP1 1 48
+ATOM 1736 O OP2 . C B 2 48 ? -0.200 -6.603 25.448 1.00 67.86 ? ? ? ? ? ? 55 C R OP2 1 48
+ATOM 1737 O "O5'" . C B 2 48 ? -2.242 -5.482 26.358 1.00 69.07 ? ? ? ? ? ? 55 C R "O5'" 1 48
+ATOM 1738 C "C5'" . C B 2 48 ? -3.646 -5.221 26.427 1.00 69.11 ? ? ? ? ? ? 55 C R "C5'" 1 48
+ATOM 1739 C "C4'" . C B 2 48 ? -3.923 -3.891 27.104 1.00 69.61 ? ? ? ? ? ? 55 C R "C4'" 1 48
+ATOM 1740 O "O4'" . C B 2 48 ? -3.596 -3.997 28.516 1.00 69.65 ? ? ? ? ? ? 55 C R "O4'" 1 48
+ATOM 1741 C "C3'" . C B 2 48 ? -3.074 -2.716 26.634 1.00 70.13 ? ? ? ? ? ? 55 C R "C3'" 1 48
+ATOM 1742 O "O3'" . C B 2 48 ? -3.542 -2.139 25.412 1.00 71.13 ? ? ? ? ? ? 55 C R "O3'" 1 48
+ATOM 1743 C "C2'" . C B 2 48 ? -3.199 -1.771 27.825 1.00 69.72 ? ? ? ? ? ? 55 C R "C2'" 1 48
+ATOM 1744 O "O2'" . C B 2 48 ? -4.425 -1.063 27.857 1.00 70.48 ? ? ? ? ? ? 55 C R "O2'" 1 48
+ATOM 1745 C "C1'" . C B 2 48 ? -3.094 -2.756 28.991 1.00 68.89 ? ? ? ? ? ? 55 C R "C1'" 1 48
+ATOM 1746 N N1 . C B 2 48 ? -1.672 -2.897 29.486 1.00 67.73 ? ? ? ? ? ? 55 C R N1 1 48
+ATOM 1747 C C2 . C B 2 48 ? -1.115 -1.908 30.324 1.00 66.72 ? ? ? ? ? ? 55 C R C2 1 48
+ATOM 1748 O O2 . C B 2 48 ? -1.786 -0.928 30.673 1.00 66.06 ? ? ? ? ? ? 55 C R O2 1 48
+ATOM 1749 N N3 . C B 2 48 ? 0.167 -2.051 30.746 1.00 65.96 ? ? ? ? ? ? 55 C R N3 1 48
+ATOM 1750 C C4 . C B 2 48 ? 0.889 -3.110 30.372 1.00 66.12 ? ? ? ? ? ? 55 C R C4 1 48
+ATOM 1751 N N4 . C B 2 48 ? 2.144 -3.192 30.825 1.00 65.85 ? ? ? ? ? ? 55 C R N4 1 48
+ATOM 1752 C C5 . C B 2 48 ? 0.355 -4.127 29.520 1.00 66.17 ? ? ? ? ? ? 55 C R C5 1 48
+ATOM 1753 C C6 . C B 2 48 ? -0.912 -3.978 29.109 1.00 67.27 ? ? ? ? ? ? 55 C R C6 1 48
+ATOM 1754 P P . G B 2 49 ? -2.484 -1.496 24.388 1.00 71.07 ? ? ? ? ? ? 56 G R P 1 49
+ATOM 1755 O OP1 . G B 2 49 ? -3.206 -1.125 23.152 1.00 69.59 ? ? ? ? ? ? 56 G R OP1 1 49
+ATOM 1756 O OP2 . G B 2 49 ? -1.316 -2.403 24.306 1.00 72.26 ? ? ? ? ? ? 56 G R OP2 1 49
+ATOM 1757 O "O5'" . G B 2 49 ? -1.997 -0.169 25.135 1.00 70.09 ? ? ? ? ? ? 56 G R "O5'" 1 49
+ATOM 1758 C "C5'" . G B 2 49 ? -2.853 0.960 25.173 1.00 70.52 ? ? ? ? ? ? 56 G R "C5'" 1 49
+ATOM 1759 C "C4'" . G B 2 49 ? -2.377 1.985 26.182 1.00 70.37 ? ? ? ? ? ? 56 G R "C4'" 1 49
+ATOM 1760 O "O4'" . G B 2 49 ? -2.024 1.355 27.441 1.00 69.03 ? ? ? ? ? ? 56 G R "O4'" 1 49
+ATOM 1761 C "C3'" . G B 2 49 ? -1.099 2.727 25.832 1.00 71.29 ? ? ? ? ? ? 56 G R "C3'" 1 49
+ATOM 1762 O "O3'" . G B 2 49 ? -1.282 3.677 24.778 1.00 73.32 ? ? ? ? ? ? 56 G R "O3'" 1 49
+ATOM 1763 C "C2'" . G B 2 49 ? -0.848 3.381 27.187 1.00 70.15 ? ? ? ? ? ? 56 G R "C2'" 1 49
+ATOM 1764 O "O2'" . G B 2 49 ? -1.722 4.456 27.464 1.00 71.67 ? ? ? ? ? ? 56 G R "O2'" 1 49
+ATOM 1765 C "C1'" . G B 2 49 ? -1.125 2.211 28.132 1.00 68.21 ? ? ? ? ? ? 56 G R "C1'" 1 49
+ATOM 1766 N N9 . G B 2 49 ? 0.118 1.509 28.466 1.00 66.22 ? ? ? ? ? ? 56 G R N9 1 49
+ATOM 1767 C C8 . G B 2 49 ? 0.498 0.241 28.086 1.00 65.38 ? ? ? ? ? ? 56 G R C8 1 49
+ATOM 1768 N N7 . G B 2 49 ? 1.676 -0.105 28.526 1.00 63.88 ? ? ? ? ? ? 56 G R N7 1 49
+ATOM 1769 C C5 . G B 2 49 ? 2.112 1.006 29.239 1.00 63.04 ? ? ? ? ? ? 56 G R C5 1 49
+ATOM 1770 C C6 . G B 2 49 ? 3.322 1.229 29.944 1.00 62.11 ? ? ? ? ? ? 56 G R C6 1 49
+ATOM 1771 O O6 . G B 2 49 ? 4.279 0.457 30.079 1.00 60.80 ? ? ? ? ? ? 56 G R O6 1 49
+ATOM 1772 N N1 . G B 2 49 ? 3.373 2.494 30.533 1.00 61.90 ? ? ? ? ? ? 56 G R N1 1 49
+ATOM 1773 C C2 . G B 2 49 ? 2.370 3.432 30.446 1.00 62.39 ? ? ? ? ? ? 56 G R C2 1 49
+ATOM 1774 N N2 . G B 2 49 ? 2.583 4.598 31.071 1.00 62.64 ? ? ? ? ? ? 56 G R N2 1 49
+ATOM 1775 N N3 . G B 2 49 ? 1.233 3.238 29.788 1.00 62.60 ? ? ? ? ? ? 56 G R N3 1 49
+ATOM 1776 C C4 . G B 2 49 ? 1.168 2.009 29.209 1.00 63.77 ? ? ? ? ? ? 56 G R C4 1 49
+ATOM 1777 P P . G B 2 50 ? -0.085 4.016 23.757 1.00 75.33 ? ? ? ? ? ? 57 G R P 1 50
+ATOM 1778 O OP1 . G B 2 50 ? -0.597 5.022 22.796 1.00 74.12 ? ? ? ? ? ? 57 G R OP1 1 50
+ATOM 1779 O OP2 . G B 2 50 ? 0.475 2.738 23.256 1.00 74.57 ? ? ? ? ? ? 57 G R OP2 1 50
+ATOM 1780 O "O5'" . G B 2 50 ? 1.039 4.692 24.679 1.00 72.62 ? ? ? ? ? ? 57 G R "O5'" 1 50
+ATOM 1781 C "C5'" . G B 2 50 ? 0.908 6.045 25.089 1.00 70.25 ? ? ? ? ? ? 57 G R "C5'" 1 50
+ATOM 1782 C "C4'" . G B 2 50 ? 1.990 6.442 26.077 1.00 68.44 ? ? ? ? ? ? 57 G R "C4'" 1 50
+ATOM 1783 O "O4'" . G B 2 50 ? 2.130 5.455 27.130 1.00 67.93 ? ? ? ? ? ? 57 G R "O4'" 1 50
+ATOM 1784 C "C3'" . G B 2 50 ? 3.389 6.533 25.501 1.00 67.83 ? ? ? ? ? ? 57 G R "C3'" 1 50
+ATOM 1785 O "O3'" . G B 2 50 ? 3.544 7.750 24.788 1.00 67.62 ? ? ? ? ? ? 57 G R "O3'" 1 50
+ATOM 1786 C "C2'" . G B 2 50 ? 4.228 6.480 26.775 1.00 67.28 ? ? ? ? ? ? 57 G R "C2'" 1 50
+ATOM 1787 O "O2'" . G B 2 50 ? 4.245 7.701 27.493 1.00 67.41 ? ? ? ? ? ? 57 G R "O2'" 1 50
+ATOM 1788 C "C1'" . G B 2 50 ? 3.480 5.411 27.565 1.00 65.42 ? ? ? ? ? ? 57 G R "C1'" 1 50
+ATOM 1789 N N9 . G B 2 50 ? 3.992 4.050 27.384 1.00 62.94 ? ? ? ? ? ? 57 G R N9 1 50
+ATOM 1790 C C8 . G B 2 50 ? 3.357 3.008 26.749 1.00 61.94 ? ? ? ? ? ? 57 G R C8 1 50
+ATOM 1791 N N7 . G B 2 50 ? 4.045 1.901 26.738 1.00 61.98 ? ? ? ? ? ? 57 G R N7 1 50
+ATOM 1792 C C5 . G B 2 50 ? 5.214 2.221 27.415 1.00 62.24 ? ? ? ? ? ? 57 G R C5 1 50
+ATOM 1793 C C6 . G B 2 50 ? 6.345 1.415 27.723 1.00 62.49 ? ? ? ? ? ? 57 G R C6 1 50
+ATOM 1794 O O6 . G B 2 50 ? 6.537 0.220 27.442 1.00 63.27 ? ? ? ? ? ? 57 G R O6 1 50
+ATOM 1795 N N1 . G B 2 50 ? 7.322 2.129 28.421 1.00 61.21 ? ? ? ? ? ? 57 G R N1 1 50
+ATOM 1796 C C2 . G B 2 50 ? 7.215 3.454 28.781 1.00 61.37 ? ? ? ? ? ? 57 G R C2 1 50
+ATOM 1797 N N2 . G B 2 50 ? 8.253 3.973 29.450 1.00 60.62 ? ? ? ? ? ? 57 G R N2 1 50
+ATOM 1798 N N3 . G B 2 50 ? 6.161 4.217 28.502 1.00 61.88 ? ? ? ? ? ? 57 G R N3 1 50
+ATOM 1799 C C4 . G B 2 50 ? 5.198 3.542 27.820 1.00 62.34 ? ? ? ? ? ? 57 G R C4 1 50
+ATOM 1800 P P . C B 2 51 ? 4.331 7.764 23.394 1.00 66.82 ? ? ? ? ? ? 58 C R P 1 51
+ATOM 1801 O OP1 . C B 2 51 ? 4.146 9.102 22.794 1.00 64.78 ? ? ? ? ? ? 58 C R OP1 1 51
+ATOM 1802 O OP2 . C B 2 51 ? 3.955 6.551 22.628 1.00 65.42 ? ? ? ? ? ? 58 C R OP2 1 51
+ATOM 1803 O "O5'" . C B 2 51 ? 5.853 7.597 23.862 1.00 65.33 ? ? ? ? ? ? 58 C R "O5'" 1 51
+ATOM 1804 C "C5'" . C B 2 51 ? 6.470 8.558 24.720 1.00 63.15 ? ? ? ? ? ? 58 C R "C5'" 1 51
+ATOM 1805 C "C4'" . C B 2 51 ? 7.754 8.014 25.325 1.00 61.23 ? ? ? ? ? ? 58 C R "C4'" 1 51
+ATOM 1806 O "O4'" . C B 2 51 ? 7.477 6.872 26.179 1.00 60.71 ? ? ? ? ? ? 58 C R "O4'" 1 51
+ATOM 1807 C "C3'" . C B 2 51 ? 8.746 7.463 24.317 1.00 60.20 ? ? ? ? ? ? 58 C R "C3'" 1 51
+ATOM 1808 O "O3'" . C B 2 51 ? 9.461 8.522 23.692 1.00 59.53 ? ? ? ? ? ? 58 C R "O3'" 1 51
+ATOM 1809 C "C2'" . C B 2 51 ? 9.603 6.564 25.208 1.00 60.13 ? ? ? ? ? ? 58 C R "C2'" 1 51
+ATOM 1810 O "O2'" . C B 2 51 ? 10.540 7.271 26.001 1.00 59.39 ? ? ? ? ? ? 58 C R "O2'" 1 51
+ATOM 1811 C "C1'" . C B 2 51 ? 8.528 5.923 26.083 1.00 58.53 ? ? ? ? ? ? 58 C R "C1'" 1 51
+ATOM 1812 N N1 . C B 2 51 ? 7.995 4.611 25.552 1.00 57.48 ? ? ? ? ? ? 58 C R N1 1 51
+ATOM 1813 C C2 . C B 2 51 ? 8.740 3.421 25.706 1.00 57.42 ? ? ? ? ? ? 58 C R C2 1 51
+ATOM 1814 O O2 . C B 2 51 ? 9.839 3.447 26.275 1.00 58.14 ? ? ? ? ? ? 58 C R O2 1 51
+ATOM 1815 N N3 . C B 2 51 ? 8.236 2.254 25.218 1.00 56.01 ? ? ? ? ? ? 58 C R N3 1 51
+ATOM 1816 C C4 . C B 2 51 ? 7.048 2.239 24.601 1.00 56.24 ? ? ? ? ? ? 58 C R C4 1 51
+ATOM 1817 N N4 . C B 2 51 ? 6.590 1.069 24.143 1.00 55.00 ? ? ? ? ? ? 58 C R N4 1 51
+ATOM 1818 C C5 . C B 2 51 ? 6.273 3.430 24.436 1.00 56.57 ? ? ? ? ? ? 58 C R C5 1 51
+ATOM 1819 C C6 . C B 2 51 ? 6.779 4.573 24.918 1.00 56.66 ? ? ? ? ? ? 58 C R C6 1 51
+ATOM 1820 P P . C B 2 52 ? 9.970 8.372 22.178 1.00 58.04 ? ? ? ? ? ? 59 C R P 1 52
+ATOM 1821 O OP1 . C B 2 52 ? 10.457 9.700 21.742 1.00 56.37 ? ? ? ? ? ? 59 C R OP1 1 52
+ATOM 1822 O OP2 . C B 2 52 ? 8.936 7.670 21.381 1.00 56.88 ? ? ? ? ? ? 59 C R OP2 1 52
+ATOM 1823 O "O5'" . C B 2 52 ? 11.218 7.381 22.342 1.00 56.91 ? ? ? ? ? ? 59 C R "O5'" 1 52
+ATOM 1824 C "C5'" . C B 2 52 ? 12.373 7.793 23.078 1.00 54.79 ? ? ? ? ? ? 59 C R "C5'" 1 52
+ATOM 1825 C "C4'" . C B 2 52 ? 13.325 6.634 23.316 1.00 53.17 ? ? ? ? ? ? 59 C R "C4'" 1 52
+ATOM 1826 O "O4'" . C B 2 52 ? 12.666 5.587 24.069 1.00 51.92 ? ? ? ? ? ? 59 C R "O4'" 1 52
+ATOM 1827 C "C3'" . C B 2 52 ? 13.788 5.902 22.066 1.00 52.19 ? ? ? ? ? ? 59 C R "C3'" 1 52
+ATOM 1828 O "O3'" . C B 2 52 ? 14.813 6.614 21.401 1.00 52.04 ? ? ? ? ? ? 59 C R "O3'" 1 52
+ATOM 1829 C "C2'" . C B 2 52 ? 14.293 4.599 22.662 1.00 50.91 ? ? ? ? ? ? 59 C R "C2'" 1 52
+ATOM 1830 O "O2'" . C B 2 52 ? 15.539 4.726 23.317 1.00 52.45 ? ? ? ? ? ? 59 C R "O2'" 1 52
+ATOM 1831 C "C1'" . C B 2 52 ? 13.203 4.330 23.688 1.00 50.14 ? ? ? ? ? ? 59 C R "C1'" 1 52
+ATOM 1832 N N1 . C B 2 52 ? 12.117 3.425 23.184 1.00 47.53 ? ? ? ? ? ? 59 C R N1 1 52
+ATOM 1833 C C2 . C B 2 52 ? 12.376 2.054 23.009 1.00 47.46 ? ? ? ? ? ? 59 C R C2 1 52
+ATOM 1834 O O2 . C B 2 52 ? 13.499 1.589 23.268 1.00 46.61 ? ? ? ? ? ? 59 C R O2 1 52
+ATOM 1835 N N3 . C B 2 52 ? 11.370 1.256 22.561 1.00 47.15 ? ? ? ? ? ? 59 C R N3 1 52
+ATOM 1836 C C4 . C B 2 52 ? 10.166 1.769 22.294 1.00 46.45 ? ? ? ? ? ? 59 C R C4 1 52
+ATOM 1837 N N4 . C B 2 52 ? 9.216 0.940 21.853 1.00 47.76 ? ? ? ? ? ? 59 C R N4 1 52
+ATOM 1838 C C5 . C B 2 52 ? 9.887 3.157 22.462 1.00 46.52 ? ? ? ? ? ? 59 C R C5 1 52
+ATOM 1839 C C6 . C B 2 52 ? 10.880 3.936 22.905 1.00 46.27 ? ? ? ? ? ? 59 C R C6 1 52
+ATOM 1840 P P . U B 2 53 ? 14.852 6.617 19.804 1.00 51.39 ? ? ? ? ? ? 60 U R P 1 53
+ATOM 1841 O OP1 . U B 2 53 ? 15.893 7.589 19.399 1.00 49.66 ? ? ? ? ? ? 60 U R OP1 1 53
+ATOM 1842 O OP2 . U B 2 53 ? 13.469 6.751 19.281 1.00 49.84 ? ? ? ? ? ? 60 U R OP2 1 53
+ATOM 1843 O "O5'" . U B 2 53 ? 15.358 5.134 19.492 1.00 49.51 ? ? ? ? ? ? 60 U R "O5'" 1 53
+ATOM 1844 C "C5'" . U B 2 53 ? 16.729 4.827 19.687 1.00 49.76 ? ? ? ? ? ? 60 U R "C5'" 1 53
+ATOM 1845 C "C4'" . U B 2 53 ? 16.990 3.360 19.429 1.00 49.17 ? ? ? ? ? ? 60 U R "C4'" 1 53
+ATOM 1846 O "O4'" . U B 2 53 ? 15.995 2.556 20.099 1.00 48.61 ? ? ? ? ? ? 60 U R "O4'" 1 53
+ATOM 1847 C "C3'" . U B 2 53 ? 16.868 2.953 17.977 1.00 50.30 ? ? ? ? ? ? 60 U R "C3'" 1 53
+ATOM 1848 O "O3'" . U B 2 53 ? 18.092 3.224 17.328 1.00 53.67 ? ? ? ? ? ? 60 U R "O3'" 1 53
+ATOM 1849 C "C2'" . U B 2 53 ? 16.607 1.458 18.086 1.00 48.65 ? ? ? ? ? ? 60 U R "C2'" 1 53
+ATOM 1850 O "O2'" . U B 2 53 ? 17.800 0.717 18.227 1.00 47.72 ? ? ? ? ? ? 60 U R "O2'" 1 53
+ATOM 1851 C "C1'" . U B 2 53 ? 15.795 1.360 19.372 1.00 47.50 ? ? ? ? ? ? 60 U R "C1'" 1 53
+ATOM 1852 N N1 . U B 2 53 ? 14.331 1.139 19.159 1.00 46.04 ? ? ? ? ? ? 60 U R N1 1 53
+ATOM 1853 C C2 . U B 2 53 ? 13.900 -0.110 18.747 1.00 46.05 ? ? ? ? ? ? 60 U R C2 1 53
+ATOM 1854 O O2 . U B 2 53 ? 14.652 -1.046 18.538 1.00 46.35 ? ? ? ? ? ? 60 U R O2 1 53
+ATOM 1855 N N3 . U B 2 53 ? 12.539 -0.229 18.583 1.00 45.25 ? ? ? ? ? ? 60 U R N3 1 53
+ATOM 1856 C C4 . U B 2 53 ? 11.588 0.752 18.788 1.00 45.23 ? ? ? ? ? ? 60 U R C4 1 53
+ATOM 1857 O O4 . U B 2 53 ? 10.404 0.491 18.600 1.00 46.01 ? ? ? ? ? ? 60 U R O4 1 53
+ATOM 1858 C C5 . U B 2 53 ? 12.112 2.027 19.216 1.00 44.64 ? ? ? ? ? ? 60 U R C5 1 53
+ATOM 1859 C C6 . U B 2 53 ? 13.435 2.170 19.383 1.00 44.49 ? ? ? ? ? ? 60 U R C6 1 53
+ATOM 1860 P P . A B 2 54 ? 18.095 3.811 15.843 1.00 55.88 ? ? ? ? ? ? 61 A R P 1 54
+ATOM 1861 O OP1 . A B 2 54 ? 19.511 4.030 15.463 1.00 55.87 ? ? ? ? ? ? 61 A R OP1 1 54
+ATOM 1862 O OP2 . A B 2 54 ? 17.121 4.925 15.779 1.00 55.17 ? ? ? ? ? ? 61 A R OP2 1 54
+ATOM 1863 O "O5'" . A B 2 54 ? 17.499 2.607 14.985 1.00 56.08 ? ? ? ? ? ? 61 A R "O5'" 1 54
+ATOM 1864 C "C5'" . A B 2 54 ? 18.247 1.418 14.804 1.00 60.18 ? ? ? ? ? ? 61 A R "C5'" 1 54
+ATOM 1865 C "C4'" . A B 2 54 ? 17.368 0.397 14.120 1.00 63.58 ? ? ? ? ? ? 61 A R "C4'" 1 54
+ATOM 1866 O "O4'" . A B 2 54 ? 16.139 0.242 14.864 1.00 65.68 ? ? ? ? ? ? 61 A R "O4'" 1 54
+ATOM 1867 C "C3'" . A B 2 54 ? 16.953 0.786 12.708 1.00 65.51 ? ? ? ? ? ? 61 A R "C3'" 1 54
+ATOM 1868 O "O3'" . A B 2 54 ? 17.601 -0.087 11.816 1.00 67.99 ? ? ? ? ? ? 61 A R "O3'" 1 54
+ATOM 1869 C "C2'" . A B 2 54 ? 15.435 0.617 12.666 1.00 66.06 ? ? ? ? ? ? 61 A R "C2'" 1 54
+ATOM 1870 O "O2'" . A B 2 54 ? 14.996 -0.118 11.540 1.00 67.03 ? ? ? ? ? ? 61 A R "O2'" 1 54
+ATOM 1871 C "C1'" . A B 2 54 ? 15.150 -0.159 13.947 1.00 66.09 ? ? ? ? ? ? 61 A R "C1'" 1 54
+ATOM 1872 N N9 . A B 2 54 ? 13.830 0.121 14.502 1.00 66.27 ? ? ? ? ? ? 61 A R N9 1 54
+ATOM 1873 C C8 . A B 2 54 ? 13.390 1.277 15.092 1.00 67.06 ? ? ? ? ? ? 61 A R C8 1 54
+ATOM 1874 N N7 . A B 2 54 ? 12.139 1.229 15.490 1.00 66.93 ? ? ? ? ? ? 61 A R N7 1 54
+ATOM 1875 C C5 . A B 2 54 ? 11.735 -0.048 15.134 1.00 66.40 ? ? ? ? ? ? 61 A R C5 1 54
+ATOM 1876 C C6 . A B 2 54 ? 10.512 -0.736 15.276 1.00 66.60 ? ? ? ? ? ? 61 A R C6 1 54
+ATOM 1877 N N6 . A B 2 54 ? 9.431 -0.193 15.845 1.00 66.56 ? ? ? ? ? ? 61 A R N6 1 54
+ATOM 1878 N N1 . A B 2 54 ? 10.447 -2.007 14.807 1.00 66.86 ? ? ? ? ? ? 61 A R N1 1 54
+ATOM 1879 C C2 . A B 2 54 ? 11.529 -2.556 14.234 1.00 66.21 ? ? ? ? ? ? 61 A R C2 1 54
+ATOM 1880 N N3 . A B 2 54 ? 12.730 -2.006 14.047 1.00 66.53 ? ? ? ? ? ? 61 A R N3 1 54
+ATOM 1881 C C4 . A B 2 54 ? 12.765 -0.745 14.523 1.00 66.31 ? ? ? ? ? ? 61 A R C4 1 54
+ATOM 1882 P P . A B 2 55 ? 18.808 0.448 10.921 1.00 70.61 ? ? ? ? ? ? 62 A R P 1 55
+ATOM 1883 O OP1 . A B 2 55 ? 19.846 1.046 11.801 1.00 70.09 ? ? ? ? ? ? 62 A R OP1 1 55
+ATOM 1884 O OP2 . A B 2 55 ? 18.189 1.269 9.850 1.00 69.57 ? ? ? ? ? ? 62 A R OP2 1 55
+ATOM 1885 O "O5'" . A B 2 55 ? 19.363 -0.920 10.281 1.00 70.02 ? ? ? ? ? ? 62 A R "O5'" 1 55
+ATOM 1886 C "C5'" . A B 2 55 ? 20.685 -1.405 10.548 1.00 68.98 ? ? ? ? ? ? 62 A R "C5'" 1 55
+ATOM 1887 C "C4'" . A B 2 55 ? 20.806 -2.926 10.497 1.00 68.42 ? ? ? ? ? ? 62 A R "C4'" 1 55
+ATOM 1888 O "O4'" . A B 2 55 ? 20.652 -3.464 11.837 1.00 67.73 ? ? ? ? ? ? 62 A R "O4'" 1 55
+ATOM 1889 C "C3'" . A B 2 55 ? 19.780 -3.698 9.671 1.00 67.81 ? ? ? ? ? ? 62 A R "C3'" 1 55
+ATOM 1890 O "O3'" . A B 2 55 ? 20.150 -3.767 8.301 1.00 67.43 ? ? ? ? ? ? 62 A R "O3'" 1 55
+ATOM 1891 C "C2'" . A B 2 55 ? 19.794 -5.065 10.356 1.00 67.15 ? ? ? ? ? ? 62 A R "C2'" 1 55
+ATOM 1892 O "O2'" . A B 2 55 ? 20.926 -5.855 10.048 1.00 66.64 ? ? ? ? ? ? 62 A R "O2'" 1 55
+ATOM 1893 C "C1'" . A B 2 55 ? 19.851 -4.633 11.811 1.00 66.76 ? ? ? ? ? ? 62 A R "C1'" 1 55
+ATOM 1894 N N9 . A B 2 55 ? 18.531 -4.335 12.368 1.00 66.14 ? ? ? ? ? ? 62 A R N9 1 55
+ATOM 1895 C C8 . A B 2 55 ? 17.961 -3.103 12.531 1.00 65.50 ? ? ? ? ? ? 62 A R C8 1 55
+ATOM 1896 N N7 . A B 2 55 ? 16.762 -3.134 13.055 1.00 66.50 ? ? ? ? ? ? 62 A R N7 1 55
+ATOM 1897 C C5 . A B 2 55 ? 16.524 -4.481 13.248 1.00 65.38 ? ? ? ? ? ? 62 A R C5 1 55
+ATOM 1898 C C6 . A B 2 55 ? 15.419 -5.178 13.774 1.00 65.32 ? ? ? ? ? ? 62 A R C6 1 55
+ATOM 1899 N N6 . A B 2 55 ? 14.316 -4.565 14.213 1.00 65.36 ? ? ? ? ? ? 62 A R N6 1 55
+ATOM 1900 N N1 . A B 2 55 ? 15.494 -6.528 13.829 1.00 65.84 ? ? ? ? ? ? 62 A R N1 1 55
+ATOM 1901 C C2 . A B 2 55 ? 16.606 -7.135 13.385 1.00 65.92 ? ? ? ? ? ? 62 A R C2 1 55
+ATOM 1902 N N3 . A B 2 55 ? 17.708 -6.582 12.869 1.00 65.79 ? ? ? ? ? ? 62 A R N3 1 55
+ATOM 1903 C C4 . A B 2 55 ? 17.602 -5.240 12.828 1.00 65.71 ? ? ? ? ? ? 62 A R C4 1 55
+ATOM 1904 P P . A B 2 56 ? 19.022 -3.797 7.162 1.00 67.83 ? ? ? ? ? ? 63 A R P 1 56
+ATOM 1905 O OP1 . A B 2 56 ? 19.713 -3.744 5.853 1.00 68.70 ? ? ? ? ? ? 63 A R OP1 1 56
+ATOM 1906 O OP2 . A B 2 56 ? 18.003 -2.770 7.474 1.00 66.63 ? ? ? ? ? ? 63 A R OP2 1 56
+ATOM 1907 O "O5'" . A B 2 56 ? 18.365 -5.245 7.349 1.00 65.68 ? ? ? ? ? ? 63 A R "O5'" 1 56
+ATOM 1908 C "C5'" . A B 2 56 ? 19.118 -6.412 7.029 1.00 65.79 ? ? ? ? ? ? 63 A R "C5'" 1 56
+ATOM 1909 C "C4'" . A B 2 56 ? 18.365 -7.669 7.413 1.00 65.99 ? ? ? ? ? ? 63 A R "C4'" 1 56
+ATOM 1910 O "O4'" . A B 2 56 ? 18.059 -7.655 8.831 1.00 66.84 ? ? ? ? ? ? 63 A R "O4'" 1 56
+ATOM 1911 C "C3'" . A B 2 56 ? 17.002 -7.824 6.758 1.00 66.13 ? ? ? ? ? ? 63 A R "C3'" 1 56
+ATOM 1912 O "O3'" . A B 2 56 ? 17.132 -8.296 5.419 1.00 65.53 ? ? ? ? ? ? 63 A R "O3'" 1 56
+ATOM 1913 C "C2'" . A B 2 56 ? 16.341 -8.827 7.702 1.00 66.33 ? ? ? ? ? ? 63 A R "C2'" 1 56
+ATOM 1914 O "O2'" . A B 2 56 ? 16.763 -10.162 7.497 1.00 67.01 ? ? ? ? ? ? 63 A R "O2'" 1 56
+ATOM 1915 C "C1'" . A B 2 56 ? 16.823 -8.316 9.060 1.00 65.48 ? ? ? ? ? ? 63 A R "C1'" 1 56
+ATOM 1916 N N9 . A B 2 56 ? 15.866 -7.394 9.678 1.00 64.09 ? ? ? ? ? ? 63 A R N9 1 56
+ATOM 1917 C C8 . A B 2 56 ? 15.881 -6.026 9.629 1.00 64.16 ? ? ? ? ? ? 63 A R C8 1 56
+ATOM 1918 N N7 . A B 2 56 ? 14.890 -5.454 10.271 1.00 63.71 ? ? ? ? ? ? 63 A R N7 1 56
+ATOM 1919 C C5 . A B 2 56 ? 14.171 -6.521 10.773 1.00 62.63 ? ? ? ? ? ? 63 A R C5 1 56
+ATOM 1920 C C6 . A B 2 56 ? 12.999 -6.589 11.549 1.00 62.92 ? ? ? ? ? ? 63 A R C6 1 56
+ATOM 1921 N N6 . A B 2 56 ? 12.331 -5.507 11.959 1.00 63.55 ? ? ? ? ? ? 63 A R N6 1 56
+ATOM 1922 N N1 . A B 2 56 ? 12.535 -7.811 11.889 1.00 64.68 ? ? ? ? ? ? 63 A R N1 1 56
+ATOM 1923 C C2 . A B 2 56 ? 13.205 -8.897 11.477 1.00 65.12 ? ? ? ? ? ? 63 A R C2 1 56
+ATOM 1924 N N3 . A B 2 56 ? 14.318 -8.955 10.742 1.00 64.84 ? ? ? ? ? ? 63 A R N3 1 56
+ATOM 1925 C C4 . A B 2 56 ? 14.754 -7.723 10.418 1.00 63.46 ? ? ? ? ? ? 63 A R C4 1 56
+ATOM 1926 P P . C B 2 57 ? 16.202 -7.701 4.256 1.00 64.35 ? ? ? ? ? ? 64 C R P 1 57
+ATOM 1927 O OP1 . C B 2 57 ? 16.630 -8.322 2.979 1.00 64.74 ? ? ? ? ? ? 64 C R OP1 1 57
+ATOM 1928 O OP2 . C B 2 57 ? 16.158 -6.226 4.374 1.00 64.06 ? ? ? ? ? ? 64 C R OP2 1 57
+ATOM 1929 O "O5'" . C B 2 57 ? 14.762 -8.261 4.660 1.00 63.87 ? ? ? ? ? ? 64 C R "O5'" 1 57
+ATOM 1930 C "C5'" . C B 2 57 ? 14.475 -9.632 4.450 1.00 64.11 ? ? ? ? ? ? 64 C R "C5'" 1 57
+ATOM 1931 C "C4'" . C B 2 57 ? 13.188 -10.026 5.137 1.00 64.62 ? ? ? ? ? ? 64 C R "C4'" 1 57
+ATOM 1932 O "O4'" . C B 2 57 ? 13.264 -9.676 6.539 1.00 64.41 ? ? ? ? ? ? 64 C R "O4'" 1 57
+ATOM 1933 C "C3'" . C B 2 57 ? 11.952 -9.289 4.653 1.00 65.26 ? ? ? ? ? ? 64 C R "C3'" 1 57
+ATOM 1934 O "O3'" . C B 2 57 ? 11.474 -9.832 3.432 1.00 66.02 ? ? ? ? ? ? 64 C R "O3'" 1 57
+ATOM 1935 C "C2'" . C B 2 57 ? 11.004 -9.512 5.827 1.00 65.59 ? ? ? ? ? ? 64 C R "C2'" 1 57
+ATOM 1936 O "O2'" . C B 2 57 ? 10.404 -10.796 5.841 1.00 65.45 ? ? ? ? ? ? 64 C R "O2'" 1 57
+ATOM 1937 C "C1'" . C B 2 57 ? 11.971 -9.331 7.001 1.00 65.21 ? ? ? ? ? ? 64 C R "C1'" 1 57
+ATOM 1938 N N1 . C B 2 57 ? 11.972 -7.932 7.538 1.00 65.99 ? ? ? ? ? ? 64 C R N1 1 57
+ATOM 1939 C C2 . C B 2 57 ? 10.991 -7.563 8.469 1.00 65.89 ? ? ? ? ? ? 64 C R C2 1 57
+ATOM 1940 O O2 . C B 2 57 ? 10.156 -8.399 8.839 1.00 65.59 ? ? ? ? ? ? 64 C R O2 1 57
+ATOM 1941 N N3 . C B 2 57 ? 10.992 -6.288 8.943 1.00 66.88 ? ? ? ? ? ? 64 C R N3 1 57
+ATOM 1942 C C4 . C B 2 57 ? 11.912 -5.407 8.529 1.00 66.35 ? ? ? ? ? ? 64 C R C4 1 57
+ATOM 1943 N N4 . C B 2 57 ? 11.866 -4.171 9.035 1.00 66.67 ? ? ? ? ? ? 64 C R N4 1 57
+ATOM 1944 C C5 . C B 2 57 ? 12.920 -5.759 7.581 1.00 65.89 ? ? ? ? ? ? 64 C R C5 1 57
+ATOM 1945 C C6 . C B 2 57 ? 12.908 -7.017 7.120 1.00 66.49 ? ? ? ? ? ? 64 C R C6 1 57
+ATOM 1946 P P . C B 2 58 ? 10.835 -8.852 2.340 1.00 66.38 ? ? ? ? ? ? 65 C R P 1 58
+ATOM 1947 O OP1 . C B 2 58 ? 10.679 -9.605 1.076 1.00 65.39 ? ? ? ? ? ? 65 C R OP1 1 58
+ATOM 1948 O OP2 . C B 2 58 ? 11.591 -7.578 2.342 1.00 66.10 ? ? ? ? ? ? 65 C R OP2 1 58
+ATOM 1949 O "O5'" . C B 2 58 ? 9.402 -8.544 2.968 1.00 66.36 ? ? ? ? ? ? 65 C R "O5'" 1 58
+ATOM 1950 C "C5'" . C B 2 58 ? 8.415 -9.549 3.103 1.00 67.74 ? ? ? ? ? ? 65 C R "C5'" 1 58
+ATOM 1951 C "C4'" . C B 2 58 ? 7.214 -8.955 3.805 1.00 70.39 ? ? ? ? ? ? 65 C R "C4'" 1 58
+ATOM 1952 O "O4'" . C B 2 58 ? 7.605 -8.542 5.140 1.00 71.34 ? ? ? ? ? ? 65 C R "O4'" 1 58
+ATOM 1953 C "C3'" . C B 2 58 ? 6.693 -7.661 3.196 1.00 71.53 ? ? ? ? ? ? 65 C R "C3'" 1 58
+ATOM 1954 O "O3'" . C B 2 58 ? 5.913 -7.861 2.023 1.00 72.00 ? ? ? ? ? ? 65 C R "O3'" 1 58
+ATOM 1955 C "C2'" . C B 2 58 ? 5.917 -7.071 4.369 1.00 72.12 ? ? ? ? ? ? 65 C R "C2'" 1 58
+ATOM 1956 O "O2'" . C B 2 58 ? 4.665 -7.687 4.621 1.00 71.68 ? ? ? ? ? ? 65 C R "O2'" 1 58
+ATOM 1957 C "C1'" . C B 2 58 ? 6.905 -7.356 5.499 1.00 71.91 ? ? ? ? ? ? 65 C R "C1'" 1 58
+ATOM 1958 N N1 . C B 2 58 ? 7.867 -6.218 5.736 1.00 71.73 ? ? ? ? ? ? 65 C R N1 1 58
+ATOM 1959 C C2 . C B 2 58 ? 7.417 -5.018 6.319 1.00 72.06 ? ? ? ? ? ? 65 C R C2 1 58
+ATOM 1960 O O2 . C B 2 58 ? 6.235 -4.893 6.648 1.00 72.91 ? ? ? ? ? ? 65 C R O2 1 58
+ATOM 1961 N N3 . C B 2 58 ? 8.297 -4.006 6.525 1.00 72.19 ? ? ? ? ? ? 65 C R N3 1 58
+ATOM 1962 C C4 . C B 2 58 ? 9.573 -4.153 6.169 1.00 72.47 ? ? ? ? ? ? 65 C R C4 1 58
+ATOM 1963 N N4 . C B 2 58 ? 10.400 -3.130 6.389 1.00 73.39 ? ? ? ? ? ? 65 C R N4 1 58
+ATOM 1964 C C5 . C B 2 58 ? 10.058 -5.355 5.571 1.00 72.68 ? ? ? ? ? ? 65 C R C5 1 58
+ATOM 1965 C C6 . C B 2 58 ? 9.181 -6.348 5.378 1.00 72.24 ? ? ? ? ? ? 65 C R C6 1 58
+ATOM 1966 P P . A B 2 59 ? 6.157 -6.872 0.783 1.00 73.36 ? ? ? ? ? ? 660 A R P 1 59
+ATOM 1967 O OP1 . A B 2 59 ? 5.571 -7.487 -0.427 1.00 73.30 ? ? ? ? ? ? 660 A R OP1 1 59
+ATOM 1968 O OP2 . A B 2 59 ? 7.582 -6.473 0.770 1.00 73.48 ? ? ? ? ? ? 660 A R OP2 1 59
+ATOM 1969 O "O5'" . A B 2 59 ? 5.314 -5.575 1.184 1.00 72.74 ? ? ? ? ? ? 660 A R "O5'" 1 59
+ATOM 1970 C "C5'" . A B 2 59 ? 3.924 -5.665 1.449 1.00 72.25 ? ? ? ? ? ? 660 A R "C5'" 1 59
+ATOM 1971 C "C4'" . A B 2 59 ? 3.469 -4.486 2.286 1.00 72.01 ? ? ? ? ? ? 660 A R "C4'" 1 59
+ATOM 1972 O "O4'" . A B 2 59 ? 4.206 -4.450 3.534 1.00 72.01 ? ? ? ? ? ? 660 A R "O4'" 1 59
+ATOM 1973 C "C3'" . A B 2 59 ? 3.731 -3.125 1.668 1.00 71.66 ? ? ? ? ? ? 660 A R "C3'" 1 59
+ATOM 1974 O "O3'" . A B 2 59 ? 2.728 -2.794 0.719 1.00 71.28 ? ? ? ? ? ? 660 A R "O3'" 1 59
+ATOM 1975 C "C2'" . A B 2 59 ? 3.696 -2.244 2.911 1.00 72.75 ? ? ? ? ? ? 660 A R "C2'" 1 59
+ATOM 1976 O "O2'" . A B 2 59 ? 2.391 -2.003 3.403 1.00 73.27 ? ? ? ? ? ? 660 A R "O2'" 1 59
+ATOM 1977 C "C1'" . A B 2 59 ? 4.488 -3.108 3.886 1.00 73.07 ? ? ? ? ? ? 660 A R "C1'" 1 59
+ATOM 1978 N N9 . A B 2 59 ? 5.932 -2.849 3.820 1.00 74.15 ? ? ? ? ? ? 660 A R N9 1 59
+ATOM 1979 C C8 . A B 2 59 ? 6.898 -3.631 3.242 1.00 74.58 ? ? ? ? ? ? 660 A R C8 1 59
+ATOM 1980 N N7 . A B 2 59 ? 8.111 -3.139 3.332 1.00 74.48 ? ? ? ? ? ? 660 A R N7 1 59
+ATOM 1981 C C5 . A B 2 59 ? 7.937 -1.946 4.014 1.00 73.91 ? ? ? ? ? ? 660 A R C5 1 59
+ATOM 1982 C C6 . A B 2 59 ? 8.841 -0.942 4.432 1.00 73.43 ? ? ? ? ? ? 660 A R C6 1 59
+ATOM 1983 N N6 . A B 2 59 ? 10.158 -0.990 4.203 1.00 73.85 ? ? ? ? ? ? 660 A R N6 1 59
+ATOM 1984 N N1 . A B 2 59 ? 8.339 0.125 5.093 1.00 72.70 ? ? ? ? ? ? 660 A R N1 1 59
+ATOM 1985 C C2 . A B 2 59 ? 7.020 0.182 5.323 1.00 72.56 ? ? ? ? ? ? 660 A R C2 1 59
+ATOM 1986 N N3 . A B 2 59 ? 6.076 -0.697 4.981 1.00 73.34 ? ? ? ? ? ? 660 A R N3 1 59
+ATOM 1987 C C4 . A B 2 59 ? 6.600 -1.749 4.322 1.00 73.85 ? ? ? ? ? ? 660 A R C4 1 59
+ATOM 1988 P P . U B 2 60 ? 3.116 -2.005 -0.622 1.00 71.84 ? ? ? ? ? ? 661 U R P 1 60
+ATOM 1989 O OP1 . U B 2 60 ? 1.940 -2.052 -1.522 1.00 72.64 ? ? ? ? ? ? 661 U R OP1 1 60
+ATOM 1990 O OP2 . U B 2 60 ? 4.423 -2.496 -1.116 1.00 71.22 ? ? ? ? ? ? 661 U R OP2 1 60
+ATOM 1991 O "O5'" . U B 2 60 ? 3.316 -0.505 -0.100 1.00 70.01 ? ? ? ? ? ? 661 U R "O5'" 1 60
+ATOM 1992 C "C5'" . U B 2 60 ? 2.241 0.173 0.553 1.00 69.47 ? ? ? ? ? ? 661 U R "C5'" 1 60
+ATOM 1993 C "C4'" . U B 2 60 ? 2.741 1.356 1.359 1.00 68.25 ? ? ? ? ? ? 661 U R "C4'" 1 60
+ATOM 1994 O "O4'" . U B 2 60 ? 3.717 0.928 2.345 1.00 67.65 ? ? ? ? ? ? 661 U R "O4'" 1 60
+ATOM 1995 C "C3'" . U B 2 60 ? 3.497 2.388 0.545 1.00 67.97 ? ? ? ? ? ? 661 U R "C3'" 1 60
+ATOM 1996 O "O3'" . U B 2 60 ? 2.603 3.226 -0.163 1.00 67.88 ? ? ? ? ? ? 661 U R "O3'" 1 60
+ATOM 1997 C "C2'" . U B 2 60 ? 4.277 3.110 1.636 1.00 67.61 ? ? ? ? ? ? 661 U R "C2'" 1 60
+ATOM 1998 O "O2'" . U B 2 60 ? 3.480 4.008 2.389 1.00 68.00 ? ? ? ? ? ? 661 U R "O2'" 1 60
+ATOM 1999 C "C1'" . U B 2 60 ? 4.726 1.919 2.488 1.00 66.13 ? ? ? ? ? ? 661 U R "C1'" 1 60
+ATOM 2000 N N1 . U B 2 60 ? 6.093 1.375 2.098 1.00 63.66 ? ? ? ? ? ? 661 U R N1 1 60
+ATOM 2001 C C2 . U B 2 60 ? 7.240 2.057 2.492 1.00 62.13 ? ? ? ? ? ? 661 U R C2 1 60
+ATOM 2002 O O2 . U B 2 60 ? 7.224 3.083 3.152 1.00 61.93 ? ? ? ? ? ? 661 U R O2 1 60
+ATOM 2003 N N3 . U B 2 60 ? 8.430 1.491 2.089 1.00 59.95 ? ? ? ? ? ? 661 U R N3 1 60
+ATOM 2004 C C4 . U B 2 60 ? 8.596 0.338 1.343 1.00 59.19 ? ? ? ? ? ? 661 U R C4 1 60
+ATOM 2005 O O4 . U B 2 60 ? 9.725 -0.046 1.055 1.00 56.54 ? ? ? ? ? ? 661 U R O4 1 60
+ATOM 2006 C C5 . U B 2 60 ? 7.366 -0.317 0.968 1.00 60.54 ? ? ? ? ? ? 661 U R C5 1 60
+ATOM 2007 C C6 . U B 2 60 ? 6.194 0.212 1.350 1.00 61.70 ? ? ? ? ? ? 661 U R C6 1 60
+ATOM 2008 P P . U B 2 61 ? 2.902 3.522 -1.708 1.00 68.53 ? ? ? ? ? ? 662 U R P 1 61
+ATOM 2009 O OP1 . U B 2 61 ? 1.692 4.153 -2.287 1.00 68.43 ? ? ? ? ? ? 662 U R OP1 1 61
+ATOM 2010 O OP2 . U B 2 61 ? 3.464 2.303 -2.334 1.00 65.79 ? ? ? ? ? ? 662 U R OP2 1 61
+ATOM 2011 O "O5'" . U B 2 61 ? 4.059 4.620 -1.611 1.00 68.79 ? ? ? ? ? ? 662 U R "O5'" 1 61
+ATOM 2012 C "C5'" . U B 2 61 ? 3.740 5.916 -1.115 1.00 69.67 ? ? ? ? ? ? 662 U R "C5'" 1 61
+ATOM 2013 C "C4'" . U B 2 61 ? 4.317 6.999 -2.007 1.00 70.36 ? ? ? ? ? ? 662 U R "C4'" 1 61
+ATOM 2014 O "O4'" . U B 2 61 ? 5.749 6.834 -2.074 1.00 70.13 ? ? ? ? ? ? 662 U R "O4'" 1 61
+ATOM 2015 C "C3'" . U B 2 61 ? 3.808 7.049 -3.448 1.00 70.69 ? ? ? ? ? ? 662 U R "C3'" 1 61
+ATOM 2016 O "O3'" . U B 2 61 ? 3.355 8.374 -3.746 1.00 70.70 ? ? ? ? ? ? 662 U R "O3'" 1 61
+ATOM 2017 C "C2'" . U B 2 61 ? 5.016 6.625 -4.288 1.00 71.10 ? ? ? ? ? ? 662 U R "C2'" 1 61
+ATOM 2018 O "O2'" . U B 2 61 ? 5.059 7.286 -5.538 1.00 70.55 ? ? ? ? ? ? 662 U R "O2'" 1 61
+ATOM 2019 C "C1'" . U B 2 61 ? 6.192 7.029 -3.396 1.00 71.40 ? ? ? ? ? ? 662 U R "C1'" 1 61
+ATOM 2020 N N1 . U B 2 61 ? 7.458 6.232 -3.525 1.00 72.53 ? ? ? ? ? ? 662 U R N1 1 61
+ATOM 2021 C C2 . U B 2 61 ? 8.528 6.733 -4.252 1.00 73.18 ? ? ? ? ? ? 662 U R C2 1 61
+ATOM 2022 O O2 . U B 2 61 ? 8.520 7.804 -4.834 1.00 74.02 ? ? ? ? ? ? 662 U R O2 1 61
+ATOM 2023 N N3 . U B 2 61 ? 9.633 5.917 -4.283 1.00 72.80 ? ? ? ? ? ? 662 U R N3 1 61
+ATOM 2024 C C4 . U B 2 61 ? 9.783 4.683 -3.672 1.00 73.39 ? ? ? ? ? ? 662 U R C4 1 61
+ATOM 2025 O O4 . U B 2 61 ? 10.839 4.072 -3.794 1.00 74.02 ? ? ? ? ? ? 662 U R O4 1 61
+ATOM 2026 C C5 . U B 2 61 ? 8.638 4.230 -2.925 1.00 73.15 ? ? ? ? ? ? 662 U R C5 1 61
+ATOM 2027 C C6 . U B 2 61 ? 7.547 5.008 -2.880 1.00 72.98 ? ? ? ? ? ? 662 U R C6 1 61
+ATOM 2028 P P . G B 2 62 ? 1.990 8.935 -3.111 1.00 73.05 ? ? ? ? ? ? 663 G R P 1 62
+ATOM 2029 O OP1 . G B 2 62 ? 1.118 7.788 -2.774 1.00 73.27 ? ? ? ? ? ? 663 G R OP1 1 62
+ATOM 2030 O OP2 . G B 2 62 ? 1.486 10.008 -3.997 1.00 73.40 ? ? ? ? ? ? 663 G R OP2 1 62
+ATOM 2031 O "O5'" . G B 2 62 ? 2.431 9.638 -1.754 1.00 71.69 ? ? ? ? ? ? 663 G R "O5'" 1 62
+ATOM 2032 C "C5'" . G B 2 62 ? 1.438 9.866 -0.773 1.00 72.31 ? ? ? ? ? ? 663 G R "C5'" 1 62
+ATOM 2033 C "C4'" . G B 2 62 ? 2.016 9.625 0.603 1.00 72.96 ? ? ? ? ? ? 663 G R "C4'" 1 62
+ATOM 2034 O "O4'" . G B 2 62 ? 3.078 8.642 0.522 1.00 72.80 ? ? ? ? ? ? 663 G R "O4'" 1 62
+ATOM 2035 C "C3'" . G B 2 62 ? 2.679 10.849 1.201 1.00 73.11 ? ? ? ? ? ? 663 G R "C3'" 1 62
+ATOM 2036 O "O3'" . G B 2 62 ? 1.703 11.632 1.857 1.00 74.84 ? ? ? ? ? ? 663 G R "O3'" 1 62
+ATOM 2037 C "C2'" . G B 2 62 ? 3.680 10.224 2.163 1.00 72.69 ? ? ? ? ? ? 663 G R "C2'" 1 62
+ATOM 2038 O "O2'" . G B 2 62 ? 3.085 9.811 3.379 1.00 73.60 ? ? ? ? ? ? 663 G R "O2'" 1 62
+ATOM 2039 C "C1'" . G B 2 62 ? 4.147 9.001 1.374 1.00 71.67 ? ? ? ? ? ? 663 G R "C1'" 1 62
+ATOM 2040 N N9 . G B 2 62 ? 5.344 9.197 0.550 1.00 70.19 ? ? ? ? ? ? 663 G R N9 1 62
+ATOM 2041 C C8 . G B 2 62 ? 5.646 10.283 -0.241 1.00 69.50 ? ? ? ? ? ? 663 G R C8 1 62
+ATOM 2042 N N7 . G B 2 62 ? 6.783 10.180 -0.865 1.00 68.29 ? ? ? ? ? ? 663 G R N7 1 62
+ATOM 2043 C C5 . G B 2 62 ? 7.277 8.949 -0.468 1.00 67.98 ? ? ? ? ? ? 663 G R C5 1 62
+ATOM 2044 C C6 . G B 2 62 ? 8.481 8.295 -0.825 1.00 66.62 ? ? ? ? ? ? 663 G R C6 1 62
+ATOM 2045 O O6 . G B 2 62 ? 9.366 8.702 -1.585 1.00 64.99 ? ? ? ? ? ? 663 G R O6 1 62
+ATOM 2046 N N1 . G B 2 62 ? 8.610 7.051 -0.208 1.00 66.74 ? ? ? ? ? ? 663 G R N1 1 62
+ATOM 2047 C C2 . G B 2 62 ? 7.680 6.509 0.652 1.00 66.89 ? ? ? ? ? ? 663 G R C2 1 62
+ATOM 2048 N N2 . G B 2 62 ? 7.968 5.301 1.152 1.00 67.29 ? ? ? ? ? ? 663 G R N2 1 62
+ATOM 2049 N N3 . G B 2 62 ? 6.545 7.111 0.997 1.00 67.70 ? ? ? ? ? ? 663 G R N3 1 62
+ATOM 2050 C C4 . G B 2 62 ? 6.405 8.327 0.404 1.00 68.85 ? ? ? ? ? ? 663 G R C4 1 62
+ATOM 2051 P P . C B 2 63 ? 1.388 13.121 1.352 1.00 77.36 ? ? ? ? ? ? 664 C R P 1 63
+ATOM 2052 O OP1 . C B 2 63 ? 0.247 13.614 2.163 1.00 77.15 ? ? ? ? ? ? 664 C R OP1 1 63
+ATOM 2053 O OP2 . C B 2 63 ? 1.291 13.114 -0.128 1.00 75.72 ? ? ? ? ? ? 664 C R OP2 1 63
+ATOM 2054 O "O5'" . C B 2 63 ? 2.703 13.937 1.767 1.00 74.70 ? ? ? ? ? ? 664 C R "O5'" 1 63
+ATOM 2055 C "C5'" . C B 2 63 ? 3.071 14.011 3.145 1.00 71.98 ? ? ? ? ? ? 664 C R "C5'" 1 63
+ATOM 2056 C "C4'" . C B 2 63 ? 3.257 15.447 3.605 1.00 68.89 ? ? ? ? ? ? 664 C R "C4'" 1 63
+ATOM 2057 O "O4'" . C B 2 63 ? 4.112 16.148 2.668 1.00 66.34 ? ? ? ? ? ? 664 C R "O4'" 1 63
+ATOM 2058 C "C3'" . C B 2 63 ? 1.995 16.288 3.758 1.00 67.15 ? ? ? ? ? ? 664 C R "C3'" 1 63
+ATOM 2059 O "O3'" . C B 2 63 ? 2.144 17.037 4.962 1.00 69.06 ? ? ? ? ? ? 664 C R "O3'" 1 63
+ATOM 2060 C "C2'" . C B 2 63 ? 1.993 17.177 2.510 1.00 66.25 ? ? ? ? ? ? 664 C R "C2'" 1 63
+ATOM 2061 O "O2'" . C B 2 63 ? 1.416 18.448 2.746 1.00 65.72 ? ? ? ? ? ? 664 C R "O2'" 1 63
+ATOM 2062 C "C1'" . C B 2 63 ? 3.485 17.326 2.207 1.00 64.00 ? ? ? ? ? ? 664 C R "C1'" 1 63
+ATOM 2063 N N1 . C B 2 63 ? 3.886 17.517 0.762 1.00 60.59 ? ? ? ? ? ? 664 C R N1 1 63
+ATOM 2064 C C2 . C B 2 63 ? 4.339 18.773 0.315 1.00 58.54 ? ? ? ? ? ? 664 C R C2 1 63
+ATOM 2065 O O2 . C B 2 63 ? 4.388 19.729 1.098 1.00 57.97 ? ? ? ? ? ? 664 C R O2 1 63
+ATOM 2066 N N3 . C B 2 63 ? 4.710 18.917 -0.985 1.00 56.69 ? ? ? ? ? ? 664 C R N3 1 63
+ATOM 2067 C C4 . C B 2 63 ? 4.651 17.880 -1.824 1.00 55.57 ? ? ? ? ? ? 664 C R C4 1 63
+ATOM 2068 N N4 . C B 2 63 ? 5.027 18.086 -3.087 1.00 54.13 ? ? ? ? ? ? 664 C R N4 1 63
+ATOM 2069 C C5 . C B 2 63 ? 4.203 16.593 -1.398 1.00 56.43 ? ? ? ? ? ? 664 C R C5 1 63
+ATOM 2070 C C6 . C B 2 63 ? 3.839 16.460 -0.113 1.00 59.25 ? ? ? ? ? ? 664 C R C6 1 63
+ATOM 2071 P P . A B 2 64 ? 0.950 17.272 6.000 1.00 70.69 ? ? ? ? ? ? 665 A R P 1 64
+ATOM 2072 O OP1 . A B 2 64 ? -0.050 16.201 5.791 1.00 72.42 ? ? ? ? ? ? 665 A R OP1 1 64
+ATOM 2073 O OP2 . A B 2 64 ? 0.559 18.696 5.896 1.00 70.42 ? ? ? ? ? ? 665 A R OP2 1 64
+ATOM 2074 O "O5'" . A B 2 64 ? 1.610 17.095 7.448 1.00 71.51 ? ? ? ? ? ? 665 A R "O5'" 1 64
+ATOM 2075 C "C5'" . A B 2 64 ? 2.194 15.864 7.861 1.00 72.59 ? ? ? ? ? ? 665 A R "C5'" 1 64
+ATOM 2076 C "C4'" . A B 2 64 ? 3.682 16.048 8.091 1.00 73.87 ? ? ? ? ? ? 665 A R "C4'" 1 64
+ATOM 2077 O "O4'" . A B 2 64 ? 4.315 16.485 6.863 1.00 73.15 ? ? ? ? ? ? 665 A R "O4'" 1 64
+ATOM 2078 C "C3'" . A B 2 64 ? 4.043 17.130 9.096 1.00 75.09 ? ? ? ? ? ? 665 A R "C3'" 1 64
+ATOM 2079 O "O3'" . A B 2 64 ? 4.004 16.605 10.413 1.00 78.27 ? ? ? ? ? ? 665 A R "O3'" 1 64
+ATOM 2080 C "C2'" . A B 2 64 ? 5.457 17.517 8.677 1.00 73.86 ? ? ? ? ? ? 665 A R "C2'" 1 64
+ATOM 2081 O "O2'" . A B 2 64 ? 6.453 16.708 9.269 1.00 73.63 ? ? ? ? ? ? 665 A R "O2'" 1 64
+ATOM 2082 C "C1'" . A B 2 64 ? 5.430 17.308 7.161 1.00 72.50 ? ? ? ? ? ? 665 A R "C1'" 1 64
+ATOM 2083 N N9 . A B 2 64 ? 5.355 18.543 6.375 1.00 71.09 ? ? ? ? ? ? 665 A R N9 1 64
+ATOM 2084 C C8 . A B 2 64 ? 4.413 18.864 5.436 1.00 70.77 ? ? ? ? ? ? 665 A R C8 1 64
+ATOM 2085 N N7 . A B 2 64 ? 4.587 20.037 4.874 1.00 70.25 ? ? ? ? ? ? 665 A R N7 1 64
+ATOM 2086 C C5 . A B 2 64 ? 5.728 20.530 5.483 1.00 69.46 ? ? ? ? ? ? 665 A R C5 1 64
+ATOM 2087 C C6 . A B 2 64 ? 6.450 21.738 5.332 1.00 68.69 ? ? ? ? ? ? 665 A R C6 1 64
+ATOM 2088 N N6 . A B 2 64 ? 6.105 22.708 4.480 1.00 68.87 ? ? ? ? ? ? 665 A R N6 1 64
+ATOM 2089 N N1 . A B 2 64 ? 7.550 21.922 6.092 1.00 67.79 ? ? ? ? ? ? 665 A R N1 1 64
+ATOM 2090 C C2 . A B 2 64 ? 7.908 20.953 6.946 1.00 69.36 ? ? ? ? ? ? 665 A R C2 1 64
+ATOM 2091 N N3 . A B 2 64 ? 7.312 19.780 7.178 1.00 69.82 ? ? ? ? ? ? 665 A R N3 1 64
+ATOM 2092 C C4 . A B 2 64 ? 6.218 19.622 6.409 1.00 70.21 ? ? ? ? ? ? 665 A R C4 1 64
+ATOM 2093 P P . C B 2 65 ? 3.137 17.338 11.542 1.00 81.19 ? ? ? ? ? ? 666 C R P 1 65
+ATOM 2094 O OP1 . C B 2 65 ? 3.058 16.420 12.706 1.00 81.02 ? ? ? ? ? ? 666 C R OP1 1 65
+ATOM 2095 O OP2 . C B 2 65 ? 1.890 17.840 10.913 1.00 80.71 ? ? ? ? ? ? 666 C R OP2 1 65
+ATOM 2096 O "O5'" . C B 2 65 ? 4.051 18.591 11.938 1.00 80.24 ? ? ? ? ? ? 666 C R "O5'" 1 65
+ATOM 2097 C "C5'" . C B 2 65 ? 5.146 18.403 12.830 1.00 80.72 ? ? ? ? ? ? 666 C R "C5'" 1 65
+ATOM 2098 C "C4'" . C B 2 65 ? 6.048 19.620 12.884 1.00 80.88 ? ? ? ? ? ? 666 C R "C4'" 1 65
+ATOM 2099 O "O4'" . C B 2 65 ? 6.613 19.850 11.570 1.00 80.29 ? ? ? ? ? ? 666 C R "O4'" 1 65
+ATOM 2100 C "C3'" . C B 2 65 ? 5.350 20.931 13.222 1.00 81.64 ? ? ? ? ? ? 666 C R "C3'" 1 65
+ATOM 2101 O "O3'" . C B 2 65 ? 5.171 21.071 14.627 1.00 83.95 ? ? ? ? ? ? 666 C R "O3'" 1 65
+ATOM 2102 C "C2'" . C B 2 65 ? 6.297 21.962 12.615 1.00 80.07 ? ? ? ? ? ? 666 C R "C2'" 1 65
+ATOM 2103 O "O2'" . C B 2 65 ? 7.430 22.230 13.423 1.00 78.39 ? ? ? ? ? ? 666 C R "O2'" 1 65
+ATOM 2104 C "C1'" . C B 2 65 ? 6.691 21.244 11.321 1.00 78.65 ? ? ? ? ? ? 666 C R "C1'" 1 65
+ATOM 2105 N N1 . C B 2 65 ? 5.832 21.602 10.132 1.00 75.84 ? ? ? ? ? ? 666 C R N1 1 65
+ATOM 2106 C C2 . C B 2 65 ? 6.202 22.682 9.312 1.00 75.18 ? ? ? ? ? ? 666 C R C2 1 65
+ATOM 2107 O O2 . C B 2 65 ? 7.228 23.331 9.564 1.00 74.05 ? ? ? ? ? ? 666 C R O2 1 65
+ATOM 2108 N N3 . C B 2 65 ? 5.417 22.991 8.243 1.00 74.35 ? ? ? ? ? ? 666 C R N3 1 65
+ATOM 2109 C C4 . C B 2 65 ? 4.311 22.286 7.985 1.00 73.74 ? ? ? ? ? ? 666 C R C4 1 65
+ATOM 2110 N N4 . C B 2 65 ? 3.581 22.638 6.925 1.00 72.83 ? ? ? ? ? ? 666 C R N4 1 65
+ATOM 2111 C C5 . C B 2 65 ? 3.913 21.185 8.802 1.00 74.51 ? ? ? ? ? ? 666 C R C5 1 65
+ATOM 2112 C C6 . C B 2 65 ? 4.695 20.888 9.848 1.00 75.15 ? ? ? ? ? ? 666 C R C6 1 65
+ATOM 2113 P P . U B 2 66 ? 3.681 21.126 15.214 1.00 85.44 ? ? ? ? ? ? 667 U R P 1 66
+ATOM 2114 O OP1 . U B 2 66 ? 2.761 20.443 14.269 1.00 84.32 ? ? ? ? ? ? 667 U R OP1 1 66
+ATOM 2115 O OP2 . U B 2 66 ? 3.423 22.533 15.602 1.00 85.16 ? ? ? ? ? ? 667 U R OP2 1 66
+ATOM 2116 O "O5'" . U B 2 66 ? 3.803 20.244 16.545 1.00 83.25 ? ? ? ? ? ? 667 U R "O5'" 1 66
+ATOM 2117 C "C5'" . U B 2 66 ? 3.811 18.830 16.438 1.00 80.35 ? ? ? ? ? ? 667 U R "C5'" 1 66
+ATOM 2118 C "C4'" . U B 2 66 ? 3.961 18.177 17.795 1.00 78.41 ? ? ? ? ? ? 667 U R "C4'" 1 66
+ATOM 2119 O "O4'" . U B 2 66 ? 2.679 18.168 18.471 1.00 77.53 ? ? ? ? ? ? 667 U R "O4'" 1 66
+ATOM 2120 C "C3'" . U B 2 66 ? 4.400 16.726 17.709 1.00 78.17 ? ? ? ? ? ? 667 U R "C3'" 1 66
+ATOM 2121 O "O3'" . U B 2 66 ? 5.812 16.660 17.870 1.00 78.19 ? ? ? ? ? ? 667 U R "O3'" 1 66
+ATOM 2122 C "C2'" . U B 2 66 ? 3.652 16.047 18.853 1.00 77.56 ? ? ? ? ? ? 667 U R "C2'" 1 66
+ATOM 2123 O "O2'" . U B 2 66 ? 4.355 16.085 20.081 1.00 78.60 ? ? ? ? ? ? 667 U R "O2'" 1 66
+ATOM 2124 C "C1'" . U B 2 66 ? 2.374 16.873 18.964 1.00 75.82 ? ? ? ? ? ? 667 U R "C1'" 1 66
+ATOM 2125 N N1 . U B 2 66 ? 1.158 16.315 18.251 1.00 73.30 ? ? ? ? ? ? 667 U R N1 1 66
+ATOM 2126 C C2 . U B 2 66 ? 0.611 15.087 18.615 1.00 72.31 ? ? ? ? ? ? 667 U R C2 1 66
+ATOM 2127 O O2 . U B 2 66 ? 1.049 14.369 19.498 1.00 71.97 ? ? ? ? ? ? 667 U R O2 1 66
+ATOM 2128 N N3 . U B 2 66 ? -0.501 14.707 17.894 1.00 70.90 ? ? ? ? ? ? 667 U R N3 1 66
+ATOM 2129 C C4 . U B 2 66 ? -1.116 15.411 16.869 1.00 70.84 ? ? ? ? ? ? 667 U R C4 1 66
+ATOM 2130 O O4 . U B 2 66 ? -2.106 14.946 16.309 1.00 70.32 ? ? ? ? ? ? 667 U R O4 1 66
+ATOM 2131 C C5 . U B 2 66 ? -0.496 16.672 16.546 1.00 70.74 ? ? ? ? ? ? 667 U R C5 1 66
+ATOM 2132 C C6 . U B 2 66 ? 0.583 17.065 17.235 1.00 72.25 ? ? ? ? ? ? 667 U R C6 1 66
+ATOM 2133 P P . C B 2 67 ? 6.763 16.185 16.670 1.00 78.26 ? ? ? ? ? ? 668 C R P 1 67
+ATOM 2134 O OP1 . C B 2 67 ? 8.146 16.577 17.031 1.00 76.72 ? ? ? ? ? ? 668 C R OP1 1 67
+ATOM 2135 O OP2 . C B 2 67 ? 6.180 16.623 15.380 1.00 77.82 ? ? ? ? ? ? 668 C R OP2 1 67
+ATOM 2136 O "O5'" . C B 2 67 ? 6.628 14.595 16.719 1.00 74.82 ? ? ? ? ? ? 668 C R "O5'" 1 67
+ATOM 2137 C "C5'" . C B 2 67 ? 7.138 13.875 17.825 1.00 71.24 ? ? ? ? ? ? 668 C R "C5'" 1 67
+ATOM 2138 C "C4'" . C B 2 67 ? 6.244 12.691 18.113 1.00 69.21 ? ? ? ? ? ? 668 C R "C4'" 1 67
+ATOM 2139 O "O4'" . C B 2 67 ? 4.898 13.168 18.353 1.00 67.80 ? ? ? ? ? ? 668 C R "O4'" 1 67
+ATOM 2140 C "C3'" . C B 2 67 ? 6.038 11.725 16.960 1.00 68.63 ? ? ? ? ? ? 668 C R "C3'" 1 67
+ATOM 2141 O "O3'" . C B 2 67 ? 7.160 10.872 16.746 1.00 68.74 ? ? ? ? ? ? 668 C R "O3'" 1 67
+ATOM 2142 C "C2'" . C B 2 67 ? 4.806 10.982 17.464 1.00 68.15 ? ? ? ? ? ? 668 C R "C2'" 1 67
+ATOM 2143 O "O2'" . C B 2 67 ? 5.090 10.060 18.501 1.00 69.50 ? ? ? ? ? ? 668 C R "O2'" 1 67
+ATOM 2144 C "C1'" . C B 2 67 ? 3.978 12.151 17.996 1.00 66.35 ? ? ? ? ? ? 668 C R "C1'" 1 67
+ATOM 2145 N N1 . C B 2 67 ? 2.969 12.650 16.994 1.00 63.67 ? ? ? ? ? ? 668 C R N1 1 67
+ATOM 2146 C C2 . C B 2 67 ? 1.701 12.042 16.943 1.00 63.26 ? ? ? ? ? ? 668 C R C2 1 67
+ATOM 2147 O O2 . C B 2 67 ? 1.429 11.120 17.722 1.00 62.50 ? ? ? ? ? ? 668 C R O2 1 67
+ATOM 2148 N N3 . C B 2 67 ? 0.791 12.485 16.034 1.00 62.12 ? ? ? ? ? ? 668 C R N3 1 67
+ATOM 2149 C C4 . C B 2 67 ? 1.107 13.479 15.202 1.00 62.02 ? ? ? ? ? ? 668 C R C4 1 67
+ATOM 2150 N N4 . C B 2 67 ? 0.172 13.870 14.334 1.00 62.50 ? ? ? ? ? ? 668 C R N4 1 67
+ATOM 2151 C C5 . C B 2 67 ? 2.388 14.112 15.228 1.00 62.03 ? ? ? ? ? ? 668 C R C5 1 67
+ATOM 2152 C C6 . C B 2 67 ? 3.275 13.667 16.128 1.00 63.06 ? ? ? ? ? ? 668 C R C6 1 67
+ATOM 2153 P P . C B 2 68 ? 7.486 10.354 15.260 1.00 69.21 ? ? ? ? ? ? 669 C R P 1 68
+ATOM 2154 O OP1 . C B 2 68 ? 8.826 9.722 15.288 1.00 68.32 ? ? ? ? ? ? 669 C R OP1 1 68
+ATOM 2155 O OP2 . C B 2 68 ? 7.223 11.455 14.306 1.00 69.12 ? ? ? ? ? ? 669 C R OP2 1 68
+ATOM 2156 O "O5'" . C B 2 68 ? 6.369 9.235 15.009 1.00 66.96 ? ? ? ? ? ? 669 C R "O5'" 1 68
+ATOM 2157 C "C5'" . C B 2 68 ? 6.613 7.904 15.433 1.00 64.72 ? ? ? ? ? ? 669 C R "C5'" 1 68
+ATOM 2158 C "C4'" . C B 2 68 ? 5.330 7.149 15.717 1.00 63.48 ? ? ? ? ? ? 669 C R "C4'" 1 68
+ATOM 2159 O "O4'" . C B 2 68 ? 4.246 8.043 16.088 1.00 60.36 ? ? ? ? ? ? 669 C R "O4'" 1 68
+ATOM 2160 C "C3'" . C B 2 68 ? 4.746 6.406 14.528 1.00 63.85 ? ? ? ? ? ? 669 C R "C3'" 1 68
+ATOM 2161 O "O3'" . C B 2 68 ? 5.491 5.232 14.211 1.00 67.88 ? ? ? ? ? ? 669 C R "O3'" 1 68
+ATOM 2162 C "C2'" . C B 2 68 ? 3.356 6.105 15.079 1.00 60.09 ? ? ? ? ? ? 669 C R "C2'" 1 68
+ATOM 2163 O "O2'" . C B 2 68 ? 3.341 5.084 16.057 1.00 58.08 ? ? ? ? ? ? 669 C R "O2'" 1 68
+ATOM 2164 C "C1'" . C B 2 68 ? 3.010 7.453 15.707 1.00 57.11 ? ? ? ? ? ? 669 C R "C1'" 1 68
+ATOM 2165 N N1 . C B 2 68 ? 2.258 8.377 14.780 1.00 52.27 ? ? ? ? ? ? 669 C R N1 1 68
+ATOM 2166 C C2 . C B 2 68 ? 0.984 8.026 14.278 1.00 49.00 ? ? ? ? ? ? 669 C R C2 1 68
+ATOM 2167 O O2 . C B 2 68 ? 0.453 6.951 14.589 1.00 45.59 ? ? ? ? ? ? 669 C R O2 1 68
+ATOM 2168 N N3 . C B 2 68 ? 0.346 8.892 13.450 1.00 47.56 ? ? ? ? ? ? 669 C R N3 1 68
+ATOM 2169 C C4 . C B 2 68 ? 0.919 10.053 13.114 1.00 48.78 ? ? ? ? ? ? 669 C R C4 1 68
+ATOM 2170 N N4 . C B 2 68 ? 0.250 10.868 12.293 1.00 47.03 ? ? ? ? ? ? 669 C R N4 1 68
+ATOM 2171 C C5 . C B 2 68 ? 2.208 10.431 13.607 1.00 49.92 ? ? ? ? ? ? 669 C R C5 1 68
+ATOM 2172 C C6 . C B 2 68 ? 2.830 9.572 14.427 1.00 51.00 ? ? ? ? ? ? 669 C R C6 1 68
+ATOM 2173 P P . G B 2 69 ? 5.428 4.614 12.732 1.00 71.37 ? ? ? ? ? ? 75 G R P 1 69
+ATOM 2174 O OP1 . G B 2 69 ? 6.788 4.138 12.394 1.00 72.21 ? ? ? ? ? ? 75 G R OP1 1 69
+ATOM 2175 O OP2 . G B 2 69 ? 4.747 5.579 11.833 1.00 71.60 ? ? ? ? ? ? 75 G R OP2 1 69
+ATOM 2176 O "O5'" . G B 2 69 ? 4.492 3.328 12.921 1.00 71.76 ? ? ? ? ? ? 75 G R "O5'" 1 69
+ATOM 2177 C "C5'" . G B 2 69 ? 3.070 3.402 12.818 1.00 72.39 ? ? ? ? ? ? 75 G R "C5'" 1 69
+ATOM 2178 C "C4'" . G B 2 69 ? 2.505 2.198 12.085 1.00 72.32 ? ? ? ? ? ? 75 G R "C4'" 1 69
+ATOM 2179 O "O4'" . G B 2 69 ? 2.928 2.238 10.698 1.00 71.55 ? ? ? ? ? ? 75 G R "O4'" 1 69
+ATOM 2180 C "C3'" . G B 2 69 ? 2.982 0.829 12.554 1.00 72.22 ? ? ? ? ? ? 75 G R "C3'" 1 69
+ATOM 2181 O "O3'" . G B 2 69 ? 2.330 0.386 13.738 1.00 72.50 ? ? ? ? ? ? 75 G R "O3'" 1 69
+ATOM 2182 C "C2'" . G B 2 69 ? 2.611 -0.005 11.334 1.00 72.20 ? ? ? ? ? ? 75 G R "C2'" 1 69
+ATOM 2183 O "O2'" . G B 2 69 ? 1.225 -0.263 11.227 1.00 72.60 ? ? ? ? ? ? 75 G R "O2'" 1 69
+ATOM 2184 C "C1'" . G B 2 69 ? 3.106 0.916 10.224 1.00 71.83 ? ? ? ? ? ? 75 G R "C1'" 1 69
+ATOM 2185 N N9 . G B 2 69 ? 4.518 0.655 9.939 1.00 72.58 ? ? ? ? ? ? 75 G R N9 1 69
+ATOM 2186 C C8 . G B 2 69 ? 5.625 1.352 10.376 1.00 72.56 ? ? ? ? ? ? 75 G R C8 1 69
+ATOM 2187 N N7 . G B 2 69 ? 6.757 0.851 9.962 1.00 71.87 ? ? ? ? ? ? 75 G R N7 1 69
+ATOM 2188 C C5 . G B 2 69 ? 6.383 -0.253 9.205 1.00 72.03 ? ? ? ? ? ? 75 G R C5 1 69
+ATOM 2189 C C6 . G B 2 69 ? 7.173 -1.195 8.496 1.00 71.88 ? ? ? ? ? ? 75 G R C6 1 69
+ATOM 2190 O O6 . G B 2 69 ? 8.407 -1.233 8.396 1.00 71.72 ? ? ? ? ? ? 75 G R O6 1 69
+ATOM 2191 N N1 . G B 2 69 ? 6.391 -2.165 7.858 1.00 71.90 ? ? ? ? ? ? 75 G R N1 1 69
+ATOM 2192 C C2 . G B 2 69 ? 5.013 -2.213 7.903 1.00 71.17 ? ? ? ? ? ? 75 G R C2 1 69
+ATOM 2193 N N2 . G B 2 69 ? 4.417 -3.209 7.237 1.00 70.27 ? ? ? ? ? ? 75 G R N2 1 69
+ATOM 2194 N N3 . G B 2 69 ? 4.263 -1.338 8.562 1.00 71.45 ? ? ? ? ? ? 75 G R N3 1 69
+ATOM 2195 C C4 . G B 2 69 ? 5.009 -0.388 9.186 1.00 72.30 ? ? ? ? ? ? 75 G R C4 1 69
+ATOM 2196 P P . G B 2 70 ? 3.082 -0.613 14.742 1.00 72.31 ? ? ? ? ? ? 76 G R P 1 70
+ATOM 2197 O OP1 . G B 2 70 ? 2.235 -0.759 15.946 1.00 73.30 ? ? ? ? ? ? 76 G R OP1 1 70
+ATOM 2198 O OP2 . G B 2 70 ? 4.484 -0.167 14.903 1.00 72.40 ? ? ? ? ? ? 76 G R OP2 1 70
+ATOM 2199 O "O5'" . G B 2 70 ? 3.086 -1.999 13.940 1.00 72.44 ? ? ? ? ? ? 76 G R "O5'" 1 70
+ATOM 2200 C "C5'" . G B 2 70 ? 1.869 -2.705 13.702 1.00 72.32 ? ? ? ? ? ? 76 G R "C5'" 1 70
+ATOM 2201 C "C4'" . G B 2 70 ? 2.065 -3.816 12.686 1.00 72.84 ? ? ? ? ? ? 76 G R "C4'" 1 70
+ATOM 2202 O "O4'" . G B 2 70 ? 2.761 -3.308 11.519 1.00 73.09 ? ? ? ? ? ? 76 G R "O4'" 1 70
+ATOM 2203 C "C3'" . G B 2 70 ? 2.928 -4.972 13.162 1.00 73.20 ? ? ? ? ? ? 76 G R "C3'" 1 70
+ATOM 2204 O "O3'" . G B 2 70 ? 2.147 -5.923 13.861 1.00 73.40 ? ? ? ? ? ? 76 G R "O3'" 1 70
+ATOM 2205 C "C2'" . G B 2 70 ? 3.451 -5.545 11.852 1.00 73.38 ? ? ? ? ? ? 76 G R "C2'" 1 70
+ATOM 2206 O "O2'" . G B 2 70 ? 2.519 -6.398 11.214 1.00 75.40 ? ? ? ? ? ? 76 G R "O2'" 1 70
+ATOM 2207 C "C1'" . G B 2 70 ? 3.679 -4.275 11.037 1.00 72.95 ? ? ? ? ? ? 76 G R "C1'" 1 70
+ATOM 2208 N N9 . G B 2 70 ? 5.049 -3.756 11.134 1.00 71.95 ? ? ? ? ? ? 76 G R N9 1 70
+ATOM 2209 C C8 . G B 2 70 ? 5.462 -2.595 11.746 1.00 71.23 ? ? ? ? ? ? 76 G R C8 1 70
+ATOM 2210 N N7 . G B 2 70 ? 6.748 -2.390 11.673 1.00 70.22 ? ? ? ? ? ? 76 G R N7 1 70
+ATOM 2211 C C5 . G B 2 70 ? 7.225 -3.485 10.968 1.00 70.28 ? ? ? ? ? ? 76 G R C5 1 70
+ATOM 2212 C C6 . G B 2 70 ? 8.546 -3.814 10.576 1.00 70.42 ? ? ? ? ? ? 76 G R C6 1 70
+ATOM 2213 O O6 . G B 2 70 ? 9.585 -3.174 10.791 1.00 70.51 ? ? ? ? ? ? 76 G R O6 1 70
+ATOM 2214 N N1 . G B 2 70 ? 8.602 -5.016 9.868 1.00 70.17 ? ? ? ? ? ? 76 G R N1 1 70
+ATOM 2215 C C2 . G B 2 70 ? 7.511 -5.803 9.576 1.00 70.03 ? ? ? ? ? ? 76 G R C2 1 70
+ATOM 2216 N N2 . G B 2 70 ? 7.746 -6.927 8.885 1.00 69.97 ? ? ? ? ? ? 76 G R N2 1 70
+ATOM 2217 N N3 . G B 2 70 ? 6.268 -5.503 9.934 1.00 70.63 ? ? ? ? ? ? 76 G R N3 1 70
+ATOM 2218 C C4 . G B 2 70 ? 6.194 -4.335 10.626 1.00 71.07 ? ? ? ? ? ? 76 G R C4 1 70
+ATOM 2219 P P . U B 2 71 ? 2.713 -6.599 15.196 1.00 74.13 ? ? ? ? ? ? 77 U R P 1 71
+ATOM 2220 O OP1 . U B 2 71 ? 1.720 -7.616 15.612 1.00 74.26 ? ? ? ? ? ? 77 U R OP1 1 71
+ATOM 2221 O OP2 . U B 2 71 ? 3.118 -5.526 16.135 1.00 72.60 ? ? ? ? ? ? 77 U R OP2 1 71
+ATOM 2222 O "O5'" . U B 2 71 ? 4.050 -7.336 14.719 1.00 73.80 ? ? ? ? ? ? 77 U R "O5'" 1 71
+ATOM 2223 C "C5'" . U B 2 71 ? 4.029 -8.495 13.889 1.00 74.24 ? ? ? ? ? ? 77 U R "C5'" 1 71
+ATOM 2224 C "C4'" . U B 2 71 ? 5.443 -8.860 13.476 1.00 74.39 ? ? ? ? ? ? 77 U R "C4'" 1 71
+ATOM 2225 O "O4'" . U B 2 71 ? 5.985 -7.832 12.601 1.00 74.84 ? ? ? ? ? ? 77 U R "O4'" 1 71
+ATOM 2226 C "C3'" . U B 2 71 ? 6.454 -8.899 14.615 1.00 73.90 ? ? ? ? ? ? 77 U R "C3'" 1 71
+ATOM 2227 O "O3'" . U B 2 71 ? 6.376 -10.083 15.398 1.00 71.11 ? ? ? ? ? ? 77 U R "O3'" 1 71
+ATOM 2228 C "C2'" . U B 2 71 ? 7.757 -8.737 13.847 1.00 74.30 ? ? ? ? ? ? 77 U R "C2'" 1 71
+ATOM 2229 O "O2'" . U B 2 71 ? 8.099 -9.890 13.101 1.00 75.85 ? ? ? ? ? ? 77 U R "O2'" 1 71
+ATOM 2230 C "C1'" . U B 2 71 ? 7.346 -7.585 12.932 1.00 74.63 ? ? ? ? ? ? 77 U R "C1'" 1 71
+ATOM 2231 N N1 . U B 2 71 ? 7.492 -6.216 13.569 1.00 74.85 ? ? ? ? ? ? 77 U R N1 1 71
+ATOM 2232 C C2 . U B 2 71 ? 8.744 -5.634 13.714 1.00 75.56 ? ? ? ? ? ? 77 U R C2 1 71
+ATOM 2233 O O2 . U B 2 71 ? 9.786 -6.155 13.350 1.00 76.56 ? ? ? ? ? ? 77 U R O2 1 71
+ATOM 2234 N N3 . U B 2 71 ? 8.741 -4.392 14.310 1.00 75.42 ? ? ? ? ? ? 77 U R N3 1 71
+ATOM 2235 C C4 . U B 2 71 ? 7.641 -3.683 14.767 1.00 75.70 ? ? ? ? ? ? 77 U R C4 1 71
+ATOM 2236 O O4 . U B 2 71 ? 7.785 -2.579 15.280 1.00 76.39 ? ? ? ? ? ? 77 U R O4 1 71
+ATOM 2237 C C5 . U B 2 71 ? 6.377 -4.345 14.587 1.00 75.87 ? ? ? ? ? ? 77 U R C5 1 71
+ATOM 2238 C C6 . U B 2 71 ? 6.362 -5.550 14.008 1.00 75.21 ? ? ? ? ? ? 77 U R C6 1 71
+ATOM 2239 P P . A B 2 72 ? 6.322 -9.915 16.991 1.00 69.61 ? ? ? ? ? ? 78 A R P 1 72
+ATOM 2240 O OP1 . A B 2 72 ? 5.846 -11.191 17.566 1.00 69.08 ? ? ? ? ? ? 78 A R OP1 1 72
+ATOM 2241 O OP2 . A B 2 72 ? 5.613 -8.654 17.309 1.00 69.17 ? ? ? ? ? ? 78 A R OP2 1 72
+ATOM 2242 O "O5'" . A B 2 72 ? 7.855 -9.693 17.386 1.00 68.19 ? ? ? ? ? ? 78 A R "O5'" 1 72
+ATOM 2243 C "C5'" . A B 2 72 ? 8.850 -10.615 16.967 1.00 66.24 ? ? ? ? ? ? 78 A R "C5'" 1 72
+ATOM 2244 C "C4'" . A B 2 72 ? 10.207 -9.942 16.934 1.00 65.11 ? ? ? ? ? ? 78 A R "C4'" 1 72
+ATOM 2245 O "O4'" . A B 2 72 ? 10.159 -8.722 16.153 1.00 64.17 ? ? ? ? ? ? 78 A R "O4'" 1 72
+ATOM 2246 C "C3'" . A B 2 72 ? 10.704 -9.449 18.280 1.00 64.46 ? ? ? ? ? ? 78 A R "C3'" 1 72
+ATOM 2247 O "O3'" . A B 2 72 ? 11.184 -10.521 19.070 1.00 64.45 ? ? ? ? ? ? 78 A R "O3'" 1 72
+ATOM 2248 C "C2'" . A B 2 72 ? 11.810 -8.498 17.843 1.00 63.71 ? ? ? ? ? ? 78 A R "C2'" 1 72
+ATOM 2249 O "O2'" . A B 2 72 ? 12.999 -9.159 17.453 1.00 63.20 ? ? ? ? ? ? 78 A R "O2'" 1 72
+ATOM 2250 C "C1'" . A B 2 72 ? 11.138 -7.822 16.649 1.00 62.80 ? ? ? ? ? ? 78 A R "C1'" 1 72
+ATOM 2251 N N9 . A B 2 72 ? 10.505 -6.551 17.007 1.00 60.44 ? ? ? ? ? ? 78 A R N9 1 72
+ATOM 2252 C C8 . A B 2 72 ? 9.168 -6.291 17.131 1.00 59.67 ? ? ? ? ? ? 78 A R C8 1 72
+ATOM 2253 N N7 . A B 2 72 ? 8.897 -5.051 17.467 1.00 59.06 ? ? ? ? ? ? 78 A R N7 1 72
+ATOM 2254 C C5 . A B 2 72 ? 10.143 -4.454 17.575 1.00 58.42 ? ? ? ? ? ? 78 A R C5 1 72
+ATOM 2255 C C6 . A B 2 72 ? 10.556 -3.141 17.903 1.00 58.02 ? ? ? ? ? ? 78 A R C6 1 72
+ATOM 2256 N N6 . A B 2 72 ? 9.707 -2.150 18.199 1.00 56.38 ? ? ? ? ? ? 78 A R N6 1 72
+ATOM 2257 N N1 . A B 2 72 ? 11.886 -2.880 17.918 1.00 57.36 ? ? ? ? ? ? 78 A R N1 1 72
+ATOM 2258 C C2 . A B 2 72 ? 12.747 -3.865 17.624 1.00 57.20 ? ? ? ? ? ? 78 A R C2 1 72
+ATOM 2259 N N3 . A B 2 72 ? 12.476 -5.133 17.303 1.00 58.27 ? ? ? ? ? ? 78 A R N3 1 72
+ATOM 2260 C C4 . A B 2 72 ? 11.148 -5.366 17.296 1.00 58.98 ? ? ? ? ? ? 78 A R C4 1 72
+ATOM 2261 P P . G B 2 73 ? 10.928 -10.493 20.649 1.00 65.14 ? ? ? ? ? ? 79 G R P 1 73
+ATOM 2262 O OP1 . G B 2 73 ? 11.299 -11.829 21.174 1.00 63.61 ? ? ? ? ? ? 79 G R OP1 1 73
+ATOM 2263 O OP2 . G B 2 73 ? 9.574 -9.943 20.912 1.00 63.23 ? ? ? ? ? ? 79 G R OP2 1 73
+ATOM 2264 O "O5'" . G B 2 73 ? 11.984 -9.399 21.147 1.00 61.88 ? ? ? ? ? ? 79 G R "O5'" 1 73
+ATOM 2265 C "C5'" . G B 2 73 ? 13.378 -9.639 21.031 1.00 59.30 ? ? ? ? ? ? 79 G R "C5'" 1 73
+ATOM 2266 C "C4'" . G B 2 73 ? 14.145 -8.353 21.257 1.00 58.01 ? ? ? ? ? ? 79 G R "C4'" 1 73
+ATOM 2267 O "O4'" . G B 2 73 ? 13.671 -7.323 20.355 1.00 57.31 ? ? ? ? ? ? 79 G R "O4'" 1 73
+ATOM 2268 C "C3'" . G B 2 73 ? 13.951 -7.693 22.613 1.00 57.77 ? ? ? ? ? ? 79 G R "C3'" 1 73
+ATOM 2269 O "O3'" . G B 2 73 ? 14.661 -8.372 23.647 1.00 57.89 ? ? ? ? ? ? 79 G R "O3'" 1 73
+ATOM 2270 C "C2'" . G B 2 73 ? 14.536 -6.321 22.310 1.00 56.72 ? ? ? ? ? ? 79 G R "C2'" 1 73
+ATOM 2271 O "O2'" . G B 2 73 ? 15.951 -6.333 22.264 1.00 57.00 ? ? ? ? ? ? 79 G R "O2'" 1 73
+ATOM 2272 C "C1'" . G B 2 73 ? 13.938 -6.053 20.929 1.00 54.88 ? ? ? ? ? ? 79 G R "C1'" 1 73
+ATOM 2273 N N9 . G B 2 73 ? 12.706 -5.265 20.993 1.00 51.28 ? ? ? ? ? ? 79 G R N9 1 73
+ATOM 2274 C C8 . G B 2 73 ? 11.420 -5.707 20.779 1.00 50.97 ? ? ? ? ? ? 79 G R C8 1 73
+ATOM 2275 N N7 . G B 2 73 ? 10.516 -4.773 20.915 1.00 49.98 ? ? ? ? ? ? 79 G R N7 1 73
+ATOM 2276 C C5 . G B 2 73 ? 11.247 -3.637 21.242 1.00 50.08 ? ? ? ? ? ? 79 G R C5 1 73
+ATOM 2277 C C6 . G B 2 73 ? 10.812 -2.310 21.505 1.00 50.67 ? ? ? ? ? ? 79 G R C6 1 73
+ATOM 2278 O O6 . G B 2 73 ? 9.651 -1.872 21.503 1.00 52.38 ? ? ? ? ? ? 79 G R O6 1 73
+ATOM 2279 N N1 . G B 2 73 ? 11.877 -1.454 21.798 1.00 49.44 ? ? ? ? ? ? 79 G R N1 1 73
+ATOM 2280 C C2 . G B 2 73 ? 13.203 -1.836 21.830 1.00 50.00 ? ? ? ? ? ? 79 G R C2 1 73
+ATOM 2281 N N2 . G B 2 73 ? 14.100 -0.881 22.130 1.00 49.13 ? ? ? ? ? ? 79 G R N2 1 73
+ATOM 2282 N N3 . G B 2 73 ? 13.620 -3.077 21.581 1.00 49.07 ? ? ? ? ? ? 79 G R N3 1 73
+ATOM 2283 C C4 . G B 2 73 ? 12.596 -3.924 21.295 1.00 49.80 ? ? ? ? ? ? 79 G R C4 1 73
+ATOM 2284 P P . G B 2 74 ? 14.122 -8.350 25.160 1.00 57.66 ? ? ? ? ? ? 80 G R P 1 74
+ATOM 2285 O OP1 . G B 2 74 ? 15.098 -9.124 25.964 1.00 57.33 ? ? ? ? ? ? 80 G R OP1 1 74
+ATOM 2286 O OP2 . G B 2 74 ? 12.693 -8.743 25.173 1.00 55.14 ? ? ? ? ? ? 80 G R OP2 1 74
+ATOM 2287 O "O5'" . G B 2 74 ? 14.209 -6.800 25.553 1.00 53.80 ? ? ? ? ? ? 80 G R "O5'" 1 74
+ATOM 2288 C "C5'" . G B 2 74 ? 15.475 -6.243 25.869 1.00 52.46 ? ? ? ? ? ? 80 G R "C5'" 1 74
+ATOM 2289 C "C4'" . G B 2 74 ? 15.433 -4.729 25.957 1.00 51.00 ? ? ? ? ? ? 80 G R "C4'" 1 74
+ATOM 2290 O "O4'" . G B 2 74 ? 14.604 -4.164 24.918 1.00 49.65 ? ? ? ? ? ? 80 G R "O4'" 1 74
+ATOM 2291 C "C3'" . G B 2 74 ? 14.770 -4.162 27.194 1.00 51.14 ? ? ? ? ? ? 80 G R "C3'" 1 74
+ATOM 2292 O "O3'" . G B 2 74 ? 15.575 -4.364 28.347 1.00 52.84 ? ? ? ? ? ? 80 G R "O3'" 1 74
+ATOM 2293 C "C2'" . G B 2 74 ? 14.648 -2.702 26.774 1.00 49.46 ? ? ? ? ? ? 80 G R "C2'" 1 74
+ATOM 2294 O "O2'" . G B 2 74 ? 15.872 -1.998 26.843 1.00 48.81 ? ? ? ? ? ? 80 G R "O2'" 1 74
+ATOM 2295 C "C1'" . G B 2 74 ? 14.205 -2.866 25.319 1.00 47.58 ? ? ? ? ? ? 80 G R "C1'" 1 74
+ATOM 2296 N N9 . G B 2 74 ? 12.761 -2.739 25.118 1.00 45.43 ? ? ? ? ? ? 80 G R N9 1 74
+ATOM 2297 C C8 . G B 2 74 ? 11.886 -3.721 24.714 1.00 43.16 ? ? ? ? ? ? 80 G R C8 1 74
+ATOM 2298 N N7 . G B 2 74 ? 10.650 -3.313 24.622 1.00 43.61 ? ? ? ? ? ? 80 G R N7 1 74
+ATOM 2299 C C5 . G B 2 74 ? 10.705 -1.975 24.988 1.00 42.89 ? ? ? ? ? ? 80 G R C5 1 74
+ATOM 2300 C C6 . G B 2 74 ? 9.674 -1.014 25.075 1.00 42.76 ? ? ? ? ? ? 80 G R C6 1 74
+ATOM 2301 O O6 . G B 2 74 ? 8.469 -1.184 24.835 1.00 45.44 ? ? ? ? ? ? 80 G R O6 1 74
+ATOM 2302 N N1 . G B 2 74 ? 10.150 0.236 25.489 1.00 41.49 ? ? ? ? ? ? 80 G R N1 1 74
+ATOM 2303 C C2 . G B 2 74 ? 11.471 0.513 25.778 1.00 41.84 ? ? ? ? ? ? 80 G R C2 1 74
+ATOM 2304 N N2 . G B 2 74 ? 11.772 1.764 26.155 1.00 39.89 ? ? ? ? ? ? 80 G R N2 1 74
+ATOM 2305 N N3 . G B 2 74 ? 12.447 -0.381 25.694 1.00 43.10 ? ? ? ? ? ? 80 G R N3 1 74
+ATOM 2306 C C4 . G B 2 74 ? 11.996 -1.602 25.296 1.00 44.40 ? ? ? ? ? ? 80 G R C4 1 74
+ATOM 2307 P P . U B 2 75 ? 14.858 -4.790 29.716 1.00 52.40 ? ? ? ? ? ? 81 U R P 1 75
+ATOM 2308 O OP1 . U B 2 75 ? 15.889 -5.311 30.644 1.00 51.65 ? ? ? ? ? ? 81 U R OP1 1 75
+ATOM 2309 O OP2 . U B 2 75 ? 13.689 -5.635 29.391 1.00 50.77 ? ? ? ? ? ? 81 U R OP2 1 75
+ATOM 2310 O "O5'" . U B 2 75 ? 14.320 -3.375 30.238 1.00 51.33 ? ? ? ? ? ? 81 U R "O5'" 1 75
+ATOM 2311 C "C5'" . U B 2 75 ? 15.231 -2.303 30.495 1.00 50.78 ? ? ? ? ? ? 81 U R "C5'" 1 75
+ATOM 2312 C "C4'" . U B 2 75 ? 14.473 -1.002 30.666 1.00 49.83 ? ? ? ? ? ? 81 U R "C4'" 1 75
+ATOM 2313 O "O4'" . U B 2 75 ? 13.684 -0.746 29.482 1.00 50.87 ? ? ? ? ? ? 81 U R "O4'" 1 75
+ATOM 2314 C "C3'" . U B 2 75 ? 13.426 -1.036 31.764 1.00 50.10 ? ? ? ? ? ? 81 U R "C3'" 1 75
+ATOM 2315 O "O3'" . U B 2 75 ? 14.033 -0.837 33.036 1.00 49.50 ? ? ? ? ? ? 81 U R "O3'" 1 75
+ATOM 2316 C "C2'" . U B 2 75 ? 12.480 0.091 31.351 1.00 49.41 ? ? ? ? ? ? 81 U R "C2'" 1 75
+ATOM 2317 O "O2'" . U B 2 75 ? 12.910 1.380 31.745 1.00 50.56 ? ? ? ? ? ? 81 U R "O2'" 1 75
+ATOM 2318 C "C1'" . U B 2 75 ? 12.508 -0.031 29.829 1.00 48.83 ? ? ? ? ? ? 81 U R "C1'" 1 75
+ATOM 2319 N N1 . U B 2 75 ? 11.300 -0.724 29.270 1.00 47.38 ? ? ? ? ? ? 81 U R N1 1 75
+ATOM 2320 C C2 . U B 2 75 ? 10.152 0.012 29.036 1.00 46.82 ? ? ? ? ? ? 81 U R C2 1 75
+ATOM 2321 O O2 . U B 2 75 ? 10.065 1.211 29.258 1.00 47.68 ? ? ? ? ? ? 81 U R O2 1 75
+ATOM 2322 N N3 . U B 2 75 ? 9.097 -0.711 28.527 1.00 44.94 ? ? ? ? ? ? 81 U R N3 1 75
+ATOM 2323 C C4 . U B 2 75 ? 9.079 -2.065 28.232 1.00 46.49 ? ? ? ? ? ? 81 U R C4 1 75
+ATOM 2324 O O4 . U B 2 75 ? 8.064 -2.577 27.774 1.00 48.37 ? ? ? ? ? ? 81 U R O4 1 75
+ATOM 2325 C C5 . U B 2 75 ? 10.309 -2.767 28.497 1.00 46.21 ? ? ? ? ? ? 81 U R C5 1 75
+ATOM 2326 C C6 . U B 2 75 ? 11.346 -2.082 28.998 1.00 47.52 ? ? ? ? ? ? 81 U R C6 1 75
+ATOM 2327 P P . A B 2 76 ? 13.798 -1.911 34.202 1.00 48.15 ? ? ? ? ? ? 82 A R P 1 76
+ATOM 2328 O OP1 . A B 2 76 ? 14.290 -1.283 35.451 1.00 46.89 ? ? ? ? ? ? 82 A R OP1 1 76
+ATOM 2329 O OP2 . A B 2 76 ? 14.356 -3.215 33.771 1.00 46.66 ? ? ? ? ? ? 82 A R OP2 1 76
+ATOM 2330 O "O5'" . A B 2 76 ? 12.207 -2.069 34.249 1.00 44.82 ? ? ? ? ? ? 82 A R "O5'" 1 76
+ATOM 2331 C "C5'" . A B 2 76 ? 11.417 -1.053 34.843 1.00 45.70 ? ? ? ? ? ? 82 A R "C5'" 1 76
+ATOM 2332 C "C4'" . A B 2 76 ? 10.370 -1.627 35.781 1.00 45.95 ? ? ? ? ? ? 82 A R "C4'" 1 76
+ATOM 2333 O "O4'" . A B 2 76 ? 9.539 -2.570 35.053 1.00 45.43 ? ? ? ? ? ? 82 A R "O4'" 1 76
+ATOM 2334 C "C3'" . A B 2 76 ? 10.920 -2.369 36.999 1.00 45.36 ? ? ? ? ? ? 82 A R "C3'" 1 76
+ATOM 2335 O "O3'" . A B 2 76 ? 10.210 -1.979 38.189 1.00 45.87 ? ? ? ? ? ? 82 A R "O3'" 1 76
+ATOM 2336 C "C2'" . A B 2 76 ? 10.697 -3.831 36.622 1.00 45.35 ? ? ? ? ? ? 82 A R "C2'" 1 76
+ATOM 2337 O "O2'" . A B 2 76 ? 10.535 -4.688 37.734 1.00 47.91 ? ? ? ? ? ? 82 A R "O2'" 1 76
+ATOM 2338 C "C1'" . A B 2 76 ? 9.389 -3.719 35.851 1.00 44.92 ? ? ? ? ? ? 82 A R "C1'" 1 76
+ATOM 2339 N N9 . A B 2 76 ? 9.070 -4.873 35.015 1.00 44.59 ? ? ? ? ? ? 82 A R N9 1 76
+ATOM 2340 C C8 . A B 2 76 ? 9.914 -5.869 34.606 1.00 45.57 ? ? ? ? ? ? 82 A R C8 1 76
+ATOM 2341 N N7 . A B 2 76 ? 9.336 -6.785 33.866 1.00 45.95 ? ? ? ? ? ? 82 A R N7 1 76
+ATOM 2342 C C5 . A B 2 76 ? 8.023 -6.360 33.781 1.00 44.58 ? ? ? ? ? ? 82 A R C5 1 76
+ATOM 2343 C C6 . A B 2 76 ? 6.889 -6.894 33.136 1.00 45.34 ? ? ? ? ? ? 82 A R C6 1 76
+ATOM 2344 N N6 . A B 2 76 ? 6.917 -8.024 32.422 1.00 47.42 ? ? ? ? ? ? 82 A R N6 1 76
+ATOM 2345 N N1 . A B 2 76 ? 5.720 -6.226 33.250 1.00 45.56 ? ? ? ? ? ? 82 A R N1 1 76
+ATOM 2346 C C2 . A B 2 76 ? 5.693 -5.094 33.966 1.00 45.89 ? ? ? ? ? ? 82 A R C2 1 76
+ATOM 2347 N N3 . A B 2 76 ? 6.694 -4.495 34.617 1.00 45.59 ? ? ? ? ? ? 82 A R N3 1 76
+ATOM 2348 C C4 . A B 2 76 ? 7.841 -5.185 34.486 1.00 44.73 ? ? ? ? ? ? 82 A R C4 1 76
+ATOM 2349 P P . G B 2 77 ? 11.017 -1.506 39.497 1.00 47.83 ? ? ? ? ? ? 83 G R P 1 77
+ATOM 2350 O OP1 . G B 2 77 ? 12.163 -2.423 39.702 1.00 45.31 ? ? ? ? ? ? 83 G R OP1 1 77
+ATOM 2351 O OP2 . G B 2 77 ? 10.038 -1.282 40.585 1.00 49.31 ? ? ? ? ? ? 83 G R OP2 1 77
+ATOM 2352 O "O5'" . G B 2 77 ? 11.600 -0.072 39.095 1.00 47.50 ? ? ? ? ? ? 83 G R "O5'" 1 77
+ATOM 2353 C "C5'" . G B 2 77 ? 10.743 1.025 38.770 1.00 45.06 ? ? ? ? ? ? 83 G R "C5'" 1 77
+ATOM 2354 C "C4'" . G B 2 77 ? 11.569 2.199 38.272 1.00 43.12 ? ? ? ? ? ? 83 G R "C4'" 1 77
+ATOM 2355 O "O4'" . G B 2 77 ? 12.687 2.441 39.163 1.00 41.40 ? ? ? ? ? ? 83 G R "O4'" 1 77
+ATOM 2356 C "C3'" . G B 2 77 ? 12.210 2.012 36.903 1.00 43.72 ? ? ? ? ? ? 83 G R "C3'" 1 77
+ATOM 2357 O "O3'" . G B 2 77 ? 12.215 3.265 36.248 1.00 47.09 ? ? ? ? ? ? 83 G R "O3'" 1 77
+ATOM 2358 C "C2'" . G B 2 77 ? 13.628 1.572 37.237 1.00 39.54 ? ? ? ? ? ? 83 G R "C2'" 1 77
+ATOM 2359 O "O2'" . G B 2 77 ? 14.543 1.853 36.205 1.00 40.86 ? ? ? ? ? ? 83 G R "O2'" 1 77
+ATOM 2360 C "C1'" . G B 2 77 ? 13.876 2.504 38.408 1.00 38.06 ? ? ? ? ? ? 83 G R "C1'" 1 77
+ATOM 2361 N N9 . G B 2 77 ? 14.986 2.146 39.276 1.00 34.85 ? ? ? ? ? ? 83 G R N9 1 77
+ATOM 2362 C C8 . G B 2 77 ? 15.352 0.889 39.689 1.00 34.47 ? ? ? ? ? ? 83 G R C8 1 77
+ATOM 2363 N N7 . G B 2 77 ? 16.395 0.886 40.469 1.00 33.72 ? ? ? ? ? ? 83 G R N7 1 77
+ATOM 2364 C C5 . G B 2 77 ? 16.739 2.227 40.581 1.00 32.97 ? ? ? ? ? ? 83 G R C5 1 77
+ATOM 2365 C C6 . G B 2 77 ? 17.790 2.841 41.305 1.00 32.85 ? ? ? ? ? ? 83 G R C6 1 77
+ATOM 2366 O O6 . G B 2 77 ? 18.644 2.303 42.017 1.00 36.28 ? ? ? ? ? ? 83 G R O6 1 77
+ATOM 2367 N N1 . G B 2 77 ? 17.800 4.226 41.161 1.00 32.89 ? ? ? ? ? ? 83 G R N1 1 77
+ATOM 2368 C C2 . G B 2 77 ? 16.893 4.933 40.407 1.00 34.15 ? ? ? ? ? ? 83 G R C2 1 77
+ATOM 2369 N N2 . G B 2 77 ? 17.070 6.262 40.398 1.00 34.45 ? ? ? ? ? ? 83 G R N2 1 77
+ATOM 2370 N N3 . G B 2 77 ? 15.895 4.374 39.719 1.00 32.54 ? ? ? ? ? ? 83 G R N3 1 77
+ATOM 2371 C C4 . G B 2 77 ? 15.879 3.019 39.853 1.00 33.39 ? ? ? ? ? ? 83 G R C4 1 77
+ATOM 2372 P P . C B 2 78 ? 11.886 3.373 34.693 1.00 49.46 ? ? ? ? ? ? 84 C R P 1 78
+ATOM 2373 O OP1 . C B 2 78 ? 11.613 2.030 34.141 1.00 48.44 ? ? ? ? ? ? 84 C R OP1 1 78
+ATOM 2374 O OP2 . C B 2 78 ? 12.962 4.192 34.093 1.00 51.80 ? ? ? ? ? ? 84 C R OP2 1 78
+ATOM 2375 O "O5'" . C B 2 78 ? 10.514 4.194 34.693 1.00 51.45 ? ? ? ? ? ? 84 C R "O5'" 1 78
+ATOM 2376 C "C5'" . C B 2 78 ? 10.439 5.554 35.117 1.00 54.65 ? ? ? ? ? ? 84 C R "C5'" 1 78
+ATOM 2377 C "C4'" . C B 2 78 ? 9.043 6.096 34.857 1.00 57.66 ? ? ? ? ? ? 84 C R "C4'" 1 78
+ATOM 2378 O "O4'" . C B 2 78 ? 8.734 5.975 33.441 1.00 58.13 ? ? ? ? ? ? 84 C R "O4'" 1 78
+ATOM 2379 C "C3'" . C B 2 78 ? 7.903 5.325 35.513 1.00 60.05 ? ? ? ? ? ? 84 C R "C3'" 1 78
+ATOM 2380 O "O3'" . C B 2 78 ? 7.710 5.639 36.892 1.00 61.35 ? ? ? ? ? ? 84 C R "O3'" 1 78
+ATOM 2381 C "C2'" . C B 2 78 ? 6.724 5.727 34.625 1.00 60.61 ? ? ? ? ? ? 84 C R "C2'" 1 78
+ATOM 2382 O "O2'" . C B 2 78 ? 6.274 7.057 34.824 1.00 62.79 ? ? ? ? ? ? 84 C R "O2'" 1 78
+ATOM 2383 C "C1'" . C B 2 78 ? 7.382 5.575 33.257 1.00 58.08 ? ? ? ? ? ? 84 C R "C1'" 1 78
+ATOM 2384 N N1 . C B 2 78 ? 7.283 4.163 32.714 1.00 57.22 ? ? ? ? ? ? 84 C R N1 1 78
+ATOM 2385 C C2 . C B 2 78 ? 6.070 3.701 32.163 1.00 57.45 ? ? ? ? ? ? 84 C R C2 1 78
+ATOM 2386 O O2 . C B 2 78 ? 5.082 4.446 32.114 1.00 59.29 ? ? ? ? ? ? 84 C R O2 1 78
+ATOM 2387 N N3 . C B 2 78 ? 6.002 2.429 31.686 1.00 55.60 ? ? ? ? ? ? 84 C R N3 1 78
+ATOM 2388 C C4 . C B 2 78 ? 7.070 1.629 31.743 1.00 55.19 ? ? ? ? ? ? 84 C R C4 1 78
+ATOM 2389 N N4 . C B 2 78 ? 6.947 0.390 31.264 1.00 54.87 ? ? ? ? ? ? 84 C R N4 1 78
+ATOM 2390 C C5 . C B 2 78 ? 8.312 2.066 32.297 1.00 55.31 ? ? ? ? ? ? 84 C R C5 1 78
+ATOM 2391 C C6 . C B 2 78 ? 8.367 3.321 32.761 1.00 56.34 ? ? ? ? ? ? 84 C R C6 1 78
+ATOM 2392 P P . G B 2 79 ? 6.866 4.631 37.815 1.00 63.25 ? ? ? ? ? ? 85 G R P 1 79
+ATOM 2393 O OP1 . G B 2 79 ? 7.429 4.689 39.182 1.00 63.12 ? ? ? ? ? ? 85 G R OP1 1 79
+ATOM 2394 O OP2 . G B 2 79 ? 6.750 3.317 37.143 1.00 62.60 ? ? ? ? ? ? 85 G R OP2 1 79
+ATOM 2395 O "O5'" . G B 2 79 ? 5.422 5.312 37.804 1.00 60.33 ? ? ? ? ? ? 85 G R "O5'" 1 79
+ATOM 2396 C "C5'" . G B 2 79 ? 4.291 4.526 38.093 1.00 59.21 ? ? ? ? ? ? 85 G R "C5'" 1 79
+ATOM 2397 C "C4'" . G B 2 79 ? 3.159 4.854 37.141 1.00 59.01 ? ? ? ? ? ? 85 G R "C4'" 1 79
+ATOM 2398 O "O4'" . G B 2 79 ? 3.589 4.833 35.754 1.00 58.55 ? ? ? ? ? ? 85 G R "O4'" 1 79
+ATOM 2399 C "C3'" . G B 2 79 ? 2.047 3.828 37.153 1.00 59.27 ? ? ? ? ? ? 85 G R "C3'" 1 79
+ATOM 2400 O "O3'" . G B 2 79 ? 1.275 3.953 38.327 1.00 60.57 ? ? ? ? ? ? 85 G R "O3'" 1 79
+ATOM 2401 C "C2'" . G B 2 79 ? 1.325 4.175 35.858 1.00 57.90 ? ? ? ? ? ? 85 G R "C2'" 1 79
+ATOM 2402 O "O2'" . G B 2 79 ? 0.601 5.387 35.895 1.00 58.82 ? ? ? ? ? ? 85 G R "O2'" 1 79
+ATOM 2403 C "C1'" . G B 2 79 ? 2.548 4.294 34.949 1.00 56.89 ? ? ? ? ? ? 85 G R "C1'" 1 79
+ATOM 2404 N N9 . G B 2 79 ? 2.969 2.989 34.430 1.00 54.26 ? ? ? ? ? ? 85 G R N9 1 79
+ATOM 2405 C C8 . G B 2 79 ? 4.195 2.392 34.598 1.00 52.40 ? ? ? ? ? ? 85 G R C8 1 79
+ATOM 2406 N N7 . G B 2 79 ? 4.286 1.222 34.034 1.00 52.13 ? ? ? ? ? ? 85 G R N7 1 79
+ATOM 2407 C C5 . G B 2 79 ? 3.041 1.022 33.456 1.00 51.80 ? ? ? ? ? ? 85 G R C5 1 79
+ATOM 2408 C C6 . G B 2 79 ? 2.545 -0.075 32.708 1.00 51.73 ? ? ? ? ? ? 85 G R C6 1 79
+ATOM 2409 O O6 . G B 2 79 ? 3.131 -1.120 32.395 1.00 51.53 ? ? ? ? ? ? 85 G R O6 1 79
+ATOM 2410 N N1 . G B 2 79 ? 1.227 0.118 32.302 1.00 51.72 ? ? ? ? ? ? 85 G R N1 1 79
+ATOM 2411 C C2 . G B 2 79 ? 0.478 1.234 32.585 1.00 51.74 ? ? ? ? ? ? 85 G R C2 1 79
+ATOM 2412 N N2 . G B 2 79 ? -0.777 1.244 32.113 1.00 52.75 ? ? ? ? ? ? 85 G R N2 1 79
+ATOM 2413 N N3 . G B 2 79 ? 0.930 2.266 33.285 1.00 51.77 ? ? ? ? ? ? 85 G R N3 1 79
+ATOM 2414 C C4 . G B 2 79 ? 2.216 2.099 33.689 1.00 52.38 ? ? ? ? ? ? 85 G R C4 1 79
+ATOM 2415 P P . G B 2 80 ? 1.228 2.708 39.335 1.00 62.35 ? ? ? ? ? ? 86 G R P 1 80
+ATOM 2416 O OP1 . G B 2 80 ? 1.013 3.258 40.692 1.00 62.27 ? ? ? ? ? ? 86 G R OP1 1 80
+ATOM 2417 O OP2 . G B 2 80 ? 2.383 1.811 39.084 1.00 59.97 ? ? ? ? ? ? 86 G R OP2 1 80
+ATOM 2418 O "O5'" . G B 2 80 ? -0.087 1.934 38.852 1.00 61.06 ? ? ? ? ? ? 86 G R "O5'" 1 80
+ATOM 2419 C "C5'" . G B 2 80 ? -1.254 2.660 38.457 1.00 60.52 ? ? ? ? ? ? 86 G R "C5'" 1 80
+ATOM 2420 C "C4'" . G B 2 80 ? -2.023 1.921 37.377 1.00 58.96 ? ? ? ? ? ? 86 G R "C4'" 1 80
+ATOM 2421 O "O4'" . G B 2 80 ? -1.228 1.792 36.170 1.00 60.02 ? ? ? ? ? ? 86 G R "O4'" 1 80
+ATOM 2422 C "C3'" . G B 2 80 ? -2.355 0.482 37.713 1.00 58.00 ? ? ? ? ? ? 86 G R "C3'" 1 80
+ATOM 2423 O "O3'" . G B 2 80 ? -3.443 0.418 38.619 1.00 57.37 ? ? ? ? ? ? 86 G R "O3'" 1 80
+ATOM 2424 C "C2'" . G B 2 80 ? -2.676 -0.070 36.330 1.00 58.05 ? ? ? ? ? ? 86 G R "C2'" 1 80
+ATOM 2425 O "O2'" . G B 2 80 ? -3.948 0.292 35.837 1.00 58.90 ? ? ? ? ? ? 86 G R "O2'" 1 80
+ATOM 2426 C "C1'" . G B 2 80 ? -1.568 0.583 35.507 1.00 58.67 ? ? ? ? ? ? 86 G R "C1'" 1 80
+ATOM 2427 N N9 . G B 2 80 ? -0.399 -0.296 35.406 1.00 58.68 ? ? ? ? ? ? 86 G R N9 1 80
+ATOM 2428 C C8 . G B 2 80 ? 0.857 -0.098 35.933 1.00 57.81 ? ? ? ? ? ? 86 G R C8 1 80
+ATOM 2429 N N7 . G B 2 80 ? 1.687 -1.073 35.683 1.00 57.19 ? ? ? ? ? ? 86 G R N7 1 80
+ATOM 2430 C C5 . G B 2 80 ? 0.936 -1.981 34.947 1.00 57.25 ? ? ? ? ? ? 86 G R C5 1 80
+ATOM 2431 C C6 . G B 2 80 ? 1.295 -3.236 34.393 1.00 57.26 ? ? ? ? ? ? 86 G R C6 1 80
+ATOM 2432 O O6 . G B 2 80 ? 2.390 -3.808 34.454 1.00 58.09 ? ? ? ? ? ? 86 G R O6 1 80
+ATOM 2433 N N1 . G B 2 80 ? 0.232 -3.843 33.722 1.00 57.48 ? ? ? ? ? ? 86 G R N1 1 80
+ATOM 2434 C C2 . G B 2 80 ? -1.026 -3.296 33.595 1.00 58.19 ? ? ? ? ? ? 86 G R C2 1 80
+ATOM 2435 N N2 . G B 2 80 ? -1.938 -4.007 32.914 1.00 58.42 ? ? ? ? ? ? 86 G R N2 1 80
+ATOM 2436 N N3 . G B 2 80 ? -1.373 -2.125 34.112 1.00 57.80 ? ? ? ? ? ? 86 G R N3 1 80
+ATOM 2437 C C4 . G B 2 80 ? -0.349 -1.521 34.770 1.00 57.74 ? ? ? ? ? ? 86 G R C4 1 80
+ATOM 2438 P P . G B 2 81 ? -3.358 -0.547 39.893 1.00 55.75 ? ? ? ? ? ? 87 G R P 1 81
+ATOM 2439 O OP1 . G B 2 81 ? -4.558 -0.317 40.729 1.00 56.05 ? ? ? ? ? ? 87 G R OP1 1 81
+ATOM 2440 O OP2 . G B 2 81 ? -2.015 -0.385 40.504 1.00 54.68 ? ? ? ? ? ? 87 G R OP2 1 81
+ATOM 2441 O "O5'" . G B 2 81 ? -3.461 -2.002 39.228 1.00 53.17 ? ? ? ? ? ? 87 G R "O5'" 1 81
+ATOM 2442 C "C5'" . G B 2 81 ? -4.602 -2.390 38.472 1.00 51.62 ? ? ? ? ? ? 87 G R "C5'" 1 81
+ATOM 2443 C "C4'" . G B 2 81 ? -4.289 -3.619 37.640 1.00 52.46 ? ? ? ? ? ? 87 G R "C4'" 1 81
+ATOM 2444 O "O4'" . G B 2 81 ? -3.197 -3.333 36.730 1.00 52.03 ? ? ? ? ? ? 87 G R "O4'" 1 81
+ATOM 2445 C "C3'" . G B 2 81 ? -3.765 -4.810 38.420 1.00 52.68 ? ? ? ? ? ? 87 G R "C3'" 1 81
+ATOM 2446 O "O3'" . G B 2 81 ? -4.805 -5.524 39.083 1.00 54.90 ? ? ? ? ? ? 87 G R "O3'" 1 81
+ATOM 2447 C "C2'" . G B 2 81 ? -3.090 -5.615 37.312 1.00 51.73 ? ? ? ? ? ? 87 G R "C2'" 1 81
+ATOM 2448 O "O2'" . G B 2 81 ? -3.989 -6.319 36.476 1.00 52.38 ? ? ? ? ? ? 87 G R "O2'" 1 81
+ATOM 2449 C "C1'" . G B 2 81 ? -2.405 -4.494 36.542 1.00 50.01 ? ? ? ? ? ? 87 G R "C1'" 1 81
+ATOM 2450 N N9 . G B 2 81 ? -1.035 -4.247 37.004 1.00 49.04 ? ? ? ? ? ? 87 G R N9 1 81
+ATOM 2451 C C8 . G B 2 81 ? -0.571 -3.162 37.715 1.00 48.04 ? ? ? ? ? ? 87 G R C8 1 81
+ATOM 2452 N N7 . G B 2 81 ? 0.703 -3.218 37.993 1.00 46.91 ? ? ? ? ? ? 87 G R N7 1 81
+ATOM 2453 C C5 . G B 2 81 ? 1.118 -4.423 37.435 1.00 46.63 ? ? ? ? ? ? 87 G R C5 1 81
+ATOM 2454 C C6 . G B 2 81 ? 2.399 -5.032 37.410 1.00 45.57 ? ? ? ? ? ? 87 G R C6 1 81
+ATOM 2455 O O6 . G B 2 81 ? 3.458 -4.617 37.890 1.00 45.95 ? ? ? ? ? ? 87 G R O6 1 81
+ATOM 2456 N N1 . G B 2 81 ? 2.393 -6.253 36.745 1.00 46.37 ? ? ? ? ? ? 87 G R N1 1 81
+ATOM 2457 C C2 . G B 2 81 ? 1.282 -6.820 36.166 1.00 47.68 ? ? ? ? ? ? 87 G R C2 1 81
+ATOM 2458 N N2 . G B 2 81 ? 1.468 -8.004 35.565 1.00 47.34 ? ? ? ? ? ? 87 G R N2 1 81
+ATOM 2459 N N3 . G B 2 81 ? 0.075 -6.262 36.176 1.00 47.12 ? ? ? ? ? ? 87 G R N3 1 81
+ATOM 2460 C C4 . G B 2 81 ? 0.062 -5.068 36.824 1.00 47.59 ? ? ? ? ? ? 87 G R C4 1 81
+ATOM 2461 P P . G B 2 82 ? -4.452 -6.318 40.437 1.00 57.33 ? ? ? ? ? ? 88 G R P 1 82
+ATOM 2462 O OP1 . G B 2 82 ? -5.721 -6.800 41.027 1.00 56.38 ? ? ? ? ? ? 88 G R OP1 1 82
+ATOM 2463 O OP2 . G B 2 82 ? -3.524 -5.481 41.237 1.00 55.25 ? ? ? ? ? ? 88 G R OP2 1 82
+ATOM 2464 O "O5'" . G B 2 82 ? -3.626 -7.587 39.914 1.00 56.94 ? ? ? ? ? ? 88 G R "O5'" 1 82
+ATOM 2465 C "C5'" . G B 2 82 ? -4.248 -8.549 39.058 1.00 56.89 ? ? ? ? ? ? 88 G R "C5'" 1 82
+ATOM 2466 C "C4'" . G B 2 82 ? -3.237 -9.570 38.575 1.00 55.72 ? ? ? ? ? ? 88 G R "C4'" 1 82
+ATOM 2467 O "O4'" . G B 2 82 ? -2.168 -8.913 37.850 1.00 55.49 ? ? ? ? ? ? 88 G R "O4'" 1 82
+ATOM 2468 C "C3'" . G B 2 82 ? -2.501 -10.306 39.680 1.00 55.58 ? ? ? ? ? ? 88 G R "C3'" 1 82
+ATOM 2469 O "O3'" . G B 2 82 ? -3.314 -11.336 40.231 1.00 55.95 ? ? ? ? ? ? 88 G R "O3'" 1 82
+ATOM 2470 C "C2'" . G B 2 82 ? -1.291 -10.825 38.913 1.00 54.34 ? ? ? ? ? ? 88 G R "C2'" 1 82
+ATOM 2471 O "O2'" . G B 2 82 ? -1.605 -11.912 38.070 1.00 54.19 ? ? ? ? ? ? 88 G R "O2'" 1 82
+ATOM 2472 C "C1'" . G B 2 82 ? -0.949 -9.601 38.069 1.00 53.58 ? ? ? ? ? ? 88 G R "C1'" 1 82
+ATOM 2473 N N9 . G B 2 82 ? -0.002 -8.686 38.711 1.00 52.96 ? ? ? ? ? ? 88 G R N9 1 82
+ATOM 2474 C C8 . G B 2 82 ? -0.277 -7.436 39.218 1.00 53.54 ? ? ? ? ? ? 88 G R C8 1 82
+ATOM 2475 N N7 . G B 2 82 ? 0.758 -6.834 39.739 1.00 52.35 ? ? ? ? ? ? 88 G R N7 1 82
+ATOM 2476 C C5 . G B 2 82 ? 1.789 -7.746 39.569 1.00 51.27 ? ? ? ? ? ? 88 G R C5 1 82
+ATOM 2477 C C6 . G B 2 82 ? 3.152 -7.648 39.933 1.00 50.82 ? ? ? ? ? ? 88 G R C6 1 82
+ATOM 2478 O O6 . G B 2 82 ? 3.722 -6.708 40.501 1.00 51.78 ? ? ? ? ? ? 88 G R O6 1 82
+ATOM 2479 N N1 . G B 2 82 ? 3.875 -8.788 39.587 1.00 50.54 ? ? ? ? ? ? 88 G R N1 1 82
+ATOM 2480 C C2 . G B 2 82 ? 3.341 -9.889 38.958 1.00 50.86 ? ? ? ? ? ? 88 G R C2 1 82
+ATOM 2481 N N2 . G B 2 82 ? 4.192 -10.891 38.700 1.00 49.84 ? ? ? ? ? ? 88 G R N2 1 82
+ATOM 2482 N N3 . G B 2 82 ? 2.062 -9.993 38.606 1.00 50.71 ? ? ? ? ? ? 88 G R N3 1 82
+ATOM 2483 C C4 . G B 2 82 ? 1.343 -8.890 38.940 1.00 51.31 ? ? ? ? ? ? 88 G R C4 1 82
+ATOM 2484 P P . U B 2 83 ? -3.334 -11.564 41.818 1.00 56.48 ? ? ? ? ? ? 89 U R P 1 83
+ATOM 2485 O OP1 . U B 2 83 ? -4.350 -12.600 42.112 1.00 56.34 ? ? ? ? ? ? 89 U R OP1 1 83
+ATOM 2486 O OP2 . U B 2 83 ? -3.425 -10.244 42.482 1.00 54.55 ? ? ? ? ? ? 89 U R OP2 1 83
+ATOM 2487 O "O5'" . U B 2 83 ? -1.879 -12.165 42.103 1.00 54.15 ? ? ? ? ? ? 89 U R "O5'" 1 83
+ATOM 2488 C "C5'" . U B 2 83 ? -1.553 -13.490 41.679 1.00 53.12 ? ? ? ? ? ? 89 U R "C5'" 1 83
+ATOM 2489 C "C4'" . U B 2 83 ? -0.059 -13.733 41.777 1.00 51.71 ? ? ? ? ? ? 89 U R "C4'" 1 83
+ATOM 2490 O "O4'" . U B 2 83 ? 0.647 -12.686 41.068 1.00 51.86 ? ? ? ? ? ? 89 U R "O4'" 1 83
+ATOM 2491 C "C3'" . U B 2 83 ? 0.517 -13.633 43.181 1.00 51.13 ? ? ? ? ? ? 89 U R "C3'" 1 83
+ATOM 2492 O "O3'" . U B 2 83 ? 0.299 -14.812 43.934 1.00 48.90 ? ? ? ? ? ? 89 U R "O3'" 1 83
+ATOM 2493 C "C2'" . U B 2 83 ? 1.989 -13.390 42.882 1.00 50.59 ? ? ? ? ? ? 89 U R "C2'" 1 83
+ATOM 2494 O "O2'" . U B 2 83 ? 2.651 -14.558 42.455 1.00 52.53 ? ? ? ? ? ? 89 U R "O2'" 1 83
+ATOM 2495 C "C1'" . U B 2 83 ? 1.876 -12.408 41.724 1.00 51.16 ? ? ? ? ? ? 89 U R "C1'" 1 83
+ATOM 2496 N N1 . U B 2 83 ? 1.939 -10.973 42.165 1.00 52.58 ? ? ? ? ? ? 89 U R N1 1 83
+ATOM 2497 C C2 . U B 2 83 ? 3.180 -10.398 42.367 1.00 53.85 ? ? ? ? ? ? 89 U R C2 1 83
+ATOM 2498 O O2 . U B 2 83 ? 4.232 -10.983 42.204 1.00 56.49 ? ? ? ? ? ? 89 U R O2 1 83
+ATOM 2499 N N3 . U B 2 83 ? 3.157 -9.088 42.774 1.00 55.13 ? ? ? ? ? ? 89 U R N3 1 83
+ATOM 2500 C C4 . U B 2 83 ? 2.040 -8.301 42.996 1.00 56.18 ? ? ? ? ? ? 89 U R C4 1 83
+ATOM 2501 O O4 . U B 2 83 ? 2.195 -7.136 43.355 1.00 58.79 ? ? ? ? ? ? 89 U R O4 1 83
+ATOM 2502 C C5 . U B 2 83 ? 0.775 -8.959 42.768 1.00 54.63 ? ? ? ? ? ? 89 U R C5 1 83
+ATOM 2503 C C6 . U B 2 83 ? 0.776 -10.241 42.373 1.00 54.47 ? ? ? ? ? ? 89 U R C6 1 83
+ATOM 2504 P P . U B 2 84 ? 0.075 -14.665 45.511 1.00 48.67 ? ? ? ? ? ? 90 U R P 1 84
+ATOM 2505 O OP1 . U B 2 84 ? -0.506 -15.933 46.007 1.00 47.76 ? ? ? ? ? ? 90 U R OP1 1 84
+ATOM 2506 O OP2 . U B 2 84 ? -0.603 -13.374 45.774 1.00 46.97 ? ? ? ? ? ? 90 U R OP2 1 84
+ATOM 2507 O "O5'" . U B 2 84 ? 1.566 -14.536 46.062 1.00 46.20 ? ? ? ? ? ? 90 U R "O5'" 1 84
+ATOM 2508 C "C5'" . U B 2 84 ? 2.420 -15.654 45.969 1.00 44.74 ? ? ? ? ? ? 90 U R "C5'" 1 84
+ATOM 2509 C "C4'" . U B 2 84 ? 3.838 -15.242 46.274 1.00 43.30 ? ? ? ? ? ? 90 U R "C4'" 1 84
+ATOM 2510 O "O4'" . U B 2 84 ? 4.267 -14.197 45.366 1.00 42.68 ? ? ? ? ? ? 90 U R "O4'" 1 84
+ATOM 2511 C "C3'" . U B 2 84 ? 4.019 -14.594 47.631 1.00 42.37 ? ? ? ? ? ? 90 U R "C3'" 1 84
+ATOM 2512 O "O3'" . U B 2 84 ? 4.017 -15.566 48.651 1.00 44.11 ? ? ? ? ? ? 90 U R "O3'" 1 84
+ATOM 2513 C "C2'" . U B 2 84 ? 5.393 -13.977 47.427 1.00 41.27 ? ? ? ? ? ? 90 U R "C2'" 1 84
+ATOM 2514 O "O2'" . U B 2 84 ? 6.438 -14.925 47.499 1.00 38.75 ? ? ? ? ? ? 90 U R "O2'" 1 84
+ATOM 2515 C "C1'" . U B 2 84 ? 5.238 -13.396 46.022 1.00 41.69 ? ? ? ? ? ? 90 U R "C1'" 1 84
+ATOM 2516 N N1 . U B 2 84 ? 4.800 -11.952 46.073 1.00 41.46 ? ? ? ? ? ? 90 U R N1 1 84
+ATOM 2517 C C2 . U B 2 84 ? 5.723 -10.971 46.409 1.00 40.57 ? ? ? ? ? ? 90 U R C2 1 84
+ATOM 2518 O O2 . U B 2 84 ? 6.893 -11.198 46.655 1.00 39.08 ? ? ? ? ? ? 90 U R O2 1 84
+ATOM 2519 N N3 . U B 2 84 ? 5.225 -9.689 46.447 1.00 40.46 ? ? ? ? ? ? 90 U R N3 1 84
+ATOM 2520 C C4 . U B 2 84 ? 3.922 -9.295 46.186 1.00 42.05 ? ? ? ? ? ? 90 U R C4 1 84
+ATOM 2521 O O4 . U B 2 84 ? 3.621 -8.106 46.254 1.00 45.54 ? ? ? ? ? ? 90 U R O4 1 84
+ATOM 2522 C C5 . U B 2 84 ? 3.015 -10.365 45.851 1.00 40.72 ? ? ? ? ? ? 90 U R C5 1 84
+ATOM 2523 C C6 . U B 2 84 ? 3.478 -11.621 45.811 1.00 40.94 ? ? ? ? ? ? 90 U R C6 1 84
+ATOM 2524 P P . A B 2 85 ? 3.462 -15.202 50.108 1.00 44.99 ? ? ? ? ? ? 91 A R P 1 85
+ATOM 2525 O OP1 . A B 2 85 ? 3.420 -16.465 50.879 1.00 45.40 ? ? ? ? ? ? 91 A R OP1 1 85
+ATOM 2526 O OP2 . A B 2 85 ? 2.227 -14.392 49.957 1.00 42.04 ? ? ? ? ? ? 91 A R OP2 1 85
+ATOM 2527 O "O5'" . A B 2 85 ? 4.617 -14.274 50.722 1.00 44.06 ? ? ? ? ? ? 91 A R "O5'" 1 85
+ATOM 2528 C "C5'" . A B 2 85 ? 5.928 -14.786 50.971 1.00 43.66 ? ? ? ? ? ? 91 A R "C5'" 1 85
+ATOM 2529 C "C4'" . A B 2 85 ? 6.948 -13.660 51.058 1.00 44.12 ? ? ? ? ? ? 91 A R "C4'" 1 85
+ATOM 2530 O "O4'" . A B 2 85 ? 6.797 -12.722 49.964 1.00 44.00 ? ? ? ? ? ? 91 A R "O4'" 1 85
+ATOM 2531 C "C3'" . A B 2 85 ? 6.797 -12.761 52.266 1.00 45.38 ? ? ? ? ? ? 91 A R "C3'" 1 85
+ATOM 2532 O "O3'" . A B 2 85 ? 7.362 -13.380 53.398 1.00 46.03 ? ? ? ? ? ? 91 A R "O3'" 1 85
+ATOM 2533 C "C2'" . A B 2 85 ? 7.574 -11.521 51.838 1.00 44.50 ? ? ? ? ? ? 91 A R "C2'" 1 85
+ATOM 2534 O "O2'" . A B 2 85 ? 8.978 -11.680 51.941 1.00 44.63 ? ? ? ? ? ? 91 A R "O2'" 1 85
+ATOM 2535 C "C1'" . A B 2 85 ? 7.169 -11.417 50.372 1.00 41.87 ? ? ? ? ? ? 91 A R "C1'" 1 85
+ATOM 2536 N N9 . A B 2 85 ? 6.071 -10.481 50.111 1.00 39.40 ? ? ? ? ? ? 91 A R N9 1 85
+ATOM 2537 C C8 . A B 2 85 ? 4.790 -10.788 49.731 1.00 38.55 ? ? ? ? ? ? 91 A R C8 1 85
+ATOM 2538 N N7 . A B 2 85 ? 4.010 -9.742 49.557 1.00 36.24 ? ? ? ? ? ? 91 A R N7 1 85
+ATOM 2539 C C5 . A B 2 85 ? 4.835 -8.670 49.840 1.00 35.05 ? ? ? ? ? ? 91 A R C5 1 85
+ATOM 2540 C C6 . A B 2 85 ? 4.612 -7.278 49.845 1.00 34.55 ? ? ? ? ? ? 91 A R C6 1 85
+ATOM 2541 N N6 . A B 2 85 ? 3.435 -6.728 49.538 1.00 33.41 ? ? ? ? ? ? 91 A R N6 1 85
+ATOM 2542 N N1 . A B 2 85 ? 5.644 -6.470 50.178 1.00 35.06 ? ? ? ? ? ? 91 A R N1 1 85
+ATOM 2543 C C2 . A B 2 85 ? 6.827 -7.024 50.485 1.00 35.95 ? ? ? ? ? ? 91 A R C2 1 85
+ATOM 2544 N N3 . A B 2 85 ? 7.157 -8.319 50.516 1.00 36.05 ? ? ? ? ? ? 91 A R N3 1 85
+ATOM 2545 C C4 . A B 2 85 ? 6.109 -9.101 50.181 1.00 37.46 ? ? ? ? ? ? 91 A R C4 1 85
+ATOM 2546 P P . C B 2 86 ? 6.789 -13.028 54.847 1.00 48.12 ? ? ? ? ? ? 92 C R P 1 86
+ATOM 2547 O OP1 . C B 2 86 ? 6.771 -14.310 55.590 1.00 48.81 ? ? ? ? ? ? 92 C R OP1 1 86
+ATOM 2548 O OP2 . C B 2 86 ? 5.542 -12.228 54.736 1.00 44.57 ? ? ? ? ? ? 92 C R OP2 1 86
+ATOM 2549 O "O5'" . C B 2 86 ? 7.933 -12.066 55.427 1.00 48.26 ? ? ? ? ? ? 92 C R "O5'" 1 86
+ATOM 2550 C "C5'" . C B 2 86 ? 9.231 -12.573 55.725 1.00 49.47 ? ? ? ? ? ? 92 C R "C5'" 1 86
+ATOM 2551 C "C4'" . C B 2 86 ? 10.101 -11.516 56.382 1.00 52.54 ? ? ? ? ? ? 92 C R "C4'" 1 86
+ATOM 2552 O "O4'" . C B 2 86 ? 10.443 -10.494 55.409 1.00 52.45 ? ? ? ? ? ? 92 C R "O4'" 1 86
+ATOM 2553 C "C3'" . C B 2 86 ? 9.467 -10.732 57.525 1.00 54.93 ? ? ? ? ? ? 92 C R "C3'" 1 86
+ATOM 2554 O "O3'" . C B 2 86 ? 9.573 -11.442 58.753 1.00 59.24 ? ? ? ? ? ? 92 C R "O3'" 1 86
+ATOM 2555 C "C2'" . C B 2 86 ? 10.325 -9.471 57.529 1.00 53.80 ? ? ? ? ? ? 92 C R "C2'" 1 86
+ATOM 2556 O "O2'" . C B 2 86 ? 11.572 -9.651 58.178 1.00 56.21 ? ? ? ? ? ? 92 C R "O2'" 1 86
+ATOM 2557 C "C1'" . C B 2 86 ? 10.521 -9.225 56.037 1.00 51.06 ? ? ? ? ? ? 92 C R "C1'" 1 86
+ATOM 2558 N N1 . C B 2 86 ? 9.491 -8.287 55.465 1.00 48.29 ? ? ? ? ? ? 92 C R N1 1 86
+ATOM 2559 C C2 . C B 2 86 ? 9.610 -6.899 55.667 1.00 47.94 ? ? ? ? ? ? 92 C R C2 1 86
+ATOM 2560 O O2 . C B 2 86 ? 10.568 -6.447 56.314 1.00 49.20 ? ? ? ? ? ? 92 C R O2 1 86
+ATOM 2561 N N3 . C B 2 86 ? 8.660 -6.075 55.142 1.00 45.47 ? ? ? ? ? ? 92 C R N3 1 86
+ATOM 2562 C C4 . C B 2 86 ? 7.636 -6.584 54.448 1.00 45.47 ? ? ? ? ? ? 92 C R C4 1 86
+ATOM 2563 N N4 . C B 2 86 ? 6.725 -5.741 53.948 1.00 46.21 ? ? ? ? ? ? 92 C R N4 1 86
+ATOM 2564 C C5 . C B 2 86 ? 7.497 -7.987 54.232 1.00 45.83 ? ? ? ? ? ? 92 C R C5 1 86
+ATOM 2565 C C6 . C B 2 86 ? 8.434 -8.787 54.751 1.00 47.06 ? ? ? ? ? ? 92 C R C6 1 86
+ATOM 2566 P P . C B 2 87 ? 8.530 -11.192 59.941 1.00 62.53 ? ? ? ? ? ? 93 C R P 1 87
+ATOM 2567 O OP1 . C B 2 87 ? 8.886 -12.134 61.027 1.00 61.81 ? ? ? ? ? ? 93 C R OP1 1 87
+ATOM 2568 O OP2 . C B 2 87 ? 7.161 -11.180 59.374 1.00 62.77 ? ? ? ? ? ? 93 C R OP2 1 87
+ATOM 2569 O "O5'" . C B 2 87 ? 8.842 -9.697 60.413 1.00 62.73 ? ? ? ? ? ? 93 C R "O5'" 1 87
+ATOM 2570 C "C5'" . C B 2 87 ? 10.038 -9.370 61.116 1.00 63.71 ? ? ? ? ? ? 93 C R "C5'" 1 87
+ATOM 2571 C "C4'" . C B 2 87 ? 10.062 -7.877 61.377 1.00 64.24 ? ? ? ? ? ? 93 C R "C4'" 1 87
+ATOM 2572 O "O4'" . C B 2 87 ? 9.922 -7.159 60.127 1.00 62.97 ? ? ? ? ? ? 93 C R "O4'" 1 87
+ATOM 2573 C "C3'" . C B 2 87 ? 8.895 -7.386 62.212 1.00 65.58 ? ? ? ? ? ? 93 C R "C3'" 1 87
+ATOM 2574 O "O3'" . C B 2 87 ? 9.208 -7.548 63.587 1.00 69.98 ? ? ? ? ? ? 93 C R "O3'" 1 87
+ATOM 2575 C "C2'" . C B 2 87 ? 8.757 -5.924 61.792 1.00 63.66 ? ? ? ? ? ? 93 C R "C2'" 1 87
+ATOM 2576 O "O2'" . C B 2 87 ? 9.588 -5.036 62.514 1.00 65.57 ? ? ? ? ? ? 93 C R "O2'" 1 87
+ATOM 2577 C "C1'" . C B 2 87 ? 9.186 -5.964 60.329 1.00 60.61 ? ? ? ? ? ? 93 C R "C1'" 1 87
+ATOM 2578 N N1 . C B 2 87 ? 8.031 -5.894 59.374 1.00 57.06 ? ? ? ? ? ? 93 C R N1 1 87
+ATOM 2579 C C2 . C B 2 87 ? 7.417 -4.656 59.104 1.00 57.01 ? ? ? ? ? ? 93 C R C2 1 87
+ATOM 2580 O O2 . C B 2 87 ? 7.826 -3.622 59.652 1.00 58.45 ? ? ? ? ? ? 93 C R O2 1 87
+ATOM 2581 N N3 . C B 2 87 ? 6.374 -4.615 58.237 1.00 54.97 ? ? ? ? ? ? 93 C R N3 1 87
+ATOM 2582 C C4 . C B 2 87 ? 5.945 -5.733 57.653 1.00 53.89 ? ? ? ? ? ? 93 C R C4 1 87
+ATOM 2583 N N4 . C B 2 87 ? 4.919 -5.630 56.806 1.00 53.67 ? ? ? ? ? ? 93 C R N4 1 87
+ATOM 2584 C C5 . C B 2 87 ? 6.548 -7.001 57.910 1.00 54.10 ? ? ? ? ? ? 93 C R C5 1 87
+ATOM 2585 C C6 . C B 2 87 ? 7.576 -7.033 58.767 1.00 55.05 ? ? ? ? ? ? 93 C R C6 1 87
+ATOM 2586 P P . G B 2 88 ? 8.200 -8.323 64.560 1.00 72.12 ? ? ? ? ? ? 94 G R P 1 88
+ATOM 2587 O OP1 . G B 2 88 ? 8.924 -8.527 65.835 1.00 72.35 ? ? ? ? ? ? 94 G R OP1 1 88
+ATOM 2588 O OP2 . G B 2 88 ? 7.638 -9.492 63.844 1.00 71.76 ? ? ? ? ? ? 94 G R OP2 1 88
+ATOM 2589 O "O5'" . G B 2 88 ? 7.017 -7.265 64.766 1.00 72.76 ? ? ? ? ? ? 94 G R "O5'" 1 88
+ATOM 2590 C "C5'" . G B 2 88 ? 7.316 -5.954 65.232 1.00 75.85 ? ? ? ? ? ? 94 G R "C5'" 1 88
+ATOM 2591 C "C4'" . G B 2 88 ? 6.274 -4.962 64.751 1.00 78.99 ? ? ? ? ? ? 94 G R "C4'" 1 88
+ATOM 2592 O "O4'" . G B 2 88 ? 6.011 -5.149 63.333 1.00 78.53 ? ? ? ? ? ? 94 G R "O4'" 1 88
+ATOM 2593 C "C3'" . G B 2 88 ? 4.927 -5.073 65.462 1.00 81.20 ? ? ? ? ? ? 94 G R "C3'" 1 88
+ATOM 2594 O "O3'" . G B 2 88 ? 4.539 -3.799 65.972 1.00 87.68 ? ? ? ? ? ? 94 G R "O3'" 1 88
+ATOM 2595 C "C2'" . G B 2 88 ? 3.990 -5.521 64.346 1.00 79.31 ? ? ? ? ? ? 94 G R "C2'" 1 88
+ATOM 2596 O "O2'" . G B 2 88 ? 2.671 -5.047 64.513 1.00 79.21 ? ? ? ? ? ? 94 G R "O2'" 1 88
+ATOM 2597 C "C1'" . G B 2 88 ? 4.645 -4.868 63.134 1.00 77.81 ? ? ? ? ? ? 94 G R "C1'" 1 88
+ATOM 2598 N N9 . G B 2 88 ? 4.148 -5.408 61.869 1.00 75.37 ? ? ? ? ? ? 94 G R N9 1 88
+ATOM 2599 C C8 . G B 2 88 ? 4.129 -6.733 61.501 1.00 74.93 ? ? ? ? ? ? 94 G R C8 1 88
+ATOM 2600 N N7 . G B 2 88 ? 3.609 -6.945 60.327 1.00 73.75 ? ? ? ? ? ? 94 G R N7 1 88
+ATOM 2601 C C5 . G B 2 88 ? 3.254 -5.680 59.882 1.00 72.45 ? ? ? ? ? ? 94 G R C5 1 88
+ATOM 2602 C C6 . G B 2 88 ? 2.640 -5.288 58.666 1.00 70.81 ? ? ? ? ? ? 94 G R C6 1 88
+ATOM 2603 O O6 . G B 2 88 ? 2.292 -6.010 57.724 1.00 69.88 ? ? ? ? ? ? 94 G R O6 1 88
+ATOM 2604 N N1 . G B 2 88 ? 2.446 -3.911 58.586 1.00 70.40 ? ? ? ? ? ? 94 G R N1 1 88
+ATOM 2605 C C2 . G B 2 88 ? 2.800 -3.019 59.572 1.00 71.08 ? ? ? ? ? ? 94 G R C2 1 88
+ATOM 2606 N N2 . G B 2 88 ? 2.528 -1.731 59.314 1.00 68.72 ? ? ? ? ? ? 94 G R N2 1 88
+ATOM 2607 N N3 . G B 2 88 ? 3.374 -3.374 60.725 1.00 72.04 ? ? ? ? ? ? 94 G R N3 1 88
+ATOM 2608 C C4 . G B 2 88 ? 3.574 -4.718 60.818 1.00 73.22 ? ? ? ? ? ? 94 G R C4 1 88
+ATOM 2609 P P . A B 2 89 ? 4.584 -3.446 67.537 1.00 92.04 ? ? ? ? ? ? 95 A R P 1 89
+ATOM 2610 O OP1 . A B 2 89 ? 5.975 -3.080 67.889 1.00 91.19 ? ? ? ? ? ? 95 A R OP1 1 89
+ATOM 2611 O OP2 . A B 2 89 ? 3.890 -4.527 68.276 1.00 92.46 ? ? ? ? ? ? 95 A R OP2 1 89
+ATOM 2612 O "O5'" . A B 2 89 ? 3.680 -2.127 67.620 1.00 93.23 ? ? ? ? ? ? 95 A R "O5'" 1 89
+ATOM 2613 C "C5'" . A B 2 89 ? 3.859 -1.104 66.652 1.00 97.33 ? ? ? ? ? ? 95 A R "C5'" 1 89
+ATOM 2614 C "C4'" . A B 2 89 ? 4.415 0.161 67.278 1.00 100.21 ? ? ? ? ? ? 95 A R "C4'" 1 89
+ATOM 2615 O "O4'" . A B 2 89 ? 5.166 0.911 66.286 1.00 101.29 ? ? ? ? ? ? 95 A R "O4'" 1 89
+ATOM 2616 C "C3'" . A B 2 89 ? 3.365 1.124 67.816 1.00 102.08 ? ? ? ? ? ? 95 A R "C3'" 1 89
+ATOM 2617 O "O3'" . A B 2 89 ? 3.881 1.747 68.988 1.00 105.23 ? ? ? ? ? ? 95 A R "O3'" 1 89
+ATOM 2618 C "C2'" . A B 2 89 ? 3.173 2.098 66.652 1.00 102.18 ? ? ? ? ? ? 95 A R "C2'" 1 89
+ATOM 2619 O "O2'" . A B 2 89 ? 2.683 3.363 67.050 1.00 101.40 ? ? ? ? ? ? 95 A R "O2'" 1 89
+ATOM 2620 C "C1'" . A B 2 89 ? 4.599 2.198 66.117 1.00 102.63 ? ? ? ? ? ? 95 A R "C1'" 1 89
+ATOM 2621 N N9 . A B 2 89 ? 4.703 2.597 64.710 1.00 103.68 ? ? ? ? ? ? 95 A R N9 1 89
+ATOM 2622 C C8 . A B 2 89 ? 5.176 3.793 64.247 1.00 104.22 ? ? ? ? ? ? 95 A R C8 1 89
+ATOM 2623 N N7 . A B 2 89 ? 5.169 3.904 62.940 1.00 104.41 ? ? ? ? ? ? 95 A R N7 1 89
+ATOM 2624 C C5 . A B 2 89 ? 4.651 2.697 62.509 1.00 104.59 ? ? ? ? ? ? 95 A R C5 1 89
+ATOM 2625 C C6 . A B 2 89 ? 4.384 2.185 61.220 1.00 104.89 ? ? ? ? ? ? 95 A R C6 1 89
+ATOM 2626 N N6 . A B 2 89 ? 4.622 2.867 60.095 1.00 105.17 ? ? ? ? ? ? 95 A R N6 1 89
+ATOM 2627 N N1 . A B 2 89 ? 3.870 0.938 61.130 1.00 105.05 ? ? ? ? ? ? 95 A R N1 1 89
+ATOM 2628 C C2 . A B 2 89 ? 3.635 0.253 62.259 1.00 104.88 ? ? ? ? ? ? 95 A R C2 1 89
+ATOM 2629 N N3 . A B 2 89 ? 3.844 0.631 63.523 1.00 104.66 ? ? ? ? ? ? 95 A R N3 1 89
+ATOM 2630 C C4 . A B 2 89 ? 4.359 1.874 63.585 1.00 104.33 ? ? ? ? ? ? 95 A R C4 1 89
+ATOM 2631 P P . U B 2 90 ? 3.059 1.780 70.362 1.00 107.65 ? ? ? ? ? ? 96 U R P 1 90
+ATOM 2632 O OP1 . U B 2 90 ? 2.059 2.865 70.231 1.00 107.76 ? ? ? ? ? ? 96 U R OP1 1 90
+ATOM 2633 O OP2 . U B 2 90 ? 4.049 1.829 71.465 1.00 107.27 ? ? ? ? ? ? 96 U R OP2 1 90
+ATOM 2634 O "O5'" . U B 2 90 ? 2.286 0.372 70.414 1.00 108.85 ? ? ? ? ? ? 96 U R "O5'" 1 90
+ATOM 2635 C "C5'" . U B 2 90 ? 2.763 -0.727 71.197 1.00 110.91 ? ? ? ? ? ? 96 U R "C5'" 1 90
+ATOM 2636 C "C4'" . U B 2 90 ? 1.848 -1.029 72.374 1.00 112.56 ? ? ? ? ? ? 96 U R "C4'" 1 90
+ATOM 2637 O "O4'" . U B 2 90 ? 1.519 0.189 73.104 1.00 114.42 ? ? ? ? ? ? 96 U R "O4'" 1 90
+ATOM 2638 C "C3'" . U B 2 90 ? 0.461 -1.556 72.036 1.00 112.56 ? ? ? ? ? ? 96 U R "C3'" 1 90
+ATOM 2639 O "O3'" . U B 2 90 ? 0.450 -2.900 71.570 1.00 110.11 ? ? ? ? ? ? 96 U R "O3'" 1 90
+ATOM 2640 C "C2'" . U B 2 90 ? -0.227 -1.363 73.386 1.00 114.12 ? ? ? ? ? ? 96 U R "C2'" 1 90
+ATOM 2641 O "O2'" . U B 2 90 ? 0.231 -2.231 74.407 1.00 114.58 ? ? ? ? ? ? 96 U R "O2'" 1 90
+ATOM 2642 C "C1'" . U B 2 90 ? 0.209 0.076 73.652 1.00 115.24 ? ? ? ? ? ? 96 U R "C1'" 1 90
+ATOM 2643 N N1 . U B 2 90 ? -0.758 1.066 73.034 1.00 117.03 ? ? ? ? ? ? 96 U R N1 1 90
+ATOM 2644 C C2 . U B 2 90 ? -1.907 1.419 73.730 1.00 117.89 ? ? ? ? ? ? 96 U R C2 1 90
+ATOM 2645 O O2 . U B 2 90 ? -2.191 0.994 74.839 1.00 117.99 ? ? ? ? ? ? 96 U R O2 1 90
+ATOM 2646 N N3 . U B 2 90 ? -2.726 2.313 73.074 1.00 118.50 ? ? ? ? ? ? 96 U R N3 1 90
+ATOM 2647 C C4 . U B 2 90 ? -2.529 2.874 71.821 1.00 118.71 ? ? ? ? ? ? 96 U R C4 1 90
+ATOM 2648 O O4 . U B 2 90 ? -3.353 3.660 71.365 1.00 119.12 ? ? ? ? ? ? 96 U R O4 1 90
+ATOM 2649 C C5 . U B 2 90 ? -1.321 2.459 71.153 1.00 118.47 ? ? ? ? ? ? 96 U R C5 1 90
+ATOM 2650 C C6 . U B 2 90 ? -0.509 1.591 71.771 1.00 117.95 ? ? ? ? ? ? 96 U R C6 1 90
+ATOM 2651 P P . G B 2 91 ? -0.719 -3.356 70.570 1.00 108.46 ? ? ? ? ? ? 97 G R P 1 91
+ATOM 2652 O OP1 . G B 2 91 ? -1.958 -3.506 71.369 1.00 108.16 ? ? ? ? ? ? 97 G R OP1 1 91
+ATOM 2653 O OP2 . G B 2 91 ? -0.210 -4.515 69.800 1.00 108.55 ? ? ? ? ? ? 97 G R OP2 1 91
+ATOM 2654 O "O5'" . G B 2 91 ? -0.898 -2.100 69.579 1.00 105.18 ? ? ? ? ? ? 97 G R "O5'" 1 91
+ATOM 2655 C "C5'" . G B 2 91 ? -0.395 -2.109 68.239 1.00 99.41 ? ? ? ? ? ? 97 G R "C5'" 1 91
+ATOM 2656 C "C4'" . G B 2 91 ? -0.451 -0.724 67.616 1.00 95.40 ? ? ? ? ? ? 97 G R "C4'" 1 91
+ATOM 2657 O "O4'" . G B 2 91 ? 0.728 -0.514 66.795 1.00 94.32 ? ? ? ? ? ? 97 G R "O4'" 1 91
+ATOM 2658 C "C3'" . G B 2 91 ? -1.604 -0.489 66.649 1.00 93.30 ? ? ? ? ? ? 97 G R "C3'" 1 91
+ATOM 2659 O "O3'" . G B 2 91 ? -2.770 -0.024 67.304 1.00 90.11 ? ? ? ? ? ? 97 G R "O3'" 1 91
+ATOM 2660 C "C2'" . G B 2 91 ? -1.025 0.546 65.690 1.00 93.38 ? ? ? ? ? ? 97 G R "C2'" 1 91
+ATOM 2661 O "O2'" . G B 2 91 ? -0.936 1.847 66.240 1.00 93.04 ? ? ? ? ? ? 97 G R "O2'" 1 91
+ATOM 2662 C "C1'" . G B 2 91 ? 0.361 -0.058 65.500 1.00 93.71 ? ? ? ? ? ? 97 G R "C1'" 1 91
+ATOM 2663 N N9 . G B 2 91 ? 0.412 -1.178 64.544 1.00 93.22 ? ? ? ? ? ? 97 G R N9 1 91
+ATOM 2664 C C8 . G B 2 91 ? 0.908 -2.437 64.796 1.00 93.14 ? ? ? ? ? ? 97 G R C8 1 91
+ATOM 2665 N N7 . G B 2 91 ? 0.835 -3.251 63.781 1.00 92.68 ? ? ? ? ? ? 97 G R N7 1 91
+ATOM 2666 C C5 . G B 2 91 ? 0.253 -2.491 62.777 1.00 92.07 ? ? ? ? ? ? 97 G R C5 1 91
+ATOM 2667 C C6 . G B 2 91 ? -0.075 -2.847 61.442 1.00 91.04 ? ? ? ? ? ? 97 G R C6 1 91
+ATOM 2668 O O6 . G B 2 91 ? 0.092 -3.936 60.879 1.00 90.22 ? ? ? ? ? ? 97 G R O6 1 91
+ATOM 2669 N N1 . G B 2 91 ? -0.654 -1.789 60.741 1.00 90.64 ? ? ? ? ? ? 97 G R N1 1 91
+ATOM 2670 C C2 . G B 2 91 ? -0.886 -0.539 61.268 1.00 91.15 ? ? ? ? ? ? 97 G R C2 1 91
+ATOM 2671 N N2 . G B 2 91 ? -1.455 0.354 60.444 1.00 91.28 ? ? ? ? ? ? 97 G R N2 1 91
+ATOM 2672 N N3 . G B 2 91 ? -0.583 -0.193 62.518 1.00 91.92 ? ? ? ? ? ? 97 G R N3 1 91
+ATOM 2673 C C4 . G B 2 91 ? -0.016 -1.211 63.224 1.00 92.35 ? ? ? ? ? ? 97 G R C4 1 91
+ATOM 2674 P P . G B 2 92 ? -4.177 -0.680 66.913 1.00 88.15 ? ? ? ? ? ? 98 G R P 1 92
+ATOM 2675 O OP1 . G B 2 92 ? -5.196 -0.117 67.829 1.00 89.11 ? ? ? ? ? ? 98 G R OP1 1 92
+ATOM 2676 O OP2 . G B 2 92 ? -3.996 -2.152 66.851 1.00 86.93 ? ? ? ? ? ? 98 G R OP2 1 92
+ATOM 2677 O "O5'" . G B 2 92 ? -4.441 -0.139 65.423 1.00 85.99 ? ? ? ? ? ? 98 G R "O5'" 1 92
+ATOM 2678 C "C5'" . G B 2 92 ? -4.702 1.244 65.157 1.00 81.47 ? ? ? ? ? ? 98 G R "C5'" 1 92
+ATOM 2679 C "C4'" . G B 2 92 ? -5.089 1.476 63.702 1.00 78.96 ? ? ? ? ? ? 98 G R "C4'" 1 92
+ATOM 2680 O "O4'" . G B 2 92 ? -4.249 0.680 62.827 1.00 77.34 ? ? ? ? ? ? 98 G R "O4'" 1 92
+ATOM 2681 C "C3'" . G B 2 92 ? -6.541 1.153 63.356 1.00 77.72 ? ? ? ? ? ? 98 G R "C3'" 1 92
+ATOM 2682 O "O3'" . G B 2 92 ? -7.170 2.313 62.821 1.00 77.97 ? ? ? ? ? ? 98 G R "O3'" 1 92
+ATOM 2683 C "C2'" . G B 2 92 ? -6.489 0.018 62.330 1.00 76.50 ? ? ? ? ? ? 98 G R "C2'" 1 92
+ATOM 2684 O "O2'" . G B 2 92 ? -7.292 0.281 61.193 1.00 75.80 ? ? ? ? ? ? 98 G R "O2'" 1 92
+ATOM 2685 C "C1'" . G B 2 92 ? -5.022 -0.068 61.904 1.00 75.46 ? ? ? ? ? ? 98 G R "C1'" 1 92
+ATOM 2686 N N9 . G B 2 92 ? -4.487 -1.439 61.826 1.00 72.64 ? ? ? ? ? ? 98 G R N9 1 92
+ATOM 2687 C C8 . G B 2 92 ? -3.547 -2.008 62.659 1.00 70.33 ? ? ? ? ? ? 98 G R C8 1 92
+ATOM 2688 N N7 . G B 2 92 ? -3.247 -3.242 62.364 1.00 68.22 ? ? ? ? ? ? 98 G R N7 1 92
+ATOM 2689 C C5 . G B 2 92 ? -4.037 -3.523 61.258 1.00 68.81 ? ? ? ? ? ? 98 G R C5 1 92
+ATOM 2690 C C6 . G B 2 92 ? -4.141 -4.716 60.497 1.00 68.33 ? ? ? ? ? ? 98 G R C6 1 92
+ATOM 2691 O O6 . G B 2 92 ? -3.532 -5.783 60.665 1.00 67.91 ? ? ? ? ? ? 98 G R O6 1 92
+ATOM 2692 N N1 . G B 2 92 ? -5.060 -4.595 59.450 1.00 68.01 ? ? ? ? ? ? 98 G R N1 1 92
+ATOM 2693 C C2 . G B 2 92 ? -5.792 -3.458 59.179 1.00 68.56 ? ? ? ? ? ? 98 G R C2 1 92
+ATOM 2694 N N2 . G B 2 92 ? -6.626 -3.531 58.132 1.00 68.46 ? ? ? ? ? ? 98 G R N2 1 92
+ATOM 2695 N N3 . G B 2 92 ? -5.704 -2.330 59.884 1.00 69.01 ? ? ? ? ? ? 98 G R N3 1 92
+ATOM 2696 C C4 . G B 2 92 ? -4.809 -2.427 60.910 1.00 70.46 ? ? ? ? ? ? 98 G R C4 1 92
+ATOM 2697 O OP3 . G C 3 1 ? 16.680 4.894 56.478 1.00 67.77 ? ? ? ? ? ? 1 G A OP3 1 1
+ATOM 2698 P P . G C 3 1 ? 16.591 4.857 55.001 1.00 67.32 ? ? ? ? ? ? 1 G A P 1 1
+ATOM 2699 O OP1 . G C 3 1 ? 17.559 5.658 54.215 1.00 66.30 ? ? ? ? ? ? 1 G A OP1 1 1
+ATOM 2700 O OP2 . G C 3 1 ? 16.756 3.435 54.599 1.00 65.81 ? ? ? ? ? ? 1 G A OP2 1 1
+ATOM 2701 O "O5'" . G C 3 1 ? 15.116 5.343 54.600 1.00 62.36 ? ? ? ? ? ? 1 G A "O5'" 1 1
+ATOM 2702 C "C5'" . G C 3 1 ? 14.036 4.409 54.495 1.00 57.38 ? ? ? ? ? ? 1 G A "C5'" 1 1
+ATOM 2703 C "C4'" . G C 3 1 ? 13.513 4.307 53.072 1.00 53.29 ? ? ? ? ? ? 1 G A "C4'" 1 1
+ATOM 2704 O "O4'" . G C 3 1 ? 14.344 3.389 52.324 1.00 49.91 ? ? ? ? ? ? 1 G A "O4'" 1 1
+ATOM 2705 C "C3'" . G C 3 1 ? 12.097 3.762 52.926 1.00 51.90 ? ? ? ? ? ? 1 G A "C3'" 1 1
+ATOM 2706 O "O3'" . G C 3 1 ? 11.148 4.823 53.089 1.00 53.15 ? ? ? ? ? ? 1 G A "O3'" 1 1
+ATOM 2707 C "C2'" . G C 3 1 ? 12.128 3.210 51.500 1.00 50.86 ? ? ? ? ? ? 1 G A "C2'" 1 1
+ATOM 2708 O "O2'" . G C 3 1 ? 11.883 4.186 50.503 1.00 48.54 ? ? ? ? ? ? 1 G A "O2'" 1 1
+ATOM 2709 C "C1'" . G C 3 1 ? 13.561 2.695 51.372 1.00 49.44 ? ? ? ? ? ? 1 G A "C1'" 1 1
+ATOM 2710 N N9 . G C 3 1 ? 13.715 1.254 51.582 1.00 47.96 ? ? ? ? ? ? 1 G A N9 1 1
+ATOM 2711 C C8 . G C 3 1 ? 14.475 0.634 52.548 1.00 47.85 ? ? ? ? ? ? 1 G A C8 1 1
+ATOM 2712 N N7 . G C 3 1 ? 14.436 -0.669 52.503 1.00 46.32 ? ? ? ? ? ? 1 G A N7 1 1
+ATOM 2713 C C5 . G C 3 1 ? 13.596 -0.940 51.434 1.00 47.44 ? ? ? ? ? ? 1 G A C5 1 1
+ATOM 2714 C C6 . G C 3 1 ? 13.172 -2.184 50.900 1.00 47.47 ? ? ? ? ? ? 1 G A C6 1 1
+ATOM 2715 O O6 . G C 3 1 ? 13.471 -3.324 51.289 1.00 47.88 ? ? ? ? ? ? 1 G A O6 1 1
+ATOM 2716 N N1 . G C 3 1 ? 12.316 -2.023 49.807 1.00 46.02 ? ? ? ? ? ? 1 G A N1 1 1
+ATOM 2717 C C2 . G C 3 1 ? 11.924 -0.805 49.299 1.00 46.75 ? ? ? ? ? ? 1 G A C2 1 1
+ATOM 2718 N N2 . G C 3 1 ? 11.095 -0.837 48.246 1.00 48.57 ? ? ? ? ? ? 1 G A N2 1 1
+ATOM 2719 N N3 . G C 3 1 ? 12.313 0.367 49.789 1.00 46.88 ? ? ? ? ? ? 1 G A N3 1 1
+ATOM 2720 C C4 . G C 3 1 ? 13.145 0.231 50.853 1.00 47.68 ? ? ? ? ? ? 1 G A C4 1 1
+ATOM 2721 P P . G C 3 2 ? 9.589 4.583 53.396 1.00 55.92 ? ? ? ? ? ? 2 G A P 1 2
+ATOM 2722 O OP1 . G C 3 2 ? 9.032 3.714 52.336 1.00 54.98 ? ? ? ? ? ? 2 G A OP1 1 2
+ATOM 2723 O OP2 . G C 3 2 ? 8.950 5.903 53.629 1.00 54.37 ? ? ? ? ? ? 2 G A OP2 1 2
+ATOM 2724 O "O5'" . G C 3 2 ? 9.627 3.783 54.787 1.00 56.00 ? ? ? ? ? ? 2 G A "O5'" 1 2
+ATOM 2725 C "C5'" . G C 3 2 ? 9.986 4.464 55.993 1.00 54.43 ? ? ? ? ? ? 2 G A "C5'" 1 2
+ATOM 2726 C "C4'" . G C 3 2 ? 10.428 3.527 57.108 1.00 53.48 ? ? ? ? ? ? 2 G A "C4'" 1 2
+ATOM 2727 O "O4'" . G C 3 2 ? 9.273 2.816 57.623 1.00 52.76 ? ? ? ? ? ? 2 G A "O4'" 1 2
+ATOM 2728 C "C3'" . G C 3 2 ? 11.449 2.454 56.739 1.00 53.00 ? ? ? ? ? ? 2 G A "C3'" 1 2
+ATOM 2729 O "O3'" . G C 3 2 ? 12.776 2.918 56.975 1.00 51.51 ? ? ? ? ? ? 2 G A "O3'" 1 2
+ATOM 2730 C "C2'" . G C 3 2 ? 11.077 1.300 57.671 1.00 52.24 ? ? ? ? ? ? 2 G A "C2'" 1 2
+ATOM 2731 O "O2'" . G C 3 2 ? 11.644 1.426 58.960 1.00 51.75 ? ? ? ? ? ? 2 G A "O2'" 1 2
+ATOM 2732 C "C1'" . G C 3 2 ? 9.562 1.439 57.773 1.00 51.55 ? ? ? ? ? ? 2 G A "C1'" 1 2
+ATOM 2733 N N9 . G C 3 2 ? 8.790 0.705 56.769 1.00 51.63 ? ? ? ? ? ? 2 G A N9 1 2
+ATOM 2734 C C8 . G C 3 2 ? 7.883 1.261 55.897 1.00 52.21 ? ? ? ? ? ? 2 G A C8 1 2
+ATOM 2735 N N7 . G C 3 2 ? 7.318 0.397 55.104 1.00 52.19 ? ? ? ? ? ? 2 G A N7 1 2
+ATOM 2736 C C5 . G C 3 2 ? 7.884 -0.817 55.466 1.00 51.22 ? ? ? ? ? ? 2 G A C5 1 2
+ATOM 2737 C C6 . G C 3 2 ? 7.647 -2.110 54.945 1.00 50.57 ? ? ? ? ? ? 2 G A C6 1 2
+ATOM 2738 O O6 . G C 3 2 ? 6.872 -2.425 54.031 1.00 51.81 ? ? ? ? ? ? 2 G A O6 1 2
+ATOM 2739 N N1 . G C 3 2 ? 8.417 -3.084 55.582 1.00 48.53 ? ? ? ? ? ? 2 G A N1 1 2
+ATOM 2740 C C2 . G C 3 2 ? 9.303 -2.830 56.603 1.00 48.48 ? ? ? ? ? ? 2 G A C2 1 2
+ATOM 2741 N N2 . G C 3 2 ? 9.957 -3.891 57.096 1.00 46.83 ? ? ? ? ? ? 2 G A N2 1 2
+ATOM 2742 N N3 . G C 3 2 ? 9.531 -1.617 57.104 1.00 49.72 ? ? ? ? ? ? 2 G A N3 1 2
+ATOM 2743 C C4 . G C 3 2 ? 8.791 -0.653 56.494 1.00 51.27 ? ? ? ? ? ? 2 G A C4 1 2
+HETATM 2744 MG MG . MG D 4 . ? 4.000 -2.776 51.209 1.00 66.65 ? ? ? ? ? ? 1 MG R MG 1 1
+HETATM 2745 O O . HOH E 5 . ? 4.376 31.687 10.017 1.00 29.48 ? ? ? ? ? ? 99 HOH P O 1 99
+HETATM 2746 O O . HOH E 5 . ? 8.620 24.826 6.657 1.00 42.09 ? ? ? ? ? ? 100 HOH P O 1 100
+HETATM 2747 O O . HOH E 5 . ? 4.700 30.085 8.176 1.00 44.90 ? ? ? ? ? ? 101 HOH P O 1 101
+HETATM 2748 O O . HOH F 5 . ? 3.779 13.244 -1.019 1.00 39.86 ? ? ? ? ? ? 3 HOH R O 1 3
+HETATM 2749 O O . HOH F 5 . ? 26.468 -4.600 41.966 1.00 27.27 ? ? ? ? ? ? 4 HOH R O 1 4
+HETATM 2750 O O . HOH F 5 . ? 12.478 -8.451 31.611 1.00 33.82 ? ? ? ? ? ? 5 HOH R O 1 5
+HETATM 2751 O O . HOH F 5 . ? 29.314 -2.272 18.976 1.00 48.37 ? ? ? ? ? ? 670 HOH R O 1 670
+HETATM 2752 O O . HOH F 5 . ? 9.514 -9.005 51.220 1.00 55.48 ? ? ? ? ? ? 671 HOH R O 1 671
+HETATM 2753 O O . HOH F 5 . ? 11.169 6.329 -1.078 1.00 59.28 ? ? ? ? ? ? 672 HOH R O 1 672
+HETATM 2754 O O . HOH F 5 . ? 2.744 -4.232 50.183 1.00 67.60 ? ? ? ? ? ? 673 HOH R O 1 673
+HETATM 2755 O O . HOH F 5 . ? 5.774 -3.685 50.326 1.00 67.45 ? ? ? ? ? ? 674 HOH R O 1 674
+HETATM 2756 O O . HOH F 5 . ? 2.234 -1.949 52.189 1.00 67.27 ? ? ? ? ? ? 675 HOH R O 1 675
+HETATM 2757 O O . HOH F 5 . ? 4.177 -4.197 52.851 1.00 67.86 ? ? ? ? ? ? 676 HOH R O 1 676
+HETATM 2758 O O . HOH G 5 . ? 5.266 -1.415 52.341 1.00 67.29 ? ? ? ? ? ? 3 HOH A O 1 3
+#
+loop_
+_pdbx_poly_seq_scheme.asym_id             
+_pdbx_poly_seq_scheme.entity_id           
+_pdbx_poly_seq_scheme.seq_id              
+_pdbx_poly_seq_scheme.mon_id              
+_pdbx_poly_seq_scheme.ndb_seq_num         
+_pdbx_poly_seq_scheme.pdb_seq_num         
+_pdbx_poly_seq_scheme.auth_seq_num        
+_pdbx_poly_seq_scheme.pdb_mon_id          
+_pdbx_poly_seq_scheme.auth_mon_id         
+_pdbx_poly_seq_scheme.pdb_strand_id       
+_pdbx_poly_seq_scheme.pdb_ins_code        
+_pdbx_poly_seq_scheme.hetero              
+A 1 1 MET 1 1 ? ? ? P . n
+A 1 2 ALA 2 2 ? ? ? P . n
+A 1 3 VAL 3 3 ? ? ? P . n
+A 1 4 PRO 4 4 ? ? ? P . n
+A 1 5 GLU 5 5 ? ? ? P . n
+A 1 6 THR 6 6 ? ? ? P . n
+A 1 7 ARG 7 7 7 ARG ARG P . n
+A 1 8 PRO 8 8 8 PRO PRO P . n
+A 1 9 ASN 9 9 9 ASN ASN P . n
+A 1 10 HIS 10 10 10 HIS HIS P . n
+A 1 11 THR 11 11 11 THR THR P . n
+A 1 12 ILE 12 12 12 ILE ILE P . n
+A 1 13 TYR 13 13 13 TYR TYR P . n
+A 1 14 ILE 14 14 14 ILE ILE P . n
+A 1 15 ASN 15 15 15 ASN ASN P . n
+A 1 16 ASN 16 16 16 ASN ASN P . n
+A 1 17 LEU 17 17 17 LEU LEU P . n
+A 1 18 ASN 18 18 18 ASN ASN P . n
+A 1 19 GLU 19 19 19 GLU GLU P . n
+A 1 20 LYS 20 20 20 LYS LYS P . n
+A 1 21 ILE 21 21 21 ILE ILE P . n
+A 1 22 LYS 22 22 22 LYS LYS P . n
+A 1 23 LYS 23 23 23 LYS LYS P . n
+A 1 24 ASP 24 24 24 ASP ASP P . n
+A 1 25 GLU 25 25 25 GLU GLU P . n
+A 1 26 LEU 26 26 26 LEU LEU P . n
+A 1 27 LYS 27 27 27 LYS LYS P . n
+A 1 28 LYS 28 28 28 LYS LYS P . n
+A 1 29 SER 29 29 29 SER SER P . n
+A 1 30 LEU 30 30 30 LEU LEU P . n
+A 1 31 HIS 31 31 31 HIS HIS P . n
+A 1 32 ALA 32 32 32 ALA ALA P . n
+A 1 33 ILE 33 33 33 ILE ILE P . n
+A 1 34 PHE 34 34 34 PHE PHE P . n
+A 1 35 SER 35 35 35 SER SER P . n
+A 1 36 ARG 36 36 36 ARG ARG P . n
+A 1 37 PHE 37 37 37 PHE PHE P . n
+A 1 38 GLY 38 38 38 GLY GLY P . n
+A 1 39 GLN 39 39 39 GLN GLN P . n
+A 1 40 ILE 40 40 40 ILE ILE P . n
+A 1 41 LEU 41 41 41 LEU LEU P . n
+A 1 42 ASP 42 42 42 ASP ASP P . n
+A 1 43 ILE 43 43 43 ILE ILE P . n
+A 1 44 LEU 44 44 44 LEU LEU P . n
+A 1 45 VAL 45 45 45 VAL VAL P . n
+A 1 46 SER 46 46 46 SER SER P . n
+A 1 47 ARG 47 47 47 ARG ARG P . n
+A 1 48 SER 48 48 48 SER SER P . n
+A 1 49 LEU 49 49 49 LEU LEU P . n
+A 1 50 LYS 50 50 50 LYS LYS P . n
+A 1 51 MET 51 51 51 MET MET P . n
+A 1 52 ARG 52 52 52 ARG ARG P . n
+A 1 53 GLY 53 53 53 GLY GLY P . n
+A 1 54 GLN 54 54 54 GLN GLN P . n
+A 1 55 ALA 55 55 55 ALA ALA P . n
+A 1 56 PHE 56 56 56 PHE PHE P . n
+A 1 57 VAL 57 57 57 VAL VAL P . n
+A 1 58 ILE 58 58 58 ILE ILE P . n
+A 1 59 PHE 59 59 59 PHE PHE P . n
+A 1 60 LYS 60 60 60 LYS LYS P . n
+A 1 61 GLU 61 61 61 GLU GLU P . n
+A 1 62 VAL 62 62 62 VAL VAL P . n
+A 1 63 SER 63 63 63 SER SER P . n
+A 1 64 SER 64 64 64 SER SER P . n
+A 1 65 ALA 65 65 65 ALA ALA P . n
+A 1 66 THR 66 66 66 THR THR P . n
+A 1 67 ASN 67 67 67 ASN ASN P . n
+A 1 68 ALA 68 68 68 ALA ALA P . n
+A 1 69 LEU 69 69 69 LEU LEU P . n
+A 1 70 ARG 70 70 70 ARG ARG P . n
+A 1 71 SER 71 71 71 SER SER P . n
+A 1 72 MET 72 72 72 MET MET P . n
+A 1 73 GLN 73 73 73 GLN GLN P . n
+A 1 74 GLY 74 74 74 GLY GLY P . n
+A 1 75 PHE 75 75 75 PHE PHE P . n
+A 1 76 PRO 76 76 76 PRO PRO P . n
+A 1 77 PHE 77 77 77 PHE PHE P . n
+A 1 78 TYR 78 78 78 TYR TYR P . n
+A 1 79 ASP 79 79 79 ASP ASP P . n
+A 1 80 LYS 80 80 80 LYS LYS P . n
+A 1 81 PRO 81 81 81 PRO PRO P . n
+A 1 82 MET 82 82 82 MET MET P . n
+A 1 83 ARG 83 83 83 ARG ARG P . n
+A 1 84 ILE 84 84 84 ILE ILE P . n
+A 1 85 GLN 85 85 85 GLN GLN P . n
+A 1 86 TYR 86 86 86 TYR TYR P . n
+A 1 87 ALA 87 87 87 ALA ALA P . n
+A 1 88 LYS 88 88 88 LYS LYS P . n
+A 1 89 THR 89 89 89 THR THR P . n
+A 1 90 ASP 90 90 90 ASP ASP P . n
+A 1 91 SER 91 91 91 SER SER P . n
+A 1 92 ASP 92 92 92 ASP ASP P . n
+A 1 93 ILE 93 93 93 ILE ILE P . n
+A 1 94 ILE 94 94 ? ? ? P . n
+A 1 95 ALA 95 95 ? ? ? P . n
+A 1 96 LYS 96 96 ? ? ? P . n
+A 1 97 MET 97 97 ? ? ? P . n
+A 1 98 LYS 98 98 ? ? ? P . n
+B 2 1 GTP 1 8 8 GTP GTP R . n
+B 2 2 G 2 9 9 G G R . n
+B 2 3 U 3 10 10 U U R . n
+B 2 4 C 4 11 11 C C R . n
+B 2 5 A 5 12 12 A A R . n
+B 2 6 C 6 13 13 C C R . n
+B 2 7 G 7 14 14 G G R . n
+B 2 8 C 8 15 15 C C R . n
+B 2 9 A 9 16 16 A A R . n
+B 2 10 C 10 17 17 C C R . n
+B 2 11 A 11 18 18 A A R . n
+B 2 12 G 12 19 19 G G R . n
+B 2 13 G 13 20 20 G G R . n
+B 2 14 G 14 21 21 G G R . n
+B 2 15 C 15 22 22 C C R . n
+B 2 16 A 16 23 23 A A R . n
+B 2 17 A 17 24 24 A A R . n
+B 2 18 A 18 25 25 A A R . n
+B 2 19 C 19 26 26 C C R . n
+B 2 20 C 20 27 27 C C R . n
+B 2 21 A 21 28 28 A A R . n
+B 2 22 U 22 29 29 U U R . n
+B 2 23 U 23 30 30 U U R . n
+B 2 24 C 24 31 31 C C R . n
+B 2 25 G 25 32 32 G G R . n
+B 2 26 A 26 33 33 A A R . n
+B 2 27 A 27 34 34 A A R . n
+B 2 28 A 28 35 35 A A R . n
+B 2 29 G 29 36 36 G G R . n
+B 2 30 A 30 37 37 A A R . n
+B 2 31 G 31 38 38 G G R . n
+B 2 32 U 32 39 39 U U R . n
+B 2 33 G 33 40 40 G G R . n
+B 2 34 G 34 41 41 G G R . n
+B 2 35 G 35 42 42 G G R . n
+B 2 36 A 36 43 43 A A R . n
+B 2 37 C 37 44 44 C C R . n
+B 2 38 G 38 45 45 G G R . n
+B 2 39 C 39 46 46 C C R . n
+B 2 40 A 40 47 47 A A R . n
+B 2 41 A 41 48 48 A A R . n
+B 2 42 A 42 49 49 A A R . n
+B 2 43 G 43 50 50 G G R . n
+B 2 44 C 44 51 51 C C R . n
+B 2 45 C 45 52 52 C C R . n
+B 2 46 U 46 53 53 U U R . n
+B 2 47 C 47 54 54 C C R . n
+B 2 48 C 48 55 55 C C R . n
+B 2 49 G 49 56 56 G G R . n
+B 2 50 G 50 57 57 G G R . n
+B 2 51 C 51 58 58 C C R . n
+B 2 52 C 52 59 59 C C R . n
+B 2 53 U 53 60 60 U U R . n
+B 2 54 A 54 61 61 A A R . n
+B 2 55 A 55 62 62 A A R . n
+B 2 56 A 56 63 63 A A R . n
+B 2 57 C 57 64 64 C C R . n
+B 2 58 C 58 65 65 C C R . n
+B 2 59 A 59 660 660 A A R . n
+B 2 60 U 60 661 661 U U R . n
+B 2 61 U 61 662 662 U U R . n
+B 2 62 G 62 663 663 G G R . n
+B 2 63 C 63 664 664 C C R . n
+B 2 64 A 64 665 665 A A R . n
+B 2 65 C 65 666 666 C C R . n
+B 2 66 U 66 667 667 U U R . n
+B 2 67 C 67 668 668 C C R . n
+B 2 68 C 68 669 669 C C R . n
+B 2 69 G 69 75 75 G G R . n
+B 2 70 G 70 76 76 G G R . n
+B 2 71 U 71 77 77 U U R . n
+B 2 72 A 72 78 78 A A R . n
+B 2 73 G 73 79 79 G G R . n
+B 2 74 G 74 80 80 G G R . n
+B 2 75 U 75 81 81 U U R . n
+B 2 76 A 76 82 82 A A R . n
+B 2 77 G 77 83 83 G G R . n
+B 2 78 C 78 84 84 C C R . n
+B 2 79 G 79 85 85 G G R . n
+B 2 80 G 80 86 86 G G R . n
+B 2 81 G 81 87 87 G G R . n
+B 2 82 G 82 88 88 G G R . n
+B 2 83 U 83 89 89 U U R . n
+B 2 84 U 84 90 90 U U R . n
+B 2 85 A 85 91 91 A A R . n
+B 2 86 C 86 92 92 C C R . n
+B 2 87 C 87 93 93 C C R . n
+B 2 88 G 88 94 94 G G R . n
+B 2 89 A 89 95 95 A A R . n
+B 2 90 U 90 96 96 U U R . n
+B 2 91 G 91 97 97 G G R . n
+B 2 92 G 92 98 98 G G R . n
+C 3 1 G 1 1 1 G G A . n
+C 3 2 G 2 2 2 G G A . n
+#
+_pdbx_struct_assembly.id                       1
+_pdbx_struct_assembly.details                  author_and_software_defined_assembly
+_pdbx_struct_assembly.method_details           PISA
+_pdbx_struct_assembly.oligomeric_details       trimeric
+_pdbx_struct_assembly.oligomeric_count         3
+#
+_pdbx_struct_assembly_gen.assembly_id           1
+_pdbx_struct_assembly_gen.oper_expression       1
+_pdbx_struct_assembly_gen.asym_id_list          A,E,B,D,F,C,G
+#
+loop_
+_pdbx_struct_assembly_prop.biol_id       
+_pdbx_struct_assembly_prop.type          
+_pdbx_struct_assembly_prop.value         
+_pdbx_struct_assembly_prop.details       
+1 "ABSA (A^2)" 3630 ?
+1 "SSA (A^2)" 18700 ?
+1 MORE -22 ?
+#
+_pdbx_struct_oper_list.id                       1
+_pdbx_struct_oper_list.type                     "identity operation"
+_pdbx_struct_oper_list.name                     1_555
+_pdbx_struct_oper_list.symmetry_operation       x,y,z
+_pdbx_struct_oper_list.matrix[1][1]             1.0000000000
+_pdbx_struct_oper_list.matrix[1][2]             0.0000000000
+_pdbx_struct_oper_list.matrix[1][3]             0.0000000000
+_pdbx_struct_oper_list.vector[1]                0.0000000000
+_pdbx_struct_oper_list.matrix[2][1]             0.0000000000
+_pdbx_struct_oper_list.matrix[2][2]             1.0000000000
+_pdbx_struct_oper_list.matrix[2][3]             0.0000000000
+_pdbx_struct_oper_list.vector[2]                0.0000000000
+_pdbx_struct_oper_list.matrix[3][1]             0.0000000000
+_pdbx_struct_oper_list.matrix[3][2]             0.0000000000
+_pdbx_struct_oper_list.matrix[3][3]             1.0000000000
+_pdbx_struct_oper_list.vector[3]                0.0000000000
+#
+loop_
+_ndb_struct_conf_na.entry_id       
+_ndb_struct_conf_na.feature        
+3UCU "double helix"
+3UCU "a-form double helix"
+3UCU tetraloop
+3UCU "bulge loop"
+3UCU "mismatched base pair"
+3UCU "triple helix"
+3UCU "quadruple helix"
+#
+loop_
+_ndb_struct_na_base_pair.model_number          
+_ndb_struct_na_base_pair.i_label_asym_id       
+_ndb_struct_na_base_pair.i_label_comp_id       
+_ndb_struct_na_base_pair.i_label_seq_id        
+_ndb_struct_na_base_pair.i_symmetry            
+_ndb_struct_na_base_pair.j_label_asym_id       
+_ndb_struct_na_base_pair.j_label_comp_id       
+_ndb_struct_na_base_pair.j_label_seq_id        
+_ndb_struct_na_base_pair.j_symmetry            
+_ndb_struct_na_base_pair.shear                 
+_ndb_struct_na_base_pair.stretch               
+_ndb_struct_na_base_pair.stagger               
+_ndb_struct_na_base_pair.buckle                
+_ndb_struct_na_base_pair.opening               
+_ndb_struct_na_base_pair.pair_number           
+_ndb_struct_na_base_pair.pair_name             
+_ndb_struct_na_base_pair.i_auth_asym_id        
+_ndb_struct_na_base_pair.i_auth_seq_id         
+_ndb_struct_na_base_pair.i_PDB_ins_code        
+_ndb_struct_na_base_pair.j_auth_asym_id        
+_ndb_struct_na_base_pair.j_auth_seq_id         
+_ndb_struct_na_base_pair.j_PDB_ins_code        
+_ndb_struct_na_base_pair.hbond_type_28         
+_ndb_struct_na_base_pair.hbond_type_12         
+1 B C 4 1_555 B G 92 1_555 0.187 0.071 0.337 9.615 -4.537 1 R_C11:G98_R R 11 ? R 98 ? 19 1
+1 B A 5 1_555 B G 91 1_555 0.554 1.617 -0.349 -16.822 -13.950 2 R_A12:G97_R R 12 ? R 97 ? 8 1
+1 B C 6 1_555 B G 88 1_555 -0.469 0.137 0.622 -20.707 -0.472 3 R_C13:G94_R R 13 ? R 94 ? 19 1
+1 B G 7 1_555 B C 87 1_555 0.184 0.135 0.584 4.716 -2.629 4 R_G14:C93_R R 14 ? R 93 ? 19 1
+1 C G 2 1_555 B C 86 1_555 0.338 0.113 -0.078 -4.607 5.538 5 A_G2:C92_R A 2 ? R 92 ? 19 1
+1 B G 12 1_555 B A 40 1_555 0.069 2.921 -0.085 -9.047 -51.751 6 R_G19:A47_R R 19 ? R 47 ? ? ?
+1 B G 13 1_555 C G 1 1_555 5.879 -0.700 -0.221 4.712 -110.433 7 R_G20:G1_A R 20 ? A 1 ? 7 4
+1 B G 14 1_555 B C 39 1_555 -0.212 0.039 -0.260 0.652 3.393 8 R_G21:C46_R R 21 ? R 46 ? 19 1
+1 B C 15 1_555 B G 38 1_555 0.173 -0.070 -0.159 9.064 3.213 9 R_C22:G45_R R 22 ? R 45 ? 19 1
+1 B G 77 1_555 B C 37 1_555 -0.330 -0.198 0.543 2.720 -5.761 10 R_G83:C44_R R 83 ? R 44 ? 19 1
+1 B A 18 1_555 B G 35 1_555 -6.754 -3.553 0.197 0.918 -0.465 11 R_A25:G42_R R 25 ? R 42 ? 11 9
+1 B C 19 1_555 B G 34 1_555 0.349 0.134 -0.325 10.614 1.783 12 R_C26:G41_R R 26 ? R 41 ? 19 1
+1 B C 20 1_555 B G 33 1_555 -0.075 -0.115 -0.112 8.320 1.321 13 R_C27:G40_R R 27 ? R 40 ? 19 1
+1 B A 21 1_555 B U 32 1_555 0.038 -0.172 0.059 1.620 5.470 14 R_A28:U39_R R 28 ? R 39 ? 20 1
+1 B U 22 1_555 B G 31 1_555 2.342 -0.524 -0.039 4.583 6.387 15 R_U29:G38_R R 29 ? R 38 ? 28 1
+1 B U 23 1_555 B A 30 1_555 0.476 -0.302 -0.019 -2.641 0.821 16 R_U30:A37_R R 30 ? R 37 ? 20 1
+1 B C 24 1_555 B G 29 1_555 0.436 -0.355 -0.148 3.903 -0.692 17 R_C31:G36_R R 31 ? R 36 ? 19 1
+1 B A 41 1_555 B U 84 1_555 -4.304 -2.416 -0.153 10.581 -89.980 18 R_A48:U90_R R 48 ? R 90 ? 24 4
+1 B G 43 1_555 B U 83 1_555 -2.395 -0.696 -0.297 -3.035 -4.662 19 R_G50:U89_R R 50 ? R 89 ? 28 1
+1 B C 44 1_555 B G 82 1_555 0.469 -0.285 -0.089 5.423 1.247 20 R_C51:G88_R R 51 ? R 88 ? 19 1
+1 B C 45 1_555 B G 81 1_555 0.087 -0.116 0.215 -1.792 1.383 21 R_C52:G87_R R 52 ? R 87 ? 19 1
+1 B C 47 1_555 B G 80 1_555 0.004 -0.104 -0.573 18.342 2.114 22 R_C54:G86_R R 54 ? R 86 ? 19 1
+1 B C 48 1_555 B G 79 1_555 0.240 -0.185 -0.103 3.870 -2.273 23 R_C55:G85_R R 55 ? R 85 ? 19 1
+1 B G 49 1_555 B C 78 1_555 -0.983 -0.389 0.218 8.779 0.707 24 R_G56:C84_R R 56 ? R 84 ? 19 1
+1 B G 50 1_555 B U 75 1_555 -1.511 -0.373 0.226 4.965 -5.608 25 R_G57:U81_R R 57 ? R 81 ? 28 1
+1 B C 51 1_555 B G 74 1_555 0.524 -0.235 0.049 12.425 3.189 26 R_C58:G80_R R 58 ? R 80 ? 19 1
+1 B C 52 1_555 B G 73 1_555 -0.007 -0.140 -0.228 3.193 -0.027 27 R_C59:G79_R R 59 ? R 79 ? 19 1
+1 B U 53 1_555 B A 72 1_555 0.250 -0.214 0.217 -5.026 -3.180 28 R_U60:A78_R R 60 ? R 78 ? 20 1
+1 B A 54 1_555 B U 71 1_555 1.394 -0.134 0.318 12.201 -3.591 29 R_A61:U77_R R 61 ? R 77 ? 20 1
+1 B C 57 1_555 B G 70 1_555 -0.041 -0.090 -0.669 18.961 6.074 30 R_C64:G76_R R 64 ? R 76 ? 19 1
+1 B C 58 1_555 B G 69 1_555 1.086 -0.174 0.344 -10.081 9.716 31 R_C65:G75_R R 65 ? R 75 ? 19 1
+#
+loop_
+_ndb_struct_na_base_pair_step.model_number            
+_ndb_struct_na_base_pair_step.i_label_asym_id_1       
+_ndb_struct_na_base_pair_step.i_label_comp_id_1       
+_ndb_struct_na_base_pair_step.i_label_seq_id_1        
+_ndb_struct_na_base_pair_step.i_symmetry_1            
+_ndb_struct_na_base_pair_step.j_label_asym_id_1       
+_ndb_struct_na_base_pair_step.j_label_comp_id_1       
+_ndb_struct_na_base_pair_step.j_label_seq_id_1        
+_ndb_struct_na_base_pair_step.j_symmetry_1            
+_ndb_struct_na_base_pair_step.i_label_asym_id_2       
+_ndb_struct_na_base_pair_step.i_label_comp_id_2       
+_ndb_struct_na_base_pair_step.i_label_seq_id_2        
+_ndb_struct_na_base_pair_step.i_symmetry_2            
+_ndb_struct_na_base_pair_step.j_label_asym_id_2       
+_ndb_struct_na_base_pair_step.j_label_comp_id_2       
+_ndb_struct_na_base_pair_step.j_label_seq_id_2        
+_ndb_struct_na_base_pair_step.j_symmetry_2            
+_ndb_struct_na_base_pair_step.shift                   
+_ndb_struct_na_base_pair_step.slide                   
+_ndb_struct_na_base_pair_step.rise                    
+_ndb_struct_na_base_pair_step.tilt                    
+_ndb_struct_na_base_pair_step.roll                    
+_ndb_struct_na_base_pair_step.twist                   
+_ndb_struct_na_base_pair_step.x_displacement          
+_ndb_struct_na_base_pair_step.y_displacement          
+_ndb_struct_na_base_pair_step.helical_rise            
+_ndb_struct_na_base_pair_step.inclination             
+_ndb_struct_na_base_pair_step.tip                     
+_ndb_struct_na_base_pair_step.helical_twist           
+_ndb_struct_na_base_pair_step.step_number             
+_ndb_struct_na_base_pair_step.step_name               
+_ndb_struct_na_base_pair_step.i_auth_asym_id_1        
+_ndb_struct_na_base_pair_step.i_auth_seq_id_1         
+_ndb_struct_na_base_pair_step.i_PDB_ins_code_1        
+_ndb_struct_na_base_pair_step.j_auth_asym_id_1        
+_ndb_struct_na_base_pair_step.j_auth_seq_id_1         
+_ndb_struct_na_base_pair_step.j_PDB_ins_code_1        
+_ndb_struct_na_base_pair_step.i_auth_asym_id_2        
+_ndb_struct_na_base_pair_step.i_auth_seq_id_2         
+_ndb_struct_na_base_pair_step.i_PDB_ins_code_2        
+_ndb_struct_na_base_pair_step.j_auth_asym_id_2        
+_ndb_struct_na_base_pair_step.j_auth_seq_id_2         
+_ndb_struct_na_base_pair_step.j_PDB_ins_code_2        
+1 B C 4 1_555 B G 92 1_555 B A 5 1_555 B G 91 1_555 0.329 -2.498 3.630 9.758 10.984 33.904 -5.459 0.820 2.710 17.833 -15.843 36.865 1 RR_C11A12:G97G98_RR R 11 ? R 98 ? R 12 ? R 97 ?
+1 B A 5 1_555 B G 91 1_555 B C 6 1_555 B G 88 1_555 2.181 -0.463 3.134 -0.142 6.202 41.158 -1.274 -3.085 3.029 8.762 0.201 41.602 2 RR_A12C13:G94G97_RR R 12 ? R 97 ? R 13 ? R 94 ?
+1 B C 6 1_555 B G 88 1_555 B G 7 1_555 B C 87 1_555 -1.045 -0.668 2.711 -5.009 16.791 28.698 -3.381 1.148 2.155 30.546 9.113 33.529 3 RR_C13G14:C93G94_RR R 13 ? R 94 ? R 14 ? R 93 ?
+1 B G 7 1_555 B C 87 1_555 C G 2 1_555 B C 86 1_555 -0.505 -1.440 3.425 1.406 5.304 40.341 -2.667 0.884 3.199 7.647 -2.027 40.697 4 RA_G14G2:C92C93_RR R 14 ? R 93 ? A 2 ? R 92 ?
+1 C G 2 1_555 B C 86 1_555 B G 12 1_555 B A 40 1_555 -2.554 3.400 3.088 -3.965 -4.060 117.011 2.032 1.459 3.067 -2.380 2.324 117.097 5 AR_G2G19:A47C92_RR A 2 ? R 92 ? R 19 ? R 47 ?
+1 B G 12 1_555 B A 40 1_555 B G 13 1_555 C G 1 1_555 -0.492 -2.731 3.149 -3.804 -0.002 46.167 -3.472 0.313 3.178 -0.003 4.842 46.315 6 RR_G19G20:G1A47_AR R 19 ? R 47 ? R 20 ? A 1 ?
+1 B G 13 1_555 C G 1 1_555 B G 14 1_555 B C 39 1_555 1.693 -1.439 3.386 0.537 0.911 -25.650 2.973 3.968 3.399 -2.052 1.208 -25.671 7 RR_G20G21:C46G1_RA R 20 ? A 1 ? R 21 ? R 46 ?
+1 B G 14 1_555 B C 39 1_555 B C 15 1_555 B G 38 1_555 0.330 -1.786 3.197 -1.954 0.154 31.912 -3.269 -0.944 3.163 0.281 3.550 31.971 8 RR_G21C22:G45C46_RR R 21 ? R 46 ? R 22 ? R 45 ?
+1 B C 15 1_555 B G 38 1_555 B G 77 1_555 B C 37 1_555 -5.423 -0.104 3.649 -12.294 -7.086 57.603 0.358 4.688 4.601 -7.234 12.551 59.179 9 RR_C22G83:C44G45_RR R 22 ? R 45 ? R 83 ? R 44 ?
+1 B A 18 1_555 B G 35 1_555 B C 19 1_555 B G 34 1_555 -0.219 -0.737 3.219 -2.754 6.282 61.924 -0.993 0.089 3.145 6.085 2.667 62.265 10 RR_A25C26:G41G42_RR R 25 ? R 42 ? R 26 ? R 41 ?
+1 B C 19 1_555 B G 34 1_555 B C 20 1_555 B G 33 1_555 -0.032 -1.880 3.288 -2.423 7.796 27.616 -5.406 -0.441 2.662 15.896 4.940 28.775 11 RR_C26C27:G40G41_RR R 26 ? R 41 ? R 27 ? R 40 ?
+1 B C 20 1_555 B G 33 1_555 B A 21 1_555 B U 32 1_555 0.231 -1.453 3.239 2.570 15.815 34.600 -4.050 -0.059 2.386 24.998 -4.062 38.027 12 RR_C27A28:U39G40_RR R 27 ? R 40 ? R 28 ? R 39 ?
+1 B A 21 1_555 B U 32 1_555 B U 22 1_555 B G 31 1_555 0.346 -0.978 3.140 2.582 10.221 39.782 -2.423 -0.232 2.831 14.709 -3.716 41.101 13 RR_A28U29:G38U39_RR R 28 ? R 39 ? R 29 ? R 38 ?
+1 B U 22 1_555 B G 31 1_555 B U 23 1_555 B A 30 1_555 -0.154 -1.916 3.126 3.332 10.226 26.693 -5.809 0.945 2.220 21.092 -6.873 28.742 14 RR_U29U30:A37G38_RR R 29 ? R 38 ? R 30 ? R 37 ?
+1 B U 23 1_555 B A 30 1_555 B C 24 1_555 B G 29 1_555 0.069 -1.598 3.105 1.614 6.134 29.658 -4.171 0.160 2.727 11.813 -3.108 30.313 15 RR_U30C31:G36A37_RR R 30 ? R 37 ? R 31 ? R 36 ?
+1 B A 41 1_555 B U 84 1_555 B G 43 1_555 B U 83 1_555 3.254 -2.249 3.664 -7.112 11.087 64.527 -2.535 -3.295 2.952 10.272 6.590 65.715 16 RR_A48G50:U89U90_RR R 48 ? R 90 ? R 50 ? R 89 ?
+1 B G 43 1_555 B U 83 1_555 B C 44 1_555 B G 82 1_555 0.267 -1.337 3.055 -3.574 4.044 42.574 -2.194 -0.690 2.892 5.543 4.899 42.899 17 RR_G50C51:G88U89_RR R 50 ? R 89 ? R 51 ? R 88 ?
+1 B C 44 1_555 B G 82 1_555 B C 45 1_555 B G 81 1_555 -0.010 -1.850 3.412 1.493 7.127 32.866 -4.342 0.257 2.954 12.406 -2.599 33.641 18 RR_C51C52:G87G88_RR R 51 ? R 88 ? R 52 ? R 87 ?
+1 B C 45 1_555 B G 81 1_555 B C 47 1_555 B G 80 1_555 -2.806 -1.058 2.913 11.418 5.518 51.856 -1.457 3.703 2.179 6.204 -12.838 53.280 19 RR_C52C54:G86G87_RR R 52 ? R 87 ? R 54 ? R 86 ?
+1 B C 47 1_555 B G 80 1_555 B C 48 1_555 B G 79 1_555 -0.843 -2.031 3.701 -4.921 10.685 34.219 -4.875 0.622 3.040 17.529 8.073 36.128 20 RR_C54C55:G85G86_RR R 54 ? R 86 ? R 55 ? R 85 ?
+1 B C 48 1_555 B G 79 1_555 B G 49 1_555 B C 78 1_555 0.175 -2.414 2.994 -3.793 6.575 19.300 -8.968 -1.788 2.000 18.701 10.789 20.726 21 RR_C55G56:C84G85_RR R 55 ? R 85 ? R 56 ? R 84 ?
+1 B G 49 1_555 B C 78 1_555 B G 50 1_555 B U 75 1_555 1.981 -1.778 3.113 0.112 6.738 49.194 -2.573 -2.352 2.866 8.050 -0.134 49.625 22 RR_G56G57:U81C84_RR R 56 ? R 84 ? R 57 ? R 81 ?
+1 B G 50 1_555 B U 75 1_555 B C 51 1_555 B G 74 1_555 0.406 -1.299 3.135 -2.152 3.525 40.540 -2.231 -0.806 2.992 5.071 3.095 40.741 23 RR_G57C58:G80U81_RR R 57 ? R 81 ? R 58 ? R 80 ?
+1 B C 51 1_555 B G 74 1_555 B C 52 1_555 B G 73 1_555 -0.649 -2.133 3.384 -0.838 7.242 27.415 -5.952 1.140 2.760 14.947 1.730 28.349 24 RR_C58C59:G79G80_RR R 58 ? R 80 ? R 59 ? R 79 ?
+1 B C 52 1_555 B G 73 1_555 B U 53 1_555 B A 72 1_555 -0.312 -2.050 3.572 -1.941 9.883 31.032 -5.378 0.217 2.817 17.891 3.513 32.587 25 RR_C59U60:A78G79_RR R 59 ? R 79 ? R 60 ? R 78 ?
+1 B U 53 1_555 B A 72 1_555 B A 54 1_555 B U 71 1_555 -0.076 -1.637 2.879 2.700 14.724 27.674 -5.130 0.526 1.786 28.311 -5.191 31.394 26 RR_U60A61:U77A78_RR R 60 ? R 78 ? R 61 ? R 77 ?
+1 B A 54 1_555 B U 71 1_555 B C 57 1_555 B G 70 1_555 -4.249 0.516 3.328 10.983 2.181 69.865 0.375 4.032 2.733 1.892 -9.528 70.643 27 RR_A61C64:G76U77_RR R 61 ? R 77 ? R 64 ? R 76 ?
+1 B C 57 1_555 B G 70 1_555 B C 58 1_555 B G 69 1_555 -0.004 -1.520 3.987 -6.292 13.783 37.819 -3.943 -0.796 3.225 20.297 9.267 40.638 28 RR_C64C65:G75G76_RR R 64 ? R 76 ? R 65 ? R 75 ?
+#
+loop_
+_software.name                 
+_software.classification       
+_software.version              
+_software.citation_id          
+_software.pdbx_ordinal         
+CBASS "data collection" . ? 1
+Phaser "model building" . ? 2
+REFMAC refinement 5.5.0109 ? 3
+#
+loop_
+_pdbx_unobs_or_zero_occ_residues.id                   
+_pdbx_unobs_or_zero_occ_residues.polymer_flag         
+_pdbx_unobs_or_zero_occ_residues.occupancy_flag       
+_pdbx_unobs_or_zero_occ_residues.PDB_model_num        
+_pdbx_unobs_or_zero_occ_residues.auth_asym_id         
+_pdbx_unobs_or_zero_occ_residues.auth_comp_id         
+_pdbx_unobs_or_zero_occ_residues.auth_seq_id          
+_pdbx_unobs_or_zero_occ_residues.PDB_ins_code         
+1 Y 1 1 P MET 1 ?
+2 Y 1 1 P ALA 2 ?
+3 Y 1 1 P VAL 3 ?
+4 Y 1 1 P PRO 4 ?
+5 Y 1 1 P GLU 5 ?
+6 Y 1 1 P THR 6 ?
+7 Y 1 1 P ILE 94 ?
+8 Y 1 1 P ALA 95 ?
+9 Y 1 1 P LYS 96 ?
+10 Y 1 1 P MET 97 ?
+11 Y 1 1 P LYS 98 ?
+#
+loop_
+_pdbx_nonpoly_scheme.asym_id             
+_pdbx_nonpoly_scheme.entity_id           
+_pdbx_nonpoly_scheme.mon_id              
+_pdbx_nonpoly_scheme.ndb_seq_num         
+_pdbx_nonpoly_scheme.pdb_seq_num         
+_pdbx_nonpoly_scheme.auth_seq_num        
+_pdbx_nonpoly_scheme.pdb_mon_id          
+_pdbx_nonpoly_scheme.auth_mon_id         
+_pdbx_nonpoly_scheme.pdb_strand_id       
+_pdbx_nonpoly_scheme.pdb_ins_code        
+D 4 MG 1 1 1 MG MO6 R .
+E 5 HOH 1 99 1 HOH HOH P .
+E 5 HOH 2 100 2 HOH HOH P .
+E 5 HOH 3 101 7 HOH HOH P .
+F 5 HOH 1 3 3 HOH HOH R .
+F 5 HOH 2 4 4 HOH HOH R .
+F 5 HOH 3 5 5 HOH HOH R .
+F 5 HOH 4 670 8 HOH HOH R .
+F 5 HOH 5 671 9 HOH HOH R .
+F 5 HOH 6 672 10 HOH HOH R .
+F 5 HOH 7 673 1 HOH MO6 R .
+F 5 HOH 8 674 1 HOH MO6 R .
+F 5 HOH 9 675 1 HOH MO6 R .
+F 5 HOH 10 676 1 HOH MO6 R .
+G 5 HOH 1 3 1 HOH MO6 A .
+#
+_pdbx_struct_mod_residue.id                   1
+_pdbx_struct_mod_residue.label_asym_id        B
+_pdbx_struct_mod_residue.label_seq_id         1
+_pdbx_struct_mod_residue.label_comp_id        GTP
+_pdbx_struct_mod_residue.auth_asym_id         R
+_pdbx_struct_mod_residue.auth_seq_id          8
+_pdbx_struct_mod_residue.auth_comp_id         GTP
+_pdbx_struct_mod_residue.PDB_ins_code         ?
+_pdbx_struct_mod_residue.parent_comp_id       G
+_pdbx_struct_mod_residue.details              "GUANOSINE-5'-TRIPHOSPHATE"
+#
+_pdbx_validate_rmsd_bond.id                   1
+_pdbx_validate_rmsd_bond.PDB_model_num        1
+_pdbx_validate_rmsd_bond.auth_atom_id_1       P
+_pdbx_validate_rmsd_bond.auth_asym_id_1       A
+_pdbx_validate_rmsd_bond.auth_comp_id_1       G
+_pdbx_validate_rmsd_bond.auth_seq_id_1        1
+_pdbx_validate_rmsd_bond.PDB_ins_code_1       ?
+_pdbx_validate_rmsd_bond.label_alt_id_1       ?
+_pdbx_validate_rmsd_bond.auth_atom_id_2       OP3
+_pdbx_validate_rmsd_bond.auth_asym_id_2       A
+_pdbx_validate_rmsd_bond.auth_comp_id_2       G
+_pdbx_validate_rmsd_bond.auth_seq_id_2        1
+_pdbx_validate_rmsd_bond.PDB_ins_code_2       ?
+_pdbx_validate_rmsd_bond.label_alt_id_2       ?
+_pdbx_validate_rmsd_bond.bond_deviation       -0.127
+#
+loop_
+_pdbx_validate_rmsd_angle.id                    
+_pdbx_validate_rmsd_angle.PDB_model_num         
+_pdbx_validate_rmsd_angle.auth_atom_id_1        
+_pdbx_validate_rmsd_angle.auth_asym_id_1        
+_pdbx_validate_rmsd_angle.auth_comp_id_1        
+_pdbx_validate_rmsd_angle.auth_seq_id_1         
+_pdbx_validate_rmsd_angle.PDB_ins_code_1        
+_pdbx_validate_rmsd_angle.label_alt_id_1        
+_pdbx_validate_rmsd_angle.auth_atom_id_2        
+_pdbx_validate_rmsd_angle.auth_asym_id_2        
+_pdbx_validate_rmsd_angle.auth_comp_id_2        
+_pdbx_validate_rmsd_angle.auth_seq_id_2         
+_pdbx_validate_rmsd_angle.PDB_ins_code_2        
+_pdbx_validate_rmsd_angle.label_alt_id_2        
+_pdbx_validate_rmsd_angle.auth_atom_id_3        
+_pdbx_validate_rmsd_angle.auth_asym_id_3        
+_pdbx_validate_rmsd_angle.auth_comp_id_3        
+_pdbx_validate_rmsd_angle.auth_seq_id_3         
+_pdbx_validate_rmsd_angle.PDB_ins_code_3        
+_pdbx_validate_rmsd_angle.label_alt_id_3        
+_pdbx_validate_rmsd_angle.angle_deviation       
+1 1 "O4'" R A 48 ? ? "C1'" R A 48 ? ? N9 R A 48 ? ? 5.2
+2 1 OP1 A G 1 ? ? P A G 1 ? ? OP2 A G 1 ? ? -12.1
+#
+_pdbx_validate_torsion.id                  1
+_pdbx_validate_torsion.PDB_model_num       1
+_pdbx_validate_torsion.auth_comp_id        ASP
+_pdbx_validate_torsion.auth_asym_id        P
+_pdbx_validate_torsion.auth_seq_id         92
+_pdbx_validate_torsion.PDB_ins_code        ?
+_pdbx_validate_torsion.phi                 74.40
+_pdbx_validate_torsion.psi                 -158.21
+#
+loop_
+_pdbx_entity_nonpoly.entity_id       
+_pdbx_entity_nonpoly.name            
+_pdbx_entity_nonpoly.comp_id         
+4 "MAGNESIUM ION" MG
+5 water HOH
+#
+loop_
+_chem_comp_bond.comp_id                  
+_chem_comp_bond.pdbx_stereo_config       
+_chem_comp_bond.pdbx_ordinal             
+_chem_comp_bond.pdbx_aromatic_flag       
+_chem_comp_bond.atom_id_1                
+_chem_comp_bond.atom_id_2                
+_chem_comp_bond.value_order              
+ARG N 1 N N CA SING
+ARG N 2 N N H SING
+ARG N 3 N N H2 SING
+ARG N 4 N CA C SING
+ARG N 5 N CA CB SING
+ARG N 6 N CA HA SING
+ARG N 7 N C O DOUB
+ARG N 8 N C OXT SING
+ARG N 9 N CB CG SING
+ARG N 10 N CB HB2 SING
+ARG N 11 N CB HB3 SING
+ARG N 12 N CG CD SING
+ARG N 13 N CG HG2 SING
+ARG N 14 N CG HG3 SING
+ARG N 15 N CD NE SING
+ARG N 16 N CD HD2 SING
+ARG N 17 N CD HD3 SING
+ARG N 18 N NE CZ SING
+ARG N 19 N NE HE SING
+ARG N 20 N CZ NH1 SING
+ARG N 21 N CZ NH2 DOUB
+ARG N 22 N NH1 HH11 SING
+ARG N 23 N NH1 HH12 SING
+ARG N 24 N NH2 HH21 SING
+ARG N 25 N NH2 HH22 SING
+ARG N 26 N OXT HXT SING
+PRO N 1 N N CA SING
+PRO N 2 N N CD SING
+PRO N 3 N N H SING
+PRO N 4 N CA C SING
+PRO N 5 N CA CB SING
+PRO N 6 N CA HA SING
+PRO N 7 N C O DOUB
+PRO N 8 N C OXT SING
+PRO N 9 N CB CG SING
+PRO N 10 N CB HB2 SING
+PRO N 11 N CB HB3 SING
+PRO N 12 N CG CD SING
+PRO N 13 N CG HG2 SING
+PRO N 14 N CG HG3 SING
+PRO N 15 N CD HD2 SING
+PRO N 16 N CD HD3 SING
+PRO N 17 N OXT HXT SING
+ASN N 1 N N CA SING
+ASN N 2 N N H SING
+ASN N 3 N N H2 SING
+ASN N 4 N CA C SING
+ASN N 5 N CA CB SING
+ASN N 6 N CA HA SING
+ASN N 7 N C O DOUB
+ASN N 8 N C OXT SING
+ASN N 9 N CB CG SING
+ASN N 10 N CB HB2 SING
+ASN N 11 N CB HB3 SING
+ASN N 12 N CG OD1 DOUB
+ASN N 13 N CG ND2 SING
+ASN N 14 N ND2 HD21 SING
+ASN N 15 N ND2 HD22 SING
+ASN N 16 N OXT HXT SING
+HIS N 1 N N CA SING
+HIS N 2 N N H SING
+HIS N 3 N N H2 SING
+HIS N 4 N CA C SING
+HIS N 5 N CA CB SING
+HIS N 6 N CA HA SING
+HIS N 7 N C O DOUB
+HIS N 8 N C OXT SING
+HIS N 9 N CB CG SING
+HIS N 10 N CB HB2 SING
+HIS N 11 N CB HB3 SING
+HIS N 12 Y CG ND1 SING
+HIS N 13 Y CG CD2 DOUB
+HIS N 14 Y ND1 CE1 DOUB
+HIS N 15 N ND1 HD1 SING
+HIS N 16 Y CD2 NE2 SING
+HIS N 17 N CD2 HD2 SING
+HIS N 18 Y CE1 NE2 SING
+HIS N 19 N CE1 HE1 SING
+HIS N 20 N NE2 HE2 SING
+HIS N 21 N OXT HXT SING
+THR N 1 N N CA SING
+THR N 2 N N H SING
+THR N 3 N N H2 SING
+THR N 4 N CA C SING
+THR N 5 N CA CB SING
+THR N 6 N CA HA SING
+THR N 7 N C O DOUB
+THR N 8 N C OXT SING
+THR N 9 N CB OG1 SING
+THR N 10 N CB CG2 SING
+THR N 11 N CB HB SING
+THR N 12 N OG1 HG1 SING
+THR N 13 N CG2 HG21 SING
+THR N 14 N CG2 HG22 SING
+THR N 15 N CG2 HG23 SING
+THR N 16 N OXT HXT SING
+ILE N 1 N N CA SING
+ILE N 2 N N H SING
+ILE N 3 N N H2 SING
+ILE N 4 N CA C SING
+ILE N 5 N CA CB SING
+ILE N 6 N CA HA SING
+ILE N 7 N C O DOUB
+ILE N 8 N C OXT SING
+ILE N 9 N CB CG1 SING
+ILE N 10 N CB CG2 SING
+ILE N 11 N CB HB SING
+ILE N 12 N CG1 CD1 SING
+ILE N 13 N CG1 HG12 SING
+ILE N 14 N CG1 HG13 SING
+ILE N 15 N CG2 HG21 SING
+ILE N 16 N CG2 HG22 SING
+ILE N 17 N CG2 HG23 SING
+ILE N 18 N CD1 HD11 SING
+ILE N 19 N CD1 HD12 SING
+ILE N 20 N CD1 HD13 SING
+ILE N 21 N OXT HXT SING
+TYR N 1 N N CA SING
+TYR N 2 N N H SING
+TYR N 3 N N H2 SING
+TYR N 4 N CA C SING
+TYR N 5 N CA CB SING
+TYR N 6 N CA HA SING
+TYR N 7 N C O DOUB
+TYR N 8 N C OXT SING
+TYR N 9 N CB CG SING
+TYR N 10 N CB HB2 SING
+TYR N 11 N CB HB3 SING
+TYR N 12 Y CG CD1 DOUB
+TYR N 13 Y CG CD2 SING
+TYR N 14 Y CD1 CE1 SING
+TYR N 15 N CD1 HD1 SING
+TYR N 16 Y CD2 CE2 DOUB
+TYR N 17 N CD2 HD2 SING
+TYR N 18 Y CE1 CZ DOUB
+TYR N 19 N CE1 HE1 SING
+TYR N 20 Y CE2 CZ SING
+TYR N 21 N CE2 HE2 SING
+TYR N 22 N CZ OH SING
+TYR N 23 N OH HH SING
+TYR N 24 N OXT HXT SING
+LEU N 1 N N CA SING
+LEU N 2 N N H SING
+LEU N 3 N N H2 SING
+LEU N 4 N CA C SING
+LEU N 5 N CA CB SING
+LEU N 6 N CA HA SING
+LEU N 7 N C O DOUB
+LEU N 8 N C OXT SING
+LEU N 9 N CB CG SING
+LEU N 10 N CB HB2 SING
+LEU N 11 N CB HB3 SING
+LEU N 12 N CG CD1 SING
+LEU N 13 N CG CD2 SING
+LEU N 14 N CG HG SING
+LEU N 15 N CD1 HD11 SING
+LEU N 16 N CD1 HD12 SING
+LEU N 17 N CD1 HD13 SING
+LEU N 18 N CD2 HD21 SING
+LEU N 19 N CD2 HD22 SING
+LEU N 20 N CD2 HD23 SING
+LEU N 21 N OXT HXT SING
+GLU N 1 N N CA SING
+GLU N 2 N N H SING
+GLU N 3 N N H2 SING
+GLU N 4 N CA C SING
+GLU N 5 N CA CB SING
+GLU N 6 N CA HA SING
+GLU N 7 N C O DOUB
+GLU N 8 N C OXT SING
+GLU N 9 N CB CG SING
+GLU N 10 N CB HB2 SING
+GLU N 11 N CB HB3 SING
+GLU N 12 N CG CD SING
+GLU N 13 N CG HG2 SING
+GLU N 14 N CG HG3 SING
+GLU N 15 N CD OE1 DOUB
+GLU N 16 N CD OE2 SING
+GLU N 17 N OE2 HE2 SING
+GLU N 18 N OXT HXT SING
+LYS N 1 N N CA SING
+LYS N 2 N N H SING
+LYS N 3 N N H2 SING
+LYS N 4 N CA C SING
+LYS N 5 N CA CB SING
+LYS N 6 N CA HA SING
+LYS N 7 N C O DOUB
+LYS N 8 N C OXT SING
+LYS N 9 N CB CG SING
+LYS N 10 N CB HB2 SING
+LYS N 11 N CB HB3 SING
+LYS N 12 N CG CD SING
+LYS N 13 N CG HG2 SING
+LYS N 14 N CG HG3 SING
+LYS N 15 N CD CE SING
+LYS N 16 N CD HD2 SING
+LYS N 17 N CD HD3 SING
+LYS N 18 N CE NZ SING
+LYS N 19 N CE HE2 SING
+LYS N 20 N CE HE3 SING
+LYS N 21 N NZ HZ1 SING
+LYS N 22 N NZ HZ2 SING
+LYS N 23 N NZ HZ3 SING
+LYS N 24 N OXT HXT SING
+ASP N 1 N N CA SING
+ASP N 2 N N H SING
+ASP N 3 N N H2 SING
+ASP N 4 N CA C SING
+ASP N 5 N CA CB SING
+ASP N 6 N CA HA SING
+ASP N 7 N C O DOUB
+ASP N 8 N C OXT SING
+ASP N 9 N CB CG SING
+ASP N 10 N CB HB2 SING
+ASP N 11 N CB HB3 SING
+ASP N 12 N CG OD1 DOUB
+ASP N 13 N CG OD2 SING
+ASP N 14 N OD2 HD2 SING
+ASP N 15 N OXT HXT SING
+SER N 1 N N CA SING
+SER N 2 N N H SING
+SER N 3 N N H2 SING
+SER N 4 N CA C SING
+SER N 5 N CA CB SING
+SER N 6 N CA HA SING
+SER N 7 N C O DOUB
+SER N 8 N C OXT SING
+SER N 9 N CB OG SING
+SER N 10 N CB HB2 SING
+SER N 11 N CB HB3 SING
+SER N 12 N OG HG SING
+SER N 13 N OXT HXT SING
+ALA N 1 N N CA SING
+ALA N 2 N N H SING
+ALA N 3 N N H2 SING
+ALA N 4 N CA C SING
+ALA N 5 N CA CB SING
+ALA N 6 N CA HA SING
+ALA N 7 N C O DOUB
+ALA N 8 N C OXT SING
+ALA N 9 N CB HB1 SING
+ALA N 10 N CB HB2 SING
+ALA N 11 N CB HB3 SING
+ALA N 12 N OXT HXT SING
+PHE N 1 N N CA SING
+PHE N 2 N N H SING
+PHE N 3 N N H2 SING
+PHE N 4 N CA C SING
+PHE N 5 N CA CB SING
+PHE N 6 N CA HA SING
+PHE N 7 N C O DOUB
+PHE N 8 N C OXT SING
+PHE N 9 N CB CG SING
+PHE N 10 N CB HB2 SING
+PHE N 11 N CB HB3 SING
+PHE N 12 Y CG CD1 DOUB
+PHE N 13 Y CG CD2 SING
+PHE N 14 Y CD1 CE1 SING
+PHE N 15 N CD1 HD1 SING
+PHE N 16 Y CD2 CE2 DOUB
+PHE N 17 N CD2 HD2 SING
+PHE N 18 Y CE1 CZ DOUB
+PHE N 19 N CE1 HE1 SING
+PHE N 20 Y CE2 CZ SING
+PHE N 21 N CE2 HE2 SING
+PHE N 22 N CZ HZ SING
+PHE N 23 N OXT HXT SING
+GLY N 1 N N CA SING
+GLY N 2 N N H SING
+GLY N 3 N N H2 SING
+GLY N 4 N CA C SING
+GLY N 5 N CA HA2 SING
+GLY N 6 N CA HA3 SING
+GLY N 7 N C O DOUB
+GLY N 8 N C OXT SING
+GLY N 9 N OXT HXT SING
+GLN N 1 N N CA SING
+GLN N 2 N N H SING
+GLN N 3 N N H2 SING
+GLN N 4 N CA C SING
+GLN N 5 N CA CB SING
+GLN N 6 N CA HA SING
+GLN N 7 N C O DOUB
+GLN N 8 N C OXT SING
+GLN N 9 N CB CG SING
+GLN N 10 N CB HB2 SING
+GLN N 11 N CB HB3 SING
+GLN N 12 N CG CD SING
+GLN N 13 N CG HG2 SING
+GLN N 14 N CG HG3 SING
+GLN N 15 N CD OE1 DOUB
+GLN N 16 N CD NE2 SING
+GLN N 17 N NE2 HE21 SING
+GLN N 18 N NE2 HE22 SING
+GLN N 19 N OXT HXT SING
+VAL N 1 N N CA SING
+VAL N 2 N N H SING
+VAL N 3 N N H2 SING
+VAL N 4 N CA C SING
+VAL N 5 N CA CB SING
+VAL N 6 N CA HA SING
+VAL N 7 N C O DOUB
+VAL N 8 N C OXT SING
+VAL N 9 N CB CG1 SING
+VAL N 10 N CB CG2 SING
+VAL N 11 N CB HB SING
+VAL N 12 N CG1 HG11 SING
+VAL N 13 N CG1 HG12 SING
+VAL N 14 N CG1 HG13 SING
+VAL N 15 N CG2 HG21 SING
+VAL N 16 N CG2 HG22 SING
+VAL N 17 N CG2 HG23 SING
+VAL N 18 N OXT HXT SING
+MET N 1 N N CA SING
+MET N 2 N N H SING
+MET N 3 N N H2 SING
+MET N 4 N CA C SING
+MET N 5 N CA CB SING
+MET N 6 N CA HA SING
+MET N 7 N C O DOUB
+MET N 8 N C OXT SING
+MET N 9 N CB CG SING
+MET N 10 N CB HB2 SING
+MET N 11 N CB HB3 SING
+MET N 12 N CG SD SING
+MET N 13 N CG HG2 SING
+MET N 14 N CG HG3 SING
+MET N 15 N SD CE SING
+MET N 16 N CE HE1 SING
+MET N 17 N CE HE2 SING
+MET N 18 N CE HE3 SING
+MET N 19 N OXT HXT SING
+GTP N 1 N PG O1G DOUB
+GTP N 2 N PG O2G SING
+GTP N 3 N PG O3G SING
+GTP N 4 N PG O3B SING
+GTP N 5 N O2G HOG2 SING
+GTP N 6 N O3G HOG3 SING
+GTP N 7 N O3B PB SING
+GTP N 8 N PB O1B DOUB
+GTP N 9 N PB O2B SING
+GTP N 10 N PB O3A SING
+GTP N 11 N O2B HOB2 SING
+GTP N 12 N O3A PA SING
+GTP N 13 N PA O1A DOUB
+GTP N 14 N PA O2A SING
+GTP N 15 N PA "O5'" SING
+GTP N 16 N O2A HOA2 SING
+GTP N 17 N "O5'" "C5'" SING
+GTP N 18 N "C5'" "C4'" SING
+GTP N 19 N "C5'" "H5'" SING
+GTP N 20 N "C5'" "H5''" SING
+GTP N 21 N "C4'" "O4'" SING
+GTP N 22 N "C4'" "C3'" SING
+GTP N 23 N "C4'" "H4'" SING
+GTP N 24 N "O4'" "C1'" SING
+GTP N 25 N "C3'" "O3'" SING
+GTP N 26 N "C3'" "C2'" SING
+GTP N 27 N "C3'" "H3'" SING
+GTP N 28 N "O3'" "HO3'" SING
+GTP N 29 N "C2'" "O2'" SING
+GTP N 30 N "C2'" "C1'" SING
+GTP N 31 N "C2'" "H2'" SING
+GTP N 32 N "O2'" "HO2'" SING
+GTP N 33 N "C1'" N9 SING
+GTP N 34 N "C1'" "H1'" SING
+GTP N 35 Y N9 C8 SING
+GTP N 36 Y N9 C4 SING
+GTP N 37 Y C8 N7 DOUB
+GTP N 38 N C8 H8 SING
+GTP N 39 Y N7 C5 SING
+GTP N 40 N C5 C6 SING
+GTP N 41 Y C5 C4 DOUB
+GTP N 42 N C6 O6 DOUB
+GTP N 43 N C6 N1 SING
+GTP N 44 N N1 C2 SING
+GTP N 45 N N1 HN1 SING
+GTP N 46 N C2 N2 SING
+GTP N 47 N C2 N3 DOUB
+GTP N 48 N N2 HN21 SING
+GTP N 49 N N2 HN22 SING
+GTP N 50 N N3 C4 SING
+G N 1 N OP3 P SING
+G N 2 N OP3 HOP3 SING
+G N 3 N P OP1 DOUB
+G N 4 N P OP2 SING
+G N 5 N P "O5'" SING
+G N 6 N OP2 HOP2 SING
+G N 7 N "O5'" "C5'" SING
+G N 8 N "C5'" "C4'" SING
+G N 9 N "C5'" "H5'" SING
+G N 10 N "C5'" "H5''" SING
+G N 11 N "C4'" "O4'" SING
+G N 12 N "C4'" "C3'" SING
+G N 13 N "C4'" "H4'" SING
+G N 14 N "O4'" "C1'" SING
+G N 15 N "C3'" "O3'" SING
+G N 16 N "C3'" "C2'" SING
+G N 17 N "C3'" "H3'" SING
+G N 18 N "O3'" "HO3'" SING
+G N 19 N "C2'" "O2'" SING
+G N 20 N "C2'" "C1'" SING
+G N 21 N "C2'" "H2'" SING
+G N 22 N "O2'" "HO2'" SING
+G N 23 N "C1'" N9 SING
+G N 24 N "C1'" "H1'" SING
+G N 25 Y N9 C8 SING
+G N 26 Y N9 C4 SING
+G N 27 Y C8 N7 DOUB
+G N 28 N C8 H8 SING
+G N 29 Y N7 C5 SING
+G N 30 N C5 C6 SING
+G N 31 Y C5 C4 DOUB
+G N 32 N C6 O6 DOUB
+G N 33 N C6 N1 SING
+G N 34 N N1 C2 SING
+G N 35 N N1 H1 SING
+G N 36 N C2 N2 SING
+G N 37 N C2 N3 DOUB
+G N 38 N N2 H21 SING
+G N 39 N N2 H22 SING
+G N 40 N N3 C4 SING
+U N 1 N OP3 P SING
+U N 2 N OP3 HOP3 SING
+U N 3 N P OP1 DOUB
+U N 4 N P OP2 SING
+U N 5 N P "O5'" SING
+U N 6 N OP2 HOP2 SING
+U N 7 N "O5'" "C5'" SING
+U N 8 N "C5'" "C4'" SING
+U N 9 N "C5'" "H5'" SING
+U N 10 N "C5'" "H5''" SING
+U N 11 N "C4'" "O4'" SING
+U N 12 N "C4'" "C3'" SING
+U N 13 N "C4'" "H4'" SING
+U N 14 N "O4'" "C1'" SING
+U N 15 N "C3'" "O3'" SING
+U N 16 N "C3'" "C2'" SING
+U N 17 N "C3'" "H3'" SING
+U N 18 N "O3'" "HO3'" SING
+U N 19 N "C2'" "O2'" SING
+U N 20 N "C2'" "C1'" SING
+U N 21 N "C2'" "H2'" SING
+U N 22 N "O2'" "HO2'" SING
+U N 23 N "C1'" N1 SING
+U N 24 N "C1'" "H1'" SING
+U N 25 N N1 C2 SING
+U N 26 N N1 C6 SING
+U N 27 N C2 O2 DOUB
+U N 28 N C2 N3 SING
+U N 29 N N3 C4 SING
+U N 30 N N3 H3 SING
+U N 31 N C4 O4 DOUB
+U N 32 N C4 C5 SING
+U N 33 N C5 C6 DOUB
+U N 34 N C5 H5 SING
+U N 35 N C6 H6 SING
+C N 1 N OP3 P SING
+C N 2 N OP3 HOP3 SING
+C N 3 N P OP1 DOUB
+C N 4 N P OP2 SING
+C N 5 N P "O5'" SING
+C N 6 N OP2 HOP2 SING
+C N 7 N "O5'" "C5'" SING
+C N 8 N "C5'" "C4'" SING
+C N 9 N "C5'" "H5'" SING
+C N 10 N "C5'" "H5''" SING
+C N 11 N "C4'" "O4'" SING
+C N 12 N "C4'" "C3'" SING
+C N 13 N "C4'" "H4'" SING
+C N 14 N "O4'" "C1'" SING
+C N 15 N "C3'" "O3'" SING
+C N 16 N "C3'" "C2'" SING
+C N 17 N "C3'" "H3'" SING
+C N 18 N "O3'" "HO3'" SING
+C N 19 N "C2'" "O2'" SING
+C N 20 N "C2'" "C1'" SING
+C N 21 N "C2'" "H2'" SING
+C N 22 N "O2'" "HO2'" SING
+C N 23 N "C1'" N1 SING
+C N 24 N "C1'" "H1'" SING
+C N 25 N N1 C2 SING
+C N 26 N N1 C6 SING
+C N 27 N C2 O2 DOUB
+C N 28 N C2 N3 SING
+C N 29 N N3 C4 DOUB
+C N 30 N C4 N4 SING
+C N 31 N C4 C5 SING
+C N 32 N N4 H41 SING
+C N 33 N N4 H42 SING
+C N 34 N C5 C6 DOUB
+C N 35 N C5 H5 SING
+C N 36 N C6 H6 SING
+A N 1 N OP3 P SING
+A N 2 N OP3 HOP3 SING
+A N 3 N P OP1 DOUB
+A N 4 N P OP2 SING
+A N 5 N P "O5'" SING
+A N 6 N OP2 HOP2 SING
+A N 7 N "O5'" "C5'" SING
+A N 8 N "C5'" "C4'" SING
+A N 9 N "C5'" "H5'" SING
+A N 10 N "C5'" "H5''" SING
+A N 11 N "C4'" "O4'" SING
+A N 12 N "C4'" "C3'" SING
+A N 13 N "C4'" "H4'" SING
+A N 14 N "O4'" "C1'" SING
+A N 15 N "C3'" "O3'" SING
+A N 16 N "C3'" "C2'" SING
+A N 17 N "C3'" "H3'" SING
+A N 18 N "O3'" "HO3'" SING
+A N 19 N "C2'" "O2'" SING
+A N 20 N "C2'" "C1'" SING
+A N 21 N "C2'" "H2'" SING
+A N 22 N "O2'" "HO2'" SING
+A N 23 N "C1'" N9 SING
+A N 24 N "C1'" "H1'" SING
+A N 25 Y N9 C8 SING
+A N 26 Y N9 C4 SING
+A N 27 Y C8 N7 DOUB
+A N 28 N C8 H8 SING
+A N 29 Y N7 C5 SING
+A N 30 Y C5 C6 SING
+A N 31 Y C5 C4 DOUB
+A N 32 N C6 N6 SING
+A N 33 Y C6 N1 DOUB
+A N 34 N N6 H61 SING
+A N 35 N N6 H62 SING
+A N 36 Y N1 C2 SING
+A N 37 Y C2 N3 DOUB
+A N 38 N C2 H2 SING
+A N 39 Y N3 C4 SING
+HOH N 1 N O H1 SING
+HOH N 2 N O H2 SING
+#
index ddf9a15..77aa0f6 100644 (file)
@@ -54,7 +54,8 @@ public class BioJsHTMLOutputTest
       {
         e.printStackTrace();
       }
-      bjsTemplate = BioJsHTMLOutput.getBioJsTemplateAsString();
+      bjsTemplate = HTMLOutput.readFileAsString(BioJsHTMLOutput
+              .getCurrentBJSTemplateFile());
       // System.out.println(bjsTemplate);
     } catch (IOException e)
     {
@@ -70,7 +71,7 @@ public class BioJsHTMLOutputTest
   {
     try
     {
-      BioJsHTMLOutput.refreshBioJSVersionsInfo(null);
+      BioJsHTMLOutput.refreshVersionInfo(null);
     } catch (URISyntaxException e)
     {
       AssertJUnit.fail("Expception occured while testing!");
@@ -85,7 +86,7 @@ public class BioJsHTMLOutputTest
     try
     {
       BioJsHTMLOutput
-              .refreshBioJSVersionsInfo(BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
+              .refreshVersionInfo(BioJsHTMLOutput.BJS_TEMPLATES_LOCAL_DIRECTORY);
       versions = BioJsHTMLOutput.getBioJsMSAVersions();
     } catch (URISyntaxException e)
     {
index f75f433..3f7edd4 100644 (file)
@@ -305,7 +305,8 @@ public class JSONFileTest
     Assert.assertNotNull(cs.getHiddenColumns());
     List<int[]> hiddenCols = cs.getHiddenColumns();
     Assert.assertEquals(hiddenCols.size(), TEST_CS_HEIGHT);
-    Assert.assertEquals(hiddenCols, expectedColSel.getHiddenColumns(),
+    Assert.assertEquals(hiddenCols.get(0), expectedColSel
+            .getHiddenColumns().get(0),
             "Mismatched hidden columns!");
   }
 
@@ -314,7 +315,8 @@ public class JSONFileTest
   {
     Assert.assertNotNull(testJsonFile.getHiddenSequences(),
             "Hidden sequence Expected but found Null");
-    Assert.assertEquals(jf.getHiddenSequences().length, 1, "Hidden sequece");
+    Assert.assertEquals(jf.getHiddenSequences().length, 1,
+            "Hidden sequence");
   }
 
   @Test(groups = { "Functional" })
index 0eaf94b..fb99865 100644 (file)
@@ -29,20 +29,20 @@ import org.testng.annotations.Test;
 
 public class PfamFormatInputTest
 {
-  @Test
+  @Test(groups = "Functional")
   public void testPfamFormatNoLimits() throws IOException
   {
-    AlignmentI al = new jalview.io.AppletFormatAdapter().readFile("ASEQ"
+    AlignmentI al = new 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
+  @Test(groups = "Functional")
   public void testPfamFormatValidLimits() throws IOException
   {
-    AlignmentI al = new jalview.io.AppletFormatAdapter().readFile(
+    AlignmentI al = new AppletFormatAdapter().readFile(
             "ASEQ/15-25" + '\t' + "...--FFAFAFF--",
             AppletFormatAdapter.PASTE, "PFAM");
     Assert.assertEquals(1, al.getHeight(), "Wrong number of sequences");
index a96a2a8..1392157 100644 (file)
@@ -35,7 +35,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_disulfideBond()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     sb.append("123456");
     SequenceFeature sf = new SequenceFeature("disulfide bond", "desc", 1,
             3, 1.2f, "group");
@@ -60,7 +60,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_status()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3,
             Float.NaN, "group");
     sf.setStatus("Confirmed");
@@ -73,7 +73,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_withScore()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3, 1.3f,
             "group");
 
@@ -106,7 +106,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_noScore()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3,
             Float.NaN, "group");
 
@@ -118,7 +118,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_clinicalSignificance()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3,
             Float.NaN, "group");
     sf.setValue("clinical_significance", "Benign");
@@ -131,7 +131,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_withScoreStatusClinicalSignificance()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3, 1.3f,
             "group");
     sf.setStatus("Confirmed");
@@ -148,7 +148,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_DescEqualsType()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "METAL", 1, 3,
             Float.NaN, "group");
 
@@ -167,7 +167,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_stripHtml()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL",
             "<html><body>hello<em>world</em></body></html>", 1, 3,
             Float.NaN, "group");
diff --git a/test/jalview/schemes/ResidueColourSchemeTest.java b/test/jalview/schemes/ResidueColourSchemeTest.java
new file mode 100644 (file)
index 0000000..a02ca06
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * 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.schemes;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+
+import jalview.datamodel.Profile;
+import jalview.datamodel.ProfileI;
+import jalview.datamodel.Profiles;
+
+import java.awt.Color;
+
+import org.testng.annotations.Test;
+
+public class ResidueColourSchemeTest
+{
+  @Test(groups = "Functional")
+  public void testAboveThreshold()
+  {
+    /*
+     * make up profiles for this alignment:
+     * AR-Q
+     * AR--
+     * SR-T
+     * SR-T
+     */
+    ProfileI[] profiles = new ProfileI[4];
+    profiles[0] = new Profile(4, 0, 2, "AS");
+    profiles[1] = new Profile(4, 0, 4, "R");
+    profiles[2] = new Profile(4, 4, 0, "");
+    profiles[3] = new Profile(4, 1, 2, "T");
+    ResidueColourScheme rcs = new ResidueColourScheme();
+    rcs.setConsensus(new Profiles(profiles));
+    
+    /*
+     * no threshold
+     */
+    rcs.setThreshold(0, true);
+    assertTrue(rcs.aboveThreshold('a', 0));
+    assertTrue(rcs.aboveThreshold('S', 0));
+    assertFalse(rcs.aboveThreshold('W', 0));
+    assertTrue(rcs.aboveThreshold('R', 1));
+    assertFalse(rcs.aboveThreshold('W', 2));
+    assertTrue(rcs.aboveThreshold('t', 3));
+    assertFalse(rcs.aboveThreshold('Q', 3));
+
+    /*
+     * with threshold, include gaps
+     */
+    rcs.setThreshold(60, false);
+    assertFalse(rcs.aboveThreshold('a', 0));
+    assertFalse(rcs.aboveThreshold('S', 0));
+    assertTrue(rcs.aboveThreshold('R', 1));
+    assertFalse(rcs.aboveThreshold('W', 2));
+    assertFalse(rcs.aboveThreshold('t', 3)); // 50% < 60%
+
+    /*
+     * with threshold, ignore gaps
+     */
+    rcs.setThreshold(60, true);
+    assertFalse(rcs.aboveThreshold('a', 0));
+    assertFalse(rcs.aboveThreshold('S', 0));
+    assertTrue(rcs.aboveThreshold('R', 1));
+    assertFalse(rcs.aboveThreshold('W', 2));
+    assertTrue(rcs.aboveThreshold('t', 3)); // 67% > 60%
+  }
+
+  /**
+   * Test colour bleaching based on conservation score and conservation slider.
+   * Scores of 10 or 11 should leave colours unchanged. Gap is always white.
+   */
+  @Test(groups = "Functional")
+  public void testApplyConservation()
+  {
+    ResidueColourScheme rcs = new ResidueColourScheme();
+
+    // no conservation present - no fading
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 12));
+    
+    // cheat by setting conservation sequence directly
+    // rather than calculating it - good enough for this test
+    String consensus = "0123456789+*-";
+    rcs.conservation = consensus.toCharArray();
+
+    // column out of range:
+    assertEquals(Color.RED,
+            rcs.applyConservation(Color.RED, consensus.length()));
+
+    /*
+     * with 100% threshold, 'fade factor' is 
+     * (11-score)/10 * 100/20 = (11-score)/2
+     * which is >= 1 for all scores i.e. all fade to white except +, *
+     */
+    rcs.setConservationInc(100);
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 0));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 1));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 2));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 3));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 4));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 5));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 6));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 7));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 8));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 9));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 10));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 11));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 12));
+
+    /*
+     * with 0% threshold, there should be no fading
+     */
+    rcs.setConservationInc(0);
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 0));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 1));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 2));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 3));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 4));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 5));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 6));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 7));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 8));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 9));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 10));
+    assertEquals(Color.RED, rcs.applyConservation(Color.RED, 11));
+    assertEquals(Color.WHITE, rcs.applyConservation(Color.RED, 12)); // gap
+
+    /*
+     * with 40% threshold, 'fade factor' is 
+     * (11-score)/10 * 40/20 = (11-score)/5
+     * which is {>1, >1, >1, >1, >1, >1, 1, 0.8, 0.6, 0.4} for score 0-9
+     * e.g. score 7 colour fades 80% of the way to white (255, 255, 255)
+     */
+    rcs.setConservationInc(40);
+    Color colour = new Color(155, 105, 55);
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 0));
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 1));
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 2));
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 3));
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 4));
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 5));
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 6));
+    assertEquals(new Color(235, 225, 215), rcs.applyConservation(colour, 7));
+    assertEquals(new Color(215, 195, 175), rcs.applyConservation(colour, 8));
+    assertEquals(new Color(195, 165, 135), rcs.applyConservation(colour, 9));
+    assertEquals(colour, rcs.applyConservation(colour, 10));
+    assertEquals(colour, rcs.applyConservation(colour, 11));
+    assertEquals(Color.WHITE, rcs.applyConservation(colour, 12));
+  }
+}
index b68ca68..be6a10c 100644 (file)
@@ -25,6 +25,7 @@ import static org.testng.AssertJUnit.assertNull;
 
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 import org.testng.annotations.Test;
 
@@ -1556,4 +1557,62 @@ public class ResiduePropertiesTest
     assertEquals('Q', ResidueProperties.getSingleCharacterCode("Gln"));
     assertEquals('Q', ResidueProperties.getSingleCharacterCode("gln"));
   }
+
+  @Test(groups = { "Functional" })
+  public void testPhysicoChemicalProperties()
+  {
+    checkProperty("aromatic", "FYWH-*");
+    checkProperty("aliphatic", "IVL-*");
+    checkProperty("tiny", "GAS-*");
+    checkProperty("small", "VCTGACSDNP-*");
+    checkProperty("charged", "HKRDE-*");
+    checkProperty("negative", "DE-*");
+    checkProperty("polar", "YWHRKTSNDEQ-*X");
+    checkProperty("positive", "HKR-*");
+    checkProperty("proline", "P-*");
+    checkProperty("hydrophobic", "MILVFYWHKTGAC-*X");
+  }
+
+  /**
+   * Verify that the residues in the list have the named property, and other
+   * residues do not
+   * 
+   * @param property
+   * @param residues
+   */
+  void checkProperty(String property, String residues)
+  {
+    Map<String, Integer> props = ResidueProperties.propHash.get(property);
+
+    /*
+     * assert residues have the property (value 1 in lookup)
+     */
+    for (char res : residues.toCharArray())
+    {
+      assertEquals(res + " should be " + property, 1,
+              props.get(String.valueOf(res)).intValue());
+    }
+
+    /*
+     * assert other residues do not (value 0 in lookup)
+     */
+    for (String res : ResidueProperties.aa)
+    {
+      if (!residues.contains(res))
+      {
+        Integer propValue = props.get(String.valueOf(res));
+
+        if (propValue != null)
+        {
+          /*
+           * conservation calculation assigns unexpected symbols
+           * the same value as '-'; here we just check those which
+           * explicitly do not have the property
+           */
+          assertEquals(res + " should not be " + property, 0,
+                  propValue.intValue());
+        }
+      }
+    }
+  }
 }
index 0d00169..66e0152 100644 (file)
@@ -104,7 +104,6 @@ public class AAStructureBindingModelTest
     pdbFiles[0] = new PDBEntry("1YCS", "A", Type.PDB, "INLINE1YCS");
     pdbFiles[1] = new PDBEntry("3A6S", "B", Type.PDB, "INLINE3A6S");
     pdbFiles[2] = new PDBEntry("1OOT", "A", Type.PDB, "INLINE1OOT");
-    String[][] chains = new String[3][];
     SequenceI[][] seqs = new SequenceI[3][];
     seqs[0] = new SequenceI[] { seq1a, seq1b };
     seqs[1] = new SequenceI[] { seq2 };
@@ -118,7 +117,7 @@ public class AAStructureBindingModelTest
     ssm.setMapping(new SequenceI[] { seq3 }, null, PDB_3,
             AppletFormatAdapter.PASTE);
 
-    testee = new AAStructureBindingModel(ssm, pdbFiles, seqs, chains, null)
+    testee = new AAStructureBindingModel(ssm, pdbFiles, seqs, null)
     {
       @Override
       public String[] getPdbFile()
@@ -140,6 +139,12 @@ public class AAStructureBindingModelTest
       public void highlightAtoms(List<AtomSpec> atoms)
       {
       }
+
+      @Override
+      public List<String> getChainNames()
+      {
+        return null;
+      }
     };
   }
 
index 69675f7..77a023f 100644 (file)
@@ -22,6 +22,7 @@ package jalview.util;
 
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertNull;
+import static org.testng.AssertJUnit.assertSame;
 
 import java.awt.Color;
 
@@ -132,4 +133,27 @@ public class ColorUtilsTest
             .getGraduatedColour(40f, 10f, minColour, 10f, maxColour);
     assertEquals(minColour, col);
   }
+
+  @Test(groups = { "Functional" })
+  public void testBleachColour()
+  {
+    Color colour = new Color(155, 105, 55);
+    assertSame(colour, ColorUtils.bleachColour(colour, 0));
+    assertEquals(Color.WHITE, ColorUtils.bleachColour(colour, 1));
+    assertEquals(Color.WHITE, ColorUtils.bleachColour(colour, 2));
+    assertEquals(new Color(175, 135, 95),
+            ColorUtils.bleachColour(colour, 0.2f));
+    assertEquals(new Color(225, 210, 195),
+            ColorUtils.bleachColour(colour, 0.7f));
+
+    /*
+     * and some 'negative fade'
+     */
+    assertEquals(Color.BLACK, ColorUtils.bleachColour(colour, -1));
+    assertEquals(Color.BLACK, ColorUtils.bleachColour(colour, -2));
+    assertEquals(new Color(124, 84, 44),
+            ColorUtils.bleachColour(colour, -0.2f));
+    assertEquals(new Color(46, 31, 16), // with rounding down
+            ColorUtils.bleachColour(colour, -0.7f));
+  }
 }
index 9aab66c..b71c270 100644 (file)
@@ -188,4 +188,16 @@ public class ComparisonTest
     assertTrue(Comparison.isNucleotideSequence("a A-g.GcCtTuU", true));
     assertFalse(Comparison.isNucleotideSequence("a A-g.GcCtTuU", false));
   }
+
+  @Test(groups = { "Functional" })
+  public void testIsSameResidue()
+  {
+    assertTrue(Comparison.isSameResidue('a', 'a', false));
+    assertTrue(Comparison.isSameResidue('a', 'a', true));
+    assertTrue(Comparison.isSameResidue('A', 'a', false));
+    assertTrue(Comparison.isSameResidue('a', 'A', false));
+
+    assertFalse(Comparison.isSameResidue('a', 'A', true));
+    assertFalse(Comparison.isSameResidue('A', 'a', true));
+  }
 }
index d1c24d1..1c68a71 100644 (file)
@@ -74,9 +74,16 @@ public class DBRefUtilsTest
     assertSame(ref2, selected[0]);
     assertSame(ref3, selected[1]);
 
-    sources = new String[] { "Uniprot", "EMBLCDS" };
+    sources = new String[] { "EMBLCDS" };
     selected = DBRefUtils.selectRefs(dbrefs, sources);
     assertNull(selected);
+
+    sources = new String[] { "embl", "uniprot" };
+    selected = DBRefUtils.selectRefs(dbrefs, sources);
+    assertEquals(3, selected.length);
+    assertSame(ref1, selected[0]);
+    assertSame(ref2, selected[1]);
+    assertSame(ref3, selected[2]);
   }
 
   /**
@@ -99,6 +106,11 @@ public class DBRefUtilsTest
     assertEquals("UNIPROTKB/SWISS-CHEESE",
             DBRefUtils.getCanonicalName("UNIPROTKB/SWISS-CHEESE"));
     assertEquals("ENSEMBL", DBRefUtils.getCanonicalName("Ensembl"));
+
+    // these are not 'known' to Jalview
+    assertEquals("PFAM", DBRefUtils.getCanonicalName("PFAM"));
+    assertEquals("pfam", DBRefUtils.getCanonicalName("pfam"));
+
   }
 
   @Test(groups = { "Functional" })
diff --git a/test/jalview/util/FormatTest.java b/test/jalview/util/FormatTest.java
new file mode 100644 (file)
index 0000000..d957b7c
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * 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.util;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.Test;
+
+public class FormatTest
+{
+  @Test(groups = "Functional")
+  public void testAppendPercentage()
+  {
+    StringBuilder sb = new StringBuilder();
+    Format.appendPercentage(sb, 123.436f, 0);
+    assertEquals(sb.toString(), "123");
+
+    sb.setLength(0);
+    Format.appendPercentage(sb, 123.536f, 0);
+    assertEquals(sb.toString(), "124");
+
+    sb.setLength(0);
+    Format.appendPercentage(sb, 799.536f, 0);
+    assertEquals(sb.toString(), "800");
+
+    sb.setLength(0);
+    Format.appendPercentage(sb, 123.436f, 1);
+    assertEquals(sb.toString(), "123.4");
+
+    sb.setLength(0);
+    Format.appendPercentage(sb, 123.436f, 2);
+    assertEquals(sb.toString(), "123.44");
+
+    sb.setLength(0);
+    Format.appendPercentage(sb, 123.436f, 3);
+    assertEquals(sb.toString(), "123.436");
+
+    sb.setLength(0);
+    Format.appendPercentage(sb, 123.436f, 4);
+    assertEquals(sb.toString(), "123.4360");
+  }
+
+  @Test(groups = "Functional")
+  public void testForm_float()
+  {
+    Format f = new Format("%3.2f");
+    assertEquals(f.form(123f), "123.00");
+    assertEquals(f.form(123.1f), "123.10");
+    assertEquals(f.form(123.12f), "123.12");
+    assertEquals(f.form(123.124f), "123.12");
+    assertEquals(f.form(123.125f), "123.13");
+    assertEquals(f.form(123.126f), "123.13");
+
+    f = new Format("%3.0f");
+    assertEquals(f.form(123f), "123.");
+    assertEquals(f.form(12f), "12.");
+    assertEquals(f.form(123.4f), "123.");
+    assertEquals(f.form(123.5f), "124.");
+    assertEquals(f.form(123.6f), "124.");
+    assertEquals(f.form(129.6f), "130.");
+  }
+
+  @Test(groups = "Functional")
+  public void testRepeat()
+  {
+    assertEquals(Format.repeat('a', 3), "aaa");
+    assertEquals(Format.repeat('b', 0), "");
+    assertEquals(Format.repeat('c', -1), "");
+  }
+}
index 655aa2a..6d04661 100644 (file)
@@ -33,8 +33,8 @@ import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.ColumnSelection;
-import jalview.datamodel.SearchResults;
-import jalview.datamodel.SearchResults.Match;
+import jalview.datamodel.SearchResultMatchI;
+import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
@@ -81,9 +81,9 @@ public class MappingUtilsTest
     /*
      * Check protein residue 12 maps to codon 5-7, 13 to codon 8-10
      */
-    SearchResults sr = MappingUtils.buildSearchResults(aseq1, 12, acfList);
+    SearchResultsI sr = MappingUtils.buildSearchResults(aseq1, 12, acfList);
     assertEquals(1, sr.getResults().size());
-    Match m = sr.getResults().get(0);
+    SearchResultMatchI m = sr.getResults().get(0);
     assertEquals(seq1.getDatasetSequence(), m.getSequence());
     assertEquals(5, m.getStart());
     assertEquals(7, m.getEnd());
@@ -134,9 +134,9 @@ public class MappingUtilsTest
     /*
      * Check protein residue 8 maps to [6, 8, 9]
      */
-    SearchResults sr = MappingUtils.buildSearchResults(aseq1, 8, acfList);
+    SearchResultsI sr = MappingUtils.buildSearchResults(aseq1, 8, acfList);
     assertEquals(2, sr.getResults().size());
-    Match m = sr.getResults().get(0);
+    SearchResultMatchI m = sr.getResults().get(0);
     assertEquals(seq1.getDatasetSequence(), m.getSequence());
     assertEquals(6, m.getStart());
     assertEquals(6, m.getEnd());
diff --git a/test/jalview/util/PlatformTest.java b/test/jalview/util/PlatformTest.java
new file mode 100644 (file)
index 0000000..e9e4628
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * 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.util;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.awt.Button;
+import java.awt.Event;
+import java.awt.event.MouseEvent;
+
+import org.testng.annotations.Test;
+
+public class PlatformTest
+{
+  Button b = new Button();
+
+  /**
+   * isControlDown for Mac should answer true for Meta-down, but not for right
+   * mouse (popup trigger)
+   */
+  @Test(groups = "Functional")
+  public void testIsControlDown_mac()
+  {
+    int clickCount = 1;
+    boolean isPopupTrigger = false;
+    int buttonNo = MouseEvent.BUTTON1;
+    boolean mac = true;
+
+    int mods = 0;
+    // not concerned with MouseEvent id, when, x, y, xAbs, yAbs values
+    assertFalse(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+
+    mods = Event.CTRL_MASK;
+    assertFalse(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+
+    mods = Event.META_MASK;
+    assertTrue(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+
+    isPopupTrigger = true;
+    assertFalse(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+
+    isPopupTrigger = false;
+    buttonNo = MouseEvent.BUTTON2;
+    mods = 0;
+    assertFalse(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+  }
+
+  /**
+   * If not a Mac, we only care whether CTRL_MASK modifier is set on the mouse
+   * event
+   */
+  @Test(groups = "Functional")
+  public void testIsControlDown_notMac()
+  {
+    int clickCount = 1;
+    boolean isPopupTrigger = false;
+    int buttonNo = MouseEvent.BUTTON1;
+    boolean mac = false;
+
+    int mods = 0;
+    // not concerned with MouseEvent id, when, x, y, xAbs, yAbs values
+    assertFalse(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+
+    mods = Event.CTRL_MASK;
+    assertTrue(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+
+    mods = Event.CTRL_MASK | Event.SHIFT_MASK | Event.ALT_MASK;
+    clickCount = 2;
+    buttonNo = 2;
+    isPopupTrigger = true;
+    assertTrue(Platform.isControlDown(new MouseEvent(b, 0, 0L, mods, 0, 0,
+            0, 0, clickCount, isPopupTrigger, buttonNo), mac));
+  }
+}
diff --git a/test/jalview/util/SparseCountTest.java b/test/jalview/util/SparseCountTest.java
new file mode 100644 (file)
index 0000000..f4a0c97
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * 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.util;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import org.testng.annotations.Test;
+public class SparseCountTest
+{
+  @Test(groups = "Functional")
+  public void testAdd()
+  {
+    SparseCount p = new SparseCount(8);
+    p.add('a', 1);
+    p.add('b', 2);
+    p.add('a', 3);
+    p.add('b', -4);
+    assertEquals(p.size(), 2);
+    assertEquals(p.get('a'), 4);
+    assertEquals(p.get('b'), -2);
+  }
+
+  @Test(groups = "Functional")
+  public void testPut()
+  {
+    SparseCount p = new SparseCount(8);
+    p.put('a', 3);
+    p.add('b', 2);
+    p.put('b', 4);
+    assertEquals(p.size(), 2);
+    assertEquals(p.get('a'), 3);
+    assertEquals(p.get('b'), 4);
+  }
+
+  /**
+   * Test handling overflow of short by switching to counting ints
+   */
+  @Test(groups = "Functional")
+  public void testOverflow()
+  {
+    SparseCount p = new SparseCount(8);
+    p.put('a', Short.MAX_VALUE - 1);
+    p.add('a', 1);
+    assertFalse(p.isUsingInt());
+    p.add('a', 1);
+    assertTrue(p.isUsingInt());
+  }
+
+  /**
+   * Test handling underflow of short by switching to counting ints
+   */
+  @Test(groups = "Functional")
+  public void testUnderflow()
+  {
+    SparseCount p = new SparseCount(8);
+    p.put('a', Short.MIN_VALUE + 1);
+    p.add('a', -1);
+    assertFalse(p.isUsingInt());
+    p.add('a', -1);
+    assertTrue(p.isUsingInt());
+  }
+
+  @Test(groups = "Functional")
+  public void testKeyAt_ValueAt()
+  {
+    SparseCount p = new SparseCount(8);
+    p.put('W', 12);
+    p.put('K', 9);
+    p.put('R', 6);
+    assertEquals(p.size(), 3);
+    assertEquals(p.keyAt(0), 'K');
+    assertEquals(p.valueAt(0), 9);
+    assertEquals(p.keyAt(1), 'R');
+    assertEquals(p.valueAt(1), 6);
+    assertEquals(p.keyAt(2), 'W');
+    assertEquals(p.valueAt(2), 12);
+  }
+
+}
diff --git a/test/jalview/util/UrlLinkTest.java b/test/jalview/util/UrlLinkTest.java
new file mode 100644 (file)
index 0000000..f219fb8
--- /dev/null
@@ -0,0 +1,402 @@
+/*
+ * 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.util;
+
+import static jalview.util.UrlConstants.DB_ACCESSION;
+import static jalview.util.UrlConstants.SEQUENCE_ID;
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertNull;
+import static org.testng.AssertJUnit.assertTrue;
+
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
+import jalview.datamodel.Sequence;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.Test;
+
+public class UrlLinkTest
+{
+
+  final static String DB = "Test";
+
+  final static String URL_PREFIX = "http://www.jalview.org/";
+
+  final static String URL_SUFFIX = "/blah";
+
+  final static String SEP = "|";
+
+  final static String DELIM = "$";
+
+  final static String REGEX_NESTED = "=/^(?:Label:)?(?:(?:gi\\|(\\d+))|([^:]+))/=";
+  
+  final static String REGEX_RUBBISH = "=/[0-9]++/=";
+
+  /**
+   * Test URL link creation when the input string has no regex
+   */
+  @Test(groups = { "Functional" })
+  public void testUrlLinkCreationNoRegex()
+  {
+    // SEQUENCE_ID
+    UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+            + DELIM + URL_SUFFIX);
+    assertEquals(DB, ul.getTarget());
+    assertEquals(DB, ul.getLabel());
+    assertEquals(URL_PREFIX, ul.getUrl_prefix());
+    assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+    assertTrue(ul.isDynamic());
+    assertFalse(ul.usesDBAccession());
+    assertNull(ul.getRegexReplace());
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    // DB_ACCESSION
+    ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION + DELIM
+            + URL_SUFFIX);
+    assertEquals(DB, ul.getTarget());
+    assertEquals(DB, ul.getLabel());
+    assertEquals(URL_PREFIX, ul.getUrl_prefix());
+    assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+    assertTrue(ul.isDynamic());
+    assertTrue(ul.usesDBAccession());
+    assertNull(ul.getRegexReplace());
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    // Not dynamic
+    ul = new UrlLink(DB + SEP + URL_PREFIX + URL_SUFFIX.substring(1));
+    assertEquals(DB, ul.getTarget());
+    assertEquals(DB, ul.getLabel());
+    assertEquals(URL_PREFIX + URL_SUFFIX.substring(1), ul.getUrl_prefix());
+    assertFalse(ul.isDynamic());
+    assertFalse(ul.usesDBAccession());
+    assertNull(ul.getRegexReplace());
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+  }
+
+  /**
+   * Test URL link creation when the input string has regex
+   */
+  @Test(groups = { "Functional" })
+  public void testUrlLinkCreationWithRegex()
+  {
+    // SEQUENCE_ID
+    UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+            + REGEX_NESTED + DELIM + URL_SUFFIX);
+    assertEquals(DB, ul.getTarget());
+    assertEquals(DB, ul.getLabel());
+    assertEquals(URL_PREFIX, ul.getUrl_prefix());
+    assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+    assertTrue(ul.isDynamic());
+    assertFalse(ul.usesDBAccession());
+    assertEquals(REGEX_NESTED.substring(2, REGEX_NESTED.length() - 2),
+            ul.getRegexReplace());
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    // DB_ACCESSION
+    ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION
+            + REGEX_NESTED + DELIM + URL_SUFFIX);
+    assertEquals(DB, ul.getTarget());
+    assertEquals(DB, ul.getLabel());
+    assertEquals(URL_PREFIX, ul.getUrl_prefix());
+    assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+    assertTrue(ul.isDynamic());
+    assertTrue(ul.usesDBAccession());
+    assertEquals(REGEX_NESTED.substring(2, REGEX_NESTED.length() - 2),
+            ul.getRegexReplace());
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    // invalid regex
+    ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION
+            + REGEX_RUBBISH + DELIM + URL_SUFFIX);
+    assertEquals(DB, ul.getTarget());
+    assertEquals(DB, ul.getLabel());
+    assertEquals(URL_PREFIX, ul.getUrl_prefix());
+    assertEquals(URL_SUFFIX, ul.getUrl_suffix());
+    assertTrue(ul.isDynamic());
+    assertTrue(ul.usesDBAccession());
+    assertEquals(REGEX_RUBBISH.substring(2, REGEX_RUBBISH.length() - 2),
+            ul.getRegexReplace());
+    assertFalse(ul.isValid());
+    assertEquals(
+            "Invalid Regular Expression : '"
+                    + REGEX_RUBBISH.substring(2, REGEX_RUBBISH.length() - 2)
+                    + "'\n",
+            ul.getInvalidMessage());
+  }
+
+  /**
+   * Test construction of link by substituting sequence id or name
+   */
+  @Test(groups = { "Functional" })
+  public void testMakeUrlNoRegex()
+  {
+    // Single non-regex
+    UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+            + DELIM + URL_SUFFIX);
+    String idstring = "FER_CAPAA";
+    String[] urls = ul.makeUrls(idstring, true);
+
+    assertEquals(2, urls.length);
+    assertEquals(idstring, urls[0]);
+    assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+
+    urls = ul.makeUrls(idstring, false);
+
+    assertEquals(2, urls.length);
+    assertEquals(idstring, urls[0]);
+    assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+  }
+
+  /**
+   * Test construction of link by substituting sequence id or name using regular
+   * expression
+   */
+  @Test(groups = { "Functional" })
+  public void testMakeUrlWithRegex()
+  {
+    // Unused regex
+    UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION
+            + REGEX_NESTED + DELIM + URL_SUFFIX);
+    String idstring = "FER_CAPAA";
+    String[] urls = ul.makeUrls(idstring, true);
+
+    assertEquals(2, urls.length);
+    assertEquals(idstring, urls[0]);
+    assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    urls = ul.makeUrls(idstring, false);
+
+    assertEquals(2, urls.length);
+    assertEquals(idstring, urls[0]);
+    assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    // nested regex
+    idstring = "Label:gi|9234|pdb|102L|A";
+    urls = ul.makeUrls(idstring, true);
+
+    assertEquals(2, urls.length);
+    assertEquals("9234", urls[0]);
+    assertEquals(URL_PREFIX + "9234" + URL_SUFFIX, urls[1]);
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    urls = ul.makeUrls(idstring, false);
+
+    assertEquals(2, urls.length);
+    assertEquals("9234", urls[0]);
+    assertEquals(URL_PREFIX + "9234" + URL_SUFFIX, urls[1]);
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    // unmatched regex
+    idstring = "this does not match";
+    urls = ul.makeUrls(idstring, true);
+
+    assertEquals(2, urls.length);
+    assertEquals(idstring, urls[0]);
+    assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    urls = ul.makeUrls(idstring, false);
+
+    assertEquals(2, urls.length);
+    assertEquals(idstring, urls[0]);
+    assertEquals(URL_PREFIX + idstring + URL_SUFFIX, urls[1]);
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+
+    // empty idstring
+    idstring = "";
+    urls = ul.makeUrls(idstring, true);
+
+    assertNull(urls);
+
+    urls = ul.makeUrls(idstring, false);
+
+    assertEquals(2, urls.length);
+    assertEquals("", urls[0]);
+    assertEquals(URL_PREFIX + URL_SUFFIX, urls[1]);
+    assertTrue(ul.isValid());
+    assertNull(ul.getInvalidMessage());
+  }
+
+  /**
+   * Test creating links with null sequence
+   */
+  @Test(groups = { "Functional" })
+  public void testCreateLinksFromNullSequence()
+  {
+    UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+            + DELIM + URL_SUFFIX);
+
+    Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+    ul.createLinksFromSeq(null, linkset);
+
+    String key = DB + SEP + URL_PREFIX;
+    assertEquals(1, linkset.size());
+    assertTrue(linkset.containsKey(key));
+    assertEquals(linkset.get(key).get(0), DB);
+    assertEquals(linkset.get(key).get(1), DB);
+    assertEquals(linkset.get(key).get(2), null);
+    assertEquals(linkset.get(key).get(3), URL_PREFIX);
+  }
+
+  /**
+   * Test creating links with non-dynamic urlLink
+   */
+  @Test(groups = { "Functional" })
+  public void testCreateLinksForNonDynamic()
+  {
+    UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + URL_SUFFIX);
+
+    Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+    ul.createLinksFromSeq(null, linkset);
+
+    String key = DB + SEP + URL_PREFIX + URL_SUFFIX;
+    assertEquals(1, linkset.size());
+    assertTrue(linkset.containsKey(key));
+    assertEquals(linkset.get(key).get(0), DB);
+    assertEquals(linkset.get(key).get(1), DB);
+    assertEquals(linkset.get(key).get(2), null);
+    assertEquals(linkset.get(key).get(3), URL_PREFIX + URL_SUFFIX);
+  }
+
+  /**
+   * Test creating links
+   */
+  @Test(groups = { "Functional" })
+  public void testCreateLinksFromSequence()
+  {
+
+    // create list of links and list of DBRefs
+    List<String> links = new ArrayList<String>();
+    List<DBRefEntry> refs = new ArrayList<DBRefEntry>();
+
+    // links as might be added into Preferences | Connections dialog
+    links.add("EMBL-EBI Search | http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$"
+            + SEQUENCE_ID + "$");
+    links.add("UNIPROT | http://www.uniprot.org/uniprot/$" + DB_ACCESSION
+            + "$");
+    links.add("INTERPRO | http://www.ebi.ac.uk/interpro/entry/$"
+            + DB_ACCESSION + "$");
+
+    // make seq0 dbrefs
+    refs.add(new DBRefEntry(DBRefSource.UNIPROT, "1", "P83527"));
+    refs.add(new DBRefEntry("INTERPRO", "1", "IPR001041"));
+    refs.add(new DBRefEntry("INTERPRO", "1", "IPR006058"));
+    refs.add(new DBRefEntry("INTERPRO", "1", "IPR012675"));
+
+    Sequence seq0 = new Sequence("FER1", "AKPNGVL");
+
+    // add all the dbrefs to the sequence
+    seq0.addDBRef(refs.get(0));
+    seq0.addDBRef(refs.get(1));
+    seq0.addDBRef(refs.get(2));
+    seq0.addDBRef(refs.get(3));
+    seq0.createDatasetSequence();
+
+    // Test where link takes a sequence id as replacement
+    UrlLink ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + SEQUENCE_ID
+            + DELIM + URL_SUFFIX);
+
+    Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+    ul.createLinksFromSeq(seq0, linkset);
+
+    String key = seq0.getName() + SEP + URL_PREFIX + seq0.getName()
+            + URL_SUFFIX;
+    assertEquals(1, linkset.size());
+    assertTrue(linkset.containsKey(key));
+    assertEquals(linkset.get(key).get(0), DB);
+    assertEquals(linkset.get(key).get(1), DB);
+    assertEquals(linkset.get(key).get(2), seq0.getName());
+    assertEquals(linkset.get(key).get(3), URL_PREFIX + seq0.getName()
+            + URL_SUFFIX);
+
+    // Test where link takes a db annotation id and only has one dbref
+    ul = new UrlLink(links.get(1));
+    linkset = new LinkedHashMap<String, List<String>>();
+    ul.createLinksFromSeq(seq0, linkset);
+
+    key = "P83527|http://www.uniprot.org/uniprot/P83527";
+    assertEquals(1, linkset.size());
+    assertTrue(linkset.containsKey(key));
+    assertEquals(linkset.get(key).get(0), DBRefSource.UNIPROT);
+    assertEquals(linkset.get(key).get(1), DBRefSource.UNIPROT + SEP
+            + "P83527");
+    assertEquals(linkset.get(key).get(2), "P83527");
+    assertEquals(linkset.get(key).get(3),
+            "http://www.uniprot.org/uniprot/P83527");
+
+    // Test where link takes a db annotation id and has multiple dbrefs
+    ul = new UrlLink(links.get(2));
+    linkset = new LinkedHashMap<String, List<String>>();
+    ul.createLinksFromSeq(seq0, linkset);
+    assertEquals(3, linkset.size());
+
+    // check each link made it in correctly
+    key = "IPR001041|http://www.ebi.ac.uk/interpro/entry/IPR001041";
+    assertTrue(linkset.containsKey(key));
+    assertEquals(linkset.get(key).get(0), "INTERPRO");
+    assertEquals(linkset.get(key).get(1), "INTERPRO" + SEP + "IPR001041");
+    assertEquals(linkset.get(key).get(2), "IPR001041");
+    assertEquals(linkset.get(key).get(3),
+            "http://www.ebi.ac.uk/interpro/entry/IPR001041");
+
+    key = "IPR006058|http://www.ebi.ac.uk/interpro/entry/IPR006058";
+    assertTrue(linkset.containsKey(key));
+    assertEquals(linkset.get(key).get(0), "INTERPRO");
+    assertEquals(linkset.get(key).get(1), "INTERPRO" + SEP + "IPR006058");
+    assertEquals(linkset.get(key).get(2), "IPR006058");
+    assertEquals(linkset.get(key).get(3),
+            "http://www.ebi.ac.uk/interpro/entry/IPR006058");
+
+    key = "IPR012675|http://www.ebi.ac.uk/interpro/entry/IPR012675";
+    assertTrue(linkset.containsKey(key));
+    assertEquals(linkset.get(key).get(0), "INTERPRO");
+    assertEquals(linkset.get(key).get(1), "INTERPRO" + SEP + "IPR012675");
+    assertEquals(linkset.get(key).get(2), "IPR012675");
+    assertEquals(linkset.get(key).get(3),
+            "http://www.ebi.ac.uk/interpro/entry/IPR012675");
+
+    // Test where there are no matching dbrefs for the link
+    ul = new UrlLink(DB + SEP + URL_PREFIX + DELIM + DB_ACCESSION + DELIM
+            + URL_SUFFIX);
+    linkset = new LinkedHashMap<String, List<String>>();
+    ul.createLinksFromSeq(seq0, linkset);
+    assertTrue(linkset.isEmpty());
+  }
+
+}
index 9f62481..2067659 100644 (file)
@@ -119,11 +119,11 @@ public class DisorderAnnotExportImport
     {
       orig_alig.deleteAnnotation(aa);
     }
-    testAnnotationFileIO("Testing IUPred Annotation IO", orig_alig);
+    checkAnnotationFileIO("Testing IUPred Annotation IO", orig_alig);
 
   }
 
-  public static void testAnnotationFileIO(String testname, AlignmentI al)
+  static void checkAnnotationFileIO(String testname, AlignmentI al)
   {
     try
     {
index 8d26c45..3f67c4c 100644 (file)
@@ -387,8 +387,8 @@ public class SiftsClientTest
               testSeq, testPDBId, "A");
       String expectedMappingOutput = "\nSequence ⟷ Structure mapping details\n"
               + "Method: SIFTS\n\n"
-              + "P00221 :  1 - 97 Maps to \n"
-              + "1A70|A :  51 - 147\n\n"
+              + "P00221 :  51 - 147 Maps to \n"
+              + "1A70|A :  1 - 97\n\n"
               + "P00221 AAYKVTLVTPTGNVEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLD\n"
               + "       |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||\n"
               + "1A70|A AAYKVTLVTPTGNVEFQCPDDVYILDAAEEEGIDLPYSCRAGSCSSCAGKLKTGSLNQDDQSFLD\n\n"
@@ -449,7 +449,7 @@ public class SiftsClientTest
   }
 
   @Test(groups = { "Functional" })
-  public void getEntityByMostOptimalMatchedIdTest()
+  public void getEntityByMostOptimalMatchedIdTest1()
   {
     SiftsClient siftsClientX = null;
     PDBfile pdbFile;
@@ -472,4 +472,34 @@ public class SiftsClientTest
     Assert.assertEquals(entityD.getEntityId(), "D");
 
   }
+
+  @Test(groups = { "Functional" })
+  public void getEntityByMostOptimalMatchedIdTest2()
+  {
+    // This test is for a SIFTS file in which entity A should map to chain P for
+    // the given PDB Id. All the other chains shouldn't be mapped as there are
+    // no SIFTS entity records for them.
+    SiftsClient siftsClientX = null;
+    PDBfile pdbFile;
+    try
+    {
+      pdbFile = new PDBfile(false, false, false,
+              "test/jalview/io/3ucu.cif", AppletFormatAdapter.FILE);
+      siftsClientX = new SiftsClient(pdbFile);
+    } catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+    Entity entityA = siftsClientX.getEntityByMostOptimalMatchedId("P");
+    Entity entityP = siftsClientX.getEntityByMostOptimalMatchedId("A");
+    Entity entityR = siftsClientX.getEntityByMostOptimalMatchedId("R");
+    Assert.assertEquals(entityA.getEntityId(), "A");
+    Assert.assertNotEquals(entityR, "A");
+    Assert.assertNotEquals(entityP, "A");
+    Assert.assertNotEquals(entityR, "R");
+    Assert.assertNotEquals(entityP, "P");
+    Assert.assertNull(entityR);
+    Assert.assertNull(entityP);
+
+  }
 }
index fc799bb..3cfc2bb 100755 (executable)
@@ -1245,7 +1245,7 @@ and any path to a file to save to the file]]></string>
                                                                <string><![CDATA[664]]></string>
                                                        </property>
                                                        <property name="sourceName">
-                                                               <string><![CDATA[Jmol-14.2.14_2015.06.11.jar]]></string>
+                                                               <string><![CDATA[Jmol-14.6.4_2016.10.26.jar]]></string>
                                                        </property>
                                                        <property name="overrideUnixPermissions">
                                                                <boolean>false</boolean>
@@ -1263,7 +1263,7 @@ and any path to a file to save to the file]]></string>
                                                                <boolean>true</boolean>
                                                        </property>
                                                        <property name="destinationName">
-                                                               <string><![CDATA[Jmol-14.2.14_2015.06.11.jar]]></string>
+                                                               <string><![CDATA[Jmol-14.6.4_2016.10.26.jar]]></string>
                                                        </property>
                                                        <property name="fileSize">
                                                                <long>5417196</long>
@@ -3846,7 +3846,7 @@ Press "Done" to quit the installer.]]></string>
                                                                                                <boolean>true</boolean>
                                                                                        </property>
                                                                                        <property name="bundledVM">
-                                                                                               <string><![CDATA[OracleJRE8u5_Macosx.vm]]></string>
+                                                                                               <string><![CDATA[OracleJRE180u92_macosx.vm]]></string>
                                                                                        </property>
                                                                                        <property name="withoutVmSearchOption">
                                                                                                <short>10</short>
@@ -3883,7 +3883,7 @@ Press "Done" to quit the installer.]]></string>
                                                                                                <boolean>true</boolean>
                                                                                        </property>
                                                                                        <property name="bundledVM">
-                                                                                               <string><![CDATA[SunJRE170_03Win32.vm]]></string>
+                                                                                               <string><![CDATA[OracleJRE8u92_windows(x86).vm]]></string>
                                                                                        </property>
                                                                                        <property name="withoutVmSearchOption">
                                                                                                <short>10</short>
@@ -3954,10 +3954,10 @@ Press "Done" to quit the installer.]]></string>
                                                                                                <boolean>true</boolean>
                                                                                        </property>
                                                                                        <property name="buildWithVM">
-                                                                                               <boolean>true</boolean>
+                                                                                               <boolean>false</boolean>
                                                                                        </property>
                                                                                        <property name="bundledVM">
-                                                                                               <string><![CDATA[JRE16_16002HPUX11PA-RISC.vm]]></string>
+                                                                                               <string><![CDATA[JRE16_16010HPUXPA-RISC.vm]]></string>
                                                                                        </property>
                                                                                        <property name="withoutVmSearchOption">
                                                                                                <short>10</short>
@@ -3994,7 +3994,7 @@ Press "Done" to quit the installer.]]></string>
                                                                                                <boolean>true</boolean>
                                                                                        </property>
                                                                                        <property name="bundledVM">
-                                                                                               <string><![CDATA[ORACLEJRE7u60_linux32.vm]]></string>
+                                                                                               <string><![CDATA[OracleJRE180u92_Linux32.vm]]></string>
                                                                                        </property>
                                                                                        <property name="withoutVmSearchOption">
                                                                                                <short>10</short>
@@ -4102,7 +4102,7 @@ Press "Done" to quit the installer.]]></string>
                                                                                                <boolean>true</boolean>
                                                                                        </property>
                                                                                        <property name="bundledVM">
-                                                                                               <string><![CDATA[ORACLEJRE7u60_linux32.vm]]></string>
+                                                                                               <string><![CDATA[OracleJRE180u92_Linux32.vm]]></string>
                                                                                        </property>
                                                                                        <property name="withoutVmSearchOption">
                                                                                                <short>10</short>
@@ -4173,7 +4173,7 @@ Press "Done" to quit the installer.]]></string>
                                                                                                <boolean>true</boolean>
                                                                                        </property>
                                                                                        <property name="bundledVM">
-                                                                                               <string><![CDATA[OracleJRE8u5_windows(x64).vm]]></string>
+                                                                                               <string><![CDATA[OracleJRE180u92_windows(x64).vm]]></string>
                                                                                        </property>
                                                                                        <property name="withoutVmSearchOption">
                                                                                                <short>10</short>
@@ -5270,7 +5270,7 @@ Press "Done" to quit the installer.]]></string>
                                        </method>
                                        <method name="put">
                                                <string><![CDATA[com.zerog.ia.installer.options.valid.vm.list]]></string>
-                                               <string><![CDATA[1.7+]]></string>
+                                               <string><![CDATA[1.8+]]></string>
                                        </method>
                                        <method name="put">
                                                <string><![CDATA[com.zerog.ia.project.build.last.date]]></string>
@@ -5366,7 +5366,7 @@ Press "Done" to quit the installer.]]></string>
                                        </method>
                                        <method name="put">
                                                <string><![CDATA[com.zerog.ia.installer.options.platform.macosx.vm.version]]></string>
-                                               <string><![CDATA[1.7+]]></string>
+                                               <string><![CDATA[1.8+]]></string>
                                        </method>
                                        <method name="put">
                                                <string><![CDATA[com.zerog.ia.build.platform.java.novm]]></string>