+ String ungapped = AlignSeq.extractGaps(Comparison.GapChars, seqString);
+ this.seqToSearch = ungapped;
+
+ return true;
+ }
+
+ /**
+ * Returns a string consisting of only the visible residues of {@code seq} from
+ * alignment column {@ fromColumn}, restricted to the current selection region
+ * if there is one.
+ * <p>
+ * As a side-effect, also computes the mapping from the true sequence positions
+ * to the positions (1, 2, ...) of the returned sequence. This is to allow
+ * search matches in the visible sequence to be converted to sequence positions.
+ *
+ * @param seq
+ * @return
+ */
+ private String getVisibleSequence(SequenceI seq)
+ {
+ /*
+ * get start / end columns of sequence and convert to base 0
+ * (so as to match the visible column ranges)
+ */
+ int seqStartCol = seq.findIndex(seq.getStart()) - 1;
+ int seqEndCol = seq.findIndex(seq.getStart() + seq.getLength() - 1) - 1;
+ Iterator<int[]> visibleColumns = viewport.getViewAsVisibleContigs(true);
+ StringBuilder visibleSeq = new StringBuilder(seqEndCol - seqStartCol);
+ List<int[]> fromRanges = new ArrayList<>();
+
+ while (visibleColumns.hasNext())
+ {
+ int[] range = visibleColumns.next();
+ if (range[0] > seqEndCol)
+ {
+ // beyond the end of the sequence
+ break;
+ }
+ if (range[1] < seqStartCol)
+ {
+ // before the start of the sequence
+ continue;
+ }
+ String subseq = seq.getSequenceAsString(range[0], range[1] + 1);
+ String ungapped = AlignSeq.extractGaps(Comparison.GapChars, subseq);
+ visibleSeq.append(ungapped);
+ if (!ungapped.isEmpty())
+ {
+ /*
+ * visible region includes at least one non-gap character,
+ * so add the range to the mapping being constructed
+ */
+ int seqResFrom = seq.findPosition(range[0]);
+ int seqResTo = seqResFrom + ungapped.length() - 1;
+ fromRanges.add(new int[] { seqResFrom, seqResTo });
+ }