diff --git a/uk/ac/sanger/artemis/components/Plot.java b/uk/ac/sanger/artemis/components/Plot.java
index b5a726915d514c500e50e94def7f14827dda16cb..175832128117d16e0d85edf50e66e3b67e3f612a 100644
--- a/uk/ac/sanger/artemis/components/Plot.java
+++ b/uk/ac/sanger/artemis/components/Plot.java
@@ -930,7 +930,7 @@ public abstract class Plot extends JPanel
* @param NUMBER_OF_SHADES
* @return
*/
- protected Color[] makeColours(Color col, int NUMBER_OF_SHADES)
+ public static Color[] makeColours(Color col, int NUMBER_OF_SHADES)
{
Color definedColour[] = new Color[NUMBER_OF_SHADES];
for(int i = 0; i < NUMBER_OF_SHADES; ++i)
diff --git a/uk/ac/sanger/artemis/components/alignment/AbstractGraphPanel.java b/uk/ac/sanger/artemis/components/alignment/AbstractGraphPanel.java
index 9f651b952c224c2165f1eb87abc1fc3944c29335..1f53fe42e48a02f0e8769c767cb3cbb5d6c7a639 100644
--- a/uk/ac/sanger/artemis/components/alignment/AbstractGraphPanel.java
+++ b/uk/ac/sanger/artemis/components/alignment/AbstractGraphPanel.java
@@ -161,6 +161,18 @@ public class AbstractGraphPanel extends JPanel
g2.drawString(maxStr, xpos, fm.getHeight());
}
+ /**
+ * Return the log value if the log scale is selected
+ * @param val
+ * @return
+ */
+ protected float getValue(int val)
+ {
+ if(val == 0)
+ return 0.f;
+ return (float) (bamView.logScale ? Math.log(val) : val);
+ }
+
protected void drawSelectionRange(final Graphics2D g2,
final float pixPerBase,
final int start,
diff --git a/uk/ac/sanger/artemis/components/alignment/BamView.java b/uk/ac/sanger/artemis/components/alignment/BamView.java
index 19d8734db49ed791c2e3eb97a6382c897c8b0be0..be26ccb51dd06460dbd098b89afdaa398e385aa1 100644
--- a/uk/ac/sanger/artemis/components/alignment/BamView.java
+++ b/uk/ac/sanger/artemis/components/alignment/BamView.java
@@ -184,7 +184,7 @@ public class BamView extends JPanel
private CoveragePanel coveragePanel;
private SnpPanel snpPanel;
- private boolean logScale = false;
+ protected boolean logScale = false;
private Ruler ruler;
private int nbasesInView;
@@ -205,6 +205,7 @@ public class BamView extends JPanel
private JCheckBoxMenuItem cbIsizeStackView = new JCheckBoxMenuItem("Inferred Size", false);
private JCheckBoxMenuItem cbCoverageView = new JCheckBoxMenuItem("Coverage", false);
private JCheckBoxMenuItem cbCoverageStrandView = new JCheckBoxMenuItem("Coverage by Strand", false);
+ private JCheckBoxMenuItem cbCoverageHeatMap = new JCheckBoxMenuItem("Coverage Heat Map", false);
private JCheckBoxMenuItem cbLastSelected;
private ButtonGroup buttonGroup = new ButtonGroup();
@@ -354,6 +355,7 @@ public class BamView extends JPanel
buttonGroup.add(cbIsizeStackView);
buttonGroup.add(cbCoverageView);
buttonGroup.add(cbCoverageStrandView);
+ buttonGroup.add(cbCoverageHeatMap);
addMouseListener(new PopupListener());
jspView = new JScrollPane(this,
@@ -1807,7 +1809,7 @@ public class BamView extends JPanel
}
int hgt = jspView.getVisibleRect().height-scaleHeight;
- if(!cbCoverageStrandView.isSelected())
+ if(!cbCoverageStrandView.isSelected() && !cbCoverageHeatMap.isSelected())
{
try
{
@@ -1819,7 +1821,8 @@ public class BamView extends JPanel
catch(Exception e){}
}
- g2.translate(0, getHeight()-hgt-scaleHeight);
+ g2.translate(0, getJspView().getViewport().getViewPosition().y);
+
coverageView.drawSelectionRange(g2, pixPerBase, start, end, getHeight(), Color.PINK);
coverageView.draw(g2, getWidth(), hgt);
coverageView.drawMax(g2);
@@ -2519,6 +2522,7 @@ public class BamView extends JPanel
cbStrandStackView.setFont(viewMenu.getFont());
cbCoverageView.setFont(viewMenu.getFont());
cbCoverageStrandView.setFont(viewMenu.getFont());
+ cbCoverageHeatMap.setFont(viewMenu.getFont());
baseQualityColour.setFont(viewMenu.getFont());
colourByCoverageColour.setFont(viewMenu.getFont());
@@ -2530,6 +2534,7 @@ public class BamView extends JPanel
{
laststart = -1;
logMenuItem.setEnabled(isIsizeStackView());
+ getJspView().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
repaint();
}
});
@@ -2541,7 +2546,9 @@ public class BamView extends JPanel
public void actionPerformed(ActionEvent e)
{
laststart = -1;
- logMenuItem.setEnabled(isIsizeStackView());
+ if(cbStackView.isSelected())
+ logMenuItem.setEnabled(false);
+ getJspView().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
repaint();
}
});
@@ -2553,7 +2560,9 @@ public class BamView extends JPanel
public void actionPerformed(ActionEvent e)
{
laststart = -1;
- logMenuItem.setEnabled(isIsizeStackView());
+ if(cbPairedStackView.isSelected())
+ logMenuItem.setEnabled(false);
+ getJspView().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
repaint();
}
});
@@ -2567,7 +2576,9 @@ public class BamView extends JPanel
if(isStrandStackView())
setViewportMidPoint();
- logMenuItem.setEnabled(isIsizeStackView());
+ if(cbStrandStackView.isSelected())
+ logMenuItem.setEnabled(false);
+ getJspView().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
repaint();
}
});
@@ -2578,11 +2589,13 @@ public class BamView extends JPanel
public void actionPerformed(ActionEvent e)
{
laststart = -1;
- logMenuItem.setEnabled(isIsizeStackView());
if(cbCoverageView.isSelected())
{
+ logMenuItem.setEnabled(true);
+ coverageView.setPlotHeatMap(false);
coverageView.setPlotByStrand(false);
setViewportBtm();
+ getJspView().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
}
repaint();
}
@@ -2594,17 +2607,39 @@ public class BamView extends JPanel
public void actionPerformed(ActionEvent e)
{
laststart = -1;
- logMenuItem.setEnabled(isIsizeStackView());
if(cbCoverageStrandView.isSelected())
{
+ logMenuItem.setEnabled(true);
+ coverageView.setPlotHeatMap(false);
coverageView.setPlotByStrand(true);
setViewportBtm();
+ getJspView().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
}
+
repaint();
}
});
viewMenu.add(cbCoverageStrandView);
+
+ cbCoverageHeatMap.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ laststart = -1;
+ if(cbCoverageHeatMap.isSelected())
+ {
+ logMenuItem.setEnabled(true);
+ coverageView.setPlotHeatMap(true);
+ setViewportBtm();
+ getJspView().setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
+ }
+
+ repaint();
+ }
+ });
+ viewMenu.add(cbCoverageHeatMap);
+
menu.add(viewMenu);
final JCheckBoxMenuItem checkBoxSNPs = new JCheckBoxMenuItem("SNP marks");
@@ -2692,7 +2727,8 @@ public class BamView extends JPanel
if( isCoverage &&
!cbCoverageView.isSelected() &&
- !cbCoverageStrandView.isSelected() )
+ !cbCoverageStrandView.isSelected() &&
+ !cbCoverageHeatMap.isSelected())
laststart = -1;
repaint();
}
@@ -2825,6 +2861,8 @@ public class BamView extends JPanel
feature_display, bases, (JPanel) mainPanel.getParent(), null);
bamView.getJspView().getVerticalScrollBar().setValue(
bamView.getJspView().getVerticalScrollBar().getMaximum());
+ getJspView().getVerticalScrollBar().setValue(
+ bamView.getJspView().getVerticalScrollBar().getMaximum());
int start = getBaseAtStartOfView();
setDisplay(start, nbasesInView+start, null);
@@ -3124,13 +3162,13 @@ public class BamView extends JPanel
}
else if(jspView != null)
{
- if(!cbCoverageView.isSelected() && !cbCoverageStrandView.isSelected() && nbasesInView >= MAX_BASES)
+ if(isCoverageView(pixPerBase) && nbasesInView >= MAX_BASES)
{
cbLastSelected = getSelectedCheckBoxMenuItem();
cbCoverageView.setSelected(true);
coverageView.setPlotByStrand(false);
}
- else if((cbCoverageView.isSelected() || cbCoverageStrandView.isSelected()) && nbasesInView < MAX_BASES && cbLastSelected != null)
+ else if(isCoverageView(pixPerBase) && nbasesInView < MAX_BASES && cbLastSelected != null)
{
cbLastSelected.setSelected(true);
cbLastSelected = null;
@@ -3358,7 +3396,7 @@ public class BamView extends JPanel
{
if(isBaseAlignmentView(pixPerBase))
return false;
- return cbCoverageView.isSelected() || cbCoverageStrandView.isSelected();
+ return cbCoverageView.isSelected() || cbCoverageStrandView.isSelected() || cbCoverageHeatMap.isSelected();
}
private boolean isIsizeStackView()
@@ -3385,6 +3423,8 @@ public class BamView extends JPanel
return cbIsizeStackView;
if(cbCoverageView.isSelected())
return cbCoverageView;
+ if(cbCoverageHeatMap.isSelected())
+ return cbCoverageHeatMap;
return cbCoverageStrandView;
}
diff --git a/uk/ac/sanger/artemis/components/alignment/CoveragePanel.java b/uk/ac/sanger/artemis/components/alignment/CoveragePanel.java
index 6e29e5b8f889116805a6f000f8688a7c2f0493fc..ffd7bd4e0ea917ee01645654f383f73c4723a255 100644
--- a/uk/ac/sanger/artemis/components/alignment/CoveragePanel.java
+++ b/uk/ac/sanger/artemis/components/alignment/CoveragePanel.java
@@ -45,6 +45,8 @@ import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
+import uk.ac.sanger.artemis.components.Plot;
+
import net.sf.samtools.AlignmentBlock;
import net.sf.samtools.SAMRecord;
@@ -60,6 +62,7 @@ import net.sf.samtools.SAMRecord;
private boolean setMaxBases = false;
private boolean plotByStrand = false;
+ private boolean plotHeatMap = false;
protected CoveragePanel(final BamView bamView)
{
@@ -115,7 +118,8 @@ import net.sf.samtools.SAMRecord;
if(plots == null)
return;
- drawSelectionRange(g2, pixPerBase, start, end, getHeight(), Color.PINK);
+ if(!plotHeatMap)
+ drawSelectionRange(g2, pixPerBase, start, end, getHeight(), Color.PINK);
drawPlot(g2);
drawMax(g2);
}
@@ -175,6 +179,7 @@ import net.sf.samtools.SAMRecord;
max = thisPlot[i][0];
}
}
+
draw(g2, getWidth(), getHeight());
}
@@ -232,7 +237,6 @@ import net.sf.samtools.SAMRecord;
else
lines = getLineAttributes(size);
- int hgt2 = hgt/2;
Enumeration<String> plotEum = plots.keys();
while(plotEum.hasMoreElements())
@@ -245,86 +249,97 @@ import net.sf.samtools.SAMRecord;
index = lines.length-1;
else
index = bamView.bamList.indexOf(fileName);
-
- g2.setColor(lines[index].getLineColour());
- if(lines[index].getPlotType() == LineAttributes.PLOT_TYPES[0])
+
+ if(plotHeatMap)
+ drawHeatMap(g2, hgt, index, thisPlot);
+ else
+ drawLinePlot(g2, wid, hgt, index, thisPlot);
+ }
+ }
+
+ private void drawLinePlot(final Graphics2D g2, int wid, int hgt, int index, int[][] thisPlot)
+ {
+ g2.setColor(lines[index].getLineColour());
+ int hgt2 = hgt/2;
+ float maxVal = getValue(max);
+
+ if(lines[index].getPlotType() == LineAttributes.PLOT_TYPES[0])
+ {
+ g2.setStroke(lines[index].getStroke());
+ for(int i=1; i<thisPlot.length; i++)
{
- g2.setStroke(lines[index].getStroke());
- for(int i=1; i<thisPlot.length; i++)
+ int x0 = (int) ((((i-1)*(windowSize)) - windowSize/2.f)*pixPerBase);
+ int x1 = (int) (((i*(windowSize)) - windowSize/2.f)*pixPerBase);
+ int y0, y1;
+ if(plotByStrand)
{
- int x0 = (int) ((((i-1)*(windowSize)) - windowSize/2.f)*pixPerBase);
- int x1 = (int) (((i*(windowSize)) - windowSize/2.f)*pixPerBase);
- int y0, y1;
- if(plotByStrand)
- {
- for(int col=0; col<2; col++)
- {
- final int factor;
- if(col == 0)
- factor = 1; // fwd strand
- else
- factor = -1; // reverse strand
-
- y0 = (int) (hgt2 - (factor)*(((float)thisPlot[i-1][col]/(float)max)*hgt2));
- y1 = (int) (hgt2 - (factor)*(((float)thisPlot[i][col]/(float)max)*hgt2));
-
- g2.drawLine(x0, y0, x1, y1);
- }
- }
- else
+ for(int col=0; col<2; col++)
{
- y0 = (int) (hgt - (((float)(thisPlot[i-1][0])/(float)max)*hgt));
- y1 = (int) (hgt - (((float)(thisPlot[i][0])/(float)max)*hgt));
+ final int factor;
+ if(col == 0)
+ factor = 1; // fwd strand
+ else
+ factor = -1; // reverse strand
+
+ y0 = (int) (hgt2 - (factor)*((getValue(thisPlot[i-1][col])/maxVal)*hgt2));
+ y1 = (int) (hgt2 - (factor)*((getValue(thisPlot[i][col])/maxVal)*hgt2));
+
g2.drawLine(x0, y0, x1, y1);
}
}
+ else
+ {
+ y0 = (int) (hgt - ((getValue(thisPlot[i-1][0])/maxVal)*hgt));
+ y1 = (int) (hgt - ((getValue(thisPlot[i][0])/maxVal)*hgt));
+ g2.drawLine(x0, y0, x1, y1);
+ }
}
- else // filled plots
- {
- g2.setComposite(makeComposite(0.75f));
+ }
+ else // filled plots
+ {
+ g2.setComposite(makeComposite(0.75f));
- if(plotByStrand)
+ if(plotByStrand)
+ {
+ final GeneralPath shapeFwd = new GeneralPath();
+ shapeFwd.moveTo(0,hgt2);
+ final GeneralPath shapeBwd = new GeneralPath();
+ shapeBwd.moveTo(0,hgt2);
+
+ for(int i=0; i<thisPlot.length; i++)
{
- final GeneralPath shapeFwd = new GeneralPath();
- shapeFwd.moveTo(0,hgt2);
- final GeneralPath shapeBwd = new GeneralPath();
- shapeBwd.moveTo(0,hgt2);
-
- for(int i=0; i<thisPlot.length; i++)
+ float xpos = ((i*(windowSize)) - windowSize/2.f)*pixPerBase;
+ for(int col=0; col<2; col++)
{
- float xpos = ((i*(windowSize)) - windowSize/2.f)*pixPerBase;
- for(int col=0; col<2; col++)
- {
- if(col == 0)
- shapeFwd.lineTo(xpos,
- hgt2 - (((float)thisPlot[i][col]/(float)max)*hgt2));
- else
- shapeBwd.lineTo(xpos,
- hgt2 + (((float)thisPlot[i][col]/(float)max)*hgt2));
- }
+ if(col == 0)
+ shapeFwd.lineTo(xpos,
+ hgt2 - ((getValue(thisPlot[i][col])/maxVal)*hgt2));
+ else
+ shapeBwd.lineTo(xpos,
+ hgt2 + ((getValue(thisPlot[i][col])/maxVal)*hgt2));
}
-
- shapeBwd.lineTo(wid,hgt2);
- shapeFwd.lineTo(wid,hgt2);
- g2.fill(shapeBwd);
- g2.fill(shapeFwd);
}
- else
+
+ shapeBwd.lineTo(wid,hgt2);
+ shapeFwd.lineTo(wid,hgt2);
+ g2.fill(shapeBwd);
+ g2.fill(shapeFwd);
+ }
+ else
+ {
+ final GeneralPath shape = new GeneralPath();
+ shape.moveTo(0,hgt);
+ for(int i=0; i<thisPlot.length; i++)
{
- final GeneralPath shape = new GeneralPath();
- shape.moveTo(0,hgt);
- for(int i=0; i<thisPlot.length; i++)
- {
- float xpos = ((i*(windowSize)) - windowSize/2.f)*pixPerBase;
- shape.lineTo(xpos,
- hgt - (((float)thisPlot[i][0]/(float)max)*hgt));
- }
- shape.lineTo(wid,hgt);
- g2.fill(shape);
+ float xpos = ((i*(windowSize)) - windowSize/2.f)*pixPerBase;
+ shape.lineTo(xpos,
+ hgt - ((getValue(thisPlot[i][0])/maxVal)*hgt));
}
+ shape.lineTo(wid,hgt);
+ g2.fill(shape);
}
}
-
+
if(plotByStrand)
{
g2.setColor(Color.GRAY);
@@ -332,6 +347,42 @@ import net.sf.samtools.SAMRecord;
}
}
+ /**
+ * Draw as heat map
+ * @param g2
+ * @param hgt
+ * @param index
+ * @param thisPlot
+ */
+ private void drawHeatMap(final Graphics2D g2, int hgt, int index, int[][] thisPlot)
+ { // heat map
+ int NUMBER_OF_SHADES = 254;
+ int plotHgt = hgt/plots.size();
+ int plotPos = plotHgt * index;
+ Color definedColours[] = Plot.makeColours(lines[index].getLineColour(),
+ NUMBER_OF_SHADES);
+
+ float maxVal = getValue(max);
+ for(int i=0; i<thisPlot.length; i++)
+ {
+ int xpos = (int) ((((i-1)*(windowSize)) - windowSize/2.f)*pixPerBase);
+
+ // this is a number between 0.0 and 1.0
+ final float scaledValue = getValue(thisPlot[i][0]) / maxVal;
+ // set color based on value
+ int colourIndex =
+ (int)(definedColours.length * 0.999 * scaledValue);
+
+ if(colourIndex > definedColours.length - 1)
+ colourIndex = definedColours.length - 1;
+ else if (colourIndex < 0)
+ colourIndex = 0;
+
+ g2.setColor(definedColours[ colourIndex ]);
+ g2.fillRect(xpos, plotPos, windowSize, plotHgt);
+ }
+ }
+
private AlphaComposite makeComposite(float alpha)
{
int type = AlphaComposite.SRC_OVER;
@@ -374,6 +425,14 @@ import net.sf.samtools.SAMRecord;
this.plotByStrand = plotByStrand;
}
+ /**
+ * @param plotHeatMap the plotHeatMap to set
+ */
+ protected void setPlotHeatMap(boolean plotHeatMap)
+ {
+ this.plotHeatMap = plotHeatMap;
+ }
+
private void defineOpts()
{
final JPanel opts = new JPanel(new GridBagLayout());