Merge remote-tracking branch 'remotes/origin/2_5_1_rna_merge' into develop (JAL-826)
authorjprocter <jprocter@compbio.dundee.ac.uk>
Tue, 4 Oct 2011 15:50:04 +0000 (16:50 +0100)
committerjprocter <jprocter@compbio.dundee.ac.uk>
Tue, 4 Oct 2011 15:50:04 +0000 (16:50 +0100)
Conflicts:
.classpath
help/html/menus/alignmentMenu.html
help/html/whatsNew.html
src/jalview/gui/PopupMenu.java

68 files changed:
.classpath
.externalToolBuilders/Jalview Release indices [Builder].launch
doc/JalviewRNASupport.html [new file with mode: 0644]
help/help.jhm
help/helpTOC.xml
help/html/calculations/consensus.html
help/html/calculations/structureconsensus.html [new file with mode: 0755]
help/html/colourSchemes/index.html
help/html/colourSchemes/nucleotide.html
help/html/colourSchemes/purinepyrimidine.html [new file with mode: 0644]
help/html/colourSchemes/rnahelicesColouring.html [new file with mode: 0644]
help/html/colourSchemes/rnahelicescoloring.png [new file with mode: 0644]
help/html/features/jmol.html
help/html/features/seqfetch.html
help/html/features/varna.html [new file with mode: 0644]
help/html/io/fileformats.html
help/html/menus/alignmentMenu.html
help/html/menus/alwcolour.html
help/html/menus/alwfile.html
help/html/na/index.html [new file with mode: 0644]
help/html/whatsNew.html
lib/VARNAv3-9.jar [new file with mode: 0644]
src/jalview/analysis/Conservation.java
src/jalview/analysis/Rna.java [new file with mode: 0644]
src/jalview/analysis/StructureFrequency.java [new file with mode: 0644]
src/jalview/appletgui/AppletJmol.java
src/jalview/commands/EditCommand.java
src/jalview/datamodel/Alignment.java
src/jalview/datamodel/AlignmentAnnotation.java
src/jalview/datamodel/AlignmentI.java
src/jalview/datamodel/Annotation.java
src/jalview/datamodel/DBRefSource.java
src/jalview/datamodel/SequenceFeature.java
src/jalview/ext/varna/JalviewVarnaBinding.java [new file with mode: 0644]
src/jalview/ext/varna/VarnaCommands.java [new file with mode: 0644]
src/jalview/gui/AlignFrame.java
src/jalview/gui/AlignViewport.java
src/jalview/gui/AnnotationPanel.java
src/jalview/gui/AppJmol.java
src/jalview/gui/AppVarna.java [new file with mode: 0644]
src/jalview/gui/AppVarnaBinding.java [new file with mode: 0644]
src/jalview/gui/Desktop.java
src/jalview/gui/RNAHelicesColourChooser.java [new file with mode: 0644]
src/jalview/gui/SeqPanel.java
src/jalview/io/AlignFile.java
src/jalview/io/AnnotationFile.java
src/jalview/io/AppletFormatAdapter.java
src/jalview/io/JalviewFileChooser.java
src/jalview/io/StockholmFile.java
src/jalview/jbgui/GAlignFrame.java
src/jalview/jbgui/GRnaStructureViewer.java [new file with mode: 0644]
src/jalview/jbgui/GStructureViewer.java
src/jalview/schemes/ColourSchemeProperty.java
src/jalview/schemes/CovariationColourScheme.java [new file with mode: 0644]
src/jalview/schemes/PurinePyrimidineColourScheme.java [new file with mode: 0644]
src/jalview/schemes/RNAHelicesColour.java [new file with mode: 0644]
src/jalview/schemes/ResidueProperties.java
src/jalview/structure/SecondaryStructureListener.java [new file with mode: 0644]
src/jalview/structure/StructureSelectionManager.java
src/jalview/util/ColorUtils.java [new file with mode: 0644]
src/jalview/ws/SequenceFetcher.java
src/jalview/ws/dbsources/Pfam.java
src/jalview/ws/dbsources/PfamFull.java
src/jalview/ws/dbsources/PfamSeed.java
src/jalview/ws/dbsources/Rfam.java [new file with mode: 0644]
src/jalview/ws/dbsources/RfamFull.java [new file with mode: 0644]
src/jalview/ws/dbsources/RfamSeed.java [new file with mode: 0644]
src/jalview/ws/dbsources/Xfam.java [new file with mode: 0644]

index 1838768..cafb124 100644 (file)
@@ -1,6 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <classpath>
        <classpathentry kind="src" path="src"/>
+       <classpathentry kind="src" path="utils"/>
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
        <classpathentry kind="lib" path="lib/activation.jar"/>
        <classpathentry kind="lib" path="lib/axis.jar" sourcepath="D:/axis-1_2RC2-src/axis-1_2RC2"/>
@@ -42,5 +43,7 @@
        <classpathentry kind="lib" path="lib/commons-codec-1.3.jar"/>
        <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin.jar"/>
 <!--   <classpathentry exported="true" kind="var" path="GROOVY_ECLIPSE_HOME/groovy-all-1.0.jar"/> -->
+       <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin.java"/>
+       <classpathentry kind="lib" path="lib/VARNAv3-9.jar"/>
        <classpathentry kind="output" path="classes"/>
 </classpath>
index 57994d7..a5659a6 100644 (file)
@@ -15,6 +15,7 @@
 <stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="jalview"/>
 <stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/>
 <stringAttribute key="org.eclipse.ui.externaltools.ATTR_ANT_TARGETS" value="buildindices,"/>
+<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_BUILDER_ENABLED" value="false"/>
 <stringAttribute key="org.eclipse.ui.externaltools.ATTR_LAUNCH_CONFIGURATION_BUILD_SCOPE" value="${none}"/>
 <stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${build_project}/build.xml"/>
 <stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,"/>
diff --git a/doc/JalviewRNASupport.html b/doc/JalviewRNASupport.html
new file mode 100644 (file)
index 0000000..d96cca5
--- /dev/null
@@ -0,0 +1,75 @@
+<html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+-->
+<title>Jalview RNA Support</title>
+<body>
+<h1>
+Jalview RNA Support
+</h1>
+<p>
+Jalview RNA support has been added in part during a 
+<a href="http://socghop.appspot.com/gsoc/program/home/google/gsoc2010">Google Summer of Code Project</a>.
+More information about this project can be found at the 
+<a href="https://www.nescent.org/wg_phyloinformatics/PhyloSoC:Extending_Jalview_to_Support_RNA_Alignment_Annotation_and_Secondary_Structure_Visualization">
+NESCent wiki page</a> and the project <a href="http://jalview-rnasupport.blogspot.com/">blog</a>. 
+</p>
+<h2>What was added</h2>
+<p>
+<ul>
+<li>Recognition of ".stk" and ".sto" extensions for Stockholm file format.</li>
+<li>Purine/Pyrimidine colour scheme.</li>
+<li>Colouring by RNA helices. Helices are determined from the secondary structure line written in WUSS format in Stockholm files.</li>
+<li>Ability to fetch sequences from RFAM.</li>
+<li>Visualization of RNA secondary structure in WUSS format (from input file) and RNA helices in the 
+annotation panel.</li>
+</ul>
+</p>
+<h2>TODO</h2>
+<h3>Secondary Structure Visualization/Annotation</h3>
+<ul>
+<li>Detection of pseudoknots and tetraloops </li>
+<li>Update colouring of RNA helices in annotation panel when "By RNA helices" colouring is selected</li>
+<li>Editing of secondary structure line</li>
+<li>Update helix colouring when secondary structure changes.</li>
+<li>Support per sequence in RNA secondary structure annotation</li>
+<li>Enable RNA secondary structure annotation to be imported/exported through Jalview annotation files</li>
+</ul>
+
+<h3>Colour schemes</h3>
+<ul>
+<li>Coloring scheme for pseudoknots</li>
+<li>Covariation colour scheme similar to RFAM's</li>
+<li>Coloring schemes from other MSA viewers, like 4Sale and Assemble</li>
+<li>Highlight positions in alignments that break base pairing specified in the secondary structure line</li>
+</ul>
+<h3>Embed VARNA, An RNA Secondary Structure Viewer</h3>
+<ul>
+<li>The homepage for VARNA can be found <a href="http://varna.lri.fr/">here</a>.</li>
+<li>Hook VARNA into Jalview</li>
+<li>Ability to port RNA secondary structure (e.g. from Stockholm files) into VARNA</li>
+<li>Mouse over and selections get highlighted in the linked views</li>
+</ul>
+<h3>Miscellaneous</h3>
+<ul>
+<li>Add changes done to the main gui to the applet gui</li>
+<li>Add export of Stockholm file format</li>
+</ul>
+</p> 
+</body>
+</html>
+
index 261d6d0..91ef827 100755 (executable)
@@ -29,6 +29,7 @@
    <mapID target="viewingpdbs" url="html/features/viewingpdbs.html"/>
    <mapID target="pdbmcviewer" url="html/features/pdbviewer.html"/>
    <mapID target="pdbjmol" url="html/features/jmol.html"/>
+   <mapID target="varna" url="html/features/varna.html"/>
    <mapID target="preferences" url="html/features/preferences.html"/>     
    <mapID target="commandline" url="html/features/commandline.html"/>
    <mapID target="clarguments" url="html/features/clarguments.html"/>
    <mapID target="colours.abovepid" url="html/colourSchemes/abovePID.html"/>
    <mapID target="colours.conservation" url="html/colourSchemes/conservation.html"/>
    <mapID target="colours.annotation" url="html/colourSchemes/annotationColouring.html"/>
+   <mapID target="colours.purinepyrimidine" url="html/colourSchemes/purinepyrimidine.html"/>
+   <mapID target="colours.rnahelices" url="html/colourSchemes/rnahelicesColouring.html"/>
    
    <mapID target="calcs.alquality" url="html/calculations/quality.html"/>   
    <mapID target="calcs.alconserv" url="html/calculations/conservation.html"/>
+   <mapID target="calcs.alstrconsensus" url="html/calculations/structureconsensus.html"/>  
    <mapID target="calcs.consensus" url="html/calculations/consensus.html"/>
    
+   <mapID target="nucleicAcids" url="html/na/index.html"/>
+   
    <mapID target="menus" url="html/menus/index.html"/>
    <mapID target="desktopMenu" url="html/menus/desktopMenu.html"/>
    <mapID target="alMenu" url="html/menus/alignmentMenu.html"/>
index 926a710..6cc51dd 100755 (executable)
 <toc version="1.0">
 <tocitem text="Jalview Documentation" target="home" expand="true" >
        <tocitem text="What's new" target="new" expand="true">
-      <tocitem text="Enhanced Jmol/Jalview interaction" target="pdbjmol"/>
-          <tocitem text="Multi-Harmony Alignment Analysis" target="shmrws"/>
-          <tocitem text="Jalview News Reader" target="newsreader"/>
-          <tocitem text="Sort alignments associated with tree" target="treeviewer"/>
-      <tocitem text="Default Annotation preferences" target="colours.annotation"/>
-      <tocitem text="Jaba Web Services" target="jabaws"/>
+               <tocitem text="Viewing RNA structure" target="varna" />
+               <tocitem text="RNA Structure Consensus" target="calcs.alstrconsensus"/>
+               <tocitem text="RNA Helices coloring" target="colours.rnahelices"/>
        </tocitem>
     <tocitem text="Editing Alignments" target ="edit"/>        
     <tocitem text="Cursor Mode" target="cursor"/>
        <tocitem text="Multiple Views" target="multipleviews"/>
        <tocitem text="Viewing Trees" target="treeviewer" expand="false"/>
        <tocitem text="Fetching Sequences" target="seqfetch"/>
+       <tocitem text="Nucleic Acid Support" target="nucleicAcids" expand="false">
+               <tocitem text="Viewing RNA structure" target="varna" />
+               <tocitem text="RNA Structure Consensus" target="calcs.alstrconsensus"/>
+               <tocitem text="RNA Helices coloring" target="colours.rnahelices"/>
+       </tocitem>
        <tocitem text="Sequence Features" target="seqfeatures" expand="false">
           <tocitem text="Sequence Feature Settings" target="seqfeatures.settings"/>
           <tocitem text="Sequence Features File" target="features.fileformat"/>
                <tocitem text="Turn propensity" target="colours.turn"/>
                <tocitem text="Buried index" target="colours.buried"/>
                <tocitem text="Nucleotide colours" target="colours.nucleotide"/>
+               <tocitem text="Purine/Pyrimidine colours" target="colours.purinepyrimidine"/>
                <tocitem text="Blosum62" target="colours.blosum"/>
                <tocitem text="by Percentage Identity" target="colours.pid"/>   
                <tocitem text="User Defined" target="colours.user"/>
                <tocitem text="Above Percentage Identity" target="colours.abovepid"/>
                <tocitem text="By conservation" target="colours.conservation"/>
                <tocitem text="By Annotation" target="colours.annotation"/>
+               <tocitem text="By RNA Helices" target="colours.rnahelices"/>
        </tocitem>
        <tocitem text="Calculations" target="calculations" expand="false">
                <tocitem text="Sorting alignments" target="sorting"/>
                <tocitem text="Remove Redundancy" target="redundancy"/>
        </tocitem>
        <tocitem text="Alignment Annotations" target ="alannotation" expand="false">
-          <tocitem text="Conservation" target="calcs.alconserv"/>
+          <tocitem text="Conservation" target="calcs.alconserv"/>          
           <tocitem text="Quality" target="calcs.alquality"/>
           <tocitem text="Consensus" target="calcs.consensus"/>
+          <tocitem text="RNA Structure Consensus" target="calcs.alstrconsensus"/>
           <tocitem text="Annotations File Format" target="annotations.fileformat"/>
         </tocitem>
        <tocitem text="Viewing PDB Files" target="viewingpdbs" expand="false">
          <tocitem text="Jmol Viewer" target="pdbjmol"/>
          <tocitem text="Simple PDB Viewer" target="pdbmcviewer"/>
        </tocitem>
+       <tocitem text="Viewing RNA structures" target="varna" expand="false">   </tocitem>
        <tocitem text="VAMSAS Data Exchange" target="vamsas">
                <!-- what can Jalview share with other apps -->
                <!-- what other apps exist -->
index 5a962a4..e03be16 100644 (file)
 <p>Select the <strong>&quot;Copy Consensus Sequence&quot;</strong> entry from 
 the consensus annotation label to copy the alignment's consensus sequence to the 
 clipboard. 
+
+<p><strong>Sequence logo</strong></p> 
+By clicking on the label you can also activate the sequence logo. It
+indicates the relative amount of residues per column which can be
+estimated by it's size in the logo. The tooltip of a column gives the
+exact numbers for all occuring residues.
 </p>
 </body>
 </html>
diff --git a/help/html/calculations/structureconsensus.html b/help/html/calculations/structureconsensus.html
new file mode 100755 (executable)
index 0000000..8455f47
--- /dev/null
@@ -0,0 +1,44 @@
+<html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6.1)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+-->
+<head><title>Alignment RNA Structure Consensus Annotation</title></head>
+<body><p><strong>Alignment RNA Structure Consensus Annotation</strong></p>
+
+<p>The RNA structure consensus displayed below the alignment is the
+percentage of valid base pairs per column. It is calculated in
+relation to a secondary structure and just paired columns are
+calculated. The canonical Watson-Crick base pairings (A-T/U, G-C) and
+the wobble base pair (G-T/U) are regarded as valid pairings.<br>  
+The amount of valid base pairs is indicated by the profile in the
+Alignment Annotation row.<br>  
+By default this calculation includes gaps in columns. You can choose
+to ignore gaps in the calculation by right clicking on the label
+&quot;StrConsensus&quot; to the left of the structure consensus bar
+chart.<br>
+
+<p><strong>Structure logo</strong></p>
+By clicking on the label you can also activate the structure logo. It is very
+similar to a sequence logo but counts the numbers of base pairs. There
+are two residues per column, the actual column and the interacting
+base. The opening bracket is always the one on the left side.<br>
+Like sequence logos the relative amount of a specific base pair can be
+estimated by it's size in the logo. The tool tip of a column gives the
+exact numbers for all occurring valid base pairs.
+</p>
+</body>
+</html>
index 70d74ee..5254819 100755 (executable)
@@ -49,6 +49,7 @@ background, and the intensity threshold for transition between them.</p>
 <p>The default colour schemes are summarised in the table below:
 <div align="center">
 <p>&nbsp;</p>
+<p><strong>Protein Colour Schemes</strong></p>
 <table border="1">
        <tr>
                <td>
@@ -291,6 +292,81 @@ background, and the intensity threshold for transition between them.</p>
                </td>
        </tr>
 </table>
+<p>&nbsp;</p>
+<p><strong>Nucleotide Colour Schemes</strong></p>
+<table border="1">
+       <tr>
+               <td>
+               <table border="1">
+                       <tr>
+                               <td nowrap></td>
+                               <td>A</td> <!--Adenine-->
+                           <td>C</td> <!--Cytosine-->
+                       <td>G</td> <!--Guanine-->
+                       <td>T</td> <!--Thymine-->
+                       <td>U</td> <!--Uracil-->
+                       <td>I</td> <!--Inosine-->
+                       <td>X</td> <!--Xanthine-->
+                       <td>R</td> <!--Unknown Purine-->
+                       <td>Y</td> <!--Unknown Pyrimidine-->
+                       <td>N</td> <!--Unknown-->
+                       <td>W</td> <!--Weak nucleotide (A or T)-->
+                       <td>S</td> <!--Strong nucleotide (G or C)-->
+                       <td>M</td> <!--Amino (A or C)-->
+                       <td>K</td> <!--Keto (G or T)-->
+                       <td>B</td> <!--Not A (G or C or T)-->
+                       <td>H</td> <!--Not G (A or C or T)-->
+                       <td>D</td> <!--Not C (A or G or T)-->
+                       <td>V</td> <!--Not T (A or G or C-->
+                       </tr>
+                       <tr>
+                               <td height="24">Nucleotide</td>
+                               <td bgcolor="#64F73F"></td>
+                               <td bgcolor="#FFB340"></td>
+                       <td bgcolor="#EB413C"></td>
+                       <td bgcolor="#3C88EE"></td>
+                       <td bgcolor="#3C88EE"></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       </tr>
+                       <tr>
+                               <td height="24">Purine/Pyrimidine</td>
+                               <td bgcolor="#FF83FA"></td>
+                               <td bgcolor="#40E0D0"></td>
+                       <td bgcolor="#FF83FA"></td>
+                       <td bgcolor="#40E0D0"></td>
+                       <td bgcolor="#40E0D0"></td>
+                       <td></td>
+                       <td></td>
+                       <td bgcolor="#FF83FA"></td>
+                       <td bgcolor="#40E0D0"></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       <td></td>
+                       </tr>
+               </table>
+               </td>
+       </tr>
+</table>
+
+
 </div>
 <p align="center">&nbsp;</p>
 </body>
index a0d4c8c..c4d42ef 100755 (executable)
@@ -35,6 +35,7 @@ td {
       <td bgcolor="#FFB340">C</td>
       <td bgcolor="#EB413C">G</td>
       <td bgcolor="#3C88EE">T</td>
+      <td bgcolor="#3C88EE">U</td>
     </tr>
   </table>
 </div>
diff --git a/help/html/colourSchemes/purinepyrimidine.html b/help/html/colourSchemes/purinepyrimidine.html
new file mode 100644 (file)
index 0000000..373f0d0
--- /dev/null
@@ -0,0 +1,40 @@
+<html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+-->
+<head><title>Purine/Pyrimidine Colour Scheme</title>
+<style type="text/css">
+<!--
+td {
+       text-align: center;
+}
+-->
+</style>
+</head>
+
+<body>
+<p><em>Purine/Pyrimidine Colours</em></p>
+<div align="center">
+  <table width="200" border="1">
+    <tr>
+      <td bgcolor="#FF83FA">Purines <BR> A, G, R</td>
+      <td bgcolor="#40E0D0">Pyrimidines <BR> C, U, T, Y</td>
+    </tr>
+  </table>
+</div>
+</body>
+</html>
diff --git a/help/html/colourSchemes/rnahelicesColouring.html b/help/html/colourSchemes/rnahelicesColouring.html
new file mode 100644 (file)
index 0000000..3034bf5
--- /dev/null
@@ -0,0 +1,50 @@
+<html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+-->
+<head><title>RNA Helices Colouring</title></head>
+
+<body>
+<p><strong> RNA Helices Colouring </strong></p>
+<p>An RNA alignment loaded from a Stockholm file can be coloured 
+   based on its helices.  The helices are determined from the 
+   secondary structure line in the Stockholm file (#GC SS_cons) 
+   written in WUSS notation
+   that specifies base pairing. See <a href="http://en.wikipedia.org/wiki/Stockholm_format">
+   Wikipedia</a> or <a href="http://jalview-rnasupport.blogspot.com/2010/06/parsing-wuss-notation-of-rna-secondary.html">
+   Jalview RNA Support Blog</a> for more information about Stockholm files and WUSS notation.</p>
+Select &quot;Colour&quot; <strong>&#8594;</strong> &quot; 
+  By RNA Helices&quot; to colour the alignment by RNA helices. <br>
+  <br>
+<p><em>Features</em></p>
+<ul>
+<li>Colours are generated randomly for the number of helices present.  
+Reselect the "By RNA Helices" option to generate another set of random colors. </li>
+<li>Sequence logo is in <a href="purinepyrimidine.html">
+Purine/Pyrimidine colour scheme</a>. </li>
+<li>Line above the "Secondary Structure" line in annotation panel is WUSS notation present
+in the input file.</li>
+</ul>
+  
+  
+  
+  <div align="center">
+  <img src="rnahelicescoloring.png" width="600" height="140"> </div> 
+
+</body>
+</html>
diff --git a/help/html/colourSchemes/rnahelicescoloring.png b/help/html/colourSchemes/rnahelicescoloring.png
new file mode 100644 (file)
index 0000000..05e9230
Binary files /dev/null and b/help/html/colourSchemes/rnahelicescoloring.png differ
index 93146a5..8a5d75b 100644 (file)
@@ -23,7 +23,7 @@
 <p><strong>The Jmol PDB Viewer</strong></p>\r
 <p>Since Jalview 2.3, <a href="http://jmol.sourceforge.net/">Jmol</a>\r
 has been integrated into Jalview for interactively viewing structures\r
-opened by selecting the <strong>&quot;Sequence&#8594;View PDB\r
+opened by selecting the <strong>&quot;Structure&#8594;View PDB\r
 entry:&quot;</strong> option in the <a href="../menus/popupMenu.html">sequence\r
 id pop-up menu</a> (if you can't see this, then you need to <a\r
        href="viewingpdbs.html">associate a PDB structure</a> with the\r
index cca5c66..f61e15a 100755 (executable)
 </head>
 <body>
 <p><strong>Sequence Fetcher</strong></p>
-<p>Jalview can retrieve sequences from certain databases using
-either the WSDBFetch service provided by the European Bioinformatics
-Institute, and, since Jalview 2.4, DAS servers capable of the <em>sequence</em>
-command (configured in <a href="dassettings.html">DAS settings</a>).</p>
-<img src="seqfetcher.gif" align="center"
-       alt="The Jalview Sequence Fetcher Dialog Box">
-<p>The Sequence Fetcher dialog box can be opened via the
-&quot;File&quot; menu on the main desktop in order to retrieve sequences
-as a new alignment, or opened via the &quot;File&quot; menu of an
-existing alignment to import additional sequences. Please note, there
-will be a short delay when the sequence fetcher is first opened, whilst
-Jalview compiles the list of available sequence datasources from the
-currently defined DAS server registry.</strong></p>
-<p>First, select the database you want to retrieve sequences from.
-Then, enter one or more accession ids (as a semi-colon separated list),
-or press the &quot;Example&quot; button to paste the example accession
-for the currently selected database into the retrieval box. Finally,
-press &quot;OK&quot; to initiate the retrieval.</p>
-<p><em>Fetching Individual PDB Chains</em><br>
-If you are retrieving sequences from the PDB, you can retrieve specific
-chains by appending a colon and the chain id to the PDB id. For example
-:<br>
-<pre> 1GAQ:A</pre>
-</p>
-<p><em>Retrieving parts of large sequence records</em><br>
-When retrieving from DAS sequence sources, coordinate range arguments
-can be passed to the server using the standard DAS sequence command
-format:<pre>
-  &lt;AccessionId&gt;:&lt;start&gt;,&lt;end&gt;</pre> If you know a source
-understands this type of query format, then you should untick the
-checkbox for 'replace commas with semi-colons' so the range query can be
-passed to the server; otherwise, the query will be split into two (e.g
-'Mito:1' and '85779' rather than 'Mito:1,85779'). In most cases,
-however, a source that supports range queries will include a range
-qualification in its example query, and Jalview will then automatically
-disable the 'replace commas with semi-colons' option.<br>
-<em>The option to disable the comma to semi-colon translation was
-added in Jalview 2.6</em></p>
-<p>If you use the WSDBFetch sequence fetcher services (EMBL,
-Uniprot, PDB and PFAM) in work for publication, please cite:</p>
-<p>Pillai S., Silventoinen V., Kallio K., Senger M., Sobhany S.,
-Tate J., Velankar S., Golovin A., Henrick K., Rice P., Stoehr P., Lopez
-R. <br>
-SOAP-based services provided by the European Bioinformatics Institute.<br>
-Nucleic Acids Res. 33(1):W25-W28 (2005) <br>
-<br>
+<p>Jalview can retrieve sequences from certain databases using either the
+WSDBFetch service provided by the European Bioinformatics Institute, and, since Jalview 2.4, DAS servers capable of the <em>sequence</em> command (configured in <a href="dassettings.html">DAS settings</a>).</p>
+<img src="seqfetcher.gif" align="center" alt="The Jalview Sequence Fetcher Dialog Box">
+<p>The Sequence Fetcher dialog box can be opened via the &quot;File&quot; 
+  menu on the main desktop in order to retrieve sequences as a new
+  alignment, or opened via the &quot;File&quot; menu of an existing alignment
+  to import additional sequences. Please note, there will be a short delay when the sequence fetcher is first opened, 
+  whilst Jalview compiles the list of available sequence datasources from the 
+  currently defined DAS server registry.</strong>
 </p>
+<p>First, select the database you want to retrieve sequences from. Then, enter
+  one or more accession ids (as a semi-colon separated list), or press the 
+  &quot;Example&quot; button to paste the example accession for the currently selected database into the retrieval box.
+   Finally, press &quot;OK&quot; to initiate the retrieval.</p>
+<p>
+  If you are retrieving sequences from the PDB, you can retrieve
+  specific chains by appending a colon and the chain id to the PDB
+  id. For example :<br><pre> 1GAQ:A</pre><br>When retrieving from DAS sequence sources,
+  coordinate range arguments can be passed to the server using the standard DAS 
+  sequence command format (<strong>:&lt;start&gt;,&lt;end&gt;</strong>)</p>
+<p>If you use the WSDBFetch sequence fetcher services (EMBL, Uniprot, PDB, PFAM, and RFAM)
+   in work for publication, please cite:</p>
+<p>Pillai S., Silventoinen V., Kallio K., Senger M., Sobhany S., Tate J., Velankar 
+  S., Golovin A., Henrick K., Rice P., Stoehr P., Lopez R. <br>
+  SOAP-based services provided by the European Bioinformatics Institute.<br>
+  Nucleic Acids Res. 33(1):W25-W28 (2005) <br>
+  <br>
+  </p>
 </body>
 </html>
diff --git a/help/html/features/varna.html b/help/html/features/varna.html
new file mode 100644 (file)
index 0000000..12d9207
--- /dev/null
@@ -0,0 +1,74 @@
+<html>\r
+<!--\r
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6.1)\r
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle\r
+ * \r
+ * This file is part of Jalview.\r
+ * \r
+ * Jalview is free software: you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License \r
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\r
+ * \r
+ * Jalview is distributed in the hope that it will be useful, but \r
+ * WITHOUT ANY WARRANTY; without even the implied warranty \r
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR \r
+ * PURPOSE.  See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.\r
+-->\r
+<head>\r
+<title>The VARNA RNA Viewer</title>\r
+</head>\r
+<body>\r
+<p><strong>The VARNA RNA Viewer</strong></p>\r
+<p>Since Jalview\r
+2.7.1, <a href="http://varna.lri.fr/index.html">VARNA</a> has been\r
+integrated into Jalview for interactively viewing structures opened by\r
+selecting the <strong>&quot;Structure&#8594;View\r
+Structure:&quot;</strong> option in\r
+the <a href="../menus/popupMenu.html">sequence id pop-up menu</a> (if\r
+you can't see this, then no RNA structure is associated with your\r
+sequence or alignment. In the pop-up menu all structures that\r
+are associated with this sequence and all sequences that are\r
+associated with the alignment are available.\r
+\r
+<p><strong>Different structures</strong></p>\r
+<ul>\r
+  <li>\r
+    <b>Alignment structures</b>:\r
+    Structures associated with the alignment are marked by having &quot;consensus&quot; attached to their name. VARNA contains two different entries for consensus structures.\r
+    <ul>\r
+      <li>Consensus structure: the individual sequence folded into the consensus structure</li>\r
+      <li>Trimmed consensus structure: the individual sequence\r
+       folded into the the gap-free consensus structure. That means all\r
+       columns that contained gaps in the individual sequence were\r
+       removed. If this breaks a base-pair the pairing is removed also.\r
+       This can be considered as an approximation for the individual structure.\r
+    </ul>\r
+  </li>\r
+  <li>\r
+    <b>Individual structures</b>:\r
+    this is a structure associated with the individual sequence and therefore not related to the alignment    \r
+  </li>\r
+\r
+<p><strong>Controls</strong><br>\r
+<ul>\r
+<li>Rotate view - Left Click and drag</li>\r
+<li>Zoom in - Press '+'</li>\r
+<li>Zoom out - Press '-'</li>\r
+<li>Choose a different structure - Left click on structure in the left hand panel</li>\r
+<li>Highlighting bases - Move mouse over columns in the Jalview alignment panel</li>\r
+</ul>\r
+\r
+<p><strong>Functionality provided by VARNA</strong></p>\r
+<p>VARNA's own functions are accessed by right-clicking in the\r
+structure display area. That will open the VARNA pop-up menu,\r
+which provides access to a number of features like different draw algorithm, color highlighting or annotations. \r
+</p>\r
+<p><strong>More Information</strong></p>\r
+<p>VARNA is a very powerful RNA viewer on its own. Only the\r
+essentials have been described here - the interested reader is\r
+referred to <a href="http://varna.lri.fr/usermanual.html">VARNA's own\r
+comprehensive online documentation</a>.</p>\r
+</body>\r
+</html>\r
index 9172b28..7f7f595 100755 (executable)
@@ -63,6 +63,11 @@ THISISASEQENCE<br></td>
 </tr><tr><td width="17%">PFAM</td>
 <td width="60%">SequenceName THISISASEQENCE</td>
 <td width="23%">.pfam</td>
+</tr><tr>
+<td width="17%">Stockholm</td>
+<td width="60%"># STOCKHOLM VersionNumber<br>
+<em>...</em><br>//</td>
+<td width="23%">.stk, .sto</td>
 </tr>
 </table>
 <p>The file extensions are used to associate jalview alignment icons
index ff74139..6a5ec9f 100755 (executable)
@@ -28,8 +28,8 @@
                <li><strong>File</strong>
                        <ul>
                                <li><strong>Fetch Sequence</strong><br> <em>Shows a
-                                               dialog window in which you can select known ids from Uniprot,
-                                               EMBL, EMBLCDS or PDB database using Web Services provided by the
+                                               dialog window in which you can retrieve known ids from Uniprot,
+                                               EMBL, EMBLCDS, PFAM, Rfam, or PDB database using Web Services provided by the
                                                European Bioinformatics Institute. See <a
                                                href="../features/seqfetch.html">Sequence Fetcher</a> </em>.</li>
                                <li><strong>Add Sequences</strong><em><br> Add
 
                                        </ul></li>
                        </ul>
+       </li>
+
+               </ul>
                </li>
 
                <li><strong>Colour</strong>
                                <li>Colour Scheme options: <strong>None, ClustalX,
                                                Blosum62 Score, Percentage Identity, Zappo, Taylor,
                                                Hydrophobicity, Helix Propensity, Strand Propensity, Turn
-                                               Propensity, Buried Index, Nucleotide, User Defined<br> </strong> <em>See
+                                               Propensity, Buried Index, Nucleotide, Purine/Pyrimidine, User Defined<br> </strong> <em>See
                                                <a href="../colourSchemes/index.html">colours</a> for a
                                                description of all colour schemes.</em><br></li>
                                <li><strong>By Conservation<br> </strong><em>See <a
                                                the alignment on a per-column value from a specified annotation.
                                                See <a href="../colourSchemes/annotationColouring.html">Annotation
                                                        Colouring</a>.</em><br></li>
+               <li><strong>By RNA Helices</strong><br>
+               <em>Colours the helices of an RNA alignment loaded from a Stockholm file. See 
+               <a href="../colourSchemes/rnahelicesColouring.html">RNA Helices
+               Colouring</a>.</em><br>
+               </li>
                        </ul></li>
                <li><strong>Calculate</strong>
                        <ul>
index 3093edd..60f8987 100755 (executable)
@@ -31,7 +31,7 @@
       </em></li>
     <li>Colour Scheme options: <strong>None, ClustalX, Blosum62 Score, Percentage 
       Identity, Zappo, Taylor, Hydrophobicity, Helix Propensity, Strand Propensity, 
-      Turn Propensity, Buried Index, Nucleotide, User Defined<br>
+      Turn Propensity, Buried Index, Nucleotide, Purine/Pyrimidine, User Defined<br>
       </strong> <em>See <a href="../colourSchemes/index.html">colours</a> for 
       a description of all colour schemes.</em><br>
     </li>
       <em>Colours the alignment on a per-column value from a specified annotation. 
       See <a href="../colourSchemes/annotationColouring.html">Annotation Colouring</a>.</em><br>
     </li>
+    <li><strong>By RNA Helices</strong><br>
+               <em>Colours the helices of an RNA alignment loaded from a Stockholm file. See 
+               <a href="../colourSchemes/rnahelicesColouring.html">RNA Helices
+               Colouring</a>.</em><br>
+               </li>
   </ul>
 </body>
 </html>
index af3e105..9cbd3ea 100755 (executable)
@@ -25,7 +25,7 @@
 <ul>
        <li><strong>Fetch Sequence</strong><br>
        <em>Shows a dialog window in which you can select known ids from
-       Uniprot, EMBL, EMBLCDS or PDB database using Web Services provided by
+       Uniprot, EMBL, EMBLCDS, PDB, PFAM, or RFAM databases using Web Services provided by
        the European Bioinformatics Institute. See <a
                href="../features/seqfetch.html">Sequence Fetcher</a></em>.</li>
        <li><strong>Add Sequences</strong><em><br>
diff --git a/help/html/na/index.html b/help/html/na/index.html
new file mode 100644 (file)
index 0000000..c247ab1
--- /dev/null
@@ -0,0 +1,58 @@
+<html>
+<!--
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+-->
+<head>
+<title>Nucleic Acid Support</title>
+<style type="text/css">
+<!--
+td {
+       font-family: "Courier New", Courier, mono;
+       font-style: normal;
+       font-size: medium;
+}
+-->
+</style>
+</head>
+<body>
+<p><strong>Nucleic Acid Support</strong></p>
+<p><em>Colour Schemes</em></p>
+<p>Jalview has color schemes for nucleic acid based sequences, ability to 
+fetch sequences from RFAM and RNA secondary structure coloring</p>
+<p>Information on the <a href="../colourSchemes/nucleotide.html">Nucleotide 
+colour scheme</a> and <a href="../colourSchemes/purinepyrimidine.html">
+Purine/Pyrimidine colour scheme</a> are available
+under the Colour Menu.  See <a href="../colourSchemes/index.html">Colour 
+Schemes</a>.</p>
+<p><em>RNA Support</em></p>
+<p>Sequences can be <a href="../features/seqfetch.html">fetched</a> from the 
+RFAM database by accession number or ID.</p>
+<p>If an RNA alignment is loaded from a Stockholm file with secondary
+structure information in WUSS notation, the alignment can be coloured by 
+the helices in the secondary structure. Helices are determined by the base-pairing
+in the secondary structure line. See <a href="../colourSchemes/rnahelicesColouring.html">
+RNA Helices Colouring</a>. Below is an example of this type of coloring</p>
+<p>Annotation panel shows the presence of RNA helices and WUSS notation from
+input file specifying secondary structure.<p>
+<div align="center">
+  <img src="../colourschemes/rnahelicescoloring.png" width="600" height="140"> </div> 
+
+</div>
+<p align="center">&nbsp;</p>
+</body>
+</html>
index cf96d47..3ff173b 100755 (executable)
                <strong>What's new ?</strong>
        </p>
        <p>
-               The Jalview 2.7 release features new web services, and important
-               improvements to the way in which Jalview handles alignments and
-               associated PDB structures, as well as numerous minor improvements and
-               bug fixes. Version 2.7 of the JalviewLite applet also features a
-               significantly enhanced Javascript API enabling it to be more easily
-               integrated with javascript based web applications. <br /> For full
-               details see the <a href="releases.html#Jalview2.7">Jalview 2.7
+               The Jalview 2.7.1 release features (tbc)
+               <br /> For full
+               details see the <a href="releases.html#Jalview2.7.1">Jalview 2.7.1
                        release history</a>.
        </p>
        <p>
-               <strong>Highlights in Jalview Desktop Version 2.7</strong>
+               <strong>Highlights in Jalview Desktop Version 2.7.1</strong>
        </p>
        <ul>
-               <li>New <a href="features/viewingpdbs.html">structure viewer
-                               options</a>:
-                       <ul>
-                               <li>Colour and superimpose 3D structures of complexes and
-                                       multi-domain chains using several different alignments</li>
-                               <li>Drag and drop to associate PDB files with sequences that
-                                       have the same name</li>
-                               <li>Open and superimpose all associated structures for the
-                                       current selection</li>
-                       </ul>
-               <li>New web services for <a href="webServices/shmr.html">alignment
-                               analysis</a></li>
-               <li>Improved graphical user interface for <a
-                       href="http://www.compbio.dundee.ac.uk/jabaws">JABAWS</a>services.
-               </li>
-               <li>Sort associated alignment views option in tree viewer</li>
-               <li>Default colours for <a
-                       href="colourSchemes/annotationColouring.html">shading alignment
-                               by quantitative annotation</a>.
-               </li>
-               <li><a href="webServices/newsreader.html">Jalview Desktop RSS
-                               reader</a> - following important updates at <a
-                       href="http://www.jalview.org/feeds/desktop/rss">http://www.jalview.org/feeds/desktop/rss</a>
+
+       <li>New Purine/Pyrimidine colour scheme</li>
+       <li>Colouring of RNA secondary structure by helices.  See <a href="na/index.html">Nucleic Acid Support</a></li>
+       <li>Embedded <a href="http://www.varna.fr/">VARNA</a> RNA secondary structure viewer.
        </ul>
 
        <p>
                <strong>Issues Resolved (a select list - see the <a
-                       href="releases.html#Jalview2.7">release history</a> for full details)
+                       href="releases.html#Jalview2.7.1">release history</a> for full details)
                </strong>
        </p>
        <p>
                <strong>Issues in the Jalview Desktop</strong>
        <ul>
-               <li>Problems viewing associated structures for sequences
-                       retrieved from UNIPROT</li>
-               <li>Problems viewing Jalview projects from older versions in
-                       version 2.6</li>
-               <li>Preservation of hidden annotation rows and tree bootstrap
-                       values in projects</li>
-               <li>Newly added JABAWS servers not always visible in web services
-                       menu</li>
        </ul>
        <strong>Issues specific to the JalviewLite Applet</strong>
        <ul>
-               <li>Layout problems when lots of annotation rows are displayed</li>
-               <li>&lt;= shown as = in annotation row tooltip</li>
-               <li>export features raises exception when no features exist</li>
-               <li>relative URLs not handled properly when used in parameters
-                       and annotation files</li>
        </ul>
        <strong>Issues affecting both applet and application</strong>
        <ul>
-               <li>sequence numbering not preserved in MSF alignment output</li>
-               <li>sequence associated secondary structure not correctly parsed
-                       in interleaved stockholm</li>
-               <li>sequences containing lowercase letters are not properly
-                       associated with their pdb files</li>
-               <li>Jalview PDB file reader does not extract sequence from deoxy
-                       nucleotide chains correctly</li>
-               <li>Sequence length given in alignment properties window is off
-                       by 1</li>
        </ul>
 </body>
 </html>
diff --git a/lib/VARNAv3-9.jar b/lib/VARNAv3-9.jar
new file mode 100644 (file)
index 0000000..b1db0a0
Binary files /dev/null and b/lib/VARNAv3-9.jar differ
index 2a065f6..8576bd1 100755 (executable)
@@ -87,7 +87,6 @@ public class Conservation
   public Conservation(String name, Hashtable propHash, int threshold,
           Vector sequences, int start, int end)
   {
-
     this.name = name;
     this.propHash = propHash;
     this.threshold = threshold;
diff --git a/src/jalview/analysis/Rna.java b/src/jalview/analysis/Rna.java
new file mode 100644 (file)
index 0000000..71ccbd1
--- /dev/null
@@ -0,0 +1,187 @@
+/* Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Author: Lauren Michelle Lui 
+ * Methods are based on RALEE methods http://personalpages.manchester.ac.uk/staff/sam.griffiths-jones/software/ralee/
+ * */
+
+package jalview.analysis;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import jalview.datamodel.SequenceFeature;
+
+public class Rna
+{
+       static Hashtable<Integer, Integer> pairHash = new Hashtable();
+  /**
+   * Based off of RALEE code ralee-get-base-pairs. Keeps track of open bracket
+   * positions in "stack" vector. When a close bracket is reached, pair this
+   * with the last element in the "stack" vector and store in "pairs" vector.
+   * Remove last element in the "stack" vector. Continue in this manner until
+   * the whole string is processed.
+   * 
+   * @param line
+   *          Secondary structure line of an RNA Stockholm file
+   * @return Array of SequenceFeature; type = RNA helix, begin is open base
+   *         pair, end is close base pair
+   */
+  public static SequenceFeature[] GetBasePairs(String line)
+  {
+
+    Vector stack = new Vector();
+    Vector pairs = new Vector();
+
+    int i = 0;
+    while (i < line.length())
+    {
+      char base = line.charAt(i);
+
+      if ((base == '<') || (base == '(') || (base == '{') || (base == '['))
+      {
+        stack.addElement(i);
+      }
+      else if ((base == '>') || (base == ')') || (base == '}')
+              || (base == ']'))
+      {
+
+        Object temp = stack.lastElement();
+        stack.remove(stack.size() - 1);
+        pairs.addElement(temp);
+        pairs.addElement(i);        
+      }
+
+      i++;
+    }
+
+    int numpairs = pairs.size() / 2;
+    SequenceFeature[] outPairs = new SequenceFeature[numpairs];
+
+    // Convert pairs to array
+    for (int p = 0; p < pairs.size(); p += 2)
+    {
+      int begin = Integer.parseInt(pairs.elementAt(p).toString());
+      int end = Integer.parseInt(pairs.elementAt(p + 1).toString());
+      
+       outPairs[p / 2] = new SequenceFeature("RNA helix", "", "", begin,
+              end, "");
+       //pairHash.put(begin, end);
+
+    }
+
+    return outPairs;
+  }
+  
+  
+  /**
+   * Function to get the end position corresponding to a given start position
+   * @param indice - start position of a base pair
+   * @return - end position of a base pair
+   */
+  /*makes no sense at the moment :(
+  public int findEnd(int indice){
+         //TODO: Probably extend this to find the start to a given end?
+         //could be done by putting everything twice to the hash
+         ArrayList<Integer> pair = new ArrayList<Integer>();
+         return pairHash.get(indice);
+  }*/
+  
+
+  /**
+   * Figures out which helix each position belongs to and stores the helix
+   * number in the 'featureGroup' member of a SequenceFeature Based off of RALEE
+   * code ralee-helix-map.
+   * 
+   * @param pairs
+   *          Array of SequenceFeature (output from Rna.GetBasePairs)
+   */
+  public static void HelixMap(SequenceFeature[] pairs)
+  {
+
+    int helix = 0; // Number of helices/current helix
+    int lastopen = 0; // Position of last open bracket reviewed
+    int lastclose = 9999999; // Position of last close bracket reviewed
+    int i = pairs.length; // Number of pairs
+
+    int open; // Position of an open bracket under review
+    int close; // Position of a close bracket under review
+    int j; // Counter
+
+    Hashtable helices = new Hashtable(); // Keep track of helix number for each
+                                         // position
+
+    // Go through each base pair and assign positions a helix
+    for (i = 0; i < pairs.length; i++)
+    {
+
+      open = pairs[i].getBegin();
+      close = pairs[i].getEnd();
+
+      // System.out.println("open " + open + " close " + close);
+      // System.out.println("lastclose " + lastclose + " lastopen " + lastopen);
+
+      // we're moving from right to left based on closing pair
+      /*
+       * catch things like <<..>>..<<..>> |
+       */
+      if (open > lastclose)
+      {
+        helix++;
+      }
+
+      /*
+       * catch things like <<..<<..>>..<<..>>>> |
+       */
+      j = pairs.length - 1;
+      while (j >= 0)
+      {
+        int popen = pairs[j].getBegin();
+
+        // System.out.println("j " + j + " popen " + popen + " lastopen "
+        // +lastopen + " open " + open);
+        if ((popen < lastopen) && (popen > open))
+        {
+          if (helices.containsValue(popen)
+                  && (((Integer) helices.get(popen)) == helix))
+          {
+            continue;
+          }
+          else
+          {
+            helix++;
+            break;
+          }
+        }
+
+        j -= 1;
+      }
+
+      // Put positions and helix information into the hashtable
+      helices.put(open, helix);
+      helices.put(close, helix);
+
+      // Record helix as featuregroup
+      pairs[i].setFeatureGroup(Integer.toString(helix));
+
+      lastopen = open;
+      lastclose = close;
+
+    }
+  }
+}
diff --git a/src/jalview/analysis/StructureFrequency.java b/src/jalview/analysis/StructureFrequency.java
new file mode 100644 (file)
index 0000000..42e8847
--- /dev/null
@@ -0,0 +1,465 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package jalview.analysis;
+
+import java.util.*;
+
+import jalview.datamodel.*;
+
+/**
+ * Takes in a vector or array of sequences and column start and column end and
+ * returns a new Hashtable[] of size maxSeqLength, if Hashtable not supplied.
+ * This class is used extensively in calculating alignment colourschemes that
+ * depend on the amount of conservation in each alignment column.
+ * 
+ * @author $author$
+ * @version $Revision$
+ */
+public class StructureFrequency
+{
+  // No need to store 1000s of strings which are not
+  // visible to the user.
+  public static final String MAXCOUNT = "C";
+
+  public static final String MAXRESIDUE = "R";
+
+  public static final String PID_GAPS = "G";
+
+  public static final String PID_NOGAPS = "N";
+
+  public static final String PROFILE = "P";
+
+  public static final String PAIRPROFILE = "B";
+
+  /**
+   * Returns the 3' position of a base pair
+   * 
+   * @param pairs
+   *          Secondary structure annotation
+   * @param indice
+   *          5' position of a base pair
+   * @return 3' position of a base pair
+   */
+  public static int findPair(SequenceFeature[] pairs, int indice)
+  {
+    for (int i = 0; i < pairs.length; i++)
+    {
+      if (pairs[i].getBegin() == indice)
+      {
+        return pairs[i].getEnd();
+      }
+    }
+    return -1;
+  }
+
+  /**
+   * Method to calculate a 'base pair consensus row', very similar to nucleotide
+   * consensus but takes into account a given structure
+   * 
+   * @param sequences
+   * @param start
+   * @param end
+   * @param result
+   * @param profile
+   * @param rnaStruc
+   */
+  public static final void calculate(SequenceI[] sequences, int start,
+          int end, Hashtable[] result, boolean profile,
+          AlignmentAnnotation rnaStruc)
+  {
+    Hashtable residueHash;
+    String maxResidue;
+    char[] seq, struc = rnaStruc.getRNAStruc().toCharArray();
+    SequenceFeature[] rna = rnaStruc._rnasecstr;
+    char c, s, cEnd;
+    int count, nonGap = 0, i, bpEnd = -1, j, jSize = sequences.length;
+    int[] values;
+    int[][] pairs;
+    float percentage;
+
+    for (i = start; i < end; i++) // foreach column
+    {
+      residueHash = new Hashtable();
+      maxResidue = "-";
+      values = new int[255];
+      pairs = new int[255][255];
+      bpEnd = -1;
+      if (i < struc.length)
+      {
+        s = struc[i];
+      }
+      else
+      {
+        s = '-';
+      }
+      if (s == '.' || s == ' ')
+      {
+        s = '-';
+      }
+
+      if (s != '(')
+      {
+        if (s == '-')
+        {
+          values['-']++;
+        }
+      }
+      else
+      {
+        for (j = 0; j < jSize; j++) // foreach row
+        {
+          if (sequences[j] == null)
+          {
+            System.err
+                    .println("WARNING: Consensus skipping null sequence - possible race condition.");
+            continue;
+          }
+          seq = sequences[j].getSequence();
+
+          if (seq.length > i)
+          {
+            c = seq[i];
+
+            // standard representation for gaps in sequence and structure
+            if (c == '.' || c == ' ')
+            {
+              c = '-';
+            }
+
+            if (c == '-')
+            {
+              values['-']++;
+              continue;
+            }
+            bpEnd = findPair(rna, i);
+            cEnd = seq[bpEnd];
+            if (checkBpType(c, cEnd))
+            {
+              values['(']++; // H means it's a helix (structured)
+            }
+            pairs[c][cEnd]++;
+
+            maxResidue = "(";
+          }
+        }
+        // nonGap++;
+      }
+      // UPDATE this for new values
+      if (profile)
+      {
+        residueHash.put(PROFILE, new int[][]
+        { values, new int[]
+        { jSize, (jSize - values['-']) } });
+
+        residueHash.put(PAIRPROFILE, pairs);
+      }
+
+      count = values['('];
+
+      residueHash.put(MAXCOUNT, new Integer(count));
+      residueHash.put(MAXRESIDUE, maxResidue);
+
+      percentage = ((float) count * 100) / (float) jSize;
+      residueHash.put(PID_GAPS, new Float(percentage));
+
+      // percentage = ((float) count * 100) / (float) nongap;
+      // residueHash.put(PID_NOGAPS, new Float(percentage));
+      if (result[i] == null)
+      {
+        result[i] = residueHash;
+      }
+      if (bpEnd > 0)
+      {
+        values[')'] = values['('];
+        values['('] = 0;
+
+        residueHash = new Hashtable();
+        maxResidue = ")";
+
+        if (profile)
+        {
+          residueHash.put(PROFILE, new int[][]
+          { values, new int[]
+          { jSize, (jSize - values['-']) } });
+
+          residueHash.put(PAIRPROFILE, pairs);
+        }
+
+        residueHash.put(MAXCOUNT, new Integer(count));
+        residueHash.put(MAXRESIDUE, maxResidue);
+
+        percentage = ((float) count * 100) / (float) jSize;
+        residueHash.put(PID_GAPS, new Float(percentage));
+
+        result[bpEnd] = residueHash;
+      }
+    }
+  }
+
+  /**
+   * Method to check if a base-pair is a canonical or a wobble bp
+   * 
+   * @param up
+   *          5' base
+   * @param down
+   *          3' base
+   * @return True if it is a canonical/wobble bp
+   */
+  public static boolean checkBpType(char up, char down)
+  {
+    if (up > 'Z')
+    {
+      up -= 32;
+    }
+    if (down > 'Z')
+    {
+      down -= 32;
+    }
+
+    switch (up)
+    {
+    case 'A':
+      switch (down)
+      {
+      case 'T':
+        return true;
+      case 'U':
+        return true;
+      }
+      break;
+    case 'C':
+      switch (down)
+      {
+      case 'G':
+        return true;
+      }
+      break;
+    case 'T':
+      switch (down)
+      {
+      case 'A':
+        return true;
+      case 'G':
+        return true;
+      }
+      break;
+    case 'G':
+      switch (down)
+      {
+      case 'C':
+        return true;
+      case 'T':
+        return true;
+      case 'U':
+        return true;
+      }
+      break;
+    case 'U':
+      switch (down)
+      {
+      case 'A':
+        return true;
+      case 'G':
+        return true;
+      }
+      break;
+    }
+    return false;
+  }
+
+  /**
+   * Compute all or part of the annotation row from the given consensus
+   * hashtable
+   * 
+   * @param consensus
+   *          - pre-allocated annotation row
+   * @param hconsensus
+   * @param iStart
+   * @param width
+   * @param ignoreGapsInConsensusCalculation
+   * @param includeAllConsSymbols
+   */
+  public static void completeConsensus(AlignmentAnnotation consensus,
+          Hashtable[] hconsensus, int iStart, int width,
+          boolean ignoreGapsInConsensusCalculation,
+          boolean includeAllConsSymbols)
+  {
+    float tval, value;
+    if (consensus == null || consensus.annotations == null
+            || consensus.annotations.length < width)
+    {
+      // called with a bad alignment annotation row - wait for it to be
+      // initialised properly
+      return;
+    }
+    for (int i = iStart; i < width; i++)
+    {
+      if (i >= hconsensus.length)
+      {
+        // happens if sequences calculated over were shorter than alignment
+        // width
+        consensus.annotations[i] = null;
+        continue;
+      }
+      value = 0;
+      if (ignoreGapsInConsensusCalculation)
+      {
+        value = ((Float) hconsensus[i].get(StructureFrequency.PID_NOGAPS))
+                .floatValue();
+      }
+      else
+      {
+        value = ((Float) hconsensus[i].get(StructureFrequency.PID_GAPS))
+                .floatValue();
+      }
+
+      String maxRes = hconsensus[i].get(StructureFrequency.MAXRESIDUE)
+              .toString();
+      String mouseOver = hconsensus[i].get(StructureFrequency.MAXRESIDUE)
+              + " ";
+      if (maxRes.length() > 1)
+      {
+        mouseOver = "[" + maxRes + "] ";
+        maxRes = "+";
+      }
+      int[][] profile = (int[][]) hconsensus[i]
+              .get(StructureFrequency.PROFILE);
+      int[][] pairs = (int[][]) hconsensus[i]
+              .get(StructureFrequency.PAIRPROFILE);
+
+      if (pairs != null && includeAllConsSymbols) // Just responsible for the
+      // tooltip
+      // TODO Update tooltips for Structure row
+      {
+        mouseOver = "";
+
+        /* TODO It's not sure what is the purpose of the alphabet and wheter it is useful for structure?
+         * 
+         * if (alphabet != null) { for (int c = 0; c < alphabet.length; c++) {
+         * tval = ((float) profile[0][alphabet[c]]) 100f / (float)
+         * profile[1][ignoreGapsInConsensusCalculation ? 1 : 0]; mouseOver +=
+         * ((c == 0) ? "" : "; ") + alphabet[c] + " " + ((int) tval) + "%"; } }
+         * else {
+         */
+        Object[] ca = new Object[625];
+        float[] vl = new float[625];
+        int x = 0;
+        for (int c = 65; c < 90; c++)
+        {
+          for (int d = 65; d < 90; d++)
+          {
+            ca[x] = new int[]
+            { c, d };
+            vl[x] = (float) pairs[c][d];
+            x++;
+          }
+        }
+        jalview.util.QuickSort.sort(vl, ca);
+        int p = 0;
+
+        for (int c = 624; c > 0; c--)
+        {
+          if (vl[c] > 0)
+          {
+            tval = ((float) vl[c] * 100f / (float) profile[1][ignoreGapsInConsensusCalculation ? 1
+                    : 0]);
+            mouseOver += ((p == 0) ? "" : "; ") + (char) ((int[]) ca[c])[0]
+                    + (char) ((int[]) ca[c])[1] + " " + ((int) tval) + "%";
+            p++;
+
+          }
+        }
+
+        // }
+      }
+      else
+      {
+        mouseOver += ((int) value + "%");
+      }
+      consensus.annotations[i] = new Annotation(maxRes, mouseOver, ' ',
+              value);
+    }
+  }
+
+  /**
+   * get the sorted base-pair profile for the given position of the consensus
+   * 
+   * @param hconsensus
+   * @return profile of the given column
+   */
+  public static int[] extractProfile(Hashtable hconsensus,
+          boolean ignoreGapsInConsensusCalculation)
+  {
+    int[] rtnval = new int[51]; // 2*(5*5)+1
+    int[][] profile = (int[][]) hconsensus.get(StructureFrequency.PROFILE);
+    int[][] pairs = (int[][]) hconsensus
+            .get(StructureFrequency.PAIRPROFILE);
+
+    if (profile == null)
+      return null;
+
+    // TODO fix the object length, also do it in completeConsensus
+    Object[] ca = new Object[625];
+    float[] vl = new float[625];
+    int x = 0;
+    for (int c = 65; c < 90; c++)
+    {
+      for (int d = 65; d < 90; d++)
+      {
+        ca[x] = new int[]
+        { c, d };
+        vl[x] = (float) pairs[c][d];
+        x++;
+      }
+    }
+    jalview.util.QuickSort.sort(vl, ca);
+
+    rtnval[0] = 1;
+    for (int c = 624; c > 0; c--)
+    {
+      if (vl[c] > 0)
+      {
+        rtnval[rtnval[0]++] = ((int[]) ca[c])[0];
+        rtnval[rtnval[0]++] = ((int[]) ca[c])[1];
+        rtnval[rtnval[0]++] = (int) ((float) vl[c] * 100f / (float) profile[1][ignoreGapsInConsensusCalculation ? 1
+                : 0]);
+      }
+    }
+
+    return rtnval;
+  }
+
+  public static void main(String args[])
+  {
+    // Short test to see if checkBpType works
+    ArrayList<String> test = new ArrayList<String>();
+    test.add("A");
+    test.add("c");
+    test.add("g");
+    test.add("T");
+    test.add("U");
+    for (String i : test)
+    {
+      for (String j : test)
+      {
+        System.out.println(i + "-" + j + ": "
+                + StructureFrequency.checkBpType(i.charAt(0), j.charAt(0)));
+      }
+    }
+  }
+}
index 7bf21a8..f3d7fa7 100644 (file)
@@ -71,6 +71,8 @@ public class AppletJmol extends EmbmenuFrame implements
   MenuItem turn = new MenuItem("Turn Propensity");
 
   MenuItem buried = new MenuItem("Buried Index");
+  
+  MenuItem purinepyrimidine = new MenuItem("Purine/Pyrimidine");
 
   MenuItem user = new MenuItem("User Defined Colours");
 
@@ -187,6 +189,7 @@ public class AppletJmol extends EmbmenuFrame implements
     strand.addActionListener(this);
     turn.addActionListener(this);
     buried.addActionListener(this);
+    purinepyrimidine.addActionListener(this);
     user.addActionListener(this);
     
     jmolHelp.addActionListener(this);
@@ -201,6 +204,7 @@ public class AppletJmol extends EmbmenuFrame implements
     coloursMenu.add(strand);
     coloursMenu.add(turn);
     coloursMenu.add(buried);
+    coloursMenu.add(purinepyrimidine);
     coloursMenu.add(user);
     coloursMenu.add(jmolColour);
     helpMenu.add(jmolHelp);
@@ -444,6 +448,10 @@ public class AppletJmol extends EmbmenuFrame implements
       setEnabled(buried);
       jmb.setJalviewColourScheme(new BuriedColourScheme());
     }
+    else if(evt.getSource() == purinepyrimidine)
+    {
+       jmb.setJalviewColourScheme(new PurinePyrimidineColourScheme());
+    }
     else if (evt.getSource() == user)
     {
       setEnabled(user);
index d18cb62..717d3d2 100644 (file)
@@ -54,6 +54,8 @@ public class EditCommand implements CommandI
   public static final int PASTE = 3;
 
   public static final int REPLACE = 4;
+  
+  public static final int INSERT_NUC=5;
 
   Edit[] edits;
 
@@ -192,6 +194,10 @@ public class EditCommand implements CommandI
       case REPLACE:
         replace(edits[e]);
         break;
+        //TODO:add deleteNuc for UNDO
+//      case INSERT_NUC:
+//     insertNuc(edits[e]);
+//     break;
       }
     }
   }
@@ -223,7 +229,7 @@ public class EditCommand implements CommandI
       case REPLACE:
         replace(edits[e]);
         break;
-      }
+       }
     }
   }
 
@@ -234,10 +240,23 @@ public class EditCommand implements CommandI
     {
       command.seqs[s].insertCharAt(command.position, command.number,
               command.gapChar);
+//      System.out.println("pos: "+command.position+" number: "+command.number);
     }
 
     adjustAnnotations(command, true, false, null);
   }
+//  
+//  final void insertNuc(Edit command)
+//  {
+//
+//    for (int s = 0; s < command.seqs.length; s++)
+//    {
+//        System.out.println("pos: "+command.position+" number: "+command.number);
+//     command.seqs[s].insertCharAt(command.position, command.number,'A');
+//    }
+//
+//    adjustAnnotations(command, true, false, null);
+//  }
 
   final void deleteGap(Edit command)
   {
index 707eee8..697920e 100755 (executable)
@@ -43,6 +43,8 @@ public class Alignment implements AlignmentI
   public static final int PROTEIN = 0;
 
   public static final int NUCLEOTIDE = 1;
+  
+  public boolean hasRNAStructure = false;
 
   /** DOCUMENT ME!! */
   public AlignmentAnnotation[] annotations;
@@ -732,6 +734,10 @@ public class Alignment implements AlignmentI
    */
   public void addAnnotation(AlignmentAnnotation aa, int pos)
   {
+    if(aa.getRNAStruc()!= null){
+      hasRNAStructure=true;
+    }
+    
     int aSize = 1;
     if (annotations != null)
     {
@@ -832,6 +838,11 @@ public class Alignment implements AlignmentI
       return false;
     }
   }
+  
+  public boolean hasRNAStructure(){
+    //TODO can it happen that structure is removed from alignment?
+    return hasRNAStructure;
+  }
 
   public void setDataset(Alignment data)
   {
index 1d624d4..4c57c89 100755 (executable)
@@ -17,6 +17,8 @@
  */
 package jalview.datamodel;
 
+import jalview.analysis.Rna;
+
 import java.util.Enumeration;
 import java.util.Hashtable;
 
@@ -35,7 +37,7 @@ public class AlignmentAnnotation
   public boolean autoCalculated = false;
 
   public String annotationId;
-
+  
   public SequenceI sequenceRef;
 
   /** DOCUMENT ME!! */
@@ -47,6 +49,35 @@ public class AlignmentAnnotation
   /** DOCUMENT ME!! */
   public Annotation[] annotations;
 
+  /**
+   * RNA secondary structure contact positions
+   */
+  public SequenceFeature[] _rnasecstr = null;
+  
+  public String rnaStructure;
+
+  /**
+   * Updates the _rnasecstr field Determines the positions that base pair and
+   * the positions of helices based on secondary structure from a Stockholm file
+   * 
+   * @param RNAannot
+   */
+  private void _updateRnaSecStr(String RNAannot)
+  {
+    _rnasecstr = Rna.GetBasePairs(RNAannot);
+    Rna.HelixMap(_rnasecstr);
+    
+    setRNAStruc(RNAannot);
+
+    if (_rnasecstr != null && _rnasecstr.length > 0)
+    {
+      // show all the RNA secondary structure annotation symbols.
+      showAllColLabels = true;
+      scaleColLabel = true;
+    }
+    // System.out.println("featuregroup " + _rnasecstr[0].getFeatureGroup());
+  }
+  
   public java.util.Hashtable sequenceMapping;
 
   /** DOCUMENT ME!! */
@@ -167,9 +198,16 @@ public class AlignmentAnnotation
     validateRangeAndDisplay();
   }
 
+  /**
+   * Checks if annotation labels represent secondary structures
+   * 
+   */
   void areLabelsSecondaryStructure()
   {
     boolean nonSSLabel = false;
+    boolean isrna = false;
+    StringBuffer rnastring = new StringBuffer();
+
     char firstChar = 0;
     for (int i = 0; i < annotations.length; i++)
     {
@@ -182,9 +220,22 @@ public class AlignmentAnnotation
       {
         hasIcons |= true;
       }
+      else
+      // Check for RNA secondary structure
+      {
+        if (annotations[i].secondaryStructure == 'S')
+        {
+          hasIcons |= true;
+          isrna |= true;
+        }
+      }
+
+      // System.out.println("displaychar " + annotations[i].displayCharacter);
 
-      if (annotations[i].displayCharacter == null)
+      if (annotations[i].displayCharacter == null
+              || annotations[i].displayCharacter.length() == 0)
       {
+        rnastring.append('.');
         continue;
       }
       if (annotations[i].displayCharacter.length() == 1)
@@ -205,6 +256,7 @@ public class AlignmentAnnotation
                 firstChar != ' '
                 && firstChar != 'H'
                 && firstChar != 'E'
+                && firstChar != 'S'
                 && firstChar != '-'
                 && firstChar < jalview.schemes.ResidueProperties.aaIndex.length)
         {
@@ -219,6 +271,10 @@ public class AlignmentAnnotation
           }
         }
       }
+      else
+      {
+        rnastring.append(annotations[i].displayCharacter.charAt(1));
+      }
 
       if (annotations[i].displayCharacter.length() > 0)
       {
@@ -241,11 +297,26 @@ public class AlignmentAnnotation
 
       }
     }
+    else
+    {
+      if (isrna)
+      {
+        _updateRnaSecStr(rnastring.toString());
+      }
+    }
 
     annotationId = this.hashCode() + "";
   }
 
-  /**
+  public void setRNAStruc(String string) {
+       rnaStructure=string;    
+}
+  
+  public String getRNAStruc(){
+         return rnaStructure;
+  }
+
+/**
    * Creates a new AlignmentAnnotation object.
    * 
    * @param label
@@ -280,7 +351,7 @@ public class AlignmentAnnotation
    * checks graphMin and graphMax, secondary structure symbols, sets graphType
    * appropriately, sets null labels to the empty string if appropriate.
    */
-  private void validateRangeAndDisplay()
+  public void validateRangeAndDisplay()
   {
 
     if (annotations == null)
index be1bff7..7810f2b 100755 (executable)
@@ -204,9 +204,9 @@ public interface AlignmentI
 
   /**
    * Deletes a specific AlignmentAnnotation from the alignment, and removes its
-   * reference from any SequenceI or SequenceGroup object's annotation if and only if aa is
-   * contained within the alignment's annotation vector. Otherwise, it will do
-   * nothing.
+   * reference from any SequenceI or SequenceGroup object's annotation if and
+   * only if aa is contained within the alignment's annotation vector.
+   * Otherwise, it will do nothing.
    * 
    * @param aa
    *          the annotation to delete
@@ -215,15 +215,17 @@ public interface AlignmentI
   public boolean deleteAnnotation(AlignmentAnnotation aa);
 
   /**
-   * Deletes a specific AlignmentAnnotation from the alignment, and optionally removes any
-   * reference from any SequenceI or SequenceGroup object's annotation if and only if aa is
-   * contained within the alignment's annotation vector. Otherwise, it will do
-   * nothing.
+   * Deletes a specific AlignmentAnnotation from the alignment, and optionally
+   * removes any reference from any SequenceI or SequenceGroup object's
+   * annotation if and only if aa is contained within the alignment's annotation
+   * vector. Otherwise, it will do nothing.
    * 
    * @param aa
    *          the annotation to delete
    * @param unhook
-   *          flag indicating if any references should be removed from annotation - use this if you intend to add the annotation back into the alignment
+   *          flag indicating if any references should be removed from
+   *          annotation - use this if you intend to add the annotation back
+   *          into the alignment
    * @return true if annotation was deleted from this alignment.
    */
   public boolean deleteAnnotation(AlignmentAnnotation aa, boolean unhook);
@@ -259,6 +261,13 @@ public interface AlignmentI
   public boolean isNucleotide();
 
   /**
+   * Test if alignment contains RNA structure
+   * 
+   * @return true if RNA structure AligmnentAnnotation was added to alignment
+   */
+  public boolean hasRNAStructure();
+
+  /**
    * Set alignment to be a nucleotide sequence
    * 
    */
index 609158d..dde0822 100755 (executable)
@@ -34,7 +34,7 @@ public class Annotation
   public String description = ""; // currently used as mouse over
 
   /** DOCUMENT ME!! */
-  public char secondaryStructure = ' '; // recognises H and E
+  public char secondaryStructure = ' '; // recognises H, E and S(?)
 
   /** DOCUMENT ME!! */
   public float value;
index e1f5f41..bd5ea91 100755 (executable)
@@ -61,6 +61,11 @@ public class DBRefSource
    * PFAM ID\r
    */\r
   public static String PFAM = "PFAM";\r
+  \r
+  /**\r
+   * RFAM ID\r
+   */\r
+  public static String RFAM = "RFAM";\r
 \r
   /**\r
    * GeneDB ID\r
@@ -86,7 +91,7 @@ public class DBRefSource
   { PDB };\r
 \r
   public static final String[] DOMAINDBS =\r
-  { PFAM };\r
+  { PFAM, RFAM };\r
 \r
   /**\r
    * set of unique DBRefSource property constants. These could be used to\r
@@ -115,7 +120,7 @@ public class DBRefSource
   public static final Object DNACODINGSEQDB = "XONCODING";\r
 \r
   /**\r
-   * DB returns several sequences associated with a protein domain\r
+   * DB returns several sequences associated with a protein/nucleotide domain\r
    */\r
   public static final Object DOMAINDB = "DOMAIN";\r
 \r
index 6fed6ee..e81292b 100755 (executable)
@@ -40,7 +40,7 @@ public class SequenceFeature
   public Hashtable otherDetails;
 
   public java.util.Vector links;
-
+  
   // Feature group can be set from a features file
   // as a group of features between STARTGROUP and ENDGROUP markers
   public String featureGroup;
@@ -95,7 +95,7 @@ public class SequenceFeature
       }
     }
   }
-
+  
   public SequenceFeature(String type, String desc, String status,
           int begin, int end, String featureGroup)
   {
diff --git a/src/jalview/ext/varna/JalviewVarnaBinding.java b/src/jalview/ext/varna/JalviewVarnaBinding.java
new file mode 100644 (file)
index 0000000..a2d020b
--- /dev/null
@@ -0,0 +1,56 @@
+/*\r
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)\r
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle\r
+ * \r
+ * This file is part of Jalview.\r
+ * \r
+ * Jalview is free software: you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License \r
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\r
+ * \r
+ * Jalview is distributed in the hope that it will be useful, but \r
+ * WITHOUT ANY WARRANTY; without even the implied warranty \r
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR \r
+ * PURPOSE.  See the GNU General Public License for more details.\r
+ * \r
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+package jalview.ext.varna;\r
+\r
+import java.io.File;\r
+\r
+import java.net.URL;\r
+import java.util.*;\r
+import java.applet.Applet;\r
+import java.awt.*;\r
+import java.awt.event.*;\r
+\r
+import javax.swing.JPanel;\r
+\r
+import jalview.api.AlignmentViewPanel;\r
+import jalview.api.FeatureRenderer;\r
+import jalview.api.SequenceRenderer;\r
+import jalview.api.SequenceStructureBinding;\r
+import jalview.api.StructureSelectionManagerProvider;\r
+import jalview.datamodel.*;\r
+import jalview.structure.*;\r
+import jalview.io.*;\r
+\r
+import org.jmol.api.*;\r
+import org.jmol.adapter.smarter.SmarterJmolAdapter;\r
+\r
+import org.jmol.popup.*;\r
+import org.jmol.viewer.JmolConstants;\r
+import org.jmol.viewer.Viewer;\r
+\r
+import jalview.schemes.*;\r
+\r
+import fr.orsay.lri.varna.applications.*;\r
+\r
+\r
+public abstract class JalviewVarnaBinding implements StructureListener, SequenceStructureBinding,\r
+        ComponentListener, StructureSelectionManagerProvider\r
+\r
+{\r
+  \r
+}\r
diff --git a/src/jalview/ext/varna/VarnaCommands.java b/src/jalview/ext/varna/VarnaCommands.java
new file mode 100644 (file)
index 0000000..9d57969
--- /dev/null
@@ -0,0 +1,142 @@
+/**\r
+ * \r
+ */\r
+package jalview.ext.varna;\r
+\r
+import jalview.api.FeatureRenderer;\r
+import jalview.api.SequenceRenderer;\r
+import jalview.datamodel.AlignmentI;\r
+import jalview.datamodel.SequenceI;\r
+import jalview.structure.StructureMapping;\r
+import jalview.structure.StructureSelectionManager;\r
+import jalview.util.Comparison;\r
+\r
+import java.awt.Color;\r
+import java.util.ArrayList;\r
+\r
+/**\r
+ * Routines for generating Jmol commands for Jalview/Jmol binding\r
+ * another cruisecontrol test.\r
+ * \r
+ * @author JimP\r
+ *\r
+ */\r
+public class VarnaCommands\r
+{\r
+\r
+  /**\r
+   * Jmol utility which constructs the commands to colour chains by the given alignment\r
+   * \r
+   */\r
+  public static String[] getColourBySequenceCommand(StructureSelectionManager ssm, String[] files, SequenceI[][] sequence, SequenceRenderer sr, FeatureRenderer fr, AlignmentI alignment)\r
+  {\r
+    ArrayList<String> str = new ArrayList<String>();\r
+    StringBuffer command = new StringBuffer();\r
+  \r
+    for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)\r
+    {\r
+      StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);\r
+  \r
+      if (mapping == null || mapping.length < 1)\r
+        continue;\r
+  \r
+      int lastPos = -1;\r
+      for (int s = 0; s < sequence[pdbfnum].length; s++)\r
+      {\r
+        for (int sp, m = 0; m < mapping.length; m++)\r
+        {\r
+          if (mapping[m].getSequence() == sequence[pdbfnum][s]\r
+                  && (sp = alignment.findIndex(sequence[pdbfnum][s])) > -1)\r
+          {\r
+            SequenceI asp = alignment.getSequenceAt(sp);\r
+            for (int r = 0; r < asp.getLength(); r++)\r
+            {\r
+              // no mapping to gaps in sequence\r
+              if (jalview.util.Comparison.isGap(asp.getCharAt(r)))\r
+              {\r
+                continue;\r
+              }\r
+              int pos = mapping[m].getPDBResNum(asp.findPosition(r));\r
+  \r
+              if (pos < 1 || pos == lastPos)\r
+                continue;\r
+  \r
+              lastPos = pos;\r
+  \r
+              Color col = sr.getResidueBoxColour(sequence[pdbfnum][s], r);\r
+  \r
+              if (fr != null)\r
+                col = fr.findFeatureColour(col, sequence[pdbfnum][s], r);\r
+              String newSelcom = (mapping[m].getChain() != " " ? ":"\r
+                      + mapping[m].getChain() : "")\r
+                      + "/"\r
+                      + (pdbfnum + 1)\r
+                      + ".1"\r
+                      + ";color["\r
+                      + col.getRed()\r
+                      + ","\r
+                      + col.getGreen()\r
+                      + ","\r
+                      + col.getBlue() + "]";\r
+              if (command.length()>newSelcom.length() && command.substring(command.length()-newSelcom.length()).equals(newSelcom))\r
+              {\r
+                command = VarnaCommands.condenseCommand(command, pos);\r
+                continue;\r
+              }\r
+              // TODO: deal with case when buffer is too large for Jmol to parse\r
+              // - execute command and flush\r
+  \r
+              command.append(";");\r
+              if (command.length()>51200)\r
+              {\r
+                // add another chunk\r
+                str.add(command.toString());\r
+                command.setLength(0);\r
+              }\r
+              command.append("select " + pos);\r
+              command.append(newSelcom);\r
+            }\r
+            break;\r
+          }\r
+        }\r
+      }\r
+    }\r
+    {\r
+      // add final chunk\r
+      str.add(command.toString());\r
+      command.setLength(0);\r
+    }\r
+    return str.toArray(new String[str.size()]);\r
+  }\r
+\r
+  public static StringBuffer condenseCommand(StringBuffer command, int pos)\r
+  {\r
+  \r
+    // work back to last 'select'\r
+    int p=command.length(),q=p;\r
+    do {\r
+      p-=6;\r
+      if (p<1) { p=0; };\r
+    } while ((q=command.indexOf("select",p))==-1 && p>0);\r
+    \r
+    StringBuffer sb = new StringBuffer(command.substring(0,q+7));\r
+  \r
+    command =  command.delete(0,q+7);\r
+  \r
+    String start;\r
+  \r
+    if (command.indexOf("-") > -1)\r
+    {\r
+      start = command.substring(0, command.indexOf("-"));\r
+    }\r
+    else\r
+    {\r
+      start = command.substring(0, command.indexOf(":"));\r
+    }\r
+  \r
+    sb.append(start + "-" + pos + command.substring(command.indexOf(":")));\r
+  \r
+    return sb;\r
+  }\r
+\r
+}\r
index 2ecd947..b61d44b 100755 (executable)
@@ -65,6 +65,7 @@ import jalview.schemes.HelixColourScheme;
 import jalview.schemes.HydrophobicColourScheme;
 import jalview.schemes.NucleotideColourScheme;
 import jalview.schemes.PIDColourScheme;
+import jalview.schemes.PurinePyrimidineColourScheme;
 import jalview.schemes.ResidueProperties;
 import jalview.schemes.StrandColourScheme;
 import jalview.schemes.TaylorColourScheme;
@@ -401,7 +402,22 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                     || evt.isShiftDown() || evt.isAltDown());
           }
           break;
-
+          
+        //case KeyEvent.VK_A:
+       //      if (viewport.cursorMode)
+       //     {
+       //              alignPanel.seqPanel.insertNucAtCursor(false,"A");
+       //              //System.out.println("A");
+       //     }
+       //      break;
+        /*     
+        case KeyEvent.VK_CLOSE_BRACKET:
+               if (viewport.cursorMode)
+            {
+                       System.out.println("closing bracket");
+            }
+               break;
+         */
         case KeyEvent.VK_DELETE:
         case KeyEvent.VK_BACK_SPACE:
           if (!viewport.cursorMode)
@@ -574,6 +590,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       }
       ap.av.updateConservation(ap);
       ap.av.updateConsensus(ap);
+      ap.av.updateStrucConsensus(ap);
     }
   }
 
@@ -2968,10 +2985,25 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     changeColour(new NucleotideColourScheme());
   }
 
+  public void purinePyrimidineColour_actionPerformed(ActionEvent e)
+  {
+    changeColour(new PurinePyrimidineColourScheme());
+  }
+  /*
+  public void covariationColour_actionPerformed(ActionEvent e)
+  {
+    changeColour(new CovariationColourScheme(viewport.alignment.getAlignmentAnnotation()[0]));
+  }
+  */
   public void annotationColour_actionPerformed(ActionEvent e)
   {
     new AnnotationColourChooser(viewport, alignPanel);
   }
+  
+  public void rnahelicesColour_actionPerformed(ActionEvent e)
+  {
+    new RNAHelicesColourChooser(viewport, alignPanel);
+  }
 
   /**
    * DOCUMENT ME!
index 13f66d9..d3c139c 100644 (file)
@@ -140,8 +140,12 @@ public class AlignViewport implements SelectionSource, VamsasSource
   /** DOCUMENT ME!! */
   public Hashtable[] hconsensus;
 
+  public Hashtable[] hStrucConsensus;
+
   AlignmentAnnotation consensus;
 
+  AlignmentAnnotation strucConsensus;
+
   AlignmentAnnotation conservation;
 
   AlignmentAnnotation quality;
@@ -152,6 +156,8 @@ public class AlignViewport implements SelectionSource, VamsasSource
 
   boolean autoCalculateConsensus = true;
 
+  boolean autoCalculateStrucConsensus = true;
+
   /** DOCUMENT ME!! */
   public int ConsPercGaps = 25; // JBPNote : This should be a scalable property!
 
@@ -407,10 +413,24 @@ public class AlignViewport implements SelectionSource, VamsasSource
       consensus.hasText = true;
       consensus.autoCalculated = true;
 
+      if (alignment.isNucleotide() && alignment.hasRNAStructure())
+      {
+        strucConsensus = new AlignmentAnnotation("StrucConsensus", "PID",
+                new Annotation[1], 0f, 100f, AlignmentAnnotation.BAR_GRAPH);
+        strucConsensus.hasText = true;
+        strucConsensus.autoCalculated = true;
+      }
+      
       if (Cache.getDefault("SHOW_IDENTITY", true))
       {
         alignment.addAnnotation(consensus);
+        // TODO: Make own if for structure
+        if (alignment.isNucleotide() && alignment.hasRNAStructure())
+        {
+          alignment.addAnnotation(strucConsensus);
+        }
       }
+
     }
 
     if (jalview.bin.Cache.getProperty("DEFAULT_COLOUR") != null)
@@ -459,14 +479,20 @@ public class AlignViewport implements SelectionSource, VamsasSource
 
   ConsensusThread consensusThread;
 
+  StrucConsensusThread strucConsensusThread;
+
   boolean consUpdateNeeded = false;
 
   static boolean UPDATING_CONSENSUS = false;
 
+  static boolean UPDATING_STRUC_CONSENSUS = false;
+
   static boolean UPDATING_CONSERVATION = false;
 
   boolean updatingConsensus = false;
 
+  boolean updatingStrucConsensus = false;
+
   boolean updatingConservation = false;
 
   /**
@@ -556,10 +582,9 @@ public class AlignViewport implements SelectionSource, VamsasSource
         consensus.annotations = new Annotation[aWidth];
 
         hconsensus = new Hashtable[aWidth];
-        AAFrequency.calculate(alignment.getSequencesArray(), 0,
-                alignment.getWidth(), hconsensus, true);
+        AAFrequency.calculate(alignment.getSequencesArray(), 0, alignment
+                .getWidth(), hconsensus, true);
         updateAnnotation(true);
-
         if (globalColourScheme != null)
         {
           globalColourScheme.setConsensus(hconsensus);
@@ -605,6 +630,131 @@ public class AlignViewport implements SelectionSource, VamsasSource
     }
   }
 
+  // --------START Structure Conservation
+  public void updateStrucConsensus(final AlignmentPanel ap)
+  {
+    // see note in mantis : issue number 8585
+    if (strucConsensus == null || !autoCalculateStrucConsensus)
+    {
+      return;
+    }
+    strucConsensusThread = new StrucConsensusThread(ap);
+    strucConsensusThread.start();
+  }
+
+  class StrucConsensusThread extends Thread
+  {
+    AlignmentPanel ap;
+
+    public StrucConsensusThread(AlignmentPanel ap)
+    {
+      this.ap = ap;
+    }
+
+    public void run()
+    {
+      updatingStrucConsensus = true;
+      while (UPDATING_STRUC_CONSENSUS)
+      {
+        try
+        {
+          if (ap != null)
+          {
+            ap.paintAlignment(false);
+          }
+
+          Thread.sleep(200);
+        } catch (Exception ex)
+        {
+          ex.printStackTrace();
+        }
+      }
+
+      UPDATING_STRUC_CONSENSUS = true;
+
+      try
+      {
+        int aWidth = (alignment != null) ? alignment.getWidth() : -1; // null
+        // pointer
+        // possibility
+        // here.
+        if (aWidth <= 0)
+        {
+          updatingStrucConsensus = false;
+          UPDATING_STRUC_CONSENSUS = false;
+          return;
+        }
+
+        strucConsensus.annotations = null;
+        strucConsensus.annotations = new Annotation[aWidth];
+
+        hStrucConsensus = new Hashtable[aWidth];
+
+        AlignmentAnnotation[] aa = ap.av.getAlignment()
+                .getAlignmentAnnotation();
+        AlignmentAnnotation rnaStruc = null;
+        for (int i = 0; i < aa.length; i++)
+        {
+          if (aa[i].getRNAStruc() != null)
+          {
+            rnaStruc = aa[i];
+            break;
+          }
+        }
+
+        AlignmentAnnotation rna = ap.av.getAlignment()
+                .getAlignmentAnnotation()[0];
+        StructureFrequency.calculate(alignment.getSequencesArray(), 0,
+                alignment.getWidth(), hStrucConsensus, true, rnaStruc);
+        // TODO AlignmentAnnotation rnaStruc!!!
+        updateAnnotation(true);
+        if (globalColourScheme != null)
+        {
+          globalColourScheme.setConsensus(hStrucConsensus);
+        }
+
+      } catch (OutOfMemoryError error)
+      {
+        alignment.deleteAnnotation(strucConsensus);
+
+        strucConsensus = null;
+        hStrucConsensus = null;
+        new OOMWarning("calculating structure consensus", error);
+      }
+      UPDATING_STRUC_CONSENSUS = false;
+      updatingStrucConsensus = false;
+
+      if (ap != null)
+      {
+        ap.paintAlignment(true);
+      }
+    }
+
+    /**
+     * update the consensus annotation from the sequence profile data using
+     * current visualization settings.
+     */
+    public void updateAnnotation()
+    {
+      updateAnnotation(false);
+    }
+
+    protected void updateAnnotation(boolean immediate)
+    {
+      // TODO: make calls thread-safe, so if another thread calls this method,
+      // it will either return or wait until one calculation is finished.
+      if (immediate
+              || (!updatingStrucConsensus && strucConsensus != null && hStrucConsensus != null))
+      {
+        StructureFrequency.completeConsensus(strucConsensus,
+                hStrucConsensus, 0, hStrucConsensus.length, false,
+                showSequenceLogo);
+      }
+    }
+  }
+
+  // --------END Structure Conservation
+
   /**
    * get the consensus sequence as displayed under the PID consensus annotation
    * row.
@@ -656,8 +806,9 @@ public class AlignViewport implements SelectionSource, VamsasSource
   /**
    * Set the selection group for this window.
    * 
-   * @param sg - group holding references to sequences in this alignment view
-   *          
+   * @param sg
+   *          - group holding references to sequences in this alignment view
+   * 
    */
   public void setSelectionGroup(SequenceGroup sg)
   {
@@ -666,6 +817,7 @@ public class AlignViewport implements SelectionSource, VamsasSource
 
   /**
    * GUI state
+   * 
    * @return true if conservation based shading is enabled
    */
   public boolean getConservationSelected()
@@ -675,6 +827,7 @@ public class AlignViewport implements SelectionSource, VamsasSource
 
   /**
    * GUI state
+   * 
    * @param b
    *          enable conservation based shading
    */
@@ -685,6 +838,7 @@ public class AlignViewport implements SelectionSource, VamsasSource
 
   /**
    * GUI state
+   * 
    * @return true if percent identity threshold is applied to shading
    */
   public boolean getAbovePIDThreshold()
@@ -696,7 +850,8 @@ public class AlignViewport implements SelectionSource, VamsasSource
    * GUI state
    * 
    * 
-   * @param b indicate if percent identity threshold is applied to shading
+   * @param b
+   *          indicate if percent identity threshold is applied to shading
    */
   public void setAbovePIDThreshold(boolean b)
   {
@@ -941,14 +1096,14 @@ public class AlignViewport implements SelectionSource, VamsasSource
   {
     if (alignment != null && alignment.getCodonFrames() != null)
     {
-      StructureSelectionManager.getStructureSelectionManager(Desktop.instance)
-              .removeMappings(alignment.getCodonFrames());
+      StructureSelectionManager.getStructureSelectionManager(
+              Desktop.instance).removeMappings(alignment.getCodonFrames());
     }
     this.alignment = align;
     if (alignment.getCodonFrames() != null)
     {
-      StructureSelectionManager.getStructureSelectionManager(Desktop.instance).addMappings(
-              alignment.getCodonFrames());
+      StructureSelectionManager.getStructureSelectionManager(
+              Desktop.instance).addMappings(alignment.getCodonFrames());
     }
   }
 
@@ -1564,7 +1719,9 @@ public class AlignViewport implements SelectionSource, VamsasSource
   public jalview.datamodel.CigarArray getViewAsCigars(
           boolean selectedRegionOnly)
   {
-    return new jalview.datamodel.CigarArray(alignment, (hasHiddenColumns ? colSel : null), (selectedRegionOnly ? selectionGroup : null));
+    return new jalview.datamodel.CigarArray(alignment,
+            (hasHiddenColumns ? colSel : null),
+            (selectedRegionOnly ? selectionGroup : null));
   }
 
   /**
@@ -1575,11 +1732,12 @@ public class AlignViewport implements SelectionSource, VamsasSource
    *          boolean true to just return the selected view
    * @return AlignmentView
    */
-  public jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly)
+  public jalview.datamodel.AlignmentView getAlignmentView(
+          boolean selectedOnly)
   {
     return getAlignmentView(selectedOnly, false);
   }
-  
+
   /**
    * return a compact representation of the current alignment selection to pass
    * to an analysis function
@@ -1587,12 +1745,16 @@ public class AlignViewport implements SelectionSource, VamsasSource
    * @param selectedOnly
    *          boolean true to just return the selected view
    * @param markGroups
-   *          boolean true to annotate the alignment view with groups on the alignment (and intersecting with selected region if selectedOnly is true) 
+   *          boolean true to annotate the alignment view with groups on the
+   *          alignment (and intersecting with selected region if selectedOnly
+   *          is true)
    * @return AlignmentView
    */
-  public jalview.datamodel.AlignmentView getAlignmentView(boolean selectedOnly, boolean markGroups)
+  public jalview.datamodel.AlignmentView getAlignmentView(
+          boolean selectedOnly, boolean markGroups)
   {
-    return new AlignmentView(alignment, colSel, selectionGroup, hasHiddenColumns, selectedOnly, markGroups);
+    return new AlignmentView(alignment, colSel, selectionGroup,
+            hasHiddenColumns, selectedOnly, markGroups);
   }
 
   /**
@@ -1732,6 +1894,10 @@ public class AlignViewport implements SelectionSource, VamsasSource
     {
       updateConsensus(ap);
     }
+    if (autoCalculateStrucConsensus)
+    {
+      updateStrucConsensus(ap);
+    }
 
     // Reset endRes of groups if beyond alignment width
     int alWidth = alignment.getWidth();
@@ -1774,8 +1940,8 @@ public class AlignViewport implements SelectionSource, VamsasSource
       {
         Alignment al = (Alignment) alignment;
         Conservation c = new Conservation("All",
-                ResidueProperties.propHash, 3, al.getSequences(), 0,
-                al.getWidth() - 1);
+                ResidueProperties.propHash, 3, al.getSequences(), 0, al
+                        .getWidth() - 1);
         c.calculate();
         c.verdict(false, ConsPercGaps);
 
@@ -1789,8 +1955,8 @@ public class AlignViewport implements SelectionSource, VamsasSource
       SequenceGroup sg = (SequenceGroup) alignment.getGroups().elementAt(s);
       if (sg.cs != null && sg.cs instanceof ClustalxColourScheme)
       {
-        ((ClustalxColourScheme) sg.cs).resetClustalX(
-                sg.getSequences(hiddenRepSequences), sg.getWidth());
+        ((ClustalxColourScheme) sg.cs).resetClustalX(sg
+                .getSequences(hiddenRepSequences), sg.getWidth());
       }
       sg.recalcConservation();
     }
@@ -2015,34 +2181,45 @@ public class AlignViewport implements SelectionSource, VamsasSource
   /**
    * checks current SelectionGroup against record of last hash value, and
    * updates record.
-   * @param b update the record of last hash value
+   * 
+   * @param b
+   *          update the record of last hash value
    * 
    * @return true if SelectionGroup changed since last call (when b is true)
    */
   boolean isSelectionGroupChanged(boolean b)
   {
-    int hc = (selectionGroup == null || selectionGroup.getSize()==0) ? -1 : selectionGroup.hashCode();
-    if (hc!=-1 && hc != sgrouphash)
+    int hc = (selectionGroup == null || selectionGroup.getSize() == 0) ? -1
+            : selectionGroup.hashCode();
+    if (hc != -1 && hc != sgrouphash)
     {
-      if (b) {sgrouphash = hc;}
+      if (b)
+      {
+        sgrouphash = hc;
+      }
       return true;
     }
     return false;
   }
 
   /**
-   * checks current colsel against record of last hash value, and optionally updates
-   * record.
-
-   * @param b update the record of last hash value
+   * checks current colsel against record of last hash value, and optionally
+   * updates record.
+   * 
+   * @param b
+   *          update the record of last hash value
    * @return true if colsel changed since last call (when b is true)
    */
   boolean isColSelChanged(boolean b)
   {
-    int hc = (colSel == null || colSel.size()==0) ? -1 : colSel.hashCode();
-    if (hc!=-1 && hc != colselhash)
+    int hc = (colSel == null || colSel.size() == 0) ? -1 : colSel
+            .hashCode();
+    if (hc != -1 && hc != colselhash)
     {
-      if (b) {colselhash = hc;}
+      if (b)
+      {
+        colselhash = hc;
+      }
       return true;
     }
     return false;
@@ -2154,6 +2331,10 @@ public class AlignViewport implements SelectionSource, VamsasSource
       {
         consensusThread.updateAnnotation();
       }
+      if (strucConsensusThread != null)
+      {
+        strucConsensusThread.updateAnnotation();
+      }
     }
     this.showSequenceLogo = showSequenceLogo;
   }
@@ -2246,39 +2427,42 @@ public class AlignViewport implements SelectionSource, VamsasSource
 
   public StructureSelectionManager getStructureSelectionManager()
   {
-    return StructureSelectionManager.getStructureSelectionManager(Desktop.instance);
+    return StructureSelectionManager
+            .getStructureSelectionManager(Desktop.instance);
   }
 
   /**
    * 
    * @param pdbEntries
-   * @return a series of SequenceI arrays, one for each PDBEntry, listing which sequence in the alignment holds a reference to it
+   * @return a series of SequenceI arrays, one for each PDBEntry, listing which
+   *         sequence in the alignment holds a reference to it
    */
   public SequenceI[][] collateForPDB(PDBEntry[] pdbEntries)
   {
     ArrayList<SequenceI[]> seqvectors = new ArrayList<SequenceI[]>();
-    for (PDBEntry pdb: pdbEntries) {
-    ArrayList<SequenceI> seqs = new ArrayList<SequenceI>();
-    for (int i = 0; i < alignment.getHeight(); i++)
-    {
-      Vector pdbs = alignment.getSequenceAt(i)
-              .getDatasetSequence().getPDBId();
-      if (pdbs == null)
-        continue;
-      SequenceI sq;
-      for (int p = 0; p < pdbs.size(); p++)
+    for (PDBEntry pdb : pdbEntries)
+    {
+      ArrayList<SequenceI> seqs = new ArrayList<SequenceI>();
+      for (int i = 0; i < alignment.getHeight(); i++)
       {
-        PDBEntry p1 = (PDBEntry) pdbs.elementAt(p);
-        if (p1.getId().equals(pdb.getId()))
+        Vector pdbs = alignment.getSequenceAt(i).getDatasetSequence()
+                .getPDBId();
+        if (pdbs == null)
+          continue;
+        SequenceI sq;
+        for (int p = 0; p < pdbs.size(); p++)
         {
-          if (!seqs.contains(sq=alignment.getSequenceAt(i)))
-            seqs.add(sq);
+          PDBEntry p1 = (PDBEntry) pdbs.elementAt(p);
+          if (p1.getId().equals(pdb.getId()))
+          {
+            if (!seqs.contains(sq = alignment.getSequenceAt(i)))
+              seqs.add(sq);
 
-          continue;
+            continue;
+          }
         }
       }
-    }
-    seqvectors.add(seqs.toArray(new SequenceI[seqs.size()]));
+      seqvectors.add(seqs.toArray(new SequenceI[seqs.size()]));
     }
     return seqvectors.toArray(new SequenceI[seqvectors.size()][]);
   }
index 359c500..753ea36 100755 (executable)
@@ -26,7 +26,10 @@ import java.util.Hashtable;
 
 import javax.swing.*;
 
+import com.stevesoft.pat.Regex;
+
 import jalview.analysis.AAFrequency;
+import jalview.analysis.StructureFrequency;
 import jalview.datamodel.*;
 import jalview.schemes.ColourSchemeI;
 
@@ -43,6 +46,11 @@ public class AnnotationPanel extends JPanel implements MouseListener,
 
   final String SHEET = "Sheet";
 
+  /**
+   * For RNA secondary structure "stems" aka helices
+   */
+  final String STEM = "RNA Helix";
+
   final String LABEL = "Label";
 
   final String REMOVE = "Remove Annotation";
@@ -53,6 +61,8 @@ public class AnnotationPanel extends JPanel implements MouseListener,
 
   final Color SHEET_COLOUR = Color.green.darker().darker();
 
+  final Color STEM_COLOUR = Color.blue.darker();
+
   /** DOCUMENT ME!! */
   AlignViewport av;
 
@@ -85,6 +95,11 @@ public class AnnotationPanel extends JPanel implements MouseListener,
 
   boolean MAC = false;
 
+  // for editing cursor
+  int cursorX = 0;
+
+  int cursorY = 0;
+
   /**
    * Creates a new AnnotationPanel object.
    * 
@@ -132,7 +147,7 @@ public class AnnotationPanel extends JPanel implements MouseListener,
    */
   public int adjustPanelHeight()
   {
-    int height=calcPanelHeight();
+    int height = calcPanelHeight();
     this.setPreferredSize(new Dimension(1, height));
     if (ap != null)
     {
@@ -144,8 +159,9 @@ public class AnnotationPanel extends JPanel implements MouseListener,
   }
 
   /**
-   * calculate the height for visible annotation, revalidating bounds where necessary
-   * ABSTRACT GUI METHOD
+   * calculate the height for visible annotation, revalidating bounds where
+   * necessary ABSTRACT GUI METHOD
+   * 
    * @return total height of annotation
    */
   public int calcPanelHeight()
@@ -303,6 +319,13 @@ public class AnnotationPanel extends JPanel implements MouseListener,
         symbol = "\u03B2";
       }
 
+      // Added by LML to color stems
+      else if (evt.getActionCommand().equals(STEM))
+      {
+        type = 'S';
+        symbol = "\u03C3";
+      }
+
       if (!aa[activeRow].hasIcons)
       {
         aa[activeRow].hasIcons = true;
@@ -357,14 +380,15 @@ public class AnnotationPanel extends JPanel implements MouseListener,
         continue;
       String tlabel = null;
       if (anot[index] != null)
-      {
+      { // LML added stem code
         if (label2.equals(HELIX) || label2.equals(SHEET)
-                || label2.equals(LABEL))
+                || label2.equals(STEM) || label2.equals(LABEL))
         {
           tlabel = anot[index].description;
           if (tlabel == null || tlabel.length() < 1)
           {
-            if (label2.equals(HELIX) || label2.equals(SHEET))
+            if (label2.equals(HELIX) || label2.equals(SHEET)
+                    || label2.equals(STEM))
             {
               tlabel = "" + anot[index].secondaryStructure;
             }
@@ -437,12 +461,25 @@ public class AnnotationPanel extends JPanel implements MouseListener,
       }
 
       JPopupMenu pop = new JPopupMenu("Structure type");
-      JMenuItem item = new JMenuItem(HELIX);
-      item.addActionListener(this);
-      pop.add(item);
-      item = new JMenuItem(SHEET);
-      item.addActionListener(this);
-      pop.add(item);
+      JMenuItem item;
+      /*
+       * Just display the needed structure options
+       */
+      if (av.alignment.isNucleotide() == true)
+      {
+        item = new JMenuItem(STEM);
+        item.addActionListener(this);
+        pop.add(item);
+      }
+      else
+      {
+        item = new JMenuItem(HELIX);
+        item.addActionListener(this);
+        pop.add(item);
+        item = new JMenuItem(SHEET);
+        item.addActionListener(this);
+        pop.add(item);
+      }
       item = new JMenuItem(LABEL);
       item.addActionListener(this);
       pop.add(item);
@@ -635,6 +672,38 @@ public class AnnotationPanel extends JPanel implements MouseListener,
    */
   public void mouseClicked(MouseEvent evt)
   {
+    if (activeRow != -1)
+    {
+      AlignmentAnnotation[] aa = av.alignment.getAlignmentAnnotation();
+      AlignmentAnnotation anot = aa[activeRow];
+
+      if (anot.description.equals("secondary structure"))
+      {
+        // System.out.println(anot.description+" "+anot.getRNAStruc());
+      }
+    }
+  }
+
+  // TODO mouseClicked-content and drawCursor are quite experimental!
+  public void drawCursor(Graphics graphics, SequenceI seq, int res, int x1,
+          int y1)
+  {
+    int pady = av.charHeight / 5;
+    int charOffset = 0;
+    graphics.setColor(Color.black);
+    graphics.fillRect(x1, y1, av.charWidth, av.charHeight);
+
+    if (av.validCharWidth)
+    {
+      graphics.setColor(Color.white);
+
+      char s = seq.getCharAt(res);
+
+      charOffset = (av.charWidth - fm.charWidth(s)) / 2;
+      graphics.drawString(String.valueOf(s), charOffset + x1,
+              (y1 + av.charHeight) - pady);
+    }
+
   }
 
   /**
@@ -811,7 +880,7 @@ public class AnnotationPanel extends JPanel implements MouseListener,
     boolean[] graphGroupDrawn = new boolean[aa.length];
     int charOffset = 0; // offset for a label
     float fmWidth, fmScaling = 1f; // scaling for a label to fit it into a
-                                   // column.
+    // column.
     Font ofont = g.getFont();
     // \u03B2 \u03B1
     for (int i = 0; i < aa.length; i++)
@@ -827,7 +896,6 @@ public class AnnotationPanel extends JPanel implements MouseListener,
       scaleColLabel = row.scaleColLabel;
       lastSS = ' ';
       lastSSX = 0;
-
       if (row.graph > 0)
       {
         if (row.graphGroup > -1 && graphGroupDrawn[row.graphGroup])
@@ -890,7 +958,9 @@ public class AnnotationPanel extends JPanel implements MouseListener,
         continue;
       }
 
-      x = 0;
+      // first pass sets up state for drawing continuation from left-hand column
+      // of startRes
+      x = (startRes == 0) ? 0 : -1;
       while (x < endRes - startRes)
       {
         if (av.hasHiddenColumns)
@@ -916,160 +986,144 @@ public class AnnotationPanel extends JPanel implements MouseListener,
         {
           validRes = true;
         }
-
-        if (activeRow == i)
+        if (x > -1)
         {
-          g.setColor(Color.red);
-
-          if (av.getColumnSelection() != null)
+          if (activeRow == i)
           {
-            for (int n = 0; n < av.getColumnSelection().size(); n++)
-            {
-              int v = av.getColumnSelection().columnAt(n);
+            g.setColor(Color.red);
 
-              if (v == column)
+            if (av.getColumnSelection() != null)
+            {
+              for (int n = 0; n < av.getColumnSelection().size(); n++)
               {
-                g.fillRect(x * av.charWidth, y, av.charWidth, av.charHeight);
+                int v = av.getColumnSelection().columnAt(n);
+
+                if (v == column)
+                {
+                  g.fillRect(x * av.charWidth, y, av.charWidth,
+                          av.charHeight);
+                }
               }
             }
           }
-        }
 
-        if (av.validCharWidth && validRes
-                && row.annotations[column].displayCharacter != null
-                && (row.annotations[column].displayCharacter.length() > 0))
-        {
-
-          if (centreColLabels || scaleColLabel)
+          if (av.validCharWidth
+                  && validRes
+                  && row.annotations[column].displayCharacter != null
+                  && (row.annotations[column].displayCharacter.length() > 0))
           {
-            fmWidth = (float) fm.charsWidth(
-                    row.annotations[column].displayCharacter.toCharArray(),
-                    0, row.annotations[column].displayCharacter.length());
 
-            if (scaleColLabel)
+            if (centreColLabels || scaleColLabel)
             {
-              // justify the label and scale to fit in column
-              if (fmWidth > av.charWidth)
+              fmWidth = (float) fm.charsWidth(
+                      row.annotations[column].displayCharacter
+                              .toCharArray(), 0,
+                      row.annotations[column].displayCharacter.length());
+
+              if (scaleColLabel)
               {
-                // scale only if the current font isn't already small enough
-                fmScaling = av.charWidth;
-                fmScaling /= fmWidth;
-                g.setFont(ofont.deriveFont(AffineTransform
-                        .getScaleInstance(fmScaling, 1.0)));
-                // and update the label's width to reflect the scaling.
-                fmWidth = av.charWidth;
+                // justify the label and scale to fit in column
+                if (fmWidth > av.charWidth)
+                {
+                  // scale only if the current font isn't already small enough
+                  fmScaling = av.charWidth;
+                  fmScaling /= fmWidth;
+                  g.setFont(ofont.deriveFont(AffineTransform
+                          .getScaleInstance(fmScaling, 1.0)));
+                  // and update the label's width to reflect the scaling.
+                  fmWidth = av.charWidth;
+                }
               }
             }
-          }
-          else
-          {
-            fmWidth = (float) fm
-                    .charWidth(row.annotations[column].displayCharacter
-                            .charAt(0));
-          }
-          charOffset = (int) ((av.charWidth - fmWidth) / 2f);
+            else
+            {
+              fmWidth = (float) fm
+                      .charWidth(row.annotations[column].displayCharacter
+                              .charAt(0));
+            }
+            charOffset = (int) ((av.charWidth - fmWidth) / 2f);
 
-          if (row.annotations[column].colour == null)
-            g.setColor(Color.black);
-          else
-            g.setColor(row.annotations[column].colour);
+            if (row.annotations[column].colour == null)
+              g.setColor(Color.black);
+            else
+              g.setColor(row.annotations[column].colour);
 
-          if (column == 0 || row.graph > 0)
-          {
-            g.drawString(row.annotations[column].displayCharacter,
-                    (x * av.charWidth) + charOffset, y + iconOffset);
-          }
-          else if (row.annotations[column - 1] == null
-                  || (labelAllCols
-                          || !row.annotations[column].displayCharacter
-                                  .equals(row.annotations[column - 1].displayCharacter) || (row.annotations[column].displayCharacter
-                          .length() < 2 && row.annotations[column].secondaryStructure == ' ')))
-          {
-            g.drawString(row.annotations[column].displayCharacter, x
-                    * av.charWidth + charOffset, y + iconOffset);
+            if (column == 0 || row.graph > 0)
+            {
+              g.drawString(row.annotations[column].displayCharacter,
+                      (x * av.charWidth) + charOffset, y + iconOffset);
+            }
+            else if (row.annotations[column - 1] == null
+                    || (labelAllCols
+                            || !row.annotations[column].displayCharacter
+                                    .equals(row.annotations[column - 1].displayCharacter) || (row.annotations[column].displayCharacter
+                            .length() < 2 && row.annotations[column].secondaryStructure == ' ')))
+            {
+              g.drawString(row.annotations[column].displayCharacter, x
+                      * av.charWidth + charOffset, y + iconOffset);
+            }
+            g.setFont(ofont);
           }
-          g.setFont(ofont);
         }
-
         if (row.hasIcons)
         {
-          if (!validRes
-                  || (row.annotations[column].secondaryStructure != lastSS))
+          char ss = validRes ? row.annotations[column].secondaryStructure
+                  : ' ';
+          if (ss == 'S')
+          {
+            // distinguish between forward/backward base-pairing
+            if (row.annotations[column].displayCharacter.indexOf(')') > -1)
+            {
+              ss = 's';
+            }
+          }
+          if (!validRes || (ss != lastSS))
           {
-            switch (lastSS)
+            if (x > -1)
             {
-            case 'H':
-              g.setColor(HELIX_COLOUR);
-              if (MAC)
+              switch (lastSS)
               {
-                // Off by 1 offset when drawing rects and ovals
-                // to offscreen image on the MAC
-                g.fillRoundRect(lastSSX, y + 4 + iconOffset,
-                        (x * av.charWidth) - lastSSX, 7, 8, 8);
+              case 'H':
+                drawHelixAnnot(g, row, lastSSX, x, y, iconOffset, startRes,
+                        column, validRes, validEnd);
                 break;
-              }
-
-              int sCol = (lastSSX / av.charWidth) + startRes;
-              int x1 = lastSSX;
-              int x2 = (x * av.charWidth);
-
-              if (sCol == 0
-                      || row.annotations[sCol - 1] == null
-                      || row.annotations[sCol - 1].secondaryStructure != 'H')
-              {
-                g.fillArc(lastSSX, y + 4 + iconOffset, av.charWidth, 8, 90,
-                        180);
-                x1 += av.charWidth / 2;
-              }
 
-              if (!validRes || row.annotations[column] == null
-                      || row.annotations[column].secondaryStructure != 'H')
-              {
-                g.fillArc((x * av.charWidth) - av.charWidth, y + 4
-                        + iconOffset, av.charWidth, 8, 270, 180);
-                x2 -= av.charWidth / 2;
-              }
-
-              g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 8);
-              break;
-
-            case 'E':
-              g.setColor(SHEET_COLOUR);
-              g.fillRect(lastSSX, y + 4 + iconOffset, (x * av.charWidth)
-                      - lastSSX - 4, 7);
-              g.fillPolygon(new int[]
-              { (x * av.charWidth) - 4, (x * av.charWidth) - 4,
-                  (x * av.charWidth) }, new int[]
-              { y + iconOffset, y + 14 + iconOffset, y + 8 + iconOffset },
-                      3);
+              case 'E':
+                drawSheetAnnot(g, row, lastSSX, x, y, iconOffset, startRes,
+                        column, validRes, validEnd);
+                break;
 
-              break;
+              case 'S': // Stem case for RNA secondary structure
+              case 's': // and opposite direction
+                drawStemAnnot(g, row, lastSSX, x, y, iconOffset, startRes,
+                        column, validRes, validEnd);
+                break;
 
-            default:
-              g.setColor(Color.gray);
-              g.fillRect(lastSSX, y + 6 + iconOffset, (x * av.charWidth)
-                      - lastSSX, 2);
+              default:
+                g.setColor(Color.gray);
+                g.fillRect(lastSSX, y + 6 + iconOffset, (x * av.charWidth)
+                        - lastSSX, 2);
 
-              break;
+                break;
+              }
             }
-
             if (validRes)
             {
-              lastSS = row.annotations[column].secondaryStructure;
+              lastSS = ss;
             }
             else
             {
               lastSS = ' ';
             }
-
-            lastSSX = (x * av.charWidth);
+            if (x > -1)
+            {
+              lastSSX = (x * av.charWidth);
+            }
           }
         }
-
         column++;
         x++;
       }
-
       if (column >= row.annotations.length)
       {
         column = row.annotations.length - 1;
@@ -1087,64 +1141,22 @@ public class AnnotationPanel extends JPanel implements MouseListener,
         switch (lastSS)
         {
         case 'H':
-          g.setColor(HELIX_COLOUR);
-          if (MAC)
-          {
-            // Off by 1 offset when drawing rects and ovals
-            // to offscreen image on the MAC
-            g.fillRoundRect(lastSSX, y + 4 + iconOffset, (x * av.charWidth)
-                    - lastSSX, 7, 8, 8);
-            break;
-          }
-
-          int sCol = (lastSSX / av.charWidth) + startRes;
-          int x1 = lastSSX;
-          int x2 = (x * av.charWidth);
-
-          if (sCol == 0 || row.annotations[sCol - 1] == null
-                  || row.annotations[sCol - 1].secondaryStructure != 'H')
-          {
-            g.fillArc(lastSSX, y + 4 + iconOffset, av.charWidth, 8, 90, 180);
-            x1 += av.charWidth / 2;
-          }
-
-          if (row.annotations[column] == null
-                  || row.annotations[column].secondaryStructure != 'H')
-          {
-            g.fillArc((x * av.charWidth) - av.charWidth,
-                    y + 4 + iconOffset, av.charWidth, 8, 270, 180);
-            x2 -= av.charWidth / 2;
-          }
-
-          g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 8);
-
+          drawHelixAnnot(g, row, lastSSX, x, y, iconOffset, startRes,
+                  column, validRes, validEnd);
           break;
 
         case 'E':
-          g.setColor(SHEET_COLOUR);
-
-          if (!validEnd || row.annotations[endRes] == null
-                  || row.annotations[endRes].secondaryStructure != 'E')
-          {
-            g.fillRect(lastSSX, y + 4 + iconOffset, (x * av.charWidth)
-                    - lastSSX - 4, 7);
-            g.fillPolygon(new int[]
-            { (x * av.charWidth) - 4, (x * av.charWidth) - 4,
-                (x * av.charWidth) }, new int[]
-            { y + iconOffset, y + 14 + iconOffset, y + 7 + iconOffset }, 3);
-          }
-          else
-          {
-            g.fillRect(lastSSX, y + 4 + iconOffset, (x + 1) * av.charWidth
-                    - lastSSX, 7);
-          }
+          drawSheetAnnot(g, row, lastSSX, x, y, iconOffset, startRes,
+                  column, validRes, validEnd);
+          break;
+        case 's':
+        case 'S': // Stem case for RNA secondary structure
+          drawStemAnnot(g, row, lastSSX, x, y, iconOffset, startRes,
+                  column, validRes, validEnd);
           break;
-
         default:
-          g.setColor(Color.gray);
-          g.fillRect(lastSSX, y + 6 + iconOffset, (x * av.charWidth)
-                  - lastSSX, 2);
-
+          drawGlyphLine(g, row, lastSSX, x, y, iconOffset, startRes,
+                  column, validRes, validEnd);
           break;
         }
       }
@@ -1214,6 +1226,157 @@ public class AnnotationPanel extends JPanel implements MouseListener,
     }
   }
 
+  private void drawStemAnnot(Graphics g, AlignmentAnnotation row,
+          int lastSSX, int x, int y, int iconOffset, int startRes,
+          int column, boolean validRes, boolean validEnd)
+  {
+    g.setColor(STEM_COLOUR);
+    int sCol = (lastSSX / av.charWidth) + startRes;
+    int x1 = lastSSX;
+    int x2 = (x * av.charWidth);
+    Regex closeparen = new Regex("(\\))");
+
+    String dc = column == 0 ? ""
+            : row.annotations[column - 1].displayCharacter;
+
+    boolean diffupstream = sCol == 0 || row.annotations[sCol - 1] == null
+            || !dc.equals(row.annotations[sCol - 1].displayCharacter);
+    boolean diffdownstream = !validRes || !validEnd
+            || row.annotations[column] == null
+            || !dc.equals(row.annotations[column].displayCharacter);
+    // System.out.println("Column "+column+" diff up: "+diffupstream+" down:"+diffdownstream);
+    // If a closing base pair half of the stem, display a backward arrow
+    if (column > 0 && closeparen.search(dc))
+    {
+      if (diffupstream)
+      // if (validRes && column>1 && row.annotations[column-2]!=null &&
+      // dc.equals(row.annotations[column-2].displayCharacter))
+      {
+        g.fillPolygon(new int[]
+        { lastSSX + 5, lastSSX + 5, lastSSX }, new int[]
+        { y + iconOffset, y + 14 + iconOffset, y + 8 + iconOffset }, 3);
+        x1 += 5;
+      }
+      if (diffdownstream)
+      {
+        x2 -= 1;
+      }
+    }
+    else
+    {
+      // display a forward arrow
+      if (diffdownstream)
+      {
+        g.fillPolygon(new int[]
+        { x2 - 5, x2 - 5, x2 }, new int[]
+        { y + iconOffset, y + 14 + iconOffset, y + 8 + iconOffset }, 3);
+        x2 -= 5;
+      }
+      if (diffupstream)
+      {
+        x1 += 1;
+      }
+    }
+    // draw arrow body
+    g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 7);
+  }
+
+  private void drawGlyphLine(Graphics g, AlignmentAnnotation row,
+          int lastSSX, int x, int y, int iconOffset, int startRes,
+          int column, boolean validRes, boolean validEnd)
+  {
+    g.setColor(Color.gray);
+    g
+            .fillRect(lastSSX, y + 6 + iconOffset, (x * av.charWidth)
+                    - lastSSX, 2);
+  }
+
+  private void drawSheetAnnot(Graphics g, AlignmentAnnotation row,
+          int lastSSX, int x, int y, int iconOffset, int startRes,
+          int column, boolean validRes, boolean validEnd)
+  {
+    g.setColor(SHEET_COLOUR);
+
+    if (!validEnd || !validRes || row.annotations[column] == null
+            || row.annotations[column].secondaryStructure != 'E')
+    {
+      g.fillRect(lastSSX, y + 4 + iconOffset, (x * av.charWidth) - lastSSX
+              - 4, 7);
+      g.fillPolygon(
+              new int[]
+              { (x * av.charWidth) - 4, (x * av.charWidth) - 4,
+                  (x * av.charWidth) }, new int[]
+              { y + iconOffset, y + 14 + iconOffset, y + 7 + iconOffset },
+              3);
+    }
+    else
+    {
+      g.fillRect(lastSSX, y + 4 + iconOffset, (x + 1) * av.charWidth
+              - lastSSX, 7);
+    }
+
+  }
+
+  private void drawHelixAnnot(Graphics g, AlignmentAnnotation row,
+          int lastSSX, int x, int y, int iconOffset, int startRes,
+          int column, boolean validRes, boolean validEnd)
+  {
+    g.setColor(HELIX_COLOUR);
+
+    int sCol = (lastSSX / av.charWidth) + startRes;
+    int x1 = lastSSX;
+    int x2 = (x * av.charWidth);
+
+    if (MAC)
+    {
+      int ofs = av.charWidth / 2;
+      // Off by 1 offset when drawing rects and ovals
+      // to offscreen image on the MAC
+      g.fillRoundRect(lastSSX, y + 4 + iconOffset, x2 - x1, 8, 8, 8);
+      if (sCol == 0 || row.annotations[sCol - 1] == null
+              || row.annotations[sCol - 1].secondaryStructure != 'H')
+      {
+      }
+      else
+      {
+        // g.setColor(Color.orange);
+        g.fillRoundRect(lastSSX, y + 4 + iconOffset, x2 - x1 - ofs + 1, 8,
+                0, 0);
+      }
+      if (!validRes || row.annotations[column] == null
+              || row.annotations[column].secondaryStructure != 'H')
+      {
+
+      }
+      else
+      {
+        // g.setColor(Color.magenta);
+        g.fillRoundRect(lastSSX + ofs, y + 4 + iconOffset, x2 - x1 - ofs
+                + 1, 8, 0, 0);
+
+      }
+
+      return;
+    }
+
+    if (sCol == 0 || row.annotations[sCol - 1] == null
+            || row.annotations[sCol - 1].secondaryStructure != 'H')
+    {
+      g.fillArc(lastSSX, y + 4 + iconOffset, av.charWidth, 8, 90, 180);
+      x1 += av.charWidth / 2;
+    }
+
+    if (!validRes || row.annotations[column] == null
+            || row.annotations[column].secondaryStructure != 'H')
+    {
+      g.fillArc((x * av.charWidth) - av.charWidth, y + 4 + iconOffset,
+              av.charWidth, 8, 270, 180);
+      x2 -= av.charWidth / 2;
+    }
+
+    g.fillRect(x1, y + 4 + iconOffset, x2 - x1, 8);
+  }
+
   public void drawLineGraph(Graphics g, AlignmentAnnotation aa, int sRes,
           int eRes, int y, float min, float max, int graphHeight)
   {
@@ -1388,46 +1551,77 @@ public class AnnotationPanel extends JPanel implements MouseListener,
       // draw profile if available
       if (renderProfile && aa.annotations[column].value != 0)
       {
+
         int profl[] = getProfileFor(aa, column);
-        int ht = y1, htn = y2 - y1;// aa.graphHeight;
-        float wdth;
-        double ht2 = 0;
-        char[] dc = new char[1];
-        LineMetrics lm;
-        for (int c = 1; profl != null && c < profl[0];)
+        // just try to draw the logo if profl is not null
+        if (profl != null)
         {
-          dc[0] = (char) profl[c++];
-          wdth = av.charWidth;
-          wdth /= (float) fm.charsWidth(dc, 0, 1);
 
-          if (c > 2)
+          int ht = y1, htn = y2 - y1;// aa.graphHeight;
+          float wdth;
+          double ht2 = 0;
+          char[] dc;
+
+          /**
+           * profl.length == 51 indicates that the profile of a secondary
+           * structure conservation row was accesed.
+           * Therefore dc gets length 2, to have space for a basepair instead of
+           * just a single nucleotide
+           */
+          if (profl.length == 51)
+          {
+            dc = new char[2];
+          }
+          else
           {
-            ht += (int) ht2;
+            dc = new char[1];
           }
+
+          LineMetrics lm;
+          for (int c = 1; profl != null && c < profl[0];)
           {
-            // if (aa.annotations[column].value==0) {
-            // g.setFont(ofont.deriveFont(AffineTransform.getScaleInstance(wdth,
-            // (ht2=(aa.graphHeight*0.1/av.charHeight)))));
-            // ht = y2-(int)ht2;
-            // } else {
-            g.setFont(ofont.deriveFont(AffineTransform.getScaleInstance(
-                    wdth, (ht2 = (htn * ((double) profl[c++]) / 100.0))
-                            / av.charHeight)));
-            lm = g.getFontMetrics().getLineMetrics(dc, 0, 1, g);
-            // htn -=ht2;
-            // }
-            g.setColor(profcolour.findColour(dc[0])); // (av.globalColourScheme!=null)
-                                                      // ? );// try to get a
-                                                      // colourscheme for the
-                                                      // group(aa.groupRef.cs==null)
-                                                      // ? av.textColour2 :
-                                                      // cs.findColour(dc));
-            g.drawChars(dc, 0, 1, x * av.charWidth,
-                    (int) (ht + lm.getHeight()));
-            // ht+=g.getFontMetrics().getAscent()-g.getFontMetrics().getDescent();
+            dc[0] = (char) profl[c++];
+
+            if (aa.label.startsWith("StrucConsensus"))
+            {
+              dc[1] = (char) profl[c++];
+            }
+            
+            wdth = av.charWidth;
+            wdth /= (float) fm.charsWidth(dc, 0, dc.length);
+
+            if (c > 2)
+            {
+              ht += (int) ht2;
+            }
+            {
+              // if (aa.annotations[column].value==0) {
+              // g.setFont(ofont.deriveFont(AffineTransform.getScaleInstance(wdth,
+              // (ht2=(aa.graphHeight*0.1/av.charHeight)))));
+              // ht = y2-(int)ht2;
+              // } else {
+              g.setFont(ofont.deriveFont(AffineTransform.getScaleInstance(
+                      wdth, (ht2 = (htn * ((double) profl[c++]) / 100.0))
+                              / av.charHeight)));
+              lm = g.getFontMetrics().getLineMetrics(dc, 0, 1, g);
+              // htn -=ht2;
+              // }
+              g.setColor(profcolour.findColour(dc[0])); // (av.globalColourScheme!=null)
+              // ? );// try to get a
+              // colourscheme for the
+              // group(aa.groupRef.cs==null)
+              // ? av.textColour2 :
+              // cs.findColour(dc));
+              // System.out.println(dc[0]);
+
+              g.drawChars(dc, 0, dc.length, x * av.charWidth,
+                      (int) (ht + lm.getHeight()));
+
+              // ht+=g.getFontMetrics().getAscent()-g.getFontMetrics().getDescent();
+            }
           }
+          g.setFont(ofont);
         }
-        g.setFont(ofont);
       }
       x++;
     }
@@ -1453,16 +1647,39 @@ public class AnnotationPanel extends JPanel implements MouseListener,
               && aa.groupRef.isShowSequenceLogo())
       {
         return AAFrequency.extractProfile(
-                aa.groupRef.consensusData[column],
-                aa.groupRef.getIgnoreGapsConsensus());
+                aa.groupRef.consensusData[column], aa.groupRef
+                        .getIgnoreGapsConsensus());
       }
       // TODO extend annotation row to enable dynamic and static profile data to
       // be stored
       if (aa.groupRef == null && aa.sequenceRef == null
               && av.isShowSequenceLogo())
       {
-        return AAFrequency.extractProfile(av.hconsensus[column],
-                av.getIgnoreGapsConsensus());
+        return AAFrequency.extractProfile(av.hconsensus[column], av
+                .getIgnoreGapsConsensus());
+      }
+    }
+    else
+    {
+      if (aa.autoCalculated && aa.label.startsWith("StrucConsensus"))
+      {
+        if (aa.groupRef != null && aa.groupRef.consensusData != null
+                && aa.groupRef.isShowSequenceLogo())
+        {
+          //TODO check what happens for group selections
+          return StructureFrequency.extractProfile(
+                  aa.groupRef.consensusData[column], aa.groupRef
+                          .getIgnoreGapsConsensus());
+        }
+        // TODO extend annotation row to enable dynamic and static profile data
+        // to
+        // be stored
+        if (aa.groupRef == null && aa.sequenceRef == null
+                && av.isShowSequenceLogo())
+        {
+          return StructureFrequency.extractProfile(av.hStrucConsensus[column],
+                  av.getIgnoreGapsConsensus());
+        }
       }
     }
     return null;
index 2c0d7d6..edd0de0 100644 (file)
@@ -1056,7 +1056,12 @@ public class AppJmol extends GStructureViewer implements Runnable,
     buriedColour.setSelected(true);
     jmb.setJalviewColourScheme(new BuriedColourScheme());
   }
-
+  
+  public void purinePyrimidineColour_actionPerformed(ActionEvent actionEvent)
+  {
+    setJalviewColourScheme(new PurinePyrimidineColourScheme());
+  }
+  
   public void userColour_actionPerformed(ActionEvent actionEvent)
   {
     userColour.setSelected(true);
diff --git a/src/jalview/gui/AppVarna.java b/src/jalview/gui/AppVarna.java
new file mode 100644 (file)
index 0000000..ecc6cb6
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package jalview.gui;
+
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.awt.*;
+
+import javax.swing.*;
+import javax.swing.event.*;
+
+import java.awt.event.*;
+import java.io.*;
+
+import jalview.api.SequenceStructureBinding;
+import jalview.bin.Cache;
+import jalview.datamodel.*;
+import jalview.gui.ViewSelectionMenu.ViewSetProvider;
+import jalview.structure.*;
+import jalview.io.*;
+import jalview.schemes.*;
+import fr.orsay.lri.varna.VARNAPanel;
+import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
+import fr.orsay.lri.varna.exceptions.ExceptionNonEqualLength;
+import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses;
+import fr.orsay.lri.varna.interfaces.InterfaceVARNAListener;
+import fr.orsay.lri.varna.models.VARNAConfig;
+import fr.orsay.lri.varna.models.annotations.HighlightRegionAnnotation;
+import fr.orsay.lri.varna.models.rna.ModeleBaseNucleotide;
+import fr.orsay.lri.varna.models.rna.RNA;
+
+
+public class AppVarna extends JInternalFrame implements InterfaceVARNAListener,SecondaryStructureListener// implements Runnable,SequenceStructureBinding, ViewSetProvider
+
+{
+  AppVarnaBinding vab;
+
+  VARNAPanel varnaPanel;
+  
+  public String name;
+  
+  public StructureSelectionManager ssm;
+  
+  /*public AppVarna(){
+         vab = new AppVarnaBinding(); 
+         initVarna();
+  }*/
+  
+  
+  public AppVarna(String seq,String struc,String name,AlignmentPanel ap){
+         ArrayList<RNA> rnaList = new ArrayList<RNA>();
+         RNA rna1 = new RNA(name);
+         try {
+                 rna1.setRNA(seq,replaceOddGaps(struc));
+         } catch (ExceptionUnmatchedClosingParentheses e2) {
+               e2.printStackTrace();
+         } catch (ExceptionFileFormatOrSyntax e3) {
+               e3.printStackTrace();
+         }
+         rnaList.add(trimRNA(rna1));     
+         rnaList.add(rna1);
+         rna1.setName("consenus_"+rna1.getName());
+         
+         
+         vab = new AppVarnaBinding(rnaList);
+         //vab = new AppVarnaBinding(seq,struc);
+         //System.out.println("Hallo: "+name);
+         this.name=name;
+         initVarna();
+      ssm = ap.getStructureSelectionManager();
+         ssm.addStructureViewerListener(this);
+  }
+  
+  public void initVarna(){
+         //vab.setFinishedInit(false);
+         varnaPanel=vab.get_varnaPanel();
+         setBackground(Color.white);
+         JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,vab.getListPanel(),varnaPanel);
+         getContentPane().setLayout(new BorderLayout());
+         getContentPane().add(split, BorderLayout.CENTER);
+         //getContentPane().add(vab.getTools(), BorderLayout.NORTH);   
+         varnaPanel.addVARNAListener(this);
+         jalview.gui.Desktop.addInternalFrame(this,"VARNA -"+name,getBounds().width, getBounds().height);
+         this.pack();
+         showPanel(true);
+  }
+  
+  public String replaceOddGaps(String oldStr){
+         String patternStr = "[^([{<>}])]";
+      String replacementStr = ".";
+      Pattern pattern = Pattern.compile(patternStr);
+      Matcher matcher = pattern.matcher(oldStr);
+      String newStr=matcher.replaceAll(replacementStr);
+         return newStr;
+  }
+  
+  public RNA trimRNA(RNA rna){
+         RNA rnaTrim = new RNA("trim_"+rna.getName());
+         try {
+                 rnaTrim.setRNA(rna.getSeq(),replaceOddGaps(rna.getStructDBN()));
+         } catch (ExceptionUnmatchedClosingParentheses e2) {
+               e2.printStackTrace();
+         } catch (ExceptionFileFormatOrSyntax e3) {
+               e3.printStackTrace();
+         }
+
+         StringBuffer seq=new StringBuffer(rnaTrim.getSeq());
+         StringBuffer struc=new StringBuffer(rnaTrim.getStructDBN());
+         for(int i=0;i<rnaTrim.getSeq().length();i++){
+                 //TODO: Jalview utility for gap detection java.utils.isGap()
+                 //TODO: Switch to jalview rna datamodel
+                 if(seq.substring(i, i+1).compareTo("-")==0 || seq.substring(i, i+1).compareTo(".")==0){
+                         if(!rnaTrim.findPair(i).isEmpty()){
+                                 int m=rnaTrim.findPair(i).get(1);
+                                 int l=rnaTrim.findPair(i).get(0);
+                                 
+                                 struc.replace(m, m+1, "*");
+                                 struc.replace(l, l+1, "*");
+                         }else{
+                                 struc.replace(i, i+1, "*");
+                         }
+                 }
+         }
+        
+         String newSeq=rnaTrim.getSeq().replace("-", "");
+         rnaTrim.getSeq().replace(".", "");
+         String newStruc=struc.toString().replace("*", "");
+
+         try {
+               rnaTrim.setRNA(newSeq,newStruc);
+         } catch (ExceptionUnmatchedClosingParentheses e) {
+               // TODO Auto-generated catch block
+               e.printStackTrace();
+         } catch (ExceptionFileFormatOrSyntax e) {
+               // TODO Auto-generated catch block
+               e.printStackTrace();
+         }
+         
+         return rnaTrim;
+  }
+
+  public void showPanel(boolean show){
+         this.setVisible(show);
+  }
+  
+  private boolean _started = false;
+
+  public void run(){
+         _started = true;
+         
+         try
+      {
+        initVarna();
+      } catch (OutOfMemoryError oomerror)
+      {
+        new OOMWarning("When trying to open the Varna viewer!", oomerror);
+      } catch (Exception ex)
+      {
+        Cache.log.error("Couldn't open Varna viewer!", ex);
+      }
+  }
+
+@Override
+public void onUINewStructure(VARNAConfig v, RNA r) {
+       // TODO Auto-generated method stub
+       
+}
+
+@Override
+public void onWarningEmitted(String s) {
+       // TODO Auto-generated method stub
+       
+}
+/**
+ * If a mouseOver event from the AlignmentPanel 
+ * is noticed the currently selected RNA in the 
+ * VARNA window is highlighted at the specific position. 
+ * To be able to remove it before the next highlight
+ * it is saved in _lastHighlight
+ */
+private  HighlightRegionAnnotation _lastHighlight;
+@Override
+public void mouseOverSequence(SequenceI sequence, int index) {
+       // TODO Auto-generated method stub
+       RNA rna=vab.getSelectedRNA();
+       rna.removeHighlightRegion(_lastHighlight);
+       
+       HighlightRegionAnnotation highlight = new HighlightRegionAnnotation(rna.getBasesBetween(index,index));
+       rna.addHighlightRegion(highlight);
+       _lastHighlight=highlight;
+       vab.updateSelectedRNA(rna);
+}
+
+@Override
+public void mouseOverStructure(int atomIndex, String strInfo) {
+       // TODO Auto-generated method stub
+       
+}
+
+@Override
+public void onStructureRedrawn()
+{
+  // TODO Auto-generated method stub
+  
+}
+
+
+}
diff --git a/src/jalview/gui/AppVarnaBinding.java b/src/jalview/gui/AppVarnaBinding.java
new file mode 100644 (file)
index 0000000..88cc288
--- /dev/null
@@ -0,0 +1,886 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package jalview.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.GridLayout;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.DropTargetDragEvent;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.dnd.DropTargetEvent;
+import java.awt.dnd.DropTargetListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ComponentEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.io.File;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import javax.swing.DefaultListModel;
+import javax.swing.DefaultListSelectionModel;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTextField;
+import javax.swing.ListModel;
+import javax.swing.ListSelectionModel;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import fr.orsay.lri.varna.VARNAPanel;
+import fr.orsay.lri.varna.components.ReorderableJList;
+import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
+import fr.orsay.lri.varna.exceptions.ExceptionLoadingFailed;
+import fr.orsay.lri.varna.exceptions.ExceptionNonEqualLength;
+import fr.orsay.lri.varna.exceptions.ExceptionUnmatchedClosingParentheses;
+import fr.orsay.lri.varna.interfaces.InterfaceVARNAListener;
+import fr.orsay.lri.varna.models.FullBackup;
+import fr.orsay.lri.varna.models.VARNAConfig;
+import fr.orsay.lri.varna.models.rna.Mapping;
+import fr.orsay.lri.varna.models.rna.RNA;
+
+public class AppVarnaBinding extends jalview.ext.varna.JalviewVarnaBinding implements DropTargetListener, InterfaceVARNAListener, MouseListener {
+
+       /**
+        * 
+        */
+       //private static final long serialVersionUID = -790155708306987257L;
+
+       private String DEFAULT_SEQUENCE = "CAGCACGACACUAGCAGUCAGUGUCAGACUGCAIACAGCACGACACUAGCAGUCAGUGUCAGACUGCAIACAGCACGACACUAGCAGUCAGUGUCAGACUGCAIA";
+       private String DEFAULT_STRUCTURE1 = "..(((((...(((((...(((((...(((((.....)))))...))))).....(((((...(((((.....)))))...))))).....)))))...)))))..";
+       private String DEFAULT_STRUCTURE2 = "..(((((...(((((...(((((........(((((...(((((.....)))))...)))))..................))))).....)))))...)))))..";
+       public VARNAPanel vp;
+
+       protected JPanel _tools = new JPanel();
+       private JPanel _input = new JPanel();
+
+       private JPanel _seqPanel = new JPanel();
+       private JPanel _strPanel = new JPanel();
+       private JLabel _info = new JLabel();
+       private JTextField _str = new JTextField();
+       private JTextField _seq = new JTextField();
+       private JLabel _strLabel = new JLabel(" Str:");
+       private JLabel _seqLabel = new JLabel(" Seq:");
+       private JButton _createButton = new JButton("Create");
+       private JButton _updateButton = new JButton("Update");
+       private JButton _deleteButton = new JButton("Delete");
+       private JButton _duplicateButton = new JButton("Snapshot");
+       
+       protected JPanel _listPanel = new JPanel();
+       private ReorderableJList _sideList = null;
+
+
+       private static String errorOpt = "error";
+       @SuppressWarnings("unused")
+       private boolean _error;
+
+       private Color _backgroundColor = Color.white;
+
+       private static int _nextID = 1;
+       @SuppressWarnings("unused")
+       private int _algoCode;
+       
+       private BackupHolder _rnaList;
+
+
+       /*public AppVarnaBinding() {
+               //super("VARNA in Jalview");
+               //this.set_seq("ATGC");
+               //this.set_str(".().");
+               //RNAPanelDemoInit();
+               
+               //initVarna("ATGCATGATATATATATAT","....((((...))))....");
+               initVarna(this.DEFAULT_SEQUENCE,this.DEFAULT_STRUCTURE1);
+       }*/
+       
+       public AppVarnaBinding(String seq,String struc){
+               //super("VARNA in Jalview");
+               initVarna(seq,struc);
+       }
+       
+       public AppVarnaBinding(ArrayList<RNA> rnaList){
+               //super("VARNA in Jalview");
+               initVarnaEdit(rnaList);
+       }
+       
+       
+       
+       private void initVarna(String seq, String str){
+               DefaultListModel dlm = new DefaultListModel(); 
+           
+               DefaultListSelectionModel m = new DefaultListSelectionModel();
+           m.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+           m.setLeadAnchorNotificationEnabled(false);
+           
+           _sideList = new ReorderableJList();
+               _sideList.setModel(dlm);
+               _sideList.addMouseListener(this);
+           _sideList.setSelectionModel(m);
+           _sideList.setPreferredSize(new Dimension(100, 0));
+           _sideList.addListSelectionListener( new ListSelectionListener(){
+                       public void valueChanged(ListSelectionEvent arg0) {
+                               if (!_sideList.isSelectionEmpty() && !arg0.getValueIsAdjusting())
+                               {
+                                       FullBackup  sel = (FullBackup) _sideList.getSelectedValue();
+                                       Mapping map = Mapping.DefaultOutermostMapping(vp.getRNA().getSize(), sel.rna.getSize());
+                                       vp.showRNAInterpolated(sel.rna,sel.config,map);
+                                       _seq.setText(sel.rna.getSeq());
+                                       _str.setText(sel.rna.getStructDBN());
+                               }
+                       }
+           });
+
+           _rnaList = new BackupHolder(dlm,_sideList);
+               RNA _RNA1 = new RNA("User defined 1");
+               
+               try {
+                       vp = new VARNAPanel("0",".");
+                       _RNA1.setRNA(seq, str);
+                       _RNA1.drawRNARadiate(vp.getConfig());
+               } catch (ExceptionNonEqualLength e) {
+                       vp.errorDialog(e);
+               } catch (ExceptionUnmatchedClosingParentheses e2) {
+               e2.printStackTrace();
+               } catch (ExceptionFileFormatOrSyntax e3) {
+               e3.printStackTrace();
+               }
+               vp.setPreferredSize(new Dimension(400, 400));
+               _rnaList.add(vp.getConfig().clone(),_RNA1,generateDefaultName(),true);
+
+               //TODO setBackground(_backgroundColor);
+               vp.setBackground(_backgroundColor);
+
+               //TODO getContentPane().setLayout(new BorderLayout());
+               //TODO getContentPane().add(vp, BorderLayout.CENTER);
+
+               //setVisible(true);
+               vp.addVARNAListener(this);
+       }
+       
+       private void initVarnaEdit(ArrayList<RNA> rnaInList) 
+       {
+           DefaultListModel dlm = new DefaultListModel(); 
+           
+
+               int marginTools = 40;
+
+           DefaultListSelectionModel m = new DefaultListSelectionModel();
+           m.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+           m.setLeadAnchorNotificationEnabled(false);
+           
+           
+               _sideList = new ReorderableJList();
+               _sideList.setModel(dlm);
+               _sideList.addMouseListener(this);
+           _sideList.setSelectionModel(m);
+           _sideList.setPreferredSize(new Dimension(100, 0));
+           _sideList.addListSelectionListener( new ListSelectionListener(){
+                       public void valueChanged(ListSelectionEvent arg0) {
+                               //System.out.println(arg0);
+                               if (!_sideList.isSelectionEmpty() && !arg0.getValueIsAdjusting())
+                               {
+                                       FullBackup  sel = (FullBackup) _sideList.getSelectedValue();
+                                       Mapping map = Mapping.DefaultOutermostMapping(vp.getRNA().getSize(), sel.rna.getSize());
+                                       vp.showRNAInterpolated(sel.rna,sel.config,map);
+                                       //_seq.setText(sel.rna.getSeq());
+                                       _str.setText(sel.rna.getStructDBN());
+                               }
+                       }
+           });
+           _rnaList = new BackupHolder(dlm,_sideList);
+                       
+               try {
+                       vp = new VARNAPanel("0",".");
+                       for(int i=0;i<rnaInList.size();i++){
+                               rnaInList.get(i).drawRNARadiate(vp.getConfig());
+                       }
+               } catch (ExceptionNonEqualLength e) {
+                       vp.errorDialog(e);
+               } 
+               vp.setPreferredSize(new Dimension(400, 400));
+               for(int i=0;i<rnaInList.size();i++){
+                       if(i<rnaInList.size()-1){
+                               _rnaList.add(vp.getConfig().clone(),rnaInList.get(i),rnaInList.get(i).getName());
+                       }else{
+                               _rnaList.add(vp.getConfig().clone(),rnaInList.get(i),rnaInList.get(i).getName(),true);
+                       }
+               }
+
+           /*_rnaList.add(vp.getConfig().clone(),_RNA2,generateDefaultName());
+           _rnaList.add(vp.getConfig().clone(),_RNA1,generateDefaultName(),true);*/
+
+           JScrollPane listScroller = new JScrollPane(_sideList);
+           listScroller.setPreferredSize(new Dimension(150, 0));
+
+               vp.setBackground(_backgroundColor);
+               
+               
+               Font textFieldsFont = Font.decode("MonoSpaced-PLAIN-12");
+
+               //_seqLabel.setHorizontalTextPosition(JLabel.LEFT);
+               //_seqLabel.setPreferredSize(new Dimension(marginTools, 15));
+               _seq.setFont(textFieldsFont);
+               _seq.setText(rnaInList.get(0).getSeq());
+               
+               _updateButton.addActionListener(new ActionListener() {
+                       public void actionPerformed(ActionEvent e) {
+                               FullBackup  sel = (FullBackup) _sideList.getSelectedValue();
+                               sel.rna.setSequence("A");
+                               }
+               });
+               
+               //_seqPanel.setLayout(new BorderLayout());
+               //_seqPanel.add(_seqLabel, BorderLayout.WEST);
+               //_seqPanel.add(_seq, BorderLayout.CENTER);
+
+               _strLabel.setPreferredSize(new Dimension(marginTools, 15));
+               _strLabel.setHorizontalTextPosition(JLabel.LEFT);
+               _str.setFont(textFieldsFont);
+               _strPanel.setLayout(new BorderLayout());
+               _strPanel.add(_strLabel, BorderLayout.WEST);
+               _strPanel.add(_str, BorderLayout.CENTER);
+
+               _input.setLayout(new GridLayout(1, 0));
+               //_input.add(_seqPanel);
+               _input.add(_strPanel);
+
+               JPanel goPanel = new JPanel();
+               goPanel.setLayout(new BorderLayout());
+
+               _tools.setLayout(new BorderLayout());
+               _tools.add(_input, BorderLayout.CENTER);
+               //_tools.add(_info, BorderLayout.SOUTH);
+               _tools.add(goPanel, BorderLayout.EAST);
+
+               /*_deleteButton.addActionListener(new ActionListener() {
+                       public void actionPerformed(ActionEvent e) {
+                               _rnaList.removeSelected();
+                       }
+               });
+               _duplicateButton.addActionListener(new ActionListener() {
+                       public void actionPerformed(ActionEvent e) {
+                                       _rnaList.add((VARNAConfig)vp.getConfig().clone(),vp.getRNA().clone(),vp.getRNA().getName()+"-"+DateFormat.getTimeInstance(DateFormat.LONG).format(new Date()),true); 
+                       }});
+               */
+               goPanel.add(_updateButton, BorderLayout.CENTER);
+               
+               
+               JPanel ops = new JPanel();
+               ops.setLayout(new GridLayout(1,2));
+               ops.add(_deleteButton);
+               ops.add(_duplicateButton);
+               
+               JLabel j = new JLabel("Structures Manager",JLabel.CENTER);
+               _listPanel.setLayout(new BorderLayout());
+               
+               _listPanel.add(ops,BorderLayout.SOUTH);
+               _listPanel.add(j,BorderLayout.NORTH);
+               _listPanel.add(listScroller,BorderLayout.CENTER);
+               
+               
+               
+               //JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,_listPanel,vp);
+               /**TODO
+               getContentPane().setLayout(new BorderLayout());
+               getContentPane().add(split, BorderLayout.CENTER);
+               getContentPane().add(_tools, BorderLayout.NORTH);
+                */
+
+               //TODO setVisible(true);
+               DropTarget dt = new DropTarget(vp, this);
+               
+               vp.addVARNAListener(this);
+       }
+       
+       public JPanel getTools(){
+               return _tools;
+       }
+       
+       public JPanel getListPanel(){
+               return _listPanel;
+       }
+       
+       /**
+        * TODO: Is it effective to transfer the whole RNA?
+        * @return Currently selected RNA
+        */
+       public RNA getSelectedRNA(){
+               return _rnaList.getElementAt(_sideList.getSelectedIndex()).rna;
+       }
+       
+       /**
+        * Substitute currently selected RNA with the edited one
+        * @param rnaEdit
+        */
+       public void updateSelectedRNA(RNA rnaEdit){
+               vp.repaint();
+               vp.showRNA(rnaEdit);
+       }
+
+       /*
+       private void RNAPanelDemoInit() 
+       {
+           DefaultListModel dlm = new DefaultListModel(); 
+           
+
+               int marginTools = 40;
+
+           DefaultListSelectionModel m = new DefaultListSelectionModel();
+           m.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+           m.setLeadAnchorNotificationEnabled(false);
+           
+           
+               _sideList = new ReorderableJList();
+               _sideList.setModel(dlm);
+               _sideList.addMouseListener(this);
+           _sideList.setSelectionModel(m);
+           _sideList.setPreferredSize(new Dimension(100, 0));
+           _sideList.addListSelectionListener( new ListSelectionListener(){
+                       public void valueChanged(ListSelectionEvent arg0) {
+                               //System.out.println(arg0);
+                               if (!_sideList.isSelectionEmpty() && !arg0.getValueIsAdjusting())
+                               {
+                                       FullBackup  sel = (FullBackup) _sideList.getSelectedValue();
+                                       Mapping map = Mapping.DefaultOutermostMapping(vp.getRNA().getSize(), sel.rna.getSize());
+                                       vp.showRNAInterpolated(sel.rna,sel.config,map);
+                                       _seq.setText(sel.rna.getSeq());
+                                       _str.setText(sel.rna.getStructDBN());
+                               }
+                       }
+           });
+
+           _rnaList = new BackupHolder(dlm,_sideList);
+               RNA _RNA1 = new RNA("User defined 1");
+               RNA _RNA2 = new RNA("User defined 2");
+               try {
+                       vp = new VARNAPanel("0",".");
+                       _RNA1.setRNA(DEFAULT_SEQUENCE, DEFAULT_STRUCTURE1);
+                       _RNA1.drawRNARadiate(vp.getConfig());
+                       _RNA2.setRNA(DEFAULT_SEQUENCE, DEFAULT_STRUCTURE2);
+                       _RNA2.drawRNARadiate(vp.getConfig());
+               } catch (ExceptionNonEqualLength e) {
+                       vp.errorDialog(e);
+               } catch (ExceptionUnmatchedClosingParentheses e2) {
+               e2.printStackTrace();
+               } catch (ExceptionFileFormatOrSyntax e3) {
+               e3.printStackTrace();
+               }
+               vp.setPreferredSize(new Dimension(400, 400));
+           _rnaList.add(vp.getConfig().clone(),_RNA2,generateDefaultName());
+           _rnaList.add(vp.getConfig().clone(),_RNA1,generateDefaultName(),true);
+
+           JScrollPane listScroller = new JScrollPane(_sideList);
+           listScroller.setPreferredSize(new Dimension(150, 0));
+
+               setBackground(_backgroundColor);
+               vp.setBackground(_backgroundColor);
+
+
+               Font textFieldsFont = Font.decode("MonoSpaced-PLAIN-12");
+
+               _seqLabel.setHorizontalTextPosition(JLabel.LEFT);
+               _seqLabel.setPreferredSize(new Dimension(marginTools, 15));
+               _seq.setFont(textFieldsFont);
+               _seq.setText(DEFAULT_SEQUENCE);
+
+               _createButton.addActionListener(new ActionListener() {
+                       public void actionPerformed(ActionEvent e) {
+                               try {
+                               RNA nRNA = new RNA(generateDefaultName());
+                               nRNA.setRNA(_seq.getText(), _str.getText());
+                               nRNA.drawRNARadiate(vp.getConfig());
+                               _rnaList.add(new VARNAConfig(),nRNA,true);
+                               } catch (ExceptionUnmatchedClosingParentheses e1) {
+                                       JOptionPane.showMessageDialog(vp, e1.getMessage(),"Error", JOptionPane.ERROR_MESSAGE);
+                               } catch (ExceptionFileFormatOrSyntax e1) {
+                                       JOptionPane.showMessageDialog(vp, e1.getMessage(),"Error", JOptionPane.ERROR_MESSAGE);
+                               }
+                       }
+               });
+
+
+               _seqPanel.setLayout(new BorderLayout());
+               _seqPanel.add(_seqLabel, BorderLayout.WEST);
+               _seqPanel.add(_seq, BorderLayout.CENTER);
+
+               _strLabel.setPreferredSize(new Dimension(marginTools, 15));
+               _strLabel.setHorizontalTextPosition(JLabel.LEFT);
+               _str.setFont(textFieldsFont);
+               _strPanel.setLayout(new BorderLayout());
+               _strPanel.add(_strLabel, BorderLayout.WEST);
+               _strPanel.add(_str, BorderLayout.CENTER);
+
+               _input.setLayout(new GridLayout(2, 0));
+               _input.add(_seqPanel);
+               _input.add(_strPanel);
+
+               JPanel goPanel = new JPanel();
+               goPanel.setLayout(new BorderLayout());
+
+               _tools.setLayout(new BorderLayout());
+               _tools.add(_input, BorderLayout.CENTER);
+               _tools.add(_info, BorderLayout.SOUTH);
+               _tools.add(goPanel, BorderLayout.EAST);
+
+               _deleteButton.addActionListener(new ActionListener() {
+                       public void actionPerformed(ActionEvent e) {
+                               _rnaList.removeSelected();
+                       }
+               });
+               _duplicateButton.addActionListener(new ActionListener() {
+                       public void actionPerformed(ActionEvent e) {
+                                       _rnaList.add((VARNAConfig)vp.getConfig().clone(),vp.getRNA().clone(),vp.getRNA().getName()+"-"+DateFormat.getTimeInstance(DateFormat.LONG).format(new Date()),true); 
+                       }});
+               
+               JPanel ops = new JPanel();
+               ops.setLayout(new GridLayout(1,2));
+               ops.add(_deleteButton);
+               ops.add(_duplicateButton);
+
+               JLabel j = new JLabel("Structures Manager",JLabel.CENTER);
+               _listPanel.setLayout(new BorderLayout());
+               
+               _listPanel.add(ops,BorderLayout.SOUTH);
+               _listPanel.add(j,BorderLayout.NORTH);
+               _listPanel.add(listScroller,BorderLayout.CENTER);
+
+               goPanel.add(_createButton, BorderLayout.CENTER);
+
+               JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,true,_listPanel,vp);
+               getContentPane().setLayout(new BorderLayout());
+               getContentPane().add(split, BorderLayout.CENTER);
+               getContentPane().add(_tools, BorderLayout.NORTH);
+
+               setVisible(true);
+               DropTarget dt = new DropTarget(vp, this);
+               
+               vp.addVARNAListener(this);
+       }
+       */
+       public static String generateDefaultName()
+       {
+               return "User file #"+_nextID++;
+       }
+
+       public RNA getRNA() {
+               return (RNA)_sideList.getSelectedValue();
+       }
+
+
+
+       public String[][] getParameterInfo() {
+               String[][] info = {
+                               // Parameter Name Kind of Value Description,
+                               { "sequenceDBN", "String", "A raw RNA sequence" },
+                               { "structureDBN", "String",
+                                               "An RNA structure in dot bracket notation (DBN)" },
+                               { errorOpt, "boolean", "To show errors" }, };
+               return info;
+       }
+
+       public void init() {
+               vp.setBackground(_backgroundColor);
+               _error = true;
+       }
+
+       @SuppressWarnings("unused")
+       private Color getSafeColor(String col, Color def) {
+               Color result;
+               try {
+                       result = Color.decode(col);
+               } catch (Exception e) {
+                       try {
+                               result = Color.getColor(col, def);
+                       } catch (Exception e2) {
+                               return def;
+                       }
+               }
+               return result;
+       }
+
+       public VARNAPanel get_varnaPanel() {
+               return vp;
+       }
+
+       public void set_varnaPanel(VARNAPanel surface) {
+               vp = surface;
+       }
+
+
+       public String get_seq() {
+               return _seq.getText();
+       }
+
+       public void set_seq(String _seq) {
+               this._seq.setText(_seq);
+       }
+       
+       public String get_str(){
+               return _str.getText();
+       }
+       
+       public void set_str(String _str){
+               this._str.setText(_str);
+       }
+
+       public JLabel get_info() {
+               return _info;
+       }
+
+       public void set_info(JLabel _info) {
+               this._info = _info;
+       }
+
+       /*public static void main(String[] args) {
+               AppVarnaBinding d = new AppVarnaBinding();
+               d.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+               d.pack();
+               d.setVisible(true);
+       }*/
+       
+
+       public void dragEnter(DropTargetDragEvent arg0) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       public void dragExit(DropTargetEvent arg0) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       public void dragOver(DropTargetDragEvent arg0) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       public void drop(DropTargetDropEvent dtde) {
+           try {
+               Transferable tr = dtde.getTransferable();
+               DataFlavor[] flavors = tr.getTransferDataFlavors();
+               for (int i = 0; i < flavors.length; i++) {
+           if (flavors[i].isFlavorJavaFileListType()) {
+             dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
+             Object ob = tr.getTransferData(flavors[i]);
+             if (ob instanceof List)
+             {
+                 List list = (List) ob;
+                 for (int j = 0; j < list.size(); j++) {
+                 Object o = list.get(j);
+                 
+                 if (dtde.getSource() instanceof DropTarget)
+                 {
+                         DropTarget dt = (DropTarget) dtde.getSource();
+                         Component c = dt.getComponent();
+                         if (c instanceof VARNAPanel)
+                         {
+                                         String path = o.toString();
+                                 VARNAPanel vp = (VARNAPanel) c;
+                                         try{
+                                 FullBackup bck =  VARNAPanel.importSession(path);
+                                 _rnaList.add(bck.config, bck.rna,bck.name,true);
+                                         }
+                                         catch (ExceptionLoadingFailed e3)
+                                         {
+                                                 RNA r = new RNA();
+                                                 r.loadSecStr(path);
+                                                 r.drawRNA(vp.getConfig());
+                                                 String name =r.getName();
+                                                 if (name.equals(""))
+                                                 { 
+                                                         name = path.substring(path.lastIndexOf(File.separatorChar)+1);
+                                                 }
+                                                 _rnaList.add(vp.getConfig().clone(),r,name,true);
+                                         }                                       
+                         }
+                 }
+                 }
+             }
+             // If we made it this far, everything worked.
+             dtde.dropComplete(true);
+             return;
+           }
+               }
+               // Hmm, the user must not have dropped a file list
+               dtde.rejectDrop();
+             } catch (Exception e) {
+               e.printStackTrace();
+               dtde.rejectDrop();
+             }
+               
+       }
+
+       public void dropActionChanged(DropTargetDragEvent arg0) {
+       }
+
+       private class BackupHolder{
+               private DefaultListModel _rnaList;
+               private ArrayList<RNA> _rnas = new ArrayList<RNA>();
+               JList _l;
+               
+               public BackupHolder(DefaultListModel rnaList, JList l)
+               {
+                       _rnaList = rnaList;
+                       _l = l;
+               }
+               
+               public void add(VARNAConfig c, RNA r)
+               {
+                       add(c, r, r.getName(),false);
+               }
+
+               public void add(VARNAConfig c, RNA r,boolean select)
+               {
+                       add(c, r, r.getName(),select);
+               }
+
+               public void add(VARNAConfig c, RNA r, String name)
+               {
+                       add(c, r, name,false);                  
+               }
+               public void add(VARNAConfig c, RNA r, String name, boolean select)
+               {
+                       if (select){
+                               _l.removeSelectionInterval(0, _rnaList.size());
+                       }
+                       if (name.equals(""))
+                       {
+                               name = generateDefaultName();
+                       }
+                       FullBackup bck = new FullBackup(c,r,name);
+                       _rnas.add(0, r);
+                       _rnaList.add(0,bck);
+                       if (select){
+                         _l.setSelectedIndex(0);
+                       }
+               }
+
+               public void remove(int i)
+               {
+                       _rnas.remove(i);
+                       _rnaList.remove(i);
+                       
+               }
+               public DefaultListModel getModel()
+               {
+                       return _rnaList;
+               }
+               public boolean contains(RNA r)
+               {
+                       return _rnas.contains(r);
+               }
+               /*public int getSize()
+               {
+                       return _rnaList.getSize();
+               }*/
+               public FullBackup getElementAt(int i)
+               {
+                       return (FullBackup) _rnaList.getElementAt(i);
+               }
+               
+               public void removeSelected()
+               {
+                       int i = _l.getSelectedIndex();
+                       if (i!=-1)
+                       {
+                         if (_rnaList.getSize()==1)
+                         {
+                                 RNA r = new RNA();
+                                 try {
+                                       r.setRNA(" ", ".");
+                                 } catch (ExceptionUnmatchedClosingParentheses e1) {
+                                 } catch (ExceptionFileFormatOrSyntax e1) {
+                                 }
+                                 vp.showRNA(r);
+                                 vp.repaint();
+                         }
+                         else
+                         {  
+                                int newi = i+1;
+                                if (newi==_rnaList.getSize())
+                                {
+                                        newi = _rnaList.getSize()-2;
+                                }
+                                FullBackup bck = (FullBackup) _rnaList.getElementAt(newi);
+                                _l.setSelectedValue(bck,true);
+                         }
+                         _rnaList.remove(i);
+                       }
+
+               }
+       }
+
+       public void onLayoutChanged() {
+               // TODO Auto-generated method stub
+               
+       }
+
+       public void onUINewStructure(VARNAConfig v, RNA r) {
+               _rnaList.add(v, r,"",true);
+       }
+
+       public void onWarningEmitted(String s) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       public void mouseClicked(MouseEvent e) {
+                          if(e.getClickCount() == 2){
+                            int index = _sideList.locationToIndex(e.getPoint());
+                            ListModel dlm = _sideList.getModel();
+                            FullBackup item = (FullBackup) dlm.getElementAt(index);;
+                            _sideList.ensureIndexIsVisible(index);
+                            /*TODO Object newName = JOptionPane.showInputDialog(
+                                           this,
+                                           "Specify a new name for this RNA",
+                                           "Rename RNA", 
+                                           JOptionPane.QUESTION_MESSAGE,
+                                           (Icon)null,
+                                           null,
+                                           item.toString());
+                            if (newName!=null)
+                            {
+                                item.name = newName.toString();
+                                this._sideList.repaint();
+                            }*/
+                            }
+       }
+
+       public void mouseEntered(MouseEvent arg0) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       public void mouseExited(MouseEvent arg0) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       public void mousePressed(MouseEvent arg0) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       public void mouseReleased(MouseEvent arg0) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       @Override
+       public Color getColour(int atomIndex, int pdbResNum, String chain,
+                       String pdbId) {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public String[] getPdbFile() {
+               // TODO Auto-generated method stub
+               return null;
+       }
+
+       @Override
+       public void highlightAtom(int atomIndex, int pdbResNum, String chain,
+                       String pdbId) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       @Override
+       public void mouseOverStructure(int atomIndex, String strInfo) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       @Override
+       public void releaseReferences(Object svl) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       @Override
+       public void updateColours(Object source) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       @Override
+       public void componentHidden(ComponentEvent e) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       @Override
+       public void componentMoved(ComponentEvent e) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       @Override
+       public void componentResized(ComponentEvent e) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       @Override
+       public void componentShown(ComponentEvent e) {
+               // TODO Auto-generated method stub
+               
+       }
+
+  @Override
+  public void onStructureRedrawn()
+  {
+    // TODO Auto-generated method stub
+    
+  }
+}
+
+
+/*
+       public static void main(String[] args)
+       {
+               JTextField str = new JTextField("ATGC");
+               
+               AppVarnaBinding vab = new AppVarnaBinding();
+               vab.varnagui.set_seq(str);
+               vab.varnagui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+               vab.varnagui.pack();
+               vab.varnagui.setVisible(true);  
+       }
+}
+*/
\ No newline at end of file
index 2a72e44..c19fbf2 100644 (file)
@@ -1060,7 +1060,7 @@ public class Desktop extends jalview.jbgui.GDesktop implements
     }
     // TODO: update this text for each release or centrally store it for lite
     // and application
-    message.append("\nAuthors:  Jim Procter, Andrew Waterhouse, Michele Clamp, James Cuff, Steve Searle,\n    David Martin & Geoff Barton."
+    message.append("\nAuthors:  Jim Procter, Jan Engelhardt, Lauren Lui, Andrew Waterhouse, Michele Clamp, James Cuff, Steve Searle,\n    David Martin & Geoff Barton."
             + "\nDevelopment managed by The Barton Group, University of Dundee, Scotland, UK.\n"
             + "\nFor help, see the FAQ at www.jalview.org and/or join the jalview-discuss@jalview.org mailing list\n"
             + "\nIf  you use Jalview, please cite:"
diff --git a/src/jalview/gui/RNAHelicesColourChooser.java b/src/jalview/gui/RNAHelicesColourChooser.java
new file mode 100644 (file)
index 0000000..3354735
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package jalview.gui;
+
+import java.util.*;
+import java.awt.event.*;
+
+import jalview.datamodel.*;
+import jalview.schemes.*;
+
+/**
+ * Helps generate the colors for RNA secondary structure. Future: add option to
+ * change colors based on covariation.
+ * 
+ * @author Lauren Michelle Lui
+ * 
+ */
+public class RNAHelicesColourChooser
+{
+
+  AlignViewport av;
+
+  AlignmentPanel ap;
+
+  ColourSchemeI oldcs;
+
+  Hashtable oldgroupColours;
+
+  jalview.datamodel.AlignmentAnnotation currentAnnotation;
+
+  boolean adjusting = false;
+
+  public RNAHelicesColourChooser(AlignViewport av, final AlignmentPanel ap)
+  {
+    oldcs = av.getGlobalColourScheme();
+    if (av.alignment.getGroups() != null)
+    {
+      oldgroupColours = new Hashtable();
+      Vector allGroups = ap.av.alignment.getGroups();
+      SequenceGroup sg;
+      for (int g = 0; g < allGroups.size(); g++)
+      {
+        sg = (SequenceGroup) allGroups.get(g);
+        if (sg.cs != null)
+        {
+          oldgroupColours.put(sg, sg.cs);
+        }
+      }
+    }
+    this.av = av;
+    this.ap = ap;
+
+    if (oldcs instanceof RNAHelicesColour)
+    {
+      RNAHelicesColour rhc = (RNAHelicesColour) oldcs;
+
+    }
+
+    adjusting = true;
+    Vector list = new Vector();
+    int index = 1;
+    for (int i = 0; i < av.alignment.getAlignmentAnnotation().length; i++)
+    {
+      String label = av.alignment.getAlignmentAnnotation()[i].label;
+      if (!list.contains(label))
+        list.addElement(label);
+      else
+        list.addElement(label + "_" + (index++));
+    }
+
+    adjusting = false;
+
+    changeColour();
+
+  }
+
+  void changeColour()
+  {
+    // Check if combobox is still adjusting
+    if (adjusting)
+    {
+      return;
+    }
+
+    currentAnnotation = av.alignment.getAlignmentAnnotation()[0];// annotations.getSelectedIndex()];
+
+    RNAHelicesColour rhc = null;
+
+    rhc = new RNAHelicesColour(currentAnnotation);
+
+    av.setGlobalColourScheme(rhc);
+
+    if (av.alignment.getGroups() != null)
+    {
+      Vector allGroups = ap.av.alignment.getGroups();
+      SequenceGroup sg;
+      for (int g = 0; g < allGroups.size(); g++)
+      {
+        sg = (SequenceGroup) allGroups.get(g);
+
+        if (sg.cs == null)
+        {
+          continue;
+        }
+
+        sg.cs = new RNAHelicesColour(currentAnnotation);
+
+      }
+    }
+
+    ap.paintAlignment(false);
+  }
+
+  void reset()
+  {
+    av.setGlobalColourScheme(oldcs);
+    if (av.alignment.getGroups() != null)
+    {
+      Vector allGroups = ap.av.alignment.getGroups();
+      SequenceGroup sg;
+      for (int g = 0; g < allGroups.size(); g++)
+      {
+        sg = (SequenceGroup) allGroups.get(g);
+        sg.cs = (ColourSchemeI) oldgroupColours.get(sg);
+      }
+    }
+  }
+
+  public void annotations_actionPerformed(ActionEvent e)
+  {
+    changeColour();
+  }
+
+}
index ca5d7f7..a84d454 100644 (file)
@@ -470,7 +470,7 @@ public class SeqPanel extends JPanel implements MouseListener,
     groupEditing = group;
     startseq = seqCanvas.cursorY;
     lastres = seqCanvas.cursorX;
-    editSequence(true, seqCanvas.cursorX + getKeyboardNo1());
+    editSequence(true, false, seqCanvas.cursorX + getKeyboardNo1());
     endEditing();
   }
 
@@ -479,9 +479,17 @@ public class SeqPanel extends JPanel implements MouseListener,
     groupEditing = group;
     startseq = seqCanvas.cursorY;
     lastres = seqCanvas.cursorX + getKeyboardNo1();
-    editSequence(false, seqCanvas.cursorX);
+    editSequence(false, false, seqCanvas.cursorX);
     endEditing();
   }
+  
+  void insertNucAtCursor(boolean group,String nuc){
+         groupEditing = group;
+           startseq = seqCanvas.cursorY;
+           lastres = seqCanvas.cursorX;
+           editSequence(false, true, seqCanvas.cursorX + getKeyboardNo1());
+           endEditing();
+  }
 
   void numberPressed(char value)
   {
@@ -1013,11 +1021,11 @@ public class SeqPanel extends JPanel implements MouseListener,
     if ((res < av.getAlignment().getWidth()) && (res < lastres))
     {
       // dragLeft, delete gap
-      editSequence(false, res);
+      editSequence(false, false,res);
     }
     else
     {
-      editSequence(true, res);
+      editSequence(true, false,res);
     }
 
     mouseDragging = true;
@@ -1027,7 +1035,8 @@ public class SeqPanel extends JPanel implements MouseListener,
     }
   }
 
-  synchronized void editSequence(boolean insertGap, int startres)
+  //TODO: Make it more clever than many booleans
+  synchronized void editSequence(boolean insertGap, boolean editSeq, int startres)
   {
     int fixedLeft = -1;
     int fixedRight = -1;
@@ -1312,10 +1321,11 @@ public class SeqPanel extends JPanel implements MouseListener,
         {
           editCommand.appendEdit(EditCommand.INSERT_GAP, new SequenceI[]
           { seq }, lastres, startres - lastres, av.alignment, true);
-        }
+         }
       }
       else
       {
+       if(!editSeq){
         // dragging to the left
         if (fixedColumns && fixedRight != -1)
         {
@@ -1349,6 +1359,21 @@ public class SeqPanel extends JPanel implements MouseListener,
             { seq }, startres, max, av.alignment, true);
           }
         }
+       }else{//insertGap==false AND editSeq==TRUE;
+               if (fixedColumns && fixedRight != -1)
+            {
+              for (int j = lastres; j < startres; j++)
+              {
+                insertChar(j, new SequenceI[]
+                { seq }, fixedRight);
+              }
+              }
+            else
+            {
+              editCommand.appendEdit(EditCommand.INSERT_NUC, new SequenceI[]
+              { seq }, lastres, startres - lastres, av.alignment, true);
+             }
+       }
       }
     }
 
index ad834be..6824eda 100755 (executable)
@@ -127,7 +127,17 @@ public abstract class AlignFile extends FileParse
     addProperties(al);
     for (int i = 0; i < annotations.size(); i++)
     {
-      al.addAnnotation((AlignmentAnnotation) annotations.elementAt(i));
+      // detect if annotations.elementAt(i) rna secondary structure
+      // if so then do:
+      /*
+       * SequenceFeature[] pairArray =
+       * Rna.GetBasePairsFromAlignmentAnnotation(annotations.elementAt(i));
+       * Rna.HelixMap(pairArray);
+       */
+      AlignmentAnnotation an = (AlignmentAnnotation) annotations
+              .elementAt(i);
+      an.validateRangeAndDisplay();
+      al.addAnnotation(an);
     }
 
   }
index 69926b5..3b73f32 100755 (executable)
@@ -1018,7 +1018,7 @@ public class AnnotationFile
         }\r
       }\r
       if (hasSymbols\r
-              && (token.equals("H") || token.equals("E") || token\r
+              && (token.equals("H") || token.equals("E") || token.equals("S") || token\r
                       .equals(" ")))\r
       {\r
         // Either this character represents a helix or sheet\r
index 635c801..dd3cced 100755 (executable)
@@ -67,7 +67,7 @@ public class AppletFormatAdapter
    */
   public static final String[] READABLE_EXTENSIONS = new String[]
   { "fa, fasta, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa", "jar",
-      "sto" }; // ,
+      "sto,stk" }; // ,
 
   // ".blast"
   // };
index 7f0bab1..0281839 100755 (executable)
@@ -80,12 +80,11 @@ public class JalviewFileChooser extends JFileChooser
     // SelectAllFilter needs to be set first before adding further
     // file filters to fix bug on Mac OSX
     setAcceptAllFileFilterUsed(selectAll);
-
+    
     for (int i = 0; i < suffix.length; i++)
     {
       JalviewFileFilter jvf = new JalviewFileFilter(suffix[i], desc[i]);
       addChoosableFileFilter(jvf);
-
       if ((selected != null) && selected.equalsIgnoreCase(desc[i]))
       {
         chosen = jvf;
index 1625241..840041d 100644 (file)
@@ -25,6 +25,7 @@ import java.util.*;
 \r
 import com.stevesoft.pat.*;\r
 import jalview.datamodel.*;\r
+import jalview.analysis.Rna;\r
 \r
 // import org.apache.log4j.*;\r
 \r
@@ -82,6 +83,9 @@ public class StockholmFile extends AlignFile
     Hashtable seqs = new Hashtable();\r
     Regex p, r, rend, s, x;\r
 \r
+    // Temporary line for processing RNA annotation\r
+    // String RNAannot = "";\r
+\r
     // ------------------ Parsing File ----------------------\r
     // First, we have to check that this file has STOCKHOLM format, i.e. the\r
     // first line must match\r
@@ -105,11 +109,20 @@ public class StockholmFile extends AlignFile
     r = new Regex("#=(G[FSRC]?)\\s+(.*)"); // Finds any annotation line\r
     x = new Regex("(\\S+)\\s+(\\S+)"); // split id from sequence\r
 \r
+    // Convert all bracket types to parentheses (necessary for passing to VARNA)\r
+    Regex openparen = new Regex("(<|\\[)", "(");\r
+    Regex closeparen = new Regex("(>|\\])", ")");\r
+\r
+    // Detect if file is RNA by looking for bracket types\r
+    Regex detectbrackets = new Regex("(<|>|\\[|\\]|\\(|\\))");\r
+\r
     rend.optimize();\r
     p.optimize();\r
     s.optimize();\r
     r.optimize();\r
     x.optimize();\r
+    openparen.optimize();\r
+    closeparen.optimize();\r
 \r
     while ((line = nextLine()) != null)\r
     {\r
@@ -136,12 +149,16 @@ public class StockholmFile extends AlignFile
           int start = 1;\r
           int end = -1;\r
           String sid = acc;\r
-          // Retrieve hash of annotations for this accession\r
+          /*\r
+           * Retrieve hash of annotations for this accession\r
+           * Associate Annotation with accession\r
+           */\r
           Hashtable accAnnotations = null;\r
 \r
           if (seqAnn != null && seqAnn.containsKey(acc))\r
           {\r
             accAnnotations = (Hashtable) seqAnn.remove(acc);\r
+            //TODO: add structures to sequence\r
           }\r
 \r
           // Split accession in id and from/to\r
@@ -171,7 +188,19 @@ public class StockholmFile extends AlignFile
               jalview.util.DBRefUtils.parseToDbRef(seqO, src, "0", acn);\r
               // seqO.addDBRef(dbref);\r
             }\r
+          }        \r
+          if (accAnnotations != null && accAnnotations.containsKey("SS"))\r
+          {\r
+                 Vector v = (Vector) accAnnotations.get("SS");\r
+                 \r
+                 for (int i = 0; i < v.size(); i++)\r
+                   {\r
+                         AlignmentAnnotation an = (AlignmentAnnotation) v.elementAt(i);\r
+                         seqO.addAlignmentAnnotation(an);\r
+                         //annotations.add(an);\r
+                   }\r
           }\r
+        \r
           Hashtable features = null;\r
           // We need to adjust the positions of all features to account for gaps\r
           try\r
@@ -413,7 +442,7 @@ public class StockholmFile extends AlignFile
               ann = new Hashtable();\r
               seqAnn.put(acc, ann);\r
             }\r
-\r
+            //TODO test structure, call parseAnnotationRow with vector from hashtable for specific sequence\r
             Hashtable features;\r
             // Get an object with all the content for an annotation\r
             if (ann.containsKey("features"))\r
@@ -448,6 +477,24 @@ public class StockholmFile extends AlignFile
             }\r
             ns += seq;\r
             content.put(description, ns);\r
+
+            if(type.equals("SS")){\r
+                Hashtable strucAnn;\r
+                if (seqAnn.containsKey(acc))\r
+                {\r
+                  strucAnn = (Hashtable) seqAnn.get(acc);\r
+                }\r
+                else\r
+                {\r
+                  strucAnn = new Hashtable();\r
+                }\r
+                \r
+                Vector newStruc=new Vector();\r
+                parseAnnotationRow(newStruc, type,ns);\r
+                \r
+                strucAnn.put(type, newStruc);\r
+                seqAnn.put(acc, strucAnn);\r
+             }\r
           }\r
           else\r
           {\r
@@ -477,6 +524,19 @@ public class StockholmFile extends AlignFile
   private AlignmentAnnotation parseAnnotationRow(Vector annotation,\r
           String label, String annots)\r
   {\r
+    String convert1, convert2 = null;\r
+\r
+    // Convert all bracket types to parentheses\r
+    Regex openparen = new Regex("(<|\\[)", "(");\r
+    Regex closeparen = new Regex("(>|\\])", ")");\r
+\r
+    // Detect if file is RNA by looking for bracket types\r
+    Regex detectbrackets = new Regex("(<|>|\\[|\\]|\\(|\\))");\r
+\r
+    convert1 = openparen.replaceAll(annots);\r
+    convert2 = closeparen.replaceAll(convert1);\r
+    annots = convert2;\r
+\r
     String type = (label.indexOf("_cons") == label.length() - 5) ? label\r
             .substring(0, label.length() - 5) : label;\r
     boolean ss = false;\r
@@ -495,8 +555,17 @@ public class StockholmFile extends AlignFile
       // be written out\r
       if (ss)\r
       {\r
-        ann.secondaryStructure = jalview.schemes.ResidueProperties\r
-                .getDssp3state(pos).charAt(0);\r
+        if (detectbrackets.search(pos))\r
+        {\r
+          ann.secondaryStructure = jalview.schemes.ResidueProperties\r
+                  .getRNASecStrucState(pos).charAt(0);\r
+        }\r
+        else\r
+        {\r
+          ann.secondaryStructure = jalview.schemes.ResidueProperties\r
+                  .getDssp3state(pos).charAt(0);\r
+        }\r
+\r
         if (ann.secondaryStructure == pos.charAt(0) || pos.charAt(0) == 'C')\r
         {\r
           ann.displayCharacter = ""; // null; // " ";\r
@@ -531,6 +600,7 @@ public class StockholmFile extends AlignFile
               annot.annotations.length);\r
       System.arraycopy(els, 0, anns, annot.annotations.length, els.length);\r
       annot.annotations = anns;\r
+      //System.out.println("else: ");\r
     }\r
     return annot;\r
   }\r
@@ -580,4 +650,38 @@ public class StockholmFile extends AlignFile
             + id);\r
     return id;\r
   }\r
+  /**\r
+   * //ssline is complete secondary structure line private AlignmentAnnotation\r
+   * addHelices(Vector annotation, String label, String ssline) {\r
+   * \r
+   * // decide on secondary structure or not. Annotation[] els = new\r
+   * Annotation[ssline.length()]; for (int i = 0; i < ssline.length(); i++) {\r
+   * String pos = ssline.substring(i, i + 1); Annotation ann; ann = new\r
+   * Annotation(pos, "", ' ', 0f); // 0f is 'valid' null - will not\r
+   * \r
+   * ann.secondaryStructure =\r
+   * jalview.schemes.ResidueProperties.getRNAssState(pos).charAt(0);\r
+   * \r
+   * ann.displayCharacter = "x" + ann.displayCharacter;\r
+   * \r
+   * System.out.println(ann.displayCharacter);\r
+   * \r
+   * els[i] = ann; } AlignmentAnnotation helicesAnnot = null; Enumeration e =\r
+   * annotation.elements(); while (e.hasMoreElements()) { helicesAnnot =\r
+   * (AlignmentAnnotation) e.nextElement(); if (helicesAnnot.label.equals(type))\r
+   * break; helicesAnnot = null; } if (helicesAnnot == null) { helicesAnnot =\r
+   * new AlignmentAnnotation(type, type, els);\r
+   * annotation.addElement(helicesAnnot); } else { Annotation[] anns = new\r
+   * Annotation[helicesAnnot.annotations.length + els.length];\r
+   * System.arraycopy(helicesAnnot.annotations, 0, anns, 0,\r
+   * helicesAnnot.annotations.length); System.arraycopy(els, 0, anns,\r
+   * helicesAnnot.annotations.length, els.length); helicesAnnot.annotations =\r
+   * anns; }\r
+   * \r
+   * helicesAnnot.features = Rna.GetBasePairs(ssline);\r
+   * Rna.HelixMap(helicesAnnot.features);\r
+   * \r
+   * \r
+   * return helicesAnnot; }\r
+   */\r
 }\r
index 6253e36..4f60de3 100755 (executable)
@@ -113,6 +113,13 @@ public class GAlignFrame extends JInternalFrame
 
   protected JRadioButtonMenuItem BLOSUM62Colour = new JRadioButtonMenuItem();
 
+  protected JRadioButtonMenuItem nucleotideColour = new JRadioButtonMenuItem();
+
+  protected JRadioButtonMenuItem purinePyrimidineColour = new JRadioButtonMenuItem();
+
+  // protected JRadioButtonMenuItem covariationColour = new
+  // JRadioButtonMenuItem();
+
   JMenuItem njTreeBlosumMenuItem = new JMenuItem();
 
   JMenuItem avDistanceTreeBlosumMenuItem = new JMenuItem();
@@ -149,8 +156,6 @@ public class GAlignFrame extends JInternalFrame
 
   public JCheckBoxMenuItem showSeqFeaturesHeight = new JCheckBoxMenuItem();
 
-  protected JRadioButtonMenuItem nucleotideColour = new JRadioButtonMenuItem();
-
   JMenuItem deleteGroups = new JMenuItem();
 
   JMenuItem delete = new JMenuItem();
@@ -217,6 +222,8 @@ public class GAlignFrame extends JInternalFrame
 
   JMenuItem annotationColour = new JMenuItem();
 
+  JMenuItem rnahelicesColour = new JMenuItem();
+
   JMenuItem associatedData = new JMenuItem();
 
   protected JCheckBoxMenuItem autoCalculate = new JCheckBoxMenuItem();
@@ -417,6 +424,8 @@ public class GAlignFrame extends JInternalFrame
     colours.add(PIDColour);
     colours.add(BLOSUM62Colour);
     colours.add(nucleotideColour);
+    colours.add(purinePyrimidineColour);
+    // colours.add(covariationColour);
 
     setColourSelected(jalview.bin.Cache
             .getDefault("DEFAULT_COLOUR", "None"));
@@ -487,6 +496,16 @@ public class GAlignFrame extends JInternalFrame
 
         break;
 
+      case ColourSchemeProperty.PURINEPYRIMIDINE:
+        purinePyrimidineColour.setSelected(true);
+
+        break;
+      /*
+       * case ColourSchemeProperty.COVARIATION:
+       * covariationColour.setSelected(true);
+       * 
+       * break;
+       */
       case ColourSchemeProperty.USER_DEFINED:
         userDefinedColour.setSelected(true);
 
@@ -850,6 +869,31 @@ public class GAlignFrame extends JInternalFrame
         BLOSUM62Colour_actionPerformed(e);
       }
     });
+    nucleotideColour.setText("Nucleotide");
+    nucleotideColour.addActionListener(new java.awt.event.ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        nucleotideColour_actionPerformed(e);
+      }
+    });
+
+    purinePyrimidineColour.setText("Purine/Pyrimidine");
+    purinePyrimidineColour
+            .addActionListener(new java.awt.event.ActionListener()
+            {
+              public void actionPerformed(ActionEvent e)
+              {
+                purinePyrimidineColour_actionPerformed(e);
+              }
+            });
+    /*
+     * covariationColour.setText("Covariation");
+     * covariationColour.addActionListener(new java.awt.event.ActionListener() {
+     * public void actionPerformed(ActionEvent e) {
+     * covariationColour_actionPerformed(e); } });
+     */
+
     avDistanceTreeBlosumMenuItem.setText("Average Distance Using BLOSUM62");
     avDistanceTreeBlosumMenuItem
             .addActionListener(new java.awt.event.ActionListener()
@@ -1389,6 +1433,16 @@ public class GAlignFrame extends JInternalFrame
         annotationColour_actionPerformed(e);
       }
     });
+
+    rnahelicesColour.setText("By RNA helices");
+    rnahelicesColour.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        rnahelicesColour_actionPerformed(e);
+      }
+    });
+
     associatedData.setText("Load Features / Annotations");
     associatedData.addActionListener(new ActionListener()
     {
@@ -1760,6 +1814,8 @@ public class GAlignFrame extends JInternalFrame
     colourMenu.add(turnColour);
     colourMenu.add(buriedColour);
     colourMenu.add(nucleotideColour);
+    colourMenu.add(purinePyrimidineColour);
+    // colourMenu.add(covariationColour);
     colourMenu.add(userDefinedColour);
     colourMenu.addSeparator();
     colourMenu.add(conservationMenuItem);
@@ -1767,6 +1823,7 @@ public class GAlignFrame extends JInternalFrame
     colourMenu.add(abovePIDThreshold);
     colourMenu.add(modifyPID);
     colourMenu.add(annotationColour);
+    colourMenu.add(rnahelicesColour);
     calculateMenu.add(sort);
     calculateMenu.add(calculateTree);
     calculateMenu.addSeparator();
@@ -2141,6 +2198,14 @@ public class GAlignFrame extends JInternalFrame
   {
   }
 
+  protected void purinePyrimidineColour_actionPerformed(ActionEvent e)
+  {
+  }
+
+  /*
+   * protected void covariationColour_actionPerformed(ActionEvent e) { }
+   */
+
   protected void noColourmenuItem_actionPerformed(ActionEvent e)
   {
   }
@@ -2293,6 +2358,11 @@ public class GAlignFrame extends JInternalFrame
 
   }
 
+  public void rnahelicesColour_actionPerformed(ActionEvent e)
+  {
+
+  }
+
   public void associatedData_actionPerformed(ActionEvent e)
   {
 
diff --git a/src/jalview/jbgui/GRnaStructureViewer.java b/src/jalview/jbgui/GRnaStructureViewer.java
new file mode 100644 (file)
index 0000000..efe6eb0
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package jalview.jbgui;
+
+import javax.swing.*;
+import java.awt.event.ActionListener;
+import java.awt.event.ActionEvent;
+
+public class GRnaStructureViewer extends JInternalFrame
+{
+  public GRnaStructureViewer()
+  {
+    try
+    {
+      jbInit();
+    } catch (Exception ex)
+    {
+      ex.printStackTrace();
+    }
+  }
+
+  private void jbInit() throws Exception
+  {
+   
+  }
+  
+}
index 28d2c7a..b7a91e2 100644 (file)
@@ -164,6 +164,15 @@ public class GStructureViewer extends JInternalFrame
         buriedColour_actionPerformed(actionEvent);
       }
     });
+    purinePyrimidineColour.setText("Purine/Pyrimidine");
+    purinePyrimidineColour.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent actionEvent)
+      {
+         purinePyrimidineColour_actionPerformed(actionEvent);
+      }
+    });
+    
     userColour.setText("User Defined ...");
     userColour.addActionListener(new ActionListener()
     {
@@ -224,6 +233,7 @@ public class GStructureViewer extends JInternalFrame
     colourMenu.add(strandColour);
     colourMenu.add(turnColour);
     colourMenu.add(buriedColour);
+    colourMenu.add(purinePyrimidineColour);
     colourMenu.add(userColour);
     colourMenu.add(jmolColour);
     colourMenu.add(backGround);
@@ -300,6 +310,9 @@ public class GStructureViewer extends JInternalFrame
   protected JRadioButtonMenuItem turnColour = new JRadioButtonMenuItem();
 
   protected JRadioButtonMenuItem buriedColour = new JRadioButtonMenuItem();
+  
+  protected JRadioButtonMenuItem purinePyrimidineColour = new JRadioButtonMenuItem();
+  
 
   protected JRadioButtonMenuItem userColour = new JRadioButtonMenuItem();
 
@@ -380,6 +393,11 @@ public class GStructureViewer extends JInternalFrame
   {
 
   }
+  
+  public void purinePyrimidineColour_actionPerformed(ActionEvent actionEvent)
+  {
+
+  }
 
   public void userColour_actionPerformed(ActionEvent actionEvent)
   {
index 0f758e0..e7c7935 100755 (executable)
@@ -153,6 +153,14 @@ public class ColourSchemeProperty
     {
       ret = NONE;
     }
+    else if (name.equalsIgnoreCase("Purine/Pyrimidine"))
+    {
+      ret = PURINEPYRIMIDINE;
+    }
+    // else if (name.equalsIgnoreCase("Covariation"))
+    // {
+    // ret = COVARIATION;
+    // }
 
     return ret;
   }
@@ -214,6 +222,13 @@ public class ColourSchemeProperty
     {
       index = NUCLEOTIDE;
     }
+    else if (cs instanceof PurinePyrimidineColourScheme)
+    {
+      index = PURINEPYRIMIDINE;
+    }
+    /*
+     * else if (cs instanceof CovariationColourScheme) { index = COVARIATION; }
+     */
     else if (cs instanceof UserColourScheme)
     {
       if ((((UserColourScheme) cs).getName() != null)
@@ -296,6 +311,16 @@ public class ColourSchemeProperty
 
       break;
 
+    case PURINEPYRIMIDINE:
+      ret = "Purine/Pyrimidine";
+
+      break;
+
+    /*
+     * case COVARIATION: ret = "Covariation";
+     * 
+     * break;
+     */
     case USER_DEFINED:
       ret = "User Defined";
 
@@ -447,6 +472,16 @@ public class ColourSchemeProperty
 
       break;
 
+    case PURINEPYRIMIDINE:
+      cs = new PurinePyrimidineColourScheme();
+
+      break;
+
+    // case COVARIATION:
+    // cs = new CovariationColourScheme(annotation);
+
+    // break;
+
     case USER_DEFINED:
       Color[] col = new Color[24];
       for (int i = 0; i < 24; i++)
diff --git a/src/jalview/schemes/CovariationColourScheme.java b/src/jalview/schemes/CovariationColourScheme.java
new file mode 100644 (file)
index 0000000..fe533ed
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package jalview.schemes;
+
+import java.awt.*;
+import java.util.Hashtable;
+
+import jalview.datamodel.AlignmentAnnotation;
+
+/**
+ * Became RNAHelicesColour.java. Placeholder for true covariation color scheme
+ * 
+ * @author Lauren Michelle Lui
+ * @version 2.5
+ */
+public class CovariationColourScheme extends ResidueColourScheme
+{
+  public Hashtable helixcolorhash = new Hashtable();
+
+  public Hashtable positionsToHelix = new Hashtable();
+
+  int numHelix = 0;
+
+  public AlignmentAnnotation annotation;
+
+  /**
+   * Creates a new CovariationColourScheme object.
+   */
+  public CovariationColourScheme(AlignmentAnnotation annotation)
+  {
+    this.annotation = annotation;
+
+    for (int x = 0; x < this.annotation._rnasecstr.length; x++)
+    {
+      // System.out.println(this.annotation._rnasecstr[x] + " Begin" +
+      // this.annotation._rnasecstr[x].getBegin());
+      // System.out.println(this.annotation._rnasecstr[x].getFeatureGroup());
+      // pairs.put(this.annotation._rnasecstr[x].getBegin(),
+      // this.annotation._rnasecstr[x].getEnd());
+
+      positionsToHelix.put(this.annotation._rnasecstr[x].getBegin(),
+              this.annotation._rnasecstr[x].getFeatureGroup());
+      positionsToHelix.put(this.annotation._rnasecstr[x].getEnd(),
+              this.annotation._rnasecstr[x].getFeatureGroup());
+
+      if (Integer.parseInt(this.annotation._rnasecstr[x].getFeatureGroup()) > numHelix)
+      {
+        numHelix = Integer.parseInt(this.annotation._rnasecstr[x]
+                .getFeatureGroup());
+      }
+
+    }
+
+    for (int j = 0; j <= numHelix; j++)
+    {
+      helixcolorhash.put(Integer.toString(j), jalview.util.ColorUtils
+              .generateRandomColor(Color.white));
+    }
+
+  }
+
+  /**
+   * DOCUMENT ME!
+   * 
+   * @param n
+   *          DOCUMENT ME!
+   * 
+   * @return DOCUMENT ME!
+   */
+  public Color findColour(char c)
+  {
+    // System.out.println("called"); log.debug
+    // Generate a random pastel color
+
+    return ResidueProperties.purinepyrimidine[ResidueProperties.purinepyrimidineIndex[c]];// jalview.util.ColorUtils.generateRandomColor(Color.white);
+  }
+
+  /**
+   * DOCUMENT ME!
+   * 
+   * @param n
+   *          DOCUMENT ME!
+   * @param j
+   *          DOCUMENT ME!
+   * 
+   * @return DOCUMENT ME!
+   */
+  public Color findColour(char c, int j)
+  {
+    Color currentColour = Color.white;
+    String currentHelix = null;
+    // System.out.println(c + " " + j);
+    currentHelix = (String) positionsToHelix.get(j);
+    // System.out.println(positionsToHelix.get(j));
+
+    if (currentHelix != null)
+    {
+      currentColour = (Color) helixcolorhash.get(currentHelix);
+    }
+
+    // System.out.println(c + " " + j + " helix " + currentHelix + " " +
+    // currentColour);
+    return currentColour;
+  }
+
+}
diff --git a/src/jalview/schemes/PurinePyrimidineColourScheme.java b/src/jalview/schemes/PurinePyrimidineColourScheme.java
new file mode 100644 (file)
index 0000000..7b0a622
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package jalview.schemes;
+
+import java.awt.*;
+
+/**
+ * Class is based off of NucleotideColourScheme
+ * 
+ * @author Lauren Michelle Lui
+ */
+public class PurinePyrimidineColourScheme extends ResidueColourScheme
+{
+  /**
+   * Creates a new PurinePyrimidineColourScheme object.
+   */
+  public PurinePyrimidineColourScheme()
+  {
+    super(ResidueProperties.purinepyrimidine, 0);
+  }
+
+  /**
+   * Finds the corresponding color for the type of character inputed
+   * 
+   * @param c
+   *          Character in sequence
+   * 
+   * @return Color from purinepyrimidineIndex in
+   *         jalview.schemes.ResidueProperties
+   */
+  public Color findColour(char c)
+  {
+    return colors[ResidueProperties.purinepyrimidineIndex[c]];
+  }
+
+  /**
+   * Returns color based on conservation
+   * 
+   * @param c
+   *          Character in sequence
+   * @param j
+   *          Threshold
+   * 
+   * @return Color in RGB
+   */
+  public Color findColour(char c, int j)
+  {
+    Color currentColour;
+    if ((threshold == 0) || aboveThreshold(c, j))
+    {
+      try
+      {
+        currentColour = colors[ResidueProperties.purinepyrimidineIndex[c]];
+      } catch (Exception ex)
+      {
+        return Color.white;
+      }
+    }
+    else
+    {
+      return Color.white;
+    }
+
+    if (conservationColouring)
+    {
+      currentColour = applyConservation(currentColour, j);
+    }
+
+    return currentColour;
+  }
+}
diff --git a/src/jalview/schemes/RNAHelicesColour.java b/src/jalview/schemes/RNAHelicesColour.java
new file mode 100644 (file)
index 0000000..26e4be2
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package jalview.schemes;
+
+import java.awt.*;
+import java.util.Hashtable;
+
+import jalview.datamodel.AlignmentAnnotation;
+
+/**
+ * Looks at the information computed from an RNA Stockholm format file on the
+ * secondary structure of the alignment. Extracts the information on the
+ * positions of the helices present and assigns colors.
+ * 
+ * @author Lauren Michelle Lui
+ * @version 2.5
+ */
+public class RNAHelicesColour extends ResidueColourScheme
+{
+
+  /**
+   * Stores random colors generated for the number of helices
+   */
+  public Hashtable helixcolorhash = new Hashtable();
+
+  /**
+   * Maps sequence positions to the RNA helix they belong to. Key: position,
+   * Value: helix
+   */
+  public Hashtable positionsToHelix = new Hashtable();
+
+  /**
+   * Number of helices in the RNA secondary structure
+   */
+  int numHelix = 0;
+
+  public AlignmentAnnotation annotation;
+
+  /**
+   * Creates a new RNAHelicesColour object.
+   */
+  public RNAHelicesColour(AlignmentAnnotation annotation)
+  {
+    this.annotation = annotation;
+
+    // Figure out number of helices
+    // Length of rnasecstr is the number of pairs of positions that base pair
+    // with each other in the secondary structure
+    for (int x = 0; x < this.annotation._rnasecstr.length; x++)
+    {
+
+      /*
+       * System.out.println(this.annotation._rnasecstr[x] + " Begin" +
+       * this.annotation._rnasecstr[x].getBegin());
+       */
+      // System.out.println(this.annotation._rnasecstr[x].getFeatureGroup());
+
+      positionsToHelix.put(this.annotation._rnasecstr[x].getBegin(),
+              this.annotation._rnasecstr[x].getFeatureGroup());
+      positionsToHelix.put(this.annotation._rnasecstr[x].getEnd(),
+              this.annotation._rnasecstr[x].getFeatureGroup());
+
+      if (Integer.parseInt(this.annotation._rnasecstr[x].getFeatureGroup()) > numHelix)
+      {
+        numHelix = Integer.parseInt(this.annotation._rnasecstr[x]
+                .getFeatureGroup());
+      }
+
+    }
+
+    // Generate random colors and store
+    for (int j = 0; j <= numHelix; j++)
+    {
+      helixcolorhash.put(Integer.toString(j), jalview.util.ColorUtils
+              .generateRandomColor(Color.white));
+    }
+
+  }
+
+  /**
+   * Returns default color base on purinepyrimidineIndex in
+   * jalview.schemes.ResidueProperties (Allows coloring in sequence logo)
+   * 
+   * @param c
+   *          Character in sequence
+   * 
+   * @return color in RGB
+   */
+  public Color findColour(char c)
+  {
+    return ResidueProperties.purinepyrimidine[ResidueProperties.purinepyrimidineIndex[c]];
+    // random colors for all positions
+    // jalview.util.ColorUtils.generateRandomColor(Color.white); If you want
+  }
+
+  /**
+   * Returns color based on helices
+   * 
+   * @param c
+   *          Character in sequence
+   * @param j
+   *          Threshold
+   * 
+   * @return Color in RGB
+   */
+  public Color findColour(char c, int j)
+  {
+    Color currentColour = Color.white;
+    String currentHelix = null;
+    currentHelix = (String) positionsToHelix.get(j);
+
+    if (currentHelix != null)
+    {
+      currentColour = (Color) helixcolorhash.get(currentHelix);
+    }
+
+    // System.out.println(c + " " + j + " helix " + currentHelix + " " +
+    // currentColour);
+    return currentColour;
+  }
+}
index c46c07d..e5ba444 100755 (executable)
@@ -30,6 +30,8 @@ public class ResidueProperties
 
   public static final int[] nucleotideIndex;
 
+  public static final int[] purinepyrimidineIndex;
+
   public static final Hashtable aa3Hash = new Hashtable();
 
   public static final Hashtable aa2Triplet = new Hashtable();
@@ -144,6 +146,54 @@ public class ResidueProperties
     nucleotideName.put("y", "Unknown Pyrimidine");
     nucleotideName.put("N", "Unknown");
     nucleotideName.put("n", "Unknown");
+    nucleotideName.put("W", "Weak nucleotide (A or T)");
+    nucleotideName.put("w", "Weak nucleotide (A or T)");
+    nucleotideName.put("S", "Strong nucleotide (G or C)");
+    nucleotideName.put("s", "Strong nucleotide (G or C)");
+    nucleotideName.put("M", "Amino (A or C)");
+    nucleotideName.put("m", "Amino (A or C)");
+    nucleotideName.put("K", "Keto (G or T)");
+    nucleotideName.put("k", "Keto (G or T)");
+    nucleotideName.put("B", "Not A (G or C or T)");
+    nucleotideName.put("b", "Not A (G or C or T)");
+    nucleotideName.put("H", "Not G (A or C or T)");
+    nucleotideName.put("h", "Not G (A or C or T)");
+    nucleotideName.put("D", "Not C (A or G or T)");
+    nucleotideName.put("d", "Not C (A or G or T)");
+    nucleotideName.put("V", "Not T (A or G or C");
+    nucleotideName.put("v", "Not T (A or G or C");
+
+  }
+
+  static
+  {
+    purinepyrimidineIndex = new int[255];
+    for (int i = 0; i < 255; i++)
+    {
+      purinepyrimidineIndex[i] = 3; // non-nucleotide symbols are all non-gap
+      // gaps.
+    }
+
+    purinepyrimidineIndex['A'] = 0;
+    purinepyrimidineIndex['a'] = 0;
+    purinepyrimidineIndex['C'] = 1;
+    purinepyrimidineIndex['c'] = 1;
+    purinepyrimidineIndex['G'] = 0;
+    purinepyrimidineIndex['g'] = 0;
+    purinepyrimidineIndex['T'] = 1;
+    purinepyrimidineIndex['t'] = 1;
+    purinepyrimidineIndex['U'] = 1;
+    purinepyrimidineIndex['u'] = 1;
+    purinepyrimidineIndex['I'] = 2;
+    purinepyrimidineIndex['i'] = 2;
+    purinepyrimidineIndex['X'] = 2;
+    purinepyrimidineIndex['x'] = 2;
+    purinepyrimidineIndex['R'] = 0;
+    purinepyrimidineIndex['r'] = 0;
+    purinepyrimidineIndex['Y'] = 1;
+    purinepyrimidineIndex['y'] = 1;
+    purinepyrimidineIndex['N'] = 2;
+    purinepyrimidineIndex['n'] = 2;
   }
 
   static
@@ -280,14 +330,22 @@ public class ResidueProperties
       new Color(235, 65, 60), // G
       new Color(60, 136, 238), // T
       new Color(60, 136, 238), // U
-      Color.white, // I
-      Color.white, // X
+      Color.white, // I (inosine)
+      Color.white, // X (xanthine)
       Color.white, // R
       Color.white, // Y
       Color.white, // N
       Color.white, // Gap
   };
 
+  // Added for PurinePyrimidineColourScheme
+  public static final Color[] purinepyrimidine =
+  { new Color(255, 131, 250), // A, G, R purines purplish/orchid
+      new Color(64, 224, 208), // C,U, T, Y pyrimidines turquoise
+      Color.white, // all other nucleotides
+      Color.white // Gap
+  };
+
   // Zappo
   public static final Color[] zappo =
   { Color.pink, // A
@@ -1258,6 +1316,46 @@ public class ResidueProperties
     return ss.toString();
   }
 
+  /**
+   * Used by getRNASecStrucState
+   * 
+   */
+  public static Hashtable toRNAssState;
+  static
+  {
+    toRNAssState = new Hashtable();
+    toRNAssState.put(")", "S");
+    toRNAssState.put("(", "S");
+  }
+
+  /**
+   * translate to RNA secondary structure representation
+   * 
+   * @param ssstring
+   * @return ssstring as a RNA-state secondary structure assignment.
+   */
+  public static String getRNASecStrucState(String ssstring)
+  {
+    if (ssstring == null)
+    {
+      return null;
+    }
+    StringBuffer ss = new StringBuffer();
+    for (int i = 0; i < ssstring.length(); i++)
+    {
+      String ssc = ssstring.substring(i, i + 1);
+      if (toRNAssState.containsKey(ssc))
+      {
+        ss.append((String) toRNAssState.get(ssc));
+      }
+      else
+      {
+        ss.append(" ");
+      }
+    }
+    return ss.toString();
+  }
+
   // main method generates perl representation of residue property hash
   // / cut here
   public static void main(String[] args)
diff --git a/src/jalview/structure/SecondaryStructureListener.java b/src/jalview/structure/SecondaryStructureListener.java
new file mode 100644 (file)
index 0000000..fe546e4
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package jalview.structure;
+
+import jalview.datamodel.*;
+
+public interface SecondaryStructureListener
+{
+  public void mouseOverSequence(SequenceI sequence, int index);
+  public void mouseOverStructure(int atomIndex, String strInfo);
+
+}
index f9e8fdb..e1aa9dc 100644 (file)
@@ -509,6 +509,9 @@ public class StructureSelectionManager
           ((VamsasListener) listeners.elementAt(i)).mouseOver(seq,
                   indexpos, source);
         }
+        else if(listeners.elementAt(i) instanceof SecondaryStructureListener){
+               ((SecondaryStructureListener) listeners.elementAt(i)).mouseOverSequence(seq,indexpos);
+        }
       }
     }
   }
diff --git a/src/jalview/util/ColorUtils.java b/src/jalview/util/ColorUtils.java
new file mode 100644 (file)
index 0000000..5aa3bee
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * author: Lauren Michelle Lui
+ */
+
+package jalview.util;
+
+import java.awt.Color;
+import java.util.Random;
+
+public class ColorUtils
+{
+
+  /**
+   * Generates a random color, will mix with input color. Code taken from
+   * http://stackoverflow
+   * .com/questions/43044/algorithm-to-randomly-generate-an-aesthetically
+   * -pleasing-color-palette
+   * 
+   * @param mix
+   * @return Random color in RGB
+   */
+  public static final Color generateRandomColor(Color mix)
+  {
+    Random random = new Random();
+    int red = random.nextInt(256);
+    int green = random.nextInt(256);
+    int blue = random.nextInt(256);
+
+    // mix the color
+    if (mix != null)
+    {
+      red = (red + mix.getRed()) / 2;
+      green = (green + mix.getGreen()) / 2;
+      blue = (blue + mix.getBlue()) / 2;
+    }
+
+    Color color = new Color(red, green, blue);
+    return color;
+
+  }
+
+}
index 4f9e0ab..75f5430 100644 (file)
@@ -61,6 +61,8 @@ public class SequenceFetcher extends ASequenceFetcher
     // alignment is\r
     // 'default' for\r
     // PFAM\r
+    addDBRefSourceImpl(jalview.ws.dbsources.RfamFull.class);\r
+    addDBRefSourceImpl(jalview.ws.dbsources.RfamSeed.class);\r
     registerDasSequenceSources();\r
   }\r
 \r
index 8ce586a..d9a2ec0 100644 (file)
@@ -37,7 +37,7 @@ import jalview.ws.seqfetcher.DbSourceProxyImpl;
  * @author JimP\r
  * \r
  */\r
-abstract public class Pfam extends DbSourceProxyImpl implements\r
+abstract public class Pfam extends Xfam implements\r
         DbSourceProxy\r
 {\r
 \r
@@ -95,17 +95,19 @@ abstract public class Pfam extends DbSourceProxyImpl implements
    * \r
    * @see jalview.ws.DbSourceProxy#getDbVersion()\r
    */\r
-  public String getDbVersion()\r
+  @Override\r
+public String getDbVersion()\r
   {\r
     // TODO Auto-generated method stub\r
     return null;\r
   }\r
 \r
-  /**\r
+  /**Returns base URL for selected Pfam alignment type\r
    * \r
    * @return PFAM URL stub for this DbSource\r
    */\r
-  protected abstract String getPFAMURL();\r
+  @Override\r
+protected abstract String getXFAMURL();\r
 \r
   /*\r
    * (non-Javadoc)\r
@@ -118,7 +120,7 @@ abstract public class Pfam extends DbSourceProxyImpl implements
     // individual references to each sequence in each family alignment that's\r
     // retrieved.\r
     startQuery();\r
-    AlignmentI rcds = new jalview.io.FormatAdapter().readFile(getPFAMURL()\r
+    AlignmentI rcds = new jalview.io.FormatAdapter().readFile(getXFAMURL()\r
             + queries.trim().toUpperCase(), jalview.io.FormatAdapter.URL,\r
             "STH");\r
     for (int s = 0, sNum = rcds.getHeight(); s < sNum; s++)\r
@@ -151,4 +153,9 @@ abstract public class Pfam extends DbSourceProxyImpl implements
   /*\r
    * public String getDbName() { return "PFAM"; // getDbSource(); }\r
    */\r
+  \r
+  \r
+  public String getXfamSource() { return jalview.datamodel.DBRefSource.PFAM; }\r
+  \r
+  \r
 }\r
index 5f579f6..ee7d9da 100644 (file)
@@ -35,7 +35,7 @@ public class PfamFull extends Pfam implements DbSourceProxy
    * \r
    * @see jalview.ws.dbsources.Pfam#getPFAMURL()\r
    */\r
-  protected String getPFAMURL()\r
+  protected String getXFAMURL()\r
   {\r
     return "http://pfam.sanger.ac.uk/family/alignment/download/format?alnType=full&format=stockholm&order=t&case=l&gaps=default&entry=";\r
   }\r
@@ -60,4 +60,8 @@ public class PfamFull extends Pfam implements DbSourceProxy
     return "PF03760";\r
   }\r
 \r
+public String getDbVersion() {\r
+       return null;\r
+}\r
+\r
 }\r
index 0e85f65..b4771b0 100644 (file)
@@ -37,7 +37,7 @@ public class PfamSeed extends Pfam implements DbSourceProxy
    * \r
    * @see jalview.ws.dbsources.Pfam#getPFAMURL()\r
    */\r
-  protected String getPFAMURL()\r
+  protected String getXFAMURL()\r
   {\r
     return "http://pfam.sanger.ac.uk/family/alignment/download/format?alnType=seed&format=stockholm&order=t&case=l&gaps=default&entry=";\r
   }\r
diff --git a/src/jalview/ws/dbsources/Rfam.java b/src/jalview/ws/dbsources/Rfam.java
new file mode 100644 (file)
index 0000000..d720f4b
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package jalview.ws.dbsources;
+
+import com.stevesoft.pat.Regex;
+
+import jalview.ws.seqfetcher.DbSourceProxy;
+
+/**
+ * Contains methods for fetching sequences from Rfam database
+ * 
+ * @author Lauren Michelle Lui
+ */
+abstract public class Rfam extends Xfam implements DbSourceProxy
+{
+
+  public Rfam()
+  {
+    super();
+    // all extensions of this RFAM source base class are DOMAINDB sources
+    addDbSourceProperty(jalview.datamodel.DBRefSource.DOMAINDB);
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see jalview.ws.DbSourceProxy#getAccessionSeparator() Left here for
+   * consistency with Pfam class
+   */
+  public String getAccessionSeparator()
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see jalview.ws.DbSourceProxy#getAccessionValidator() * Left here for
+   */
+  public Regex getAccessionValidator()
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * Left here for consistency with Pfam class
+   * 
+   * @see jalview.ws.DbSourceProxy#getDbSource() public String getDbSource() { *
+   * this doesn't work - DbSource is key for the hash of DbSourceProxy instances
+   * - 1:many mapping for DbSource to proxy will be lost. * suggest : RFAM is an
+   * 'alignment' source - means proxy is higher level than a sequence source.
+   * return jalview.datamodel.DBRefSource.RFAM; }
+   */
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see jalview.ws.DbSourceProxy#getDbVersion()
+   */
+  @Override
+  public String getDbVersion()
+  {
+    // TODO Auto-generated method stub
+    return null;
+  }
+
+  /**Returns base URL for selected Rfam alignment type
+   * 
+   * @return RFAM URL stub for this DbSource
+   */
+  @Override
+  protected abstract String getXFAMURL();
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see jalview.ws.DbSourceProxy#isValidReference(java.lang.String)
+   */
+  public boolean isValidReference(String accession)
+  {
+    return accession.indexOf("RF") == 0;
+  }
+
+  /* (non-Javadoc)
+   * @see jalview.ws.dbsources.Xfam#getXfamSource()
+   */
+  public String getXfamSource()
+  {
+    return jalview.datamodel.DBRefSource.RFAM;
+  }
+
+}
diff --git a/src/jalview/ws/dbsources/RfamFull.java b/src/jalview/ws/dbsources/RfamFull.java
new file mode 100644 (file)
index 0000000..f8b1952
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package jalview.ws.dbsources;
+
+import jalview.ws.seqfetcher.DbSourceProxy;
+
+/**
+ * Flyweight class specifying retrieval of Full family alignments from RFAM
+ * 
+ * @author Lauren Michelle Lui
+ * 
+ */
+public class RfamFull extends Rfam implements DbSourceProxy
+{
+  public RfamFull()
+  {
+    super();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see jalview.ws.dbsources.Rfam#getXFAMURL()
+   */
+  protected String getXFAMURL()
+  {
+    return "http://rfam.sanger.ac.uk/family/alignment/download/format?alnType=full&nseLabels=0&format=stockholm&acc=";
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see jalview.ws.seqfetcher.DbSourceProxy#getDbName()
+   */
+  public String getDbName()
+  {
+    return "RFAM (Full)";
+  }
+
+  public String getDbSource()
+  {
+    return getDbName(); // so we have unique DbSource string.
+  }
+
+  public String getTestQuery()
+  {
+    // Can be retrieved from http://rfam.janelia.org/cgi-bin/getdesc?acc=RF00014
+    // or
+    // http://rfam.sanger.ac.uk/family/alignment/download/format?alnType=full&nseLabels=0&format=stockholm&acc=RF00014
+    return "RF00014";
+  }
+
+  public String getDbVersion()
+  {
+    return null;
+  }
+
+}
diff --git a/src/jalview/ws/dbsources/RfamSeed.java b/src/jalview/ws/dbsources/RfamSeed.java
new file mode 100644 (file)
index 0000000..7c6a82d
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package jalview.ws.dbsources;
+
+import jalview.ws.seqfetcher.DbSourceProxy;
+
+/**
+ * Flyweight class specifying retrieval of Seed family alignments from RFAM
+ * 
+ * @author Lauren Michelle Lui
+ * 
+ */
+public class RfamSeed extends Rfam implements DbSourceProxy
+{
+  public RfamSeed()
+  {
+    super();
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see jalview.ws.dbsources.Rfam#getRFAMURL()
+   */
+  protected String getXFAMURL()
+  {
+    return "http://rfam.sanger.ac.uk/family/alignment/download/format?alnType=seed&nseLabels=0&format=stockholm&acc=";
+    // Janelia Farms url
+    // "http://rfam.janelia.org/cgi-bin/getalignment?type=seed&fmt=stockholm&acc=";
+  }
+
+  /*
+   * (non-Javadoc)
+   * 
+   * @see jalview.ws.seqfetcher.DbSourceProxy#getDbName()
+   */
+  public String getDbName()
+  {
+    return "RFAM (Seed)";
+  }
+
+  public String getDbSource()
+  {
+    return getDbName(); // so we have unique DbSource string.
+  }
+
+  public String getTestQuery()
+  {
+    return "RF00014";
+  } // http://rfam.janelia.org/cgi-bin/getdesc?acc=RF00014
+
+  public String getDbVersion()
+  {
+    return null;
+  }
+
+}
diff --git a/src/jalview/ws/dbsources/Xfam.java b/src/jalview/ws/dbsources/Xfam.java
new file mode 100644 (file)
index 0000000..b092a25
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
+ * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+ * 
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package jalview.ws.dbsources;
+
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.DBRefEntry;
+import jalview.ws.seqfetcher.DbSourceProxyImpl;
+
+/**
+ * Acts as a superclass for the Rfam and Pfam classes
+ * 
+ * @author Lauren Michelle Lui
+ * 
+ */
+public abstract class Xfam extends DbSourceProxyImpl
+{
+
+  public Xfam()
+  {
+    super();
+  }
+
+  protected abstract String getXFAMURL();
+
+  public abstract String getDbVersion();
+
+  abstract String getXfamSource();
+
+  public AlignmentI getSequenceRecords(String queries) throws Exception
+  {
+    // TODO: this is not a perfect implementation. We need to be able to add
+    // individual references to each sequence in each family alignment that's
+    // retrieved.
+    startQuery();
+    AlignmentI rcds = new jalview.io.FormatAdapter().readFile(getXFAMURL()
+            + queries.trim().toUpperCase(), jalview.io.FormatAdapter.URL,
+            "STH");
+    for (int s = 0, sNum = rcds.getHeight(); s < sNum; s++)
+    {
+      rcds.getSequenceAt(s).addDBRef(new DBRefEntry(getXfamSource(),
+      // getDbSource(),
+              getDbVersion(), queries.trim().toUpperCase()));
+      if (!getDbSource().equals(getXfamSource()))
+      { // add the specific ref too
+        rcds.getSequenceAt(s).addDBRef(
+                new DBRefEntry(getDbSource(), getDbVersion(), queries
+                        .trim().toUpperCase()));
+      }
+    }
+    stopQuery();
+    return rcds;
+  }
+
+}
\ No newline at end of file