Merge branch 'develop' of https://source.jalview.org/git/jalview into develop
authortcofoegbu <tcnofoegbu@dundee.ac.uk>
Mon, 21 Nov 2016 13:03:50 +0000 (13:03 +0000)
committertcofoegbu <tcnofoegbu@dundee.ac.uk>
Mon, 21 Nov 2016 13:03:50 +0000 (13:03 +0000)
33 files changed:
THIRDPARTYLIBS
help/html/colourSchemes/abovePID.html
help/html/io/exportseqreport.html
help/html/releases.html
help/html/webServices/dbreffetcher.html
help/html/webServices/urllinks.html
resources/lang/Messages.properties
resources/lang/Messages_es.properties
src/jalview/analysis/AAFrequency.java
src/jalview/api/AlignViewportI.java
src/jalview/api/FeatureRenderer.java
src/jalview/appletgui/APopupMenu.java
src/jalview/datamodel/Profiles.java [new file with mode: 0644]
src/jalview/datamodel/ProfilesI.java [new file with mode: 0644]
src/jalview/datamodel/SequenceGroup.java
src/jalview/ext/android/ContainerHelpers.java
src/jalview/ext/android/SparseIntArray.java
src/jalview/ext/android/SparseShortArray.java
src/jalview/gui/IdPanel.java
src/jalview/gui/PopupMenu.java
src/jalview/gui/SeqPanel.java
src/jalview/io/SequenceAnnotationReport.java
src/jalview/renderer/AnnotationRenderer.java
src/jalview/schemes/Blosum62ColourScheme.java
src/jalview/schemes/ColourSchemeI.java
src/jalview/schemes/FollowerColourScheme.java
src/jalview/schemes/PIDColourScheme.java
src/jalview/schemes/ResidueColourScheme.java
src/jalview/viewmodel/AlignmentViewport.java
src/jalview/workers/ConsensusThread.java
test/jalview/analysis/AAFrequencyTest.java
test/jalview/io/SequenceAnnotationReportTest.java
test/jalview/schemes/ResidueColourSchemeTest.java

index 7d12783..85aa587 100644 (file)
@@ -6,8 +6,11 @@ A number of sources have also been adapted for incorporation into Jalview's sour
 
 ext.edu.ucsf.rbvi.strucviz2 includes sources originally developed by Scooter Morris and Nadezhda Doncheva for the Cytoscape StructureViz2 plugin. It is released under the Berkley license and we hereby acknowledge its original copyright is held by the UCSF Computer Graphics Laboratory
  and the software was developed with support by the NIH National Center for Research Resources, grant P41-RR01081. 
+ jalview.ext.android includes code taken from the Android Open Source Project (https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/util).
+ The Apache 2.0 Licence (http://www.apache.org/licenses/LICENSE-2.0) is acknowledged in the source code.
 
-Licencing information for each library is given below:
+Licensing information for each library is given below:
 
 JGoogleAnalytics_0.3.jar       APL 2.0 License - http://code.google.com/p/jgoogleanalytics/
 Jmol-14.2.14_2015.06.11.jar    GPL/LGPLv2 http://sourceforge.net/projects/jmol/files/
index ad47dae..8adacc9 100755 (executable)
@@ -35,11 +35,10 @@ td {
     <strong>Colouring above a percentage identity threshold</strong>
   </p>
   <p>Selecting this option causes the colour scheme to be applied to
-    only those residues that occur in that column more than a certain
+    only those residues that occur in that column at least a certain
     percentage of the time. For instance, selecting the threshold to be
-    100 will only colour those columns with 100% identity.</p>
-   <p>To be coloured, a residue must match the consensus (most commonly occurring) residue for the column (or joint equal consensus).</p>
+    100 will only colour those columns with 100% identity, and selecting 50 will shade residues appearing in least 50% of the rows (or sequences) in each column.</p>
    <p>The percentage calculation may include or exclude gaps in the column, depending on the option selected for the <a href="../calculations/consensus.html">consensus calculation</a>.</p>
-   <p>With a threshold of 0, colouring is unchanged (including non-consensus residues).</p>
+   <p>With a threshold of 0, colouring is unchanged.</p>
 </body>
 </html>
index ba97557..3f6a058 100644 (file)
     Much of the information retrieved by Jalview about a sequence is
     visualized on the alignment. Often, however, there are a huge number
     of ontology terms, cross-references, links to publications and other
-    kinds of data shown in the sequence ID tooltip that cannot be
-    examined. In this case, you can view and export the information
-    shown in a sequence's ID tooltip by right-clicking and selecting the
+    kinds of data associated with a sequence, and only some of these are shown in 
+    sequence ID tooltip. To show the full set of annotation and database links for
+    a sequence, right-click and select the
     <strong>&quot;<em>(sequence's name)</em></em>&rarr;Sequence
       Details ...&quot;
     </strong> entry from the <a href="../menus/popupMenu.html">pop-up menu</a>.
   </p>
   <p>
     <strong>Annotation Reports for a range of sequences</strong><br />
-    If you would like to view the tooltips for a number of sequences,
+    If you would like to view database and metadata for a number of sequences,
     simply select them all and then use the <strong>Selection&rarr;Sequence
       Details ...</strong> entry in the <a href="../menus/popupMenu.html">pop-up
       menu</a>.
index 3fe08cb..140466b 100755 (executable)
     <tr>
       <td width="60" nowrap>
         <div align="center">
+          <strong><a name="Jalview.2.10.1">2.10.1</a><br />
+            <em>22/11/2016</em></strong>
+        </div>
+      </td>
+      <td><div align="left">
+           <em>General</em>
+            <ul>
+             <li><!-- JAL-98 -->Improved memory usage: sparse arrays used for all consensus calculations</li>
+             <li><!-- JAL- --></li>
+          </ul>
+          <em>Application</em>
+          <ul>
+        <li><!-- JAL-1723 -->Sequence ID tool tips have been tamed (databases sorted alphabetically, abridged ID sets) </li>
+           <li><!-- JAL-2282-->New replacement token for creating URLs <em>just</em> from database cross references. Users with custom links will receive a warning dialog asking them to update their preferences.</li>
+           <li><!-- JAL-2287-->Cancel button and escape listener on dialog warning user about disconnecting Jalview from a Chimera session</li>
+           <li><!-- JAL-2281-->Custom URL links for database cross-references are matched to database name regardless of case</li>
+           <li></li>
+           
+
+          </ul>
+          <em>Applet</em>
+          <ul>
+          </ul>
+          <em>Build and deployment</em>
+          <ul>
+            <li></li>
+          </ul>
+         </div>
+      </td>
+      <td>
+        <div align="left">
+          <em>General</em>
+          <ul>
+           <li><!-- JAL-2286 -->Columns with more than one modal residue are not coloured or thresholded according to percent identity (first observed in Jalview 2.8.2)</li>
+           <li><!-- JAL-2301 -->Threonine incorrectly reported as not hydrophobic</li>
+           <li><!-- JAL-2318 -->Updates to documentation pages (above PID threshold, amino acid properties)</li>
+           <li><!-- JAL-2292 -->Lower case residues in sequences are not reported as mapped to residues in a structure file in the View Mapping report</li>
+          </ul>
+          <em>Application</em>
+          <ul>
+           <li><!-- JAL-2282-->Custom URL links for specific database names without regular expressions also offer invalid links from Sequence ID</li>
+           <li><!-- JAL-2315-->Removing a single configured link in the URL links pane in Connections preferences doesn't actually update Jalview configuration</li>
+           <li><!-- JAL-2272-->CTRL-Click on a selected region to open the alignment area popup menu doesn't work on El-Capitan</li>
+           <li><!-- JAL-2280 -->Jalview doesn't offer to associate mmCIF files with similarly named sequences if dropped onto the alignment</li>
+           <li><!-- JAL-2312 -->Additional mappings are shown for PDB entries where more chains exist in the PDB accession than are reported in the SIFTS file</li>
+           <li><!-- --></li>
+           <li><!-- --></li>
+           <li><!-- --></li>
+          </ul>
+          <em>Applet</em>
+          <ul>
+          </ul>
+          <em>Build and deployment</em>
+          <ul>
+            <li><!-- JAL-2308, -->Failing/passing unit tests</li>
+          </ul>
+          <em>New Known Issues</em>
+          <ul>
+            <li></li>
+          </ul>
+        </div>
+      </td>
+    </tr>
+      <td width="60" nowrap>
+        <div align="center">
           <strong><a name="Jalview.2.10.0b1">2.10.0b1</a><br />
             <em>25/10/2016</em></strong>
         </div>
               <!-- JAL-1306 -->Quality and Conservation are now shown on
               load even when Consensus calculation is disabled
             </li>
+            <li>
+              <!-- JAL-1932 -->Remove right on penultimate column of 
+              alignment does nothing
+            </li>
           </ul>
           <em>Application</em>
           <ul>
index 52220d2..83c80ba 100644 (file)
 <p>
 <p>
   <strong>Discovering Database References for Sequences</strong><br>
-  Database references are associated with a sequence are displayed as a
-  list in the tooltip shown when mousing over its sequence ID. Jalview
-  uses references for the retrieval of <a
-    href="../features/viewingpdbs.html">PDB structures</a> and <a
+  Database references associated with a sequence are displayed as an
+  abbreviated list in the tooltip shown when mousing over its sequence
+  ID, and can be viewed in full via the
+  <a href="../io/exportseqreport.html">Sequence Details</a> window. .
+  Jalview also uses references for the retrieval of
+  <a href="../features/viewingpdbs.html">PDB structures</a> and <a
     href="../features/dasfeatures.html">DAS features</a>, and for
   retrieving sequence cross-references such as the protein products of a
   DNA sequence.
index 1a1f0d0..36c7c6b 100644 (file)
     the sequence ID for the sequence (<em>since Jalview 2.10.1</em>).
   </p>
   <p>
+  If Jalview opens a project with links which include $SEQUENCE_ID$ tokens, it will present
+  the user with a warning message, as these links may need to be updated to use $DB_ACCESSION$, if
+  they were added before Jalview 2.10.1. The message lists the links which should be reviewed. 
+  The warning can be turned off completely via a checkbox in the message dialog.
+  </p>
+  <p>
     <strong>Regular Expression Substitution</strong><br> A url may
     contain a string of the form $SEQUENCE_ID=/<em>regular
     expression</em>/=$ or $DB_ACCESSION=/<em>regular expression</em>/=$. 
index 49a0456..01ba0ff 100644 (file)
@@ -1272,3 +1272,4 @@ label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ is no longer used for DB access
 label.SEQUENCE_ID_for_DB_ACCESSION1 = Please review your URL links in the 'Connections' tab of the Preferences window:
 label.SEQUENCE_ID_for_DB_ACCESSION2 = URL links using '$SEQUENCE_ID$' for DB accessions now use '$DB_ACCESSION$'.
 label.do_not_display_again = Do not display this message again
+label.output_seq_details = Output Sequence Details to list all database references
index 96c8ef2..9c2436c 100644 (file)
@@ -1272,4 +1272,5 @@ label.operation_failed = Operaci
 label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ no se utiliza más para accesiones DB
 label.SEQUENCE_ID_for_DB_ACCESSION1 = Por favor, revise sus URLs en la pestaña 'Conexiones' de la ventana de Preferencias:
 label.SEQUENCE_ID_for_DB_ACCESSION2 = URL enlaza usando '$SEQUENCE_ID$' para accesiones DB ahora usar '$DB_ACCESSION$'.
-label.do_not_display_again = No mostrar este mensaje de nuevo
\ No newline at end of file
+label.do_not_display_again = No mostrar este mensaje de nuevo
+label.output_seq_details = Seleccionar Detalles de la secuencia para ver todas
index 6bdffe1..17874e6 100755 (executable)
@@ -26,9 +26,11 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.Profile;
 import jalview.datamodel.ProfileI;
+import jalview.datamodel.Profiles;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.ResidueCount;
-import jalview.datamodel.SequenceI;
 import jalview.datamodel.ResidueCount.SymbolCounts;
+import jalview.datamodel.SequenceI;
 import jalview.ext.android.SparseIntArray;
 import jalview.util.Comparison;
 import jalview.util.Format;
@@ -65,13 +67,13 @@ public class AAFrequency
     }
   }
 
-  public static final ProfileI[] calculate(List<SequenceI> list,
+  public static final ProfilesI calculate(List<SequenceI> list,
           int start, int end)
   {
     return calculate(list, start, end, false);
   }
 
-  public static final ProfileI[] calculate(List<SequenceI> sequences,
+  public static final ProfilesI calculate(List<SequenceI> sequences,
           int start, int end, boolean profile)
   {
     SequenceI[] seqs = new SequenceI[sequences.size()];
@@ -81,20 +83,19 @@ public class AAFrequency
       for (int i = 0; i < sequences.size(); i++)
       {
         seqs[i] = sequences.get(i);
-        if (seqs[i].getLength() > width)
+        int length = seqs[i].getLength();
+        if (length > width)
         {
-          width = seqs[i].getLength();
+          width = length;
         }
       }
 
-      ProfileI[] reply = new ProfileI[width];
-
       if (end >= width)
       {
         end = width;
       }
 
-      calculate(seqs, start, end, reply, profile);
+      ProfilesI reply = calculate(seqs, width, start, end, profile);
       return reply;
     }
   }
@@ -103,17 +104,17 @@ public class AAFrequency
    * Calculate the consensus symbol(s) for each column in the given range.
    * 
    * @param sequences
+   * @param width
+   *          the full width of the alignment
    * @param start
    *          start column (inclusive, base zero)
    * @param end
    *          end column (exclusive)
-   * @param result
-   *          array in which to store profile per column
    * @param saveFullProfile
    *          if true, store all symbol counts
    */
-  public static final void calculate(final SequenceI[] sequences,
-          int start, int end, ProfileI[] result, boolean saveFullProfile)
+  public static final ProfilesI calculate(final SequenceI[] sequences,
+          int width, int start, int end, boolean saveFullProfile)
   {
     // long now = System.currentTimeMillis();
     int seqCount = sequences.length;
@@ -121,6 +122,8 @@ public class AAFrequency
     int nucleotideCount = 0;
     int peptideCount = 0;
 
+    ProfileI[] result = new ProfileI[width];
+
     for (int column = start; column < end; column++)
     {
       /*
@@ -183,6 +186,7 @@ public class AAFrequency
 
       result[column] = profile;
     }
+    return new Profiles(result);
     // long elapsed = System.currentTimeMillis() - now;
     // System.out.println(elapsed);
   }
@@ -221,10 +225,10 @@ public class AAFrequency
    *          the annotation row to add annotations to
    * @param profiles
    *          the source consensus data
-   * @param iStart
-   *          start column
-   * @param width
-   *          end column
+   * @param startCol
+   *          start column (inclusive)
+   * @param endCol
+   *          end column (exclusive)
    * @param ignoreGaps
    *          if true, normalise residue percentages ignoring gaps
    * @param showSequenceLogo
@@ -234,12 +238,12 @@ public class AAFrequency
    *          number of sequences
    */
   public static void completeConsensus(AlignmentAnnotation consensus,
-          ProfileI[] profiles, int iStart, int width, boolean ignoreGaps,
+          ProfilesI profiles, int startCol, int endCol, boolean ignoreGaps,
           boolean showSequenceLogo, long nseq)
   {
     // long now = System.currentTimeMillis();
     if (consensus == null || consensus.annotations == null
-            || consensus.annotations.length < width)
+            || consensus.annotations.length < endCol)
     {
       /*
        * called with a bad alignment annotation row 
@@ -248,21 +252,21 @@ public class AAFrequency
       return;
     }
 
-    final int dp = getPercentageDp(nseq);
-
-    for (int i = iStart; i < width; i++)
+    for (int i = startCol; i < endCol; i++)
     {
-      ProfileI profile;
-      if (i >= profiles.length || ((profile = profiles[i]) == null))
+      ProfileI profile = profiles.get(i);
+      if (profile == null)
       {
         /*
          * happens if sequences calculated over were 
          * shorter than alignment width
          */
         consensus.annotations[i] = null;
-        continue;
+        return;
       }
 
+      final int dp = getPercentageDp(nseq);
+
       float value = profile.getPercentageIdentity(ignoreGaps);
 
       String description = getTooltip(profile, value, showSequenceLogo,
@@ -277,8 +281,8 @@ public class AAFrequency
       {
         modalResidue = "+";
       }
-      consensus.annotations[i] = new Annotation(modalResidue,
-              description, ' ', value);
+      consensus.annotations[i] = new Annotation(modalResidue, description,
+              ' ', value);
     }
     // long elapsed = System.currentTimeMillis() - now;
     // System.out.println(-elapsed);
index e30a052..8b80531 100644 (file)
@@ -26,7 +26,7 @@ import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentView;
 import jalview.datamodel.CigarArray;
 import jalview.datamodel.ColumnSelection;
-import jalview.datamodel.ProfileI;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
@@ -82,7 +82,7 @@ public interface AlignViewportI extends ViewStyleI
 
   ColumnSelection getColumnSelection();
 
-  ProfileI[] getSequenceConsensusHash();
+  ProfilesI getSequenceConsensusHash();
 
   /**
    * Get consensus data table for the cDNA complement of this alignment (if any)
@@ -145,7 +145,7 @@ public interface AlignViewportI extends ViewStyleI
    * 
    * @param hconsensus
    */
-  void setSequenceConsensusHash(ProfileI[] hconsensus);
+  void setSequenceConsensusHash(ProfilesI hconsensus);
 
   /**
    * Set the cDNA complement consensus for the viewport
index dbc9880..f54231e 100644 (file)
@@ -132,7 +132,8 @@ public interface FeatureRenderer
   void setGroupVisibility(String group, boolean visible);
 
   /**
-   * locate features at a particular position on the given sequence
+   * Returns features at the specified position on the given sequence.
+   * Non-positional features are not included.
    * 
    * @param sequence
    * @param res
index 45e39cc..160224b 100644 (file)
@@ -802,7 +802,7 @@ public class APopupMenu extends java.awt.PopupMenu implements
 
     CutAndPasteTransfer cap = new CutAndPasteTransfer(false, ap.alignFrame);
 
-    StringBuffer contents = new StringBuffer();
+    StringBuilder contents = new StringBuilder(128);
     for (SequenceI seq : sequences)
     {
       contents.append(MessageManager.formatMessage(
@@ -813,7 +813,6 @@ public class APopupMenu extends java.awt.PopupMenu implements
               seq,
               true,
               true,
-              false,
               (ap.seqPanel.seqCanvas.fr != null) ? ap.seqPanel.seqCanvas.fr
                       .getMinMax() : null);
       contents.append("</p>");
diff --git a/src/jalview/datamodel/Profiles.java b/src/jalview/datamodel/Profiles.java
new file mode 100644 (file)
index 0000000..98a8c6d
--- /dev/null
@@ -0,0 +1,43 @@
+package jalview.datamodel;
+
+public class Profiles implements ProfilesI
+{
+
+  private ProfileI[] profiles;
+
+  public Profiles(ProfileI[] p)
+  {
+    profiles = p;
+  }
+
+  /**
+   * Returns the profile for the given column, or null if none found
+   * 
+   * @param col
+   */
+  @Override
+  public ProfileI get(int col)
+  {
+    return profiles != null && col >= 0 && col < profiles.length ? profiles[col]
+            : null;
+  }
+
+  /**
+   * Returns the first column (base 0) covered by the profiles
+   */
+  @Override
+  public int getStartColumn()
+  {
+    return 0;
+  }
+
+  /**
+   * Returns the last column (base 0) covered by the profiles
+   */
+  @Override
+  public int getEndColumn()
+  {
+    return profiles == null ? 0 : profiles.length - 1;
+  }
+
+}
diff --git a/src/jalview/datamodel/ProfilesI.java b/src/jalview/datamodel/ProfilesI.java
new file mode 100644 (file)
index 0000000..6719de6
--- /dev/null
@@ -0,0 +1,12 @@
+package jalview.datamodel;
+
+public interface ProfilesI
+{
+
+  ProfileI get(int i);
+
+  int getStartColumn();
+
+  int getEndColumn();
+
+}
index ca90003..9245761 100755 (executable)
@@ -527,7 +527,7 @@ public class SequenceGroup implements AnnotatedCollectionI
     boolean upd = false;
     try
     {
-      ProfileI[] cnsns = AAFrequency.calculate(sequences, startRes,
+      ProfilesI cnsns = AAFrequency.calculate(sequences, startRes,
               endRes + 1, showSequenceLogo);
       if (consensus != null)
       {
@@ -599,9 +599,9 @@ public class SequenceGroup implements AnnotatedCollectionI
     c.completeAnnotations(conservation, null, startRes, endRes + 1);
   }
 
-  public ProfileI[] consensusData = null;
+  public ProfilesI consensusData = null;
 
-  private void _updateConsensusRow(ProfileI[] cnsns, long nseq)
+  private void _updateConsensusRow(ProfilesI cnsns, long nseq)
   {
     if (consensus == null)
     {
index f536819..4033dcc 100644 (file)
@@ -16,6 +16,12 @@ package jalview.ext.android;
  * limitations under the License.
  */
 
+/*
+ * Copied to Jalview September 2016.
+ * Only the members of this class required for SparseIntArray were copied.
+ * Method binarySearch(short[] array, int size, short value) added to support
+ * SparseShortArray.
+ */
 class ContainerHelpers
 {
   static final boolean[] EMPTY_BOOLEANS = new boolean[0];
@@ -83,7 +89,7 @@ class ContainerHelpers
     while (lo <= hi)
     {
       final int mid = (lo + hi) >>> 1;
-      final int midVal = array[mid];
+      final short midVal = array[mid];
       if (midVal < value)
       {
         lo = mid + 1;
index 2b9c4af..fcd4f1f 100644 (file)
@@ -40,6 +40,13 @@ package jalview.ext.android;
  * order in the case of <code>valueAt(int)<code>.
  * </p>
  */
+
+/*
+ * Imported into Jalview September 2016
+ * Change log:
+ *   Sep 2016 method add(int, int) added for more efficient increment of counts
+ *            (a single binary search, rather than one on read and one on write)
+ */
 public class SparseIntArray implements Cloneable
 {
   private int[] mKeys;
index 375d745..f961f55 100644 (file)
@@ -40,12 +40,15 @@ package jalview.ext.android;
  * order in the case of <code>valueAt(int)<code>.
  * </p>
  */
-/**
- * A copy of SparseShortArray designed to store short values (to minimise space
- * usage).
+
+/*
+ * Added to Jalview September 2016. A copy of SparseIntArray designed to store
+ * short values (to minimise space usage).
  * <p>
- * Note that operations append, put, add throw ArithmeticException if the
- * resulting value overflows the range of a short.
+ * Note that operations append, put, add throw ArithmeticException if either the
+ * key or the resulting value overflows the range of a short. Calling code
+ * should trap and handle this, for example by switching to using a
+ * SparseIntArray instead.
  */
 public class SparseShortArray implements Cloneable
 {
index e321a74..6a20872 100755 (executable)
@@ -109,8 +109,8 @@ public class IdPanel extends JPanel implements MouseListener,
     if (seq > -1 && seq < av.getAlignment().getHeight())
     {
       SequenceI sequence = av.getAlignment().getSequenceAt(seq);
-      StringBuffer tip = new StringBuffer(64);
-      seqAnnotReport.createSequenceAnnotationReport(tip, sequence,
+      StringBuilder tip = new StringBuilder(64);
+      seqAnnotReport.createTooltipAnnotationReport(tip, sequence,
               av.isShowDBRefs(), av.isShowNPFeats(),
               sp.seqCanvas.fr.getMinMax());
       setToolTipText(JvSwingUtils.wrapTooltip(true,
index bb816cd..5825382 100644 (file)
@@ -1677,7 +1677,7 @@ public class PopupMenu extends JPopupMenu
   public void createSequenceDetailsReport(SequenceI[] sequences)
   {
     CutAndPasteHtmlTransfer cap = new CutAndPasteHtmlTransfer();
-    StringBuffer contents = new StringBuffer();
+    StringBuilder contents = new StringBuilder(128);
     for (SequenceI seq : sequences)
     {
       contents.append("<p><h2>"
@@ -1692,7 +1692,6 @@ public class PopupMenu extends JPopupMenu
                       seq,
                       true,
                       true,
-                      false,
                       (ap.getSeqPanel().seqCanvas.fr != null) ? ap
                               .getSeqPanel().seqCanvas.fr.getMinMax()
                               : null);
index 3266fab..73ed744 100644 (file)
@@ -124,7 +124,7 @@ public class SeqPanel extends JPanel implements MouseListener,
 
   private final SequenceAnnotationReport seqARep;
 
-  StringBuffer tooltipText = new StringBuffer();
+  StringBuilder tooltipText = new StringBuilder();
 
   String tmpString;
 
@@ -785,7 +785,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       seqARep.appendFeatures(tooltipText, rpos, features,
               this.ap.getSeqPanel().seqCanvas.fr.getMinMax());
     }
-    if (tooltipText.length() == 6) // <html></html>
+    if (tooltipText.length() == 6) // <html>
     {
       setToolTipText(null);
       lastTooltip = null;
index 89f1068..850b1dc 100644 (file)
 package jalview.io;
 
 import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.DBRefSource;
 import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceI;
 import jalview.io.gff.GffConstants;
+import jalview.util.MessageManager;
 import jalview.util.UrlLink;
 
-import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Comparator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
@@ -39,8 +42,69 @@ import java.util.Map;
  */
 public class SequenceAnnotationReport
 {
+  private static final String COMMA = ",";
+
+  private static final String ELLIPSIS = "...";
+
+  private static final int MAX_REFS_PER_SOURCE = 4;
+
+  private static final int MAX_SOURCES = 40;
+
+  private static final String[][] PRIMARY_SOURCES = new String[][] {
+      DBRefSource.CODINGDBS, DBRefSource.DNACODINGDBS,
+      DBRefSource.PROTEINDBS };
+
   final String linkImageURL;
 
+  /*
+   * Comparator to order DBRefEntry by Source + accession id (case-insensitive)
+   */
+  private static Comparator<DBRefEntry> comparator = new Comparator<DBRefEntry>()
+  {
+
+    @Override
+    public int compare(DBRefEntry ref1, DBRefEntry ref2)
+    {
+      String s1 = ref1.getSource();
+      String s2 = ref2.getSource();
+      boolean s1Primary = isPrimarySource(s1);
+      boolean s2Primary = isPrimarySource(s2);
+      if (s1Primary && !s2Primary)
+      {
+        return -1;
+      }
+      if (!s1Primary && s2Primary)
+      {
+        return 1;
+      }
+      int comp = s1 == null ? -1 : (s2 == null ? 1 : s1
+              .compareToIgnoreCase(s2));
+      if (comp == 0)
+      {
+        String a1 = ref1.getAccessionId();
+        String a2 = ref2.getAccessionId();
+        comp = a1 == null ? -1 : (a2 == null ? 1 : a1
+                .compareToIgnoreCase(a2));
+      }
+      return comp;
+    }
+
+    private boolean isPrimarySource(String source)
+    {
+      for (String[] primary : PRIMARY_SOURCES)
+      {
+        for (String s : primary)
+        {
+          if (source.equals(s))
+          {
+            return true;
+          }
+        }
+      }
+      return false;
+    }
+  };
+
   public SequenceAnnotationReport(String linkImageURL)
   {
     this.linkImageURL = linkImageURL;
@@ -49,37 +113,36 @@ public class SequenceAnnotationReport
   /**
    * Append text for the list of features to the tooltip
    * 
-   * @param tooltipText2
+   * @param sb
    * @param rpos
    * @param features
    * @param minmax
    */
-  public void appendFeatures(final StringBuffer tooltipText2, int rpos,
+  public void appendFeatures(final StringBuilder sb, int rpos,
           List<SequenceFeature> features, Map<String, float[][]> minmax)
   {
     if (features != null)
     {
       for (SequenceFeature feature : features)
       {
-        appendFeature(tooltipText2, rpos, minmax, feature);
+        appendFeature(sb, rpos, minmax, feature);
       }
     }
   }
 
   /**
-   * Appends text for one sequence feature to the string buffer
+   * Appends the feature at rpos to the given buffer
    * 
    * @param sb
    * @param rpos
    * @param minmax
-   *          {{min, max}, {min, max}} positional and non-positional feature
-   *          scores for this type
    * @param feature
    */
-  void appendFeature(final StringBuffer sb, int rpos,
+  void appendFeature(final StringBuilder sb, int rpos,
           Map<String, float[][]> minmax, SequenceFeature feature)
   {
-    if ("disulfide bond".equals(feature.getType()))
+    String tmpString;
+    if (feature.getType().equals("disulfide bond"))
     {
       if (feature.getBegin() == rpos || feature.getEnd() == rpos)
       {
@@ -109,21 +172,20 @@ public class SequenceAnnotationReport
         }
         if (feature.begin != feature.end)
         {
-          sb.append(" " + feature.end);
+          sb.append(" ").append(feature.end);
         }
 
         if (feature.getDescription() != null
                 && !feature.description.equals(feature.getType()))
         {
-          String tmpString = feature.getDescription();
+          tmpString = feature.getDescription();
           String tmp2up = tmpString.toUpperCase();
-          final int startTag = tmp2up.indexOf("<HTML>");
+          int startTag = tmp2up.indexOf("<HTML>");
           if (startTag > -1)
           {
             tmpString = tmpString.substring(startTag + 6);
             tmp2up = tmp2up.substring(startTag + 6);
           }
-          // TODO strips off </body> but not <body> - is that intended?
           int endTag = tmp2up.indexOf("</BODY>");
           if (endTag > -1)
           {
@@ -148,7 +210,9 @@ public class SequenceAnnotationReport
               // be used, so we must remove < > symbols
               tmpString = tmpString.replaceAll("<", "&lt;");
               tmpString = tmpString.replaceAll(">", "&gt;");
-              sb.append("; ").append(tmpString);
+
+              sb.append("; ");
+              sb.append(tmpString);
             }
             else
             {
@@ -156,18 +220,14 @@ public class SequenceAnnotationReport
             }
           }
         }
-
-        /*
-         * score should be shown if there is one, and min != max
-         * for this feature type (e.g. not all 0)
-         */
+        // check score should be shown
         if (!Float.isNaN(feature.getScore()))
         {
-          float[][] rng = (minmax == null) ? null : minmax.get(feature
-                  .getType());
+          float[][] rng = (minmax == null) ? null : ((float[][]) minmax
+                  .get(feature.getType()));
           if (rng != null && rng[0] != null && rng[0][0] != rng[0][1])
           {
-            sb.append(" Score=").append(String.valueOf(feature.getScore()));
+            sb.append(" Score=" + feature.getScore());
           }
         }
         String status = (String) feature.getValue("status");
@@ -183,7 +243,6 @@ public class SequenceAnnotationReport
         }
       }
     }
-    appendLinks(sb, feature);
   }
 
   /**
@@ -254,26 +313,42 @@ public class SequenceAnnotationReport
     return urlSets.values();
   }
 
-  public void createSequenceAnnotationReport(final StringBuffer tip,
+  public void createSequenceAnnotationReport(final StringBuilder tip,
           SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
           Map<String, float[][]> minmax)
   {
     createSequenceAnnotationReport(tip, sequence, showDbRefs, showNpFeats,
-            true, minmax);
+            minmax, false);
   }
 
-  public void createSequenceAnnotationReport(final StringBuffer tip,
+  /**
+   * Builds an html formatted report of sequence details and appends it to the
+   * provided buffer.
+   * 
+   * @param sb
+   *          buffer to append report to
+   * @param sequence
+   *          the sequence the report is for
+   * @param showDbRefs
+   *          whether to include database references for the sequence
+   * @param showNpFeats
+   *          whether to include non-positional sequence features
+   * @param minmax
+   * @param summary
+   * @return
+   */
+  int createSequenceAnnotationReport(final StringBuilder sb,
           SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
-          boolean tableWrap, Map<String, float[][]> minmax)
+          Map<String, float[][]> minmax, boolean summary)
   {
     String tmp;
-    tip.append("<i>");
+    sb.append("<i>");
 
     int maxWidth = 0;
     if (sequence.getDescription() != null)
     {
       tmp = sequence.getDescription();
-      tip.append("<br>" + tmp);
+      sb.append("<br>").append(tmp);
       maxWidth = Math.max(maxWidth, tmp.length());
     }
     SequenceI ds = sequence;
@@ -284,16 +359,81 @@ public class SequenceAnnotationReport
     DBRefEntry[] dbrefs = ds.getDBRefs();
     if (showDbRefs && dbrefs != null)
     {
-      for (int i = 0; i < dbrefs.length; i++)
+      // note this sorts the refs held on the sequence!
+      Arrays.sort(dbrefs, comparator);
+      boolean ellipsis = false;
+      String source = null;
+      String lastSource = null;
+      int countForSource = 0;
+      int sourceCount = 0;
+      boolean moreSources = false;
+      int lineLength = 0;
+
+      for (DBRefEntry ref : dbrefs)
+      {
+        source = ref.getSource();
+        if (source == null)
+        {
+          // shouldn't happen
+          continue;
+        }
+        boolean sourceChanged = !source.equals(lastSource);
+        if (sourceChanged)
+        {
+          lineLength = 0;
+          countForSource = 0;
+          sourceCount++;
+        }
+        if (sourceCount > MAX_SOURCES && summary)
+        {
+          ellipsis = true;
+          moreSources = true;
+          break;
+        }
+        lastSource = source;
+        countForSource++;
+        if (countForSource == 1 || !summary)
+        {
+          sb.append("<br>");
+        }
+        if (countForSource <= MAX_REFS_PER_SOURCE || !summary)
+        {
+          String accessionId = ref.getAccessionId();
+          lineLength += accessionId.length() + 1;
+          if (countForSource > 1 && summary)
+          {
+            sb.append(", ").append(accessionId);
+            lineLength++;
+          }
+          else
+          {
+            sb.append(source).append(" ").append(accessionId);
+            lineLength += source.length();
+          }
+          maxWidth = Math.max(maxWidth, lineLength);
+        }
+        if (countForSource == MAX_REFS_PER_SOURCE && summary)
+        {
+          sb.append(COMMA).append(ELLIPSIS);
+          ellipsis = true;
+        }
+      }
+      if (moreSources)
       {
-        tip.append("<br>");
-        tmp = dbrefs[i].getSource() + " " + dbrefs[i].getAccessionId();
-        tip.append(tmp);
-        maxWidth = Math.max(maxWidth, tmp.length());
+        sb.append("<br>").append(ELLIPSIS).append(COMMA).append(source)
+                .append(COMMA).append(ELLIPSIS);
+      }
+      if (ellipsis)
+      {
+        sb.append("<br>(");
+        sb.append(MessageManager.getString("label.output_seq_details"));
+        sb.append(")");
       }
     }
 
-    // ADD NON POSITIONAL SEQUENCE INFO
+    /*
+     * add non-positional features if wanted
+     */
     SequenceFeature[] features = sequence.getSequenceFeatures();
     if (showNpFeats && features != null)
     {
@@ -301,21 +441,29 @@ public class SequenceAnnotationReport
       {
         if (features[i].begin == 0 && features[i].end == 0)
         {
-          int sz = -tip.length();
-          List<SequenceFeature> tfeat = new ArrayList<SequenceFeature>();
-          tfeat.add(features[i]);
-          appendFeatures(tip, 0, tfeat, minmax);
-          sz += tip.length();
+          int sz = -sb.length();
+          appendFeature(sb, 0, minmax, features[i]);
+          sz += sb.length();
           maxWidth = Math.max(maxWidth, sz);
         }
       }
     }
+    sb.append("</i>");
+    return maxWidth;
+  }
+
+  public void createTooltipAnnotationReport(final StringBuilder tip,
+          SequenceI sequence, boolean showDbRefs, boolean showNpFeats,
+          Map<String, float[][]> minmax)
+  {
+    int maxWidth = createSequenceAnnotationReport(tip, sequence,
+            showDbRefs, showNpFeats, minmax, true);
 
-    if (tableWrap && maxWidth > 60)
+    if (maxWidth > 60)
     {
-      tip.insert(0, "<table width=350 border=0><tr><td><i>");
-      tip.append("</i></td></tr></table>");
+      // ? not sure this serves any useful purpose
+      // tip.insert(0, "<table width=350 border=0><tr><td>");
+      // tip.append("</td></tr></table>");
     }
-
   }
 }
index d7ae950..a0e530c 100644 (file)
@@ -28,7 +28,7 @@ import jalview.api.AlignViewportI;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.ColumnSelection;
-import jalview.datamodel.ProfileI;
+import jalview.datamodel.ProfilesI;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ResidueProperties;
 import jalview.util.Platform;
@@ -74,7 +74,7 @@ public class AnnotationRenderer
 
   private ColumnSelection columnSelection;
 
-  private ProfileI[] hconsensus;
+  private ProfilesI hconsensus;
 
   private Hashtable[] complementConsensus;
 
@@ -352,7 +352,7 @@ public class AnnotationRenderer
       {
         // TODO? group consensus for cDNA complement
         return AAFrequency.extractProfile(
-                aa.groupRef.consensusData[column],
+                aa.groupRef.consensusData.get(column),
                 aa.groupRef.getIgnoreGapsConsensus());
       }
       // TODO extend annotation row to enable dynamic and static profile data to
@@ -366,7 +366,8 @@ public class AnnotationRenderer
         }
         else
         {
-          return AAFrequency.extractProfile(hconsensus[column],
+          return AAFrequency.extractProfile(
+hconsensus.get(column),
                   av_ignoreGapsConsensus);
         }
       }
index 37c31f9..c47f171 100755 (executable)
@@ -47,7 +47,7 @@ public class Blosum62ColourScheme extends ResidueColourScheme
       res -= ('a' - 'A');
     }
 
-    if (consensus == null || j >= consensus.length || consensus[j] == null
+    if (consensus == null || consensus.get(j) == null
             || (threshold != 0 && !aboveThreshold(res, j)))
     {
       return Color.white;
@@ -60,7 +60,7 @@ public class Blosum62ColourScheme extends ResidueColourScheme
       /*
        * test if this is the consensus (or joint consensus) residue
        */
-      String max = consensus[j].getModalResidue();
+      String max = consensus.get(j).getModalResidue();
 
       if (max.indexOf(res) > -1)
       {
index fb71686..da99a4a 100755 (executable)
@@ -21,7 +21,7 @@
 package jalview.schemes;
 
 import jalview.datamodel.AnnotatedCollectionI;
-import jalview.datamodel.ProfileI;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceI;
 
@@ -53,7 +53,7 @@ public interface ColourSchemeI
   /**
    * assign the given consensus profile for the colourscheme
    */
-  public void setConsensus(ProfileI[] hconsensus);
+  public void setConsensus(ProfilesI hconsensus);
 
   /**
    * assign the given conservation to the colourscheme
index 86fce4e..35be31b 100644 (file)
@@ -21,7 +21,7 @@
 package jalview.schemes;
 
 import jalview.analysis.Conservation;
-import jalview.datamodel.ProfileI;
+import jalview.datamodel.ProfilesI;
 
 /**
  * Colourscheme that takes its colours from some other colourscheme
@@ -40,7 +40,7 @@ public class FollowerColourScheme extends ResidueColourScheme
   }
 
   @Override
-  public void setConsensus(ProfileI[] consensus)
+  public void setConsensus(ProfilesI consensus)
   {
     if (colourScheme != null)
     {
index ccc69c2..0ad5b5c 100755 (executable)
@@ -20,6 +20,7 @@
  */
 package jalview.schemes;
 
+import jalview.datamodel.ProfileI;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.util.Comparison;
@@ -48,7 +49,7 @@ public class PIDColourScheme extends ResidueColourScheme
       c -= ('a' - 'A');
     }
 
-    if (consensus == null || j >= consensus.length || consensus[j] == null)
+    if (consensus == null || consensus.get(j) == null)
     {
       return Color.white;
     }
@@ -62,19 +63,16 @@ public class PIDColourScheme extends ResidueColourScheme
 
     double sc = 0;
 
-    if (consensus.length <= j)
-    {
-      return Color.white;
-    }
 
     /*
      * test whether this is the consensus (or joint consensus) residue
      */
-    boolean matchesConsensus = consensus[j].getModalResidue().contains(
+    ProfileI profile = consensus.get(j);
+    boolean matchesConsensus = profile.getModalResidue().contains(
             String.valueOf(c));
     if (matchesConsensus)
     {
-      sc = consensus[j].getPercentageIdentity(ignoreGaps);
+      sc = profile.getPercentageIdentity(ignoreGaps);
 
       if (!Comparison.isGap(c))
       {
index 31b8320..f6b7c5e 100755 (executable)
@@ -23,6 +23,7 @@ package jalview.schemes;
 import jalview.analysis.Conservation;
 import jalview.datamodel.AnnotatedCollectionI;
 import jalview.datamodel.ProfileI;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.SequenceCollectionI;
 import jalview.datamodel.SequenceI;
 import jalview.util.ColorUtils;
@@ -54,7 +55,7 @@ public class ResidueColourScheme implements ColourSchemeI
   /*
    * Consensus data indexed by column
    */
-  ProfileI[] consensus;
+  ProfilesI consensus;
 
   /*
    * Conservation string as a char array 
@@ -182,19 +183,20 @@ public class ResidueColourScheme implements ColourSchemeI
       residue -= ('a' - 'A');
     }
 
-    if (consensus == null || consensus.length < column
-            || consensus[column] == null)
+    if (consensus == null)
     {
       return false;
     }
 
+    ProfileI profile = consensus.get(column);
+
     /*
      * test whether this is the consensus (or joint consensus) residue
      */
-    if (consensus[column].getModalResidue().contains(
-            String.valueOf(residue)))
+    if (profile != null
+            && profile.getModalResidue().contains(String.valueOf(residue)))
     {
-      if (consensus[column].getPercentageIdentity(ignoreGaps) >= threshold)
+      if (profile.getPercentageIdentity(ignoreGaps) >= threshold)
       {
         return true;
       }
@@ -234,7 +236,7 @@ public class ResidueColourScheme implements ColourSchemeI
    *          DOCUMENT ME!
    */
   @Override
-  public void setConsensus(ProfileI[] consensus)
+  public void setConsensus(ProfilesI consensus)
   {
     if (consensus == null)
     {
index 57258ef..438eaf8 100644 (file)
@@ -36,7 +36,7 @@ import jalview.datamodel.Annotation;
 import jalview.datamodel.CigarArray;
 import jalview.datamodel.ColumnSelection;
 import jalview.datamodel.HiddenSequences;
-import jalview.datamodel.ProfileI;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.SearchResults;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceCollectionI;
@@ -701,7 +701,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   /**
    * results of alignment consensus analysis for visible portion of view
    */
-  protected ProfileI[] hconsensus = null;
+  protected ProfilesI hconsensus = null;
 
   /**
    * results of cDNA complement consensus visible portion of view
@@ -735,7 +735,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   }
 
   @Override
-  public void setSequenceConsensusHash(ProfileI[] hconsensus)
+  public void setSequenceConsensusHash(ProfilesI hconsensus)
   {
     this.hconsensus = hconsensus;
   }
@@ -747,7 +747,7 @@ public abstract class AlignmentViewport implements AlignViewportI,
   }
 
   @Override
-  public ProfileI[] getSequenceConsensusHash()
+  public ProfilesI getSequenceConsensusHash()
   {
     return hconsensus;
   }
index 2b11477..debe45d 100644 (file)
@@ -26,7 +26,7 @@ import jalview.api.AlignmentViewPanel;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.Annotation;
-import jalview.datamodel.ProfileI;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.SequenceI;
 import jalview.schemes.ColourSchemeI;
 
@@ -124,10 +124,11 @@ public class ConsensusThread extends AlignCalcWorker
    */
   protected void computeConsensus(AlignmentI alignment)
   {
-    ProfileI[] hconsensus = new ProfileI[alignment.getWidth()];
 
     SequenceI[] aseqs = getSequences();
-    AAFrequency.calculate(aseqs, 0, alignment.getWidth(), hconsensus, true);
+    int width = alignment.getWidth();
+    ProfilesI hconsensus = AAFrequency.calculate(aseqs, width, 0,
+            width, true);
 
     alignViewport.setSequenceConsensusHash(hconsensus);
     setColourSchemeConsensus(hconsensus);
@@ -144,7 +145,7 @@ public class ConsensusThread extends AlignCalcWorker
   /**
    * @param hconsensus
    */
-  protected void setColourSchemeConsensus(ProfileI[] hconsensus)
+  protected void setColourSchemeConsensus(ProfilesI hconsensus)
   {
     ColourSchemeI globalColourScheme = alignViewport
             .getGlobalColourScheme();
@@ -177,7 +178,7 @@ public class ConsensusThread extends AlignCalcWorker
   public void updateResultAnnotation(boolean immediate)
   {
     AlignmentAnnotation consensus = getConsensusAnnotation();
-    ProfileI[] hconsensus = (ProfileI[]) getViewportConsensus();
+    ProfilesI hconsensus = (ProfilesI) getViewportConsensus();
     if (immediate || !calcMan.isWorking(this) && consensus != null
             && hconsensus != null)
     {
@@ -195,11 +196,14 @@ public class ConsensusThread extends AlignCalcWorker
    *          the computed consensus data
    */
   protected void deriveConsensus(AlignmentAnnotation consensusAnnotation,
-          ProfileI[] hconsensus)
+          ProfilesI hconsensus)
   {
+
     long nseq = getSequences().length;
-    AAFrequency.completeConsensus(consensusAnnotation, hconsensus, 0,
-            hconsensus.length, alignViewport.isIgnoreGapsConsensus(),
+    AAFrequency.completeConsensus(consensusAnnotation, hconsensus,
+            hconsensus.getStartColumn(),
+            hconsensus.getEndColumn() + 1,
+            alignViewport.isIgnoreGapsConsensus(),
             alignViewport.isShowSequenceLogo(), nseq);
   }
 
@@ -208,7 +212,7 @@ public class ConsensusThread extends AlignCalcWorker
    * 
    * @return
    */
-  protected Object[] getViewportConsensus()
+  protected Object getViewportConsensus()
   {
     // TODO convert ComplementConsensusThread to use Profile
     return alignViewport.getSequenceConsensusHash();
index 1c04b8e..58601a9 100644 (file)
@@ -26,6 +26,7 @@ import static org.testng.AssertJUnit.assertNull;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.Annotation;
 import jalview.datamodel.ProfileI;
+import jalview.datamodel.ProfilesI;
 import jalview.datamodel.Sequence;
 import jalview.datamodel.SequenceI;
 
@@ -41,12 +42,12 @@ public class AAFrequencyTest
     SequenceI seq3 = new Sequence("Seq3", "C---G");
     SequenceI seq4 = new Sequence("Seq4", "CA--t");
     SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
-    ProfileI[] result = new ProfileI[seq1.getLength()];
-
-    AAFrequency.calculate(seqs, 0, seq1.getLength(), result, false);
+    int width = seq1.getLength();
+    ProfilesI result = AAFrequency.calculate(seqs, width, 0, width,
+            false);
 
     // col 0 is 100% C
-    ProfileI col = result[0];
+    ProfileI col = result.get(0);
     assertEquals(100f, col.getPercentageIdentity(false));
     assertEquals(100f, col.getPercentageIdentity(true));
     assertEquals(4, col.getMaxCount());
@@ -54,28 +55,28 @@ public class AAFrequencyTest
     assertNull(col.getCounts());
 
     // col 1 is 75% A
-    col = result[1];
+    col = result.get(1);
     assertEquals(75f, col.getPercentageIdentity(false));
     assertEquals(100f, col.getPercentageIdentity(true));
     assertEquals(3, col.getMaxCount());
     assertEquals("A", col.getModalResidue());
 
     // col 2 is 50% G 50% C or 25/25 counting gaps
-    col = result[2];
+    col = result.get(2);
     assertEquals(25f, col.getPercentageIdentity(false));
     assertEquals(50f, col.getPercentageIdentity(true));
     assertEquals(1, col.getMaxCount());
     assertEquals("CG", col.getModalResidue());
 
     // col 3 is all gaps
-    col = result[3];
+    col = result.get(3);
     assertEquals(0f, col.getPercentageIdentity(false));
     assertEquals(0f, col.getPercentageIdentity(true));
     assertEquals(0, col.getMaxCount());
     assertEquals("", col.getModalResidue());
 
     // col 4 is 75% T 25% G
-    col = result[4];
+    col = result.get(4);
     assertEquals(75f, col.getPercentageIdentity(false));
     assertEquals(75f, col.getPercentageIdentity(true));
     assertEquals(3, col.getMaxCount());
@@ -90,26 +91,27 @@ public class AAFrequencyTest
     SequenceI seq3 = new Sequence("Seq3", "C--G");
     SequenceI seq4 = new Sequence("Seq4", "CA-t");
     SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
-    ProfileI[] result = new ProfileI[seq1.getLength()];
+    int width = seq1.getLength();
+    ProfilesI result = AAFrequency.calculate(seqs, width, 0, width,
+            true);
 
-    AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true);
-    ProfileI profile = result[0];
+    ProfileI profile = result.get(0);
     assertEquals(4, profile.getCounts().getCount('C'));
     assertEquals(4, profile.getHeight());
     assertEquals(4, profile.getNonGapped());
 
-    profile = result[1];
+    profile = result.get(1);
     assertEquals(3, profile.getCounts().getCount('A'));
     assertEquals(4, profile.getHeight());
     assertEquals(3, profile.getNonGapped());
 
-    profile = result[2];
+    profile = result.get(2);
     assertEquals(1, profile.getCounts().getCount('C'));
     assertEquals(1, profile.getCounts().getCount('G'));
     assertEquals(4, profile.getHeight());
     assertEquals(2, profile.getNonGapped());
 
-    profile = result[3];
+    profile = result.get(3);
     assertEquals(3, profile.getCounts().getCount('T'));
     assertEquals(1, profile.getCounts().getCount('G'));
     assertEquals(4, profile.getHeight());
@@ -124,15 +126,16 @@ public class AAFrequencyTest
     SequenceI seq3 = new Sequence("Seq3", "C--G");
     SequenceI seq4 = new Sequence("Seq4", "CA-t");
     SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
-    ProfileI[] result = new ProfileI[seq1.getLength()];
 
-    // ensure class loaded and initialized
-    AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true);
+    // ensure class loaded and initialised
+    int width = seq1.getLength();
+    AAFrequency.calculate(seqs, width, 0, width, true);
+
     int reps = 100000;
     long start = System.currentTimeMillis();
     for (int i = 0; i < reps; i++)
     {
-      AAFrequency.calculate(seqs, 0, seq1.getLength(), result, true);
+      AAFrequency.calculate(seqs, width, 0, width, true);
     }
     System.out.println(System.currentTimeMillis() - start);
   }
@@ -154,11 +157,11 @@ public class AAFrequencyTest
     SequenceI seq3 = new Sequence("Seq3", "C---G");
     SequenceI seq4 = new Sequence("Seq4", "CA--t");
     SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
-    ProfileI[] profiles = new ProfileI[seq1.getLength()];
-    AAFrequency.calculate(seqs, 0, seq1.getLength(), profiles, true);
+    int width = seq1.getLength();
+    ProfilesI profiles = AAFrequency.calculate(seqs, width, 0, width, true);
 
     AlignmentAnnotation consensus = new AlignmentAnnotation("Consensus",
-            "PID", new Annotation[seq1.getLength()]);
+            "PID", new Annotation[width]);
     AAFrequency
             .completeConsensus(consensus, profiles, 0, 5, false, true, 4);
 
@@ -195,11 +198,11 @@ public class AAFrequencyTest
     SequenceI seq3 = new Sequence("Seq3", "C---G");
     SequenceI seq4 = new Sequence("Seq4", "CA--t");
     SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3, seq4 };
-    ProfileI[] profiles = new ProfileI[seq1.getLength()];
-    AAFrequency.calculate(seqs, 0, seq1.getLength(), profiles, true);
+    int width = seq1.getLength();
+    ProfilesI profiles = AAFrequency.calculate(seqs, width, 0, width, true);
   
     AlignmentAnnotation consensus = new AlignmentAnnotation("Consensus",
-            "PID", new Annotation[seq1.getLength()]);
+            "PID", new Annotation[width]);
     AAFrequency
             .completeConsensus(consensus, profiles, 0, 5, true, false, 4);
   
index a96a2a8..1392157 100644 (file)
@@ -35,7 +35,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_disulfideBond()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     sb.append("123456");
     SequenceFeature sf = new SequenceFeature("disulfide bond", "desc", 1,
             3, 1.2f, "group");
@@ -60,7 +60,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_status()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3,
             Float.NaN, "group");
     sf.setStatus("Confirmed");
@@ -73,7 +73,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_withScore()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3, 1.3f,
             "group");
 
@@ -106,7 +106,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_noScore()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3,
             Float.NaN, "group");
 
@@ -118,7 +118,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_clinicalSignificance()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3,
             Float.NaN, "group");
     sf.setValue("clinical_significance", "Benign");
@@ -131,7 +131,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_withScoreStatusClinicalSignificance()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "Fe2-S", 1, 3, 1.3f,
             "group");
     sf.setStatus("Confirmed");
@@ -148,7 +148,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_DescEqualsType()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL", "METAL", 1, 3,
             Float.NaN, "group");
 
@@ -167,7 +167,7 @@ public class SequenceAnnotationReportTest
   public void testAppendFeature_stripHtml()
   {
     SequenceAnnotationReport sar = new SequenceAnnotationReport(null);
-    StringBuffer sb = new StringBuffer();
+    StringBuilder sb = new StringBuilder();
     SequenceFeature sf = new SequenceFeature("METAL",
             "<html><body>hello<em>world</em></body></html>", 1, 3,
             Float.NaN, "group");
index 318ba3f..c7c558d 100644 (file)
@@ -6,6 +6,7 @@ import static org.testng.AssertJUnit.assertTrue;
 
 import jalview.datamodel.Profile;
 import jalview.datamodel.ProfileI;
+import jalview.datamodel.Profiles;
 
 import java.awt.Color;
 
@@ -23,13 +24,13 @@ public class ResidueColourSchemeTest
      * SR-T
      * SR-T
      */
-    ProfileI[] profiles = new ProfileI[4]; 
+    ProfileI[] profiles = new ProfileI[4];
     profiles[0] = new Profile(4, 0, 2, "AS");
     profiles[1] = new Profile(4, 0, 4, "R");
     profiles[2] = new Profile(4, 4, 0, "");
     profiles[3] = new Profile(4, 1, 2, "T");
     ResidueColourScheme rcs = new ResidueColourScheme();
-    rcs.setConsensus(profiles);
+    rcs.setConsensus(new Profiles(profiles));
     
     /*
      * no threshold