JAL-2418 source formatting
[jalview.git] / src / jalview / analysis / scoremodels / PIDModel.java
index 58667c0..f4599e8 100644 (file)
@@ -1,24 +1,45 @@
 package jalview.analysis.scoremodels;
 
+import jalview.api.AlignmentViewPanel;
 import jalview.api.analysis.PairwiseScoreModelI;
+import jalview.api.analysis.ScoreModelI;
 import jalview.api.analysis.SimilarityParamsI;
-import jalview.api.analysis.SimilarityScoreModelI;
 import jalview.datamodel.AlignmentView;
 import jalview.math.Matrix;
 import jalview.math.MatrixI;
 import jalview.util.Comparison;
 
 /**
- * A class to provide sequence pairwise similarity based on residue identity
+ * A class to provide sequence pairwise similarity based on residue identity.
+ * Instances of this class are immutable and thread-safe, so the same object is
+ * returned from calls to getInstance().
  */
-public class PIDModel implements SimilarityScoreModelI,
-        PairwiseScoreModelI
+public class PIDModel extends SimilarityScoreModel
+        implements PairwiseScoreModelI
 {
+  private static final String NAME = "PID";
+
+  /**
+   * Constructor
+   */
+  public PIDModel()
+  {
+  }
 
   @Override
   public String getName()
   {
-    return "% Identity (PID)";
+    return NAME;
+  }
+
+  /**
+   * Answers null for description. If a display name is needed, use getName() or
+   * an internationalized string built from the name.
+   */
+  @Override
+  public String getDescription()
+  {
+    return null;
   }
 
   @Override
@@ -61,12 +82,43 @@ public class PIDModel implements SimilarityScoreModelI,
     return c;
   }
 
+  /**
+   * Computes similarity scores based on pairwise percentage identity of
+   * sequences. For consistency with Jalview 2.10.1's SeqSpace mode PCA
+   * calculation, the percentage scores are rescaled to the width of the
+   * sequences (as if counts of identical residues). This method is thread-safe.
+   */
   @Override
-  public MatrixI findSimilarities(AlignmentView seqData)
+  public MatrixI findSimilarities(AlignmentView seqData,
+          SimilarityParamsI options)
   {
-    // TODO reuse code in ScoreMatrix instead somehow
-    String[] seqs = seqData.getSequenceStrings(' ');
-    return findSimilarities(seqs, SimilarityParams.Jalview);
+    String[] seqs = seqData.getSequenceStrings(Comparison.GAP_DASH);
+
+    MatrixI result = findSimilarities(seqs, options);
+
+    result.multiply(seqData.getWidth() / 100d);
+
+    return result;
+  }
+
+  /**
+   * A distance score is computed in the usual way (by reversing the range of
+   * the similarity score results), and then rescaled to percentage values
+   * (reversing the rescaling to count values done in findSimilarities). This
+   * method is thread-safe.
+   */
+  @Override
+  public MatrixI findDistances(AlignmentView seqData,
+          SimilarityParamsI options)
+  {
+    MatrixI result = super.findDistances(seqData, options);
+
+    if (seqData.getWidth() != 0)
+    {
+      result.multiply(100d / seqData.getWidth());
+    }
+
+    return result;
   }
 
   /**
@@ -80,6 +132,7 @@ public class PIDModel implements SimilarityScoreModelI,
   protected MatrixI findSimilarities(String[] seqs,
           SimilarityParamsI options)
   {
+    // TODO reuse code in ScoreMatrix instead somehow
     double[][] values = new double[seqs.length][];
     for (int row = 0; row < seqs.length; row++)
     {
@@ -102,7 +155,7 @@ public class PIDModel implements SimilarityScoreModelI,
    * @param options
    * @return
    */
-  protected double computePID(String seq1, String seq2,
+  public static double computePID(String seq1, String seq2,
           SimilarityParamsI options)
   {
     int len1 = seq1.length();
@@ -123,7 +176,7 @@ public class PIDModel implements SimilarityScoreModelI,
         {
           break;
         }
-        if (options.denominatorIncludesGaps())
+        if (options.includeGaps())
         {
           divideBy++;
         }
@@ -158,7 +211,7 @@ public class PIDModel implements SimilarityScoreModelI,
          * gap-residue: include if options say so, 
          * count as match if options say so
          */
-        if (options.denominatorIncludesGaps())
+        if (options.includeGaps())
         {
           divideBy++;
         }
@@ -181,4 +234,10 @@ public class PIDModel implements SimilarityScoreModelI,
 
     return divideBy == 0 ? 0D : 100D * total / divideBy;
   }
+
+  @Override
+  public ScoreModelI getInstance(AlignmentViewPanel avp)
+  {
+    return this;
+  }
 }