Skip to content
Snippets Groups Projects
Commit c99b1b9d authored by tjc's avatar tjc
Browse files

add graphs

git-svn-id: svn+ssh://svn.internal.sanger.ac.uk/repos/svn/pathsoft/artemis/trunk@15609 ee4ac58c-ac51-4696-9907-e4b3aa274f04
parent 768b5c5a
No related branches found
No related tags found
No related merge requests found
package uk.ac.sanger.artemis.components.variant;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.GeneralPath;
import java.io.IOException;
import java.text.DecimalFormat;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTextField;
import uk.ac.sanger.artemis.FeatureVector;
import uk.ac.sanger.artemis.components.variant.BCFReader.BCFReaderIterator;
public class GraphPanel extends JPanel
{
private static final long serialVersionUID = 1L;
protected boolean autoWinSize = true;
protected int userWinSize = 1;
protected JPopupMenu popup = new JPopupMenu();
private VCFview vcfView;
private static String TYPES[] = { "SNP", "DP" };
private int type = 0; // 0 - SNP; 1 - DP
public GraphPanel(final VCFview vcfView)
{
super();
this.vcfView = vcfView;
setBackground(Color.white);
initPopupMenu(this);
}
/**
* Override
*/
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
float pixPerBase = vcfView.getPixPerBaseByWidth();
int sbeg = vcfView.getBaseAtStartOfView();
int send = sbeg+vcfView.getBasesInView();
int windowSize;
if(autoWinSize)
{
windowSize = (vcfView.getBasesInView()/300);
userWinSize = windowSize;
}
else
windowSize = userWinSize;
if(windowSize < 1)
windowSize = 1;
int nBins = Math.round((send-sbeg+1.f)/windowSize);
int snpCount[] = new int[nBins];
int max = 0;
for(int i=0; i<snpCount.length; i++)
snpCount[i] = 0;
AbstractVCFReader readers[] = vcfView.getVcfReaders();
FeatureVector features = vcfView.getCDSFeaturesInRange(sbeg, send);
for(int i=0; i<readers.length; i++)
{
max = countAll(readers[i], sbeg, send, windowSize, nBins, features, snpCount, max);
}
g2.setColor(Color.red);
g2.setStroke(new BasicStroke(1.f));
if(windowSize == 1)
{
GeneralPath shape = new GeneralPath();
shape.moveTo(0,getHeight());
for(int i=0; i<snpCount.length; i++)
{
float xpos1 = ((i*windowSize) )*pixPerBase;
float xpos2 = ((i*windowSize) + windowSize)*pixPerBase;
shape.lineTo(xpos1,getHeight());
shape.lineTo(xpos1,
getHeight() - (((float)snpCount[i]/(float)max)*getHeight()));
shape.lineTo(xpos2,
getHeight() - (((float)snpCount[i]/(float)max)*getHeight()));
shape.lineTo(xpos2,getHeight());
}
shape.lineTo(getWidth(),getHeight());
g2.fill(shape);
}
else
{
for(int i=1; i<snpCount.length; i++)
{
int x0 = (int) (((i*windowSize) - windowSize/2.f)*pixPerBase);
int y0 = (int) (getHeight() - (((float)snpCount[i-1]/(float)max)*getHeight()));
int x1 = (int) ((((i+1)*windowSize) - windowSize/2.f)*pixPerBase);
int y1 = (int) (getHeight() - (((float)snpCount[i]/(float)max)*getHeight()));
g2.drawLine(x0, y0, x1, y1);
}
}
DecimalFormat df = new DecimalFormat("0.00##");
String maxStr = TYPES[type]+" : "+df.format((float)max/(float)windowSize);
FontMetrics fm = getFontMetrics(getFont());
g2.setColor(Color.black);
int xpos = getWidth() - fm.stringWidth(maxStr) - 10;
g2.drawString(maxStr, xpos, fm.getHeight());
}
private int countAll(AbstractVCFReader reader, int sbeg, int send, int windowSize,
int nBins, FeatureVector features, int snpCount[], int max)
{
if(vcfView.isConcatenate())
{
String[] contigs = reader.getSeqNames();
for(int j=0; j<contigs.length; j++)
{
int offset = vcfView.getSequenceOffset(contigs[j]);
int nextOffset;
if(j<contigs.length-1)
nextOffset = vcfView.getSequenceOffset(contigs[j+1]);
else
nextOffset = vcfView.seqLength;
if( (offset >= sbeg && offset < send) ||
(offset < sbeg && sbeg < nextOffset) )
{
int thisStart = sbeg - offset;
if(thisStart < 1)
thisStart = 1;
int thisEnd = send - offset;
max = count(reader, contigs[j], thisStart, thisEnd, windowSize, nBins, features, snpCount, max);
}
}
return max;
}
else
return count(reader, vcfView.getChr(), sbeg, send, windowSize, nBins, features, snpCount, max);
}
private int count(AbstractVCFReader reader, String chr, int sbeg, int send, int windowSize,
int nBins, FeatureVector features, int snpCount[], int max)
{
if(reader instanceof BCFReader)
{
try
{
BCFReader bcfReader = (BCFReader)reader;
BCFReaderIterator it = bcfReader.query(chr, sbeg, send);
VCFRecord record;
while((record = it.next()) != null)
{
max = calc(record, features, reader, windowSize, nBins, snpCount, max);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
else
{
TabixReader.Iterator iter =
((TabixReader)reader).query(chr+":"+sbeg+"-"+send); // get the iterator
if (iter == null)
return max;
try
{
String s;
while ((s = iter.next()) != null)
{
VCFRecord record = VCFRecord.parse(s);
max = calc(record, features, reader, windowSize, nBins, snpCount, max);
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
return max;
}
private int calc(VCFRecord record, FeatureVector features,
AbstractVCFReader reader, int windowSize, int nBins, int snpCount[], int max)
{
int pos = record.getPos() + vcfView.getSequenceOffset(record.getChrom());
if(!vcfView.showVariant(record, features, pos, reader.isVcf_v4()))
return max;
int bin = (int)((pos-vcfView.getBaseAtStartOfView()) / windowSize);
if(bin < 0 || bin > nBins-1)
return max;
if(type == 1)
{
int dp = 0;
try
{
dp = Integer.parseInt(record.getInfoValue("DP"));
}
catch(Exception e){ e.printStackTrace(); }
snpCount[bin]+=dp;
}
else
snpCount[bin]+=1;
if(snpCount[bin] > max)
max = snpCount[bin];
return max;
}
private void initPopupMenu(final JPanel graphPanel)
{
final JMenuItem setScale = new JMenuItem("Set the Window Size...");
setScale.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent _)
{
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
JPanel pane = new JPanel(gridbag);
final JTextField newWinSize = new JTextField(Integer.toString(userWinSize), 10);
final JLabel lab = new JLabel("Window size:");
c.gridy = 0;
pane.add(lab, c);
pane.add(newWinSize, c);
final JCheckBox autoSet = new JCheckBox("Automatically set window size", false);
autoSet.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
lab.setEnabled(!autoSet.isSelected());
newWinSize.setEnabled(!autoSet.isSelected());
}
});
c.gridy = 1;
c.gridwidth = GridBagConstraints.REMAINDER;
pane.add(autoSet, c);
String window_options[] = { "OK", "Cancel" };
int select = JOptionPane.showOptionDialog(null, pane, "Window Size",
JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null,
window_options, window_options[0]);
if (select == 1)
return;
autoWinSize = autoSet.isSelected();
try
{
userWinSize = Integer.parseInt(newWinSize.getText().trim());
}
catch (NumberFormatException nfe)
{
return;
}
graphPanel.repaint();
}
});
popup.add(setScale);
addMouseListener(new PopupListener());
}
/**
* @param type the type to set
*/
protected void setType(int type)
{
this.type = type;
}
/**
* Popup menu listener
*/
class PopupListener extends MouseAdapter
{
JMenuItem gotoMateMenuItem;
JMenuItem showDetails;
public void mouseClicked(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
maybeShowPopup(e);
}
public void mouseReleased(MouseEvent e)
{
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e)
{
if(e.isPopupTrigger())
{
popup.show(e.getComponent(),
e.getX(), e.getY());
}
}
}
}
\ No newline at end of file
......@@ -54,6 +54,7 @@ import java.util.List;
import java.util.Vector;
import java.util.regex.Pattern;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JCheckBox;
......@@ -131,6 +132,8 @@ public class VCFview extends JPanel
private String chr;
private VCFRecord mouseVCF;
private int mouseOverIndex = -1;
private GraphPanel graphPanel;
//record of where a mouse drag starts
private int dragStart = -1;
......@@ -222,7 +225,8 @@ public class VCFview extends JPanel
vcfPanel.add(jspView, BorderLayout.CENTER);
JPanel bottomPanel = new JPanel(new BorderLayout());
GraphPanel graphPanel = new GraphPanel(this);
graphPanel = new GraphPanel(this);
graphPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, Color.gray));
graphPanel.setPreferredSize(new Dimension(900, 100));
graphPanel.setVisible(false);
......@@ -565,6 +569,33 @@ public class VCFview extends JPanel
}
});
view.add(viewFasta);
JMenu graph = new JMenu("Graph");
popup.add(graph);
final JCheckBoxMenuItem graphSNP = new JCheckBoxMenuItem("SNP");
final JCheckBoxMenuItem graphDP = new JCheckBoxMenuItem("Depth (DP)");
graph.add(graphSNP);
graphSNP.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
graphPanel.setVisible(graphSNP.isSelected());
graphDP.setSelected(false);
graphPanel.setType(0);
graphPanel.repaint();
}
});
graph.add(graphDP);
graphDP.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
graphPanel.setVisible(graphDP.isSelected());
graphSNP.setSelected(false);
graphPanel.setType(1);
graphPanel.repaint();
}
});
}
private static EntryGroup getReference(String reference)
......@@ -616,13 +647,21 @@ public class VCFview extends JPanel
* @param fileName
* @return
*/
private String testForURL(String fileName)
private String testForURL(String fileName, boolean isBCF)
{
if(!fileName.startsWith("http:"))
return fileName;
String newFileName = download(fileName, null, ".bcf");
download(fileName+".bci", newFileName, ".bci");
if(isBCF)
{
String newFileName = download(fileName, null, ".bcf");
download(fileName+".bci", newFileName, ".bci");
return newFileName;
}
String newFileName = download(fileName, null, ".vcf.gz");
download(fileName+".tbi", newFileName, ".tbi");
return newFileName;
}
......@@ -673,7 +712,7 @@ public class VCFview extends JPanel
{
if(IOUtils.isBCF(fileName))
{
fileName = testForURL(fileName);
fileName = testForURL(fileName, true);
vcfReaders[index] = new BCFReader(new File(fileName));
String hdr = ((BCFReader)vcfReaders[index]).headerToString();
......@@ -682,6 +721,7 @@ public class VCFview extends JPanel
return hdr;
}
fileName = testForURL(fileName, false);
BlockCompressedInputStream is =
new BlockCompressedInputStream(new FileInputStream(fileName));
vcfReaders[index] = new TabixReader(fileName);
......@@ -790,6 +830,13 @@ public class VCFview extends JPanel
return offsetLengths.get(refName);
}
public void repaint()
{
super.repaint();
if(graphPanel != null && graphPanel.isVisible())
graphPanel.repaint();
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
......@@ -892,7 +939,7 @@ public class VCFview extends JPanel
}
}
private FeatureVector getCDSFeaturesInRange(int start, int end)
protected FeatureVector getCDSFeaturesInRange(int start, int end)
{
if(entryGroup == null)
return null;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment