Java tutorial
/* * Copyright (c) 2003-2012 Fred Hutchinson Cancer Research Center * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.fhcrc.cpl.viewer.gui; import org.fhcrc.cpl.viewer.Localizer; import org.fhcrc.cpl.toolbox.proteomics.MSRun; import org.fhcrc.cpl.viewer.ViewerUserManualGenerator; import org.fhcrc.cpl.viewer.Application; import org.fhcrc.cpl.toolbox.commandline.CommandLineModule; import org.fhcrc.cpl.viewer.commandline.ViewerCommandLineModuleDiscoverer; import org.fhcrc.cpl.viewer.mrm.commandline.MRMCommandLineModule; import org.fhcrc.cpl.toolbox.proteomics.Clusterer2D; import org.fhcrc.cpl.viewer.util.ElutionDataPoint; import org.fhcrc.cpl.toolbox.filehandler.TempFileManager; import org.fhcrc.cpl.toolbox.gui.chart.PanelWithChart; import org.fhcrc.cpl.toolbox.gui.HtmlViewerPanel; import org.fhcrc.cpl.toolbox.gui.ListenerHelper; import org.fhcrc.cpl.viewer.mrm.*; import org.fhcrc.cpl.viewer.mrm.utilities.*; import org.fhcrc.cpl.toolbox.ApplicationContext; import org.fhcrc.cpl.toolbox.TextProvider; import org.jfree.chart.ChartFactory; import org.jfree.chart.JFreeChart; import org.jfree.chart.ChartPanel; import org.jfree.chart.annotations.XYLineAnnotation; import org.jfree.chart.annotations.XYTextAnnotation; import org.jfree.chart.axis.Axis; import org.jfree.chart.axis.ValueAxis; import org.jfree.chart.event.AxisChangeEvent; import org.jfree.chart.event.AxisChangeListener; import org.jfree.chart.plot.*; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.data.Range; import org.jfree.data.xy.XYDataItem; import org.jfree.data.xy.XYSeries; import org.jfree.data.xy.XYSeriesCollection; import javax.swing.*; import javax.swing.border.Border; import javax.swing.event.*; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableModel; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.awt.event.*; import java.awt.geom.Line2D; import java.io.*; import java.text.NumberFormat; import java.util.*; import java.util.List; /** * GUI */ public class MRMDialog extends JFrame implements Serializable { protected JLabel titleText; protected JLabel elutionTableLabel; protected MRMTransition[] _mrmTransitions; protected int currentTransitionIndex = 0; protected MSRun _run; protected float _precursorDiscoveryMzTolerance; protected float _daughterMzTolerance; protected float _precursorChromatogramWindow; protected File _mzXMLFile; protected JFileChooser _mzXMLFileChooser; protected JFileChooser _outputFileChooser; protected JFileChooser _inputTSVFileChooser; protected JFileChooser _imageOutputFileChooser; protected boolean _traceAllFragments; protected ListSelectionListener _ptmlsl; protected transitionListSelectionListener _tlsl; protected boolean _synclh; //Widgets public JList listTransition; public JScrollPane listScrollPane; public JScrollPane peaksScrollPane; public static JTable peaksTable; public JLabel fileNameLabel; public JPanel precursorContainerPanel; public JPanel precursorContainerContainerPanel; public JPanel daughterContainerContainerPanel; public JPanel daughterContainerPanel; public JLabel topGraphLabel; public JButton buttonZC; public JButton buttonPrev; public JButton buttonNext; public JButton buttonSave; public JButton buttonAccept; public JButton buttonReject; public JButton buttonZoom; public JButton buttonFindMate; public JButton buttonBoost; public JButton buttonTiming; public JButton buttonRejectGroup; public JMenuBar menuBarMain; public JMenu menuFile; public JMenuItem menuItemQuit; public JMenuItem menuItemOpen; public JMenuItem menuItemLoadTSV; public JMenu menuOptions; public JMenu menuHelp; public JMenuItem menuItemArguments; public JMenuItem menuItemOptions; public JMenuItem menuItemDefinitions; public JMenuItem menuItemTips; public JMenuItem menuItemSICtolerance; public JMenuItem menuItemPrecDiscTol; public JMenuItem menuItemDaughterDiscTol; public JMenuItem menuItemTraceAllFragments; public JMenuItem menuItemChangeStrategy; public JMenuItem menuItemSyncLH; public JMenuItem menuItemPMin; public JMenuItem menuItemAMin; public JMenuItem menuItemSaveImage; ListenerHelper helper = null; public boolean _sim = false; public boolean _conn = false; public float _sictol = 0.0f; public Class _ecurveclass = null; public Container contentPanel = null; public MRMTransition transitionOnPlot = null; public TransitionDefinitionHeader transDefHeader = null; public float _minPeakCutoff; public float _minAreaCutoff; /* todo: these are totally hokey and needs to be re-thought */ private static enum whichGraph { Precursor, Daughter }; private static enum whichAxis { Domain, Range }; private void menuBarInitializations() { menuBarMain = new JMenuBar(); this.setJMenuBar(menuBarMain); menuFile = new JMenu("File"); menuBarMain.add(menuFile); menuItemOpen = new JMenuItem("Open mzXML"); menuFile.add(menuItemOpen); menuItemSaveImage = new JMenuItem("Save Chromatogram"); menuItemQuit = new JMenuItem("Quit"); menuItemLoadTSV = new JMenuItem("Load TSV table"); menuFile.add(menuItemLoadTSV); menuFile.add(menuItemSaveImage); menuFile.add(menuItemQuit); menuOptions = new JMenu("Options"); menuItemSICtolerance = new JMenuItem("SIC Tolerance"); menuOptions.add(menuItemSICtolerance); menuItemPrecDiscTol = new JMenuItem("Precursor Tolerance"); menuOptions.add(menuItemPrecDiscTol); menuItemDaughterDiscTol = new JMenuItem("Product Tolerance"); menuOptions.add(menuItemDaughterDiscTol); menuItemTraceAllFragments = new JMenuItem("Trace Chromats"); menuOptions.add(menuItemTraceAllFragments); menuItemChangeStrategy = new JMenuItem("Curve Strategy"); menuOptions.add(menuItemChangeStrategy); menuItemSyncLH = new JMenuItem("Synchronize L/H label elution regions"); menuOptions.add(menuItemSyncLH); menuItemPMin = new JMenuItem("Refilter Min Peak Height"); menuOptions.add(menuItemPMin); menuItemAMin = new JMenuItem("Refilter Min Curve Area"); menuOptions.add(menuItemAMin); menuBarMain.add(menuOptions); menuHelp = new JMenu("Help"); menuItemArguments = new JMenuItem("Java commandline options"); menuItemOptions = new JMenuItem("Options help"); menuHelp.add(menuItemOptions); menuItemDefinitions = new JMenuItem("Definitions"); menuHelp.add(menuItemDefinitions); menuItemTips = new JMenuItem("User Tips"); menuHelp.add(menuItemTips); menuHelp.add(menuItemArguments); menuBarMain.add(menuHelp); } private void listenerHelperInitializations() { helper.addListener(menuItemSICtolerance, "buttonSICUpdate_actionPerformed"); helper.addListener(menuItemPrecDiscTol, "buttonPDT_actionPerformed"); helper.addListener(menuItemDaughterDiscTol, "buttonDTOL_actionPerformed"); helper.addListener(menuItemTraceAllFragments, "menuItemTraceAllFragments_actionPerformed"); helper.addListener(menuItemChangeStrategy, "menuItemChangeStrategy_actionPerformed"); helper.addListener(menuItemSyncLH, "menuItemSyncLH_actionPerformed"); helper.addListener(buttonZC, "buttonZC_actionPerformed"); helper.addListener(menuItemPMin, "menuItemPMin_actionPerformed"); helper.addListener(menuItemAMin, "menuItemAMin_actionPerformed"); helper.addListener(buttonNext, "buttonNext_actionPerformed"); helper.addListener(buttonPrev, "buttonPrev_actionPerformed"); helper.addListener(buttonSave, "buttonSave_actionPerformed"); helper.addListener(buttonAccept, "buttonAccept_actionPerformed"); helper.addListener(buttonBoost, "buttonBoost_actionPerformed"); helper.addListener(buttonTiming, "buttonTiming_actionPerformed"); helper.addListener(buttonReject, "buttonReject_actionPerformed"); helper.addListener(buttonRejectGroup, "buttonRejectGroup_actionPerformed"); helper.addListener(contentPanel, "contentPanel_mouseClicked"); helper.addListener(menuItemQuit, "menuItemQuit_actionPerformed"); helper.addListener(menuItemTips, "menuItemTips_actionPerformed"); helper.addListener(menuItemDefinitions, "menuItemDefinitions_actionPerformed"); helper.addListener(menuItemOptions, "menuItemOptions_actionPerformed"); helper.addListener(menuItemArguments, "menuItemArguments_actionPerformed"); helper.addListener(menuItemLoadTSV, "menuItemLoadTSV_actionPerformed"); helper.addListener(menuItemOpen, "menuItemOpen_actionPerformed"); helper.addListener(buttonZoom, "buttonZoom_actionPerformed"); helper.addListener(buttonFindMate, "buttonFindMate_actionPerformed"); helper.addListener(menuItemSaveImage, "menuItemSaveImage_actionPerformed"); } /** * Initialize the GUI and show the first transition * @param mzXMLFile */ public MRMDialog(File mzXMLFile, float precDiscTol, float daughterTol, float chromTol, Class ECurveStrat, boolean traceAllFragments, boolean synclh, float minP, float minA) { super(); this.setTitle(TextProvider.getText("MRMer") + " v. " + TextProvider.getText("MRMER_VERSION") + " (build " + (String) ApplicationContext.getProperty("REVISION") + ")"); //frameInit(); _precursorDiscoveryMzTolerance = precDiscTol; _daughterMzTolerance = daughterTol; _precursorChromatogramWindow = chromTol; _mzXMLFile = mzXMLFile; _ecurveclass = ECurveStrat; currentTransitionIndex = 0; _traceAllFragments = traceAllFragments; _synclh = synclh; _minPeakCutoff = minP; _minAreaCutoff = minA; //graphical stuff contentPanel = null; helper = new ListenerHelper(this); try { contentPanel = Localizer.renderSwixml("org/fhcrc/cpl/viewer/gui/MRMDialog.xml", this); contentPanel.setBackground(new Color(255, 255, 153)); menuBarInitializations(); _mzXMLFileChooser = new JFileChooser(); _mzXMLFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); _mzXMLFileChooser.setMultiSelectionEnabled(false); _mzXMLFileChooser.setFileFilter(new javax.swing.filechooser.FileFilter() { public boolean accept(File f) { if (f.isDirectory()) return true; String fname = f.getName(); String parts[] = fname.split("\\."); if (parts.length != 2) return false; return parts[1].equalsIgnoreCase("mzXML"); } public String getDescription() { return "mzXML files"; } }); _outputFileChooser = new JFileChooser(); _outputFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); _outputFileChooser.setMultiSelectionEnabled(false); _outputFileChooser.setFileFilter(new javax.swing.filechooser.FileFilter() { public boolean accept(File f) { return f.toString().endsWith(".tsv") || f.isDirectory(); } public String getDescription() { return "TSV files"; } }); _imageOutputFileChooser = new JFileChooser(); _imageOutputFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); _imageOutputFileChooser.setMultiSelectionEnabled(false); _imageOutputFileChooser.setFileFilter(new javax.swing.filechooser.FileFilter() { public boolean accept(File f) { return f.toString().endsWith(".png") || f.isDirectory(); } public String getDescription() { return "PNG graphics files"; } }); _inputTSVFileChooser = new JFileChooser(); _inputTSVFileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY); _inputTSVFileChooser.setMultiSelectionEnabled(false); _inputTSVFileChooser.setFileFilter(new javax.swing.filechooser.FileFilter() { public boolean accept(File f) { return f.toString().endsWith(".tsv") || f.isDirectory(); } public String getDescription() { return "TSV files"; } }); this.add(contentPanel); setResizable(true); } catch (Exception x) { System.err.println("Failed in MRMDialog initializer: " + x); ApplicationContext.errorMessage(TextProvider.getText("ERROR_CREATING_DIALOG"), x); throw new RuntimeException(x); } initStuff(); listenerHelperInitializations(); } private void transitionListInitializations() { listTransition = new JList(); listTransition.setCellRenderer(new coloredMRMListRenderer()); listTransition.setModel(new DefaultListModel()); listTransition.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); _tlsl = new transitionListSelectionListener(); listTransition.addListSelectionListener(_tlsl); listTransition.addMouseWheelListener(new MouseWheelListener() { public void mouseWheelMoved(MouseWheelEvent event) { int move = event.getWheelRotation(); int curIndex = listTransition.getSelectedIndex(); int newIndex = curIndex; if (move > 0) { newIndex = Math.min(curIndex + move, listTransition.getModel().getSize()); listTransition.setSelectedIndex(newIndex); } if (move < 0) { newIndex = Math.max(curIndex + move, 0); listTransition.setSelectedIndex(newIndex); } listTransition.ensureIndexIsVisible(newIndex); } }); for (MRMTransition curTran : _mrmTransitions) ((DefaultListModel) listTransition.getModel()).addElement(curTran); listTransition.setVisible(true); listScrollPane.getViewport().setView(listTransition); listScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); listScrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent ae) { if (!ae.getValueIsAdjusting()) { listTransition.repaint(); } } }); } private void peaksDataInitializations() { String classElements[] = _ecurveclass.getName().split("\\."); elutionTableLabel.setText("<html><body><center>Elution Data<br><font size='-1'>(" + classElements[classElements.length - 1] + ")</font></center></body></html>"); elutionTableLabel.setHorizontalAlignment(JLabel.CENTER); elutionTableLabel.setHorizontalTextPosition(JLabel.CENTER); if (transDefHeader == null || transDefHeader.getAQUApairs() == null || transDefHeader.getAQUApairs().size() == 0) { buttonFindMate.setVisible(false); } else { buttonFindMate.setVisible(true); } peaksScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); peaksScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); peaksTable = new JTable(new PeaksTableModel()); //peaksTable.setPreferredScrollableViewportSize(new Dimension(500, 700)); peaksTable.setSelectionModel(new peaksTableSelectionModel()); peaksTable.setAutoscrolls(true); peaksTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); int totalTableRows = 1; for (MRMTransition curTrans : _mrmTransitions) totalTableRows += (1 + curTrans.getDaughters().size()); ((PeaksTableModel) (peaksTable.getModel())).data = new Object[totalTableRows - 1][peaksData.values().length]; for (peaksData pd : EnumSet.allOf(peaksData.class)) { peaksTable.getColumnModel().getColumn(pd.colno).setPreferredWidth(pd.colWidth); } peaksTable.doLayout(); ((DefaultCellEditor) peaksTable.getDefaultEditor(peaksData.Accept.colClass)).setClickCountToStart(1); int i = 0; for (MRMTransition curTrans : _mrmTransitions) { curTrans.setGraphData(makeParentSeries(curTrans)); int curPrecursorIndex = i; curTrans.setTableRow(curPrecursorIndex); for (peaksData pd : EnumSet.allOf(peaksData.class)) { ((PeaksTableModel) (peaksTable.getModel())).data[i][pd.colno] = null; pd.makeVisible(true); } ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Accept.colno] = null; ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Precursor.colno] = curTrans; for (MRMDaughter d : curTrans.getDaughters().values()) { i++; d.setGraphData(d.makeDaughterSeries()); d.setContinDaughterData(d.makeDaughterSeries(d, true)); d.setElutionDataTableRow(i); ElutionCurveStrategy bes = ElutionCurveStrategy.getInstance(curTrans, d, _ecurveclass); bes.calculateParentElutionCurves(null); bes.calculateDaughterElutionCurves(null); bes.calculateBestCurves(); d.calculateQuality(); curTrans.getElutionCurves().put(d, bes); ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Accept.colno] = new Boolean( !Utils.allYsAre0(d)); ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Peptide.colno] = ""; ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Precursor.colno] = curTrans; ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Daughter.colno] = d; ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.CoStart.colno] = null; ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.CoEnd.colno] = null; ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.CoDelta.colno] = null; ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.AUC.colno] = null; ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.MaxPeak.colno] = null; ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.MidTime.colno] = null; ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Quality.colno] = null; ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Label.colno] = ""; ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Code.colno] = null; ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.LHRatio.colno] = null; ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Comment.colno] = ""; if (transDefHeader != null && transDefHeader.getDToTD() != null && transDefHeader.getDToTD().get(d) != null) { TransitionDefinition td = transDefHeader.getDToTD().get(d); ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Peptide.colno] = td.getPeptide(); ((PeaksTableModel) (peaksTable .getModel())).data[curPrecursorIndex][peaksData.Peptide.colno] = td.getPeptide(); ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Code.colno] = new Integer( td.getAQUAcode()); } ElutionCurve bestPrecursorCurve = bes.getBestParentCurve(); if (bestPrecursorCurve == null || bestPrecursorCurve.getMinElutionTimeSecs() <= 0.0) { ((PeaksTableModel) (peaksTable .getModel())).data[curPrecursorIndex][peaksData.AUC.colno] = new Float(-1); ((PeaksTableModel) (peaksTable .getModel())).data[curPrecursorIndex][peaksData.MaxPeak.colno] = new Float(-1); ((PeaksTableModel) (peaksTable .getModel())).data[curPrecursorIndex][peaksData.Quality.colno] = new Float(-1); ((PeaksTableModel) (peaksTable .getModel())).data[curPrecursorIndex][peaksData.MidTime.colno] = new Float(-1); } else { ((PeaksTableModel) (peaksTable .getModel())).data[curPrecursorIndex][peaksData.AUC.colno] = new Float( bestPrecursorCurve.getAUC()); ((PeaksTableModel) (peaksTable .getModel())).data[curPrecursorIndex][peaksData.MaxPeak.colno] = new Float( bestPrecursorCurve.getHighestPointY()); ((PeaksTableModel) (peaksTable .getModel())).data[curPrecursorIndex][peaksData.Quality.colno] = new Float( curTrans.getQuality()); } ElutionCurve bestDaughterCurve = bes.getBestDaughterCurve(); if (bestDaughterCurve == null || bestDaughterCurve.getMinElutionTimeSecs() <= 0.0) { ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Accept.colno] = new Boolean( false); ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.AUC.colno] = new Float(-1); ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.MaxPeak.colno] = new Float(-1); ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Quality.colno] = new Float(-1); ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.MidTime.colno] = new Float(-1); } else { ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.AUC.colno] = new Float( bestDaughterCurve.getAUC()); ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.MaxPeak.colno] = new Float( bestDaughterCurve.getHighestPointY()); d.setBestElutionCurve(bestDaughterCurve); ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Quality.colno] = new Float( d.getQuality()); if (_minPeakCutoff > 0 && bestDaughterCurve.getHighestPointY() < _minPeakCutoff) ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Accept.colno] = new Boolean( false); if (_minAreaCutoff > 0 && bestDaughterCurve.getAUC() < _minAreaCutoff) ((PeaksTableModel) (peaksTable.getModel())).data[i][peaksData.Accept.colno] = new Boolean( false); } } curTrans.setElutionRegionStart(curTrans.calculateMinOfAllBestDaughterCurves()); curTrans.setElutionRegionEnd(curTrans.calculateMaxOfAllBestDaughterCurves()); curTrans.calcMaxYofAllDaughters(); for (int j = curPrecursorIndex; j <= i; j++) { ((PeaksTableModel) (peaksTable.getModel())).data[j][peaksData.CoStart.colno] = new Float( curTrans.getElutionRegionStart()); ((PeaksTableModel) (peaksTable.getModel())).data[j][peaksData.CoEnd.colno] = new Float( curTrans.getElutionRegionEnd()); ((PeaksTableModel) (peaksTable.getModel())).data[j][peaksData.CoDelta.colno] = new Float( curTrans.getElutionRegionEnd() - curTrans.getElutionRegionStart()); ((PeaksTableModel) (peaksTable.getModel())).data[j][peaksData.MidTime.colno] = new Float( curTrans.getCalcXatMaxYAllDaughters()); } i++; } peaksTable.setDefaultRenderer(MRMTransition.class, new MRMTransitionTableRenderer(false)); peaksTable.setDefaultRenderer(MRMDaughter.class, new MRMDaughterTableRenderer(false)); peaksTable.setDefaultRenderer(Number.class, new MRMNumberTableRenderer()); peaksTable.setDefaultRenderer(Integer.class, new MRMNumberTableRenderer()); peaksTable.setDefaultRenderer(Boolean.class, new MRMBooleanRenderer()); peaksTable.getColumnModel().getColumn(peaksData.CoStart.colno).setCellEditor(new NumberTableCellEditor()); peaksTable.getColumnModel().getColumn(peaksData.CoEnd.colno).setCellEditor(new NumberTableCellEditor()); peaksTable.getColumnModel().getColumn(peaksData.Code.colno).setCellEditor(new NumberTableCellEditor()); peaksTable.getColumnModel().getColumn(peaksData.LHRatio.colno).setCellEditor(new NumberTableCellEditor()); peaksScrollPane.getViewport().setView(peaksTable); if (transDefHeader == null) { peaksData.Peptide.makeVisible(false); peaksData.Label.makeVisible(false); peaksData.LHRatio.makeVisible(false); peaksData.Code.makeVisible(false); } else { if (transDefHeader.getAQUApairs() == null || transDefHeader.getAQUApairs().isEmpty()) { peaksData.Label.makeVisible(false); peaksData.LHRatio.makeVisible(false); peaksData.Code.makeVisible(false); } } // "Quality" column, currently unused, is invisible unless one or more of its // values is not -1 peaksData.Quality.makeVisible(!Utils.qualColIsEmpty()); peaksScrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent ae) { if (!ae.getValueIsAdjusting()) { peaksTable.repaint(); } } }); peaksTable.getModel().addTableModelListener(new peaksTableListener()); _ptmlsl = new PeaksTableListSelectionListener(); peaksTable.getSelectionModel().addListSelectionListener(_ptmlsl); } public void AQUAinitializations() { if (transDefHeader == null || transDefHeader.getAQUApairs() == null) return; for (TransitionDefinitionHeader.AQUApair aqp : transDefHeader.getAQUApairs().values()) { if (aqp.getHeavyMember().getAssociatedProduct() == null || aqp.getLightMember().getAssociatedProduct() == null) continue; MRMDaughter light = aqp.getLightMember().getAssociatedProduct(); MRMDaughter heavy = aqp.getHeavyMember().getAssociatedProduct(); if (light.getBestElutionCurve() == null || heavy.getBestElutionCurve() == null) continue; ElutionCurve lec = light.getBestElutionCurve(); ElutionCurve hec = heavy.getBestElutionCurve(); Float lhratio = new Float(lec.getAUC() / hec.getAUC()); ((PeaksTableModel) (peaksTable.getModel())).setValueAt( new Character(aqp.getLightMember().getLowOrHigh()).toString(), light.getElutionDataTableRow(), peaksData.Label.colno); ((PeaksTableModel) (peaksTable.getModel())).setValueAt( new Character(aqp.getHeavyMember().getLowOrHigh()).toString(), heavy.getElutionDataTableRow(), peaksData.Label.colno); ((PeaksTableModel) (peaksTable.getModel())).setValueAt(lhratio, light.getElutionDataTableRow(), peaksData.LHRatio.colno); ((PeaksTableModel) (peaksTable.getModel())).setValueAt(lhratio, heavy.getElutionDataTableRow(), peaksData.LHRatio.colno); } } public void initStuff() { transDefHeader = null; transitionOnPlot = null; try { //long start = System.currentTimeMillis(); _run = MSRun.load(_mzXMLFile.getAbsolutePath()); //long end = System.currentTimeMillis(); //System.out.println("time to read mzXML (ms): "+(end-start)); //System.exit(0); _mrmTransitions = loadMRMTransitions(_run); if (_mrmTransitions == null) { throw new RuntimeException("_mrmTransitions is null MRMDialog"); } } catch (Exception e) { System.err.println("Failed in initstuff: " + e); ApplicationContext.errorMessage(TextProvider.getText("ERROR_CREATING_DIALOG"), e); } this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); String _transitionDefFilePath = _mzXMLFile.getAbsolutePath().replaceAll("\\.mzXML$", ".transition.tsv"); if ((new File(_transitionDefFilePath)).exists()) { transDefHeader = new TransitionDefinitionHeader(_transitionDefFilePath, new TSVTransitionDefinitionParser()); try { transDefHeader.getParser().setTransitionDefFile(_transitionDefFilePath); transDefHeader.doParse(); if (transDefHeader == null || transDefHeader.getTransitionDefs() == null || transDefHeader.getTransitionDefs().size() == 0) { transDefHeader = null; } else { transDefHeader.linkUpToTransitionList(_mrmTransitions, _precursorDiscoveryMzTolerance, _daughterMzTolerance); transDefHeader.determinePairs(); } } catch (Exception e) { System.err.println(e); } } if (transDefHeader != null && transDefHeader.getComment() != null && !transDefHeader.getComment().equals("")) { fileNameLabel.setText("<html><body><center>" + _mzXMLFile.getName() + "<br>" + transDefHeader.getComment() + "</center></body></html>"); fileNameLabel.setHorizontalAlignment(JLabel.CENTER); fileNameLabel.setHorizontalTextPosition(JLabel.CENTER); fileNameLabel.setMinimumSize(new Dimension(1200, 30)); } else { fileNameLabel.setText(_mzXMLFile.getName()); } if (transDefHeader != null && transDefHeader.getMzXMLFile() != null && !transDefHeader.getMzXMLFile().equals("")) { if (!transDefHeader.getMzXMLFile().trim().equals(_mzXMLFile.getName().trim())) { ApplicationContext.infoMessage("Note: current mzXML (" + _mzXMLFile.getName() + ") does not match mzXML file name in transition.tsv file (" + transDefHeader.getMzXMLFile() + ")"); } } helper.addListener(this, "contentPanel_componentResized"); transitionListInitializations(); peaksDataInitializations(); AQUAinitializations(); String mzToleranceText = "" + (double) _precursorChromatogramWindow; //this is kind of arbitrary: one digit after decimal. It also doesn't support //comma-radix. Whatever. if (mzToleranceText.contains(".")) mzToleranceText = mzToleranceText.substring(0, mzToleranceText.indexOf(".") + 2); _mzXMLFileChooser.setCurrentDirectory(_mzXMLFile.getAbsoluteFile().getParentFile()); _outputFileChooser.setCurrentDirectory(_mzXMLFile.getAbsoluteFile().getParentFile()); _inputTSVFileChooser.setCurrentDirectory(_mzXMLFile.getAbsoluteFile().getParentFile()); listTransition.setSelectedIndex(0); //updateChartsAndFields(false); peaksScrollPane.updateUI(); listScrollPane.updateUI(); pack(); //debug // System.out.println(Runtime.getRuntime().freeMemory()+" bytes available before freeing _run"); _run.close(); _run = null; for (MRMTransition mrmt : _mrmTransitions) mrmt.setRun(null); System.gc(); // System.out.println(Runtime.getRuntime().freeMemory()+" bytes available after freeing _run"); } // Listeners private volatile boolean _kludge_listener_removal = false; public class transitionListSelectionListener implements ListSelectionListener { public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting()) return; if (_kludge_listener_removal) return; MRMTransition curTrans = null; try { listTransition.getSelectionModel().removeListSelectionListener(this); int indices[] = listTransition.getSelectedIndices(); DefaultListModel dlm = (DefaultListModel) listTransition.getModel(); for (int i = 0; i < indices.length; i++) { curTrans = (MRMTransition) dlm.get(indices[i]); curTrans.setCurrentDaughterIndex(0); int dataIndex = -1; Object[][] tableData = ((PeaksTableModel) (peaksTable.getModel())).data; for (int j = 0; j < tableData.length; j++) { if (curTrans == (MRMTransition) (tableData[j][peaksData.Precursor.colno])) { dataIndex = j; } } if (dataIndex > -1) { ListSelectionListener curlsl = null; ListSelectionListener larr[] = ((peaksTableSelectionModel) peaksTable.getSelectionModel()) .getListSelectionListeners(); for (int ii = 0; ii < larr.length; ii++) { if (larr[ii] instanceof PeaksTableListSelectionListener) { curlsl = larr[ii]; peaksTable.getSelectionModel().removeListSelectionListener(curlsl); //break; } } scrollPeakTableToRow(curTrans.getCurrentDaughter().getElutionDataTableRow()); if (curlsl != null) peaksTable.getSelectionModel().addListSelectionListener(curlsl); } } transitionOnPlot = curTrans; updateChartsAndFields(false); listTransition.getSelectionModel().addListSelectionListener(this); } catch (Exception ee) { ApplicationContext.infoMessage("Can't plot selected index: " + ee); } } } public class PeaksTableListSelectionListener implements ListSelectionListener { public void valueChanged(ListSelectionEvent event) { if (event.getValueIsAdjusting()) return; try { ((ListSelectionModel) (event.getSource())).removeListSelectionListener(this); // Switch transitions table to appropriate transition int oldIndex = transitionOnPlot.getCurrentDaughter().getElutionDataTableRow(); int index = -1; if (event.getLastIndex() != oldIndex) { index = event.getLastIndex(); } else { if (event.getFirstIndex() != oldIndex) { index = event.getFirstIndex(); } else { System.err.println("Failed in peakstablelistselectionlistener: can't find row index "); ApplicationContext .errorMessage("Problem in PeaksTableListener: can't find correct row index", null); ((ListSelectionModel) (event.getSource())).addListSelectionListener(this); return; } } // The transition we selected MRMTransition curTrans = (MRMTransition) ((PeaksTableModel) (peaksTable .getModel())).data[index][peaksData.Precursor.colno]; //Get currently selected daughter. If we aren't positioned on a row //that contains a daughter, assume the first daughter of the transition MRMDaughter curD = (MRMDaughter) ((PeaksTableModel) (peaksTable .getModel())).data[index][peaksData.Daughter.colno]; if (curD == null) curD = curTrans.getDaughters().values().iterator().next(); //Set transition's current daughter to the daughter on the table row Object dArr[] = curTrans.getDaughters().values().toArray(); for (int i = 0; i < dArr.length; i++) { if (dArr[i] == (Object) curD) { curTrans.setCurrentDaughterIndex(i); break; } } //Move the transition list (left table on screen) to the correct index //if we have moved from one transition to another //Make sure to remove and replace listener, so it won't do any //mischief. Then replace it afterward *only if it had been there before*! //find listTransition listener of the proper variety, if there is one ListSelectionListener curlsl = null; ListSelectionListener larr[] = listTransition.getListSelectionListeners(); for (int i = 0; i < larr.length; i++) { if (larr[i] instanceof transitionListSelectionListener) { curlsl = larr[i]; listTransition.removeListSelectionListener(curlsl); //break; } } //todo: find out why removal of transitionListSelectionListener isn't working _kludge_listener_removal = true; if (curTrans != listTransition.getSelectedValues()[0]) { listTransition.setSelectedValue(curTrans, true); } _kludge_listener_removal = false; //replace listener if it had been there before if (transDefHeader != null) { buttonFindMate.setEnabled(transDefHeader.getMatchingDaughter(curD) != null); } if (curlsl != null) listTransition.addListSelectionListener(curlsl); // redisplay graph transitionOnPlot = curTrans; updateChartsAndFields(false); //put current selection model back ((ListSelectionModel) (event.getSource())).addListSelectionListener(this); } catch (Exception e) { ApplicationContext .infoMessage("Can't set MRMer to selected row: " + e + "\nPlease contact maintainers."); e.printStackTrace(); ((ListSelectionModel) (event.getSource())).addListSelectionListener(this); } } } public class domainAxisZoomCoordinator implements AxisChangeListener { public CenterZoomNumberAxis getMyAxis() { return myAxis; } public void setMyAxis(CenterZoomNumberAxis myAxis) { this.myAxis = myAxis; } CenterZoomNumberAxis myAxis; public domainAxisZoomCoordinator(CenterZoomNumberAxis na) { myAxis = na; } public void axisChanged(AxisChangeEvent ace) { if (precursorChromatogramEmpty(transitionOnPlot)) return; CenterZoomNumberAxis theOtherAxis = null; domainAxisZoomCoordinator theOtherCoordinator = null; if (getMyAxis() == findAxisOfPanel(precursorContainerPanel, whichAxis.Domain)) { theOtherAxis = (CenterZoomNumberAxis) findAxisOfPanel(daughterContainerPanel, whichAxis.Domain); } else { theOtherAxis = (CenterZoomNumberAxis) findAxisOfPanel(precursorContainerPanel, whichAxis.Domain); } theOtherCoordinator = theOtherAxis.getTheListener(); theOtherAxis.removeChangeListener(theOtherCoordinator); getMyAxis().removeChangeListener(this); theOtherAxis.setLowerBound(getMyAxis().getLowerBound()); theOtherAxis.setUpperBound(getMyAxis().getUpperBound()); getMyAxis().addChangeListener(this); theOtherAxis.addChangeListener(theOtherCoordinator); // theOtherCoordinator.axisChanged(new AxisChangeEvent(theOtherAxis)); } } public class daughterRangeAxisChangeListener implements AxisChangeListener { public void axisChanged(AxisChangeEvent ace) { XYPlot xyp = (XYPlot) ace.getAxis().getPlot(); if (xyp != null && ace.getAxis() == xyp.getRangeAxis()) { ValueAxis precursorRangeAxis = (ValueAxis) findAxisOfPanel(precursorContainerPanel, whichAxis.Range); ValueAxis daughterRangeAxis = (ValueAxis) ace.getAxis(); precursorRangeAxis.setLowerBound(daughterRangeAxis.getLowerBound()); precursorRangeAxis.setUpperBound(daughterRangeAxis.getUpperBound()); } } } public class peaksTableSelectionModel extends DefaultListSelectionModel { public ListSelectionListener[] getListSelectionListeners() { return (ListSelectionListener[]) listenerList.getListeners(ListSelectionListener.class); } } public class peaksTableListener implements TableModelListener { public void tableChanged(TableModelEvent e) { int row = e.getFirstRow(); int column = e.getColumn(); TableModel model = (TableModel) e.getSource(); String columnName = model.getColumnName(column); if (!columnName.equalsIgnoreCase("Start") && !columnName.equalsIgnoreCase("End") && !columnName.equalsIgnoreCase("Accept")) return; Object data = model.getValueAt(row, column); if (columnName.equalsIgnoreCase("Accept")) { if (data != null) { boolean accepted = (Boolean) data; if (!accepted) { //model.setValueAt(new Float(-1),row,peaksData.AUC.colno); } else { MRMDaughter curD = (MRMDaughter) model.getValueAt(row, peaksData.Daughter.colno); ElutionCurve curEC = null; if (curD != null) curEC = curD.getBestElutionCurve(); if (curEC != null) { model.setValueAt(new Float(curEC.getAUC()), row, peaksData.AUC.colno); } } } updateDaughterCharts(false); return; } float colVal = Float.parseFloat(data.toString()); float otherVal = 0.0f; float start = 0f; float end = 0f; // Is this a daughter or parent? // assume daughter first MRMTransition mrt = null; MRMDaughter mrd = (MRMDaughter) model.getValueAt(row, peaksData.Daughter.colno); if (mrd == null) { mrt = (MRMTransition) model.getValueAt(row, peaksData.Precursor.colno); } else { mrt = mrd.getPrecursor(); } if (columnName.equalsIgnoreCase("Start")) { start = colVal; otherVal = Float.parseFloat(model.getValueAt(row, peaksData.CoEnd.colno).toString()); end = otherVal; if (colVal >= otherVal) { JOptionPane.showMessageDialog(null, "Starting elution time must be less than ending elution time", "Elution Range Error", JOptionPane.ERROR_MESSAGE); model.removeTableModelListener(this); model.setValueAt(new Float(0.0f), row, column); model.addTableModelListener(this); return; } mrt.setElutionRegionStart(start); } else { end = colVal; otherVal = Float.parseFloat(model.getValueAt(row, peaksData.CoStart.colno).toString()); start = otherVal; if (colVal <= otherVal) { JOptionPane.showMessageDialog(null, "End elution time must be greater than starting elution time", "Elution Range Error", JOptionPane.ERROR_MESSAGE); model.removeTableModelListener(this); model.setValueAt(new Float(100000000.0f), row, column); model.addTableModelListener(this); return; } mrt.setElutionRegionEnd(end); } // elution boundaries have been changed manually // change all daughter columns model.removeTableModelListener(this); model.setValueAt(new Float(start), mrt.getTableRow(), peaksData.CoStart.colno); model.setValueAt(new Float(end), mrt.getTableRow(), peaksData.CoEnd.colno); float delta = end - start; model.setValueAt(new Float(delta), mrt.getTableRow(), peaksData.CoDelta.colno); for (MRMDaughter mrmd : mrt.getDaughters().values()) { model.setValueAt(new Float(start), mrmd.getElutionDataTableRow(), peaksData.CoStart.colno); model.setValueAt(new Float(end), mrmd.getElutionDataTableRow(), peaksData.CoEnd.colno); model.setValueAt(new Float(delta), mrmd.getElutionDataTableRow(), peaksData.CoDelta.colno); } Vector<MRMDaughter> matchingDaughters = null; //if synchronize low-high is set, and this is an AQUA-like assay, synchronize the matching //low row and high row to the same new elution range if (transDefHeader != null && _synclh) { matchingDaughters = new Vector<MRMDaughter>(); for (MRMDaughter mrmd : mrt.getDaughters().values()) { MRMDaughter matchingDaughter = transDefHeader.getMatchingDaughter(mrmd); if (matchingDaughter != null) { model.setValueAt(new Float(start), matchingDaughter.getElutionDataTableRow(), peaksData.CoStart.colno); model.setValueAt(new Float(end), matchingDaughter.getElutionDataTableRow(), peaksData.CoEnd.colno); model.setValueAt(new Float(delta), matchingDaughter.getElutionDataTableRow(), peaksData.CoDelta.colno); matchingDaughters.add(matchingDaughter); } } } // recalculate all curves?? // or reselect region as elution curve? // seems like a dumb idea mrt.getElutionCurves().clear(); for (MRMDaughter d : mrt.getDaughters().values()) { d.setBestElutionCurve(null); ElutionCurveStrategy ecs = ElutionCurveStrategy.getInstance(mrt, d, _ecurveclass); ecs.calculateParentElutionCurves(null); ecs.calculateDaughterElutionCurves(null); ecs.calculateBestCurves(); d.setBestElutionCurve(ecs.getBestDaughterCurve()); mrt.getElutionCurves().put(d, ecs); ElutionCurve bestPrecursorCurve = ecs.getBestParentCurve(); ElutionCurve bestDaughterCurve = ecs.getBestDaughterCurve(); if (bestPrecursorCurve == null || bestPrecursorCurve.getMinElutionTimeSecs() <= 0.0) { model.setValueAt(new Float(-1), mrt.getTableRow(), peaksData.AUC.colno); } else { model.setValueAt(new Float(bestPrecursorCurve.getAUC()), mrt.getTableRow(), peaksData.AUC.colno); } if (bestDaughterCurve == null || bestDaughterCurve.getMinElutionTimeSecs() <= 0.0) { model.setValueAt(new Float(-1), d.getElutionDataTableRow(), peaksData.AUC.colno); model.setValueAt(new Float(-1), d.getElutionDataTableRow(), peaksData.MaxPeak.colno); model.setValueAt(new Float(-1), d.getElutionDataTableRow(), peaksData.Quality.colno); model.setValueAt(new Float(-1), d.getElutionDataTableRow(), peaksData.MidTime.colno); } else { model.setValueAt(new Float(bestDaughterCurve.getAUC()), d.getElutionDataTableRow(), peaksData.AUC.colno); model.setValueAt(new Float(bestDaughterCurve.getHighestPointY()), d.getElutionDataTableRow(), peaksData.MaxPeak.colno); model.setValueAt(new Float(d.getQuality()), d.getElutionDataTableRow(), peaksData.Quality.colno); } } //Can't do this until all daughter curves have be recalculated mrt.calcMaxYofAllDaughters(); model.setValueAt(new Float(mrt.getCalcXatMaxYAllDaughters()), mrt.getTableRow(), peaksData.MidTime.colno); for (MRMDaughter d : mrt.getDaughters().values()) { model.setValueAt(new Float(mrt.getCalcXatMaxYAllDaughters()), d.getElutionDataTableRow(), peaksData.MidTime.colno); } //For AQUA assays, etc. if (matchingDaughters != null && !matchingDaughters.isEmpty()) { MRMTransition otherMRT = matchingDaughters.get(0).getPrecursor(); otherMRT.getElutionCurves().clear(); model.setValueAt(new Float(start), otherMRT.getTableRow(), peaksData.CoStart.colno); model.setValueAt(new Float(end), otherMRT.getTableRow(), peaksData.CoEnd.colno); model.setValueAt(new Float(delta), otherMRT.getTableRow(), peaksData.CoDelta.colno); otherMRT.setElutionRegionStart(mrt.getElutionRegionStart()); otherMRT.setElutionRegionEnd(mrt.getElutionRegionEnd()); for (MRMDaughter md : matchingDaughters) { md.setBestElutionCurve(null); ElutionCurveStrategy mecs = ElutionCurveStrategy.getInstance(otherMRT, md, _ecurveclass); mecs.calculateParentElutionCurves(null); mecs.calculateDaughterElutionCurves(null); mecs.calculateBestCurves(); md.setBestElutionCurve(mecs.getBestDaughterCurve()); otherMRT.getElutionCurves().put(md, mecs); ElutionCurve bestPrecursorCurve = mecs.getBestParentCurve(); ElutionCurve bestDaughterCurve = mecs.getBestDaughterCurve(); if (bestPrecursorCurve == null || bestPrecursorCurve.getMinElutionTimeSecs() <= 0.0) { model.setValueAt(new Float(-1), otherMRT.getTableRow(), peaksData.AUC.colno); } else { model.setValueAt(new Float(bestPrecursorCurve.getAUC()), otherMRT.getTableRow(), peaksData.AUC.colno); } if (bestDaughterCurve == null || bestDaughterCurve.getMinElutionTimeSecs() <= 0.0) { model.setValueAt(new Float(-1), md.getElutionDataTableRow(), peaksData.AUC.colno); } else { model.setValueAt(new Float(bestDaughterCurve.getAUC()), md.getElutionDataTableRow(), peaksData.AUC.colno); } } } // redisplay AUCs if (mrt == transitionOnPlot) { updateChartsAndFields(new defaultGraphZone()); } if (transDefHeader != null) AQUAinitializations(); model.addTableModelListener(this); } } public void buttonPostPressTasks() { listTransition.requestFocus(); } public void buttonSICUpdate_actionPerformed(ActionEvent event) { try { NumberFormat nf = NumberFormat.getNumberInstance(); nf.setMaximumFractionDigits(2); nf.setMinimumFractionDigits(2); String answer = nf.format(_precursorChromatogramWindow); String newAnswer = JOptionPane.showInputDialog("New value for MS1 SIC tolerance:", answer); _precursorChromatogramWindow = (float) Double.parseDouble(newAnswer); for (MRMTransition t : _mrmTransitions) { t.setGraphData(null); for (MRMDaughter d : t.getDaughters().values()) { d.setGraphData(null); } } updateChartsAndFields(false); } catch (Exception e) { ApplicationContext.infoMessage("Bad value for MZ tolerance, please try again"); } } public void buttonPDT_actionPerformed(ActionEvent event) { try { NumberFormat nf = NumberFormat.getNumberInstance(); nf.setMaximumFractionDigits(2); nf.setMinimumFractionDigits(2); String answer = nf.format(_precursorDiscoveryMzTolerance); String newAnswer = JOptionPane.showInputDialog("New value for precursor tolerance:", answer); _precursorDiscoveryMzTolerance = (float) Double.parseDouble(newAnswer); initStuff(); } catch (Exception e) { ApplicationContext.infoMessage("Bad value for precursor tolerance."); } } public void buttonDTOL_actionPerformed(ActionEvent event) { try { NumberFormat nf = NumberFormat.getNumberInstance(); nf.setMaximumFractionDigits(4); nf.setMinimumFractionDigits(4); String answer = nf.format(_daughterMzTolerance); String newAnswer = JOptionPane.showInputDialog("New value for product tolerance:", answer); _daughterMzTolerance = (float) Double.parseDouble(newAnswer); initStuff(); } catch (Exception e) { ApplicationContext.infoMessage("Bad value for product tolerance."); } } public void menuItemPMin_actionPerformed(ActionEvent event) { try { NumberFormat nf = NumberFormat.getNumberInstance(); nf.setMaximumFractionDigits(2); nf.setMinimumFractionDigits(2); nf.setGroupingUsed(false); String answer = nf.format(_minPeakCutoff); String newAnswer = JOptionPane.showInputDialog("New value for min peak cutoff:", answer); if (newAnswer == null) return; float newCutoff = Float.parseFloat(newAnswer); if (newCutoff > 0.0f) { for (MRMTransition mrt : _mrmTransitions) { for (MRMDaughter curd : mrt.getDaughters().values()) { if (curd.getBestElutionCurve() != null && curd.getBestElutionCurve().getHighestPointY() < newCutoff) { ((PeaksTableModel) (peaksTable.getModel())).setValueAt(new Boolean(false), curd.getElutionDataTableRow(), peaksData.Accept.colno); } } } } _minPeakCutoff = newCutoff; } catch (Exception e) { ApplicationContext.infoMessage("Failed to change min acceptable peak height: " + e); } } public void menuItemAMin_actionPerformed(ActionEvent event) { try { NumberFormat nf = NumberFormat.getNumberInstance(); nf.setMaximumFractionDigits(2); nf.setMinimumFractionDigits(2); nf.setGroupingUsed(false); String answer = nf.format(_minAreaCutoff); String newAnswer = JOptionPane.showInputDialog("New value for min AUC cutoff:", answer); if (newAnswer == null) return; float newCutoff = Float.parseFloat(newAnswer); if (newCutoff > 0.0f) { for (MRMTransition mrt : _mrmTransitions) { for (MRMDaughter curd : mrt.getDaughters().values()) { if (curd.getBestElutionCurve() != null && curd.getBestElutionCurve().getAUC() < newCutoff) { ((PeaksTableModel) (peaksTable.getModel())).setValueAt(new Boolean(false), curd.getElutionDataTableRow(), peaksData.Accept.colno); } } } } _minAreaCutoff = newCutoff; } catch (Exception e) { ApplicationContext.infoMessage("Failed to change min acceptable AUC: " + e); } } public void menuItemQuit_actionPerformed(ActionEvent event) { try { System.err.println("Normal exit"); System.exit(0); } catch (Exception e) { ApplicationContext.infoMessage("Cannot quit: " + e); } } public void menuItemTraceAllFragments_actionPerformed(ActionEvent event) { try { int newTraceAllCode = JOptionPane.showConfirmDialog(this, "Trace over elution curves of ALL fragments?", "Trace All Fragments", JOptionPane.YES_NO_CANCEL_OPTION); if (newTraceAllCode != JOptionPane.YES_OPTION && newTraceAllCode != JOptionPane.NO_OPTION) return; boolean newTraceAll = (newTraceAllCode == JOptionPane.YES_OPTION); if (newTraceAll != _traceAllFragments) { _traceAllFragments = newTraceAll; updateChartsAndFields(false); } _traceAllFragments = newTraceAll; } catch (Exception e) { ApplicationContext.infoMessage("Cannot change 'Trace All' mode: " + e); } } public void menuItemSyncLH_actionPerformed(ActionEvent event) { try { int newsync = JOptionPane.showConfirmDialog(this, "Synchronize L/H Elution Regions", "Sync Label Elution Regions", JOptionPane.YES_NO_CANCEL_OPTION); if (newsync != JOptionPane.YES_OPTION && newsync != JOptionPane.NO_OPTION) return; boolean newsyncbool = (newsync == JOptionPane.YES_OPTION); _synclh = newsyncbool; } catch (Exception e) { ApplicationContext.infoMessage("Cannot change 'Synchronize L/H' mode: " + e); } } public void menuItemChangeStrategy_actionPerformed(ActionEvent event) { try { String newStrategyName = (String) JOptionPane.showInputDialog(this, "Which elution curve strategy would you like to use?", "Elution Strategy", JOptionPane.PLAIN_MESSAGE, null, MRMCommandLineModule.strategies, MRMCommandLineModule.strategies[0]); newStrategyName = "org.fhcrc.cpl.viewer.mrm." + newStrategyName; if (newStrategyName != _ecurveclass.getName()) { Class newClass = Class.forName(newStrategyName); _ecurveclass = newClass; initStuff(); } } catch (Exception e) { ApplicationContext.infoMessage("Cannot change elution curve strategy: " + e); } } public void menuItemOpen_actionPerformed(ActionEvent event) { try { int returnVal = _mzXMLFileChooser.showOpenDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { _mzXMLFile = _mzXMLFileChooser.getSelectedFile(); initStuff(); } } catch (Exception e) { ApplicationContext.infoMessage("Cannot open file '" + _mzXMLFileChooser.getName() + "': " + e); } } public void menuItemLoadTSV_actionPerformed(ActionEvent event) { boolean result; try { /* _inputTSVFileChooser.setCurrentDirectory(_mzXMLFile.getParentFile()); System.err.println("restore file directory="+_inputTSVFileChooser.getCurrentDirectory()); System.err.println("derived from "+_mzXMLFile.getParent()); */ int returnVal = _inputTSVFileChooser.showOpenDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { File restoreFile = _inputTSVFileChooser.getSelectedFile(); result = ((PeaksTableModel) peaksTable.getModel()).restoreModelFromTSV(restoreFile); if (!result) JOptionPane.showMessageDialog(this, "TSV file is not correct for this MRMer data."); } } catch (Exception e) { ApplicationContext.infoMessage("Cannot restore from TSV: " + e); e.printStackTrace(); } } public void menuItemTips_actionPerformed(ActionEvent event) { try { HtmlViewerPanel.showURLInDialog("http://proteomics.fhcrc.org/CPL/mrm_user_tips.html", "Tips for Using MRMer"); } catch (Exception e) { ApplicationContext.infoMessage("Cannot display TIPS help:" + e); } } public void menuItemDefinitions_actionPerformed(ActionEvent event) { try { HtmlViewerPanel.showURLInDialog("http://proteomics.fhcrc.org/CPL/MRMer_help.html#mrmcomopt", "OPTION menu commands"); } catch (Exception e) { ApplicationContext.infoMessage("Cannot display Definitions help:" + e); } } public void menuItemOptions_actionPerformed(ActionEvent event) { try { HtmlViewerPanel.showURLInDialog("http://proteomics.fhcrc.org/CPL/MRMer_help.html#mrmmenopt", "OPTION menu commands"); } catch (Exception e) { ApplicationContext.infoMessage("Cannot display OPTIONS help:" + e); } } public void menuItemArguments_actionPerformed(ActionEvent event) { try { CommandLineModule module = ViewerCommandLineModuleDiscoverer.getSingletonInstance() .getCommandLineModule("MRM"); String dummyCaller = "dummy_help_caller"; File tempHelpFile = TempFileManager.createTempFile("help_mrm", dummyCaller); PrintWriter outPW = new PrintWriter(tempHelpFile); new ViewerUserManualGenerator().generateCommandManualEntry(module, outPW); outPW.flush(); outPW.close(); HtmlViewerPanel.showFileInDialog(tempHelpFile, "Java command line options"); } catch (Exception e) { ApplicationContext.infoMessage("Cannot show ARGUMENTS help:" + e); } } public void buttonSave_actionPerformed(ActionEvent event) { //System.err.println("save file directory="+_mzXMLFile.getAbsoluteFile().getParent()); int returnVal = _outputFileChooser.showSaveDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { PeaksTableModel ptm = (PeaksTableModel) peaksTable.getModel(); if (!ptm.saveSaveModelAsTSV(_outputFileChooser.getSelectedFile())) ApplicationContext.infoMessage("Cannot save data to '" + _outputFileChooser.getName() + "'"); } else { ApplicationContext.infoMessage( "Cannot save data to '" + _outputFileChooser.getName() + "', returnVal=" + returnVal); } buttonPostPressTasks(); } public void menuItemSaveImage_actionPerformed(ActionEvent event) { int returnVal = _imageOutputFileChooser.showSaveDialog(this); if (returnVal == JFileChooser.APPROVE_OPTION) { File imfi = _imageOutputFileChooser.getSelectedFile(); if (imfi != null && !imfi.toString().toUpperCase().endsWith(".PNG")) { imfi = new File(imfi.toString() + ".png"); } if (imfi == null) { ApplicationContext.infoMessage("Cannot save chromatogram image."); } else { int width = daughterContainerPanel.getWidth(); int height = daughterContainerPanel.getHeight(); BufferedImage dataForFile = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = dataForFile.createGraphics(); daughterContainerPanel.paint(g2d); g2d.dispose(); try { ImageIO.write(dataForFile, "png", imfi); } catch (Exception e) { ApplicationContext.infoMessage("Cannot save chromatogram image: " + e); buttonPostPressTasks(); } } } else { ApplicationContext.infoMessage("Cannot save chromatogram image to '" + _imageOutputFileChooser.getName() + "', returnVal=" + returnVal); } buttonPostPressTasks(); } public void buttonZC_actionPerformed(ActionEvent event) { try { if (((PeaksTableModel) (peaksTable.getModel())).data[peaksTable .getSelectedRow()][peaksData.Daughter.colno] == null) return; updateChartsAndFields(new zoomToCurveGraphZone()); } catch (Exception e) { ApplicationContext.infoMessage("Can't zoom to current curve"); } buttonPostPressTasks(); } public void buttonZoom_actionPerformed(ActionEvent event) { try { updateChartsAndFields(new zoomedGraphZone()); } catch (Exception e) { System.err.println("Failed in ZOOM: " + e); e.printStackTrace(); ApplicationContext.errorMessage("Can't zoom:" + e, e); } buttonPostPressTasks(); } public void buttonNext_actionPerformed(ActionEvent event) { try { int newIndex = transitionOnPlot.getCurrentDaughter().getElutionDataTableRow() + 1; //what if we're positioned on a precursor line? if (((PeaksTableModel) (peaksTable.getModel())).data[peaksTable .getSelectedRow()][peaksData.Daughter.colno] == null) newIndex--; //what if we've moved out of the current group? if (((PeaksTableModel) peaksTable.getModel()).data[newIndex][peaksData.Daughter.colno] == null) { newIndex++; } if (newIndex < ((PeaksTableModel) peaksTable.getModel()).data.length) { scrollPeakTableToRow(newIndex); } //updateChartsAndFields(false); } catch (ArrayIndexOutOfBoundsException aioobe) { System.gc(); } catch (Exception e) { ApplicationContext.infoMessage("Can't display NEXT plot"); } buttonPostPressTasks(); } public void buttonPrev_actionPerformed(ActionEvent event) { try { int newIndex = transitionOnPlot.getCurrentDaughter().getElutionDataTableRow() - 1; if (((PeaksTableModel) peaksTable.getModel()).data[newIndex][peaksData.Daughter.colno] == null) { newIndex--; } if (newIndex > 0) { scrollPeakTableToRow(newIndex); } else { System.gc(); } //updateChartsAndFields(false); } catch (Exception e) { ApplicationContext.infoMessage("Can't display PREVIOUS plot"); } buttonPostPressTasks(); } public void buttonReject_actionPerformed(ActionEvent event) { try { int selectedIndex = peaksTable.getSelectedRow(); if (selectedIndex >= 0) { if (((PeaksTableModel) (peaksTable .getModel())).data[selectedIndex][peaksData.Daughter.colno] == null) return; ((PeaksTableModel) (peaksTable .getModel())).data[selectedIndex][peaksData.Accept.colno] = new Boolean(false); ((PeaksTableModel) (peaksTable.getModel())).fireTableCellUpdated(selectedIndex, peaksData.Accept.colno); buttonNext.doClick(); } } catch (Exception e) { ApplicationContext.infoMessage("Can't REJECT peak: " + e); } buttonPostPressTasks(); } public void buttonRejectGroup_actionPerformed(ActionEvent event) { try { int selectedIndex = peaksTable.getSelectedRow(); if (selectedIndex >= 0) { int maxIndex = -1; MRMTransition curTrans = ((PeaksTableModel) (peaksTable .getModel())).data[selectedIndex][peaksData.Daughter.colno] != null ? ((MRMDaughter) ((PeaksTableModel) (peaksTable .getModel())).data[selectedIndex][peaksData.Daughter.colno]).getPrecursor() : ((MRMTransition) ((PeaksTableModel) (peaksTable .getModel())).data[selectedIndex][peaksData.Precursor.colno]); for (MRMDaughter curd : curTrans.getDaughters().values()) { int curIndex = curd.getElutionDataTableRow(); ((PeaksTableModel) (peaksTable .getModel())).data[curIndex][peaksData.Accept.colno] = new Boolean(false); ((PeaksTableModel) (peaksTable.getModel())).fireTableCellUpdated(curIndex, peaksData.Accept.colno); if (curIndex > maxIndex) maxIndex = curIndex; } peaksTable.getSelectionModel().setSelectionInterval(maxIndex, maxIndex); buttonNext.doClick(); } } catch (Exception e) { ApplicationContext.infoMessage("Can't REJECT group: " + e); } buttonPostPressTasks(); } public void buttonAccept_actionPerformed(ActionEvent event) { try { int selectedIndex = peaksTable.getSelectedRow(); if (selectedIndex >= 0) { if (((PeaksTableModel) (peaksTable .getModel())).data[selectedIndex][peaksData.Daughter.colno] == null) return; ((PeaksTableModel) (peaksTable .getModel())).data[selectedIndex][peaksData.Accept.colno] = new Boolean(true); ((PeaksTableModel) (peaksTable.getModel())).fireTableCellUpdated(selectedIndex, peaksData.Accept.colno); buttonNext.doClick(); } } catch (Exception e) { ApplicationContext.infoMessage("Can't ACCEPT peak: " + e); } buttonPostPressTasks(); } public void buttonBoost_actionPerformed(ActionEvent event) { try { int selectedIndex = peaksTable.getSelectedRow(); if (selectedIndex >= 0) { String comVal = (String) ((PeaksTableModel) (peaksTable .getModel())).data[selectedIndex][peaksData.Comment.colno]; if (comVal.startsWith("D ")) return; ((PeaksTableModel) (peaksTable.getModel())).data[selectedIndex][peaksData.Comment.colno] = "D " + comVal; ((PeaksTableModel) (peaksTable.getModel())).fireTableCellUpdated(selectedIndex, peaksData.Comment.colno); buttonAccept.doClick(); } } catch (Exception e) { ApplicationContext.infoMessage("Can't add Dwell comment to product: " + e); } buttonPostPressTasks(); } public void buttonTiming_actionPerformed(ActionEvent event) { try { int selectedIndex = peaksTable.getSelectedRow(); PeaksTableModel model = (PeaksTableModel) peaksTable.getModel(); String tmp; tmp = ((String) model.data[transitionOnPlot.getTableRow()][MRMDialog.peaksData.Comment.colno]); if (tmp == null) tmp = ""; if (!tmp.startsWith("T ")) { tmp = "T " + tmp; model.data[transitionOnPlot.getTableRow()][peaksData.Comment.colno] = tmp; } for (MRMDaughter d : transitionOnPlot.getDaughters().values()) { tmp = ((String) model.data[d.getElutionDataTableRow()][peaksData.Comment.colno]); if (tmp == null) tmp = ""; if (!tmp.startsWith("T ")) { tmp = "T " + tmp; model.setValueAt(tmp, d.getElutionDataTableRow(), peaksData.Comment.colno); } } tmp = ((String) model.data[transitionOnPlot.getTableRow()][MRMDialog.peaksData.Comment.colno]); if (tmp == null) tmp = ""; if (!tmp.startsWith("T ")) { tmp = "T " + tmp; } model.setValueAt(tmp, transitionOnPlot.getTableRow(), peaksData.Comment.colno); peaksTable.getSelectionModel().setSelectionInterval(selectedIndex, selectedIndex); } catch (Exception e) { ApplicationContext.infoMessage("Can't add TIMING comment to product: " + e); } buttonPostPressTasks(); } public void buttonFindMate_actionPerformed(ActionEvent event) { try { if (transDefHeader == null || transDefHeader.getAQUApairs() == null) throw new Exception("No transitions defined."); MRMDaughter curMRMD = transitionOnPlot.getCurrentDaughter(); if (curMRMD == null) throw new Exception("Can't find current daughter"); TransitionDefinition curTD = transDefHeader.getDToTD().get(curMRMD); if (curTD == null) throw new Exception("Can't find transition definition for " + curMRMD.toString()); TransitionDefinitionHeader.AQUApair curAQUA = transDefHeader.getAQUApairs().get(curTD.getAQUAcode()); if (curAQUA == null) throw new Exception("Can't find AQUA or SILAC pair"); MRMDaughter matchingDaughter = null; if (curTD.isHigh()) { matchingDaughter = curAQUA.getLightMember().getAssociatedProduct(); } else { if (curTD.isLow()) { matchingDaughter = curAQUA.getHeavyMember().getAssociatedProduct(); } } if (matchingDaughter == null) throw new Exception("Can't find opposite labeled product"); scrollPeakTableToRow(matchingDaughter.getElutionDataTableRow()); } catch (Exception e) { ApplicationContext.errorMessage("Can't find matching label: ", e); } buttonPostPressTasks(); } public void contentPanel_componentResized(ComponentEvent event) { try { updateChartsAndFields(false); } catch (Exception e) { System.err.println("Failed to resize chart: " + e); e.printStackTrace(); ApplicationContext.infoMessage("Cannot resize chart"); } } public void contentPanel_mouseClicked(MouseEvent event) { if (event.getButton() == MouseEvent.BUTTON3) { contentPanel.setBackground( JColorChooser.showDialog(this, "Choose Background Color", contentPanel.getBackground())); } } // Renderers public class coloredMRMListRenderer extends JPanel implements ListCellRenderer { public coloredMRMListRenderer() { super(); } public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { this.removeAll(); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); NumberFormat nf = NumberFormat.getNumberInstance(); nf.setMaximumFractionDigits(3); nf.setMinimumFractionDigits(3); JLabel precursor = new JLabel( ((MRMTransition) value).getName() + "\u00B1" + nf.format(_precursorDiscoveryMzTolerance)); Font tmpFont = precursor.getFont(); tmpFont = tmpFont.deriveFont(tmpFont.getSize() + 4.0F); tmpFont = tmpFont.deriveFont(Font.BOLD); precursor.setFont(tmpFont); this.add(precursor); for (MRMDaughter d : ((MRMTransition) value).getDaughters().values()) { JLabel dname = new JLabel(" " + d.getName()); dname.setFont(tmpFont); Color dcolor = (Color) d.getGraphColor(); dname.setForeground(dcolor); this.add(dname); } setBackground(isSelected ? Color.LIGHT_GRAY : Color.WHITE); this.setVisible(true); return this; } } public class MRMTransitionTableRenderer extends JLabel implements TableCellRenderer { Border unselectedBorder = null; Border selectedBorder = null; boolean isBordered = true; public MRMTransitionTableRenderer(boolean isBordered) { super(); this.isBordered = isBordered; setOpaque(true); //MUST do this for background to show up. } public Component getTableCellRendererComponent(JTable table, Object transition, boolean isSelected, boolean hasFocus, int row, int column) { setText(""); this.setHorizontalAlignment(JLabel.RIGHT); Color newColor = Color.BLACK; setForeground(newColor); if (isBordered) { if (isSelected) { if (selectedBorder == null) { selectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5, table.getSelectionBackground()); } setBorder(selectedBorder); } else { if (unselectedBorder == null) { unselectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5, table.getBackground()); } setBorder(unselectedBorder); } } if (transition != null) { this.setText(((MRMTransition) transition).getName()); Font tmpFont = this.getFont(); tmpFont = tmpFont.deriveFont(tmpFont.getSize() + 4.0f); } super.setBackground(UIManager.getColor("Table.focusCellBackground")); return this; } } protected DrawingSupplier getDrawingSupplierForPlot(MRMTransition plot) { Paint colorseq[]; if (plot != null) { int nColors = 0; nColors += plot.getDaughters().size(); colorseq = new Paint[nColors]; int i = 0; for (MRMDaughter d : plot.getDaughters().values()) { if (d == plot.getCurrentDaughter()) { colorseq[i] = Utils.paleColor((Color) plot.getCurrentDaughter().getGraphColor()); } else { colorseq[i] = Color.LIGHT_GRAY; } i++; } } else { colorseq = new Paint[1]; colorseq[0] = Color.WHITE; } return new DefaultDrawingSupplier(colorseq, DefaultDrawingSupplier.DEFAULT_OUTLINE_PAINT_SEQUENCE, DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE, DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE, DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE); } public enum peaksData { Accept, Peptide, Precursor, Daughter { public String toString() { return "Product"; } }, CoStart { public String toString() { return "Start"; } }, CoEnd { public String toString() { return "End"; } }, CoDelta { public String toString() { return "Width"; } }, AUC, MaxPeak, MidTime, Quality, Label, Code, LHRatio, Comment; public static NumberFormat floatFormat = NumberFormat.getNumberInstance(); public int colno = -1; public Class colClass = null; public int colWidth = -1; protected boolean visible = true; protected int oldMinWidth = 0; protected int oldMaxWidth = 0; public void makeVisible(boolean viz) { if (viz == visible) return; if (viz) { peaksTable.getColumnModel().getColumn(this.colno).setMinWidth(this.oldMinWidth); peaksTable.getColumnModel().getColumn(this.colno).setMaxWidth(this.oldMaxWidth); this.visible = true; } else { this.oldMinWidth = peaksTable.getColumnModel().getColumn(this.colno).getMinWidth(); this.oldMaxWidth = peaksTable.getColumnModel().getColumn(this.colno).getMaxWidth(); peaksTable.getColumnModel().getColumn(this.colno).setMinWidth(0); peaksTable.getColumnModel().getColumn(this.colno).setMaxWidth(0); this.visible = false; } peaksTable.updateUI(); } static { floatFormat.setMaximumFractionDigits(2); floatFormat.setMinimumFractionDigits(2); floatFormat.setGroupingUsed(false); for (peaksData pd : peaksData.values()) pd.colno = pd.ordinal(); Accept.colClass = Boolean.class; Peptide.colClass = String.class; Precursor.colClass = MRMTransition.class; Daughter.colClass = MRMDaughter.class; CoStart.colClass = Number.class; CoEnd.colClass = Number.class; CoDelta.colClass = Number.class; AUC.colClass = Number.class; MaxPeak.colClass = Number.class; MidTime.colClass = Number.class; Quality.colClass = Number.class; Label.colClass = String.class; Code.colClass = Integer.class; LHRatio.colClass = Number.class; Comment.colClass = String.class; Accept.colWidth = 50; Peptide.colWidth = 75; Precursor.colWidth = 60; Daughter.colWidth = 50; CoStart.colWidth = 50; CoEnd.colWidth = 50; CoDelta.colWidth = 50; AUC.colWidth = 90; MaxPeak.colWidth = 90; MidTime.colWidth = 90; Quality.colWidth = 50; Label.colWidth = 50; Code.colWidth = 35; LHRatio.colWidth = 45; Comment.colWidth = 150; } public String SaveFileFormat(Object thing) { NumberFormat nf = NumberFormat.getNumberInstance(); nf.setGroupingUsed(false); if (thing == null) return ""; switch (this) { case Accept: return ((Boolean) thing).toString(); case Peptide: return (String) thing; case Code: return ((Integer) thing).toString(); case Precursor: nf.setMaximumFractionDigits(3); nf.setMinimumFractionDigits(3); return nf.format(((MRMTransition) thing).getPrecursorMz()); case Daughter: nf.setMaximumFractionDigits(3); nf.setMinimumFractionDigits(3); return nf.format(((MRMDaughter) thing).getMeanMz()); case CoStart: nf.setMaximumFractionDigits(1); nf.setMinimumFractionDigits(1); return nf.format(((Number) thing).doubleValue()); case CoEnd: nf.setMaximumFractionDigits(1); nf.setMinimumFractionDigits(1); return nf.format(((Number) thing).doubleValue()); case CoDelta: nf.setMaximumFractionDigits(1); nf.setMinimumFractionDigits(1); return nf.format(((Number) thing).doubleValue()); case LHRatio: case AUC: case MaxPeak: case MidTime: case Quality: nf.setMaximumFractionDigits(2); nf.setMinimumFractionDigits(2); return nf.format(((Number) thing).doubleValue()); case Label: case Comment: return (String) thing; default: return ""; } } } protected void scrollPeakTableToRow(int row) { peaksTable.getSelectionModel().setSelectionInterval(row, row); int rowHeight = peaksTable.getHeight() / ((PeaksTableModel) peaksTable.getModel()).getRowCount(); int scrollVal = (row - 5) * rowHeight; if (scrollVal < 0) scrollVal = 0; peaksScrollPane.getVerticalScrollBar().setValue(scrollVal); peaksTable.repaint(); } protected void scrollPeakTableToTransition(MRMTransition trans) { int dataIndex = -1; Object[][] tableData = ((PeaksTableModel) (peaksTable.getModel())).data; for (int j = 0; j < tableData.length; j++) { if (trans == (MRMTransition) (tableData[j][peaksData.Precursor.colno])) { dataIndex = j; break; } } if (dataIndex > -1) { scrollPeakTableToRow(dataIndex + trans.getCurrentDaughterIndex() + 1); } peaksTable.repaint(); } Axis findAxisOfPanel(JPanel panel, whichAxis wa) { for (Component c : panel.getComponents()) { if (c instanceof PanelWithChart) { PanelWithChart pwc = (PanelWithChart) c; JFreeChart jfc = pwc.getChart(); XYPlot xyp = (XYPlot) jfc.getPlot(); switch (wa) { case Domain: return xyp.getDomainAxis(); case Range: return xyp.getRangeAxis(); default: return null; } } } return null; } protected void updateDaughterCharts(boolean clear, graphZone gz) { XYSeriesCollection daughterDatasets = new XYSeriesCollection(); if (clear) { transitionOnPlot = null; } else { daughterDatasets = makeDaughterCollection(); } //Center daughter data on graph by finding the time associated //with the most data (a centroid or center of mass), centering //this time on the plot, and scaling to assure the extreme //timepoints are included /* double weightedAverageTime = getWeightedAverageDaughtersTime(daughterDatasets); double extremeHalf = Math.max(weightedAverageTime-getMinRetentionTimeForPlot(transitionOnPlot),getMaxRetentionTimeForPlot(transitionsOnPlot)-weightedAverageTime); double left = weightedAverageTime-extremeHalf; double right = weightedAverageTime+extremeHalf; */ Range r = null; if (transitionOnPlot != null) r = gz.getRange(transitionOnPlot); if (r == null) { r = new Range(transitionOnPlot.getMinTimeOfAllDaughters(), transitionOnPlot.getMaxTimeOfAllDaughters()); } createChartInPanel(daughterContainerPanel, daughterDatasets, r.getLowerBound(), r.getUpperBound(), getDrawingSupplierForPlot(transitionOnPlot), whichGraph.Daughter); } protected void updateDaughterCharts(boolean clear) { updateDaughterCharts(clear, new defaultGraphZone()); } protected void updateDaughterCharts(graphZone gz) { updateDaughterCharts(false, gz); } protected void updatePrecursorChart(boolean clear, graphZone gz) { XYSeriesCollection precursorDatasets = new XYSeriesCollection(); if (clear) { transitionOnPlot = null; } else { if (transitionOnPlot.getGraphData() == null) //transitionOnPlot.setGraphData(makeParentSeries(transitionOnPlot)); ApplicationContext .infoMessage("Precursor data for '" + transitionOnPlot.toString() + "' wasn't initialized"); precursorDatasets.addSeries(transitionOnPlot.getGraphData()); } //Center daughter data on graph by finding the time associated //with the most data (a centroid or center of mass), centering //this time on the plot, and scaling to assure the extreme //timepoints are included /* double weightedAverageTime = getWeightedAverageDaughtersTime(makeDaughterCollection()); double extremeHalf = Math.max(weightedAverageTime-getMinRetentionTimeForPlot(transitionsOnPlot),getMaxRetentionTimeForPlot(transitionsOnPlot)-weightedAverageTime); double left = weightedAverageTime-extremeHalf; double right = weightedAverageTime+extremeHalf; */ Range r = null; if (transitionOnPlot != null) r = gz.getRange(transitionOnPlot); if (r == null) r = new Range(0, 100); createChartInPanel(precursorContainerPanel, precursorDatasets, r.getLowerBound(), r.getUpperBound(), null, whichGraph.Precursor); } protected void updatePrecursorChart(boolean clear) { updatePrecursorChart(clear, new defaultGraphZone()); } protected void updatePrecursorChart(graphZone gz) { updatePrecursorChart(false, gz); } public void updateChartsAndFields(boolean clear) { updatePrecursorChart(clear); updateDaughterCharts(clear); } public void updateChartsAndFields(graphZone gz) { updatePrecursorChart(gz); updateDaughterCharts(gz); //System.gc(); } protected double getMinRetentionTimeForPlot(MRMTransition plot) { if (plot == null) return 0; double retVal = 1000000d; for (MRMDaughter mrmd : plot.getDaughters().values()) { //Note: scanVals are sorted so we only have to look at the first one Double testVal = mrmd.getScanVals().values().iterator().next().getTime(); if (testVal < retVal) retVal = testVal; } return retVal; } protected double getMaxRetentionTimeForPlot(MRMTransition plot) { if (plot == null) return 5000d; double retVal = 0d; for (MRMDaughter mrmd : plot.getDaughters().values()) { //Note: scanVals are sorted so we only have to look at the first one ElutionDataPoint edpvals[] = mrmd.getScanVals().values().toArray(new ElutionDataPoint[0]); Double testVal = edpvals[edpvals.length - 1].getTime(); if (testVal > retVal) retVal = testVal; } return retVal; } protected XYSeries makeParentSeries(MRMTransition parent) { float minMz = parent.getPrecursorMz() - _precursorDiscoveryMzTolerance - _precursorChromatogramWindow; float maxMz = parent.getPrecursorMz() + _precursorDiscoveryMzTolerance + _precursorChromatogramWindow; NumberFormat nf = NumberFormat.getNumberInstance(); nf.setMaximumFractionDigits(1); nf.setMinimumFractionDigits(1); XYSeries result = new XYSeries(parent.getName() + "\u00B1" + nf.format(_precursorDiscoveryMzTolerance + _precursorChromatogramWindow)); //precursor scans for (int i = parent.getMinScanOfDaughters(); i <= parent.getMaxScanOfDaughters(); i++) { int scanNum = _run.getIndexForScanNum(i); if (scanNum <= 0) continue; MSRun.MSScan ms1Scan = _run.getScan(scanNum); boolean sim_only = _sim; String scanType = ms1Scan.getScanType(); if (!sim_only || (sim_only && scanType.equalsIgnoreCase("SIM"))) result.add(ms1Scan.getDoubleRetentionTime(), Utils.getMaxIntensityForScan(ms1Scan, minMz, maxMz)); } return result; } public boolean precursorChromatogramEmpty(MRMTransition parent) { if (parent == null) return true; XYSeries pData; if ((pData = parent.getGraphData()) == null) return true; for (Object xydio : pData.getItems()) { XYDataItem xydi = (XYDataItem) xydio; if (xydi.getY().doubleValue() != 0.0) return false; } return true; } private XYSeriesCollection makeDaughterCollection() { XYSeriesCollection retVal = new XYSeriesCollection(); for (MRMDaughter d : transitionOnPlot.getDaughters().values()) { if (d.getGraphData() == null) d.setGraphData(d.makeDaughterSeries()); //if ((Boolean)(((PeaksTableModel)(peaksTable.getModel())).data[d.getElutionDataTableRow()][peaksData.Accept.colno])) retVal.addSeries(d.getGraphData()); } return retVal; } public class defaultGraphZone implements graphZone { public Range getRange(MRMTransition mrmt) { double left = 0; double right = 0; double elutionWidth = 0; if (mrmt.getElutionRegionStart() != -1 && mrmt.getElutionRegionEnd() != -1) { elutionWidth = mrmt.getElutionRegionEnd() - mrmt.getElutionRegionStart(); left = Math.max(0.0, mrmt.getElutionRegionStart() - (elutionWidth * 0.1)); right = mrmt.getElutionRegionEnd() + (elutionWidth * 0.1); } else { left = mrmt.calculateMinOfAllBestDaughterCurves(); right = mrmt.calculateMaxOfAllBestDaughterCurves(); } if (right <= 0) { if (mrmt.getParentData() != null && mrmt.getParentData().getItemCount() > 0) { left = mrmt.getParentData().getDataItem(0).getX().doubleValue(); right = mrmt.getParentData().getDataItem(mrmt.getParentData().getItemCount() - 1).getX() .doubleValue(); left = Math.max(0, left - ((right - left) * 0.05)); right = right + ((right - left) * 0.05); } } if (left >= right) return null; return new Range(left, right); } } public class zoomedGraphZone implements graphZone { public Range getRange(MRMTransition mrmt) { double left = getMinRetentionTimeForPlot(transitionOnPlot); double right = getMaxRetentionTimeForPlot(transitionOnPlot); if (left >= right) return null; return new Range(left, right); } } // zoom in on best elution curve public class zoomToCurveGraphZone implements graphZone { public Range getRange(MRMTransition mrmt) { MRMDaughter mrmd = mrmt.getCurrentDaughter(); zoomedGraphZone zgd = new zoomedGraphZone(); if (mrmd == null) return zgd.getRange(mrmt); ElutionCurve ec = mrmd.getBestElutionCurve(); if (ec == null) return zgd.getRange(mrmt); double left = ec.getMinElutionTimeSecs(); double right = ec.getMaxElutionTimeSecs(); if (left >= right) return null; return new Range(left, right); } } protected void createChartInPanelPrecursorTasksOnly(XYPlot xyp) { boolean shouldDisplay = false; if (!precursorChromatogramEmpty(transitionOnPlot)) { shouldDisplay = true; if (!transitionOnPlot.getElutionCurves().isEmpty()) { ElutionCurveStrategy ecs = transitionOnPlot.getElutionCurves().values().iterator().next(); List<ElutionCurve> ecl = ecs.getParentCurves(); if (ecl != null) { for (ElutionCurve e : ecl) { List<Line2D.Double> ll2dd = e.getSegments(); for (Line2D.Double l2dd : ll2dd) { xyp.addAnnotation(Utils.line2Annotation(l2dd, new BasicStroke(2.0f), (ecs.isBestParentCurve(e)) ? Color.GREEN : Color.LIGHT_GRAY)); } } } } } precursorContainerContainerPanel.setVisible(shouldDisplay); // updateDaughterCharts(false); if (this.getWidth() >= 100 && this.getHeight() >= 100) this.setPreferredSize(new Dimension(this.getWidth(), this.getHeight())); pack(); } protected void createChartInPanelDaughterTasksOnly(XYPlot xyp) { XYSeries coloredDataset = transitionOnPlot.getCurrentDaughter().getGraphData(); Paint daughterColor = Utils.paleColor((Color) transitionOnPlot.getCurrentDaughter().getGraphColor()); ArrayList<XYLineAnnotation> coloredDaughters = new ArrayList<XYLineAnnotation>(); //Trace calculated elution curves over data spikes if (transitionOnPlot.getElutionCurves() != null && !transitionOnPlot.getElutionCurves().isEmpty()) { MRMDaughter curDaughter = transitionOnPlot.getCurrentDaughter(); ElutionCurveStrategy ecs = transitionOnPlot.getElutionCurves().get(curDaughter); //Is current daughter rejected? Boolean accepted = (Boolean) ((PeaksTableModel) peaksTable.getModel()).data[curDaughter .getElutionDataTableRow()][peaksData.Accept.colno]; if (accepted == null || !accepted) { xyp.setBackgroundPaint(new Color(255, 230, 230)); } List<ElutionCurve> ecl = ecs.getDaughterCurves(); if (ecl != null) { for (ElutionCurve e : ecl) { List<Line2D.Double> ll2dd = e.getSegments(); for (Line2D.Double l2dd : ll2dd) { xyp.addAnnotation(Utils.line2Annotation(l2dd, new BasicStroke(2.0f), ecs.isBestDaughterCurve(e) ? Color.BLACK : Color.LIGHT_GRAY)); } } } } // If there is a valid "current" daughter draw the spikes in the daughter's color // as annotations (sensu JFree) if (coloredDataset != null) { int nOfPoints = coloredDataset.getItemCount(); for (int i = 0; i < (nOfPoints - 1); i++) { XYDataItem p1 = coloredDataset.getDataItem(i); XYDataItem p2 = coloredDataset.getDataItem(i + 1); coloredDaughters.add(new XYLineAnnotation(p1.getX().doubleValue(), p1.getY().doubleValue(), p2.getX().doubleValue(), p2.getY().doubleValue(), new BasicStroke(1.5f), transitionOnPlot.getCurrentDaughter().getGraphColor()) // new XYLineAnnotation(p1.getX().doubleValue(),p1.getY().doubleValue(),p2.getX().doubleValue(),p2.getY().doubleValue(),new BasicStroke(1.5f),daughterColor) ); } } if (_traceAllFragments) { for (MRMDaughter d : transitionOnPlot.getDaughters().values()) { if (d == transitionOnPlot.getCurrentDaughter()) continue; XYSeries curXYSeries = d.getContinDaughterData(); if (curXYSeries == null || curXYSeries.getItemCount() == 0) continue; if (d.getBestElutionCurve() == null) continue; int nOfPoints = curXYSeries.getItemCount(); for (int i = 0; i < (nOfPoints - 1); i++) { XYDataItem p1 = curXYSeries.getDataItem(i); XYDataItem p2 = curXYSeries.getDataItem(i + 1); coloredDaughters.add( // new XYLineAnnotation(p1.getX().doubleValue(),p1.getY().doubleValue(),p2.getX().doubleValue(),p2.getY().doubleValue(),new BasicStroke(1f),Utils.paleColor((Color)d.getGraphColor())) new XYLineAnnotation(p1.getX().doubleValue(), p1.getY().doubleValue(), p2.getX().doubleValue(), p2.getY().doubleValue(), new BasicStroke(1f), d.getGraphColor())); } } } if (coloredDaughters != null) { for (XYLineAnnotation xyla : coloredDaughters) { xyp.addAnnotation(xyla); } } coloredDaughters.clear(); //Display L or H label in upper left hand corner Range xRange = xyp.getDomainAxis().getRange(); Range yRange = xyp.getRangeAxis().getRange(); XYTextAnnotation lab = new XYTextAnnotation( (String) ((PeaksTableModel) peaksTable.getModel()).data[transitionOnPlot.getCurrentDaughter() .getElutionDataTableRow()][peaksData.Label.colno], xRange.getUpperBound() - (0.05 * xRange.getLength()), yRange.getUpperBound() - (0.05 * yRange.getLength())); lab.setFont(lab.getFont().deriveFont(Font.BOLD, 40.0F)); xyp.addAnnotation(lab); XYTextAnnotation midMarker = new XYTextAnnotation("\u25BC", ((MRMTransition) transitionOnPlot).getCalcXatMaxYAllDaughters(), ((MRMTransition) transitionOnPlot).getCalcMaxYAllDaughters()); midMarker.setPaint(Color.RED); midMarker.setFont(midMarker.getFont().deriveFont(Font.BOLD, 20F)); XYTextAnnotation midMarkerOutline = new XYTextAnnotation("\u25BC", ((MRMTransition) transitionOnPlot).getCalcXatMaxYAllDaughters(), ((MRMTransition) transitionOnPlot).getCalcMaxYAllDaughters()); midMarkerOutline.setPaint(Color.BLACK); midMarkerOutline.setFont(midMarker.getFont().deriveFont(Font.BOLD, 23F)); xyp.addAnnotation(midMarkerOutline); xyp.addAnnotation(midMarker); } public XYPlot oldPrecursorChart = null; public XYPlot oldProductChart = null; protected void clearPreviousChartJunk(XYPlot xyp) { if (xyp != null) { xyp.clearAnnotations(); xyp.clearDomainAxes(); xyp.clearRangeAxes(); xyp.setDataset(null); } } /** * Draw a chart in a panel. Good for precursors and daughters * @param parentPanel * @param dataset * @param domainMin * @param domainMax * @param supplier * @param wg */ protected void createChartInPanel(JPanel parentPanel, XYSeriesCollection dataset, Double domainMin, Double domainMax, DrawingSupplier supplier, whichGraph wg) { if (precursorChromatogramEmpty(transitionOnPlot) && wg == whichGraph.Precursor) { precursorContainerContainerPanel.setVisible(false); if (this.getWidth() >= 100 && this.getHeight() >= 100) this.setPreferredSize(new Dimension(this.getWidth(), this.getHeight())); pack(); return; } switch (wg) { case Precursor: clearPreviousChartJunk(oldPrecursorChart); oldPrecursorChart = null; break; case Daughter: clearPreviousChartJunk(oldProductChart); oldProductChart = null; break; } JFreeChart chart = ChartFactory.createXYLineChart(null, "seconds", null, dataset, PlotOrientation.VERTICAL, true, false, false); chart.setBackgroundPaint(new Color(220, 220, 220)); XYPlot xyp = (XYPlot) (chart.getPlot()); xyp.setBackgroundPaint(Color.WHITE); xyp.setDomainGridlinesVisible(true); xyp.setRangeGridlinesVisible(true); xyp.setDomainGridlinePaint(Color.LIGHT_GRAY); xyp.setRangeGridlinePaint(Color.LIGHT_GRAY); if (supplier != null) { xyp.setDrawingSupplier(supplier); } else { xyp.setDrawingSupplier(Utils.plainDrawingSupplier(Color.LIGHT_GRAY)); } xyp.setSeriesRenderingOrder(SeriesRenderingOrder.REVERSE); CenterZoomNumberAxis axisDomain = new CenterZoomNumberAxis("seconds"); axisDomain.setAutoRangeIncludesZero(false); axisDomain.setRange(Math.max(0.0, domainMin), domainMax); axisDomain.addChangeListener(new domainAxisZoomCoordinator(axisDomain)); xyp.clearAnnotations(); xyp.setDomainAxis(axisDomain); xyp.getDomainAxis().setAutoRange(false); xyp.getRangeAxis().setAutoRange(false); XYLineAndShapeRenderer xylsr = (XYLineAndShapeRenderer) xyp.getRenderer(); xylsr.setLegendLine(Utils.legendThing(16, 6)); xylsr.setShapesFilled(true); xylsr.setBaseShapesFilled(true); PanelWithChart panelWithChart = new PanelWithChart(chart); ChartPanel cp = panelWithChart.getChartPanel(); cp.removeMouseListener(cp); cp.removeMouseMotionListener(cp); if (peaksTable != null) { MRMerMouseListener mml = new MRMerMouseListener(cp, (PeaksTableModel) peaksTable.getModel()); cp.addMouseListener(mml); cp.addMouseMotionListener(mml); } cp.setPreferredSize(new Dimension(parentPanel.getWidth(), parentPanel.getHeight() - 10)); cp.setDomainZoomable(true); cp.setRangeZoomable(false); cp.setPopupMenu(null); parentPanel.removeAll(); parentPanel.add(panelWithChart); switch (wg) { case Precursor: createChartInPanelPrecursorTasksOnly(xyp); oldPrecursorChart = xyp; break; case Daughter: createChartInPanelDaughterTasksOnly(xyp); oldProductChart = xyp; break; } parentPanel.updateUI(); listTransition.requestFocus(); } private int indexOfMaxY(XYSeries s) { double _maxy = -10000000000.0; int retVal = -1; for (int i = 0; i < s.getItemCount(); i++) { XYDataItem xydi = s.getDataItem(i); if (_maxy < xydi.getY().doubleValue()) { _maxy = xydi.getY().doubleValue(); retVal = i; } } return retVal; } private static NumberFormat _transitionNumberFormat = NumberFormat.getNumberInstance(); static { _transitionNumberFormat.setMaximumFractionDigits(4); _transitionNumberFormat.setMinimumFractionDigits(4); } public interface mzXML2TransitionArray { public MRMTransition[] reParse(MSRun run); } public static boolean isMRM(MSRun.MSScan scan) { return (scan != null) && scan.getScanType() != null && (scan.getScanType().equalsIgnoreCase("MRM") || scan.getScanType().equalsIgnoreCase("SRM") || scan.getScanType().equalsIgnoreCase("MultipleReaction")); } protected class originalReParser implements mzXML2TransitionArray { public MRMTransition[] reParse(MSRun run) { Vector<MRMTransition> transitions = new Vector<MRMTransition>(); Map<Float, MRMDaughter> meanDaughterTransitionMap = new HashMap<Float, MRMDaughter>(); for (MSRun.MSScan ms2Scan : run.getMS2Scans()) { if (isMRM(ms2Scan)) { // See if a parent MRMTransition within the mz tolerance exists // If not. Create one. float testPrecursor = ms2Scan.getPrecursorMz(); MRMTransition curTrans = null; for (MRMTransition testTrans : transitions) { if (testTrans.getPrecursorMz() >= (testPrecursor - _precursorDiscoveryMzTolerance) && testTrans.getPrecursorMz() <= (testPrecursor + _precursorDiscoveryMzTolerance)) { curTrans = testTrans; break; } } if (curTrans == null) { curTrans = new MRMTransition(testPrecursor, run); curTrans.setName(_transitionNumberFormat.format(curTrans.getPrecursorMz())); transitions.add(curTrans); } // See if a daughter mean mz exists yet for that parent // If not. Create one. Attach it to parent. float meanDaughter = (ms2Scan.getLowMz() + ms2Scan.getHighMz()) / 2; MRMDaughter curDaughter = null; for (MRMDaughter testDaughter : curTrans.getDaughters().values()) { if (meanDaughter >= (testDaughter.getMeanMz() - _daughterMzTolerance) && meanDaughter <= (testDaughter.getMeanMz() + _daughterMzTolerance)) { curDaughter = testDaughter; break; } } if (curDaughter == null) { curDaughter = new MRMDaughter(meanDaughter, ms2Scan.getLowMz(), ms2Scan.getHighMz(), ms2Scan.getNum(), ms2Scan.getNum(), curTrans); curDaughter.setGraphColor(MRMTransition.COLOR_SERIES[curTrans.getDaughters().size() % (MRMTransition.COLOR_SERIES.length)]); curDaughter .setName(_transitionNumberFormat.format(curDaughter.getPrecursor().getPrecursorMz()) + "/" + _transitionNumberFormat.format(curDaughter.getMeanMz())); meanDaughterTransitionMap.put(curDaughter.getMeanMz(), curDaughter); curTrans.getDaughters().put(curDaughter.getMeanMz(), curDaughter); //make sure this line doesn't duplicate initial scan number curDaughter.addScanVal(ms2Scan.getNum(), new ElutionDataPoint(ms2Scan.getDoubleRetentionTime(), Utils.getMaxIntensityForScan( ms2Scan, curDaughter.getLowMz(), curDaughter.getHighMz()))); //allDaughters.add(new ReactionClusterable(curTrans.getPrecursorMz(),curDaughter.getMeanMz())); } else { // Add current scan to daughter. curDaughter.addScanVal(ms2Scan.getNum(), new ElutionDataPoint(ms2Scan.getDoubleRetentionTime(), Utils.getMaxIntensityForScan( ms2Scan, curDaughter.getLowMz(), curDaughter.getHighMz()))); //allDaughters.add(new ReactionClusterable(curTrans.getPrecursorMz(),curDaughter.getMeanMz())); } } } ArrayList<MRMDaughter> mrmTransitionLists = new ArrayList<MRMDaughter>(); for (MRMDaughter daughter : meanDaughterTransitionMap.values()) { mrmTransitionLists.add(daughter); } MRMTransition[] result = transitions.toArray(new MRMTransition[0]); Arrays.sort(result, new MRMTransition.PrecursorMzComparator()); return result; } } protected class thermoReParser implements mzXML2TransitionArray { protected Range[] parseFilterLine(String fline) { String rangeStrings[] = fline.split("\\[")[1].split(","); rangeStrings[rangeStrings.length - 1] = rangeStrings[rangeStrings.length - 1].replace("]", ""); Range retVal[] = new Range[rangeStrings.length]; for (int i = 0; i < rangeStrings.length; i++) { String ends[] = rangeStrings[i].split("-"); retVal[i] = new Range(Double.parseDouble(ends[0]), Double.parseDouble(ends[1])); } return retVal; } public MRMTransition[] reParse(MSRun run) { // New (Post Jan '08) thermo files have "filterLine" attributes // on the <run> element. These define transitions. There will // be one "peak" in the <peaks> element for each daughter. // Considerations: each daughter must (should) be assigned a // distinct time. So the entire ms2/MRM scan should be divided // into n retention time segments for n daughters. This means // we have to know the value of the NEXT scan retention time // in order to get some estimate for the length of the ms2 // scan. It also means we'll keep around average times so that // we can process the last scan. //for final mean scan time double sumRetentionTimeDeltas = 0.0d; int countMRMScans = 0; //places to keep precursors and products Vector<MRMTransition> transitions = new Vector<MRMTransition>(); Map<Float, MRMDaughter> meanProductTransitionMap = new HashMap<Float, MRMDaughter>(); for (MSRun.MSScan ms2Scan : run.getMS2Scans()) { if (isMRM(ms2Scan)) { try { if (ms2Scan.getFilterLine() == null) { throw new Exception("No filter line in Thermo MRM scan '" + ms2Scan.toString() + "'"); } float testPrecursor = ms2Scan.getPrecursorMz(); MRMTransition curTrans = null; // Have we seen a transition with this precursor value yet? for (MRMTransition testTrans : transitions) { if (testTrans.getPrecursorMz() >= (testPrecursor - _precursorDiscoveryMzTolerance) && testTrans .getPrecursorMz() <= (testPrecursor + _precursorDiscoveryMzTolerance)) { curTrans = testTrans; break; } } if (curTrans == null) { curTrans = new MRMTransition(testPrecursor, run); curTrans.setName(_transitionNumberFormat.format(curTrans.getPrecursorMz())); transitions.add(curTrans); } //Determine length of scan double scanLen = 0d; MSRun.MSScan nextScan = _run.getScanByNum(ms2Scan.getNum() + 1); if (nextScan != null) { scanLen = nextScan.getDoubleRetentionTime() - ms2Scan.getDoubleRetentionTime(); sumRetentionTimeDeltas += scanLen; countMRMScans++; } else { scanLen = sumRetentionTimeDeltas / countMRMScans; //mean daughter scan time } //Create a daughter (if necessary) or just a daughter datapoint //Assume there are as many points in the "spectrum" as there are //daughters. Assume they come in the same order as they are described //in the filterLine. We can change the assumptions and complicate the //code if necessary. Range productRanges[] = parseFilterLine(ms2Scan.getFilterLine()); Vector<MRMDaughter> productRangeDaughters = new Vector<MRMDaughter>(); for (int i = 0; i < productRanges.length; i++) { Range daughterCenter = productRanges[i]; float meanDaughter = (float) daughterCenter.getCentralValue(); MRMDaughter curDaughter = null; for (MRMDaughter testDaughter : curTrans.getDaughters().values()) { if (meanDaughter >= (testDaughter.getMeanMz() - _daughterMzTolerance) && meanDaughter <= (testDaughter.getMeanMz() + _daughterMzTolerance)) { curDaughter = testDaughter; break; } } if (curDaughter == null) { curDaughter = new MRMDaughter(meanDaughter, (float) daughterCenter.getLowerBound(), (float) daughterCenter.getUpperBound(), ms2Scan.getNum(), ms2Scan.getNum(), curTrans); curDaughter.setGraphColor(MRMTransition.COLOR_SERIES[curTrans.getDaughters().size() % (MRMTransition.COLOR_SERIES.length)]); curDaughter.setName( _transitionNumberFormat.format(curDaughter.getPrecursor().getPrecursorMz()) + "/" + _transitionNumberFormat.format(curDaughter.getMeanMz())); meanProductTransitionMap.put(curDaughter.getMeanMz(), curDaughter); curTrans.getDaughters().put(curDaughter.getMeanMz(), curDaughter); } productRangeDaughters.add(curDaughter); } //Now we know a daughter defined by the filterLine is associated with //with the precursor. We have to find which spectrum datapoint goes //with which daughter. int dcount = -1; for (MRMDaughter mrmd : productRangeDaughters) { dcount++; int spectrumPointCount = 0; double curMZ = -1d; double curIntensity = -1d; for (int j = 0; j < ms2Scan.getSpectrum()[0].length; j++) { if ((ms2Scan.getSpectrum()[0][j] >= (mrmd.getMeanMz() - _daughterMzTolerance)) && (ms2Scan.getSpectrum()[0][j] <= (mrmd.getMeanMz() + _daughterMzTolerance))) { curMZ = ms2Scan.getSpectrum()[0][j]; curIntensity = ms2Scan.getSpectrum()[1][j]; spectrumPointCount++; } } if (spectrumPointCount == 1) { mrmd.addScanVal(ms2Scan.getNum(), new ElutionDataPoint( ms2Scan.getDoubleRetentionTime() + ((scanLen / productRanges.length) * dcount), curIntensity)); } else { if (spectrumPointCount > 1) { ApplicationContext.infoMessage( "More than one spectrum point can belong to same daughter in same scan"); } else { if (spectrumPointCount == 0) { mrmd.addScanVal(ms2Scan.getNum(), new ElutionDataPoint(ms2Scan.getDoubleRetentionTime() + ((scanLen / productRanges.length) * dcount), 0d)); ApplicationContext.infoMessage("No datapoint found matching daughter " + mrmd + " for scan " + ms2Scan.getNum()); } } } } } catch (Exception e) { ApplicationContext .infoMessage("Can't parse scan " + ms2Scan.getNum() + " in thermo reparser: " + e); } } } ArrayList<MRMDaughter> mrmTransitionLists = new ArrayList<MRMDaughter>(); for (MRMDaughter daughter : meanProductTransitionMap.values()) { mrmTransitionLists.add(daughter); } MRMTransition[] result = transitions.toArray(new MRMTransition[0]); Arrays.sort(result, new MRMTransition.PrecursorMzComparator()); return result; } } protected class agilentReParser implements mzXML2TransitionArray { public MRMTransition[] reParse(MSRun run) { // New (Post Sept '09) agilent files translated by TRAPPER. // These files are similar to thermo files in that they store // all the MRM products in one scan. But they do not have // thermo's FilterLine data to suggest M/Z of the products. // So the daughter M/Zs must be deduced from the scan. Also // as in the thermo reparser, each product lacks its own // distinct time. So the entire ms2/MRM scan must be divided // into n retention time segments for n daughters. This means // we have to know the value of the NEXT scan retention time // in order to get some estimate for the length of the ms2 // scan. It also means we'll keep around average times so that // we can fill in something reasonable for the last scan. //for final mean scan time double sumRetentionTimeDeltas = 0.0d; int countMRMScans = 0; //places to keep precursors and products Vector<MRMTransition> transitions = new Vector<MRMTransition>(); Map<Float, MRMDaughter> meanProductTransitionMap = new HashMap<Float, MRMDaughter>(); for (MSRun.MSScan ms2Scan : run.getMS2Scans()) { if (isMRM(ms2Scan)) { try { float testPrecursor = ms2Scan.getPrecursorMz(); MRMTransition curTrans = null; // Have we seen a transition with this precursor value yet? for (MRMTransition testTrans : transitions) { if (testTrans.getPrecursorMz() >= (testPrecursor - _precursorDiscoveryMzTolerance) && testTrans .getPrecursorMz() <= (testPrecursor + _precursorDiscoveryMzTolerance)) { curTrans = testTrans; break; } } if (curTrans == null) { curTrans = new MRMTransition(testPrecursor, run); curTrans.setName(_transitionNumberFormat.format(curTrans.getPrecursorMz())); transitions.add(curTrans); } //Determine time-span of scan double scanLen = 0d; MSRun.MSScan nextScan = _run.getScanByNum(ms2Scan.getNum() + 1); if (nextScan != null) { scanLen = nextScan.getDoubleRetentionTime() - ms2Scan.getDoubleRetentionTime(); sumRetentionTimeDeltas += scanLen; countMRMScans++; } else { scanLen = sumRetentionTimeDeltas / countMRMScans; //mean daughter scan time } //Create a daughter (if necessary) or just a daughter datapoint Vector<MRMDaughter> productRangeDaughters = new Vector<MRMDaughter>(); for (int i = 0; i < ms2Scan.getPeaksCount(); i++) { float meanDaughter = ms2Scan.getSpectrum()[0][i]; MRMDaughter curDaughter = null; for (MRMDaughter testDaughter : curTrans.getDaughters().values()) { if (meanDaughter >= (testDaughter.getMeanMz() - _daughterMzTolerance) && meanDaughter <= (testDaughter.getMeanMz() + _daughterMzTolerance)) { curDaughter = testDaughter; break; } } if (curDaughter == null) { curDaughter = new MRMDaughter(meanDaughter, ms2Scan.getSpectrum()[0][i] - _daughterMzTolerance, ms2Scan.getSpectrum()[0][i] + _daughterMzTolerance, ms2Scan.getNum(), ms2Scan.getNum(), curTrans); curDaughter.setGraphColor(MRMTransition.COLOR_SERIES[curTrans.getDaughters().size() % (MRMTransition.COLOR_SERIES.length)]); curDaughter.setName( _transitionNumberFormat.format(curDaughter.getPrecursor().getPrecursorMz()) + "/" + _transitionNumberFormat.format(curDaughter.getMeanMz())); meanProductTransitionMap.put(curDaughter.getMeanMz(), curDaughter); curTrans.getDaughters().put(curDaughter.getMeanMz(), curDaughter); } productRangeDaughters.add(curDaughter); } //Now we know a daughter is associated with //with the precursor. We have to find which spectrum datapoint goes //with which daughter. int dcount = -1; for (MRMDaughter mrmd : productRangeDaughters) { dcount++; int spectrumPointCount = 0; double curMZ = -1d; double curIntensity = -1d; for (int j = 0; j < ms2Scan.getSpectrum()[0].length; j++) { if ((ms2Scan.getSpectrum()[0][j] >= (mrmd.getMeanMz() - _daughterMzTolerance)) && (ms2Scan.getSpectrum()[0][j] <= (mrmd.getMeanMz() + _daughterMzTolerance))) { curMZ = ms2Scan.getSpectrum()[0][j]; curIntensity = ms2Scan.getSpectrum()[1][j]; spectrumPointCount++; } } if (spectrumPointCount == 1) { mrmd.addScanVal(ms2Scan.getNum(), new ElutionDataPoint( ms2Scan.getDoubleRetentionTime() + ((scanLen / ms2Scan.getSpectrum()[0].length) * dcount), curIntensity)); } else { if (spectrumPointCount > 1) { ApplicationContext.infoMessage( "More than one spectrum point can belong to same daughter in same scan"); } else { if (spectrumPointCount == 0) { mrmd.addScanVal(ms2Scan.getNum(), new ElutionDataPoint(ms2Scan.getDoubleRetentionTime() + ((scanLen / ms2Scan.getSpectrum()[0].length) * dcount), 0d)); ApplicationContext.infoMessage("No datapoint found matching daughter " + mrmd + " for scan " + ms2Scan.getNum()); } } } } } catch (Exception e) { ApplicationContext .infoMessage("Can't parse scan " + ms2Scan.getNum() + " in thermo reparser: " + e); } } } ArrayList<MRMDaughter> mrmTransitionLists = new ArrayList<MRMDaughter>(); for (MRMDaughter daughter : meanProductTransitionMap.values()) { mrmTransitionLists.add(daughter); } MRMTransition[] result = transitions.toArray(new MRMTransition[0]); Arrays.sort(result, new MRMTransition.PrecursorMzComparator()); return result; } } /** /** * Detect all the transitions and load into an array * @param run * @return * * There is a lot of legacy code here to be cleaned up later * */ private MRMTransition[] loadMRMTransitions(MSRun run) { for (MSRun.MSScan ms2Scan : run.getMS2Scans()) { if (isMRM(ms2Scan)) { if (ms2Scan.getFilterLine() != null && ms2Scan.getFilterLine().length() > 0) { return (new thermoReParser()).reParse(run); } else if (ms2Scan.getScanType().equalsIgnoreCase("MultipleReaction")) { return (new agilentReParser()).reParse(run); } else return (new originalReParser()).reParse(run); } break; } return (new originalReParser()).reParse(run); } }