net.sf.mzmine.util.components.PeakSummaryComponent.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.mzmine.util.components.PeakSummaryComponent.java

Source

/*
 * Copyright 2006-2015 The MZmine 2 Development Team
 * 
 * This file is part of MZmine 2.
 * 
 * MZmine 2 is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 * 
 * MZmine 2 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * MZmine 2; if not, write to the Free Software Foundation, Inc., 51 Franklin
 * St, Fifth Floor, Boston, MA 02110-1301 USA
 */

package net.sf.mzmine.util.components;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DecimalFormat;
import java.text.Format;
import java.util.HashMap;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;

import net.sf.mzmine.datamodel.Feature;
import net.sf.mzmine.datamodel.IsotopePattern;
import net.sf.mzmine.datamodel.PeakIdentity;
import net.sf.mzmine.datamodel.PeakListRow;
import net.sf.mzmine.datamodel.RawDataFile;
import net.sf.mzmine.main.MZmineCore;
import net.sf.mzmine.modules.rawdatamethods.peakpicking.manual.ManualPeakPickerModule;
import net.sf.mzmine.modules.visualization.spectra.SpectraVisualizerModule;
import net.sf.mzmine.modules.visualization.threed.ThreeDVisualizerModule;
import net.sf.mzmine.modules.visualization.tic.TICPlotType;
import net.sf.mzmine.modules.visualization.tic.TICVisualizerModule;
import net.sf.mzmine.modules.visualization.twod.TwoDVisualizerModule;
import net.sf.mzmine.parameters.parametertypes.selectors.ScanSelection;

import com.google.common.collect.Range;

public class PeakSummaryComponent extends JPanel implements ActionListener {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    private static final DecimalFormat formatter = new DecimalFormat("###.#");

    private static final Font defaultFont = new Font("SansSerif", Font.PLAIN, 11);
    private static final Font titleFont = new Font("SansSerif", Font.BOLD, 14);
    private static final Font ratioFont = new Font("SansSerif", Font.PLAIN, 18);

    private static final Dimension xicPreferredSize = new Dimension(350, 70);

    private JButton btnChange, btnShow;
    private JComboBox<String> comboShow;
    private JLabel ratio;

    private PeakSummaryTableModel listElementModel;
    private JTable peaksInfoList;

    private PeakListRow row;

    private static String[] visualizers = { "Chromatogram", "Mass spectrum", "Peak in 2D", "Peak in 3D", "MS/MS",
            "Isotope pattern" };

    private Color bg = new Color(255, 250, 205); // default color

    public PeakSummaryComponent(PeakListRow row, boolean headerVisible, boolean ratioVisible, boolean graphVisible,
            boolean tableVisible, boolean buttonsVisible, Color backgroundColor) {
        this(row, row.getRawDataFiles(), headerVisible, ratioVisible, graphVisible, tableVisible, buttonsVisible,
                backgroundColor);
    }

    /**
     * @param index
     * @param dataSet
     * @param fold
     * @param frame
     */
    public PeakSummaryComponent(PeakListRow row, RawDataFile[] rawDataFiles, boolean headerVisible,
            boolean ratioVisible, boolean graphVisible, boolean tableVisible, boolean buttonsVisible,
            Color backgroundColor) {

        if (backgroundColor != null) {
            bg = backgroundColor;
        }

        setBackground(bg);

        this.row = row;

        // Get info
        Feature[] peaks = new Feature[rawDataFiles.length];
        for (int i = 0; i < peaks.length; i++) {
            peaks[i] = row.getPeak(rawDataFiles[i]);
        }

        PeakIdentity identity = row.getPreferredPeakIdentity();

        // General container
        JPanel pnlAll = new JPanel(new BorderLayout());
        pnlAll.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
        pnlAll.setBackground(bg);

        // Header peak identification & ratio
        JPanel headerPanel = new JPanel();
        headerPanel.setLayout(new BoxLayout(headerPanel, BoxLayout.Y_AXIS));
        JLabel name, info;
        if (identity != null) {
            name = new JLabel(identity.getName(), SwingUtilities.LEFT);
            StringBuffer buf = new StringBuffer();
            Format mzFormat = MZmineCore.getConfiguration().getMZFormat();
            Format timeFormat = MZmineCore.getConfiguration().getRTFormat();
            buf.append("#" + row.getID() + " ");
            buf.append(mzFormat.format(row.getAverageMZ()));
            buf.append(" m/z @");
            buf.append(timeFormat.format(row.getAverageRT()));
            info = new JLabel(buf.toString(), SwingUtilities.LEFT);
            info.setBackground(bg);
            info.setFont(defaultFont);
            headerPanel.add(name, BorderLayout.NORTH);
            headerPanel.add(info, BorderLayout.CENTER);
        } else {
            name = new JLabel(row.toString(), SwingUtilities.LEFT);
            headerPanel.add(name, BorderLayout.CENTER);
        }

        name.setFont(titleFont);
        name.setBackground(bg);
        headerPanel.setBackground(bg);
        headerPanel.setPreferredSize(new Dimension(290, 50));
        headerPanel.setVisible(headerVisible);

        // Ratio between peaks
        JPanel ratioPanel = new JPanel(new BorderLayout());
        ratio = new JLabel("", SwingUtilities.LEFT);
        ratio.setFont(ratioFont);

        ratio.setBackground(bg);
        ratioPanel.add(ratio, BorderLayout.CENTER);

        ratioPanel.setBackground(bg);
        ratioPanel.setVisible(ratioVisible);

        JPanel headerAndRatioPanel = new JPanel(new BorderLayout());
        headerAndRatioPanel.add(headerPanel, BorderLayout.WEST);
        headerAndRatioPanel.add(Box.createVerticalGlue(), BorderLayout.CENTER);
        headerAndRatioPanel.add(ratioPanel, BorderLayout.EAST);
        headerAndRatioPanel.setBackground(bg);
        pnlAll.add(headerAndRatioPanel, BorderLayout.NORTH);
        // <-

        // Plot section
        JPanel plotPanel = new JPanel();
        plotPanel.setLayout(new BoxLayout(plotPanel, BoxLayout.Y_AXIS));
        Border one = BorderFactory.createEtchedBorder(EtchedBorder.RAISED);
        Border two = BorderFactory.createEmptyBorder(5, 5, 5, 5);
        plotPanel.setBorder(BorderFactory.createCompoundBorder(one, two));
        plotPanel.setBackground(Color.white);
        // No tooltip
        CombinedXICComponent xic = new CombinedXICComponent(peaks, -1);
        xic.setPreferredSize(xicPreferredSize);
        plotPanel.add(xic);
        plotPanel.setVisible(graphVisible);
        pnlAll.add(plotPanel, BorderLayout.CENTER);
        // <-

        // Table with peak's information
        JPanel tablePanel = new JPanel();
        tablePanel.setLayout(new BoxLayout(tablePanel, BoxLayout.Y_AXIS));
        tablePanel.setBackground(bg);

        listElementModel = new PeakSummaryTableModel();
        peaksInfoList = new JTable();
        peaksInfoList.setModel(listElementModel);
        peaksInfoList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        peaksInfoList.setDefaultRenderer(Object.class, new PeakSummaryTableCellRenderer());

        int colorIndex = 0;
        Color peakColor;

        for (Feature peak : peaks) {
            // set color for current XIC
            if (peak != null) {
                peakColor = CombinedXICComponent.plotColors[colorIndex];
                listElementModel.addElement(peak, peakColor);
            }
            colorIndex = (colorIndex + 1) % CombinedXICComponent.plotColors.length;
        }

        JPanel listPanel = new JPanel(new BorderLayout());
        listPanel.add(new JScrollPane(peaksInfoList), BorderLayout.CENTER);
        listPanel.add(peaksInfoList.getTableHeader(), BorderLayout.NORTH);
        listPanel.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));

        Dimension d = calculatedTableDimension(peaksInfoList);
        listPanel.setPreferredSize(d);

        tablePanel.add(Box.createVerticalStrut(5));
        tablePanel.add(listPanel, BorderLayout.CENTER);
        tablePanel.setBackground(bg);
        tablePanel.setVisible(tableVisible);

        // Buttons
        comboShow = new JComboBox<String>(visualizers);

        btnShow = new JButton("Show");
        btnShow.setActionCommand("SHOW");
        btnShow.addActionListener(this);

        btnChange = new JButton("Change");
        btnChange.setActionCommand("CHANGE");
        btnChange.addActionListener(this);

        JPanel pnlShow = new JPanel(new BorderLayout());
        pnlShow.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));

        pnlShow.add(comboShow, BorderLayout.NORTH);
        pnlShow.add(btnShow, BorderLayout.CENTER);
        pnlShow.setBackground(bg);

        JPanel buttonsPanel = new JPanel(new BorderLayout());
        buttonsPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        buttonsPanel.add(pnlShow, BorderLayout.NORTH);
        buttonsPanel.add(Box.createVerticalGlue(), BorderLayout.CENTER);
        buttonsPanel.add(btnChange, BorderLayout.SOUTH);
        buttonsPanel.setBackground(bg);
        buttonsPanel.setVisible(buttonsVisible);

        JPanel buttonsAndTablePanel = new JPanel(new BorderLayout());
        buttonsAndTablePanel.add(tablePanel, BorderLayout.CENTER);
        buttonsAndTablePanel.add(buttonsPanel, BorderLayout.EAST);
        buttonsAndTablePanel.setBackground(bg);

        pnlAll.add(buttonsAndTablePanel, BorderLayout.SOUTH);
        setLayout(new BorderLayout());
        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        add(pnlAll, BorderLayout.CENTER);

    }

    public void setRatio(double area1, double area2) {
        String text;
        Color ratioColor;
        if (area1 > area2) {
            text = formatter.format(area1 / area2) + "x";
            ratioColor = CombinedXICComponent.plotColors[0];
        } else {
            text = formatter.format(area2 / area1) + "x";
            ratioColor = CombinedXICComponent.plotColors[1];
        }
        ratio.setForeground(ratioColor);
        ratio.setText(text);
    }

    /**
     * @param peaksInfoList
     * @return
     */
    private Dimension calculatedTableDimension(JTable peaksInfoList) {

        int numRows = peaksInfoList.getRowCount();
        int numCols = peaksInfoList.getColumnCount();
        int maxWidth = 0, compWidth, totalWidth = 0, totalHeight = 0;
        TableCellRenderer renderer = peaksInfoList.getDefaultRenderer(Object.class);
        TableCellRenderer headerRenderer = peaksInfoList.getTableHeader().getDefaultRenderer();
        TableModel model = peaksInfoList.getModel();
        Component comp;
        TableColumn column;

        for (int c = 0; c < numCols; c++) {
            for (int r = 0; r < numRows; r++) {

                if (r == 0) {
                    comp = headerRenderer.getTableCellRendererComponent(peaksInfoList, model.getColumnName(c),
                            false, false, r, c);
                    compWidth = comp.getPreferredSize().width + 10;
                    maxWidth = Math.max(maxWidth, compWidth);

                }

                comp = renderer.getTableCellRendererComponent(peaksInfoList, model.getValueAt(r, c), false, false,
                        r, c);

                compWidth = comp.getPreferredSize().width + 10;
                maxWidth = Math.max(maxWidth, compWidth);

                if (c == 0) {
                    totalHeight += comp.getPreferredSize().height;
                }

                // Consider max 10 rows
                if (r == 8) {
                    break;
                }

            }
            totalWidth += maxWidth;
            column = peaksInfoList.getColumnModel().getColumn(c);
            column.setPreferredWidth(maxWidth);
            maxWidth = 0;
        }

        // add 30x10 px for a scrollbar
        totalWidth += 30;
        totalHeight += 10;

        comp = headerRenderer.getTableCellRendererComponent(peaksInfoList, model.getColumnName(0), false, false, 0,
                0);
        totalHeight += comp.getPreferredSize().height;

        return new Dimension(totalWidth, totalHeight);

    }

    public void actionPerformed(ActionEvent e) {

        String command = e.getActionCommand();

        if (command.equals("SHOW")) {

            String visualizerType = (String) comboShow.getSelectedItem();
            int[] indexesRow = peaksInfoList.getSelectedRows();
            Feature[] selectedPeaks = new Feature[indexesRow.length];
            RawDataFile[] dataFiles = new RawDataFile[indexesRow.length];
            Range<Double> rtRange = null, mzRange = null;
            for (int i = 0; i < indexesRow.length; i++) {
                selectedPeaks[i] = listElementModel.getElementAt(indexesRow[i]);
                dataFiles[i] = selectedPeaks[i].getDataFile();

                if ((rtRange == null) || (mzRange == null)) {
                    rtRange = dataFiles[i].getDataRTRange(1);
                    mzRange = selectedPeaks[i].getRawDataPointsMZRange();
                } else {
                    rtRange = rtRange.span(dataFiles[i].getDataRTRange(1));
                    mzRange = mzRange.span(selectedPeaks[i].getRawDataPointsMZRange());
                }
            }

            if (dataFiles.length == 0) {
                return;
            }

            if (visualizerType.equals("Chromatogram")) {

                // Label best peak with preferred identity.
                final Feature bestPeak = row.getBestPeak();
                final PeakIdentity peakIdentity = row.getPreferredPeakIdentity();
                final Map<Feature, String> labelMap = new HashMap<Feature, String>(1);
                if (bestPeak != null && peakIdentity != null) {

                    labelMap.put(bestPeak, peakIdentity.getName());
                }

                ScanSelection scanSelection = new ScanSelection(rtRange, 1);

                TICVisualizerModule.showNewTICVisualizerWindow(dataFiles, selectedPeaks, labelMap, scanSelection,
                        TICPlotType.BASEPEAK, mzRange);
                return;

            } else if (visualizerType.equals("Mass spectrum")) {
                for (int i = 0; i < selectedPeaks.length; i++) {
                    SpectraVisualizerModule.showNewSpectrumWindow(dataFiles[i],
                            selectedPeaks[i].getRepresentativeScanNumber());
                }
            } else if (visualizerType.equals("Peak in 2D")) {
                for (int i = 0; i < selectedPeaks.length; i++) {
                    Range<Double> peakRTRange = selectedPeaks[i].getRawDataPointsRTRange();
                    Range<Double> peakMZRange = selectedPeaks[i].getRawDataPointsMZRange();
                    final double rtLen = peakRTRange.upperEndpoint() - peakRTRange.lowerEndpoint();
                    Range<Double> localRTRange = Range.closed(Math.max(0, peakRTRange.lowerEndpoint() - rtLen),
                            peakRTRange.upperEndpoint() + rtLen);

                    final double mzLen = peakMZRange.upperEndpoint() - peakMZRange.lowerEndpoint();
                    Range<Double> localMZRange = Range.closed(Math.max(0, peakMZRange.lowerEndpoint() - mzLen),
                            peakMZRange.upperEndpoint() + mzLen);
                    TwoDVisualizerModule.show2DVisualizerSetupDialog(dataFiles[i], localMZRange, localRTRange);
                }
            } else if (visualizerType.equals("Peak in 3D")) {
                for (int i = 0; i < selectedPeaks.length; i++) {
                    Range<Double> peakRTRange = selectedPeaks[i].getRawDataPointsRTRange();
                    Range<Double> peakMZRange = selectedPeaks[i].getRawDataPointsMZRange();
                    final double rtLen = peakRTRange.upperEndpoint() - peakRTRange.lowerEndpoint();
                    Range<Double> localRTRange = Range.closed(Math.max(0, peakRTRange.lowerEndpoint() - rtLen),
                            peakRTRange.upperEndpoint() + rtLen);
                    final double mzLen = peakMZRange.upperEndpoint() - peakMZRange.lowerEndpoint();
                    Range<Double> localMZRange = Range.closed(Math.max(0, peakMZRange.lowerEndpoint() - mzLen),
                            peakMZRange.upperEndpoint() + mzLen);
                    ThreeDVisualizerModule.setupNew3DVisualizer(dataFiles[i], localMZRange, localRTRange);
                }
            } else if (visualizerType.equals("MS/MS")) {
                for (int i = 0; i < selectedPeaks.length; i++) {
                    int scanNumber = selectedPeaks[i].getMostIntenseFragmentScanNumber();
                    if (scanNumber > 0) {
                        SpectraVisualizerModule.showNewSpectrumWindow(dataFiles[i], scanNumber);
                    } else {
                        JFrame frame = (JFrame) SwingUtilities.getAncestorOfClass(JFrame.class, this);
                        MZmineCore.getDesktop().displayMessage(frame, "There is no fragment for the mass "
                                + MZmineCore.getConfiguration().getMZFormat().format(selectedPeaks[i].getMZ())
                                + "m/z in the current raw data.");
                        return;
                    }
                }

            } else if (visualizerType.equals("Isotope pattern")) {
                for (int i = 0; i < selectedPeaks.length; i++) {
                    IsotopePattern ip = selectedPeaks[i].getIsotopePattern();
                    if (ip == null) {
                        return;
                    }
                    SpectraVisualizerModule.showNewSpectrumWindow(dataFiles[i],
                            selectedPeaks[i].getMostIntenseFragmentScanNumber(), ip);

                }
            }
            return;
        }

        if (command.equals("CHANGE")) {
            int indexRow = peaksInfoList.getSelectedRow();
            if (indexRow == -1) {
                return;
            }
            Feature selectedPeak = listElementModel.getElementAt(indexRow);
            ManualPeakPickerModule.runManualDetection(selectedPeak.getDataFile(), row, null, null);

            return;
        }

    }

}