{
StringBuffer visibleSeq = new StringBuffer();
- int blockStart = start;
- int blockEnd = end;
-
- Iterator<int[]> regions = new BoundedHiddenColsIterator(start,
+ Iterator<int[]> blocks = new VisibleBlocksIterator(start,
end, false);
- while (regions.hasNext())
- {
- int[] region = regions.next();
- blockStart = Math.min(blockStart, region[1] + 1);
- blockEnd = Math.min(blockEnd, region[0]);
-
- visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd));
-
- blockStart = region[1] + 1;
- blockEnd = end;
- }
-
- if (end > blockStart)
+ while (blocks.hasNext())
{
- visibleSeq.append(seqs[i].getSequence(blockStart, end));
+ int[] block = blocks.next();
+ visibleSeq.append(seqs[i].getSequence(block[0], block[1]));
}
selections[i] = visibleSeq.toString();
// mangle the alignmentAnnotation annotation array
Vector<Annotation[]> annels = new Vector<>();
Annotation[] els = null;
- int blockStart = start;
- int blockEnd = end;
- int w = 0;
- Iterator<int[]> regions = new BoundedHiddenColsIterator(start, end,
+ int w = 0;
+
+ Iterator<int[]> blocks = new VisibleBlocksIterator(start, end,
false);
- while (regions.hasNext())
- {
- int[] region = regions.next();
- blockStart = Math.min(blockStart, region[1] + 1);
- blockEnd = Math.min(blockEnd, region[0]);
-
- els = new Annotation[blockEnd - blockStart];
- annels.addElement(els);
- System.arraycopy(alignmentAnnotation.annotations, blockStart, els, 0,
- els.length);
- w += els.length;
-
- blockStart = region[1] + 1;
- blockEnd = end;
- }
-
- if (end > blockStart)
+ int copylength;
+ int annotationLength;
+ while (blocks.hasNext())
{
- els = new Annotation[end - blockStart + 1];
- annels.addElement(els);
- if ((els.length
- + blockStart) <= alignmentAnnotation.annotations.length)
+ int[] block = blocks.next();
+
+ if (blocks.hasNext())
{
+ annotationLength = block[1] - block[0];
// copy just the visible segment of the annotation row
- System.arraycopy(alignmentAnnotation.annotations, blockStart, els,
- 0, els.length);
+ copylength = annotationLength;
}
else
{
- // copy to the end of the annotation row
- System.arraycopy(alignmentAnnotation.annotations, blockStart, els,
- 0, (alignmentAnnotation.annotations.length - blockStart));
+ annotationLength = block[1] - block[0] + 1;
+ if (annotationLength + block[0] <= alignmentAnnotation.annotations.length)
+ {
+ // copy just the visible segment of the annotation row
+ copylength = annotationLength;
+ }
+ else
+ {
+ // copy to the end of the annotation row
+ copylength = alignmentAnnotation.annotations.length - block[0];
+ }
}
- w += els.length;
+
+ els = new Annotation[annotationLength];
+ annels.addElement(els);
+ System.arraycopy(alignmentAnnotation.annotations, block[0], els, 0,
+ copylength);
+ w += annotationLength;
}
-
+
if (w != 0)
{
alignmentAnnotation.annotations = new Annotation[w];
return result;
}
}
+
+ /**
+ * An iterator which iterates over visible regions in a range.
+ */
+ private class VisibleBlocksIterator implements Iterator<int[]>
+ {
+ private List<int[]> vcontigs = new ArrayList<>();
+
+ private int currentPosition = 0;
+
+ VisibleBlocksIterator(int start, int end, boolean usecopy)
+ {
+ try
+ {
+ if (usecopy)
+ {
+ LOCK.readLock().lock();
+ }
+
+ if (hiddenColumns != null && hiddenColumns.size() > 0)
+ {
+ int blockStart = start;
+ int blockEnd = end;
+
+ // iterate until a region overlaps with [start,end]
+ int i = 0;
+ while ((i < hiddenColumns.size())
+ && (hiddenColumns.get(i)[1] < start))
+ {
+ i++;
+ }
+
+ // iterate from start to end, adding each hidden region. Positions are
+ // absolute, and all regions which *overlap* [start,end] are used.
+ while (i < hiddenColumns.size()
+ && (hiddenColumns.get(i)[0] <= end))
+ {
+ int[] region = hiddenColumns.get(i);
+
+ blockStart = Math.min(blockStart, region[1] + 1);
+ blockEnd = Math.min(blockEnd, region[0]);
+
+ int[] contig = new int[] { blockStart, blockEnd };
+ vcontigs.add(contig);
+
+ blockStart = region[1] + 1;
+ blockEnd = end;
+
+ i++;
+ }
+
+ if (end > blockStart)
+ {
+ int[] contig = new int[] { blockStart, end };
+ vcontigs.add(contig);
+ }
+ }
+ else
+ {
+ int[] contig = new int[] { start, end };
+ vcontigs.add(contig);
+ }
+ } finally
+ {
+ if (usecopy)
+ {
+ LOCK.readLock().unlock();
+ }
+ }
+ }
+
+ @Override
+ public boolean hasNext()
+ {
+ return (currentPosition < vcontigs.size());
+ }
+
+ @Override
+ public int[] next()
+ {
+ int[] result = vcontigs.get(currentPosition);
+ currentPosition++;
+ return result;
+ }
+ }
+
}