Java tutorial
/* * EuroCarbDB, a framework for carbohydrate bioinformatics * * Copyright (c) 2006-2009, Eurocarb project, or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. * * This copyrighted material is made available to anyone wishing to use, modify, * copy, or redistribute it subject to the terms and conditions of the GNU * Lesser General Public License, as published by the Free Software Foundation. * A copy of this license accompanies this distribution in the file LICENSE.txt. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * for more details. * * Last commit: $Rev: 1930 $ by $Author: david@nixbioinf.org $ on $Date:: 2010-07-29 #$ */ /** @author Alessio Ceroni (a.ceroni@imperial.ac.uk) */ package org.eurocarbdb.application.glycoworkbench.plugin; import org.eurocarbdb.application.glycanbuilder.*; import org.eurocarbdb.application.glycoworkbench.*; import java.io.File; import java.awt.*; import java.awt.geom.*; import java.awt.event.*; import java.awt.print.PrinterJob; import java.util.*; import javax.swing.*; import org.jfree.chart.JFreeChart; import org.jfree.chart.ChartPanel; import org.jfree.chart.plot.XYPlot; import org.jfree.data.Range; import org.jfree.data.xy.DefaultXYDataset; import org.jfree.data.xy.XYDataset; import org.jfree.chart.annotations.XYShapeAnnotation; import org.jfree.chart.annotations.XYTextAnnotation; import org.jfree.chart.renderer.xy.StandardXYItemRenderer; public class SpectraPanel extends DocumentPanel<SpectraDocument> implements ActionListener, MouseListener, MouseMotionListener { public interface SelectionChangeListener { public void selectionChanged(SelectionChangeEvent e); } public static class SelectionChangeEvent { private SpectraPanel src; public SelectionChangeEvent(SpectraPanel _src) { src = _src; } public SpectraPanel getSource() { return src; } } // components protected AnnotatedPeakList theSearchResults; protected DefaultXYDataset theDataset; protected DefaultXYDataset theIsotopesDataset; protected XYPlot thePlot; protected JFreeChart theChart; protected ChartPanel theChartPanel; protected JToolBar theToolBar; // data protected int current_ind; protected TreeMap<Double, Double> visibleData; // selection protected Peak current_peak; protected TreeSet<Peak> selected_peaks; // actions protected String shown_mslevel; protected JButton mslevel_button; protected boolean was_moving; protected boolean is_moving; protected Point2D mouse_start_point; protected Rectangle2D zoom_rectangle; protected Cursor hand_cursor; protected GlycanAction ms_action; protected GlycanAction msms_action; protected boolean update_isotope_curves; protected boolean automatic_update_isotope_curves; protected boolean show_all_isotopes; protected JButton isotopes_button; protected JButton ftmode_button; // protected Vector<SelectionChangeListener> listeners; // public SpectraPanel() { super(); } protected void initSingletons() { super.initSingletons(); theSearchResults = null; selected_peaks = new TreeSet<Peak>(); shown_mslevel = "msms"; current_ind = 0; visibleData = new TreeMap<Double, Double>(); update_isotope_curves = false; automatic_update_isotope_curves = true; show_all_isotopes = false; } protected void initComponents() { setLayout(new BorderLayout()); // create chart theDataset = new DefaultXYDataset(); theIsotopesDataset = new DefaultXYDataset(); theChart = org.jfree.chart.ChartFactory.createScatterPlot("Spectrum", "m/z ratio", "Intensity", theDataset, org.jfree.chart.plot.PlotOrientation.VERTICAL, false, false, false); thePlot = (XYPlot) theChart.getPlot(); thePlot.setRenderer(new StandardXYItemRenderer(StandardXYItemRenderer.LINES)); thePlot.setDataset(1, theIsotopesDataset); thePlot.setRenderer(1, new StandardXYItemRenderer(StandardXYItemRenderer.LINES)); theChartPanel = new ChartPanel(theChart); theChartPanel.setDomainZoomable(false); theChartPanel.setRangeZoomable(false); theChartPanel.setPopupMenu(null); //TODO: PAINT-RESTORE add(theChartPanel, BorderLayout.CENTER); // create toolbar theToolBar = createToolBar(); //TODO: PAINT-RESTORE add(theToolBar, BorderLayout.SOUTH); } protected void finalSettings() { // load cursors hand_cursor = FileUtils.createCursor("hand"); // add listeners listeners = new Vector<SelectionChangeListener>(); thePlot.getDomainAxis().addChangeListener(new org.jfree.chart.event.AxisChangeListener() { public void axisChanged(org.jfree.chart.event.AxisChangeEvent event) { updateChart(); } }); theChartPanel.addMouseMotionListener(this); theChartPanel.addMouseListener(this); was_moving = false; is_moving = false; mouse_start_point = null; zoom_rectangle = null; super.finalSettings(); } public SpectraDocument getDocumentFromWorkspace(GlycanWorkspace workspace) { return (workspace != null) ? workspace.getSpectra() : null; } public void setDocumentFromWorkspace(GlycanWorkspace workspace) { if (theDocument != null) theDocument.removeDocumentChangeListener(this); if (theSearchResults != null) theSearchResults.removeDocumentChangeListener(this); theDocument = getDocumentFromWorkspace(workspace); if (theDocument == null) theDocument = new SpectraDocument(); theSearchResults = (workspace != null) ? workspace.getSearchResults() : null; theDocument.addDocumentChangeListener(this); if (theSearchResults != null) theSearchResults.addDocumentChangeListener(this); current_ind = 0; updateView(); updateActions(); } protected void createActions() { theActionManager.add("mslevel=ms", FileUtils.defaultThemeManager.getImageIcon("msms"), "Change current scan level", -1, "", this); theActionManager.add("mslevel=msms", FileUtils.defaultThemeManager.getImageIcon("ms"), "Change current scan level", -1, "", this); theActionManager.add("updateisotopecurves=true", FileUtils.defaultThemeManager.getImageIcon("isotopesoff"), "Automatic computation of isotopic distributions inactive", -1, "", this); theActionManager.add("updateisotopecurves=false", FileUtils.defaultThemeManager.getImageIcon("isotopeson"), "Automatic computation of isotopic distributions active", -1, "", this); theActionManager.add("showallisotopes=true", FileUtils.defaultThemeManager.getImageIcon("ftmodeoff"), "FTICR mode inactive", -1, "", this); theActionManager.add("showallisotopes=false", FileUtils.defaultThemeManager.getImageIcon("ftmodeon"), "FTICR mode active", -1, "", this); theActionManager.add("close", FileUtils.defaultThemeManager.getImageIcon("close"), "Close structure", KeyEvent.VK_S, "", this); theActionManager.add("previous", FileUtils.defaultThemeManager.getImageIcon("previous"), "Previous structure", KeyEvent.VK_L, "", this); theActionManager.add("next", FileUtils.defaultThemeManager.getImageIcon("next"), "Next structure", KeyEvent.VK_N, "", this); theActionManager.add("edit", FileUtils.defaultThemeManager.getImageIcon("edit"), "Edit scan data", -1, "", this); theActionManager.add("new", FileUtils.defaultThemeManager.getImageIcon("new"), "Clear", KeyEvent.VK_N, "", this); theActionManager.add("openspectra", FileUtils.defaultThemeManager.getImageIcon("openspectra"), "Open Spectra", KeyEvent.VK_O, "", this); theActionManager.add("print", FileUtils.defaultThemeManager.getImageIcon("print"), "Print...", KeyEvent.VK_P, "", this); theActionManager.add("addpeaks", FileUtils.defaultThemeManager.getImageIcon("addpeaks"), "Add selected peaks to list", -1, "", this); theActionManager.add("annotatepeaks", FileUtils.defaultThemeManager.getImageIcon("annotatepeaks"), "Find possible annotations for selected peaks", -1, "", this); theActionManager.add("baselinecorrection", FileUtils.defaultThemeManager.getImageIcon("baseline"), "Baseline correction of current spectrum", -1, "", this); theActionManager.add("noisefilter", FileUtils.defaultThemeManager.getImageIcon("noisefilter"), "Filter noise in current spectrum", -1, "", this); theActionManager.add("centroid", FileUtils.defaultThemeManager.getImageIcon("centroid"), "Compute peak centroids", -1, "", this); theActionManager.add("arrow", FileUtils.defaultThemeManager.getImageIcon("arrow"), "Activate zoom", -1, "", this); theActionManager.add("hand", FileUtils.defaultThemeManager.getImageIcon("hand"), "Activate moving", -1, "", this); theActionManager.add("zoomnone", FileUtils.defaultThemeManager.getImageIcon("zoomnone"), "Reset zoom", -1, "", this); theActionManager.add("zoomin", FileUtils.defaultThemeManager.getImageIcon("zoomin"), "Zoom in", -1, "", this); theActionManager.add("zoomout", FileUtils.defaultThemeManager.getImageIcon("zoomout"), "Zoom out", -1, "", this); } protected void updatePeakActions() { if (ms_action == null && theApplication.getPluginManager().getMsPeakActions().size() > 0) ms_action = theApplication.getPluginManager().getMsPeakActions().iterator().next(); if (msms_action == null && theApplication.getPluginManager().getMsMsPeakActions().size() > 0) msms_action = theApplication.getPluginManager().getMsMsPeakActions().iterator().next(); } protected void updateActions() { theActionManager.get("close").setEnabled(theDocument.getNoScans() != 0); theActionManager.get("previous").setEnabled(current_ind > 0); theActionManager.get("next").setEnabled(current_ind < (theDocument.getNoScans() - 1)); theActionManager.get("arrow").setEnabled(is_moving); theActionManager.get("hand").setEnabled(!is_moving); theActionManager.get("edit").setEnabled(theDocument.getNoScans() > 0); theActionManager.get("zoomnone").setEnabled(theDocument.getNoScans() > 0); theActionManager.get("zoomin").setEnabled(theDocument.getNoScans() > 0); theActionManager.get("zoomout").setEnabled(theDocument.getNoScans() > 0); theActionManager.get("addpeaks").setEnabled(selected_peaks.size() > 0); theActionManager.get("annotatepeaks").setEnabled(selected_peaks.size() > 0); theActionManager.get("baselinecorrection").setEnabled(theDocument.getNoScans() != 0); theActionManager.get("noisefilter").setEnabled(theDocument.getNoScans() != 0); theActionManager.get("centroid").setEnabled(theDocument.getNoScans() != 0); updateMsLevel(); } protected void updateData() { } private JToolBar createToolBar() { JToolBar toolbar = new JToolBar(); toolbar.setFloatable(false); toolbar.add(theActionManager.get("previous")); toolbar.add(theActionManager.get("close")); toolbar.add(theActionManager.get("next")); toolbar.addSeparator(); toolbar.add(theActionManager.get("new")); toolbar.add(theActionManager.get("openspectra")); toolbar.add(theActionManager.get("edit")); toolbar.addSeparator(); toolbar.add(theActionManager.get("print")); toolbar.addSeparator(); toolbar.add(theActionManager.get("arrow")); toolbar.add(theActionManager.get("hand")); toolbar.addSeparator(); toolbar.add(theActionManager.get("zoomnone")); toolbar.add(theActionManager.get("zoomin")); toolbar.add(theActionManager.get("zoomout")); toolbar.addSeparator(); toolbar.add(mslevel_button = new JButton(theActionManager.get("mslevel=msms"))); mslevel_button.setText(null); toolbar.add(theActionManager.get("addpeaks")); toolbar.add(theActionManager.get("annotatepeaks")); toolbar.addSeparator(); toolbar.add(theActionManager.get("noisefilter")); toolbar.add(theActionManager.get("baselinecorrection")); toolbar.add(theActionManager.get("centroid")); toolbar.add(isotopes_button = new JButton(theActionManager.get("updateisotopecurves=false"))); isotopes_button.setText(null); toolbar.add(ftmode_button = new JButton(theActionManager.get("showallisotopes=true"))); ftmode_button.setText(null); return toolbar; } private JPopupMenu createPopupMenu(boolean over_peak) { JPopupMenu menu = new JPopupMenu(); if (over_peak) { updatePeakActions(); menu.add(theActionManager.get("addpeaks")); ButtonGroup group = new ButtonGroup(); if (shown_mslevel.equals("ms")) { for (GlycanAction a : theApplication.getPluginManager().getMsPeakActions()) { JRadioButtonMenuItem last = new JRadioButtonMenuItem( new GlycanAction(a, "annotatepeaks", -1, "", this)); menu.add(last); last.setSelected(a == ms_action); group.add(last); } } else { for (GlycanAction a : theApplication.getPluginManager().getMsMsPeakActions()) { JRadioButtonMenuItem last = new JRadioButtonMenuItem( new GlycanAction(a, "annotatepeaks", -1, "", this)); menu.add(last); last.setSelected(a == msms_action); group.add(last); } } menu.addSeparator(); } menu.add(theActionManager.get("zoomnone")); menu.add(theActionManager.get("zoomin")); menu.add(theActionManager.get("zoomout")); return menu; } //----------- // Visualization public double screenToDataX(double length) { Rectangle2D data_area = theChartPanel.getScreenDataArea(); double mz_unit = thePlot.getDomainAxis().lengthToJava2D(1., data_area, thePlot.getDomainAxisEdge()); return length / mz_unit; } public double screenToDataY(double length) { Rectangle2D data_area = theChartPanel.getScreenDataArea(); double int_unit = thePlot.getRangeAxis().lengthToJava2D(1., data_area, thePlot.getRangeAxisEdge()); return length / int_unit; } public Point2D screenToDataCoords(Point2D p) { Rectangle2D data_area = theChartPanel.getScreenDataArea(); double x = thePlot.getDomainAxis().java2DToValue(p.getX(), data_area, thePlot.getDomainAxisEdge()); double y = thePlot.getRangeAxis().java2DToValue(p.getY(), data_area, thePlot.getRangeAxisEdge()); return new Point2D.Double(x, y); } public double screenToDataCoordX(double x) { Rectangle2D data_area = theChartPanel.getScreenDataArea(); return thePlot.getDomainAxis().java2DToValue(x, data_area, thePlot.getDomainAxisEdge()); } public double screenToDataCoordY(double y) { Rectangle2D data_area = theChartPanel.getScreenDataArea(); return thePlot.getRangeAxis().java2DToValue(y, data_area, thePlot.getRangeAxisEdge()); } public void updateMZAxis() { if (theDocument.getNoScans() > 0) thePlot.getDomainAxis().setRange(theDocument.getPeakDataAt(current_ind).getMZRange()); else thePlot.getDomainAxis().setRange(new Range(0., 1.)); } public void updateIntensityAxis() { double max_int = 0.; for (int d = 0; d < thePlot.getDatasetCount(); d++) { XYDataset dataset = thePlot.getDataset(d); for (int s = 0; s < dataset.getSeriesCount(); s++) for (int i = 0; i < dataset.getItemCount(s); i++) max_int = Math.max(max_int, dataset.getYValue(s, i)); } if (max_int == 0.) { // no data return; } Range new_int_range = new Range(0., max_int); // make space for annotations Rectangle2D data_area = theChartPanel.getScreenDataArea(); if (data_area.getHeight() > 0) new_int_range = Range.expand(new_int_range, 0., 12. / data_area.getHeight()); thePlot.getRangeAxis().setRange(new_int_range); } public void updateChart() { // auto zoom if (theDocument.getNoScans() > 0) { Range mz_range = thePlot.getDomainAxis().getRange(); // update data double mz_toll = screenToDataX(1.); double[][] data = theDocument.getPeakDataAt(current_ind).getData(mz_range, mz_toll); // update visible data and compute intensity range visibleData.clear(); double min_int = (data[0].length > 0) ? data[1][0] : 0.; double max_int = (data[0].length > 0) ? data[1][0] : 0.; for (int i = 0; i < data[0].length; i++) { min_int = Math.min(min_int, data[1][i]); max_int = Math.max(max_int, data[1][i]); visibleData.put(data[0][i], data[1][i]); } //Range new_int_range = new Range(min_int,max_int); Range new_int_range = new Range(0., max_int); // make space for annotations Rectangle2D data_area = theChartPanel.getScreenDataArea(); if (data_area.getHeight() > 0) new_int_range = Range.expand(new_int_range, 0., 12. / data_area.getHeight()); // resize y axis thePlot.getRangeAxis().setRange(new_int_range); // reload dataset //theDataset.removeSeries("intensities"); theDataset.addSeries("intensities", data); /* for( int i=0; i<theDataset.getSeriesCount(); i++ ) { if( theDataset.getSeriesKey(i).equals("intensities") ) thePlot.getRenderer().setSeriesPaint(i,Color.red); else thePlot.getRenderer().setSeriesPaint(i,Color.blue); } */ } else { thePlot.getRangeAxis().setRange(new Range(0., 1.)); for (int i = 0; i < theDataset.getSeriesCount(); i++) theDataset.removeSeries(theDataset.getSeriesKey(i)); } // restore annotation shapes showSelection(); } public void updateTitle() { if (theDocument.getNoScans() > 0) { String title = "Spectrum " + theDocument.getScanNum(current_ind) + "/" + theDocument.getNoScans(); int ms_level; if (shown_mslevel.equals("ms")) ms_level = 1; else { ms_level = theDocument.getScanDataAt(current_ind).getMSLevel(); if (ms_level == 1) ms_level = 2; } if (ms_level == 1) title += ", MS"; else if (ms_level == 2) title += ", MS/MS"; else if (ms_level > 2) title += ", MS" + ms_level; if (ms_level > 1) title += ", precursor= " + new java.text.DecimalFormat("0.0000") .format(theDocument.getScanDataAt(current_ind).getPrecursorMZ()) + " Da"; theChart.setTitle(title); } else { theChart.setTitle("Spectrum"); } } public void updateMsLevel() { if (theWorkspace.getCurrentScan() != null) onSetMsLevel(theWorkspace.getCurrentScan().isMsMs() ? "msms" : "ms", false); else onSetMsLevel("msms", false); } public void updateView() { current_ind = Math.max(0, Math.min(current_ind, theDocument.getNoScans() - 1)); // clear selection resetSelection(); // update title updateMZAxis(); updateChart(); updateTitle(); } //-------------- // manage selection private Peak findNearestPeak(double mz, double intensity, double mz_toll, double int_toll) { java.util.SortedMap<Double, Double> submap = visibleData.subMap(mz - mz_toll, mz + mz_toll); Peak found = null; double min_diff = 0.; for (Map.Entry<Double, Double> e : submap.entrySet()) { double diff = Math.abs(e.getValue() - intensity); if (diff <= int_toll) { if (found == null || diff < min_diff) found = new Peak(e.getKey(), e.getValue()); } } return found; } public Peak findPeakAt(Point2D p) { if (theDocument.getNoScans() > 0) { Point2D dp = screenToDataCoords(p); double mz_toll = screenToDataX(3.); double int_toll = screenToDataY(3.); return findNearestPeak(dp.getX(), dp.getY(), mz_toll, int_toll); } return null; } public boolean hasSelection() { return (selected_peaks.size() > 0); } public boolean isSelected(Peak peak) { return (peak == null) ? false : selected_peaks.contains(peak); } public void resetSelection() { current_peak = null; selected_peaks.clear(); fireUpdatedSelection(); } public void setSelection(Peak peak) { if (peak != null) { selected_peaks.clear(); selected_peaks.add(peak); current_peak = peak; fireUpdatedSelection(); } else resetSelection(); } public void addSelection(Peak peak) { if (peak != null) { if (!isSelected(peak)) selected_peaks.add(peak); else current_peak = peak; fireUpdatedSelection(); } } public void enforceSelection(Peak peak) { if (peak != null) { if (!isSelected(peak)) setSelection(peak); else { current_peak = peak; fireUpdatedSelection(); } } else resetSelection(); } private void showSelection() { thePlot.clearAnnotations(); if (selected_peaks.size() > 0) { double width = screenToDataX(6.); double height = screenToDataY(6.); double margin = screenToDataY(8.); for (Peak p : selected_peaks) { // add annotation Shape shape = new Rectangle2D.Double(p.getMZ() - width / 2., p.getIntensity() - height / 2., width, height); if (p.equals(current_peak)) { thePlot.addAnnotation(new XYShapeAnnotation(shape, new BasicStroke(2.f), Color.blue)); thePlot.addAnnotation( new XYTextAnnotation(new java.text.DecimalFormat("0.0000").format(p.getMZ()), p.getMZ(), p.getIntensity() + margin)); } else thePlot.addAnnotation(new XYShapeAnnotation(shape, new BasicStroke(1.f), Color.black)); } } } //----------------- // actions public int getCurrentInd() { return current_ind; } public void closeCurrent() { if (theDocument.getNoScans() > 0) { int old_ind = current_ind; current_ind = Math.min(current_ind, theDocument.getNoScans() - 2); current_ind = Math.max(current_ind, 0); theDocument.removeScan(old_ind); updateActions(); updateView(); } } public void showPrevious() { if (theDocument.getNoScans() > 0 && current_ind > 0) { current_ind--; updateView(); } } public void showNext() { if (theDocument.getNoScans() > 0 && current_ind < (theDocument.getNoScans() - 1)) { current_ind++; updateView(); } } public void showScan(int s_ind) { if (s_ind >= 0 && s_ind < theDocument.getNoScans()) { current_ind = s_ind; updateView(); } } public void onEditScanData() { if (theDocument.getNoScans() > 0) new ScanDataPropertiesDialog(theApplication, theDocument.getScanDataAt(current_ind), theWorkspace) .setVisible(true); } public void onPrint() { PrinterJob pj = theWorkspace.getPrinterJob(); if (pj == null) return; try { pj.setPrintable(theChartPanel); if (pj.printDialog()) pj.print(); } catch (Exception e) { LogUtils.report(e); } } public void onActivateZooming() { is_moving = false; theChartPanel.setCursor(Cursor.getDefaultCursor()); } public void onActivateMoving() { is_moving = true; //theChartPanel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); theChartPanel.setCursor(hand_cursor); } public void onZoomNone() { if (theDocument.getNoScans() > 0) thePlot.getDomainAxis().setRange(theDocument.getPeakDataAt(current_ind).getMZRange()); } public void onZoomIn() { if (theDocument.getNoScans() > 0) thePlot.getDomainAxis().resizeRange(0.5); } public void onZoomOut() { if (theDocument.getNoScans() > 0) { thePlot.getDomainAxis().resizeRange(2.0); if (thePlot.getDomainAxis().getRange().contains(theDocument.getPeakDataAt(current_ind).getMinMZ()) || thePlot.getDomainAxis().getRange() .contains(theDocument.getPeakDataAt(current_ind).getMaxMZ())) thePlot.getDomainAxis().setRange(theDocument.getPeakDataAt(current_ind).getMZRange()); } } public void onSetMsLevel(String mslevel, boolean changedoc) { shown_mslevel = mslevel; if (mslevel.equals("ms")) { mslevel_button.setAction(theActionManager.get("mslevel=msms")); mslevel_button.setText(null); if (changedoc) theWorkspace.setMsMs(theWorkspace.getCurrentScan(), false); } else { mslevel_button.setAction(theActionManager.get("mslevel=ms")); mslevel_button.setText(null); if (changedoc) theWorkspace.setMsMs(theWorkspace.getCurrentScan(), true); } updateTitle(); } public void onSetUpdateIsotopeCurves(Boolean f) { automatic_update_isotope_curves = f; if (automatic_update_isotope_curves) isotopes_button.setAction(theActionManager.get("updateisotopecurves=false")); else isotopes_button.setAction(theActionManager.get("updateisotopecurves=true")); isotopes_button.setText(null); } public void onSetShowAllIsotopes(Boolean f) { show_all_isotopes = f; if (show_all_isotopes) ftmode_button.setAction(theActionManager.get("showallisotopes=false")); else ftmode_button.setAction(theActionManager.get("showallisotopes=true")); ftmode_button.setText(null); } public boolean onAddPeaks() { try { if (selected_peaks.size() > 0) { // add selected peaks to list theApplication.getWorkspace().getPeakList().mergeData(selected_peaks); theApplication.getPluginManager().show("PeakList", "PeakList"); return true; } return false; } catch (Exception e) { LogUtils.report(e); return false; } } public boolean onAnnotatePeaks(String parent_action) { try { if (selected_peaks.size() > 0) { updatePeakActions(); if (shown_mslevel.equals("ms")) { if (parent_action != null) ms_action = theApplication.getPluginManager().getMsPeakAction(parent_action); if (theApplication.getPluginManager().runAction(ms_action, new PeakList(selected_peaks))) { update_isotope_curves = automatic_update_isotope_curves; return true; } return false; } if (parent_action != null) msms_action = theApplication.getPluginManager().getMsMsPeakAction(parent_action); if (theApplication.getPluginManager().runAction(msms_action, new PeakList(selected_peaks))) { update_isotope_curves = automatic_update_isotope_curves; return true; } return false; } return false; } catch (Exception e) { LogUtils.report(e); return false; } } private void removeIsotopeCurves() { while (theIsotopesDataset.getSeriesCount() > 0) theIsotopesDataset.removeSeries(theIsotopesDataset.getSeriesKey(0)); } private void updateIsotopeCurves() { update_isotope_curves = false; TreeMap<Peak, Collection<Annotation>> map = new TreeMap<Peak, Collection<Annotation>>(); for (PeakAnnotationMultiple pam : theSearchResults.getAnnotations()) { if (map.get(pam.getPeak()) == null) map.put(pam.getPeak(), new Vector<Annotation>()); Collection<Annotation> dest = map.get(pam.getPeak()); for (Vector<Annotation> va : pam.getAnnotations()) dest.addAll(va); } addIsotopeCurves(map); } public void addIsotopeCurves(TreeMap<Peak, Collection<Annotation>> annotations) { if (theDocument.size() == 0) return; // remove old curves removeIsotopeCurves(); // add curves if (annotations != null) { // set renderer if (show_all_isotopes) { thePlot.setRenderer(1, new StandardXYItemRenderer(StandardXYItemRenderer.SHAPES)); thePlot.getRenderer(1).setShape(new Ellipse2D.Double(0, 0, 7, 7)); } else thePlot.setRenderer(1, new StandardXYItemRenderer(StandardXYItemRenderer.LINES)); MSUtils.IsotopeList isotope_list = new MSUtils.IsotopeList(show_all_isotopes); for (Map.Entry<Peak, Collection<Annotation>> pa : annotations.entrySet()) { Peak p = pa.getKey(); double[] best_peak = theDocument.getPeakDataAt(current_ind).findNearestPeak(p.getMZ()); // get compositions HashSet<Molecule> compositions = new HashSet<Molecule>(); for (Annotation a : pa.getValue()) { try { compositions.add(a.getFragmentEntry().fragment.computeIon()); } catch (Exception e) { e.printStackTrace(); } } // collect curves for this peak HashMap<String, double[][]> all_curves = new HashMap<String, double[][]>(); for (Molecule m : compositions) { try { double[][] data = MSUtils.getIsotopesCurve(1, m, show_all_isotopes); // overlay the distribution with the existing list of isotopes isotope_list.adjust(data, best_peak[0], best_peak[1]); all_curves.put(m.toString(), data); } catch (Exception e) { LogUtils.report(e); } } // add average curve for this peak if (all_curves.size() > 1) { double[][] data = MSUtils.average(all_curves.values(), show_all_isotopes); // add the average to the chart String name = "average-" + p.getMZ(); theIsotopesDataset.addSeries(name, data); thePlot.getRenderer(1).setSeriesPaint(theIsotopesDataset.indexOf(name), Color.magenta); thePlot.getRenderer(1).setSeriesStroke(theIsotopesDataset.indexOf(name), new BasicStroke(2)); // add the average to the isotope list isotope_list.add(data, false); } else if (all_curves.size() == 1) { // add the only curve to the isotope list isotope_list.add(all_curves.values().iterator().next(), false); } // add the other curves for (Map.Entry<String, double[][]> e : all_curves.entrySet()) { String name = e.getKey() + "-" + p.getMZ(); theIsotopesDataset.addSeries(name, e.getValue()); thePlot.getRenderer(1).setSeriesPaint(theIsotopesDataset.indexOf(name), Color.blue); } } } updateIntensityAxis(); } public void noiseFilter() { theDocument.noiseFilter(current_ind); } public void baselineCorrection() { theDocument.baselineCorrection(current_ind); } public void computeCentroids() { ((SpectraPlugin) theApplication.getPluginManager().get("Spectra")).computeCentroids(current_ind); } //----------- // listeners public void addSelectionChangeListener(SelectionChangeListener l) { if (l != null) listeners.add(l); } public void removeSelectionChangeListener(SelectionChangeListener l) { if (l != null) listeners.remove(l); } public void fireUpdatedSelection() { for (SelectionChangeListener l : listeners) l.selectionChanged(new SelectionChangeEvent(this)); removeIsotopeCurves(); updateIntensityAxis(); showSelection(); updateActions(); } public void actionPerformed(ActionEvent e) { String action = GlycanAction.getAction(e); String param = GlycanAction.getParam(e); if (action.equals("previous")) showPrevious(); else if (action.equals("next")) showNext(); else if (action.equals("close")) closeCurrent(); else if (action.equals("new")) theApplication.onNew(theDocument); else if (action.equals("openspectra")) theApplication.onOpen(null, theDocument, false); else if (action.equals("edit")) onEditScanData(); else if (action.equals("print")) onPrint(); else if (action.equals("arrow")) onActivateZooming(); else if (action.equals("hand")) onActivateMoving(); else if (action.equals("zoomnone")) onZoomNone(); else if (action.equals("zoomin")) onZoomIn(); else if (action.equals("zoomout")) onZoomOut(); else if (action.equals("mslevel")) onSetMsLevel(param, true); else if (action.equals("addpeaks")) onAddPeaks(); else if (action.equals("annotatepeaks")) onAnnotatePeaks(param); else if (action.equals("updateisotopecurves")) onSetUpdateIsotopeCurves(Boolean.valueOf(param)); else if (action.equals("showallisotopes")) onSetShowAllIsotopes(Boolean.valueOf(param)); else if (action.equals("noisefilter")) noiseFilter(); else if (action.equals("baselinecorrection")) baselineCorrection(); else if (action.equals("centroid")) computeCentroids(); updateActions(); } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed(MouseEvent e) { if (MouseUtils.isPopupTrigger(e)) { // open popup current_peak = findPeakAt(e.getPoint()); enforceSelection(current_peak); createPopupMenu(current_peak != null).show(theChartPanel, e.getX(), e.getY()); } else { was_moving = is_moving; if ((MouseUtils.isPushTrigger(e) || MouseUtils.isMoveTrigger(e)) && theChartPanel.getScreenDataArea().contains(e.getPoint())) { mouse_start_point = e.getPoint(); if (MouseUtils.isMoveTrigger(e)) onActivateMoving(); } } } public void mouseMoved(MouseEvent e) { } public void mouseDragged(MouseEvent e) { if (mouse_start_point != null && theDocument.getNoScans() > 0) { if (is_moving) { // moving double mz_delta = screenToDataX(mouse_start_point.getX() - e.getPoint().getX()); if (mz_delta > 0.) { double old_upper_bound = thePlot.getDomainAxis().getUpperBound(); double old_lower_bound = thePlot.getDomainAxis().getLowerBound(); double new_upper_bound = Math.min(old_upper_bound + mz_delta, theDocument.getPeakDataAt(current_ind).getMaxMZ()); double new_lower_bound = old_lower_bound + new_upper_bound - old_upper_bound; thePlot.getDomainAxis().setRange(new Range(new_lower_bound, new_upper_bound)); } else { double old_upper_bound = thePlot.getDomainAxis().getUpperBound(); double old_lower_bound = thePlot.getDomainAxis().getLowerBound(); double new_lower_bound = Math.max(old_lower_bound + mz_delta, theDocument.getPeakDataAt(current_ind).getMinMZ()); double new_upper_bound = old_upper_bound + new_lower_bound - old_lower_bound; thePlot.getDomainAxis().setRange(new Range(new_lower_bound, new_upper_bound)); } mouse_start_point = e.getPoint(); } else { // zooming Graphics2D g2 = (Graphics2D) theChartPanel.getGraphics(); g2.setXORMode(java.awt.Color.gray); // delete old rectangle if (zoom_rectangle != null) g2.draw(zoom_rectangle); // create new rectangle double start_x = Math.min(e.getX(), mouse_start_point.getX()); double end_x = Math.max(e.getX(), mouse_start_point.getX()); Rectangle2D data_area = theChartPanel.getScreenDataArea((int) start_x, (int) mouse_start_point.getY()); double xmax = Math.min(end_x, data_area.getMaxX()); zoom_rectangle = new Rectangle2D.Double(start_x, data_area.getMinY(), xmax - start_x, data_area.getHeight()); // draw new rectangle g2.draw(zoom_rectangle); g2.dispose(); } } } public void mouseReleased(MouseEvent e) { if (MouseUtils.isPopupTrigger(e)) { // clear all if (zoom_rectangle != null) { Graphics2D g2 = (Graphics2D) getGraphics(); g2.setXORMode(java.awt.Color.gray); g2.draw(zoom_rectangle); g2.dispose(); } mouse_start_point = null; zoom_rectangle = null; // open popup current_peak = findPeakAt(e.getPoint()); enforceSelection(current_peak); createPopupMenu(current_peak != null).show(theChartPanel, e.getX(), e.getY()); } else { if (zoom_rectangle != null && mouse_start_point != null) { if (Math.abs(e.getX() - mouse_start_point.getX()) > 10) { //if( e.getX() < mouse_start_point.getX() ) { // unzoom all // onZoomNone(); //} //else { // zoom area double start_x = Math.min(e.getX(), mouse_start_point.getX()); double end_x = Math.max(e.getX(), mouse_start_point.getX()); Rectangle2D data_area = theChartPanel.getScreenDataArea((int) start_x, (int) mouse_start_point.getY()); double new_lower_bound = screenToDataCoordX(start_x); double new_upper_bound = screenToDataCoordX(Math.min(end_x, data_area.getMaxX())); thePlot.getDomainAxis().setRange(new Range(new_lower_bound, new_upper_bound)); } else { // clear rectangle Graphics2D g2 = (Graphics2D) getGraphics(); g2.setXORMode(java.awt.Color.gray); g2.draw(zoom_rectangle); g2.dispose(); } } // restore zooming if (!was_moving && is_moving) onActivateZooming(); zoom_rectangle = null; mouse_start_point = null; } } public void mouseClicked(MouseEvent e) { // find peak under mouse current_peak = findPeakAt(e.getPoint()); if (MouseUtils.isSelectTrigger(e)) setSelection(current_peak); else if (MouseUtils.isAddSelectTrigger(e)) addSelection(current_peak); else if (MouseUtils.isActionTrigger(e)) { setSelection(current_peak); onAnnotatePeaks(null); } else if (MouseUtils.isCtrlActionTrigger(e)) { setSelection(current_peak); onAddPeaks(); } } public void documentChanged(BaseDocument.DocumentChangeEvent e) { if (e.getSource() == theWorkspace.getSearchResults()) { if (update_isotope_curves) updateIsotopeCurves(); } else { removeIsotopeCurves(); super.documentChanged(e); } } public void internalDocumentChanged(GlycanWorkspace.Event e) { updateMsLevel(); } public void componentResized(ComponentEvent e) { if (!checkForUpdates()) updateChart(); } public void componentShown(ComponentEvent e) { if (!checkForUpdates()) updateChart(); } }