JAL-192 ‘efficiently’ locate visible bounds for a sequence (needs scalability testing)
authorJim Procter <jprocter@issues.jalview.org>
Fri, 29 Apr 2016 09:41:46 +0000 (10:41 +0100)
committerJim Procter <jprocter@issues.jalview.org>
Fri, 29 Apr 2016 09:41:46 +0000 (10:41 +0100)
src/jalview/datamodel/ColumnSelection.java
test/jalview/datamodel/ColumnSelectionTest.java

index e28a6b4..c062884 100644 (file)
@@ -20,6 +20,7 @@
  */
 package jalview.datamodel;
 
+import jalview.util.Comparison;
 import jalview.util.ShiftList;
 import jalview.viewmodel.annotationfilter.AnnotationFilterParameter;
 import jalview.viewmodel.annotationfilter.AnnotationFilterParameter.SearchableAnnotationField;
@@ -1079,6 +1080,76 @@ public class ColumnSelection
   }
 
   /**
+   * Locate the first and last position visible for this sequence. if seq isn't
+   * visible then return the position of the left and right of the hidden
+   * boundary region
+   * 
+   * @param seq
+   * @return int[] { visible start, visible end, first seqpos, last seqpos }
+   */
+  public int[] locateVisibleBoundsOfSequence(SequenceI seq)
+  {
+    int fpos=seq.getStart(),lpos= seq.getEnd();
+    int start = 0;
+    int end = seq.getLength();
+    
+    if (hiddenColumns == null || hiddenColumns.size() == 0)
+    {
+      return new int[] { seq.findIndex(fpos), seq.findIndex(lpos), fpos,
+          lpos };
+    }
+
+    // Simply walk along the sequence whilst watching for hidden column
+    // boundaries
+    List<int[]> regions = getHiddenColumns();
+    int spos = fpos, lastvispos = -1, rcount = 0, hideStart = seq
+            .getLength(), hideEnd = -1;
+    int visPrev = 0, visNext = 0, base = 0;
+    boolean foundStart = false;
+    for (int p = 0, pLen = seq.getLength(); spos <= seq.getEnd()
+            && p < pLen; p++)
+    {
+      if (!Comparison.isGap(seq.getCharAt(p)))
+      {
+        // update hidden region start/end
+        while (hideEnd < p && rcount < regions.size())
+        {
+          int[] region = regions.get(rcount++);
+          visNext += region[1] + 1 - region[0];
+          visPrev = visNext-1;
+          hideStart = region[0];
+          hideEnd = region[1];
+        }
+        if (hideEnd < p)
+        {
+          hideStart = seq.getLength();
+        }
+        // update visible boundary for sequence
+        if (p < hideStart)
+        {
+          if (!foundStart)
+          {
+            fpos = spos;
+            start = p;
+            foundStart = true;
+          }
+          lastvispos = p;
+          lpos = spos;
+        }
+        // look for next sequence position
+        spos++;
+      }
+    }
+    if (foundStart)
+    {
+      return new int[] { findColumnPosition(start),
+          findColumnPosition(lastvispos), fpos, lpos };
+    }
+    // otherwise, sequence was completely hidden
+    return new int[] { visPrev, visNext, 0, 0 };
+  }
+
+  /**
    * delete any columns in alignmentAnnotation that are hidden (including
    * sequence associated annotation).
    * 
index 0245b15..0e7678b 100644 (file)
@@ -93,6 +93,26 @@ public class ColumnSelectionTest
     assertEquals(2, cs.findColumnPosition(5));
   }
 
+  /**
+   * Test the code used to locate the reference sequence ruler origin
+   */
+  @Test(groups = { "Functional" })
+  public void testLocateVisibleBoundsofSequence()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    SequenceI seq = new Sequence("RefSeq", "-A-SD-ASD--E");
+    assertEquals(2, seq.findIndex(seq.getStart()));
+    assertEquals(Arrays.toString(new int[] { seq.findIndex(seq.getStart()),
+        seq.findIndex(seq.getEnd()), seq.getStart(), seq.getEnd() }),
+            Arrays.toString(cs.locateVisibleBoundsOfSequence(seq)));
+    cs.hideColumns(1, 3);
+    cs.hideColumns(6, 11);
+    assertEquals("-D",
+            cs.getVisibleSequenceStrings(0, 5, new SequenceI[] { seq })[0]);
+    assertEquals(Arrays.toString(new int[] { 1, 1, 3, 3 }),
+            Arrays.toString(cs.locateVisibleBoundsOfSequence(seq)));
+  }
+
   @Test(groups = { "Functional" })
   public void testHideColumns()
   {