JAL-2791 select columns by _visible_ features
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 31 Oct 2017 16:23:19 +0000 (16:23 +0000)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Tue, 31 Oct 2017 16:23:19 +0000 (16:23 +0000)
src/jalview/controller/AlignViewController.java
test/jalview/controller/AlignViewControllerTest.java
test/jalview/gui/AlignFrameTest.java

index 460c2b3..7bb295e 100644 (file)
@@ -36,6 +36,7 @@ import jalview.datamodel.SequenceI;
 import jalview.io.DataSourceType;
 import jalview.io.FeaturesFile;
 import jalview.util.MessageManager;
+import jalview.viewmodel.seqfeatures.FeatureRendererModel;
 
 import java.awt.Color;
 import java.util.BitSet;
@@ -215,17 +216,22 @@ public class AlignViewController implements AlignViewControllerI
 
   /**
    * 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.
+   * collection which includes a visible feature of the specified feature type.
+   * Returns the number of sequences which have the feature visible in the
+   * selected range.
    * 
    * @param featureType
    * @param sqcol
    * @param bs
    * @return
    */
-  static int findColumnsWithFeature(String featureType,
+  int findColumnsWithFeature(String featureType,
           SequenceCollectionI sqcol, BitSet bs)
   {
+    FeatureRendererModel fr = alignPanel == null ? null
+            : (FeatureRendererModel) alignPanel.getFeatureRenderer();
+    List<String> visibleFeatures = fr.getDisplayedFeatureTypes();
+
     final int startColumn = sqcol.getStartRes() + 1; // converted to base 1
     final int endColumn = sqcol.getEndRes() + 1;
     List<SequenceI> seqs = sqcol.getSequences();
@@ -238,13 +244,22 @@ public class AlignViewController implements AlignViewControllerI
         List<SequenceFeature> sfs = sq.findFeatures(startColumn,
                 endColumn, featureType);
 
-        if (!sfs.isEmpty())
-        {
-          nseq++;
-        }
-
+        boolean found = false;
         for (SequenceFeature sf : sfs)
         {
+          {
+            if (!visibleFeatures.contains(sf.getType())
+                    || fr.getColour(sf) == null) // could pull up getColour to
+                                                 // FeatureRenderer interface
+            {
+              continue;
+            }
+          }
+          if (!found)
+          {
+            nseq++;
+          }
+          found = true;
           int sfStartCol = sq.findIndex(sf.getBegin());
           int sfEndCol = sq.findIndex(sf.getEnd());
 
index 2e89b0e..efee93b 100644 (file)
@@ -25,6 +25,8 @@ import static org.testng.AssertJUnit.assertTrue;
 
 import jalview.analysis.Finder;
 import jalview.api.AlignViewControllerI;
+import jalview.api.FeatureColourI;
+import jalview.datamodel.Alignment;
 import jalview.datamodel.SearchResults;
 import jalview.datamodel.SearchResultsI;
 import jalview.datamodel.Sequence;
@@ -35,7 +37,9 @@ import jalview.gui.AlignFrame;
 import jalview.gui.JvOptionPane;
 import jalview.io.DataSourceType;
 import jalview.io.FileLoader;
+import jalview.schemes.FeatureColour;
 
+import java.awt.Color;
 import java.util.Arrays;
 import java.util.BitSet;
 
@@ -67,13 +71,14 @@ public class AlignViewControllerTest
             null));
     seq1.addSequenceFeature(new SequenceFeature("Helix", "desc", 1, 15, 0f,
             null));
-    seq2.addSequenceFeature(new SequenceFeature("Metal", "desc", 4, 10, 0f,
+    seq2.addSequenceFeature(new SequenceFeature("Metal", "desc", 4, 10,
+            10f,
             null));
     seq3.addSequenceFeature(new SequenceFeature("Metal", "desc", 11, 15,
-            0f, null));
+            10f, null));
     // disulfide bond is a 'contact feature' - only select its 'start' and 'end'
-    seq3.addSequenceFeature(new SequenceFeature("disulfide bond", "desc", 8, 12,
-            0f, null));
+    seq3.addSequenceFeature(new SequenceFeature("disulfide bond", "desc",
+            8, 12, 0f, null));
 
     /*
      * select the first five columns --> Metal in seq1 cols 4-5
@@ -86,9 +91,18 @@ public class AlignViewControllerTest
     sg.addSequence(seq3, false);
     sg.addSequence(seq4, false);
 
+    /*
+     * set features visible on a viewport as only visible features are selected
+     */
+    AlignFrame af = new AlignFrame(new Alignment(new SequenceI[] { seq1,
+        seq2, seq3, seq4 }), 100, 100);
+    af.getFeatureRenderer().findAllFeatures(true);
+
+    AlignViewController avc = new AlignViewController(af, af.getViewport(),
+            af.alignPanel);
+
     BitSet bs = new BitSet();
-    int seqCount = AlignViewController.findColumnsWithFeature("Metal", sg,
-            bs);
+    int seqCount = avc.findColumnsWithFeature("Metal", sg, bs);
     assertEquals(1, seqCount);
     assertEquals(2, bs.cardinality());
     assertTrue(bs.get(3)); // base 0
@@ -99,7 +113,7 @@ public class AlignViewControllerTest
      */
     sg.setEndRes(6);
     bs.clear();
-    seqCount = AlignViewController.findColumnsWithFeature("Metal", sg, bs);
+    seqCount = avc.findColumnsWithFeature("Metal", sg, bs);
     assertEquals(2, seqCount);
     assertEquals(4, bs.cardinality());
     assertTrue(bs.get(3));
@@ -113,7 +127,7 @@ public class AlignViewControllerTest
     sg.setStartRes(13);
     sg.setEndRes(13);
     bs.clear();
-    seqCount = AlignViewController.findColumnsWithFeature("Metal", sg, bs);
+    seqCount = avc.findColumnsWithFeature("Metal", sg, bs);
     assertEquals(1, seqCount);
     assertEquals(1, bs.cardinality());
     assertTrue(bs.get(13));
@@ -124,18 +138,35 @@ public class AlignViewControllerTest
     sg.setStartRes(17);
     sg.setEndRes(19);
     bs.clear();
-    seqCount = AlignViewController.findColumnsWithFeature("Metal", sg, bs);
+    seqCount = avc.findColumnsWithFeature("Metal", sg, bs);
     assertEquals(0, seqCount);
     assertEquals(0, bs.cardinality());
 
     /*
+     * threshold Metal to hide where score < 5
+     * seq1 feature in columns 4-6 is hidden
+     * seq2 feature in columns 6-7 is shown
+     */
+    FeatureColourI fc = new FeatureColour(Color.red, Color.blue, 0f, 10f);
+    fc.setAboveThreshold(true);
+    fc.setThreshold(5f);
+    af.getFeatureRenderer().setColour("Metal", fc);
+    sg.setStartRes(0);
+    sg.setEndRes(6);
+    bs.clear();
+    seqCount = avc.findColumnsWithFeature("Metal", sg, bs);
+    assertEquals(1, seqCount);
+    assertEquals(2, bs.cardinality());
+    assertTrue(bs.get(5));
+    assertTrue(bs.get(6));
+
+    /*
      * columns 11-13 should not match disulfide bond at 8/12
      */
     sg.setStartRes(10);
     sg.setEndRes(12);
     bs.clear();
-    seqCount = AlignViewController.findColumnsWithFeature("disulfide bond",
-            sg, bs);
+    seqCount = avc.findColumnsWithFeature("disulfide bond", sg, bs);
     assertEquals(0, seqCount);
     assertEquals(0, bs.cardinality());
 
@@ -145,8 +176,7 @@ public class AlignViewControllerTest
     sg.setStartRes(5);
     sg.setEndRes(17);
     bs.clear();
-    seqCount = AlignViewController.findColumnsWithFeature("disulfide bond",
-            sg, bs);
+    seqCount = avc.findColumnsWithFeature("disulfide bond", sg, bs);
     assertEquals(1, seqCount);
     assertEquals(2, bs.cardinality());
     assertTrue(bs.get(8));
@@ -158,7 +188,7 @@ public class AlignViewControllerTest
     sg.setStartRes(0);
     sg.setEndRes(19);
     bs.clear();
-    seqCount = AlignViewController.findColumnsWithFeature("Pfam", sg, bs);
+    seqCount = avc.findColumnsWithFeature("Pfam", sg, bs);
     assertEquals(0, seqCount);
     assertEquals(0, bs.cardinality());
   }
index af9c045..1ee25c7 100644 (file)
@@ -26,6 +26,7 @@ import static org.testng.Assert.assertNotSame;
 import static org.testng.Assert.assertSame;
 import static org.testng.Assert.assertTrue;
 
+import jalview.api.FeatureColourI;
 import jalview.bin.Cache;
 import jalview.bin.Jalview;
 import jalview.datamodel.Alignment;
@@ -39,6 +40,7 @@ import jalview.io.FileLoader;
 import jalview.io.Jalview2xmlTests;
 import jalview.renderer.ResidueShaderI;
 import jalview.schemes.BuriedColourScheme;
+import jalview.schemes.FeatureColour;
 import jalview.schemes.HelixColourScheme;
 import jalview.schemes.JalviewColourScheme;
 import jalview.schemes.StrandColourScheme;
@@ -69,16 +71,21 @@ public class AlignFrameTest
   {
     SequenceI seq1 = new Sequence("Seq1", "ABCDEFGHIJ");
     SequenceI seq2 = new Sequence("Seq2", "ABCDEFGHIJ");
-    seq1.addSequenceFeature(new SequenceFeature("Metal", "", 1, 5,
-            Float.NaN, null));
-    seq2.addSequenceFeature(new SequenceFeature("Metal", "", 6, 10,
-            Float.NaN, null));
+    seq1.addSequenceFeature(new SequenceFeature("Metal", "", 1, 5, 0f, null));
+    seq2.addSequenceFeature(new SequenceFeature("Metal", "", 6, 10, 10f,
+            null));
     seq1.addSequenceFeature(new SequenceFeature("Turn", "", 2, 4,
             Float.NaN, null));
     seq2.addSequenceFeature(new SequenceFeature("Turn", "", 7, 9,
             Float.NaN, null));
     AlignmentI al = new Alignment(new SequenceI[] { seq1, seq2 });
-    AlignFrame alignFrame = new AlignFrame(al, al.getWidth(), al.getHeight());
+    AlignFrame alignFrame = new AlignFrame(al, al.getWidth(),
+            al.getHeight());
+
+    /*
+     * make all features visible (select feature columns checks visibility)
+     */
+    alignFrame.getFeatureRenderer().findAllFeatures(true);
 
     /*
      * hiding a feature not present does nothing
@@ -86,13 +93,11 @@ public class AlignFrameTest
     assertFalse(alignFrame.hideFeatureColumns("exon", true));
     assertTrue(alignFrame.getViewport().getColumnSelection().isEmpty());
     assertTrue(alignFrame.getViewport().getAlignment().getHiddenColumns()
-            .getHiddenColumnsCopy()
-            .isEmpty());
+            .getHiddenColumnsCopy().isEmpty());
     assertFalse(alignFrame.hideFeatureColumns("exon", false));
     assertTrue(alignFrame.getViewport().getColumnSelection().isEmpty());
     assertTrue(alignFrame.getViewport().getAlignment().getHiddenColumns()
-            .getHiddenColumnsCopy()
-            .isEmpty());
+            .getHiddenColumnsCopy().isEmpty());
 
     /*
      * hiding a feature in all columns does nothing
@@ -100,15 +105,31 @@ public class AlignFrameTest
     assertFalse(alignFrame.hideFeatureColumns("Metal", true));
     assertTrue(alignFrame.getViewport().getColumnSelection().isEmpty());
     List<int[]> hidden = alignFrame.getViewport().getAlignment()
-            .getHiddenColumns()
-            .getHiddenColumnsCopy();
+            .getHiddenColumns().getHiddenColumnsCopy();
     assertTrue(hidden.isEmpty());
 
     /*
+     * threshold Metal to hide features where score < 5
+     * seq1 feature in columns 1-5 is hidden
+     * seq2 feature in columns 6-10 is shown
+     */
+    FeatureColourI fc = new FeatureColour(Color.red, Color.blue, 0f, 10f);
+    fc.setAboveThreshold(true);
+    fc.setThreshold(5f);
+    alignFrame.getFeatureRenderer().setColour("Metal", fc);
+    assertTrue(alignFrame.hideFeatureColumns("Metal", true));
+    hidden = alignFrame.getViewport().getAlignment().getHiddenColumns()
+            .getHiddenColumnsCopy();
+    assertEquals(hidden.size(), 1);
+    assertEquals(hidden.get(0)[0], 5);
+    assertEquals(hidden.get(0)[1], 9);
+
+    /*
      * hide a feature present in some columns
      * sequence positions [2-4], [7-9] are column positions
      * [1-3], [6-8] base zero
      */
+    alignFrame.getViewport().showAllHiddenColumns();
     assertTrue(alignFrame.hideFeatureColumns("Turn", true));
     hidden = alignFrame.getViewport().getAlignment().getHiddenColumns()
             .getHiddenColumnsCopy();