JAL-1445 ported routine for selecting containing/non-containing columns from groovy...
authorJim Procter <jprocter@compbio.dundee.ac.uk>
Mon, 17 Feb 2014 18:12:12 +0000 (18:12 +0000)
committerJim Procter <jprocter@compbio.dundee.ac.uk>
Mon, 17 Feb 2014 18:12:12 +0000 (18:12 +0000)
src/jalview/api/AlignViewControllerI.java
src/jalview/controller/AlignViewController.java

index fc63fd6..1d1e5fb 100644 (file)
@@ -21,4 +21,6 @@ public interface AlignViewControllerI<ViewportI>
 
   public void setViewportAndAlignmentPanel(AlignViewportI viewport, AlignmentViewPanel alignPanel);
 
+  boolean markColumnsContainingFeatures(boolean invert, String featureType);
+
 }
index 45ab9c4..1a1d219 100644 (file)
@@ -1,10 +1,15 @@
 package jalview.controller;
 
 import java.awt.Color;
+import java.util.BitSet;
+import java.util.List;
 
+import jalview.api.AlignViewControllerGuiI;
 import jalview.api.AlignViewControllerI;
 import jalview.api.AlignViewportI;
 import jalview.api.AlignmentViewPanel;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SequenceFeature;
 import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 
@@ -102,5 +107,109 @@ public class AlignViewController implements AlignViewControllerI
     }
     return false;
   }
-    
+   
+  @Override
+  public boolean markColumnsContainingFeatures(boolean invert,
+          String featureType)
+  {
+    // JBPNote this routine could also mark rows, not just columns.
+    // need a decent query structure to allow all types of feature searches
+    BitSet bs = new BitSet();
+    List<SequenceI> seqs = viewport.getAlignment().getSequences();
+    int alw = viewport.getAlignment().getWidth();
+    int nseq = 0;
+    for (SequenceI sq : seqs)
+    {
+      int tfeat = 0;
+      if (sq != null)
+      {
+        SequenceI dsq = sq.getDatasetSequence();
+        while (dsq.getDatasetSequence() != null)
+        {
+          dsq = dsq.getDatasetSequence();
+        }
+        ;
+        SequenceFeature[] sf = dsq.getSequenceFeatures();
+        if (sf != null)
+        {
+          for (SequenceFeature sfpos : sf)
+          {
+            // future functionalty - featureType == null means mark columns
+            // containing all displayed features
+            if (sfpos != null && (featureType.equals(sfpos.getType())))
+            {
+              tfeat++;
+              // optimisation - could consider 'spos,apos' like cursor argument
+              // - findIndex wastes time by starting from first character and
+              // counting
+
+              int i = sq.findIndex(sfpos.getBegin());
+              int ist = sq.findIndex(sq.getStart());
+              if (i < ist)
+              {
+                i = ist;
+              }
+              int j = sq.findIndex(sfpos.getEnd());
+              if (j > alw)
+              {
+                j = alw;
+              }
+              for (; i <= j; i++)
+              {
+                bs.set(i - 1);
+              }
+            }
+          }
+        }
+
+        if (tfeat > 0)
+        {
+          nseq++;
+        }
+      }
+    }
+    if (bs.cardinality() > 0 || invert)
+    {
+      ColumnSelection cs = viewport.getColumnSelection();
+      if (cs == null)
+      {
+        cs = new ColumnSelection();
+      }
+      if (invert)
+      {
+        for (int i = bs.nextClearBit(0), ibs = bs.nextSetBit(0); i >= 0
+                && i < alw;)
+        {
+          if (ibs < 0 || i < ibs)
+          {
+            cs.addElement(i++);
+          }
+          else
+          {
+            i = bs.nextClearBit(ibs);
+            ibs = bs.nextSetBit(i);
+          }
+        }
+      }
+      else
+      {
+        for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1))
+        {
+          cs.addElement(i);
+        }
+      }
+      viewport.setColumnSelection(cs);
+      alignPanel.paintAlignment(true);
+      avcg.setStatus("Marked "
+              + (invert ? alw - bs.cardinality() : bs.cardinality())
+              + " columns containing features of type " + featureType
+              + " across " + nseq);
+      return true;
+    }
+    else
+    {
+      avcg.setStatus("No features of type " + featureType + " found.");
+      return false;
+    }
   }
+}