From 586bcf511622737d2beaaf2ac83e4ffa5b3e857f Mon Sep 17 00:00:00 2001
From: tjc <tjc@ee4ac58c-ac51-4696-9907-e4b3aa274f04>
Date: Thu, 14 Apr 2011 09:47:10 +0000
Subject: [PATCH] changes to filtering of reads

git-svn-id: svn+ssh://svn.internal.sanger.ac.uk/repos/svn/pathsoft/artemis/trunk@15952 ee4ac58c-ac51-4696-9907-e4b3aa274f04
---
 .../artemis/components/alignment/BamView.java |  22 ++--
 .../components/alignment/SAMRecordFilter.java | 106 +++++++++++-------
 .../SAMRecordFlagConjunctionPredicate.java    |  75 +++++--------
 .../alignment/SAMRecordFlagPredicate.java     |  13 ++-
 4 files changed, 115 insertions(+), 101 deletions(-)

diff --git a/uk/ac/sanger/artemis/components/alignment/BamView.java b/uk/ac/sanger/artemis/components/alignment/BamView.java
index dc79b8faa..6d4a1eea9 100644
--- a/uk/ac/sanger/artemis/components/alignment/BamView.java
+++ b/uk/ac/sanger/artemis/components/alignment/BamView.java
@@ -142,9 +142,11 @@ public class BamView extends JPanel
   protected List<String> bamList;
   private List<Integer> hideBamList = new Vector<Integer>();
 
-  private SAMRecordFlagPredicate samRecordFlagPredicate;
+  private SAMRecordPredicate samRecordFlagPredicate;
   private SAMRecordMapQPredicate samRecordMapQPredicate;
-  
+
+  private SAMRecordFilter filterFrame;
+
   private Bases bases;
   private JScrollPane jspView;
   private JScrollBar scrollBar;
@@ -237,6 +239,8 @@ public class BamView extends JPanel
     this.feature_display = feature_display;
     this.bases = bases;
     
+    System.out.println(nbasesInView);
+    
     containerPanel.setLayout(new BoxLayout(containerPanel, BoxLayout.Y_AXIS));
     containerPanel.add(mainPanel);
     
@@ -2310,17 +2314,19 @@ public class BamView extends JPanel
       }
     });
     
-    JMenuItem filter = new JMenuItem("Filter by Flag...");
+    JMenuItem filter = new JMenuItem("Filter Reads ...");
     menu.add(filter);
     filter.addActionListener(new ActionListener()
     {
       public void actionPerformed(ActionEvent e)
       {
-        new SAMRecordFilter(BamView.this);
+        if(filterFrame == null)
+          filterFrame = new SAMRecordFilter(BamView.this);
+        else
+          filterFrame.setVisible(true);
       } 
     });
-    
-    
+
     final JMenuItem bamSplitter = new JMenuItem("Clone window");
     bamSplitter.addActionListener(new ActionListener()
     {
@@ -3159,13 +3165,13 @@ public class BamView extends JPanel
     viewDetail.appendString(new String(thisSAMRecord.getReadBases()), Level.DEBUG);
   }
 
-  protected SAMRecordFlagPredicate getSamRecordFlagPredicate()
+  protected SAMRecordPredicate getSamRecordFlagPredicate()
   {
     return samRecordFlagPredicate;
   }
 
   protected void setSamRecordFlagPredicate(
-      SAMRecordFlagPredicate samRecordFlagPredicate)
+      SAMRecordPredicate samRecordFlagPredicate)
   {
     laststart = -1;
     lastend = -1;
diff --git a/uk/ac/sanger/artemis/components/alignment/SAMRecordFilter.java b/uk/ac/sanger/artemis/components/alignment/SAMRecordFilter.java
index 3291258c0..f769a5bbe 100644
--- a/uk/ac/sanger/artemis/components/alignment/SAMRecordFilter.java
+++ b/uk/ac/sanger/artemis/components/alignment/SAMRecordFilter.java
@@ -7,13 +7,12 @@ import java.awt.Point;
 import java.awt.Toolkit;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
 import java.awt.event.KeyAdapter;
 import java.awt.event.KeyEvent;
+import java.util.Vector;
 
 import javax.swing.JButton;
-import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
 import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
@@ -24,13 +23,17 @@ import javax.swing.JTextField;
  * Filter reads bases on their mapping quality (mapq) or the
  * flags that are set in the BAM file.
  */
-class SAMRecordFilter extends JPanel
+class SAMRecordFilter extends JFrame
 {
   private static final long serialVersionUID = 1L;
 
   public SAMRecordFilter(final BamView bamView)
   {
-    super(new GridBagLayout());
+    super("Filter Reads");
+    
+    JPanel pane = (JPanel) getContentPane();
+    pane.setLayout(new GridBagLayout());
+    
     int nflags = SAMRecordFlagPredicate.FLAGS.length;
     GridBagConstraints c = new GridBagConstraints();
     
@@ -43,7 +46,7 @@ class SAMRecordFilter extends JPanel
     c.gridy = nrows++;
     
     // MAPQ
-    add(new JLabel("Mappying quality (mapq) cut-off:"),c);
+    pane.add(new JLabel(" By Mappying Quality (mapq) cut-off:"),c);
     
     c.gridy = nrows++;
     c.gridwidth = 1;
@@ -59,7 +62,7 @@ class SAMRecordFilter extends JPanel
           setQualityCutOff(cutOff, bamView);
       }
     });
-    add(cutOff,c);
+    pane.add(cutOff,c);
     
     c.gridx = 1;
     final JButton setCutOff = new JButton("SET");
@@ -70,64 +73,63 @@ class SAMRecordFilter extends JPanel
         setQualityCutOff(cutOff, bamView);
       }
     });
-    add(setCutOff,c);
+    pane.add(setCutOff,c);
     
     // FLAGS
     c.gridwidth = 2;
     c.gridx = 0;
     c.gridy = nrows++;
-    add(new JSeparator(),c);
+    pane.add(new JSeparator(),c);
     
     c.gridy = nrows++;
-    add(new JLabel("To filter reads using the FLAG column in the BAM file"),c);
+    pane.add(new JLabel(" By SAM FLAG column:"),c);
     c.gridy = nrows++;
-    add(new JLabel("select any of the options below to hide the reads with"),c);
+    pane.add(new JLabel(" Select below to show or hide only the reads with "),c);
     c.gridy = nrows++;
-    add(new JLabel("that flag set."),c);
-    final JCheckBox flagCheck[] = new JCheckBox[nflags];
-    final SAMRecordFlagPredicate predicate = bamView.getSamRecordFlagPredicate();
+    pane.add(new JLabel(" the flag set."),c);
+    
+    final JComboBox flagCombo[] = new JComboBox[nflags];
     
+    final String[] items = {"", "SHOW", "HIDE"};
+    c.gridwidth = 1;
     for(int j=0; j<nflags; j++)
     {
-      flagCheck[j] = new JCheckBox(
-          SAMRecordFlagPredicate.FLAGS_DESCRUIPTION[j], false);
-      
-      if(predicate != null &&
-         predicate.isFlagSet(SAMRecordFlagPredicate.FLAGS[j]))
-        flagCheck[j].setSelected(true);
+      flagCombo[j] = new JComboBox(items);
+      if(SAMRecordFlagPredicate.FLAGS_DESCRIPTION[j].equalsIgnoreCase("Read Unmapped"))
+        flagCombo[j].setSelectedItem("HIDE");
       
-      flagCheck[j].addItemListener(new ItemListener()
+      flagCombo[j].addActionListener(new ActionListener() 
       {
-        public void itemStateChanged(ItemEvent e)
+        public void actionPerformed(ActionEvent e)
         {
-          filterChange(bamView, flagCheck);
-        }            
+          filterChange(bamView, flagCombo);
+        } 
       });
       
       c.gridy = nrows++;
-      add(flagCheck[j], c);
+      c.gridx = 0;
+      pane.add(flagCombo[j], c);
+      c.gridx = 1;
+      pane.add(new JLabel(SAMRecordFlagPredicate.FLAGS_DESCRIPTION[j]), c);
     }
 
-    
-    final JFrame f = new JFrame("Filter Settings");
     JButton closeFrame = new JButton("Close");
     closeFrame.addActionListener(new ActionListener()
     {
       public void actionPerformed(ActionEvent e)
       {
-        f.dispose();
+        setVisible(false);
       }
     });
     c.gridx = 1;
     c.gridy = nrows++;
     c.fill = GridBagConstraints.NONE;
-    add(closeFrame, c);
+    pane.add(closeFrame, c);
 
-    f.getContentPane().add(this);
-    f.pack();
+    pack();
     
-    rightJustifyFrame(f);
-    f.setVisible(true);
+    rightJustifyFrame(this);
+    setVisible(true);
   } 
   
   private void rightJustifyFrame(JFrame frame)
@@ -162,23 +164,45 @@ class SAMRecordFilter extends JPanel
     }
     bamView.repaint();
   }
-  
-  private void filterChange(final BamView bamView,
-                            final JCheckBox flagCheck[])
+
+  private void filterChange(final BamView bamView, final JComboBox flagCheck[])
   {
     int nflags = SAMRecordFlagPredicate.FLAGS.length;
     int flagCombined = 0;
-    for(int j=0; j<nflags; j++)
+    Vector <SAMRecordPredicate> predicates = new Vector<SAMRecordPredicate>();
+    
+    for (int j = 0; j < nflags; j++)
     {
-      if(flagCheck[j].isSelected())
+      String opt = (String) flagCheck[j].getSelectedItem();
+      if (opt.equals("HIDE"))
         flagCombined = flagCombined | SAMRecordFlagPredicate.FLAGS[j];
+      else if(opt.equals("SHOW"))
+        predicates.add(new SAMRecordFlagPredicate( SAMRecordFlagPredicate.FLAGS[j], false ));
     }
 
-    if(flagCombined == 0)
+    if (flagCombined == 0 && predicates.size() == 0)
       bamView.setSamRecordFlagPredicate(null);
     else
-      bamView.setSamRecordFlagPredicate(new SAMRecordFlagPredicate(flagCombined));
+    {
+      final SAMRecordPredicate predicate;
+      if(predicates.size()  == 0)
+        predicate = new SAMRecordFlagPredicate(flagCombined);
+      else if(flagCombined == 0)
+      {
+        predicate = 
+          new SAMRecordFlagConjunctionPredicate(predicates, SAMRecordFlagConjunctionPredicate.OR);
+      }
+      else
+      {
+        SAMRecordFlagPredicate p1 = new SAMRecordFlagPredicate(flagCombined);
+        SAMRecordFlagConjunctionPredicate p2 = 
+          new SAMRecordFlagConjunctionPredicate(predicates, SAMRecordFlagConjunctionPredicate.OR);
+        
+        predicate = new SAMRecordFlagConjunctionPredicate(p1, p2, 
+            SAMRecordFlagConjunctionPredicate.OR);
+      }
+      bamView.setSamRecordFlagPredicate(predicate);
+    }
     bamView.repaint();
   }
-  
 }
\ No newline at end of file
diff --git a/uk/ac/sanger/artemis/components/alignment/SAMRecordFlagConjunctionPredicate.java b/uk/ac/sanger/artemis/components/alignment/SAMRecordFlagConjunctionPredicate.java
index 251fc5c74..57d829444 100644
--- a/uk/ac/sanger/artemis/components/alignment/SAMRecordFlagConjunctionPredicate.java
+++ b/uk/ac/sanger/artemis/components/alignment/SAMRecordFlagConjunctionPredicate.java
@@ -21,6 +21,8 @@
 
 package uk.ac.sanger.artemis.components.alignment;
 
+import java.util.Vector;
+
 import net.sf.samtools.SAMRecord;
 
 /**
@@ -28,71 +30,44 @@ import net.sf.samtools.SAMRecord;
  **/
 public class SAMRecordFlagConjunctionPredicate implements SAMRecordPredicate
 {
-  private SAMRecordPredicate p1;
-  private SAMRecordPredicate p2;
+  private Vector<SAMRecordPredicate> predicates;
   private int type;  // AND or OR
-  private boolean is1 = true;
-  private boolean is2 = true;
-  private static int AND = 0;
+  protected static int AND = 0;
+  protected static int OR = 1;
   
-  public SAMRecordFlagConjunctionPredicate(SAMRecordPredicate p1, SAMRecordPredicate p2, int type, boolean is1, boolean is2)
+  public SAMRecordFlagConjunctionPredicate(SAMRecordPredicate p1, SAMRecordPredicate p2, int type)
   {
-    this.p1 = p1;
-    this.p2 = p2;
+    predicates = new Vector<SAMRecordPredicate>();
+    predicates.add(p1);
+    predicates.add(p2);
     this.type = type;
-    this.is1 = is1;
-    this.is2 = is2;
   }
   
+  public SAMRecordFlagConjunctionPredicate(Vector<SAMRecordPredicate> predicates, int type)
+  {
+    this.predicates = predicates;
+    this.type = type;
+  }
+
   public boolean testPredicate(SAMRecord samRecord)
   {
-    if(type == AND)
+    for(SAMRecordPredicate predicate: predicates)
     {
-      if(!is1 && !is2)
-      {
-        if(!p1.testPredicate(samRecord) && !p2.testPredicate(samRecord))
-          return true;
-      }
-      else if(!is1)
-      {
-        if(!p1.testPredicate(samRecord) && p2.testPredicate(samRecord))
-          return true;
-      }
-      else if(!is2)
+      if(predicate.testPredicate(samRecord))
       {
-        if(p1.testPredicate(samRecord) && !p2.testPredicate(samRecord))
+        if(type == OR)
           return true;
       }
-      else if(is1 && is2)
+      else
       {
-        if(p1.testPredicate(samRecord) && p2.testPredicate(samRecord))
-          return true;
-      }
-    }
-    else
-    {
-      if(!is1 && !is2)
-      {
-        if(!p1.testPredicate(samRecord) || !p2.testPredicate(samRecord))
-          return true;
-      }
-      else if(!is1)
-      {
-        if(!p1.testPredicate(samRecord) || p2.testPredicate(samRecord))
-          return true;
-      }
-      else if(!is2)
-      {
-        if(p1.testPredicate(samRecord) || !p2.testPredicate(samRecord))
-          return true;
-      }
-      else if(is1 && is2)
-      {
-        if(p1.testPredicate(samRecord) || p2.testPredicate(samRecord))
-          return true;
+        if(type == AND)
+          return false;
       }
     }
+
+    if(type == AND)
+      return true;
     return false;
   }
-  
+
 }
\ No newline at end of file
diff --git a/uk/ac/sanger/artemis/components/alignment/SAMRecordFlagPredicate.java b/uk/ac/sanger/artemis/components/alignment/SAMRecordFlagPredicate.java
index 4ae02c6f3..d3b8ea9cf 100644
--- a/uk/ac/sanger/artemis/components/alignment/SAMRecordFlagPredicate.java
+++ b/uk/ac/sanger/artemis/components/alignment/SAMRecordFlagPredicate.java
@@ -29,6 +29,7 @@ import net.sf.samtools.SAMRecord;
 public class SAMRecordFlagPredicate implements SAMRecordPredicate
 {
   private int flag;
+  private boolean isSet;
   
   protected static final int READ_PAIRED_FLAG = 0x1;
   protected static final int PROPER_PAIR_FLAG = 0x2;
@@ -42,7 +43,7 @@ public class SAMRecordFlagPredicate implements SAMRecordPredicate
   protected static final int READ_FAILS_VENDOR_QUALITY_CHECK_FLAG = 0x200;
   protected static final int DUPLICATE_READ_FLAG = 0x400;
   
-  protected static final String[] FLAGS_DESCRUIPTION =
+  protected static final String[] FLAGS_DESCRIPTION =
   {
     "Read Paired",
     "Proper Pair",
@@ -74,8 +75,14 @@ public class SAMRecordFlagPredicate implements SAMRecordPredicate
 
   
   public SAMRecordFlagPredicate(int flag)
+  {
+    this(flag, true);
+  }
+  
+  public SAMRecordFlagPredicate(int flag, boolean isSet)
   {
     this.flag = flag;
+    this.isSet = isSet;
   }
   
   /**
@@ -86,10 +93,12 @@ public class SAMRecordFlagPredicate implements SAMRecordPredicate
    **/
   public boolean testPredicate (final SAMRecord samRecord)
   {
+    if(!isSet)
+      return !isFlagSet(samRecord.getFlags());
     return isFlagSet(samRecord.getFlags());
   }
   
-  protected boolean isFlagSet(int thisFlag)
+  private boolean isFlagSet(int thisFlag)
   {
     for(int i=0; i<FLAGS.length; i++)
     {
-- 
GitLab