diff --git a/uk/ac/sanger/artemis/components/EntryEdit.java b/uk/ac/sanger/artemis/components/EntryEdit.java index 9ecfae72a5f9876bc50ac18dd9f71f2d59ba2e1f..c22d76a8b5f6ef928f876ba23fba56b9e34a37af 100644 --- a/uk/ac/sanger/artemis/components/EntryEdit.java +++ b/uk/ac/sanger/artemis/components/EntryEdit.java @@ -34,6 +34,7 @@ import uk.ac.sanger.artemis.components.alignment.FileSelectionDialog; import uk.ac.sanger.artemis.components.alignment.LookSeqPanel; import uk.ac.sanger.artemis.components.filetree.FileList; import uk.ac.sanger.artemis.components.filetree.FileManager; +import uk.ac.sanger.artemis.components.variant.VCFview; import uk.ac.sanger.artemis.editor.BigPane; import uk.ac.sanger.artemis.editor.FastaTextPane; import uk.ac.sanger.artemis.editor.HitInfo; @@ -112,8 +113,10 @@ public class EntryEdit extends JFrame /** Alignment panel */ private BamView jamView; - private JPanel jamPanel; + private JPanel bamPanel; + private JPanel vcfPanel; private JSplitPane lowerSplitPane; + private JSplitPane ngSplitPane; /** * The EntrySourceVector reference that is created in the constructor. @@ -233,20 +236,27 @@ public class EntryEdit extends JFrame base_plot_group = new BasePlotGroup(getEntryGroup(), this, getSelection(), getGotoEventSource()); - //box_panel.add(base_plot_group); - jamPanel = new JPanel(); + bamPanel = new JPanel(); + vcfPanel = new JPanel(); + ngSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, + bamPanel, vcfPanel); + ngSplitPane.setBorder(null); + ngSplitPane.setResizeWeight(0.5); + ngSplitPane.setDividerLocation(1); + Dimension minimumSize = new Dimension(0, 0); + bamPanel.setMinimumSize(minimumSize); + vcfPanel.setMinimumSize(minimumSize); + + lowerSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, - jamPanel, mainPanel); + ngSplitPane, mainPanel); lowerSplitPane.setResizeWeight(0.); lowerSplitPane.setDividerSize(0); lowerSplitPane.setDividerLocation(0); - - //lowerSplitPane.setBorder(null); - + final JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, base_plot_group, lowerSplitPane); - splitPane.setDividerSize(0); splitPane.setResizeWeight(0.); splitPane.setBorder(null); @@ -274,7 +284,7 @@ public class EntryEdit extends JFrame getGotoEventSource(), base_plot_group); // read alignment panel - //main_box_panel.add(jamPanel); + //main_box_panel.add(bamPanel); one_line_per_entry_display.setShowLabels(false); one_line_per_entry_display.setOneLinePerEntry(true); @@ -530,15 +540,20 @@ public class EntryEdit extends JFrame return base_plot_group; } - protected JPanel getJamPanel() + protected JPanel getBamPanel() { - return jamPanel; + return bamPanel; } protected JPanel getJamView() { return jamView; } + + protected JPanel getVcfPanel() + { + return vcfPanel; + } /** @@ -1245,50 +1260,94 @@ public class EntryEdit extends JFrame file_menu.addSeparator(); - JMenuItem read_bam_file = new JMenuItem("Read BAM ..."); + JMenuItem read_bam_file = new JMenuItem("Read BAM / VCF ..."); read_bam_file.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { FileSelectionDialog fileChooser = new FileSelectionDialog( - null, false, "BamView", "BAM"); - List<String> listBams = fileChooser.getBamFiles(); + null, false, "BAM / VCF View", "BAM / VCF"); - jamPanel.removeAll(); + List<String> listBams = fileChooser.getFiles(".*\\.bam$"); + logger4j.debug("No. BAM FILES="+listBams.size()); - try + if(listBams.size() > 0) { - jamView = new BamView(listBams, null, 2000); + bamPanel.removeAll(); + try + { + jamView = new BamView(listBams, null, 2000); + } + catch (Exception ex) + { + JOptionPane.showMessageDialog(null, ex.getMessage(), "Error", + JOptionPane.ERROR_MESSAGE); + return; + } + + jamView.setShowScale(false); + jamView.setBases(getEntryGroup().getBases()); + jamView.addJamToPanel(bamPanel, null, true, feature_display); + jamView.getJspView().setHorizontalScrollBarPolicy( + JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + jamView.removeBorder(); + jamView.setDisplay(feature_display.getFirstVisibleForwardBase(), + feature_display.getLastVisibleForwardBase(), null); + bamPanel.revalidate(); + jamView.getJspView().getVerticalScrollBar().setValue( + jamView.getJspView().getVerticalScrollBar().getMaximum()); + feature_display.addDisplayAdjustmentListener(jamView); + feature_display.getSelection().addSelectionChangeListener(jamView); + + lowerSplitPane.setDividerSize(3); + lowerSplitPane.setDividerLocation(0.35d); + + if(vcfPanel.getComponents().length > 0) + { + ngSplitPane.setResizeWeight(0.5); + ngSplitPane.setDividerSize(3); + ngSplitPane.setDividerLocation(0.5); + } + else + { + ngSplitPane.setResizeWeight(1); + ngSplitPane.setDividerSize(1); + ngSplitPane.setDividerLocation(1.d); + } } - catch(Exception ex) + + List<String> vcfFiles = fileChooser.getFiles(".*\\.vcf(\\.gz)*$"); + logger4j.debug("No. VCF FILES="+vcfFiles.size()); + if (vcfFiles.size() > 0) { - JOptionPane.showMessageDialog(null, - ex.getMessage(), - "Error", - JOptionPane.ERROR_MESSAGE); - return; + vcfPanel.removeAll(); + VCFview vcfView = new VCFview(null, vcfPanel, vcfFiles, + feature_display.getMaxVisibleBases(), 1, null, null, + feature_display); + + feature_display.addDisplayAdjustmentListener(vcfView); + + lowerSplitPane.setDividerSize(3); + lowerSplitPane.setDividerLocation(0.35d); + + if(bamPanel.getComponents().length > 0) + { + ngSplitPane.setResizeWeight(0.5); + ngSplitPane.setDividerSize(3); + ngSplitPane.setDividerLocation(0.5); + } + else + { + ngSplitPane.setResizeWeight(0); + ngSplitPane.setDividerSize(0); + ngSplitPane.setDividerLocation(0.); + } } - - jamView.setShowScale(false); - jamView.setBases(getEntryGroup().getBases()); - jamView.addJamToPanel(jamPanel, null, true, feature_display); - jamView.getJspView().setHorizontalScrollBarPolicy( - JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - jamView.removeBorder(); - jamView.setDisplay(feature_display.getFirstVisibleForwardBase(), - feature_display.getLastVisibleForwardBase(), null); - jamPanel.revalidate(); - jamView.getJspView().getVerticalScrollBar().setValue( - jamView.getJspView().getVerticalScrollBar().getMaximum()); - feature_display.addDisplayAdjustmentListener(jamView); - feature_display.getSelection().addSelectionChangeListener(jamView); - - lowerSplitPane.setDividerSize(3); - lowerSplitPane.setDividerLocation(0.35d); } }); file_menu.add(read_bam_file); - + + file_menu.addSeparator(); final JMenuItem save_default = diff --git a/uk/ac/sanger/artemis/components/MultiComparator.java b/uk/ac/sanger/artemis/components/MultiComparator.java index d29924d36dc32a05a3aa31b97952ce61411e17bb..29294c11e6ce2b89c64e69ddc6da8c0e90dde6e9 100644 --- a/uk/ac/sanger/artemis/components/MultiComparator.java +++ b/uk/ac/sanger/artemis/components/MultiComparator.java @@ -949,7 +949,7 @@ public class MultiComparator extends JFrame { FileSelectionDialog fileChooser = new FileSelectionDialog( null, false, "BamView", "BAM"); - List<String> listBams = fileChooser.getBamFiles(); + List<String> listBams = fileChooser.getFiles(".*\\.bam$"); thisBamPanel.removeAll(); thisBamPanel.setVisible(true); diff --git a/uk/ac/sanger/artemis/components/PrintArtemis.java b/uk/ac/sanger/artemis/components/PrintArtemis.java index be57b8e3f4feacc3bd5830832b9063c9fc00fa61..80de655eefc4095bea72ca372e50c3d5d92720b8 100644 --- a/uk/ac/sanger/artemis/components/PrintArtemis.java +++ b/uk/ac/sanger/artemis/components/PrintArtemis.java @@ -96,8 +96,8 @@ public class PrintArtemis extends ScrollPanel implements Printable if(jamDisplay.isSelected() && entry.getJamView() != null && entry.getJamView().isVisible()) { - entry.getJamPanel().paintComponents(g2d); - g2d.translate(0,entry.getJamPanel().getHeight()); + entry.getBamPanel().paintComponents(g2d); + g2d.translate(0,entry.getBamPanel().getHeight()); } // one line per entry @@ -152,7 +152,7 @@ public class PrintArtemis extends ScrollPanel implements Printable if(jamDisplay.isSelected() && entry.getJamView() != null && entry.getJamView().isVisible()) - height += entry.getJamPanel().getHeight(); + height += entry.getBamPanel().getHeight(); if(plotsDisplay.isSelected()) height += entry.getBasePlotGroup().getHeight(); diff --git a/uk/ac/sanger/artemis/components/alignment/BamView.java b/uk/ac/sanger/artemis/components/alignment/BamView.java index 82a69a6806e7de1bec4cb2aaedcfb675f7d15c37..9fe224ea57bb1fc1ad83a19f1c647631de5d6d8d 100644 --- a/uk/ac/sanger/artemis/components/alignment/BamView.java +++ b/uk/ac/sanger/artemis/components/alignment/BamView.java @@ -2026,10 +2026,10 @@ public class BamView extends JPanel { FileSelectionDialog bamFileSelection = new FileSelectionDialog( null, false, "BamView", "BAM"); - List<String> bamFiles = bamFileSelection.getBamFiles(); + List<String> bamFiles = bamFileSelection.getFiles(".*\\.bam$"); int count = bamList.size(); - bamList.addAll(bamFileSelection.getBamFiles()); + bamList.addAll(bamFileSelection.getFiles(".*\\.bam$")); for(int i=0; i<bamFiles.size(); i++) addToViewMenu(i+count); @@ -2925,13 +2925,16 @@ public class BamView extends JPanel System.setProperty("default_directory", System.getProperty("user.dir")); FileSelectionDialog fileSelection = new FileSelectionDialog( null, true, "BamView", "BAM"); - bam = fileSelection.getBamFiles(); + bam = fileSelection.getFiles(".*\\.bam$"); reference = fileSelection.getReferenceFile(); if(reference == null || reference.equals("")) reference = null; if(bam == null || bam.size() < 1) + { + System.err.println("No files found."); System.exit(0); + } } else if(!args[0].startsWith("-")) { diff --git a/uk/ac/sanger/artemis/components/alignment/FileSelectionDialog.java b/uk/ac/sanger/artemis/components/alignment/FileSelectionDialog.java index ccf7efe7baec57712779928fc1d42cfba680b84c..288039d183f1dfcf4ea867468494d7b04bddd4e7 100644 --- a/uk/ac/sanger/artemis/components/alignment/FileSelectionDialog.java +++ b/uk/ac/sanger/artemis/components/alignment/FileSelectionDialog.java @@ -19,6 +19,8 @@ import java.io.Reader; import java.net.URL; import java.util.List; import java.util.Vector; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.swing.JButton; import javax.swing.JDialog; @@ -254,27 +256,38 @@ public class FileSelectionDialog extends JDialog } /** - * Get the BAM files as a <code>List</code> of <code>String</code>'s. + * Get the BAM or VCF files as a <code>List</code> of <code>String</code>'s. * @return */ - public List<String> getBamFiles() + public List<String> getFiles(String patternStr) { - List<String> bamFiles = new Vector<String>(); + Pattern p = Pattern.compile(patternStr); + + List<String> files = new Vector<String>(); for(int i=0; i<bamFields.size(); i++) { String file = bamFields.get(i).getText(); - if(file != null && !file.equals("")) { if(isListOfFiles(file)) { - bamFiles.addAll(getListOfFiles(file)); + List<String> filesInList = getListOfFiles(file); + for(int j=0; j<filesInList.size(); j++) + { + Matcher m = p.matcher(filesInList.get(j)); + if(m.matches()) + files.add(filesInList.get(j)); + } } else - bamFiles.add(file); + { + Matcher m = p.matcher(file); + if(m.matches()) + files.add(file); + } } } - return bamFiles; + return files; } /** diff --git a/uk/ac/sanger/artemis/components/variant/VCFview.java b/uk/ac/sanger/artemis/components/variant/VCFview.java index 984064f3468f6e8f7d2c73abe84ae1b2f2f11eb8..317a9229cf0038e50eefc32284182bed07988984 100644 --- a/uk/ac/sanger/artemis/components/variant/VCFview.java +++ b/uk/ac/sanger/artemis/components/variant/VCFview.java @@ -27,6 +27,7 @@ import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; +import java.awt.FlowLayout; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Insets; @@ -49,6 +50,7 @@ import java.util.Vector; import javax.swing.JButton; import javax.swing.JComboBox; +import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; @@ -57,6 +59,8 @@ import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollBar; import javax.swing.JScrollPane; +import javax.swing.border.Border; +import javax.swing.border.EmptyBorder; import net.sf.samtools.util.BlockCompressedInputStream; @@ -65,8 +69,13 @@ import org.apache.log4j.Level; import uk.ac.sanger.artemis.Entry; import uk.ac.sanger.artemis.EntryGroup; import uk.ac.sanger.artemis.Options; +import uk.ac.sanger.artemis.SelectionChangeEvent; +import uk.ac.sanger.artemis.SelectionChangeListener; import uk.ac.sanger.artemis.SimpleEntryGroup; +import uk.ac.sanger.artemis.components.DisplayAdjustmentEvent; +import uk.ac.sanger.artemis.components.DisplayAdjustmentListener; import uk.ac.sanger.artemis.components.EntryFileDialog; +import uk.ac.sanger.artemis.components.FeatureDisplay; import uk.ac.sanger.artemis.components.FileViewer; import uk.ac.sanger.artemis.components.MessageDialog; import uk.ac.sanger.artemis.components.alignment.FileSelectionDialog; @@ -86,42 +95,50 @@ import uk.ac.sanger.artemis.util.OutOfRangeException; public class VCFview extends JPanel + implements DisplayAdjustmentListener, SelectionChangeListener { private static final long serialVersionUID = 1L; private JScrollBar scrollBar; + private JPanel vcfPanel; private TabixReader tr[]; private String header[]; + private FeatureDisplay feature_display; private int nbasesInView; private int seqLength; private String chr; private String mouseOverVCFline; private int mouseOverIndex = -1; private JPopupMenu popup; - private int LINE_HEIGHT = 25; + private int LINE_HEIGHT = 20; - public VCFview(final JFrame frame, + public VCFview(final JFrame frame, + final JPanel vcfPanel, final List<String> vcfFiles, final int nbasesInView, final int seqLength, final String chr, - final String reference) + final String reference, + final FeatureDisplay feature_display) { super(); this.nbasesInView = nbasesInView; this.seqLength = seqLength; this.chr = chr; + this.feature_display = feature_display; + this.vcfPanel = vcfPanel; setBackground(Color.white); - setPreferredSize(new Dimension(900, vcfFiles.size()*(LINE_HEIGHT+5))); MultiLineToolTipUI.initialize(); setToolTipText(""); + vcfPanel.setPreferredSize(new Dimension(900, vcfFiles.size()*(LINE_HEIGHT+5))); - if(reference != null) - { - EntryGroup entryGroup = getReference(reference); - this.seqLength = entryGroup.getSequenceEntry().getBases().getLength(); - } + if(feature_display != null) + this.seqLength = feature_display.getBases().getLength(); + else if(reference != null) + this.seqLength = getReference(reference).getSequenceEntry().getBases().getLength(); + + try { @@ -136,7 +153,6 @@ public class VCFview extends JPanel } catch (IOException e) { - // TODO Auto-generated catch block e.printStackTrace(); } @@ -144,7 +160,8 @@ public class VCFview extends JPanel JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - frame.getContentPane().add(jspView, BorderLayout.CENTER); + vcfPanel.setLayout(new BorderLayout()); + vcfPanel.add(jspView, BorderLayout.CENTER); if(this.nbasesInView > this.seqLength) this.nbasesInView = this.seqLength/2; @@ -177,9 +194,32 @@ public class VCFview extends JPanel addMouseListener(new PopupListener()); // - // - JMenuBar topPanel = new JMenuBar(); - frame.setJMenuBar((JMenuBar)topPanel); + createMenus(frame); + setDisplay(); + + if(feature_display == null) + { + vcfPanel.add(scrollBar, BorderLayout.SOUTH); + frame.pack(); + frame.setVisible(true); + } + else + { + Border empty = new EmptyBorder(0,0,0,0); + jspView.setBorder(empty); + } + } + + private void createMenus(JFrame frame) + { + JComponent topPanel; + if(feature_display != null) + topPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 0, 0)); + else + { + topPanel = new JMenuBar(); + frame.setJMenuBar((JMenuBar)topPanel); + } JMenu fileMenu = new JMenu("File"); topPanel.add(fileMenu); @@ -223,7 +263,6 @@ public class VCFview extends JPanel } }); - JButton zoomIn = new JButton("-"); Insets ins = new Insets(1,1,1,1); zoomIn.setMargin(ins); @@ -248,7 +287,6 @@ public class VCFview extends JPanel topPanel.add(zoomOut); final JComboBox combo = new JComboBox(tr[0].getmSeq()); - if(chr == null) this.chr = tr[0].getmSeq()[0]; combo.setSelectedItem(this.chr); @@ -264,10 +302,6 @@ public class VCFview extends JPanel } }); topPanel.add(combo); - - frame.getContentPane().add(scrollBar, BorderLayout.SOUTH); - frame.pack(); - frame.setVisible(true); } private static EntryGroup getReference(String reference) @@ -381,17 +415,17 @@ public class VCFview extends JPanel protected void paintComponent(Graphics g) { super.paintComponent(g); - mouseOverVCFline = null; float pixPerBase = getPixPerBaseByWidth(); String s; - int start = scrollBar.getValue(); + int start = getBaseAtStartOfView(); int end = start+nbasesInView; String region = chr+":"+start+"-"+end; - drawScale((Graphics2D)g, start, end, pixPerBase, getHeight()); + //if(feature_display == null) + drawScale((Graphics2D)g, start, end, pixPerBase, getHeight()); // a region is specified; random access for (int i = 0; i < tr.length; i++) { @@ -413,6 +447,14 @@ public class VCFview extends JPanel } } + protected int getBaseAtStartOfView() + { + if(feature_display != null) + return feature_display.getForwardBaseAtLeftEdge(); + else + return scrollBar.getValue(); + } + private void drawVariantCall(Graphics g, String line, int start, int index, float pixPerBase) { String parts[] = line.split("\\t"); @@ -437,8 +479,7 @@ public class VCFview extends JPanel String parts[] = line.split("\\t"); int pos[] = new int[2]; pos[0] = Math.round((Integer.parseInt(parts[1]) - start)*pixPerBase); - pos[1] = getHeight() - 15 - (vcfFileIndex*(LINE_HEIGHT+5)); - + pos[1] = getHeight() - 15 - (vcfFileIndex*(LINE_HEIGHT+5)); return pos; } @@ -446,7 +487,7 @@ public class VCFview extends JPanel { float pixPerBase = getPixPerBaseByWidth(); String s; - int start = scrollBar.getValue(); + int start = getBaseAtStartOfView(); int end = start+nbasesInView; String region = chr+":"+start+"-"+end; @@ -618,7 +659,7 @@ public class VCFview extends JPanel private float getPixPerBaseByWidth() { - return (float)getWidth() / (float)nbasesInView; + return (float)vcfPanel.getWidth() / (float)nbasesInView; } /** @@ -698,6 +739,25 @@ public class VCFview extends JPanel } } + private void setDisplay() + { + Dimension d = new Dimension(); + d.setSize(nbasesInView*getPixPerBaseByWidth(), tr.length*(LINE_HEIGHT+5)); + setPreferredSize(d); + } + + public void displayAdjustmentValueChanged(DisplayAdjustmentEvent event) + { + nbasesInView = feature_display.getMaxVisibleBases(); + setDisplay(); + repaint(); + } + + public void selectionChanged(SelectionChangeEvent event) + { + + } + public static void main(String args[]) { List<String> vcfFileList = new Vector<String>(); @@ -707,7 +767,7 @@ public class VCFview extends JPanel System.setProperty("default_directory", System.getProperty("user.dir")); FileSelectionDialog fileSelection = new FileSelectionDialog( null, true, "VCFview", "VCF"); - vcfFileList = fileSelection.getBamFiles(); + vcfFileList = fileSelection.getFiles(".vcf"); reference = fileSelection.getReferenceFile(); if(reference.equals("")) reference = null; @@ -766,7 +826,8 @@ public class VCFview extends JPanel else { JFrame f = new JFrame(); - new VCFview(f, vcfFileList, nbasesInView, 100000000, null, reference); + new VCFview(f, (JPanel) f.getContentPane(), vcfFileList, + nbasesInView, 100000000, null, reference, null); } } } \ No newline at end of file