Merge branch 'Release_2_8_1_Branch' into Release_2_8_1_Branch_i18n
authorJim Procter <jprocter@compbio.dundee.ac.uk>
Tue, 8 Oct 2013 14:23:40 +0000 (15:23 +0100)
committerJim Procter <jprocter@compbio.dundee.ac.uk>
Tue, 8 Oct 2013 14:23:40 +0000 (15:23 +0100)
Conflicts:
src/jalview/appletgui/APopupMenu.java
src/jalview/appletgui/AlignFrame.java

54 files changed:
.classpath
.project
examples/unfolded_RF00031.aln [new file with mode: 0644]
help/help.jhm
help/helpTOC.xml
help/html/menus/alignmentMenu.html
help/html/menus/alwselect.html
help/html/menus/popupMenu.html
help/html/webServices/RNAalifold.html [new file with mode: 0644]
help/html/webServices/RNAalifoldAnnotationRows.png [new file with mode: 0644]
lib/min-jaba-client-2.0.jar [deleted file]
lib/min-jabaws-client-2.1.0.jar [new file with mode: 0644]
src/jalview/analysis/AAFrequency.java
src/jalview/analysis/StructureFrequency.java
src/jalview/api/AlignViewControllerI.java [new file with mode: 0644]
src/jalview/api/AlignViewportI.java
src/jalview/appletgui/APopupMenu.java
src/jalview/appletgui/AlignFrame.java
src/jalview/appletgui/AlignViewport.java
src/jalview/appletgui/TreeCanvas.java
src/jalview/controller/AlignViewController.java [new file with mode: 0644]
src/jalview/datamodel/Sequence.java
src/jalview/datamodel/SequenceGroup.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AlignViewport.java
src/jalview/gui/AnnotationPanel.java
src/jalview/gui/Desktop.java
src/jalview/gui/Jalview2XML.java
src/jalview/gui/PopupMenu.java
src/jalview/gui/SeqPanel.java
src/jalview/gui/TreeCanvas.java
src/jalview/jbgui/GAlignFrame.java
src/jalview/schemes/RNAHelicesColour.java
src/jalview/schemes/RNAHelicesColourChooser.java
src/jalview/structure/StructureSelectionManager.java
src/jalview/viewmodel/AlignmentViewport.java
src/jalview/workers/ConsensusThread.java
src/jalview/workers/StrucConsensusThread.java
src/jalview/ws/jws2/AAConClient.java
src/jalview/ws/jws2/AADisorderClient.java
src/jalview/ws/jws2/JabaWsServerQuery.java
src/jalview/ws/jws2/JabawsAlignCalcWorker.java
src/jalview/ws/jws2/JabawsCalcWorker.java [new file with mode: 0644]
src/jalview/ws/jws2/Jws2Discoverer.java
src/jalview/ws/jws2/ParameterUtils.java
src/jalview/ws/jws2/RNAalifoldClient.java [new file with mode: 0644]
src/jalview/ws/jws2/SequenceAnnotationWSClient.java
src/jalview/ws/jws2/dm/JabaOption.java
src/jalview/ws/jws2/jabaws2/Jws2Instance.java
src/jalview/ws/jws2/jabaws2/Jws2InstanceFactory.java [new file with mode: 0644]
src/jalview/ws/uimodel/AlignAnalysisUIText.java [new file with mode: 0644]
test/jalview/gui/JAL1353bugdemo.java [new file with mode: 0644]
test/jalview/ws/jabaws/RNAStructExportImport.java [new file with mode: 0644]
utils/InstallAnywhere/Jalview.iap_xml

index 6cffc21..c22cae5 100644 (file)
        <classpathentry kind="lib" path="lib/miglayout-4.0-swing.jar"/>
        <classpathentry kind="lib" path="lib/jswingreader-0.3.jar" sourcepath="/jswingreader"/>
        <classpathentry kind="lib" path="lib/commons-codec-1.3.jar"/>
-       <classpathentry kind="lib" path="lib/min-jaba-client-2.0.jar" sourcepath="/clustengine2"/>
        <classpathentry kind="lib" path="lib/Jmol-12.2.4.jar"/>
        <classpathentry kind="lib" path="appletlib/JmolApplet-12.2.4.jar"/>
        <classpathentry kind="lib" path="lib/jdas-1.0.4.jar"/>
        <classpathentry kind="lib" path="lib/spring-core-3.0.5.RELEASE.jar"/>
        <classpathentry kind="lib" path="lib/spring-web-3.0.5.RELEASE.jar"/>
+       <classpathentry kind="lib" path="lib/VARNAv3-9-dev.jar"/>
+       <classpathentry kind="lib" path="lib/groovy-all-1.8.2.jar"/>
+       <classpathentry kind="lib" path="lib/min-jabaws-client-2.1.0.jar" sourcepath="/clustengine"/>
        <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin.jar"/>
-       <classpathentry kind="lib" path="/Users/jimp/git/jalview_clean/lib/VARNAv3-9-dev.jar"/>
        <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
        <classpathentry kind="output" path="classes"/>
 </classpath>
index 5f4b511..aa7e6f2 100644 (file)
--- a/.project
+++ b/.project
                                </dictionary>
                        </arguments>
                </buildCommand>
-               <buildCommand>
-                       <name>org.eclipse.ui.externaltools.ExternalToolBuilder</name>
-                       <triggers>full,incremental,</triggers>
-                       <arguments>
-                               <dictionary>
-                                       <key>LaunchConfigHandle</key>
-                                       <value>&lt;project&gt;/.externalToolBuilders/buildapplet [Builder].launch</value>
-                               </dictionary>
-                       </arguments>
-               </buildCommand>
        </buildSpec>
        <natures>
                <nature>org.eclipse.jdt.groovy.core.groovyNature</nature>
diff --git a/examples/unfolded_RF00031.aln b/examples/unfolded_RF00031.aln
new file mode 100644 (file)
index 0000000..69a7850
--- /dev/null
@@ -0,0 +1,126 @@
+CLUSTAL
+
+B.taurus.1/1-64       C-UUGCGUU--AAUGAGAACAGAAACG-UAAA--CUAUAA-CCUAG-G---------GGU
+D.melanogaster.3/1-68 G-UGGCGCU--UAUGACGCAGUUGUCU-UAAA-CUCGAAC--UCGA-GC--------GGG
+D.melanogaster.2/1-63 C-AUUCAACU-UAUGAGGAUUAUUUCU-UAAA-GGCCUCU---GGC--U-------CGGA
+D.melanogaster.1/1-65 G-AGCC-CU---AUGAUCGAUGAUUGG-CAAA-UCCUCUC--GAGG--A-------ACCG
+R.norvegicus.7/1-66   C-CGGCACU--CAUGACGGUCUGCCUG-AAAA-CCAGCCC--GCUG-GU--------GGG
+R.norvegicus.6/1-67   G-CCGCUUC---AUGACAGGAAGGACU-GAAA-UGUCUCA-AAGAC--C-----UGUGGU
+R.norvegicus.5/1-62   G-UUUUUCC---AUGACGGUGUUUCCUCUAAA--UUUAC----AUG-----------GAG
+R.norvegicus.4/1-61   G-UCAGAUG---AUGACGGCCUGUGCA-GAAA-CCCCCAC-GUGGG--C--------UGC
+R.norvegicus.3/1-67   U-UUGCAUU--AAUGAGGAUUACACAG-AAAA-CCUUUGU--UAAGGGU--------UUG
+R.norvegicus.2/1-64   G-UUACAUU--GAUGAGAACAGAAACA-UAAA--CUAUGA-CCUAG-G---------GGU
+R.norvegicus.1/1-61   A-UAUUUGUU-UAUGAUGGUCACAGUG-UAAA--GUUCA----CAC-----------AGC
+O.aries.1/1-68        G-ACGCUUC---AUGACAGGAAGGACU-GAAA-UGUCUCU-UGGAC-GC------CUGGU
+M.musculus.9/1-66     C-CGGCACU--CAUGAAGGUCUGCUUG-AAAA-CCAGCCU--GCUG-GU--------GGG
+M.musculus.8/1-67     U-UUGCAUU--AAUGAGGAUUACACAG-AAAA-CCUUUGU--UAAG-GA-------CUUG
+O.niloticus.3/1-65    G-UGUCUCU---GUGAAGUUCGGUUUU-UAAA-AGGGUCA---UCC--A-------GAAA
+M.musculus.7/1-64     G-UGUCUCU---AUGAAGGAGGGGCCC-GAAG-CCCUUGU---GGG--C--------GGG
+O.niloticus.2/1-61    U-GUUUAUU--AAUGACGGCUACAGAU-UAAA--CCUUU----AGC-----------CUC
+M.musculus.6/1-61     G-UCAGAUG---AUGAUGGCCUGGGCA-GAAA-CCCCAUG--UGGG--C--------CGC
+O.niloticus.1/1-59    G-UUUCUCA---GUGAAGGCUACAGAU-UAAA--CCUCU----GGC-----------CUC
+M.musculus.5/1-66     G-CCGCUUC---AUGACAGGAAGGACU-GAAA-UGUCUUA---GAC--C-----UGUGGU
+M.musculus.4/1-65     G-UGUGCGA---AUGAUAACUACUGAC-GAAA-GAGCUGU-CUGCU--C-------AGUC
+M.musculus.3/1-64     G-GUUCUUC--CAUGAUGGUGUUUCCUCUAAA--UUUGC----ACG-----------GAG
+M.musculus.2/1-64     G-UUACAUU--AAUGAGAACAGAAACA-UAAA--CUAUGA-CCUAG-G---------GGU
+M.musculus.1/1-64     G-UCACCGA---AUGAUCUGCUCUGGU-CAAA-UCCUUCU---AUG--C------CAGCC
+C.elegans.1/1-64      G-AGGCAGCUUUGUGACGACCUUUGGC-UAAA-CUCCAUC--GUGA-GC--------GCC
+H.sapiens.15/1-63     U-UUUCAUC--UAUGAGGGUGUUUCCUCUAAA--CCUACG---AGG-----------GAG
+H.sapiens.14/1-62     C-ACUGCUG---AUGACGAACUAUCUC-UAAC-UGGUCUU--GACC--A-------CGAG
+H.sapiens.13/1-64     G-UCACUGC---AUGAUCCGCUCUGGU-CAAA-CCCUUCC---AGG--C------CAGCC
+H.sapiens.12/1-67     C-UCUGUUA---AUGACGUCUCUCCCUCUAAA-CCCCAUU-AAGGA--C--------UGG
+D.rerio.1/1-66        A-UGUGGUCUUUAUGAAGGCAGGUGCA-GAAA-CUAUGCA---CUA-GU--------GGU
+H.sapiens.11/1-63     G-CCGGAUG---AUGACGACCUGGGUG-GAAA-CCUACCC-UGUGG--G--------CAC
+H.sapiens.10/1-62     C-CGGCACU--CAUGACGGCCUGCCUG-CAAA--CCUGC----UGG--U--------GGG
+S.mansoni.1/1-67      C-UCGCUAU---AUGACGAUGGCAAUC-UCAA--AUGUU----CAU--U--------GGU
+S.scrofa.4/1-64       C-UGGCACC--CAUGACAGUCUGCCUA-AAAA-CCAGCC----CUG-GU--------GGG
+S.scrofa.3/1-63       A-UUUUAUC--CAUGAAAGUGUUUCCUCUAAA--CCUAU----GUG-----------GAG
+S.scrofa.2/1-65       C-UGGCACC--CAUGACAGUCUGCCUA-AAAA-CCAGCCC---CUG-GU--------GGG
+S.scrofa.1/1-68       G-ACGCUUC---AUGACAGGAAGGACU-GAAA-UGUCUUG-UGGAC-GC------CUGGU
+H.sapiens.9/1-58      U-AUUUGUU--UAUGAUGGCCACAGCC-UAAA--GUACA----CAC-----------GGC
+H.sapiens.8/1-67      U-UUGCUUU--AAUGAGAAUAGAAACG-UAAA--CUAUGA-CCUAG-G---------GGU
+X.laevis.1/1-67       G-UGUUUGCA-AAUGACGACCGAUUUU-GAAA-UGGUCUCACGGCC--A-------AAAA
+H.sapiens.7/1-70      U-GGCGUCUU-CAUGAGGGAGGGGCCC--AAA-GCCCUUG--UGGG--C--------GGA
+H.sapiens.6/1-66      G-UGUGCGG---AUGAUAACUACUGAC-GAAAGAGUCAUC---GAC--C-----UCAGUU
+H.sapiens.5/1-57      U-UCACAGA---AUGAUGGCACCUUCC-UAA---ACCCU----CAU-----------GGG
+H.sapiens.4/1-71      G-ACUGACAU-UAUGAAGGCCUGUACU-GAAG-ACAGCAA--GCUG--U-------UAGU
+H.sapiens.3/1-68      G-ACGCUUC---AUGAUAGGAAGGACU-GAAA-AGUCUUG-UGGAC--A-----CCUGGU
+H.sapiens.2/1-65      G-UGUGCGG---AUGAUAACUACUGAC-GAAA-GAGUCAU-CGACU--C-------AGUU
+H.sapiens.1/1-63      G-CCAGAUG---AUGACGACCUGGGUG-GAAA-CCUACCC-UGUGG--G--------CAC
+M.musculus.14/1-67    C-UCUGAUA---AUGAUGUCUCUCCCU-CUAA-CUCCCAGUAAGGA--C--------UGG
+M.musculus.13/1-60    C-AUGCGUC--CAUGAAGUCACUGGCC-UCAA-GCCCAA----GUG-GU--------GGG
+M.musculus.12/1-65    C-UCAGCAG--GAUGAUGAGAAGGGCU-GAAA-UGCUGCC--AAAC--C-------AGGU
+M.musculus.11/1-63    U-AUUUGUG--UAUGAUGGUCACAGUG-UAAA--GUUCC----CAC-----------AGC
+M.musculus.10/1-66    C-CGGCACU--CAUGAAGGUCUGCCUG-AAAA-CCAGCCU--GCUG-GU--------GGG
+B.taurus.7/1-61       U-UUUGCCC---AUGAAGGUGUUCCCUCUAAA--CCUAC----GUG-----------GAG
+B.taurus.6/1-67       G-AUGCGUC--CAUGAAGUCACCAGCC-CCAA-GCCCCUC---GUG-GU--------GGG
+B.taurus.5/1-61       G-CCAGAUG---AUGAGGACCUGUGCG-GAAA-CCCCCCG--CGGG--C--------UGC
+B.taurus.4/1-64       ACUUGCGUU--AAUGAGAACAGAAACG-UAAA--CUAUAA-CCUAG-G---------GGU
+G.gallus.3/1-73       U-AUUUCUU--UGUGAUGACCGAUUUU-GAAA-UGGGUUU---CUC--UAAUGCCAGGAA
+B.taurus.3/1-66       C-CCGGUGCC-UAUGACGGUCUGUCUG-AAAA-CCAGCCC---CUG-GU--------GGG
+G.gallus.2/1-60       U-AUUUGUC---AUGACAGUCACAGCA-UAAA--GCGCA----GAC-----------GGC
+B.taurus.2/1-64       C-UUGCGUU--AAUGAGAACAGAAACG-AAAA--CUAUAA-CCUAG-G---------GGU
+G.gallus.1/1-63       G-UGUGUUU---AUGAAGAGCACUAAC-AAAA-GAGUAAU-UGACU--C-------AGUU
+
+B.taurus.1/1-64       UUC-U-G-UUGGAU--GGUUG-------GCAAC
+D.melanogaster.3/1-68 CAA-U-U-GCUGAU---UACG---AUUAACCAC
+D.melanogaster.2/1-63 AAU-A-G-UCUGAA---CCU--------UAUUG
+D.melanogaster.1/1-65 AUC-G-U-UGAGAA--CCCCU-----UUGCCUU
+R.norvegicus.7/1-66   GCA-G-U-CCCGAG-GACCUG-------GCGUG
+R.norvegicus.6/1-67   CUU-U-C-UUCGAU--GUUCU-------GCGGC
+R.norvegicus.5/1-62   AAA-C-A-CCUGAU-UUCCAG------AAAAAU
+R.norvegicus.4/1-61   -CA-G-G-UUUGAA---CCC--------CUGGC
+R.norvegicus.3/1-67   UGUCG-A-UCUGCU--AAUUG-------GCAAA
+R.norvegicus.2/1-64   UUC-U-G-UUGGAU--AGCUC-------GUAAU
+R.norvegicus.1/1-61   UGU-G-A-CUUGAU--UUUUA-------AAAAU
+O.aries.1/1-68        CCU-U-C-CUUGAU--GUUCU------CACGGC
+M.musculus.9/1-66     GCA-G-U-CCUGAG-GACCUG-------GCGUG
+M.musculus.8/1-67     UGU-AGA-UCUGAU--AAUUG-------GCAAA
+O.niloticus.3/1-65    ACC-G-ACACUGAU--GUUUC------CGACAC
+M.musculus.7/1-64     CCU-C-C-CCUGAG---CCCG----UCUGUGGU
+O.niloticus.2/1-61    UGG-A-G-CCAGAU--GCAUU------CAAACA
+M.musculus.6/1-61     CCA-G-G-UUUGAA---CCC--------CUGGC
+O.niloticus.1/1-59    UGG-A-G-CCAGAU--GCAUU-------GAAAC
+M.musculus.5/1-66     CUU-U-C-CUCGAU--GUUCC------UGCGGC
+M.musculus.4/1-65     UGU-G-G-UUGGAU---GUAG------UCACAC
+M.musculus.3/1-64     AAA-C-A-CCUGAU-UUCCAG-----GAAAAUC
+M.musculus.2/1-64     UUC-U-G-UUGGAU--AGCUU-------GUAAU
+M.musculus.1/1-64     AGG-G-U-GGUGAU--GACCC-------GUGAC
+C.elegans.1/1-64      UCU-G-G-UCUGAU---GC---------GCCUC
+H.sapiens.15/1-63     GAA-C-A-CCUGAU---CUUA-----CAGAAAA
+H.sapiens.14/1-62     CUA-G-U-UCUGAA---UU-G-------CAGGG
+H.sapiens.13/1-64     AGA-G-U-GGGGAU--GGUCU-------GUGAC
+H.sapiens.12/1-67     GAG-A-G-GCAGAGCAAGCCU-------CAGAG
+D.rerio.1/1-66        GUC-U-G-UCUGAU--GUUUG-------GCCAU
+H.sapiens.11/1-63     CCA-U-G-UCCGAG---CCCC-------CUGGC
+H.sapiens.10/1-62     GCA-G-A-CCCGAA-AAUCCA-------GCGUG
+S.mansoni.1/1-67      UGC-C-A-UUUGAU--GAAAUCAGUUUUGUGUG
+S.scrofa.4/1-64       GCA-G-A-CUCGAG-AACCUG-------GCGUG
+S.scrofa.3/1-63       GAA-C-A-CCUGAU-GUCCAG------GAAAAU
+S.scrofa.2/1-65       GCA-G-A-CUCGAG-AACCUG-------GCGUG
+S.scrofa.1/1-68       CCU-U-C-CCUGAU--GUUCU------CAUGGC
+H.sapiens.9/1-58      UGU-G-A-CUUGAU---UCA--------AAAGA
+H.sapiens.8/1-67      UUC-U-G-UUGGAU-AAUUAG-----CAGUUUA
+X.laevis.1/1-67       CUC-GUG-UCCGAC---AUC--------AACCC
+H.sapiens.7/1-70      CCU-C-C-CCUGAG---CCUGUCUGAGGGGCCA
+H.sapiens.6/1-66      AGU-G-G-UUGGAU---GUAG------UCACAU
+H.sapiens.5/1-57      UGG-U-G-UCUGAG--AGGC--------GUGAA
+H.sapiens.4/1-71      ACA-G-A-CCAGAU--GCUUU--CUUGGCAGGC
+H.sapiens.3/1-68      CUU-U-C-CCUGAU--GUUCU------CGUGGC
+H.sapiens.2/1-65      AGU-G-G-UUGGAU---GUAG------UCACAU
+H.sapiens.1/1-63      CCA-U-G-UCCGAG---CCCC-------CUGGC
+M.musculus.14/1-67    GAG-A-G-GCUGAACAAACCU-------CAGAG
+M.musculus.13/1-60    CAG-U-G-ACAGAA---GA---------GCUGC
+M.musculus.12/1-65    CCU-U-U-UCUGAU--GGUGG-------CUGGG
+M.musculus.11/1-63    UGU-G-A-CUUGAU--UUUUA----AAAAUGUC
+M.musculus.10/1-66    GCA-G-U-CCUGAG-GACCUG-------GCGUG
+B.taurus.7/1-61       GAA-U-G-CCUGAU-GUCCAG-------GAAAA
+B.taurus.6/1-67       UGG-U-G-AUGGAA-CCGUCA-----AAGCAGU
+B.taurus.5/1-61       CCA-U-G-UCUGAG---CCC--------CUGGC
+B.taurus.4/1-64       UUC-U-G-UUGGAU--GGUUG-------GCAA-
+G.gallus.3/1-73       AUC-GUG-UCUGAU---GUUG-----UCAAGUA
+B.taurus.3/1-66       GCA-G-A-CCUGAG-AACCUG-------GCGUG
+G.gallus.2/1-60       UGU-G-A-CCUGAU--UUUAG------AAAAUA
+B.taurus.2/1-64       UUC-U-G-UUGGAU--GGUUG-------GCAAC
+G.gallus.1/1-63       GGU-G-U-UCAGAU--GCU---------CUCAC
+
index b850b79..aaaaaf8 100755 (executable)
@@ -37,6 +37,7 @@
    <mapID target="newsreader" url="html/webServices/newsreader.html"/>
    <mapID target="disorder" url="html/webServices/proteinDisorder.html"/>
    <mapID target="aacon" url="html/webServices/AACon.html"/>
+   <mapID target="rnaalifold" url="html/webServices/RNAalifold.html"/>
    <mapID target="seqfetch" url="html/features/seqfetch.html"/>
    <mapID target="dbreffetcher" url="html/webServices/dbreffetcher.html"/>
    <mapID target="seqmappings" url="html/features/seqmappings.html"/>
index 0d2e096..e27d41a 100755 (executable)
@@ -22,6 +22,7 @@
        <tocitem text="What's new" target="new" expand="true">
     <tocitem text="Protein Disorder Prediction" target="disorder"/>
     <tocitem text="Alignment Conservation Analysis" target="aacon"/>
+       <tocitem text="RNAalifold RNA Secondary Structure Prediction" target="rnaalifold"/>
                <tocitem text="Viewing RNA structure" target="varna" />
                <tocitem text="RNA Structure Consensus" target="calcs.alstrconsensus"/>
                <tocitem text="RNA Helices coloring" target="colours.rnahelices"/>
@@ -65,6 +66,7 @@
                 <tocitem text="Multiple Alignment Subjobs" target="msaservice"/>
             </tocitem>
           <tocitem text="Secondary Structure Prediction" target="jnet"/>
+          <tocitem text="RNAalifold RNA Secondary Structure Prediction" target="rnaalifold"/>
           <tocitem text="Protein Disorder Prediction" target="disorder"/>
           <tocitem text="Alignment Conservation Analysis" target="aacon"/>
           <tocitem text="Multi-Harmony Alignment Analysis" target="shmrws"/>
index 9ec5adc..d53b3eb 100755 (executable)
                                </strong><em>Any columns currently not selected will replace the current
                                                column selection. </em>
                                </li>
-                               <li><strong>Undefine Groups (Control U)<br> </strong><em>The
-                                               alignment will be reset with no defined groups.<br> <strong>WARNING</strong>:
-                                               This cannot be undone.</em>
-                               </li>
-                               <li><strong>Make Groups<br /> </strong> <em>The currently
+                                 <li><strong>Create Group (Control G)<br></strong>
+  <em>Create a group containing the currently selected sequences.</em></li>
+  <li><strong>Remove Group (Shift Control G)<br></strong>
+  <em>Ungroup the currently selected sequence group. (Create/Remove group new in Jalview 2.8.1)</em></li>
+                       <li><strong>Make Groups for selection<br /> </strong> <em>The currently
                                                selected groups of the alignment will be subdivided according to
                                                the contents of the currently selected region. <br />Use this to
                                                subdivide an alignment based on the different combinations of
                                                residues observed at specific positions. (new in jalview 2.5)</em>
                                </li>
-                       </ul></li>
+       <li><strong>Undefine Groups (Control U)<br> </strong><em>The
+            alignment will be reset with no defined groups.<br> <strong>WARNING</strong>:
+            This cannot be undone.</em>
+        </li>
+               </ul></li>
                <li><strong>View</strong>
                        <ul>
                                <li><strong>New View (Control T)</strong><em><br>
index c4b3002..bd17fa7 100644 (file)
        <li><strong>Invert Column Selection (Control Alt I)<br>
        </strong><em>Any columns currently not selected will replace the current
        column selection. </em></li>
-       <li><strong>Undefine Groups (Control U)<br>
-       </strong><em>The alignment will be reset with no defined groups.<br>
-       <strong>WARNING</strong>: This cannot be undone.</em></li>
-       <li><strong>Make Groups<br/></strong>
+       <li><strong>Create Group (Control G)<br></strong>
+       <em>Create a group containing the currently selected sequences.</em></li>
+  <li><strong>Remove Group (Shift Control G)<br></strong>
+  <em>Ungroup the currently selected sequence group. (Create/Remove group new in Jalview 2.8.1)</em></li>
+       <li><strong>Make Groups for selection<br/></strong>
        <em>The currently selected groups of the alignment will be subdivided according to the contents of the currently selected region. <br/>Use this to subdivide an alignment based on the different combinations of residues observed at specific positions. (new in jalview 2.5)</em></li>
+<li><strong>Undefine Groups (Control U)<br>
+  </strong><em>The alignment will be reset with no defined groups.<br>
+  <strong>WARNING</strong>: This cannot be undone.</em></li>
+  
 </ul>
 </body>
 </html>
index 7c3db2c..8eab2d0 100755 (executable)
@@ -59,18 +59,22 @@ not be accessible when in 'Cursor Mode' (toggled with the F2 key).</em></p>
       <li><strong><a href="../features/creatinFeatures.html">Create Sequence Feature...</a></strong><br>
         <em>Opens the dialog box for creating sequence features over the currently 
         selected region on each selected sequence.</em></li>
-      <li><strong>Group</strong><br>
-        <em>Group Operations</em> 
-        <ul>
-          <li><strong>Group</strong><em>This is the first entry in the
-         menu, and will display the currently selected group's
-         name. Selecting it displays a window allowing the name and
-         description for this group to be edited. Click OK to set the
-         new name and decription, and cancel to leave the existing
-         name and description unchanged.</em></li>
+      <li><strong>Create Group<br>
+            </strong><em>This will define a new group from the current selection.</em><strong> 
+            </strong></li>
           <li><strong>Remove Group<br>
             </strong><em>This will undefine the selected group. </em><strong> 
             </strong></li>
+          <li><strong>Edit (New) Group</strong><br>
+        <em>Group Editing Menu</em> <br />Options in this menu modify
+                                       the name and display properties of the currently selected group, or
+                                       a new group defined using the current selection.
+                                       <ul>
+          <li><strong>Name: &lt;Group&gt;</strong> or <strong>Edit name and description</strong><br><em>The first entry in the
+         menu displays the name for the currently selected group, if it has one. Selecting this option opens a window allowing the name and
+         description for this group to be edited. Click OK to set the
+         new name and decription, and cancel to leave the existing
+         name and description unchanged.</em></li>
           <li><strong>Group Colour<br>
             </strong><em>Sets the <a href="../colourSchemes/index.html">colour</a> 
             of the group.</em><strong> </strong></li>
diff --git a/help/html/webServices/RNAalifold.html b/help/html/webServices/RNAalifold.html
new file mode 100644 (file)
index 0000000..ac9df34
--- /dev/null
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="ISO-8859-1">
+<title>RNAalifold Web Service</title>
+</head>
+<body>
+       <strong>RNAalifold RNA Alignment Secondary Structure
+               Prediction Service</strong>
+       <p>
+               RNAalifold is part of the <a href="http://www.tbi.univie.ac.at/RNA/">Vienna
+                       RNA</a> Secondary Structure Prediction and Comparison Package. It was
+               described in 2008 by Ivo L. Hofacker, Sebastian Will, Andreas R.
+               Gruber, and Peter F. Stadler, <em>RNAalifold: Improved consensus
+               structure prediction for RNA alignments</em>. (<a
+                       href=http://www.biomedcentral.com/1471-2105/9/474>BMC
+                       Bioinformatics, 9:474, 2008</a>).
+       </p>
+       <p>
+               <strong>Example RNAalifold Output</strong><br />
+               RNAalifold prints a consensus alignment and mfe structure to stdout with its
+               associated energy. Depending on the arguments given, other information such as
+               alternate structures are displayed below while base pairing probabilities (-p or --MEA 
+               options) are stored in a separate 'alifold.out' file.<br />
+               <pre><br />
+G_UUUCAUU___AUGACGGCCUGUGCU_UAAA__CCUCC____GAG__C________GGGUCA_G_G_UCUGAU___CUUG_______GAGAC
+(.((((...........(((((((((........(((......)))............))))).).).))..................))))) (-19.16 = -11.80 +  -7.36) 
+(.((((...........(((((((((........(((......)))............))))).).).))..................))))) [-19.32]
+       frequency of mfe structure in ensemble 0.765639
+(.((((...........(((((((((........(((......)))............))))).).).))..................))))) -19.16 {-11.80 +  -7.36}
+(.((((...........(((((((((........(((......)))............))))).).).))..................))))) { 13.20 MEA=92.14}
+
+Alifold.out
+       6    89  9  99.2%   0.023 CG:29   GC:14   UA:9   
+       4    91 11  99.1%   0.028 CG:20   GC:11   UG:2    UA:17  
+       3    92 18  96.9%   0.090 CG:5    GC:2    GU:1    UG:4    AU:6    UA:25  
+       35    46  3  93.3%   0.195 CG:31   GC:16   UG:2    AU:5    UA:4   
+       36    45 10  93.6%   0.185 CG:16   GC:6    GU:1    UG:2    AU:8    UA:18  
+               .
+               .
+               .
+       </pre>
+       </p>
+       <p>
+               <strong>Running RNAalifold from Jalview</strong><br />
+               To run RNAalifold go to <strong>Webservices&rarr;RNA Structure Prediction</strong>
+               and choose <strong>RNAalifold Defaults</strong> to run with no arguments or 
+               <strong>edit settings and run ...</strong> to adjust the parameters before running.
+               Details of all the RNAalifold parameters can be found in the 
+               <a href=http://www.tbi.univie.ac.at/RNA/man/RNAalifold.html>RNAalifold Manpage</a>.
+               JABAWS and Jalview support a selection of the RNAalifold arguments only.
+       </p>
+       <p><strong>Supported Arguments which give alternate structures</strong></p>
+       <p>
+       <em>Partition Function (-p)</em><br />
+       Calculate the Partition Function and base pairing probability matrix in addition to the mfe 
+       structure. A coarse representation of the pair probabilities in the from of a psuedo
+       bracket notation, as well as the centroid structure derived from the pair probabilities
+       are displayed. The most likely base pairings are stored in a separate file by RNAalifold
+       and represented in Jalview by a bar graph annotation line labelled 'Contact Probabilities'.
+       </p>
+       <p>
+       <em>Maximum Expected Accuracy Structure (--MEA)</em><br />
+       Calculate an MEA structure where the expected Accuracy is computed from the base pair 
+       probabilities. A more detailed description is found in the <a href=http://www.tbi.univie.ac.at/RNA/man/RNAfold.html>
+       RNAfold documentation</a>.
+       </p>
+       <p><strong>Example RNAalifold Structure Annotation rows</strong><p>
+       
+               <div align="center">
+               <img src="RNAalifoldAnnotationRows.png" width="500" height="216"></div>
+       
+</body>
+</html>
\ No newline at end of file
diff --git a/help/html/webServices/RNAalifoldAnnotationRows.png b/help/html/webServices/RNAalifoldAnnotationRows.png
new file mode 100644 (file)
index 0000000..5077d19
Binary files /dev/null and b/help/html/webServices/RNAalifoldAnnotationRows.png differ
diff --git a/lib/min-jaba-client-2.0.jar b/lib/min-jaba-client-2.0.jar
deleted file mode 100644 (file)
index 4ba3f33..0000000
Binary files a/lib/min-jaba-client-2.0.jar and /dev/null differ
diff --git a/lib/min-jabaws-client-2.1.0.jar b/lib/min-jabaws-client-2.1.0.jar
new file mode 100644 (file)
index 0000000..7ad030a
Binary files /dev/null and b/lib/min-jabaws-client-2.1.0.jar differ
index 50b1b4b..df5ca8d 100755 (executable)
@@ -19,6 +19,7 @@ package jalview.analysis;
 
 import java.util.*;
 
+import jalview.util.Format;
 import jalview.datamodel.*;
 
 /**
@@ -90,7 +91,7 @@ public class AAFrequency
     Hashtable residueHash;
     int maxCount, nongap, i, j, v, jSize = sequences.length;
     String maxResidue;
-    char c;
+    char c='-';
     float percentage;
 
     int[] values = new int[255];
@@ -104,7 +105,7 @@ public class AAFrequency
       maxResidue = "";
       nongap = 0;
       values = new int[255];
-
+      
       for (j = 0; j < jSize; j++)
       {
         if (sequences[j] == null)
@@ -142,8 +143,11 @@ public class AAFrequency
           values['-']++;
         }
       }
-
-      for (v = 'A'; v < 'Z'; v++)
+      if (jSize==1)
+      {
+        maxResidue = String.valueOf(c);
+        maxCount=1;
+      } else {for (v = 'A'; v < 'Z'; v++)
       {
         if (values[v] < 2 || values[v] < maxCount)
         {
@@ -160,7 +164,7 @@ public class AAFrequency
         }
         maxCount = values[v];
       }
-
+      }
       if (maxResidue.length() == 0)
       {
         maxResidue = "-";
@@ -194,14 +198,15 @@ public class AAFrequency
    * @param width
    * @param ignoreGapsInConsensusCalculation
    * @param includeAllConsSymbols
+   * @param nseq 
    */
   public static void completeConsensus(AlignmentAnnotation consensus,
           Hashtable[] hconsensus, int iStart, int width,
           boolean ignoreGapsInConsensusCalculation,
-          boolean includeAllConsSymbols)
+          boolean includeAllConsSymbols, long nseq)
   {
     completeConsensus(consensus, hconsensus, iStart, width,
-            ignoreGapsInConsensusCalculation, includeAllConsSymbols, null); // new
+            ignoreGapsInConsensusCalculation, includeAllConsSymbols, null, nseq); // new
                                                                             // char[]
     // { 'A', 'C', 'G', 'T', 'U' });
   }
@@ -209,7 +214,7 @@ public class AAFrequency
   public static void completeConsensus(AlignmentAnnotation consensus,
           Hashtable[] hconsensus, int iStart, int width,
           boolean ignoreGapsInConsensusCalculation,
-          boolean includeAllConsSymbols, char[] alphabet)
+          boolean includeAllConsSymbols, char[] alphabet, long nseq)
   {
     float tval, value;
     if (consensus == null || consensus.annotations == null
@@ -219,6 +224,23 @@ public class AAFrequency
       // initialised properly
       return;
     }
+    String fmtstr="%3.1f";
+    int precision=0;
+    while (nseq>=10) {
+      precision++;
+      nseq/=10;
+    }
+    final Format fmt;
+    if (precision>1)
+    {
+      //if (precision>2)
+      {
+        fmtstr = "%"+(2+precision)+"."+(precision)+"f";
+      }
+      fmt = new Format(fmtstr);
+    } else {
+      fmt = null;
+    }
     for (int i = iStart; i < width; i++)
     {
       Hashtable hci;
@@ -229,7 +251,6 @@ public class AAFrequency
         consensus.annotations[i] = null;
         continue;
       }
-
       value = 0;
       Float fv;
       if (ignoreGapsInConsensusCalculation)
@@ -265,7 +286,7 @@ public class AAFrequency
             tval = profile[0][alphabet[c]] * 100f
                     / profile[1][ignoreGapsInConsensusCalculation ? 1 : 0];
             mouseOver += ((c == 0) ? "" : "; ") + alphabet[c] + " "
-                    + ((int) tval) + "%";
+                    + ((fmt!=null) ? fmt.form(tval) : ((int) tval)) + "%";
           }
         }
         else
@@ -288,7 +309,7 @@ public class AAFrequency
                       * 100f
                       / profile[1][ignoreGapsInConsensusCalculation ? 1 : 0];
               mouseOver += ((p == 0) ? "" : "; ") + ((char[]) ca[c])[0]
-                      + " " + ((int) tval) + "%";
+                      + " " + ((fmt!=null) ? fmt.form(tval) : ((int) tval)) + "%";
               p++;
 
             }
@@ -298,7 +319,7 @@ public class AAFrequency
       }
       else
       {
-        mouseOver += ((int) value + "%");
+        mouseOver += ((fmt!=null) ? fmt.form(value) : ((int) value)) + "%";
       }
       consensus.annotations[i] = new Annotation(maxRes, mouseOver, ' ',
               value);
index 08bb3fd..948bdc1 100644 (file)
@@ -21,6 +21,7 @@ package jalview.analysis;
 
 import java.util.*;
 
+import jalview.util.Format;
 import jalview.datamodel.*;
 
 /**
@@ -299,7 +300,7 @@ public class StructureFrequency
   public static void completeConsensus(AlignmentAnnotation consensus,
           Hashtable[] hconsensus, int iStart, int width,
           boolean ignoreGapsInConsensusCalculation,
-          boolean includeAllConsSymbols)
+          boolean includeAllConsSymbols, long nseq)
   {
     float tval, value;
     if (consensus == null || consensus.annotations == null
@@ -309,6 +310,18 @@ public class StructureFrequency
       // initialised properly
       return;
     }
+    String fmtstr="%3.1f";
+    int precision=2;
+    while (nseq>100) {
+      precision++;
+      nseq/=10;
+    }
+    if (precision>2)
+    {
+      fmtstr = "%"+(2+precision)+"."+precision+"f";
+    }
+    Format fmt = new Format(fmtstr);
+    
     for (int i = iStart; i < width; i++)
     {
       Hashtable hci;
@@ -385,7 +398,7 @@ public class StructureFrequency
             tval = (vl[c] * 100f / profile[1][ignoreGapsInConsensusCalculation ? 1
                     : 0]);
             mouseOver += ((p == 0) ? "" : "; ") + (char) ((int[]) ca[c])[0]
-                    + (char) ((int[]) ca[c])[1] + " " + ((int) tval) + "%";
+                    + (char) ((int[]) ca[c])[1] + " " + fmt.form(tval) + "%";
             p++;
 
           }
@@ -395,7 +408,7 @@ public class StructureFrequency
       }
       else
       {
-        mouseOver += ((int) value + "%");
+        mouseOver += (fmt.form(value) + "%");
       }
       consensus.annotations[i] = new Annotation(maxRes, mouseOver, ' ',
               value);
diff --git a/src/jalview/api/AlignViewControllerI.java b/src/jalview/api/AlignViewControllerI.java
new file mode 100644 (file)
index 0000000..fc63fd6
--- /dev/null
@@ -0,0 +1,24 @@
+package jalview.api;
+
+/**
+ * prototype abstract controller for a Jalview alignment view
+ * @author jimp
+ * 
+ * All operations should return true if the view has changed as a result of the operation
+ * @param <ViewportI>
+ *
+ */
+public interface AlignViewControllerI<ViewportI>
+{
+
+  public boolean makeGroupsFromSelection();
+
+  public boolean createGroup();
+
+  public boolean unGroup();
+
+  public boolean deleteGroups();
+
+  public void setViewportAndAlignmentPanel(AlignViewportI viewport, AlignmentViewPanel alignPanel);
+
+}
index f42293d..5f759b8 100644 (file)
  */
 package jalview.api;
 
+import java.awt.Color;
 import java.util.Hashtable;
 import java.util.Map;
 
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.CigarArray;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.SequenceCollectionI;
+import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.schemes.ColourSchemeI;
 
@@ -155,4 +159,29 @@ public interface AlignViewportI
   void updateGroupAnnotationSettings(boolean applyGlobalSettings,
           boolean preserveNewGroupSettings);
 
+  void setSequenceColour(SequenceI seq, Color col);
+
+  Color getSequenceColour(SequenceI seq);
+
+  void updateSequenceIdColours();
+
+  SequenceGroup getSelectionGroup();
+
+  SequenceI[] getSequenceSelection();
+
+  void clearSequenceColours();
+
+  CigarArray getViewAsCigars(boolean selectedRegionOnly);
+
+  AlignmentView getAlignmentView(boolean selectedOnly);
+
+  AlignmentView getAlignmentView(boolean selectedOnly, boolean markGroups);
+
+  String[] getViewAsString(boolean selectedRegionOnly);
+
+  void setSelectionGroup(SequenceGroup sg);
+
+  char getGapCharacter();
+
+
 }
index ce1bae2..c51653d 100644 (file)
@@ -70,6 +70,8 @@ public class APopupMenu extends java.awt.PopupMenu implements
 
   MenuItem unGroupMenuItem = new MenuItem();
 
+  MenuItem createGroupMenuItem = new MenuItem();
+
   MenuItem nucleotideMenuItem = new MenuItem();
 
   Menu colourMenu = new Menu();
@@ -167,7 +169,11 @@ public class APopupMenu extends java.awt.PopupMenu implements
       displayNonconserved.setState(sg.getShowNonconserved());
       if (!ap.av.getAlignment().getGroups().contains(sg))
       {
+        menu1.setLabel(MessageManager.getString("action.edit_new_group"));
         groupMenu.remove(unGroupMenuItem);
+      } else {
+        menu1.setLabel(MessageManager.getString("action.edit_group"));
+        groupMenu.remove(createGroupMenuItem);
       }
 
     }
@@ -458,6 +464,11 @@ public class APopupMenu extends java.awt.PopupMenu implements
       unGroupMenuItem_actionPerformed();
     }
 
+    else if (source == createGroupMenuItem)
+    {
+      createGroupMenuItem_actionPerformed();
+    }
+
     else if (source == sequenceName)
     {
       editName();
@@ -730,7 +741,6 @@ public class APopupMenu extends java.awt.PopupMenu implements
 
   private void jbInit() throws Exception
   {
-    groupMenu.setLabel(MessageManager.getString("label.group"));
     groupMenu.setLabel(MessageManager.getString("label.selection"));
     sequenceFeature.addActionListener(this);
 
@@ -738,6 +748,9 @@ public class APopupMenu extends java.awt.PopupMenu implements
     unGroupMenuItem.setLabel(MessageManager.getString("action.remove_group"));
     unGroupMenuItem.addActionListener(this);
 
+    createGroupMenuItem.setLabel(MessageManager.getString("action.create_group"));
+    createGroupMenuItem.addActionListener(this);
+
     nucleotideMenuItem.setLabel(MessageManager.getString("label.nucleotide"));
     nucleotideMenuItem.addActionListener(this);
     conservationMenuItem.addItemListener(this);
@@ -770,10 +783,11 @@ public class APopupMenu extends java.awt.PopupMenu implements
     this.add(revealSeq);
     this.add(revealAll);
     // groupMenu.add(selSeqDetails);
-    groupMenu.add(editGroupName);
     groupMenu.add(editMenu);
     groupMenu.add(outputmenu);
     groupMenu.add(sequenceFeature);
+    groupMenu.add(createGroupMenuItem);
+    groupMenu.add(unGroupMenuItem);
     groupMenu.add(menu1);
 
     colourMenu.add(noColourmenuItem);
@@ -843,7 +857,7 @@ public class APopupMenu extends java.awt.PopupMenu implements
       seqMenu.add(pdb);
     }
     seqMenu.add(repGroup);
-    menu1.add(unGroupMenuItem);
+    menu1.add(editGroupName);
     menu1.add(colourMenu);
     menu1.add(showBoxes);
     menu1.add(showText);
@@ -1027,6 +1041,12 @@ public class APopupMenu extends java.awt.PopupMenu implements
     ap.paintAlignment(true);
   }
 
+  void createGroupMenuItem_actionPerformed()
+  {
+    getGroup(); // implicitly create group
+    refresh();
+  }
+
   public void showColourText_itemStateChanged()
   {
     getGroup().setColourText(showColourText.getState());
index 865f0d4..564f28c 100644 (file)
@@ -19,6 +19,7 @@ package jalview.appletgui;
 
 import jalview.analysis.AlignmentSorter;
 import jalview.analysis.Conservation;
+import jalview.api.AlignViewControllerI;
 import jalview.api.SequenceStructureBinding;
 import jalview.bin.JalviewLite;
 import jalview.commands.CommandI;
@@ -93,6 +94,7 @@ import java.util.Vector;
 public class AlignFrame extends EmbmenuFrame implements ActionListener,
         ItemListener, KeyListener
 {
+  public AlignViewControllerI avc;
   public AlignmentPanel alignPanel;
 
   public AlignViewport viewport;
@@ -121,7 +123,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
     viewport = new AlignViewport(al, applet);
     alignPanel = new AlignmentPanel(this, viewport);
-
+    avc = new jalview.controller.AlignViewController(viewport, alignPanel);
     viewport.updateConservation(alignPanel);
     viewport.updateConsensus(alignPanel);
 
@@ -542,6 +544,20 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
       }
       break;
 
+    case KeyEvent.VK_G:
+      if (evt.isControlDown())
+      {
+        if (evt.isShiftDown())
+        {
+          this.unGroup_actionPerformed();
+        }
+        else
+        {
+          this.createGroup_actionPerformed();
+        }
+      }
+      break;
+      
     case KeyEvent.VK_U:
       if (evt.isControlDown())
       {
@@ -1887,41 +1903,30 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
   protected void makeGrpsFromSelection_actionPerformed()
   {
-    if (viewport.getSelectionGroup() != null)
-    {
-      SequenceGroup[] gps = jalview.analysis.Grouping.makeGroupsFrom(
-              viewport.getSequenceSelection(),
-              viewport.getAlignmentView(true).getSequenceStrings(
-                      viewport.getGapCharacter()), viewport.getAlignment()
-                      .getGroups());
-      viewport.getAlignment().deleteAllGroups();
-      viewport.sequenceColours = null;
-      viewport.setSelectionGroup(null);
-      // set view properties for each group
-      for (int g = 0; g < gps.length; g++)
-      {
-        // gps[g].setShowunconserved(viewport.getShowUnconserved());
-        gps[g].setshowSequenceLogo(viewport.isShowSequenceLogo());
-        viewport.getAlignment().addGroup(gps[g]);
-        Color col = new Color((int) (Math.random() * 255),
-                (int) (Math.random() * 255), (int) (Math.random() * 255));
-        col = col.brighter();
-        for (SequenceI sq : gps[g].getSequences(null))
-          viewport.setSequenceColour(sq, col);
-      }
+    if (avc.makeGroupsFromSelection()) {
       PaintRefresher.Refresh(this, viewport.getSequenceSetId());
       alignPanel.updateAnnotation();
       alignPanel.paintAlignment(true);
     }
   }
 
+  protected void createGroup_actionPerformed()
+  {
+    avc.createGroup();
+  }
+  protected void unGroup_actionPerformed()
+  {
+    if (avc.unGroup())
+    {
+      alignPanel.alignmentChanged();
+    }
+  }
   protected void deleteGroups_actionPerformed()
   {
-    viewport.getAlignment().deleteAllGroups();
-    viewport.sequenceColours = null;
-    viewport.setSelectionGroup(null);
-
-    alignPanel.paintAlignment(true);
+    if (avc.deleteGroups())
+    {
+      alignPanel.alignmentChanged();
+    }
   }
 
   public void selectAllSequenceMenuItem_actionPerformed()
@@ -2866,6 +2871,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
 
   MenuItem grpsFromSelection = new MenuItem();
 
+  MenuItem createGroup = new MenuItem();
+
+  MenuItem unGroup = new MenuItem();
+
   MenuItem delete = new MenuItem();
 
   MenuItem copy = new MenuItem();
@@ -3074,6 +3083,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     deleteGroups.addActionListener(this);
     grpsFromSelection.setLabel(MessageManager.getString("action.make_groups_selection"));
     grpsFromSelection.addActionListener(this);
+    createGroup.setLabel(MessageManager.getString("action.create_group"));
+    unGroup.setLabel(MessageManager.getString("action.remove_group"));
     copy.setLabel(MessageManager.getString("action.copy"));
     copy.addActionListener(this);
     cut.setLabel(MessageManager.getString("action.cut"));
@@ -3302,6 +3313,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
     selectMenu.add(deselectAllSequenceMenuItem);
     selectMenu.add(invertSequenceMenuItem);
     selectMenu.add(invertColSel);
+    selectMenu.add(createGroup);
+    selectMenu.add(unGroup);
     selectMenu.add(grpsFromSelection);
     selectMenu.add(deleteGroups);
 
index cc04b58..9e4f071 100644 (file)
@@ -91,8 +91,6 @@ public class AlignViewport extends AlignmentViewport implements
 
   public jalview.bin.JalviewLite applet;
 
-  Hashtable sequenceColours;
-
   boolean MAC = false;
 
   Stack historyList = new Stack();
@@ -592,35 +590,6 @@ public class AlignViewport extends AlignmentViewport implements
     showHiddenMarkers = show;
   }
 
-  public Color getSequenceColour(SequenceI seq)
-  {
-    if (sequenceColours == null || !sequenceColours.containsKey(seq))
-    {
-      return Color.white;
-    }
-    else
-    {
-      return (Color) sequenceColours.get(seq);
-    }
-  }
-
-  public void setSequenceColour(SequenceI seq, Color col)
-  {
-    if (sequenceColours == null)
-    {
-      sequenceColours = new Hashtable();
-    }
-
-    if (col == null)
-    {
-      sequenceColours.remove(seq);
-    }
-    else
-    {
-      sequenceColours.put(seq, col);
-    }
-  }
-
   boolean centreColumnLabels;
 
   public boolean getCentreColumnLabels()
@@ -628,21 +597,6 @@ public class AlignViewport extends AlignmentViewport implements
     return centreColumnLabels;
   }
 
-  public void updateSequenceIdColours()
-  {
-
-    for (SequenceGroup sg : alignment.getGroups())
-    {
-      if (sg.idColour != null)
-      {
-        for (SequenceI s : sg.getSequences(getHiddenRepSequences()))
-        {
-          this.setSequenceColour(s, sg.idColour);
-        }
-      }
-    }
-  }
-
   public boolean followHighlight = true;
 
   public boolean getFollowHighlight()
index 5c62234..68ffd7a 100755 (executable)
@@ -578,7 +578,7 @@ public class TreeCanvas extends Panel implements MouseListener,
 
         av.setSelectionGroup(null);
         av.getAlignment().deleteAllGroups();
-        av.sequenceColours = null;
+        av.clearSequenceColours();
 
         colourGroups();
 
diff --git a/src/jalview/controller/AlignViewController.java b/src/jalview/controller/AlignViewController.java
new file mode 100644 (file)
index 0000000..16e8cdd
--- /dev/null
@@ -0,0 +1,100 @@
+package jalview.controller;
+
+import java.awt.Color;
+
+import jalview.api.AlignViewControllerI;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+
+public class AlignViewController implements AlignViewControllerI
+{
+  AlignViewportI viewport=null;
+  AlignmentViewPanel alignPanel=null;
+  @Override
+  protected void finalize() throws Throwable {
+    viewport = null;
+    alignPanel = null;
+  };
+  
+  public AlignViewController(AlignViewportI viewport,
+          AlignmentViewPanel alignPanel)
+  {
+    this.viewport=viewport;
+    this.alignPanel = alignPanel;
+  }
+  @Override
+  public void setViewportAndAlignmentPanel(AlignViewportI viewport,AlignmentViewPanel alignPanel)
+  {
+    this.alignPanel = alignPanel;
+    this.viewport = viewport;
+    
+  }
+  @Override
+  public boolean makeGroupsFromSelection()
+  {
+
+    if (viewport.getSelectionGroup() != null)
+    {
+      SequenceGroup[] gps = jalview.analysis.Grouping.makeGroupsFrom(
+              viewport.getSequenceSelection(),
+              viewport.getAlignmentView(true).getSequenceStrings(
+                      viewport.getGapCharacter()), viewport.getAlignment()
+                      .getGroups());
+      viewport.getAlignment().deleteAllGroups();
+      viewport.clearSequenceColours();
+      viewport.setSelectionGroup(null);
+      // set view properties for each group
+      for (int g = 0; g < gps.length; g++)
+      {
+        // gps[g].setShowunconserved(viewport.getShowUnconserved());
+        gps[g].setshowSequenceLogo(viewport.isShowSequenceLogo());
+        viewport.getAlignment().addGroup(gps[g]);
+        Color col = new Color((int) (Math.random() * 255),
+                (int) (Math.random() * 255), (int) (Math.random() * 255));
+        col = col.brighter();
+        for (SequenceI sq : gps[g].getSequences(null))
+          viewport.setSequenceColour(sq, col);
+      }
+      return true;
+    }
+    return false;
+}
+  @Override
+  public boolean createGroup()
+  {
+
+    SequenceGroup sg = viewport.getSelectionGroup();
+    if (sg!=null)
+    {
+        viewport.getAlignment().addGroup(sg);
+        return true;
+      } 
+    return false;
+  }
+  @Override
+  public boolean unGroup()
+  {
+    SequenceGroup sg = viewport.getSelectionGroup();
+    if (sg!=null)
+    {
+        viewport.getAlignment().deleteGroup(sg);
+        return true;
+    }
+    return false;
+  }
+  @Override
+  public boolean deleteGroups()
+  {
+    if (viewport.getAlignment().getGroups()!=null && viewport.getAlignment().getGroups().size()>0)
+    {
+    viewport.getAlignment().deleteAllGroups();
+    viewport.clearSequenceColours();
+    viewport.setSelectionGroup(null);
+    return true;
+    }
+    return false;
+  }
+    
+  }
index 580c850..fa063ff 100755 (executable)
@@ -707,6 +707,7 @@ public class Sequence implements SequenceI
     {
       tmp = new char[i];
       System.arraycopy(sequence, 0, tmp, 0, i);
+      j=sequence.length;
     }
     else
     {
@@ -715,6 +716,9 @@ public class Sequence implements SequenceI
       System.arraycopy(sequence, j, tmp, i, sequence.length - j);
     }
     boolean createNewDs = false;
+    // TODO: take a look at the new dataset creation validation method below -
+    // this could become time comsuming for large sequences - consider making it
+    // more efficient
     for (int s = i; s < j; s++)
     {
       if (jalview.schemes.ResidueProperties.aaIndex[sequence[s]] != 23)
index 65dc13f..5fcd2bf 100755 (executable)
@@ -493,7 +493,7 @@ public class SequenceGroup implements AnnotatedCollectionI
               endRes + 1, showSequenceLogo);
       if (consensus != null)
       {
-        _updateConsensusRow(cnsns);
+        _updateConsensusRow(cnsns, sequences.size());
       }
       if (cs != null)
       {
@@ -552,7 +552,7 @@ public class SequenceGroup implements AnnotatedCollectionI
 
   public Hashtable[] consensusData = null;
 
-  private void _updateConsensusRow(Hashtable[] cnsns)
+  private void _updateConsensusRow(Hashtable[] cnsns, long nseq)
   {
     if (consensus == null)
     {
@@ -569,7 +569,7 @@ public class SequenceGroup implements AnnotatedCollectionI
     consensus.annotations = new Annotation[aWidth]; // should be alignment width
 
     AAFrequency.completeConsensus(consensus, cnsns, startRes, endRes + 1,
-            ignoreGapsInConsensus, showSequenceLogo); // TODO: setting container
+            ignoreGapsInConsensus, showSequenceLogo, nseq); // TODO: setting container
                                                       // for
                                                       // ignoreGapsInConsensusCalculation);
   }
index 423f7b9..e2fe90c 100644 (file)
@@ -24,6 +24,7 @@ import jalview.analysis.CrossRef;
 import jalview.analysis.NJTree;
 import jalview.analysis.ParseProperties;
 import jalview.analysis.SequenceIdMatcher;
+import jalview.api.AlignViewControllerI;
 import jalview.bin.Cache;
 import jalview.commands.CommandI;
 import jalview.commands.EditCommand;
@@ -78,6 +79,7 @@ import jalview.schemes.ZappoColourScheme;
 import jalview.util.MessageManager;
 import jalview.ws.jws1.Discoverer;
 import jalview.ws.jws2.Jws2Discoverer;
+import jalview.ws.jws2.jabaws2.Jws2Instance;
 import jalview.ws.seqfetcher.DbSourceProxy;
 
 import java.awt.BorderLayout;
@@ -145,6 +147,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public AlignmentPanel alignPanel;
 
   AlignViewport viewport;
+  public AlignViewControllerI avc;
 
   Vector alignPanels = new Vector();
 
@@ -288,6 +293,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    */
   void init()
   {
+    avc = new jalview.controller.AlignViewController(viewport, alignPanel);
     if (viewport.getAlignmentConservationAnnotation() == null)
     {
       BLOSUM62Colour.setEnabled(false);
@@ -330,7 +336,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
 
     addKeyListener();
-
+    
   }
 
   /**
@@ -557,6 +563,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public void addAlignmentPanel(final AlignmentPanel ap, boolean newPanel)
   {
     ap.alignFrame = this;
+    avc = new jalview.controller.AlignViewController(viewport, alignPanel);
 
     alignPanels.addElement(ap);
 
@@ -734,7 +741,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     rnahelicesColour
             .setSelected(av.getGlobalColourScheme() instanceof jalview.schemes.RNAHelicesColour);
     setShowProductsEnabled();
-
     updateEditMenuBar();
   }
 
@@ -2132,12 +2138,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   protected void deleteGroups_actionPerformed(ActionEvent e)
   {
-    viewport.getAlignment().deleteAllGroups();
-    viewport.sequenceColours = null;
-    viewport.setSelectionGroup(null);
-    PaintRefresher.Refresh(this, viewport.getSequenceSetId());
-    alignPanel.updateAnnotation();
-    alignPanel.paintAlignment(true);
+    if (avc.deleteGroups()) {
+      PaintRefresher.Refresh(this, viewport.getSequenceSetId());
+      alignPanel.updateAnnotation();
+      alignPanel.paintAlignment(true);
+    }
   }
 
   /**
@@ -4149,6 +4154,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       @Override
       public void run()
       {
+        final List<JMenuItem> legacyItems=new ArrayList<JMenuItem>();
         try
         {
           System.err.println("Building ws menu again "
@@ -4180,28 +4186,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             // TODO: refactor to allow list of AbstractName/Handler bindings to
             // be
             // stored or retrieved from elsewhere
-            Vector msaws = null; // (Vector) Discoverer.services.get("MsaWS");
+            // No MSAWS used any more:
+            // Vector msaws = null; // (Vector) Discoverer.services.get("MsaWS");
             Vector secstrpr = (Vector) Discoverer.services
                     .get("SecStrPred");
-            Vector seqsrch = null; // (Vector)
-                                   // Discoverer.services.get("SeqSearch");
-            // TODO: move GUI generation code onto service implementation - so a
-            // client instance attaches itself to the GUI with method call like
-            // jalview.ws.MsaWSClient.bind(servicehandle, Desktop.instance,
-            // alignframe)
-            if (msaws != null)
-            {
-              // Add any Multiple Sequence Alignment Services
-              for (int i = 0, j = msaws.size(); i < j; i++)
-              {
-                final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle) msaws
-                        .get(i);
-                jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
-                        .getServiceClient(sh);
-                impl.attachWSMenuEntry(msawsmenu, me);
-
-              }
-            }
             if (secstrpr != null)
             {
               // Add any secondary structure prediction services
@@ -4211,35 +4199,23 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                         .get(i);
                 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
                         .getServiceClient(sh);
+                int p=secstrmenu.getItemCount();
                 impl.attachWSMenuEntry(secstrmenu, me);
-              }
-            }
-            if (seqsrch != null)
-            {
-              // Add any sequence search services
-              for (int i = 0, j = seqsrch.size(); i < j; i++)
-              {
-                final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle) seqsrch
-                        .elementAt(i);
-                jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
-                        .getServiceClient(sh);
-                impl.attachWSMenuEntry(seqsrchmenu, me);
+                int q=secstrmenu.getItemCount();
+                for (int litm=p;litm<q; litm++)
+                {
+                  legacyItems.add(secstrmenu.getItem(litm));
+                }
               }
             }
           }
-
+          
           // Add all submenus in the order they should appear on the web
           // services menu
           wsmenu.add(msawsmenu);
           wsmenu.add(secstrmenu);
           wsmenu.add(dismenu);
           wsmenu.add(analymenu);
-          // final ArrayList<JMenu> submens=new ArrayList<JMenu>();
-          // submens.add(msawsmenu);
-          // submens.add(secstrmenu);
-          // submens.add(dismenu);
-          // submens.add(analymenu);
-
           // No search services yet
           // wsmenu.add(seqsrchmenu);
 
@@ -4264,6 +4240,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                   webService.add(me.webServiceNoServices);
                 }
                 // TODO: move into separate menu builder class.
+                boolean new_sspred=false;
                 if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
                 {
                   Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
@@ -4272,6 +4249,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                     if (jws2servs.hasServices())
                     {
                       jws2servs.attachWSMenuEntry(webService, me);
+                      for (Jws2Instance sv:jws2servs.getServices()) {
+                        if (sv.description.toLowerCase().contains("jpred"))
+                        {
+                          for (JMenuItem jmi:legacyItems)
+                          {
+                            jmi.setVisible(false);
+                          }
+                        }
+                      }
+                      
                     }
                     if (jws2servs.isRunning())
                     {
@@ -4282,7 +4269,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                     }
                   }
                 }
-
                 build_urlServiceMenu(me.webService);
                 build_fetchdbmenu(webService);
                 for (JMenu item : wsmenu)
@@ -5020,6 +5006,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       alignPanel = (AlignmentPanel) alignPanels.elementAt(index);
       viewport = alignPanel.av;
+      avc.setViewportAndAlignmentPanel(viewport, alignPanel);
       setMenusFromViewport(viewport);
     }
   }
@@ -5460,34 +5447,31 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
   {
-    if (viewport.getSelectionGroup() != null)
-    {
-      SequenceGroup[] gps = jalview.analysis.Grouping.makeGroupsFrom(
-              viewport.getSequenceSelection(),
-              viewport.getAlignmentView(true).getSequenceStrings(
-                      viewport.getGapCharacter()), viewport.getAlignment()
-                      .getGroups());
-      viewport.getAlignment().deleteAllGroups();
-      viewport.sequenceColours = null;
-      viewport.setSelectionGroup(null);
-      // set view properties for each group
-      for (int g = 0; g < gps.length; g++)
-      {
-        gps[g].setShowNonconserved(viewport.getShowUnconserved());
-        gps[g].setshowSequenceLogo(viewport.isShowSequenceLogo());
-        viewport.getAlignment().addGroup(gps[g]);
-        Color col = new Color((int) (Math.random() * 255),
-                (int) (Math.random() * 255), (int) (Math.random() * 255));
-        col = col.brighter();
-        for (SequenceI s : gps[g].getSequences())
-          viewport.setSequenceColour(s, col);
-      }
+    if (avc.makeGroupsFromSelection()) {
       PaintRefresher.Refresh(this, viewport.getSequenceSetId());
       alignPanel.updateAnnotation();
       alignPanel.paintAlignment(true);
     }
   }
 
+  @Override
+  protected void createGroup_actionPerformed(ActionEvent e)
+  {
+    if (avc.createGroup())
+    {
+      alignPanel.alignmentChanged();
+    }
+  }
+
+  @Override
+  protected void unGroup_actionPerformed(ActionEvent e)
+  {
+    if (avc.unGroup())
+    {
+      alignPanel.alignmentChanged();
+    }
+  }
+
   /**
    * make the given alignmentPanel the currently selected tab
    * 
index 7a01b27..407fa94 100644 (file)
@@ -138,8 +138,6 @@ public class AlignViewport extends AlignmentViewport implements
 
   Stack redoList = new Stack();
 
-  Hashtable sequenceColours;
-
   int thresholdTextColour = 0;
 
   Color textColour = Color.black;
@@ -934,35 +932,6 @@ public class AlignViewport extends AlignmentViewport implements
     showHiddenMarkers = show;
   }
 
-  public Color getSequenceColour(SequenceI seq)
-  {
-    if (sequenceColours == null || !sequenceColours.containsKey(seq))
-    {
-      return Color.white;
-    }
-    else
-    {
-      return (Color) sequenceColours.get(seq);
-    }
-  }
-
-  public void setSequenceColour(SequenceI seq, Color col)
-  {
-    if (sequenceColours == null)
-    {
-      sequenceColours = new Hashtable();
-    }
-
-    if (col == null)
-    {
-      sequenceColours.remove(seq);
-    }
-    else
-    {
-      sequenceColours.put(seq, col);
-    }
-  }
-
   /**
    * returns the visible column regions of the alignment
    * 
@@ -1044,23 +1013,6 @@ public class AlignViewport extends AlignmentViewport implements
     centreColumnLabels = centrecolumnlabels;
   }
 
-  public void updateSequenceIdColours()
-  {
-    if (sequenceColours == null)
-    {
-      sequenceColours = new Hashtable();
-    }
-    for (SequenceGroup sg : alignment.getGroups())
-    {
-      if (sg.idColour != null)
-      {
-        for (SequenceI s : sg.getSequences(getHiddenRepSequences()))
-        {
-          sequenceColours.put(s, sg.idColour);
-        }
-      }
-    }
-  }
 
   /**
    * enable or disable the display of Database Cross References in the sequence
index 9e096be..ce731ad 100755 (executable)
@@ -665,7 +665,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
               && aa[row].annotations[res].description != null
               && aa[row].annotations[res].description.length() > 0)
       {
-        this.setToolTipText(aa[row].annotations[res].description);
+        this.setToolTipText("<html>"+JvSwingUtils.wrapTooltip(aa[row].annotations[res].description)+"</html>");
       }
       else
       {
index f77e64d..f4d1885 100644 (file)
@@ -648,8 +648,8 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
     // IF JALVIEW IS RUNNING HEADLESS
     // ///////////////////////////////////////////////
-    if (System.getProperty("java.awt.headless") != null
-            && System.getProperty("java.awt.headless").equals("true"))
+    if (instance == null || (System.getProperty("java.awt.headless") != null
+            && System.getProperty("java.awt.headless").equals("true")))
     {
       return;
     }
@@ -2435,7 +2435,9 @@ public class Desktop extends jalview.jbgui.GDesktop implements
   {
     boolean alive = true;
     Thread t0 = null, t1 = null, t2 = null;
-
+    // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
+    if (true)
+    {
     // todo: changesupport handlers need to be transferred
     if (discoverer == null)
     {
@@ -2445,28 +2447,31 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     }
     // JAL-940 - disabled JWS1 service configuration - always start discoverer
     // until we phase out completely
-    if (true)
-    {
       (t0 = new Thread(discoverer)).start();
     }
 
-    try
+    // ENFIN services are EOLed as of Jalview 2.8.1 release
+    if (false)
     {
-      if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
+      try
       {
-        // EnfinEnvision web service menu entries are rebuild every time the
-        // menu is shown, so no changeSupport events are needed.
-        jalview.ws.EnfinEnvision2OneWay.getInstance();
-        (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
-                .start();
+        if (Cache.getDefault("SHOW_ENFIN_SERVICES", true))
+        {
+          // EnfinEnvision web service menu entries are rebuild every time the
+          // menu is shown, so no changeSupport events are needed.
+          jalview.ws.EnfinEnvision2OneWay.getInstance();
+          (t1 = new Thread(jalview.ws.EnfinEnvision2OneWay.getInstance()))
+                  .start();
+        }
+      } catch (Exception e)
+      {
+        Cache.log
+                .info("Exception when trying to launch Envision2 workflow discovery.",
+                        e);
+        Cache.log.info(e.getStackTrace());
       }
-    } catch (Exception e)
-    {
-      Cache.log
-              .info("Exception when trying to launch Envision2 workflow discovery.",
-                      e);
-      Cache.log.info(e.getStackTrace());
     }
+
     if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
     {
       if (jalview.ws.jws2.Jws2Discoverer.getDiscoverer().isRunning())
index e88b190..2ec76a7 100644 (file)
@@ -429,7 +429,7 @@ public class Jalview2XML
     object.setVamsasModel(new jalview.schemabinding.version2.VamsasModel());
 
     object.setCreationDate(new java.util.Date(System.currentTimeMillis()));
-    object.setVersion(jalview.bin.Cache.getProperty("VERSION"));
+    object.setVersion(jalview.bin.Cache.getDefault("VERSION","Development Build"));
 
     jalview.datamodel.AlignmentI jal = av.getAlignment();
 
index 1a367c5..29370ac 100644 (file)
@@ -89,7 +89,7 @@ public class PopupMenu extends JPopupMenu
   JMenuItem sequenceSelDetails = new JMenuItem();
 
   SequenceI sequence;
-
+  JMenuItem createGroupMenuItem = new JMenuItem();
   JMenuItem unGroupMenuItem = new JMenuItem();
 
   JMenuItem outline = new JMenuItem();
@@ -392,9 +392,10 @@ public class PopupMenu extends JPopupMenu
     }
 
     SequenceGroup sg = ap.av.getSelectionGroup();
+    boolean isDefinedGroup = (sg!=null) ? ap.av.getAlignment().getGroups().contains(sg) : false;
 
     if (sg != null && sg.getSize() > 0)
-    {
+    {      
       groupName.setText("Name: " + sg.getName());
       groupName.setText("Edit name and description of current group.");
 
@@ -520,9 +521,15 @@ public class PopupMenu extends JPopupMenu
       editMenu.setVisible(false);
     }
 
-    if (!ap.av.getAlignment().getGroups().contains(sg))
+    if (!isDefinedGroup)
     {
+      createGroupMenuItem.setVisible(true);
       unGroupMenuItem.setVisible(false);
+      jMenu1.setText("Edit New Group");
+    } else {
+      createGroupMenuItem.setVisible(false);
+      unGroupMenuItem.setVisible(true);
+      jMenu1.setText("Edit Group");
     }
 
     if (seq == null)
@@ -935,6 +942,14 @@ public class PopupMenu extends JPopupMenu
         unGroupMenuItem_actionPerformed();
       }
     });
+    createGroupMenuItem.setText("Create Group");
+    createGroupMenuItem.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        createGroupMenuItem_actionPerformed();
+      }
+    });
 
     outline.setText("Border colour");
     outline.addActionListener(new java.awt.event.ActionListener()
@@ -1097,6 +1112,8 @@ public class PopupMenu extends JPopupMenu
     groupMenu.add(editMenu);
     groupMenu.add(outputMenu);
     groupMenu.add(sequenceFeature);
+    groupMenu.add(createGroupMenuItem);
+    groupMenu.add(unGroupMenuItem);
     groupMenu.add(jMenu1);
     sequenceMenu.add(sequenceName);
     sequenceMenu.add(sequenceDetails);
@@ -1153,7 +1170,6 @@ public class PopupMenu extends JPopupMenu
     pdbMenu.add(enterPDB);
     pdbMenu.add(discoverPDB);
     jMenu1.add(groupName);
-    jMenu1.add(unGroupMenuItem);
     jMenu1.add(colourMenu);
     jMenu1.add(showBoxes);
     jMenu1.add(showText);
@@ -1726,6 +1742,11 @@ public class PopupMenu extends JPopupMenu
     ap.av.setSelectionGroup(null);
     refresh();
   }
+  void createGroupMenuItem_actionPerformed()
+  {
+    getGroup(); // implicitly creates group - note - should apply defaults / use standard alignment window logic for this
+    refresh();
+  }
 
   /**
    * DOCUMENT ME!
index fbf6a91..c71b154 100644 (file)
@@ -130,8 +130,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       addMouseMotionListener(this);
       addMouseListener(this);
       addMouseWheelListener(this);
-      ssm = StructureSelectionManager
-              .getStructureSelectionManager(Desktop.instance);
+      ssm = av.getStructureSelectionManager();
       ssm.addStructureViewerListener(this);
       ssm.addSelectionListener(this);
     }
index ce44054..09708da 100755 (executable)
@@ -852,7 +852,7 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
         {
           aps[a].av.setSelectionGroup(null);
           aps[a].av.getAlignment().deleteAllGroups();
-          aps[a].av.sequenceColours = null;
+          aps[a].av.clearSequenceColours();
         }
         colourGroups();
       }
index de1487a..f070c84 100755 (executable)
@@ -182,6 +182,9 @@ public class GAlignFrame extends JInternalFrame
   public JCheckBoxMenuItem showSeqFeaturesHeight = new JCheckBoxMenuItem();
 
   JMenuItem deleteGroups = new JMenuItem();
+  
+  JMenuItem createGroup = new JMenuItem();
+  JMenuItem unGroup = new JMenuItem();
 
   JMenuItem delete = new JMenuItem();
 
@@ -618,7 +621,7 @@ public class GAlignFrame extends JInternalFrame
                 invertSequenceMenuItem_actionPerformed(e);
               }
             });
-    grpsFromSelection.setText("Make Groups for selection");
+    grpsFromSelection.setText("Make Groups For Selection");
     grpsFromSelection.addActionListener(new java.awt.event.ActionListener()
     {
       public void actionPerformed(ActionEvent e)
@@ -1200,6 +1203,28 @@ public class GAlignFrame extends JInternalFrame
         deleteGroups_actionPerformed(e);
       }
     });
+    createGroup.setText("Create group");
+    createGroup.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
+            java.awt.event.KeyEvent.VK_G, Toolkit.getDefaultToolkit()
+                    .getMenuShortcutKeyMask(), false));
+    createGroup.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        createGroup_actionPerformed(e);
+      }
+    });
+    unGroup.setText("Remove Group");
+    unGroup.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
+            java.awt.event.KeyEvent.VK_G,Toolkit.getDefaultToolkit()
+                    .getMenuShortcutKeyMask() | java.awt.event.KeyEvent.SHIFT_MASK, false));
+    unGroup.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        unGroup_actionPerformed(e);
+      }
+    });
     copy.setText("Copy");
     copy.setAccelerator(javax.swing.KeyStroke.getKeyStroke(
             java.awt.event.KeyEvent.VK_C, Toolkit.getDefaultToolkit()
@@ -1947,8 +1972,10 @@ public class GAlignFrame extends JInternalFrame
     selectMenu.add(deselectAllSequenceMenuItem);
     selectMenu.add(invertSequenceMenuItem);
     selectMenu.add(invertColSel);
-    selectMenu.add(deleteGroups);
+    selectMenu.add(createGroup);
+    selectMenu.add(unGroup);
     selectMenu.add(grpsFromSelection);
+    selectMenu.add(deleteGroups);
     // TODO - determine if the listenToViewSelections button is needed : see bug
     // JAL-574
     // selectMenu.addSeparator();
@@ -2308,6 +2335,14 @@ public class GAlignFrame extends JInternalFrame
   protected void deleteGroups_actionPerformed(ActionEvent e)
   {
   }
+  
+  protected void createGroup_actionPerformed(ActionEvent e)
+  {
+  }
+  
+  protected void unGroup_actionPerformed(ActionEvent e)
+  {
+  }
 
   protected void copy_actionPerformed(ActionEvent e)
   {
index 168aa31..a2ffff5 100644 (file)
@@ -66,7 +66,8 @@ public class RNAHelicesColour extends ResidueColourScheme
 
   public void refresh()
   {
-    if (lastrefresh != annotation._rnasecstr.hashCode()
+    if ((annotation._rnasecstr == null
+               || lastrefresh != annotation._rnasecstr.hashCode())
             && annotation.isValidStruc())
     {
       annotation.getRNAStruc();
index 25b65b3..cef7eb6 100644 (file)
@@ -97,8 +97,24 @@ public class RNAHelicesColourChooser
       return;
     }
 
-    currentAnnotation = av.getAlignment().getAlignmentAnnotation()[0];// annotations.getSelectedIndex()];
-
+    // This loop will find the first rna structure annotation by which to colour
+    //  the sequences.
+    AlignmentAnnotation[] annotations = av.getAlignment().getAlignmentAnnotation();
+    for (int i = 0; i < annotations.length; i++) {
+       
+       // is this a sensible way of determining type of annotation?
+       if (annotations[i].getRNAStruc() != null) { 
+               currentAnnotation = annotations[i];
+               break;
+       }
+    }
+    if (currentAnnotation == null)   
+    {
+       System.err.println("Jalview is about to try and colour by RNAHelices even"
+                       + " though there are no RNA secondary structure annotations present!");
+       currentAnnotation = av.getAlignment().getAlignmentAnnotation()[0];// annotations.getSelectedIndex()];
+    }
+    
     RNAHelicesColour rhc = null;
 
     rhc = new RNAHelicesColour(currentAnnotation);
index 7415712..8d684c1 100644 (file)
@@ -53,13 +53,25 @@ public class StructureSelectionManager
   }
 
   Hashtable mappingData = new Hashtable();
-
+  private static StructureSelectionManager nullProvider = null;
   public static StructureSelectionManager getStructureSelectionManager(
           StructureSelectionManagerProvider context)
   {
-    if (context==null)
-    {
-      throw new Error("Implementation error. Structure selection manager's context is 'null'", new NullPointerException("SSM context is null"));
+    if (context==null) { 
+      if (nullProvider == null)
+      {
+        if (instances != null)
+        {
+          throw new Error(
+                  "Implementation error. Structure selection manager's context is 'null'",
+                  new NullPointerException("SSM context is null"));
+        }
+        else
+        {
+          nullProvider = new StructureSelectionManager();
+        }
+        return nullProvider;
+      }
     }
     if (instances == null)
     {
@@ -68,7 +80,13 @@ public class StructureSelectionManager
     StructureSelectionManager instance = instances.get(context);
     if (instance == null)
     {
-      instances.put(context, instance = new StructureSelectionManager());
+      if (nullProvider!=null)
+      {
+        instance = nullProvider;
+      } else {
+        instance = new StructureSelectionManager();
+      }
+      instances.put(context, instance);
     }
     return instance;
   }
index d65486d..cceff86 100644 (file)
@@ -40,6 +40,7 @@ import jalview.workers.AlignCalcManager;
 import jalview.workers.ConsensusThread;
 import jalview.workers.StrucConsensusThread;
 
+import java.awt.Color;
 import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.List;
@@ -594,6 +595,7 @@ public abstract class AlignmentViewport implements AlignViewportI
    * 
    * @return null or the currently selected sequence region
    */
+  @Override
   public SequenceGroup getSelectionGroup()
   {
     return selectionGroup;
@@ -606,6 +608,7 @@ public abstract class AlignmentViewport implements AlignViewportI
    *          - group holding references to sequences in this alignment view
    * 
    */
+  @Override
   public void setSelectionGroup(SequenceGroup sg)
   {
     selectionGroup = sg;
@@ -781,6 +784,8 @@ public abstract class AlignmentViewport implements AlignViewportI
 
   protected boolean showConsensus = true;
 
+  Hashtable sequenceColours;
+
   /**
    * Property change listener for changes in alignment
    * 
@@ -1054,6 +1059,7 @@ public abstract class AlignmentViewport implements AlignViewportI
    * 
    * @return array of references to sequence objects
    */
+  @Override
   public SequenceI[] getSequenceSelection()
   {
     SequenceI[] sequences = null;
@@ -1076,6 +1082,7 @@ public abstract class AlignmentViewport implements AlignViewportI
    * 
    * @return String[]
    */
+  @Override
   public jalview.datamodel.CigarArray getViewAsCigars(
           boolean selectedRegionOnly)
   {
@@ -1092,6 +1099,7 @@ public abstract class AlignmentViewport implements AlignViewportI
    *          boolean true to just return the selected view
    * @return AlignmentView
    */
+  @Override
   public jalview.datamodel.AlignmentView getAlignmentView(
           boolean selectedOnly)
   {
@@ -1110,6 +1118,7 @@ public abstract class AlignmentViewport implements AlignViewportI
    *          is true)
    * @return AlignmentView
    */
+  @Override
   public jalview.datamodel.AlignmentView getAlignmentView(
           boolean selectedOnly, boolean markGroups)
   {
@@ -1125,6 +1134,7 @@ public abstract class AlignmentViewport implements AlignViewportI
    * 
    * @return String[]
    */
+  @Override
   public String[] getViewAsString(boolean selectedRegionOnly)
   {
     String[] selection = null;
@@ -1535,4 +1545,60 @@ public abstract class AlignmentViewport implements AlignViewportI
     oldrfs.clear();
   }
 
+  @Override
+  public Color getSequenceColour(SequenceI seq)
+  {
+    Color sqc=Color.white;
+    if (sequenceColours != null)
+    {
+      sqc = (Color) sequenceColours.get(seq);
+      if (sqc == null) {
+        sqc = Color.white;
+      }
+    }
+    return sqc;
+  }
+
+  @Override
+  public void setSequenceColour(SequenceI seq, Color col)
+  {
+    if (sequenceColours == null)
+    {
+      sequenceColours = new Hashtable();
+    }
+
+    if (col == null)
+    {
+      sequenceColours.remove(seq);
+    }
+    else
+    {
+      sequenceColours.put(seq, col);
+    }
+  }
+
+  @Override
+  public void updateSequenceIdColours()
+  {
+    if (sequenceColours == null)
+    {
+      sequenceColours = new Hashtable();
+    }
+    for (SequenceGroup sg : alignment.getGroups())
+    {
+      if (sg.idColour != null)
+      {
+        for (SequenceI s : sg.getSequences(getHiddenRepSequences()))
+        {
+          sequenceColours.put(s, sg.idColour);
+        }
+      }
+    }
+  }
+
+  @Override
+  public void clearSequenceColours()
+  {
+    sequenceColours = null;
+  };
 }
index 343e64d..c2b4d66 100644 (file)
@@ -24,6 +24,7 @@ import jalview.api.AlignmentViewPanel;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.SequenceI;
 import jalview.schemes.ColourSchemeI;
 
 import java.util.Hashtable;
@@ -31,6 +32,8 @@ import java.util.Hashtable;
 public class ConsensusThread extends AlignCalcWorker implements
         AlignCalcWorkerI
 {
+  private long nseq=-1;
+
   public ConsensusThread(AlignViewportI alignViewport,
           AlignmentViewPanel alignPanel)
   {
@@ -94,7 +97,9 @@ public class ConsensusThread extends AlignCalcWorker implements
       hconsensus = new Hashtable[aWidth];
       try
       {
-        AAFrequency.calculate(alignment.getSequencesArray(), 0,
+        SequenceI aseqs[] = alignment.getSequencesArray();
+        nseq = aseqs.length;
+        AAFrequency.calculate(aseqs, 0,
                 alignment.getWidth(), hconsensus, true);
       } catch (ArrayIndexOutOfBoundsException x)
       {
@@ -150,7 +155,7 @@ public class ConsensusThread extends AlignCalcWorker implements
     {
       AAFrequency.completeConsensus(consensus, hconsensus, 0,
               hconsensus.length, alignViewport.getIgnoreGapsConsensus(),
-              alignViewport.isShowSequenceLogo());
+              alignViewport.isShowSequenceLogo(), nseq);
     }
   }
 }
index 86c3336..25e5cde 100644 (file)
@@ -26,6 +26,7 @@ import jalview.api.AlignmentViewPanel;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
+import jalview.datamodel.SequenceI;
 
 public class StrucConsensusThread extends AlignCalcWorker implements
         AlignCalcWorkerI
@@ -40,6 +41,8 @@ public class StrucConsensusThread extends AlignCalcWorker implements
 
   Hashtable[] hStrucConsensus;
 
+  private long nseq=-1;
+
   @Override
   public void run()
   {
@@ -107,8 +110,10 @@ public class StrucConsensusThread extends AlignCalcWorker implements
 
       try
       {
-        jalview.analysis.StructureFrequency.calculate(
-                alignment.getSequencesArray(), 0, alignment.getWidth(),
+        final SequenceI[] arr=
+                alignment.getSequencesArray();
+        nseq = arr.length;
+        jalview.analysis.StructureFrequency.calculate(arr, 0, alignment.getWidth(),
                 hStrucConsensus, true, rnaStruc);
       } catch (ArrayIndexOutOfBoundsException x)
       {
@@ -159,7 +164,7 @@ public class StrucConsensusThread extends AlignCalcWorker implements
       StructureFrequency.completeConsensus(strucConsensus, hStrucConsensus,
               0, hStrucConsensus.length,
               alignViewport.getIgnoreGapsConsensus(),
-              alignViewport.isShowSequenceLogo());
+              alignViewport.isShowSequenceLogo(), nseq);
     }
   }
 
index 7f3847b..2750293 100644 (file)
@@ -23,6 +23,7 @@ import jalview.gui.AlignmentPanel;
 import jalview.ws.jws2.dm.AAConSettings;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
 import jalview.ws.params.WsParamSetI;
+import jalview.ws.uimodel.AlignAnalysisUIText;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -48,23 +49,6 @@ public class AAConClient extends JabawsAlignCalcWorker
     initViewportParams();
   }
 
-  protected void initViewportParams()
-  {
-    ((jalview.gui.AlignViewport) alignViewport).setCalcIdSettingsFor(
-            getCalcId(),
-            new AAConSettings(true, service, this.preset,
-                    (arguments != null) ? JabaParamStore
-                            .getJwsArgsfromJaba(arguments) : null), true);
-  }
-
-  @Override
-  public void updateParameters(WsParamSetI newpreset,
-          java.util.List<Argument> newarguments)
-  {
-    super.updateParameters(newpreset, newarguments);
-    initViewportParams();
-  };
-
   public String getServiceActionText()
   {
     return "calculating Amino acid consensus using AACon service";
@@ -114,17 +98,21 @@ public class AAConClient extends JabawsAlignCalcWorker
     }
   }
 
+  @Override
   public String getCalcId()
   {
-    return SequenceAnnotationWSClient.AAConCalcId;
+    return CALC_ID;
   }
+  private static String CALC_ID="jabaws2.AACon";
 
-  public static void removeAAConsAnnotation(AlignmentPanel alignPanel)
+  public static AlignAnalysisUIText getAlignAnalysisUITest()
   {
-    for (AlignmentAnnotation aa : alignPanel.getAlignment().findAnnotation(
-            SequenceAnnotationWSClient.AAConCalcId))
-    {
-      alignPanel.getAlignment().deleteAnnotation(aa);
-    }
+    return new AlignAnalysisUIText(
+            compbio.ws.client.Services.AAConWS.toString(),
+            jalview.ws.jws2.AAConClient.class, CALC_ID, false, true, true,
+            "AACon Calculations",
+            "When checked, AACon calculations are updated automatically.",
+            "Change AACon Settings...",
+            "Modify settings for AACon calculations.");
   }
 }
index 3c19dc5..8db1358 100644 (file)
@@ -41,7 +41,7 @@ import compbio.data.sequence.Score;
 import compbio.data.sequence.ScoreManager.ScoreHolder;
 import compbio.metadata.Argument;
 
-public class AADisorderClient extends JabawsAlignCalcWorker implements
+public class AADisorderClient extends JabawsCalcWorker implements
         AlignCalcWorkerI
 {
 
index 73d5654..fe61ff3 100644 (file)
@@ -22,6 +22,7 @@ package jalview.ws.jws2;
 
 import jalview.bin.Cache;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.jws2.jabaws2.Jws2InstanceFactory;
 
 import java.util.HashSet;
 import java.util.Set;
@@ -75,7 +76,7 @@ public class JabaWsServerQuery implements Runnable
   { Services.ClustalWS, Services.MuscleWS, Services.MafftWS,
       Services.ProbconsWS, Services.TcoffeeWS, Services.AAConWS,
       Services.DisemblWS, Services.GlobPlotWS, Services.IUPredWS,
-      Services.JronnWS };
+      Services.JronnWS, Services.RNAalifoldWS };
 
   /*
    * (non-Javadoc)
@@ -115,7 +116,14 @@ public class JabaWsServerQuery implements Runnable
 
             jabasws2 = true;
             srv_set = registry.getSupportedServices();
+            
+            // dan test
+            System.out.println("registry.getSupportedServices: " + srv_set.toString());
+            
             svccategories = registry.getServiceCategories();
+            
+            // dan test
+//            System.out.println("registry.getServiceCategories: " + svccategories.toString());
 
           }
         } catch (Exception ex)
@@ -170,12 +178,12 @@ public class JabaWsServerQuery implements Runnable
 
                 String description = registry.getServiceDescription(srv);
 
-                svc = new Jws2Instance(jwsservers, srv.toString(),
+                svc = Jws2InstanceFactory.newJws2Instance(jwsservers, srv.toString(),
                         cat.name, description, service);
               }
               if (svc == null)
               {
-                svc = new Jws2Instance(jwsservers, srv.toString(),
+                svc = Jws2InstanceFactory.newJws2Instance(jwsservers, srv.toString(),
                         cat.name, "JABAWS 1 Alignment Service", service);
               }
               jws2Discoverer.addService(jwsservers, svc);
index 720e76a..baafc8a 100644 (file)
  */
 package jalview.ws.jws2;
 
-import jalview.analysis.AlignSeq;
-import jalview.analysis.SeqsetUtils;
 import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.Annotation;
-import jalview.datamodel.SequenceI;
 import jalview.gui.AlignFrame;
-import jalview.gui.IProgressIndicator;
 import jalview.workers.AlignCalcWorker;
-import jalview.ws.jws2.dm.JabaWsParamSet;
+import jalview.ws.jws2.dm.AAConSettings;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
 import jalview.ws.params.WsParamSetI;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 
 import compbio.data.msa.SequenceAnnotation;
-import compbio.data.sequence.FastaSequence;
-import compbio.data.sequence.Score;
-import compbio.data.sequence.ScoreManager;
 import compbio.metadata.Argument;
-import compbio.metadata.ChunkHolder;
-import compbio.metadata.JobStatus;
-import compbio.metadata.JobSubmissionException;
-import compbio.metadata.Option;
-import compbio.metadata.ResultNotAvailableException;
-import compbio.metadata.WrongParameterException;
 
-public abstract class JabawsAlignCalcWorker extends AlignCalcWorker
+public abstract class JabawsAlignCalcWorker extends JabawsCalcWorker
 {
-  Jws2Instance service;
-
-  @SuppressWarnings("unchecked")
-  protected SequenceAnnotation aaservice;
-
-  protected ScoreManager scoremanager;
-
-  protected WsParamSetI preset;
-
-  protected List<Argument> arguments;
 
   public JabawsAlignCalcWorker(AlignViewportI alignViewport,
           AlignmentViewPanel alignPanel)
   {
     super(alignViewport, alignPanel);
   }
-
-  IProgressIndicator guiProgress;
-
+  
+  
+  
+  
   public JabawsAlignCalcWorker(Jws2Instance service, AlignFrame alignFrame,
           WsParamSetI preset, List<Argument> paramset)
   {
-    this(alignFrame.getCurrentView(), alignFrame.alignPanel);
-    this.guiProgress = alignFrame;
-    this.preset = preset;
-    this.arguments = paramset;
-    this.service = service;
-    aaservice = (SequenceAnnotation) service.service;
-
-  }
-
-  public WsParamSetI getPreset()
-  {
-    return preset;
-  }
-
-  public List<Argument> getArguments()
-  {
-    return arguments;
-  }
-
-  /**
-   * reconfigure and restart the AAConClient. This method will spawn a new
-   * thread that will wait until any current jobs are finished, modify the
-   * parameters and restart the conservation calculation with the new values.
-   * 
-   * @param newpreset
-   * @param newarguments
-   */
-  public void updateParameters(final WsParamSetI newpreset,
-          final List<Argument> newarguments)
-  {
-    preset = newpreset;
-    arguments = newarguments;
-    calcMan.startWorker(this);
-  }
-
-  public List<Option> getJabaArguments()
-  {
-    List<Option> newargs = new ArrayList<Option>();
-    if (preset != null && preset instanceof JabaWsParamSet)
-    {
-      newargs.addAll(((JabaWsParamSet) preset).getjabaArguments());
-    }
-    if (arguments != null && arguments.size() > 0)
-    {
-      for (Argument rg : arguments)
-      {
-        if (Option.class.isAssignableFrom(rg.getClass()))
-        {
-          newargs.add((Option) rg);
-        }
-      }
-    }
-    return newargs;
+    super(service, alignFrame, preset, paramset);
   }
 
-  @Override
-  public void run()
-  {
-    if (aaservice == null)
-    {
-      return;
-    }
-    long progressId = -1;
-
-    int serverErrorsLeft = 3;
-
-    String rslt = "JOB NOT DEFINED";
-    StringBuffer msg = new StringBuffer();
-    try
-    {
-      if (checkDone())
-      {
-        return;
-      }
-      List<compbio.data.sequence.FastaSequence> seqs = getInputSequences(alignViewport
-              .getAlignment());
-
-      if (seqs == null)
-      {
-        calcMan.workerComplete(this);
-        return;
-      }
-
-      AlignmentAnnotation[] aa = alignViewport.getAlignment()
-              .getAlignmentAnnotation();
-      if (guiProgress != null)
-      {
-        guiProgress.setProgressBar("JABA " + getServiceActionText(),
-                progressId = System.currentTimeMillis());
-      }
-      if (preset == null && arguments == null)
-      {
-        rslt = aaservice.analize(seqs);
-      }
-      else
-      {
-        try
-        {
-          rslt = aaservice.customAnalize(seqs, getJabaArguments());
-        } catch (WrongParameterException x)
-        {
-          throw new JobSubmissionException(
-                  "Invalid parameter set. Check Jalview implementation.", x);
-
-        }
-      }
-      boolean finished = false;
-      long rpos = 0;
-      do
-      {
-        JobStatus status = aaservice.getJobStatus(rslt);
-        if (status.equals(JobStatus.FINISHED))
-        {
-          finished = true;
-        }
-        if (calcMan.isPending(this) && this instanceof AAConClient)
-        {
-          finished = true;
-          // cancel this job and yield to the new job
-          try
-          {
-            if (aaservice.cancelJob(rslt))
-            {
-              System.err.println("Cancelled AACon job: " + rslt);
-            }
-            else
-            {
-              System.err.println("FAILED TO CANCEL AACon job: " + rslt);
-            }
-
-          } catch (Exception x)
-          {
-
-          }
-
-          return;
-        }
-        long cpos;
-        ChunkHolder stats = null;
-        do
-        {
-          cpos = rpos;
-          boolean retry = false;
-          do
-          {
-            try
-            {
-              stats = aaservice.pullExecStatistics(rslt, rpos);
-            } catch (Exception x)
-            {
-
-              if (x.getMessage().contains(
-                      "Position in a file could not be negative!"))
-              {
-                // squash index out of bounds exception- seems to happen for
-                // disorder predictors which don't (apparently) produce any
-                // progress information and JABA server throws an exception
-                // because progress length is -1.
-                stats = null;
-              }
-              else
-              {
-                if (--serverErrorsLeft > 0)
-                {
-                  retry = true;
-                  try
-                  {
-                    Thread.sleep(200);
-                  } catch (InterruptedException q)
-                  {
-                  }
-                  ;
-                }
-                else
-                {
-                  throw x;
-                }
-              }
-            }
-          } while (retry);
-          if (stats != null)
-          {
-            System.out.print(stats.getChunk());
-            msg.append(stats);
-            rpos = stats.getNextPosition();
-          }
-        } while (stats != null && rpos > cpos);
-
-        if (!finished && status.equals(JobStatus.FAILED))
-        {
-          try
-          {
-            Thread.sleep(200);
-          } catch (InterruptedException x)
-          {
-          }
-          ;
-        }
-      } while (!finished);
-      if (serverErrorsLeft > 0)
-      {
-        try
-        {
-          Thread.sleep(200);
-        } catch (InterruptedException x)
-        {
-        }
-        ;
-        scoremanager = aaservice.getAnnotation(rslt);
-        if (scoremanager != null)
-        {
-          jalview.bin.Cache.log
-                  .debug("Updating result annotation from Job " + rslt
-                          + " at " + service.getUri());
-          updateResultAnnotation(true);
-          ap.adjustAnnotationHeight();
-        }
-      }
-    }
 
-    catch (JobSubmissionException x)
-    {
 
-      System.err.println("submission error with " + getServiceActionText()
-              + " :");
-      x.printStackTrace();
-      calcMan.workerCannotRun(this);
-    } catch (ResultNotAvailableException x)
-    {
-      System.err.println("collection error:\nJob ID: " + rslt);
-      x.printStackTrace();
-      calcMan.workerCannotRun(this);
-
-    } catch (OutOfMemoryError error)
-    {
-      calcMan.workerCannotRun(this);
-
-      // consensus = null;
-      // hconsensus = null;
-      ap.raiseOOMWarning(getServiceActionText(), error);
-    } catch (Exception x)
-    {
-      calcMan.workerCannotRun(this);
-
-      // consensus = null;
-      // hconsensus = null;
-      System.err
-              .println("Blacklisting worker due to unexpected exception:");
-      x.printStackTrace();
-    } finally
-    {
-
-      calcMan.workerComplete(this);
-      if (ap != null)
-      {
-        calcMan.workerComplete(this);
-        if (guiProgress != null && progressId != -1)
-        {
-          guiProgress.setProgressBar("", progressId);
-        }
-        ap.paintAlignment(true);
-      }
-      if (msg.length() > 0)
-      {
-        // TODO: stash message somewhere in annotation or alignment view.
-        // code below shows result in a text box popup
-        /*
-         * jalview.gui.CutAndPasteTransfer cap = new
-         * jalview.gui.CutAndPasteTransfer(); cap.setText(msg.toString());
-         * jalview.gui.Desktop.addInternalFrame(cap,
-         * "Job Status for "+getServiceActionText(), 600, 400);
-         */
-      }
-    }
-
-  }
-
-  @Override
-  public void updateAnnotation()
-  {
-    updateResultAnnotation(false);
-  }
-
-  public abstract void updateResultAnnotation(boolean immediate);
-
-  public abstract String getServiceActionText();
-
-  boolean submitGaps = true;
-
-  boolean alignedSeqs = true;
-
-  boolean nucleotidesAllowed = false;
-
-  boolean proteinAllowed = false;
 
   /**
-   * record sequences for mapping result back to afterwards
+   * Recover any existing parameters for this service 
    */
-  protected boolean bySequence = false;
-
-  Map<String, SequenceI> seqNames;
-
-  boolean[] gapMap;
-
-  int realw;
-
-  public List<FastaSequence> getInputSequences(AlignmentI alignment)
+  protected void initViewportParams()
   {
-    if (alignment == null || alignment.getWidth() <= 0
-            || alignment.getSequences() == null
-            // || (alignedSeqs && !alignment.isAligned() && !submitGaps)
-            || alignment.isNucleotide() ? !nucleotidesAllowed
-            : !proteinAllowed)
-    {
-      return null;
-    }
-    List<compbio.data.sequence.FastaSequence> seqs = new ArrayList<compbio.data.sequence.FastaSequence>();
-
-    int minlen = 10;
-    int ln = -1;
-    if (bySequence)
-    {
-      seqNames = new HashMap<String, SequenceI>();
-    }
-    gapMap = new boolean[0];
-    for (SequenceI sq : ((List<SequenceI>) alignment.getSequences()))
-    {
-      if (sq.getEnd() - sq.getStart() > minlen - 1)
-      {
-        String newname = SeqsetUtils.unique_name(seqs.size() + 1);
-        // make new input sequence with or without gaps
-        if (seqNames != null)
-        {
-          seqNames.put(newname, sq);
-        }
-        FastaSequence seq;
-        if (submitGaps)
-        {
-          seqs.add(seq = new compbio.data.sequence.FastaSequence(newname,
-                  sq.getSequenceAsString()));
-          if (gapMap == null || gapMap.length < seq.getSequence().length())
-          {
-            boolean[] tg = gapMap;
-            gapMap = new boolean[seq.getLength()];
-            System.arraycopy(tg, 0, gapMap, 0, tg.length);
-            for (int p = tg.length; p < gapMap.length; p++)
-            {
-              gapMap[p] = false; // init as a gap
-            }
-          }
-          for (int apos : sq.gapMap())
-          {
-            gapMap[apos] = true; // aligned.
-          }
-        }
-        else
-        {
-          seqs.add(seq = new compbio.data.sequence.FastaSequence(newname,
-                  AlignSeq.extractGaps(jalview.util.Comparison.GapChars,
-                          sq.getSequenceAsString())));
-        }
-        if (seq.getSequence().length() > ln)
-        {
-          ln = seq.getSequence().length();
-        }
-      }
-    }
-    if (alignedSeqs && submitGaps)
-    {
-      realw = 0;
-      for (int i = 0; i < gapMap.length; i++)
-      {
-        if (gapMap[i])
-        {
-          realw++;
-        }
-      }
-      // try real hard to return something submittable
-      // TODO: some of AAcon measures need a minimum of two or three amino
-      // acids at each position, and AAcon doesn't gracefully degrade.
-      for (int p = 0; p < seqs.size(); p++)
-      {
-        FastaSequence sq = seqs.get(p);
-        int l = sq.getSequence().length();
-        // strip gapped columns
-        char[] padded = new char[realw], orig = sq.getSequence()
-                .toCharArray();
-        for (int i = 0, pp = 0; i < realw; pp++)
-        {
-          if (gapMap[pp])
-          {
-            if (orig.length > pp)
-            {
-              padded[i++] = orig[pp];
-            }
-            else
-            {
-              padded[i++] = '-';
-            }
-          }
-        }
-        seqs.set(p, new compbio.data.sequence.FastaSequence(sq.getId(),
-                new String(padded)));
-      }
-    }
-    return seqs;
+    ((jalview.gui.AlignViewport) alignViewport).setCalcIdSettingsFor(
+            getCalcId(),
+            new AAConSettings(true, service, this.preset,
+                    (arguments != null) ? JabaParamStore
+                            .getJwsArgsfromJaba(arguments) : null), true);
   }
 
   /**
-   * notify manager that we have started, and wait for a free calculation slot
    * 
-   * @return true if slot is obtained and work still valid, false if another
-   *         thread has done our work for us.
+   * @return
    */
-  boolean checkDone()
-  {
-    calcMan.notifyStart(this);
-    ap.paintAlignment(false);
-    while (!calcMan.notifyWorking(this))
-    {
-      if (calcMan.isWorking(this))
-      {
-        return true;
-      }
-      try
-      {
-        if (ap != null)
-        {
-          ap.paintAlignment(false);
-        }
-
-        Thread.sleep(200);
-      } catch (Exception ex)
-      {
-        ex.printStackTrace();
-      }
-    }
-    if (alignViewport.isClosed())
-    {
-      abortAndDestroy();
-      return true;
-    }
-    return false;
-  }
-
-  protected void createAnnotationRowsForScores(
-          List<AlignmentAnnotation> ourAnnot, String calcId, int alWidth,
-          Score scr)
-  {
-    // simple annotation row
-    AlignmentAnnotation annotation = alignViewport.getAlignment()
-            .findOrCreateAnnotation(scr.getMethod(), calcId, true, null,
-                    null);
-    if (alWidth == gapMap.length) // scr.getScores().size())
-    {
-      constructAnnotationFromScore(annotation, 0, alWidth, scr);
-      ourAnnot.add(annotation);
-    }
-  }
+  public abstract String getCalcId();
 
-  protected AlignmentAnnotation createAnnotationRowsForScores(
-          List<AlignmentAnnotation> ourAnnot, String typeName,
-          String calcId, SequenceI dseq, int base, Score scr)
-  {
-    System.out.println("Creating annotation on dseq:" + dseq.getStart()
-            + " base is " + base + " and length=" + dseq.getLength()
-            + " == " + scr.getScores().size());
-    // AlignmentAnnotation annotation = new AlignmentAnnotation(
-    // scr.getMethod(), typeName, new Annotation[]
-    // {}, 0, -1, AlignmentAnnotation.LINE_GRAPH);
-    // annotation.setCalcId(calcId);
-    AlignmentAnnotation annotation = alignViewport.getAlignment()
-            .findOrCreateAnnotation(typeName, calcId, false, dseq, null);
-    constructAnnotationFromScore(annotation, 0, dseq.getLength(), scr);
-    annotation.createSequenceMapping(dseq, base, false);
-    annotation.adjustForAlignment();
-    dseq.addAlignmentAnnotation(annotation);
-    ourAnnot.add(annotation);
-    return annotation;
-  }
 
-  private void constructAnnotationFromScore(AlignmentAnnotation annotation,
-          int base, int alWidth, Score scr)
-  {
-    Annotation[] elm = new Annotation[alWidth];
-    Iterator<Float> vals = scr.getScores().iterator();
-    float m = 0f, x = 0f;
-    for (int i = 0; vals.hasNext(); i++)
-    {
-      float val = vals.next().floatValue();
-      if (i == 0)
-      {
-        m = val;
-        x = val;
-      }
-      else
-      {
-        if (m > val)
-        {
-          m = val;
-        }
-        ;
-        if (x < val)
-        {
-          x = val;
-        }
-      }
-      // if we're at a gapped column then skip to next ungapped position
-      if (gapMap != null && gapMap.length > 0)
-      {
-        while (!gapMap[i])
-        {
-          elm[i++] = new Annotation("", "", ' ', Float.NaN);
-        }
-      }
-      elm[i] = new Annotation("", "" + val, ' ', val);
-    }
 
-    annotation.annotations = elm;
-    annotation.belowAlignment = true;
-    if (x < 0)
-    {
-      x = 0;
-    }
-    x += (x - m) * 0.1;
-    annotation.graphMax = x;
-    annotation.graphMin = m;
-    annotation.validateRangeAndDisplay();
-  }
 
-  protected void updateOurAnnots(List<AlignmentAnnotation> ourAnnot)
+  @Override
+  public void updateParameters(WsParamSetI newpreset, java.util.List<Argument> newarguments)
   {
-    List<AlignmentAnnotation> our = ourAnnots;
-    ourAnnots = ourAnnot;
-    AlignmentI alignment = alignViewport.getAlignment();
-    if (our != null)
-    {
-      if (our.size() > 0)
-      {
-        for (AlignmentAnnotation an : our)
-        {
-          if (!ourAnnots.contains(an))
-          {
-            // remove the old annotation
-            alignment.deleteAnnotation(an);
-          }
-        }
-      }
-      our.clear();
-
-      ap.adjustAnnotationHeight();
-    }
+    super.updateParameters(newpreset, newarguments);
+    initViewportParams();
   }
 }
diff --git a/src/jalview/ws/jws2/JabawsCalcWorker.java b/src/jalview/ws/jws2/JabawsCalcWorker.java
new file mode 100644 (file)
index 0000000..4a78209
--- /dev/null
@@ -0,0 +1,599 @@
+package jalview.ws.jws2;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import compbio.data.msa.SequenceAnnotation;
+import compbio.data.sequence.FastaSequence;
+import compbio.data.sequence.Score;
+import compbio.data.sequence.ScoreManager;
+import compbio.metadata.Argument;
+import compbio.metadata.ChunkHolder;
+import compbio.metadata.JobStatus;
+import compbio.metadata.JobSubmissionException;
+import compbio.metadata.Option;
+import compbio.metadata.ResultNotAvailableException;
+import compbio.metadata.WrongParameterException;
+import jalview.analysis.AlignSeq;
+import jalview.analysis.SeqsetUtils;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.IProgressIndicator;
+import jalview.workers.AlignCalcWorker;
+import jalview.ws.jws2.dm.JabaWsParamSet;
+import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.params.WsParamSetI;
+
+public abstract class JabawsCalcWorker extends AlignCalcWorker
+{
+
+  protected Jws2Instance service;
+  @SuppressWarnings("unchecked")
+  protected SequenceAnnotation aaservice;
+  protected ScoreManager scoremanager;
+  protected WsParamSetI preset;
+  protected List<Argument> arguments;
+  protected IProgressIndicator guiProgress;
+
+  public JabawsCalcWorker(AlignViewportI alignViewport,
+          AlignmentViewPanel alignPanel)
+  {
+    super(alignViewport, alignPanel);
+  }
+
+  public JabawsCalcWorker(Jws2Instance service, AlignFrame alignFrame,
+          WsParamSetI preset, List<Argument> paramset)
+  {
+    this(alignFrame.getCurrentView(), alignFrame.alignPanel);
+    this.guiProgress = alignFrame;
+    this.preset = preset;
+    this.arguments = paramset;
+    this.service = service;
+    aaservice = (SequenceAnnotation) service.service;
+
+  }
+
+  public WsParamSetI getPreset()
+  {
+    return preset;
+  }
+
+  public List<Argument> getArguments()
+  {
+    return arguments;
+  }
+
+  /**
+   * reconfigure and restart the AAConClient. This method will spawn a new
+   * thread that will wait until any current jobs are finished, modify the
+   * parameters and restart the conservation calculation with the new values.
+   * 
+   * @param newpreset
+   * @param newarguments
+   */
+  public void updateParameters(final WsParamSetI newpreset, final List<Argument> newarguments)
+  {
+    preset = newpreset;
+    arguments = newarguments;
+    calcMan.startWorker(this);
+  }
+
+  public List<Option> getJabaArguments()
+  {
+    List<Option> newargs = new ArrayList<Option>();
+    if (preset != null && preset instanceof JabaWsParamSet)
+    {
+      newargs.addAll(((JabaWsParamSet) preset).getjabaArguments());
+    }
+    if (arguments != null && arguments.size() > 0)
+    {
+      for (Argument rg : arguments)
+      {
+        if (Option.class.isAssignableFrom(rg.getClass()))
+        {
+          newargs.add((Option) rg);
+        }
+      }
+    }
+    return newargs;
+  }
+
+  @Override
+  public void run()
+  {
+    if (aaservice == null)
+    {
+      return;
+    }
+    long progressId = -1;
+  
+    int serverErrorsLeft = 3;
+  
+    String rslt = "JOB NOT DEFINED";
+    StringBuffer msg = new StringBuffer();
+    try
+    {
+      if (checkDone())
+      {
+        return;
+      }
+      List<compbio.data.sequence.FastaSequence> seqs = getInputSequences(alignViewport
+              .getAlignment());
+  
+      if (seqs == null)
+      {
+        calcMan.workerComplete(this);
+        return;
+      }
+  
+      AlignmentAnnotation[] aa = alignViewport.getAlignment()
+              .getAlignmentAnnotation();
+      if (guiProgress != null)
+      {
+        guiProgress.setProgressBar("JABA " + getServiceActionText(),
+                progressId = System.currentTimeMillis());
+      }
+      if (preset == null && arguments == null)
+      {
+        rslt = aaservice.analize(seqs);
+      }
+      else
+      {
+        try
+        {
+          rslt = aaservice.customAnalize(seqs, getJabaArguments());
+        } catch (WrongParameterException x)
+        {
+          throw new JobSubmissionException(
+                  "Invalid parameter set. Check Jalview implementation.", x);
+  
+        }
+      }
+      boolean finished = false;
+      long rpos = 0;
+      do
+      {
+        JobStatus status = aaservice.getJobStatus(rslt);
+        if (status.equals(JobStatus.FINISHED))
+        {
+          finished = true;
+        }
+        if (calcMan.isPending(this) && this instanceof AAConClient)
+        {
+          finished = true;
+          // cancel this job and yield to the new job
+          try
+          {
+            if (aaservice.cancelJob(rslt))
+            {
+              System.err.println("Cancelled AACon job: " + rslt);
+            }
+            else
+            {
+              System.err.println("FAILED TO CANCEL AACon job: " + rslt);
+            }
+  
+          } catch (Exception x)
+          {
+  
+          }
+  
+          return;
+        }
+        long cpos;
+        ChunkHolder stats = null;
+        do
+        {
+          cpos = rpos;
+          boolean retry = false;
+          do
+          {
+            try
+            {
+              stats = aaservice.pullExecStatistics(rslt, rpos);
+            } catch (Exception x)
+            {
+  
+              if (x.getMessage().contains(
+                      "Position in a file could not be negative!"))
+              {
+                // squash index out of bounds exception- seems to happen for
+                // disorder predictors which don't (apparently) produce any
+                // progress information and JABA server throws an exception
+                // because progress length is -1.
+                stats = null;
+              }
+              else
+              {
+                if (--serverErrorsLeft > 0)
+                {
+                  retry = true;
+                  try
+                  {
+                    Thread.sleep(200);
+                  } catch (InterruptedException q)
+                  {
+                  }
+                  ;
+                }
+                else
+                {
+                  throw x;
+                }
+              }
+            }
+          } while (retry);
+          if (stats != null)
+          {
+            System.out.print(stats.getChunk());
+            msg.append(stats);
+            rpos = stats.getNextPosition();
+          }
+        } while (stats != null && rpos > cpos);
+  
+        if (!finished && status.equals(JobStatus.FAILED))
+        {
+          try
+          {
+            Thread.sleep(200);
+          } catch (InterruptedException x)
+          {
+          }
+          ;
+        }
+      } while (!finished);
+      if (serverErrorsLeft > 0)
+      {
+        try
+        {
+          Thread.sleep(200);
+        } catch (InterruptedException x)
+        {
+        }
+        ;
+        scoremanager = aaservice.getAnnotation(rslt);
+        if (scoremanager != null)
+        {
+          jalview.bin.Cache.log
+                  .debug("Updating result annotation from Job " + rslt
+                          + " at " + service.getUri());
+          updateResultAnnotation(true);
+          ap.adjustAnnotationHeight();
+        }
+      }
+    }
+  
+    catch (JobSubmissionException x)
+    {
+  
+      System.err.println("submission error with " + getServiceActionText()
+              + " :");
+      x.printStackTrace();
+      calcMan.workerCannotRun(this);
+    } catch (ResultNotAvailableException x)
+    {
+      System.err.println("collection error:\nJob ID: " + rslt);
+      x.printStackTrace();
+      calcMan.workerCannotRun(this);
+  
+    } catch (OutOfMemoryError error)
+    {
+      calcMan.workerCannotRun(this);
+  
+      // consensus = null;
+      // hconsensus = null;
+      ap.raiseOOMWarning(getServiceActionText(), error);
+    } catch (Exception x)
+    {
+      calcMan.workerCannotRun(this);
+  
+      // consensus = null;
+      // hconsensus = null;
+      System.err
+              .println("Blacklisting worker due to unexpected exception:");
+      x.printStackTrace();
+    } finally
+    {
+  
+      calcMan.workerComplete(this);
+      if (ap != null)
+      {
+        calcMan.workerComplete(this);
+        if (guiProgress != null && progressId != -1)
+        {
+          guiProgress.setProgressBar("", progressId);
+        }
+        ap.paintAlignment(true);
+      }
+      if (msg.length() > 0)
+      {
+        // TODO: stash message somewhere in annotation or alignment view.
+        // code below shows result in a text box popup
+        /*
+         * jalview.gui.CutAndPasteTransfer cap = new
+         * jalview.gui.CutAndPasteTransfer(); cap.setText(msg.toString());
+         * jalview.gui.Desktop.addInternalFrame(cap,
+         * "Job Status for "+getServiceActionText(), 600, 400);
+         */
+      }
+    }
+  
+  }
+
+  @Override
+  public void updateAnnotation()
+  {
+    updateResultAnnotation(false);
+  }
+
+  public abstract void updateResultAnnotation(boolean immediate);
+
+  public abstract String getServiceActionText();
+
+  protected boolean submitGaps = true;
+  protected boolean alignedSeqs = true;
+  protected boolean nucleotidesAllowed = false;
+  protected boolean proteinAllowed = false;
+  /**
+   * record sequences for mapping result back to afterwards
+   */
+  protected boolean bySequence = false;
+  protected Map<String, SequenceI> seqNames;
+  protected boolean[] gapMap;
+  int realw;
+
+  public List<FastaSequence> getInputSequences(AlignmentI alignment)
+  {
+    if (alignment == null || alignment.getWidth() <= 0
+            || alignment.getSequences() == null
+            // || (alignedSeqs && !alignment.isAligned() && !submitGaps)
+            || alignment.isNucleotide() ? !nucleotidesAllowed
+            : !proteinAllowed)
+    {
+      return null;
+    }
+    List<compbio.data.sequence.FastaSequence> seqs = new ArrayList<compbio.data.sequence.FastaSequence>();
+  
+    int minlen = 10;
+    int ln = -1;
+    if (bySequence)
+    {
+      seqNames = new HashMap<String, SequenceI>();
+    }
+    gapMap = new boolean[0];
+    for (SequenceI sq : ((List<SequenceI>) alignment.getSequences()))
+    {
+      if (sq.getEnd() - sq.getStart() > minlen - 1)
+      {
+        String newname = SeqsetUtils.unique_name(seqs.size() + 1);
+        // make new input sequence with or without gaps
+        if (seqNames != null)
+        {
+          seqNames.put(newname, sq);
+        }
+        FastaSequence seq;
+        if (submitGaps)
+        {
+          seqs.add(seq = new compbio.data.sequence.FastaSequence(newname,
+                  sq.getSequenceAsString()));
+          if (gapMap == null || gapMap.length < seq.getSequence().length())
+          {
+            boolean[] tg = gapMap;
+            gapMap = new boolean[seq.getLength()];
+            System.arraycopy(tg, 0, gapMap, 0, tg.length);
+            for (int p = tg.length; p < gapMap.length; p++)
+            {
+              gapMap[p] = false; // init as a gap
+            }
+          }
+          for (int apos : sq.gapMap())
+          {
+            gapMap[apos] = true; // aligned.
+          }
+        }
+        else
+        {
+          seqs.add(seq = new compbio.data.sequence.FastaSequence(newname,
+                  AlignSeq.extractGaps(jalview.util.Comparison.GapChars,
+                          sq.getSequenceAsString())));
+        }
+        if (seq.getSequence().length() > ln)
+        {
+          ln = seq.getSequence().length();
+        }
+      }
+    }
+    if (alignedSeqs && submitGaps)
+    {
+      realw = 0;
+      for (int i = 0; i < gapMap.length; i++)
+      {
+        if (gapMap[i])
+        {
+          realw++;
+        }
+      }
+      // try real hard to return something submittable
+      // TODO: some of AAcon measures need a minimum of two or three amino
+      // acids at each position, and AAcon doesn't gracefully degrade.
+      for (int p = 0; p < seqs.size(); p++)
+      {
+        FastaSequence sq = seqs.get(p);
+        int l = sq.getSequence().length();
+        // strip gapped columns
+        char[] padded = new char[realw], orig = sq.getSequence()
+                .toCharArray();
+        for (int i = 0, pp = 0; i < realw; pp++)
+        {
+          if (gapMap[pp])
+          {
+            if (orig.length > pp)
+            {
+              padded[i++] = orig[pp];
+            }
+            else
+            {
+              padded[i++] = '-';
+            }
+          }
+        }
+        seqs.set(p, new compbio.data.sequence.FastaSequence(sq.getId(),
+                new String(padded)));
+      }
+    }
+    return seqs;
+  }
+
+  /**
+   * notify manager that we have started, and wait for a free calculation slot
+   * 
+   * @return true if slot is obtained and work still valid, false if another
+   *         thread has done our work for us.
+   */
+  boolean checkDone()
+  {
+    calcMan.notifyStart(this);
+    ap.paintAlignment(false);
+    while (!calcMan.notifyWorking(this))
+    {
+      if (calcMan.isWorking(this))
+      {
+        return true;
+      }
+      try
+      {
+        if (ap != null)
+        {
+          ap.paintAlignment(false);
+        }
+  
+        Thread.sleep(200);
+      } catch (Exception ex)
+      {
+        ex.printStackTrace();
+      }
+    }
+    if (alignViewport.isClosed())
+    {
+      abortAndDestroy();
+      return true;
+    }
+    return false;
+  }
+
+  protected void createAnnotationRowsForScores(List<AlignmentAnnotation> ourAnnot, String calcId,
+          int alWidth, Score scr)
+  {
+    // simple annotation row
+    AlignmentAnnotation annotation = alignViewport.getAlignment()
+            .findOrCreateAnnotation(scr.getMethod(), calcId, true, null,
+                    null);
+    if (alWidth == gapMap.length) // scr.getScores().size())
+    {
+      constructAnnotationFromScore(annotation, 0, alWidth, scr);
+      ourAnnot.add(annotation);
+    }
+  }
+
+  protected AlignmentAnnotation createAnnotationRowsForScores(List<AlignmentAnnotation> ourAnnot, String typeName,
+          String calcId, SequenceI dseq, int base, Score scr)
+  {
+    System.out.println("Creating annotation on dseq:" + dseq.getStart()
+            + " base is " + base + " and length=" + dseq.getLength()
+            + " == " + scr.getScores().size());
+    // AlignmentAnnotation annotation = new AlignmentAnnotation(
+    // scr.getMethod(), typeName, new Annotation[]
+    // {}, 0, -1, AlignmentAnnotation.LINE_GRAPH);
+    // annotation.setCalcId(calcId);
+    AlignmentAnnotation annotation = alignViewport.getAlignment()
+            .findOrCreateAnnotation(typeName, calcId, false, dseq, null);
+    constructAnnotationFromScore(annotation, 0, dseq.getLength(), scr);
+    annotation.createSequenceMapping(dseq, base, false);
+    annotation.adjustForAlignment();
+    dseq.addAlignmentAnnotation(annotation);
+    ourAnnot.add(annotation);
+    return annotation;
+  }
+
+  private void constructAnnotationFromScore(AlignmentAnnotation annotation, int base,
+          int alWidth, Score scr)
+  {
+    Annotation[] elm = new Annotation[alWidth];
+    Iterator<Float> vals = scr.getScores().iterator();
+    float m = 0f, x = 0f;
+    for (int i = 0; vals.hasNext(); i++)
+    {
+      float val = vals.next().floatValue();
+      if (i == 0)
+      {
+        m = val;
+        x = val;
+      }
+      else
+      {
+        if (m > val)
+        {
+          m = val;
+        }
+        ;
+        if (x < val)
+        {
+          x = val;
+        }
+      }
+      // if we're at a gapped column then skip to next ungapped position
+      if (gapMap != null && gapMap.length > 0)
+      {
+        while (!gapMap[i])
+        {
+          elm[i++] = new Annotation("", "", ' ', Float.NaN);
+        }
+      }
+      elm[i] = new Annotation("", "" + val, ' ', val);
+    }
+  
+    annotation.annotations = elm;
+    annotation.belowAlignment = true;
+    if (x < 0)
+    {
+      x = 0;
+    }
+    x += (x - m) * 0.1;
+    annotation.graphMax = x;
+    annotation.graphMin = m;
+    annotation.validateRangeAndDisplay();
+  }
+
+  protected void updateOurAnnots(List<AlignmentAnnotation> ourAnnot)
+  {
+    List<AlignmentAnnotation> our = ourAnnots;
+    ourAnnots = ourAnnot;
+    AlignmentI alignment = alignViewport.getAlignment();
+    if (our != null)
+    {
+      if (our.size() > 0)
+      {
+        for (AlignmentAnnotation an : our)
+        {
+          if (!ourAnnots.contains(an))
+          {
+            // remove the old annotation
+            alignment.deleteAnnotation(an);
+          }
+        }
+      }
+      our.clear();
+  
+      ap.adjustAnnotationHeight();
+    }
+  }
+
+}
index 8ad14e0..8f56e2f 100644 (file)
@@ -38,6 +38,7 @@ import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.StringTokenizer;
 import java.util.Vector;
 
@@ -105,6 +106,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
 
   public void run()
   {
+
     if (running && oldthread != null && oldthread.isAlive())
     {
       if (!aborted)
@@ -126,6 +128,15 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
       Cache.log.debug("Old discovery thread has finished.");
     }
     running = true;
+    
+    // first set up exclusion list if needed
+    final Set<String> ignoredServices = new HashSet<String>();
+    for (String ignored:jalview.bin.Cache.getDefault("IGNORED_JABAWS_SERVICETYPES", Services.JpredWS.toString()).split("\\|"))
+    {
+      ignoredServices.add(ignored);
+    }
+
+    
     changeSupport.firePropertyChange("services", services, new Vector());
     oldthread = Thread.currentThread();
     try
@@ -169,7 +180,10 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
         // for all possible services
         for (Services sv : squery.JABAWS2SERVERS)
         {
-          svctypes.add(sv.toString());
+          if (!ignoredServices.contains(sv.toString()))
+          {
+            svctypes.add(sv.toString());
+          }
         }
 
       }
@@ -189,7 +203,9 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
       ;
       for (JabaWsServerQuery squery : qrys)
       {
-        finished = finished && !squery.isRunning();
+        if (squery.isRunning()){
+          finished=false;
+        }
       }
       if (aborted)
       {
@@ -222,7 +238,10 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
         services = new Vector<Jws2Instance>();
         for (Jws2Instance svc : svcs)
         {
-          services.add(svc);
+          if (!ignoredServices.contains(svc.serviceType))
+          {
+            services.add(svc);
+          }
         }
       }
     }
index 16959ff..e6b9f53 100644 (file)
@@ -17,6 +17,7 @@
  */
 package jalview.ws.jws2;
 
+import java.net.MalformedURLException;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -126,6 +127,7 @@ public class ParameterUtils
   {
     copy.setName(option.getName());
     copy.setDescription(option.getDescription());
+    copy.setBasicURL(option.getBasicURL());
     copy.setFurtherDetails(option.getFurtherDetails());
     copy.setRequired(option.isRequired());
     List<String> names = option.getOptionNames();
diff --git a/src/jalview/ws/jws2/RNAalifoldClient.java b/src/jalview/ws/jws2/RNAalifoldClient.java
new file mode 100644 (file)
index 0000000..ec40552
--- /dev/null
@@ -0,0 +1,371 @@
+package jalview.ws.jws2;
+
+import jalview.api.AlignCalcWorkerI;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.gui.AlignFrame;
+import jalview.ws.jws2.dm.AAConSettings;
+import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.params.WsParamSetI;
+import jalview.ws.uimodel.AlignAnalysisUIText;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.TreeSet;
+import java.util.regex.Pattern;
+
+import compbio.data.sequence.RNAStructReader.AlifoldResult;
+import compbio.data.sequence.RNAStructScoreManager;
+import compbio.data.sequence.Range;
+import compbio.data.sequence.Score;
+import compbio.metadata.Argument;
+
+/**
+ * Client for the JABA RNA Alifold Service
+ * @author daluke - Daniel Barton
+ *
+ */
+
+public class RNAalifoldClient extends JabawsAlignCalcWorker implements
+        AlignCalcWorkerI
+{
+
+  String methodName;
+
+  AlignFrame af;
+
+  // keeps track of whether the RNAalifold result includes base contact
+  // probabilities
+  boolean bpScores;
+
+  public RNAalifoldClient(Jws2Instance sh, AlignFrame alignFrame,
+          WsParamSetI preset, List<Argument> paramset)
+  {
+    super(sh, alignFrame, preset, paramset);
+
+    //if (arguments == null)
+    //  arguments = new ArrayList<Argument>();
+
+    af = alignFrame;
+    methodName = sh.serviceType;
+    alignedSeqs=true;
+    submitGaps=true;
+    nucleotidesAllowed = true;
+    proteinAllowed = false;
+    initViewportParams();
+  }
+  
+  public String getCalcId()
+  {
+    return CALC_ID;
+  }
+  private static String CALC_ID="jalview.ws.jws2.RNAalifoldClient";
+
+  public static AlignAnalysisUIText getAlignAnalysisUITest()
+  {
+    return new AlignAnalysisUIText(
+            compbio.ws.client.Services.RNAalifoldWS.toString(),
+            jalview.ws.jws2.RNAalifoldClient.class,
+            CALC_ID,
+            true,
+            false,
+            true,
+            "RNAAliFold Prediction",
+            "When checked, RNA secondary structure predictions will be calculated for the alignment, and updated when edits are made.",
+            "Change RNAAliFold settings...",
+            "Modify settings for the RNAAliFold prediction. Use this to hide or show different results of the RNA calculation, and change RNA folding parameters");
+
+  }
+
+  @Override
+  public String getServiceActionText()
+  {
+    return "Submitting RNA alignment for Secondary Structure prediction using "
+            + "RNAalifold Service";
+  }
+
+  @Override
+  public void updateResultAnnotation(boolean immediate)
+  {
+
+    if (immediate || !calcMan.isWorking(this) && scoremanager != null)
+    {
+
+      List<AlignmentAnnotation> ourAnnot = new ArrayList<AlignmentAnnotation>();
+
+      // Unpack the ScoreManager
+      List<String> structs = ((RNAStructScoreManager) scoremanager)
+              .getStructs();
+      List<TreeSet<Score>> data = ((RNAStructScoreManager) scoremanager)
+              .getData();
+
+      // test to see if this data object contains base pair contacts
+      Score fscore = data.get(0).first();
+      this.bpScores = (fscore.getMethod()
+              .equals(AlifoldResult.contactProbabilities.toString()));
+
+      // add annotation for the consensus sequence alignment
+      createAnnotationRowforScoreHolder(ourAnnot, getCalcId(),
+              structs.get(0), null, null);
+
+      // Add annotations for the mfe Structure
+      createAnnotationRowforScoreHolder(ourAnnot, getCalcId(),
+              structs.get(1), data.get(1), null);
+
+      // decide whether to add base pair contact probability histogram
+      int count = 2;
+      if (bpScores)
+      {
+        createAnnotationRowforScoreHolder(ourAnnot, getCalcId(),
+                structs.get(2), data.get(0), data.get(2));
+        count++;
+      }
+
+      // Now loop for the rest of the Annotations (if there it isn't stochastic
+      // output
+      // only the centroid and MEA structures remain anyway)
+      for (int i = count; i < structs.size(); i++)
+      {
+        // The ensemble values should be displayed in the description of the
+        // first (or all?) Stochastic Backtrack Structures.
+        if (!data.get(i).first().getMethod()
+                .equals(AlifoldResult.ensembleValues.toString()))
+        {
+
+          createAnnotationRowforScoreHolder(ourAnnot, getCalcId(),
+                  structs.get(i), data.get(i), null);
+        }
+      }
+
+      if (ourAnnot.size() > 0)
+      {
+
+        updateOurAnnots(ourAnnot);
+        ap.adjustAnnotationHeight();
+      }
+    }
+  }
+
+  protected void createAnnotationRowforScoreHolder(
+          List<AlignmentAnnotation> ourAnnot, String calcId, String struct,
+          TreeSet<Score> data, TreeSet<Score> descriptionData)
+  {
+    /*
+     * If contactProbability information is returned from RNAalifold it is
+     * stored in the first TreeSet<Score> object corresponding to the String Id
+     * which holds the consensus alignment. The method enumeration is then
+     * updated to AlifoldResult.contactProbabilties. This line recreates the
+     * same data object as was overwritten with the contact probabilites data.
+     */
+    if (data == null)
+      data = compbio.data.sequence.RNAStructReader
+              .newEmptyScore(AlifoldResult.consensusAlignment);
+
+    if (descriptionData == null)
+      descriptionData = data;
+
+    String[] typenameAndDescription = constructTypenameAndDescription(descriptionData
+            .first());
+    String typename = typenameAndDescription[0];
+    String description = typenameAndDescription[1];
+
+    AlignmentAnnotation annotation = alignViewport.getAlignment()
+            .findOrCreateAnnotation(typename, calcId, false, null, null);
+
+    constructAnnotationFromScoreHolder(annotation, struct, data);
+
+    /*
+     * update annotation description with the free Energy, frequency in ensemble
+     * or other data where appropriate.
+     * 
+     * Doesnt deal with AlifoldResult.ensembleValues, the free energy of
+     * ensemble and frequency of mfe structure in ensemble. How to deal with
+     * these?
+     */
+    annotation.description = description;
+
+    annotation.belowAlignment = false;
+    // annotation.showAllColLabels = true;
+
+    alignViewport.getAlignment().validateAnnotation(annotation);
+    af.setMenusForViewport();
+
+    ourAnnot.add(annotation);
+  }
+
+  private AlignmentAnnotation constructAnnotationFromScoreHolder(
+          AlignmentAnnotation annotation, String struct, TreeSet<Score> data)
+  {
+    Annotation[] anns = new Annotation[struct.length()];
+
+    if (data != null
+            && data.size() > 1
+            && data.first().getMethod()
+                    .equals(AlifoldResult.contactProbabilities.toString()))
+    {
+
+      // The base pair probabilities are stored in a set in scoreholder. we want
+      // a map
+      LinkedHashMap<Range, Float> basePairs = new LinkedHashMap<Range, Float>();
+      for (Score score : data)
+      {
+        // The Score objects contain a set of size one containing the range and
+        // an ArrayList<float> of size one containing the probabilty
+        basePairs.put(score.getRanges().first(), new Float(score
+                .getScores().get(0)));
+      }
+      
+      for (int i = 0,ri=0,iEnd=struct.length();i<iEnd; i++,ri++)
+      {
+        if (gapMap!=null)
+        {
+          // skip any gapped columns in the input data
+          while (!gapMap[ri])
+          {
+            ri++;
+          }
+        }
+        // Return all the contacts associated with position i
+        LinkedHashMap<Range, Float> contacts = isContact(basePairs, i + 1);
+
+        String description = "";
+        float prob = 0f;
+
+        if (contacts.size() == 0)
+        {
+          description = "No Data";
+        }
+        else
+        {
+          for (Range contact : contacts.keySet())
+          {
+            float t = contacts.get(contact);
+            if (t > prob)
+              prob = t;
+            description += Integer.toString(contact.from) + "->"
+                    + Integer.toString(contact.to) + ": "
+                    + Float.toString(t) + "%  |  ";
+          }
+        }
+
+        anns[ri] = new Annotation(struct.substring(i, i + 1), description,
+                isSS(struct.charAt(i)), prob);
+      }
+    }
+    else if (data == null || data.size() == 1)
+    {
+      for (int i = 0,ri=0,iEnd=struct.length();i<iEnd; i++,ri++)
+      {
+        if (gapMap!=null)
+        {
+          // skip any gapped columns in the input data
+          while (!gapMap[ri])
+          {
+            ri++;
+          }
+        }
+        anns[ri] = new Annotation(struct.substring(i, i + 1), "",
+                isSS(struct.charAt(i)), Float.NaN);
+      }
+
+      annotation.graph = 0; // No graph
+    }
+
+    annotation.annotations = anns;
+
+    return annotation;
+  }
+
+  private String[] constructTypenameAndDescription(Score score)
+  {
+    String description = "";
+    String typename = "";
+    String datatype = score.getMethod();
+
+    // Look up java switch syntax and use one here
+    if (datatype.equals(AlifoldResult.mfeStructure.toString()))
+    {
+
+      description = MessageFormat.format(
+              "Minimum Free Energy Structure. Energy: {0} = {1} + {2}",
+              score.getScores().get(0), score.getScores().get(1), score
+                      .getScores().get(2));
+      typename = "MFE Structure";
+    }
+    else if (datatype.equals(AlifoldResult.contactProbabilityStructure
+            .toString()))
+    {
+      description = MessageFormat
+              .format("Base Pair Contact Probabilities. "
+                      + "Energy of Ensemble: {0}  Frequency of Ensemble: {1}",
+                      score.getScores().get(0), score.getScores().get(1));
+      typename = "Contact Probabilities";
+    }
+    else if (datatype.equals(AlifoldResult.centroidStructure.toString()))
+    {
+      description = MessageFormat.format(
+              "Centroid Structure. Energy: {0} = {1} + {2}", score
+                      .getScores().get(0), score.getScores().get(1), score
+                      .getScores().get(2));
+      typename = "Centroid Structure";
+    }
+    else if (datatype.equals(AlifoldResult.stochBTStructure.toString()))
+    {
+      if (score.getScores().size() > 0)
+      {
+        description = MessageFormat.format("Probability: {0}  Energy: {1}",
+                score.getScores().get(0), score.getScores().get(1));
+      }
+      else
+        description = "Stochastic Backtrack Structure";
+    }
+    else if (datatype.equals(AlifoldResult.MEAStucture.toString()))
+    {
+      description = MessageFormat.format(
+              "Maximum Expected Accuracy Values: '{' {0} MEA={1} '}", score
+                      .getScores().get(0), score.getScores().get(1));
+      typename = "MEA Structure";
+    }
+    else if (datatype.equals(AlifoldResult.consensusAlignment.toString()))
+    {
+      typename = "RNAalifold Consensus";
+      description = "Consensus Alignment Produced by RNAalifold";
+    }
+    else
+    {
+      typename = datatype;
+      description = typename;
+    }
+
+    return new String[]
+    { typename, description };
+  }
+
+  // Check whether, at position i there is a base contact and return all the
+  // contacts at this position. Should be in order of descending probability.
+  private LinkedHashMap<Range, Float> isContact(
+          LinkedHashMap<Range, Float> basePairs, int i)
+  {
+    LinkedHashMap<Range, Float> contacts = new LinkedHashMap<Range, Float>();
+
+    for (Range contact : basePairs.keySet())
+    {
+      // finds the contacts associtated with position i ordered by the natural
+      // ordering of the Scores TreeSet in ScoreManager which is, descending
+      // probability
+      if (contact.from == i || contact.to == i)
+        contacts.put(contact, basePairs.get(contact));
+    }
+
+    return contacts;
+  }
+
+  private char isSS(char chr)
+  {
+    String regex = "\\(|\\)|\\{|\\}|\\[|\\]";
+    char ss = (Pattern.matches(regex, Character.toString(chr))) ? 'S' : ' ';
+    return ss;
+  }
+}
index d57eae4..59cc962 100644 (file)
@@ -25,6 +25,7 @@ import jalview.gui.JvSwingUtils;
 import jalview.ws.jws2.dm.AAConSettings;
 import jalview.ws.jws2.jabaws2.Jws2Instance;
 import jalview.ws.params.WsParamSetI;
+import jalview.ws.uimodel.AlignAnalysisUIText;
 
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
@@ -43,9 +44,6 @@ import javax.swing.event.MenuListener;
  */
 public class SequenceAnnotationWSClient extends Jws2Client
 {
-
-  public static final String AAConCalcId = "jabaws2.AACon";
-
   /**
    * initialise a client so its attachWSMenuEntry method can be called.
    */
@@ -61,44 +59,59 @@ public class SequenceAnnotationWSClient extends Jws2Client
     initSequenceAnnotationWSClient(sh, alignFrame, preset, editParams);
   }
 
+  // dan think. Do I need to change this method to run RNAalifold through the GUI
+  
   public void initSequenceAnnotationWSClient(final Jws2Instance sh,
           AlignFrame alignFrame, WsParamSetI preset, boolean editParams)
   {
-    if (alignFrame.getViewport().getAlignment().isNucleotide())
-    {
-      JOptionPane.showMessageDialog(Desktop.desktop, sh.serviceType
-              + " can only be used\nfor amino acid alignments.",
-              "Wrong type of sequences!", JOptionPane.WARNING_MESSAGE);
-      return;
-
-    }
-    if (sh.action.toLowerCase().contains("conservation"))
+       // dan changed! dan test. comment out if conditional
+//    if (alignFrame.getViewport().getAlignment().isNucleotide())
+//    {
+//      JOptionPane.showMessageDialog(Desktop.desktop, sh.serviceType
+//              + " can only be used\nfor amino acid alignments.",
+//              "Wrong type of sequences!", JOptionPane.WARNING_MESSAGE);
+//      return;
+//
+//    }
+    AlignAnalysisUIText aaui = sh.getAlignAnalysisUI();
+    if (aaui!=null)
     {
+      Class clientClass = aaui.getClient();
+      
       // Build an AACon style client - take alignment, return annotation for
       // columns
 
       List<AlignCalcWorkerI> clnts = alignFrame.getViewport()
               .getCalcManager()
-              .getRegisteredWorkersOfClass(AAConClient.class);
+              .getRegisteredWorkersOfClass(clientClass);
+      JabawsAlignCalcWorker worker;
       if (clnts == null || clnts.size() == 0)
       {
         if (!processParams(sh, editParams))
         {
           return;
         }
-        AAConClient worker;
+        try {
+          worker = (JabawsAlignCalcWorker) (clientClass.getConstructor(
+                  new Class[] { Jws2Instance.class, 
+                          AlignFrame.class, WsParamSetI.class, 
+                          List.class }).newInstance(new Object[] { sh, alignFrame, this.preset, paramset}));
+        } catch (Exception x)
+        {
+          x.printStackTrace();
+          throw new Error("Implementation error",x);
+        }
         alignFrame
                 .getViewport()
                 .getCalcManager()
                 .registerWorker(
-                        worker = new AAConClient(sh, alignFrame,
-                                this.preset, paramset));
+                        worker);
         alignFrame.getViewport().getCalcManager().startWorker(worker);
 
       }
       else
       {
-        AAConClient worker = (AAConClient) clnts.get(0);
+        worker = (JabawsAlignCalcWorker) clnts.get(0);
         if (editParams)
         {
           paramset = worker.getArguments();
@@ -113,7 +126,6 @@ public class SequenceAnnotationWSClient extends Jws2Client
         // invalid parameters)
         alignFrame.getViewport().getCalcManager().workerMayRun(worker);
         worker.updateParameters(this.preset, paramset);
-
       }
     }
     if (sh.action.toLowerCase().contains("disorder"))
@@ -131,7 +143,6 @@ public class SequenceAnnotationWSClient extends Jws2Client
               .startWorker(
                       new AADisorderClient(sh, alignFrame, preset, paramset));
     }
-
   }
 
   public SequenceAnnotationWSClient(AAConSettings fave,
@@ -151,10 +162,8 @@ public class SequenceAnnotationWSClient extends Jws2Client
   public void attachWSMenuEntry(JMenu wsmenu, final Jws2Instance service,
           final AlignFrame alignFrame)
   {
-    if (service.serviceType.equals(compbio.ws.client.Services.AAConWS
-            .toString()))
-    {
-      registerAAConWSInstance(wsmenu, service, alignFrame);
+    if (registerAAConWSInstance(wsmenu, service, alignFrame)) {
+      // Alignment dependent analysis calculation WS gui
       return;
     }
     boolean hasparams = service.hasParameters();
@@ -240,21 +249,24 @@ public class SequenceAnnotationWSClient extends Jws2Client
     }
   }
 
-  private final String AAconToggle = "AACon Calculations",
-          AAconToggleTooltip = "When checked, AACon calculations are updated automatically.",
-          AAeditSettings = "Change AACon Settings...",
-          AAeditSettingsTooltip = "Modify settings for AACon calculations.";
-
-  private void registerAAConWSInstance(final JMenu wsmenu,
+  
+  private boolean registerAAConWSInstance(final JMenu wsmenu,
           final Jws2Instance service, final AlignFrame alignFrame)
   {
-    // register this in the AACon settings set
+    final AlignAnalysisUIText aaui = service.getAlignAnalysisUI(); // null ; // AlignAnalysisUIText.aaConGUI.get(service.serviceType.toString());
+    if (aaui==null)
+    {
+      // not an instantaneous calculation GUI type service
+      return false;
+    }
+    // create the instaneous calculation GUI bits and update state if existing GUI elements already present
+    
     JCheckBoxMenuItem _aaConEnabled = null;
     for (int i = 0; i < wsmenu.getItemCount(); i++)
     {
       JMenuItem item = wsmenu.getItem(i);
       if (item instanceof JCheckBoxMenuItem
-              && item.getText().equals(AAconToggle))
+              && item.getText().equals(aaui.getAAconToggle()))
       {
         _aaConEnabled = (JCheckBoxMenuItem) item;
       }
@@ -264,10 +276,10 @@ public class SequenceAnnotationWSClient extends Jws2Client
     {
       List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
               .getCalcManager()
-              .getRegisteredWorkersOfClass(AAConClient.class);
+              .getRegisteredWorkersOfClass(aaui.getClient());
       if (aaconClient != null && aaconClient.size() > 0)
       {
-        AAConClient worker = (AAConClient) aaconClient.get(0);
+        JabawsAlignCalcWorker worker = (JabawsAlignCalcWorker) aaconClient.get(0);
         if (!worker.service.hosturl.equals(service.hosturl))
         {
           // javax.swing.SwingUtilities.invokeLater(new Runnable()
@@ -275,8 +287,8 @@ public class SequenceAnnotationWSClient extends Jws2Client
             // @Override
             // public void run()
             {
-              removeCurrentAAConWorkerFor(alignFrame);
-              buildCurrentAAConWorkerFor(alignFrame, service);
+              removeCurrentAAConWorkerFor(aaui, alignFrame);
+              buildCurrentAAConWorkerFor(aaui, alignFrame, service);
             }
           }// );
         }
@@ -288,85 +300,95 @@ public class SequenceAnnotationWSClient extends Jws2Client
     if (_aaConEnabled == null)
     {
       final JCheckBoxMenuItem aaConEnabled = new JCheckBoxMenuItem(
-              AAconToggle);
-      wsmenu.addMenuListener(new MenuListener()
-      {
+              aaui.getAAconToggle());
 
+      aaConEnabled.setToolTipText("<html><p>"
+              + JvSwingUtils.wrapTooltip(aaui.getAAconToggleTooltip() + "</p>")
+              + "</html>");
+      aaConEnabled.addActionListener(new ActionListener()
+      {
         @Override
-        public void menuSelected(MenuEvent arg0)
+        public void actionPerformed(ActionEvent arg0)
         {
-          wsmenu.setEnabled(!alignFrame.getViewport().getAlignment()
-                  .isNucleotide());
           List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
                   .getCalcManager()
-                  .getRegisteredWorkersOfClass(AAConClient.class);
+                  .getRegisteredWorkersOfClass(aaui.getClient());
           if (aaconClient != null && aaconClient.size() > 0)
           {
-            aaConEnabled.setSelected(true);
+            removeCurrentAAConWorkerFor(aaui, alignFrame);
           }
           else
           {
-            aaConEnabled.setSelected(false);
+            buildCurrentAAConWorkerFor(aaui, alignFrame);
+
           }
         }
 
-        @Override
-        public void menuDeselected(MenuEvent arg0)
-        {
-          // TODO Auto-generated method stub
-
-        }
+      });
+      wsmenu.add(aaConEnabled);
+      final JMenuItem modifyParams = new JMenuItem(aaui.getAAeditSettings());
+      modifyParams.setToolTipText("<html><p>"
+              + JvSwingUtils.wrapTooltip(aaui.getAAeditSettingsTooltip() + "</p>")
+              + "</html>");
+      modifyParams.addActionListener(new ActionListener()
+      {
 
         @Override
-        public void menuCanceled(MenuEvent arg0)
+        public void actionPerformed(ActionEvent arg0)
         {
-          // TODO Auto-generated method stub
-
+          showAAConAnnotationSettingsFor(aaui, alignFrame);
         }
       });
-      aaConEnabled.setToolTipText("<html><p>"
-              + JvSwingUtils.wrapTooltip(AAconToggleTooltip + "</p>")
-              + "</html>");
-      aaConEnabled.addActionListener(new ActionListener()
+      wsmenu.add(modifyParams);
+      wsmenu.addMenuListener(new MenuListener()
       {
+
         @Override
-        public void actionPerformed(ActionEvent arg0)
+        public void menuSelected(MenuEvent arg0)
         {
+          // TODO: refactor to the implementing class.
+          if (alignFrame.getViewport().getAlignment()
+                  .isNucleotide() ? aaui.isNa() : aaui.isPr()) {
+            aaConEnabled.setEnabled(true);
+            modifyParams.setEnabled(true);
+          }
+          else {
+            aaConEnabled.setEnabled(false);
+            modifyParams.setEnabled(false);
+          }
           List<AlignCalcWorkerI> aaconClient = alignFrame.getViewport()
                   .getCalcManager()
-                  .getRegisteredWorkersOfClass(AAConClient.class);
+                  .getRegisteredWorkersOfClass(aaui.getClient());
           if (aaconClient != null && aaconClient.size() > 0)
           {
-            removeCurrentAAConWorkerFor(alignFrame);
+            aaConEnabled.setSelected(true);
           }
           else
           {
-            buildCurrentAAConWorkerFor(alignFrame);
-
+            aaConEnabled.setSelected(false);
           }
         }
 
-      });
-      wsmenu.add(aaConEnabled);
-      JMenuItem modifyParams = new JMenuItem(AAeditSettings);
-      modifyParams.setToolTipText("<html><p>"
-              + JvSwingUtils.wrapTooltip(AAeditSettingsTooltip + "</p>")
-              + "</html>");
-      modifyParams.addActionListener(new ActionListener()
-      {
+        @Override
+        public void menuDeselected(MenuEvent arg0)
+        {
+          // TODO Auto-generated method stub
+
+        }
 
         @Override
-        public void actionPerformed(ActionEvent arg0)
+        public void menuCanceled(MenuEvent arg0)
         {
-          showAAConAnnotationSettingsFor(alignFrame);
+          // TODO Auto-generated method stub
+
         }
       });
-      wsmenu.add(modifyParams);
 
     }
+    return true;
   }
 
-  private static void showAAConAnnotationSettingsFor(AlignFrame alignFrame)
+  private static void showAAConAnnotationSettingsFor(final AlignAnalysisUIText aaui, AlignFrame alignFrame)
   {
     /*
      * preferred settings Whether AACon is automatically recalculated Which
@@ -374,21 +396,21 @@ public class SequenceAnnotationWSClient extends Jws2Client
      */
     // could actually do a class search for this too
     AAConSettings fave = (AAConSettings) alignFrame.getViewport()
-            .getCalcIdSettingsFor(AAConCalcId);
+            .getCalcIdSettingsFor(aaui.getCalcId());
     if (fave == null)
     {
-      fave = createDefaultAAConSettings();
+      fave = createDefaultAAConSettings(aaui);
     }
     new SequenceAnnotationWSClient(fave, alignFrame, true);
 
   }
 
-  private static void buildCurrentAAConWorkerFor(AlignFrame alignFrame)
+  private static void buildCurrentAAConWorkerFor(final AlignAnalysisUIText aaui, AlignFrame alignFrame)
   {
-    buildCurrentAAConWorkerFor(alignFrame, null);
+    buildCurrentAAConWorkerFor(aaui, alignFrame, null);
   }
 
-  private static void buildCurrentAAConWorkerFor(AlignFrame alignFrame,
+  private static void buildCurrentAAConWorkerFor(final AlignAnalysisUIText aaui, AlignFrame alignFrame,
           Jws2Instance service)
   {
     /*
@@ -396,10 +418,10 @@ public class SequenceAnnotationWSClient extends Jws2Client
      * AACon server to use What parameters to use
      */
     AAConSettings fave = (AAConSettings) alignFrame.getViewport()
-            .getCalcIdSettingsFor(AAConCalcId);
+            .getCalcIdSettingsFor(aaui.getCalcId());
     if (fave == null)
     {
-      fave = createDefaultAAConSettings(service);
+      fave = createDefaultAAConSettings(aaui, service);
     }
     else
     {
@@ -414,12 +436,12 @@ public class SequenceAnnotationWSClient extends Jws2Client
     new SequenceAnnotationWSClient(fave, alignFrame, false);
   }
 
-  private static AAConSettings createDefaultAAConSettings()
+  private static AAConSettings createDefaultAAConSettings(AlignAnalysisUIText aaui)
   {
-    return createDefaultAAConSettings(null);
+    return createDefaultAAConSettings(aaui, null);
   }
 
-  private static AAConSettings createDefaultAAConSettings(
+  private static AAConSettings createDefaultAAConSettings(AlignAnalysisUIText aaui,
           Jws2Instance service)
   {
     if (service != null)
@@ -447,7 +469,7 @@ public class SequenceAnnotationWSClient extends Jws2Client
     {
       // get the default service for AACon
       service = Jws2Discoverer.getDiscoverer().getPreferredServiceFor(null,
-              compbio.ws.client.Services.AAConWS.toString());
+              aaui.getServiceType());
     }
     if (service == null)
     {
@@ -458,9 +480,9 @@ public class SequenceAnnotationWSClient extends Jws2Client
     return new AAConSettings(true, service, null, null);
   }
 
-  private static void removeCurrentAAConWorkerFor(AlignFrame alignFrame)
+  private static void removeCurrentAAConWorkerFor(AlignAnalysisUIText aaui, AlignFrame alignFrame)
   {
     alignFrame.getViewport().getCalcManager()
-            .removeRegisteredWorkersOfClass(AAConClient.class);
+            .removeRegisteredWorkersOfClass(aaui.getClient());
   }
 }
index 69f8f7b..7316d2f 100644 (file)
@@ -20,6 +20,7 @@ package jalview.ws.jws2.dm;
 import jalview.ws.jws2.ParameterUtils;
 import jalview.ws.params.OptionI;
 
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.List;
 
@@ -49,7 +50,15 @@ public class JabaOption implements jalview.ws.params.OptionI
   @Override
   public URL getFurtherDetails()
   {
-    return opt.getFurtherDetails();
+    try {
+    return new URL(opt.getBasicURL().toExternalForm()+"/"+opt.getFurtherDetails());
+    }
+    catch (NullPointerException q) {}
+    catch (MalformedURLException q)
+    {
+      
+    }
+    return null;
   }
 
   @Override
index aa42ff7..509b96f 100644 (file)
@@ -48,6 +48,14 @@ public class Jws2Instance
 
   public String docUrl;
 
+  /**
+   * 
+   * @param hosturl Service endpoint
+   * @param serviceType Category for this service's analysis
+   * @param action text describing their action that service performs (eg 'aligning', 'analysing')
+   * @param description Description from JABAWS registry
+   * @param service JABAWS registry ID for service
+   */
   public Jws2Instance(String hosturl, String serviceType, String action,
           String description, JABAService service)
   {
@@ -224,4 +232,9 @@ public class Jws2Instance
   {
     return "java:" + serviceType;
   }
+  jalview.ws.uimodel.AlignAnalysisUIText aaui;
+  public jalview.ws.uimodel.AlignAnalysisUIText getAlignAnalysisUI()
+  {
+    return aaui;
+  }
 }
diff --git a/src/jalview/ws/jws2/jabaws2/Jws2InstanceFactory.java b/src/jalview/ws/jws2/jabaws2/Jws2InstanceFactory.java
new file mode 100644 (file)
index 0000000..5907713
--- /dev/null
@@ -0,0 +1,53 @@
+package jalview.ws.jws2.jabaws2;
+
+import java.util.HashMap;
+
+import compbio.data.msa.JABAService;
+
+import jalview.ws.jws2.AAConClient;
+import jalview.ws.jws2.RNAalifoldClient;
+import jalview.ws.uimodel.AlignAnalysisUIText;
+
+public class Jws2InstanceFactory
+{
+  private static HashMap<String, AlignAnalysisUIText> aaConGUI;
+  private static String category_rewrite(String cat_name)
+  {
+    return (cat_name != null && cat_name.equals("Prediction")) ? "Secondary Structure Prediction" : cat_name;
+  }
+  private static void init()
+  {
+    if (aaConGUI == null)
+    {
+      aaConGUI = new HashMap<String, AlignAnalysisUIText>();
+      aaConGUI.put(compbio.ws.client.Services.AAConWS.toString(),
+              AAConClient.getAlignAnalysisUITest());
+      aaConGUI.put(compbio.ws.client.Services.RNAalifoldWS.toString(),
+              RNAalifoldClient.getAlignAnalysisUITest());
+    }
+  }
+
+  /**
+   * construct a service instance and configure it with any additional
+   * properties needed so Jalview can access it correctly
+   * 
+   * @param jwsservers
+   * @param serviceType
+   * @param name
+   * @param description
+   * @param service
+   * @return
+   */
+  public static Jws2Instance newJws2Instance(String jwsservers,
+          String serviceType, String name, String description,
+          JABAService service)
+  {
+    init();
+    Jws2Instance svc = new Jws2Instance(jwsservers, serviceType, category_rewrite(name),
+            description, service);
+    
+    svc.aaui = aaConGUI.get(serviceType.toString());
+    return svc;
+  }
+
+}
diff --git a/src/jalview/ws/uimodel/AlignAnalysisUIText.java b/src/jalview/ws/uimodel/AlignAnalysisUIText.java
new file mode 100644 (file)
index 0000000..0d018a3
--- /dev/null
@@ -0,0 +1,115 @@
+package jalview.ws.uimodel;
+
+import java.util.HashMap;
+
+public class AlignAnalysisUIText
+{
+
+  private String serviceType;
+
+  public String getServiceType()
+  {
+    return serviceType;
+  }
+
+  private Class client;
+
+  private String calcId;
+
+  public String getCalcId()
+  {
+    return calcId;
+  }
+
+  private String AAconToggle, AAconToggleTooltip, AAeditSettings,
+          AAeditSettingsTooltip;
+
+  private boolean isNa;
+
+  public boolean isNa()
+  {
+    return isNa;
+  }
+
+  public boolean isPr()
+  {
+    return isPr;
+  }
+
+  public boolean isAA()
+  {
+    return isAA;
+  }
+
+  private boolean isPr;
+
+  private boolean isAA;
+
+  public AlignAnalysisUIText(String serviceType, Class<?> client,
+          String calcId, boolean acceptNucl, boolean acceptProt,
+          boolean acceptGaps, String toggle, String toggleTooltip,
+          String settings, String settingsTooltip)
+  {
+    this.serviceType = serviceType;
+    this.calcId = calcId;
+    isNa = acceptNucl;
+    isPr = acceptProt;
+    isAA = acceptGaps;
+    this.client = client;
+    this.AAconToggle = toggle;
+    this.AAconToggleTooltip = toggleTooltip;
+    this.AAeditSettings = settings;
+    this.AAeditSettingsTooltip = settingsTooltip;
+  }
+
+  public Class getClient()
+  {
+    return client;
+  }
+
+  public void setClient(Class client)
+  {
+    this.client = client;
+  }
+
+  public String getAAconToggle()
+  {
+    return AAconToggle;
+  }
+
+  public void setAAconToggle(String aAconToggle)
+  {
+    AAconToggle = aAconToggle;
+  }
+
+  public String getAAconToggleTooltip()
+  {
+    return AAconToggleTooltip;
+  }
+
+  public void setAAconToggleTooltip(String aAconToggleTooltip)
+  {
+    AAconToggleTooltip = aAconToggleTooltip;
+  }
+
+  public String getAAeditSettings()
+  {
+    return AAeditSettings;
+  }
+
+  public void setAAeditSettings(String aAeditSettings)
+  {
+    AAeditSettings = aAeditSettings;
+  }
+
+  public String getAAeditSettingsTooltip()
+  {
+    return AAeditSettingsTooltip;
+  }
+
+  public void setAAeditSettingsTooltip(String aAeditSettingsTooltip)
+  {
+    AAeditSettingsTooltip = aAeditSettingsTooltip;
+  }
+
+}
\ No newline at end of file
diff --git a/test/jalview/gui/JAL1353bugdemo.java b/test/jalview/gui/JAL1353bugdemo.java
new file mode 100644 (file)
index 0000000..486c098
--- /dev/null
@@ -0,0 +1,127 @@
+package jalview.gui;
+
+import static org.junit.Assert.*;
+import jalview.bin.Cache;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+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.JPanel;
+import javax.swing.JTextArea;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class JAL1353bugdemo
+{
+
+  @BeforeClass
+  public static void setUpBeforeClass() throws Exception
+  {
+  }
+
+  @AfterClass
+  public static void tearDownAfterClass() throws Exception
+  {
+  }
+  volatile boolean finish=false;
+
+  @Test
+  public void test()
+  {
+    Cache.initLogger();
+    // final Desktop foo = new Desktop();
+    final JFrame cfoo = new JFrame("Crash Java");
+    final JDesktopPane foo=new JDesktopPane();
+    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.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()
+    {
+      
+      @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();
+//        parent.setBounds(foo.getBounds());
+//        JPanel oo = new JPanel();
+//        parent.add(oo);
+//        oo.setVisible(true);
+//        parent.setVisible(true);
+        EditNameDialog end =new EditNameDialog("Sequence Name", "Sequence Description","label 1", "Label 2", "Try and drag between the two text fields", foo);//);cont.getRootPane());
+        assert(end!=null);
+        finish=true;
+      }
+    });
+    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;
+      }
+    });
+    foo.setVisible(true);
+    cfoo.setVisible(true);
+    while (!finish)
+    {
+      try {
+        Thread.sleep(100);
+      } catch (InterruptedException x) {}
+    }
+  }
+
+}
diff --git a/test/jalview/ws/jabaws/RNAStructExportImport.java b/test/jalview/ws/jabaws/RNAStructExportImport.java
new file mode 100644 (file)
index 0000000..2753e64
--- /dev/null
@@ -0,0 +1,232 @@
+package jalview.ws.jabaws;
+
+import static org.junit.Assert.*;
+
+import java.awt.Component;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Vector;
+
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+
+import jalview.api.AlignCalcManagerI;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.gui.Jalview2XML;
+import jalview.io.AnnotationFile;
+import jalview.io.FormatAdapter;
+import jalview.io.StockholmFileTest;
+import jalview.ws.jws2.AADisorderClient;
+import jalview.ws.jws2.Jws2Discoverer;
+import jalview.ws.jws2.RNAalifoldClient;
+import jalview.ws.jws2.SequenceAnnotationWSClient;
+import jalview.ws.jws2.dm.JabaOption;
+import jalview.ws.jws2.jabaws2.Jws2Instance;
+import jalview.ws.params.AutoCalcSetting;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import compbio.metadata.WrongParameterException;
+
+public class RNAStructExportImport
+{
+  public static String testseqs = "examples/unfolded_RF00031.aln";
+
+  public static Jws2Discoverer disc;
+
+  public static Jws2Instance rnaalifoldws;
+
+  jalview.ws.jws2.RNAalifoldClient alifoldClient;
+
+  public static jalview.gui.AlignFrame af = null;
+
+  @BeforeClass
+  public static void setUpBeforeClass() throws Exception
+  {
+
+    jalview.bin.Cache.initLogger();
+    disc = JalviewJabawsTestUtils.getJabawsDiscoverer();
+
+    for (Jws2Instance svc : disc.getServices())
+    {
+
+      if (svc.getServiceTypeURI().toLowerCase().contains("rnaalifoldws"))
+      {
+        rnaalifoldws = svc;
+      }
+    }
+
+    System.out.println("State of rnaalifoldws: " + rnaalifoldws);
+
+    if (rnaalifoldws == null)
+      System.exit(0);
+
+    jalview.io.FileLoader fl = new jalview.io.FileLoader(false);
+
+    af = fl.LoadFileWaitTillLoaded(testseqs, jalview.io.FormatAdapter.FILE);
+
+    assertNotNull("Couldn't load test data ('" + testseqs + "')", af);
+
+  }
+
+  @AfterClass
+  public static void tearDownAfterClass() throws Exception
+  {
+    if (af != null)
+    {
+      af.setVisible(false);
+      af.dispose();
+    }
+  }
+
+  @Test
+  public void testRNAStructExport()
+  {
+
+    alifoldClient = new RNAalifoldClient(rnaalifoldws, af, null, null);
+
+    af.getViewport().getCalcManager().startWorker(alifoldClient);
+
+    do
+    {
+      try
+      {
+        Thread.sleep(50);
+      } catch (InterruptedException x)
+      {
+      }
+      ;
+    } while (af.getViewport().getCalcManager().isWorking());
+
+    AlignmentI orig_alig = af.getViewport().getAlignment();
+
+    testAnnotationFileIO("Testing RNAalifold Annotation IO", orig_alig);
+
+  }
+
+  public static void testAnnotationFileIO(String testname, AlignmentI al)
+  {
+    try
+    {
+      // what format would be appropriate for RNAalifold annotations?
+      String aligfileout = new FormatAdapter().formatSequences("PFAM",
+              al.getSequencesArray());
+
+      String anfileout = new AnnotationFile().printAnnotations(
+              al.getAlignmentAnnotation(), al.getGroups(),
+              al.getProperties());
+      assertTrue(
+              "Test "
+                      + testname
+                      + "\nAlignment annotation file was not regenerated. Null string",
+              anfileout != null);
+      assertTrue(
+              "Test "
+                      + testname
+                      + "\nAlignment annotation file was not regenerated. Empty string",
+              anfileout.length() > "JALVIEW_ANNOTATION".length());
+
+      System.out.println("Output annotation file:\n" + anfileout
+              + "\n<<EOF\n");
+
+      // again what format would be appropriate?
+      AlignmentI al_new = new FormatAdapter().readFile(aligfileout,
+              FormatAdapter.PASTE, "PFAM");
+      assertTrue(
+              "Test "
+                      + testname
+                      + "\nregenerated annotation file did not annotate alignment.",
+              new AnnotationFile().readAnnotationFile(al_new, anfileout,
+                      FormatAdapter.PASTE));
+
+      // test for consistency in io
+      StockholmFileTest.testAlignmentEquivalence(al, al_new);
+      return;
+    } catch (Exception e)
+    {
+      e.printStackTrace();
+    }
+    fail("Test "
+            + testname
+            + "\nCouldn't complete Annotation file roundtrip input/output/input test.");
+  }
+
+  @Test
+  public void testRnaalifoldSettingsRecovery()
+  {
+    List<compbio.metadata.Argument> opts = new ArrayList<compbio.metadata.Argument>();
+    for (compbio.metadata.Argument rg : (List<compbio.metadata.Argument>) rnaalifoldws
+            .getRunnerConfig().getArguments())
+    {
+      if (rg.getDescription().contains("emperature"))
+      {
+        try
+        {
+          rg.setValue("292");
+        } catch (WrongParameterException q)
+        {
+          fail("Couldn't set the temperature parameter "
+                  + q.getStackTrace());
+        }
+        opts.add(rg);
+      }
+      if (rg.getDescription().contains("max"))
+      {
+        opts.add(rg);
+      }
+    }
+    alifoldClient = new RNAalifoldClient(rnaalifoldws, af, null, opts);
+    
+    af.getViewport().getCalcManager().startWorker(alifoldClient);
+    
+    do
+    {
+      try
+      {
+        Thread.sleep(50);
+      } catch (InterruptedException x)
+      {
+      }
+      ;
+    } while (af.getViewport().getCalcManager().isWorking());
+    AutoCalcSetting oldacs = af.getViewport().getCalcIdSettingsFor(alifoldClient.getCalcId());
+    String oldsettings = oldacs.getWsParamFile();
+    // write out parameters
+    jalview.gui.AlignFrame nalf=null;
+    assertTrue("Couldn't write out the Jar file",new Jalview2XML(false).SaveAlignment(af, "testRnalifold_param.jar","trial parameter writeout"));
+    assertTrue("Couldn't read back the Jar file",(nalf = new Jalview2XML(false).LoadJalviewAlign("testRnalifold_param.jar"))!=null);
+    if (nalf!=null)
+    {
+      AutoCalcSetting acs = af.getViewport().getCalcIdSettingsFor(alifoldClient.getCalcId());
+      assertTrue("Calc ID settings not recovered from viewport stash", acs.equals(oldacs));
+      assertTrue("Serialised Calc ID settings not identical to those recovered from viewport stash", acs.getWsParamFile().equals(oldsettings));
+      JMenu nmenu=new JMenu();
+      new SequenceAnnotationWSClient().attachWSMenuEntry(nmenu, rnaalifoldws, af);
+      assertTrue("Couldn't get menu entry for service",nmenu.getItemCount()>0);
+      for (Component itm: nmenu.getMenuComponents())
+      {
+        if (itm instanceof JMenuItem)
+        {
+          JMenuItem i = (JMenuItem) itm;
+          if (i.getText().equals(rnaalifoldws.getAlignAnalysisUI().getAAconToggle()))
+                  {
+            i.doClick();
+            break;
+                  }
+        }
+      }
+      while (af.getViewport().isCalcInProgress())
+      {
+        try { Thread.sleep(200);
+        } catch (Exception x) {};
+      }
+      AutoCalcSetting acs2 = af.getViewport().getCalcIdSettingsFor(alifoldClient.getCalcId());
+      assertTrue("Calc ID settings after recalculation has not been recovered.", acs2.getWsParamFile().equals(oldsettings));
+    }
+  }
+}
index 1fc49fc..2647f18 100755 (executable)
@@ -1268,7 +1268,7 @@ and any path to a file to save to the file]]></string>
                                                                <string><![CDATA[664]]></string>
                                                        </property>
                                                        <property name="sourceName">
-                                                               <string><![CDATA[min-jaba-client-2.0.jar]]></string>
+                                                               <string><![CDATA[min-jabaws-client-2.1.0.jar]]></string>
                                                        </property>
                                                        <property name="overrideUnixPermissions">
                                                                <boolean>false</boolean>
@@ -1286,7 +1286,7 @@ and any path to a file to save to the file]]></string>
                                                                <boolean>true</boolean>
                                                        </property>
                                                        <property name="destinationName">
-                                                               <string><![CDATA[min-jaba-client-2.0.jar]]></string>
+                                                               <string><![CDATA[min-jabaws-client-2.1.0.jar]]></string>
                                                        </property>
                                                        <property name="fileSize">
                                                                <long>133065</long>