import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
+import java.util.Iterator;
import java.util.List;
public class Dna
private final String[] seqstring;
- private final List<int[]> contigs;
+ private final Iterator<int[]> contigs;
private final char gapChar;
* @param viewport
* @param visibleContigs
*/
- public Dna(AlignViewportI viewport, List<int[]> visibleContigs)
+ public Dna(AlignViewportI viewport, Iterator<int[]> visibleContigs)
{
this.selection = Arrays.asList(viewport.getSequenceSelection());
this.seqstring = viewport.getViewAsString(true);
ShiftList vismapping = new ShiftList(); // map from viscontigs to seqstring
// intervals
int vc = 0;
- int[] scontigs = new int[contigs.size() * 2];
+
int npos = 0;
int[] lastregion = null;
- for (int[] region : contigs)
+ while (contigs.hasNext())
{
+ int[] region = contigs.next();
if (lastregion == null)
{
vismapping.addShift(npos, region[0]);
vismapping.addShift(npos, region[0] - lastregion[1] + 1);
}
lastregion = region;
+ vc++;
+ }
+ int[] scontigs = new int[vc];
+ vc = 0;
+ while (contigs.hasNext())
+ {
+ int[] region = contigs.next();
scontigs[vc] = region[0];
scontigs[vc + 1] = region[1];
vc++;
return copy;
}
- /**
- * return all visible segments between the given start and end boundaries
- *
- * @param start
- * (first column inclusive from 0)
- * @param end
- * (last column - not inclusive)
- * @return List<int[]> {[i_start, i_end], ..} where intervals lie in
- * start<=i_start<=i_end<end
- */
- public List<int[]> getVisibleContigs(int start, int end)
- {
- try
- {
- LOCK.readLock().lock();
- List<int[]> vcontigs = new ArrayList<>();
- if (hiddenColumns != null && hiddenColumns.size() > 0)
- {
- int vstart = start;
- int hideStart;
- int hideEnd;
-
- for (int[] region : hiddenColumns)
- {
- hideStart = region[0];
- hideEnd = region[1];
-
- // navigate to start
- if (hideEnd < vstart)
- {
- continue;
- }
- if (hideStart > vstart)
- {
- int[] contig = new int[] { vstart, hideStart - 1 };
- vcontigs.add(contig);
- }
- vstart = hideEnd + 1;
-
- // exit if we're past the end
- if (vstart >= end)
- {
- break;
- }
- }
-
- if (vstart < end)
- {
- int[] contig = new int[] { vstart, end - 1 };
- vcontigs.add(contig);
- }
- }
- else
- {
- int[] contig = new int[] { start, end - 1 };
- vcontigs.add(contig);
- }
- return vcontigs;
- } finally
- {
- LOCK.readLock().unlock();
- }
- }
-
public String[] getVisibleSequenceStrings(int start, int end,
SequenceI[] seqs)
{
int blockStart = start;
int blockEnd = end;
- int hideStart;
- int hideEnd;
- for (int[] region : hiddenColumns)
+ Iterator<int[]> regions = new BoundedHiddenColsIterator(start,
+ end, false);
+ while (regions.hasNext())
{
- hideStart = region[0];
- hideEnd = region[1];
-
- if (hideStart < start)
- {
- continue;
- }
-
- blockStart = Math.min(blockStart, hideEnd + 1);
- blockEnd = Math.min(blockEnd, hideStart);
-
- if (blockStart > blockEnd)
- {
- break;
- }
+ 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 = hideEnd + 1;
+ blockStart = region[1] + 1;
blockEnd = end;
}
try
{
LOCK.readLock().lock();
- if (alignmentAnnotation.annotations == null)
- {
- return;
- }
- if (start == end && end == -1)
- {
- start = 0;
- end = alignmentAnnotation.annotations.length;
- }
- if (hiddenColumns != null && hiddenColumns.size() > 0)
- {
- // then mangle the alignmentAnnotation annotation array
- Vector<Annotation[]> annels = new Vector<>();
- Annotation[] els = null;
- int blockStart = start;
- int blockEnd = end;
- int hideStart;
- int hideEnd;
- int w = 0;
-
- for (int[] region : hiddenColumns)
- {
- hideStart = region[0];
- hideEnd = region[1];
- if (hideStart < start)
- {
- continue;
- }
-
- blockStart = Math.min(blockStart, hideEnd + 1);
- blockEnd = Math.min(blockEnd, hideStart);
-
- if (blockStart > blockEnd)
- {
- break;
- }
+ int startFrom = start;
+ int endAt = end;
- els = new Annotation[blockEnd - blockStart];
- annels.addElement(els);
- System.arraycopy(alignmentAnnotation.annotations, blockStart, els,
- 0, els.length);
- w += els.length;
- blockStart = hideEnd + 1;
- blockEnd = end;
+ if (alignmentAnnotation.annotations != null)
+ {
+ if (start == end && end == -1)
+ {
+ startFrom = 0;
+ endAt = alignmentAnnotation.annotations.length;
}
-
- if (end > blockStart)
+ if (hiddenColumns != null && hiddenColumns.size() > 0)
{
- els = new Annotation[end - blockStart + 1];
- annels.addElement(els);
- if ((els.length
- + blockStart) <= alignmentAnnotation.annotations.length)
- {
- // copy just the visible segment of the annotation row
- System.arraycopy(alignmentAnnotation.annotations, blockStart,
- els, 0, els.length);
- }
- else
- {
- // copy to the end of the annotation row
- System.arraycopy(alignmentAnnotation.annotations, blockStart,
- els, 0,
- (alignmentAnnotation.annotations.length - blockStart));
- }
- w += els.length;
+ removeHiddenAnnotation(startFrom, endAt, alignmentAnnotation);
}
- if (w == 0)
+ else
{
- return;
+ alignmentAnnotation.restrict(startFrom, endAt);
}
+ }
+ } finally
+ {
+ LOCK.readLock().unlock();
+ }
+ }
- alignmentAnnotation.annotations = new Annotation[w];
- w = 0;
+ private void removeHiddenAnnotation(int start, int end,
+ AlignmentAnnotation alignmentAnnotation)
+ {
+ // 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,
+ false);
+ while (regions.hasNext())
+ {
+ int[] region = regions.next();
+ blockStart = Math.min(blockStart, region[1] + 1);
+ blockEnd = Math.min(blockEnd, region[0]);
- for (Annotation[] chnk : annels)
- {
- System.arraycopy(chnk, 0, alignmentAnnotation.annotations, w,
- chnk.length);
- w += chnk.length;
- }
+ 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)
+ {
+ els = new Annotation[end - blockStart + 1];
+ annels.addElement(els);
+ if ((els.length
+ + blockStart) <= alignmentAnnotation.annotations.length)
+ {
+ // copy just the visible segment of the annotation row
+ System.arraycopy(alignmentAnnotation.annotations, blockStart, els,
+ 0, els.length);
}
else
{
- alignmentAnnotation.restrict(start, end);
+ // copy to the end of the annotation row
+ System.arraycopy(alignmentAnnotation.annotations, blockStart, els,
+ 0, (alignmentAnnotation.annotations.length - blockStart));
}
- } finally
+ w += els.length;
+ }
+
+ if (w != 0)
{
- LOCK.readLock().unlock();
+ alignmentAnnotation.annotations = new Annotation[w];
+
+ w = 0;
+ for (Annotation[] chnk : annels)
+ {
+ System.arraycopy(chnk, 0, alignmentAnnotation.annotations, w,
+ chnk.length);
+ w += chnk.length;
+ }
}
}
}
}
+ /**
+ * Return an iterator over the hidden regions
+ */
public Iterator<int[]> iterator()
{
if (hiddenColumns != null)
}
}
+ /**
+ * Return a bounded iterator over the hidden regions
+ *
+ * @param start
+ * position to start from (inclusive, absolute column position)
+ * @param end
+ * position to end at (inclusive, absolute column position)
+ * @return
+ */
public Iterator<int[]> getBoundedIterator(int start, int end)
{
return new BoundedHiddenColsIterator(start, end, true);
}
+ /**
+ * Return a bounded iterator over the *visible* start positions of hidden
+ * regions
+ *
+ * @param start
+ * position to start from (inclusive, visible column position)
+ * @param end
+ * position to end at (inclusive, visible column position)
+ */
public Iterator<Integer> getBoundedStartIterator(int start, int end)
{
return new BoundedStartRegionIterator(start, end, true);
}
+ /**
+ * Return an iterator over visible columns between the given start and end
+ * boundaries
+ *
+ * @param start
+ * first column (inclusive)
+ * @param end
+ * last column (inclusive)
+ */
public Iterator<Integer> getVisibleColsIterator(int start, int end)
{
return new VisibleColsIterator(start, end, true);
}
/**
- * An iterator which iterates over hidden column regions in a range.
+ * return an iterator over visible segments between the given start and end
+ * boundaries
*
- * @author kmourao
- *
+ * @param start
+ * (first column inclusive from 0)
+ * @param end
+ * (last column - not inclusive)
*/
- class BoundedHiddenColsIterator implements Iterator<int[]>
+ public Iterator<int[]> getVisContigsIterator(int start, int end)
+ {
+ return new VisibleContigsIterator(start, end, true);
+ }
+
+ /**
+ * An iterator which iterates over hidden column regions in a range.
+ */
+ private class BoundedHiddenColsIterator implements Iterator<int[]>
{
private int start; // start position to iterate from
}
}
- class BoundedStartRegionIterator implements Iterator<Integer>
+ /**
+ * An iterator which iterates over visible start positions of hidden column
+ * regions in a range.
+ */
+ private class BoundedStartRegionIterator implements Iterator<Integer>
{
+ // start position to iterate from
+ private int start;
- private int start; // start position to iterate from
-
- private int end; // end position to iterate to
+ // end position to iterate to
+ private int end;
// current index in hiddenColumns
private int currentPosition = 0;
return (currentPosition < positions.size());
}
+ /**
+ * Get next hidden region start position
+ *
+ * @return the start position in *visible* coordinates
+ */
@Override
public Integer next()
{
}
}
- public class VisibleColsIterator implements Iterator<Integer>
+ private class VisibleColsIterator implements Iterator<Integer>
{
private int last;
private int lasthiddenregion;
- public VisibleColsIterator(int firstcol, int lastcol, boolean useCopy)
+ VisibleColsIterator(int firstcol, int lastcol, boolean useCopy)
{
last = lastcol;
current = firstcol;
throw new UnsupportedOperationException();
}
}
+
+ /**
+ * An iterator which iterates over visible regions in a range.
+ */
+ private class VisibleContigsIterator implements Iterator<int[]>
+ {
+ private List<int[]> vcontigs = new ArrayList<>();
+
+ private int currentPosition = 0;
+
+ VisibleContigsIterator(int start, int end, boolean usecopy)
+ {
+ try
+ {
+ if (usecopy)
+ {
+ LOCK.readLock().lock();
+ }
+
+ if (hiddenColumns != null && hiddenColumns.size() > 0)
+ {
+ int vstart = start;
+ int hideStart;
+ int hideEnd;
+
+ for (int[] region : hiddenColumns)
+ {
+ hideStart = region[0];
+ hideEnd = region[1];
+
+ // navigate to start
+ if (hideEnd < vstart)
+ {
+ continue;
+ }
+ if (hideStart > vstart)
+ {
+ int[] contig = new int[] { vstart, hideStart - 1 };
+ vcontigs.add(contig);
+ }
+ vstart = hideEnd + 1;
+
+ // exit if we're past the end
+ if (vstart >= end)
+ {
+ break;
+ }
+ }
+
+ if (vstart < end)
+ {
+ int[] contig = new int[] { vstart, end - 1 };
+ vcontigs.add(contig);
+ }
+ }
+ else
+ {
+ int[] contig = new int[] { start, end - 1 };
+ 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;
+ }
+ }
}
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
import java.util.Vector;
* area
* @return
*/
- public List<int[]> getViewAsVisibleContigs(boolean selectedRegionOnly)
+ public Iterator<int[]> getViewAsVisibleContigs(boolean selectedRegionOnly)
{
- List<int[]> viscontigs = null;
- int start = 0, end = 0;
+ int start = 0;
+ int end = 0;
if (selectedRegionOnly && selectionGroup != null)
{
start = selectionGroup.getStartRes();
{
end = alignment.getWidth();
}
- viscontigs = alignment.getHiddenColumns().getVisibleContigs(start, end);
- return viscontigs;
+ return (alignment.getHiddenColumns().getVisContigsIterator(start, end));
}
/**
import java.util.Hashtable;
import java.util.IdentityHashMap;
import java.util.Iterator;
-import java.util.List;
import javax.swing.JInternalFrame;
}
else
{
- // int[] intervals = colsel.getVisibleContigs(
- // seqsel.getStartRes(), seqsel.getEndRes() + 1);
- List<int[]> intervals = hidden.getVisibleContigs(
- seqsel.getStartRes(), seqsel.getEndRes() + 1);
- for (int[] region : intervals)
+ Iterator<int[]> intervals = hidden
+ .getVisContigsIterator(seqsel.getStartRes(),
+ seqsel.getEndRes() + 1);
+ while (intervals.hasNext())
{
+ int[] region = intervals.next();
Seg s = new Seg();
- s.setStart(region[0] + 1); // vamsas indices begin at
- // 1, not zero.
+ s.setStart(region[0] + 1); // vamsas indices begin at 1,
+ // not zero.
s.setEnd(region[1] + 1);
s.setInclusive(true);
range.addSeg(s);
import jalview.io.FormatAdapter;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Iterator;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
FileFormat.Fasta);
HiddenColumns cs = new HiddenColumns();
AlignViewportI av = new AlignViewport(alf, cs);
- int[] contig = new int[] { 0, alf.getWidth() - 1 };
- List<int[]> contigs = new ArrayList<>();
- contigs.add(contig);
+ Iterator<int[]> contigs = cs.getVisContigsIterator(0, alf.getWidth());
Dna dna = new Dna(av, contigs);
AlignmentI translated = dna.translateCdna();
assertNotNull("Couldn't do a full width translation of test data.",
cs.hideColumns(0, ipos - 1);
}
cs.hideColumns(ipos + vwidth, alf.getWidth());
- List<int[]> vcontigs = cs.getVisibleContigs(0, alf.getWidth());
+ Iterator<int[]> vcontigs = cs.getVisContigsIterator(0,
+ alf.getWidth());
AlignViewportI av = new AlignViewport(alf, cs);
Dna dna = new Dna(av, vcontigs);
AlignmentI transAlf = dna.translateCdna();
DataSourceType.PASTE, FileFormat.Fasta);
HiddenColumns cs = new HiddenColumns();
AlignViewportI av = new AlignViewport(alf, cs);
- int[] contig = new int[] { 0, alf.getWidth() - 1 };
- List<int[]> contigs = new ArrayList<>();
- contigs.add(contig);
+ Iterator<int[]> contigs = cs.getVisContigsIterator(0, alf.getWidth());
Dna dna = new Dna(av, contigs);
AlignmentI translated = dna.translateCdna();
String aa = translated.getSequenceAt(0).getSequenceAsString();
cs.hideColumns(24, 35); // hide codons 9-12
cs.hideColumns(177, 191); // hide codons 60-64
AlignViewportI av = new AlignViewport(alf, cs);
- int[] contig = new int[] { 0, alf.getWidth() - 1 };
- List<int[]> contigs = new ArrayList<>();
- contigs.add(contig);
+ Iterator<int[]> contigs = cs.getVisContigsIterator(0, alf.getWidth());
Dna dna = new Dna(av, contigs);
AlignmentI translated = dna.translateCdna();
String aa = translated.getSequenceAt(0).getSequenceAsString();
.generate(12, 8, 97, 5, 5);
HiddenColumns cs = new HiddenColumns();
AlignViewportI av = new AlignViewport(cdna, cs);
- int[] contig = new int[] { 0, cdna.getWidth() - 1 };
- List<int[]> contigs = new ArrayList<>();
- contigs.add(contig);
+ Iterator<int[]> contigs = cs.getVisContigsIterator(0, cdna.getWidth());
Dna dna = new Dna(av, contigs);
AlignmentI translated = dna.translateCdna();
}
AlignmentI cdnaReordered = new Alignment(sorted);
av = new AlignViewport(cdnaReordered, cs);
- contig = new int[] { 0, cdna.getWidth() - 1 };
- contigs = new ArrayList<>();
- contigs.add(contig);
+ contigs = cs.getVisContigsIterator(0, cdna.getWidth());
dna = new Dna(av, contigs);
AlignmentI translated2 = dna.translateCdna();
HiddenColumns cs = new HiddenColumns();
AlignViewportI av = new AlignViewport(al, cs);
- int[] contig = new int[] { 0, al.getWidth() - 1 };
- List<int[]> contigs = new ArrayList<>();
- contigs.add(contig);
+ Iterator<int[]> contigs = cs.getVisContigsIterator(0, al.getWidth());
Dna testee = new Dna(av, contigs);
AlignmentI reversed = testee.reverseCdna(false);
assertEquals(1, reversed.getHeight());
}
@Test(groups = { "Functional" })
- public void testGetVisibleContigs()
+ public void testVisibleContigsIterator()
{
HiddenColumns cs = new HiddenColumns();
- List<int[]> visible = cs.getVisibleContigs(3, 10);
- assertEquals("[3, 9]", Arrays.toString(visible.get(0)));
+ Iterator<int[]> visible = cs.getVisContigsIterator(3, 10);
+ int[] region = visible.next();
+ assertEquals("[3, 9]", Arrays.toString(region));
+ assertFalse(visible.hasNext());
cs.hideColumns(3, 6);
cs.hideColumns(8, 9);
// Test both ends visible region
// start position is inclusive, end position exclusive
- visible = cs.getVisibleContigs(1, 13);
- assertEquals("[1, 2]", Arrays.toString(visible.get(0)));
- assertEquals("[7, 7]", Arrays.toString(visible.get(1)));
- assertEquals("[10, 11]", Arrays.toString(visible.get(2)));
+ visible = cs.getVisContigsIterator(1, 13);
+ region = visible.next();
+ assertEquals("[1, 2]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[7, 7]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[10, 11]", Arrays.toString(region));
+ assertFalse(visible.hasNext());
// Test start hidden, end visible
- visible = cs.getVisibleContigs(4, 14);
- assertEquals("[7, 7]", Arrays.toString(visible.get(0)));
- assertEquals("[10, 11]", Arrays.toString(visible.get(1)));
- assertEquals("[13, 13]", Arrays.toString(visible.get(2)));
+ visible = cs.getVisContigsIterator(4, 14);
+ region = visible.next();
+ assertEquals("[7, 7]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[10, 11]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[13, 13]", Arrays.toString(region));
+ assertFalse(visible.hasNext());
// Test start hidden, end hidden
- visible = cs.getVisibleContigs(3, 10);
- assertEquals("[7, 7]", Arrays.toString(visible.get(0)));
+ visible = cs.getVisContigsIterator(3, 10);
+ region = visible.next();
+ assertEquals("[7, 7]", Arrays.toString(region));
+ assertFalse(visible.hasNext());
// Test start visible, end hidden
- visible = cs.getVisibleContigs(0, 13);
- assertEquals("[0, 2]", Arrays.toString(visible.get(0)));
- assertEquals("[7, 7]", Arrays.toString(visible.get(1)));
- assertEquals("[10, 11]", Arrays.toString(visible.get(2)));
+ visible = cs.getVisContigsIterator(0, 13);
+ region = visible.next();
+ assertEquals("[0, 2]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[7, 7]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[10, 11]", Arrays.toString(region));
+ assertFalse(visible.hasNext());
// Test empty result
- visible = cs.getVisibleContigs(4, 6);
- assertEquals(0, visible.size());
+ visible = cs.getVisContigsIterator(4, 6);
+ assertFalse(visible.hasNext());
}
@Test(groups = { "Functional" })
false);
// confirm that original contigs are as expected
- List<int[]> visible = hidden.getVisibleContigs(0, 25);
- assertEquals("[0, 14]", Arrays.toString(visible.get(0)));
- assertEquals("[18, 24]", Arrays.toString(visible.get(1)));
+ Iterator<int[]> visible = hidden.getVisContigsIterator(0, 25);
+ int[] region = visible.next();
+ assertEquals("[0, 14]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[18, 24]", Arrays.toString(region));
// propagate insertions
HiddenColumns result = HiddenColumns.propagateInsertions(profileseq, al,
view);
// confirm that the contigs have changed to account for the gaps
- visible = result.getVisibleContigs(0, 25);
- assertEquals("[0, 10]", Arrays.toString(visible.get(0)));
- assertEquals("[14, 24]", Arrays.toString(visible.get(1)));
+ visible = result.getVisContigsIterator(0, 25);
+ region = visible.next();
+ assertEquals("[0, 10]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[14, 24]", Arrays.toString(region));
// confirm the alignment has been changed so that the other sequences have
// gaps inserted where the columns are hidden
false);
// confirm that original contigs are as expected
- List<int[]> visible = hidden.getVisibleContigs(0, 20);
- assertEquals("[0, 6]", Arrays.toString(visible.get(0)));
- assertEquals("[11, 19]", Arrays.toString(visible.get(1)));
+ Iterator<int[]> visible = hidden.getVisContigsIterator(0, 20);
+ int[] region = visible.next();
+ assertEquals("[0, 6]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[11, 19]", Arrays.toString(region));
+ assertFalse(visible.hasNext());
// propagate insertions
HiddenColumns result = HiddenColumns.propagateInsertions(profileseq, al,
view);
// confirm that the contigs have changed to account for the gaps
- visible = result.getVisibleContigs(0, 20);
- assertEquals("[0, 4]", Arrays.toString(visible.get(0)));
- assertEquals("[7, 19]", Arrays.toString(visible.get(1)));
+ visible = result.getVisContigsIterator(0, 20);
+ region = visible.next();
+ assertEquals("[0, 4]", Arrays.toString(region));
+ region = visible.next();
+ assertEquals("[7, 19]", Arrays.toString(region));
+ assertFalse(visible.hasNext());
// confirm the alignment has been changed so that the other sequences have
// gaps inserted where the columns are hidden