X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=test%2Fjalview%2Fdatamodel%2FSequenceTest.java;h=9629b6f1b1b04ab266b2caba934a4cd20b2fdd92;hb=aab74f8748bf49bf6b17ba82f0bc5644d4dc2853;hp=d1f42909826d3031c0abaaf1115df2f957184f0a;hpb=bba9e58f08fc55c0f789f8354d1444e5c5e1b0e6;p=jalview.git diff --git a/test/jalview/datamodel/SequenceTest.java b/test/jalview/datamodel/SequenceTest.java index d1f4290..9629b6f 100644 --- a/test/jalview/datamodel/SequenceTest.java +++ b/test/jalview/datamodel/SequenceTest.java @@ -28,6 +28,7 @@ import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertSame; import static org.testng.AssertJUnit.assertTrue; +import jalview.analysis.AlignmentGenerator; import jalview.commands.EditCommand; import jalview.commands.EditCommand.Action; import jalview.datamodel.PDBEntry.Type; @@ -38,16 +39,17 @@ import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; +import java.util.Iterator; import java.util.List; import java.util.Vector; -import junit.extensions.PA; - import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import junit.extensions.PA; + public class SequenceTest { @@ -245,7 +247,9 @@ public class SequenceTest sq.sequenceChanged(); assertEquals(6, sq.findIndex(9)); - sq = new Sequence("test/8-13", "-A--B-C-D-E-F--"); + final String aligned = "-A--B-C-D-E-F--"; + assertEquals(15, aligned.length()); + sq = new Sequence("test/8-13", aligned); assertEquals(2, sq.findIndex(8)); sq.sequenceChanged(); assertEquals(5, sq.findIndex(9)); @@ -261,6 +265,84 @@ public class SequenceTest // beyond end returns last residue column sq.sequenceChanged(); assertEquals(13, sq.findIndex(99)); + + /* + * residue before sequence 'end' but beyond end of sequence returns + * length of sequence (last column) (rightly or wrongly!) + */ + sq = new Sequence("test/8-15", "A-B-C-"); // trailing gap case + assertEquals(6, sq.getLength()); + sq.sequenceChanged(); + assertEquals(sq.getLength(), sq.findIndex(14)); + sq = new Sequence("test/8-99", "-A--B-C-D"); // trailing residue case + sq.sequenceChanged(); + assertEquals(sq.getLength(), sq.findIndex(65)); + + /* + * residue after sequence 'start' but before first residue returns + * zero (before first column) (rightly or wrongly!) + */ + sq = new Sequence("test/8-15", "-A-B-C-"); // leading gap case + sq.sequenceChanged(); + assertEquals(0, sq.findIndex(3)); + sq = new Sequence("test/8-15", "A-B-C-"); // leading residue case + sq.sequenceChanged(); + assertEquals(0, sq.findIndex(2)); + } + + @Test(groups = { "Functional" }) + public void testFindPositions() + { + SequenceI sq = new Sequence("test/8-13", "-ABC---DE-F--"); + + /* + * invalid inputs + */ + assertNull(sq.findPositions(6, 5)); + assertNull(sq.findPositions(0, 5)); + assertNull(sq.findPositions(-1, 5)); + + /* + * all gapped ranges + */ + assertNull(sq.findPositions(1, 1)); // 1-based columns + assertNull(sq.findPositions(5, 5)); + assertNull(sq.findPositions(5, 6)); + assertNull(sq.findPositions(5, 7)); + + /* + * all ungapped ranges + */ + assertEquals(new Range(8, 8), sq.findPositions(2, 2)); // A + assertEquals(new Range(8, 9), sq.findPositions(2, 3)); // AB + assertEquals(new Range(8, 10), sq.findPositions(2, 4)); // ABC + assertEquals(new Range(9, 10), sq.findPositions(3, 4)); // BC + + /* + * gap to ungapped range + */ + assertEquals(new Range(8, 10), sq.findPositions(1, 4)); // ABC + assertEquals(new Range(11, 12), sq.findPositions(6, 9)); // DE + + /* + * ungapped to gapped range + */ + assertEquals(new Range(10, 10), sq.findPositions(4, 5)); // C + assertEquals(new Range(9, 13), sq.findPositions(3, 11)); // BCDEF + + /* + * ungapped to ungapped enclosing gaps + */ + assertEquals(new Range(10, 11), sq.findPositions(4, 8)); // CD + assertEquals(new Range(8, 13), sq.findPositions(2, 11)); // ABCDEF + + /* + * gapped to gapped enclosing ungapped + */ + assertEquals(new Range(8, 10), sq.findPositions(1, 5)); // ABC + assertEquals(new Range(11, 12), sq.findPositions(5, 10)); // DE + assertEquals(new Range(8, 13), sq.findPositions(1, 13)); // the lot + assertEquals(new Range(8, 13), sq.findPositions(1, 99)); } /** @@ -438,8 +520,7 @@ public class SequenceTest assertEquals("test:Pos13:Col10:startCol3:endCol10:tok0", PA.getValue(sq, "cursor").toString()); sq.sequenceChanged(); - assertEquals(12, sq.findPosition(8)); - cursor = (SequenceCursor) PA.getValue(sq, "cursor"); + assertEquals(12, sq.findPosition(8)); // E12 // sequenceChanged() invalidates cursor.lastResidueColumn cursor = (SequenceCursor) PA.getValue(sq, "cursor"); assertEquals("test:Pos12:Col9:startCol3:endCol0:tok1", @@ -478,6 +559,13 @@ public class SequenceTest assertEquals(6, sq.getEnd()); assertNull(PA.getValue(sq, "datasetSequence")); + sq = new Sequence("test", "ABCDE"); + sq.deleteChars(0, 3); + assertEquals("DE", sq.getSequenceAsString()); + assertEquals(4, sq.getStart()); + assertEquals(5, sq.getEnd()); + assertNull(PA.getValue(sq, "datasetSequence")); + /* * delete at end */ @@ -487,6 +575,21 @@ public class SequenceTest assertEquals(1, sq.getStart()); assertEquals(4, sq.getEnd()); assertNull(PA.getValue(sq, "datasetSequence")); + + /* + * delete more positions than there are + */ + sq = new Sequence("test/8-11", "ABCD"); + sq.deleteChars(0, 99); + assertEquals("", sq.getSequenceAsString()); + assertEquals(12, sq.getStart()); // = findPosition(99) ?!? + assertEquals(11, sq.getEnd()); + + sq = new Sequence("test/8-11", "----"); + sq.deleteChars(0, 99); // ArrayIndexOutOfBoundsException <= 2.10.2 + assertEquals("", sq.getSequenceAsString()); + assertEquals(8, sq.getStart()); + assertEquals(11, sq.getEnd()); } @Test(groups = { "Functional" }) @@ -799,7 +902,7 @@ public class SequenceTest Assert.assertEquals(pdbe1a, sq.getDatasetSequence().getPDBEntry("1PDB"), "PDB Entry '1PDB' not found on dataset sequence via getPDBEntry."); - ArrayList annotsList = new ArrayList(); + ArrayList annotsList = new ArrayList<>(); System.out.println(">>>>>> " + sq.getSequenceAsString().length()); annotsList.add(new Annotation("A", "A", 'X', 0.1f)); annotsList.add(new Annotation("A", "A", 'X', 0.1f)); @@ -1343,23 +1446,25 @@ public class SequenceTest null); sq.addSequenceFeature(sf0); // add feature on BCD - SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 9, 11, 2f, + SequenceFeature sfBCD = new SequenceFeature("Cath", "desc", 9, 11, 2f, null); - sq.addSequenceFeature(sf1); + sq.addSequenceFeature(sfBCD); // add feature on DE - SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 11, 12, 2f, + SequenceFeature sfDE = new SequenceFeature("Cath", "desc", 11, 12, 2f, null); - sq.addSequenceFeature(sf2); + sq.addSequenceFeature(sfDE); // add contact feature at [B, H] - SequenceFeature sf3 = new SequenceFeature("Disulphide bond", "desc", 9, - 15, 2f, - null); - sq.addSequenceFeature(sf3); + SequenceFeature sfContactBH = new SequenceFeature("Disulphide bond", + "desc", 9, 15, 2f, null); + sq.addSequenceFeature(sfContactBH); // add contact feature at [F, G] - SequenceFeature sf4 = new SequenceFeature("Disulfide Bond", "desc", 13, - 14, 2f, - null); - sq.addSequenceFeature(sf4); + SequenceFeature sfContactFG = new SequenceFeature("Disulfide Bond", + "desc", 13, 14, 2f, null); + sq.addSequenceFeature(sfContactFG); + // add single position feature at [I] + SequenceFeature sfI = new SequenceFeature("Disulfide Bond", + "desc", 16, 16, null); + sq.addSequenceFeature(sfI); // no features in columns 1-2 (-A) List found = sq.findFeatures(1, 2); @@ -1368,20 +1473,29 @@ public class SequenceTest // columns 1-6 (-ABC--) includes BCD and B/H feature but not DE found = sq.findFeatures(1, 6); assertEquals(2, found.size()); - assertTrue(found.contains(sf1)); - assertTrue(found.contains(sf3)); + assertTrue(found.contains(sfBCD)); + assertTrue(found.contains(sfContactBH)); // columns 5-6 (--) includes (enclosing) BCD but not (contact) B/H feature found = sq.findFeatures(5, 6); assertEquals(1, found.size()); - assertTrue(found.contains(sf1)); + assertTrue(found.contains(sfBCD)); // columns 7-10 (DEF-) includes BCD, DE, F/G but not B/H feature found = sq.findFeatures(7, 10); assertEquals(3, found.size()); - assertTrue(found.contains(sf1)); - assertTrue(found.contains(sf2)); - assertTrue(found.contains(sf4)); + assertTrue(found.contains(sfBCD)); + assertTrue(found.contains(sfDE)); + assertTrue(found.contains(sfContactFG)); + + // columns 10-11 (--) should find nothing + found = sq.findFeatures(10, 11); + assertEquals(0, found.size()); + + // columns 14-14 (I) should find variant feature + found = sq.findFeatures(14, 14); + assertEquals(1, found.size()); + assertTrue(found.contains(sfI)); } @Test(groups = { "Functional" }) @@ -1389,14 +1503,61 @@ public class SequenceTest { Sequence sq = new Sequence("test/8-13", "-A--BCD-EF--"); - // find F given A + // find F given A, check cursor is now at the found position assertEquals(10, sq.findIndex(13, new SequenceCursor(sq, 8, 2, 0))); + SequenceCursor cursor = (SequenceCursor) PA.getValue(sq, "cursor"); + assertEquals(13, cursor.residuePosition); + assertEquals(10, cursor.columnPosition); // find A given F assertEquals(2, sq.findIndex(8, new SequenceCursor(sq, 13, 10, 0))); + cursor = (SequenceCursor) PA.getValue(sq, "cursor"); + assertEquals(8, cursor.residuePosition); + assertEquals(2, cursor.columnPosition); - // find C given C + // find C given C (no cursor update is done for this case) assertEquals(6, sq.findIndex(10, new SequenceCursor(sq, 10, 6, 0))); + SequenceCursor cursor2 = (SequenceCursor) PA.getValue(sq, "cursor"); + assertSame(cursor2, cursor); + + /* + * sequence 'end' beyond end of sequence returns length of sequence + * (for compatibility with pre-cursor code) + * - also verify the cursor is left in a valid state + */ + sq = new Sequence("test/8-99", "-A--B-C-D-E-F--"); // trailing gap case + assertEquals(7, sq.findIndex(10)); // establishes a cursor + cursor = (SequenceCursor) PA.getValue(sq, "cursor"); + assertEquals(10, cursor.residuePosition); + assertEquals(7, cursor.columnPosition); + assertEquals(sq.getLength(), sq.findIndex(65)); + cursor2 = (SequenceCursor) PA.getValue(sq, "cursor"); + assertSame(cursor, cursor2); // not updated for this case! + + sq = new Sequence("test/8-99", "-A--B-C-D-E-F"); // trailing residue case + sq.findIndex(10); // establishes a cursor + cursor = (SequenceCursor) PA.getValue(sq, "cursor"); + assertEquals(sq.getLength(), sq.findIndex(65)); + cursor2 = (SequenceCursor) PA.getValue(sq, "cursor"); + assertSame(cursor, cursor2); // not updated for this case! + + /* + * residue after sequence 'start' but before first residue should return + * zero (for compatibility with pre-cursor code) + */ + sq = new Sequence("test/8-15", "-A-B-C-"); // leading gap case + sq.findIndex(10); // establishes a cursor + cursor = (SequenceCursor) PA.getValue(sq, "cursor"); + assertEquals(0, sq.findIndex(3)); + cursor2 = (SequenceCursor) PA.getValue(sq, "cursor"); + assertSame(cursor, cursor2); // not updated for this case! + + sq = new Sequence("test/8-15", "A-B-C-"); // leading residue case + sq.findIndex(10); // establishes a cursor + cursor = (SequenceCursor) PA.getValue(sq, "cursor"); + assertEquals(0, sq.findIndex(2)); + cursor2 = (SequenceCursor) PA.getValue(sq, "cursor"); + assertSame(cursor, cursor2); // not updated for this case! } @Test(groups = { "Functional" }) @@ -1529,6 +1690,10 @@ public class SequenceTest // cursor should now be at [D 6] cursor = (SequenceCursor) PA.getValue(sq, "cursor"); assertEquals(new SequenceCursor(sq, 11, 6, ++token), cursor); + assertEquals(0, cursor.lastColumnPosition); // not yet found + assertEquals(13, sq.findPosition(8)); // E13 + cursor = (SequenceCursor) PA.getValue(sq, "cursor"); + assertEquals(9, cursor.lastColumnPosition); // found /* * deleteChars should invalidate the cached cursor @@ -1608,57 +1773,383 @@ public class SequenceTest } @Test(groups = { "Functional" }) - public void testFindPositions() + public void testGapBitset() { SequenceI sq = new Sequence("test/8-13", "-ABC---DE-F--"); + BitSet bs = sq.gapBitset(); + BitSet expected = new BitSet(); + expected.set(0); + expected.set(4, 7); + expected.set(9); + expected.set(11, 13); + + assertTrue(bs.equals(expected)); + } + + public void testFindFeatures_largeEndPos() + { /* - * invalid inputs + * imitate a PDB sequence where end is larger than end position */ - assertNull(sq.findPositions(6, 5)); - assertNull(sq.findPositions(0, 5)); - assertNull(sq.findPositions(-1, 5)); + SequenceI sq = new Sequence("test", "-ABC--DEF--", 1, 20); + sq.createDatasetSequence(); + + assertTrue(sq.findFeatures(1, 9).isEmpty()); + // should be no array bounds exception - JAL-2772 + assertTrue(sq.findFeatures(1, 15).isEmpty()); + + // add feature on BCD + SequenceFeature sfBCD = new SequenceFeature("Cath", "desc", 2, 4, 2f, + null); + sq.addSequenceFeature(sfBCD); + + // no features in columns 1-2 (-A) + List found = sq.findFeatures(1, 2); + assertTrue(found.isEmpty()); + + // columns 1-6 (-ABC--) includes BCD + found = sq.findFeatures(1, 6); + assertEquals(1, found.size()); + assertTrue(found.contains(sfBCD)); + + // columns 10-11 (--) should find nothing + found = sq.findFeatures(10, 11); + assertEquals(0, found.size()); + } + + @Test(groups = { "Functional" }) + public void testSetName() + { + SequenceI sq = new Sequence("test", "-ABC---DE-F--"); + assertEquals("test", sq.getName()); + assertEquals(1, sq.getStart()); + assertEquals(6, sq.getEnd()); + + sq.setName("testing"); + assertEquals("testing", sq.getName()); + + sq.setName("test/8-10"); + assertEquals("test", sq.getName()); + assertEquals(8, sq.getStart()); + assertEquals(13, sq.getEnd()); // note end is recomputed + + sq.setName("testing/7-99"); + assertEquals("testing", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); // end may be beyond physical end + + sq.setName("/2-3"); + assertEquals("", sq.getName()); + assertEquals(2, sq.getStart()); + assertEquals(7, sq.getEnd()); + + sq.setName("test/"); // invalid + assertEquals("test/", sq.getName()); + assertEquals(2, sq.getStart()); + assertEquals(7, sq.getEnd()); + + sq.setName("test/6-13/7-99"); + assertEquals("test/6-13", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName("test/0-5"); // 0 is invalid - ignored + assertEquals("test/0-5", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName("test/a-5"); // a is invalid - ignored + assertEquals("test/a-5", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName("test/6-5"); // start > end is invalid - ignored + assertEquals("test/6-5", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName("test/5"); // invalid - ignored + assertEquals("test/5", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName("test/-5"); // invalid - ignored + assertEquals("test/-5", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName("test/5-"); // invalid - ignored + assertEquals("test/5-", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName("test/5-6-7"); // invalid - ignored + assertEquals("test/5-6-7", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + + sq.setName(null); // invalid, gets converted to space + assertEquals("", sq.getName()); + assertEquals(7, sq.getStart()); + assertEquals(99, sq.getEnd()); + } + + @Test(groups = { "Functional" }) + public void testCheckValidRange() + { + Sequence sq = new Sequence("test/7-12", "-ABC---DE-F--"); + assertEquals(7, sq.getStart()); + assertEquals(12, sq.getEnd()); /* - * all gapped ranges + * checkValidRange ensures end is at least the last residue position */ - assertNull(sq.findPositions(1, 1)); // 1-based columns - assertNull(sq.findPositions(5, 5)); - assertNull(sq.findPositions(5, 6)); - assertNull(sq.findPositions(5, 7)); + PA.setValue(sq, "end", 2); + sq.checkValidRange(); + assertEquals(12, sq.getEnd()); /* - * all ungapped ranges + * end may be beyond the last residue position */ - assertEquals(new Range(8, 8), sq.findPositions(2, 2)); // A - assertEquals(new Range(8, 9), sq.findPositions(2, 3)); // AB - assertEquals(new Range(8, 10), sq.findPositions(2, 4)); // ABC - assertEquals(new Range(9, 10), sq.findPositions(3, 4)); // BC + PA.setValue(sq, "end", 22); + sq.checkValidRange(); + assertEquals(22, sq.getEnd()); + } + @Test(groups = { "Functional" }) + public void testDeleteChars_withGaps() + { /* - * gap to ungapped range + * delete gaps only */ - assertEquals(new Range(8, 10), sq.findPositions(1, 4)); // ABC - assertEquals(new Range(11, 12), sq.findPositions(6, 9)); // DE + SequenceI sq = new Sequence("test/8-10", "A-B-C"); + sq.createDatasetSequence(); + assertEquals("ABC", sq.getDatasetSequence().getSequenceAsString()); + sq.deleteChars(1, 2); // delete first gap + assertEquals("AB-C", sq.getSequenceAsString()); + assertEquals(8, sq.getStart()); + assertEquals(10, sq.getEnd()); + assertEquals("ABC", sq.getDatasetSequence().getSequenceAsString()); /* - * ungapped to gapped range + * delete gaps and residues at start (no new dataset sequence) */ - assertEquals(new Range(10, 10), sq.findPositions(4, 5)); // C - assertEquals(new Range(9, 13), sq.findPositions(3, 11)); // BCDEF + sq = new Sequence("test/8-10", "A-B-C"); + sq.createDatasetSequence(); + sq.deleteChars(0, 3); // delete A-B + assertEquals("-C", sq.getSequenceAsString()); + assertEquals(10, sq.getStart()); + assertEquals(10, sq.getEnd()); + assertEquals("ABC", sq.getDatasetSequence().getSequenceAsString()); /* - * ungapped to ungapped enclosing gaps + * delete gaps and residues at end (no new dataset sequence) */ - assertEquals(new Range(10, 11), sq.findPositions(4, 8)); // CD - assertEquals(new Range(8, 13), sq.findPositions(2, 11)); // ABCDEF + sq = new Sequence("test/8-10", "A-B-C"); + sq.createDatasetSequence(); + sq.deleteChars(2, 5); // delete B-C + assertEquals("A-", sq.getSequenceAsString()); + assertEquals(8, sq.getStart()); + assertEquals(8, sq.getEnd()); + assertEquals("ABC", sq.getDatasetSequence().getSequenceAsString()); /* - * gapped to gapped enclosing ungapped + * delete gaps and residues internally (new dataset sequence) + * first delete from gap to residue */ - assertEquals(new Range(8, 10), sq.findPositions(1, 5)); // ABC - assertEquals(new Range(11, 12), sq.findPositions(5, 10)); // DE - assertEquals(new Range(8, 13), sq.findPositions(1, 13)); // the lot - assertEquals(new Range(8, 13), sq.findPositions(1, 99)); + sq = new Sequence("test/8-10", "A-B-C"); + sq.createDatasetSequence(); + sq.deleteChars(1, 3); // delete -B + assertEquals("A-C", sq.getSequenceAsString()); + assertEquals(8, sq.getStart()); + assertEquals(9, sq.getEnd()); + assertEquals("AC", sq.getDatasetSequence().getSequenceAsString()); + assertEquals(8, sq.getDatasetSequence().getStart()); + assertEquals(9, sq.getDatasetSequence().getEnd()); + + /* + * internal delete from gap to gap + */ + sq = new Sequence("test/8-10", "A-B-C"); + sq.createDatasetSequence(); + sq.deleteChars(1, 4); // delete -B- + assertEquals("AC", sq.getSequenceAsString()); + assertEquals(8, sq.getStart()); + assertEquals(9, sq.getEnd()); + assertEquals("AC", sq.getDatasetSequence().getSequenceAsString()); + assertEquals(8, sq.getDatasetSequence().getStart()); + assertEquals(9, sq.getDatasetSequence().getEnd()); + + /* + * internal delete from residue to residue + */ + sq = new Sequence("test/8-10", "A-B-C"); + sq.createDatasetSequence(); + sq.deleteChars(2, 3); // delete B + assertEquals("A--C", sq.getSequenceAsString()); + assertEquals(8, sq.getStart()); + assertEquals(9, sq.getEnd()); + assertEquals("AC", sq.getDatasetSequence().getSequenceAsString()); + assertEquals(8, sq.getDatasetSequence().getStart()); + assertEquals(9, sq.getDatasetSequence().getEnd()); + } + + /** + * Test the code used to locate the reference sequence ruler origin + */ + @Test(groups = { "Functional" }) + public void testLocateVisibleStartofSequence() + { + // create random alignment + AlignmentGenerator gen = new AlignmentGenerator(false); + AlignmentI al = gen.generate(50, 20, 123, 5, 5); + + HiddenColumns cs = al.getHiddenColumns(); + ColumnSelection colsel = new ColumnSelection(); + + SequenceI seq = new Sequence("RefSeq", "-A-SD-ASD--E---"); + assertEquals(2, seq.findIndex(seq.getStart())); + + // no hidden columns + assertEquals(seq.findIndex(seq.getStart()) - 1, + seq.firstResidueOutsideIterator(cs.iterator())); + + // hidden column on gap after end of sequence - should not affect bounds + colsel.hideSelectedColumns(13, al.getHiddenColumns()); + assertEquals(seq.findIndex(seq.getStart()) - 1, + seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + // hidden column on gap before beginning of sequence - should vis bounds by + // one + colsel.hideSelectedColumns(0, al.getHiddenColumns()); + assertEquals(seq.findIndex(seq.getStart()) - 2, + cs.absoluteToVisibleColumn( + seq.firstResidueOutsideIterator(cs.iterator()))); + + cs.revealAllHiddenColumns(colsel); + // hide columns around most of sequence - leave one residue remaining + cs.hideColumns(1, 3); + cs.hideColumns(6, 11); + + Iterator it = cs.getVisContigsIterator(0, 6, false); + + assertEquals("-D", seq.getSequenceStringFromIterator(it)); + // cs.getVisibleSequenceStrings(0, 5, new SequenceI[] + // { seq })[0]); + + assertEquals(4, seq.firstResidueOutsideIterator(cs.iterator())); + cs.revealAllHiddenColumns(colsel); + + // hide whole sequence - should just get location of hidden region + // containing sequence + cs.hideColumns(1, 11); + assertEquals(0, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(0, 15); + assertEquals(0, seq.firstResidueOutsideIterator(cs.iterator())); + + SequenceI seq2 = new Sequence("RefSeq2", "-------A-SD-ASD--E---"); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(7, 17); + assertEquals(0, seq2.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(3, 17); + assertEquals(0, seq2.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(3, 19); + assertEquals(0, seq2.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(0, 0); + assertEquals(1, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(0, 1); + assertEquals(3, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(0, 2); + assertEquals(3, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(1, 1); + assertEquals(3, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(1, 2); + assertEquals(3, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(1, 3); + assertEquals(4, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(0, 2); + cs.hideColumns(5, 6); + assertEquals(3, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(0, 2); + cs.hideColumns(5, 6); + cs.hideColumns(9, 10); + assertEquals(3, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(0, 2); + cs.hideColumns(7, 11); + assertEquals(3, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(2, 4); + cs.hideColumns(7, 11); + assertEquals(1, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(2, 4); + cs.hideColumns(7, 12); + assertEquals(1, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(1, 11); + assertEquals(0, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(0, 12); + assertEquals(0, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(0, 4); + cs.hideColumns(6, 12); + assertEquals(0, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(0, 1); + cs.hideColumns(3, 12); + assertEquals(0, seq.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(3, 14); + cs.hideColumns(17, 19); + assertEquals(0, seq2.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(3, 7); + cs.hideColumns(9, 14); + cs.hideColumns(17, 19); + assertEquals(0, seq2.firstResidueOutsideIterator(cs.iterator())); + + cs.revealAllHiddenColumns(colsel); + cs.hideColumns(0, 1); + cs.hideColumns(3, 4); + cs.hideColumns(6, 8); + cs.hideColumns(10, 12); + assertEquals(0, seq.firstResidueOutsideIterator(cs.iterator())); + } }