From b89d9889b3cc4ef1fd81de15edfd94ff9c426fa5 Mon Sep 17 00:00:00 2001 From: Jim Procter Date: Mon, 17 Feb 2014 18:12:12 +0000 Subject: [PATCH 1/1] JAL-1445 ported routine for selecting containing/non-containing columns from groovy example --- src/jalview/api/AlignViewControllerI.java | 2 + src/jalview/controller/AlignViewController.java | 111 ++++++++++++++++++++++- 2 files changed, 112 insertions(+), 1 deletion(-) diff --git a/src/jalview/api/AlignViewControllerI.java b/src/jalview/api/AlignViewControllerI.java index fc63fd6..1d1e5fb 100644 --- a/src/jalview/api/AlignViewControllerI.java +++ b/src/jalview/api/AlignViewControllerI.java @@ -21,4 +21,6 @@ public interface AlignViewControllerI public void setViewportAndAlignmentPanel(AlignViewportI viewport, AlignmentViewPanel alignPanel); + boolean markColumnsContainingFeatures(boolean invert, String featureType); + } diff --git a/src/jalview/controller/AlignViewController.java b/src/jalview/controller/AlignViewController.java index 45ab9c4..1a1d219 100644 --- a/src/jalview/controller/AlignViewController.java +++ b/src/jalview/controller/AlignViewController.java @@ -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 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; + } } +} -- 1.7.10.2