update author list in license for (JAL-826)
[jalview.git] / src / jalview / analysis / Conservation.java
index 31a4b66..8e3b6e4 100755 (executable)
@@ -1,23 +1,23 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
- * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
+ * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
  * 
- * This program 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 2
- * of the License, or (at your option) any later version.
+ * This file is part of Jalview.
  * 
- * This program 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.
+ * 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.
  * 
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+ * 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.awt.Color;
 import java.util.*;
 
 import jalview.datamodel.*;
@@ -72,23 +72,21 @@ public class Conservation
    * Creates a new Conservation object.
    * 
    * @param name
-   *                Name of conservation
+   *          Name of conservation
    * @param propHash
-   *                hash of properties for each symbol
+   *          hash of properties for each symbol
    * @param threshold
-   *                to count the residues in residueHash(). commonly used value
-   *                is 3
+   *          to count the residues in residueHash(). commonly used value is 3
    * @param sequences
-   *                sequences to be used in calculation
+   *          sequences to be used in calculation
    * @param start
-   *                start residue position
+   *          start residue position
    * @param end
-   *                end residue position
+   *          end residue position
    */
   public Conservation(String name, Hashtable propHash, int threshold,
           Vector sequences, int start, int end)
   {
-
     this.name = name;
     this.propHash = propHash;
     this.threshold = threshold;
@@ -101,7 +99,7 @@ public class Conservation
     int s, sSize = sequences.size();
     SequenceI[] sarray = new SequenceI[sSize];
     this.sequences = sarray;
-
+    try {
     for (s = 0; s < sSize; s++)
     {
       sarray[s] = (SequenceI) sequences.elementAt(s);
@@ -110,6 +108,12 @@ public class Conservation
         maxLength = sarray[s].getLength();
       }
     }
+    } catch (ArrayIndexOutOfBoundsException ex)
+    {
+      // bail - another thread has modified the sequence array, so the current calculation is probably invalid. 
+      this.sequences=new SequenceI[0];
+      maxLength=0;
+    }
   }
 
   /**
@@ -272,7 +276,9 @@ public class Conservation
         }
       }
 
-      total[i - start] = resultHash;
+      if (total.length>0) {
+        total[i - start] = resultHash;
+      }
     }
   }
 
@@ -331,10 +337,10 @@ public class Conservation
    * Calculates the conservation sequence
    * 
    * @param consflag
-   *                if true, poitiveve conservation; false calculates negative
-   *                conservation
+   *          if true, poitiveve conservation; false calculates negative
+   *          conservation
    * @param percentageGaps
-   *                commonly used value is 25
+   *          commonly used value is 25
    */
   public void verdict(boolean consflag, float percentageGaps)
   {
@@ -488,9 +494,9 @@ public class Conservation
    * Calculates the quality of the set of sequences
    * 
    * @param start
-   *                Start residue
+   *          Start residue
    * @param end
-   *                End residue
+   *          End residue
    */
   public void findQuality(int start, int end)
   {
@@ -591,4 +597,101 @@ public class Conservation
     qualityRange[0] = new Double(0);
     qualityRange[1] = new Double(newmax);
   }
+
+  /**
+   * complete the given consensus and quuality annotation rows. Note: currently
+   * this method will enlarge the given annotation row if it is too small,
+   * otherwise will leave its length unchanged.
+   * 
+   * @param conservation
+   *          conservation annotation row
+   * @param quality2
+   *          (optional - may be null)
+   * @param istart
+   *          first column for conservation
+   * @param alWidth
+   *          extent of conservation
+   */
+  public void completeAnnotations(AlignmentAnnotation conservation,
+          AlignmentAnnotation quality2, int istart, int alWidth)
+  {
+    char[] sequence = getConsSequence().getSequence();
+    float minR;
+    float minG;
+    float minB;
+    float maxR;
+    float maxG;
+    float maxB;
+    minR = 0.3f;
+    minG = 0.0f;
+    minB = 0f;
+    maxR = 1.0f - minR;
+    maxG = 0.9f - minG;
+    maxB = 0f - minB; // scalable range for colouring both Conservation and
+    // Quality
+
+    float min = 0f;
+    float max = 11f;
+    float qmin = 0f;
+    float qmax = 0f;
+
+    char c;
+
+    if (conservation.annotations != null
+            && conservation.annotations.length < alWidth)
+    {
+      conservation.annotations = new Annotation[alWidth];
+    }
+
+    if (quality2 != null)
+    {
+      quality2.graphMax = qualityRange[1].floatValue();
+      if (quality2.annotations != null
+              && quality2.annotations.length < alWidth)
+      {
+        quality2.annotations = new Annotation[alWidth];
+      }
+      qmin = qualityRange[0].floatValue();
+      qmax = qualityRange[1].floatValue();
+    }
+
+    for (int i = 0; i < alWidth; i++)
+    {
+      float value = 0;
+
+      c = sequence[i];
+
+      if (Character.isDigit(c))
+      {
+        value = (int) (c - '0');
+      }
+      else if (c == '*')
+      {
+        value = 11;
+      }
+      else if (c == '+')
+      {
+        value = 10;
+      }
+
+      float vprop = value - min;
+      vprop /= max;
+      conservation.annotations[i] = new Annotation(String.valueOf(c),
+              String.valueOf(value), ' ', value, new Color(minR
+                      + (maxR * vprop), minG + (maxG * vprop), minB
+                      + (maxB * vprop)));
+
+      // Quality calc
+      if (quality2 != null)
+      {
+        value = ((Double) quality.elementAt(i)).floatValue();
+        vprop = value - qmin;
+        vprop /= qmax;
+        quality2.annotations[i] = new Annotation(" ",
+                String.valueOf(value), ' ', value, new Color(minR
+                        + (maxR * vprop), minG + (maxG * vprop), minB
+                        + (maxB * vprop)));
+      }
+    }
+  }
 }