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