JAL-2544 check feature overlaps selection region
[jalview.git] / src / jalview / analysis / AlignmentSorter.java
index a3810da..693e794 100755 (executable)
@@ -20,6 +20,8 @@
  */
 package jalview.analysis;
 
+import jalview.analysis.scoremodels.PIDModel;
+import jalview.analysis.scoremodels.SimilarityParams;
 import jalview.datamodel.AlignmentAnnotation;
 import jalview.datamodel.AlignmentI;
 import jalview.datamodel.AlignmentOrder;
@@ -27,7 +29,6 @@ import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.datamodel.SequenceNode;
-import jalview.util.Comparison;
 import jalview.util.MessageManager;
 import jalview.util.QuickSort;
 
@@ -87,46 +88,29 @@ public class AlignmentSorter
   private static boolean sortLengthAscending;
 
   /**
-   * Sort by Percentage Identity w.r.t. s
+   * Sorts sequences in the alignment by Percentage Identity with the given
+   * reference sequence, sorting the highest identity to the top
    * 
    * @param align
    *          AlignmentI
    * @param s
    *          SequenceI
-   * @param tosort
-   *          sequences from align that are to be sorted.
-   */
-  public static void sortByPID(AlignmentI align, SequenceI s,
-          SequenceI[] tosort)
-  {
-    sortByPID(align, s, tosort, 0, -1);
-  }
-
-  /**
-   * Sort by Percentage Identity w.r.t. s
-   * 
-   * @param align
-   *          AlignmentI
-   * @param s
-   *          SequenceI
-   * @param tosort
-   *          sequences from align that are to be sorted.
-   * @param start
-   *          start column (0 for beginning
    * @param end
    */
-  public static void sortByPID(AlignmentI align, SequenceI s,
-          SequenceI[] tosort, int start, int end)
+  public static void sortByPID(AlignmentI align, SequenceI s)
   {
     int nSeq = align.getHeight();
 
     float[] scores = new float[nSeq];
     SequenceI[] seqs = new SequenceI[nSeq];
+    String refSeq = s.getSequenceAsString();
 
+    SimilarityParams pidParams = new SimilarityParams(true, true, true,
+            true);
     for (int i = 0; i < nSeq; i++)
     {
-      scores[i] = Comparison.PID(align.getSequenceAt(i)
-              .getSequenceAsString(), s.getSequenceAsString());
+      scores[i] = (float) PIDModel.computePID(align.getSequenceAt(i)
+              .getSequenceAsString(), refSeq, pidParams);
       seqs[i] = align.getSequenceAt(i);
     }
 
@@ -827,17 +811,23 @@ public class AlignmentSorter
       for (int f = 0; f < sf.length; f++)
       {
         // filter for selection criteria
-        if (
-        // ignore features outwith alignment start-stop positions.
-        (sf[f].end < sstart || sf[f].begin > sstop) ||
-        // or ignore based on selection criteria
-                (featureLabels != null && !AlignmentSorter
-                        .containsIgnoreCase(sf[f].type, featureLabels))
-                || (groupLabels != null
-                // problem here: we cannot eliminate null feature group features
-                && (sf[f].getFeatureGroup() != null && !AlignmentSorter
-                        .containsIgnoreCase(sf[f].getFeatureGroup(),
-                                groupLabels))))
+        SequenceFeature feature = sf[f];
+
+        /*
+         * double-check feature overlaps columns (JAL-2544)
+         * (could avoid this with a findPositions(fromCol, toCol) method)
+         * findIndex returns base 1 column values, startCol/endCol are base 0
+         */
+        boolean noOverlap = seqs[i].findIndex(feature.getBegin()) > stop + 1
+                || seqs[i].findIndex(feature.getEnd()) < start + 1;
+        boolean skipFeatureType = featureLabels != null
+                && !AlignmentSorter.containsIgnoreCase(feature.type,
+                        featureLabels);
+        boolean skipFeatureGroup = groupLabels != null
+                && (feature.getFeatureGroup() != null && !AlignmentSorter
+                        .containsIgnoreCase(feature.getFeatureGroup(),
+                                groupLabels));
+        if (noOverlap || skipFeatureType || skipFeatureGroup)
         {
           // forget about this feature
           sf[f] = null;
@@ -846,7 +836,7 @@ public class AlignmentSorter
         else
         {
           // or, also take a look at the scores if necessary.
-          if (!ignoreScore && !Float.isNaN(sf[f].getScore()))
+          if (!ignoreScore && !Float.isNaN(feature.getScore()))
           {
             if (seqScores[i] == 0)
             {
@@ -854,7 +844,7 @@ public class AlignmentSorter
             }
             seqScores[i]++;
             hasScore[i] = true;
-            scores[i] += sf[f].getScore(); // take the first instance of this
+            scores[i] += feature.getScore(); // take the first instance of this
             // score.
           }
         }