From 585a6abef0a5beef8b5247d9b44105dbf389ba45 Mon Sep 17 00:00:00 2001 From: gmungoc Date: Tue, 23 Aug 2016 09:16:51 +0100 Subject: [PATCH] JAL-2174 markColumns() refactored inside ColumnSelection --- src/jalview/controller/AlignViewController.java | 104 +++----------------- src/jalview/datamodel/ColumnSelection.java | 82 ++++++++++++++- .../controller/AlignViewControllerTest.java | 104 +------------------- test/jalview/datamodel/ColumnSelectionTest.java | 92 +++++++++++++++++ test/jalview/datamodel/SequenceTest.java | 14 ++- 5 files changed, 195 insertions(+), 201 deletions(-) diff --git a/src/jalview/controller/AlignViewController.java b/src/jalview/controller/AlignViewController.java index f966072..82c8d38 100644 --- a/src/jalview/controller/AlignViewController.java +++ b/src/jalview/controller/AlignViewController.java @@ -182,14 +182,15 @@ public class AlignViewController implements AlignViewControllerI if (bs.cardinality() > 0 || invert) { - boolean changed = selectMarkedColumns(cs, invert, extendCurrent, - toggle, bs, sqcol.getStartRes(), sqcol.getEndRes()); + boolean changed = cs.markColumns(bs, sqcol.getStartRes(), + sqcol.getEndRes(), invert, extendCurrent, toggle); if (changed) { viewport.setColumnSelection(cs); alignPanel.paintAlignment(true); int columnCount = invert ? (sqcol.getEndRes() - sqcol.getStartRes() + 1) - - bs.cardinality() : bs.cardinality(); + - bs.cardinality() + : bs.cardinality(); avcg.setStatus(MessageManager.formatMessage( "label.view_controller_toggled_marked", new String[] { @@ -198,8 +199,8 @@ public class AlignViewController implements AlignViewControllerI String.valueOf(columnCount), MessageManager .getString(invert ? "label.not_containing" - : "label.containing"), - featureType, Integer.valueOf(nseq).toString() })); + : "label.containing"), featureType, + Integer.valueOf(nseq).toString() })); return true; } } @@ -208,7 +209,7 @@ public class AlignViewController implements AlignViewControllerI avcg.setStatus(MessageManager.formatMessage( "label.no_feature_of_type_found", new String[] { featureType })); - if (!extendCurrent && cs != null) + if (!extendCurrent) { cs.clear(); alignPanel.paintAlignment(true); @@ -218,85 +219,9 @@ public class AlignViewController implements AlignViewControllerI } /** - * Updates the column selection depending on the parameters, and returns true - * if any change was made to the selection. - * - * @param columnSelection - * the current column selection - * @param invert - * if true, deselect marked columns and select unmarked - * @param extendCurrent - * if true, extend rather than replacing the current column selection - * @param toggle - * if true, toggle the selection state of marked columns - * @param markedColumns - * a set identify marked columns - * @param startCol - * the first column of the range to operate over - * @param endCol - * the last column of the range to operate over - * @return - */ - static boolean selectMarkedColumns(ColumnSelection columnSelection, - boolean invert, boolean extendCurrent, boolean toggle, - BitSet markedColumns, int startCol, int endCol) - { - boolean changed = false; - if (!extendCurrent && !toggle) - { - changed = !columnSelection.isEmpty(); - columnSelection.clear(); - } - if (invert) - { - // invert only in the currently selected sequence region - int i = markedColumns.nextClearBit(startCol); - int ibs = markedColumns.nextSetBit(startCol); - while (i >= startCol && i <= endCol) - { - if (ibs < 0 || i < ibs) - { - changed = true; - if (toggle && columnSelection.contains(i)) - { - columnSelection.removeElement(i++); - } - else - { - columnSelection.addElement(i++); - } - } - else - { - i = markedColumns.nextClearBit(ibs); - ibs = markedColumns.nextSetBit(i); - } - } - } - else - { - int i = markedColumns.nextSetBit(startCol); - while (i >= startCol && i <= endCol) - { - changed = true; - if (toggle && columnSelection.contains(i)) - { - columnSelection.removeElement(i); - } - else - { - columnSelection.addElement(i); - } - i = markedColumns.nextSetBit(i + 1); - } - } - return changed; - } - - /** - * Sets a bit in the BitSet for each column in the sequence collection which - * includes the specified feature type. Returns the number of sequences which - * have the feature in the selected range. + * Sets a bit in the BitSet for each column (base 0) in the sequence + * collection which includes the specified feature type. Returns the number of + * sequences which have the feature in the selected range. * * @param featureType * @param sqcol @@ -304,8 +229,7 @@ public class AlignViewController implements AlignViewControllerI * @return */ static int findColumnsWithFeature(String featureType, - SequenceCollectionI sqcol, - BitSet bs) + SequenceCollectionI sqcol, BitSet bs) { final int startPosition = sqcol.getStartRes() + 1; // converted to base 1 final int endPosition = sqcol.getEndRes() + 1; @@ -319,6 +243,10 @@ public class AlignViewController implements AlignViewControllerI SequenceFeature[] sfs = sq.getSequenceFeatures(); if (sfs != null) { + /* + * check whether the feature start/end (base 1) + * overlaps the selection start/end + */ int ist = sq.findIndex(sq.getStart()); int iend = sq.findIndex(sq.getEnd()); if (iend < startPosition || ist > endPosition) @@ -358,7 +286,7 @@ public class AlignViewController implements AlignViewControllerI } for (; i <= j; i++) { - bs.set(i - 1); + bs.set(i - 1); // convert to base 0 } } } diff --git a/src/jalview/datamodel/ColumnSelection.java b/src/jalview/datamodel/ColumnSelection.java index 47acbd0..7ef2a68 100644 --- a/src/jalview/datamodel/ColumnSelection.java +++ b/src/jalview/datamodel/ColumnSelection.java @@ -986,7 +986,7 @@ public class ColumnSelection SequenceI[] seqs) { int i, iSize = seqs.length; - String selection[] = new String[iSize]; + String selections[] = new String[iSize]; if (hiddenColumns != null && hiddenColumns.size() > 0) { for (i = 0; i < iSize; i++) @@ -1028,18 +1028,18 @@ public class ColumnSelection visibleSeq.append(seqs[i].getSequence(blockStart, end)); } - selection[i] = visibleSeq.toString(); + selections[i] = visibleSeq.toString(); } } else { for (i = 0; i < iSize; i++) { - selection[i] = seqs[i].getSequenceAsString(start, end); + selections[i] = seqs[i].getSequenceAsString(start, end); } } - return selection; + return selections; } /** @@ -1704,4 +1704,78 @@ public class ColumnSelection return true; } + /** + * Updates the column selection depending on the parameters, and returns true + * if any change was made to the selection + * + * @param markedColumns + * a set identifying marked columns (base 0) + * @param startCol + * the first column of the range to operate over (base 0) + * @param endCol + * the last column of the range to operate over (base 0) + * @param invert + * if true, deselect marked columns and select unmarked + * @param extendCurrent + * if true, extend rather than replacing the current column selection + * @param toggle + * if true, toggle the selection state of marked columns + * + * @return + */ + public boolean markColumns(BitSet markedColumns, int startCol, + int endCol, boolean invert, boolean extendCurrent, boolean toggle) + { + boolean changed = false; + if (!extendCurrent && !toggle) + { + changed = !this.isEmpty(); + clear(); + } + if (invert) + { + // invert only in the currently selected sequence region + int i = markedColumns.nextClearBit(startCol); + int ibs = markedColumns.nextSetBit(startCol); + while (i >= startCol && i <= endCol) + { + if (ibs < 0 || i < ibs) + { + changed = true; + if (toggle && contains(i)) + { + removeElement(i++); + } + else + { + addElement(i++); + } + } + else + { + i = markedColumns.nextClearBit(ibs); + ibs = markedColumns.nextSetBit(i); + } + } + } + else + { + int i = markedColumns.nextSetBit(startCol); + while (i >= startCol && i <= endCol) + { + changed = true; + if (toggle && contains(i)) + { + removeElement(i); + } + else + { + addElement(i); + } + i = markedColumns.nextSetBit(i + 1); + } + } + return changed; + } + } diff --git a/test/jalview/controller/AlignViewControllerTest.java b/test/jalview/controller/AlignViewControllerTest.java index d85b68f..3eefada 100644 --- a/test/jalview/controller/AlignViewControllerTest.java +++ b/test/jalview/controller/AlignViewControllerTest.java @@ -3,14 +3,12 @@ package jalview.controller; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertTrue; -import jalview.datamodel.ColumnSelection; import jalview.datamodel.Sequence; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import java.util.BitSet; -import java.util.List; import org.testng.annotations.Test; @@ -37,7 +35,7 @@ public class AlignViewControllerTest 0f, null)); /* - * select the first three columns --> seq1 2-3 + * select the first three columns --> Metal in seq1 2-3 */ SequenceGroup sg = new SequenceGroup(); sg.setStartRes(0); // base 0 @@ -56,7 +54,7 @@ public class AlignViewControllerTest assertTrue(bs.get(2)); /* - * select the first four columns: seq1 2:4, seq2 4:4 + * select the first four columns: Metal in seq1 2:4, seq2 4:4 */ sg.setEndRes(3); bs.clear(); @@ -69,7 +67,7 @@ public class AlignViewControllerTest assertTrue(bs.get(3)); /* - * select column 11: seq3 only + * select column 11: Metal in seq3 only */ sg.setStartRes(10); sg.setEndRes(10); @@ -99,100 +97,4 @@ public class AlignViewControllerTest assertEquals(0, seqCount); assertEquals(0, bs.cardinality()); } - - @Test(groups = "Functional") - public void testSelectMarkedColumns_invert() - { - ColumnSelection cs = new ColumnSelection(); - cs.addElement(5); // this will be cleared - BitSet toMark = new BitSet(); - toMark.set(1); - toMark.set(3); - toMark.set(6); - toMark.set(9); - - /* - * inverted selection of {3, 6} should select {4, 5, 7, 8} - */ - assertTrue(AlignViewController.selectMarkedColumns(cs, true, false, - false, toMark, 3, 8)); - List selected = cs.getSelected(); - assertEquals(4, selected.size()); - assertTrue(selected.contains(4)); - assertTrue(selected.contains(5)); - assertTrue(selected.contains(7)); - assertTrue(selected.contains(8)); - } - - @Test(groups = "Functional") - public void testSelectMarkedColumns() - { - ColumnSelection cs = new ColumnSelection(); - cs.addElement(5); // this will be cleared - BitSet toMark = new BitSet(); - toMark.set(1); - toMark.set(3); - toMark.set(6); - toMark.set(9); - - assertTrue(AlignViewController.selectMarkedColumns(cs, false, false, - false, toMark, 3, 8)); - List selected = cs.getSelected(); - assertEquals(2, selected.size()); - assertTrue(selected.contains(3)); - assertTrue(selected.contains(6)); - } - - @Test(groups = "Functional") - public void testSelectMarkedColumns_extend() - { - ColumnSelection cs = new ColumnSelection(); - cs.addElement(1); - cs.addElement(5); - BitSet toMark = new BitSet(); - toMark.set(1); - toMark.set(3); - toMark.set(6); - toMark.set(9); - - /* - * extending selection of {3, 6} should leave {1, 3, 5, 6} selected - */ - assertTrue(AlignViewController.selectMarkedColumns(cs, false, true, - false, toMark, 3, 8)); - List selected = cs.getSelected(); - assertEquals(4, selected.size()); - assertTrue(selected.contains(1)); - assertTrue(selected.contains(3)); - assertTrue(selected.contains(5)); - assertTrue(selected.contains(6)); - } - - @Test(groups = "Functional") - public void testSelectMarkedColumns_toggle() - { - ColumnSelection cs = new ColumnSelection(); - cs.addElement(1); // outside change range - cs.addElement(3); - cs.addElement(4); - cs.addElement(10); // outside change range - BitSet toMark = new BitSet(); - toMark.set(1); - toMark.set(3); - toMark.set(6); - toMark.set(9); - - /* - * toggling state of {3, 6} should leave {1, 4, 6, 10} selected - */ - assertTrue(AlignViewController.selectMarkedColumns(cs, false, false, - true, toMark, 3, 8)); - List selected = cs.getSelected(); - assertEquals(4, selected.size()); - assertTrue(selected.contains(1)); - assertTrue(selected.contains(4)); - assertTrue(selected.contains(6)); - assertTrue(selected.contains(10)); - } - // TODO testSelectMarkedColumns with combinations of invert/extend/toggle set } diff --git a/test/jalview/datamodel/ColumnSelectionTest.java b/test/jalview/datamodel/ColumnSelectionTest.java index 2deb1a7..e59719c 100644 --- a/test/jalview/datamodel/ColumnSelectionTest.java +++ b/test/jalview/datamodel/ColumnSelectionTest.java @@ -27,6 +27,7 @@ import static org.testng.AssertJUnit.assertSame; import static org.testng.AssertJUnit.assertTrue; import java.util.Arrays; +import java.util.BitSet; import java.util.List; import org.testng.annotations.Test; @@ -577,4 +578,95 @@ public class ColumnSelectionTest assertEquals(21, selected3.get(1).intValue()); assertEquals(1, selected3.get(2).intValue()); } + + @Test(groups = "Functional") + public void testMarkColumns() + { + ColumnSelection cs = new ColumnSelection(); + cs.addElement(5); // this will be cleared + BitSet toMark = new BitSet(); + toMark.set(1); + toMark.set(3); + toMark.set(6); + toMark.set(9); + + assertTrue(cs.markColumns(toMark, 3, 8, false, false, false)); + List selected = cs.getSelected(); + assertEquals(2, selected.size()); + assertTrue(selected.contains(3)); + assertTrue(selected.contains(6)); + } + + @Test(groups = "Functional") + public void testMarkColumns_extend() + { + ColumnSelection cs = new ColumnSelection(); + cs.addElement(1); + cs.addElement(5); + BitSet toMark = new BitSet(); + toMark.set(1); + toMark.set(3); + toMark.set(6); + toMark.set(9); + + /* + * extending selection of {3, 6} should leave {1, 3, 5, 6} selected + */ + assertTrue(cs.markColumns(toMark, 3, 8, false, true, false)); + List selected = cs.getSelected(); + assertEquals(4, selected.size()); + assertTrue(selected.contains(1)); + assertTrue(selected.contains(3)); + assertTrue(selected.contains(5)); + assertTrue(selected.contains(6)); + } + + @Test(groups = "Functional") + public void testMarkColumns_invert() + { + ColumnSelection cs = new ColumnSelection(); + cs.addElement(5); // this will be cleared + BitSet toMark = new BitSet(); + toMark.set(1); + toMark.set(3); + toMark.set(6); + toMark.set(9); + + /* + * inverted selection of {3, 6} should select {4, 5, 7, 8} + */ + assertTrue(cs.markColumns(toMark, 3, 8, true, false, false)); + List selected = cs.getSelected(); + assertEquals(4, selected.size()); + assertTrue(selected.contains(4)); + assertTrue(selected.contains(5)); + assertTrue(selected.contains(7)); + assertTrue(selected.contains(8)); + } + + @Test(groups = "Functional") + public void testMarkColumns_toggle() + { + ColumnSelection cs = new ColumnSelection(); + cs.addElement(1); // outside change range + cs.addElement(3); + cs.addElement(4); + cs.addElement(10); // outside change range + BitSet toMark = new BitSet(); + toMark.set(1); + toMark.set(3); + toMark.set(6); + toMark.set(9); + + /* + * toggling state of {3, 6} should leave {1, 4, 6, 10} selected + */ + assertTrue(cs.markColumns(toMark, 3, 8, false, false, true)); + List selected = cs.getSelected(); + assertEquals(4, selected.size()); + assertTrue(selected.contains(1)); + assertTrue(selected.contains(4)); + assertTrue(selected.contains(6)); + assertTrue(selected.contains(10)); + } } diff --git a/test/jalview/datamodel/SequenceTest.java b/test/jalview/datamodel/SequenceTest.java index 71719dd..cfc4cbb 100644 --- a/test/jalview/datamodel/SequenceTest.java +++ b/test/jalview/datamodel/SequenceTest.java @@ -110,8 +110,7 @@ public class SequenceTest { AlignmentAnnotation ann1 = addAnnotation("label1", "desc1", "calcId1", 1f); - AlignmentAnnotation ann2 = addAnnotation("label2", "desc2", "calcId2", - 1f); + addAnnotation("label2", "desc2", "calcId2", 1f); AlignmentAnnotation ann3 = addAnnotation("label1", "desc3", "calcId3", 1f); AlignmentAnnotation[] anns = seq.getAnnotation("label1"); @@ -133,16 +132,15 @@ public class SequenceTest @Test(groups = { "Functional" }) public void testGetAlignmentAnnotations_forCalcIdAndLabel() { - AlignmentAnnotation ann1 = addAnnotation("label1", "desc1", "calcId1", - 1f); + addAnnotation("label1", "desc1", "calcId1", 1f); AlignmentAnnotation ann2 = addAnnotation("label2", "desc2", "calcId2", 1f); - AlignmentAnnotation ann3 = addAnnotation("label2", "desc3", "calcId3", - 1f); + addAnnotation("label2", "desc3", "calcId3", 1f); AlignmentAnnotation ann4 = addAnnotation("label2", "desc3", "calcId2", 1f); - AlignmentAnnotation ann5 = addAnnotation("label5", "desc3", null, 1f); - AlignmentAnnotation ann6 = addAnnotation(null, "desc3", "calcId3", 1f); + addAnnotation("label5", "desc3", null, 1f); + addAnnotation(null, "desc3", "calcId3", 1f); + List anns = seq.getAlignmentAnnotations("calcId2", "label2"); assertEquals(2, anns.size()); -- 1.7.10.2