}
/**
+ * Find the visible column which is a given visible number of columns to the
+ * left of another visible column. i.e. for a startColumn x, the column which
+ * is distance 1 away will be column x-1.
+ *
+ * @param visibleDistance
+ * the number of visible columns to offset by
+ * @param startColumn
+ * the column to start from
+ * @return the position of the column in the visible alignment
+ */
+ public int findColumnNToLeft(int visibleDistance, int startColumn)
+ {
+ int distance = visibleDistance;
+
+ // in case startColumn is in a hidden region, move it to the left
+ int start = adjustForHiddenColumns(findColumnPosition(startColumn));
+
+ // get index of hidden region to left of start
+ int index = getHiddenIndexLeft(start);
+ if (index == -1)
+ {
+ // no hidden regions to left of startColumn
+ return start - distance;
+ }
+
+ // walk backwards through the alignment subtracting the counts of visible
+ // columns from distance
+ int[] region;
+ int gap = 0;
+ int nextstart = start;
+
+ while ((index > -1) && (distance - gap > 0))
+ {
+ // subtract the gap to right of region from distance
+ distance -= gap;
+ start = nextstart;
+
+ // calculate the next gap
+ region = hiddenColumns.get(index);
+ gap = start - region[1];
+
+ // set start to just to left of current region
+ nextstart = region[0] - 1;
+ index--;
+ }
+
+ if (distance - gap > 0)
+ {
+ // fell out of loop because there are no more hidden regions
+ distance -= gap;
+ return nextstart - distance;
+ }
+ return start - distance;
+
+ }
+
+ /**
* Use this method to determine where the next hiddenRegion starts
*
* @param hiddenRegion
}
+ /**
+ * This method returns the index of the hidden region to the left of a column
+ * position. If the column is in a hidden region it returns the index of the
+ * region to the left. If there is no hidden region to the left it returns -1.
+ *
+ * @param pos
+ * int
+ */
+ private int getHiddenIndexLeft(int pos)
+ {
+ if (hiddenColumns != null)
+ {
+ int index = hiddenColumns.size() - 1;
+ do
+ {
+ int[] region = hiddenColumns.elementAt(index);
+ if (pos > region[1])
+ {
+ return index;
+ }
+
+ index--;
+ } while (index > -1);
+ }
+
+ return -1;
+
+ }
+
public void hideSelectedColumns()
{
synchronized (selection)
}
/**
+ * Test the method that finds the visible column position a given distance
+ * before another column
+ */
+ @Test(groups = { "Functional" })
+ public void testFindColumnNToLeft()
+ {
+ ColumnSelection cs = new ColumnSelection();
+
+ // test that without hidden columns, findColumnNToLeft returns
+ // position n to left of provided position
+ int pos = cs.findColumnNToLeft(3, 10);
+ assertEquals(7, pos);
+
+ // 0 returns same position
+ pos = cs.findColumnNToLeft(0, 10);
+ assertEquals(10, pos);
+
+ // overflow to left returns negative number
+ pos = cs.findColumnNToLeft(3, 0);
+ assertEquals(-3, pos);
+
+ // test that with hidden columns to left of result column
+ // behaviour is the same as above
+ cs.hideColumns(1, 3);
+
+ // position n to left of provided position
+ pos = cs.findColumnNToLeft(3, 10);
+ assertEquals(7, pos);
+
+ // 0 returns same position
+ pos = cs.findColumnNToLeft(0, 10);
+ assertEquals(10, pos);
+
+ // test with one set of hidden columns between start and required position
+ cs.hideColumns(12, 15);
+ pos = cs.findColumnNToLeft(8, 17);
+ assertEquals(5, pos);
+
+ // test with two sets of hidden columns between start and required position
+ cs.hideColumns(20, 21);
+ pos = cs.findColumnNToLeft(8, 23);
+ assertEquals(9, pos);
+
+ // repeat last 2 tests with no hidden columns to left of required position
+ cs.revealAllHiddenColumns();
+
+ // test with one set of hidden columns between start and required position
+ cs.hideColumns(12, 15);
+ pos = cs.findColumnNToLeft(8, 17);
+ assertEquals(5, pos);
+
+ // test with two sets of hidden columns between start and required position
+ cs.hideColumns(20, 21);
+ pos = cs.findColumnNToLeft(8, 23);
+ assertEquals(9, pos);
+
+ }
+
+ /**
* Test the code used to locate the reference sequence ruler origin
*/
@Test(groups = { "Functional" })
JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
}
- static int SEQ_COUNT = 10;
+ static int SEQ_COUNT = 25;
SequenceI[] seqs;
seqs = new SequenceI[SEQ_COUNT];
for (int i = 0; i < SEQ_COUNT; i++)
{
- // sequence lengths are 1, 2, ... 10
- seqs[i] = new Sequence("Seq" + i, "abcdefghijk".substring(0, i + 1));
+ // sequence lengths are 1, 2, ... 25
+ seqs[i] = new Sequence("Seq" + i,
+ "abcdefghijklmnopqrstuvwxy".substring(0, i + 1));
}
}
/*
* alignment is now seq0/2/3/4/7/8/9
*/
- assertEquals(7, al.getHeight());
+ assertEquals(SEQ_COUNT - 3, al.getHeight());
assertEquals(0, hs.adjustForHiddenSeqs(0));
assertEquals(2, hs.adjustForHiddenSeqs(1));
assertEquals(3, hs.adjustForHiddenSeqs(2));
/*
* alignment is now seq0/2/3/4/7/8/9
*/
- assertEquals(7, al.getHeight());
+ assertEquals(SEQ_COUNT - 3, al.getHeight());
assertEquals(0, hs.findIndexWithoutHiddenSeqs(0));
assertEquals(0, hs.findIndexWithoutHiddenSeqs(1));
assertEquals(1, hs.findIndexWithoutHiddenSeqs(2));
}
/**
+ * Test the method that finds the visible row position a given distance before
+ * another row
+ */
+ @Test(groups = { "Functional" })
+ public void testFindIndexNFromRow()
+ {
+ AlignmentI al = new Alignment(seqs);
+ HiddenSequences hs = new HiddenSequences(al);
+
+ // test that without hidden rows, findIndexNFromRow returns
+ // position n above provided position
+ int pos = hs.findIndexNAboveRow(3, 10);
+ assertEquals(7, pos);
+
+ // 0 returns same position
+ pos = hs.findIndexNAboveRow(0, 10);
+ assertEquals(10, pos);
+
+ // overflow to top returns negative number
+ pos = hs.findIndexNAboveRow(3, 0);
+ assertEquals(-3, pos);
+
+ // test that with hidden rows above result row
+ // behaviour is the same as above
+ hs.hideSequence(seqs[1]);
+ hs.hideSequence(seqs[2]);
+ hs.hideSequence(seqs[3]);
+
+ // position n above provided position
+ pos = hs.findIndexNAboveRow(3, 10);
+ assertEquals(7, pos);
+
+ // 0 returns same position
+ pos = hs.findIndexNAboveRow(0, 10);
+ assertEquals(10, pos);
+
+ // test with one set of hidden rows between start and required position
+ hs.hideSequence(seqs[12]);
+ hs.hideSequence(seqs[13]);
+ hs.hideSequence(seqs[14]);
+ hs.hideSequence(seqs[15]);
+ pos = hs.findIndexNAboveRow(8, 17);
+ assertEquals(5, pos);
+
+ // test with two sets of hidden rows between start and required position
+ hs.hideSequence(seqs[20]);
+ hs.hideSequence(seqs[21]);
+ pos = hs.findIndexNAboveRow(8, 23);
+ assertEquals(9, pos);
+
+ // repeat last 2 tests with no hidden columns to left of required position
+ hs.showAll(null);
+
+ // test with one set of hidden rows between start and required position
+ hs.hideSequence(seqs[12]);
+ hs.hideSequence(seqs[13]);
+ hs.hideSequence(seqs[14]);
+ hs.hideSequence(seqs[15]);
+ pos = hs.findIndexNAboveRow(8, 17);
+ assertEquals(5, pos);
+
+ // test with two sets of hidden rows between start and required position
+ hs.hideSequence(seqs[20]);
+ hs.hideSequence(seqs[21]);
+ pos = hs.findIndexNAboveRow(8, 23);
+ assertEquals(9, pos);
+
+ }
+
+ /**
* Test the method that reconstructs (sort of) the full alignment including
* hidden sequences
*/
assertTrue(al.getSequences().contains(seqs[1]));
HiddenSequences hs = al.getHiddenSequences();
assertEquals(0, hs.getSize());
- assertEquals(10, al.getHeight());
+ assertEquals(SEQ_COUNT, al.getHeight());
/*
* hide the second sequence in the alignment
assertTrue(hs.isHidden(seqs[1]));
assertFalse(al.getSequences().contains(seqs[1]));
assertEquals(1, hs.getSize());
- assertEquals(9, al.getHeight());
+ assertEquals(SEQ_COUNT - 1, al.getHeight());
assertSame(seqs[2], al.getSequenceAt(1));
/*
assertFalse(al.getSequences().contains(seqs[1]));
assertFalse(al.getSequences().contains(seqs[2]));
assertEquals(2, hs.getSize());
- assertEquals(8, al.getHeight());
+ assertEquals(SEQ_COUNT - 2, al.getHeight());
/*
* perform 'reveal' on what is now the second sequence in the alignment
assertTrue(revealed.contains(seqs[1]));
assertTrue(revealed.contains(seqs[2]));
assertEquals(0, hs.getSize());
- assertEquals(10, al.getHeight());
+ assertEquals(SEQ_COUNT, al.getHeight());
}
/**
assertTrue(al.getSequences().contains(seqs[1]));
HiddenSequences hs = al.getHiddenSequences();
assertEquals(0, hs.getSize());
- assertEquals(10, al.getHeight());
+ assertEquals(SEQ_COUNT, al.getHeight());
/*
* hide the last sequence in the alignment
*/
- hs.hideSequence(seqs[9]);
- assertFalse(hs.isHidden(seqs[8]));
- assertTrue(hs.isHidden(seqs[9]));
- assertFalse(al.getSequences().contains(seqs[9]));
+ hs.hideSequence(seqs[SEQ_COUNT - 1]);
+ assertFalse(hs.isHidden(seqs[SEQ_COUNT - 2]));
+ assertTrue(hs.isHidden(seqs[SEQ_COUNT - 1]));
+ assertFalse(al.getSequences().contains(seqs[SEQ_COUNT - 1]));
assertEquals(1, hs.getSize());
- assertEquals(9, al.getHeight());
+ assertEquals(SEQ_COUNT - 1, al.getHeight());
/*
* hide the third last sequence in the alignment
*/
- hs.hideSequence(seqs[7]);
- assertFalse(hs.isHidden(seqs[8]));
- assertTrue(hs.isHidden(seqs[7]));
- assertFalse(al.getSequences().contains(seqs[7]));
+ hs.hideSequence(seqs[SEQ_COUNT - 3]);
+ assertFalse(hs.isHidden(seqs[SEQ_COUNT - 2]));
+ assertTrue(hs.isHidden(seqs[SEQ_COUNT - 3]));
+ assertFalse(al.getSequences().contains(seqs[SEQ_COUNT - 3]));
assertEquals(2, hs.getSize());
- assertEquals(8, al.getHeight());
+ assertEquals(SEQ_COUNT - 2, al.getHeight());
/*
* reveal all the sequences, which should be reinstated in the same order as they started in
*/
hs.showAll(null);
- assertFalse(hs.isHidden(seqs[7]));
- assertFalse(hs.isHidden(seqs[9]));
- assertEquals(seqs[7], al.getSequences().get(7));
- assertEquals(seqs[8], al.getSequences().get(8));
- assertEquals(seqs[9], al.getSequences().get(9));
+ assertFalse(hs.isHidden(seqs[SEQ_COUNT - 3]));
+ assertFalse(hs.isHidden(seqs[SEQ_COUNT - 1]));
+ assertEquals(seqs[SEQ_COUNT - 3], al.getSequences().get(SEQ_COUNT - 3));
+ assertEquals(seqs[SEQ_COUNT - 2], al.getSequences().get(SEQ_COUNT - 2));
+ assertEquals(seqs[SEQ_COUNT - 1], al.getSequences().get(SEQ_COUNT - 1));
assertEquals(0, hs.getSize());
- assertEquals(10, al.getHeight());
+ assertEquals(SEQ_COUNT, al.getHeight());
}
@Test(groups = "Functional")