Merge branch 'develop' into task/JAL-2196pdbeProperties
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Wed, 5 Oct 2016 15:17:59 +0000 (16:17 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Wed, 5 Oct 2016 15:17:59 +0000 (16:17 +0100)
Conflicts:
src/jalview/datamodel/PDBEntry.java
test/jalview/ws/dbsources/UniprotTest.java

142 files changed:
RELEASE
build.xml
examples/exampleFeatures.txt
examples/groovy/featureCounter.groovy
examples/plantfdx.fa
examples/plantfdx.features
examples/testdata/jal-2005.fa [new file with mode: 0644]
examples/testdata/jal-2005.jvf [new file with mode: 0644]
examples/uniref50.fa
help/help.jhm
help/helpTOC.xml
help/html/calculations/consensus.html
help/html/calculations/referenceseq.html
help/html/calculations/sorting.html
help/html/calculations/structureconsensus.html
help/html/colourSchemes/annotationColouring.html
help/html/features/annotation.html
help/html/features/columnFilterByAnnotation.html
help/html/features/ensemblsequencefetcher.html [new file with mode: 0644]
help/html/features/featuresettings.html
help/html/features/groovy.html
help/html/features/selectfetchdb.gif
help/html/features/seqfetch.html
help/html/features/siftsmapping.html
help/html/features/structurechooser.html
help/html/features/uniprotsequencefetcher.html
help/html/features/viewingpdbs.html
help/html/groovy/featureCounter.html [new file with mode: 0644]
help/html/menus/alwannotation.html
help/html/menus/alwannotationpanel.html
help/html/menus/index.html
help/html/menus/popupMenu.html
help/html/na/index.html
help/html/releases.html
help/html/webServices/newsreader.html
help/html/whatsNew.html
resources/embl_mapping.xml
resources/fts/pdb_data_columns.txt
resources/lang/Messages.properties
resources/lang/Messages_es.properties
src/ext/edu/ucsf/rbvi/strucviz2/ChimeraManager.java
src/jalview/analysis/AlignmentUtils.java
src/jalview/analysis/Conservation.java
src/jalview/analysis/CrossRef.java
src/jalview/analysis/Rna.java
src/jalview/analysis/StructureFrequency.java
src/jalview/api/AlignViewportI.java
src/jalview/appletgui/APopupMenu.java
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/AlignmentPanel.java
src/jalview/appletgui/AnnotationColourChooser.java
src/jalview/appletgui/AnnotationColumnChooser.java
src/jalview/appletgui/AnnotationRowFilter.java
src/jalview/appletgui/AppletJmol.java
src/jalview/appletgui/TreeCanvas.java
src/jalview/bin/Cache.java
src/jalview/bin/Jalview.java
src/jalview/bin/JalviewLite.java
src/jalview/datamodel/Alignment.java
src/jalview/datamodel/ColumnSelection.java
src/jalview/datamodel/PDBEntry.java
src/jalview/datamodel/Sequence.java
src/jalview/datamodel/SequenceGroup.java
src/jalview/datamodel/SequenceI.java
src/jalview/datamodel/xdb/embl/EmblFile.java
src/jalview/ext/ensembl/EnsemblGene.java
src/jalview/ext/ensembl/EnsemblRestClient.java
src/jalview/ext/ensembl/EnsemblSeqProxy.java
src/jalview/ext/jmol/JalviewJmolBinding.java
src/jalview/ext/jmol/JmolParser.java
src/jalview/ext/so/SequenceOntology.java
src/jalview/fts/core/FTSRestClient.java
src/jalview/fts/core/GFTSPanel.java
src/jalview/fts/service/pdb/PDBFTSPanel.java
src/jalview/fts/service/uniprot/UniprotFTSPanel.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AlignViewport.java
src/jalview/gui/AlignmentPanel.java
src/jalview/gui/AnnotationColourChooser.java
src/jalview/gui/AnnotationColumnChooser.java
src/jalview/gui/AnnotationLabels.java
src/jalview/gui/AnnotationPanel.java
src/jalview/gui/AnnotationRowFilter.java
src/jalview/gui/AppJmol.java
src/jalview/gui/Desktop.java
src/jalview/gui/JDatabaseTree.java
src/jalview/gui/Jalview2XML.java
src/jalview/gui/Jalview2XML_V1.java
src/jalview/gui/PopupMenu.java
src/jalview/gui/StructureChooser.java
src/jalview/gui/TreeCanvas.java
src/jalview/gui/VamsasApplication.java
src/jalview/io/AnnotationFile.java
src/jalview/io/AppletFormatAdapter.java
src/jalview/io/PDBFeatureSettings.java
src/jalview/io/StructureFile.java
src/jalview/io/gff/SequenceOntologyFactory.java
src/jalview/io/gff/SequenceOntologyLite.java
src/jalview/io/vamsas/DatastoreRegistry.java
src/jalview/javascript/JSFunctionExec.java
src/jalview/javascript/MouseOverStructureListener.java
src/jalview/jbgui/GStructureChooser.java
src/jalview/renderer/AnnotationRenderer.java
src/jalview/schemes/ResidueProperties.java
src/jalview/schemes/TCoffeeColourScheme.java
src/jalview/structure/StructureSelectionManager.java
src/jalview/util/DBRefUtils.java
src/jalview/viewmodel/AlignmentViewport.java
src/jalview/workers/ConservationThread.java
src/jalview/ws/DBRefFetcher.java
src/jalview/ws/dbsources/EmblXmlSource.java
src/jalview/ws/dbsources/Pdb.java
src/jalview/ws/dbsources/Uniprot.java
src/jalview/ws/ebi/EBIFetchClient.java
test/MCview/PDBfileTest.java
test/jalview/analysis/AlignmentUtilsTests.java
test/jalview/analysis/CrossRefTest.java
test/jalview/analysis/RnaTest.java
test/jalview/commands/EditCommandTest.java
test/jalview/datamodel/AlignmentTest.java
test/jalview/datamodel/ColumnSelectionTest.java
test/jalview/datamodel/PDBEntryTest.java
test/jalview/datamodel/SequenceTest.java
test/jalview/datamodel/xdb/embl/EmblEntryTest.java
test/jalview/datamodel/xdb/embl/EmblFileTest.java
test/jalview/datamodel/xdb/embl/EmblTestHelper.java
test/jalview/ext/jmol/JmolParserTest.java
test/jalview/ext/jmol/JmolVsJalviewPDBParserEndToEndTest.java
test/jalview/gui/AlignViewportTest.java
test/jalview/gui/AnnotationChooserTest.java
test/jalview/gui/JAL1353bugdemo.java
test/jalview/gui/StructureChooserTest.java
test/jalview/io/AnnotatedPDBFileInputTest.java
test/jalview/io/AnnotationFileIOTest.java
test/jalview/io/JSONFileTest.java
test/jalview/io/StockholmFileTest.java
test/jalview/schemes/DnaCodonTests.java
test/jalview/structure/StructureSelectionManagerTest.java
test/jalview/ws/PDBSequenceFetcherTest.java
test/jalview/ws/dbsources/UniprotTest.java
test/jalview/ws/seqfetcher/DbRefFetcherTest.java
test/jalview/ws/sifts/SiftsClientTest.java

diff --git a/RELEASE b/RELEASE
index 6cd9254..c29c5d5 100644 (file)
--- a/RELEASE
+++ b/RELEASE
@@ -1,2 +1,2 @@
-jalview.release=Release_2_9_0b1_Branch
-jalview.version=2.9.0b2
+jalview.release=Release_2_10_Branch
+jalview.version=2.10.0
index 7feacfb..d8f12e0 100755 (executable)
--- a/build.xml
+++ b/build.xml
     </testng>
   </target>
 
-  <target name="buildindices" depends="init, prepare,linkcheck" unless="help.uptodate">
+  <target name="buildindices" depends="init, prepare" unless="help.uptodate">
     <java classname="com.sun.java.help.search.Indexer" classpathref="build.classpath" fork="true" dir="${outputDir}/${helpDir}">
       <arg line="html" />
     </java>
   </axis-wsdl2java>
 </target>
 
-<target name="makedist" depends="build, buildPropertiesFile, buildindices">
+<target name="makedist" depends="build, buildPropertiesFile, linkcheck, buildindices">
   <!-- make the package jar if not already existing -->
   <mkdir dir="${packageDir}" />
   <!-- clean dir if it already existed -->
 
 <target name="compileApplet" depends="init,clean">
   <mkdir dir="${outputDir}" />
-  <javac source="${javac.source}" target="${javac.target}" srcdir="${sourceDir}" destdir="${outputDir}" debug="${javac.debug}" classpathref="jalviewlite.deps" includes="jalview/appletgui/**" excludes="ext/**,gui/**,jbgui/**,MCview/**,org/**,vamsas/**,jalview/ext/rbvi/**,jalview/ext/paradise/**,jalview/ext/ensembl/**,jalview/ext/so" />
+  <javac source="${javac.source}" target="${javac.target}" srcdir="${sourceDir}" destdir="${outputDir}" debug="${javac.debug}" classpathref="jalviewlite.deps" includes="jalview/appletgui/**" excludes="ext/**,gui/**,jbgui/**,MCview/**,org/**,vamsas/**,jalview/ext/rbvi/**,jalview/ext/paradise/**,jalview/ext/ensembl/**,jalview/ext/so/**" />
 </target>
 
 <target name="packageApplet" depends="compileApplet, buildPropertiesFile">
     </packageset>
   </javadoc>
 </target>
-<target name="linkcheck">
-  <!-- finally, publish the help files -->
+<target name="linkcheck" depends="init,prepare">
   <javac srcdir="utils" destdir="utils" includes="HelpLinksChecker.java"/>
   <java fork="true" dir="${helpDir}" classpath="utils" classname="HelpLinksChecker" failonerror="true">
     <arg file="${helpDir}"/>
index c0098a9..2de9817 100755 (executable)
@@ -79,12 +79,12 @@ Iron-sulfur (2Fe-2S)        FER_BRANA       -1      47      47      METAL
 Iron-sulfur (2Fe-2S)   FER_BRANA       -1      77      77      METAL
 <html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_8</a></html>     FER_BRANA       -1      8       83      Pfam
 Ferredoxin_fold Status: True Positive  FER_BRANA       -1      2       96      Cath
-Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      91      91      METAL
-Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      96      96      METAL
-Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      99      99      METAL
-Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      129     129     METAL
-<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_13</a></html>   FER2_ARATH      -1      60      135     Pfam
-Ferredoxin_fold Status: True Positive  FER2_ARATH      -1      50      145     Cath
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      91      91      METAL
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      96      96      METAL
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      99      99      METAL
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      129     129     METAL
+<html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_13</a></html>   FER1_ARATH      -1      60      135     Pfam
+Ferredoxin_fold Status: True Positive  FER1_ARATH      -1      50      145     Cath
 <html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_11</a></html>   Q93Z60_ARATH    -1      60      118     Pfam
 Ferredoxin_fold Status: True Positive  Q93Z60_ARATH    -1      52      118     Cath
 Iron-sulfur (2Fe-2S)   FER1_MAIZE      -1      91      91      METAL
@@ -127,13 +127,13 @@ STARTGROUP        netphos
 <html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00221&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 112_11</a></html>     FER1_SPIOL      -1      112     112     PHOSPHORYLATION (S)
 <html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00221&amp;service=NetPhos-2.0">PHOSPHORYLATION (T) 139_13</a></html>     FER1_SPIOL      -1      139     139     PHOSPHORYLATION (T)
 <html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00221&amp;service=NetPhos-2.0">PHOSPHORYLATION (Y) 73_7</a></html>       FER1_SPIOL      -1      73      73      PHOSPHORYLATION (Y)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 19_1</a></html>   FER1_ARATH      -1      19      19      PHOSPHORYLATION (S)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 24_2</a></html>   FER1_ARATH      -1      24      24      PHOSPHORYLATION (S)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 90_9</a></html>   FER1_ARATH      -1      90      90      PHOSPHORYLATION (S)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 107_10</a></html> FER1_ARATH      -1      107     107     PHOSPHORYLATION (S)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 114_11</a></html> FER1_ARATH      -1      114     114     PHOSPHORYLATION (S)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (T) 141_14</a></html> FER1_ARATH      -1      141     141     PHOSPHORYLATION (T)
-<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER1_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (Y) 75_7</a></html>   FER1_ARATH      -1      75      75      PHOSPHORYLATION (Y)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 19_1</a></html>   FER2_ARATH      -1      19      19      PHOSPHORYLATION (S)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 24_2</a></html>   FER2_ARATH      -1      24      24      PHOSPHORYLATION (S)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 90_9</a></html>   FER2_ARATH      -1      90      90      PHOSPHORYLATION (S)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 107_10</a></html> FER2_ARATH      -1      107     107     PHOSPHORYLATION (S)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 114_11</a></html> FER2_ARATH      -1      114     114     PHOSPHORYLATION (S)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (T) 141_14</a></html> FER2_ARATH      -1      141     141     PHOSPHORYLATION (T)
+<html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=FER2_ARATH&amp;service=NetPhos-2.0">PHOSPHORYLATION (Y) 75_7</a></html>   FER2_ARATH      -1      75      75      PHOSPHORYLATION (Y)
 <html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00227&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 38_3</a></html>       FER_BRANA       -1      38      38      PHOSPHORYLATION (S)
 <html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00227&amp;service=NetPhos-2.0">PHOSPHORYLATION (S) 62_6</a></html>       FER_BRANA       -1      62      62      PHOSPHORYLATION (S)
 <html>High confidence server. Only hits with scores over 0.8 are reported. <a href="http://www.cbs.dtu.dk/cgi-bin/proview/webface-link?seqid=P00227&amp;service=NetPhos-2.0">PHOSPHORYLATION (T) 89_8</a></html>       FER_BRANA       -1      89      89      PHOSPHORYLATION (T)
index a16d8bb..9059dd0 100644 (file)
@@ -1,3 +1,24 @@
+/*
+ * 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.
+ */
 import jalview.workers.FeatureCounterI;
 import jalview.workers.AlignmentAnnotationFactory;
 
index 1412a5a..f314c85 100644 (file)
@@ -35,17 +35,17 @@ IETHKEEELTA-
 EVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDVT
 IETHREEDMV--
 >FER1_ARATH/1-148
-----MASTALSSAIVGTSFIRRSPAPISLRSLPSANT-QSLFGLKS-GTARGGRVTAMATYKVKFITPEGEL
-EVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDVT
-IETHKEEDIV--
+----MASTALSSAIVSTSFLRRQQTPISLRSLPFANT-QSLFGLKS-STARGGRVTAMATYKVKFITPEGEQ
+EVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDVV
+IETHKEEAIM--
 >FER_BRANA/1-96
 ----------------------------------------------------------ATYKVKFITPEGEQ
 EVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDVT
 IETHKEEELV--
 >FER2_ARATH/1-148
-----MASTALSSAIVSTSFLRRQQTPISLRSLPFANT-QSLFGLKS-STARGGRVTAMATYKVKFITPEGEQ
-EVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDVV
-IETHKEEAIM--
+----MASTALSSAIVGTSFIRRSPAPISLRSLPSANT-QSLFGLKS-GTARGGRVTAMATYKVKFITPEGEL
+EVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDVT
+IETHKEEDIV--
 >Q93Z60_ARATH/1-118
 ----MASTALSSAIVSTSFLRRQQTPISLRSLPFANT-QSLFGLKS-STARGGRVTAMATYKVKFITPEGEQ
 EVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD--------------------
index 872dadc..6a2e058 100644 (file)
@@ -78,23 +78,23 @@ Iron-sulfur (2Fe-2S)        FER3_RAPSA      -1      77      77      METAL
 R -> K         FER3_RAPSA      -1      91      91      VARIANT
 M -> V         FER3_RAPSA      -1      95      95      VARIANT
 <html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_83</a></html>       FER3_RAPSA      -1      8       83      Pfam
-Chloroplast    FER1_ARATH      -1      1       52      TRANSIT
-Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      91      91      METAL
-Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      96      96      METAL
-Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      99      99      METAL
-Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      129     129     METAL
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_135</a></html>     FER1_ARATH      -1      60      135     Pfam
-Iron-sulfur (2Fe-2S)   FER_BRANA       -1      39      39      METAL
-Iron-sulfur (2Fe-2S)   FER_BRANA       -1      44      44      METAL
-Iron-sulfur (2Fe-2S)   FER_BRANA       -1      47      47      METAL
-Iron-sulfur (2Fe-2S)   FER_BRANA       -1      77      77      METAL
-<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_83</a></html>       FER_BRANA       -1      8       83      Pfam
 Chloroplast    FER2_ARATH      -1      1       52      TRANSIT
 Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      91      91      METAL
 Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      96      96      METAL
 Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      99      99      METAL
 Iron-sulfur (2Fe-2S)   FER2_ARATH      -1      129     129     METAL
 <html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_135</a></html>     FER2_ARATH      -1      60      135     Pfam
+Iron-sulfur (2Fe-2S)   FER_BRANA       -1      39      39      METAL
+Iron-sulfur (2Fe-2S)   FER_BRANA       -1      44      44      METAL
+Iron-sulfur (2Fe-2S)   FER_BRANA       -1      47      47      METAL
+Iron-sulfur (2Fe-2S)   FER_BRANA       -1      77      77      METAL
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_83</a></html>       FER_BRANA       -1      8       83      Pfam
+Chloroplast    FER1_ARATH      -1      1       52      TRANSIT
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      91      91      METAL
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      96      96      METAL
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      99      99      METAL
+Iron-sulfur (2Fe-2S)   FER1_ARATH      -1      129     129     METAL
+<html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_135</a></html>     FER1_ARATH      -1      60      135     Pfam
 <html>Description: Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 60_118</a></html>     Q93Z60_ARATH    -1      60      118     Pfam
 Chloroplast    FER1_MAIZE      -1      1       52      TRANSIT
 STRAND FER1_MAIZE      -1      57      59      STRAND
diff --git a/examples/testdata/jal-2005.fa b/examples/testdata/jal-2005.fa
new file mode 100644 (file)
index 0000000..cc58469
--- /dev/null
@@ -0,0 +1,16 @@
+>a
+QQQ
+>b
+QQQ
+>c
+QQQ
+>d
+QQQ
+>e
+QQQ
+>f
+QQQ
+>g
+QQQ
+>h
+QQQ
diff --git a/examples/testdata/jal-2005.jvf b/examples/testdata/jal-2005.jvf
new file mode 100644 (file)
index 0000000..8f37849
--- /dev/null
@@ -0,0 +1,11 @@
+feature_1      8c25cd
+
+STARTGROUP     Jalview
+feature_1      a       -1      1       1       feature_1       0.4
+feature_1      a       -1      2       2       feature_1       0.6
+feature_1      b       -1      1       1       feature_1       0.8
+feature_1      b       -1      2       2       feature_1       1.0
+feature_1      c       -1      1       1       feature_1       1.5
+feature_1      d       -1      1       1       feature_1       2.0
+feature_1      e       -1      1       1       feature_1       3.0
+ENDGROUP       Jalview
index 72c062d..4bdbfb4 100755 (executable)
@@ -35,17 +35,17 @@ TIETHKEEELTA-
 QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDDQIAEGFVLTCAAYPTSDV
 TIETHREEDMV--
 >FER1_ARATH Ferredoxin-1, chloroplast precursor
-MAST----ALSSAIVGTSFIRRSPAPISLRSLPSANTQ--SLFGLKS-GTARGGRVTAMATYKVKFITPEGE
-LEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDV
-TIETHKEEDIV--
+MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE
+QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDV
+VIETHKEEAIM--
 >FER_BRANA Ferredoxin
 -----------------------------------------------------------ATYKVKFITPEGE
 QEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGFVDQSDESFLDDDQIAEGFVLTCAAYPTSDV
 TIETHKEEELV--
 >FER2_ARATH Ferredoxin-2, chloroplast precursor
-MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE
-QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDDEQMSEGYVLTCVAYPTSDV
-VIETHKEEAIM--
+MAST----ALSSAIVGTSFIRRSPAPISLRSLPSANTQ--SLFGLKS-GTARGGRVTAMATYKVKFITPEGE
+LEVECDDDVYVLDAAEEAGIDLPYSCRAGSCSSCAGKVVSGSVDQSDQSFLDDEQIGEGFVLTCAAYPTSDV
+TIETHKEEDIV--
 >Q93Z60_ARATH At1g10960/T19D16_12
 MAST----ALSSAIVSTSFLRRQQTPISLRSLPFANTQ--SLFGLKS-STARGGRVTAMATYKVKFITPEGE
 QEVECEEDVYVLDAAEEAGLDLPYSCRAGSCSSCAGKVVSGSIDQSDQSFLDD-------------------
index ce98085..7e14204 100755 (executable)
    
    <mapID target="memory" url="html/memory.html" />
    <mapID target="groovy" url="html/features/groovy.html" />
+   <mapID target="groovy.featurecounter" url="html/groovy/featureCounter.html" />
    <mapID target="privacy" url="html/privacy.html" />
    <mapID target="vamsas" url="html/vamsas/index.html"/>
    <mapID target="aminoAcids" url="html/misc/aminoAcids.html" />
    
    <mapID target="biojson" url="html/features/bioJsonFormat.html" />
    <mapID target="pdbfetcher" url="html/features/pdbsequencefetcher.html" />
+   <mapID target="siftsmapping" url="html/features/siftsmapping.html" />
    <mapID target="pdbchooser" url="html/features/structurechooser.html" />
    <mapID target="selectcolbyannot" url="html/features/columnFilterByAnnotation.html" />
    <mapID target="biojsmsa" url="html/features/biojsmsa.html" />
    
+   <mapID target="ensemblfetch" url="html/features/ensemblsequencefetcher.html" />
+   
+   <mapID target="uniprotfetcher" url="html/features/uniprotsequencefetcher.html" />
+   
    <mapID target="backIcon" url="icons/back.png" />
    <mapID target="forwardIcon" url="icons/forward.png" />
    <mapID target="homeIcon" url="icons/Home.png" />
index a6145c1..bf1710c 100755 (executable)
 <!-- 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="Split Frame View" target="splitframe" />
-                               <tocitem text="PDB Sequence Fetcher" target="pdbfetcher" />
-                               <tocitem text="PDB Structure Chooser" target="pdbchooser" />
-                               <tocitem text="Chimera Viewer" target="chimera" />
-                               <tocitem text="Select Columns by Annotation" target="selectcolbyannot" />
+                               <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>
                
                </tocitem>
                <tocitem text="Preferences" target="preferences" />
                <tocitem text="Memory Settings" target="memory" expand="false"/>
+               <tocitem text="Scripting with Groovy" target="groovy">
+                       <tocitem text="Groovy Feature Counter example" target="groovy.featurecounter"/>
+               </tocitem>
                <tocitem text="Command Line" target="commandline" expand="false">
                        <tocitem text="Command Line Arguments" target="clarguments" />
-                       <tocitem text="Groovy Shell" target="groovy" />
                </tocitem>
                <tocitem text="Privacy" target="privacy" />
        </tocitem>
index c870887..2ade2e0 100644 (file)
@@ -43,7 +43,7 @@
     entry from the consensus annotation label to copy the alignment's
     consensus sequence to the clipboard.
   <p>
-    <strong>Sequence logo</strong>
+    <a name="logo"><strong>Sequence logo</strong></a>
   </p>
   By clicking on the label you can also activate the sequence logo. It
   indicates the relative amount of residues per column which can be
index 03d24a5..912be55 100644 (file)
   <p>
     <strong>Reference Sequence Alignment Views</strong>
   </p>
+  <p>Many alignment analysis tasks concern a query, or reference
+    sequence. For instance, when searching for sequences from other
+    organisms that are similar to a newly sequenced gene, or when
+    searching for structurally similar sequences for use in homology
+    modelling.</p>
+<p>
+    <strong>What happens when a reference sequence is defined ?</strong>
+  </p>
   <p>
     The reference sequence for an alignment is indicated by its ID being
-    shown in bold. When a reference sequence has been defined, the <strong>Format&#8594;Show
-      unconserved</strong> option highlights mutations with respect to the
-    reference sequence, rather than the alignment's consensus sequence.
-  </p>
+    shown in bold. In addition:</p>
+  <ul>
+    <li><strong>Reference sequence numbering</strong>. Instead of
+      column numbers, the alignment ruler shows the reference sequence
+      positions at each column. At each tick mark, either the reference
+      sequence symbol and position is given, or the column number when a
+      gap is present at that position in the reference sequence.</li>
+    <li><strong>Format&#8594;Show unconserved</strong> highlights
+      mutations with respect to the reference sequence, rather than the
+      alignment's consensus sequence.</li>
+  </ul>
   <p>
+    <strong>Defining the reference sequence</strong>
+  </p>
+  <p>Each alignment view can have its own reference sequence.</p>
   <ul>
-    <li>Jalview automatically assigns a reference sequence when <a
-      href="../webServices/jnet.html"
-    >JPred4</a> predictions are imported.
-    </li>
-    <li><strong>Assigning a reference sequence</strong><br /> A
-      sequence can be marked as the reference sequence by right-clicking
-      on it's ID to open the popup menu, and selecting the "<strong>(Sequence
-        ID)&#8594;Mark as Reference</strong>" entry."</li>
+    <li><strong>Manually assigning a reference sequence</strong><br />
+      A sequence can be marked as the reference sequence by
+      right-clicking on its ID to open the popup menu, and selecting the
+      "<strong>(Sequence ID)&#8594;Mark as Reference</strong>" entry.</li>
+    <li><strong>Defining a reference when importing
+        annotation</strong><br />Jalview automatically assigns a reference
+      sequence when importing analysis results, such as those returned
+      from <a href="../webServices/jnet.html">JPred4</a> . A reference
+      sequence can also be assigned via the <a
+      href="../features/annotationsFormat.html#refsandviews">SET_REF</a> command in
+      an alignment annotation file.</li>
   </ul>
   <p>
     <em>Reference sequence based alignment visualisation was
-      introduced in Jalview 2.9.</em>
+      introduced in Jalview 2.9, and support for storage and retrieval
+      of reference sequence views in 2.10.</em>
   </p>
 </html>
index 8c017a9..afee753 100755 (executable)
         sorting.
       </p>
   </ul>
-  <p>
+  <p><strong>Sorting according to sequence features</strong><br/>
+    Additional sort operations for
+    alignments containing sequence features are provided in the
+    <strong><a href="../features/featuresettings.html#sortbyfeature">Feature
+        Settings</a></strong> dialog, opened via <strong>View&#8594;Feature
+      Settings...</strong><p>
     <strong>Reversing the Order</strong>
   </p>
   <p>Selecting any item from the Sort menu will sort sequences in an
     ascending order according to the property defining the sort. If the
     same sort is re-applied, the sequences will be sorted in the inverse
-    order. In the case of trees and alignment orderings, Jalview will
-    remember your last choice for sorting the alignment and only apply
-    the inverse ordering if you select the same tree or alignment
-    ordering item again.</p>
+    order. In both cases, for sequences which are equivalent under the sort
+    operation, their order will be preserved (since version 2.10). In
+    the case of trees and alignment orderings, Jalview will remember
+    your last choice for sorting the alignment and only apply the
+    inverse ordering if you select the same tree or alignment ordering
+    item again.</p>
 
 </body>
 </html>
index 7325439..c194a53 100755 (executable)
     <strong>Alignment RNA Structure Consensus Annotation</strong>
   </p>
 
+  <p>The RNA structure consensus displayed below the alignment gives the
+    percentage of valid base pairs per column for the first secondary
+    structure annotation shown on the annotation panel. These values are
+    shown as a histogram labeled &quot;StrucConsensus&quot;, where a
+    symbol below each bar indicates whether the majority of base pairs
+    are:<ul>
+    <li>'(' - Watson-Crick (C:G, A:U/T)</li>
+    <li>'[' - Non-canonical (a.ka. wobble) (G:U/T)</li>
+    <li>'{' - Invalid (a.k.a. tertiary) (the rest)</li>
+  </ul>
+  <p>Mousing over the column gives the fraction of pairs classified
+    as Watson-Crick, Canonical or Invalid.</p>
+
+  <p>By default
+    this calculation includes gaps in columns. You can choose to ignore
+    gaps in the calculation by right clicking on the label
+    &quot;StrucConsensus&quot; to the left of the structure consensus bar
+    chart.<br>
+  
   <p>
-    The RNA structure consensus displayed below the alignment is the
-    percentage of valid base pairs per column. It is calculated in
-    relation to a secondary structure and just paired columns are
-    calculated. The canonical Watson-Crick base pairings (A-T/U, G-C)
-    and the wobble base pair (G-T/U) are regarded as valid pairings.<br>
-    The amount of valid base pairs is indicated by the profile in the
-    Alignment Annotation row.<br> By default this calculation
-    includes gaps in columns. You can choose to ignore gaps in the
-    calculation by right clicking on the label &quot;StrConsensus&quot;
-    to the left of the structure consensus bar chart.<br>
-  <p>
-    <strong>Structure logo</strong>
-  </p>
-  By clicking on the label you can also activate the structure logo. It
-  is very similar to a sequence logo but counts the numbers of base
-  pairs. There are two residues per column, the actual column and the
-  interacting base. The opening bracket is always the one on the left
-  side.
-  <br> Like sequence logos the relative amount of a specific base
-  pair can be estimated by its size in the logo. The tool tip of a
-  column gives the exact numbers for all occurring valid base pairs.
+    <strong>RNA Structure logo</strong><br /> Right-clicking on the
+    label allows you to enable the structure logo. It is very similar to
+    a sequence logo but instead shows the distribution of base pairs.
+    There are two residues per column, the actual column and the
+    interacting base. The opening bracket is always the one on the left
+    side. <br> Like <a href="consensus.html#logo">sequence
+      logos</a>, the relative amount of a specific base pair can be
+    estimated by its size in the logo, and this can be made more obvious
+    by <em>normalising</em> the logo (enabled via the popup menu). When
+    the logo is displayed, the tool tip for a column gives the exact
+    percentages for all base pairs at that position.
   </p>
 </body>
 </html>
index 30b6396..ed0ab3f 100755 (executable)
   </div>
   <ul>
     <li>Select which annotation to base the colouring scheme on
-      using the top left selection box.<br />If the <strong>Per-sequence
-        only</strong> tick box is not greyed out, then ticking it will limit the
-      available annotation rows to just those that are sequence
-      associated (e.g. T-COFFEE scores and <a
-      href="../webServices/proteinDisorder.html"
-    >protein disorder predictions</a>), which will colour each sequence
-      according to its own per-residue scores.<br /> <em>Per-sequence
-        associated annotation colouring was introduced in Jalview 2.8</em>
+      using the top left selection box. Sequence associated alignment
+      annotation are shown with the seuqence's name appended.<br />If
+      the <strong>Per-sequence only</strong> tick box is not greyed out,
+      then ticking it will limit the list of available annotation rows
+      to just the labels for those that are sequence associated.
+      Annotation rows on each sequence with the same label (e.g.
+      T-COFFEE scores and <a href="../webServices/proteinDisorder.html">protein
+        disorder predictions</a>) will then be used to colour its
+      corresponding positions in the alignment.<br /> <em>Per-sequence
+        associated annotation colouring is currently only available in
+        the Desktop.</em>
     </li>
     <li>If the &quot;Use Original Colours&quot; box is selected,
       the colouring scheme will use the colouring scheme present on the
index 7e52c46..d13afe4 100755 (executable)
  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  -->
-<head><title>Alignment Annotation</title></head>
+<head>
+<title>Alignment Annotation</title>
+</head>
 <body>
-<p><strong>Alignment Annotation</strong></p>
+  <p>
+    <strong>Alignment Annotation</strong>
+  </p>
 
-<p>In addition to the definition of groups and sequence features,
-  Jalview can display symbols and graphs under the columns of an
-  alignment, and allow you to mark particular columns of an alignment and add symbols and text 
-  in the annotation area shown below the alignment (which may be hidden if <strong>View&#8594;Show 
-  Annotation</strong> is not ticked). Any displayed annotation row can be hidden (using the pop-up 
-  menu obtained by right-clicking the label), or re-ordered by dragging the label to a new 
-  position with the left mouse button.</p>
-<p>
-Web services can also add annotation to an alignment (see the <a
-href="../webServices/jnet.html">JNet</a> and <a
-href="../webServices/proteinDisorder.html">Disorder</a> protein
-structure prediction services), and as of Jalview 2.08 quantitative
-and symbolic annotations can be added to an alignment via an <a
-href="annotationsFormat.html">Annotations File</a> dragged into the
-alignment window or loaded from the alignment's file menu.
-</p>
-<p><a name="seqannots"/><strong>Sequence Reference Annotation</strong>
-</p>
-<p>
-               Sequence reference annotation is created from 3D structure
-               data, and from the results of sequence based prediction of
-               <a href="../webServices/jnet.html">secondary structure</a> and <a
-                       href="../webServices/proteinDisorder.html">disordered region</a>
-               prediction methods. 
-</p>
-<p><strong>Sequence Group Annotation</strong>
-</p>
-<p>
-       If sequence groups are defined, <a href="../calculations/conservation.html">Conservation</a>
-        and <a href="../calculations/consensus.html">Consensus</a> annotation can be enabled
-       for each group from the <a href="../menus/alwannotation.html">Annotations menu</a>, or can
-       be imported from a Jalview <a href="annotationsFormat.html">Annotations file</a>.
-</p>
-<p><strong>Sequence Selection from Annotation</strong>
-</p>
-<p>
-    Sequences associated with sequence (or sequence group) annotations can be selected by
-    double-clicking the annotation label with these key combinations:
-    <ul>
-    <li>double-click - Select associated sequences (replaces current selection)</li>
-    <li>shift double-click - add  sequences to selection</li>
-    <li>Ctrl (Mac CMD) double-click - toggles inclusion of associated sequences in the current selection</li>
-    </ul>
-    Note this also works in combination with manual sequence selection in the alignment.
-<p><strong>Interactive Alignment Annotation</strong></p>
-<p>
-Annotation rows are added using the <strong>Annotation Label</strong>
-menu, which is obtained by clicking anywhere on the annotation row labels
-area (below the sequence ID area).
-</p>
-<ul>
-  <li><strong>Add New Row</strong><br>
-    <em>Adds a new, named annotation row (a dialog box will pop up for you to 
-    enter the label for the new row). </em> </li>
-  <li><strong>Edit Label/Description</strong><br>
-    <em>This opens a dialog where you can change the name (displayed label), or the description
-    (as shown on the label tooltip) of the clicked annotation. </em> </li>
-  <li><strong>Hide This Row</strong><br>
-    <em>Hides the annotation row whose label was clicked in order to bring up 
-    the menu.</em> </li>
-  <li><strong>Hide All <em>&lt;label&gt;</em></strong><br>
-    <em>Hides all annotation rows whose label matches the one clicked. 
-    (This option is only shown for annotations that relate to individual sequences, 
-    not for whole alignment annotations. Since Jalview 2.8.2.)</em> </li>
-  <li><strong>Delete This Row</strong><br>
-    <em>Deletes the annotation row whose label was clicked in order to bring up 
-    the menu.</em> </li>
-  <li><strong>Show All Hidden Rows</strong><br>
-    <em>Shows all hidden annotation rows.</em> </li>
-          <li><strong>Export Annotation</strong> <em>(Application only)</em><br>
-       <em>Annotations can be saved to file or output to a text window in either the 
-        Jalview annotations format or as a spreadsheet style set of comma separated values (CSV). </em> </li>
-      <li><strong>Show Values in Text Box</strong> <em>(applet only)</em><br>
-        <em>Opens a text box with a list of comma-separated values corresponding 
-        to the annotation (numerical or otherwise) at each position in the row. 
-        This is useful to export alignment quality measurements for further analysis.</em> 
-      </li>
-      <li><strong>Scale Label To Column</strong><em>(introduced in 2.5)</em><br>
-      <em>Selecting this toggles whether column labels will be shrunk to fit within each column, or displayed using the view's standard font size.</em></li>
-</ul>
-<p>
-<strong>Editing Label and secondary structure Annotation</strong></p>
-<p>
-Use the <strong>left mouse button</strong> to select a position along the row that are to
-be annotated - these regions will be coloured red. <strong>Control</strong> and <strong>shift</strong> in combination
-with the left-click will select more than one position, or a range of
-positions on the alignment.
-</p>
-<p>Once the desired position has been selected, use the <strong>right mouse
-button</strong> to open the <strong>annotation menu</strong>:</p>
-<ul>
-<li>Helix<br><em>Mark selected positions with a helix glyph (a red
-oval), and optional text label (see below). A
-dialog box will open for you to enter the text. Consecutive ovals
-will be rendered as an unbroken red line.</em>
-</li>
-<li>Sheet<br><em>Mark selected positions with a sheet glyph (a green
-arrow oriented from left to right), and optional text label (see
-below). A dialog box will open for you to enter the text. Consecutive
-arrows will be joined together to form a single green arrow.</em>
-</li>
-<li><a name="rna">RNA Helix</a> (only shown when working with nucleotide sequences)<br>
-<em>Mark selected positions as participating in a base pair
-either upstream or downstream. When the dialog box opens, enter a
-'(' to indicate these bases pair with columns upstream (to right),
-and ')' to indicate this region pairs with bases to the left of the
-highlighted columns.<br />If any brackets do not match up, then an
-orange square will highlight the first position where a bracket was
-found not to match.
-</em>
-</li>
-<li>Label<br><em>Set the text label at the selected positions. A
-dialog box will open for you to enter the text.  If
-more than one consecutive position is marked with the same label, only
-the first position's label will be rendered.</em>
-</li>
-<li>Colour<br><em>Changes the colour of the annotation text label.</em>
-</li>
-<li>Remove Annotation<br><em>Blanks any annotation at the selected positions on
-the row. Note: <strong>This cannot be undone</strong></em>
-</li>
-</ul>
-<p>
-User defined annotation is stored and retrieved using <a
-href="../features/jalarchive.html">Jalview Archives</a>.
-</p>
-<p><em>Current Limitations</em></p>
-<p>As of version 2.5, the Jalview user interface does not support the 
-creation and editing of quantitative annotation (histograms and line graphs), or 
-to create annotation associated with a specific sequence. It is also incapable of
-annotation grouping or changing the style of existing annotation (to change between line or bar charts, or to make multiple line graphs). These annotation capabilities are only possible by the import of an 
-<a href="annotationsFormat.html">Annotation file</a>.<br>
-</p>
+  <p>
+    In addition to the definition of groups and sequence features,
+    Jalview can display symbols and graphs under the columns of an
+    alignment. These annotation tracks are displayed in the annotation
+    area below the alignment. The annotation area's visibility is
+    controlled with the <strong>View&#8594;Show Annotation</strong>
+    option.
+  </p>
+  <p>
+    <strong>Types of annotation</strong>
+  <ul>
+    <li><a name="seqannots"><strong>Sequence
+          associated annotation.</strong></a><br/>Data displayed on sequence annotation
+      rows are associated with the positions of a sequence. Often this
+      is 'Reference annotation' such as secondary structure information
+      derived from 3D structure data, or from the results of sequence
+      based prediction of <a href="../webServices/jnet.html">secondary
+        structure</a> and <a href="../webServices/proteinDisorder.html">disorder</a>.
+      If reference annotation is available for a the currently selected
+      sequences, it can be shown by selecting the <strong>Add
+        Reference Annotation</strong> option in the sequence or selection popup
+      menu.</li>
+    <li><strong>Group associated annotation.</strong><br/>Data can be associated with
+      groups defined on the alignment.     If sequence groups are defined, <a
+      href="../calculations/conservation.html">Conservation</a> and <a
+      href="../calculations/consensus.html">Consensus</a> annotation can
+    be enabled for each group from the <a
+      href="../menus/alwannotation.html">Annotations menu</a>, or can be
+    imported from a Jalview <a href="annotationsFormat.html">Annotations
+      file</a>.</li>
+    <li><strong>Alignment associated annotation.</strong><br />Annotation rows
+      associated with columns on the alignment are simply 'alignment
+      annotation'. Controls allow you to <a href="#iaannot">interactively create
+        alignment annotation</a> to add labels and symbols to alignment columns.
+      Jalview's consensus, conservation and quality calculations also
+      create histogram and sequence logo annotations on the alignment.
+    </li>
+  </ul>
+  <p>
+    <strong>Importing and exporting annotation</strong><br />
+    Annotations on an alignment view are saved in Jalview project files.
+    You can also load <a href="annotationsFormat.html">Annotations
+      Files</a> in order to add any kind of quantitative and symbolic
+    annotations to an alignment. To see an example, use the <strong>Export
+      Features/Annotation</strong> option from an alignment window's File menu.
+  </p>
+  <p>
+    <strong>Layout and display controls</strong><br /> Individual and
+    groups of annotation rows can be shown or hidden using the pop-up
+    menu obtained by right-clicking the label. You can also reorder them
+    by dragging the label to a new position with the left mouse button.
+    The
+    <strong>Annotations</strong> menu provides settings controlling the
+    ordering and display of sequence, group and alignment associated
+    annotation. The
+    <strong>Colour by annotation</strong> option in the colour menu
+    allows annotation to be used to
+    <a href="../colourSchemes/annotationColouring.html">shade the
+      alignment</a>. Annotations can also be used to
+    <a href="../features/columnFilterByAnnotation.html">select or
+      hide columns</a> via the dialog opened from the
+    <strong>Selection</strong> menu.
+  </p>
+  <p>
+    <strong>Sequence Highlighting and Selection from Annotation</strong>
+  </p>
+  <p>
+    A <strong>single click</strong> on the label of an annotation row
+    associated with sequences and sequence groups will cause the
+    associated sequences to be highlighted in the alignment view. <strong>Double
+      clicking</strong> the label will select the associated sequences, replacing
+    any existing selection. Like with other kinds of selection, <strong>shift
+      double-click</strong> will add associated sequences, and <strong>Ctrl
+      (Mac CMD) double-click</strong> will toggle inclusion of associated
+    sequences in the selection.
+  <p>
+    <strong>Interactive Alignment Annotation</strong>
+  </p>
+  <p>
+    <a name="iaannot"> Annotation rows</a> are added using the <strong>Annotation
+      Label</strong> menu, which is obtained by clicking anywhere on the
+    annotation row labels area (below the sequence ID area).
+  </p>
+  <ul>
+    <li><strong>Add New Row</strong><br> <em>Adds a new,
+        named annotation row (a dialog box will pop up for you to enter
+        the label for the new row). </em></li>
+    <li><strong>Edit Label/Description</strong><br> <em>This
+        opens a dialog where you can change the name (displayed label),
+        or the description (as shown on the label tooltip) of the
+        clicked annotation. </em></li>
+    <li><strong>Hide This Row</strong><br> <em>Hides the
+        annotation row whose label was clicked in order to bring up the
+        menu.</em></li>
+    <li><strong>Hide All <em>&lt;label&gt;</em></strong><br> <em>Hides
+        all annotation rows whose label matches the one clicked. (This
+        option is only shown for annotations that relate to individual
+        sequences, not for whole alignment annotations. Since Jalview
+        2.8.2.)</em></li>
+    <li><strong>Delete This Row</strong><br> <em>Deletes
+        the annotation row whose label was clicked in order to bring up
+        the menu.</em></li>
+    <li><strong>Show All Hidden Rows</strong><br> <em>Shows
+        all hidden annotation rows.</em></li>
+    <li><strong>Export Annotation</strong> <em>(Application
+        only)</em><br> <em>Annotations can be saved to file or
+        output to a text window in either the Jalview annotations format
+        or as a spreadsheet style set of comma separated values (CSV). </em>
+    </li>
+    <li><strong>Show Values in Text Box</strong> <em>(applet
+        only)</em><br> <em>Opens a text box with a list of
+        comma-separated values corresponding to the annotation
+        (numerical or otherwise) at each position in the row. This is
+        useful to export alignment quality measurements for further
+        analysis.</em></li>
+    <li><strong>Scale Label To Column</strong><em>(introduced
+        in 2.5)</em><br> <em>Selecting this toggles whether column
+        labels will be shrunk to fit within each column, or displayed
+        using the view's standard font size.</em></li>
+  </ul>
+  <p>
+    <strong>Editing labels and secondary structure annotation rows</strong>
+  </p>
+  <p>
+    Use the <strong>left mouse button</strong> to select a position
+    along the row that are to be annotated - these regions will be
+    coloured red. Press <strong>Control</strong> or <strong>shift</strong> in
+    combination with the left-click to either select an additional position,
+    or a range of positions on the alignment.
+  </p>
+  <p>
+    Once positions have been selected, use the <strong>right
+      mouse button</strong> and select one of the following from the <strong>annotation menu</strong>:
+  </p>
+  <ul>
+    <li>Helix<br>
+    <em>Marks selected positions with a helix glyph (a red oval),
+        and optional text label (see below). A dialog box will open for
+        you to enter the text. Consecutive ovals will be rendered as an
+        unbroken red line.</em>
+    </li>
+    <li>Sheet<br>
+    <em>Marks selected positions with a sheet glyph (a green arrow
+        oriented from left to right), and optional text label (see
+        below). A dialog box will open for you to enter the text.
+        Consecutive arrows will be joined together to form a single
+        green arrow.</em>
+    </li>
+    <li><a name="rna">RNA Helix</a> (only shown when working with
+      nucleotide sequences)<br> <em>Marks selected positions
+        as participating in a base pair either upstream or downstream.
+        When the dialog box opens, enter a '(' to indicate these bases
+        pair with columns upstream (to right), and ')' to indicate this
+        region pairs with bases to the left of the highlighted columns.
+        Other kinds of base-pair annotation are also supported (e.g. 'A'
+        and 'a', or '&lt;' and '&gt;'), and Jalview will suggest an
+        appropriate symbol based on the closest unmatched
+        parenthesis to the left.<br />If any brackets do not match up, then an
+        orange square will highlight the first position where a bracket
+        was found not to match.
+    </em></li>
+    <li>Label<br>
+    <em>Set the text label at the selected positions. A dialog box
+        will open for you to enter the text. If more than one
+        consecutive position is marked with the same label, only the
+        first position's label will be rendered.</em>
+    </li>
+    <li>Colour<br>
+    <em>Changes the colour of the annotation text label.</em>
+    </li>
+    <li>Remove Annotation<br>
+    <em>Blanks any annotation at the selected positions on the row.
+        Note: <strong>This cannot be undone</strong>
+    </em>
+    </li>
+  </ul>
+  <p>
+    User defined annotation is stored and retrieved using <a
+      href="../features/jalarchive.html">Jalview Archives</a>.
+  </p>
+  <p>
+    <em>Current Limitations</em>
+  </p>
+  <p>
+    The Jalview user interface does not support interactive
+    creation and editing of quantitative annotation (histograms and line
+    graphs), or to create annotation associated with a specific
+    sequence or group. It is also incapable of annotation grouping or changing
+    the style of existing annotation (e.g. to change between line or bar
+    charts, or to make multiple line graphs). These annotation
+    capabilities are only possible by the import of an <a
+      href="annotationsFormat.html">Annotation file</a>.<br>
+  </p>
 </body>
 </html>
index 2b7d0ec..c53844b 100644 (file)
@@ -32,7 +32,7 @@
     or hidden according to annotation rows on the alignment. The dialog
     box is opened <em>via</em> &quot;<strong>Select&#8594;Select/Hide
       Columns by Annotation...</strong>&quot;, and different filters are
-    presented dependent upon the data shown in the selected annotation
+    then presented for filtering data according to the selected annotation
     row.
   </p>
   <table>
       <td><img src="AnnotationColumnSelectionWithoutSM.gif"></td>
     </tr>
   </table>
-
-  <p>If an annotation with numeric values is selected, the threshold
+  <p>The drop down menu lists the annotation available on the
+    alignment. Sequence associated annotation rows will be shown with
+    the sequence ID appended to the annotation label. It is only
+    possible to select one row at a time.</p>
+  <p>
+    If an annotation with numeric values is selected, the threshold
     filter option is activated. For other types of annotation, use the
     text box and secondary structure check boxes (right). The radio
     buttons at the bottom of the dialog specify the action applied to
-    columns matching the query.</p>
+    columns matching the query.<br /> <em>Note: annotation
+      containing only numeric labels (e.g. T-COFFEE column confidence
+      scores) will not be treated as quantitative data. You will need to
+      enter search expressions to select columns in this case.</em>
+  </p>
   <ul>
     <li><strong>Search Filter</strong>
       <ul>
diff --git a/help/html/features/ensemblsequencefetcher.html b/help/html/features/ensemblsequencefetcher.html
new file mode 100644 (file)
index 0000000..54b57a3
--- /dev/null
@@ -0,0 +1,100 @@
+<html>
+<!--
+ * 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.
+ -->
+<head>
+<title>Fetching ENSEMBL Data in Jalview</title>
+</head>
+<body>
+
+  <strong>Fetching ENSEMBL Data in Jalview</strong>
+  <br /> Jalview Version 2.10 (October 2016) introduced support to
+  retrieve annotated transcripts, peptides and genomic contigs from
+  <a href="http://www.ensembl.org">ENSEMBL</a>.
+  <br />
+  <img src="selectfetchdb.gif" align="left" width="480" height="204"
+    alt="Database selection dialog for fetching sequences (introduced in Jalview 2.8)">
+
+  <p>
+    Two types of ENSEMBL source are provided. ENSEMBL queries the main
+    ENSEMBL warehouse containing data for higher eukaryotes, and
+    EnsemblGenomes, which queries Ensembl Pathogens, and other
+    warehouses.<br />
+    <em>Ensembl support is new in Jalview, and we expect to merge
+      these sources in a future release.</em>
+  </p>
+  <p>
+    <strong>General Use</strong><br /> If you have a set of Ensembl gene
+    or transcript IDs, then you can retrieve them <em>via</em> the
+    sequence fetcher dialog opened after selecting the most appropriate
+    source (either 'ENSEMBL', or Ensembl Genomes). However, Jalview's
+    Ensembl client has a couple of additional capabilities:
+  </p>
+  <p>
+    <strong>Retrieving aligned transcripts for a genomic ID</strong>
+  </p>
+  <p>If a single genomic identifier is entered in the Ensembl
+    fetcher, Jalview will return all transcripts and products for the
+    locus, and display them in a split view - complete with sequence
+    variant annotation.</p>
+  <p>
+    <strong>Retrieving orthologs for a gene ID</strong>
+  </p>
+  <p>
+    If a gene ID is entered (e.g. fox1), Jalview will resolve Ensembl
+    genomic identifiers for a predefined set of taxa (Mouse, Rat, Human,
+    Yeast in Jalview 2.10).<br />
+  </p>
+  <p>
+    <strong><a name="ensemblannotation">Ensembl Sequence
+        Features</a></strong><br /> Jalview 2.10 includes support for the
+    visualisation and transfer genomic and transcriptomic sequence
+    features onto protein product sequences. Retrieval of a genomic
+    locus results in a set of transcripts that are annotated with
+    nucleotide variant information and exonic regions. By default,
+    intronic regions will be hidden.
+  </p>
+  <p>
+    <strong><a name="variantvis">Variant information on
+        Protein Products</a></strong><br />Jalview can translate genomic variant
+    annotation into protein sequence variant codes for variants
+    intersecting coding regions of a gene. To see this in action, use
+    the <strong>Calculate&#8594;Show cross-references</strong> menu to
+    view protein product sequences for the currently displayed (or
+    selected) sequences. The same menu allows you to recover Ensembl
+    exon, transcript and variant information when viewing UniProt
+    sequences.
+  </p>
+  <p>
+    <strong>Viewing more information about variant annotation</strong><br />
+    Variants are highlighted as red sequence features on the protein
+    sequence, with each one reporting all protein sequence variants
+    observed at that position as a result of the genomic variants.
+    Right-clicking a variant allows you to open the Ensembl Variants web
+    page for each variant, via the <strong>Link</strong> submenu.
+  </p>
+  <p>
+    <strong>Work in Progress !</strong><br />In the next few releases,
+    we hope to improve and extend Jalview's support for working with
+    Ensembl. If you have any problems, questions or suggestions then
+    please get in contact with us via the Jalview discussion list.
+  </p>
+</body>
+</html>
\ No newline at end of file
index 200fc8f..dba62cc 100755 (executable)
   </p>
   <p>
     <strong><em>Feature settings pop-up menu</em></strong><br> <strong>Right-click</strong>
-    on a feature to open a pop-up menu that allows you to sort the
-    alignment or current selection using that feature type (see below),
-    or toggle the type of colouring used for the feature. Features may
-    be highlighted with either a single colour or a <a
-      href="featureschemes.html"
-    >feature colourscheme</a> based on either the scores associated with
-    that feature or from the feature's description (e.g. to distinguish
+    on a feature to open a pop-up menu that allows you to<ul><li>Hide, show and
+    select columns containing that feature</li><li>Sort the alignment or
+    current selection using that feature type (see below)</li><li>Toggle the
+    type of colouring used for the feature</li></ul><p>Features may be highlighted
+    with either a single colour or a <a href="featureschemes.html">feature
+      colourscheme</a> based on either the scores associated with that
+    feature or from the feature's description (e.g. to distinguish
     different names associated with a DOMAIN feature).
   </p>
   <p>
-    <strong>Ordering alignment by features</strong><br> The 'Seq
+    <strong><a name="sortbyfeature">Ordering alignment by features</a></strong><br> The 'Seq
     Sort by Score' and 'Seq Sort by Density' buttons will sort the
     alignment based on the average score or total number of currently
     active features and groups on each sequence. To order the alignment
index a2bc627..079cf9e 100644 (file)
     <strong>The Groovy Shell</strong>
   </p>
   <p>
-    <a href="http://www.groovy-lang.org/">Groovy</a> is an &quot;<em>agile
-      and dynamic language for the Java platform</em>&quot;. The groovy
-    scripting language makes it extremely easy to programmatically
-    interact with Java programs, in much the same way that Javascript is
-    used to generate and interact with applets and other objects on the
-    page.
+    Groovy (<a href="http://www.groovy-lang.org/">www.groovy-lang.org</a>)
+    is an &quot;<em>agile and dynamic language for the Java
+      platform</em>&quot;. The groovy scripting language makes it extremely
+    easy to programmatically interact with Java programs, in much the
+    same way that Javascript is used to generate and interact with
+    applets and other objects on the page.
   </p>
   <p>
-    <strong><em>Getting Groovy...</em> </strong><br> Jalview comes with
-    an embedded installation of Groovy. All you need is to select <strong>Tools&#8594;Groovy
-      Console...</strong> menu option from the Jalview Desktop's
-    drop-down menu. After a short pause, you should then see the <a
-      href="http://groovy-lang.org/groovyconsole.html"
-    >Groovy Console</a> appear. This allows you to interactively execute Groovy
-    scripts within the Jalview run-time environment.
+    <em>Getting Groovy...</em><br> Jalview comes with an embedded
+    installation of Groovy. Just select <strong>Tools&#8594;Groovy
+      Console...</strong> from the Jalview Desktop's drop-down menu. After a
+    short pause, you should then see the <a
+      href="http://groovy-lang.org/groovyconsole.html">Groovy
+      Console</a> appear. This allows you to interactively execute Groovy
+    scripts whilst Jalview is running. We've also provided a <strong>Calculations&#8594;Execute
+      Groovy Script</strong> button so you can execute the currently loaded
+    groovy script whilst viewing an alignment.
   </p>
   <p>
     <strong>Executing groovy scripts on Jalview startup</strong><br>
     </em>
   </p>
   <p>
-    <strong>Executing a groovy script on a particular alignment</strong><br/>
-    
-  <p>
     <strong>Access to Jalview's functions from Groovy Scripts</strong><br>
-    There is as yet no properly defined scripting interface to Jalview,
-    but all the public methods of the jalview class hierarchy can be
-    called from Groovy scripts. The access point for this is the <strong>Jalview</strong>
-    object defined in the groovy environment which corresponds to the
-  <pre>jalview.gui.Desktop</pre>
-  object which manages all the Jalview windows. Here's an example to get
-  you started:
-  <br>
+    The scripting interface to Jalview is still a work in progress, so
+    we recommend you also take a look at Jalview's source, since all the
+    public methods of the jalview class hierarchy can be called from
+    Groovy scripts. In addition, the following objects are also defined:
+
+  
+  <ul>
+    <li><strong>Jalview</strong> - this is bound to <code>jalview.bin.Jalview</code>.<br />Useful
+      methods include:
+      <ul>
+        <li>Jalview.getAlignFrames() - returns a list of
+          jalview.gui.AlignFrame objects</li>
+        <li>Jalview.getCurrentAlignFrame() - returns the alignment
+          window which is currently being looked at by the user</li>
+      </ul></li>
+    <li><strong>currentAlFrame</strong> - this is only defined when
+      running a Groovy script via the -groovy command line argument. It
+      returns the first alignment window created after acting on the
+      other arguments passed on the command line.</li>
+  </ul>
+  <p>
+    <em>A simple script</em><br />
   <ul>
     <li>Getting the title, alignment and first sequence from the
       current alignFrame<br> <pre>
@@ -77,13 +90,26 @@ def alignment = alf[0].viewport.alignment;
 def seq = alignment.getSequenceAt(0);
 </pre>
     </li>
-    <li>When running a groovy script from the command line, the
-      alignment that was just loaded can be referred to like so:<br>
-    <pre>
+    <li>If you wanted to do the same thing from the command line, you can refer to
+      alignment that was just loaded with currentAlFrame:<br>
+      <pre>
 print currentAlFrame.getTitle();</pre>
   </ul>
-  If you have downloaded the InstallAnywhere version of Jalview, you can
-  find additional groovy scripts in the examples/groovy subfolder of the
-  installation directory.
+  <p>
+    <em>Example scripts</em><br />If you have downloaded the
+    InstallAnywhere version of Jalview, you can find additional groovy
+    scripts in the examples/groovy subfolder of the installation
+    directory. The examples are also available at <a
+      href="http://www.jalview.org/examples/groovy">http://www.jalview.org/examples/groovy</a>.
+  </p>
+  <p>
+    <em>Using Groovy to add new Alignment Calculations</em><br />We've
+    simplified the alignment analysis programming interface in Jalview
+    2.10 to make it easy for you to add your own dynamic annotation
+    tracks with Groovy. Have a look at the <a
+      href="../groovy/featureCounter.html">featureCounter.groovy</a>
+    example for more information.
+  </p>
+
 </body>
 </html>
index 6e1ce10..de0a7e6 100644 (file)
Binary files a/help/html/features/selectfetchdb.gif and b/help/html/features/selectfetchdb.gif differ
index ff5c1b0..04d3c1d 100755 (executable)
     Institute, or, since Jalview 2.4, DAS servers capable of the <em>sequence</em>
     command (configured in <a href="dassettings.html">DAS settings</a>).
   </p>
-  <img src="seqfetcher.gif" align="center"
-    alt="The Jalview Sequence Fetcher Dialog Box"
-  >
-  <p>The Sequence Fetcher dialog box can be opened via the
+  <p>The Sequence Fetcher can be opened via the
     &quot;File&quot; menu on the main desktop in order to retrieve
     sequences as a new alignment, or opened via the &quot;File&quot;
     menu of an existing alignment to import additional sequences. There
     whilst Jalview compiles the list of available sequence datasources
     from the currently defined DAS server registry.</p>
   <p>
-    First, <strong>select the database you want to retrieve
-      sequences from</strong> by clicking the button labeled 'Select database
-    retrieval source'. If a database source is already selected, then
-    the button's label will change to show the currently selected
-    database.
+    Every time a new fetcher is opened, you will need to <strong>select the database you want to retrieve
+      sequences</strong> from the database chooser.
   </p>
-  <img src="selectfetchdb.gif" align="left"
+  <img src="selectfetchdb.gif" align="left" width="480" height="204"
     alt="Database selection dialog for fetching sequences (introduced in Jalview 2.8)"
   >
-  <p>Since Jalview 2.8, the available databases are shown as a tree
-    in a popup dialog box. The databases are ordered alphabetically, and
-    if there are many sources for the same type of sequence identifier,
-    they will be grouped together in a sub-branch branch labeled with
-    the identifier.</p>
-  <p>
-    Once you have selected the sequence database using the popup dialog
-    box, <strong>enter one or more accession ids</strong> (as a
-    semi-colon separated list), or press the &quot;Example&quot; button
-    to paste the example accession for the currently selected database
-    into the retrieval box. Finally, press &quot;OK&quot; to initiate
-    the retrieval.
-  </p>
-  <p>
-    <strong>Fetching from The PDB with the EMBL-EBI PDBe Search
-      Interface</strong>
-  </p>
-  <p>
-    Since Jalview 2.9, selecting PDB as the sequence database will open
-    the <a href="pdbsequencefetcher.html">PDB Sequence Fetcher</a> for
-    discovering and retrieving structures.
-  </p>
+  <p>The databases are shown as a tree, and ordered alphabetically;
+    tooltips are shown if you mouse over some sources, explaining what
+    the database will retrieve. You can select one by using the up/down
+    arrow keys and hitting return, or by double clicking with the mouse.
+    <br/><em>If you have DAS sources enabled, then you may have several sources
+    for the same type of sequence identifier, and these will be grouped
+    together in a sub-branch branch labeled with the identifier.</em></p>
+  <p>Once you have selected a sequence database, its fetcher dialog
+    will open. Jalview provides two types of dialog:</p>
+    <ol><li><strong>The Free-text Search Interface</strong>
+  
+  <br/>Free-text search clients are provided for PDB (Since 2.9), and
+    UniProt (Since 2.10). They provide access to each database's own
+    query system, enabling you to retrieve data by accession, free text
+    description, or any other type of supported field. For full details,
+    see each client's help page:
+  <ul>
+    <li><a href="pdbsequencefetcher.html">PDB Sequence Fetcher</a></li>
+    <li><a href="uniprotsequencefetcher.html">UniProt Sequence
+        Fetcher</a></li>
+  </ul>
+  </li>
+  <li><strong>Accession based sequence retrieval</strong>
+  <br/>
+
+  <img src="seqfetcher.gif" align="center"
+    alt="The Jalview Sequence Fetcher Dialog Box"><br/>
+  To retrieve sequences, simply <strong>enter one or more accession ids</strong> (as a semi-colon
+  separated list), or press the &quot;Example&quot; button to paste the
+  example accession for the currently selected database into the
+  retrieval box. Finally, press &quot;OK&quot; to initiate the
+  retrieval.
+  </li>
+  </ol>
   <p>
     <strong>Only retrieving part of a sequence</strong>
   </p>
   <p>
-    DAS sources (indicated by a &quot;<em>(DAS)</em>&quot;) allow a
-    range to be specified in addition to a sequence ID. To retrieve 50
-    residues starting at position 35 in UNIPROT sequence P73137 using
-    the UNIPROT DAS server, you would enter &quot;'P73137:35,84'.<br />
-    <em>Full support for DAS range queries was introduced in
-      Jalview 2.8</em>
+    When using DAS sources (indicated by a &quot;<em>(DAS)</em>&quot;),
+    you can append a range in addition to a sequence ID. For example, to
+    retrieve 50 residues starting at position 35 in UNIPROT sequence
+    P73137 using the UNIPROT DAS server, you would enter
+    &quot;'P73137:35,84'.<br /> <em>Full support for DAS range
+      queries was introduced in Jalview 2.8</em>
   </p>
 
   <p>If you use the WSDBFetch sequence fetcher services (EMBL,
index 80c0294..9492d70 100644 (file)
     record and use that information to construct a mapping between the
     sequence and downloaded structure.</p>
   <p>If, for some reason, no SIFTS mapping data exists, then Jalview
-    will generate a mapping using its built-in Needleman and Wunsch
-    global alignment algorithm. This method of mapping was used for all
-    structures prior to version 2.10.
-  <p>
-    <strong>Controlling and troubleshooting SIFTS mappings</strong> <br />
+    will generate a mapping using the built-in Needleman and Wunsch
+    global alignment algorithm. This is how sequence-structure mappings
+    were created before version 2.10.</p>
+  <p><strong>Controlling and troubleshooting SIFTS mappings</strong> <br />
     Configuration options controlling whether SIFTS mappings are used
     can be found in the <strong>Tools &rarr; Preferences &rarr;
       Structure tab</strong>, under 'Sequence &harr; Structure method'.<br /> <em>Note:</em>
     <strong>Multi-Chain Mappings</strong> <br />SIFTS gives Jalview the
     ability to display multi-chain mappings between UniProt sequences
     and PDB structure data. This is important when working with
-    multimeric proteins, since the biological unit will contain several
+    multimeric proteins, when the biological assembly can contain several
     structures for the same protein sequence. Multi-chain mapping allows
     all residues in a structure to be located in the alignment, and
     also, when shading the structure by sequence colours, enables
     conservation patterns between oligomer interfaces to be explored.
   </p>
-  <p>To see this in action, load uniprot sequence for FER1_MAIZE
-    then veiw PDB structure for 3B2F, you will notice that mousing over
+  <p>To see this in action, Retrieve the UniProt sequence
+    FER1_MAIZE, and then view one of its structures: 3B2F. Mousing over
     the sequence results to two positions being highlighted in the
-    structure, also colouring the sequence transfers the color to all
+    structure, and colouring the alignment transfers the color to all
     the mapped chains in the structure.</p>
 
   <p>
     <Strong>Viewing Mapping Output</Strong> <br /> The mapping provided
     by the SIFTS record is accessible via <strong>File &rarr;
       View mapping</strong> menu of the structure viewers. The screenshot below
-    is the mapping output for the <Strong>{FER1_MAIZE &harr;
-      3B2F}</Strong> example described above, and confirms that all two chains
-    were mapped. The mapping method used can be seen within the area
-    highlighted with red boarder.
+    shows the mapping created between UniProt sequence FER1_MAIZE and proteins in PDB 3B2F, which reports thattwo chains
+    were mapped. The mapping method is also reported (highlighted with red border).
   <p>
 
     &emsp;<img src="sifts_mapping_output.png" align="left"
       alt="SIFTS mapping output" />
+      <br/>
   <p>
     <em>SIFTS Mapping integration was added in Jalview 2.10</em>
   </p>
index f5f5916..c9600bb 100644 (file)
     <strong>Structure Chooser</strong>
   </p>
 
-  The Structure Chooser interface provides a smart technique for
-  selecting PDB structures to view in Jalview by querying readily
-  available meta-data of structures. The Interface can be invoked by
-  selecting the
-  <strong>"3D Structure Data.."</strong> option from a sequence's
-  <a href="../menus/popupMenu.html">pop-up menu</a>. Some of the main
-  features it provides are listed below:
+  <p>
+    The Structure Chooser interface allows you to interactively select
+    which PDB structures to view for the currently selected set of
+    sequences. It's opened by selecting the <strong>"3D
+      Structure Data.."</strong> option from the Sequence ID panel's <a
+      href="../menus/popupMenu.html">pop-up menu</a>. The dialog
+    provides:
+  </p>
   <ul>
     <li>Automatic discovery, retrieval and association of PDB
-      entries for an alignment's sequences</li>
-    <li>Visualisation of discovered structures' meta-data</li>
-    <li>Ability to configure the meta-data entries to visualise</li>
-    <li>Auto-selection of the best structure via filtering by the
-      available metric parameters in the meta-data (i.e. resolution,
-      quality etc).</li>
-    <li>Selection of multiple structures in a single operation</li>
+      entries for sequences</li>
+    <li>Exploration of meta-data for available 3D structures</li>
+    <li>Automatic selection of the 'best structure' to display for
+      each sequence</li>
+    <li>Manual association of PDB entries by entering a PDB Id</li>
+    <li>Association of structure data from a local file (in mmCIF
+      or PDB format)</li>
   </ul>
-  Additionally, the Structure Chooser retains the following contemporary
-  features of Jalview:
-  <ul>
-    <li>Manual association of PDB entries via entering the PDB Id
-      or From File</li>
-    <li>Ability to view cached PDB entries</li>
-  </ul>
-
 
-  <strong>Associating PDB files with Sequences</strong>
-  <br> Discovery/Association of PDB entries to a sequence now
-  happens automatically during the initialisation of the Structure
-  Chooser Interface. Jalview uses the sequence's ID to query the PDB
-  Rest API provided by the EBI to discover PDB Ids associated with the
-  sequence.
-
-  <br>
-  <br>
-  <strong>Configuring displayed meta-data for Structures</strong>
-  <br> To configure the visible meta-data displayed for the
-  discovered structures, click the 'Configure Displayed Columns' tab,
-  then tick the options which you intend to make visible.
-
-  <br>
-  <br>
-  <strong>Auto-selection of best Structures</strong>
-  <br> Jalview can automatically filter and select the best
-  structures using various metric categories avaialble from the
-  meta-data of the structures. To perform this simply select any of the
-  following options from the drop-down menu in the Structure Chooser
-  interface: Best UniProt coverage, Higest Resolution, Best Quality,
-  Highest Protein Chain etc. When the 'Invert' option is selected,
-  Jalview returns an inverse result for the current selected option in
-  the drop-down menu.
+  <p>
+    <strong>Automated discovery of structure data</strong>
+  </p>
+  <p>After selecting "3D Structure Data ..", Jalview queries the PDB
+    via the PDBe SOLR Rest API provided by EMBL-EBI to discover PDB ids
+    associated with the sequence. It does this based on the sequence's
+    ID string, and any other associated database IDs.</p>
+  <p>
+    <strong>Exploration of meta-data for available structures</strong>
+  </p>
+  <p>Information on each structure available is displayed in columns
+    in the dialog box. By default, only the title, resolution and PDB
+    identifier are shown, but many more are provided by the PDBe. To
+    configure which ones are displayed, select the 'Configure Displayed
+    Columns' tab and tick the columns which you want to see.</p>
+  <p>
+    <strong>Selection of the best structure for each sequence</strong>
+  </p>
+  <p>Jalview can automatically select the best structures according
+    to meta-data provided by the PDB. By default, the 'Best Quality'
+    structure for each sequence will be selected, but clicking on the
+    drop down menu allows other criteria to be chosen, including
+    Resolution (only defined for X-Ray structures), Highest Protein
+    Chain etc. When 'Invert' is selected, structures are selected in
+    reverse order for the current criteria (e.g. worst quality rather
+    than best).</p>
   <p>
 
     <img src="schooser_main.png" style="width: 464px; height: 369px;">
     sample alignment. Note however that if no structures were
     auto-discovered, a different interface for manual association will
     be invoked as seen in the screenshot below.
+  
   <p>
     <img src="schooser_enter-id.png"
-      style="width: 464px; height: 369px;"
-    >
+      style="width: 464px; height: 369px;">
+  
   <p>
     <strong>Manual selection/association of PDB files with
       Sequences</strong>
   </p>
-  <p>To manually associate PDB files with a sequence, select any of
-    the follwing options listed below from the drop-down menu in the
-    interface:
+  <p>To manually associate PDB files with a sequence, select 'From
+    File', or 'Enter PDB Id' from the drop-down menu:
+  
   <ul>
-    <li><strong>From File</strong> - You can load a PDB file from
-      the local machine or network and associate it with the selected
-      sequence. PDB files associated in this way will also be saved in
-      the <a href="jalarchive.html">Jalview Archive file</a>.<br></li>
-    <li><strong>Enter PDB Id</strong> - Jalview will use the PDB
-      Rest API, provided by the EBI, to fetch the PDB file with the
-      entered Id.<br></li>
-    <li><strong>Cached PDB Entries</strong> - You can view PDB
-      structures which have previously been downloaded/viewed using this
-      option. Jalview caches previously downloaded PDB entries in the
-      computer memory. However, if the project is saved before exiting
-      Jalview, Jalview will serialize the cached entries to the file
-      system.</li>
+    <li><strong>From File</strong> - allows you to load a PDB file
+      from the local machine or network and associate it with the
+      selected sequence. PDB files associated in this way will also be
+      saved in the <a href="jalarchive.html">Jalview Archive file</a>.<br></li>
+    <li><strong>Enter PDB Id</strong> - allows you specify a PDB ID
+      for your sequence. The PDB Rest API, provided by EMBL-EBI, is used
+      to validate and fetch structure data.<br></li>
   </ul>
+  <p>
+    <strong>Viewing existing structures for your sequences</strong>
+  </p>
+  <p>
+    If you have previously associated structure data on the alignment,
+    selecting <strong>Cached PDB Entries</strong> from the drop down
+    menu allows you to select these structures for display.
+  </p>
 
   <p>
     <em>The Structure Chooser interface was introduced in Jalview
index ed7cbb7..b4b1d86 100644 (file)
@@ -48,7 +48,7 @@
   </p>
   <p>
     To search UniProt, simply begin typing in the text box. After a
-    short delay (uabout 1.5 seconds), results will be shown in the table
+    short delay (about 1.5 seconds), results will be shown in the table
     below. You can sort results by clicking on the displayed columns,
     and select entries with the mouse or keyboard. Once you have
     selected one or more entries, hit the <strong>OK</strong> button to
index edb3762..9cead2d 100755 (executable)
             Entries</strong> option from the drop down menu at the top of the
           dialog box.</li>
       </ul></li>
-    <li>To view selected structures, click the <strong>"View"</strong>
-      button.
-    </li>
+    <li><strong>To view selected structures, click the <strong>"View"</strong>
+      button.</strong><br />
+      <ul>
+        <li>Additional structure data will be downloaded with the
+          EMBL-EBI's dbfetch service</li>
+        <li><a href="siftsmapping.html">SIFTS</a> records will also
+          be downloaded for mapping UniProt protein sequence data to PDB
+          coordinates.</li>
+      </ul></li>
   </ol>
 
   The
diff --git a/help/html/groovy/featureCounter.html b/help/html/groovy/featureCounter.html
new file mode 100644 (file)
index 0000000..fe848a9
--- /dev/null
@@ -0,0 +1,262 @@
+<html>
+<!--
+ * 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.
+ -->
+<head>
+<title>Extending Jalview with Groovy - Feature Counter Example</title>
+</head>
+<body>
+  <p>
+    <strong>Extending Jalview with Groovy - A customisable
+      feature counter</strong><br /> 
+    <br />The groovy script below shows how to add a new calculation
+    track to a Jalview alignment window.</p><p>As currently written, it will
+    add two tracks to a protein alignment view which count Pfam features
+    in each column, and ones where a charge residue also occur.</p><p>To try
+    it for yourself:</p><ol><li>Copy and paste it into the groovy script
+    console</li><li>Load the example Feredoxin project (the one that opens
+    by default when you first launched Jalview)</li><li>Select <strong>Calculations&#8594;Execute
+      Groovy Script</strong> from the alignment window's menu bar to run the script on
+    the current view.</li></ol>
+  <em><a
+      href="http://www.jalview.org/examples/groovy/featureCounter.groovy">http://www.jalview.org/examples/groovy/featureCounter.groovy</a> - rendered with <a href="http://hilite.me">hilite.me</a></em>
+  <!-- HTML generated using hilite.me -->
+  <div
+    style="background: #ffffff; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
+    <pre style="margin: 0; line-height: 125%">
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * Jalview - A Sequence Alignment Editor and Viewer (Version 2.10)</span>
+<span style="color: #888888"> * Copyright (C) 2016 The Jalview Authors</span>
+<span style="color: #888888"> * </span>
+<span style="color: #888888"> * This file is part of Jalview.</span>
+<span style="color: #888888"> * </span>
+<span style="color: #888888"> * Jalview is free software: you can redistribute it and/or</span>
+<span style="color: #888888"> * modify it under the terms of the GNU General Public License </span>
+<span style="color: #888888"> * as published by the Free Software Foundation, either version 3</span>
+<span style="color: #888888"> * of the License, or (at your option) any later version.</span>
+<span style="color: #888888"> *  </span>
+<span style="color: #888888"> * Jalview is distributed in the hope that it will be useful, but </span>
+<span style="color: #888888"> * WITHOUT ANY WARRANTY; without even the implied warranty </span>
+<span style="color: #888888"> * of MERCHANTABILITY or FITNESS FOR A PARTICULAR </span>
+<span style="color: #888888"> * PURPOSE.  See the GNU General Public License for more details.</span>
+<span style="color: #888888"> * </span>
+<span style="color: #888888"> * You should have received a copy of the GNU General Public License</span>
+<span style="color: #888888"> * along with Jalview.  If not, see &lt;http://www.gnu.org/licenses/&gt;.</span>
+<span style="color: #888888"> * The Jalview Authors are detailed in the &#39;AUTHORS&#39; file.</span>
+<span style="color: #888888"> */</span>
+<span style="color: #008800; font-weight: bold">import</span> <span
+        style="color: #0e84b5; font-weight: bold">jalview.workers.FeatureCounterI</span><span
+        style="color: #333333">;</span>
+<span style="color: #008800; font-weight: bold">import</span> <span
+        style="color: #0e84b5; font-weight: bold">jalview.workers.AlignmentAnnotationFactory</span><span
+        style="color: #333333">;</span>
+
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * Example script that registers two alignment annotation calculators</span>
+<span style="color: #888888"> * - one that counts residues in a column with Pfam annotation</span>
+<span style="color: #888888"> * - one that counts only charged residues with Pfam annotation</span>
+<span style="color: #888888"> *</span>
+<span style="color: #888888"> * To try:</span>
+<span style="color: #888888"> * 1. load uniref50.fa from the examples folder</span>
+<span style="color: #888888"> * 2. load features onto it from from examples/exampleFeatures.txt</span>
+<span style="color: #888888"> * 3. Open this script in the Groovy console.</span>
+<span style="color: #888888"> * 4. Either execute this script from the console, or via Calculate-&gt;Run Groovy Script</span>
+<span style="color: #888888"> </span>
+<span style="color: #888888"> * To explore further, try changing this script to count other kinds of occurrences of </span>
+<span style="color: #888888"> * residue and sequence features at columns in an alignment.</span>
+<span style="color: #888888"> */</span>
+
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * A closure that returns true for any Charged residue</span>
+<span style="color: #888888"> */</span>
+<span style="color: #333399; font-weight: bold">def</span> isCharged <span
+        style="color: #333333">=</span> <span style="color: #333333">{</span> residue <span
+        style="color: #333333">-&gt;</span>
+    <span style="color: #008800; font-weight: bold">switch</span><span
+        style="color: #333333">(</span>residue<span
+        style="color: #333333">)</span> <span style="color: #333333">{</span>
+        <span style="color: #008800; font-weight: bold">case</span> <span
+        style="color: #333333">[</span><span
+        style="background-color: #fff0f0">&#39;D&#39;</span><span
+        style="color: #333333">,</span> <span
+        style="background-color: #fff0f0">&#39;d&#39;</span><span
+        style="color: #333333">,</span> <span
+        style="background-color: #fff0f0">&#39;E&#39;</span><span
+        style="color: #333333">,</span> <span
+        style="background-color: #fff0f0">&#39;e&#39;</span><span
+        style="color: #333333">,</span> <span
+        style="background-color: #fff0f0">&#39;H&#39;</span><span
+        style="color: #333333">,</span> <span
+        style="background-color: #fff0f0">&#39;h&#39;</span><span
+        style="color: #333333">,</span> <span
+        style="background-color: #fff0f0">&#39;K&#39;</span><span
+        style="color: #333333">,</span> <span
+        style="background-color: #fff0f0">&#39;k&#39;</span><span
+        style="color: #333333">,</span> <span
+        style="background-color: #fff0f0">&#39;R&#39;</span><span
+        style="color: #333333">,</span> <span
+        style="background-color: #fff0f0">&#39;r&#39;</span><span
+        style="color: #333333">]:</span>
+            <span style="color: #008800; font-weight: bold">return</span> <span
+        style="color: #008800; font-weight: bold">true</span>
+    <span style="color: #333333">}</span>
+    <span style="color: #008800; font-weight: bold">false</span>
+<span style="color: #333333">}</span> 
+
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * A closure that returns 1 if sequence features include type &#39;Pfam&#39;, else 0</span>
+<span style="color: #888888"> * Argument should be a list of SequenceFeature </span>
+<span style="color: #888888"> */</span>
+<span style="color: #333399; font-weight: bold">def</span> hasPfam <span
+        style="color: #333333">=</span> <span style="color: #333333">{</span> features <span
+        style="color: #333333">-&gt;</span> 
+    <span style="color: #008800; font-weight: bold">for</span> <span
+        style="color: #333333">(</span>sf <span
+        style="color: #008800; font-weight: bold">in</span> features<span
+        style="color: #333333">)</span>
+    <span style="color: #333333">{</span>
+        <span style="color: #888888">/*</span>
+<span style="color: #888888">         * Here we inspect the type of the sequence feature.</span>
+<span style="color: #888888">         * You can also test sf.description, sf.score, sf.featureGroup,</span>
+<span style="color: #888888">         * sf.strand, sf.phase, sf.begin, sf.end</span>
+<span style="color: #888888">         * or sf.getValue(attributeName) for GFF &#39;column 9&#39; properties</span>
+<span style="color: #888888">         */</span>
+        <span style="color: #008800; font-weight: bold">if</span> <span
+        style="color: #333333">(</span><span
+        style="background-color: #fff0f0">&quot;Pfam&quot;</span><span
+        style="color: #333333">.</span><span style="color: #0000CC">equals</span><span
+        style="color: #333333">(</span>sf<span style="color: #333333">.</span><span
+        style="color: #0000CC">type</span><span style="color: #333333">))</span>
+        <span style="color: #333333">{</span>
+            <span style="color: #008800; font-weight: bold">return</span> <span
+        style="color: #008800; font-weight: bold">true</span>
+        <span style="color: #333333">}</span>
+    <span style="color: #333333">}</span>
+    <span style="color: #008800; font-weight: bold">false</span>
+<span style="color: #333333">}</span>
+
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * Closure that computes an annotation based on </span>
+<span style="color: #888888"> * presence of particular residues and features</span>
+<span style="color: #888888"> * Parameters are</span>
+<span style="color: #888888"> * - the name (label) for the alignment annotation</span>
+<span style="color: #888888"> * - the description (tooltip) for the annotation</span>
+<span style="color: #888888"> * - a closure (groovy function) that tests whether to include a residue</span>
+<span style="color: #888888"> * - a closure that tests whether to increment count based on sequence features  </span>
+<span style="color: #888888"> */</span>
+<span style="color: #333399; font-weight: bold">def</span> getColumnCounter <span
+        style="color: #333333">=</span> <span style="color: #333333">{</span> name<span
+        style="color: #333333">,</span> desc<span style="color: #333333">,</span> acceptResidue<span
+        style="color: #333333">,</span> acceptFeatures <span
+        style="color: #333333">-&gt;</span>
+    <span style="color: #333333">[</span>
+     <span style="color: #997700; font-weight: bold">getName:</span> <span
+        style="color: #333333">{</span> name <span
+        style="color: #333333">},</span> 
+     <span style="color: #997700; font-weight: bold">getDescription:</span> <span
+        style="color: #333333">{</span> desc <span
+        style="color: #333333">},</span>
+     <span style="color: #997700; font-weight: bold">getMinColour:</span> <span
+        style="color: #333333">{</span> <span style="color: #333333">[</span><span
+        style="color: #0000DD; font-weight: bold">0</span><span
+        style="color: #333333">,</span> <span
+        style="color: #0000DD; font-weight: bold">255</span><span
+        style="color: #333333">,</span> <span
+        style="color: #0000DD; font-weight: bold">255</span><span
+        style="color: #333333">]</span> <span style="color: #333333">},</span> <span
+        style="color: #888888">// cyan</span>
+     <span style="color: #997700; font-weight: bold">getMaxColour:</span> <span
+        style="color: #333333">{</span> <span style="color: #333333">[</span><span
+        style="color: #0000DD; font-weight: bold">0</span><span
+        style="color: #333333">,</span> <span
+        style="color: #0000DD; font-weight: bold">0</span><span
+        style="color: #333333">,</span> <span
+        style="color: #0000DD; font-weight: bold">255</span><span
+        style="color: #333333">]</span> <span style="color: #333333">},</span> <span
+        style="color: #888888">// blue</span>
+     <span style="color: #997700; font-weight: bold">count:</span> 
+         <span style="color: #333333">{</span> res<span
+        style="color: #333333">,</span> feats <span
+        style="color: #333333">-&gt;</span> 
+            <span style="color: #333399; font-weight: bold">def</span> c <span
+        style="color: #333333">=</span> <span
+        style="color: #0000DD; font-weight: bold">0</span>
+            <span style="color: #008800; font-weight: bold">if</span> <span
+        style="color: #333333">(</span>acceptResidue<span
+        style="color: #333333">.</span><span style="color: #0000CC">call</span><span
+        style="color: #333333">(</span>res<span style="color: #333333">))</span>
+            <span style="color: #333333">{</span>
+                <span style="color: #008800; font-weight: bold">if</span> <span
+        style="color: #333333">(</span>acceptFeatures<span
+        style="color: #333333">.</span><span style="color: #0000CC">call</span><span
+        style="color: #333333">(</span>feats<span style="color: #333333">))</span>
+                <span style="color: #333333">{</span>
+                    c<span style="color: #333333">++</span>
+                <span style="color: #333333">}</span>
+            <span style="color: #333333">}</span>
+            c
+         <span style="color: #333333">}</span>
+     <span style="color: #333333">]</span> <span
+        style="color: #008800; font-weight: bold">as</span> FeatureCounterI
+<span style="color: #333333">}</span>
+
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * Define an annotation row that counts any residue with Pfam domain annotation</span>
+<span style="color: #888888"> */</span>
+<span style="color: #333399; font-weight: bold">def</span> pfamAnnotation <span
+        style="color: #333333">=</span> getColumnCounter<span
+        style="color: #333333">(</span><span
+        style="background-color: #fff0f0">&quot;Pfam&quot;</span><span
+        style="color: #333333">,</span> <span
+        style="background-color: #fff0f0">&quot;Count of residues with Pfam domain annotation&quot;</span><span
+        style="color: #333333">,</span> <span style="color: #333333">{</span><span
+        style="color: #008800; font-weight: bold">true</span><span
+        style="color: #333333">},</span> hasPfam<span
+        style="color: #333333">)</span>
+
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * Define an annotation row that counts charged residues with Pfam domain annotation</span>
+<span style="color: #888888"> */</span>
+<span style="color: #333399; font-weight: bold">def</span> chargedPfamAnnotation <span
+        style="color: #333333">=</span> getColumnCounter<span
+        style="color: #333333">(</span><span
+        style="background-color: #fff0f0">&quot;Pfam charged&quot;</span><span
+        style="color: #333333">,</span> <span
+        style="background-color: #fff0f0">&quot;Count of charged residues with Pfam domain annotation&quot;</span><span
+        style="color: #333333">,</span> isCharged<span
+        style="color: #333333">,</span> hasPfam<span
+        style="color: #333333">)</span>
+
+<span style="color: #888888">/*</span>
+<span style="color: #888888"> * Register the annotations</span>
+<span style="color: #888888"> */</span>
+AlignmentAnnotationFactory<span style="color: #333333">.</span><span
+        style="color: #0000CC">newCalculator</span><span
+        style="color: #333333">(</span>pfamAnnotation<span
+        style="color: #333333">)</span> 
+AlignmentAnnotationFactory<span style="color: #333333">.</span><span
+        style="color: #0000CC">newCalculator</span><span
+        style="color: #333333">(</span>chargedPfamAnnotation<span
+        style="color: #333333">)</span>
+</pre>
+  </div>
+</body>
+</html>
index f8f4889..6f91d2f 100755 (executable)
@@ -25,8 +25,8 @@
 
 <body>
   <p>
-    <strong>Alignment Window Annotations Menu</strong> (Since Jalview
-    2.8.2)
+    <strong>Alignment Window Annotations Menu</strong> <em>Since Jalview
+    2.8.2</em>
   </p>
   <ul>
     <li><strong>Show Alignment Related</strong><em><br>
index ad9596a..7d07595 100755 (executable)
     <li><strong>Annotation Label Popup Menu</strong><br> <em>This
         menu is opened by clicking anywhere on the annotation row labels
         area (below the sequence ID area).</em>
+        <br/><em><strong>Mac Users:</strong> pressing CTRL whilst clicking
+      the mouse/track pad is the same as a right-click. See your
+      system's settings to configure your track-pad's corners to
+      generate right-clicks.</em>
       <ul>
         <li><strong>Add New Row</strong><br> <em>Adds a
             new, named annotation row (a dialog box will pop up for you
index cbc4217..fcfcdae 100755 (executable)
   <p>
     The <a href="popupMenu.html">Popup Menus</a> are opened by clicking
     with the right mouse button in the alignment display area or on a
-    sequence label in the alignment window.
+    sequence label in the alignment window.<br />
+    <em><strong>Mac Users:</strong> pressing CTRL whilst clicking
+      the mouse/track pad is the same as a right-click. See your
+      system's settings to configure your track-pad's corners to
+      generate right-clicks.</em>
   </p>
   <p>
     The <a href="alwannotationpanel.html">Annotations Menu</a> is opened
index 353fb41..79e7ada 100755 (executable)
 
 <body>
   <p>
-    <strong>Popup Menu</strong><br> <em>This menu is visible
-      when right clicking either within a selected region on the
-      alignment or on a selected sequence name. It may not be accessible
-      when in 'Cursor Mode' (toggled with the F2 key).</em>
+    <strong>Popup Menu</strong><br> <em>This menu is visible when
+      right clicking either within a selected region on the alignment or
+      on a selected sequence name. It may not be accessible when in
+      'Cursor Mode' (toggled with the F2 key).</em><br /> <em><strong>Mac Users:</strong> pressing CTRL whilst clicking
+        the mouse/track pad is the same as a right-click. See your
+        system's settings to configure your track-pad's corners to
+        generate right-clicks.</em>
   </p>
   <ul>
     <li><strong>Selection</strong>
       </ul></li>
     <li><strong>3D Structure Data...</strong> </strong><em>This menu is
         visible when you right-click on a sequence name. When this
-        option is clicked, Jalview will open a <a
-        href="../features/structurechooser.html"
-      >'Structure Chooser' </a> dialogue with options to select the
-        structure which will eventually be opened in a 3D interactive
-        view.<br> These entries will only be present if the
-        sequence has <a href="../features/viewingpdbs.html">associated
-          PDB structures</a>.
+        option is clicked, Jalview will open the <a
+        href="../features/structurechooser.html">'Structure
+          Chooser' </a>, which allows you to discover and view 3D structures
+        for the current selection. For more info, see <a
+        href="../features/viewingpdbs.html">viewing PDB structures</a>.
     </em></li>
     <li><strong>VARNA 2D Structure</strong><br />
     <em> If the sequence or alignment has RNA structure, then <strong>VARNA
index 22ea27e..1d17058 100644 (file)
@@ -79,7 +79,7 @@ td {
     the alignment will have a secondary structure line shown below it,
     and a number of additional options become available:
   <ul>
-    <li><a href="../colourschemes/rnahelicesColouring.html">RNA
+    <li><a href="../colourSchemes/rnahelicesColouring.html">RNA
         Helix colouring</a> - highlights columns of alignment involved in
       particular RNA helices, Uses the first displayed secondary
       structure annotation.</li>
index c4a8bab..3a8c9f9 100755 (executable)
     <tr>
       <td width="60" nowrap>
         <div align="center">
-          <strong><a name="Jalview.2.10.0">2.10.0</a><br /> <em>13/9/2016</em></strong>
+          <strong><a name="Jalview.2.10.0">2.10.0</a><br /> <em>04/10/2016</em></strong>
         </div>
       </td>
       <td><em>General</em>
         <ul>
-            <li><!-- JAL---></li>
+            <li><!-- JAL-2164,JAL-1919,JAL-2148 -->Jmol now primary parser for importing structure data to Jalview. Enables mmCIF and better PDB parsing.</li>
             <li><!-- JAL-192 --->Alignment ruler shows positions relative to reference sequence</li>
+            <li><!-- JAL-2202 -->Position/residue shown in status bar when mousing over sequence associated annotation</li>
+            <li><!-- JAL-2171 -->Default RNA SS symbol to 'matching bracket' for manual entry</li>
+            <li><!-- JAL-2214 -->RNA Structure consensus indicates wc-only '()', canonical '[]' and invalid '{}' base pair populations for each column</li>
+            <li><!-- JAL-2092 -->Feature settings popup menu options for showing or hiding columns containing a feature</li>
+            <li><!-- JAL-1557 -->Edit selected group by double clicking on group and sequence associated annotation labels</li>
+            <li><!-- JAL-2236 -->Sequence name added to annotation label in select/hide columns by annotation and colour by annotation dialogs</li>
+            
         </ul> <em>Application</em>
         <ul>
-            <li><!-- JAL---></li>
-            <li><!-- JAL---></li>
-            <li><!-- JAL---></li>
-            <li><!-- JAL---></li>
-            <li><!-- JAL---></li>
-            <li><!-- JAL---></li>
+            <li><!-- JAL-2050-->Automatically hide introns when opening a gene/transcript view</li>
+            <li><!-- JAL-1563 -->Uniprot Sequence fetcher Free Text Search dialog</li>
+            <li><!--  JAL-1957, JAL-1479 JAL-1491 -->UniProt - PDB protein structure mappings with the EMBL-EBI PDBe SIFTS database</li>          
+            <li><!-- JAL-2079 -->Updated download sites used for Rfam and Pfam sources to xfam.org</li>
+            <li><!-- JAL-2084 -->Disabled Rfam(Full) in the sequence fetcher</li>
             <li><!-- JAL-2123 -->Show residue labels in Chimera when mousing over sequences in Jalview</li>
             <li><!-- JAL-2027-->Support for reverse-complement coding regions in ENA and EMBL</li>
-            <li><!-- JAL-1855, JAL-2113, JAL-2114-->Upgrade to EMBL XML 1.2 for ENA record retrieval</li>
-            <li><!--  JAL 1812 -->New 'execute Groovy script' option in an alignment window's Calculate menu</li>
-            <li><!--  JAL 1812 -->Allow groovy scripts that call Jalview.getAlignFrames() to run in headless mode</li>
+            <li><!-- JAL-1855, JAL-2113, JAL-2114-->Upgrade to EMBL XML 1.2 for record retrieval via ENA rest API</li>
+            <li><!-- JAL-2027 -->Support for ENA CDS records with reverse complement operator</li>
+            <li><!--  JAL-1812 -->Update to groovy-2.4.6-indy - for faster groovy script execution</li>
+            <li><!--  JAL-1812 -->New 'execute Groovy script' option in an alignment window's Calculate menu</li>
+            <li><!--  JAL-1812 -->Allow groovy scripts that call Jalview.getAlignFrames() to run in headless mode</li>
+            <li><!--  JAL-2068 -->Support for creating new alignment calculation workers from groovy scripts</li>
             <li><!-- JAL-1369 --->Store/restore reference sequence in Jalview projects</li>
+            <li><!-- JAL-1803 -->Chain codes for a sequence's PDB associations are now saved/restored from project</li>
+            <li><!-- JAL-1993 -->Database selection dialog always shown before sequence fetcher is opened</li>
+            <li><!-- JAL-2183 -->Double click on an entry in Jalview's database chooser opens a sequence fetcher</li>
+            <li><!-- JAL-1563 -->Free-text search client for UniProt using the UniProt REST API</li>
+            <li><!-- JAL-2168 -->-nonews command line parameter to prevent the news reader opening</li>
+            <li><!-- JAL-2028 -->Displayed columns for PDBe and Uniprot querying stored in preferences</li>
+            <li><!-- JAL-2091 -->Pagination for displaying PDBe and Uniprot search results</li>
+            <li><!-- JAL-1977-->Tooltips shown on database chooser</li>
+            <li><!--  JAL-391 -->Reverse complement function in calculate menu for nucleotide sequences</li>
+            <li>
+              <!-- JAL-2005, JAL-599 -->Alignment sort by feature scores and feature counts preserves alignment ordering (and debugged for complex feature sets).  
+            </li>
+            <li>
+              <!-- -->   
+            </li>
+            <li>
+              <!-- JAL- -->  
+            </li>
+            <li>
+              <!-- JAL- -->  
+            </li>
+            <li>
+              <!-- JAL- -->  
+            </li>
+                    
              
         </ul> <em>Applet</em>
         <ul>
             <li><!-- JAL-2077 -->reinstate CTRL-click for opening pop-up menu on OSX</li>
             <li><!-- JAL-2018-->Export features in Jalview format (again) includes graduated colourschemes</li>
             <li><!-- JAL-1722, JAL-2001-->More responsive when working with big alignments and lots of hidden columns</li>
-            <li><!-- JAL-2053-->hidden column markers not always rendered at right of alignment window</li>
-            <li><!-- JAL-2067, JAL-  -->Tidied up links in help file table of contents</li>
+            <li><!-- JAL-2053-->Hidden column markers not always rendered at right of alignment window</li>
+            <li><!-- JAL-2067 -->Tidied up links in help file table of contents</li>
             <li><!-- JAL-2072  -->Feature based tree calculation not shown for DNA alignments</li>
             <li><!-- JAL-2075  -->Hidden columns ignored during feature based tree calculation</li>
             <li><!-- JAL-2065  -->Alignment view stops updating when show unconserved enabled for group on alignment</li>
             <li><!--  JAL-2086  -->Cannot insert gaps into sequence when set as reference</li>
-            
+            <li><!-- JAL-2146 -->Alignment column in status incorrectly shown as &quot;Sequence position&quot; when mousing over annotation</li>
+            <li><!--  JAL-2099 -->Incorrect column numbers in ruler when hidden columns present</li>
+            <li><!--  JAL-1577 -->Colour by RNA Helices not enabled when user created annotation added to alignment</li>
+            <li><!-- JAL-1841 -->RNA Structure consensus only computed for '()' base pair annotation</li>
+            <li><!-- JAL-2215, JAL-1841 -->Enabling 'Ignore Gaps' results in zero scores for all base pairs in RNA Structure Consensus</li>
+            <li><!-- JAL-2174-->Extend selection with columns containing feature not working</li>
+            <li><!-- JAL-2275 -->Pfam format writer puts extra space at beginning of sequence</li>            
+            <li><!-- JAL-1827 -->Incomplete sequence extracted from pdb entry 3a6s </li>
+            <li><!-- JAL-2238 -->Cannot create groups on an alignment from from a tree when t-coffee scores are shown</li>
+            <li><!-- JAL-1836,1967 -->Cannot import and view PDB structures with chains containing negative resnums (4q4h)</li>
+            <li><!--  JAL-1998 -->ArithmeticExceptions raised when parsing some structures</li>
+            <li><!--  JAL-1991, JAl-1952 -->'Empty' alignment blocks added to Clustal, PIR and PileUp output</li>
+            <li><!--  JAL-2008 -->Reordering sequence features that are not visible causes alignment window to repaint</li>
+            <li>
+              <!--  JAL-2006 -->Threshold sliders don't work in
+              graduated colour and colour by annotation row for e-value
+              scores associated with features and annotation rows
+            </li>
+            <li>
+              <!-- JAL-1797 -->amino acid physicochemical conservation
+              calculation should be case independent
+            </li>
+            <li>
+              <!-- JAL-2173 -->Remove annotation also updates hidden
+              columns
+            </li>
+            <li>
+              <!-- JAL-2234 -->FER1_ARATH and FER2_ARATH mislabelled in example file (uniref50.fa, feredoxin.fa, unaligned.fa, exampleFile_2_7.jar, exampleFile.jar, exampleFile_2_3.jar)
+            </li>
+            <li>
+              <!-- JAL-2065 -->Null pointer exceptions and redraw problems when reference sequence defined and 'show non-conserved' enabled
+            </li>
+            <li><!-- JAL-1306 -->Quality and Conservation are now shown on load even when Consensus calculation is disabled</li>
+            <li>
+              <!-- JAL- -->
+            </li>
+            <li>
+              <!-- JAL- -->
+            </li>
+            <li>
+              <!-- JAL- -->
+            </li>
           </ul>
           <em>Application</em>
           <ul>
             <li><!--  JAL-1011  -->Columns are suddenly selected in other alignments and views when revealing hidden columns</li>
             <li><!--  JAL-1989  -->Hide columns not mirrored in complement view in a cDNA/Protein splitframe</li>
             <li><!--  JAL-1369 -->Cannot save/restore representative sequence from project when only one sequence is represented</li>
+            <li><!-- JAL-2002 -->Disabled 'Best Uniprot Coverage' option in Structure Chooser</li>
+            <li><!-- JAL-2215 -->Modifying 'Ignore Gaps' on consensus or structure consensus didn't refresh annotation panel</li>
+            <li><!-- JAL-1962 -->View mapping in structure view shows mappings between sequence and all chains in a PDB file</li>   
+            <li><!-- JAL-2102, JAL-2101, JAL-2102, -->PDB and Uniprot FTS dialogs format columns correctly, don't display array data, sort columns according to type</li>
+            <li><!-- JAL-1975 -->Export complete shown after destination file chooser is cancelled during an image export </li>
+            <li><!-- JAL-2025 -->Error when querying PDB Service with sequence name containing special characters</li>
+            <li><!-- JAL-2024 -->Manual PDB structure querying should be case insensitive</li>
+            <li><!-- JAL-2104 -->Large tooltips with broken HTML formatting don't wrap</li>
+            <li><!-- JAL-1128 -->Figures exported from wrapped view are truncated so L looks like I in consensus annotation</li>
+            <li><!-- JAL-2003 -->Export features should only export the currently displayed features for the current selection or view</li>
+            <li><!-- JAL-2036 -->Enable 'Get Cross-References' in menu after fetching cross-references</li>
+            <li><!-- JAL-2032 -->Mouseover of a copy of a sequence is not followed in the structure viewer</li>
+            <li><!-- JAL-2163 -->Titles for individual alignments in splitframe not restored from project</li>
+            <li>
+              <!-- JAL-2145 -->missing autocalculated annotation at trailing end of protein alignment in transcript/product splitview when pad-gaps not enabled by default
+            </li>
+            <li>
+              <!-- JAL-1797 -->amino acid physicochemical conservation is case dependent
+            </li>
+            <li>
+              <!-- JAL-1448 -->RSS reader doesn't stay hidden after last article has been read (reopened issue due to internationalisation problems)
+            </li>
+            <li><!-- JAL-1960 -->Only offer PDB structures in structure viewer based on sequence name, PDB and Uniprot cross-references</li>
+            
+            <li>
+              <!-- JAL-1976 -->No progress bar shown during export of alignment as HTML
+            </li>
+            <li>
+              <!-- JAL-2213,JAL-1856 -->Improved warning messages when DB Ref Fetcher fails to match, or otherwise updates sequence data from external database records.
+            </li>
+            <li>
+              <!-- JAL-2213 -->Structures not always superimposed after multiple structures are shown for one or more sequences.
+            </li>
+            <li>
+              <!-- JAL-1370 -->Reference sequence characters should not be replaced with '.' when 'Show unconserved' format option is enabled.
+            </li>
+            <li>
+              <!-- JAL-1823 -->Cannot specify chain code when entering specific PDB id for sequence
+            </li>
+            <li>
+              <!-- JAL-1944 -->File->Export->.. as doesn't work when 'Export hidden sequences' is enabled, but 'export hidden columns' is disabled. 
+            </li>
+            <li><!--JAL-2026-->Best Quality option in structure chooser selects lowest rather than highest resolution structures for each sequence</li>
+            <li>
+              <!-- JAL-1887 -->Incorrect start and end reported for PDB to sequence mapping in 'View Mappings' report
+            </li>
+            <li>
+              <!-- JAL- -->
+            </li>
+            <li>
+              <!-- JAL- -->
+            </li>
+
             <!--  may exclude, this is an external service stability issue  JAL-1941 /> RNA 3D structure not added via DSSR service</li> -->
           </ul>
           <em>Applet</em>
           <ul>
-            <li><!--  --></li>
+            <li><!-- JAL-2151 -->Incorrect columns are selected when hidden columns present before start of sequence</li>
+            <li><!-- JAL-1986 -->Missing dependencies on applet pages (JSON jars)</li>
+            <li>
+              <!-- JAL-1947 -->Overview pixel size changes when sequences are hidden in applet
+            </li>
+            <li><!-- JAL-1996 -->Updated instructions for applet deployment on examples pages.
+            </li>
           </ul>
         </div>
       </td>
index 5ec088a..1f2b7c9 100644 (file)
       href="http://jswingreader.sourceforge.net/"
     >JSwingReader</a>.
   </p>
-  <br/><em>From Jalview 2.10.0, check for news on startup can be disabled with <a href="../features/clarguments.html">command-line parameter</a> &#39;-nonews&#39;. 
-  This is not recommended for normal use, but may be useful to avoid interruptions when teaching, demonstrating, recording etc.</em>
+  <br />
+  <em>If you need to prevent the news-reader opening, then add the
+    <a href="../features/clarguments.html">command-line parameter</a>
+    &#39;-nonews&#39; to Jalview's command-line launch.
+  </em>
 </body>
 </html>
index 407eca3..1743f1c 100755 (executable)
   <p>
     <strong>Highlights in Jalview 2.10</strong>
   <ul>
-    <li><strong>Ensembl sequence fetcher.</strong> Annotated Genes, transcripts and
-      proteins can be retrieved via Jalview's new Ensembl REST client.</li>
-    <li><strong>Improved sequence/structure mappings.</strong>
-      Jalview now utilises the PDBe's SIFTS database (at EMBL-EBI) to
-      match PDB data positions in UniProt sequences.</li>
+    <li><strong>Ensembl sequence fetcher.</strong> 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>Sequence variant data.</strong> Jalview
+          propagates variant annotation on genomic regions onto transcripts and
+          protein products, complete with associated metadata such as
+          clinical significance.</li>
+        <li><strong>Aligned locus view.</strong> 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>
+      </ul></li>
+    <li><strong>Working with structures.</strong>
+      <ul>
+        <li><strong>More accurate structure mappings.</strong>
+          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>. 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>
+      </ul></li>
+    <li><strong>UniProt Free Text Search.</strong> The new search
+      dialog for UniProt allows you to browse and retrieve sequences
+      from UniProt with free-text search and more structured queries</li>
+    <li><strong>Reference sequence alignment view.</strong>.
+      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>Ensembl and ENA 'show cross-references'
+        support.</strong>The Calculations menu's 'Show cross-references' will now
+      offer Ensembl as well as EMBLCDS and Uniprot when CDS/Protein
+      mapping data is available for download or display.</li>
   </ul>
 
 </body>
index 01b921a..7e494b4 100644 (file)
@@ -26,6 +26,7 @@
          see ftp://ftp.sra.ebi.ac.uk/meta/xsd/sra_1_5/ENA.embl.xsd
          see http://www.ebi.ac.uk/ena/submit/data-formats
        -->
+       <!--
        <class name="jalview.datamodel.xdb.embl.EmblFile">
                <map-to xml="ROOT"/>
                <field name="entries" type="jalview.datamodel.xdb.embl.EmblEntry" collection="vector">
@@ -35,7 +36,9 @@
                        <bind-xml name="Error"/>
                </field>
        </class>
+       -->
        <class name="jalview.datamodel.xdb.embl.EmblEntry">
+               <map-to xml="entry"/>
                <field name="accession" type="string">
                        <bind-xml name="accession" node="attribute"/>
                </field>
index 5ac50bb..278b86e 100644 (file)
@@ -44,7 +44,7 @@ _data_column.preferred_col_width
 _data_column.is_shown_by_default
 _data_column.is_searchable
 PDB Id;pdb_id;String;g2;40;60;45;true;true
-Title;title;String;g6;300;1500;400;true;false
+Title;title;String;g6;50;1500;400;true;false
 Molecule;molecule_name;String;g3;50;400;95;false;true
 Molecule Type;molecule_type;String;g3;50;400;95;false;true
 Sequence;molecule_sequence;String;g6;50;400;95;false;false
@@ -111,7 +111,7 @@ R Free;r_free;Double|T|3;g1;50;150;85;false;false
 Number of Polymer Entities;number_of_polymer_entities;int;g6;50;400;95;false;false
 Number of Bound Entities;number_of_bound_entities;int;g6;50;400;95;false;false
 Crystallisation Reservoir;crystallisation_reservoir;String;g6;50;400;95;false;false
-Data Scalling Software;data_scaling_software;String;g4;50;400;95;false;false
+Data Scaling Software;data_scaling_software;String;g4;50;400;95;false;false
 Detector;detector;String;g6;50;400;95;false;false
 Detector Type;detector_type;String;g6;50;400;95;false;false
 Modified Residue Flag;modified_residue_flag;String;g6;50;400;95;false;false
index b01464a..378fb64 100644 (file)
@@ -729,8 +729,8 @@ label.move_url_down = Move URL Down
 label.add_sbrs_definition = Add a SBRS Definition
 label.edit_sbrs_definition = Edit SBRS Definition
 label.delete_sbrs_definition = Delete SBRS Definition
-label.your_sequences_have_been_verified = Your sequences have been verified against known sequence databases. Some of the ids have been\n altered, most likely the start/end residue will have been updated.\n Save your alignment to maintain the updated id.\n\n
-label.sequence_names_updated = Sequence names updated
+label.your_sequences_have_been_verified = Your sequences have been verified against known sequence databases.\n(Use Calculate | Show flanking regions to show enclosing sequence.)\nTo preserve data changes, save your alignment.\n\n
+label.sequences_updated = Sequences updated
 label.dbref_search_completed = DBRef search completed
 label.show_all_chains = Show all chains
 label.fetch_all_param = Fetch all {0}
@@ -772,7 +772,7 @@ label.select_backgroud_colour = Select Background Colour
 label.invalid_font = Invalid Font
 label.separate_multiple_accession_ids = Enter one or more accession IDs separated by a semi-colon ";"
 label.separate_multiple_query_values = Enter one or more {0}s separated by a semi-colon ";"
-label.search_all = Enter one or more search values separated by a semi-colon ";" (Note: This Searches the entire database)
+label.search_all = Enter one or more search values separated by a semi-colon ";" (Note: This searches the entire database)
 label.replace_commas_semicolons = Replace commas with semi-colons
 label.parsing_failed_syntax_errors_shown_below_param = Parsing failed. Syntax errors shown below {0}
 label.parsing_failed_unrecoverable_exception_thrown_param = \nParsing failed. An unrecoverable exception was thrown\:\n {0}
index 87538be..7bea515 100644 (file)
@@ -674,8 +674,8 @@ label.move_url_down = Mover la URL hacia abajo
 label.add_sbrs_definition = Añadir una definición SBRS 
 label.edit_sbrs_definition = Editar una definición SBRS 
 label.delete_sbrs_definition = Borrar una definición SBRS 
-label.your_sequences_have_been_verified = Sus secuencias has sido verificadas en una base de datos de secuencias conocidas. Algunos de sus ID se han alterado y\n, probablemente, el residuo de inicio/fin se haya actualizado.\nGuarde su alineamiento para mantener el ID actualizado.\n\n 
-label.sequence_names_updated = Nombres de secuencia actualizados
+label.your_sequences_have_been_verified = Sus secuencias has sido verificadas en una base de datos de secuencias conocidas.\n(Usar Calcular | Mostrar flancos para ver ampliación.)\nPara mantener los datos actualizados, guarde su alineamiento.\n\n 
+label.sequences_updated = Secuencias actualizadas
 label.dbref_search_completed = Búsqueda de DBRef terminada
 label.show_all_chains = Mostrar todas las cadenas
 label.fetch_all_param = Recuperar todas {0}
index c0c7c46..fdcf34f 100644 (file)
@@ -27,6 +27,10 @@ import ext.edu.ucsf.rbvi.strucviz2.port.ListenerThreads;
  */
 public class ChimeraManager
 {
+  private static final int REST_REPLY_TIMEOUT_MS = 15000;
+
+  private static final int CONNECTION_TIMEOUT_MS = 100;
+
   private static final boolean debug = false;
 
   private int chimeraRestPort;
@@ -782,8 +786,8 @@ public class ChimeraManager
     BufferedReader response = null;
     try
     {
-      response = HttpClientUtils
-              .doHttpUrlPost(restUrl, commands, 100, 5000);
+      response = HttpClientUtils.doHttpUrlPost(restUrl, commands, CONNECTION_TIMEOUT_MS,
+              REST_REPLY_TIMEOUT_MS);
       String line = "";
       while ((line = response.readLine()) != null)
       {
index ea330d8..c521d9b 100644 (file)
@@ -1731,8 +1731,7 @@ public class AlignmentUtils
            */
           AlignedCodonFrame dnaToCdsMapping = new AlignedCodonFrame();
           MapList dnaToCdsMap = new MapList(mapList.getFromRanges(),
-                  cdsRange, 1,
-                  1);
+                  cdsRange, 1, 1);
           dnaToCdsMapping.addMap(dnaSeq.getDatasetSequence(), cdsSeqDss,
                   dnaToCdsMap);
           if (!mappings.contains(dnaToCdsMapping))
@@ -1786,7 +1785,7 @@ public class AlignmentUtils
           /*
            * transfer any features on dna that overlap the CDS
            */
-          transferFeatures(dnaSeq, cdsSeq, cdsToProteinMap, null,
+          transferFeatures(dnaSeq, cdsSeq, dnaToCdsMap, null,
                   SequenceOntologyI.CDS);
         }
       }
index 21d990c..711710b 100755 (executable)
@@ -24,11 +24,12 @@ import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
+import jalview.schemes.ResidueProperties;
 
 import java.awt.Color;
-import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Map;
 import java.util.Vector;
 
 /**
@@ -45,13 +46,14 @@ public class Conservation
 
   int end;
 
-  Vector seqNums; // vector of int vectors where first is sequence checksum
+  Vector<int[]> seqNums; // vector of int vectors where first is sequence
+                         // checksum
 
   int maxLength = 0; // used by quality calcs
 
   boolean seqNumsChanged = false; // updated after any change via calcSeqNum;
 
-  Hashtable[] total;
+  Map<String, Integer>[] total;
 
   boolean canonicaliseAa = true; // if true then conservation calculation will
 
@@ -60,22 +62,18 @@ public class Conservation
   // symbol
 
   /** Stores calculated quality values */
-  public Vector quality;
+  private Vector<Double> quality;
 
   /** Stores maximum and minimum values of quality values */
-  public Double[] qualityRange = new Double[2];
+  private double[] qualityRange = new double[2];
 
-  String consString = "";
+  private Sequence consSequence;
 
-  Sequence consSequence;
+  private int threshold;
 
-  Hashtable propHash;
+  private String name = "";
 
-  int threshold;
-
-  String name = "";
-
-  int[][] cons2;
+  private int[][] cons2;
 
   private String[] consSymbs;
 
@@ -84,8 +82,6 @@ public class Conservation
    * 
    * @param name
    *          Name of conservation
-   * @param propHash
-   *          hash of properties for each symbol
    * @param threshold
    *          to count the residues in residueHash(). commonly used value is 3
    * @param sequences
@@ -95,11 +91,10 @@ public class Conservation
    * @param end
    *          end residue position
    */
-  public Conservation(String name, Hashtable propHash, int threshold,
+  public Conservation(String name, int threshold,
           List<SequenceI> sequences, int start, int end)
   {
     this.name = name;
-    this.propHash = propHash;
     this.threshold = threshold;
     this.start = start;
     this.end = end;
@@ -151,7 +146,7 @@ public class Conservation
         seqNums.addElement(new int[sq.length() + 1]);
       }
 
-      if (sq.hashCode() != ((int[]) seqNums.elementAt(i))[0])
+      if (sq.hashCode() != seqNums.elementAt(i)[0])
       {
         int j;
         int len;
@@ -193,12 +188,9 @@ public class Conservation
    */
   public void calculate()
   {
-    Hashtable resultHash, ht;
     int thresh, j, jSize = sequences.length;
     int[] values; // Replaces residueHash
-    String type, res = null;
     char c;
-    Enumeration enumeration2;
 
     total = new Hashtable[maxLength];
 
@@ -214,8 +206,7 @@ public class Conservation
 
           if (canonicaliseAa)
           { // lookup the base aa code symbol
-            c = (char) jalview.schemes.ResidueProperties.aaIndex[sequences[j]
-                    .getCharAt(i)];
+            c = (char) ResidueProperties.aaIndex[sequences[j].getCharAt(i)];
             if (c > 20)
             {
               c = '-';
@@ -223,7 +214,7 @@ public class Conservation
             else
             {
               // recover canonical aa symbol
-              c = jalview.schemes.ResidueProperties.aa[c].charAt(0);
+              c = ResidueProperties.aa[c].charAt(0);
             }
           }
           else
@@ -249,21 +240,18 @@ public class Conservation
       thresh = (threshold * (jSize)) / 100;
 
       // loop over all the found residues
-      resultHash = new Hashtable();
+      Hashtable<String, Integer> resultHash = new Hashtable<String, Integer>();
       for (char v = '-'; v < 'Z'; v++)
       {
 
         if (values[v] > thresh)
         {
-          res = String.valueOf(v);
+          String res = String.valueOf(v);
 
           // Now loop over the properties
-          enumeration2 = propHash.keys();
-
-          while (enumeration2.hasMoreElements())
+          for (String type : ResidueProperties.propHash.keySet())
           {
-            type = (String) enumeration2.nextElement();
-            ht = (Hashtable) propHash.get(type);
+            Map<String, Integer> ht = ResidueProperties.propHash.get(type);
 
             // Have we ticked this before?
             if (!resultHash.containsKey(type))
@@ -277,7 +265,7 @@ public class Conservation
                 resultHash.put(type, ht.get("-"));
               }
             }
-            else if (((Integer) resultHash.get(type)).equals(ht.get(res)) == false)
+            else if (!resultHash.get(type).equals(ht.get(res)))
             {
               resultHash.put(type, new Integer(-1));
             }
@@ -364,7 +352,7 @@ public class Conservation
    * Calculates the conservation sequence
    * 
    * @param consflag
-   *          if true, poitiveve conservation; false calculates negative
+   *          if true, positive conservation; false calculates negative
    *          conservation
    * @param percentageGaps
    *          commonly used value is 25
@@ -372,13 +360,6 @@ public class Conservation
   public void verdict(boolean consflag, float percentageGaps)
   {
     StringBuffer consString = new StringBuffer();
-    String type;
-    Integer result;
-    int[] gapcons;
-    int totGaps, count;
-    float pgaps;
-    Hashtable resultHash;
-    Enumeration enumeration;
 
     // NOTE THIS SHOULD CHECK IF THE CONSEQUENCE ALREADY
     // EXISTS AND NOT OVERWRITE WITH '-', BUT THIS CASE
@@ -390,26 +371,23 @@ public class Conservation
     consSymbs = new String[end - start + 1];
     for (int i = start; i <= end; i++)
     {
-      gapcons = countConsNGaps(i);
-      totGaps = gapcons[1];
-      pgaps = ((float) totGaps * 100) / sequences.length;
+      int[] gapcons = countConsNGaps(i);
+      int totGaps = gapcons[1];
+      float pgaps = ((float) totGaps * 100) / sequences.length;
       consSymbs[i - start] = new String();
 
       if (percentageGaps > pgaps)
       {
-        resultHash = total[i - start];
+        Map<String, Integer> resultHash = total[i - start];
         // Now find the verdict
-        count = 0;
-        enumeration = resultHash.keys();
-
-        while (enumeration.hasMoreElements())
+        int count = 0;
+        for (String type : resultHash.keySet())
         {
-          type = (String) enumeration.nextElement();
-          result = (Integer) resultHash.get(type);
+          int result = resultHash.get(type).intValue();
           // Do we want to count +ve conservation or +ve and -ve cons.?
           if (consflag)
           {
-            if (result.intValue() == 1)
+            if (result == 1)
             {
               consSymbs[i - start] = type + " " + consSymbs[i - start];
               count++;
@@ -417,19 +395,16 @@ public class Conservation
           }
           else
           {
-            if (result.intValue() != -1)
+            if (result != -1)
             {
+              if (result == 0)
               {
-                if (result.intValue() == 0)
-                {
-                  consSymbs[i - start] = consSymbs[i - start] + " !" + type;
-                }
-                else
-                {
-                  consSymbs[i - start] = type + " " + consSymbs[i - start];
-                }
+                consSymbs[i - start] = consSymbs[i - start] + " !" + type;
+              }
+              else
+              {
+                consSymbs[i - start] = type + " " + consSymbs[i - start];
               }
-
               count++;
             }
           }
@@ -474,7 +449,7 @@ public class Conservation
    */
   private void percentIdentity2()
   {
-    seqNums = new Vector();
+    seqNums = new Vector<int[]>();
     // calcSeqNum(s);
     int i = 0, iSize = sequences.length;
     // Do we need to calculate this again?
@@ -501,7 +476,7 @@ public class Conservation
 
       while (j < sequences.length)
       {
-        sqnum = (int[]) seqNums.elementAt(j);
+        sqnum = seqNums.elementAt(j);
 
         for (i = 1; i < sqnum.length; i++)
         {
@@ -531,17 +506,17 @@ public class Conservation
   /**
    * Calculates the quality of the set of sequences
    * 
-   * @param start
+   * @param startRes
    *          Start residue
-   * @param end
+   * @param endRes
    *          End residue
    */
-  public void findQuality(int start, int end)
+  public void findQuality(int startRes, int endRes)
   {
-    quality = new Vector();
+    quality = new Vector<Double>();
 
     double max = -10000;
-    int[][] BLOSUM62 = jalview.schemes.ResidueProperties.getBLOSUM62();
+    int[][] BLOSUM62 = ResidueProperties.getBLOSUM62();
 
     // Loop over columns // JBPNote Profiling info
     // long ts = System.currentTimeMillis();
@@ -556,10 +531,10 @@ public class Conservation
 
     for (l = 0; l < size; l++)
     {
-      lengths[l] = ((int[]) seqNums.elementAt(l)).length - 1;
+      lengths[l] = seqNums.elementAt(l).length - 1;
     }
 
-    for (j = start; j <= end; j++)
+    for (j = startRes; j <= endRes; j++)
     {
       bigtot = 0;
 
@@ -583,7 +558,7 @@ public class Conservation
       {
         tot = 0;
         xx = new double[24];
-        seqNum = (j < lengths[k]) ? ((int[]) seqNums.elementAt(k))[j + 1]
+        seqNum = (j < lengths[k]) ? seqNums.elementAt(k)[j + 1]
                 : 23; // Sequence, or gap at the end
 
         // This is a loop over r
@@ -617,9 +592,9 @@ public class Conservation
 
     double newmax = -10000;
 
-    for (j = start; j <= end; j++)
+    for (j = startRes; j <= endRes; j++)
     {
-      tmp = ((Double) quality.elementAt(j)).doubleValue();
+      tmp = quality.elementAt(j).doubleValue();
       tmp = ((max - tmp) * (size - cons2[j][23])) / size;
 
       // System.out.println(tmp+ " " + j);
@@ -632,12 +607,12 @@ public class Conservation
     }
 
     // System.out.println("Quality " + s);
-    qualityRange[0] = new Double(0);
-    qualityRange[1] = new Double(newmax);
+    qualityRange[0] = 0D;
+    qualityRange[1] = newmax;
   }
 
   /**
-   * complete the given consensus and quuality annotation rows. Note: currently
+   * Complete the given consensus and quuality annotation rows. Note: currently
    * this method will enlarge the given annotation row if it is too small,
    * otherwise will leave its length unchanged.
    * 
@@ -675,7 +650,7 @@ public class Conservation
 
     char c;
 
-    if (conservation.annotations != null
+    if (conservation != null && conservation.annotations != null
             && conservation.annotations.length < alWidth)
     {
       conservation.annotations = new Annotation[alWidth];
@@ -683,14 +658,14 @@ public class Conservation
 
     if (quality2 != null)
     {
-      quality2.graphMax = qualityRange[1].floatValue();
+      quality2.graphMax = (float) qualityRange[1];
       if (quality2.annotations != null
               && quality2.annotations.length < alWidth)
       {
         quality2.annotations = new Annotation[alWidth];
       }
-      qmin = qualityRange[0].floatValue();
-      qmax = qualityRange[1].floatValue();
+      qmin = (float) qualityRange[0];
+      qmax = (float) qualityRange[1];
     }
 
     for (int i = istart; i < alWidth; i++)
@@ -712,20 +687,23 @@ public class Conservation
         value = 10;
       }
 
-      float vprop = value - min;
-      vprop /= max;
-      int consp = i - start;
-      String conssym = (value > 0 && consp > -1 && consp < consSymbs.length) ? consSymbs[consp]
-              : "";
-      conservation.annotations[i] = new Annotation(String.valueOf(c),
-              conssym, ' ', value, new Color(minR + (maxR * vprop), minG
-                      + (maxG * vprop), minB + (maxB * vprop)));
+      if (conservation != null)
+      {
+        float vprop = value - min;
+        vprop /= max;
+        int consp = i - start;
+        String conssym = (value > 0 && consp > -1 && consp < consSymbs.length) ? consSymbs[consp]
+                : "";
+        conservation.annotations[i] = new Annotation(String.valueOf(c),
+                conssym, ' ', value, new Color(minR + (maxR * vprop), minG
+                        + (maxG * vprop), minB + (maxB * vprop)));
+      }
 
       // Quality calc
       if (quality2 != null)
       {
-        value = ((Double) quality.elementAt(i)).floatValue();
-        vprop = value - qmin;
+        value = quality.elementAt(i).floatValue();
+        float vprop = value - qmin;
         vprop /= qmax;
         quality2.annotations[i] = new Annotation(" ",
                 String.valueOf(value), ' ', value, new Color(minR
@@ -740,9 +718,6 @@ public class Conservation
    * 
    * @param name
    *          - name of conservation
-   * @param consHash
-   *          - hash table of properties for each amino acid (normally
-   *          ResidueProperties.propHash)
    * @param threshold
    *          - minimum number of conserved residues needed to indicate
    *          conservation (typically 3)
@@ -760,35 +735,18 @@ public class Conservation
    * @return Conservation object ready for use in visualization
    */
   public static Conservation calculateConservation(String name,
-          Hashtable consHash, int threshold, List<SequenceI> seqs,
-          int start, int end, boolean posOrNeg, int consPercGaps,
-          boolean calcQuality)
-  {
-    Conservation cons = new Conservation(name, consHash, threshold, seqs,
-            start, end);
-    return calculateConservation(cons, posOrNeg, consPercGaps, calcQuality);
-  }
-
-  /**
-   * @param b
-   *          positive (true) or negative (false) conservation
-   * @param consPercGaps
-   *          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(Conservation cons,
-          boolean b, int consPercGaps, boolean calcQuality)
+          int threshold, List<SequenceI> seqs, int start, int end,
+          boolean posOrNeg, int consPercGaps, boolean calcQuality)
   {
+    Conservation cons = new Conservation(name, threshold, seqs, start, end);
     cons.calculate();
-    cons.verdict(b, consPercGaps);
-
+    cons.verdict(posOrNeg, consPercGaps);
+    
     if (calcQuality)
     {
       cons.findQuality();
     }
-
+    
     return cons;
   }
 }
index 1295b46..cd71bbd 100644 (file)
@@ -24,6 +24,7 @@ import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
 import jalview.datamodel.Mapping;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceFeature;
@@ -106,6 +107,16 @@ public class CrossRef
         findXrefSourcesForSequence(seq, dna, sources);
       }
     }
+    sources.remove(DBRefSource.EMBL); // hack to prevent EMBL xrefs resulting in
+                                      // redundant datasets
+    if (dna)
+    {
+      sources.remove(DBRefSource.ENSEMBL); // hack to prevent Ensembl and
+                                           // EnsemblGenomes xref option shown
+                                           // from cdna panel
+      sources.remove(DBRefSource.ENSEMBLGENOMES);
+    }
+    // redundant datasets
     return sources;
   }
 
@@ -296,20 +307,28 @@ public class CrossRef
               if (!rseqs.contains(matchInDataset))
               {
                 rseqs.add(matchInDataset);
-                // need to try harder to only add unique mappings
-                if (xref.getMap().getMap().isTripletMap()
-                        && dataset.getMapping(seq, matchInDataset) == null
-                        && cf.getMappingBetween(seq, matchInDataset) == null)
+              }
+              // even if rseqs contained matchInDataset - check mappings between
+              // these seqs are added
+              // need to try harder to only add unique mappings
+              if (xref.getMap().getMap().isTripletMap()
+                      && dataset.getMapping(seq, matchInDataset) == null
+                      && cf.getMappingBetween(seq, matchInDataset) == null)
+              {
+                // materialise a mapping for highlighting between these
+                // sequences
+                if (fromDna)
                 {
-                  // materialise a mapping for highlighting between these sequences
-                  if (fromDna)
-                  {
-                    cf.addMap(dss, matchInDataset, xref.getMap().getMap(), xref.getMap().getMappedFromId());
-                  } else {
-                    cf.addMap(matchInDataset, dss, xref.getMap().getMap().getInverse(), xref.getMap().getMappedFromId());
-                  }
+                  cf.addMap(dss, matchInDataset, xref.getMap().getMap(),
+                          xref.getMap().getMappedFromId());
+                }
+                else
+                {
+                  cf.addMap(matchInDataset, dss, xref.getMap().getMap()
+                          .getInverse(), xref.getMap().getMappedFromId());
                 }
               }
+
               refIterator.remove();
               continue;
             }
@@ -393,28 +412,7 @@ public class CrossRef
     // first filter in case we are retrieving crossrefs that have already been
     // retrieved. this happens for cases where a database record doesn't yield
     // protein products for CDS
-    DBRefEntry[] dbrSourceSet = sourceRefs.toArray(new DBRefEntry[0]);
-    for (SequenceI sq : dataset.getSequences())
-    {
-      boolean dupeFound = false;
-      // !fromDna means we are looking only for nucleotide sequences, not
-      // protein
-      if (sq.isProtein() == fromDna)
-      {
-        for (DBRefEntry dbr : sq.getPrimaryDBRefs())
-        {
-          for (DBRefEntry found : DBRefUtils.searchRefs(dbrSourceSet, dbr))
-          {
-            sourceRefs.remove(found);
-            dupeFound = true;
-          }
-        }
-      }
-      if (dupeFound)
-      {
-        dbrSourceSet = sourceRefs.toArray(new DBRefEntry[0]);
-      }
-    }
+    removeAlreadyRetrievedSeqs(sourceRefs, fromDna);
     if (sourceRefs.size() == 0)
     {
       // no more work to do! We already had all requested sequence records in
@@ -434,131 +432,240 @@ public class CrossRef
 
     if (retrieved != null)
     {
-      updateDbrefMappings(seq, xrfs, retrieved, cf, fromDna);
+      boolean addedXref = false;
+      List<SequenceI> newDsSeqs = new ArrayList<SequenceI>(), doNotAdd = new ArrayList<SequenceI>();
+
       for (SequenceI retrievedSequence : retrieved)
       {
         // dataset gets contaminated ccwith non-ds sequences. why ??!
         // try: Ensembl -> Nuc->Ensembl, Nuc->Uniprot-->Protein->EMBL->
         SequenceI retrievedDss = retrievedSequence.getDatasetSequence() == null ? retrievedSequence
                 : retrievedSequence.getDatasetSequence();
-        DBRefEntry[] dbr = retrievedSequence.getDBRefs();
-        if (dbr != null)
+        addedXref |= importCrossRefSeq(cf, newDsSeqs, doNotAdd, dss,
+                retrievedDss);
+      }
+      if (!addedXref)
+      {
+        // try again, after looking for matching IDs
+        // shouldn't need to do this unless the dbref mechanism has broken.
+        updateDbrefMappings(seq, xrfs, retrieved, cf, fromDna);
+        for (SequenceI retrievedSequence : retrieved)
+        {
+          // dataset gets contaminated ccwith non-ds sequences. why ??!
+          // try: Ensembl -> Nuc->Ensembl, Nuc->Uniprot-->Protein->EMBL->
+          SequenceI retrievedDss = retrievedSequence.getDatasetSequence() == null ? retrievedSequence
+                  : retrievedSequence.getDatasetSequence();
+          addedXref |= importCrossRefSeq(cf, newDsSeqs, doNotAdd, dss,
+                  retrievedDss);
+        }
+      }
+      for (SequenceI newToSeq : newDsSeqs)
+      {
+        if (!doNotAdd.contains(newToSeq)
+                && dataset.findIndex(newToSeq) == -1)
         {
-          for (DBRefEntry dbref : dbr)
+          dataset.addSequence(newToSeq);
+          matcher.add(newToSeq);
+        }
+      }
+    }
+  }
+
+  /**
+   * Search dataset for sequences with a primary reference contained in
+   * sourceRefs.
+   * 
+   * @param sourceRefs
+   *          - list of references to filter.
+   * @param fromDna
+   *          - type of sequence to search for matching primary reference.
+   */
+  private void removeAlreadyRetrievedSeqs(List<DBRefEntry> sourceRefs,
+          boolean fromDna)
+  {
+    DBRefEntry[] dbrSourceSet = sourceRefs.toArray(new DBRefEntry[0]);
+    for (SequenceI sq : dataset.getSequences())
+    {
+      boolean dupeFound = false;
+      // !fromDna means we are looking only for nucleotide sequences, not
+      // protein
+      if (sq.isProtein() == fromDna)
+      {
+        for (DBRefEntry dbr : sq.getPrimaryDBRefs())
+        {
+          for (DBRefEntry found : DBRefUtils.searchRefs(dbrSourceSet, dbr))
           {
-            // find any entry where we should put in the sequence being
-            // cross-referenced into the map
-            Mapping map = dbref.getMap();
-            if (map != null)
+            sourceRefs.remove(found);
+            dupeFound = true;
+          }
+        }
+      }
+      if (dupeFound)
+      {
+        // rebuild the search array from the filtered sourceRefs list
+        dbrSourceSet = sourceRefs.toArray(new DBRefEntry[0]);
+      }
+    }
+  }
+
+  /**
+   * process sequence retrieved via a dbref on source sequence to resolve and
+   * transfer data
+   * 
+   * @param cf
+   * @param sourceSequence
+   * @param retrievedSequence
+   * @return true if retrieveSequence was imported
+   */
+  private boolean importCrossRefSeq(AlignedCodonFrame cf,
+          List<SequenceI> newDsSeqs, List<SequenceI> doNotAdd,
+          SequenceI sourceSequence, SequenceI retrievedSequence)
+  {
+    /**
+     * set when retrievedSequence has been verified as a crossreference for
+     * sourceSequence
+     */
+    boolean imported = false;
+    DBRefEntry[] dbr = retrievedSequence.getDBRefs();
+    if (dbr != null)
+    {
+      for (DBRefEntry dbref : dbr)
+      {
+        SequenceI matched = findInDataset(dbref);
+        if (matched == sourceSequence)
+        {
+          // verified retrieved and source sequence cross-reference each other
+          imported = true;
+        }
+        // find any entry where we should put in the sequence being
+        // cross-referenced into the map
+        Mapping map = dbref.getMap();
+        if (map != null)
+        {
+          if (map.getTo() != null && map.getMap() != null)
+          {
+            if (map.getTo() == sourceSequence)
+            {
+              // already called to import once, and most likely this sequence
+              // already imported !
+              continue;
+            }
+            if (matched == null)
             {
-              if (map.getTo() != null && map.getMap() != null)
+              /*
+               * sequence is new to dataset, so save a reference so it can be added. 
+               */
+              newDsSeqs.add(map.getTo());
+              continue;
+            }
+
+            /*
+             * there was a matching sequence in dataset, so now, check to see if we can update the map.getTo() sequence to the existing one.
+             */
+
+            try
+            {
+              // compare ms with dss and replace with dss in mapping
+              // if map is congruent
+              SequenceI ms = map.getTo();
+              // TODO findInDataset requires exact sequence match but
+              // 'congruent' test is only for the mapped part
+              // maybe not a problem in practice since only ENA provide a
+              // mapping and it is to the full protein translation of CDS
+              // matcher.findIdMatch(map.getTo());
+              // TODO addendum: if matched is shorter than getTo, this will fail
+              // - when it should really succeed.
+              int sf = map.getMap().getToLowest();
+              int st = map.getMap().getToHighest();
+              SequenceI mappedrg = ms.getSubSequence(sf, st);
+              if (mappedrg.getLength() > 0
+                      && ms.getSequenceAsString().equals(
+                              matched.getSequenceAsString()))
               {
-                // TODO findInDataset requires exact sequence match but
-                // 'congruent' test is only for the mapped part
-                // maybe not a problem in practice since only ENA provide a
-                // mapping and it is to the full protein translation of CDS
-                SequenceI matched = findInDataset(dbref);
-                // matcher.findIdMatch(map.getTo());
-                if (matched != null)
+                /*
+                 * sequences were a match, 
+                 */
+                String msg = "Mapping updated from " + ms.getName()
+                        + " to retrieved crossreference "
+                        + matched.getName();
+                System.out.println(msg);
+
+                DBRefEntry[] toRefs = map.getTo().getDBRefs();
+                if (toRefs != null)
                 {
                   /*
-                   * already got an xref to this sequence; update this
-                   * map to point to the same sequence, and add
-                   * any new dbrefs to it
+                   * transfer database refs
                    */
-                  DBRefEntry[] toRefs = map.getTo().getDBRefs();
-                  if (toRefs != null)
+                  for (DBRefEntry ref : toRefs)
                   {
-                    for (DBRefEntry ref : toRefs)
+                    if (dbref.getSrcAccString().equals(
+                            ref.getSrcAccString()))
                     {
-                      matched.addDBRef(ref); // add or update mapping
+                      continue; // avoid overwriting the ref on source sequence
                     }
-                  }
-                  map.setTo(matched);
-                }
-                else
-                {
-                  if (dataset.findIndex(map.getTo()) == -1)
-                  {
-                    dataset.addSequence(map.getTo());
-                    matcher.add(map.getTo());
+                    matched.addDBRef(ref); // add or update mapping
                   }
                 }
-                try
-                {
-                  // compare ms with dss and replace with dss in mapping
-                  // if map is congruent
-                  SequenceI ms = map.getTo();
-                  int sf = map.getMap().getToLowest();
-                  int st = map.getMap().getToHighest();
-                  SequenceI mappedrg = ms.getSubSequence(sf, st);
-                  // SequenceI loc = dss.getSubSequence(sf, st);
-                  if (mappedrg.getLength() > 0
-                          && ms.getSequenceAsString().equals(
-                                  dss.getSequenceAsString()))
-                  // && mappedrg.getSequenceAsString().equals(
-                  // loc.getSequenceAsString()))
-                  {
-                    String msg = "Mapping updated from " + ms.getName()
-                            + " to retrieved crossreference "
-                            + dss.getName();
-                    System.out.println(msg);
-                    map.setTo(dss);
+                doNotAdd.add(map.getTo());
+                map.setTo(matched);
 
-                    /*
-                     * give the reverse reference the inverse mapping 
-                     * (if it doesn't have one already)
-                     */
-                    setReverseMapping(dss, dbref, cf);
+                /*
+                 * give the reverse reference the inverse mapping 
+                 * (if it doesn't have one already)
+                 */
+                setReverseMapping(matched, dbref, cf);
 
+                /*
+                 * copy sequence features as well, avoiding
+                 * duplication (e.g. same variation from two 
+                 * transcripts)
+                 */
+                SequenceFeature[] sfs = ms.getSequenceFeatures();
+                if (sfs != null)
+                {
+                  for (SequenceFeature feat : sfs)
+                  {
                     /*
-                     * copy sequence features as well, avoiding
-                     * duplication (e.g. same variation from two 
-                     * transcripts)
+                     * make a flyweight feature object which ignores Parent
+                     * attribute in equality test; this avoids creating many
+                     * otherwise duplicate exon features on genomic sequence
                      */
-                    SequenceFeature[] sfs = ms.getSequenceFeatures();
-                    if (sfs != null)
+                    SequenceFeature newFeature = new SequenceFeature(
+                            feat)
                     {
-                      for (SequenceFeature feat : sfs)
+                      @Override
+                      public boolean equals(Object o)
                       {
-                        /*
-                         * make a flyweight feature object which ignores Parent
-                         * attribute in equality test; this avoids creating many
-                         * otherwise duplicate exon features on genomic sequence
-                         */
-                        SequenceFeature newFeature = new SequenceFeature(
-                                feat)
-                        {
-                          @Override
-                          public boolean equals(Object o)
-                          {
-                            return super.equals(o, true);
-                          }
-                        };
-                        dss.addSequenceFeature(newFeature);
+                        return super.equals(o, true);
                       }
-                    }
+                    };
+                    matched.addSequenceFeature(newFeature);
                   }
-                  cf.addMap(retrievedDss, map.getTo(), map.getMap());
-                } catch (Exception e)
-                {
-                  System.err
-                          .println("Exception when consolidating Mapped sequence set...");
-                  e.printStackTrace(System.err);
                 }
+
               }
+              cf.addMap(retrievedSequence, map.getTo(), map.getMap());
+            } catch (Exception e)
+            {
+              System.err
+                      .println("Exception when consolidating Mapped sequence set...");
+              e.printStackTrace(System.err);
             }
           }
         }
-        retrievedSequence.updatePDBIds();
-        rseqs.add(retrievedDss);
-        if (dataset.findIndex(retrievedDss) == -1)
-        {
-          dataset.addSequence(retrievedDss);
-          matcher.add(retrievedDss);
-        }
       }
     }
+    if (imported)
+    {
+      retrievedSequence.updatePDBIds();
+      rseqs.add(retrievedSequence);
+      if (dataset.findIndex(retrievedSequence) == -1)
+      {
+        dataset.addSequence(retrievedSequence);
+        matcher.add(retrievedSequence);
+      }
+    }
+    return imported;
   }
   /**
    * Sets the inverse sequence mapping in the corresponding dbref of the mapped
@@ -602,9 +709,12 @@ public class CrossRef
   }
 
   /**
-   * Returns the first identical sequence in the dataset if any, else null
+   * Returns null or the first sequence in the dataset which is identical to
+   * xref.mapTo, and has a) a primary dbref matching xref, or if none found, the
+   * first one with an ID source|xrefacc
    * 
    * @param xref
+   *          with map and mapped-to sequence
    * @return
    */
   SequenceI findInDataset(DBRefEntry xref)
@@ -618,22 +728,42 @@ public class CrossRef
     String name2 = xref.getSource() + "|" + name;
     SequenceI dss = mapsTo.getDatasetSequence() == null ? mapsTo : mapsTo
             .getDatasetSequence();
+    // first check ds if ds is directly referenced
+    if (dataset.findIndex(dss) > -1)
+    {
+      return dss;
+    }
+    DBRefEntry template = new DBRefEntry(xref.getSource(), null,
+            xref.getAccessionId());
+    /**
+     * remember the first ID match - in case we don't find a match to template
+     */
+    SequenceI firstIdMatch = null;
     for (SequenceI seq : dataset.getSequences())
     {
+      // first check primary refs.
+      List<DBRefEntry> match = DBRefUtils.searchRefs(seq.getPrimaryDBRefs()
+              .toArray(new DBRefEntry[0]), template);
+      if (match != null && match.size() == 1 && sameSequence(seq, dss))
+      {
+        return seq;
+      }
       /*
        * clumsy alternative to using SequenceIdMatcher which currently
        * returns sequences with a dbref to the matched accession id 
        * which we don't want
        */
-      if (name.equals(seq.getName()) || seq.getName().startsWith(name2))
+      if (firstIdMatch == null
+              && (name.equals(seq.getName()) || seq.getName().startsWith(
+                      name2)))
       {
         if (sameSequence(seq, dss))
         {
-          return seq;
+          firstIdMatch = seq;
         }
       }
     }
-    return null;
+    return firstIdMatch;
   }
 
   /**
index e3d999a..41324d9 100644 (file)
@@ -359,8 +359,8 @@ public class Rna
   }
 
   /**
-   * Answers true if the base-pair is either a canonical (A-T/U, C-G) or a
-   * wobble (G-T/U) pair (either way round), else false
+   * Answers true if the base-pair is either a Watson-Crick (A:T/U, C:G) or a
+   * wobble (G:T/U) pair (either way round), else false
    * 
    * @param first
    * @param second
@@ -417,6 +417,62 @@ public class Rna
   }
 
   /**
+   * Answers true if the base-pair is Watson-Crick - (A:T/U or C:G, either way
+   * round), else false
+   * 
+   * @param first
+   * @param second
+   * @return
+   */
+  public static boolean isCanonicalPair(char first, char second)
+  {
+
+    if (first > 'Z')
+    {
+      first -= 32;
+    }
+    if (second > 'Z')
+    {
+      second -= 32;
+    }
+
+    switch (first)
+    {
+    case 'A':
+      switch (second)
+      {
+      case 'T':
+      case 'U':
+        return true;
+      }
+      break;
+    case 'G':
+      switch (second)
+      {
+      case 'C':
+        return true;
+      }
+      break;
+    case 'C':
+      switch (second)
+      {
+      case 'G':
+        return true;
+      }
+      break;
+    case 'T':
+    case 'U':
+      switch (second)
+      {
+      case 'A':
+        return true;
+      }
+      break;
+    }
+    return false;
+  }
+
+  /**
    * Returns the matching close pair symbol for the given opening symbol.
    * Currently returns a-z for A-Z, or )]}> for ([{<, or the input symbol if it
    * is not a valid opening symbol.
index 479c856..ad3f8d9 100644 (file)
@@ -112,8 +112,9 @@ public class StructureFrequency
 
     for (int i = start; i < end; i++) // foreach column
     {
-      int canonicalOrWobblePairCount = 0;
+      int canonicalOrWobblePairCount = 0, canonical = 0;
       int otherPairCount = 0;
+      int nongap = 0;
       maxResidue = "-";
       values = new int[255];
       pairs = new int[255][255];
@@ -161,7 +162,7 @@ public class StructureFrequency
               values['-']++;
               continue;
             }
-
+            nongap++;
             /*
              * ensure upper-case for counting purposes
              */
@@ -175,20 +176,19 @@ public class StructureFrequency
             }
             if (Rna.isCanonicalOrWobblePair(c, cEnd))
             {
-              values['(']++;
-              maxResidue = "(";
               canonicalOrWobblePairCount++;
+              if (Rna.isCanonicalPair(c, cEnd))
+              {
+                canonical++;
+              }
             }
             else
             {
-              values['[']++;
-              maxResidue = "[";
               otherPairCount++;
             }
             pairs[c][cEnd]++;
           }
         }
-        // nonGap++;
       }
 
       residueHash = new Hashtable();
@@ -200,7 +200,9 @@ public class StructureFrequency
 
         residueHash.put(PAIRPROFILE, pairs);
       }
-
+      values['('] = canonicalOrWobblePairCount;
+      values['['] = canonical;
+      values['{'] = otherPairCount;
       /*
        * the count is the number of valid pairs (as a percentage, determines
        * the relative size of the profile logo)
@@ -208,13 +210,20 @@ public class StructureFrequency
       int count = canonicalOrWobblePairCount;
 
       /*
-       * currently displaying as '(' if most pairs are valid, or as
-       * '[' if there are more invalid than valid pairs 
+       * display '(' if most pairs are canonical, or as
+       * '[' if there are more wobble pairs. 
        */
-      if (!maxResidue.equals("-"))
+      if (canonicalOrWobblePairCount > 0 || otherPairCount > 0)
       {
-        maxResidue = canonicalOrWobblePairCount >= otherPairCount ? "("
+        if (canonicalOrWobblePairCount >= otherPairCount)
+        {
+          maxResidue = (canonicalOrWobblePairCount - canonical) < canonical ? "("
                 : "[";
+        }
+        else
+        {
+          maxResidue = "{";
+        }
       }
       residueHash.put(MAXCOUNT, new Integer(count));
       residueHash.put(MAXRESIDUE, maxResidue);
@@ -222,8 +231,9 @@ public class StructureFrequency
       percentage = ((float) count * 100) / jSize;
       residueHash.put(PID_GAPS, new Float(percentage));
 
-      // percentage = ((float) count * 100) / (float) nongap;
-      // residueHash.put(PID_NOGAPS, new Float(percentage));
+      percentage = ((float) count * 100) / nongap;
+      residueHash.put(PID_NOGAPS, new Float(percentage));
+
       if (result[i] == null)
       {
         result[i] = residueHash;
@@ -232,9 +242,12 @@ public class StructureFrequency
       {
         values[')'] = values['('];
         values[']'] = values['['];
+        values['}'] = values['{'];
         values['('] = 0;
         values['['] = 0;
-        maxResidue = maxResidue.equals("(") ? ")" : "]";
+        values['{'] = 0;
+        maxResidue = maxResidue.equals("(") ? ")"
+                : maxResidue.equals("[") ? "]" : "}";
 
         residueHash = new Hashtable();
         if (profile)
@@ -251,6 +264,9 @@ public class StructureFrequency
         percentage = ((float) count * 100) / jSize;
         residueHash.put(PID_GAPS, new Float(percentage));
 
+        percentage = ((float) count * 100) / nongap;
+        residueHash.put(PID_NOGAPS, new Float(percentage));
+
         result[bpEnd] = residueHash;
       }
     }
index df57cc0..0840520 100644 (file)
@@ -53,6 +53,18 @@ public interface AlignViewportI extends ViewStyleI
    */
   public int calcPanelHeight();
 
+  /**
+   * Answers true if the viewport has at least one column selected
+   * 
+   * @return
+   */
+  boolean hasSelectedColumns();
+
+  /**
+   * Answers true if the viewport has at least one hidden column
+   * 
+   * @return
+   */
   boolean hasHiddenColumns();
 
   boolean isValidCharWidth();
@@ -110,6 +122,11 @@ public interface AlignViewportI extends ViewStyleI
   boolean isClosed();
 
   /**
+   * Dispose of all references or resources held by the viewport
+   */
+  void dispose();
+
+  /**
    * get the associated calculation thread manager for the view
    * 
    * @return
index ec7cd25..c30fdad 100644 (file)
@@ -43,7 +43,6 @@ import jalview.schemes.HelixColourScheme;
 import jalview.schemes.HydrophobicColourScheme;
 import jalview.schemes.NucleotideColourScheme;
 import jalview.schemes.PIDColourScheme;
-import jalview.schemes.ResidueProperties;
 import jalview.schemes.StrandColourScheme;
 import jalview.schemes.TaylorColourScheme;
 import jalview.schemes.TurnColourScheme;
@@ -1208,10 +1207,10 @@ public class APopupMenu extends java.awt.PopupMenu implements
     if (conservationMenuItem.getState())
     {
 
-      sg.cs.setConservation(Conservation.calculateConservation("Group",
-              ResidueProperties.propHash, 3, sg.getSequences(ap.av
-                      .getHiddenRepSequences()), 0, ap.av.getAlignment()
-                      .getWidth(), false, ap.av.getConsPercGaps(), false));
+      sg.cs.setConservation(Conservation.calculateConservation("Group", 3,
+              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 e9e0786..511a264 100644 (file)
@@ -702,9 +702,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       // Hide everything by the current selection - this is a hack - we do the
       // invert and then hide
       // first check that there will be visible columns after the invert.
-      if ((viewport.getColumnSelection() != null
-              && viewport.getColumnSelection().getSelected() != null && viewport
-              .getColumnSelection().getSelected().size() > 0)
+      if (viewport.hasSelectedColumns()
               || (sg != null && sg.getSize() > 0 && sg.getStartRes() <= sg
                       .getEndRes()))
       {
@@ -732,8 +730,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
         hide = true;
         viewport.hideAllSelectedSeqs();
       }
-      else if (!(toggleCols && viewport.getColumnSelection().getSelected()
-              .size() > 0))
+      else if (!(toggleCols && viewport.hasSelectedColumns()))
       {
         viewport.showAllHiddenSeqs();
       }
@@ -741,7 +738,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
     if (toggleCols)
     {
-      if (viewport.getColumnSelection().getSelected().size() > 0)
+      if (viewport.hasSelectedColumns())
       {
         viewport.hideSelectedColumns();
         if (!toggleSeqs)
index 34e0cc0..813ab84 100644 (file)
@@ -68,7 +68,8 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
   // this value is set false when selection area being dragged
   boolean fastPaint = true;
 
-  public void finalize()
+  @Override
+  public void finalize() throws Throwable
   {
     alignFrame = null;
     av = null;
@@ -80,6 +81,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
     annotationPanel = null;
     annotationPanelHolder = null;
     annotationSpaceFillerHolder = null;
+    super.finalize();
   }
 
   public AlignmentPanel(AlignFrame af, final AlignViewport av)
@@ -121,6 +123,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
 
     addComponentListener(new ComponentAdapter()
     {
+      @Override
       public void componentResized(ComponentEvent evt)
       {
         setScrollValues(av.getStartRes(), av.getStartSeq());
@@ -146,6 +149,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
     final AlignmentPanel ap = this;
     av.addPropertyChangeListener(new java.beans.PropertyChangeListener()
     {
+      @Override
       public void propertyChange(java.beans.PropertyChangeEvent evt)
       {
         if (evt.getPropertyName().equals("alignment"))
@@ -538,6 +542,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
    * automatically adjust annotation panel height for new annotation whilst
    * ensuring the alignment is still visible.
    */
+  @Override
   public void adjustAnnotationHeight()
   {
     // TODO: display vertical annotation scrollbar if necessary
@@ -770,6 +775,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
 
   }
 
+  @Override
   public void adjustmentValueChanged(AdjustmentEvent evt)
   {
     int oldX = av.getStartRes();
@@ -947,6 +953,7 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
   /**
    * Repaint the alignment and annotations, and, optionally, any overview window
    */
+  @Override
   public void paintAlignment(boolean updateOverview)
   {
     final AnnotationSorter sorter = new AnnotationSorter(getAlignment(),
@@ -969,11 +976,13 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
     }
   }
 
+  @Override
   public void update(Graphics g)
   {
     paint(g);
   }
 
+  @Override
   public void paint(Graphics g)
   {
     invalidate();
index 5a9cd55..79d2f1f 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.appletgui;
 
+import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.SequenceGroup;
 import jalview.schemes.AnnotationColourGradient;
 import jalview.schemes.ColourSchemeI;
@@ -96,7 +97,8 @@ public class AnnotationColourChooser extends Panel implements
     slider.addAdjustmentListener(this);
     slider.addMouseListener(this);
 
-    if (av.getAlignment().getAlignmentAnnotation() == null)
+    AlignmentAnnotation[] anns = av.getAlignment().getAlignmentAnnotation();
+    if (anns == null)
     {
       return;
     }
@@ -117,11 +119,15 @@ public class AnnotationColourChooser extends Panel implements
       // seqAssociated.setState(acg.isSeqAssociated());
     }
 
-    Vector list = new Vector();
+    Vector<String> list = new Vector<String>();
     int index = 1;
-    for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
+    for (int i = 0; i < anns.length; i++)
     {
-      String label = av.getAlignment().getAlignmentAnnotation()[i].label;
+      String label = anns[i].label;
+      if (anns[i].sequenceRef != null)
+      {
+        label = label + "_" + anns[i].sequenceRef.getName();
+      }
       if (!list.contains(label))
       {
         list.addElement(label);
@@ -309,6 +315,7 @@ public class AnnotationColourChooser extends Panel implements
 
   Checkbox thresholdIsMin = new Checkbox();
 
+  @Override
   public void actionPerformed(ActionEvent evt)
   {
     if (evt.getSource() == thresholdValue)
@@ -351,6 +358,7 @@ public class AnnotationColourChooser extends Panel implements
     }
   }
 
+  @Override
   public void itemStateChanged(ItemEvent evt)
   {
     if (evt.getSource() == currentColours)
@@ -368,6 +376,7 @@ public class AnnotationColourChooser extends Panel implements
     changeColour();
   }
 
+  @Override
   public void adjustmentValueChanged(AdjustmentEvent evt)
   {
     if (!adjusting)
@@ -552,23 +561,28 @@ public class AnnotationColourChooser extends Panel implements
 
   }
 
+  @Override
   public void mouseClicked(MouseEvent evt)
   {
   }
 
+  @Override
   public void mousePressed(MouseEvent evt)
   {
   }
 
+  @Override
   public void mouseReleased(MouseEvent evt)
   {
     ap.paintAlignment(true);
   }
 
+  @Override
   public void mouseEntered(MouseEvent evt)
   {
   }
 
+  @Override
   public void mouseExited(MouseEvent evt)
   {
   }
index e3def25..a8dff62 100644 (file)
@@ -135,17 +135,22 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
     slider.addAdjustmentListener(this);
     slider.addMouseListener(this);
 
-    if (av.getAlignment().getAlignmentAnnotation() == null)
+    AlignmentAnnotation[] anns = av.getAlignment().getAlignmentAnnotation();
+    if (anns == null)
     {
       return;
     }
     setOldColumnSelection(av.getColumnSelection());
     adjusting = true;
-    Vector list = new Vector();
+    Vector<String> list = new Vector<String>();
     int index = 1;
-    for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
+    for (int i = 0; i < anns.length; i++)
     {
-      String label = av.getAlignment().getAlignmentAnnotation()[i].label;
+      String label = anns[i].label;
+      if (anns[i].sequenceRef != null)
+      {
+        label = label + "_" + anns[i].sequenceRef.getName();
+      }
       if (!list.contains(label))
       {
         list.addElement(label);
@@ -273,6 +278,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
     this.validate();
   }
 
+  @Override
   @SuppressWarnings("unchecked")
   public void reset()
   {
@@ -302,6 +308,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
 
   }
 
+  @Override
   public void adjustmentValueChanged(AdjustmentEvent evt)
   {
     if (!adjusting)
@@ -343,6 +350,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
     });
   }
 
+  @Override
   public void valueChanged(boolean updateAllAnnotation)
   {
     if (slider.isEnabled())
@@ -866,6 +874,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
     }
   }
 
+  @Override
   public void actionPerformed(ActionEvent evt)
   {
     if (evt.getSource() == thresholdValue)
index fc49de5..8d67d71 100644 (file)
@@ -85,45 +85,6 @@ public abstract class AnnotationRowFilter extends Panel
 
   }
 
-  public Vector getAnnotationItems(boolean isSeqAssociated)
-  {
-    Vector list = new Vector();
-    int index = 1;
-    int[] anmap = new int[av.getAlignment().getAlignmentAnnotation().length];
-    for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
-    {
-      if (av.getAlignment().getAlignmentAnnotation()[i].sequenceRef == null)
-      {
-        if (isSeqAssociated)
-        {
-          continue;
-        }
-      }
-      else
-      {
-        enableSeqAss = true;
-      }
-      String label = av.getAlignment().getAlignmentAnnotation()[i].label;
-      if (!list.contains(label))
-      {
-        anmap[list.size()] = i;
-        list.add(label);
-
-      }
-      else
-      {
-        if (!isSeqAssociated)
-        {
-          anmap[list.size()] = i;
-          list.add(label + "_" + (index++));
-        }
-      }
-    }
-    this.annmap = new int[list.size()];
-    System.arraycopy(anmap, 0, this.annmap, 0, this.annmap.length);
-    return list;
-  }
-
   protected int getSelectedThresholdItem(int indexValue)
   {
     int selectedThresholdItem = -1;
index b925284..c39204f 100644 (file)
@@ -63,6 +63,8 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Vector;
 
+import org.jmol.util.Logger;
+
 public class AppletJmol extends EmbmenuFrame implements
 // StructureListener,
         KeyListener, ActionListener, ItemListener
@@ -268,6 +270,7 @@ public class AppletJmol extends EmbmenuFrame implements
       jmb.allocateViewer(renderPanel, true, ap.av.applet.getName()
               + "_jmol_", ap.av.applet.getDocumentBase(),
               ap.av.applet.getCodeBase(), "-applet", scriptWindow, null);
+      Logger.setLogLevel(Logger.LEVEL_WARN);
     } catch (Exception e)
     {
       System.err
index c8f526c..47c2d28 100755 (executable)
@@ -29,7 +29,6 @@ import jalview.datamodel.SequenceI;
 import jalview.datamodel.SequenceNode;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.ResidueProperties;
 import jalview.schemes.UserColourScheme;
 import jalview.util.Format;
 import jalview.util.MappingUtils;
@@ -627,9 +626,9 @@ public class TreeCanvas extends Panel implements MouseListener,
 
       Color col = new Color((int) (Math.random() * 255),
               (int) (Math.random() * 255), (int) (Math.random() * 255));
-      setColor((SequenceNode) tree.getGroups().elementAt(i), col.brighter());
+      setColor(tree.getGroups().elementAt(i), col.brighter());
 
-      Vector<SequenceNode> l = tree.findLeaves((SequenceNode) tree
+      Vector<SequenceNode> l = tree.findLeaves(tree
               .getGroups().elementAt(i));
 
       Vector<SequenceI> sequences = new Vector<SequenceI>();
@@ -679,9 +678,8 @@ public class TreeCanvas extends Panel implements MouseListener,
       if (av.getGlobalColourScheme() != null
               && av.getGlobalColourScheme().conservationApplied())
       {
-        Conservation c = new Conservation("Group",
-                ResidueProperties.propHash, 3, sg.getSequences(null),
-                sg.getStartRes(), sg.getEndRes());
+        Conservation c = new Conservation("Group", 3,
+                sg.getSequences(null), sg.getStartRes(), sg.getEndRes());
 
         c.calculate();
         c.verdict(false, av.getConsPercGaps());
index 508e8a7..00c8b86 100755 (executable)
@@ -444,11 +444,12 @@ public class Cache
             .println("Jalview Version: " + codeVersion + codeInstallation);
 
     StructureImportSettings.setDefaultStructureFileFormat(jalview.bin.Cache
-            .getDefault(
-"PDB_DOWNLOAD_FORMAT", PDB_DOWNLOAD_FORMAT));
+            .getDefault("PDB_DOWNLOAD_FORMAT", PDB_DOWNLOAD_FORMAT));
     StructureImportSettings
-            .setDefaultPDBFileParser(jalview.bin.Cache.getDefault(
-                    "DEFAULT_PDB_FILE_PARSER", DEFAULT_PDB_FILE_PARSER));
+            .setDefaultPDBFileParser(DEFAULT_PDB_FILE_PARSER);
+    // StructureImportSettings
+    // .setDefaultPDBFileParser(jalview.bin.Cache.getDefault(
+    // "DEFAULT_PDB_FILE_PARSER", DEFAULT_PDB_FILE_PARSER));
     // jnlpVersion will be null if we're using InstallAnywhere
     // Dont do this check if running in headless mode
     if (jnlpVersion == null
index 3294c26..763b10b 100755 (executable)
@@ -23,6 +23,7 @@ package jalview.bin;
 import groovy.lang.Binding;
 import groovy.util.GroovyScriptEngine;
 
+import jalview.ext.so.SequenceOntology;
 import jalview.gui.AlignFrame;
 import jalview.gui.Desktop;
 import jalview.gui.PromptUserConfig;
@@ -33,6 +34,7 @@ import jalview.io.FormatAdapter;
 import jalview.io.HtmlSvgOutput;
 import jalview.io.IdentifyFile;
 import jalview.io.NewickFile;
+import jalview.io.gff.SequenceOntologyFactory;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemeProperty;
 import jalview.schemes.UserColourScheme;
@@ -288,6 +290,15 @@ public class Jalview
       }
     }
 
+    /*
+     * configure 'full' SO model if preferences say to, 
+     * else use the default (SO Lite)
+     */
+    if (Cache.getDefault("USE_FULL_SO", false))
+    {
+      SequenceOntologyFactory.setInstance(new SequenceOntology());
+    }
+
     if (!headless)
     {
       desktop = new Desktop();
index 210a07a..b30ad41 100644 (file)
@@ -466,7 +466,7 @@ public class JalviewLite extends Applet implements
         SequenceI rs = sel.getSequenceAt(0);
         start = rs.findIndex(start);
         end = rs.findIndex(end);
-        List<Integer> cs = csel.getSelected();
+        List<Integer> cs = new ArrayList<Integer>(csel.getSelected());
         csel.clear();
         for (Integer selectedCol : cs)
         {
index 2f64759..2289ac6 100755 (executable)
@@ -24,6 +24,7 @@ import jalview.analysis.AlignmentUtils;
 import jalview.datamodel.AlignedCodonFrame.SequenceToSequenceMapping;
 import jalview.io.FastaFile;
 import jalview.util.Comparison;
+import jalview.util.LinkedIdentityHashSet;
 import jalview.util.MessageManager;
 
 import java.util.ArrayList;
@@ -290,13 +291,23 @@ public class Alignment implements AlignmentI
   }
 
   @Override
-  public void finalize()
+  public void finalize() throws Throwable
   {
     if (getDataset() != null)
     {
       getDataset().removeAlignmentRef();
     }
 
+    nullReferences();
+    super.finalize();
+  }
+
+  /**
+   * Defensively nulls out references in case this object is not garbage
+   * collected
+   */
+  void nullReferences()
+  {
     dataset = null;
     sequences = null;
     groups = null;
@@ -305,14 +316,16 @@ public class Alignment implements AlignmentI
   }
 
   /**
-   * decrement the alignmentRefs counter by one and call finalize if it goes to
-   * zero.
+   * decrement the alignmentRefs counter by one and null references if it goes
+   * to zero.
+   * 
+   * @throws Throwable
    */
-  private void removeAlignmentRef()
+  private void removeAlignmentRef() throws Throwable
   {
     if (--alignmentRefs == 0)
     {
-      finalize();
+      nullReferences();
     }
   }
 
@@ -1042,6 +1055,7 @@ public class Alignment implements AlignmentI
   private void resolveAndAddDatasetSeq(SequenceI currentSeq,
           Set<SequenceI> seqs, boolean createDatasetSequence)
   {
+    SequenceI alignedSeq = currentSeq;
     if (currentSeq.getDatasetSequence() != null)
     {
       currentSeq = currentSeq.getDatasetSequence();
@@ -1076,12 +1090,19 @@ public class Alignment implements AlignmentI
         {
           if (dbr.getMap() != null && dbr.getMap().getTo() != null)
           {
+            if (dbr.getMap().getTo() == alignedSeq)
+            {
+              /*
+               * update mapping to be to the newly created dataset sequence
+               */
+              dbr.getMap().setTo(currentSeq);
+            }
             if (dbr.getMap().getTo().getDatasetSequence() != null)
             {
-              throw new Error("Implementation error: Map.getTo() for dbref"
-                      + dbr + " is not a dataset sequence.");
-              // TODO: if this happens, could also rewrite the reference to
-              // point to new dataset sequence
+              throw new Error(
+                      "Implementation error: Map.getTo() for dbref " + dbr
+                              + " from " + curDs.getName()
+                              + " is not a dataset sequence.");
             }
             // we recurse to add all forward references to dataset sequences via
             // DBRefs/etc
@@ -1103,7 +1124,7 @@ public class Alignment implements AlignmentI
       return;
     }
     // try to avoid using SequenceI.equals at this stage, it will be expensive
-    Set<SequenceI> seqs = new jalview.util.LinkedIdentityHashSet<SequenceI>();
+    Set<SequenceI> seqs = new LinkedIdentityHashSet<SequenceI>();
 
     for (int i = 0; i < getHeight(); i++)
     {
index 7ef2a68..8bc8f54 100644 (file)
@@ -45,19 +45,52 @@ public class ColumnSelection
     /*
      * list of selected columns (ordered by selection order, not column order)
      */
-    private List<Integer> order = new ArrayList<Integer>();
+    private List<Integer> order;
+
+    /*
+     * an unmodifiable view of the selected columns list
+     */
+    private List<Integer> _uorder;
 
     /**
      * bitfield for column selection - allows quick lookup
      */
-    private BitSet selected = new BitSet();
+    private BitSet selected;
+
+    /**
+     * Constructor
+     */
+    IntList()
+    {
+      order = new ArrayList<Integer>();
+      _uorder = Collections.unmodifiableList(order);
+      selected = new BitSet();
+    }
+
+    /**
+     * Copy constructor
+     * 
+     * @param other
+     */
+    IntList(IntList other)
+    {
+      this();
+      if (other != null)
+      {
+        int j = other.size();
+        for (int i = 0; i < j; i++)
+        {
+          add(other.elementAt(i));
+        }
+      }
+    }
 
     /**
      * adds a new column i to the selection - only if i is not already selected
      * 
      * @param i
      */
-    public void add(int i)
+    void add(int i)
     {
       if (!selected.get(i))
       {
@@ -66,13 +99,13 @@ public class ColumnSelection
       }
     }
 
-    public void clear()
+    void clear()
     {
       order.clear();
       selected.clear();
     }
 
-    public void remove(int col)
+    void remove(int col)
     {
 
       Integer colInt = new Integer(col);
@@ -87,22 +120,27 @@ public class ColumnSelection
       }
     }
 
-    public boolean contains(Integer colInt)
+    boolean contains(Integer colInt)
     {
       return selected.get(colInt);
     }
 
-    public boolean isEmpty()
+    boolean isEmpty()
     {
       return order.isEmpty();
     }
 
-    public List<Integer> getList()
+    /**
+     * Returns a read-only view of the selected columns list
+     * 
+     * @return
+     */
+    List<Integer> getList()
     {
-      return order;
+      return _uorder;
     }
 
-    public int size()
+    int size()
     {
       return order.size();
     }
@@ -113,7 +151,7 @@ public class ColumnSelection
      * @param i
      * @return
      */
-    public int elementAt(int i)
+    int elementAt(int i)
     {
       return order.get(i);
     }
@@ -156,7 +194,7 @@ public class ColumnSelection
      * @param change
      *          - delta for shift
      */
-    public void compensateForEdits(int start, int change)
+    void compensateForEdits(int start, int change)
     {
       BitSet mask = new BitSet();
       for (int i = 0; i < order.size(); i++)
@@ -175,17 +213,17 @@ public class ColumnSelection
       selected.or(mask);
     }
 
-    public boolean isSelected(int column)
+    boolean isSelected(int column)
     {
       return selected.get(column);
     }
 
-    public int getMaxColumn()
+    int getMaxColumn()
     {
       return selected.length() - 1;
     }
 
-    public int getMinColumn()
+    int getMinColumn()
     {
       return selected.get(0) ? 0 : selected.nextSetBit(0);
     }
@@ -193,7 +231,7 @@ public class ColumnSelection
     /**
      * @return a series of selection intervals along the range
      */
-    public List<int[]> getRanges()
+    List<int[]> getRanges()
     {
       List<int[]> rlist = new ArrayList<int[]>();
       if (selected.isEmpty())
@@ -288,14 +326,18 @@ public class ColumnSelection
   }
 
   /**
-   * Returns a list of selected columns. The list contains no duplicates but is
-   * not necessarily ordered. It also may include columns hidden from the
-   * current view. This returns a copy of the actual list, and changes to the
-   * copy will not affect the selection.
+   * Returns a read-only view of the (possibly empty) list of selected columns
+   * <p>
+   * The list contains no duplicates but is not necessarily ordered. It also may
+   * include columns hidden from the current view. To modify (for example sort)
+   * the list, you should first make a copy.
+   * <p>
+   * The list is not thread-safe: iterating over it could result in
+   * ConcurrentModificationException if it is modified by another thread.
    */
   public List<Integer> getSelected()
   {
-    return new ArrayList<Integer>(selection.getList());
+    return selection.getList();
   }
 
   /**
@@ -949,14 +991,7 @@ public class ColumnSelection
   {
     if (copy != null)
     {
-      if (copy.selection != null)
-      {
-        selection = new IntList();
-        for (int i = 0, j = copy.selection.size(); i < j; i++)
-        {
-          selection.add(copy.selection.elementAt(i));
-        }
-      }
+      selection = new IntList(copy.selection);
       if (copy.hiddenColumns != null)
       {
         hiddenColumns = new Vector<int[]>(copy.hiddenColumns.size());
index 7c2d290..6a6ccd0 100755 (executable)
@@ -25,7 +25,6 @@ import jalview.util.CaseInsensitiveString;
 import java.util.Collections;
 import java.util.Enumeration;
 import java.util.Hashtable;
-import java.util.Map.Entry;
 
 public class PDBEntry
 {
@@ -35,7 +34,9 @@ public class PDBEntry
    */
   private static final String CHAIN_ID = "chain_code";
 
-  Hashtable<String, Object> properties;
+  private Hashtable<String, Object> properties;
+
+  private static final int PDB_ID_LENGTH = 4;
 
   private String file;
 
@@ -77,10 +78,9 @@ public class PDBEntry
   }
 
 
-  /*
-   * (non-Javadoc)
-   * 
-   * @see java.lang.Object#equals(java.lang.Object)
+  /**
+   * Answers true if obj is a PDBEntry with the same id and chain code (both
+   * ignoring case), file, type and properties
    */
   @Override
   public boolean equals(Object obj)
@@ -94,14 +94,24 @@ public class PDBEntry
       return true;
     }
     PDBEntry o = (PDBEntry) obj;
-    return (type == o.type || (type != null && o.type != null && o.type
-            .equals(type)))
-            && (id == o.id || (id != null && o.id != null && o.id
-                    .equalsIgnoreCase(id)))
-            && (properties == o.properties || (properties != null
-                    && o.properties != null && properties
-                      .equals(o.properties)));
 
+    /*
+     * note that chain code is stored as a property wrapped by a 
+     * CaseInsensitiveString, so we are in effect doing a 
+     * case-insensitive comparison of chain codes
+     */
+    boolean idMatches = id == o.id
+            || (id != null && id.equalsIgnoreCase(o.id));
+    boolean fileMatches = file == o.file
+            || (file != null && file.equals(o.file));
+    boolean typeMatches = type == o.type
+            || (type != null && type.equals(o.type));
+    if (idMatches && fileMatches && typeMatches)
+    {
+      return properties == o.properties
+              || (properties != null && properties.equals(o.properties));
+    }
+    return false;
   }
 
   /**
@@ -125,8 +135,19 @@ public class PDBEntry
   public PDBEntry(String pdbId, String chain, PDBEntry.Type type,
           String filePath)
   {
+    init(pdbId, chain, type, filePath);
+  }
+
+  /**
+   * @param pdbId
+   * @param chain
+   * @param entryType
+   * @param filePath
+   */
+  void init(String pdbId, String chain, PDBEntry.Type entryType, String filePath)
+  {
     this.id = pdbId;
-    this.type = type == null ? null : type.toString();
+    this.type = entryType == null ? null : entryType.toString();
     this.file = filePath;
     setChainCode(chain);
   }
@@ -147,6 +168,35 @@ public class PDBEntry
     }
   }
 
+  /**
+   * Make a PDBEntry from a DBRefEntry. The accession code is used for the PDB
+   * id, but if it is 5 characters in length, the last character is removed and
+   * set as the chain code instead.
+   * 
+   * @param dbr
+   */
+  public PDBEntry(DBRefEntry dbr)
+  {
+    if (!DBRefSource.PDB.equals(dbr.getSource()))
+    {
+      throw new IllegalArgumentException("Invalid source: "
+              + dbr.getSource());
+    }
+
+    String pdbId = dbr.getAccessionId();
+    String chainCode = null;
+    if (pdbId.length() == PDB_ID_LENGTH + 1)
+    {
+      char chain = pdbId.charAt(PDB_ID_LENGTH);
+      if (('a' <= chain && chain <= 'z') || ('A' <= chain && chain <= 'Z'))
+      {
+        pdbId = pdbId.substring(0, PDB_ID_LENGTH);
+        chainCode = String.valueOf(chain);
+      }
+    }
+    init(pdbId, chainCode, null, null);
+  }
+
   public void setFile(String f)
   {
     this.file = f;
@@ -290,46 +340,103 @@ public class PDBEntry
   }
 
   /**
-   * update entry with details from another entry concerning the same PDB
-   * ID/file spec.
+   * Answers true if this object is either equivalent to, or can be 'improved'
+   * by, the given entry.
+   * <p>
+   * If newEntry has the same id (ignoring case), and doesn't have a conflicting
+   * file spec or chain code, then update this entry from its file and/or chain
+   * code.
    * 
    * @param newEntry
    * @return true if modifications were made
    */
   public boolean updateFrom(PDBEntry newEntry)
   {
-    boolean modified = false;
+    if (this.equals(newEntry))
+    {
+      return true;
+    }
+
+    String newId = newEntry.getId();
+    if (newId == null || getId() == null)
+    {
+      return false; // shouldn't happen
+    }
+
+    /*
+     * id has to match (ignoring case)
+     */
+    if (!getId().equalsIgnoreCase(newId))
+    {
+      return false;
+    }
+
+    /*
+     * Don't update if associated with different structure files
+     */
+    String newFile = newEntry.getFile();
+    if (newFile != null && getFile() != null && !newFile.equals(getFile()))
+    {
+      return false;
+    }
 
-    if (getFile() == null)
+    /*
+     * Don't update if associated with different chains (ignoring case)
+     */
+    String newChain = newEntry.getChainCode();
+    if (newChain != null && newChain.length() > 0 && getChainCode() != null
+            && getChainCode().length() > 0
+            && !getChainCode().equalsIgnoreCase(newChain))
     {
-      // update file and type of file
-      modified = newEntry.getFile() != null;
-      setFile(newEntry.getFile());
+      return false;
     }
-    if (newEntry.getType() != null && newEntry.getFile() != null
-            && newEntry.getFile().equals(getFile()))
+
+    /*
+     * set file path if not already set
+     */
+    String newType = newEntry.getType();
+    if (getFile() == null && newFile != null)
+    {
+      setFile(newFile);
+      setType(newType);
+    }
+
+    /*
+     * set file type if new entry has it and we don't
+     * (for the case where file was not updated)
+     */
+    if (getType() == null && newType != null)
     {
-      setType(newEntry.getType());
+      setType(newType);
     }
-    if (getChainCode() == null
-            || (getChainCode() != null && getChainCode().length() == 0 && newEntry
-                    .getChainCode() != null))
+
+    /*
+     * set chain if not already set (we excluded differing 
+     * chains earlier) (ignoring case change only)
+     */
+    if (newChain != null && newChain.length() > 0
+            && !newChain.equalsIgnoreCase(getChainCode()))
     {
-      modified |= (getChainCode() == null || !newEntry.getChainCode()
-              .equals(getChainCode()));
-      setChainCode(newEntry.getChainCode());
+      setChainCode(newChain);
     }
-    if (newEntry.properties != null)
+
+    /*
+     * copy any new or modified properties
+     */
+    Enumeration<String> newProps = newEntry.getProperties();
+    while (newProps.hasMoreElements())
     {
-      for (Entry<String, Object> entry : newEntry.properties.entrySet())
+      /*
+       * copy properties unless value matches; this defends against changing
+       * the case of chain_code which is wrapped in a CaseInsensitiveString
+       */
+      String key = newProps.nextElement();
+      Object value = newEntry.getProperty(key);
+      if (!value.equals(getProperty(key)))
       {
-        if (!entry.getValue().equals(getProperty(entry.getKey())))
-        {
-          modified = true;
-        }
-        setProperty(entry.getKey(), entry.getValue());
+        setProperty(key, value);
       }
     }
-    return modified;
+    return true;
   }
 }
index 4f626a4..68c8c50 100755 (executable)
@@ -22,6 +22,7 @@ package jalview.datamodel;
 
 import jalview.analysis.AlignSeq;
 import jalview.api.DBRefEntryI;
+import jalview.util.Comparison;
 import jalview.util.DBRefUtils;
 import jalview.util.MapList;
 import jalview.util.StringUtils;
@@ -412,72 +413,24 @@ public class Sequence extends ASequence implements SequenceI
   }
 
   @Override
-  public void addPDBId(PDBEntry entry)
+  public boolean addPDBId(PDBEntry entry)
   {
     if (pdbIds == null)
     {
       pdbIds = new Vector<PDBEntry>();
+      pdbIds.add(entry);
+      return true;
     }
-    if (!updatedPDBEntry(pdbIds, entry))
-    {
-      pdbIds.addElement(entry);
-    }
-  }
 
-  private static boolean updatedPDBEntry(List<PDBEntry> entries,
-          PDBEntry newEntry)
-  {
-    for (PDBEntry xtant : entries)
+    for (PDBEntry pdbe : pdbIds)
     {
-      if (xtant.getFile() != null && newEntry.getFile() != null
-              && !xtant.getFile().equals(newEntry.getFile()))
-      {
-        // different structure data, so leave alone.
-        continue;
-      }
-      // loop through to check whether we can find a matching ID
-
-      // either exact
-      if (!xtant.getId().equals(newEntry.getId()))
+      if (pdbe.updateFrom(entry))
       {
-        /* TODO: support stemming to group PDB IDs.
-        // or stemming, with exactly one alphanumeric character difference
-        if (xtant.getId().length() < newEntry.getId().length())
-        {
-          if (!newEntry.getId().startsWith(xtant.getId()))
-          {
-            continue;
-          }
-          // newEntry may be chain specific PDBEntry
-          // TODO: copy/update details from newEntry to xtant
-        }
-        else
-        {
-          if (!xtant.getId().startsWith(newEntry.getId()))
-          {
-            continue;
-          }
-          // xtant may be chain specific PDBEntry
-          // TODO: copy/update missing details from newEntry
-        }*/
-        continue;
-      }
-      if (xtant.getChainCode() != null && xtant.getChainCode().length() > 0
-              && newEntry.getChainCode() != null
-              && !newEntry.getChainCode().equals(xtant.getChainCode()))
-      {
-        // don't overwrite - multiple chain mappings for a sequence yield
-        // multiple PDBEntries
-        // each with different chaincode
-        continue;
+        return false;
       }
-
-      xtant.updateFrom(newEntry);
-
-      return true;
     }
-    // if we got to the end of the loop, nothing was updated.
-    return false;
+    pdbIds.addElement(entry);
+    return true;
   }
 
   /**
@@ -992,7 +945,17 @@ public class Sequence extends ASequence implements SequenceI
   @Override
   public void setDBRefs(DBRefEntry[] dbref)
   {
+    if (dbrefs == null && datasetSequence != null
+            && this != datasetSequence)
+    {
+      datasetSequence.setDBRefs(dbref);
+      return;
+    }
     dbrefs = dbref;
+    if (dbrefs != null)
+    {
+      DBRefUtils.ensurePrimaries(this);
+    }
   }
 
   @Override
@@ -1009,7 +972,12 @@ public class Sequence extends ASequence implements SequenceI
   @Override
   public void addDBRef(DBRefEntry entry)
   {
-    // TODO add to dataset sequence instead if there is one?
+    if (datasetSequence != null)
+    {
+      datasetSequence.addDBRef(entry);
+      return;
+    }
+
     if (dbrefs == null)
     {
       dbrefs = new DBRefEntry[0];
@@ -1037,12 +1005,23 @@ public class Sequence extends ASequence implements SequenceI
     temp[temp.length - 1] = entry;
 
     dbrefs = temp;
+
+    DBRefUtils.ensurePrimaries(this);
   }
 
   @Override
   public void setDatasetSequence(SequenceI seq)
   {
-    // TODO check for circular reference before setting?
+    if (seq == this)
+    {
+      throw new IllegalArgumentException(
+              "Implementation Error: self reference passed to SequenceI.setDatasetSequence");
+    }
+    if (seq != null && seq.getDatasetSequence() != null)
+    {
+      throw new IllegalArgumentException(
+              "Implementation error: cascading dataset sequences are not allowed.");
+    }
     datasetSequence = seq;
   }
 
@@ -1139,6 +1118,10 @@ public class Sequence extends ASequence implements SequenceI
 
   private long _seqhash = 0;
 
+  /**
+   * Answers false if the sequence is more than 85% nucleotide (ACGTU), else
+   * true
+   */
   @Override
   public boolean isProtein()
   {
@@ -1149,7 +1132,7 @@ public class Sequence extends ASequence implements SequenceI
     if (_seqhash != sequence.hashCode())
     {
       _seqhash = sequence.hashCode();
-      _isNa=jalview.util.Comparison.isNucleotide(new SequenceI[] { this });
+      _isNa = Comparison.isNucleotide(this);
     }
     return !_isNa;
   };
@@ -1269,46 +1252,22 @@ public class Sequence extends ASequence implements SequenceI
     {
       return false;
     }
-    Vector newpdb = new Vector();
-    for (int i = 0; i < dbrefs.length; i++)
+    boolean added = false;
+    for (DBRefEntry dbr : dbrefs)
     {
-      if (DBRefSource.PDB.equals(dbrefs[i].getSource()))
+      if (DBRefSource.PDB.equals(dbr.getSource()))
       {
-        PDBEntry pdbe = new PDBEntry();
-        pdbe.setId(dbrefs[i].getAccessionId());
-        if (pdbIds == null || pdbIds.size() == 0)
-        {
-          newpdb.addElement(pdbe);
-        }
-        else
-        {
-          Enumeration en = pdbIds.elements();
-          boolean matched = false;
-          while (!matched && en.hasMoreElements())
-          {
-            PDBEntry anentry = (PDBEntry) en.nextElement();
-            if (anentry.getId().equals(pdbe.getId()))
-            {
-              matched = true;
-            }
-          }
-          if (!matched)
-          {
-            newpdb.addElement(pdbe);
-          }
-        }
-      }
-    }
-    if (newpdb.size() > 0)
-    {
-      Enumeration en = newpdb.elements();
-      while (en.hasMoreElements())
-      {
-        addPDBId((PDBEntry) en.nextElement());
+        /*
+         * 'Add' any PDB dbrefs as a PDBEntry - add is only performed if the
+         * PDB id is not already present in a 'matching' PDBEntry
+         * Constructor parses out a chain code if appended to the accession id
+         * (a fudge used to 'store' the chain code in the DBRef)
+         */
+        PDBEntry pdbe = new PDBEntry(dbr);
+        added |= addPDBId(pdbe);
       }
-      return true;
     }
-    return false;
+    return added;
   }
 
   @Override
index 046f1e6..9a408e3 100755 (executable)
@@ -23,7 +23,6 @@ package jalview.datamodel;
 import jalview.analysis.AAFrequency;
 import jalview.analysis.Conservation;
 import jalview.schemes.ColourSchemeI;
-import jalview.schemes.ResidueProperties;
 
 import java.awt.Color;
 import java.util.ArrayList;
@@ -548,9 +547,8 @@ public class SequenceGroup implements AnnotatedCollectionI
       if ((conservation != null)
               || (cs != null && cs.conservationApplied()))
       {
-        Conservation c = new Conservation(groupName,
-                ResidueProperties.propHash, 3, sequences, startRes,
-                endRes + 1);
+        Conservation c = new Conservation(groupName, 3, sequences,
+                startRes, endRes + 1);
         c.calculate();
         c.verdict(false, consPercGaps);
         if (conservation != null)
index 55c59db..49ddf86 100755 (executable)
@@ -217,8 +217,11 @@ public interface SequenceI extends ASequenceI
   public int[] findPositionMap();
 
   /**
+   * Answers true if the sequence is composed of amino acid characters. Note
+   * that implementations may use heuristic methods which are not guaranteed to
+   * give the biologically 'right' answer.
    * 
-   * @return true if sequence is composed of amino acid characters
+   * @return
    */
   public boolean isProtein();
 
@@ -289,16 +292,18 @@ public interface SequenceI extends ASequenceI
   public Vector<PDBEntry> getAllPDBEntries();
 
   /**
-   * add entry to the *normalised* vector of PDBIds.
+   * Adds the entry to the *normalised* list of PDBIds.
    * 
-   * If a PDBEntry is passed with an entry.getID() string, as one already in the
-   * list, or one is added that appears to be the same but has a chain ID
+   * If a PDBEntry is passed with the same entry.getID() string as one already
+   * in the list, or one is added that appears to be the same but has a chain ID
    * appended, then the existing PDBEntry will be updated with the new
-   * attributes.
+   * attributes instead, unless the entries have distinct chain codes or
+   * associated structure files.
    * 
    * @param entry
+   * @return true if the entry was added, false if updated
    */
-  public void addPDBId(PDBEntry entry);
+  public boolean addPDBId(PDBEntry entry);
 
   /**
    * update the list of PDBEntrys to include any DBRefEntrys citing structural
@@ -312,6 +317,14 @@ public interface SequenceI extends ASequenceI
 
   public void setVamsasId(String id);
 
+  /**
+   * set the array of Database references for the sequence.
+   * 
+   * @param dbs
+   * @deprecated - use is discouraged since side-effects may occur if DBRefEntry
+   *             set are not normalised.
+   */
+  @Deprecated
   public void setDBRefs(DBRefEntry[] dbs);
 
   public DBRefEntry[] getDBRefs();
index 69870b6..534b38c 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.datamodel.xdb.embl;
 
+import jalview.bin.Cache;
 import jalview.datamodel.DBRefEntry;
 import jalview.ws.dbsources.Uniprot;
 
@@ -27,6 +28,7 @@ import java.io.File;
 import java.io.FileReader;
 import java.io.PrintWriter;
 import java.io.Reader;
+import java.net.URL;
 import java.util.Vector;
 
 import org.exolab.castor.mapping.Mapping;
@@ -81,12 +83,12 @@ public class EmblFile
   }
 
   /**
-   * Parse an EmblXML file into an EmblFile object
+   * Parse an Embl XML file into an EmblEntry object
    * 
    * @param file
    * @return parsed EmblXML or null if exceptions were raised
    */
-  public static EmblFile getEmblFile(File file)
+  public static EmblEntry getEmblEntry(File file)
   {
     if (file == null)
     {
@@ -94,7 +96,7 @@ public class EmblFile
     }
     try
     {
-      return EmblFile.getEmblFile(new FileReader(file));
+      return EmblFile.getEntry(new FileReader(file));
     } catch (Exception e)
     {
       System.err.println("Exception whilst reading EMBLfile from " + file);
@@ -103,26 +105,32 @@ public class EmblFile
     return null;
   }
 
-  public static EmblFile getEmblFile(Reader file)
+  /**
+   * Reads the XML response from file and unmarshals into a Java object
+   * 
+   * @param fileReader
+   * @return
+   */
+  public static EmblEntry getEntry(Reader fileReader)
   {
-    EmblFile record = new EmblFile();
+    EmblEntry record = new EmblEntry();
     try
     {
       // 1. Load the mapping information from the file
       Mapping map = new Mapping(record.getClass().getClassLoader());
 
-      java.net.URL url = record.getClass().getResource("/embl_mapping.xml");
+      URL url = record.getClass().getResource("/embl_mapping.xml");
       map.loadMapping(url);
 
       // 2. Unmarshal the data
       Unmarshaller unmar = new Unmarshaller(record);
       try
       {
-        // uncomment to DEBUG EMBLFile reading
-        if (jalview.bin.Cache.getDefault(jalview.bin.Cache.CASTORLOGLEVEL,
+        if (Cache.getDefault(Cache.CASTORLOGLEVEL,
                 "debug").equalsIgnoreCase("DEBUG"))
         {
-          unmar.setDebug(jalview.bin.Cache.log.isDebugEnabled());
+          unmar.setDebug(Cache.log.isDebugEnabled());
+          // unmar.setDebug(true);// uncomment to debug unmarshalling
         }
       } catch (Exception e)
       {
@@ -131,7 +139,7 @@ public class EmblFile
       unmar.setIgnoreExtraAttributes(true);
       unmar.setMapping(map);
       unmar.setLogWriter(new PrintWriter(System.out));
-      record = (EmblFile) unmar.unmarshal(file);
+      record = (EmblEntry) unmar.unmarshal(fileReader);
 
       canonicaliseDbRefs(record);
     } catch (Exception e)
@@ -147,13 +155,17 @@ public class EmblFile
    * Change blank version to "0" in any DBRefEntry, to ensure consistent
    * comparison with other DBRefEntry in Jalview
    * 
-   * @param record
+   * @param entry
    * @see Uniprot#getDbVersion
    */
-  static void canonicaliseDbRefs(EmblFile record)
+  static void canonicaliseDbRefs(EmblEntry entry)
   {
-    for (EmblEntry entry : record.getEntries())
+    if (entry == null)
     {
+      return;
+    }
+//    for (EmblEntry entry : record.getEntries())
+//    {
       if (entry.getDbRefs() != null)
       {
         for (DBRefEntry dbref : entry.getDbRefs())
@@ -165,7 +177,7 @@ public class EmblFile
         }
       }
 
-      if (entry.getFeatures() != null)
+    if (entry.getFeatures() != null)
       {
         for (EmblFeature feature : entry.getFeatures())
         {
@@ -181,6 +193,6 @@ public class EmblFile
           }
         }
       }
-    }
+    // }
   }
 }
index 50e1032..0c20e12 100644 (file)
@@ -118,7 +118,10 @@ public class EnsemblGene extends EnsemblSeqProxy
        * fetch the gene sequence(s) with features and xrefs
        */
       AlignmentI geneAlignment = super.getSequenceRecords(geneId);
-
+      if (geneAlignment == null)
+      {
+        continue;
+      }
       if (geneAlignment.getHeight() == 1)
       {
         getTranscripts(geneAlignment, geneId);
index 72efdc1..30dcee8 100644 (file)
@@ -34,10 +34,11 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
    * update these constants when Jalview has been checked / updated for
    * changes to Ensembl REST API
    * @see https://github.com/Ensembl/ensembl-rest/wiki/Change-log
+   * @see http://rest.ensembl.org/info/rest?content-type=application/json
    */
   private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "4.6";
 
-  private static final String LATEST_ENSEMBL_REST_VERSION = "4.6";
+  private static final String LATEST_ENSEMBL_REST_VERSION = "4.7";
 
   private static final String REST_CHANGE_LOG = "https://github.com/Ensembl/ensembl-rest/wiki/Change-log";
 
@@ -208,6 +209,11 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
     URL url = getUrl(ids);
   
     BufferedReader reader = getHttpResponse(url, ids);
+    if (reader == null)
+    {
+      // request failed
+      return null;
+    }
     FileParse fp = new FileParse(reader, url.toString(), "HTTP_POST");
     return fp;
   }
@@ -248,7 +254,6 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
       writePostBody(connection, ids);
     }
   
-    InputStream response = connection.getInputStream();
     int responseCode = connection.getResponseCode();
   
     if (responseCode != 200)
@@ -257,10 +262,12 @@ abstract class EnsemblRestClient extends EnsemblSequenceFetcher
        * note: a GET request for an invalid id returns an error code e.g. 415
        * but POST request returns 200 and an empty Fasta response 
        */
-      throw new IOException(
-              "Response code was not 200. Detected response was "
-                      + responseCode);
+      System.err.println("Response code " + responseCode + " for " + url);
+      return null;
     }
+    // get content
+    InputStream response = connection.getInputStream();
+
     // System.out.println(getClass().getName() + " took "
     // + (System.currentTimeMillis() - now) + "ms to fetch");
 
index 5fccedd..91b09ea 100644 (file)
@@ -2,9 +2,11 @@ package jalview.ext.ensembl;
 
 import jalview.analysis.AlignmentUtils;
 import jalview.analysis.Dna;
+import jalview.bin.Cache;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
 import jalview.datamodel.Mapping;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
@@ -158,6 +160,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
                 + " chunks. Unexpected problem (" + r.getLocalizedMessage()
                 + ")";
         System.err.println(msg);
+        r.printStackTrace();
         break;
       }
     }
@@ -281,6 +284,44 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
         DBRefEntry dbr = new DBRefEntry(getDbSource(),
                 getEnsemblDataVersion(), proteinSeq.getName(), map);
         querySeq.getDatasetSequence().addDBRef(dbr);
+        DBRefEntry[] uprots = DBRefUtils.selectRefs(ds.getDBRefs(),
+                new String[] { DBRefSource.UNIPROT });
+        DBRefEntry[] upxrefs = DBRefUtils.selectRefs(querySeq.getDBRefs(),
+                new String[] { DBRefSource.UNIPROT });
+        if (uprots != null)
+        {
+          for (DBRefEntry up : uprots)
+          {
+            // locate local uniprot ref and map
+            List<DBRefEntry> upx = DBRefUtils.searchRefs(upxrefs, up.getAccessionId());
+            DBRefEntry upxref;
+            if (upx.size() != 0)
+            {
+              upxref = upx.get(0);
+
+              if (upx.size() > 1)
+              {
+                Cache.log
+                        .warn("Implementation issue - multiple uniprot acc on product sequence.");
+              }
+            }
+            else
+            {
+              upxref = new DBRefEntry(DBRefSource.UNIPROT,
+                    getEnsemblDataVersion(), up.getAccessionId());
+            }
+
+            Mapping newMap = new Mapping(ds, mapList);
+            upxref.setVersion(getEnsemblDataVersion());
+            upxref.setMap(newMap);
+            if (upx.size() == 0)
+            {
+              // add the new uniprot ref
+              querySeq.getDatasetSequence().addDBRef(upxref);
+            }
+            
+          }
+        }
         
         /*
          * copy exon features to protein, compute peptide variants from dna 
@@ -343,6 +384,11 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
       throw new JalviewException("ENSEMBL Rest API not available.");
     }
     FileParse fp = getSequenceReader(ids);
+    if (fp == null)
+    {
+      return alignment;
+    }
+
     FastaFile fr = new FastaFile(fp);
     if (fr.hasWarningMessage())
     {
index 2ccf118..b1b5ce4 100644 (file)
@@ -449,12 +449,12 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
       }
       if (selectioncom.length() > 0)
       {
-        System.out.println("Select regions:\n" + selectioncom.toString());
+        // System.out.println("Select regions:\n" + selectioncom.toString());
         evalStateCommand("select *; cartoons off; backbone; select ("
                 + selectioncom.toString() + "); cartoons; ");
         // selcom.append("; ribbons; ");
         String cmdString = command.toString();
-        System.out.println("Superimpose command(s):\n" + cmdString);
+        // System.out.println("Superimpose command(s):\n" + cmdString);
 
         evalStateCommand(cmdString);
       }
@@ -465,7 +465,7 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
       {
         selectioncom.setLength(selectioncom.length() - 1);
       }
-      System.out.println("Select regions:\n" + selectioncom.toString());
+      // System.out.println("Select regions:\n" + selectioncom.toString());
       evalStateCommand("select *; cartoons off; backbone; select ("
               + selectioncom.toString() + "); cartoons; ");
       // evalStateCommand("select *; backbone; select "+selcom.toString()+"; cartoons; center "+selcom.toString());
index 7836d24..65b4b96 100644 (file)
@@ -28,6 +28,7 @@ import jalview.io.FileParse;
 import jalview.io.StructureFile;
 import jalview.schemes.ResidueProperties;
 import jalview.structure.StructureImportSettings;
+import jalview.util.Format;
 import jalview.util.MessageManager;
 
 import java.io.IOException;
@@ -60,15 +61,13 @@ public class JmolParser extends StructureFile implements JmolStatusListener
 {
   Viewer viewer = null;
 
-  public JmolParser(boolean addAlignmentAnnotations, boolean predictSecStr,
-          boolean externalSecStr, String inFile, String type)
+  public JmolParser(String inFile, String type)
           throws IOException
   {
     super(inFile, type);
   }
 
-  public JmolParser(boolean addAlignmentAnnotations, boolean predictSecStr,
-          boolean externalSecStr, FileParse fp) throws IOException
+  public JmolParser(FileParse fp) throws IOException
   {
     super(fp);
   }
@@ -125,8 +124,13 @@ public class JmolParser extends StructureFile implements JmolStatusListener
     {
       try
       {
+        /*
+         * params -o (output to sysout) -i (no info logging, less verbose)
+         * -n (nodisplay) -x (exit when finished)
+         * see http://wiki.jmol.org/index.php/Jmol_Application
+         */
         viewer = (Viewer) JmolViewer.allocateViewer(null, null, null, null,
-                null, "-x -o -n", this);
+                null, "-x -o -n -i", this);
         // ensure the 'new' (DSSP) not 'old' (Ramachandran) SS method is used
         viewer.setBooleanProperty("defaultStructureDSSP", true);
       } catch (ClassCastException x)
@@ -230,8 +234,8 @@ public class JmolParser extends StructureFile implements JmolStatusListener
         curAtom.resNumber = atom.getResno();
         curAtom.occupancy = ms.occupancies != null ? ms.occupancies[atom
                 .getIndex()] : Float.valueOf(atom.getOccupancy100());
-        curAtom.resNumIns = ("" + curAtom.resNumber + curAtom.insCode)
-                .trim();
+        String fmt = new Format("%4i").form(curAtom.resNumber);
+        curAtom.resNumIns = (fmt + curAtom.insCode);
         curAtom.tfactor = atom.getBfactor100() / 100f;
         curAtom.type = 0;
         // significantAtoms.add(curAtom);
index af80b7a..28ddfd9 100644 (file)
@@ -77,11 +77,11 @@ public class SequenceOntology implements SequenceOntologyI
    */
   protected void loadOntologyZipFile(String ontologyFile)
   {
+    long now = System.currentTimeMillis();
     ZipInputStream zipStream = null;
     try
     {
       String zipFile = ontologyFile + ".zip";
-      System.out.println("Loading Sequence Ontology from " + zipFile);
       InputStream inStream = this.getClass().getResourceAsStream(
               "/" + zipFile);
       zipStream = new ZipInputStream(new BufferedInputStream(inStream));
@@ -93,6 +93,9 @@ public class SequenceOntology implements SequenceOntologyI
           loadOboFile(zipStream);
         }
       }
+      long elapsed = System.currentTimeMillis() - now;
+      System.out.println("Loaded Sequence Ontology from " + zipFile + " ("
+              + elapsed + "ms)");
     } catch (Exception e)
     {
       e.printStackTrace();
index 00a081b..230cbdb 100644 (file)
@@ -451,7 +451,8 @@ public abstract class FTSRestClient implements FTSRestClientI
     case 502:
     case 504:
     case 505:
-      message = MessageManager.getString("exception.fts_server_error");
+      message = MessageManager.formatMessage("exception.fts_server_error",
+              service);
       break;
     case 503:
       message = MessageManager.getString("exception.service_not_available");
index 33fa020..30b6417 100644 (file)
@@ -35,6 +35,7 @@ import java.awt.CardLayout;
 import java.awt.Dimension;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
 import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
 import java.awt.event.KeyAdapter;
@@ -84,7 +85,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
   protected JInternalFrame mainFrame = new JInternalFrame(
           getFTSFrameTitle());
 
-  protected IProgressIndicator progressIdicator;
+  protected IProgressIndicator progressIndicator;
 
   protected JComboBox<FTSDataColumnI> cmb_searchTarget = new JComboBox<FTSDataColumnI>();
 
@@ -231,6 +232,14 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
     try
     {
       jbInit();
+      mainFrame.addFocusListener(new FocusAdapter()
+      {
+        @Override
+        public void focusGained(FocusEvent e)
+        {
+          txt_search.requestFocusInWindow();
+        }
+      });
       mainFrame.invalidate();
       mainFrame.pack();
     } catch (Exception e)
@@ -757,7 +766,7 @@ public abstract class GFTSPanel extends JPanel implements GFTSPanelI
   protected void btn_back_ActionPerformed()
   {
     closeAction();
-    new SequenceFetcher(progressIdicator);
+    new SequenceFetcher(progressIndicator);
   }
 
   protected void disableActionButtons()
index dc2b403..3fe8603 100644 (file)
@@ -48,7 +48,7 @@ public class PDBFTSPanel extends GFTSPanel
     super();
     pageLimit = PDBFTSRestClient.getInstance().getDefaultResponsePageSize();
     this.seqFetcher = seqFetcher;
-    this.progressIdicator = (seqFetcher == null) ? null : seqFetcher
+    this.progressIndicator = (seqFetcher == null) ? null : seqFetcher
             .getProgressIndicator();
   }
 
index 5691db1..0d02cc0 100644 (file)
@@ -50,7 +50,7 @@ public class UniprotFTSPanel extends GFTSPanel
     pageLimit = UniProtFTSRestClient.getInstance()
             .getDefaultResponsePageSize();
     this.seqFetcher = seqFetcher;
-    this.progressIdicator = (seqFetcher == null) ? null : seqFetcher
+    this.progressIndicator = (seqFetcher == null) ? null : seqFetcher
             .getProgressIndicator();
   }
 
index 1848595..49bd138 100644 (file)
@@ -2977,9 +2977,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       // Hide everything by the current selection - this is a hack - we do the
       // invert and then hide
       // first check that there will be visible columns after the invert.
-      if ((viewport.getColumnSelection() != null
-              && viewport.getColumnSelection().getSelected() != null && viewport
-              .getColumnSelection().getSelected().size() > 0)
+      if (viewport.hasSelectedColumns()
               || (sg != null && sg.getSize() > 0 && sg.getStartRes() <= sg
                       .getEndRes()))
       {
@@ -3007,8 +3005,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         hideSelSequences_actionPerformed(null);
         hide = true;
       }
-      else if (!(toggleCols && viewport.getColumnSelection().getSelected()
-              .size() > 0))
+      else if (!(toggleCols && viewport.hasSelectedColumns()))
       {
         showAllSeqs_actionPerformed(null);
       }
@@ -3016,7 +3013,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
 
     if (toggleCols)
     {
-      if (viewport.getColumnSelection().getSelected().size() > 0)
+      if (viewport.hasSelectedColumns())
       {
         hideSelColumns_actionPerformed(null);
         if (!toggleSeqs)
index 62e05d0..f755b25 100644 (file)
@@ -419,10 +419,11 @@ public class AlignViewport extends AlignmentViewport implements
    * @param align
    *          DOCUMENT ME!
    */
+  @Override
   public void setAlignment(AlignmentI align)
   {
     replaceMappings(align);
-    this.alignment = align;
+    super.setAlignment(align);
   }
 
   /**
index 87d5933..424d52f 100644 (file)
@@ -101,6 +101,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
    */
   private boolean dontScrollComplement;
 
+  private PropertyChangeListener propertyChangeListener;
+
   /**
    * Creates a new AlignmentPanel object.
    * 
@@ -135,7 +137,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
     vscroll.addAdjustmentListener(this);
 
     final AlignmentPanel ap = this;
-    av.addPropertyChangeListener(new PropertyChangeListener()
+    propertyChangeListener = new PropertyChangeListener()
     {
       @Override
       public void propertyChange(PropertyChangeEvent evt)
@@ -146,7 +148,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
           alignmentChanged();
         }
       }
-    });
+    };
+    av.addPropertyChangeListener(propertyChangeListener);
     fontChanged();
     adjustAnnotationHeight();
     updateLayout();
@@ -1595,8 +1598,18 @@ public class AlignmentPanel extends GAlignmentPanel implements
     PaintRefresher.RemoveComponent(getSeqPanel().seqCanvas);
     PaintRefresher.RemoveComponent(getIdPanel().getIdCanvas());
     PaintRefresher.RemoveComponent(this);
+
+    /*
+     * try to ensure references are nulled
+     */
+    if (annotationPanel != null)
+    {
+      annotationPanel.dispose();
+    }
+
     if (av != null)
     {
+      av.removePropertyChangeListener(propertyChangeListener);
       jalview.structure.StructureSelectionManager ssm = av
               .getStructureSelectionManager();
       ssm.removeStructureViewerListener(getSeqPanel(), null);
@@ -1604,7 +1617,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
       ssm.removeCommandListener(av);
       ssm.removeStructureViewerListener(getSeqPanel(), null);
       ssm.removeSelectionListener(getSeqPanel());
-      av.setAlignment(null);
+      av.dispose();
       av = null;
     }
     else
index 93c9a6b..39cde03 100644 (file)
@@ -210,7 +210,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        ok_actionPerformed(e);
+        ok_actionPerformed();
       }
     });
     cancel.setOpaque(false);
@@ -220,7 +220,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        cancel_actionPerformed(e);
+        cancel_actionPerformed();
       }
     });
     defColours.setOpaque(false);
@@ -233,7 +233,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent arg0)
       {
-        resetColours_actionPerformed(arg0);
+        resetColours_actionPerformed();
       }
     });
 
@@ -242,7 +242,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        annotations_actionPerformed(e);
+        annotations_actionPerformed();
       }
     });
     getThreshold().addActionListener(new ActionListener()
@@ -250,7 +250,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        threshold_actionPerformed(e);
+        threshold_actionPerformed();
       }
     });
     thresholdValue.addActionListener(new ActionListener()
@@ -258,7 +258,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        thresholdValue_actionPerformed(e);
+        thresholdValue_actionPerformed();
       }
     });
     slider.setPaintLabels(false);
@@ -278,7 +278,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        currentColours_actionPerformed(e);
+        currentColours_actionPerformed();
       }
     });
     thresholdIsMin.setBackground(Color.white);
@@ -290,7 +290,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent actionEvent)
       {
-        thresholdIsMin_actionPerformed(actionEvent);
+        thresholdIsMin_actionPerformed();
       }
     });
     seqAssociated.setBackground(Color.white);
@@ -303,7 +303,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
       @Override
       public void actionPerformed(ActionEvent arg0)
       {
-        seqAssociated_actionPerformed(arg0, annotations, seqAssociated);
+        seqAssociated_actionPerformed(annotations);
       }
     });
 
@@ -332,7 +332,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
     this.validate();
   }
 
-  protected void resetColours_actionPerformed(ActionEvent arg0)
+  protected void resetColours_actionPerformed()
   {
     setDefaultMinMax();
     updateView();
@@ -372,6 +372,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
     updateView();
   }
 
+  @Override
   public void reset()
   {
     av.setGlobalColourScheme(oldcs);
@@ -385,6 +386,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
     }
   }
 
+  @Override
   public void valueChanged(boolean updateAllAnnotation)
   {
     if (slider.isEnabled())
@@ -411,7 +413,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
     this.threshold = threshold;
   }
 
-  public void currentColours_actionPerformed(ActionEvent e)
+  public void currentColours_actionPerformed()
   {
     if (currentColours.isSelected())
     {
index c0d7084..1290d70 100644 (file)
@@ -178,7 +178,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        ok_actionPerformed(e);
+        ok_actionPerformed();
       }
     });
 
@@ -189,7 +189,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        cancel_actionPerformed(e);
+        cancel_actionPerformed();
       }
     });
 
@@ -201,7 +201,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        threshold_actionPerformed(e);
+        threshold_actionPerformed();
       }
     });
 
@@ -212,7 +212,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        thresholdValue_actionPerformed(e);
+        thresholdValue_actionPerformed();
       }
     });
 
@@ -288,14 +288,15 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
     String defaultTtip = MessageManager
             .getString("info.change_threshold_mode_to_enable");
 
-    String threshold = getThreshold().getSelectedItem().toString();
-    if (threshold.equalsIgnoreCase("No Threshold"))
+    String thresh = getThreshold().getSelectedItem().toString();
+    if (thresh.equalsIgnoreCase("No Threshold"))
     {
       thresholdValue.setToolTipText(defaultTtip);
       slider.setToolTipText(defaultTtip);
     }
   }
 
+  @Override
   public void reset()
   {
     if (this.getOldColumnSelection() != null)
@@ -324,6 +325,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
 
   }
 
+  @Override
   public void valueChanged(boolean updateAllAnnotation)
   {
     if (slider.isEnabled())
index 92c6dc6..1a9541c 100755 (executable)
@@ -219,6 +219,7 @@ public class AnnotationLabels extends JPanel implements MouseListener,
     AlignmentAnnotation[] aa = ap.av.getAlignment()
             .getAlignmentAnnotation();
 
+    boolean fullRepaint = false;
     if (evt.getActionCommand().equals(ADDNEW))
     {
       AlignmentAnnotation newAnnotation = new AlignmentAnnotation(null,
@@ -231,11 +232,16 @@ public class AnnotationLabels extends JPanel implements MouseListener,
 
       ap.av.getAlignment().addAnnotation(newAnnotation);
       ap.av.getAlignment().setAnnotationIndex(newAnnotation, 0);
+      fullRepaint = true;
     }
     else if (evt.getActionCommand().equals(EDITNAME))
     {
+      String name = aa[selectedRow].label;
       editLabelDescription(aa[selectedRow]);
-      repaint();
+      if (!name.equalsIgnoreCase(aa[selectedRow].label))
+      {
+        fullRepaint = true;
+      }
     }
     else if (evt.getActionCommand().equals(HIDE))
     {
@@ -245,6 +251,7 @@ public class AnnotationLabels extends JPanel implements MouseListener,
     {
       ap.av.getAlignment().deleteAnnotation(aa[selectedRow]);
       ap.av.getCalcManager().removeWorkerForAnnotation(aa[selectedRow]);
+      fullRepaint = true;
     }
     else if (evt.getActionCommand().equals(SHOWALL))
     {
@@ -255,6 +262,7 @@ public class AnnotationLabels extends JPanel implements MouseListener,
           aa[i].visible = true;
         }
       }
+      fullRepaint = true;
     }
     else if (evt.getActionCommand().equals(OUTPUT_TEXT))
     {
@@ -283,18 +291,30 @@ public class AnnotationLabels extends JPanel implements MouseListener,
       aa[selectedRow].scaleColLabel = !aa[selectedRow].scaleColLabel;
     }
 
-    refresh();
+    refresh(fullRepaint);
 
   }
 
   /**
    * Redraw sensibly.
+   * 
+   * @adjustHeight if true, try to recalculate panel height for visible
+   *               annotations
    */
-  protected void refresh()
+  protected void refresh(boolean adjustHeight)
   {
-    ap.validateAnnotationDimensions(false);
+    ap.validateAnnotationDimensions(adjustHeight);
     ap.addNotify();
-    ap.repaint();
+    if (adjustHeight)
+    {
+      // sort, repaint, update overview
+      ap.paintAlignment(true);
+    }
+    else
+    {
+      // lightweight repaint
+      ap.repaint();
+    }
   }
 
   /**
@@ -305,6 +325,7 @@ public class AnnotationLabels extends JPanel implements MouseListener,
    */
   boolean editLabelDescription(AlignmentAnnotation annotation)
   {
+    // TODO i18n
     EditNameDialog dialog = new EditNameDialog(annotation.label,
             annotation.description, "       Annotation Name ",
             "Annotation Description ", "Edit Annotation Name/Description",
@@ -398,7 +419,7 @@ public class AnnotationLabels extends JPanel implements MouseListener,
             // ann.visible = false;
             // }
             // }
-            refresh();
+            refresh(true);
           }
         });
         pop.add(hideType);
@@ -460,6 +481,7 @@ public class AnnotationLabels extends JPanel implements MouseListener,
             {
               ap.av.setIgnoreGapsConsensus(cbmi.getState(), ap);
             }
+            ap.alignmentChanged();
           }
         });
         pop.add(cbmi);
index bd903b3..0b2f6cc 100755 (executable)
@@ -49,6 +49,7 @@ import java.awt.event.MouseMotionListener;
 import java.awt.event.MouseWheelEvent;
 import java.awt.event.MouseWheelListener;
 import java.awt.image.BufferedImage;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
@@ -122,8 +123,6 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
 
   boolean mouseDragging = false;
 
-  boolean MAC = false;
-
   // for editing cursor
   int cursorX = 0;
 
@@ -141,9 +140,6 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
    */
   public AnnotationPanel(AlignmentPanel ap)
   {
-
-    MAC = jalview.util.Platform.isAMac();
-
     ToolTipManager.sharedInstance().registerComponent(this);
     ToolTipManager.sharedInstance().setInitialDelay(0);
     ToolTipManager.sharedInstance().setDismissDelay(10000);
@@ -445,8 +441,12 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     StringBuilder collatedInput = new StringBuilder(64);
     String last = "";
     ColumnSelection viscols = av.getColumnSelection();
-    // TODO: refactor and save av.getColumnSelection for efficiency
-    List<Integer> selected = viscols.getSelected();
+
+    /*
+     * the selection list (read-only view) is in selection order, not
+     * column order; make a copy so we can sort it
+     */
+    List<Integer> selected = new ArrayList<Integer>(viscols.getSelected());
     Collections.sort(selected);
     for (int index : selected)
     {
@@ -1134,4 +1134,25 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
       return null;
     }
   }
+
+  /**
+   * Try to ensure any references held are nulled
+   */
+  public void dispose()
+  {
+    av = null;
+    ap = null;
+    image = null;
+    fadedImage = null;
+    gg = null;
+    _mwl = null;
+
+    /*
+     * I created the renderer so I will dispose of it
+     */
+    if (renderer != null)
+    {
+      renderer.dispose();
+    }
+  }
 }
index f0bea60..37f1e55 100644 (file)
@@ -26,7 +26,6 @@ import jalview.datamodel.SequenceGroup;
 import jalview.schemes.AnnotationColourGradient;
 import jalview.util.MessageManager;
 
-import java.awt.event.ActionEvent;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.util.Vector;
@@ -52,7 +51,7 @@ public abstract class AnnotationRowFilter extends JPanel
 
   protected boolean enableSeqAss = false;
 
-  private jalview.datamodel.AlignmentAnnotation currentAnnotation;
+  private AlignmentAnnotation currentAnnotation;
 
   protected boolean adjusting = false;
 
@@ -161,11 +160,20 @@ public abstract class AnnotationRowFilter extends JPanel
         enableSeqAss = true;
       }
       String label = av.getAlignment().getAlignmentAnnotation()[i].label;
+      // add associated sequence ID if available
+      if (!isSeqAssociated
+              && av.getAlignment().getAlignmentAnnotation()[i].sequenceRef != null)
+      {
+        label = label
+                + "_"
+                + av.getAlignment().getAlignmentAnnotation()[i].sequenceRef
+                        .getName();
+      }
+      // make label unique
       if (!list.contains(label))
       {
         anmap[list.size()] = i;
         list.add(label);
-
       }
       else
       {
@@ -200,7 +208,7 @@ public abstract class AnnotationRowFilter extends JPanel
     seqAssociated.setEnabled(enableSeqAss);
   }
 
-  public void ok_actionPerformed(ActionEvent e)
+  public void ok_actionPerformed()
   {
     try
     {
@@ -210,7 +218,7 @@ public abstract class AnnotationRowFilter extends JPanel
     }
   }
 
-  public void cancel_actionPerformed(ActionEvent e)
+  public void cancel_actionPerformed()
   {
     reset();
     ap.paintAlignment(true);
@@ -222,22 +230,22 @@ public abstract class AnnotationRowFilter extends JPanel
     }
   }
 
-  public void thresholdCheck_actionPerformed(ActionEvent e)
+  public void thresholdCheck_actionPerformed()
   {
     updateView();
   }
 
-  public void annotations_actionPerformed(ActionEvent e)
+  public void annotations_actionPerformed()
   {
     updateView();
   }
 
-  public void threshold_actionPerformed(ActionEvent e)
+  public void threshold_actionPerformed()
   {
     updateView();
   }
 
-  public void thresholdValue_actionPerformed(ActionEvent e)
+  public void thresholdValue_actionPerformed()
   {
     try
     {
@@ -249,7 +257,7 @@ public abstract class AnnotationRowFilter extends JPanel
     }
   }
 
-  public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
+  public void thresholdIsMin_actionPerformed()
   {
     updateView();
   }
@@ -264,8 +272,7 @@ public abstract class AnnotationRowFilter extends JPanel
             .getString("label.threshold_feature_below_threshold"));
   }
 
-  protected void seqAssociated_actionPerformed(ActionEvent arg0,
-          JComboBox<String> annotations, JCheckBox seqAssociated)
+  protected void seqAssociated_actionPerformed(JComboBox<String> annotations)
   {
     adjusting = true;
     String cursel = (String) annotations.getSelectedItem();
@@ -323,25 +330,25 @@ public abstract class AnnotationRowFilter extends JPanel
   }
 
   protected boolean colorAlignmContaining(
-          AlignmentAnnotation currentAnnotation, int selectedThresholdItem)
+          AlignmentAnnotation currentAnn, int selectedThresholdOption)
   {
 
     AnnotationColourGradient acg = null;
     if (currentColours.isSelected())
     {
-      acg = new AnnotationColourGradient(currentAnnotation,
-              av.getGlobalColourScheme(), selectedThresholdItem);
+      acg = new AnnotationColourGradient(currentAnn,
+              av.getGlobalColourScheme(), selectedThresholdOption);
     }
     else
     {
-      acg = new AnnotationColourGradient(currentAnnotation,
+      acg = new AnnotationColourGradient(currentAnn,
               minColour.getBackground(), maxColour.getBackground(),
-              selectedThresholdItem);
+              selectedThresholdOption);
     }
     acg.setSeqAssociated(seqAssociated.isSelected());
 
-    if (currentAnnotation.graphMin == 0f
-            && currentAnnotation.graphMax == 0f)
+    if (currentAnn.graphMin == 0f
+            && currentAnn.graphMax == 0f)
     {
       acg.setPredefinedColours(true);
     }
@@ -362,17 +369,17 @@ public abstract class AnnotationRowFilter extends JPanel
 
         if (currentColours.isSelected())
         {
-          sg.cs = new AnnotationColourGradient(currentAnnotation, sg.cs,
-                  selectedThresholdItem);
+          sg.cs = new AnnotationColourGradient(currentAnn, sg.cs,
+                  selectedThresholdOption);
           ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
                   .isSelected());
 
         }
         else
         {
-          sg.cs = new AnnotationColourGradient(currentAnnotation,
+          sg.cs = new AnnotationColourGradient(currentAnn,
                   minColour.getBackground(), maxColour.getBackground(),
-                  selectedThresholdItem);
+                  selectedThresholdOption);
           ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
                   .isSelected());
         }
index a1846bc..2299c26 100644 (file)
@@ -41,6 +41,7 @@ import jalview.schemes.ZappoColourScheme;
 import jalview.structures.models.AAStructureBindingModel;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
+import jalview.ws.dbsources.Pdb;
 
 import java.awt.BorderLayout;
 import java.awt.Color;
@@ -70,6 +71,7 @@ import javax.swing.JMenuItem;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JSplitPane;
+import javax.swing.SwingUtilities;
 import javax.swing.event.InternalFrameAdapter;
 import javax.swing.event.InternalFrameEvent;
 import javax.swing.event.MenuEvent;
@@ -77,6 +79,10 @@ import javax.swing.event.MenuListener;
 
 public class AppJmol extends StructureViewerBase
 {
+  private static final String SPACE = " ";
+
+  private static final String BACKSLASH = "\"";
+
   AppJmolBinding jmb;
 
   JPanel scriptWindow;
@@ -375,8 +381,11 @@ public class AppJmol extends StructureViewerBase
       scriptWindow.setVisible(false);
     }
 
-    jmb.allocateViewer(renderPanel, true, "", null, null, "", scriptWindow,
-            null);
+    /*
+     * -i for no info logging (less verbose)
+     */
+    jmb.allocateViewer(renderPanel, true, "", null, null, "-i",
+            scriptWindow, null);
     // jmb.newJmolPopup("Jmol");
     if (command == null)
     {
@@ -475,15 +484,163 @@ public class AppJmol extends StructureViewerBase
   public void run()
   {
     _started = true;
+    try
+    {
+      List<String> files = fetchPdbFiles();
+      if (files.size() > 0)
+      {
+        showFilesInViewer(files);
+      }
+    } finally
+    {
+      _started = false;
+      worker = null;
+    }
+  }
+
+  /**
+   * Either adds the given files to a structure viewer or opens a new viewer to
+   * show them
+   * 
+   * @param files
+   *          list of absolute paths to structure files
+   */
+  void showFilesInViewer(List<String> files)
+  {
+    long lastnotify = jmb.getLoadNotifiesHandled();
+    StringBuilder fileList = new StringBuilder();
+    for (String s : files)
+    {
+      fileList.append(SPACE).append(BACKSLASH).append(Platform.escapeString(s))
+              .append(BACKSLASH);
+    }
+    String filesString = fileList.toString();
+
+    if (!addingStructures)
+    {
+      try
+      {
+        initJmol("load FILES " + filesString);
+      } catch (OutOfMemoryError oomerror)
+      {
+        new OOMWarning("When trying to open the Jmol viewer!", oomerror);
+        Cache.log.debug("File locations are " + filesString);
+      } catch (Exception ex)
+      {
+        Cache.log.error("Couldn't open Jmol viewer!", ex);
+      }
+    }
+    else
+    {
+      StringBuilder cmd = new StringBuilder();
+      cmd.append("loadingJalviewdata=true\nload APPEND ");
+      cmd.append(filesString);
+      cmd.append("\nloadingJalviewdata=null");
+      final String command = cmd.toString();
+      lastnotify = jmb.getLoadNotifiesHandled();
+
+      try
+      {
+        jmb.evalStateCommand(command);
+      } catch (OutOfMemoryError oomerror)
+      {
+        new OOMWarning(
+                "When trying to add structures to the Jmol viewer!",
+                oomerror);
+        Cache.log.debug("File locations are " + filesString);
+      } catch (Exception ex)
+      {
+        Cache.log.error("Couldn't add files to Jmol viewer!", ex);
+      }
+    }
+
+    // need to wait around until script has finished
+    int waitMax = 5000; // give up after 5 seconds
+    int waitFor = 35;
+    int waitTotal = 0;
+    while (addingStructures ? lastnotify >= jmb.getLoadNotifiesHandled()
+            : !(jmb.isFinishedInit() && jmb.getPdbFile() != null && jmb
+                    .getPdbFile().length == files.size()))
+    {
+      try
+      {
+        Cache.log.debug("Waiting around for jmb notify.");
+        Thread.sleep(waitFor);
+        waitTotal += waitFor;
+      } catch (Exception e)
+      {
+      }
+      if (waitTotal > waitMax)
+      {
+        System.err.println("Timed out waiting for Jmol to load files");
+        break;
+      }
+    }
+
+    // refresh the sequence colours for the new structure(s)
+    for (AlignmentPanel ap : _colourwith)
+    {
+      jmb.updateColours(ap);
+    }
+    // do superposition if asked to
+    if (Cache.getDefault("AUTOSUPERIMPOSE", true) && alignAddedStructures)
+    {
+      alignAddedStructures();
+    }
+    addingStructures = false;
+  }
+
+  /**
+   * Queues a thread to align structures with Jalview alignments
+   */
+  void alignAddedStructures()
+  {
+    javax.swing.SwingUtilities.invokeLater(new Runnable()
+    {
+      @Override
+      public void run()
+      {
+        if (jmb.viewer.isScriptExecuting())
+        {
+          SwingUtilities.invokeLater(this);
+          try
+          {
+            Thread.sleep(5);
+          } catch (InterruptedException q)
+          {
+          }
+          return;
+        }
+        else
+        {
+          alignStructs_withAllAlignPanels();
+        }
+      }
+    });
+    alignAddedStructures = false;
+  }
+
+  /**
+   * Retrieves and saves as file any modelled PDB entries for which we do not
+   * already have a file saved. Returns a list of absolute paths to structure
+   * files which were either retrieved, or already stored but not modelled in
+   * the structure viewer (i.e. files to add to the viewer display).
+   * 
+   * @return
+   */
+  List<String> fetchPdbFiles()
+  {
+    // todo - record which pdbids were successfully imported.
+    StringBuilder errormsgs = new StringBuilder();
+
+    List<String> files = new ArrayList<String>();
     String pdbid = "";
-    // todo - record which pdbids were successfuly imported.
-    StringBuffer errormsgs = new StringBuffer(), files = new StringBuffer();
     try
     {
-      String[] curfiles = jmb.getPdbFile(); // files currently in viewer
+      String[] filesInViewer = jmb.getPdbFile();
       // TODO: replace with reference fetching/transfer code (validate PDBentry
       // as a DBRef?)
-      jalview.ws.dbsources.Pdb pdbclient = new jalview.ws.dbsources.Pdb();
+      Pdb pdbclient = new Pdb();
       for (int pi = 0; pi < jmb.getPdbCount(); pi++)
       {
         String file = jmb.getPdbEntry(pi).getFile();
@@ -507,12 +664,15 @@ public class AppJmol extends StructureViewerBase
           } catch (Exception ex)
           {
             ex.printStackTrace();
-            errormsgs.append("'" + pdbid + "'");
-          }
-          if (progressBar != null)
+            errormsgs.append("'").append(pdbid).append("'");
+          } finally
           {
-            progressBar.setProgressBar(
-                    MessageManager.getString("label.state_completed"), hdl);
+            if (progressBar != null)
+            {
+              progressBar.setProgressBar(
+                      MessageManager.getString("label.state_completed"),
+                      hdl);
+            }
           }
           if (pdbseq != null)
           {
@@ -521,22 +681,21 @@ public class AppJmol extends StructureViewerBase
             file = new File(pdbseq.getSequenceAt(0).getAllPDBEntries()
                     .elementAt(0).getFile()).getAbsolutePath();
             jmb.getPdbEntry(pi).setFile(file);
-
-            files.append(" \"" + Platform.escapeString(file) + "\"");
+            files.add(file);
           }
           else
           {
-            errormsgs.append("'" + pdbid + "' ");
+            errormsgs.append("'").append(pdbid).append("' ");
           }
         }
         else
         {
-          if (curfiles != null && curfiles.length > 0)
+          if (filesInViewer != null && filesInViewer.length > 0)
           {
             addingStructures = true; // already files loaded.
-            for (int c = 0; c < curfiles.length; c++)
+            for (int c = 0; c < filesInViewer.length; c++)
             {
-              if (curfiles[c].equals(file))
+              if (filesInViewer[c].equals(file))
               {
                 file = null;
                 break;
@@ -545,7 +704,7 @@ public class AppJmol extends StructureViewerBase
           }
           if (file != null)
           {
-            files.append(" \"" + Platform.escapeString(file) + "\"");
+            files.add(file);
           }
         }
       }
@@ -555,114 +714,18 @@ public class AppJmol extends StructureViewerBase
     } catch (Exception ex)
     {
       ex.printStackTrace();
-      errormsgs.append("When retrieving pdbfiles : current was: '" + pdbid
-              + "'");
+      errormsgs.append("When retrieving pdbfiles : current was: '")
+              .append(pdbid).append("'");
     }
     if (errormsgs.length() > 0)
     {
-
       JOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
               .formatMessage("label.pdb_entries_couldnt_be_retrieved",
                       new String[] { errormsgs.toString() }),
               MessageManager.getString("label.couldnt_load_file"),
               JOptionPane.ERROR_MESSAGE);
-
-    }
-    long lastnotify = jmb.getLoadNotifiesHandled();
-    if (files.length() > 0)
-    {
-      if (!addingStructures)
-      {
-
-        try
-        {
-          initJmol("load FILES " + files.toString());
-        } catch (OutOfMemoryError oomerror)
-        {
-          new OOMWarning("When trying to open the Jmol viewer!", oomerror);
-          Cache.log.debug("File locations are " + files);
-        } catch (Exception ex)
-        {
-          Cache.log.error("Couldn't open Jmol viewer!", ex);
-        }
-      }
-      else
-      {
-        StringBuffer cmd = new StringBuffer();
-        cmd.append("loadingJalviewdata=true\nload APPEND ");
-        cmd.append(files.toString());
-        cmd.append("\nloadingJalviewdata=null");
-        final String command = cmd.toString();
-        cmd = null;
-        lastnotify = jmb.getLoadNotifiesHandled();
-
-        try
-        {
-          jmb.evalStateCommand(command);
-        } catch (OutOfMemoryError oomerror)
-        {
-          new OOMWarning(
-                  "When trying to add structures to the Jmol viewer!",
-                  oomerror);
-          Cache.log.debug("File locations are " + files);
-        } catch (Exception ex)
-        {
-          Cache.log.error("Couldn't add files to Jmol viewer!", ex);
-        }
-      }
-
-      // need to wait around until script has finished
-      while (addingStructures ? lastnotify >= jmb.getLoadNotifiesHandled()
-              : (!jmb.isFinishedInit() && jmb.getPdbFile() != null && jmb
-                      .getPdbFile().length != jmb.getPdbCount()))
-      {
-        try
-        {
-          Cache.log.debug("Waiting around for jmb notify.");
-          Thread.sleep(35);
-        } catch (Exception e)
-        {
-        }
-      }
-
-      // refresh the sequence colours for the new structure(s)
-      for (AlignmentPanel ap : _colourwith)
-      {
-        jmb.updateColours(ap);
-      }
-      // do superposition if asked to
-      if (Cache.getDefault("AUTOSUPERIMPOSE", true) && alignAddedStructures)
-      {
-        javax.swing.SwingUtilities.invokeLater(new Runnable()
-        {
-          @Override
-          public void run()
-          {
-            if (jmb.viewer.isScriptExecuting())
-            {
-              javax.swing.SwingUtilities.invokeLater(this);
-              try
-              {
-                Thread.sleep(5);
-              } catch (InterruptedException q)
-              {
-              }
-              ;
-              return;
-            }
-            else
-            {
-              alignStructs_withAllAlignPanels();
-            }
-          }
-        });
-        alignAddedStructures = false;
-      }
-      addingStructures = false;
-
     }
-    _started = false;
-    worker = null;
+    return files;
   }
 
   @Override
index 387a2a9..00b359a 100644 (file)
@@ -64,12 +64,10 @@ import java.awt.event.FocusListener;
 import java.awt.event.KeyEvent;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
 import java.awt.event.WindowAdapter;
 import java.awt.event.WindowEvent;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
-import java.beans.PropertyVetoException;
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileOutputStream;
@@ -102,6 +100,8 @@ import javax.swing.KeyStroke;
 import javax.swing.SwingUtilities;
 import javax.swing.event.HyperlinkEvent;
 import javax.swing.event.HyperlinkEvent.EventType;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
 import javax.swing.event.MenuEvent;
 import javax.swing.event.MenuListener;
 
@@ -814,24 +814,25 @@ public class Desktop extends jalview.jbgui.GDesktop implements
               * ((openFrameCount - 1) % 10) + yOffset);
     }
 
+    /*
+     * add an entry for the new frame in the Window menu 
+     * (and remove it when the frame is closed)
+     */
     final JMenuItem menuItem = new JMenuItem(title);
-    frame.addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
+    frame.addInternalFrameListener(new InternalFrameAdapter()
     {
       @Override
-      public void internalFrameActivated(
-              javax.swing.event.InternalFrameEvent evt)
+      public void internalFrameActivated(InternalFrameEvent evt)
       {
         JInternalFrame itf = desktop.getSelectedFrame();
         if (itf != null)
         {
           itf.requestFocus();
         }
-
       }
 
       @Override
-      public void internalFrameClosed(
-              javax.swing.event.InternalFrameEvent evt)
+      public void internalFrameClosed(InternalFrameEvent evt)
       {
         PaintRefresher.RemoveComponent(frame);
 
@@ -843,11 +844,23 @@ public class Desktop extends jalview.jbgui.GDesktop implements
         {
           openFrameCount--;
         }
+
+        /*
+         * ensure no reference to alignFrame retained by menu item listener
+         */
+        if (menuItem.getActionListeners().length > 0)
+        {
+          menuItem.removeActionListener(menuItem.getActionListeners()[0]);
+        }
         windowMenu.remove(menuItem);
         JInternalFrame itf = desktop.getSelectedFrame();
         if (itf != null)
         {
           itf.requestFocus();
+          if (itf instanceof AlignFrame)
+          {
+            Jalview.setCurrentAlignFrame((AlignFrame) itf);
+          }
         }
         System.gc();
       };
@@ -868,47 +881,6 @@ public class Desktop extends jalview.jbgui.GDesktop implements
         }
       }
     });
-    menuItem.addMouseListener(new MouseListener()
-    {
-
-      @Override
-      public void mouseReleased(MouseEvent e)
-      {
-      }
-
-      @Override
-      public void mousePressed(MouseEvent e)
-      {
-      }
-
-      @Override
-      public void mouseExited(MouseEvent e)
-      {
-        try
-        {
-          frame.setSelected(false);
-        } catch (PropertyVetoException e1)
-        {
-        }
-      }
-
-      @Override
-      public void mouseEntered(MouseEvent e)
-      {
-        try
-        {
-          frame.setSelected(true);
-        } catch (PropertyVetoException e1)
-        {
-        }
-      }
-
-      @Override
-      public void mouseClicked(MouseEvent e)
-      {
-
-      }
-    });
 
     windowMenu.add(menuItem);
 
@@ -1328,6 +1300,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
   @Override
   public void closeAll_actionPerformed(ActionEvent e)
   {
+    // TODO show a progress bar while closing?
     JInternalFrame[] frames = desktop.getAllFrames();
     for (int i = 0; i < frames.length; i++)
     {
@@ -1338,6 +1311,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       {
       }
     }
+    Jalview.setCurrentAlignFrame(null);
     System.out.println("ALL CLOSED");
     if (v_client != null)
     {
@@ -1354,6 +1328,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     {
       ssm.resetAll();
     }
+    System.gc();
   }
 
   @Override
index 59c34ec..2a3d788 100644 (file)
@@ -323,7 +323,6 @@ public class JDatabaseTree extends JalviewDialog implements KeyListener
   protected void okPressed()
   {
     _setSelectionState();
-    closeDialog();
   }
 
   @Override
index aad4bb8..473d8ab 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.gui;
 
+import jalview.analysis.Conservation;
 import jalview.api.FeatureColourI;
 import jalview.api.ViewStyleI;
 import jalview.api.structures.JalviewStructureDisplayI;
@@ -3387,8 +3388,7 @@ public class Jalview2XML
         }
         if (jGroup.getConsThreshold() != 0)
         {
-          jalview.analysis.Conservation c = new jalview.analysis.Conservation(
-                  "All", ResidueProperties.propHash, 3,
+          Conservation c = new Conservation("All", 3,
                   sg.getSequences(null), 0, sg.getWidth() - 1);
           c.calculate();
           c.verdict(false, 25);
index 61e20fa..f8a296f 100755 (executable)
@@ -20,6 +20,7 @@
  */
 package jalview.gui;
 
+import jalview.analysis.Conservation;
 import jalview.binding.Annotation;
 import jalview.binding.AnnotationElement;
 import jalview.binding.Features;
@@ -37,7 +38,6 @@ import jalview.binding.Viewport;
 import jalview.datamodel.PDBEntry;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.ResidueProperties;
 import jalview.structure.StructureSelectionManager;
 import jalview.util.MessageManager;
 import jalview.util.jarInputStreamProvider;
@@ -359,8 +359,7 @@ public class Jalview2XML_V1
 
         if (groups[i].getConsThreshold() != 0)
         {
-          jalview.analysis.Conservation c = new jalview.analysis.Conservation(
-                  "All", ResidueProperties.propHash, 3,
+          Conservation c = new Conservation("All", 3,
                   sg.getSequences(null), 0, sg.getWidth() - 1);
           c.calculate();
           c.verdict(false, 25);
index d28dc60..939c087 100644 (file)
@@ -49,7 +49,6 @@ import jalview.schemes.HydrophobicColourScheme;
 import jalview.schemes.NucleotideColourScheme;
 import jalview.schemes.PIDColourScheme;
 import jalview.schemes.PurinePyrimidineColourScheme;
-import jalview.schemes.ResidueProperties;
 import jalview.schemes.StrandColourScheme;
 import jalview.schemes.TaylorColourScheme;
 import jalview.schemes.TurnColourScheme;
@@ -2039,9 +2038,8 @@ public class PopupMenu extends JPopupMenu
     if (conservationMenuItem.isSelected())
     {
       // JBPNote: Conservation name shouldn't be i18n translated
-      Conservation c = new Conservation("Group",
-              ResidueProperties.propHash, 3, sg.getSequences(ap.av
-                      .getHiddenRepSequences()), sg.getStartRes(),
+      Conservation c = new Conservation("Group", 3, sg.getSequences(ap.av
+              .getHiddenRepSequences()), sg.getStartRes(),
               sg.getEndRes() + 1);
 
       c.calculate();
index 33c7ff3..af8b2f3 100644 (file)
@@ -65,8 +65,6 @@ import javax.swing.table.AbstractTableModel;
 public class StructureChooser extends GStructureChooser implements
         IProgressIndicator
 {
-  private boolean structuresDiscovered = false;
-
   private SequenceI selectedSequence;
 
   private SequenceI[] selectedSequences;
@@ -103,6 +101,8 @@ public class StructureChooser extends GStructureChooser implements
       progressBar = new ProgressBar(this.statusPanel, this.statusBar);
     }
 
+    // ensure a filter option is in force for search
+    populateFilterComboBox(true);
     Thread discoverPDBStructuresThread = new Thread(new Runnable()
     {
       @Override
@@ -117,7 +117,8 @@ public class StructureChooser extends GStructureChooser implements
                 .getString("status.searching_for_pdb_structures"),
                 startTime);
         fetchStructuresMetaData();
-        populateFilterComboBox();
+        // revise filter options if no results were found
+        populateFilterComboBox(isStructuresDiscovered());
         updateProgressIndicator(null, startTime);
         mainFrame.setVisible(true);
         updateCurrentView();
@@ -161,6 +162,10 @@ public class StructureChooser extends GStructureChooser implements
       pdbRequest.setAllowEmptySeq(false);
       pdbRequest.setResponseSize(500);
       pdbRequest.setFieldToSearchBy("(");
+      FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
+              .getSelectedItem());
+      pdbRequest.setFieldToSortBy(selectedFilterOpt.getValue(),
+              !chk_invertFilter.isSelected());
       pdbRequest.setWantedFields(wantedFields);
       pdbRequest.setSearchTerm(buildQuery(seq) + ")");
       pdbRequest.setAssociatedSequence(seq);
@@ -191,7 +196,6 @@ public class StructureChooser extends GStructureChooser implements
       getResultTable().setModel(
               FTSRestResponse.getTableModel(lastPdbRequest,
               discoveredStructuresSet));
-      structuresDiscovered = true;
       noOfStructuresFound = discoveredStructuresSet.size();
       mainFrame.setTitle(MessageManager.formatMessage(
               "label.structure_chooser_no_of_structures",
@@ -524,10 +528,15 @@ public class StructureChooser extends GStructureChooser implements
    * Populates the filter combo-box options dynamically depending on discovered
    * structures
    */
-  @Override
-  protected void populateFilterComboBox()
+  protected void populateFilterComboBox(boolean haveData)
   {
-    if (isStructuresDiscovered())
+    /*
+     * temporarily suspend the change listener behaviour
+     */
+    cmb_filterOption.removeItemListener(this);
+
+    cmb_filterOption.removeAllItems();
+    if (haveData)
     {
       cmb_filterOption.addItem(new FilterOption("Best Quality",
               "overall_quality", VIEWS_FILTER));
@@ -546,12 +555,13 @@ public class StructureChooser extends GStructureChooser implements
             VIEWS_FROM_FILE));
     cmb_filterOption.addItem(new FilterOption("Cached PDB Entries", "-",
             VIEWS_LOCAL_PDB));
+
+    cmb_filterOption.addItemListener(this);
   }
 
   /**
    * Updates the displayed view based on the selected filter option
    */
-  @Override
   protected void updateCurrentView()
   {
     FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
@@ -717,6 +727,7 @@ public class StructureChooser extends GStructureChooser implements
   {
     final long progressSessionId = System.currentTimeMillis();
     final StructureSelectionManager ssm = ap.getStructureSelectionManager();
+    final int preferredHeight = pnl_filter.getHeight();
     ssm.setProgressIndicator(this);
     ssm.setProgressSessionId(progressSessionId);
     new Thread(new Runnable()
@@ -724,84 +735,82 @@ public class StructureChooser extends GStructureChooser implements
       @Override
       public void run()
       {
-    FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
-            .getSelectedItem());
-    String currentView = selectedFilterOpt.getView();
-    if (currentView == VIEWS_FILTER)
-    {
+        FilterOption selectedFilterOpt = ((FilterOption) cmb_filterOption
+                .getSelectedItem());
+        String currentView = selectedFilterOpt.getView();
+        if (currentView == VIEWS_FILTER)
+        {
           int pdbIdColIndex = getResultTable().getColumn("PDB Id")
                   .getModelIndex();
           int refSeqColIndex = getResultTable().getColumn("Ref Sequence")
-              .getModelIndex();
+                  .getModelIndex();
           int[] selectedRows = getResultTable().getSelectedRows();
-      PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
-      int count = 0;
-      ArrayList<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
-      for (int row : selectedRows)
-      {
+          PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
+          int count = 0;
+          ArrayList<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
+          for (int row : selectedRows)
+          {
             String pdbIdStr = getResultTable().getValueAt(row,
-                    pdbIdColIndex)
-                .toString();
+                    pdbIdColIndex).toString();
             SequenceI selectedSeq = (SequenceI) getResultTable()
-                    .getValueAt(row,
-                refSeqColIndex);
-        selectedSeqsToView.add(selectedSeq);
+                    .getValueAt(row, refSeqColIndex);
+            selectedSeqsToView.add(selectedSeq);
             PDBEntry pdbEntry = selectedSeq.getPDBEntry(pdbIdStr);
             if (pdbEntry == null)
             {
               pdbEntry = getFindEntry(pdbIdStr,
                       selectedSeq.getAllPDBEntries());
             }
-        if (pdbEntry == null)
-        {
-          pdbEntry = new PDBEntry();
-          pdbEntry.setId(pdbIdStr);
-          pdbEntry.setType(PDBEntry.Type.PDB);
-          selectedSeq.getDatasetSequence().addPDBId(pdbEntry);
-        }
-        pdbEntriesToView[count++] = pdbEntry;
-      }
-      SequenceI[] selectedSeqs = selectedSeqsToView
-              .toArray(new SequenceI[selectedSeqsToView.size()]);
+            if (pdbEntry == null)
+            {
+              pdbEntry = new PDBEntry();
+              pdbEntry.setId(pdbIdStr);
+              pdbEntry.setType(PDBEntry.Type.PDB);
+              selectedSeq.getDatasetSequence().addPDBId(pdbEntry);
+            }
+            pdbEntriesToView[count++] = pdbEntry;
+          }
+          SequenceI[] selectedSeqs = selectedSeqsToView
+                  .toArray(new SequenceI[selectedSeqsToView.size()]);
           launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
-    }
-    else if (currentView == VIEWS_LOCAL_PDB)
-    {
-      int[] selectedRows = tbl_local_pdb.getSelectedRows();
-      PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
-      int count = 0;
+        }
+        else if (currentView == VIEWS_LOCAL_PDB)
+        {
+          int[] selectedRows = tbl_local_pdb.getSelectedRows();
+          PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
+          int count = 0;
           int pdbIdColIndex = tbl_local_pdb.getColumn("PDB Id")
                   .getModelIndex();
-      int refSeqColIndex = tbl_local_pdb.getColumn("Ref Sequence")
-              .getModelIndex();
-      ArrayList<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
-      for (int row : selectedRows)
-      {
-        PDBEntry pdbEntry = (PDBEntry) tbl_local_pdb.getValueAt(row,
-                pdbIdColIndex);
-        pdbEntriesToView[count++] = pdbEntry;
-        SequenceI selectedSeq = (SequenceI) tbl_local_pdb.getValueAt(row,
-                refSeqColIndex);
-        selectedSeqsToView.add(selectedSeq);
-      }
-      SequenceI[] selectedSeqs = selectedSeqsToView
-              .toArray(new SequenceI[selectedSeqsToView.size()]);
+          int refSeqColIndex = tbl_local_pdb.getColumn("Ref Sequence")
+                  .getModelIndex();
+          ArrayList<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
+          for (int row : selectedRows)
+          {
+            PDBEntry pdbEntry = (PDBEntry) tbl_local_pdb.getValueAt(row,
+                    pdbIdColIndex);
+            pdbEntriesToView[count++] = pdbEntry;
+            SequenceI selectedSeq = (SequenceI) tbl_local_pdb.getValueAt(
+                    row, refSeqColIndex);
+            selectedSeqsToView.add(selectedSeq);
+          }
+          SequenceI[] selectedSeqs = selectedSeqsToView
+                  .toArray(new SequenceI[selectedSeqsToView.size()]);
           launchStructureViewer(ssm, pdbEntriesToView, ap, selectedSeqs);
-    }
-    else if (currentView == VIEWS_ENTER_ID)
-    {
-      SequenceI userSelectedSeq = ((AssociateSeqOptions) idInputAssSeqPanel
-              .getCmb_assSeq().getSelectedItem()).getSequence();
-      if (userSelectedSeq != null)
-      {
-        selectedSequence = userSelectedSeq;
-      }
+        }
+        else if (currentView == VIEWS_ENTER_ID)
+        {
+          SequenceI userSelectedSeq = ((AssociateSeqOptions) idInputAssSeqPanel
+                  .getCmb_assSeq().getSelectedItem()).getSequence();
+          if (userSelectedSeq != null)
+          {
+            selectedSequence = userSelectedSeq;
+          }
 
-      String pdbIdStr = txt_search.getText();
-      PDBEntry pdbEntry = selectedSequence.getPDBEntry(pdbIdStr);
-      if (pdbEntry == null)
-      {
-        pdbEntry = new PDBEntry();
+          String pdbIdStr = txt_search.getText();
+          PDBEntry pdbEntry = selectedSequence.getPDBEntry(pdbIdStr);
+          if (pdbEntry == null)
+          {
+            pdbEntry = new PDBEntry();
             if (pdbIdStr.split(":").length > 1)
             {
               pdbEntry.setId(pdbIdStr.split(":")[0]);
@@ -811,31 +820,31 @@ public class StructureChooser extends GStructureChooser implements
             {
               pdbEntry.setId(pdbIdStr);
             }
-        pdbEntry.setType(PDBEntry.Type.PDB);
-        selectedSequence.getDatasetSequence().addPDBId(pdbEntry);
-      }
+            pdbEntry.setType(PDBEntry.Type.PDB);
+            selectedSequence.getDatasetSequence().addPDBId(pdbEntry);
+          }
 
-      PDBEntry[] pdbEntriesToView = new PDBEntry[] { pdbEntry };
+          PDBEntry[] pdbEntriesToView = new PDBEntry[] { pdbEntry };
           launchStructureViewer(ssm, pdbEntriesToView, ap,
                   new SequenceI[] { selectedSequence });
-    }
-    else if (currentView == VIEWS_FROM_FILE)
-    {
-      SequenceI userSelectedSeq = ((AssociateSeqOptions) fileChooserAssSeqPanel
-              .getCmb_assSeq().getSelectedItem()).getSequence();
-      if (userSelectedSeq != null)
-      {
-        selectedSequence = userSelectedSeq;
-      }
-      PDBEntry fileEntry = new AssociatePdbFileWithSeq()
-              .associatePdbWithSeq(selectedPdbFileName,
-                      jalview.io.AppletFormatAdapter.FILE,
-                      selectedSequence, true, Desktop.instance);
+        }
+        else if (currentView == VIEWS_FROM_FILE)
+        {
+          SequenceI userSelectedSeq = ((AssociateSeqOptions) fileChooserAssSeqPanel
+                  .getCmb_assSeq().getSelectedItem()).getSequence();
+          if (userSelectedSeq != null)
+          {
+            selectedSequence = userSelectedSeq;
+          }
+          PDBEntry fileEntry = new AssociatePdbFileWithSeq()
+                  .associatePdbWithSeq(selectedPdbFileName,
+                          jalview.io.AppletFormatAdapter.FILE,
+                          selectedSequence, true, Desktop.instance);
 
           launchStructureViewer(ssm, new PDBEntry[] { fileEntry }, ap,
                   new SequenceI[] { selectedSequence });
-    }
-        closeAction();
+        }
+        closeAction(preferredHeight);
       }
     }).start();
   }
@@ -865,7 +874,7 @@ public class StructureChooser extends GStructureChooser implements
 
     if (SiftsSettings.isMapWithSifts())
     {
-      ArrayList<SequenceI> seqsWithoutSourceDBRef = new ArrayList<SequenceI>();
+      List<SequenceI> seqsWithoutSourceDBRef = new ArrayList<SequenceI>();
       int p = 0;
       // TODO: skip PDBEntry:Sequence pairs where PDBEntry doesn't look like a
       // real PDB ID. For moment, we can also safely do this if there is already
@@ -906,7 +915,8 @@ public class StructureChooser extends GStructureChooser implements
         {
           seqWithoutSrcDBRef[x++] = fSeq;
         }
-        new DBRefFetcher(seqWithoutSrcDBRef).fetchDBRefs(true);
+        DBRefFetcher dbRefFetcher = new DBRefFetcher(seqWithoutSrcDBRef);
+        dbRefFetcher.fetchDBRefs(true);
       }
     }
     if (pdbEntriesToView.length > 1)
@@ -963,12 +973,8 @@ public class StructureChooser extends GStructureChooser implements
 
   public boolean isStructuresDiscovered()
   {
-    return structuresDiscovered;
-  }
-
-  public void setStructuresDiscovered(boolean structuresDiscovered)
-  {
-    this.structuresDiscovered = structuresDiscovered;
+    return discoveredStructuresSet != null
+            && !discoveredStructuresSet.isEmpty();
   }
 
   public Collection<FTSData> getDiscoveredStructuresSet()
index 6bfea9e..ef65b92 100755 (executable)
@@ -29,7 +29,6 @@ import jalview.datamodel.SequenceI;
 import jalview.datamodel.SequenceNode;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.ResidueProperties;
 import jalview.schemes.UserColourScheme;
 import jalview.structure.SelectionSource;
 import jalview.util.Format;
@@ -1020,10 +1019,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",
-                  ResidueProperties.propHash, 3, sg.getSequences(null),
-                  sg.getStartRes(), sg.getEndRes());
-
+          Conservation c = new Conservation("Group", 3,
+                  sg.getSequences(null), sg.getStartRes(), sg.getEndRes());
           c.calculate();
           c.verdict(false, aps[a].av.getConsPercGaps());
           sg.cs.setConservation(c);
index 7588e07..afb6df4 100644 (file)
@@ -321,6 +321,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
     Thread udthread = new Thread(new Runnable()
     {
 
+      @Override
       public void run()
       {
         Cache.log.info("Jalview updating to the Vamsas Session.");
@@ -639,6 +640,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
     final VamsasApplication client = this;
     vclient.addDocumentUpdateHandler(new PropertyChangeListener()
     {
+      @Override
       public void propertyChange(PropertyChangeEvent evt)
       {
         Cache.log.debug("Dealing with document update event.");
@@ -656,6 +658,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
             uk.ac.vamsas.client.Events.DOCUMENT_REQUESTTOCLOSE,
             new PropertyChangeListener()
             {
+              @Override
               public void propertyChange(PropertyChangeEvent evt)
               {
                 if (client.promptUser)
@@ -774,6 +777,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
         {
           String last = null;
 
+          @Override
           public void handleMessage(Message message)
           {
             if (vobj2jv == null)
@@ -998,6 +1002,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
         selecter = new SelectionListener()
         {
 
+          @Override
           public void selection(SequenceGroup seqsel,
                   ColumnSelection colsel, SelectionSource source)
           {
@@ -1065,11 +1070,10 @@ public class VamsasApplication implements SelectionSource, VamsasSource
                   {
                     // gather selected columns outwith the sequence positions
                     // too
-                    for (Object obj : colsel.getSelected())
+                    for (Integer ival : colsel.getSelected())
                     {
-                      int ival = ((Integer) obj).intValue();
                       Pos p = new Pos();
-                      p.setI(ival + 1);
+                      p.setI(ival.intValue() + 1);
                       range.addPos(p);
                     }
                   }
index d738882..34fdabe 100755 (executable)
@@ -32,7 +32,6 @@ import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.ResidueProperties;
 import jalview.schemes.UserColourScheme;
 
 import java.io.BufferedReader;
@@ -1638,9 +1637,9 @@ public class AnnotationFile
         else if (key.equalsIgnoreCase("consThreshold"))
         {
           sg.cs.setConservationInc(Integer.parseInt(value));
-          Conservation c = new Conservation("Group",
-                  ResidueProperties.propHash, 3, sg.getSequences(null),
-                  sg.getStartRes(), sg.getEndRes() + 1);
+          Conservation c = new Conservation("Group", 3,
+                  sg.getSequences(null), sg.getStartRes(),
+                  sg.getEndRes() + 1);
 
           c.calculate();
           c.verdict(false, 25); // TODO: refer to conservation percent threshold
index 55bb03d..9695891 100755 (executable)
@@ -27,6 +27,7 @@ import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentView;
 import jalview.datamodel.PDBEntry.Type;
+import jalview.ext.jmol.JmolParser;
 import jalview.structure.StructureImportSettings;
 import jalview.util.MessageManager;
 
@@ -289,9 +290,7 @@ public class AppletFormatAdapter
         {
           StructureImportSettings.addSettings(annotFromStructure,
                   localSecondaryStruct, serviceSecondaryStruct);
-          alignFile = new jalview.ext.jmol.JmolParser(annotFromStructure,
-                  localSecondaryStruct, serviceSecondaryStruct, inFile,
-                  type);
+          alignFile = new jalview.ext.jmol.JmolParser(inFile, type);
         }
         else
         {
@@ -308,8 +307,7 @@ public class AppletFormatAdapter
       {
         StructureImportSettings.addSettings(annotFromStructure,
                 localSecondaryStruct, serviceSecondaryStruct);
-        alignFile = new jalview.ext.jmol.JmolParser(annotFromStructure,
-                localSecondaryStruct, serviceSecondaryStruct, inFile, type);
+        alignFile = new jalview.ext.jmol.JmolParser(inFile, type);
         ((StructureFile) alignFile).setDbRefType(format);
       }
       else if (format.equals("STH"))
@@ -443,8 +441,7 @@ public class AppletFormatAdapter
         {
           StructureImportSettings.addSettings(annotFromStructure,
                   localSecondaryStruct, serviceSecondaryStruct);
-          alignFile = new jalview.ext.jmol.JmolParser(annotFromStructure,
-                  localSecondaryStruct, serviceSecondaryStruct, source);
+          alignFile = new JmolParser(source);
         }
         else
         {
@@ -458,8 +455,7 @@ public class AppletFormatAdapter
       {
         StructureImportSettings.addSettings(annotFromStructure,
                 localSecondaryStruct, serviceSecondaryStruct);
-        alignFile = new jalview.ext.jmol.JmolParser(annotFromStructure,
-                localSecondaryStruct, serviceSecondaryStruct, source);
+        alignFile = new JmolParser(source);
         ((StructureFile) alignFile).setDbRefType(Type.MMCIF);
       }
       else if (format.equals("STH"))
index ecce1a3..5294c45 100644 (file)
@@ -8,10 +8,10 @@ import java.awt.Color;
 
 public class PDBFeatureSettings extends FeatureSettingsAdapter
 {
+  // TODO find one central place to define feature names
+  private static final String FEATURE_INSERTION = "INSERTION";
 
-  public static final String FEATURE_INSERTION = "INSERTION";
-
-  public static final String FEATURE_RES_NUM = "RESNUM";
+  private static final String FEATURE_RES_NUM = "RESNUM";
 
   @Override
   public boolean isFeatureDisplayed(String type)
index 6ce907a..322c6b8 100644 (file)
@@ -282,11 +282,10 @@ public abstract class StructureFile extends AlignFile
       Class cl = Class.forName("jalview.ext.jmol.JmolParser");
       if (cl != null)
       {
-        final Constructor constructor = cl.getConstructor(new Class[] {
-            boolean.class, boolean.class, boolean.class, FileParse.class });
-        final Object[] args = new Object[] { visibleChainAnnotation,
-            predictSecondaryStructure, externalSecondaryStructure,
-            new FileParse(getDataName(), type) };
+        final Constructor constructor = cl
+                .getConstructor(new Class[] { FileParse.class });
+        final Object[] args = new Object[] { new FileParse(getDataName(),
+                type) };
 
         StructureImportSettings.setShowSeqFeatures(false);
         StructureImportSettings.setVisibleChainAnnotation(false);
index 3eaa5d1..2053b86 100644 (file)
@@ -1,5 +1,14 @@
 package jalview.io.gff;
 
+
+/**
+ * A factory class that returns a model of the Sequence Ontology. By default a
+ * hard-coded subset is used (for the applet, or testing), or setInstance() can
+ * be used to set full Ontology data.
+ * 
+ * @author gmcarstairs
+ *
+ */
 public class SequenceOntologyFactory
 {
   private static SequenceOntologyI instance;
@@ -8,7 +17,6 @@ public class SequenceOntologyFactory
   {
     if (instance == null)
     {
-      // instance = new SequenceOntology();
       instance = new SequenceOntologyLite();
     }
     return instance;
index b3f8161..d46dcbe 100644 (file)
@@ -51,6 +51,7 @@ public class SequenceOntologyLite implements SequenceOntologyI
     { "miRNA", "transcript" },
     { "lincRNA", "transcript" },
     { "rRNA", "transcript" },
+    { "mRNA", "transcript" },
     // there are many more sub-types of ncRNA...
     
     /*
@@ -180,9 +181,11 @@ public class SequenceOntologyLite implements SequenceOntologyI
     {
       if (!termsNotFound.contains(term))
       {
-        System.out.println("SO term " + term
-                + " not known - may be invalid, or model if needed in "
-                + getClass().getName());
+        // suppress logging here as it reports Uniprot sequence features
+        // (which do not use SO terms) when auto-configuring feature colours
+        // System.out.println("SO term " + term
+        // + " not known - add to model if needed in "
+        // + getClass().getName());
         termsNotFound.add(term);
       }
     }
index 2879889..ff7a764 100644 (file)
@@ -152,7 +152,8 @@ public class DatastoreRegistry
     return dsregitem;
   }
 
-  protected void finalize()
+  @Override
+  protected void finalize() throws Throwable
   {
     if (dsObjReg != null)
     {
@@ -171,5 +172,6 @@ public class DatastoreRegistry
     {
       dsItemReg.clear();
     }
+    super.finalize();
   }
 }
index 4d7c0d4..6daf275 100644 (file)
@@ -39,7 +39,8 @@ public class JSFunctionExec implements Runnable
     jvlite.setExecutor(this);
   }
 
-  public void finalize()
+  @Override
+  protected void finalize() throws Throwable
   {
     jvlite = null;
     executor = null;
@@ -48,6 +49,7 @@ public class JSFunctionExec implements Runnable
       jsExecQueue.clear();
     }
     jsExecQueue = null;
+    super.finalize();
   }
 
   private Vector jsExecQueue;
@@ -82,6 +84,7 @@ public class JSFunctionExec implements Runnable
     executor = null;
   }
 
+  @Override
   public void run()
   {
     while (jsExecQueue != null)
@@ -164,6 +167,7 @@ public class JSFunctionExec implements Runnable
     final Exception[] jsex = new Exception[1];
     Runnable exec = new Runnable()
     {
+      @Override
       public void run()
       {
         try
@@ -196,7 +200,7 @@ public class JSFunctionExec implements Runnable
             if (jex instanceof netscape.javascript.JSException
                     && jvlite.jsfallbackEnabled)
             {
-              jsex[0] = (netscape.javascript.JSException) jex;
+              jsex[0] = jex;
               if (jvlite.debug)
               {
                 System.err.println("Falling back to javascript: url call");
index 35c7860..4f833bc 100644 (file)
@@ -298,7 +298,7 @@ public class MouseOverStructureListener extends JSFunctionExec implements
     return _listenerfn;
   }
 
-  public void finalise()
+  public void finalize() throws Throwable
   {
     jvlite = null;
     super.finalize();
index 1348e59..4d66a18 100644 (file)
@@ -166,7 +166,7 @@ public abstract class GStructureChooser extends JPanel implements
 
   protected JScrollPane scrl_localPDB = new JScrollPane(tbl_local_pdb);
 
-  private JTabbedPane pnl_filter = new JTabbedPane();
+  protected JTabbedPane pnl_filter = new JTabbedPane();
 
   protected FTSDataColumnPreferences pdbDocFieldPrefs = new FTSDataColumnPreferences(
           PreferenceSource.STRUCTURE_CHOOSER,
@@ -414,7 +414,7 @@ public abstract class GStructureChooser extends JPanel implements
       @Override
       public void actionPerformed(ActionEvent e)
       {
-        closeAction();
+        closeAction(pnl_filter.getHeight());
       }
     });
     btn_cancel.addKeyListener(new KeyAdapter()
@@ -424,7 +424,7 @@ public abstract class GStructureChooser extends JPanel implements
       {
         if (evt.getKeyCode() == KeyEvent.VK_ENTER)
         {
-          closeAction();
+          closeAction(pnl_filter.getHeight());
         }
       }
     });
@@ -577,7 +577,7 @@ public abstract class GStructureChooser extends JPanel implements
               @Override
               public void internalFrameClosing(InternalFrameEvent e)
               {
-                closeAction();
+                closeAction(pnl_filter.getHeight());
               }
             });
     mainFrame.setVisible(true);
@@ -592,7 +592,7 @@ public abstract class GStructureChooser extends JPanel implements
     Desktop.addInternalFrame(mainFrame, frameTitle, width, height);
   }
 
-  protected void closeAction()
+  protected void closeAction(int preferredHeight)
   {
     // System.out.println(">>>>>>>>>> closing internal frame!!!");
     // System.out.println("width : " + mainFrame.getWidth());
@@ -600,11 +600,12 @@ public abstract class GStructureChooser extends JPanel implements
     // System.out.println("x : " + mainFrame.getX());
     // System.out.println("y : " + mainFrame.getY());
     tempUserPrefs.put("structureChooser.width", pnl_filter.getWidth());
-    tempUserPrefs.put("structureChooser.height", pnl_filter.getHeight());
+    tempUserPrefs.put("structureChooser.height", preferredHeight);
     tempUserPrefs.put("structureChooser.x", mainFrame.getX());
     tempUserPrefs.put("structureChooser.y", mainFrame.getY());
     mainFrame.dispose();
   }
+
   public boolean wantedFieldsUpdated()
   {
     if (previousWantedFields == null)
@@ -801,10 +802,6 @@ public abstract class GStructureChooser extends JPanel implements
 
   protected abstract void stateChanged(ItemEvent e);
 
-  protected abstract void updateCurrentView();
-
-  protected abstract void populateFilterComboBox();
-
   protected abstract void ok_ActionPerformed();
 
   protected abstract void pdbFromFile_actionPerformed();
index 82f6ffb..e58ba02 100644 (file)
@@ -30,6 +30,7 @@ import jalview.datamodel.Annotation;
 import jalview.datamodel.ColumnSelection;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ResidueProperties;
+import jalview.util.Platform;
 
 import java.awt.BasicStroke;
 import java.awt.Color;
@@ -57,6 +58,70 @@ public class AnnotationRenderer
    */
   private final boolean debugRedraw;
 
+  private int charWidth, endRes, charHeight;
+
+  private boolean validCharWidth, hasHiddenColumns;
+
+  private FontMetrics fm;
+
+  private final boolean MAC = Platform.isAMac();
+
+  boolean av_renderHistogram = true, av_renderProfile = true,
+          av_normaliseProfile = false;
+
+  ColourSchemeI profcolour = null;
+
+  private ColumnSelection columnSelection;
+
+  private Hashtable[] hconsensus;
+
+  private Hashtable[] complementConsensus;
+
+  private Hashtable[] hStrucConsensus;
+
+  private boolean av_ignoreGapsConsensus;
+
+  /**
+   * attributes set from AwtRenderPanelI
+   */
+  /**
+   * old image used when data is currently being calculated and cannot be
+   * rendered
+   */
+  private Image fadedImage;
+
+  /**
+   * panel being rendered into
+   */
+  private ImageObserver annotationPanel;
+
+  /**
+   * width of image to render in panel
+   */
+  private int imgWidth;
+
+  /**
+   * offset to beginning of visible area
+   */
+  private int sOffset;
+
+  /**
+   * offset to end of visible area
+   */
+  private int visHeight;
+
+  /**
+   * indicate if the renderer should only render the visible portion of the
+   * annotation given the current view settings
+   */
+  private boolean useClip = true;
+
+  /**
+   * master flag indicating if renderer should ever try to clip. not enabled for
+   * jalview 2.8.1
+   */
+  private boolean canClip = false;
+
   public AnnotationRenderer()
   {
     this(false);
@@ -74,6 +139,18 @@ public class AnnotationRenderer
     this.debugRedraw = debugRedraw;
   }
 
+  /**
+   * Remove any references and resources when this object is no longer required
+   */
+  public void dispose()
+  {
+    hconsensus = null;
+    complementConsensus = null;
+    hStrucConsensus = null;
+    fadedImage = null;
+    annotationPanel = null;
+  }
+
   void drawStemAnnot(Graphics g, Annotation[] row_annotations,
           int lastSSX, int x, int y, int iconOffset, int startRes,
           int column, boolean validRes, boolean validEnd)
@@ -134,70 +211,6 @@ public class AnnotationRenderer
     g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 7);
   }
 
-  private int charWidth, endRes, charHeight;
-
-  private boolean validCharWidth, hasHiddenColumns;
-
-  private FontMetrics fm;
-
-  private final boolean MAC = jalview.util.Platform.isAMac();
-
-  boolean av_renderHistogram = true, av_renderProfile = true,
-          av_normaliseProfile = false;
-
-  ColourSchemeI profcolour = null;
-
-  private ColumnSelection columnSelection;
-
-  private Hashtable[] hconsensus;
-
-  private Hashtable[] complementConsensus;
-
-  private Hashtable[] hStrucConsensus;
-
-  private boolean av_ignoreGapsConsensus;
-
-  /**
-   * attributes set from AwtRenderPanelI
-   */
-  /**
-   * old image used when data is currently being calculated and cannot be
-   * rendered
-   */
-  private Image fadedImage;
-
-  /**
-   * panel being rendered into
-   */
-  private ImageObserver annotationPanel;
-
-  /**
-   * width of image to render in panel
-   */
-  private int imgWidth;
-
-  /**
-   * offset to beginning of visible area
-   */
-  private int sOffset;
-
-  /**
-   * offset to end of visible area
-   */
-  private int visHeight;
-
-  /**
-   * indicate if the renderer should only render the visible portion of the
-   * annotation given the current view settings
-   */
-  private boolean useClip = true;
-
-  /**
-   * master flag indicating if renderer should ever try to clip. not enabled for
-   * jalview 2.8.1
-   */
-  private boolean canClip = false;
-
   void drawNotCanonicalAnnot(Graphics g, Color nonCanColor,
           Annotation[] row_annotations, int lastSSX, int x, int y,
           int iconOffset, int startRes, int column, boolean validRes,
index d0d26b0..c235c7a 100755 (executable)
@@ -26,6 +26,7 @@ import jalview.api.analysis.ScoreModelI;
 
 import java.awt.Color;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.Hashtable;
@@ -223,36 +224,36 @@ public class ResidueProperties
 
   static
   {
-    aa3Hash.put("ALA", new Integer(0));
-    aa3Hash.put("ARG", new Integer(1));
-    aa3Hash.put("ASN", new Integer(2));
-    aa3Hash.put("ASP", new Integer(3)); // D
-    aa3Hash.put("CYS", new Integer(4));
-    aa3Hash.put("GLN", new Integer(5)); // Q
-    aa3Hash.put("GLU", new Integer(6)); // E
-    aa3Hash.put("GLY", new Integer(7));
-    aa3Hash.put("HIS", new Integer(8));
-    aa3Hash.put("ILE", new Integer(9));
-    aa3Hash.put("LEU", new Integer(10));
-    aa3Hash.put("LYS", new Integer(11));
-    aa3Hash.put("MET", new Integer(12));
-    aa3Hash.put("PHE", new Integer(13));
-    aa3Hash.put("PRO", new Integer(14));
-    aa3Hash.put("SER", new Integer(15));
-    aa3Hash.put("THR", new Integer(16));
-    aa3Hash.put("TRP", new Integer(17));
-    aa3Hash.put("TYR", new Integer(18));
-    aa3Hash.put("VAL", new Integer(19));
+    aa3Hash.put("ALA", Integer.valueOf(0));
+    aa3Hash.put("ARG", Integer.valueOf(1));
+    aa3Hash.put("ASN", Integer.valueOf(2));
+    aa3Hash.put("ASP", Integer.valueOf(3)); // D
+    aa3Hash.put("CYS", Integer.valueOf(4));
+    aa3Hash.put("GLN", Integer.valueOf(5)); // Q
+    aa3Hash.put("GLU", Integer.valueOf(6)); // E
+    aa3Hash.put("GLY", Integer.valueOf(7));
+    aa3Hash.put("HIS", Integer.valueOf(8));
+    aa3Hash.put("ILE", Integer.valueOf(9));
+    aa3Hash.put("LEU", Integer.valueOf(10));
+    aa3Hash.put("LYS", Integer.valueOf(11));
+    aa3Hash.put("MET", Integer.valueOf(12));
+    aa3Hash.put("PHE", Integer.valueOf(13));
+    aa3Hash.put("PRO", Integer.valueOf(14));
+    aa3Hash.put("SER", Integer.valueOf(15));
+    aa3Hash.put("THR", Integer.valueOf(16));
+    aa3Hash.put("TRP", Integer.valueOf(17));
+    aa3Hash.put("TYR", Integer.valueOf(18));
+    aa3Hash.put("VAL", Integer.valueOf(19));
     // IUB Nomenclature for ambiguous peptides
-    aa3Hash.put("ASX", new Integer(20)); // "B";
-    aa3Hash.put("GLX", new Integer(21)); // Z
-    aa3Hash.put("XAA", new Integer(22)); // X unknown
-    aa3Hash.put("-", new Integer(23));
-    aa3Hash.put("*", new Integer(23));
-    aa3Hash.put(".", new Integer(23));
-    aa3Hash.put(" ", new Integer(23));
-    aa3Hash.put("Gap", new Integer(23));
-    aa3Hash.put("UR3", new Integer(24));
+    aa3Hash.put("ASX", Integer.valueOf(20)); // "B";
+    aa3Hash.put("GLX", Integer.valueOf(21)); // Z
+    aa3Hash.put("XAA", Integer.valueOf(22)); // X unknown
+    aa3Hash.put("-", Integer.valueOf(23));
+    aa3Hash.put("*", Integer.valueOf(23));
+    aa3Hash.put(".", Integer.valueOf(23));
+    aa3Hash.put(" ", Integer.valueOf(23));
+    aa3Hash.put("Gap", Integer.valueOf(23));
+    aa3Hash.put("UR3", Integer.valueOf(24));
   }
 
   static
@@ -305,24 +306,24 @@ public class ResidueProperties
 
   public static final Color midBlue = new Color(100, 100, 255);
 
-  public static final Vector scaleColours = new Vector();
-
-  static
-  {
-    scaleColours.addElement(new Color(114, 0, 147));
-    scaleColours.addElement(new Color(156, 0, 98));
-    scaleColours.addElement(new Color(190, 0, 0));
-    scaleColours.addElement(Color.red);
-    scaleColours.addElement(new Color(255, 125, 0));
-    scaleColours.addElement(Color.orange);
-    scaleColours.addElement(new Color(255, 194, 85));
-    scaleColours.addElement(Color.yellow);
-    scaleColours.addElement(new Color(255, 255, 181));
-    scaleColours.addElement(Color.white);
-  }
-
-  public static final Color[] taylor = { new Color(204, 255, 0), // A
-                                                                 // Greenish-yellowy-yellow
+  // not currently in use
+  // public static final Vector<Color> scaleColours = new Vector<Color>();
+  // static
+  // {
+  // scaleColours.addElement(new Color(114, 0, 147));
+  // scaleColours.addElement(new Color(156, 0, 98));
+  // scaleColours.addElement(new Color(190, 0, 0));
+  // scaleColours.addElement(Color.red);
+  // scaleColours.addElement(new Color(255, 125, 0));
+  // scaleColours.addElement(Color.orange);
+  // scaleColours.addElement(new Color(255, 194, 85));
+  // scaleColours.addElement(Color.yellow);
+  // scaleColours.addElement(new Color(255, 255, 181));
+  // scaleColours.addElement(Color.white);
+  // }
+
+  public static final Color[] taylor = { new Color(204, 255, 0),
+      // A Greenish-yellowy-yellow
       new Color(0, 0, 255), // R Blueish-bluey-blue
       new Color(204, 0, 255), // N Blueish-reddy-blue
       new Color(255, 0, 0), // D Reddish-reddy-red
@@ -572,21 +573,21 @@ public class ResidueProperties
       { -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8, -8,
           -8, -8, -8, -8, -8, -8, 1 }, };
 
-  public static final Hashtable ssHash = new Hashtable(); // stores the number
-  // value of the aa
-
-  static
-  {
-    ssHash.put("H", Color.magenta);
-    ssHash.put("E", Color.yellow);
-    ssHash.put("-", Color.white);
-    ssHash.put(".", Color.white);
-    ssHash.put("S", Color.cyan);
-    ssHash.put("T", Color.blue);
-    ssHash.put("G", Color.pink);
-    ssHash.put("I", Color.pink);
-    ssHash.put("B", Color.yellow);
-  }
+  // not currently used
+  // public static final Map<String, Color> ssHash = new Hashtable<String,
+  // Color>();
+  // static
+  // {
+  // ssHash.put("H", Color.magenta);
+  // ssHash.put("E", Color.yellow);
+  // ssHash.put("-", Color.white);
+  // ssHash.put(".", Color.white);
+  // ssHash.put("S", Color.cyan);
+  // ssHash.put("T", Color.blue);
+  // ssHash.put("G", Color.pink);
+  // ssHash.put("I", Color.pink);
+  // ssHash.put("B", Color.yellow);
+  // }
 
   /*
    * new Color(60, 136, 238), // U Color.white, // I Color.white, // X
@@ -618,7 +619,6 @@ public class ResidueProperties
     scoreMatrices.put("BLOSUM62", new ScoreMatrix("BLOSUM62", BLOSUM62, 0));
     scoreMatrices.put("PAM250", new ScoreMatrix("PAM250", PAM250, 0));
     scoreMatrices.put("DNA", new ScoreMatrix("DNA", DNA, 1));
-
   }
 
   public static final Color[] pidColours = { midBlue,
@@ -628,77 +628,10 @@ public class ResidueProperties
 
   public static final float[] pidThresholds = { 80, 60, 40, };
 
-  public static Map<String, List<String>> codonHash = new HashMap<String, List<String>>();
-
-  private static List<String> Lys = new ArrayList<String>();
-
-  private static List<String> Asn = new ArrayList<String>();
-
-  private static List<String> Gln = new ArrayList<String>();
-
-  private static List<String> His = new ArrayList<String>();
-
-  private static List<String> Glu = new ArrayList<String>();
-
-  private static List<String> Asp = new ArrayList<String>();
-
-  private static List<String> Tyr = new ArrayList<String>();
-
-  private static List<String> Thr = new ArrayList<String>();
-
-  private static List<String> Pro = new ArrayList<String>();
-
-  private static List<String> Ala = new ArrayList<String>();
-
-  private static List<String> Ser = new ArrayList<String>();
-
-  private static List<String> Arg = new ArrayList<String>();
-
-  private static List<String> Gly = new ArrayList<String>();
-
-  private static List<String> Trp = new ArrayList<String>();
-
-  private static List<String> Cys = new ArrayList<String>();
-
-  private static List<String> Ile = new ArrayList<String>();
-
-  private static List<String> Met = new ArrayList<String>();
-
-  private static List<String> Leu = new ArrayList<String>();
-
-  private static List<String> Val = new ArrayList<String>();
-
-  private static List<String> Phe = new ArrayList<String>();
-
-  public static List<String> STOP = new ArrayList<String>();
+  public static List<String> STOP = Arrays.asList("TGA", "TAA", "TAG");
 
   public static String START = "ATG";
 
-  static
-  {
-    codonHash.put("K", Lys);
-    codonHash.put("N", Asn);
-    codonHash.put("Q", Gln);
-    codonHash.put("H", His);
-    codonHash.put("E", Glu);
-    codonHash.put("D", Asp);
-    codonHash.put("Y", Tyr);
-    codonHash.put("T", Thr);
-    codonHash.put("P", Pro);
-    codonHash.put("A", Ala);
-    codonHash.put("S", Ser);
-    codonHash.put("R", Arg);
-    codonHash.put("G", Gly);
-    codonHash.put("W", Trp);
-    codonHash.put("C", Cys);
-    codonHash.put("I", Ile);
-    codonHash.put("M", Met);
-    codonHash.put("L", Leu);
-    codonHash.put("V", Val);
-    codonHash.put("F", Phe);
-    codonHash.put("STOP", STOP);
-  }
-
   /**
    * Nucleotide Ambiguity Codes
    */
@@ -885,7 +818,6 @@ public class ResidueProperties
         // make all codons for this combination
         char allres[][] = new char[tpos.length][];
         String _acodon = "";
-        char _anuc;
         for (ipos = 0; ipos < tpos.length; ipos++)
         {
           if (acodon[ipos].length == 0 || tpos[ipos] < 0)
@@ -951,379 +883,294 @@ public class ResidueProperties
         }
       }
     }
-
-  }
-
-  static
-  {
-    Lys.add("AAA");
-    Lys.add("AAG");
-    Asn.add("AAC");
-    Asn.add("AAT");
-
-    Gln.add("CAA");
-    Gln.add("CAG");
-    His.add("CAC");
-    His.add("CAT");
-
-    Glu.add("GAA");
-    Glu.add("GAG");
-    Asp.add("GAC");
-    Asp.add("GAT");
-
-    Tyr.add("TAC");
-    Tyr.add("TAT");
-
-    Thr.add("ACA");
-    Thr.add("ACG");
-    Thr.add("ACC");
-    Thr.add("ACT");
-
-    Pro.add("CCA");
-    Pro.add("CCG");
-    Pro.add("CCC");
-    Pro.add("CCT");
-
-    Ala.add("GCA");
-    Ala.add("GCG");
-    Ala.add("GCC");
-    Ala.add("GCT");
-
-    Ser.add("TCA");
-    Ser.add("TCG");
-    Ser.add("TCC");
-    Ser.add("TCT");
-    Ser.add("AGC");
-    Ser.add("AGT");
-
-    Arg.add("AGA");
-    Arg.add("AGG");
-    Arg.add("CGA");
-    Arg.add("CGG");
-    Arg.add("CGC");
-    Arg.add("CGT");
-
-    Gly.add("GGA");
-    Gly.add("GGG");
-    Gly.add("GGC");
-    Gly.add("GGT");
-
-    STOP.add("TGA");
-    STOP.add("TAA");
-    STOP.add("TAG");
-
-    Trp.add("TGG");
-
-    Cys.add("TGC");
-    Cys.add("TGT");
-
-    Ile.add("ATA");
-    Ile.add("ATC");
-    Ile.add("ATT");
-
-    Met.add("ATG");
-
-    Leu.add("CTA");
-    Leu.add("CTG");
-    Leu.add("CTC");
-    Leu.add("CTT");
-    Leu.add("TTA");
-    Leu.add("TTG");
-
-    Val.add("GTA");
-    Val.add("GTG");
-    Val.add("GTC");
-    Val.add("GTT");
-
-    Phe.add("TTC");
-    Phe.add("TTT");
   }
 
   // Stores residue codes/names and colours and other things
-  public static Hashtable propHash = new Hashtable();
+  public static Map<String, Map<String, Integer>> propHash = new Hashtable<String, Map<String, Integer>>();
 
-  public static Hashtable hydrophobic = new Hashtable();
+  public static Map<String, Integer> hydrophobic = new Hashtable<String, Integer>();
 
-  public static Hashtable polar = new Hashtable();
+  public static Map<String, Integer> polar = new Hashtable<String, Integer>();
 
-  public static Hashtable small = new Hashtable();
+  public static Map<String, Integer> small = new Hashtable<String, Integer>();
 
-  public static Hashtable positive = new Hashtable();
+  public static Map<String, Integer> positive = new Hashtable<String, Integer>();
 
-  public static Hashtable negative = new Hashtable();
+  public static Map<String, Integer> negative = new Hashtable<String, Integer>();
 
-  public static Hashtable charged = new Hashtable();
+  public static Map<String, Integer> charged = new Hashtable<String, Integer>();
 
-  public static Hashtable aromatic = new Hashtable();
+  public static Map<String, Integer> aromatic = new Hashtable<String, Integer>();
 
-  public static Hashtable aliphatic = new Hashtable();
+  public static Map<String, Integer> aliphatic = new Hashtable<String, Integer>();
 
-  public static Hashtable tiny = new Hashtable();
+  public static Map<String, Integer> tiny = new Hashtable<String, Integer>();
 
-  public static Hashtable proline = new Hashtable();
+  public static Map<String, Integer> proline = new Hashtable<String, Integer>();
 
   static
   {
-    hydrophobic.put("I", new Integer(1));
-    hydrophobic.put("L", new Integer(1));
-    hydrophobic.put("V", new Integer(1));
-    hydrophobic.put("C", new Integer(1));
-    hydrophobic.put("A", new Integer(1));
-    hydrophobic.put("G", new Integer(1));
-    hydrophobic.put("M", new Integer(1));
-    hydrophobic.put("F", new Integer(1));
-    hydrophobic.put("Y", new Integer(1));
-    hydrophobic.put("W", new Integer(1));
-    hydrophobic.put("H", new Integer(1));
-    hydrophobic.put("K", new Integer(1));
-    hydrophobic.put("X", new Integer(1));
-    hydrophobic.put("-", new Integer(1));
-    hydrophobic.put("*", new Integer(1));
-    hydrophobic.put("R", new Integer(0));
-    hydrophobic.put("E", new Integer(0));
-    hydrophobic.put("Q", new Integer(0));
-    hydrophobic.put("D", new Integer(0));
-    hydrophobic.put("N", new Integer(0));
-    hydrophobic.put("S", new Integer(0));
-    hydrophobic.put("T", new Integer(0));
-    hydrophobic.put("P", new Integer(0));
+    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));
   }
 
   static
   {
-    polar.put("Y", new Integer(1));
-    polar.put("W", new Integer(1));
-    polar.put("H", new Integer(1));
-    polar.put("K", new Integer(1));
-    polar.put("R", new Integer(1));
-    polar.put("E", new Integer(1));
-    polar.put("Q", new Integer(1));
-    polar.put("D", new Integer(1));
-    polar.put("N", new Integer(1));
-    polar.put("S", new Integer(1));
-    polar.put("T", new Integer(1));
-    polar.put("X", new Integer(1));
-    polar.put("-", new Integer(1));
-    polar.put("*", new Integer(1));
-    polar.put("I", new Integer(0));
-    polar.put("L", new Integer(0));
-    polar.put("V", new Integer(0));
-    polar.put("C", new Integer(0));
-    polar.put("A", new Integer(0));
-    polar.put("G", new Integer(0));
-    polar.put("M", new Integer(0));
-    polar.put("F", new Integer(0));
-    polar.put("P", new Integer(0));
+    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));
   }
 
   static
   {
-    small.put("I", new Integer(0));
-    small.put("L", new Integer(0));
-    small.put("V", new Integer(1));
-    small.put("C", new Integer(1));
-    small.put("A", new Integer(1));
-    small.put("G", new Integer(1));
-    small.put("M", new Integer(0));
-    small.put("F", new Integer(0));
-    small.put("Y", new Integer(0));
-    small.put("W", new Integer(0));
-    small.put("H", new Integer(0));
-    small.put("K", new Integer(0));
-    small.put("R", new Integer(0));
-    small.put("E", new Integer(0));
-    small.put("Q", new Integer(0));
-    small.put("D", new Integer(1));
-    small.put("N", new Integer(1));
-    small.put("S", new Integer(1));
-    small.put("T", new Integer(1));
-    small.put("P", new Integer(1));
-    small.put("-", new Integer(1));
-    small.put("*", new Integer(1));
+    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));
   }
 
   static
   {
-    positive.put("I", new Integer(0));
-    positive.put("L", new Integer(0));
-    positive.put("V", new Integer(0));
-    positive.put("C", new Integer(0));
-    positive.put("A", new Integer(0));
-    positive.put("G", new Integer(0));
-    positive.put("M", new Integer(0));
-    positive.put("F", new Integer(0));
-    positive.put("Y", new Integer(0));
-    positive.put("W", new Integer(0));
-    positive.put("H", new Integer(1));
-    positive.put("K", new Integer(1));
-    positive.put("R", new Integer(1));
-    positive.put("E", new Integer(0));
-    positive.put("Q", new Integer(0));
-    positive.put("D", new Integer(0));
-    positive.put("N", new Integer(0));
-    positive.put("S", new Integer(0));
-    positive.put("T", new Integer(0));
-    positive.put("P", new Integer(0));
-    positive.put("-", new Integer(1));
-    positive.put("*", new Integer(1));
+    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));
   }
 
   static
   {
-    negative.put("I", new Integer(0));
-    negative.put("L", new Integer(0));
-    negative.put("V", new Integer(0));
-    negative.put("C", new Integer(0));
-    negative.put("A", new Integer(0));
-    negative.put("G", new Integer(0));
-    negative.put("M", new Integer(0));
-    negative.put("F", new Integer(0));
-    negative.put("Y", new Integer(0));
-    negative.put("W", new Integer(0));
-    negative.put("H", new Integer(0));
-    negative.put("K", new Integer(0));
-    negative.put("R", new Integer(0));
-    negative.put("E", new Integer(1));
-    negative.put("Q", new Integer(0));
-    negative.put("D", new Integer(1));
-    negative.put("N", new Integer(0));
-    negative.put("S", new Integer(0));
-    negative.put("T", new Integer(0));
-    negative.put("P", new Integer(0));
-    negative.put("-", new Integer(1));
-    negative.put("*", new Integer(1));
+    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));
   }
 
   static
   {
-    charged.put("I", new Integer(0));
-    charged.put("L", new Integer(0));
-    charged.put("V", new Integer(0));
-    charged.put("C", new Integer(0));
-    charged.put("A", new Integer(0));
-    charged.put("G", new Integer(0));
-    charged.put("M", new Integer(0));
-    charged.put("F", new Integer(0));
-    charged.put("Y", new Integer(0));
-    charged.put("W", new Integer(0));
-    charged.put("H", new Integer(1));
-    charged.put("K", new Integer(1));
-    charged.put("R", new Integer(1));
-    charged.put("E", new Integer(1));
-    charged.put("Q", new Integer(0));
-    charged.put("D", new Integer(1));
-    charged.put("N", new Integer(0)); // Asparagine is polar but not charged.
+    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.
                                       // Alternative would be charged and
                                       // negative (in basic form)?
-    charged.put("S", new Integer(0));
-    charged.put("T", new Integer(0));
-    charged.put("P", new Integer(0));
-    charged.put("-", new Integer(1));
-    charged.put("*", new Integer(1));
+    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));
   }
 
   static
   {
-    aromatic.put("I", new Integer(0));
-    aromatic.put("L", new Integer(0));
-    aromatic.put("V", new Integer(0));
-    aromatic.put("C", new Integer(0));
-    aromatic.put("A", new Integer(0));
-    aromatic.put("G", new Integer(0));
-    aromatic.put("M", new Integer(0));
-    aromatic.put("F", new Integer(1));
-    aromatic.put("Y", new Integer(1));
-    aromatic.put("W", new Integer(1));
-    aromatic.put("H", new Integer(1));
-    aromatic.put("K", new Integer(0));
-    aromatic.put("R", new Integer(0));
-    aromatic.put("E", new Integer(0));
-    aromatic.put("Q", new Integer(0));
-    aromatic.put("D", new Integer(0));
-    aromatic.put("N", new Integer(0));
-    aromatic.put("S", new Integer(0));
-    aromatic.put("T", new Integer(0));
-    aromatic.put("P", new Integer(0));
-    aromatic.put("-", new Integer(1));
-    aromatic.put("*", new Integer(1));
+    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));
   }
 
   static
   {
-    aliphatic.put("I", new Integer(1));
-    aliphatic.put("L", new Integer(1));
-    aliphatic.put("V", new Integer(1));
-    aliphatic.put("C", new Integer(0));
-    aliphatic.put("A", new Integer(0));
-    aliphatic.put("G", new Integer(0));
-    aliphatic.put("M", new Integer(0));
-    aliphatic.put("F", new Integer(0));
-    aliphatic.put("Y", new Integer(0));
-    aliphatic.put("W", new Integer(0));
-    aliphatic.put("H", new Integer(0));
-    aliphatic.put("K", new Integer(0));
-    aliphatic.put("R", new Integer(0));
-    aliphatic.put("E", new Integer(0));
-    aliphatic.put("Q", new Integer(0));
-    aliphatic.put("D", new Integer(0));
-    aliphatic.put("N", new Integer(0));
-    aliphatic.put("S", new Integer(0));
-    aliphatic.put("T", new Integer(0));
-    aliphatic.put("P", new Integer(0));
-    aliphatic.put("-", new Integer(1));
-    aliphatic.put("*", new Integer(1));
+    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));
   }
 
   static
   {
-    tiny.put("I", new Integer(0));
-    tiny.put("L", new Integer(0));
-    tiny.put("V", new Integer(0));
-    tiny.put("C", new Integer(0));
-    tiny.put("A", new Integer(1));
-    tiny.put("G", new Integer(1));
-    tiny.put("M", new Integer(0));
-    tiny.put("F", new Integer(0));
-    tiny.put("Y", new Integer(0));
-    tiny.put("W", new Integer(0));
-    tiny.put("H", new Integer(0));
-    tiny.put("K", new Integer(0));
-    tiny.put("R", new Integer(0));
-    tiny.put("E", new Integer(0));
-    tiny.put("Q", new Integer(0));
-    tiny.put("D", new Integer(0));
-    tiny.put("N", new Integer(0));
-    tiny.put("S", new Integer(1));
-    tiny.put("T", new Integer(0));
-    tiny.put("P", new Integer(0));
-    tiny.put("-", new Integer(1));
-    tiny.put("*", new Integer(1));
+    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));
   }
 
   static
   {
-    proline.put("I", new Integer(0));
-    proline.put("L", new Integer(0));
-    proline.put("V", new Integer(0));
-    proline.put("C", new Integer(0));
-    proline.put("A", new Integer(0));
-    proline.put("G", new Integer(0));
-    proline.put("M", new Integer(0));
-    proline.put("F", new Integer(0));
-    proline.put("Y", new Integer(0));
-    proline.put("W", new Integer(0));
-    proline.put("H", new Integer(0));
-    proline.put("K", new Integer(0));
-    proline.put("R", new Integer(0));
-    proline.put("E", new Integer(0));
-    proline.put("Q", new Integer(0));
-    proline.put("D", new Integer(0));
-    proline.put("N", new Integer(0));
-    proline.put("S", new Integer(0));
-    proline.put("T", new Integer(0));
-    proline.put("P", new Integer(1));
-    proline.put("-", new Integer(1));
-    proline.put("*", new Integer(1));
+    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));
   }
 
   static
@@ -1368,11 +1215,9 @@ public class ResidueProperties
         propMatrixF[i][j] = 0;
         propMatrixPos[i][j] = 0;
         propMatrixEpos[i][j] = 0;
-        for (Enumeration<String> en = propHash.keys(); en.hasMoreElements();)
+        for (String ph : propHash.keySet())
         {
-          String ph = en.nextElement();
-          Map<String, Integer> pph = (Map<String, Integer>) propHash
-                  .get(ph);
+          Map<String, Integer> pph = propHash.get(ph);
           if (pph.get(ic) != null && pph.get(jc) != null)
           {
             int icp = pph.get(ic).intValue(), jcp = pph.get(jc).intValue();
@@ -1470,22 +1315,8 @@ public class ResidueProperties
     return pog;
   }
 
-  public static Vector getCodons(String res)
-  {
-    if (codonHash.containsKey(res))
-    {
-      return (Vector) codonHash.get(res);
-    }
-
-    return null;
-  }
-
   public static String codonTranslate(String lccodon)
   {
-    if (false)
-    {
-      return _codonTranslate(lccodon);
-    }
     String cdn = codonHash2.get(lccodon.toUpperCase());
     if ("*".equals(cdn))
     {
@@ -1494,25 +1325,6 @@ public class ResidueProperties
     return cdn;
   }
 
-  public static String _codonTranslate(String lccodon)
-  {
-    String codon = lccodon.toUpperCase();
-    // all base ambiguity codes yield an 'X' amino acid residue
-    if (codon.indexOf('X') > -1 || codon.indexOf('N') > -1)
-    {
-      return "X";
-    }
-    for (String key : codonHash.keySet())
-    {
-      if (codonHash.get(key).contains(codon))
-      {
-        return key;
-      }
-    }
-
-    return null;
-  }
-
   public static int[][] getDefaultPeptideMatrix()
   {
     return ResidueProperties.getBLOSUM62();
@@ -1560,10 +1372,10 @@ public class ResidueProperties
     return pog;
   }
 
-  public static Hashtable toDssp3State;
+  public static Hashtable<String, String> toDssp3State;
   static
   {
-    toDssp3State = new Hashtable();
+    toDssp3State = new Hashtable<String, String>();
     toDssp3State.put("H", "H");
     toDssp3State.put("E", "E");
     toDssp3State.put("C", " ");
@@ -1593,7 +1405,7 @@ public class ResidueProperties
       String ssc = ssstring.substring(i, i + 1);
       if (toDssp3State.containsKey(ssc))
       {
-        ss.append((String) toDssp3State.get(ssc));
+        ss.append(toDssp3State.get(ssc));
       }
       else
       {
@@ -2921,51 +2733,47 @@ public class ResidueProperties
 
   }
 
-  public static String getCanonicalAminoAcid(String aa)
+  public static String getCanonicalAminoAcid(String aA)
   {
-    String canonical = modifications.get(aa);
-    return canonical == null ? aa : canonical;
+    String canonical = modifications.get(aA);
+    return canonical == null ? aA : canonical;
   }
 
   // main method generates perl representation of residue property hash
   // / cut here
   public static void main(String[] args)
   {
-    Hashtable aa = new Hashtable();
+    Hashtable<String, Vector<String>> aaProps = new Hashtable<String, Vector<String>>();
     System.out.println("my %aa = {");
     // invert property hashes
-    Enumeration prop = propHash.keys();
-    while (prop.hasMoreElements())
+    for (String pname : propHash.keySet())
     {
-      String pname = (String) prop.nextElement();
-      Hashtable phash = (Hashtable) propHash.get(pname);
-      Enumeration res = phash.keys();
-      while (res.hasMoreElements())
+      Map<String, Integer> phash = propHash.get(pname);
+      for (String rname : phash.keySet())
       {
-        String rname = (String) res.nextElement();
-        Vector aprops = (Vector) aa.get(rname);
+        Vector<String> aprops = aaProps.get(rname);
         if (aprops == null)
         {
-          aprops = new Vector();
-          aa.put(rname, aprops);
+          aprops = new Vector<String>();
+          aaProps.put(rname, aprops);
         }
-        Integer hasprop = (Integer) phash.get(rname);
+        Integer hasprop = phash.get(rname);
         if (hasprop.intValue() == 1)
         {
           aprops.addElement(pname);
         }
       }
     }
-    Enumeration res = aa.keys();
+    Enumeration<String> res = aaProps.keys();
     while (res.hasMoreElements())
     {
-      String rname = (String) res.nextElement();
+      String rname = res.nextElement();
 
       System.out.print("'" + rname + "' => [");
-      Enumeration props = ((Vector) aa.get(rname)).elements();
+      Enumeration<String> props = aaProps.get(rname).elements();
       while (props.hasMoreElements())
       {
-        System.out.print("'" + (String) props.nextElement() + "'");
+        System.out.print("'" + props.nextElement() + "'");
         if (props.hasMoreElements())
         {
           System.out.println(", ");
@@ -2981,15 +2789,15 @@ public class ResidueProperties
   /**
    * Returns a list of residue characters for the specified inputs
    * 
-   * @param nucleotide
+   * @param forNucleotide
    * @param includeAmbiguous
    * @return
    */
-  public static List<String> getResidues(boolean nucleotide,
+  public static List<String> getResidues(boolean forNucleotide,
           boolean includeAmbiguous)
   {
     List<String> result = new ArrayList<String>();
-    if (nucleotide)
+    if (forNucleotide)
     {
       for (String nuc : nucleotideName.keySet())
       {
index 62f3a2e..2be51c2 100644 (file)
@@ -86,6 +86,10 @@ public class TCoffeeColourScheme extends ResidueColourScheme
     seqMap = new IdentityHashMap<SequenceI, Color[]>();
     AnnotatedCollectionI alcontext = alignment instanceof AlignmentI ? alignment
             : alignment.getContext();
+    if (alcontext == null)
+    {
+      return;
+    }
     int w = 0;
     for (AlignmentAnnotation al : alcontext
             .findAnnotation(TCoffeeScoreFile.TCOFFEE_SCORE))
index c27289c..7b103be 100644 (file)
@@ -32,6 +32,7 @@ import jalview.datamodel.Annotation;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SearchResults;
 import jalview.datamodel.SequenceI;
+import jalview.ext.jmol.JmolParser;
 import jalview.gui.IProgressIndicator;
 import jalview.io.AppletFormatAdapter;
 import jalview.io.StructureFile;
@@ -384,21 +385,7 @@ public class StructureSelectionManager
     boolean isMapUsingSIFTs = SiftsSettings.isMapWithSifts();
     try
     {
-
-      boolean isParseWithJMOL = StructureImportSettings
-              .getDefaultPDBFileParser().equalsIgnoreCase(
-                      StructureImportSettings.StructureParser.JMOL_PARSER
-                              .toString());
-      if (isParseWithJMOL || (pdbFile != null && isCIFFile(pdbFile)))
-      {
-        pdb = new jalview.ext.jmol.JmolParser(addTempFacAnnot, parseSecStr,
-                secStructServices, pdbFile, protocol);
-      }
-      else
-      {
-        pdb = new PDBfile(addTempFacAnnot, parseSecStr, secStructServices,
-                pdbFile, protocol);
-      }
+      pdb = new JmolParser(pdbFile, protocol);
 
       if (pdb.getId() != null && pdb.getId().trim().length() > 0
               && AppletFormatAdapter.FILE.equals(protocol))
index 4a0a55d..e6aa472 100755 (executable)
@@ -26,6 +26,7 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceI;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -300,7 +301,8 @@ public class DBRefUtils
     @Override
     public boolean matches(DBRefEntry refa, DBRefEntry refb)
     {
-      if (refa.getSource() != null && refb.getSource() != null
+      if (refa.getSource() != null
+              && refb.getSource() != null
               && DBRefUtils.getCanonicalName(refb.getSource()).equals(
                       DBRefUtils.getCanonicalName(refa.getSource())))
       {
@@ -332,7 +334,8 @@ public class DBRefUtils
     @Override
     public boolean matches(DBRefEntry refa, DBRefEntry refb)
     {
-      if (refa.getSource() != null && refb.getSource() != null
+      if (refa.getSource() != null
+              && refb.getSource() != null
               && DBRefUtils.getCanonicalName(refb.getSource()).equals(
                       DBRefUtils.getCanonicalName(refa.getSource())))
       {
@@ -369,7 +372,8 @@ public class DBRefUtils
     @Override
     public boolean matches(DBRefEntry refa, DBRefEntry refb)
     {
-      if (refa.getSource() != null && refb.getSource() != null
+      if (refa.getSource() != null
+              && refb.getSource() != null
               && DBRefUtils.getCanonicalName(refb.getSource()).equals(
                       DBRefUtils.getCanonicalName(refa.getSource())))
       {
@@ -409,7 +413,8 @@ public class DBRefUtils
     @Override
     public boolean matches(DBRefEntry refa, DBRefEntry refb)
     {
-      if (refa.getSource() != null && refb.getSource() != null
+      if (refa.getSource() != null
+              && refb.getSource() != null
               && DBRefUtils.getCanonicalName(refb.getSource()).equals(
                       DBRefUtils.getCanonicalName(refa.getSource())))
       {
@@ -605,4 +610,127 @@ public class DBRefUtils
     return matches;
   }
 
+  /**
+   * promote direct database references to primary for nucleotide or protein
+   * sequences if they have an appropriate primary ref
+   * <table>
+   * <tr>
+   * <th>Seq Type</th>
+   * <th>Primary DB</th>
+   * <th>Direct which will be promoted</th>
+   * </tr>
+   * <tr align=center>
+   * <td>peptides</td>
+   * <td>Ensembl</td>
+   * <td>Uniprot</td>
+   * </tr>
+   * <tr align=center>
+   * <td>peptides</td>
+   * <td>Ensembl</td>
+   * <td>Uniprot</td>
+   * </tr>
+   * <tr align=center>
+   * <td>dna</td>
+   * <td>Ensembl</td>
+   * <td>ENA</td>
+   * </tr>
+   * </table>
+   * 
+   * @param sequence
+   */
+  public static void ensurePrimaries(SequenceI sequence)
+  {
+    List<DBRefEntry> pr = sequence.getPrimaryDBRefs();
+    if (pr.size() == 0)
+    {
+      // nothing to do
+      return;
+    }
+    List<DBRefEntry> selfs = new ArrayList<DBRefEntry>();
+    {
+      DBRefEntry[] selfArray = selectDbRefs(!sequence.isProtein(),
+              sequence.getDBRefs());
+      if (selfArray == null || selfArray.length == 0)
+      {
+        // nothing to do
+        return;
+      }
+      selfs.addAll(Arrays.asList(selfArray));
+    }
+
+    // filter non-primary refs
+    for (DBRefEntry p : pr)
+    {
+      while (selfs.contains(p))
+      {
+        selfs.remove(p);
+      }
+    }
+    List<DBRefEntry> toPromote = new ArrayList<DBRefEntry>();
+
+    for (DBRefEntry p : pr)
+    {
+      List<String> promType = new ArrayList<String>();
+      if (sequence.isProtein())
+      {
+        switch (getCanonicalName(p.getSource()))
+        {
+        case DBRefSource.UNIPROT:
+          // case DBRefSource.UNIPROTKB:
+          // case DBRefSource.UP_NAME:
+          // search for and promote ensembl
+          promType.add(DBRefSource.ENSEMBL);
+          break;
+        case DBRefSource.ENSEMBL:
+          // search for and promote Uniprot
+          promType.add(DBRefSource.UNIPROT);
+          break;
+        }
+      }
+      else
+      {
+        // TODO: promote transcript refs
+      }
+
+      // collate candidates and promote them
+      DBRefEntry[] candidates = selectRefs(
+              selfs.toArray(new DBRefEntry[0]),
+              promType.toArray(new String[0]));
+      if (candidates != null)
+      {
+        for (DBRefEntry cand : candidates)
+        {
+          if (cand.hasMap())
+          {
+            if (cand.getMap().getTo() != null
+                    && cand.getMap().getTo() != sequence)
+            {
+              // can't promote refs with mappings to other sequences
+              continue;
+            }
+            if (cand.getMap().getMap().getFromLowest() != sequence
+                    .getStart()
+                    && cand.getMap().getMap().getFromHighest() != sequence
+                            .getEnd())
+            {
+              // can't promote refs with mappings from a region of this sequence
+              // - eg CDS
+              continue;
+            }
+          }
+          // and promote
+          cand.setVersion(p.getVersion() + " (promoted)");
+          selfs.remove(cand);
+          toPromote.add(cand);
+          if (!cand.isPrimaryCandidate())
+          {
+            System.out.println("Warning: Couldn't promote dbref "
+                    + cand.toString() + " for sequence "
+                    + sequence.toString());
+          }
+        }
+      }
+    }
+  }
+
 }
index 97f2e1c..80319be 100644 (file)
@@ -44,7 +44,6 @@ import jalview.datamodel.SequenceI;
 import jalview.schemes.Blosum62ColourScheme;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.PIDColourScheme;
-import jalview.schemes.ResidueProperties;
 import jalview.structure.CommandListener;
 import jalview.structure.StructureSelectionManager;
 import jalview.structure.VamsasSource;
@@ -58,6 +57,7 @@ import jalview.workers.ConsensusThread;
 import jalview.workers.StrucConsensusThread;
 
 import java.awt.Color;
+import java.beans.PropertyChangeSupport;
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.BitSet;
@@ -807,7 +807,8 @@ public abstract class AlignmentViewport implements AlignViewportI,
   public void updateConservation(final AlignmentViewPanel ap)
   {
     // see note in mantis : issue number 8585
-    if (alignment.isNucleotide() || conservation == null
+    if (alignment.isNucleotide()
+            || (conservation == null && quality == null)
             || !autoCalculateConsensus)
     {
       return;
@@ -913,6 +914,35 @@ public abstract class AlignmentViewport implements AlignViewportI,
     return false;
   }
 
+  public void setAlignment(AlignmentI align)
+  {
+    this.alignment = align;
+  }
+
+  /**
+   * Clean up references when this viewport is closed
+   */
+  @Override
+  public void dispose()
+  {
+    /*
+     * defensively null out references to large objects in case
+     * this object is not garbage collected (as if!)
+     */
+    consensus = null;
+    complementConsensus = null;
+    strucConsensus = null;
+    conservation = null;
+    quality = null;
+    groupConsensus = null;
+    groupConservation = null;
+    hconsensus = null;
+    hcomplementConsensus = null;
+    // TODO removed listeners from changeSupport?
+    changeSupport = null;
+    setAlignment(null);
+  }
+
   @Override
   public boolean isClosed()
   {
@@ -1107,6 +1137,13 @@ public abstract class AlignmentViewport implements AlignViewportI,
   }
 
   @Override
+  public boolean hasSelectedColumns()
+  {
+    ColumnSelection columnSelection = getColumnSelection();
+    return columnSelection != null && columnSelection.hasSelectedColumns();
+  }
+
+  @Override
   public boolean hasHiddenColumns()
   {
     return colSel != null && colSel.hasHiddenColumns();
@@ -1233,10 +1270,9 @@ public abstract class AlignmentViewport implements AlignViewportI,
     return ignoreGapsInConsensusCalculation;
   }
 
-  // / property change stuff
-
+  // property change stuff
   // JBPNote Prolly only need this in the applet version.
-  private final java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(
+  private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
           this);
 
   protected boolean showConservation = true;
@@ -1827,9 +1863,9 @@ public abstract class AlignmentViewport implements AlignViewportI,
       cs.setConsensus(hconsensus);
       if (cs.conservationApplied())
       {
-        cs.setConservation(Conservation.calculateConservation("All",
-                ResidueProperties.propHash, 3, alignment.getSequences(), 0,
-                alignment.getWidth(), false, getConsPercGaps(), false));
+        cs.setConservation(Conservation.calculateConservation("All", 3,
+                alignment.getSequences(), 0, alignment.getWidth(), false,
+                getConsPercGaps(), false));
       }
     }
 
@@ -2763,8 +2799,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
     if (sg != null
             && (sgs = sg.getStartRes()) >= 0
             && sg.getStartRes() <= (sge = sg.getEndRes())
-            && (colSel == null || colSel.getSelected() == null || colSel
-                    .getSelected().size() == 0))
+            && !this.hasSelectedColumns())
     {
       if (!wholewidth && alignment.getWidth() == (1 + sge - sgs))
       {
index 5c303fd..11ec521 100644 (file)
@@ -94,8 +94,7 @@ public class ConservationThread extends AlignCalcWorker
       }
       try
       {
-        cons = Conservation.calculateConservation("All",
-                jalview.schemes.ResidueProperties.propHash, 3,
+        cons = Conservation.calculateConservation("All", 3,
                 alignment.getSequences(), 0, alWidth - 1, false,
                 ConsPercGaps, quality != null);
       } catch (IndexOutOfBoundsException x)
index ca403c5..453cd00 100644 (file)
@@ -29,15 +29,19 @@ import jalview.datamodel.Mapping;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.gui.CutAndPasteTransfer;
+import jalview.gui.DasSourceBrowser;
 import jalview.gui.Desktop;
 import jalview.gui.FeatureSettings;
 import jalview.gui.IProgressIndicator;
 import jalview.gui.OOMWarning;
+import jalview.util.DBRefUtils;
 import jalview.util.MessageManager;
 import jalview.ws.dbsources.das.api.jalviewSourceI;
+import jalview.ws.dbsources.das.datamodel.DasSequenceSource;
 import jalview.ws.seqfetcher.DbSourceProxy;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Enumeration;
 import java.util.Hashtable;
 import java.util.List;
@@ -45,6 +49,7 @@ import java.util.StringTokenizer;
 import java.util.Vector;
 
 import uk.ac.ebi.picr.model.UPEntry;
+import uk.ac.ebi.www.picr.AccessionMappingService.AccessionMapperServiceLocator;
 
 /**
  * Implements a runnable for validating a sequence against external databases
@@ -55,21 +60,19 @@ import uk.ac.ebi.picr.model.UPEntry;
  */
 public class DBRefFetcher implements Runnable
 {
+  private static final String NEWLINE = System.lineSeparator();
+
   public interface FetchFinishedListenerI
   {
     void finished();
   }
 
-  private List<FetchFinishedListenerI> listeners;
-
   SequenceI[] dataset;
 
   IProgressIndicator progressWindow;
 
   CutAndPasteTransfer output = new CutAndPasteTransfer();
 
-  StringBuffer sbuffer = new StringBuffer();
-
   boolean running = false;
 
   /**
@@ -77,17 +80,19 @@ public class DBRefFetcher implements Runnable
    */
   uk.ac.ebi.www.picr.AccessionMappingService.AccessionMapperInterface picrClient = null;
 
-  // /This will be a collection of Vectors of sequenceI refs.
+  // This will be a collection of Vectors of sequenceI refs.
   // The key will be the seq name or accession id of the seq
-  Hashtable seqRefs;
+  Hashtable<String, Vector<SequenceI>> seqRefs;
 
   DbSourceProxy[] dbSources;
 
   SequenceFetcher sfetcher;
 
+  private List<FetchFinishedListenerI> listeners;
+
   private SequenceI[] alseqs;
 
-  /**
+  /*
    * when true - retrieved sequences will be trimmed to cover longest derived
    * alignment sequence
    */
@@ -137,59 +142,74 @@ public class DBRefFetcher implements Runnable
     trimDsSeqs = Cache.getDefault("TRIM_FETCHED_DATASET_SEQS", true);
     if (sources == null)
     {
-      // af.featureSettings_actionPerformed(null);
-      String[] defdb = null, otherdb = sfetcher
-              .getDbInstances(jalview.ws.dbsources.das.datamodel.DasSequenceSource.class);
-      List<DbSourceProxy> selsources = new ArrayList<DbSourceProxy>();
-      Vector<jalviewSourceI> dasselsrc = (featureSettings != null) ? featureSettings
-              .getSelectedSources() : new jalview.gui.DasSourceBrowser()
-              .getSelectedSources();
-      Enumeration<jalviewSourceI> en = dasselsrc.elements();
-      while (en.hasMoreElements())
+      setDatabaseSources(featureSettings, isNucleotide);
+    }
+    else
+    {
+      // we assume the caller knows what they're doing and ensured that all the
+      // db source names are valid
+      dbSources = sources;
+    }
+  }
+
+  /**
+   * Helper method to configure the list of database sources to query
+   * 
+   * @param featureSettings
+   * @param forNucleotide
+   */
+  void setDatabaseSources(FeatureSettings featureSettings,
+          boolean forNucleotide)
+  {
+    // af.featureSettings_actionPerformed(null);
+    String[] defdb = null;
+    List<DbSourceProxy> selsources = new ArrayList<DbSourceProxy>();
+    Vector<jalviewSourceI> dasselsrc = (featureSettings != null) ? featureSettings
+            .getSelectedSources() : new DasSourceBrowser()
+            .getSelectedSources();
+
+    for (jalviewSourceI src : dasselsrc)
+    {
+      List<DbSourceProxy> sp = src.getSequenceSourceProxies();
+      if (sp != null)
       {
-        jalviewSourceI src = en.nextElement();
-        List<DbSourceProxy> sp = src.getSequenceSourceProxies();
-        if (sp != null)
+        selsources.addAll(sp);
+        if (sp.size() > 1)
         {
-          selsources.addAll(sp);
-          if (sp.size() > 1)
-          {
-            Cache.log.debug("Added many Db Sources for :" + src.getTitle());
-          }
+          Cache.log.debug("Added many Db Sources for :" + src.getTitle());
         }
       }
-      // select appropriate databases based on alignFrame context.
-      if (isNucleotide)
-      {
-        defdb = DBRefSource.DNACODINGDBS;
-      }
-      else
-      {
-        defdb = DBRefSource.PROTEINDBS;
-      }
-      List<DbSourceProxy> srces = new ArrayList<DbSourceProxy>();
-      for (String ddb : defdb)
+    }
+    // select appropriate databases based on alignFrame context.
+    if (forNucleotide)
+    {
+      defdb = DBRefSource.DNACODINGDBS;
+    }
+    else
+    {
+      defdb = DBRefSource.PROTEINDBS;
+    }
+    List<DbSourceProxy> srces = new ArrayList<DbSourceProxy>();
+    for (String ddb : defdb)
+    {
+      List<DbSourceProxy> srcesfordb = sfetcher.getSourceProxy(ddb);
+      if (srcesfordb != null)
       {
-        List<DbSourceProxy> srcesfordb = sfetcher.getSourceProxy(ddb);
-        if (srcesfordb != null)
+        for (DbSourceProxy src : srcesfordb)
         {
-          srces.addAll(srcesfordb);
+          if (!srces.contains(src))
+          {
+            srces.addAll(srcesfordb);
+          }
         }
       }
-      // append the PDB data source, since it is 'special', catering for both
-      // nucleotide and protein
-      srces.addAll(sfetcher.getSourceProxy(DBRefSource.PDB));
-
-      // append the selected sequence sources to the default dbs
-      srces.addAll(selsources);
-      dbSources = srces.toArray(new DbSourceProxy[0]);
-    }
-    else
-    {
-      // we assume the caller knows what they're doing and ensured that all the
-      // db source names are valid
-      dbSources = sources;
     }
+    // append the PDB data source, since it is 'special', catering for both
+    // nucleotide and protein
+    // srces.addAll(sfetcher.getSourceProxy(DBRefSource.PDB));
+
+    srces.addAll(selsources);
+    dbSources = srces.toArray(new DbSourceProxy[srces.size()]);
   }
 
   /**
@@ -224,7 +244,7 @@ public class DBRefFetcher implements Runnable
     }
     // append additional sources
     DbSourceProxy[] otherdb = sfetcher
-            .getDbSourceProxyInstances(jalview.ws.dbsources.das.datamodel.DasSequenceSource.class);
+            .getDbSourceProxyInstances(DasSequenceSource.class);
     if (otherdb != null && otherdb.length > 0)
     {
       DbSourceProxy[] newsrc = new DbSourceProxy[dbSources.length
@@ -243,6 +263,9 @@ public class DBRefFetcher implements Runnable
    */
   public void fetchDBRefs(boolean waitTillFinished)
   {
+    // TODO can we not simply write
+    // if (waitTillFinished) { run(); } else { new Thread(this).start(); }
+
     Thread thread = new Thread(this);
     thread.start();
     running = true;
@@ -274,10 +297,10 @@ public class DBRefFetcher implements Runnable
   {
     key = key.toUpperCase();
 
-    Vector seqs;
+    Vector<SequenceI> seqs;
     if (seqRefs.containsKey(key))
     {
-      seqs = (Vector) seqRefs.get(key);
+      seqs = seqRefs.get(key);
 
       if (seqs != null && !seqs.contains(seq))
       {
@@ -285,14 +308,14 @@ public class DBRefFetcher implements Runnable
       }
       else if (seqs == null)
       {
-        seqs = new Vector();
+        seqs = new Vector<SequenceI>();
         seqs.addElement(seq);
       }
 
     }
     else
     {
-      seqs = new Vector();
+      seqs = new Vector<SequenceI>();
       seqs.addElement(seq);
     }
 
@@ -323,7 +346,7 @@ public class DBRefFetcher implements Runnable
     {
       if (Cache.getDefault("DBREFFETCH_USEPICR", false))
       {
-        picrClient = new uk.ac.ebi.www.picr.AccessionMappingService.AccessionMapperServiceLocator()
+        picrClient = new AccessionMapperServiceLocator()
                 .getAccessionMapperPort();
       }
     } catch (Exception e)
@@ -331,149 +354,145 @@ public class DBRefFetcher implements Runnable
       System.err.println("Couldn't locate PICR service instance.\n");
       e.printStackTrace();
     }
+
+    Vector<SequenceI> sdataset = new Vector<SequenceI>(
+            Arrays.asList(dataset));
+    List<String> warningMessages = new ArrayList<String>();
+
     int db = 0;
-    Vector sdataset = new Vector();
-    for (int s = 0; s < dataset.length; s++)
-    {
-      sdataset.addElement(dataset[s]);
-    }
     while (sdataset.size() > 0 && db < dbSources.length)
     {
-      int maxqlen = 1; // default number of queries made to at one time
-      System.err.println("Verifying against " + dbSources[db].getDbName());
-      boolean dn = false;
+      int maxqlen = 1; // default number of queries made at one time
+      System.out.println("Verifying against " + dbSources[db].getDbName());
 
       // iterate through db for each remaining un-verified sequence
       SequenceI[] currSeqs = new SequenceI[sdataset.size()];
       sdataset.copyInto(currSeqs);// seqs that are to be validated against
       // dbSources[db]
-      Vector queries = new Vector(); // generated queries curSeq
-      seqRefs = new Hashtable();
+      Vector<String> queries = new Vector<String>(); // generated queries curSeq
+      seqRefs = new Hashtable<String, Vector<SequenceI>>();
 
       int seqIndex = 0;
 
-      jalview.ws.seqfetcher.DbSourceProxy dbsource = dbSources[db];
+      DbSourceProxy dbsource = dbSources[db];
+      // for moment, we dumbly iterate over all retrieval sources for a
+      // particular database
+      // TODO: introduce multithread multisource queries and logic to remove a
+      // query from other sources if any source for a database returns a
+      // record
+      maxqlen = dbsource.getMaximumQueryCount();
+
+      while (queries.size() > 0 || seqIndex < currSeqs.length)
       {
-        // for moment, we dumbly iterate over all retrieval sources for a
-        // particular database
-        // TODO: introduce multithread multisource queries and logic to remove a
-        // query from other sources if any source for a database returns a
-        // record
-        maxqlen = dbsource.getMaximumQueryCount();
-
-        while (queries.size() > 0 || seqIndex < currSeqs.length)
+        if (queries.size() > 0)
         {
-          if (queries.size() > 0)
-          {
-            // Still queries to make for current seqIndex
-            StringBuffer queryString = new StringBuffer("");
-            int numq = 0, nqSize = (maxqlen > queries.size()) ? queries
-                    .size() : maxqlen;
+          // Still queries to make for current seqIndex
+          StringBuffer queryString = new StringBuffer("");
+          int numq = 0;
+          int nqSize = (maxqlen > queries.size()) ? queries
+                  .size() : maxqlen;
 
-            while (queries.size() > 0 && numq < nqSize)
-            {
-              String query = (String) queries.elementAt(0);
-              if (dbsource.isValidReference(query))
-              {
-                queryString.append((numq == 0) ? "" : dbsource
-                        .getAccessionSeparator());
-                queryString.append(query);
-                numq++;
-              }
-              // remove the extracted query string
-              queries.removeElementAt(0);
-            }
-            // make the queries and process the response
-            AlignmentI retrieved = null;
-            try
-            {
-              if (jalview.bin.Cache.log.isDebugEnabled())
-              {
-                jalview.bin.Cache.log.debug("Querying "
-                        + dbsource.getDbName() + " with : '"
-                        + queryString.toString() + "'");
-              }
-              retrieved = dbsource.getSequenceRecords(queryString
-                      .toString());
-            } catch (Exception ex)
-            {
-              ex.printStackTrace();
-            } catch (OutOfMemoryError err)
+          while (queries.size() > 0 && numq < nqSize)
+          {
+            String query = queries.elementAt(0);
+            if (dbsource.isValidReference(query))
             {
-              new OOMWarning("retrieving database references ("
-                      + queryString.toString() + ")", err);
+              queryString.append((numq == 0) ? "" : dbsource
+                      .getAccessionSeparator());
+              queryString.append(query);
+              numq++;
             }
-            if (retrieved != null)
+            // remove the extracted query string
+            queries.removeElementAt(0);
+          }
+          // make the queries and process the response
+          AlignmentI retrieved = null;
+          try
+          {
+            if (Cache.log.isDebugEnabled())
             {
-              transferReferences(sdataset, dbsource.getDbSource(),
-                      retrieved, trimDsSeqs);
+              Cache.log.debug("Querying " + dbsource.getDbName()
+                      + " with : '" + queryString.toString() + "'");
             }
+            retrieved = dbsource.getSequenceRecords(queryString.toString());
+          } catch (Exception ex)
+          {
+            ex.printStackTrace();
+          } catch (OutOfMemoryError err)
+          {
+            new OOMWarning("retrieving database references ("
+                    + queryString.toString() + ")", err);
+          }
+          if (retrieved != null)
+          {
+            transferReferences(sdataset, dbsource.getDbSource(), retrieved,
+                    trimDsSeqs, warningMessages);
           }
-          else
+        }
+        else
+        {
+          // make some more strings for use as queries
+          for (int i = 0; (seqIndex < dataset.length) && (i < 50); seqIndex++, i++)
           {
-            // make some more strings for use as queries
-            for (int i = 0; (seqIndex < dataset.length) && (i < 50); seqIndex++, i++)
+            SequenceI sequence = dataset[seqIndex];
+            DBRefEntry[] uprefs = DBRefUtils.selectRefs(
+                    sequence.getDBRefs(),
+                    new String[] { dbsource.getDbSource() }); // jalview.datamodel.DBRefSource.UNIPROT
+            // });
+            // check for existing dbrefs to use
+            if (uprefs != null && uprefs.length > 0)
             {
-              SequenceI sequence = dataset[seqIndex];
-              DBRefEntry[] uprefs = jalview.util.DBRefUtils.selectRefs(
-                      sequence.getDBRefs(),
-                      new String[] { dbsource.getDbSource() }); // jalview.datamodel.DBRefSource.UNIPROT
-              // });
-              // check for existing dbrefs to use
-              if (uprefs != null && uprefs.length > 0)
+              for (int j = 0; j < uprefs.length; j++)
               {
-                for (int j = 0; j < uprefs.length; j++)
-                {
-                  addSeqId(sequence, uprefs[j].getAccessionId());
-                  queries.addElement(uprefs[j].getAccessionId()
-                          .toUpperCase());
-                }
+                addSeqId(sequence, uprefs[j].getAccessionId());
+                queries.addElement(uprefs[j].getAccessionId().toUpperCase());
               }
-              else
+            }
+            else
+            {
+              // generate queries from sequence ID string
+              StringTokenizer st = new StringTokenizer(sequence.getName(),
+                      "|");
+              while (st.hasMoreTokens())
               {
-                // generate queries from sequence ID string
-                StringTokenizer st = new StringTokenizer(
-                        sequence.getName(), "|");
-                while (st.hasMoreTokens())
+                String token = st.nextToken();
+                UPEntry[] presp = null;
+                if (picrClient != null)
                 {
-                  String token = st.nextToken();
-                  UPEntry[] presp = null;
-                  if (picrClient != null)
+                  // resolve the string against PICR to recover valid IDs
+                  try
                   {
-                    // resolve the string against PICR to recover valid IDs
-                    try
-                    {
-                      presp = picrClient.getUPIForAccession(token, null,
-                              picrClient.getMappedDatabaseNames(), null,
-                              true);
-                    } catch (Exception e)
-                    {
-                      System.err.println("Exception with Picr for '"
-                              + token + "'\n");
-                      e.printStackTrace();
-                    }
-                  }
-                  if (presp != null && presp.length > 0)
+                    presp = picrClient
+                            .getUPIForAccession(token, null,
+                                    picrClient.getMappedDatabaseNames(),
+                                    null, true);
+                  } catch (Exception e)
                   {
-                    for (int id = 0; id < presp.length; id++)
-                    {
-                      // construct sequences from response if sequences are
-                      // present, and do a transferReferences
-                      // otherwise transfer non sequence x-references directly.
-                    }
-                    System.out
-                            .println("Validated ID against PICR... (for what its worth):"
-                                    + token);
-                    addSeqId(sequence, token);
-                    queries.addElement(token.toUpperCase());
+                    System.err.println("Exception with Picr for '" + token
+                            + "'\n");
+                    e.printStackTrace();
                   }
-                  else
+                }
+                if (presp != null && presp.length > 0)
+                {
+                  for (int id = 0; id < presp.length; id++)
                   {
-                    // if ()
-                    // System.out.println("Not querying source with token="+token+"\n");
-                    addSeqId(sequence, token);
-                    queries.addElement(token.toUpperCase());
+                    // construct sequences from response if sequences are
+                    // present, and do a transferReferences
+                    // otherwise transfer non sequence x-references directly.
                   }
+                  System.out
+                          .println("Validated ID against PICR... (for what its worth):"
+                                  + token);
+                  addSeqId(sequence, token);
+                  queries.addElement(token.toUpperCase());
+                }
+                else
+                {
+                  // if ()
+                  // System.out.println("Not querying source with token="+token+"\n");
+                  addSeqId(sequence, token);
+                  queries.addElement(token.toUpperCase());
                 }
               }
             }
@@ -482,14 +501,20 @@ public class DBRefFetcher implements Runnable
       }
       // advance to next database
       db++;
-    } // all databases have been queries.
-    if (sbuffer.length() > 0)
+    } // all databases have been queried
+    if (!warningMessages.isEmpty())
     {
-      output.setText(MessageManager
-              .getString("label.your_sequences_have_been_verified")
-              + sbuffer.toString());
+      StringBuilder sb = new StringBuilder(warningMessages.size() * 30);
+      sb.append(MessageManager
+              .getString("label.your_sequences_have_been_verified"));
+      for (String msg : warningMessages)
+      {
+        sb.append(msg).append(NEWLINE);
+      }
+      output.setText(sb.toString());
+
       Desktop.addInternalFrame(output,
-              MessageManager.getString("label.sequence_names_updated"),
+              MessageManager.getString("label.sequences_updated"),
               600, 300);
       // The above is the dataset, we must now find out the index
       // of the viewed sequence
@@ -511,57 +536,62 @@ public class DBRefFetcher implements Runnable
 
   /**
    * Verify local sequences in seqRefs against the retrieved sequence database
-   * records.
+   * records. Returns true if any sequence was modified as a result (start/end
+   * changed and/or sequence enlarged), else false.
    * 
+   * @param sdataset
+   *          dataset sequences we are retrieving for
+   * @param dbSource
+   *          database source we are retrieving from
+   * @param retrievedAl
+   *          retrieved sequences as alignment
    * @param trimDatasetSeqs
-   * 
+   *          if true, sequences will not be enlarged to match longer retrieved
+   *          sequences, only their start/end adjusted
+   * @param warningMessages
+   *          a list of messages to add to
    */
-  void transferReferences(Vector sdataset, String dbSource,
-          AlignmentI retrievedAl, boolean trimDatasetSeqs) // File
-  // file)
+  boolean transferReferences(Vector<SequenceI> sdataset,
+          String dbSource,
+          AlignmentI retrievedAl, boolean trimDatasetSeqs,
+          List<String> warningMessages)
   {
-    System.out.println("trimming ? " + trimDatasetSeqs);
+    // System.out.println("trimming ? " + trimDatasetSeqs);
     if (retrievedAl == null || retrievedAl.getHeight() == 0)
     {
-      return;
+      return false;
     }
+
+    boolean modified = false;
     SequenceI[] retrieved = recoverDbSequences(retrievedAl
             .getSequencesArray());
     SequenceI sequence = null;
-    boolean transferred = false;
-    StringBuffer messages = new StringBuffer();
 
-    // Vector entries = new Uniprot().getUniprotEntries(file);
-
-    int i, iSize = retrieved.length; // entries == null ? 0 : entries.size();
-    // UniprotEntry entry;
-    for (i = 0; i < iSize; i++)
+    for (SequenceI retrievedSeq : retrieved)
     {
-      SequenceI entry = retrieved[i]; // (UniprotEntry) entries.elementAt(i);
-
       // Work out which sequences this sequence matches,
       // taking into account all accessionIds and names in the file
-      Vector sequenceMatches = new Vector();
+      Vector<SequenceI> sequenceMatches = new Vector<SequenceI>();
       // look for corresponding accession ids
-      DBRefEntry[] entryRefs = jalview.util.DBRefUtils.selectRefs(
-              entry.getDBRefs(), new String[] { dbSource });
+      DBRefEntry[] entryRefs = DBRefUtils.selectRefs(retrievedSeq.getDBRefs(),
+              new String[] { dbSource });
       if (entryRefs == null)
       {
         System.err
                 .println("Dud dbSource string ? no entryrefs selected for "
-                        + dbSource + " on " + entry.getName());
+                        + dbSource + " on " + retrievedSeq.getName());
         continue;
       }
       for (int j = 0; j < entryRefs.length; j++)
       {
-        String accessionId = entryRefs[j].getAccessionId(); // .getAccession().elementAt(j).toString();
+        String accessionId = entryRefs[j].getAccessionId();
         // match up on accessionId
         if (seqRefs.containsKey(accessionId.toUpperCase()))
         {
-          Vector seqs = (Vector) seqRefs.get(accessionId);
+          Vector<SequenceI> seqs = seqRefs.get(accessionId);
           for (int jj = 0; jj < seqs.size(); jj++)
           {
-            sequence = (SequenceI) seqs.elementAt(jj);
+            sequence = seqs.elementAt(jj);
             if (!sequenceMatches.contains(sequence))
             {
               sequenceMatches.addElement(sequence);
@@ -569,17 +599,17 @@ public class DBRefFetcher implements Runnable
           }
         }
       }
-      if (sequenceMatches.size() == 0)
+      if (sequenceMatches.isEmpty())
       {
         // failed to match directly on accessionId==query so just compare all
         // sequences to entry
-        Enumeration e = seqRefs.keys();
+        Enumeration<String> e = seqRefs.keys();
         while (e.hasMoreElements())
         {
-          Vector sqs = (Vector) seqRefs.get(e.nextElement());
+          Vector<SequenceI> sqs = seqRefs.get(e.nextElement());
           if (sqs != null && sqs.size() > 0)
           {
-            Enumeration sqe = sqs.elements();
+            Enumeration<SequenceI> sqe = sqs.elements();
             while (sqe.hasMoreElements())
             {
               sequenceMatches.addElement(sqe.nextElement());
@@ -603,10 +633,11 @@ public class DBRefFetcher implements Runnable
        */
       // sequenceMatches now contains the set of all sequences associated with
       // the returned db record
-      String entrySeq = entry.getSequenceAsString().toUpperCase();
+      final String retrievedSeqString = retrievedSeq.getSequenceAsString();
+      String entrySeq = retrievedSeqString.toUpperCase();
       for (int m = 0; m < sequenceMatches.size(); m++)
       {
-        sequence = (SequenceI) sequenceMatches.elementAt(m);
+        sequence = sequenceMatches.elementAt(m);
         // only update start and end positions and shift features if there are
         // no existing references
         // TODO: test for legacy where uniprot or EMBL refs exist but no
@@ -616,13 +647,13 @@ public class DBRefFetcher implements Runnable
         // TODO:
         // verify sequence against the entry sequence
 
+        Mapping mp;
+        final int sequenceStart = sequence.getStart();
+
+        boolean remoteEnclosesLocal = false;
         String nonGapped = AlignSeq.extractGaps("-. ",
                 sequence.getSequenceAsString()).toUpperCase();
-
         int absStart = entrySeq.indexOf(nonGapped);
-        Mapping mp;
-
-        final int sequenceStart = sequence.getStart();
         if (absStart == -1)
         {
           // couldn't find local sequence in sequence from database, so check if
@@ -632,17 +663,20 @@ public class DBRefFetcher implements Runnable
           {
             // verification failed. couldn't find any relationship between
             // entrySeq and local sequence
-            messages.append(sequence.getName()
-                    + " SEQUENCE NOT %100 MATCH \n");
+            // messages suppressed as many-to-many matches are confusing
+            // String msg = sequence.getName()
+            // + " Sequence not 100% match with "
+            // + retrievedSeq.getName();
+            // addWarningMessage(warningMessages, msg);
             continue;
           }
           /*
-           * found match for the whole of the database sequence within the local
-           * sequence's reference frame. 
+           * retrieved sequence is a proper subsequence of local sequence
            */
-          transferred = true;
-          sbuffer.append(sequence.getName() + " HAS " + absStart
-                  + " PREFIXED RESIDUES COMPARED TO " + dbSource + "\n");
+          String msg = sequence.getName() + " has " + absStart
+                  + " prefixed residues compared to "
+                  + retrievedSeq.getName();
+          addWarningMessage(warningMessages, msg);
 
           /*
            * So create a mapping to the external entry from the matching region of 
@@ -650,50 +684,40 @@ public class DBRefFetcher implements Runnable
            */
           mp = new Mapping(null, new int[] { sequenceStart + absStart,
               sequenceStart + absStart + entrySeq.length() - 1 }, new int[]
-          { entry.getStart(), entry.getStart() + entrySeq.length() - 1 },
+          { retrievedSeq.getStart(), retrievedSeq.getStart() + entrySeq.length() - 1 },
                   1, 1);
           updateRefFrame = false;
         }
         else
         {
           /*
-           * found a match for the local sequence within sequence from 
-           * the external database 
+           * local sequence is a subsequence of (or matches) retrieved sequence
            */
-          transferred = true;
-
-          // update start and end of local sequence to place it in entry's
-          // reference frame.
-          // apply identity map map from whole of local sequence to matching
-          // region of database
-          // sequence
-          mp = null; // Mapping.getIdentityMap();
-          // new Mapping(null,
-          // new int[] { absStart+sequence.getStart(),
-          // absStart+sequence.getStart()+entrySeq.length()-1},
-          // new int[] { entry.getStart(), entry.getEnd() }, 1, 1);
-          // relocate local features for updated start
+          remoteEnclosesLocal = true;
+          mp = null;
 
           if (updateRefFrame)
           {
-            if (sequence.getSequenceFeatures() != null)
+            SequenceFeature[] sfs = sequence.getSequenceFeatures();
+            if (sfs != null)
             {
               /*
                * relocate existing sequence features by offset
                */
-              SequenceFeature[] sf = sequence.getSequenceFeatures();
               int start = sequenceStart;
               int end = sequence.getEnd();
-              int startShift = 1 - absStart - start; // how much the features
-                                                     // are
-              // to be shifted by
-              for (int sfi = 0; sfi < sf.length; sfi++)
+              int startShift = 1 - absStart - start;
+
+              if (startShift != 0)
               {
-                if (sf[sfi].getBegin() >= start && sf[sfi].getEnd() <= end)
+                for (SequenceFeature sf : sfs)
                 {
-                  // shift feature along by absstart
-                  sf[sfi].setBegin(sf[sfi].getBegin() + startShift);
-                  sf[sfi].setEnd(sf[sfi].getEnd() + startShift);
+                  if (sf.getBegin() >= start && sf.getEnd() <= end)
+                  {
+                    sf.setBegin(sf.getBegin() + startShift);
+                    sf.setEnd(sf.getEnd() + startShift);
+                    modified = true;
+                  }
                 }
               }
             }
@@ -701,16 +725,36 @@ public class DBRefFetcher implements Runnable
         }
 
         System.out.println("Adding dbrefs to " + sequence.getName()
-                + " from " + dbSource + " sequence : " + entry.getName());
-        sequence.transferAnnotation(entry, mp);
+                + " from " + dbSource + " sequence : " + retrievedSeq.getName());
+        sequence.transferAnnotation(retrievedSeq, mp);
 
-        absStart += entry.getStart();
+        absStart += retrievedSeq.getStart();
         int absEnd = absStart + nonGapped.length() - 1;
         if (!trimDatasetSeqs)
         {
-          // insert full length sequence from record
-          sequence.setSequence(entry.getSequenceAsString());
-          sequence.setStart(entry.getStart());
+          /*
+           * update start position and/or expand to longer retrieved sequence
+           */
+          if (!retrievedSeqString.equals(sequence.getSequenceAsString())
+                  && remoteEnclosesLocal)
+          {
+            sequence.setSequence(retrievedSeqString);
+            modified = true;
+            addWarningMessage(warningMessages,
+                    "Sequence for " + sequence.getName()
+                            + " expanded from " + retrievedSeq.getName());
+          }
+          if (sequence.getStart() != retrievedSeq.getStart())
+          {
+            sequence.setStart(retrievedSeq.getStart());
+            modified = true;
+            if (absStart != sequenceStart)
+            {
+              addWarningMessage(warningMessages, "Start/end position for "
+                      + sequence.getName() + " updated from "
+                      + retrievedSeq.getName());
+            }
+          }
         }
         if (updateRefFrame)
         {
@@ -718,8 +762,16 @@ public class DBRefFetcher implements Runnable
           if (trimDatasetSeqs)
           {
             // just fix start/end
-            sequence.setStart(absStart);
-            sequence.setEnd(absEnd);
+            if (sequence.getStart() != absStart
+                    || sequence.getEnd() != absEnd)
+            {
+              sequence.setStart(absStart);
+              sequence.setEnd(absEnd);
+              modified = true;
+              addWarningMessage(warningMessages, "Start/end for "
+                      + sequence.getName() + " updated from "
+                      + retrievedSeq.getName());
+            }
           }
           // search for alignment sequences to update coordinate frame for
           for (int alsq = 0; alsq < alseqs.length; alsq++)
@@ -736,6 +788,7 @@ public class DBRefFetcher implements Runnable
               {
                 alseqs[alsq].setEnd(ngAlsq.length()
                         + alseqs[alsq].getStart() - 1);
+                modified = true;
               }
             }
           }
@@ -752,10 +805,20 @@ public class DBRefFetcher implements Runnable
         // ids, so we can query all enabled DAS servers for them ?
       }
     }
-    if (!transferred)
+    return modified;
+  }
+
+  /**
+   * Adds the message to the list unless it already contains it
+   * 
+   * @param messageList
+   * @param msg
+   */
+  void addWarningMessage(List<String> messageList, String msg)
+  {
+    if (!messageList.contains(msg))
     {
-      // report the ID/sequence mismatches
-      sbuffer.append(messages);
+      messageList.add(msg);
     }
   }
 
@@ -767,12 +830,12 @@ public class DBRefFetcher implements Runnable
    */
   private SequenceI[] recoverDbSequences(SequenceI[] sequencesArray)
   {
-    Vector nseq = new Vector();
+    Vector<SequenceI> nseq = new Vector<SequenceI>();
     for (int i = 0; sequencesArray != null && i < sequencesArray.length; i++)
     {
       nseq.addElement(sequencesArray[i]);
-      DBRefEntry dbr[] = sequencesArray[i].getDBRefs();
-      jalview.datamodel.Mapping map = null;
+      DBRefEntry[] dbr = sequencesArray[i].getDBRefs();
+      Mapping map = null;
       for (int r = 0; (dbr != null) && r < dbr.length; r++)
       {
         if ((map = dbr[r].getMap()) != null)
index 2049766..73e67aa 100644 (file)
@@ -72,7 +72,7 @@ public abstract class EmblXmlSource extends EbiFileRetrievedProxy
               "exception.ebiembl_retrieval_failed_on", new String[] {
                   emprefx.toLowerCase(), query.trim() }), e);
     }
-    return getEmblSequenceRecords(emprefx, query, reply);
+    return getEmblSequenceRecords(emprefx, reply);
   }
 
   /**
@@ -81,46 +81,38 @@ public abstract class EmblXmlSource extends EbiFileRetrievedProxy
    * @param emprefx
    *          either EMBL or EMBLCDS strings are allowed - anything else will
    *          not retrieve emblxml
-   * @param query
    * @param file
    *          the EMBL XML file containing the results of a query
    * @return
    * @throws Exception
    */
-  public AlignmentI getEmblSequenceRecords(String emprefx, String query,
-          File reply) throws Exception
+  public AlignmentI getEmblSequenceRecords(String emprefx, File reply)
+          throws Exception
   {
-    EmblFile efile = null;
-    List<SequenceI> seqs = new ArrayList<SequenceI>();
+    EmblEntry entry = null;
 
     if (reply != null && reply.exists())
     {
       file = reply.getAbsolutePath();
       if (reply.length() > EMBL_NOT_FOUND_REPLY.length())
       {
-        efile = EmblFile.getEmblFile(reply);
+        entry = EmblFile.getEmblEntry(reply);
       }
     }
 
+    // TODO don't need peptides any more?
     List<SequenceI> peptides = new ArrayList<SequenceI>();
-    if (efile != null)
+    AlignmentI al = null;
+    if (entry != null)
     {
-      for (EmblEntry entry : efile.getEntries())
+      SequenceI seq = entry.getSequence(emprefx, peptides);
+      if (seq != null)
       {
-        SequenceI seq = entry.getSequence(emprefx, peptides);
-        if (seq != null)
-        {
-          seqs.add(seq.deriveSequence());
-          // place DBReferences on dataset and refer
-        }
+        seq.deriveSequence();
+        // place DBReferences on dataset and refer
+        al = new Alignment(new SequenceI[] { seq });
       }
     }
-
-    AlignmentI al = null;
-    if (!seqs.isEmpty())
-    {
-      al = new Alignment(seqs.toArray(new SequenceI[seqs.size()]));
-    }
     stopQuery();
     return al;
   }
index 04c23a2..a50ed14 100644 (file)
@@ -37,7 +37,6 @@ import jalview.ws.ebi.EBIFetchClient;
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.Vector;
 
 import com.stevesoft.pat.Regex;
 
@@ -47,15 +46,16 @@ import com.stevesoft.pat.Regex;
  */
 public class Pdb extends EbiFileRetrievedProxy
 {
+  private static final String SEPARATOR = "|";
+  private static final String COLON = ":";
+  private static final int PDB_ID_LENGTH = 4;
+
+
   public Pdb()
   {
     super();
   }
 
-  public static final String FEATURE_INSERTION = "INSERTION";
-
-  public static final String FEATURE_RES_NUM = "RESNUM";
-
   /*
    * (non-Javadoc)
    * 
@@ -64,7 +64,6 @@ public class Pdb extends EbiFileRetrievedProxy
   @Override
   public String getAccessionSeparator()
   {
-    // TODO Auto-generated method stub
     return null;
   }
 
@@ -110,23 +109,28 @@ public class Pdb extends EbiFileRetrievedProxy
   public AlignmentI getSequenceRecords(String queries) throws Exception
   {
     AlignmentI pdbAlignment = null;
-    Vector result = new Vector();
     String chain = null;
     String id = null;
-    if (queries.indexOf(":") > -1)
+    if (queries.indexOf(COLON) > -1)
     {
-      chain = queries.substring(queries.indexOf(":") + 1);
-      id = queries.substring(0, queries.indexOf(":"));
+      chain = queries.substring(queries.indexOf(COLON) + 1);
+      id = queries.substring(0, queries.indexOf(COLON));
     }
     else
     {
       id = queries;
     }
-    if (queries.length() > 4 && chain == null)
+
+    /*
+     * extract chain code if it is appended to the id and we
+     * don't already have one
+     */
+    if (queries.length() > PDB_ID_LENGTH && chain == null)
     {
-      chain = queries.substring(4, 5);
-      id = queries.substring(0, 4);
+      chain = queries.substring(PDB_ID_LENGTH, PDB_ID_LENGTH + 1);
+      id = queries.substring(0, PDB_ID_LENGTH);
     }
+
     if (!isValidReference(id))
     {
       System.err.println("Ignoring invalid pdb query: '" + id + "'");
@@ -165,8 +169,6 @@ public class Pdb extends EbiFileRetrievedProxy
               chid = pid.getChainCode();
 
             }
-            ;
-
           }
           if (chain == null
                   || (chid != null && (chid.equals(chain)
@@ -175,8 +177,8 @@ public class Pdb extends EbiFileRetrievedProxy
           {
             // FIXME seems to result in 'PDB|1QIP|1qip|A' - 1QIP is redundant.
             // TODO: suggest simplify naming to 1qip|A as default name defined
-            pdbcs.setName(jalview.datamodel.DBRefSource.PDB + "|" + id
-                    + "|" + pdbcs.getName());
+            pdbcs.setName(jalview.datamodel.DBRefSource.PDB + SEPARATOR + id
+                    + SEPARATOR + pdbcs.getName());
             // Might need to add more metadata to the PDBEntry object
             // like below
             /*
index 81b4caf..caed598 100644 (file)
@@ -222,6 +222,38 @@ public class Uniprot extends DbSourceProxyImpl
       {
         onlyPdbEntries.addElement(pdb);
       }
+      if ("EMBL".equals(pdb.getType()))
+      {
+        // look for a CDS reference and add it, too.
+        String cdsId = (String) pdb.getProperty("protein sequence ID");
+        if (cdsId != null && cdsId.trim().length() > 0)
+        {
+          // remove version
+          String[] vrs = cdsId.split("\\.");
+          dbr = new DBRefEntry(DBRefSource.EMBLCDS, vrs.length > 1 ? vrs[1]
+                  : DBRefSource.UNIPROT + ":" + dbVersion, vrs[0]);
+          dbRefs.add(dbr);
+        }
+      }
+      if ("Ensembl".equals(pdb.getType()))
+      {
+        /*UniprotXML
+         * <dbReference type="Ensembl" id="ENST00000321556">
+        * <molecule id="Q9BXM7-1"/>
+        * <property type="protein sequence ID" value="ENSP00000364204"/>
+        * <property type="gene ID" value="ENSG00000158828"/>
+        * </dbReference> 
+         */
+        String cdsId = (String) pdb.getProperty("protein sequence ID");
+        if (cdsId != null && cdsId.trim().length() > 0)
+        {
+          dbr = new DBRefEntry(DBRefSource.ENSEMBL, DBRefSource.UNIPROT
+                  + ":" + dbVersion, cdsId.trim());
+          dbRefs.add(dbr);
+
+        }
+      }
+
     }
 
     sequence.setPDBId(onlyPdbEntries);
@@ -233,7 +265,10 @@ public class Uniprot extends DbSourceProxyImpl
         sequence.addSequenceFeature(sf);
       }
     }
-    sequence.setDBRefs(dbRefs.toArray(new DBRefEntry[0]));
+    for (DBRefEntry dbr : dbRefs)
+    {
+      sequence.addDBRef(dbr);
+    }
     return sequence;
   }
 
index 1dff32f..5531512 100644 (file)
@@ -208,6 +208,7 @@ public class EBIFetchClient
       if (outFile != null)
       {
         FileOutputStream fio = new FileOutputStream(outFile);
+        // fio.write("<?xml version='1.0' encoding='UTF-8'?>\n".getBytes());
         byte[] bb = new byte[32 * 1024];
         int l;
         while ((l = is.read(bb)) > 0)
index a6a1de4..8e2e2fe 100644 (file)
@@ -26,6 +26,7 @@ import static org.testng.AssertJUnit.assertNull;
 import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.bin.Cache;
 import jalview.datamodel.Alignment;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
@@ -33,10 +34,12 @@ import jalview.datamodel.PDBEntry;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 import jalview.io.AppletFormatAdapter;
+import jalview.structure.StructureImportSettings;
 
 import java.io.IOException;
 import java.util.List;
 
+import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 public class PDBfileTest
@@ -307,4 +310,19 @@ public class PDBfileTest
     pf.addAnnotations(al);
     return al.getAlignmentAnnotation();
   }
+
+  //@formatter:on
+  
+  @BeforeMethod(alwaysRun = true)
+  public void setUp()
+  {
+    Cache.loadProperties("test/jalview/io/testProps.jvprops");
+    Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
+            Boolean.TRUE.toString());
+    Cache.applicationProperties.setProperty("ADD_TEMPFACT_ANN",
+            Boolean.TRUE.toString());
+    Cache.applicationProperties.setProperty("ADD_SS_ANN",
+            Boolean.TRUE.toString());
+    StructureImportSettings.setDefaultStructureFileFormat("PDB");
+  }
 }
index ddd38e7..b4628b8 100644 (file)
@@ -977,7 +977,7 @@ public class AlignmentUtilsTests
     /*
      * scenario:
      *     dna1 --> [4, 6] [10,12]        --> pep1 
-     *     dna2 --> [1, 3] [7, 9] [13,15] --> pep1 
+     *     dna2 --> [1, 3] [7, 9] [13,15] --> pep2
      */
     SequenceI dna1 = new Sequence("dna1", "aaaGGGcccTTTaaa");
     SequenceI dna2 = new Sequence("dna2", "GGGcccTTTaaaCCC");
@@ -993,6 +993,13 @@ public class AlignmentUtilsTests
     dna.setDataset(null);
 
     /*
+     * put a variant feature on dna2 base 8
+     * - should transfer to cds2 base 5
+     */
+    dna2.addSequenceFeature(new SequenceFeature("variant", "hgmd", 8, 8,
+            0f, null));
+
+    /*
      * need a sourceDbRef if we are to construct dbrefs to the CDS
      * sequence from the dna contig sequences
      */
@@ -1154,6 +1161,16 @@ public class AlignmentUtilsTests
     assertSame(cds2Dss, m.getSequence());
     assertEquals(7, m.getStart());
     assertEquals(9, m.getEnd());
+
+    /*
+     * check cds2 acquired a variant feature in position 5
+     */
+    SequenceFeature[] sfs = cds2Dss.getSequenceFeatures();
+    assertNotNull(sfs);
+    assertEquals(1, sfs.length);
+    assertEquals("variant", sfs[0].type);
+    assertEquals(5, sfs[0].begin);
+    assertEquals(5, sfs[0].end);
   }
 
   /**
index 24ddb34..759f527 100644 (file)
@@ -121,8 +121,9 @@ public class CrossRefTest
     seq.addDBRef(new DBRefEntry("ENSEMBLGENOMES", "0", "E2350"));
     sources = new CrossRef(new SequenceI[] { seq }, al)
             .findXrefSourcesForSequences(false);
-    assertEquals(4, sources.size());
-    assertEquals("[EMBL, EMBLCDS, GENEDB, ENSEMBL]", sources.toString());
+    // method is patched to remove EMBL from the sources to match
+    assertEquals(3, sources.size());
+    assertEquals("[EMBLCDS, GENEDB, ENSEMBL]", sources.toString());
 
     /*
      * add a sequence to the alignment which has a dbref to UNIPROT|A1234
@@ -140,8 +141,9 @@ public class CrossRefTest
     al.addSequence(seq2);
     sources = new CrossRef(new SequenceI[] { seq, seq2 }, al)
             .findXrefSourcesForSequences(false);
-    assertEquals(3, sources.size());
-    assertEquals("[EMBLCDS, EMBL, GENEDB]", sources.toString());
+    // method removed EMBL from sources to match
+    assertEquals(2, sources.size());
+    assertEquals("[EMBLCDS, GENEDB]", sources.toString());
   }
 
   /**
@@ -402,11 +404,14 @@ public class CrossRefTest
   public void testFindXrefSequences_withFetch()
   {
     SequenceI dna1 = new Sequence("AF039662", "GGGGCAGCACAAGAAC");
-    dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2"));
-    dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "P30419"));
-    dna1.addDBRef(new DBRefEntry("UNIPROT", "0", "P00314"));
+    dna1.addDBRef(new DBRefEntry("UNIPROT", "ENA:0", "Q9ZTS2"));
+    dna1.addDBRef(new DBRefEntry("UNIPROT", "ENA:0", "P30419"));
+    dna1.addDBRef(new DBRefEntry("UNIPROT", "ENA:0", "P00314"));
     final SequenceI pep1 = new Sequence("Q9ZTS2", "MYQLIRSSW");
+    pep1.addDBRef(new DBRefEntry("UNIPROT", "0", "Q9ZTS2"));
+
     final SequenceI pep2 = new Sequence("P00314", "MRKLLAASG");
+    pep2.addDBRef(new DBRefEntry("UNIPROT", "0", "P00314"));
 
     /*
      * argument false suppresses adding DAS sources
@@ -471,7 +476,7 @@ public class CrossRefTest
      * 'spliced transcript' with CDS ranges
      */
     SequenceI braf002 = new Sequence("ENST00000497784", "gCAGGCtaTCTGTTCaa");
-    braf002.addDBRef(new DBRefEntry("UNIPROT", "0", "H7C5K3"));
+    braf002.addDBRef(new DBRefEntry("UNIPROT", "ENSEMBL|0", "H7C5K3"));
     braf002.addSequenceFeature(new SequenceFeature("CDS", "", 2, 6, 0f,
             null));
     braf002.addSequenceFeature(new SequenceFeature("CDS", "", 9, 15, 0f,
@@ -483,8 +488,9 @@ public class CrossRefTest
      * which happens to be true for Uniprot,PDB,EMBL but not Pfam,Rfam,Ensembl 
      */
     final SequenceI pep1 = new Sequence("UNIPROT|P15056", "MAAL");
+    pep1.addDBRef(new DBRefEntry("UNIPROT", "0", "P15056"));
     final SequenceI pep2 = new Sequence("UNIPROT|H7C5K3", "QALF");
-
+    pep2.addDBRef(new DBRefEntry("UNIPROT", "0", "H7C5K3"));
     /*
      * argument false suppresses adding DAS sources
      * todo: define an interface type SequenceFetcherI and mock that
@@ -620,7 +626,7 @@ public class CrossRefTest
      */
     final SequenceI x07547 = new Sequence("EMBL|X07547", "cccAAACCCTTTGGG");
     DBRefEntry dbref7 = new DBRefEntry("UNIPROT", "0", "P0CE20");
-    dbref7.setMap(new Mapping(new Sequence("UNIPROT|P0CE19", "KPFG"),
+    dbref7.setMap(new Mapping(new Sequence("UNIPROT|P0CE20", "PFGK"),
             new MapList(map2)));
     x07547.addDBRef(dbref7);
     DBRefEntry dbref8 = new DBRefEntry("UNIPROT", "0", "B0BCM4");
index f33525f..f96d2c9 100644 (file)
@@ -188,6 +188,33 @@ public class RnaTest
     }
   }
 
+  @Test(groups = { "Functional" })
+  public void testIsCanonicalPair()
+  {
+    String bases = "acgtuACGTU";
+    for (int i = 0; i < bases.length(); i++)
+    {
+      for (int j = 0; j < bases.length(); j++)
+      {
+        char first = bases.charAt(i);
+        char second = bases.charAt(j);
+        boolean result = Rna.isCanonicalPair(first, second);
+        String pair = new String(new char[] { first, second })
+                .toUpperCase();
+        if (pair.equals("AT") || pair.equals("TA") || pair.equals("AU")
+                || pair.equals("UA") || pair.equals("GC")
+                || pair.equals("CG"))
+        {
+          assertTrue(pair + " should be valid", result);
+        }
+        else
+        {
+          assertFalse(pair + " should be invalid", result);
+        }
+      }
+    }
+  }
+
   /**
    * Tests for isOpeningParenthesis with char or String argument
    */
index 9afae37..7fb80fb 100644 (file)
@@ -239,7 +239,7 @@ public class EditCommandTest
   public void testReplace()
   {
     // seem to need a dataset sequence on the edited sequence here
-    seqs[1].setDatasetSequence(seqs[1]);
+    seqs[1].createDatasetSequence();
     new EditCommand("", Action.REPLACE, "ZXY", new SequenceI[] { seqs[1] },
             4, 8, al);
     assertEquals("abcdefghjk", seqs[0].getSequenceAsString());
index 7ad9436..fcf724a 100644 (file)
@@ -1042,4 +1042,67 @@ public class AlignmentTest
     assertEquals(23, startEnd[1]);
   }
 
+  /**
+   * Tests that dbrefs with mappings to sequence get updated if the sequence
+   * acquires a dataset sequence
+   */
+  @Test(groups = "Functional")
+  public void testCreateDataset_updateDbrefMappings()
+  {
+    SequenceI pep = new Sequence("pep", "ASD");
+    SequenceI dna = new Sequence("dna", "aaaGCCTCGGATggg");
+    SequenceI cds = new Sequence("cds", "GCCTCGGAT");
+  
+    // add dbref from dna to peptide
+    DBRefEntry dbr = new DBRefEntry("UNIPROT", "", "pep");
+    dbr.setMap(new Mapping(pep, new MapList(new int[] { 4, 15 }, new int[] {
+        1, 4 }, 3, 1)));
+    dna.addDBRef(dbr);
+
+    // add dbref from dna to peptide
+    DBRefEntry dbr2 = new DBRefEntry("UNIPROT", "", "pep");
+    dbr2.setMap(new Mapping(pep, new MapList(new int[] { 1, 12 }, new int[]
+    { 1, 4 }, 3, 1)));
+    cds.addDBRef(dbr2);
+
+    // add dbref from peptide to dna
+    DBRefEntry dbr3 = new DBRefEntry("EMBL", "", "dna");
+    dbr3.setMap(new Mapping(dna, new MapList(new int[] { 1, 4 }, new int[] {
+        4, 15 }, 1, 3)));
+    pep.addDBRef(dbr3);
+
+    // add dbref from peptide to cds
+    DBRefEntry dbr4 = new DBRefEntry("EMBLCDS", "", "cds");
+    dbr4.setMap(new Mapping(cds, new MapList(new int[] { 1, 4 }, new int[] {
+        1, 12 }, 1, 3)));
+    pep.addDBRef(dbr4);
+
+    AlignmentI protein = new Alignment(new SequenceI[] { pep });
+  
+    /*
+     * create the alignment dataset
+     */
+    ((Alignment) protein).createDatasetAlignment();
+  
+    AlignmentI ds = protein.getDataset();
+  
+    // should be 3 sequences in dataset
+    assertEquals(3, ds.getHeight());
+    assertTrue(ds.getSequences().contains(pep.getDatasetSequence()));
+    assertTrue(ds.getSequences().contains(dna));
+    assertTrue(ds.getSequences().contains(cds));
+
+    /*
+     * verify peptide.cdsdbref.peptidedbref is now mapped to peptide dataset
+     */
+    DBRefEntry[] dbRefs = pep.getDBRefs();
+    assertEquals(2, dbRefs.length);
+    assertSame(dna, dbRefs[0].map.to);
+    assertSame(cds, dbRefs[1].map.to);
+    assertEquals(1, dna.getDBRefs().length);
+    assertSame(pep.getDatasetSequence(), dna.getDBRefs()[0].map.to);
+    assertEquals(1, cds.getDBRefs().length);
+    assertSame(pep.getDatasetSequence(), cds.getDBRefs()[0].map.to);
+  }
+
 }
index e59719c..a943e7c 100644 (file)
@@ -22,12 +22,14 @@ package jalview.datamodel;
 
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
-import static org.testng.AssertJUnit.assertNotSame;
 import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.AssertJUnit.fail;
 
 import java.util.Arrays;
 import java.util.BitSet;
+import java.util.Collections;
+import java.util.ConcurrentModificationException;
 import java.util.List;
 
 import org.testng.annotations.Test;
@@ -68,8 +70,8 @@ public class ColumnSelectionTest
 
     // removing an element in the list removes it
     cs.removeElement(2);
-    // ...but not from the copy list!
-    assertEquals(2, sel.size());
+    // ...and also from the read-only view
+    assertEquals(1, sel.size());
     sel = cs.getSelected();
     assertEquals(1, sel.size());
     assertEquals(new Integer(5), sel.get(0));
@@ -542,7 +544,7 @@ public class ColumnSelectionTest
    * were added
    */
   @Test(groups = { "Functional" })
-  public void testGetSelection()
+  public void testGetSelected()
   {
     ColumnSelection cs = new ColumnSelection();
     int[] sel = { 4, 3, 7, 21 };
@@ -551,32 +553,90 @@ public class ColumnSelectionTest
       cs.addElement(col);
     }
 
-    List<Integer> selected1 = cs.getSelected();
-    assertEquals(4, selected1.size());
+    List<Integer> selected = cs.getSelected();
+    assertEquals(4, selected.size());
+    assertEquals("[4, 3, 7, 21]", selected.toString());
 
     /*
-     * getSelected returns a copy, verify the list
-     * is externally immutable
+     * getSelected returns a read-only view of the list
+     * verify the view follows any changes in it
      */
-    selected1.clear();
-    List<Integer> selected2 = cs.getSelected();
-    assertNotSame(selected1, selected2);
-    assertEquals(4, selected2.size());
-    int i = 0;
-    for (int col : sel)
+    cs.removeElement(7);
+    cs.addElement(1);
+    cs.removeElement(4);
+    assertEquals("[3, 21, 1]", selected.toString());
+  }
+
+  /**
+   * Test to verify that the list returned by getSelection cannot be modified
+   */
+  @Test(groups = { "Functional" })
+  public void testGetSelected_isReadOnly()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(3);
+
+    List<Integer> selected = cs.getSelected();
+    try
+    {
+      selected.clear();
+      fail("expected exception");
+    } catch (UnsupportedOperationException e)
+    {
+      // expected
+    }
+    try
+    {
+      selected.add(1);
+      fail("expected exception");
+    } catch (UnsupportedOperationException e)
+    {
+      // expected
+    }
+    try
+    {
+      selected.remove(3);
+      fail("expected exception");
+    } catch (UnsupportedOperationException e)
     {
-      assertEquals(col, selected2.get(i++).intValue());
+      // expected
     }
+    try
+    {
+      Collections.sort(selected);
+      fail("expected exception");
+    } catch (UnsupportedOperationException e)
+    {
+      // expected
+    }
+  }
 
-    cs.removeElement(7);
+  /**
+   * Test that demonstrates a ConcurrentModificationException is thrown if you
+   * change the selection while iterating over it
+   */
+  @Test(
+    groups = "Functional",
+    expectedExceptions = { ConcurrentModificationException.class })
+  public void testGetSelected_concurrentModification()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(0);
     cs.addElement(1);
-    cs.removeElement(4);
+    cs.addElement(2);
 
-    List<Integer> selected3 = cs.getSelected();
-    assertEquals(3, selected3.size());
-    assertEquals(3, selected3.get(0).intValue());
-    assertEquals(21, selected3.get(1).intValue());
-    assertEquals(1, selected3.get(2).intValue());
+    /*
+     * simulate changing the list under us (e.g. in a separate
+     * thread) while iterating over it -> ConcurrentModificationException
+     */
+    List<Integer> selected = cs.getSelected();
+    for (Integer col : selected)
+    {
+      if (col.intValue() == 0)
+      {
+        cs.removeElement(1);
+      }
+    }
   }
 
   @Test(groups = "Functional")
@@ -669,4 +729,25 @@ public class ColumnSelectionTest
     assertTrue(selected.contains(6));
     assertTrue(selected.contains(10));
   }
+
+  @Test(groups = "Functional")
+  public void testCopyConstructor()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(3);
+    cs.addElement(1);
+    cs.hideColumns(10, 11);
+    cs.hideColumns(5, 7);
+    assertEquals("[5, 7]", Arrays.toString(cs.getHiddenColumns().get(0)));
+
+    ColumnSelection cs2 = new ColumnSelection(cs);
+    assertTrue(cs2.hasSelectedColumns());
+    assertTrue(cs2.hasHiddenColumns());
+    // order of column selection is preserved
+    assertEquals("[3, 1]", cs2.getSelected().toString());
+    assertEquals(2, cs2.getHiddenColumns().size());
+    // hidden columns are held in column order
+    assertEquals("[5, 7]", Arrays.toString(cs2.getHiddenColumns().get(0)));
+    assertEquals("[10, 11]", Arrays.toString(cs2.getHiddenColumns().get(1)));
+  }
 }
index df29437..e9d5cb2 100644 (file)
@@ -1,4 +1,5 @@
 /*
+    assertEquals(case7, case9);
  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
  * Copyright (C) $$Year-Rel$$ The Jalview Authors
  * 
@@ -23,7 +24,13 @@ package jalview.datamodel;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNotSame;
 import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertSame;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import jalview.datamodel.PDBEntry.Type;
 
 //import org.testng.Assert;
 import org.testng.annotations.AfterMethod;
@@ -49,23 +56,34 @@ public class PDBEntryTest
     PDBEntry pdbEntry = new PDBEntry("1xyz", "A", PDBEntry.Type.PDB,
             "x/y/z/File");
 
+    // id comparison is not case sensitive
     PDBEntry case1 = new PDBEntry("1XYZ", "A", PDBEntry.Type.PDB,
             "x/y/z/File");
+    // chain code comparison is not case sensitive
     PDBEntry case2 = new PDBEntry("1xyz", "a", PDBEntry.Type.PDB,
             "x/y/z/File");
+    // different type
     PDBEntry case3 = new PDBEntry("1xyz", "A", PDBEntry.Type.FILE,
             "x/y/z/File");
+    // different everything
     PDBEntry case4 = new PDBEntry(null, null, null, null);
+    // null id
     PDBEntry case5 = new PDBEntry(null, "A", PDBEntry.Type.PDB,
             "x/y/z/File");
+    // null chain
     PDBEntry case6 = new PDBEntry("1xyz", null, PDBEntry.Type.PDB,
             "x/y/z/File");
+    // null type
     PDBEntry case7 = new PDBEntry("1xyz", "A", null, "x/y/z/File");
+    // null file
     PDBEntry case8 = new PDBEntry("1xyz", "A", PDBEntry.Type.PDB, null);
+    // identical to case7
     PDBEntry case9 = new PDBEntry("1xyz", "A", null, "x/y/z/File");
+    // different file only
+    PDBEntry case10 = new PDBEntry("1xyz", "A", null, "a/b/c/File");
 
     /*
-     * assertions will invoke PDBEntry.equals()
+     * assertEquals will invoke PDBEntry.equals()
      */
     assertFalse(pdbEntry.equals(null));
     assertFalse(pdbEntry.equals("a"));
@@ -76,8 +94,17 @@ public class PDBEntryTest
     assertNotEquals(case5, pdbEntry);
     assertNotEquals(case6, pdbEntry);
     assertNotEquals(case7, pdbEntry);
-    assertEquals(case8, pdbEntry);
+    assertNotEquals(case8, pdbEntry);
     assertEquals(case7, case9);
+    assertNotEquals(case9, case10);
+
+    // add properties
+    case7.setProperty("hello", "world");
+    assertNotEquals(case7, case9);
+    case9.setProperty("hello", "world");
+    assertEquals(case7, case9);
+    case9.setProperty("hello", "WORLD");
+    assertNotEquals(case7, case9);
 
     /*
      * change string wrapper property to string...
@@ -100,4 +127,175 @@ public class PDBEntryTest
     pdbEntry.setChainCode(null);
     assertNull(pdbEntry.getChainCode());
   }
+
+  @Test(groups = { "Functional" })
+  public void testGetType()
+  {
+    assertSame(PDBEntry.Type.FILE, PDBEntry.Type.getType("FILE"));
+    assertSame(PDBEntry.Type.FILE, PDBEntry.Type.getType("File"));
+    assertSame(PDBEntry.Type.FILE, PDBEntry.Type.getType("file"));
+    assertNotSame(PDBEntry.Type.FILE, PDBEntry.Type.getType("file "));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testTypeMatches()
+  {
+    // TODO Type.matches() is not used - delete?
+    assertTrue(PDBEntry.Type.FILE.matches("FILE"));
+    assertTrue(PDBEntry.Type.FILE.matches("File"));
+    assertTrue(PDBEntry.Type.FILE.matches("file"));
+    assertFalse(PDBEntry.Type.FILE.matches("FILE "));
+  }
+
+  @Test(groups = { "Functional" })
+  public void testUpdateFrom()
+  {
+    PDBEntry pdb1 = new PDBEntry("3A6S", null, null, null);
+    PDBEntry pdb2 = new PDBEntry("3A6S", null, null, null);
+    assertTrue(pdb1.updateFrom(pdb2));
+
+    /*
+     * mismatch of pdb id not allowed
+     */
+    pdb2 = new PDBEntry("1A70", "A", null, null);
+    assertFalse(pdb1.updateFrom(pdb2));
+    assertNull(pdb1.getChainCode());
+
+    /*
+     * match of pdb id is not case sensitive
+     */
+    pdb2 = new PDBEntry("3a6s", "A", null, null);
+    assertTrue(pdb1.updateFrom(pdb2));
+    assertEquals(pdb1.getChainCode(), "A");
+    assertEquals(pdb1.getId(), "3A6S");
+
+    /*
+     * add chain - with differing case for id
+     */
+    pdb1 = new PDBEntry("3A6S", null, null, null);
+    pdb2 = new PDBEntry("3a6s", "A", null, null);
+    assertTrue(pdb1.updateFrom(pdb2));
+    assertEquals(pdb1.getChainCode(), "A");
+
+    /*
+     * change of chain is not allowed
+     */
+    pdb2 = new PDBEntry("3A6S", "B", null, null);
+    assertFalse(pdb1.updateFrom(pdb2));
+    assertEquals(pdb1.getChainCode(), "A");
+
+    /*
+     * change chain from null
+     */
+    pdb1 = new PDBEntry("3A6S", null, null, null);
+    pdb2 = new PDBEntry("3A6S", "B", null, null);
+    assertTrue(pdb1.updateFrom(pdb2));
+    assertEquals(pdb1.getChainCode(), "B");
+
+    /*
+     * set file and type
+     */
+    pdb2 = new PDBEntry("3A6S", "B", Type.FILE, "filePath");
+    assertTrue(pdb1.updateFrom(pdb2));
+    assertEquals(pdb1.getFile(), "filePath");
+    assertEquals(pdb1.getType(), Type.FILE.toString());
+
+    /*
+     * change of file is not allowed
+     */
+    pdb1 = new PDBEntry("3A6S", null, null, "file1");
+    pdb2 = new PDBEntry("3A6S", "A", null, "file2");
+    assertFalse(pdb1.updateFrom(pdb2));
+    assertNull(pdb1.getChainCode());
+    assertEquals(pdb1.getFile(), "file1");
+
+    /*
+     * set type without change of file
+     */
+    pdb1 = new PDBEntry("3A6S", null, null, "file1");
+    pdb2 = new PDBEntry("3A6S", null, Type.PDB, "file1");
+    assertTrue(pdb1.updateFrom(pdb2));
+    assertEquals(pdb1.getType(), Type.PDB.toString());
+
+    /*
+     * set file with differing case of id and chain code
+     */
+    pdb1 = new PDBEntry("3A6S", "A", null, null);
+    pdb2 = new PDBEntry("3a6s", "a", Type.PDB, "file1");
+    assertTrue(pdb1.updateFrom(pdb2));
+    assertEquals(pdb1.getType(), Type.PDB.toString());
+    assertEquals(pdb1.getId(), "3A6S"); // unchanged
+    assertEquals(pdb1.getFile(), "file1"); // updated
+    assertEquals(pdb1.getChainCode(), "A"); // unchanged
+
+    /*
+     * changing nothing returns true
+     */
+    pdb1 = new PDBEntry("3A6S", "A", Type.PDB, "file1");
+    pdb2 = new PDBEntry("3A6S", null, null, null);
+    assertTrue(pdb1.updateFrom(pdb2));
+    assertEquals(pdb1.getChainCode(), "A");
+    assertEquals(pdb1.getType(), Type.PDB.toString());
+    assertEquals(pdb1.getFile(), "file1");
+
+    /*
+     * add and update properties only
+     */
+    pdb1 = new PDBEntry("3A6S", null, null, null);
+    pdb2 = new PDBEntry("3A6S", null, null, null);
+    pdb1.setProperty("destination", "mars");
+    pdb1.setProperty("hello", "world");
+    pdb2.setProperty("hello", "moon");
+    pdb2.setProperty("goodbye", "world");
+    assertTrue(pdb1.updateFrom(pdb2));
+    assertEquals(pdb1.getProperty("destination"), "mars");
+    assertEquals(pdb1.getProperty("hello"), "moon");
+    assertEquals(pdb1.getProperty("goodbye"), "world");
+
+    /*
+     * add properties only
+     */
+    pdb1 = new PDBEntry("3A6S", null, null, null);
+    pdb2 = new PDBEntry("3A6S", null, null, null);
+    pdb2.setProperty("hello", "moon");
+    assertTrue(pdb1.updateFrom(pdb2));
+    assertEquals(pdb1.getProperty("hello"), "moon");
+  }
+
+  @Test(groups = { "Functional" })
+  public void testConstructor_fromDbref()
+  {
+    PDBEntry pdb = new PDBEntry(new DBRefEntry("PDB", "0", "1A70"));
+    assertEquals(pdb.getId(), "1A70");
+    assertNull(pdb.getChainCode());
+    assertNull(pdb.getType());
+    assertNull(pdb.getFile());
+
+    /*
+     * from dbref with chain code appended
+     */
+    pdb = new PDBEntry(new DBRefEntry("PDB", "0", "1A70B"));
+    assertEquals(pdb.getId(), "1A70");
+    assertEquals(pdb.getChainCode(), "B");
+
+    /*
+     * from dbref with overlong accession
+     */
+    pdb = new PDBEntry(new DBRefEntry("PDB", "0", "1A70BC"));
+    assertEquals(pdb.getId(), "1A70BC");
+    assertNull(pdb.getChainCode());
+
+    /*
+     * from dbref which is not for PDB
+     */
+    try
+    {
+      pdb = new PDBEntry(new DBRefEntry("PDBe", "0", "1A70"));
+      fail("Expected exception");
+    } catch (IllegalArgumentException e)
+    {
+      // expected;
+    }
+  }
+
 }
index c7e53a9..25804bc 100644 (file)
@@ -366,7 +366,16 @@ public class SequenceTest
      * is there a usecase for this ? setDatasetSequence should throw an error if
      * this actually occurs.
      */
-    sq.getDatasetSequence().setDatasetSequence(sq); // loop!
+    try
+    {
+      sq.getDatasetSequence().setDatasetSequence(sq); // loop!
+      Assert.fail("Expected Error to be raised when calling setDatasetSequence with self reference");
+    } catch (IllegalArgumentException e)
+    {
+      // TODO Jalview error/exception class for raising implementation errors
+      assertTrue(e.getMessage().toLowerCase()
+              .contains("implementation error"));
+    }
     assertNull(sq.getSequenceFeatures());
   }
 
@@ -451,19 +460,20 @@ public class SequenceTest
     sq.addPDBId(new PDBEntry("2PDB", "A", Type.MMCIF, "filePath/test2"));
     sq.addPDBId(new PDBEntry("2PDB", "B", Type.MMCIF, "filePath/test2"));
     
+    // these are the same as ones already added
     DBRefEntry pdb1pdb = new DBRefEntry("PDB", "version1", "1PDB");
-    DBRefEntry pdb2pdb = new DBRefEntry("PDB", "version1", "2PDB");
+    DBRefEntry pdb2pdb = new DBRefEntry("PDB", "version2", "2PDB");
 
     
     List<DBRefEntry> primRefs = Arrays.asList(new DBRefEntry[] { pdb1pdb,
         pdb2pdb });
 
-    sq.getDatasetSequence().addDBRef(pdb1pdb);
-    sq.getDatasetSequence().addDBRef(pdb2pdb);
+    sq.getDatasetSequence().addDBRef(pdb1pdb); // should do nothing
+    sq.getDatasetSequence().addDBRef(pdb2pdb); // should do nothing
     sq.getDatasetSequence().addDBRef(
-            new DBRefEntry("PDB", "version3", "3PDB"));
+            new DBRefEntry("PDB", "version3", "3PDB")); // should do nothing
     sq.getDatasetSequence().addDBRef(
-            new DBRefEntry("PDB", "version4", "4PDB"));
+            new DBRefEntry("PDB", "version4", "4PDB")); // should do nothing
     
     PDBEntry pdbe1a=new PDBEntry("1PDB", "A", Type.PDB, "filePath/test1");
     PDBEntry pdbe1b = new PDBEntry("1PDB", "B", Type.PDB, "filePath/test1");
@@ -500,11 +510,14 @@ public class SequenceTest
             new AlignmentAnnotation("Test annot", "Test annot description",
                     annots));
     Assert.assertEquals(sq.getDescription(), "Test sequence description..");
-    Assert.assertEquals(sq.getDBRefs().length, 5);
+    Assert.assertEquals(sq.getDBRefs().length, 5); // DBRefs are on dataset
+                                                   // sequence
     Assert.assertEquals(sq.getAllPDBEntries().size(), 4);
     Assert.assertNotNull(sq.getAnnotation());
     Assert.assertEquals(sq.getAnnotation()[0].annotations.length, 2);
-    Assert.assertEquals(sq.getDatasetSequence().getDBRefs().length, 4);
+    Assert.assertEquals(sq.getDatasetSequence().getDBRefs().length, 5); // same
+                                                                        // as
+                                                                        // sq.getDBRefs()
     Assert.assertEquals(sq.getDatasetSequence().getAllPDBEntries().size(),
             4);
     Assert.assertNotNull(sq.getDatasetSequence().getAnnotation());
@@ -513,11 +526,11 @@ public class SequenceTest
 
     Assert.assertEquals(derived.getDescription(),
             "Test sequence description..");
-    Assert.assertEquals(derived.getDBRefs().length, 4); // come from dataset
+    Assert.assertEquals(derived.getDBRefs().length, 5); // come from dataset
     Assert.assertEquals(derived.getAllPDBEntries().size(), 4);
     Assert.assertNotNull(derived.getAnnotation());
     Assert.assertEquals(derived.getAnnotation()[0].annotations.length, 2);
-    Assert.assertEquals(derived.getDatasetSequence().getDBRefs().length, 4);
+    Assert.assertEquals(derived.getDatasetSequence().getDBRefs().length, 5);
     Assert.assertEquals(derived.getDatasetSequence().getAllPDBEntries()
             .size(), 4);
     Assert.assertNotNull(derived.getDatasetSequence().getAnnotation());
@@ -884,4 +897,105 @@ public class SequenceTest
     assertTrue(primaryDBRefs.contains(dbr1));
     assertTrue(primaryDBRefs.contains(dbr3));
   }
+
+  /**
+   * Test the method that updates the list of PDBEntry from any new DBRefEntry
+   * for PDB
+   */
+  @Test(groups = { "Functional" })
+  public void testUpdatePDBIds()
+  {
+    PDBEntry pdbe1 = new PDBEntry("3A6S", null, null, null);
+    seq.addPDBId(pdbe1);
+    seq.addDBRef(new DBRefEntry("Ensembl", "8", "ENST1234"));
+    seq.addDBRef(new DBRefEntry("PDB", "0", "1A70"));
+    seq.addDBRef(new DBRefEntry("PDB", "0", "4BQGa"));
+    seq.addDBRef(new DBRefEntry("PDB", "0", "3a6sB"));
+    // 7 is not a valid chain code:
+    seq.addDBRef(new DBRefEntry("PDB", "0", "2GIS7"));
+    
+    seq.updatePDBIds();
+    List<PDBEntry> pdbIds = seq.getAllPDBEntries();
+    assertEquals(4, pdbIds.size());
+    assertSame(pdbe1, pdbIds.get(0));
+    // chain code got added to 3A6S:
+    assertEquals("B", pdbe1.getChainCode());
+    assertEquals("1A70", pdbIds.get(1).getId());
+    // 4BQGA is parsed into id + chain
+    assertEquals("4BQG", pdbIds.get(2).getId());
+    assertEquals("a", pdbIds.get(2).getChainCode());
+    assertEquals("2GIS7", pdbIds.get(3).getId());
+    assertNull(pdbIds.get(3).getChainCode());
+  }
+
+  /**
+   * Test the method that either adds a pdbid or updates an existing one
+   */
+  @Test(groups = { "Functional" })
+  public void testAddPDBId()
+  {
+    PDBEntry pdbe = new PDBEntry("3A6S", null, null, null);
+    seq.addPDBId(pdbe);
+    assertEquals(1, seq.getAllPDBEntries().size());
+    assertSame(pdbe, seq.getPDBEntry("3A6S"));
+    assertSame(pdbe, seq.getPDBEntry("3a6s")); // case-insensitive
+
+    // add the same entry
+    seq.addPDBId(pdbe);
+    assertEquals(1, seq.getAllPDBEntries().size());
+    assertSame(pdbe, seq.getPDBEntry("3A6S"));
+
+    // add an identical entry
+    seq.addPDBId(new PDBEntry("3A6S", null, null, null));
+    assertEquals(1, seq.getAllPDBEntries().size());
+    assertSame(pdbe, seq.getPDBEntry("3A6S"));
+
+    // add a different entry
+    PDBEntry pdbe2 = new PDBEntry("1A70", null, null, null);
+    seq.addPDBId(pdbe2);
+    assertEquals(2, seq.getAllPDBEntries().size());
+    assertSame(pdbe, seq.getAllPDBEntries().get(0));
+    assertSame(pdbe2, seq.getAllPDBEntries().get(1));
+
+    // update pdbe with chain code, file, type
+    PDBEntry pdbe3 = new PDBEntry("3a6s", "A", Type.PDB, "filepath");
+    seq.addPDBId(pdbe3);
+    assertEquals(2, seq.getAllPDBEntries().size());
+    assertSame(pdbe, seq.getAllPDBEntries().get(0)); // updated in situ
+    assertEquals("3A6S", pdbe.getId()); // unchanged
+    assertEquals("A", pdbe.getChainCode()); // updated
+    assertEquals(Type.PDB.toString(), pdbe.getType()); // updated
+    assertEquals("filepath", pdbe.getFile()); // updated
+    assertSame(pdbe2, seq.getAllPDBEntries().get(1));
+
+    // add with a different file path
+    PDBEntry pdbe4 = new PDBEntry("3a6s", "A", Type.PDB, "filepath2");
+    seq.addPDBId(pdbe4);
+    assertEquals(3, seq.getAllPDBEntries().size());
+    assertSame(pdbe4, seq.getAllPDBEntries().get(2));
+
+    // add with a different chain code
+    PDBEntry pdbe5 = new PDBEntry("3a6s", "B", Type.PDB, "filepath");
+    seq.addPDBId(pdbe5);
+    assertEquals(4, seq.getAllPDBEntries().size());
+    assertSame(pdbe5, seq.getAllPDBEntries().get(3));
+  }
+
+  @Test(
+    groups = { "Functional" },
+    expectedExceptions = { IllegalArgumentException.class })
+  public void testSetDatasetSequence_toSelf()
+  {
+    seq.setDatasetSequence(seq);
+  }
+
+  @Test(
+    groups = { "Functional" },
+    expectedExceptions = { IllegalArgumentException.class })
+  public void testSetDatasetSequence_cascading()
+  {
+    SequenceI seq2 = new Sequence("Seq2", "xyz");
+    seq2.createDatasetSequence();
+    seq.setDatasetSequence(seq2);
+  }
 }
index abe5099..f332fa6 100644 (file)
@@ -1,6 +1,7 @@
 package jalview.datamodel.xdb.embl;
 
 import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
 import static org.testng.AssertJUnit.assertNull;
 import static org.testng.AssertJUnit.assertSame;
 
@@ -40,20 +41,21 @@ public class EmblEntryTest
     // not the whole sequence but enough for this test...
     List<SequenceI> peptides = new ArrayList<SequenceI>();
     SequenceIdMatcher matcher = new SequenceIdMatcher(peptides);
-    EmblFile ef = EmblTestHelper.getEmblFile();
-    assertEquals(1, ef.getEntries().size());
-    EmblEntry testee = ef.getEntries().get(0);
+    EmblEntry ef = EmblTestHelper.getEmblFile();
+    assertNotNull(ef);
+    // assertEquals(1, ef.getEntries().size());
+    // EmblEntry testee = ef.getEntries().get(0);
     String sourceDb = "EMBL";
-    SequenceI dna = testee.makeSequence(sourceDb);
+    SequenceI dna = ef.makeSequence(sourceDb);
 
     /*
      * parse three CDS features, with two/one/no Uniprot cross-refs
      */
-    for (EmblFeature feature : ef.getEntries().get(0).getFeatures())
+    for (EmblFeature feature : ef.getFeatures())
     {
       if ("CDS".equals(feature.getName()))
       {
-        testee.parseCodingFeature(feature, sourceDb, dna, peptides, matcher);
+        ef.parseCodingFeature(feature, sourceDb, dna, peptides, matcher);
       }
     }
 
index 906436f..6afdced 100644 (file)
 package jalview.datamodel.xdb.embl;
 
 import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
 import static org.testng.AssertJUnit.assertNull;
 
 import jalview.datamodel.DBRefEntry;
 
-import java.util.Vector;
-
 import org.testng.annotations.Test;
 
 public class EmblFileTest
@@ -35,9 +34,10 @@ public class EmblFileTest
   @Test(groups = { "Functional" })
   public void testGetEmblFile()
   {
-    Vector<EmblEntry> entries = EmblTestHelper.getEmblFile().getEntries();
-    assertEquals(1, entries.size());
-    EmblEntry entry = entries.get(0);
+    EmblEntry entry = EmblTestHelper.getEmblFile();
+    assertNotNull(entry);
+    // assertEquals(1, entries.size());
+    // EmblEntry entry = entries.get(0);
 
     assertEquals("X07547", entry.getAccession());
     assertEquals("C. trachomatis plasmid", entry.getDescription());
index 6349164..a79bdb8 100644 (file)
@@ -7,7 +7,7 @@ public class EmblTestHelper
   // adapted from http://www.ebi.ac.uk/ena/data/view/X07547&display=xml
   // dna and translations truncated for convenience
   private static final String TESTDATA = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"
-          + "<ROOT>"
+          // + "<ROOT>"
           + "<entry accession=\"X07547\" version=\"1\" entryVersion=\"8\""
           + " dataClass=\"STD\" taxonomicDivision=\"PRO\""
           + " moleculeType=\"genomic DNA\" sequenceLength=\"7499\" topology=\"linear\""
@@ -52,10 +52,10 @@ public class EmblTestHelper
            */
           + "<sequence>GGTATGTCCTCTAGTACAAAC\n"
           + "ACCCCCAATATTGTGATATAATTAAAAACATAGCAT"
-          + "</sequence></entry></ROOT>";
+ + "</sequence></entry>";
 
-  static EmblFile getEmblFile()
+  static EmblEntry getEmblFile()
   {
-    return EmblFile.getEmblFile(new StringReader(TESTDATA));
+    return EmblFile.getEntry(new StringReader(TESTDATA));
   }
 }
index 7ab058e..f728d63 100644 (file)
@@ -86,8 +86,11 @@ public class JmolParserTest
   @BeforeMethod(alwaysRun = true)
   public void setUp()
   {
+    Cache.loadProperties("test/jalview/io/testProps.jvprops");
     Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
             Boolean.TRUE.toString());
+    Cache.applicationProperties.setProperty("ADD_TEMPFACT_ANN",
+            Boolean.FALSE.toString());
     Cache.applicationProperties.setProperty("ADD_SS_ANN",
             Boolean.TRUE.toString());
     StructureImportSettings.setDefaultStructureFileFormat("PDB");
@@ -114,8 +117,7 @@ public class JmolParserTest
     {
       PDBfile mctest = new PDBfile(false, false, false, pdbStr,
               AppletFormatAdapter.FILE);
-      JmolParser jtest = new JmolParser(false, false, false, pdbStr,
-              jalview.io.AppletFormatAdapter.FILE);
+      JmolParser jtest = new JmolParser(pdbStr, AppletFormatAdapter.FILE);
       Vector<SequenceI> seqs = jtest.getSeqs(), mcseqs = mctest.getSeqs();
 
       assertTrue(
@@ -163,7 +165,8 @@ public class JmolParserTest
 
   private void checkFirstAAIsAssoc(SequenceI sq)
   {
-    assertTrue("No secondary structure assigned for protein sequence.",
+    assertTrue("No secondary structure assigned for protein sequence for "
+            + sq.getName(),
             sq.getAnnotation() != null && sq.getAnnotation().length >= 1
                     && sq.getAnnotation()[0].hasIcons);
     assertTrue(
@@ -182,13 +185,8 @@ public class JmolParserTest
     PDBfile mctest = new PDBfile(false, false, false,
             pastePDBDataWithChainBreak,
             AppletFormatAdapter.PASTE);
-    boolean annotFromStructure = false;
-    boolean localSecondaryStruct = false;
-    boolean serviceSecondaryStruct = false;
-    JmolParser jtest = new JmolParser(annotFromStructure,
-            localSecondaryStruct, serviceSecondaryStruct,
-            pastePDBDataWithChainBreak,
-            jalview.io.AppletFormatAdapter.PASTE);
+    JmolParser jtest = new JmolParser(pastePDBDataWithChainBreak,
+            AppletFormatAdapter.PASTE);
     Vector<SequenceI> seqs = jtest.getSeqs();
     Vector<SequenceI> mcseqs = mctest.getSeqs();
 
@@ -210,12 +208,8 @@ public class JmolParserTest
   {
     PDBfile mctest = new PDBfile(false, false, false, pdbWithAltLoc,
             AppletFormatAdapter.PASTE);
-    boolean annotFromStructure = false;
-    boolean localSecondaryStruct = false;
-    boolean serviceSecondaryStruct = false;
-    JmolParser jtest = new JmolParser(annotFromStructure,
-            localSecondaryStruct, serviceSecondaryStruct, pdbWithAltLoc,
-            jalview.io.AppletFormatAdapter.PASTE);
+    JmolParser jtest = new JmolParser(pdbWithAltLoc,
+            AppletFormatAdapter.PASTE);
     Vector<SequenceI> seqs = jtest.getSeqs();
     Vector<SequenceI> mcseqs = mctest.getSeqs();
   
index 8a89830..c984b3a 100644 (file)
@@ -53,8 +53,7 @@ public class JmolVsJalviewPDBParserEndToEndTest
       {
         mctest = new PDBfile(false, false, false, testFile,
                 AppletFormatAdapter.FILE);
-        jtest = new JmolParser(false, false, false, testFile,
-                jalview.io.AppletFormatAdapter.FILE);
+        jtest = new JmolParser(testFile, AppletFormatAdapter.FILE);
       } catch (IOException e)
       {
         System.err.println("Exception thrown while parsing : " + pdbStr);
index eff3fdc..bbad963 100644 (file)
@@ -26,9 +26,13 @@ import static org.testng.AssertJUnit.assertNotNull;
 import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
 
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
 import jalview.datamodel.AlignedCodonFrame;
 import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.PDBEntry.Type;
 import jalview.datamodel.Sequence;
@@ -55,8 +59,7 @@ public class AlignViewportTest
   @BeforeClass(alwaysRun = true)
   public static void setUpBeforeClass() throws Exception
   {
-    jalview.bin.Jalview.main(new String[] { "-props",
-        "test/jalview/testProps.jvprops" });
+    Jalview.main(new String[] { "-props", "test/jalview/testProps.jvprops" });
   }
 
   @BeforeMethod(alwaysRun = true)
@@ -297,4 +300,32 @@ public class AlignViewportTest
     assertTrue(ssmMappings.contains(acf2));
     assertFalse(ssmMappings.contains(acf3));
   }
+  
+  /**
+   * Test for JAL-1306 - conservation thread should run even when only Quality
+   * (and not Conservation) is enabled in Preferences
+   */
+  @Test(groups = { "Functional" })
+  public void testUpdateConservation_qualityOnly()
+  {
+    Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
+            Boolean.TRUE.toString());
+    Cache.applicationProperties.setProperty("SHOW_QUALITY",
+            Boolean.TRUE.toString());
+    Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
+            Boolean.FALSE.toString());
+    Cache.applicationProperties.setProperty("SHOW_IDENTITY",
+            Boolean.FALSE.toString());
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            "examples/uniref50.fa", FormatAdapter.FILE);
+    AlignmentAnnotation[] anns = af.viewport.getAlignment().getAlignmentAnnotation();
+    assertNotNull("No annotations found", anns);
+    assertEquals("More than one annotation found", 1, anns.length);
+    assertTrue("Annotation is not Quality",
+            anns[0].description.startsWith("Alignment Quality"));
+    Annotation[] annotations = anns[0].annotations;
+    assertNotNull("Quality annotations are null", annotations);
+    assertNotNull("Quality in column 1 is null", annotations[0]);
+    assertTrue("No quality value in column 1", annotations[0].value > 10f);
+  }
 }
index f08fa8d..6621a94 100644 (file)
@@ -75,6 +75,7 @@ public class AnnotationChooserTest
   @BeforeMethod(alwaysRun = true)
   public void setUp() throws IOException
   {
+    Cache.loadProperties("test/jalview/io/testProps.jvprops");
     // pin down annotation sort order for test
     Cache.applicationProperties.setProperty(Preferences.SORT_ANNOTATIONS,
             SequenceAnnotationOrder.NONE.name());
index 9d0cedb..489fe4f 100644 (file)
@@ -23,16 +23,12 @@ package jalview.gui;
 import jalview.bin.Cache;
 
 import java.awt.Dimension;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
 
 import javax.swing.JDesktopPane;
 import javax.swing.JFrame;
 import javax.swing.JInternalFrame;
-import javax.swing.JMenu;
-import javax.swing.JMenuItem;
 import javax.swing.JTextArea;
 
 import org.testng.annotations.AfterClass;
@@ -64,49 +60,29 @@ public class JAL1353bugdemo
     foo.setPreferredSize(new Dimension(600, 800));
     cfoo.setSize(600, 800);
     final JInternalFrame cont = new JInternalFrame("My Frame");
-    JTextArea evt;
-    cont.setPreferredSize(new Dimension(400, 300));
-    cont.add(evt = new JTextArea(
-            "Click here and drag text over this window to freeze java.\n\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\nThis is a dummy string. See teh dummy string go.\n"));
+    cont.setPreferredSize(new Dimension(400, 400));
+    String msg = "This is a dummy string. See the dummy string go.\n";
+    msg += msg; // 2
+    msg += msg; // 4
+    msg += msg; // 8
+    msg += msg; // 16
+    JTextArea evt = new JTextArea(
+            "Click here and drag text over this window to freeze java.\n\n"
+                    + msg);
+    cont.add(evt);
     cont.pack();
     foo.add("A frame", cont);
     foo.setVisible(true);
     foo.setEnabled(true);
     foo.doLayout();
     cfoo.add(foo);
-    final JMenu jm = new JMenu("Do");
-    JMenuItem jmi = new JMenuItem("this");
-    jm.add(jmi);
-    evt.addMouseListener(new MouseListener()
+    // final JMenu jm = new JMenu("Do");
+    // JMenuItem jmi = new JMenuItem("this");
+    // jm.add(jmi);
+    evt.addMouseListener(new MouseAdapter()
     {
 
       @Override
-      public void mouseReleased(MouseEvent e)
-      {
-      }
-
-      @Override
-      public void mousePressed(MouseEvent e)
-      {
-        // TODO Auto-generated method stub
-
-      }
-
-      @Override
-      public void mouseExited(MouseEvent e)
-      {
-        // TODO Auto-generated method stub
-
-      }
-
-      @Override
-      public void mouseEntered(MouseEvent e)
-      {
-        // TODO Auto-generated method stub
-
-      }
-
-      @Override
       public void mouseClicked(MouseEvent e)
       {
         // JFrame parent = new JFrame();
@@ -124,19 +100,19 @@ public class JAL1353bugdemo
     });
     cont.setVisible(true);
 
-    jmi.addActionListener(new ActionListener()
-    {
-
-      @Override
-      public void actionPerformed(ActionEvent arg0)
-      {
-        EditNameDialog end = new EditNameDialog("Sequence Name",
-                "Sequence Description", "label 1", "Label 2",
-                "Try and drag between the two text fields", cont);
-        assert (end != null);
-        finish = true;
-      }
-    });
+    // jmi.addActionListener(new ActionListener()
+    // {
+    //
+    // @Override
+    // public void actionPerformed(ActionEvent arg0)
+    // {
+    // EditNameDialog end = new EditNameDialog("Sequence Name",
+    // "Sequence Description", "label 1", "Label 2",
+    // "Try and drag between the two text fields", cont);
+    // assert (end != null);
+    // finish = true;
+    // }
+    // });
     foo.setVisible(true);
     cfoo.setVisible(true);
     while (!finish)
index bad536b..1e41a16 100644 (file)
@@ -44,7 +44,7 @@ public class StructureChooserTest
   {
     seq = new Sequence("PDB|4kqy|4KQY|A", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1,
             26);
-    seq.setDatasetSequence(seq);
+    seq.createDatasetSequence();
     for (int x = 1; x < 5; x++)
     {
       DBRefEntry dbRef = new DBRefEntry();
@@ -105,24 +105,16 @@ public class StructureChooserTest
   }
 
   @Test(groups = { "Functional" })
-  public void populateFilterComboBoxTest()
+  public void populateFilterComboBoxTest() throws InterruptedException
   {
     SequenceI[] selectedSeqs = new SequenceI[] { seq };
     StructureChooser sc = new StructureChooser(selectedSeqs, seq, null);
-    sc.populateFilterComboBox();
+    sc.populateFilterComboBox(false);
     int optionsSize = sc.getCmbFilterOption().getItemCount();
     assertEquals(3, optionsSize); // if structures are not discovered then don't
                                   // populate filter options
 
-    sc.setStructuresDiscovered(true);
-    sc.populateFilterComboBox();
-    try
-    {
-      Thread.sleep(2000);
-    } catch (InterruptedException e)
-    {
-      e.printStackTrace();
-    }
+    sc.populateFilterComboBox(true);
     optionsSize = sc.getCmbFilterOption().getItemCount();
     assertTrue(optionsSize > 3); // if structures are found, filter options
                                  // should be populated
index e03f7a1..fd989ad 100644 (file)
@@ -122,9 +122,9 @@ public class AnnotatedPDBFileInputTest
     SequenceFeature[] sf = al.getSequenceAt(0).getSequenceFeatures();
     assertEquals(296, sf.length);
     assertEquals("RESNUM", sf[0].getType());
-    assertEquals("GLU:19 1gaqA", sf[0].getDescription());
+    assertEquals("GLU:  19  1gaqA", sf[0].getDescription());
     assertEquals("RESNUM", sf[295].getType());
-    assertEquals("TYR:314 1gaqA", sf[295].getDescription());
+    assertEquals("TYR: 314  1gaqA", sf[295].getDescription());
 
     /*
      * 1GAQ/B
@@ -132,9 +132,9 @@ public class AnnotatedPDBFileInputTest
     sf = al.getSequenceAt(1).getSequenceFeatures();
     assertEquals(98, sf.length);
     assertEquals("RESNUM", sf[0].getType());
-    assertEquals("ALA:1 1gaqB", sf[0].getDescription());
+    assertEquals("ALA:   1  1gaqB", sf[0].getDescription());
     assertEquals("RESNUM", sf[97].getType());
-    assertEquals("ALA:98 1gaqB", sf[97].getDescription());
+    assertEquals("ALA:  98  1gaqB", sf[97].getDescription());
 
     /*
      * 1GAQ/C
@@ -142,9 +142,9 @@ public class AnnotatedPDBFileInputTest
     sf = al.getSequenceAt(2).getSequenceFeatures();
     assertEquals(296, sf.length);
     assertEquals("RESNUM", sf[0].getType());
-    assertEquals("GLU:19 1gaqC", sf[0].getDescription());
+    assertEquals("GLU:  19  1gaqC", sf[0].getDescription());
     assertEquals("RESNUM", sf[295].getType());
-    assertEquals("TYR:314 1gaqC", sf[295].getDescription());
+    assertEquals("TYR: 314  1gaqC", sf[295].getDescription());
   }
 
   @Test(groups = { "Functional" })
index 625244d..c9b5f4a 100644 (file)
@@ -75,8 +75,7 @@ public class AnnotationFileIOTest
       // make sure dataset is initialised ? not sure about this
       for (int i = 0; i < al.getSequencesArray().length; ++i)
       {
-        al.getSequenceAt(i).setDatasetSequence(
-                al.getSequenceAt(i).createDatasetSequence());
+        al.getSequenceAt(i).createDatasetSequence();
       }
       assertNotNull("Couldn't read supplied alignment data.", al);
       return al;
index 93fb12b..f75f433 100644 (file)
@@ -114,7 +114,7 @@ public class JSONFileTest
 
     for (Sequence seq : seqs)
     {
-      seq.setDatasetSequence(seq);
+      seq.createDatasetSequence();
       expectedSeqs.put(seq.getName(), seq);
     }
 
index b034fb0..b635aa3 100644 (file)
@@ -103,7 +103,7 @@ public class StockholmFileTest
       // make sure dataset is initialised ? not sure about this
       for (int i = 0; i < al.getSequencesArray().length; ++i)
       {
-        al.getSequenceAt(i).setDatasetSequence(al.getSequenceAt(i));
+        al.getSequenceAt(i).createDatasetSequence();
       }
       String outputfile = rf.formatSequences(ioformat, al, true);
       System.out.println("Output file in '" + ioformat + "':\n"
@@ -228,7 +228,7 @@ public class StockholmFileTest
     }
     assertEquals(
             "Generated and imported alignment have different annotation sets",
-            aa_new_size, aa_original_size);
+            aa_original_size, aa_new_size);
 
     // check sequences, annotation and features
     SequenceI[] seq_original = new SequenceI[al.getSequencesArray().length];
index ff2f2aa..45b56c2 100644 (file)
@@ -55,43 +55,4 @@ public class DnaCodonTests
               + codon.getKey() + "\", \"" + codon.getValue() + "\");");
     }
   }
-
-  @Test(groups = { "Functional" })
-  public void checkOldCodonagainstNewCodonTable()
-  {
-    // note - this test will be removed once the old codon table (including
-    // Vectors) is removed
-    String additional = "", failtrans = "", differentTr = "";
-    for (String amacid : ResidueProperties.codonHash.keySet())
-    {
-      for (String codon : ResidueProperties.codonHash.get(amacid))
-      {
-        String trans = ResidueProperties.codonTranslate(codon);
-        String oldtrans = ResidueProperties._codonTranslate(codon);
-        if (trans == null)
-        {
-          additional += "\nOld translation table includes additional codons for "
-                  + amacid + " : " + codon;
-        }
-        if (oldtrans == null)
-        {
-          failtrans += ("\nold translation routine failed for old translation entry (aa was "
-                  + amacid + " codon was " + codon + ")");
-        }
-        if (!oldtrans.equals(trans))
-        {
-          differentTr += ("\nDifferent translation for old and new routines: "
-                  + amacid
-                  + " "
-                  + codon
-                  + " => expected "
-                  + oldtrans
-                  + " and got " + trans);
-        }
-      }
-    }
-    assertTrue("" + additional + "\n" + failtrans + "\n" + differentTr,
-            additional.length() == 0 && failtrans.length() == 0
-                    && differentTr.length() == 0);
-  }
 }
index baaa96b..2074fb4 100644 (file)
@@ -138,7 +138,7 @@ public class StructureSelectionManagerTest
     SequenceFeature sf = pmap.getSeqs().get(0).getSequenceFeatures()[0];
     assertEquals("RESNUM", sf.getType());
     assertEquals("1gaq", sf.getFeatureGroup());
-    assertEquals("GLU:19 1gaqA", sf.getDescription());
+    assertEquals("GLU:  19  1gaqA", sf.getDescription());
 
     /*
      * Verify a RESNUM sequence feature in the StructureSelectionManager mapped
@@ -148,6 +148,6 @@ public class StructureSelectionManagerTest
     sf = map.sequence.getSequenceFeatures()[0];
     assertEquals("RESNUM", sf.getType());
     assertEquals("1gaq", sf.getFeatureGroup());
-    assertEquals("ALA:1 1gaqB", sf.getDescription());
+    assertEquals("ALA:   1  1gaqB", sf.getDescription());
   }
 }
index c1d1144..1401f6a 100644 (file)
@@ -42,6 +42,7 @@ public class PDBSequenceFetcherTest
   @BeforeMethod(alwaysRun = true)
   public void setUp() throws Exception
   {
+    Cache.loadProperties("test/jalview/io/testProps.jvprops");
     // ensure 'add annotation from structure' is selected
     Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
             Boolean.TRUE.toString());
@@ -62,8 +63,6 @@ public class PDBSequenceFetcherTest
   @Test(groups = { "Network" }, enabled = true)
   public void testRnaSeqRetrieve() throws Exception
   {
-    Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
-            Boolean.TRUE.toString());
     Cache.applicationProperties.setProperty("PDB_DOWNLOAD_FORMAT",
             "PDB");
     List<DbSourceProxy> sps = sf.getSourceProxy("PDB");
@@ -85,8 +84,6 @@ public class PDBSequenceFetcherTest
   @Test(groups = { "Network" }, enabled = true)
   public void testPdbSeqRetrieve() throws Exception
   {
-    Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
-            Boolean.TRUE.toString());
     StructureImportSettings.setDefaultStructureFileFormat("PDB");
     StructureImportSettings
             .setDefaultPDBFileParser(StructureParser.JALVIEW_PARSER);
@@ -97,8 +94,6 @@ public class PDBSequenceFetcherTest
   @Test(groups = { "Network" }, enabled = true)
   public void testmmCifSeqRetrieve() throws Exception
   {
-    Cache.applicationProperties.setProperty("STRUCT_FROM_PDB",
-            Boolean.TRUE.toString());
     StructureImportSettings.setDefaultStructureFileFormat("mmCIF");
     testRetrieveProteinSeqFromPDB();
   }
index 26fcaf0..4b88b2b 100644 (file)
@@ -22,10 +22,12 @@ package jalview.ws.dbsources;
 
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertNotNull;
 import static org.testng.AssertJUnit.assertNull;
 
 import jalview.datamodel.PDBEntry;
 import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
 import jalview.datamodel.UniprotEntry;
 
 import java.io.Reader;
@@ -47,6 +49,7 @@ public class UniprotTest
           + "<protein><recommendedName><fullName>Mitogen-activated protein kinase 13</fullName><fullName>Henry</fullName></recommendedName></protein>"
           + "<dbReference type=\"PDB\" id=\"2FSQ\"><property type=\"method\" value=\"X-ray\"/><property type=\"resolution\" value=\"1.40\"/></dbReference>"
           + "<dbReference type=\"PDBsum\" id=\"2FSR\"/>"
+          + "<dbReference type=\"EMBL\" id=\"AE007869\"><property type=\"protein sequence ID\" value=\"AAK85932.1\"/><property type=\"molecule type\" value=\"Genomic_DNA\"/></dbReference>"
           + "<feature type=\"signal peptide\" evidence=\"7\"><location><begin position=\"1\"/><end position=\"18\"/></location></feature>"
           + "<feature type=\"propeptide\" description=\"Activation peptide\" id=\"PRO_0000027399\" evidence=\"9 16 17 18\"><location><begin position=\"19\"/><end position=\"20\"/></location></feature>"
           + "<feature type=\"chain\" description=\"Granzyme B\" id=\"PRO_0000027400\"><location><begin position=\"21\"/><end position=\"247\"/></location></feature>"
@@ -110,7 +113,7 @@ public class UniprotTest
      * Check cross-references
      */
     Vector<PDBEntry> xrefs = entry.getDbReference();
-    assertEquals(2, xrefs.size());
+    assertEquals(3, xrefs.size());
 
     PDBEntry xref = xrefs.get(0);
     assertEquals("2FSQ", xref.getId());
@@ -122,8 +125,26 @@ public class UniprotTest
     assertEquals("2FSR", xref.getId());
     assertEquals("PDBsum", xref.getType());
     assertFalse(xref.getProperties().hasMoreElements());
+
+    xref = xrefs.get(2);
+    assertEquals("AE007869", xref.getId());
+    assertEquals("EMBL", xref.getType());
+    assertEquals("AAK85932.1",
+ xref.getProperty("protein sequence ID"));
+    assertEquals("Genomic_DNA",
+ xref.getProperty("molecule type"));
   }
 
+  @Test(groups = { "Functional" })
+  public void testGetUniprotSequence()
+  {
+    UniprotEntry entry = new Uniprot().getUniprotEntries(
+            new StringReader(UNIPROT_XML)).get(0);
+    SequenceI seq = new Uniprot().uniprotEntryToSequenceI(entry);
+    assertNotNull(seq);
+    assertEquals(6, seq.getDBRefs().length); // 2*Uniprot, PDB, PDBsum, 2*EMBL
+
+  }
   /**
    * Test the method that formats the sequence id
    */
index 59bf445..0a565bd 100644 (file)
@@ -173,8 +173,7 @@ public class DbRefFetcherTest
                     sfs[0].getType()));
     assertEquals(embl.getDbSource(), sfs[0].getFeatureGroup());
     DBRefEntry[] dr = DBRefUtils.selectRefs(seq.getDBRefs(),
-            new String[] { DBRefSource.UNIPROT, DBRefSource.UNIPROTKB,
-                DBRefSource.EMBLCDSProduct, DBRefSource.ENSEMBL });
+            new String[] { DBRefSource.UNIPROT });
     assertNotNull(dr);
     assertEquals("Expected a single Uniprot cross reference", 1, dr.length);
     assertEquals("Expected cross reference map to be one amino acid", dr[0]
index 6f9a864..d3b485e 100644 (file)
@@ -21,6 +21,7 @@
 package jalview.ws.sifts;
 
 import jalview.api.DBRefEntryI;
+import jalview.bin.Cache;
 import jalview.datamodel.DBRefEntry;
 import jalview.datamodel.DBRefSource;
 import jalview.datamodel.Sequence;
@@ -170,6 +171,8 @@ public class SiftsClientTest
   @BeforeTest(alwaysRun = true)
   public void setUpSiftsClient() throws SiftsException
   {
+    // read test props before manipulating config
+    Cache.loadProperties("test/jalview/io/testProps.jvprops");
     // SIFTs entries are updated weekly - so use saved SIFTs file to enforce
     // test reproducibility
     new SiftsSettings();