diff --git a/src/main/icons/btnspectraprocessing.png b/src/main/icons/btnspectraprocessing.png new file mode 100644 index 000000000..474557ec5 Binary files /dev/null and b/src/main/icons/btnspectraprocessing.png differ diff --git a/src/main/java/net/sf/mzmine/main/MZmineModulesList.java b/src/main/java/net/sf/mzmine/main/MZmineModulesList.java index 50db51329..b96e28a17 100644 --- a/src/main/java/net/sf/mzmine/main/MZmineModulesList.java +++ b/src/main/java/net/sf/mzmine/main/MZmineModulesList.java @@ -121,6 +121,10 @@ import net.sf.mzmine.modules.visualization.scatterplot.ScatterPlotVisualizerModule; import net.sf.mzmine.modules.visualization.spectra.msms.MsMsVisualizerModule; import net.sf.mzmine.modules.visualization.spectra.simplespectra.SpectraVisualizerModule; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingManager; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.identification.sumformulaprediction.DPPSumFormulaPredictionModule; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.isotopes.deisotoper.DPPIsotopeGrouperModule; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.massdetection.DPPMassDetectionModule; import net.sf.mzmine.modules.visualization.spectra.simplespectra.spectraidentification.customdatabase.CustomDBSpectraSearchModule; import net.sf.mzmine.modules.visualization.spectra.simplespectra.spectraidentification.lipidsearch.LipidSpectraSearchModule; import net.sf.mzmine.modules.visualization.spectra.simplespectra.spectraidentification.onlinedatabase.OnlineDBSpectraSearchModule; @@ -214,7 +218,9 @@ public class MZmineModulesList { // all other regular MZmineRunnableModule (not MZmineProcessingModule) NOT LISTED IN MENU SpectraIdentificationSpectralDatabaseModule.class, LibrarySubmitModule.class, CustomDBSpectraSearchModule.class, LipidSpectraSearchModule.class, - OnlineDBSpectraSearchModule.class, SumFormulaSpectraSearchModule.class + OnlineDBSpectraSearchModule.class, SumFormulaSpectraSearchModule.class, + // Data point processing + DataPointProcessingManager.class, DPPMassDetectionModule.class, DPPSumFormulaPredictionModule.class, DPPIsotopeGrouperModule.class }; } diff --git a/src/main/java/net/sf/mzmine/modules/peaklistmethods/identification/lipididentification/LipidSearchTask.java b/src/main/java/net/sf/mzmine/modules/peaklistmethods/identification/lipididentification/LipidSearchTask.java index b58447454..4e3926bd1 100644 --- a/src/main/java/net/sf/mzmine/modules/peaklistmethods/identification/lipididentification/LipidSearchTask.java +++ b/src/main/java/net/sf/mzmine/modules/peaklistmethods/identification/lipididentification/LipidSearchTask.java @@ -251,12 +251,12 @@ private void searchMsmsFragments(PeakListRow row, double lipidIonMass, LipidIden massDetector = new CentroidMassDetector(); CentroidMassDetectorParameters parametersMSMS = new CentroidMassDetectorParameters(); CentroidMassDetectorParameters.noiseLevel.setValue(noiseLevelMSMS); - massList = massDetector.getMassValues(msmsScan, parametersMSMS); + massList = massDetector.getMassValues(msmsScan.getDataPoints(), parametersMSMS); } else { massDetector = new ExactMassDetector(); ExactMassDetectorParameters parametersMSMS = new ExactMassDetectorParameters(); ExactMassDetectorParameters.noiseLevel.setValue(noiseLevelMSMS); - massList = massDetector.getMassValues(msmsScan, parametersMSMS); + massList = massDetector.getMassValues(msmsScan.getDataPoints(), parametersMSMS); } } MSMSLipidTools msmsLipidTools = new MSMSLipidTools(); diff --git a/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/MassDetector.java b/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/MassDetector.java index 0a3c02832..c264dcf2c 100644 --- a/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/MassDetector.java +++ b/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/MassDetector.java @@ -31,6 +31,8 @@ public interface MassDetector extends MZmineModule { /** * Returns mass and intensity values detected in given scan */ + public DataPoint[] getMassValues(DataPoint[] dp, ParameterSet parameters); + public DataPoint[] getMassValues(Scan scan, ParameterSet parameters); } diff --git a/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/centroid/CentroidMassDetector.java b/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/centroid/CentroidMassDetector.java index e1f375cac..2954a0445 100644 --- a/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/centroid/CentroidMassDetector.java +++ b/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/centroid/CentroidMassDetector.java @@ -34,14 +34,16 @@ public class CentroidMassDetector implements MassDetector { public DataPoint[] getMassValues(Scan scan, ParameterSet parameters) { + return getMassValues(scan.getDataPoints(), parameters); + } + + public DataPoint[] getMassValues(DataPoint dataPoints[], ParameterSet parameters) { double noiseLevel = parameters.getParameter(CentroidMassDetectorParameters.noiseLevel).getValue(); ArrayList mzPeaks = new ArrayList(); - DataPoint dataPoints[] = scan.getDataPoints(); - // Find possible mzPeaks for (int j = 0; j < dataPoints.length; j++) { diff --git a/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/exactmass/ExactMassDetector.java b/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/exactmass/ExactMassDetector.java index 87adb7b39..899176f62 100644 --- a/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/exactmass/ExactMassDetector.java +++ b/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/exactmass/ExactMassDetector.java @@ -33,10 +33,14 @@ public class ExactMassDetector implements MassDetector { + public DataPoint[] getMassValues(Scan scan, ParameterSet parameters) { + return getMassValues(scan.getDataPoints(), parameters); + } + /** * @see net.sf.mzmine.modules.peakpicking.threestep.massdetection.MassDetector#getMassValues(net.sf.mzmine.datamodel.Scan) */ - public DataPoint[] getMassValues(Scan scan, ParameterSet parameters) { + public DataPoint[] getMassValues(DataPoint dataPoints[], ParameterSet parameters) { double noiseLevel = parameters.getParameter(ExactMassDetectorParameters.noiseLevel).getValue(); @@ -50,7 +54,7 @@ public DataPoint[] getMassValues(Scan scan, ParameterSet parameters) { new DataPointSorter(SortingProperty.Intensity, SortingDirection.Descending)); // First get all candidate peaks (local maximum) - getLocalMaxima(scan, candidatePeaks, noiseLevel); + getLocalMaxima(dataPoints, candidatePeaks, noiseLevel); // We calculate the exact mass for each peak, // starting with biggest intensity peak and so on @@ -83,10 +87,9 @@ public DataPoint[] getMassValues(Scan scan, ParameterSet parameters) { * @param scan * @return */ - private void getLocalMaxima(Scan scan, TreeSet candidatePeaks, + private void getLocalMaxima(DataPoint scanDataPoints[], TreeSet candidatePeaks, double noiseLevel) { - DataPoint[] scanDataPoints = scan.getDataPoints(); if (scanDataPoints.length == 0) return; DataPoint localMaximum = scanDataPoints[0]; diff --git a/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/localmaxima/LocalMaxMassDetector.java b/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/localmaxima/LocalMaxMassDetector.java index ef720952f..e717b0193 100644 --- a/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/localmaxima/LocalMaxMassDetector.java +++ b/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/localmaxima/LocalMaxMassDetector.java @@ -31,8 +31,12 @@ * This class detects all local maxima in a given scan. */ public class LocalMaxMassDetector implements MassDetector { - + public DataPoint[] getMassValues(Scan scan, ParameterSet parameters) { + return getMassValues(scan.getDataPoints(), parameters); + } + + public DataPoint[] getMassValues(DataPoint dataPoints[], ParameterSet parameters) { double noiseLevel = parameters.getParameter(LocalMaxMassDetectorParameters.noiseLevel).getValue(); @@ -40,8 +44,6 @@ public DataPoint[] getMassValues(Scan scan, ParameterSet parameters) { // List of found mz peaks ArrayList mzPeaks = new ArrayList(); - DataPoint dataPoints[] = scan.getDataPoints(); - // All data points of current m/z peak // Top data point of current m/z peak diff --git a/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/recursive/RecursiveMassDetector.java b/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/recursive/RecursiveMassDetector.java index 242705731..69aebc17f 100644 --- a/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/recursive/RecursiveMassDetector.java +++ b/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/recursive/RecursiveMassDetector.java @@ -34,6 +34,10 @@ public class RecursiveMassDetector implements MassDetector { public DataPoint[] getMassValues(Scan scan, ParameterSet parameters) { + return getMassValues(scan.getDataPoints(), parameters); + } + + public DataPoint[] getMassValues(DataPoint dataPoints[], ParameterSet parameters) { double noiseLevel = parameters.getParameter(RecursiveMassDetectorParameters.noiseLevel).getValue(); @@ -42,7 +46,6 @@ public DataPoint[] getMassValues(Scan scan, ParameterSet parameters) { double maximumMZPeakWidth = parameters.getParameter(RecursiveMassDetectorParameters.maximumMZPeakWidth).getValue(); - DataPoint dataPoints[] = scan.getDataPoints(); TreeSet mzPeaks = new TreeSet(new DataPointSorter(SortingProperty.MZ, SortingDirection.Ascending)); diff --git a/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/wavelet/WaveletMassDetector.java b/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/wavelet/WaveletMassDetector.java index 2407fbb55..04cf2b81d 100644 --- a/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/wavelet/WaveletMassDetector.java +++ b/src/main/java/net/sf/mzmine/modules/rawdatamethods/peakpicking/massdetection/wavelet/WaveletMassDetector.java @@ -38,6 +38,10 @@ * to detect possible peaks in the original raw datapoints. */ public class WaveletMassDetector implements MassDetector { + + public DataPoint[] getMassValues(Scan scan, ParameterSet parameters) { + return getMassValues(scan.getDataPoints(), parameters); + } /** * Parameters of the wavelet, NPOINTS is the number of wavelet values to use The WAVELET_ESL & @@ -47,15 +51,13 @@ public class WaveletMassDetector implements MassDetector { private static final int WAVELET_ESL = -5; private static final int WAVELET_ESR = 5; - public DataPoint[] getMassValues(Scan scan, ParameterSet parameters) { + public DataPoint[] getMassValues(DataPoint originalDataPoints[] , ParameterSet parameters) { double noiseLevel = parameters.getParameter(WaveletMassDetectorParameters.noiseLevel).getValue(); int scaleLevel = parameters.getParameter(WaveletMassDetectorParameters.scaleLevel).getValue(); double waveletWindow = parameters.getParameter(WaveletMassDetectorParameters.waveletWindow).getValue(); - DataPoint originalDataPoints[] = scan.getDataPoints(); - DataPoint waveletDataPoints[] = performCWT(originalDataPoints, waveletWindow, scaleLevel); DataPoint mzPeaks[] = getMzPeaks(noiseLevel, originalDataPoints, waveletDataPoints); diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraBottomPanel.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraBottomPanel.java index b9e91f484..978658a13 100644 --- a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraBottomPanel.java +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraBottomPanel.java @@ -22,20 +22,21 @@ import java.awt.Color; import java.awt.Font; import java.util.logging.Logger; - import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; +import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JPanel; import javax.swing.SwingConstants; import javax.swing.event.TreeModelEvent; import javax.swing.event.TreeModelListener; import javax.swing.tree.DefaultMutableTreeNode; - import net.sf.mzmine.datamodel.PeakList; import net.sf.mzmine.datamodel.RawDataFile; import net.sf.mzmine.main.MZmineCore; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingManager; +import net.sf.mzmine.parameters.ParameterSet; import net.sf.mzmine.util.GUIUtils; /** @@ -56,6 +57,8 @@ class SpectraBottomPanel extends JPanel implements TreeModelListener { private JPanel topPanel, bottomPanel; private JComboBox msmsSelector; private JComboBox peakListSelector; + private JCheckBox processingCbx; + private JButton processingParametersBtn ; private RawDataFile dataFile; private SpectraVisualizerWindow masterFrame; @@ -97,6 +100,19 @@ class SpectraBottomPanel extends JPanel implements TreeModelListener { peakListSelector.setActionCommand("PEAKLIST_CHANGE"); topPanel.add(peakListSelector); + + processingCbx = GUIUtils.addCheckbox(topPanel, "Enable Processing", masterFrame, + "ENABLE_PROCESSING", "Enables quick scan processing."); + processingCbx.setBackground(Color.white); + processingCbx.setFont(smallFont); + updateProcessingCheckbox(); + + processingParametersBtn = GUIUtils.addButton(topPanel, "Spectra processing", null, + masterFrame, "SET_PROCESSING_PARAMETERS", "Set the parameters for quick spectra processing."); + processingParametersBtn.setBackground(Color.white); + processingParametersBtn.setFont(smallFont); + updateProcessingButton(); + topPanel.add(Box.createHorizontalGlue()); JButton nextScanBtn = GUIUtils.addButton(topPanel, rightArrow, null, masterFrame, "NEXT_SCAN"); @@ -214,4 +230,11 @@ public void treeStructureChanged(TreeModelEvent event) { rebuildPeakListSelector(); } + public void updateProcessingCheckbox() { + processingCbx.setSelected(DataPointProcessingManager.getInst().isEnabled()); + } + + public void updateProcessingButton() { + processingParametersBtn.setEnabled(DataPointProcessingManager.getInst().isEnabled()); + } } diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraPlot.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraPlot.java index 0fb347089..6fc278cf3 100644 --- a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraPlot.java +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraPlot.java @@ -34,6 +34,7 @@ import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.block.BlockBorder; +import org.jfree.chart.labels.XYItemLabelGenerator; import org.jfree.chart.plot.DatasetRenderingOrder; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; @@ -47,13 +48,15 @@ import net.sf.mzmine.datamodel.MassSpectrumType; import net.sf.mzmine.datamodel.Scan; import net.sf.mzmine.main.MZmineCore; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingController; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingManager; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPResultsDataSet; import net.sf.mzmine.modules.visualization.spectra.simplespectra.datasets.IsotopesDataSet; import net.sf.mzmine.modules.visualization.spectra.simplespectra.datasets.PeakListDataSet; import net.sf.mzmine.modules.visualization.spectra.simplespectra.datasets.ScanDataSet; import net.sf.mzmine.modules.visualization.spectra.simplespectra.renderers.ContinuousRenderer; import net.sf.mzmine.modules.visualization.spectra.simplespectra.renderers.PeakRenderer; import net.sf.mzmine.modules.visualization.spectra.simplespectra.renderers.SpectraItemLabelGenerator; -import net.sf.mzmine.modules.visualization.spectra.simplespectra.spectraidentification.SpectraDatabaseSearchLabelGenerator; import net.sf.mzmine.util.GUIUtils; import net.sf.mzmine.util.SaveImage; import net.sf.mzmine.util.SaveImage.FileType; @@ -94,7 +97,11 @@ public class SpectraPlot extends EChartPanel { // increasing even when we remove old data sets private int numOfDataSets = 0; - public SpectraPlot(ActionListener masterPlot) { + // Spectra processing + DataPointProcessingController controller; + private boolean processingAllowed; + + public SpectraPlot(ActionListener masterPlot, boolean processingAllowed) { super(ChartFactory.createXYLineChart("", // title "m/z", // x-axis label @@ -217,6 +224,13 @@ public SpectraPlot(ActionListener masterPlot) { ZoomHistory history = getZoomHistory(); if (history != null) history.clear(); + + // set processingAllowed + setProcessingAllowed(processingAllowed); + } + + public SpectraPlot(ActionListener masterPlot) { + this(masterPlot, false); } @Override @@ -376,6 +390,12 @@ public void mouseClicked(MouseEvent event) { } public synchronized void removeAllDataSets() { + + // if the data sets are removed, we have to cancel the tasks. + if (controller != null) + controller.cancelTasks(); + controller = null; + for (int i = 0; i < plot.getDatasetCount(); i++) { plot.setDataset(i, null); } @@ -410,11 +430,13 @@ public synchronized void addDataSet(XYDataset dataSet, Color color, boolean tran plot.setRenderer(numOfDataSets, newRenderer); numOfDataSets++; + if (dataSet instanceof ScanDataSet) + checkAndRunController(); } // add Dataset with label generator public synchronized void addDataSet(XYDataset dataSet, Color color, boolean transparency, - SpectraDatabaseSearchLabelGenerator labelGenerator) { + XYItemLabelGenerator labelGenerator) { XYItemRenderer newRenderer; @@ -445,6 +467,8 @@ public synchronized void addDataSet(XYDataset dataSet, Color color, boolean tran plot.setRenderer(numOfDataSets, newRenderer); numOfDataSets++; + if (dataSet instanceof ScanDataSet) + checkAndRunController(); } @@ -457,7 +481,7 @@ public synchronized void removePeakListDataSets() { } } - ScanDataSet getMainScanDataSet() { + public ScanDataSet getMainScanDataSet() { for (int i = 0; i < plot.getDatasetCount(); i++) { XYDataset dataSet = plot.getDataset(i); if (dataSet instanceof ScanDataSet) { @@ -467,4 +491,50 @@ ScanDataSet getMainScanDataSet() { return null; } + /** + * Checks if the spectra processing is enabled & allowed and executes the controller if it is. + * Processing is forbidden for instances of ParameterSetupDialogWithScanPreviews + */ + public void checkAndRunController() { + + // if controller != null, processing on the current spectra has already been executed. When + // loading a new spectrum, the controller is set to null in removeAllDataSets() + DataPointProcessingManager inst = DataPointProcessingManager.getInst(); + + if (!isProcessingAllowed() || !inst.isEnabled()) + return; + + if(controller != null) + controller = null; + + // if a controller is re-run then delete previous results + removeDataPointProcessingResultDataSets(); + + // if enabled, do the data point processing as set up by the user + XYDataset dataSet = getMainScanDataSet(); + if (dataSet instanceof ScanDataSet) { + + controller = new DataPointProcessingController(inst.getProcessingQueue(), this, + getMainScanDataSet().getDataPoints()); + inst.addController(controller); + } + } + + public boolean isProcessingAllowed() { + return processingAllowed; + } + + public void setProcessingAllowed(boolean processingAllowed) { + this.processingAllowed = processingAllowed; + } + + public void removeDataPointProcessingResultDataSets() { + for (int i = 0; i < plot.getDatasetCount(); i++) { + XYDataset dataSet = plot.getDataset(i); + if (dataSet instanceof DPPResultsDataSet) { + plot.setDataset(i, null); + } + } + } + } diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraVisualizerModule.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraVisualizerModule.java index 8d00526ac..ccbcf8734 100644 --- a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraVisualizerModule.java +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraVisualizerModule.java @@ -99,7 +99,7 @@ public static SpectraVisualizerWindow showNewSpectrumWindow(RawDataFile dataFile return null; } - SpectraVisualizerWindow newWindow = new SpectraVisualizerWindow(dataFile); + SpectraVisualizerWindow newWindow = new SpectraVisualizerWindow(dataFile, true); newWindow.loadRawData(scan); if (peak != null) diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraVisualizerParameters.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraVisualizerParameters.java index 2763e8f9d..aca334163 100644 --- a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraVisualizerParameters.java +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraVisualizerParameters.java @@ -20,6 +20,7 @@ import net.sf.mzmine.parameters.Parameter; import net.sf.mzmine.parameters.impl.SimpleParameterSet; +import net.sf.mzmine.parameters.parametertypes.BooleanParameter; import net.sf.mzmine.parameters.parametertypes.IntegerParameter; import net.sf.mzmine.parameters.parametertypes.WindowSettingsParameter; import net.sf.mzmine.parameters.parametertypes.selectors.RawDataFilesParameter; @@ -30,7 +31,7 @@ public class SpectraVisualizerParameters extends SimpleParameterSet { public static final IntegerParameter scanNumber = new IntegerParameter("Scan number", "Scan number"); - + /** * Windows size and position */ diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraVisualizerWindow.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraVisualizerWindow.java index 09014ac03..78862d41e 100644 --- a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraVisualizerWindow.java +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/SpectraVisualizerWindow.java @@ -28,6 +28,7 @@ import java.util.Arrays; import java.util.Map; import java.util.logging.Logger; +import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFileChooser; import javax.swing.JFrame; @@ -53,6 +54,8 @@ import net.sf.mzmine.main.MZmineCore; import net.sf.mzmine.modules.peaklistmethods.io.spectraldbsubmit.view.MSMSLibrarySubmissionWindow; import net.sf.mzmine.modules.peaklistmethods.isotopes.isotopeprediction.IsotopePatternCalculator; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingManager; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingParameters; import net.sf.mzmine.modules.visualization.spectra.simplespectra.datasets.IsotopesDataSet; import net.sf.mzmine.modules.visualization.spectra.simplespectra.datasets.PeakListDataSet; import net.sf.mzmine.modules.visualization.spectra.simplespectra.datasets.ScanDataSet; @@ -64,6 +67,7 @@ import net.sf.mzmine.modules.visualization.spectra.simplespectra.spectraidentification.sumformula.SumFormulaSpectraSearchModule; import net.sf.mzmine.parameters.ParameterSet; import net.sf.mzmine.parameters.parametertypes.WindowSettingsParameter; +import net.sf.mzmine.util.ExitCode; import net.sf.mzmine.util.dialogs.AxesSetupDialog; import net.sf.mzmine.util.scans.ScanUtils; @@ -96,9 +100,11 @@ public class SpectraVisualizerWindow extends JFrame implements ActionListener { // Current scan data set private ScanDataSet spectrumDataSet; + private ParameterSet paramSet; + private static final double zoomCoefficient = 1.2f; - public SpectraVisualizerWindow(RawDataFile dataFile) { + public SpectraVisualizerWindow(RawDataFile dataFile, boolean enableProcessing) { super("Spectrum loading..."); this.dataFile = dataFile; @@ -106,7 +112,7 @@ public SpectraVisualizerWindow(RawDataFile dataFile) { setDefaultCloseOperation(DISPOSE_ON_CLOSE); setBackground(Color.white); - spectrumPlot = new SpectraPlot(this); + spectrumPlot = new SpectraPlot(this, enableProcessing); add(spectrumPlot, BorderLayout.CENTER); toolBar = new SpectraToolBar(this); @@ -128,8 +134,7 @@ public SpectraVisualizerWindow(RawDataFile dataFile) { pack(); // get the window settings parameter - ParameterSet paramSet = - MZmineCore.getConfiguration().getModuleParameters(SpectraVisualizerModule.class); + paramSet = MZmineCore.getConfiguration().getModuleParameters(SpectraVisualizerModule.class); WindowSettingsParameter settings = paramSet.getParameter(SpectraVisualizerParameters.windowSettings); @@ -138,6 +143,12 @@ public SpectraVisualizerWindow(RawDataFile dataFile) { this.addComponentListener(settings); } + + public SpectraVisualizerWindow(RawDataFile dataFile) { + this(dataFile, false); + } + + @Override public void dispose() { @@ -597,6 +608,37 @@ public void run() { }); } + if (command.equals("SET_PROCESSING_PARAMETERS")) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + // DPPSetupWindow.getInstance().show(); + if (DataPointProcessingManager.getInst().getParameters() + .showSetupDialog(MZmineCore.getDesktop().getMainWindow(), true) == ExitCode.OK + && DataPointProcessingManager.getInst().isEnabled()) { + getSpectrumPlot().checkAndRunController(); + } + } + }); + } + + if (command.equals("ENABLE_PROCESSING")) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + DataPointProcessingManager inst = DataPointProcessingManager.getInst(); + inst.setEnabled(!inst.isEnabled()); + bottomPanel.updateProcessingButton(); + getSpectrumPlot().checkAndRunController(); + + // if the tick is removed, set the data back to default + if(!inst.isEnabled()) { +// getSpectrumPlot().removeDataPointProcessingResultDataSets(); + loadRawData(currentScan); + } + } + }); + } } public void addAnnotation(Map annotation) { diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DPPControllerStatusListener.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DPPControllerStatusListener.java new file mode 100644 index 000000000..07efd6be8 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DPPControllerStatusListener.java @@ -0,0 +1,32 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing; + +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingController.ControllerStatus; + +/** + * Listens to changes in the status of a DataPointProcessingController. + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +@FunctionalInterface +public interface DPPControllerStatusListener { + public void statusChanged(DataPointProcessingController controller, ControllerStatus newStatus, ControllerStatus oldStatus); +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingController.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingController.java new file mode 100644 index 000000000..4ce5159a1 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingController.java @@ -0,0 +1,328 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Logger; +import org.apache.xalan.xsltc.compiler.util.ErrorMessages; +import org.jfree.data.xy.XYDataset; +import com.sun.xml.bind.v2.runtime.reflect.Accessor.SetterOnlyReflection; +import net.sf.mzmine.datamodel.DataPoint; +import net.sf.mzmine.datamodel.IsotopePattern; +import net.sf.mzmine.datamodel.IsotopePattern.IsotopePatternStatus; +import net.sf.mzmine.datamodel.impl.SimpleIsotopePattern; +import net.sf.mzmine.main.MZmineCore; +import net.sf.mzmine.modules.MZmineProcessingStep; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.SpectraPlot; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.ProcessedDataPoint; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPIsotopePatternResult; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPResult.ResultType; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPResultsDataSet; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPResultsLabelGenerator; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datasets.IsotopesDataSet; +import net.sf.mzmine.parameters.ParameterSet; +import net.sf.mzmine.taskcontrol.Task; +import net.sf.mzmine.taskcontrol.TaskStatus; +import net.sf.mzmine.taskcontrol.TaskStatusListener; + +/** + * This class will control the tasks to process the DataPoints in a SpectraWindow. Every SpectraPlot + * is meant to have an instance of this class associated with it. + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public class DataPointProcessingController { + + private Logger logger = Logger.getLogger(DataPointProcessingController.class.getName()); + + private DataPoint[] dataPoints; + private ProcessedDataPoint[] results; + private List listener; + private DataPointProcessingTask currentTask; + private MZmineProcessingStep currentStep; + private DataPointProcessingQueue queue; + private SpectraPlot plot; + + public enum ControllerStatus { + WAITING, PROCESSING, ERROR, CANCELED, FINISHED + }; + + /** + * This is used to cancel the execution of this controller. It is set to NORMAL in the + * constructor. + */ + public enum ForcedControllerStatus { + NORMAL, CANCEL + }; + + ControllerStatus status; + ForcedControllerStatus forcedStatus; + + public DataPointProcessingController(DataPointProcessingQueue steps, SpectraPlot plot, + DataPoint[] dataPoints) { + + setQueue(steps); + setPlot(plot); + setdataPoints(dataPoints); + setStatus(ControllerStatus.WAITING); + setForcedStatus(ForcedControllerStatus.NORMAL); + } + + public DataPointProcessingQueue getQueue() { + return queue; + } + + public SpectraPlot getPlot() { + return plot; + } + + private void setQueue(DataPointProcessingQueue queue) { + this.queue = queue; + } + + private void setPlot(SpectraPlot plot) { + this.plot = plot; + } + + /** + * + * @return The original data points this controller started execution with. + */ + public DataPoint[] getDataPoints() { + return dataPoints; + } + + private void setdataPoints(DataPoint[] dataPoints) { + this.dataPoints = dataPoints; + } + + /** + * + * @return Results of this task. Might be null, make sure to check the status first! + */ + public ProcessedDataPoint[] getResults() { + return results; + } + + private void setResults(ProcessedDataPoint[] results) { + this.results = results; + } + + public DataPointProcessingTask getCurrentTask() { + return currentTask; + } + + private void setCurrentTask(DataPointProcessingTask currentTask) { + this.currentTask = currentTask; + } + + private MZmineProcessingStep getCurrentStep() { + return this.currentStep; + } + + private void setCurrentStep(MZmineProcessingStep step) { + this.currentStep = step; + } + + public ForcedControllerStatus getForcedStatus() { + return forcedStatus; + } + + private void setForcedStatus(ForcedControllerStatus forcedStatus) { + this.forcedStatus = forcedStatus; + } + + /** + * Convenience method to cancel the execution of this controller. The manager will listen to this + * change by its DPControllerStatusListener. The ControllerStatus is changed in the execute() + * method of this controller. + */ + public void cancelTasks() { + setForcedStatus(ForcedControllerStatus.CANCEL); + if (getCurrentTask() != null) + getCurrentTask().setStatus(TaskStatus.CANCELED); + } + + /** + * This will execute the modules associated with the plot. It will start with the first one and + * execute the following ones afterwards automatically. This method is called by the public method + * execute(). The status listener in this method starts the next task recursively after the + * previous one has finished. + * + * @param dp + * @param module + * @param plot + */ + private void execute(DataPoint[] dp, MZmineProcessingStep step, + SpectraPlot plot) { + if (queue == null || queue.isEmpty() || plot == null) { + logger.warning("execute called, without queue or plot being set."); + setStatus(ControllerStatus.FINISHED); + return; + } + + if (getForcedStatus() == ForcedControllerStatus.CANCEL) { + setResults(ProcessedDataPoint.convert(dp)); + logger + .finest("Canceled controller, not starting new tasks. Results are set to latest array."); + setStatus(ControllerStatus.CANCELED); + return; + } + + if (step.getModule() instanceof DataPointProcessingModule) { + + DataPointProcessingModule inst = step.getModule(); + ParameterSet parameters = step.getParameterSet(); + + Task t = ((DataPointProcessingModule) inst).createTask(dp, parameters, plot, this, + new TaskStatusListener() { + @Override + public void taskStatusChanged(Task task, TaskStatus newStatus, TaskStatus oldStatus) { + if (!(task instanceof DataPointProcessingTask)) { + // TODO: Throw exception? + logger.warning("This should have been a DataPointProcessingTask."); + return; + } + // logger.finest("Task status changed to " + newStatus.toString()); + switch (newStatus) { + case FINISHED: + if (queue.hasNextStep(step)) { + if (DataPointProcessingManager.getInst() + .isRunning(((DataPointProcessingTask) task).getController())) { + + MZmineProcessingStep next = + queue.getNextStep(step); + + // pass results to next task and start recursively + ProcessedDataPoint[] result = ((DataPointProcessingTask) task).getResults(); + ((DataPointProcessingTask) task).displayResults(); + + execute(result, next, plot); + } else { + logger.warning( + "This controller was already removed from the running list, although it " + + "had not finished processing. Exiting"); + break; + } + } else { + setResults(((DataPointProcessingTask) task).getResults()); + ((DataPointProcessingTask) task).displayResults(); + setStatus(ControllerStatus.FINISHED); + } + break; + case PROCESSING: + setStatus(ControllerStatus.PROCESSING); + break; + case WAITING: + // should we even set to WAITING here? + break; + case ERROR: + setStatus(ControllerStatus.ERROR); + break; + case CANCELED: + setStatus(ControllerStatus.CANCELED); + break; + } + } + }); + + + logger.finest("Start processing of " + t.getClass().getName()); + MZmineCore.getTaskController().addTask(t); + setCurrentTask((DataPointProcessingTask) t); // maybe we need this some time + setCurrentStep(step); + } + } + + + /** + * Executes the modules in the PlotModuleCombo to the plot with the given DataPoints. This will be + * called by the DataPointProcessingManager. This starts the first module, which recursively + * starts the following ones after finishing. + */ + public void execute() { + if (queue == null || queue.isEmpty() || plot == null) { + setStatus(ControllerStatus.FINISHED); + logger.warning("execute called, without queue or plot being set."); + return; + } + + MZmineProcessingStep first = queue.getFirstStep(); + if (first == null) { + setStatus(ControllerStatus.ERROR); + return; + } + + setStatus(ControllerStatus.PROCESSING); + logger.finest("Executing DataPointProcessingTasks."); + execute(getDataPoints(), first, getPlot()); + } + + public boolean addControllerStatusListener(DPPControllerStatusListener list) { + if (listener == null) + listener = new ArrayList(); + return listener.add(list); + } + + public boolean removeControllerStatusListener(DPPControllerStatusListener list) { + if (listener != null) + return listener.remove(list); + return false; + } + + public void clearControllerStatusListeners() { + if (listener != null) + listener.clear(); + } + + /** + * + * @return True if the current task is the last one, false otherwise. + */ + public boolean isLastTaskRunning() { + if (getQueue().indexOf(getCurrentStep()) == getQueue().size() - 1) + return true; + return false; + } + + /** + * + * @return The current ControllerStatus. + */ + public ControllerStatus getStatus() { + return status; + } + + /** + * Changes the status of this controller and notifies listeners. + * + * @param status New ControllerStatus. + */ + public void setStatus(ControllerStatus status) { + ControllerStatus old = this.status; + this.status = status; + + if (listener != null) + for (DPPControllerStatusListener l : listener) + l.statusChanged(this, this.status, old); + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingManager.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingManager.java new file mode 100644 index 000000000..9ce3970e4 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingManager.java @@ -0,0 +1,358 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.logging.Logger; +import javax.annotation.Nonnull; +import net.sf.mzmine.main.MZmineCore; +import net.sf.mzmine.modules.MZmineModule; +import net.sf.mzmine.modules.MZmineProcessingStep; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingController.ControllerStatus; +import net.sf.mzmine.parameters.Parameter; +import net.sf.mzmine.parameters.ParameterSet; + +/** + * There will be a single instance of this class, use getInst(). This class keeps track of every + * DataPointProcessingController and manages their assignment to the TaskController. Default + * settings are loaded as set in the preferences. + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public class DataPointProcessingManager implements MZmineModule { + + private static final DataPointProcessingManager inst = new DataPointProcessingManager(); + private static final int MAX_RUNNING = 3; + private static final String MODULE_NAME = "Data point processing manager"; + + private ParameterSet parameters; + + private static Logger logger = Logger.getLogger(DataPointProcessingManager.class.getName()); + + private List waiting; + private List running; + + private DataPointProcessingQueue processingList; + + public DataPointProcessingManager() { + waiting = new ArrayList<>(); + running = new ArrayList<>(); + + // parameters = + // MZmineCore.getConfiguration().getModuleParameters(DataPointProcessingManager.class); + + processingList = new DataPointProcessingQueue(); + } + + public static DataPointProcessingManager getInst() { + return inst; + } + + public ParameterSet getParameters() { + if (parameters == null) { + parameters = + MZmineCore.getConfiguration().getModuleParameters(DataPointProcessingManager.class); + processingList = parameters.getParameter(DataPointProcessingParameters.processing).getValue(); + } + return parameters; + } + + /** + * Adds a controller to the end of the waiting list. Automatically tries to start a controller + * after addition. + * + * @param controller Controller to add. + */ + public void addController(@Nonnull DataPointProcessingController controller) { + synchronized (waiting) { + if (waiting.contains(controller)) { + // logger.fine("Warning: Controller was already added to waiting list at index " + // + waiting.indexOf(controller) + "/" + waiting.size() + ". Skipping."); + return; + } + waiting.add(controller); + } + logger.finest("Controller added to waiting list. (size = " + waiting.size() + ")"); + startNextController(); + } + + /** + * Removes a controller from the waiting list. Use this if the current plot has changed. + * + * @param controller + */ + public boolean removeWaitingController(DataPointProcessingController controller) { +// if (!waiting.contains(controller)) +// return false; + + synchronized (waiting) { + return waiting.remove(controller); + } + // logger.finest("Controller removed from wating list. (size = " + waiting.size() + ")"); + } + + /** + * Adds a controller to the running list. Don't use publicly. Is called by startNextController() + * if running.size < MAX_RUNNING. + * + * @param controller + */ + private void addRunningController(@Nonnull DataPointProcessingController controller) { + synchronized (running) { + if (running.contains(controller)) { + // logger.fine("Warning: Controller was already added to waiting list at index " + // + running.indexOf(controller) + "/" + running.size() + ". Skipping."); + return; + } + running.add(controller); + } + // logger.finest("Controller added to running list. (size = " + running.size() + ")"); + } + + /** + * Removes a controller from the running list. Don't use publicly. Is called by the + * DPControllerStatusListener in the startNextController method, if the task was canceled or + * finished. + * + * @param controller + */ + private boolean removeRunningController(DataPointProcessingController controller) { +// if (!running.contains(controller)) +// return; + + synchronized (running) { + return running.remove(controller); + } + // logger.finest("Controller removed from running list. (size = " + running.size() + ")"); + } + + /** + * Clears the list of all waiting controllers. + */ + private void removeAllWaitingControllers() { + synchronized (waiting) { + waiting.clear(); + } + } + + /** + * Tries to remove the controller from waiting OR running list. + * @param controller + * @return + */ + public boolean removeController(DataPointProcessingController controller) { + if(removeRunningController(controller)) + return true; + else return removeWaitingController(controller); + } + + /** + * Tries to start the next controller from the waiting list and adds a listener to automatically + * start the next one when finished. Every SpectraPlot will call this method after adding its + * controller. + */ + public void startNextController() { + if (!isEnabled()) + return; + + DataPointProcessingController next; + + synchronized (waiting) { + if (running.size() >= MAX_RUNNING) { + // logger.info("Too much controllers running, cannot start the next one."); + return; + } + if (waiting.isEmpty()) { + // logger.info("No more waiting controllers, cannot start the next one."); + return; + } + + next = waiting.get(0); + removeWaitingController(next); + } + + addRunningController(next); + next.addControllerStatusListener(new DPPControllerStatusListener() { + + @Override + public void statusChanged(DataPointProcessingController controller, + ControllerStatus newStatus, ControllerStatus oldStatus) { + if (newStatus == ControllerStatus.FINISHED) { + // One controller finished, now we can remove it and start the next one. + removeController(controller); + startNextController(); + // logger.finest("Controller finished, trying to start the next one. (size = " + // + running.size() + ")"); + } else if (newStatus == ControllerStatus.CANCELED) { + // this will be called, when the controller is forcefully canceled. The current task will + // be completed, then the status will be changed and this method is called. + removeController(controller); + startNextController(); + } else if (newStatus == ControllerStatus.ERROR) { + // if a controller's task errors out, we should cancel the whole controller here + // the controller status is set to ERROR automatically, if a task error's out. + + // since the next controller wont be started, just using cancelTasks() here is not + // sufficient, we have to remove it manually + removeController(controller); + } + } + }); + + next.execute(); // this will start the actual task via the controller method. + // logger.finest("Started controller from running list. (size = " + running.size() + ")"); + } + + /** + * Cancels the execution of a specific controller or removes it from waiting list. + * + * @param controller + */ + public void cancelController(DataPointProcessingController controller) { + synchronized (waiting) { + if (waiting.contains(controller)) { + controller.cancelTasks(); + // removing the controller will be executed by the statusListener in startNextController() + // since the forcedStatus of the controller has been set. Controller.execute checks before + // every task launch if the controller was canceled. + // removeWaitingController(controller); + } + } + synchronized (running) { + if (running.contains(controller)) { + controller.cancelTasks(); + // removing the controller will be executed by the statusListener in startNextController() + // removeRunningController(controller); + } + } + } + + /** + * Cancels the execution of all running controllers. Keep in mind that calling only this method + * will only cancel the running ones, the currently waiting ones will be started afterwards. + * Consider calling removeAllWaiting first or use cancelAndRemoveAll() instead. + */ + public void cancelAllRunning() { + synchronized (running) { + for (DataPointProcessingController c : running) { + c.cancelTasks(); + } + } + } + + /** + * Cancels every running task and removed all waiting controllers. + */ + public void cancelAndRemoveAll() { + removeAllWaitingControllers(); + synchronized (running) { + for (DataPointProcessingController c : running) { + c.cancelTasks(); + } + } + } + + /** + * Convenience method to double check if a controller is allowed to run. + * + * @param controller + * @return true or false if the controller is still in the running list. If this is false and the + * controller wants to execute() something went wrong. Check the setStatus method of the + * controller and the tasks. + */ + public boolean isRunning(DataPointProcessingController controller) { + return running.contains(controller); + } + + /** + * Adds a processing step to the list. + * + * @param step Processing step to add. + * @return {@link Collection#add} + */ + public boolean addProcessingStep(MZmineProcessingStep step) { + if (processingList == null) + processingList = new DataPointProcessingQueue(); + return processingList.add(step); + } + + /** + * Removes a processing step from the list. + * + * @param step Processing step to remove. + * @return {@link Collection#remove} + */ + public boolean removeProcessingStep(MZmineProcessingStep step) { + if (processingList == null) + processingList = new DataPointProcessingQueue(); + return processingList.remove(step); + } + + /** + * Clears the list of processing steps + */ + public void clearProcessingSteps() { + if (processingList == null) { + logger.warning("The processing queue is null and clearProcessingSteps was called."); + processingList = new DataPointProcessingQueue(); + } + processingList.clear(); + } + + public @Nonnull DataPointProcessingQueue getProcessingQueue() { + getParameters(); + return processingList; + } + + /** + * Sets the processing list. + * + * @param list New processing list. + */ + public void setProcessingQueue(@Nonnull DataPointProcessingQueue list) { + if(list != null) + processingList = list; + else + logger.warning("The processing list was about to be set to null."); + } + + public boolean isEnabled() { + getParameters(); + return getParameters().getParameter(DataPointProcessingParameters.spectraProcessing).getValue(); + } + + public void setEnabled(boolean enabled) { + getParameters().getParameter(DataPointProcessingParameters.spectraProcessing).setValue(enabled); + logger.finest("Enabled changed to " + enabled); + } + + @Override + public String getName() { + return "Data point/Spectra processing"; + } + + @Override + public Class getParameterSetClass() { + return DataPointProcessingParameters.class; + } + +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingModule.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingModule.java new file mode 100644 index 000000000..7220bb0e2 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingModule.java @@ -0,0 +1,46 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing; + +import javax.annotation.Nonnull; +import net.sf.mzmine.datamodel.DataPoint; +import net.sf.mzmine.modules.MZmineModule; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.SpectraPlot; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.ModuleSubCategory; +import net.sf.mzmine.parameters.ParameterSet; +import net.sf.mzmine.taskcontrol.TaskStatusListener; + +/** + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public interface DataPointProcessingModule extends MZmineModule { + + /** + * @return The module sub category of this module. + */ + @Nonnull + public ModuleSubCategory getModuleSubCategory(); + + @Nonnull + public DataPointProcessingTask createTask(DataPoint[] dataPoints, ParameterSet parameterSet, + SpectraPlot plot, DataPointProcessingController controller, TaskStatusListener listener); + +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingParameters.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingParameters.java new file mode 100644 index 000000000..96320671f --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingParameters.java @@ -0,0 +1,25 @@ +package net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing; + +import java.awt.Window; +import net.sf.mzmine.parameters.Parameter; +import net.sf.mzmine.parameters.impl.SimpleParameterSet; +import net.sf.mzmine.parameters.parametertypes.BooleanParameter; +import net.sf.mzmine.parameters.parametertypes.HiddenParameter; +import net.sf.mzmine.parameters.parametertypes.ProcessingParameter; +import net.sf.mzmine.parameters.parametertypes.filenames.FileNameParameter; +import net.sf.mzmine.util.ExitCode; + +public class DataPointProcessingParameters extends SimpleParameterSet { + /** + * Processing + */ + public static final HiddenParameter spectraProcessing = + new HiddenParameter<>(new BooleanParameter("Enable Processing", "", false)); + + public static final ProcessingParameter processing = new ProcessingParameter("Processing queue", + "Set the modules to be executed in the processing queue."); + + public DataPointProcessingParameters() { + super(new Parameter[] {spectraProcessing, processing}); + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingQueue.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingQueue.java new file mode 100644 index 000000000..03770ef33 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingQueue.java @@ -0,0 +1,202 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Collection; +import java.util.Vector; +import java.util.logging.Logger; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.TransformerFactoryConfigurationError; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; +import net.sf.mzmine.main.MZmineCore; +import net.sf.mzmine.modules.MZmineModule; +import net.sf.mzmine.modules.MZmineProcessingStep; +import net.sf.mzmine.modules.impl.MZmineProcessingStepImpl; +import net.sf.mzmine.parameters.ParameterSet; + +public class DataPointProcessingQueue extends Vector> { + + private static final long serialVersionUID = 1L; + + private static final Logger logger = Logger.getLogger(DataPointProcessingQueue.class.getName()); + + private static final String DATA_POINT_PROCESSING_STEP_ELEMENT = "processingstep"; + private static final String METHOD_ELEMENT = "method"; + + public static @Nonnull DataPointProcessingQueue loadfromXML(final @Nonnull Element xmlElement) { + DataPointProcessingQueue queue = new DataPointProcessingQueue(); + + // Get the loaded modules. + final Collection allModules = MZmineCore.getAllModules(); + + // Process the processing step elements. + final NodeList nodes = xmlElement.getElementsByTagName(DATA_POINT_PROCESSING_STEP_ELEMENT); + final int nodesLength = nodes.getLength(); + + for (int i = 0; i < nodesLength; i++) { + + final Element stepElement = (Element) nodes.item(i); + final String methodName = stepElement.getAttribute(METHOD_ELEMENT); + logger.info("loading method " + methodName); + + for (MZmineModule module : allModules) { + if (module instanceof DataPointProcessingModule + && module.getClass().getName().equals(methodName)) { + + ParameterSet parameterSet = + MZmineCore.getConfiguration().getModuleParameters(module.getClass()); + + parameterSet.loadValuesFromXML(stepElement); + queue.add(new MZmineProcessingStepImpl( + (DataPointProcessingModule) module, parameterSet)); + // add to treeView + break; + } + + } + + } + return queue; + } + + public static @Nonnull DataPointProcessingQueue loadFromFile(@Nonnull File file) { + try { + Element element = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file).getDocumentElement(); + return loadfromXML(element); + } catch (SAXException | IOException | ParserConfigurationException e) { + e.printStackTrace(); + return new DataPointProcessingQueue(); + } + } + + public void saveToXML(final @Nonnull Element xmlElement) { + + final Document document = xmlElement.getOwnerDocument(); + + // Process each step. + for (final MZmineProcessingStep step : this) { + + // Append a new batch step element. + final Element stepElement = document.createElement(DATA_POINT_PROCESSING_STEP_ELEMENT); + + stepElement.setAttribute(METHOD_ELEMENT, step.getModule().getClass().getName()); + xmlElement.appendChild(stepElement); + + // Save parameters. + final ParameterSet parameters = step.getParameterSet(); + if (parameters != null) { + parameters.saveValuesToXML(stepElement); + } + } + } + + public void saveToFile(final @Nonnull File file) { + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument(); + final Element element = document.createElement("DataPointProcessing"); + document.appendChild(element); + + // Serialize batch queue. + this.saveToXML(element); + + // Create transformer. + final Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.METHOD, "xml"); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); + + // Write to file and transform. + transformer.transform(new DOMSource(document), new StreamResult(new FileOutputStream(file))); + + logger.info("Saved " + this.size() + " processing step(s) to " + file.getName()); + + } catch (ParserConfigurationException | TransformerFactoryConfigurationError | FileNotFoundException | TransformerException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return; + } + + } + + /** + * + * @return Returns true if the module list is initialized and > 0. + */ + public boolean stepsValid() { + if(!this.isEmpty()) + return true; + return false; + } + + /** + * + * @param current A pointer to the current module. + * @return Returns true if there is one or more steps, false if not. + */ + public boolean hasNextStep(MZmineProcessingStep current) { + if (this.contains(current)) { + int index = this.indexOf(current); + if (index + 1 < this.size()) { + return true; + } + } + return false; + } + + /** + * + * @param current A pointer to the current module. + * @return Returns the next module in this PlotModuleCombo. If this pmc has no next module the + * return is null. Use hasNextModule to check beforehand. + */ + public @Nullable MZmineProcessingStep getNextStep(@Nonnull MZmineProcessingStep current) { + if (hasNextStep(current)) + return this.get(this.indexOf(current) + 1); + return null; + } + + /** + * + * @return Returns the first module in this PlotModuleCombo. If the list of steps is not + * initialised, the return is null. + */ + public @Nullable MZmineProcessingStep getFirstStep() { + if (this.size() > 0) { + return this.get(0); + } + return null; + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingTask.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingTask.java new file mode 100644 index 000000000..ed891151f --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/DataPointProcessingTask.java @@ -0,0 +1,220 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nonnull; +import org.jfree.data.xy.XYDataset; +import com.jogamp.newt.event.GestureHandler.GestureListener; +import net.sf.mzmine.datamodel.DataPoint; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.SpectraPlot; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.ProcessedDataPoint; +import net.sf.mzmine.parameters.ParameterSet; +import net.sf.mzmine.taskcontrol.AbstractTask; +import net.sf.mzmine.taskcontrol.TaskStatus; +import net.sf.mzmine.taskcontrol.TaskStatusListener; +import net.sf.mzmine.util.scans.ScanUtils; + +/** + * + * This abstract class defines the methods for processing an array of DataPoints. When implementing + * this, make sure to use setStatus and setResults at the end of the task. The next task will not be + * launched, if the status has not been set to FINISHED. The next Task will be launched using + * ProcessedDataPoint[] results. DataPoints passed to this task will be stored in dataPoints[] (an + * array of DataPoint[]). If you method requires mass detection, it is recommended to chech if it's + * an instance of ProcessedDataPoint[]. ParameterSet, plot and controller are also stored during the + * constructor of this this abstract class. + * + * @author Steffen Heuckeroth steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public abstract class DataPointProcessingTask extends AbstractTask { + + private SpectraPlot targetPlot; + protected DataPoint[] dataPoints; + protected ParameterSet parameterSet; + private DataPointProcessingController controller; + protected String taskDescription; + protected Color color; + protected boolean displayResults; + + + // move the results into this array by setReults to be collected by the controller and passed on + // to the next DPPTask by it + private ProcessedDataPoint[] results; + + /** + * Stores the dataPoints, plot, parameters, controller, and TaskStatusListener passed to this task + * and sets the task status to WAITING. Make sure to call this super constructor in your extending + * class. + * + * @param dataPoints + * @param plot + * @param parameterSet + * @param controller + * @param listener + */ + public DataPointProcessingTask(@Nonnull DataPoint[] dataPoints, @Nonnull SpectraPlot plot, + @Nonnull ParameterSet parameterSet, @Nonnull DataPointProcessingController controller, + @Nonnull TaskStatusListener listener) { + setDataPoints(dataPoints); + setTargetPlot(plot); + setParameterSet(parameterSet); + setController(controller); + String name = this.getClass().getName(); + name = name.substring(name.lastIndexOf(".") + 1); + setTaskDescription(name + " of scan #" + plot.getMainScanDataSet().getScan().getScanNumber()); + addTaskStatusListener(listener); + setStatus(TaskStatus.WAITING); + } + + public abstract void displayResults(); + + public @Nonnull DataPoint[] getDataPoints() { + return dataPoints; + } + + private void setDataPoints(@Nonnull DataPoint[] dataPoints) { + this.dataPoints = dataPoints; + } + + public @Nonnull SpectraPlot getTargetPlot() { + return targetPlot; + } + + private void setTargetPlot(@Nonnull SpectraPlot targetPlot) { + this.targetPlot = targetPlot; + } + + /** + * + * @return Array of ProcessedDataPoints. Make sure the task has finished. If results are not set a + * new ProcessedDataPoint[0] will be returned. + */ + public @Nonnull ProcessedDataPoint[] getResults() { + if (results != null) + return results; + return new ProcessedDataPoint[0]; + } + + /** + * Set the results when your task is done processing. + * + * @param dp Array the results shall be set to. + */ + public void setResults(@Nonnull ProcessedDataPoint[] dp) { + this.results = dp; + } + + /** + * + * @return The parameter set passed to this task. + */ + public @Nonnull ParameterSet getParameterSet() { + return parameterSet; + } + + private void setParameterSet(@Nonnull ParameterSet parameterSet) { + this.parameterSet = parameterSet; + } + + public @Nonnull DataPointProcessingController getController() { + return controller; + } + + private void setController(@Nonnull DataPointProcessingController controller) { + this.controller = controller; + } + + @Override + public String getTaskDescription() { + return taskDescription; + } + + private void setTaskDescription(String taskDescription) { + this.taskDescription = taskDescription; + } + + /** + * Convenience method to execute the {@link ParameterSet#checkParameterValues} method and set + * an error message using setErrorMessage method. + * + * @return true if all values are valid, false otherwise. + */ + protected boolean checkParameterSet() { + List error = new ArrayList(); + if (!parameterSet.checkParameterValues(error)) { + setErrorMessage( + "Data point/Spectra processing: Parameter check failed. \n" + error.toString()); + return false; + } + return true; + } + + /** + * Checks if any invalid arguments were passed through the constructor of this class and sets an + * error message using setErrorMessage. Only checks for errors that would cause a + * NullPointerException, the length of the passed DataPoint array is not checked. + * + * @return true if all arguments are valid, false otherwise. + */ + protected boolean checkValues() { + if (getDataPoints() == null || getTargetPlot() == null || getParameterSet() == null + || getController() == null) { + setErrorMessage("Data point/Spectra processing: Invalid constructor arguments passed to " + + getTaskDescription()); + return false; + } + return true; + } + + /** + * + * @return Returns the color the results of this task should be displayed with. + */ + public Color getColor() { + return color; + } + + /** + * + * @return true if the results should be displayed, false otherwise. + */ + public boolean isDisplayResults() { + return displayResults; + } + + /** + * Sets the color of the results of this task. + * @param color + */ + protected void setColor(Color color) { + this.color = color; + } + + /** + * Sets if the results of this task should be displayed. + * @param displayResults + */ + protected void setDisplayResults(boolean displayResults) { + this.displayResults = displayResults; + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/DPPModuleCategoryTreeItem.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/DPPModuleCategoryTreeItem.java new file mode 100644 index 000000000..b2be00a03 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/DPPModuleCategoryTreeItem.java @@ -0,0 +1,45 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel; + +import javafx.scene.control.TreeItem; + +/** + * Stores module categories in a tree item. Used to organize the tree view automatically. Every + * {@link ModuleSubCategory} is automatically added in {@link DPPSetupWindowController}. + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public class DPPModuleCategoryTreeItem extends TreeItem { + private ModuleSubCategory category; + + public DPPModuleCategoryTreeItem(ModuleSubCategory category) { + super(category.getName()); + setCategory(category); + } + + public ModuleSubCategory getCategory() { + return category; + } + + private void setCategory(ModuleSubCategory category) { + this.category = category; + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/DPPModuleCategoryTreeNode.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/DPPModuleCategoryTreeNode.java new file mode 100644 index 000000000..9745a7a45 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/DPPModuleCategoryTreeNode.java @@ -0,0 +1,31 @@ +package net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel; + +import javax.swing.tree.DefaultMutableTreeNode; + +/** + * Stores module categories in a tree item. Used to organize the tree view automatically. Every + * {@link ModuleSubCategory} is automatically added in {@link DPPSetupWindowController}. + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public class DPPModuleCategoryTreeNode extends DefaultMutableTreeNode { + /** + * + */ + private static final long serialVersionUID = 1L; + private ModuleSubCategory category; + + public DPPModuleCategoryTreeNode(ModuleSubCategory category) { + super(category.getName()); + setCategory(category); + } + + public ModuleSubCategory getCategory() { + return category; + } + + private void setCategory(ModuleSubCategory category) { + this.category = category; + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/DPPModuleTreeItem.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/DPPModuleTreeItem.java new file mode 100644 index 000000000..de26017d4 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/DPPModuleTreeItem.java @@ -0,0 +1,79 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel; + +import javafx.scene.control.TreeItem; +import net.sf.mzmine.main.MZmineCore; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingModule; +import net.sf.mzmine.parameters.ParameterSet; + +/** + * Stores {@link DataPointProcessingModule}s and their parameters in a tree item. All MZmineModules implementing + * DataPointProcessingModule are automatically added in {@link DPPSetupWindowController}. + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public class DPPModuleTreeItem extends TreeItem { + + private String name; + private DataPointProcessingModule module; + private ModuleSubCategory subCat; + private ParameterSet parameters; + + public DPPModuleTreeItem(DataPointProcessingModule module) { + super(module.getName()); + setName(module.getName()); + setModule(module); + setSubCat(module.getModuleSubCategory()); + setParameters(MZmineCore.getConfiguration().getModuleParameters(module.getClass())); + } + + public String getName() { + return name; + } + + public DataPointProcessingModule getModule() { + return module; + } + + private void setName(String name) { + this.name = name; + } + + private void setModule(DataPointProcessingModule module) { + this.module = module; + } + + public ModuleSubCategory getSubCat() { + return subCat; + } + + private void setSubCat(ModuleSubCategory subCat) { + this.subCat = subCat; + } + + public ParameterSet getParameters() { + return parameters; + } + + public void setParameters(ParameterSet parameters) { + this.parameters = parameters; + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/DPPModuleTreeNode.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/DPPModuleTreeNode.java new file mode 100644 index 000000000..bd6f2e45d --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/DPPModuleTreeNode.java @@ -0,0 +1,55 @@ +package net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel; + +import javax.swing.tree.DefaultMutableTreeNode; +import net.sf.mzmine.main.MZmineCore; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingModule; +import net.sf.mzmine.parameters.ParameterSet; + +/** + * Stores {@link DataPointProcessingModule}s and their parameters in a tree item. All MZmineModules implementing + * DataPointProcessingModule are automatically added in {@link DPPSetupWindowController}. + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public class DPPModuleTreeNode extends DefaultMutableTreeNode { + private DataPointProcessingModule module; + private ModuleSubCategory subCat; + private ParameterSet parameters; + + public DPPModuleTreeNode(DataPointProcessingModule module) { + super(module.getName()); + setModule(module); + setSubCat(module.getModuleSubCategory()); + setParameters(MZmineCore.getConfiguration().getModuleParameters(module.getClass())); + } + + public DataPointProcessingModule getModule() { + return module; + } + + private void setModule(DataPointProcessingModule module) { + this.module = module; + } + + public ModuleSubCategory getSubCat() { + return subCat; + } + + private void setSubCat(ModuleSubCategory subCat) { + this.subCat = subCat; + } + + public ParameterSet getParameters() { + return parameters; + } + + public void setParameters(ParameterSet parameters) { + this.parameters = parameters; + } + + @Override + public DPPModuleTreeNode clone() { + return new DPPModuleTreeNode(module); + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/ModuleSubCategory.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/ModuleSubCategory.java new file mode 100644 index 000000000..2fecc1e08 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/ModuleSubCategory.java @@ -0,0 +1,40 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel; + +/** + * The module sub category is used to classify module categories that can be executed on data points + * by data point processing tasks. + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public enum ModuleSubCategory { + MASSDETECTION("Mass detection"), ISOTOPES("Isotopes"), IDENTIFICATION("Identification"); + + private final String name; + + ModuleSubCategory(String name) { + this.name = name; + } + + public String getName() { + return name; + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/ProcessedDataPoint.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/ProcessedDataPoint.java new file mode 100644 index 000000000..48dbd2175 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/ProcessedDataPoint.java @@ -0,0 +1,223 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Vector; +import net.sf.mzmine.datamodel.DataPoint; +import net.sf.mzmine.datamodel.impl.SimpleDataPoint; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPResult; + +/** + * This class stores the results of DataPointProcessingTasks. It offers more functionality, e.g. + * assigning identities. + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public class ProcessedDataPoint extends SimpleDataPoint { + + // this map is set in the add... methods so we don't use too much memory + Vector> results; + + /** + * Generates an array of ProcessedDataPoints from DataPoints. + * + * @param dp DataPoints to convert. + * @return Array of ProcessedDataPoints from DataPoints. + */ + public static ProcessedDataPoint[] convert(DataPoint[] dp) { + if (dp == null) + return new ProcessedDataPoint[0]; + + ProcessedDataPoint[] pdp = new ProcessedDataPoint[dp.length]; + for (int i = 0; i < pdp.length; i++) + pdp[i] = new ProcessedDataPoint(dp[i]); + return pdp; + } + + public ProcessedDataPoint(DataPoint dp) { + super(dp); + } + + public ProcessedDataPoint(DataPoint dp, DPPResult result) { + this(dp); + addResult(result); + } + + public ProcessedDataPoint(DataPoint dp, Collection> results) { + this(dp); + addAllResults(results); + } + + /** + * Adds a single result to this data point. + * + * @param result + */ + public void addResult(DPPResult result) { + if (result == null) + return; + + if (results == null) + results = new Vector>(); + + results.add(result); + } + + /** + * Adds a collection of DPPResults to this data point. + * + * @param results + */ + public void addAllResults(Collection> results) { + if (results == null) + return; + + if (this.results == null) + this.results = new Vector>(); + + for (DPPResult result : results) { + this.results.add(result); + } + } + + public void addAllResults(DPPResult[] result) { + if (result == null) + return; + + if (results == null) + results = new Vector>(); + + for (DPPResult r : result) { + results.add(r); + } + } + + /** + * + * @param i Index of the specified result + * @return DPPResult with the given key, may be null if no result with that key exits or no result + * exists at all. + */ + public DPPResult getResult(int i) { + if (results == null) + return null; + return results.get(i); + } + + /** + * Specifies if a result with the given type exists. + * + * @param type + * @return + */ + public boolean resultTypeExists(DPPResult.ResultType type) { + if (results == null) + return false; + + for (DPPResult r : results) + if (r.getResultType() == type) + return true; + return false; + } + + /** + * The number of results with the given type. + * @param type + * @return + */ + public int getNumberOfResultsByType(DPPResult.ResultType type) { + if (results == null) + return 0; + + int i = 0; + for (DPPResult r : results) + if (r.getResultType() == type) + i++; + + return i; + } + + /** + * + * @return Returns List of all results of the given type. Null if no result exists. + */ + public List> getAllResultsByType(DPPResult.ResultType type) { + if (results == null) + return null; + + List> list = new ArrayList<>(); + + for (DPPResult r : results) { + if (r.getResultType() == type) { + list.add(r); + } + } + + if (list.isEmpty()) + return null; + + return list; + } + + /** + * Returns the first result of the given type. + * @param type + * @return Instance of DPPResult or null if no result of that type exists. + */ + public DPPResult getFirstResultByType(DPPResult.ResultType type){ + if (results == null) + return null; + + for(DPPResult r : results) + if(r.getResultType() == type) + return r; + return null; + } + + public void removeResult(int i) { + results.remove(i); + } + + public void removeResult(DPPResult result) { + results.remove(result); + } + /* + * public boolean equals(ProcessedDataPoint p) { //TODO } + */ + + /** + * @return The number of results + */ + public int getNumberOfResults() { + if (results == null) + return 0; + + return results.size(); + } + + public boolean hasResults() { + if (results == null || results.isEmpty()) + return false; + return true; + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/results/DPPIsotopePatternResult.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/results/DPPIsotopePatternResult.java new file mode 100644 index 000000000..3d42c709f --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/results/DPPIsotopePatternResult.java @@ -0,0 +1,43 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results; + +import net.sf.mzmine.datamodel.IsotopePattern; +/** + * Used to store a detected isotope pattern in a {@link net.sf.mzmine.modules.datapointprocessing.datamodel.ProcessedDataPoint}. + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public class DPPIsotopePatternResult extends DPPResult{ + + public DPPIsotopePatternResult(IsotopePattern value) { + super(value); + } + + @Override + public String toString() { + return "Isotope pattern (" + getValue().getNumberOfDataPoints() + ")"; + } + + @Override + public ResultType getResultType() { + return ResultType.ISOTOPEPATTERN; + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/results/DPPResult.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/results/DPPResult.java new file mode 100644 index 000000000..4039e8ad0 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/results/DPPResult.java @@ -0,0 +1,45 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results; + +/** + * This interface is used to store data point processing results in a {@link net.sf.mzmine.modules.datapointprocessing.datamodel.ProcessedDataPoint} + * When adding a new result type, also add it to the ResultType enum. + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public abstract class DPPResult { + + public enum ResultType {SUMFORMULA, ISOTOPEPATTERN, ADDUCT, FRAGMENT}; + + final T value; + + public DPPResult (T value) { + this.value = value; + } + + public T getValue() { + return value; + } + + public abstract String toString(); + + public abstract ResultType getResultType(); +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/results/DPPResultsDataSet.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/results/DPPResultsDataSet.java new file mode 100644 index 000000000..5f2b6de51 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/results/DPPResultsDataSet.java @@ -0,0 +1,36 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results; + +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.ProcessedDataPoint; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datasets.DataPointsDataSet; + +public class DPPResultsDataSet extends DataPointsDataSet { + + private static final long serialVersionUID = 1L; + + public DPPResultsDataSet(String label, ProcessedDataPoint[] mzPeaks) { + super(label, mzPeaks); + } + + public ProcessedDataPoint[] getDataPoints() { + return (ProcessedDataPoint[]) mzPeaks; + } + +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/results/DPPResultsLabelGenerator.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/results/DPPResultsLabelGenerator.java new file mode 100644 index 000000000..a7726d1c0 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/results/DPPResultsLabelGenerator.java @@ -0,0 +1,122 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results; + +import java.text.NumberFormat; +import org.jfree.data.xy.XYDataset; +import net.sf.mzmine.main.MZmineCore; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.SpectraPlot; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.ProcessedDataPoint; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPResult.ResultType; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datasets.ScanDataSet; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.renderers.SpectraItemLabelGenerator; + +public class DPPResultsLabelGenerator extends SpectraItemLabelGenerator { + + public DPPResultsLabelGenerator(SpectraPlot plot) { + super(plot); + } + + /** + * @see org.jfree.chart.labels.XYItemLabelGenerator#generateLabel(org.jfree.data.xy.XYDataset, + * int, int) + */ + public String generateLabel(XYDataset dataset, int series, int item) { + + // X and Y values of current data point + double originalX = dataset.getX(series, item).doubleValue(); + double originalY = dataset.getY(series, item).doubleValue(); + + // Calculate data size of 1 screen pixel + double xLength = (double) plot.getXYPlot().getDomainAxis().getRange().getLength(); + double pixelX = xLength / plot.getWidth(); + + // Size of data set + int itemCount = dataset.getItemCount(series); + + // Search for data points higher than this one in the interval + // from limitLeft to limitRight + double limitLeft = originalX - ((POINTS_RESERVE_X / 2) * pixelX); + double limitRight = originalX + ((POINTS_RESERVE_X / 2) * pixelX); + + // Iterate data points to the left and right + for (int i = 1; (item - i > 0) || (item + i < itemCount); i++) { + + // If we get out of the limit we can stop searching + if ((item - i > 0) && (dataset.getXValue(series, item - i) < limitLeft) + && ((item + i >= itemCount) || (dataset.getXValue(series, item + i) > limitRight))) + break; + + if ((item + i < itemCount) && (dataset.getXValue(series, item + i) > limitRight) + && ((item - i <= 0) || (dataset.getXValue(series, item - i) < limitLeft))) + break; + + // If we find higher data point, bail out + if ((item - i > 0) && (originalY <= dataset.getYValue(series, item - i))) + return null; + + if ((item + i < itemCount) && (originalY <= dataset.getYValue(series, item + i))) + return null; + + } + + // Create label + String label = null; + if (dataset instanceof ScanDataSet) { + label = ((ScanDataSet) dataset).getAnnotation(item); + } else if (dataset instanceof DPPResultsDataSet) { + label = createLabel(((DPPResultsDataSet) dataset).getDataPoints()[item]); + } + + if (label == null || label.equals("")) { + double mzValue = dataset.getXValue(series, item); + label = mzFormat.format(mzValue); + } + + return label; + } + + private String createLabel(ProcessedDataPoint dp) { + String label = ""; + + if (!dp.hasResults()) + return label; + + NumberFormat mzForm = MZmineCore.getConfiguration().getMZFormat(); + String mz; + String formulas = ""; + mz = mzForm.format(dp.getMZ()); + // System.out.println(dp.getMZ() + " has " + keys.length + " keys " + keys.toString()); + + if (dp.resultTypeExists(ResultType.SUMFORMULA)) { + for (DPPResult r : dp.getAllResultsByType(ResultType.SUMFORMULA)) { + if (r instanceof DPPSumFormulaResult) { + formulas += r.toString() + " "; + } + } + } + + label = mz + " "; + + if (!formulas.equals("")) + label += "\n" + formulas; + + return label; + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/results/DPPSumFormulaResult.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/results/DPPSumFormulaResult.java new file mode 100644 index 000000000..288c89962 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/datamodel/results/DPPSumFormulaResult.java @@ -0,0 +1,64 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results; + +import java.text.DecimalFormat; +import java.text.NumberFormat; + +public class DPPSumFormulaResult extends DPPResult { + + private final double ppm; + private final double score; + + + private static final NumberFormat format = new DecimalFormat("0.00"); + + public DPPSumFormulaResult(String formula, double ppm) { + super(formula); + this.ppm = ppm; + this.score = 0.f; + } + + public DPPSumFormulaResult(String formula, double ppm, double score) { + super(formula); + this.ppm = ppm; + this.score = score; + } + + @Override + public String toString() { + String strScore = ", -"; + if(score != 0.0d) + strScore = ", " + format.format(score * 100.0) + " %"; + return getValue() + " (Δ " + format.format(ppm) + " ppm" + strScore + ")"; + } + + public double getPpm() { + return ppm; + } + + public double getScore() { + return score; + } + + @Override + public ResultType getResultType() { + return ResultType.SUMFORMULA; + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/help/help.html b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/help/help.html new file mode 100644 index 000000000..32dcbf685 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/help/help.html @@ -0,0 +1,45 @@ + + + SP - Spectra Processing + + + + + + +

Spectra Processing

+

General information

+ +

The purpose of this module is quick automated spectra + processing with a defined set of modules and parameters. + This is similar to the batch mode for peak lists. The modules and their parameters can be + configured by opening a scan and pressing the "Spectra processing" button. + Please note, that the aim of this functions is not to identify compounds by looking at a single + spectra. The target is to give the user a quick overview over a specific scan. +

+ +

Processing queue

+

The processing queue is, if enabled, automatically executed sequentially from top to bottom. + Most modules require a mass detection to be run first.

+ +

Adding modules & Setting parameters

+

Modules can be added to the processing queue by double-clicking or pressing the "Add" button. + Modules can be removed from the processing queue by pressing the "Remove" button. + The parameters can be set using the "Set parameters" button or by double-clicking on a module in + the processing queue.

+ +
Displaying results
+

Every module has the parameters "Display results" and "Dataset color". "Display results" specifies + if the results of a module should be displayed in the plot or just be passed to the next module. + The results of the last module in the processing queue will be displayed regardless. + "Dataset color" specifies a color, the results should be displayed with in the spectra plot.

+ +
Troubleshooting
+
Nothing is happening, even though the processing is enabled.
+
Check the parameters or the modules. For example, if the mass detection is set to a specific + noise level for one MS1 scan and the intensities vary between scans, the noise level might be too high. + If switching between MS1 and MS2 scans, this is especially relevant. +
+ + + diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/identification/sumformulaprediction/DPPSumFormulaPredictionModule.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/identification/sumformulaprediction/DPPSumFormulaPredictionModule.java new file mode 100644 index 000000000..8ce33574b --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/identification/sumformulaprediction/DPPSumFormulaPredictionModule.java @@ -0,0 +1,53 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.identification.sumformulaprediction; + +import net.sf.mzmine.datamodel.DataPoint; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.SpectraPlot; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingController; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingModule; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingTask; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.ModuleSubCategory; +import net.sf.mzmine.parameters.ParameterSet; +import net.sf.mzmine.taskcontrol.TaskStatusListener; + +public class DPPSumFormulaPredictionModule implements DataPointProcessingModule { + + @Override + public String getName() { + return "Sum formula prediction"; + } + + @Override + public Class getParameterSetClass() { + return DPPSumFormulaPredictionParameters.class; + } + + @Override + public ModuleSubCategory getModuleSubCategory() { + return ModuleSubCategory.IDENTIFICATION; + } + + @Override + public DataPointProcessingTask createTask(DataPoint[] dataPoints, ParameterSet parameterSet, + SpectraPlot plot, DataPointProcessingController controller, TaskStatusListener listener) { + return new DPPSumFormulaPredictionTask(dataPoints, plot, parameterSet, controller, listener); + } + +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/identification/sumformulaprediction/DPPSumFormulaPredictionParameters.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/identification/sumformulaprediction/DPPSumFormulaPredictionParameters.java new file mode 100644 index 000000000..978125fda --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/identification/sumformulaprediction/DPPSumFormulaPredictionParameters.java @@ -0,0 +1,85 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.identification.sumformulaprediction; + +import java.awt.Color; +import net.sf.mzmine.datamodel.IonizationType; +import net.sf.mzmine.modules.peaklistmethods.identification.formulaprediction.elements.ElementsParameter; +import net.sf.mzmine.modules.peaklistmethods.identification.formulaprediction.restrictions.elements.ElementalHeuristicParameters; +import net.sf.mzmine.modules.peaklistmethods.identification.formulaprediction.restrictions.rdbe.RDBERestrictionParameters; +import net.sf.mzmine.modules.peaklistmethods.isotopes.isotopepatternscore.IsotopePatternScoreParameters; +import net.sf.mzmine.parameters.Parameter; +import net.sf.mzmine.parameters.impl.SimpleParameterSet; +import net.sf.mzmine.parameters.parametertypes.BooleanParameter; +import net.sf.mzmine.parameters.parametertypes.ColorParameter; +import net.sf.mzmine.parameters.parametertypes.ComboParameter; +import net.sf.mzmine.parameters.parametertypes.DoubleParameter; +import net.sf.mzmine.parameters.parametertypes.IntegerParameter; +import net.sf.mzmine.parameters.parametertypes.OptionalParameter; +import net.sf.mzmine.parameters.parametertypes.submodules.OptionalModuleParameter; +import net.sf.mzmine.parameters.parametertypes.tolerances.MZToleranceParameter; + +/** + */ +public class DPPSumFormulaPredictionParameters extends SimpleParameterSet { + + public static final IntegerParameter charge = new IntegerParameter("Charge", "Charge"); + + public static final DoubleParameter noiseLevel = new DoubleParameter("Noise level", + "Minimum intensity of a data point to predict a sum formula for."); + + public static final ComboParameter ionization = + new ComboParameter("Ionization type", "Ionization type", + IonizationType.values()); + + public static final MZToleranceParameter mzTolerance = new MZToleranceParameter(); + + public static final ElementsParameter elements = + new ElementsParameter("Elements", "Elements and ranges"); + + public static final OptionalModuleParameter elementalRatios = + new OptionalModuleParameter("Element count heuristics", + "Restrict formulas by heuristic restrictions of elemental counts and ratios", + new ElementalHeuristicParameters()); + + public static final OptionalModuleParameter rdbeRestrictions = + new OptionalModuleParameter("RDBE restrictions", + "Search only for formulas which correspond to the given RDBE restrictions", + new RDBERestrictionParameters()); + + public static final OptionalModuleParameter isotopeFilter = + new OptionalModuleParameter("Isotope pattern filter", + "Search only for formulas with a isotope pattern similar", + new IsotopePatternScoreParameters()); + + public static final OptionalParameter displayResults = + new OptionalParameter(new IntegerParameter("Display results (#)", + "Check if you want to display the sum formula prediction results in the plot. " + + "Displaying too much datasets might decrease clarity.\nPlease enter the number " + + "of predicted sum formulas, you would like to display.", + 1)); + + public static final ColorParameter datasetColor = new ColorParameter("Dataset color", + "Set the color you want the detected isotope patterns to be displayed with.", Color.BLACK); + + public DPPSumFormulaPredictionParameters() { + super(new Parameter[] {charge, noiseLevel, ionization, mzTolerance, elements, elementalRatios, + rdbeRestrictions, isotopeFilter, displayResults, datasetColor}); + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/identification/sumformulaprediction/DPPSumFormulaPredictionTask.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/identification/sumformulaprediction/DPPSumFormulaPredictionTask.java new file mode 100644 index 000000000..20e7ce224 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/identification/sumformulaprediction/DPPSumFormulaPredictionTask.java @@ -0,0 +1,348 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.identification.sumformulaprediction; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.logging.Logger; +import org.openscience.cdk.formula.MolecularFormulaGenerator; +import org.openscience.cdk.formula.MolecularFormulaRange; +import org.openscience.cdk.interfaces.IChemObjectBuilder; +import org.openscience.cdk.interfaces.IMolecularFormula; +import org.openscience.cdk.silent.SilentChemObjectBuilder; +import org.openscience.cdk.tools.manipulator.MolecularFormulaManipulator; +import com.google.common.collect.Range; +import net.sf.mzmine.datamodel.DataPoint; +import net.sf.mzmine.datamodel.IonizationType; +import net.sf.mzmine.datamodel.IsotopePattern; +import net.sf.mzmine.modules.peaklistmethods.identification.formulaprediction.restrictions.elements.ElementalHeuristicChecker; +import net.sf.mzmine.modules.peaklistmethods.identification.formulaprediction.restrictions.rdbe.RDBERestrictionChecker; +import net.sf.mzmine.modules.peaklistmethods.isotopes.isotopepatternscore.IsotopePatternScoreCalculator; +import net.sf.mzmine.modules.peaklistmethods.isotopes.isotopepatternscore.IsotopePatternScoreParameters; +import net.sf.mzmine.modules.peaklistmethods.isotopes.isotopeprediction.IsotopePatternCalculator; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.SpectraPlot; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingController; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingTask; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.ProcessedDataPoint; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPResult.ResultType; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPResultsDataSet; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPResultsLabelGenerator; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.isotopes.deisotoper.DPPIsotopeGrouperParameters; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.learnermodule.DPPLearnerModuleParameters; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPSumFormulaResult; +import net.sf.mzmine.parameters.ParameterSet; +import net.sf.mzmine.parameters.parametertypes.tolerances.MZTolerance; +import net.sf.mzmine.taskcontrol.TaskStatus; +import net.sf.mzmine.taskcontrol.TaskStatusListener; +import net.sf.mzmine.util.FormulaUtils; +import net.sf.mzmine.util.SpectraPlotUtils; + +/** + * Predicts sum formulas just like + * net.sf.mzmine.modules.peaklistmethods.identification.formulaprediction + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public class DPPSumFormulaPredictionTask extends DataPointProcessingTask { + + private Logger logger = Logger.getLogger(DPPSumFormulaPredictionTask.class.getName()); + + int currentIndex; + + private MZTolerance mzTolerance; + private int foundFormulas = 0; + private IonizationType ionType; + private int charge; + private double noiseLevel; + private boolean checkRatios; + private boolean checkRDBE; + private ParameterSet ratiosParameters; + private ParameterSet rdbeParameters; + private ParameterSet isotopeParameters; + private boolean checkIsotopes; + private int numResults; + + private MolecularFormulaRange elementCounts; + private MolecularFormulaGenerator generator; + private Range massRange; + + public DPPSumFormulaPredictionTask(DataPoint[] dataPoints, SpectraPlot targetPlot, + ParameterSet parameterSet, DataPointProcessingController controller, + TaskStatusListener listener) { + super(dataPoints, targetPlot, parameterSet, controller, listener); + + charge = parameterSet.getParameter(DPPSumFormulaPredictionParameters.charge).getValue(); + noiseLevel = parameterSet.getParameter(DPPSumFormulaPredictionParameters.noiseLevel).getValue(); + ionType = parameterSet.getParameter(DPPSumFormulaPredictionParameters.ionization).getValue(); + + checkRDBE = + parameterSet.getParameter(DPPSumFormulaPredictionParameters.rdbeRestrictions).getValue(); + rdbeParameters = parameterSet.getParameter(DPPSumFormulaPredictionParameters.rdbeRestrictions) + .getEmbeddedParameters(); + + isotopeParameters = parameterSet.getParameter(DPPSumFormulaPredictionParameters.isotopeFilter) + .getEmbeddedParameters(); + + checkIsotopes = + parameterSet.getParameter(DPPSumFormulaPredictionParameters.isotopeFilter).getValue(); + + checkRatios = + parameterSet.getParameter(DPPSumFormulaPredictionParameters.elementalRatios).getValue(); + ratiosParameters = parameterSet.getParameter(DPPSumFormulaPredictionParameters.elementalRatios) + .getEmbeddedParameters(); + + elementCounts = + parameterSet.getParameter(DPPSumFormulaPredictionParameters.elements).getValue(); + + mzTolerance = + parameterSet.getParameter(DPPSumFormulaPredictionParameters.mzTolerance).getValue(); + + setDisplayResults( + parameterSet.getParameter(DPPSumFormulaPredictionParameters.displayResults).getValue()); + setColor(parameterSet.getParameter(DPPSumFormulaPredictionParameters.datasetColor).getValue()); + + numResults = parameterSet.getParameter(DPPSumFormulaPredictionParameters.displayResults) + .getEmbeddedParameter().getValue(); + + currentIndex = 0; + } + + + @Override + public double getFinishedPercentage() { + if (getDataPoints().length == 0) + return 0; + return ((double) currentIndex / getDataPoints().length); + } + + @Override + public void run() { + if(!checkParameterSet() || !checkValues()) { + setStatus(TaskStatus.ERROR); + return; + } + + if (getDataPoints().length == 0) { + logger.info("Data point/Spectra processing: 0 data points were passed to " + + getTaskDescription() + " Please check the parameters."); + setStatus(TaskStatus.CANCELED); + return; + } + + if (!(getDataPoints() instanceof ProcessedDataPoint[])) { + + logger.info("Data point/Spectra processing: The array of data points passed to " + + getTaskDescription() + + " is not an instance of ProcessedDataPoint. Make sure to run mass detection first."); + setStatus(TaskStatus.CANCELED); + return; + } + + setStatus(TaskStatus.PROCESSING); + + IChemObjectBuilder builder = SilentChemObjectBuilder.getInstance(); + + for (int i = 0; i < dataPoints.length; i++) { + + if (isCanceled()) + return; + + if (dataPoints[i].getIntensity() < noiseLevel) + continue; + + massRange = + mzTolerance.getToleranceRange((dataPoints[i].getMZ() - ionType.getAddedMass()) / charge); + generator = new MolecularFormulaGenerator(builder, massRange.lowerEndpoint(), + massRange.upperEndpoint(), elementCounts); + + List formulas = + generateFormulas((ProcessedDataPoint) dataPoints[i], massRange, charge, generator); + + DPPSumFormulaResult[] results = genereateResults(formulas, numResults); + + ((ProcessedDataPoint) dataPoints[i]).addAllResults(results); + currentIndex++; + } + + setResults((ProcessedDataPoint[]) dataPoints); + setStatus(TaskStatus.FINISHED); + } + + + private class PredResult { + public double ppm; + public String formula; + public double score; + + PredResult(double ppm, String formula) { + this.ppm = ppm; + this.formula = formula; + } + + PredResult(double ppm, String formula, double score) { + this.ppm = ppm; + this.formula = formula; + this.score = score; + } + } + + /** + * Predicts sum formulas for a given m/z and parameters. + * + * @param mz m/z to generate sum formulas from + * @param massRange Mass range for sum formulas + * @param charge Charge of the molecule + * @param generator instance of MolecularFormulaGenerator + * @return List sorted by relative ppm difference and String of the formula. + */ + private List generateFormulas(ProcessedDataPoint dp, Range massRange, + int charge, MolecularFormulaGenerator generator) { + + List possibleFormulas = new ArrayList<>(); + + IMolecularFormula cdkFormula; + + while ((cdkFormula = generator.getNextFormula()) != null) { + + // Mass is ok, so test other constraints + if (!checkConstraints(cdkFormula)) + continue; + + String formula = MolecularFormulaManipulator.getString(cdkFormula); + + // calc rel mass deviation + Double relMassDev = ((((dp.getMZ() - // + ionType.getAddedMass()) / charge)// + - (FormulaUtils.calculateExactMass(// + MolecularFormulaManipulator.getString(cdkFormula))) / charge) + / ((dp.getMZ() // + - ionType.getAddedMass()) / charge)) + * 1000000; + + // write to map + if (checkIsotopes && dp.resultTypeExists(ResultType.ISOTOPEPATTERN)) { + double score = getIsotopeSimilarityScore(cdkFormula, + (IsotopePattern) dp.getFirstResultByType(ResultType.ISOTOPEPATTERN).getValue()); + possibleFormulas.add(new PredResult(relMassDev, formula, score)); + } else { + possibleFormulas.add(new PredResult(relMassDev, formula)); + } + } + + // sort by score or ppm + if (checkIsotopes && dp.resultTypeExists(ResultType.ISOTOPEPATTERN)) { + possibleFormulas.sort((Comparator) (PredResult o1, PredResult o2) -> { + return -1 * Double.compare(Math.abs(o1.score), Math.abs(o2.score)); // *-1 to sort + // descending + }); + } else { + possibleFormulas.sort((Comparator) (PredResult o1, PredResult o2) -> { + return Double.compare(Math.abs(o1.ppm), Math.abs(o2.ppm)); + }); + } + + return possibleFormulas; + } + + private DPPSumFormulaResult[] genereateResults(List formulas, int n) { + if (formulas.size() < n) + n = formulas.size(); + + DPPSumFormulaResult[] results = new DPPSumFormulaResult[n]; + + for (int i = 0; i < results.length; i++) { + results[i] = new DPPSumFormulaResult(formulas.get(i).formula, formulas.get(i).ppm, + formulas.get(i).score); + } + + return results; + } + + private double getIsotopeSimilarityScore(IMolecularFormula cdkFormula, + IsotopePattern detectedPattern) { + + IsotopePattern predictedIsotopePattern = null; + Double isotopeScore = null; + String stringFormula = MolecularFormulaManipulator.getString(cdkFormula); + + String adjustedFormula = FormulaUtils.ionizeFormula(stringFormula, ionType, charge); + + final double isotopeNoiseLevel = + isotopeParameters.getParameter(IsotopePatternScoreParameters.isotopeNoiseLevel).getValue(); + + final double detectedPatternHeight = detectedPattern.getHighestDataPoint().getIntensity(); + + final double minPredictedAbundance = isotopeNoiseLevel / detectedPatternHeight; + + predictedIsotopePattern = IsotopePatternCalculator.calculateIsotopePattern(adjustedFormula, + minPredictedAbundance, charge, ionType.getPolarity()); + + isotopeScore = IsotopePatternScoreCalculator.getSimilarityScore(detectedPattern, + predictedIsotopePattern, isotopeParameters); + + return isotopeScore; + } + + private boolean checkConstraints(IMolecularFormula cdkFormula) { + + // Check elemental ratios + if (checkRatios) { + boolean check = ElementalHeuristicChecker.checkFormula(cdkFormula, ratiosParameters); + if (!check) + return false; + } + + Double rdbeValue = RDBERestrictionChecker.calculateRDBE(cdkFormula); + + // Check RDBE condition + if (checkRDBE && (rdbeValue != null)) { + boolean check = RDBERestrictionChecker.checkRDBE(rdbeValue, rdbeParameters); + if (!check) + return false; + } + + return true; + } + + @Override + public void cancel() { + super.cancel(); + + // We need to cancel the formula generator, because searching for next + // candidate formula may take a looong time + if (generator != null) + generator.cancel(); + + } + + @Override + public void displayResults() { + if (displayResults || getController().isLastTaskRunning()) { + SpectraPlotUtils.clearDatasetLabelGenerators(getTargetPlot(), DPPResultsDataSet.class); + DPPResultsLabelGenerator labelGen = new DPPResultsLabelGenerator(getTargetPlot()); + getTargetPlot().addDataSet( + new DPPResultsDataSet("Sum formula prediction results (" + getResults().length + ")", + getResults()), + color, false, labelGen); + } + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/identification/sumformulaprediction/help/help.html b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/identification/sumformulaprediction/help/help.html new file mode 100644 index 000000000..bef0e994f --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/identification/sumformulaprediction/help/help.html @@ -0,0 +1,61 @@ + + + SP - Identification - Formula prediction + + + + + + +

Formula prediction

+ +

Description

+ +

+ This module attempts to calculate all possible molecular formulas for a data point, + using given elemental and heuristic constraints. For a detailed description of the + functionality and the embedded algorithms, please see the following publication:
+ Pluskal T. et al, Highly Accurate Chemical Formula Prediction Tool Utilizing High-Resolution Mass + Spectra, MS/MS Fragmentation, Heuristic Rules, and Isotope Pattern Matching. + Anal Chem (2012), 84(10):4396-403. +

+ +

Method parameters

+
+
Charge
+
The predicted charge of peaks to calculate the neutral mass.
+ +
Noise level
+
The minimum intensity of peaks to calculate a sum formula of.
+ +
Ionisation
+
The predicted ionisation of peaks. E.g. [M+] or [M+NH4]+
+ +
Neutral mass
+
The neutral mass is calculated from the peak m/z value, its charge and type of ionization adduct.
+ +
m/z tolerance
+
Tolerance of the neutral mass for searching the formula.
+ +
Elements
+
Elements allowed in the formula and their minimum and maximum counts.
+ +
Element count heuristics
+
Selection of heuristic restrictions on element counts.
+ +
RDBE restrictions
+
Selection of restrictions on RDBE (rings double bonds) values. .
+ +
Isotope pattern filter
+
If selected, only results which fit the required isotope pattern similarity score will be returned. Furthermore, the results will be ranked by descending isotope pattern score.
+ +
Display results
+
If enabled, the result will be displayed in the spectrum plot. If this is the last module in the processing list, the results will be displayed in any way.
+ +
Dataset color
+
Select the color, the results of this module shall be displayed in.
+ +
+ + + diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/isotopes/deisotoper/DPPIsotopeGrouperModule.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/isotopes/deisotoper/DPPIsotopeGrouperModule.java new file mode 100644 index 000000000..f7d9daeaf --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/isotopes/deisotoper/DPPIsotopeGrouperModule.java @@ -0,0 +1,52 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.isotopes.deisotoper; + +import net.sf.mzmine.datamodel.DataPoint; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.SpectraPlot; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingController; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingModule; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingTask; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.ModuleSubCategory; +import net.sf.mzmine.parameters.ParameterSet; +import net.sf.mzmine.taskcontrol.TaskStatusListener; + +public class DPPIsotopeGrouperModule implements DataPointProcessingModule { + + @Override + public String getName() { + return "13C-Isotope grouper"; + } + + @Override + public Class getParameterSetClass() { + return DPPIsotopeGrouperParameters.class; + } + + @Override + public ModuleSubCategory getModuleSubCategory() { + return ModuleSubCategory.ISOTOPES; + } + + @Override + public DataPointProcessingTask createTask(DataPoint[] dataPoints, ParameterSet parameterSet, + SpectraPlot plot, DataPointProcessingController controller, TaskStatusListener listener) { + return new DPPIsotopeGrouperTask(dataPoints, plot, parameterSet, controller, listener); + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/isotopes/deisotoper/DPPIsotopeGrouperParameters.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/isotopes/deisotoper/DPPIsotopeGrouperParameters.java new file mode 100644 index 000000000..c0012e12f --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/isotopes/deisotoper/DPPIsotopeGrouperParameters.java @@ -0,0 +1,70 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.isotopes.deisotoper; + +import java.awt.Color; +import net.sf.mzmine.parameters.Parameter; +import net.sf.mzmine.parameters.impl.SimpleParameterSet; +import net.sf.mzmine.parameters.parametertypes.BooleanParameter; +import net.sf.mzmine.parameters.parametertypes.ColorParameter; +import net.sf.mzmine.parameters.parametertypes.ComboParameter; +import net.sf.mzmine.parameters.parametertypes.IntegerParameter; +import net.sf.mzmine.parameters.parametertypes.StringParameter; +import net.sf.mzmine.parameters.parametertypes.tolerances.MZToleranceParameter; + +public class DPPIsotopeGrouperParameters extends SimpleParameterSet { + + public static final String ChooseTopIntensity = "Most intense"; + public static final String ChooseLowestMZ = "Lowest m/z"; + + public static final String[] representativeIsotopeValues = {ChooseTopIntensity, ChooseLowestMZ}; + +// public static final StringParameter element = new StringParameter("Element", "Element symbol of the element to deisotope for."); + + public static final MZToleranceParameter mzTolerance = new MZToleranceParameter(); + + public static final BooleanParameter monotonicShape = new BooleanParameter("Monotonic shape", + "If true, then monotonically decreasing height of isotope pattern is required"); + + public static final IntegerParameter maximumCharge = new IntegerParameter("Maximum charge", + "Maximum charge to consider for detecting the isotope patterns"); + + public static final ComboParameter representativeIsotope = new ComboParameter( + "Representative isotope", + "Which peak should represent the whole isotope pattern. For small molecular weight\n" + + "compounds with monotonically decreasing isotope pattern, the most intense isotope\n" + + "should be representative. For high molecular weight peptides, the lowest m/z\n" + + "peptides, the lowest m/z isotope may be the representative.", + representativeIsotopeValues); + + public static final BooleanParameter autoRemove = new BooleanParameter("Remove non-isotopes", + "If checked, all peaks without an isotope pattern will not be displayed and not passed to the next module."); + + public static final BooleanParameter displayResults = new BooleanParameter("Display results", + "Check if you want to display the deisotoping results in the plot. Displaying too much datasets might decrease clarity.", false); + + public static final ColorParameter datasetColor = new ColorParameter("Dataset color", + "Set the color you want the detected isotope patterns to be displayed with.", Color.GREEN); + + public DPPIsotopeGrouperParameters() { + super(new Parameter[] {/*element,*/ mzTolerance, monotonicShape, + maximumCharge, representativeIsotope, autoRemove, displayResults, datasetColor}); + } + +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/isotopes/deisotoper/DPPIsotopeGrouperTask.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/isotopes/deisotoper/DPPIsotopeGrouperTask.java new file mode 100644 index 000000000..4191e08da --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/isotopes/deisotoper/DPPIsotopeGrouperTask.java @@ -0,0 +1,344 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.isotopes.deisotoper; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Vector; +import java.util.logging.Logger; +import net.sf.mzmine.datamodel.DataPoint; +import net.sf.mzmine.datamodel.IsotopePattern; +import net.sf.mzmine.datamodel.IsotopePattern.IsotopePatternStatus; +import net.sf.mzmine.datamodel.PolarityType; +import net.sf.mzmine.datamodel.impl.SimpleIsotopePattern; +import net.sf.mzmine.modules.peaklistmethods.isotopes.isotopeprediction.IsotopePatternCalculator; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.SpectraPlot; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingController; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingTask; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.ProcessedDataPoint; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPIsotopePatternResult; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPResult.ResultType; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPResultsDataSet; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datasets.IsotopesDataSet; +import net.sf.mzmine.parameters.ParameterSet; +import net.sf.mzmine.parameters.parametertypes.tolerances.MZTolerance; +import net.sf.mzmine.taskcontrol.TaskStatus; +import net.sf.mzmine.taskcontrol.TaskStatusListener; +import net.sf.mzmine.util.FormulaUtils; + +/** + * + * This is basically copy-pasted from + * net.sf.mzmine.modules.peaklistmethods.isotopes.deisotoper.IsotopeGrouperTask + * + */ +public class DPPIsotopeGrouperTask extends DataPointProcessingTask { + + private static Logger logger = Logger.getLogger(DPPIsotopeGrouperTask.class.getName()); + + // peaks counter + private int processedPeaks, totalPeaks; + + // parameter values + private MZTolerance mzTolerance; + private boolean monotonicShape; + private int maximumCharge; + private String element = "C"; + private boolean autoRemove; + + public DPPIsotopeGrouperTask(DataPoint[] dataPoints, SpectraPlot plot, ParameterSet parameterSet, + DataPointProcessingController controller, TaskStatusListener listener) { + super(dataPoints, plot, parameterSet, controller, listener); + + // Get parameter values for easier use + mzTolerance = parameterSet.getParameter(DPPIsotopeGrouperParameters.mzTolerance).getValue(); + monotonicShape = + parameterSet.getParameter(DPPIsotopeGrouperParameters.monotonicShape).getValue(); + maximumCharge = parameterSet.getParameter(DPPIsotopeGrouperParameters.maximumCharge).getValue(); + // element = parameterSet.getParameter(DPPIsotopeGrouperParameters.element).getValue(); + autoRemove = parameterSet.getParameter(DPPIsotopeGrouperParameters.autoRemove).getValue(); + setDisplayResults( + parameterSet.getParameter(DPPIsotopeGrouperParameters.displayResults).getValue()); + setColor(parameterSet.getParameter(DPPIsotopeGrouperParameters.datasetColor).getValue()); + } + + + @Override + public void run() { + if(!checkParameterSet() || !checkValues()) { + setStatus(TaskStatus.ERROR); + return; + } + + if (!FormulaUtils.checkMolecularFormula(element)) { + setStatus(TaskStatus.ERROR); + logger.warning("Data point/Spectra processing: Invalid element parameter in " + getTaskDescription()); + } + + if (getDataPoints().length == 0) { + logger.info("Data point/Spectra processing: 0 data points were passed to " + getTaskDescription() + + " Please check the parameters."); + setStatus(TaskStatus.CANCELED); + return; + } + + if (!(getDataPoints() instanceof ProcessedDataPoint[])) { + logger.warning( + "Data point/Spectra processing: The data points passed to Isotope Grouper were not an instance of processed data points." + + " Make sure to run mass detection first."); + setStatus(TaskStatus.CANCELED); + return; + } + + setStatus(TaskStatus.PROCESSING); + + ProcessedDataPoint[] dataPoints = (ProcessedDataPoint[]) getDataPoints(); + + int charges[] = new int[maximumCharge]; + for (int i = 0; i < maximumCharge; i++) + charges[i] = i + 1; + + IsotopePattern pattern = + IsotopePatternCalculator.calculateIsotopePattern(element, 0.01, 1, PolarityType.POSITIVE); + double isotopeDistance = + pattern.getDataPoints()[1].getMZ() - pattern.getDataPoints()[0].getMZ(); + + ProcessedDataPoint[] sortedDataPoints = dataPoints.clone(); + Arrays.sort(sortedDataPoints, (d1, d2) -> { + return -1 * Double.compare(d1.getIntensity(), d2.getIntensity()); // *-1 to sort descending + }); + + List deisotopedDataPoints = new ArrayList<>(); + + for (int i = 0; i < sortedDataPoints.length; i++) { + if (isCanceled()) + return; + + DataPoint aPeak = sortedDataPoints[i]; + + if (aPeak == null) { + processedPeaks++; + continue; + } + + // Check which charge state fits best around this peak + int bestFitCharge = 0; + int bestFitScore = -1; + Vector bestFitPeaks = null; + for (int charge : charges) { + + Vector fittedPeaks = new Vector(); + fittedPeaks.add(aPeak); + fitPattern(fittedPeaks, aPeak, charge, sortedDataPoints, isotopeDistance); + + int score = fittedPeaks.size(); + if ((score > bestFitScore) || ((score == bestFitScore) && (bestFitCharge > charge))) { + bestFitScore = score; + bestFitCharge = charge; + bestFitPeaks = fittedPeaks; + } + } + + assert bestFitPeaks != null; + + // Verify the number of detected isotopes. If there is only one + // isotope, we skip this left the original peak in the peak list. + if (bestFitPeaks.size() == 1) { + if (!autoRemove) + deisotopedDataPoints.add(sortedDataPoints[i]); + processedPeaks++; + continue; + } + + DataPoint[] originalPeaks = bestFitPeaks.toArray(new DataPoint[0]); + SimpleIsotopePattern newPattern = + new SimpleIsotopePattern(originalPeaks, IsotopePatternStatus.DETECTED, aPeak.toString()); + + sortedDataPoints[i].addResult(new DPPIsotopePatternResult(newPattern)); + deisotopedDataPoints.add(sortedDataPoints[i]); + + // logger.info("Found isotope pattern for m/z " + dataPoints[i].getMZ() + " size: " + // + newPattern.getNumberOfDataPoints()); + + for (int j = 0; j < sortedDataPoints.length; j++) { + if (bestFitPeaks.contains(sortedDataPoints[j])) + sortedDataPoints[j] = null; + } + + // Update completion rate + processedPeaks++; + } + + deisotopedDataPoints.sort((d1, d2) -> { + return Double.compare(d1.getMZ(), d2.getMZ()); + }); + + setResults(deisotopedDataPoints.toArray(new ProcessedDataPoint[0])); + setStatus(TaskStatus.FINISHED); + } + + /** + * Fits isotope pattern around one peak. + * + * @param p Pattern is fitted around this peak + * @param charge Charge state of the fitted pattern + */ + private void fitPattern(Vector fittedPeaks, DataPoint p, int charge, + DataPoint[] sortedPeaks, double isotopeDistance) { + + if (charge == 0) { + return; + } + + // Search for peaks before the start peak + if (!monotonicShape) { + fitHalfPattern(p, charge, -1, fittedPeaks, sortedPeaks, isotopeDistance); + } + + // Search for peaks after the start peak + fitHalfPattern(p, charge, 1, fittedPeaks, sortedPeaks, isotopeDistance); + + } + + /** + * Helper method for fitPattern. Fits only one half of the pattern. + * + * @param p Pattern is fitted around this peak + * @param charge Charge state of the fitted pattern + * @param direction Defines which half to fit: -1=fit to peaks before start M/Z, +1=fit to peaks + * after start M/Z + * @param fittedPeaks All matching peaks will be added to this set + */ + private void fitHalfPattern(DataPoint p, int charge, int direction, Vector fittedPeaks, + DataPoint[] sortedPeaks, double isotopeDistance) { + + // Use M/Z and RT of the strongest peak of the pattern (peak 'p') + double mainMZ = p.getMZ(); + // double mainRT = p.getRT(); + + // Variable n is the number of peak we are currently searching. 1=first + // peak before/after start peak, 2=peak before/after previous, 3=... + boolean followingPeakFound; + int n = 1; + do { + + // Assume we don't find match for n:th peak in the pattern (which + // will end the loop) + followingPeakFound = false; + + // Loop through all peaks, and collect candidates for the n:th peak + // in the pattern + Vector goodCandidates = new Vector(); + for (int ind = 0; ind < sortedPeaks.length; ind++) { + + DataPoint candidatePeak = sortedPeaks[ind]; + + if (candidatePeak == null) + continue; + + // Get properties of the candidate peak + double candidatePeakMZ = candidatePeak.getMZ(); + // double candidatePeakRT = candidatePeak.getRT(); + + // Does this peak fill all requirements of a candidate? + // - within tolerances from the expected location (M/Z and RT) + // - not already a fitted peak (only necessary to avoid + // conflicts when parameters are set too wide) + double isotopeMZ = candidatePeakMZ - isotopeDistance * direction * n / (double) charge; + + if (mzTolerance.checkWithinTolerance(isotopeMZ, mainMZ) + // && rtTolerance.checkWithinTolerance(candidatePeakRT, mainRT) + && (!fittedPeaks.contains(candidatePeak))) { + goodCandidates.add(candidatePeak); + + } + + } + + // Add all good candidates to the isotope pattern (note: in MZmine + // 2.3 and older, only the highest candidate was added) + if (!goodCandidates.isEmpty()) { + + fittedPeaks.addAll(goodCandidates); + + // n:th peak was found, so let's move on to n+1 + n++; + followingPeakFound = true; + } + + } while (followingPeakFound); + + } + + + /* + * @Override public String getTaskDescription() { return "Deisotoping of Scan #" + + * getTargetPlot().getMainScanDataSet().getScan().getScanNumber(); } + */ + + @Override + public double getFinishedPercentage() { + if (getDataPoints().length == 0) + return 0.0f; + return (double) processedPeaks / (double) getDataPoints().length; + } + + @Override + public void displayResults() { + if (isDisplayResults() || getController().isLastTaskRunning()) { + getTargetPlot().addDataSet( + new DPPResultsDataSet("Isotopes (" + getResults().length + ")", getResults()), getColor(), + false); + } + } + + /** + * This method generates a single IsotopesDataSet from all detected isotope patterns in the + * results. + * + * @param dataPoints + * @return + */ + private IsotopesDataSet compressIsotopeDataSets(ProcessedDataPoint[] dataPoints) { + List list = new ArrayList<>(); + + for (ProcessedDataPoint dp : dataPoints) { + if (dp.resultTypeExists(ResultType.ISOTOPEPATTERN)) { + list.add(((DPPIsotopePatternResult) dp.getFirstResultByType(ResultType.ISOTOPEPATTERN)) + .getValue()); + } + } + if (list.isEmpty()) + return null; + + List dpList = new ArrayList<>(); + + for (IsotopePattern pattern : list) { + for (DataPoint dp : pattern.getDataPoints()) + dpList.add(dp); + } + if (dpList.isEmpty()) + return null; + + IsotopePattern full = new SimpleIsotopePattern(dpList.toArray(new DataPoint[0]), + IsotopePatternStatus.DETECTED, "Isotope patterns"); + return new IsotopesDataSet(full); + } +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/isotopes/deisotoper/help/help.html b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/isotopes/deisotoper/help/help.html new file mode 100644 index 000000000..7f3ea61dc --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/isotopes/deisotoper/help/help.html @@ -0,0 +1,69 @@ + + + SP - Isotopes - Isotopic peaks grouper + + + + + + +

Isotopic peaks grouper

+ +

Description

+ +

+This module attempts to find those peaks in a scan, which form an isotope pattern. +When isotope pattern is found, the information about the charge and isotope ratios is saved, and additional isotopic peaks are removed from the peak list. +Only the highest/lightest isotopic peak is kept. +

+ +

Method parameters

+
+ +
m/z tolerance
+
Maximum distance in m/z from the expected location of a peak
+ +
Monotonic shape
+
If true, then monotonically decreasing height of isotope pattern is required
+ +
Maximum charge
+
Maximum charge to consider for detecting the isotope patterns
+ +
Representative isotope
+
Which peak should represent the whole isotope pattern. For small molecular weight + compounds with monotonically decreasing isotope pattern, the most intense isotope + should be representative. For high molecular weight peptides, the lowest m/z + peptides, the lowest m/z isotope may be the representative.
+ +
Remove non-isotopes
+
If checked, all peaks without an isotope pattern will not be displayed and not passed to the next module.
+ +
Display results
+
If enabled, the result will be displayed in the spectrum plot. If this is the last module in the processing list, the results will be displayed in any way.
+ +
Dataset color
+
Select the color, the results of this module shall be displayed in.
+ +

Deisotoping algorithm

+ +

+Peaks in the peak list are processed in the order of decreasing height. +For each peak, MZmine tries to find the most appropriate charge state by comparing the number of identified isotopes for each possible charge. +For each charge state, peaks which fit the m/z and RT distance limits are considered as isotopes. +The charge state with the highest number of identified isotopes is selected, and the isotope pattern is generated. +

+ +

Mass difference between isotopes

+ +

+The difference between neighboring isotopes is a single neutron. +The exact mass of 1 neutron is 1.008665 Da, but part of this mass is +consumed as a binding energy to other nucleons. +This small difference may become significant with high-resolution MS data. +The actual mass difference between isotopes depends on the chemical formula of the molecule. +Since MZmine does not know the formula at the time of deisotoping, it assumes the default distance +of ~1.0033 Da, with user-defined tolerance (the m/z tolerance parameter). +

+ + + diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/learnermodule/DPPLearnerModule.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/learnermodule/DPPLearnerModule.java new file mode 100644 index 000000000..c51dd2812 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/learnermodule/DPPLearnerModule.java @@ -0,0 +1,66 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.learnermodule; + +import net.sf.mzmine.datamodel.DataPoint; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.SpectraPlot; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingController; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingModule; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingTask; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.ModuleSubCategory; +import net.sf.mzmine.parameters.ParameterSet; +import net.sf.mzmine.taskcontrol.TaskStatusListener; + +/** + * New modules need to implement DataPointProcessingModules. To make them show up in the list of + * addable modules, they have to be added in the MZmineModulesList.java + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public class DPPLearnerModule implements DataPointProcessingModule { + + @Override + public String getName() { + return "Learner module"; + } + + @Override + public Class getParameterSetClass() { + + return DPPLearnerModuleParameters.class; + } + + @Override + public DataPointProcessingTask createTask(DataPoint[] dataPoints, ParameterSet parameterSet, + SpectraPlot plot, DataPointProcessingController controller, TaskStatusListener listener) { + + return new DPPLearnerModuleTask(dataPoints, plot, parameterSet, controller, listener); + } + + /** + * Additional module categories can be added in {@link ModuleSubCategory}. The module is + * classified by this value and listed accordingly in the tree view of the ProcessingComponent. + */ + @Override + public ModuleSubCategory getModuleSubCategory() { + return ModuleSubCategory.IDENTIFICATION; + } + +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/learnermodule/DPPLearnerModuleParameters.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/learnermodule/DPPLearnerModuleParameters.java new file mode 100644 index 000000000..c656c1940 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/learnermodule/DPPLearnerModuleParameters.java @@ -0,0 +1,57 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.learnermodule; + +import java.awt.Color; +import net.sf.mzmine.modules.rawdatamethods.peakpicking.massdetection.MassDetector; +import net.sf.mzmine.modules.rawdatamethods.peakpicking.massdetection.centroid.CentroidMassDetector; +import net.sf.mzmine.modules.rawdatamethods.peakpicking.massdetection.exactmass.ExactMassDetector; +import net.sf.mzmine.modules.rawdatamethods.peakpicking.massdetection.localmaxima.LocalMaxMassDetector; +import net.sf.mzmine.modules.rawdatamethods.peakpicking.massdetection.recursive.RecursiveMassDetector; +import net.sf.mzmine.modules.rawdatamethods.peakpicking.massdetection.wavelet.WaveletMassDetector; +import net.sf.mzmine.parameters.Parameter; +import net.sf.mzmine.parameters.impl.SimpleParameterSet; +import net.sf.mzmine.parameters.parametertypes.BooleanParameter; +import net.sf.mzmine.parameters.parametertypes.ColorParameter; +import net.sf.mzmine.parameters.parametertypes.DoubleParameter; +import net.sf.mzmine.parameters.parametertypes.ModuleComboParameter; + +/** + * This is an example class for a new DataPointProcessingModule. Every parameter set should contain + * the parameters "Display results" and "Dataset color", so the user can specify, if and how the + * results should be displayed in the plot. + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public class DPPLearnerModuleParameters extends SimpleParameterSet { + + + public static final BooleanParameter displayResults = new BooleanParameter("Display results", + "Check if you want to display the mass detection results in the plot. Displaying too much datasets might decrease clarity.", + false); + + public static final ColorParameter datasetColor = new ColorParameter("Dataset color", + "Set the color you want the detected isotope patterns to be displayed with.", Color.CYAN); + + public DPPLearnerModuleParameters() { + super(new Parameter[] {displayResults, datasetColor}); + } + +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/learnermodule/DPPLearnerModuleTask.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/learnermodule/DPPLearnerModuleTask.java new file mode 100644 index 000000000..ce71bebca --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/learnermodule/DPPLearnerModuleTask.java @@ -0,0 +1,100 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.learnermodule; + +import net.sf.mzmine.datamodel.DataPoint; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.SpectraPlot; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingController; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingTask; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.ProcessedDataPoint; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPResultsDataSet; +import net.sf.mzmine.parameters.ParameterSet; +import net.sf.mzmine.taskcontrol.TaskStatus; +import net.sf.mzmine.taskcontrol.TaskStatusListener; + +/** + * This is the heart of every DataPointProcessingModule, the actual task being executed. Every new + * implementation of DataPointProcessingTask should use this basic structure to function + * accordingly. + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + */ +public class DPPLearnerModuleTask extends DataPointProcessingTask { + + int currentIndex; + + DPPLearnerModuleTask(DataPoint[] dataPoints, SpectraPlot targetPlot, ParameterSet parameterSet, + DataPointProcessingController controller, TaskStatusListener listener) { + // call the super constructor, this is important to set up the class-wide variables. + super(dataPoints, targetPlot, parameterSet, controller, listener); + currentIndex = 0; + + // since these parameters are acquired by the parameter set, they have to be set here manually. + setDisplayResults( + parameterSet.getParameter(DPPLearnerModuleParameters.displayResults).getValue()); + setColor(parameterSet.getParameter(DPPLearnerModuleParameters.datasetColor).getValue()); + } + + + @Override + public double getFinishedPercentage() { + if (getDataPoints().length == 0) + return 0; + return currentIndex / getDataPoints().length; + } + + @Override + public void run() { + + // check the parameter set and constructor values first, and back out, if they are invalid. + // error messages are set within these convenience methods. + if (!checkParameterSet() || !checkValues()) { + setStatus(TaskStatus.ERROR); + return; + } + + // check if this task has been cancelled by now + if (getStatus() == TaskStatus.CANCELED) { + return; + } + + // set status to processing and start + setStatus(TaskStatus.PROCESSING); + + // do your processing now + + ProcessedDataPoint[] dp = new ProcessedDataPoint[0]; + + // it is CRUCIAL the results are being set in general, and it is crucial they are set BEFORE the + // status of this task is set to FINISHED, because the status listener will start the next task. + setResults(dp); + setStatus(TaskStatus.FINISHED); + } + + @Override + public void displayResults() { + // if this is the last task, display even if not checked. + if (getController().isLastTaskRunning() || isDisplayResults()) { + getTargetPlot().addDataSet(new DPPResultsDataSet( + "Mass detection results (" + getResults().length + ")", getResults()), getColor(), false); + } + } + +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/massdetection/DPPMassDetectionModule.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/massdetection/DPPMassDetectionModule.java new file mode 100644 index 000000000..b0dcbf525 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/massdetection/DPPMassDetectionModule.java @@ -0,0 +1,55 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.massdetection; + +import net.sf.mzmine.datamodel.DataPoint; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.SpectraPlot; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingController; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingModule; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingTask; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.ModuleSubCategory; +import net.sf.mzmine.parameters.ParameterSet; +import net.sf.mzmine.taskcontrol.TaskStatusListener; + +public class DPPMassDetectionModule implements DataPointProcessingModule { + + @Override + public String getName() { + return "Mass detection"; + } + + @Override + public Class getParameterSetClass() { + + return DPPMassDetectionParameters.class; + } + + @Override + public DataPointProcessingTask createTask(DataPoint[] dataPoints, ParameterSet parameterSet, + SpectraPlot plot, DataPointProcessingController controller, TaskStatusListener listener) { + + return new DPPMassDetectionTask(dataPoints, plot, parameterSet, controller, listener); + } + + @Override + public ModuleSubCategory getModuleSubCategory() { + return ModuleSubCategory.MASSDETECTION; + } + +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/massdetection/DPPMassDetectionParameters.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/massdetection/DPPMassDetectionParameters.java new file mode 100644 index 000000000..866fbfae9 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/massdetection/DPPMassDetectionParameters.java @@ -0,0 +1,56 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.massdetection; + +import java.awt.Color; +import net.sf.mzmine.modules.rawdatamethods.peakpicking.massdetection.MassDetector; +import net.sf.mzmine.modules.rawdatamethods.peakpicking.massdetection.centroid.CentroidMassDetector; +import net.sf.mzmine.modules.rawdatamethods.peakpicking.massdetection.exactmass.ExactMassDetector; +import net.sf.mzmine.modules.rawdatamethods.peakpicking.massdetection.localmaxima.LocalMaxMassDetector; +import net.sf.mzmine.modules.rawdatamethods.peakpicking.massdetection.recursive.RecursiveMassDetector; +import net.sf.mzmine.modules.rawdatamethods.peakpicking.massdetection.wavelet.WaveletMassDetector; +import net.sf.mzmine.parameters.Parameter; +import net.sf.mzmine.parameters.impl.SimpleParameterSet; +import net.sf.mzmine.parameters.parametertypes.BooleanParameter; +import net.sf.mzmine.parameters.parametertypes.ColorParameter; +import net.sf.mzmine.parameters.parametertypes.DoubleParameter; +import net.sf.mzmine.parameters.parametertypes.ModuleComboParameter; + +public class DPPMassDetectionParameters extends SimpleParameterSet { + + public static final MassDetector massDetectors[] = + {new CentroidMassDetector(), new ExactMassDetector(), new LocalMaxMassDetector(), + new RecursiveMassDetector(), new WaveletMassDetector()}; + + public static final ModuleComboParameter massDetector = + new ModuleComboParameter("Mass detector", + "Algorithm to use for mass detection and its parameters", massDetectors); + + public static final BooleanParameter displayResults = new BooleanParameter("Display results", + "Check if you want to display the mass detection results in the plot. Displaying too much datasets might decrease clarity.", + false); + + public static final ColorParameter datasetColor = new ColorParameter("Dataset color", + "Set the color you want the detected isotope patterns to be displayed with.", Color.CYAN); + + public DPPMassDetectionParameters() { + super(new Parameter[] {massDetector, displayResults, datasetColor}); + } + +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/massdetection/DPPMassDetectionTask.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/massdetection/DPPMassDetectionTask.java new file mode 100644 index 000000000..6966de737 --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/massdetection/DPPMassDetectionTask.java @@ -0,0 +1,100 @@ +/* + * Copyright 2006-2018 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.modules.visualization.spectra.simplespectra.datapointprocessing.massdetection; + +import org.jmol.util.Logger; +import net.sf.mzmine.datamodel.DataPoint; +import net.sf.mzmine.modules.MZmineProcessingStep; +import net.sf.mzmine.modules.rawdatamethods.peakpicking.massdetection.MassDetector; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.SpectraPlot; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingController; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingTask; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.ProcessedDataPoint; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.results.DPPResultsDataSet; +import net.sf.mzmine.parameters.ParameterSet; +import net.sf.mzmine.taskcontrol.TaskStatus; +import net.sf.mzmine.taskcontrol.TaskStatusListener; + +public class DPPMassDetectionTask extends DataPointProcessingTask { + + int currentIndex; + // private MZmineProcessingStep pMassDetector; + private MZmineProcessingStep massDetector; + + DPPMassDetectionTask(DataPoint[] dataPoints, SpectraPlot targetPlot, ParameterSet parameterSet, + DataPointProcessingController controller, TaskStatusListener listener) { + super(dataPoints, targetPlot, parameterSet, controller, listener); + currentIndex = 0; + massDetector = parameterSet.getParameter(DPPMassDetectionParameters.massDetector).getValue(); + // massDetector = step.getModule(); + setDisplayResults( + parameterSet.getParameter(DPPMassDetectionParameters.displayResults).getValue()); + setColor(parameterSet.getParameter(DPPMassDetectionParameters.datasetColor).getValue()); + } + + + @Override + public double getFinishedPercentage() { + if (getDataPoints().length == 0) + return 0; + return currentIndex / getDataPoints().length; + } + + @Override + public void run() { + + if(!checkParameterSet() || !checkValues()) { + setStatus(TaskStatus.ERROR); + return; + } + + + if(getStatus() == TaskStatus.CANCELED) { + return; + } + + setStatus(TaskStatus.PROCESSING); + + MassDetector detector = massDetector.getModule(); + DataPoint[] masses = detector.getMassValues(getDataPoints(), massDetector.getParameterSet()); + + if(masses == null || masses.length <= 0) { + Logger.info("Data point/Spectra processing: No masses were detected with the given parameters."); + setStatus(TaskStatus.CANCELED); + return; + } + + ProcessedDataPoint[] dp = ProcessedDataPoint.convert(masses); + + currentIndex = dataPoints.length; + + setResults(dp); + setStatus(TaskStatus.FINISHED); + } + + @Override + public void displayResults() { + // if this is the last task, display even if not checked. + if (getController().isLastTaskRunning() || isDisplayResults()) { + getTargetPlot().addDataSet(new DPPResultsDataSet("Mass detection results (" + getResults().length + ")", getResults()), + getColor(), false); + } + } + +} diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/massdetection/help/help.html b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/massdetection/help/help.html new file mode 100644 index 000000000..cdfc17e2d --- /dev/null +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datapointprocessing/massdetection/help/help.html @@ -0,0 +1,35 @@ + + + SP - Peak detection - Mass detection + + + + + + +

Mass detection

+ +

Description

+ +

+The Mass detection module generates a list of masses (ions) for a scan. +Several algorithms are provided for this step. +The choice of the optimal algorithm depends on the raw data characteristics (mass resolution, mass precision, peak shape, noise). +In case the raw data is already centroided, only one algorithm (Centroid mass detector) can be used. +Other algorithms work only with continuous type data. +A mass detection is needed for other processing steps. +

+ +

Method parameters

+
+
Mass detector
+
Algorithm to use for mass detection and its parameters
+ +
Display results
+
If enabled, the result will be displayed in the spectrum plot. If this is the last module in the processing list, the results will be displayed in any way.
+ +
Dataset color
+
Select the color, the results of this module shall be displayed in.
+ + + diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datasets/DataPointsDataSet.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datasets/DataPointsDataSet.java index 5154c1e98..ba9f2e383 100644 --- a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datasets/DataPointsDataSet.java +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datasets/DataPointsDataSet.java @@ -32,7 +32,7 @@ public class DataPointsDataSet extends AbstractXYDataset implements IntervalXYDa * */ private static final long serialVersionUID = 1L; - private DataPoint mzPeaks[]; + protected DataPoint mzPeaks[]; private String label; public DataPointsDataSet(String label, DataPoint mzPeaks[]) { diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datasets/ScanDataSet.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datasets/ScanDataSet.java index 3bb21ad70..872d6ffbe 100644 --- a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datasets/ScanDataSet.java +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/datasets/ScanDataSet.java @@ -143,4 +143,7 @@ public String getAnnotation(int item) { return null; } + public DataPoint[] getDataPoints() { + return dataPoints; + } } diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/renderers/SpectraItemLabelGenerator.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/renderers/SpectraItemLabelGenerator.java index e467b1df3..2c8d9de23 100644 --- a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/renderers/SpectraItemLabelGenerator.java +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/renderers/SpectraItemLabelGenerator.java @@ -36,9 +36,9 @@ public class SpectraItemLabelGenerator implements XYItemLabelGenerator { */ public static final int POINTS_RESERVE_X = 100; - private SpectraPlot plot; + protected SpectraPlot plot; - private NumberFormat mzFormat = MZmineCore.getConfiguration().getMZFormat(); + protected NumberFormat mzFormat = MZmineCore.getConfiguration().getMZFormat(); public SpectraItemLabelGenerator(SpectraPlot plot) { this.plot = plot; diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/customdatabase/SpectraIdentificationCustomDatabaseTask.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/customdatabase/SpectraIdentificationCustomDatabaseTask.java index fc89bedca..54a003f23 100644 --- a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/customdatabase/SpectraIdentificationCustomDatabaseTask.java +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/customdatabase/SpectraIdentificationCustomDatabaseTask.java @@ -141,12 +141,12 @@ public void run() { massDetector = new CentroidMassDetector(); CentroidMassDetectorParameters parameters = new CentroidMassDetectorParameters(); CentroidMassDetectorParameters.noiseLevel.setValue(noiseLevel); - massList = massDetector.getMassValues(currentScan, parameters); + massList = massDetector.getMassValues(currentScan.getDataPoints(), parameters); } else { massDetector = new ExactMassDetector(); ExactMassDetectorParameters parameters = new ExactMassDetectorParameters(); ExactMassDetectorParameters.noiseLevel.setValue(noiseLevel); - massList = massDetector.getMassValues(currentScan, parameters); + massList = massDetector.getMassValues(currentScan.getDataPoints(), parameters); } numItems = massList.length; diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/lipidsearch/SpectraIdentificationLipidSearchTask.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/lipidsearch/SpectraIdentificationLipidSearchTask.java index baca7d517..f75e42f9b 100644 --- a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/lipidsearch/SpectraIdentificationLipidSearchTask.java +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/lipidsearch/SpectraIdentificationLipidSearchTask.java @@ -148,12 +148,12 @@ public void run() { massDetector = new CentroidMassDetector(); CentroidMassDetectorParameters parameters = new CentroidMassDetectorParameters(); CentroidMassDetectorParameters.noiseLevel.setValue(noiseLevel); - massList = massDetector.getMassValues(currentScan, parameters); + massList = massDetector.getMassValues(currentScan.getDataPoints(), parameters); } else { massDetector = new ExactMassDetector(); ExactMassDetectorParameters parameters = new ExactMassDetectorParameters(); ExactMassDetectorParameters.noiseLevel.setValue(noiseLevel); - massList = massDetector.getMassValues(currentScan, parameters); + massList = massDetector.getMassValues(currentScan.getDataPoints(), parameters); } totalSteps = massList.length; // loop through every peak in mass list diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/onlinedatabase/SpectraIdentificationOnlineDatabaseTask.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/onlinedatabase/SpectraIdentificationOnlineDatabaseTask.java index 4b5dcaa0d..1a9fb8029 100644 --- a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/onlinedatabase/SpectraIdentificationOnlineDatabaseTask.java +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/onlinedatabase/SpectraIdentificationOnlineDatabaseTask.java @@ -136,12 +136,12 @@ public void run() { massDetector = new CentroidMassDetector(); CentroidMassDetectorParameters parameters = new CentroidMassDetectorParameters(); CentroidMassDetectorParameters.noiseLevel.setValue(noiseLevel); - massList = massDetector.getMassValues(currentScan, parameters); + massList = massDetector.getMassValues(currentScan.getDataPoints(), parameters); } else { massDetector = new ExactMassDetector(); ExactMassDetectorParameters parameters = new ExactMassDetectorParameters(); ExactMassDetectorParameters.noiseLevel.setValue(noiseLevel); - massList = massDetector.getMassValues(currentScan, parameters); + massList = massDetector.getMassValues(currentScan.getDataPoints(), parameters); } numItems = massList.length; for (int i = 0; i < massList.length; i++) { diff --git a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/sumformula/SpectraIdentificationSumFormulaTask.java b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/sumformula/SpectraIdentificationSumFormulaTask.java index 996a1d245..d5c1fb957 100644 --- a/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/sumformula/SpectraIdentificationSumFormulaTask.java +++ b/src/main/java/net/sf/mzmine/modules/visualization/spectra/simplespectra/spectraidentification/sumformula/SpectraIdentificationSumFormulaTask.java @@ -162,12 +162,12 @@ public void run() { massDetector = new CentroidMassDetector(); CentroidMassDetectorParameters parameters = new CentroidMassDetectorParameters(); CentroidMassDetectorParameters.noiseLevel.setValue(noiseLevel); - massList = massDetector.getMassValues(currentScan, parameters); + massList = massDetector.getMassValues(currentScan.getDataPoints(), parameters); } else { massDetector = new ExactMassDetector(); ExactMassDetectorParameters parameters = new ExactMassDetectorParameters(); ExactMassDetectorParameters.noiseLevel.setValue(noiseLevel); - massList = massDetector.getMassValues(currentScan, parameters); + massList = massDetector.getMassValues(currentScan.getDataPoints(), parameters); } numItems = massList.length; // loop through every peak in mass list diff --git a/src/main/java/net/sf/mzmine/parameters/parametertypes/HiddenParameter.java b/src/main/java/net/sf/mzmine/parameters/parametertypes/HiddenParameter.java new file mode 100644 index 000000000..20da4ff37 --- /dev/null +++ b/src/main/java/net/sf/mzmine/parameters/parametertypes/HiddenParameter.java @@ -0,0 +1,73 @@ +package net.sf.mzmine.parameters.parametertypes; + +import java.util.Collection; +import org.w3c.dom.Element; +import net.sf.mzmine.parameters.Parameter; + +/** + * This is a container for any user parameter, that is not shown in the parameter setup dialog. + * HiddenParameter can be used to store additional variables, that are not shown in the parameter + * setup dialog. E.g.: spectraProcessing in + * {@link net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingParameters#spectraProcessing + * this} is a HiddenParameter, so it can be toggled by a checkbox in a different window. + * + * @author SteffenHeu steffen.heuckeroth@gmx.de / s_heuc03@uni-muenster.de + * + * @param The type of the contained UserParameter + * @param The value type of the contained UserParameter + * + * @see UserParameter + */ +public class HiddenParameter, ValueType> + implements Parameter { + + private Parameter embeddedParameter; + + public HiddenParameter(Parameter param) { + setEmbeddedParameter(param); + } + + @Override + public String getName() { + return getEmbeddedParameter().getName(); + } + + @Override + public ValueType getValue() { + return getEmbeddedParameter().getValue(); + } + + @Override + public void setValue(ValueType newValue) { + getEmbeddedParameter().setValue(newValue); + } + + @Override + public boolean checkValue(Collection errorMessages) { + return getEmbeddedParameter().checkValue(errorMessages); + } + + @Override + public void loadValueFromXML(Element xmlElement) { + getEmbeddedParameter().loadValueFromXML(xmlElement); + } + + @Override + public void saveValueToXML(Element xmlElement) { + getEmbeddedParameter().saveValueToXML(xmlElement); + } + + @Override + public HiddenParameter cloneParameter() { + Parameter param = getEmbeddedParameter().cloneParameter(); + return new HiddenParameter(param); + } + + public Parameter getEmbeddedParameter() { + return embeddedParameter; + } + + private void setEmbeddedParameter(Parameter param) { + this.embeddedParameter = param; + } +} diff --git a/src/main/java/net/sf/mzmine/parameters/parametertypes/ProcessingComponent.java b/src/main/java/net/sf/mzmine/parameters/parametertypes/ProcessingComponent.java new file mode 100644 index 000000000..dd88bc261 --- /dev/null +++ b/src/main/java/net/sf/mzmine/parameters/parametertypes/ProcessingComponent.java @@ -0,0 +1,369 @@ +package net.sf.mzmine.parameters.parametertypes; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.logging.Logger; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.swing.JPanel; +import javax.swing.JSplitPane; +import javax.swing.JTree; +import javax.swing.filechooser.FileNameExtensionFilter; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; +import net.sf.mzmine.main.MZmineCore; +import net.sf.mzmine.modules.MZmineModule; +import net.sf.mzmine.modules.MZmineProcessingStep; +import net.sf.mzmine.modules.impl.MZmineProcessingStepImpl; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingManager; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingModule; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingQueue; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.DPPModuleCategoryTreeNode; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.DPPModuleTreeNode; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.datamodel.ModuleSubCategory; +import net.sf.mzmine.parameters.ParameterSet; +import net.sf.mzmine.util.ExitCode; +import net.sf.mzmine.util.GUIUtils; +import net.sf.mzmine.util.dialogs.LoadSaveFileChooser; + +public class ProcessingComponent extends JPanel implements ActionListener { + + /** + * + */ + private static final long serialVersionUID = 1L; + + private static final Logger logger = Logger.getLogger(ProcessingComponent.class.getName()); + + private JTree tvProcessing; + private JTree tvAllModules; + private final JSplitPane split; + private final JPanel buttonPanel; + + // File chooser + private final LoadSaveFileChooser chooser; + private static final String XML_EXTENSION = "xml"; + + public ProcessingComponent() { + super(new BorderLayout()); + setPreferredSize(new Dimension(600, 400)); + + + setupTreeViews(); + split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, tvProcessing, tvAllModules); + initTreeListeners(); + add(split, BorderLayout.CENTER); + split.setDividerLocation(300); + + buttonPanel = new JPanel(new FlowLayout()); + GUIUtils.addButton(buttonPanel, "Add", null, this, "BTN_ADD"); + GUIUtils.addButton(buttonPanel, "Remove", null, this, "BTN_REMOVE"); + GUIUtils.addButton(buttonPanel, "Set parameters", null, this, "BTN_SET_PARAMETERS"); + GUIUtils.addButton(buttonPanel, "Load", null, this, "BTN_LOAD"); + GUIUtils.addButton(buttonPanel, "Save", null, this, "BTN_SAVE"); + // GUIUtils.addButton(buttonPanel, "Set Default...", null, this, "BTN_SET_DEFAULT"); + add(buttonPanel, BorderLayout.SOUTH); + + chooser = new LoadSaveFileChooser("Select Processing Queue File"); + chooser.addChoosableFileFilter(new FileNameExtensionFilter("XML files", XML_EXTENSION)); + + super.repaint(); + } + + public ProcessingComponent(@Nullable DataPointProcessingQueue queue) { + this(); + setTreeViewProcessingItemsFromQueue(queue); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("BTN_ADD")) { + addModule(); + sendQueue(); + } else if (e.getActionCommand().equals("BTN_REMOVE")) { + removeModule(); + sendQueue(); + } else if (e.getActionCommand().equals("BTN_SET_PARAMETERS")) { + setParameters(getSelectedItem(tvProcessing)); + } else if (e.getActionCommand().equals("BTN_LOAD")) { + final File file = chooser.getLoadFile(this); + if (file != null) { + DataPointProcessingQueue queue = DataPointProcessingQueue.loadFromFile(file); + setTreeViewProcessingItemsFromQueue(queue); + sendQueue(); + } + } else if (e.getActionCommand().equals("BTN_SAVE")) { + final File file = chooser.getSaveFile(this, XML_EXTENSION); + if (file != null) { + DataPointProcessingQueue queue = getProcessingQueueFromTreeView(); + queue.saveToFile(file); + } + } + // else if(e.getActionCommand().equals("BTN_SET_DEFAULT")) { + // final File file = chooser.getLoadFile(DPPSetupWindow.getInstance().getFrame()); + // if (file != null) { + // DataPointProcessingManager.getInst().getParameters() + // .getParameter(DataPointProcessingParameters.defaultDPPQueue).setValue(file); + // logger.finest("Set default processing queue to: " + file.getAbsolutePath()); + // } + } + + private void setupTreeViews() { + DefaultMutableTreeNode tiProcessingRoot = new DefaultMutableTreeNode("Processing queue"); + DefaultMutableTreeNode tiAllModulesRoot = new DefaultMutableTreeNode("Modules"); + + // create category items dynamically, if a new category is added later on. + DPPModuleCategoryTreeNode[] moduleCategories = + new DPPModuleCategoryTreeNode[ModuleSubCategory.values().length]; + for (int i = 0; i < moduleCategories.length; i++) { + moduleCategories[i] = new DPPModuleCategoryTreeNode(ModuleSubCategory.values()[i]); + tiAllModulesRoot.add(moduleCategories[i]); + } + + // add modules to their module category items + Collection moduleList = MZmineCore.getAllModules(); + for (MZmineModule module : moduleList) { + if (module instanceof DataPointProcessingModule) { + DataPointProcessingModule dppm = (DataPointProcessingModule) module; + + // add each module as a child of the module category items + for (DPPModuleCategoryTreeNode catItem : moduleCategories) { + if (dppm.getModuleSubCategory().equals(catItem.getCategory())) { + catItem.add(new DPPModuleTreeNode(dppm)); + } + } + } + } + + // add the categories to the root item + tvProcessing = new JTree(tiProcessingRoot); + tvAllModules = new JTree(tiAllModulesRoot); + + tvAllModules.setRootVisible(true); + tvProcessing.setRootVisible(true); + expandAllNodes(tvAllModules); + } + + private void initTreeListeners() { + tvProcessing.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + if (e.getClickCount() == 2) { + setParameters(getSelectedItem(tvProcessing)); + } + } + }); + + tvAllModules.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + if (e.getClickCount() == 2) { + addModule(); + } + } + }); + } + + /** + * Opens the parameter setup dialog of the selected module. + */ + private void setParameters(@Nonnull DefaultMutableTreeNode _selected) { + if (_selected == null || !(_selected instanceof DPPModuleTreeNode)) + return; + + DPPModuleTreeNode selected = (DPPModuleTreeNode) _selected; + + MZmineModule module = selected.getModule(); + ParameterSet stepParameters = + MZmineCore.getConfiguration().getModuleParameters(module.getClass()); + + if (stepParameters.getParameters().length > 0) { + ExitCode exitCode = stepParameters.showSetupDialog(null, true); + if (exitCode == ExitCode.OK) { + // store the parameters in the tree item + selected.setParameters(stepParameters); + sendQueue(); // update the list + } + } + + } + + /** + * Adds the selected module in the tvAllModules to the processing list + */ + private void addModule() { + DefaultMutableTreeNode selected = getSelectedItem(tvAllModules); + if (selected == null) + return; + + if (selected instanceof DPPModuleTreeNode) { + addModule((DPPModuleTreeNode) selected.clone()); + } else { + logger.finest("Cannot add item " + selected.toString() + " to processing list."); + } + } + + /** + * Adds a module in the tvAllModules to the processing list + */ + private void addModule(@Nonnull DPPModuleTreeNode node) { + // a module cannot be added twice + if (treeContains(tvProcessing, node)) { + logger.finest("Cannot add module " + ((DPPModuleTreeNode) node).getModule().getName() + + " to processing list twice."); + return; + } + + DefaultMutableTreeNode root = (DefaultMutableTreeNode) tvProcessing.getModel().getRoot(); + ((DefaultTreeModel) tvProcessing.getModel()).insertNodeInto(node, root, root.getChildCount()); + + logger.finest("Added module " + ((DPPModuleTreeNode) node).getModule().getName() + + " to processing list."); + expandAllNodes(tvProcessing); + } + + /** + * Removes the selected module in the tvProcessingList from the list + */ + private void removeModule() { + DefaultMutableTreeNode selected = getSelectedItem(tvProcessing); + if (selected == null) + return; + + if (selected instanceof DPPModuleTreeNode) { + ((DefaultMutableTreeNode) tvProcessing.getModel().getRoot()).remove(selected); + // selected.removeFromParent(); + logger.finest("Removed module " + ((DPPModuleTreeNode) selected).getModule().getName() + + " from processing list."); + } else { + logger.finest("Cannot remove item " + selected.toString() + " from processing list."); + } + ((DefaultTreeModel) tvProcessing.getModel()).reload(); + } + + /** + * Creates a DataPointProcessingQueue from the items currently in the tree view. + * + * @return Instance of DataPointProcessingQueue. + */ + public @Nonnull DataPointProcessingQueue getProcessingQueueFromTreeView() { + DataPointProcessingQueue list = new DataPointProcessingQueue(); + + if (((DefaultMutableTreeNode) tvProcessing.getModel().getRoot()).getChildCount() < 1) + return list; + + Enumeration nodes = ((DefaultMutableTreeNode) tvProcessing.getModel().getRoot()).children(); + do { + DefaultMutableTreeNode item = (DefaultMutableTreeNode) nodes.nextElement(); + if (!(item instanceof DPPModuleTreeNode)) + continue; + DPPModuleTreeNode moduleitem = (DPPModuleTreeNode) item; + list.add(createProcessingStep(moduleitem)); + } while (nodes.hasMoreElements()); + + return list; + } + + /** + * Creates a MZmineProcessingStep from an DPPModuleTreeItem. + * + * @param item Tree item. + * @return Instance of MZmineProcessingStep. + */ + private @Nonnull MZmineProcessingStep createProcessingStep( + @Nonnull DPPModuleTreeNode item) { + return new MZmineProcessingStepImpl<>(item.getModule(), item.getParameters()); + } + + /** + * Sends the queue to the DataPointProcessingManager. + */ + private void sendQueue() { + // if (((DefaultMutableTreeNode) tvProcessing.getModel().getRoot()).getChildCount() < 1) + // return; + + DataPointProcessingQueue queue = getProcessingQueueFromTreeView(); + if (queue.isEmpty()) + logger.info("Processing queue is empty. Sending empty list."); + + DataPointProcessingManager manager = DataPointProcessingManager.getInst(); + manager.clearProcessingSteps(); + manager.setProcessingQueue(queue); + } + + /** + * Creates a collection of DPPModuleTreeItem from a queue. Can be used after loading a queue from + * a file. + * + * @param queue The queue. + * @return Collection. + */ + private @Nonnull Collection createTreeItemsFromQueue( + @Nullable DataPointProcessingQueue queue) { + Collection items = new ArrayList(); + + if (queue == null) + return items; + + for (MZmineProcessingStep step : queue) { + items.add(new DPPModuleTreeNode(step.getModule())); + } + + return items; + } + + /** + * Convenience method to publicly set the items of the processing list from the tree view. Used to + * set the default queue, if set, loaded by the manager's constructor. + * + * @param queue + */ + public void setTreeViewProcessingItemsFromQueue(@Nullable DataPointProcessingQueue queue) { + logger.info("Loading queue into tvProcessing..."); + DefaultMutableTreeNode root = (DefaultMutableTreeNode) tvProcessing.getModel().getRoot(); + root.removeAllChildren(); + ((DefaultTreeModel) tvProcessing.getModel()).reload(); + Collection moduleNodes = createTreeItemsFromQueue(queue); + for (DPPModuleTreeNode node : moduleNodes) { + addModule(node); + } + expandAllNodes(tvProcessing); + } + + private boolean treeContains(@Nonnull JTree tree, @Nonnull DefaultMutableTreeNode comp) { + DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot(); + Enumeration e = root.depthFirstEnumeration(); + while (e.hasMoreElements()) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) e.nextElement(); + if (node.toString().equalsIgnoreCase(comp.toString())) { + return true; + } + } + return false; + } + + private @Nullable DefaultMutableTreeNode getSelectedItem(@Nonnull JTree tree) { + TreeSelectionModel selectionModel = tree.getSelectionModel(); + if (selectionModel == null) + return null; + TreePath path = selectionModel.getSelectionPath(); + if (path == null) + return null; + return (DefaultMutableTreeNode) path.getLastPathComponent(); + } + + private void expandAllNodes(@Nonnull JTree tree) { + for (int i = 0; i < tree.getRowCount(); i++) { + tree.expandRow(i); + } + } +} diff --git a/src/main/java/net/sf/mzmine/parameters/parametertypes/ProcessingParameter.java b/src/main/java/net/sf/mzmine/parameters/parametertypes/ProcessingParameter.java new file mode 100644 index 000000000..ccad0682a --- /dev/null +++ b/src/main/java/net/sf/mzmine/parameters/parametertypes/ProcessingParameter.java @@ -0,0 +1,92 @@ +package net.sf.mzmine.parameters.parametertypes; + +import java.util.Collection; +import org.w3c.dom.Element; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingManager; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.datapointprocessing.DataPointProcessingQueue; +import net.sf.mzmine.parameters.UserParameter; + +public class ProcessingParameter + implements UserParameter { + + private String name; + private String description; + private DataPointProcessingQueue value; + + public ProcessingParameter(String name, String description) { + this.name = name; + this.description = description; + this.value = new DataPointProcessingQueue(); + // if(queue == null) + // this.value = DataPointProcessingManager.getInst().getProcessingQueue(); + // else + // this.value = queue; + } + + @Override + public String getName() { + return name; + } + + @Override + public DataPointProcessingQueue getValue() { + return value; + } + + @Override + public void setValue(DataPointProcessingQueue newValue) { + this.value = newValue; + } + + @Override + public boolean checkValue(Collection errorMessages) { + if (value == null) { + errorMessages.add("Queue has not been set up. (null)"); + return false; + } + return true; + } + + @Override + public void loadValueFromXML(Element xmlElement) { + this.value = DataPointProcessingQueue.loadfromXML(xmlElement); + } + + @Override + public void saveValueToXML(Element xmlElement) { + if (value != null) + value.saveToXML(xmlElement); + } + + @Override + public String getDescription() { + return description; + } + + @Override + public ProcessingComponent createEditingComponent() { + ProcessingComponent comp = new ProcessingComponent(); + // if(value != null) + // comp.setTreeViewProcessingItemsFromQueue(value); + return comp; + } + + @Override + public void setValueFromComponent(ProcessingComponent component) { + this.value = component.getProcessingQueueFromTreeView(); + } + + @Override + public void setValueToComponent(ProcessingComponent component, + DataPointProcessingQueue newValue) { + component.setTreeViewProcessingItemsFromQueue(newValue); + } + + @Override + public UserParameter cloneParameter() { + ProcessingParameter copy = new ProcessingParameter(name, description); + copy.setValue(this.value); + return copy; + } + +} diff --git a/src/main/java/net/sf/mzmine/util/GUIUtils.java b/src/main/java/net/sf/mzmine/util/GUIUtils.java index 74c6d2764..eea8277b5 100644 --- a/src/main/java/net/sf/mzmine/util/GUIUtils.java +++ b/src/main/java/net/sf/mzmine/util/GUIUtils.java @@ -31,6 +31,7 @@ import javax.swing.Box; import javax.swing.Icon; import javax.swing.JButton; +import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JEditorPane; import javax.swing.JLabel; @@ -483,4 +484,86 @@ public static JPanel makeTablePanel(int rows, int cols, int mainColumn, JCompone return panel; } + /** + * + * Add a new checkbox to given component + * + * @param container Component to add the checkbox to + * @param text Checkbox' text + * @param icon Checkbox' icon or null + * @param listener Checkbox' listener or null + * @param actionCommand Checkbox' action command or null + * @param mnemonic Checkbox' mnemonic (virtual key code) or 0 + * @param toolTip Checkbox' tool tip or null + * @param state Checkbox' state + * @return Created checkbox + */ + public static JCheckBox addCheckbox(Container component, String text, Icon icon, + ActionListener listener, String actionCommand, int mnemonic, String toolTip, boolean state) { + JCheckBox checkbox = new JCheckBox(text, icon, state); + if (listener != null) + checkbox.addActionListener(listener); + if (actionCommand != null) + checkbox.setActionCommand(actionCommand); + if (mnemonic > 0) + checkbox.setMnemonic(mnemonic); + if (toolTip != null) + checkbox.setToolTipText(toolTip); + if (component != null) + component.add(checkbox); + return checkbox; + } + + /** + * + * Add a new checkbox to given component + * + * @param component Component to add the checkbox to + * @param text Checkbox' text + * @param icon Checkbox' icon or null + * @param listener Checkbox' listener or null + * @param actionCommand Checkbox' action command or null + * @param toolTip Checkbox' tool tip or null + * @param state Checkbox' state + * @return + */ + public static JCheckBox addCheckbox(Container component, String text, Icon icon, + ActionListener listener, String actionCommand, String toolTip, boolean state) { + return addCheckbox(component, text, icon, listener, actionCommand, 0, toolTip, state); + } + + /** + * + * Add a new checkbox to given component + * + * @param component Component to add the checkbox to + * @param text Checkbox' text + * @param icon Checkbox' icon or null + * @param listener Checkbox' listener or null + * @param actionCommand Checkbox' action command or null + * @param toolTip Checkbox' tool tip or null + * @return + */ + public static JCheckBox addCheckbox(Container component, String text, Icon icon, + ActionListener listener, String actionCommand, String toolTip) { + return addCheckbox(component, text, icon, listener, actionCommand, 0, toolTip, false); + } + + /** + * + * Add a new checkbox to given component + * + * @param component Component to add the checkbox to + * @param text Checkbox' text + * @param listener Checkbox' listener or null + * @param actionCommand Checkbox' action command or null + * @param toolTip Checkbox' tool tip or null + * @return + */ + public static JCheckBox addCheckbox(Container component, String text, + ActionListener listener, String actionCommand, String toolTip) { + return addCheckbox(component, text, null, listener, actionCommand, 0, toolTip, false); + } + + } diff --git a/src/main/java/net/sf/mzmine/util/SpectraPlotUtils.java b/src/main/java/net/sf/mzmine/util/SpectraPlotUtils.java new file mode 100644 index 000000000..359ca5828 --- /dev/null +++ b/src/main/java/net/sf/mzmine/util/SpectraPlotUtils.java @@ -0,0 +1,45 @@ +package net.sf.mzmine.util; + +import java.util.List; +import org.jfree.data.xy.XYDataset; +import net.sf.mzmine.modules.visualization.spectra.simplespectra.SpectraPlot; + +public class SpectraPlotUtils { + + /** + * Removes all label generators of datasets that are not of the given type. + * + * @param plot Plot to apply this method to. + * @param ignore List of class objects of the instances to ignore. + */ + public static void clearDatasetLabelGenerators(SpectraPlot plot, + List> ignore) { + for (int i = 0; i < plot.getXYPlot().getDatasetCount(); i++) { + XYDataset dataset = plot.getXYPlot().getDataset(i); + // check if object of dataset is an instance of ignore.class + boolean remove = true; + for (Class datasetClass : ignore) { + if ((datasetClass.isInstance(dataset))) + remove = false; + } + + if (remove) + plot.getXYPlot().getRendererForDataset(dataset).setDefaultItemLabelGenerator(null); + } + } + + /** + * Removes all label generators of datasets that are not of the given type. + * + * @param plot Plot to apply this method to. + * @param ignore Class object of the instances to ignore. + */ + public static void clearDatasetLabelGenerators(SpectraPlot plot, Class ignore) { + for (int i = 0; i < plot.getXYPlot().getDatasetCount(); i++) { + XYDataset dataset = plot.getXYPlot().getDataset(i); + // check if object of dataset is an instance of ignore.class + if (!(ignore.isInstance(dataset))) + plot.getXYPlot().getRendererForDataset(dataset).setDefaultItemLabelGenerator(null); + } + } +}