JAL-3490 Finder match across entirely gapped hidden regions
[jalview.git] / src / jalview / analysis / Finder.java
index 3cbef6d..ab71894 100644 (file)
@@ -162,35 +162,54 @@ public class Finder implements FinderI
   }
 
   /**
-   * Answers the start-end column range of the visible region of
-   * <code>sequence</code> starting at or after the given <code>column</code>.
-   * If there are no hidden columns, this just returns the remaining width of
-   * the sequence. The range is restricted to the current <code>selection</code>
-   * if there is one. Answers null if there are no visible columns at or after
-   * <code>column</code>.
+   * Answers the start-end column range of the contiguous visible regions of
+   * {@code sequence} starting at or after the given {@code column}. If there are
+   * no hidden columns, this just returns the remaining width of the sequence.
+   * Otherwise, visible columns are added as long as they are contiguous on the
+   * sequence (hidden regions only contain gaps). The range is restricted to the
+   * current {@code selection} if there is one. Answers null if there are no
+   * visible columns at or after {@code column}.
+   * 
+   * @param sequence
+   * @param column
+   * @return
    */
   protected Range getNextVisibleSequenceRegion(SequenceI sequence,
-          int column)
+          final int column)
   {
-    int seqColStart = column;
-    int seqColEnd = sequence.getLength() - 1;
-
-    /*
-     * restrict search to (next) visible column region, 
-     * in case there are hidden columns
-     */
     AlignmentI alignment = viewport.getAlignment();
     VisibleContigsIterator visibleRegions = alignment.getHiddenColumns()
             .getVisContigsIterator(column, alignment.getWidth(),
                     false);
-    int[] visible = visibleRegions.hasNext() ? visibleRegions.next() : null;
-    if (visible == null)
+    if (!visibleRegions.hasNext())
     {
-      columnIndex = seqColEnd + 1;
+      // off the end of the sequence - force search to next sequence
+      columnIndex = sequence.getLength();
       return null;
     }
-    seqColStart = Math.max(seqColStart, visible[0]);
-    seqColEnd = Math.min(seqColEnd, visible[1]);
+
+    int[] visible = visibleRegions.next();
+    int seqColStart = Math.max(column, visible[0]);
+    int seqColEnd = visible[1];
+    // end residue of region (next residue if end position is gapped)
+    int endSeqPos = sequence.findPosition(visible[1]);
+    if (Comparison.isGap(sequence.getCharAt(visible[1])))
+    {
+      endSeqPos--;
+    }
+    while (visibleRegions.hasNext())
+    {
+      visible = visibleRegions.next();
+      int startSeqPos = sequence.findPosition(visible[0]);
+      if (startSeqPos - endSeqPos > 1)
+      {
+        // this visible region is not contiguous - ignore it
+        break;
+      }
+      endSeqPos = sequence.findPosition(visible[1]);
+      seqColEnd = visible[1];
+    }
+    seqColEnd = Math.min(sequence.getLength() - 1, seqColEnd);
 
     /*
      * restrict search to selected region if there is one