From 46f1f348ce62e2f630ed518344626be6f41f5538 Mon Sep 17 00:00:00 2001
From: tcarver <tjc>
Date: Fri, 26 Oct 2012 15:57:12 +0100
Subject: [PATCH] select BAM file in heatmap view

---
 .../artemis/components/alignment/BamView.java | 59 +++++++++++--
 .../components/alignment/CoveragePanel.java   | 87 ++++++++++++++++---
 2 files changed, 126 insertions(+), 20 deletions(-)

diff --git a/uk/ac/sanger/artemis/components/alignment/BamView.java b/uk/ac/sanger/artemis/components/alignment/BamView.java
index 3e3ef70d4..d77f92a96 100644
--- a/uk/ac/sanger/artemis/components/alignment/BamView.java
+++ b/uk/ac/sanger/artemis/components/alignment/BamView.java
@@ -1829,7 +1829,8 @@ public class BamView extends JPanel
 
     coverageView.drawSelectionRange(g2, pixPerBase, start, end, getHeight(), Color.PINK);
     coverageView.draw(g2, getWidth(), hgt, hideBamList);
-    coverageView.drawMax(g2);  
+    if(!coverageView.isPlotHeatMap())
+      coverageView.drawMax(g2);  
   }
   
   /**
@@ -3627,8 +3628,10 @@ public class BamView extends JPanel
   */
   class PopupListener extends MouseAdapter
   {
-	JMenuItem gotoMateMenuItem;
-	JMenuItem showDetails;
+	private JMenuItem gotoMateMenuItem;
+	private JMenuItem showDetails;
+	private JMenu coverageMenu;
+	private JMenuItem createGroup;
 	
     public void mouseClicked(MouseEvent e)
     {
@@ -3641,7 +3644,13 @@ public class BamView extends JPanel
       if(e.getClickCount() > 1)
         getSelection().clear(); 
       else if(e.getButton() == MouseEvent.BUTTON1)
-        highlightSAMRecord = mouseOverSAMRecord;
+      {
+        if(isCoverageView(getPixPerBaseByWidth()))
+          coverageView.singleClick(e.isShiftDown(),
+              e.getPoint().y-getJspView().getViewport().getViewPosition().y);
+        else
+          highlightSAMRecord = mouseOverSAMRecord;
+      }
       else
         highlightRange(e, MouseEvent.BUTTON2_DOWN_MASK);
       repaint();
@@ -3661,19 +3670,53 @@ public class BamView extends JPanel
     private void maybeShowPopup(MouseEvent e)
     {
       if(e.isPopupTrigger())
-      {
+      {       
+        //
+        // main menu options
         if(popup == null)
         {
           popup = new JPopupMenu();
           createMenus(popup);
         }
-        
+
+        //
+        // coverage heatmap menu options
+        if(coverageMenu != null)
+          popup.remove(coverageMenu);
+        if(isCoverageView(getPixPerBaseByWidth()) && coverageView.isPlotHeatMap())
+        {
+          if(coverageMenu == null)
+          {
+            coverageMenu = new JMenu("Coverage HeatMap");
+            final JCheckBoxMenuItem coverageGrid = new JCheckBoxMenuItem("Heatmap grid", false);
+            coverageGrid.addActionListener(new ActionListener()
+            {
+              public void actionPerformed(ActionEvent e) 
+              {
+                coverageView.showLabels(coverageGrid.isSelected());
+              }
+            });
+            coverageMenu.add(coverageGrid);
+
+            createGroup = new JMenuItem("Create group from selected BAMs");
+            createGroup.addActionListener(new ActionListener()
+            {
+              public void actionPerformed(ActionEvent e) 
+              {
+                
+              }
+            });
+            coverageMenu.add(createGroup);
+          }
+          createGroup.setEnabled(coverageView.hasSelectedBams());
+          popup.add(coverageMenu);
+        }
+
         if(gotoMateMenuItem != null)
           popup.remove(gotoMateMenuItem);
-
         if(showDetails != null)
           popup.remove(showDetails);
-        
+
         if( mouseOverSAMRecord != null && 
             mouseOverSAMRecord.sam.getReadPairedFlag() &&
            !mouseOverSAMRecord.sam.getMateUnmappedFlag() )
diff --git a/uk/ac/sanger/artemis/components/alignment/CoveragePanel.java b/uk/ac/sanger/artemis/components/alignment/CoveragePanel.java
index 19b5188d9..1f3c6e0a4 100644
--- a/uk/ac/sanger/artemis/components/alignment/CoveragePanel.java
+++ b/uk/ac/sanger/artemis/components/alignment/CoveragePanel.java
@@ -25,11 +25,13 @@
 package uk.ac.sanger.artemis.components.alignment;
 
 import java.awt.AlphaComposite;
+import java.awt.BasicStroke;
 import java.awt.Color;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
+import java.awt.Stroke;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.geom.GeneralPath;
@@ -62,10 +64,12 @@ import net.sf.samtools.SAMRecord;
 
     private static boolean redraw = false;
     private boolean setMaxBases = false;
-    
+
     private boolean plotByStrand = false;
     private boolean plotHeatMap = false;
     private List<HeatMapLn> heatPlots;
+    private List<String> selected = new Vector<String>();
+    private boolean showGrid = false;
 
     protected CoveragePanel(final BamView bamView)
     {
@@ -259,7 +263,8 @@ import net.sf.samtools.SAMRecord;
         {
           if(hideBamList != null)
             idx = adjustIdx(idx, hideBamList);
-          drawHeatMap(g2, hgt, line, idx, thisPlot, fName);
+          drawHeatMap(g2, hgt, line, idx, thisPlot, fName, 
+              (idx == plots.size()-1));
         }
         else
           drawLinePlot(g2, wid, hgt, line, thisPlot);
@@ -379,14 +384,14 @@ import net.sf.samtools.SAMRecord;
      * @param idx
      * @param thisPlot
      */
-    private void drawHeatMap(final Graphics2D g2, int hgt, LineAttributes line, int idx, int[][] thisPlot, String fName)
+    private void drawHeatMap(final Graphics2D g2, int hgt, LineAttributes line, int idx, int[][] thisPlot, String fName, boolean lastPlot)
     { // heat map
-      int NSHADES = 240;
-      int plotHgt = hgt/plots.size();
-      int plotPos = plotHgt * idx;
-      Color definedColours[] = Plot.makeColours(line.getLineColour(), NSHADES);
+      final int NSHADES = 240;
+      final int plotHgt = hgt/plots.size();
+      final int plotPos = (hgt*idx)/plots.size();
+      final Color definedColours[] = Plot.makeColours(line.getLineColour(), NSHADES);
 
-      heatPlots.add(new HeatMapLn(plotPos, plotPos+plotHgt, idx, fName));
+      heatPlots.add(new HeatMapLn(plotPos, plotPos+plotHgt, fName));
       
       float maxVal = getValue(max);
       for(int i=0; i<thisPlot.length; i++)
@@ -406,6 +411,22 @@ import net.sf.samtools.SAMRecord;
         g2.setColor(definedColours[ colourIdx ]);
         g2.fillRect(xpos, plotPos, (int) (windowSize*2*pixPerBase), plotHgt);
       }
+      
+      if(showGrid && !lastPlot)
+      {
+        g2.setColor(Color.darkGray);
+        g2.drawLine(0, plotPos+plotHgt-1, bamView.getWidth(), plotPos+plotHgt-1);
+      }
+      
+      if(selected.contains(fName))
+      {
+        g2.setColor(Color.darkGray);
+        Stroke stroke = g2.getStroke();
+        g2.setStroke(new BasicStroke(2.f));
+        g2.drawLine(0, plotPos+1, bamView.getWidth(), plotPos+1);
+        g2.drawLine(0, plotPos+plotHgt-1, bamView.getWidth(), plotPos+plotHgt-1);
+        g2.setStroke(stroke);
+      }
     }
     
     private AlphaComposite makeComposite(float alpha)
@@ -483,6 +504,13 @@ import net.sf.samtools.SAMRecord;
 
       return null;
     }
+    
+    protected void showLabels(boolean showLabel)
+    {
+      //
+      this.showGrid = showLabel;
+      bamView.repaint();
+    }
 
     private void defineOpts()
     {
@@ -560,16 +588,51 @@ import net.sf.samtools.SAMRecord;
         return;
       }
     }
+    
+    /**
+     * Click on heatmap
+     * @param y
+     */
+    protected void singleClick(boolean isShiftDown, int ypos)
+    {
+      if(!isPlotHeatMap())
+        return;
+      
+      String sel = null;
+      for(HeatMapLn h: heatPlots)
+      {
+        if(ypos > h.yTop && ypos < h.yBtm)
+          sel = h.fName;
+      }
+      
+      if(selected.contains(sel))
+      {
+        if(!isShiftDown)
+          selected.clear();
+        else
+          selected.remove(sel);
+      }
+      else
+      {
+        if(!isShiftDown)
+          selected.clear();
+        selected.add(sel);
+      }
+    }
+    
+    protected boolean hasSelectedBams()
+    {
+      return (selected.size() > 0);
+    }
 
     class HeatMapLn
     {
-      int yTop, yBtm, idx;
-      String fName;
-      HeatMapLn(int yTop, int yBtm, int idx, String fName)
+      private int yTop, yBtm;
+      private String fName;
+      HeatMapLn(int yTop, int yBtm, String fName)
       {
         this.yTop = yTop;
         this.yBtm = yBtm;
-        this.idx  = idx;
         this.fName = fName;
       }
       
-- 
GitLab