From 1362b83e9bc93b2963da18478b83e19f364ce535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Mail=C3=A4nder?= Date: Tue, 26 Oct 2021 19:56:17 +0200 Subject: [PATCH] Translate the options available in MSD to WSD. --- .../firstderivative/core/PeakDetectorWSD.java | 249 +++++++++++++++--- .../settings/PeakDetectorSettingsWSD.java | 116 ++++++++ .../wsd/model/core/AbstractScanWSD.java | 36 +++ .../chemclipse/wsd/model/core/IScanWSD.java | 10 +- .../support/AbstractMarkedWavelengths.java | 12 +- .../model/core/support/IMarkedWavelength.java | 33 ++- .../core/support/IMarkedWavelengths.java | 3 + .../model/core/support/MarkedWavelengths.java | 30 ++- .../model/core/support/PeakBuilderWSD.java | 93 +++++-- .../xwc/ITotalWavelengthSignalExtractor.java | 16 +- .../xwc/TotalWavelengthSignalExtractor.java | 70 ++++- 11 files changed, 578 insertions(+), 90 deletions(-) diff --git a/chemclipse/plugins/org.eclipse.chemclipse.chromatogram.xxd.peak.detector.supplier.firstderivative/src/org/eclipse/chemclipse/chromatogram/xxd/peak/detector/supplier/firstderivative/core/PeakDetectorWSD.java b/chemclipse/plugins/org.eclipse.chemclipse.chromatogram.xxd.peak.detector.supplier.firstderivative/src/org/eclipse/chemclipse/chromatogram/xxd/peak/detector/supplier/firstderivative/core/PeakDetectorWSD.java index 7fdb994f29..aed4830dcc 100644 --- a/chemclipse/plugins/org.eclipse.chemclipse.chromatogram.xxd.peak.detector.supplier.firstderivative/src/org/eclipse/chemclipse/chromatogram/xxd/peak/detector/supplier/firstderivative/core/PeakDetectorWSD.java +++ b/chemclipse/plugins/org.eclipse.chemclipse.chromatogram.xxd.peak.detector.supplier.firstderivative/src/org/eclipse/chemclipse/chromatogram/xxd/peak/detector/supplier/firstderivative/core/PeakDetectorWSD.java @@ -13,12 +13,18 @@ package org.eclipse.chemclipse.chromatogram.xxd.peak.detector.supplier.firstderivative.core; import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; import org.eclipse.chemclipse.chromatogram.peak.detector.exceptions.ValueMustNotBeNullException; +import org.eclipse.chemclipse.chromatogram.peak.detector.model.Threshold; import org.eclipse.chemclipse.chromatogram.peak.detector.support.IRawPeak; import org.eclipse.chemclipse.chromatogram.wsd.peak.detector.core.IPeakDetectorWSD; import org.eclipse.chemclipse.chromatogram.wsd.peak.detector.settings.IPeakDetectorSettingsWSD; +import org.eclipse.chemclipse.chromatogram.xxd.calculator.core.noise.NoiseChromatogramClassifier; import org.eclipse.chemclipse.chromatogram.xxd.peak.detector.supplier.firstderivative.preferences.PreferenceSupplier; import org.eclipse.chemclipse.chromatogram.xxd.peak.detector.supplier.firstderivative.settings.PeakDetectorSettingsWSD; import org.eclipse.chemclipse.chromatogram.xxd.peak.detector.supplier.firstderivative.support.FirstDerivativeDetectorSlope; @@ -28,24 +34,33 @@ import org.eclipse.chemclipse.logging.core.Logger; import org.eclipse.chemclipse.model.core.IChromatogram; import org.eclipse.chemclipse.model.core.IPeak; +import org.eclipse.chemclipse.model.core.IScan; +import org.eclipse.chemclipse.model.exceptions.ChromatogramIsNullException; import org.eclipse.chemclipse.model.exceptions.PeakException; import org.eclipse.chemclipse.model.signals.ITotalScanSignal; import org.eclipse.chemclipse.model.signals.ITotalScanSignals; -import org.eclipse.chemclipse.model.signals.TotalScanSignals; import org.eclipse.chemclipse.model.signals.TotalScanSignalsModifier; import org.eclipse.chemclipse.model.support.IScanRange; +import org.eclipse.chemclipse.model.support.NoiseSegment; import org.eclipse.chemclipse.model.support.ScanRange; import org.eclipse.chemclipse.msd.model.core.IChromatogramPeakMSD; import org.eclipse.chemclipse.numeric.core.IPoint; import org.eclipse.chemclipse.numeric.core.Point; +import org.eclipse.chemclipse.numeric.equations.Equations; +import org.eclipse.chemclipse.numeric.equations.LinearEquation; import org.eclipse.chemclipse.processing.core.IProcessingInfo; import org.eclipse.chemclipse.processing.core.MessageType; import org.eclipse.chemclipse.processing.core.ProcessingMessage; import org.eclipse.chemclipse.wsd.model.core.IChromatogramPeakWSD; import org.eclipse.chemclipse.wsd.model.core.IChromatogramWSD; +import org.eclipse.chemclipse.wsd.model.core.IScanWSD; import org.eclipse.chemclipse.wsd.model.core.selection.IChromatogramSelectionWSD; +import org.eclipse.chemclipse.wsd.model.core.support.IMarkedWavelengths; import org.eclipse.chemclipse.wsd.model.core.support.PeakBuilderWSD; +import org.eclipse.chemclipse.wsd.model.xwc.ITotalWavelengthSignalExtractor; +import org.eclipse.chemclipse.wsd.model.xwc.TotalWavelengthSignalExtractor; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; public class PeakDetectorWSD

, R> extends BasePeakDetector implements IPeakDetectorWSD { @@ -62,13 +77,21 @@ public IProcessingInfo detect(IChromatogramSelectionWSD chromatogramSelection IProcessingInfo processingInfo = validate(chromatogramSelection, detectorSettings, monitor); if(!processingInfo.hasErrorMessages()) { if(detectorSettings instanceof PeakDetectorSettingsWSD) { + SubMonitor subMonitor = SubMonitor.convert(monitor, 100); PeakDetectorSettingsWSD peakDetectorSettings = (PeakDetectorSettingsWSD)detectorSettings; - List peaks = detectPeaks(chromatogramSelection, peakDetectorSettings, monitor); + /* + * Extract the noise segments. + */ + List noiseSegments = null; IChromatogramWSD chromatogram = chromatogramSelection.getChromatogram(); + if(peakDetectorSettings.isUseNoiseSegments()) { + noiseSegments = NoiseChromatogramClassifier.getNoiseSegments(chromatogram, chromatogramSelection, false, subMonitor.split(10)); + } + List peaks = detectPeaks(chromatogramSelection, peakDetectorSettings, noiseSegments, subMonitor.split(90)); for(IChromatogramPeakWSD peak : peaks) { chromatogram.addPeak(peak); } - processingInfo.addMessage(new ProcessingMessage(MessageType.INFO, FirstDerivativePeakDetector.DETECTOR_DESCRIPTION, "Peaks have been detected successfully.")); + processingInfo.addMessage(new ProcessingMessage(MessageType.INFO, FirstDerivativePeakDetector.DETECTOR_DESCRIPTION, peaks.size() + " peaks have been detected successfully.")); } else { logger.warn("Settings is not of type: " + PeakDetectorSettingsWSD.class); } @@ -92,11 +115,77 @@ public IProcessingInfo detect(IChromatogramSelectionWSD chromatogramSelection * @param chromatogramSelection * @throws ValueMustNotBeNullException */ - public List detectPeaks(IChromatogramSelectionWSD chromatogramSelection, PeakDetectorSettingsWSD peakDetectorSettings, IProgressMonitor monitor) { + public List detectPeaks(IChromatogramSelectionWSD chromatogramSelection, PeakDetectorSettingsWSD peakDetectorSettings, List noiseSegments, IProgressMonitor monitor) { - IFirstDerivativeDetectorSlopes slopes = getFirstDerivativeSlopes(chromatogramSelection, peakDetectorSettings.getMovingAverageWindowSize()); - List rawPeaks = getRawPeaks(slopes, peakDetectorSettings.getThreshold(), monitor); - return extractPeaks(rawPeaks, chromatogramSelection.getChromatogram(), peakDetectorSettings); + List extractPeaks = new ArrayList<>(); + Collection filterWavelengths = peakDetectorSettings.getFilterWavelengths(); + IChromatogramWSD chromatogram = chromatogramSelection.getChromatogram(); + for(IMarkedWavelengths wavelengths : filterWavelengths) { + Threshold threshold = peakDetectorSettings.getThreshold(); + int windowSize = peakDetectorSettings.getMovingAverageWindowSize(); + List rawPeaks = new ArrayList<>(); + // + if(noiseSegments != null && !noiseSegments.isEmpty()) { + /* + * Initial retention time range before running the detection using + * noise segments. + * | --- [S] --- [N] --- [E] --- | + */ + Iterator iterator = noiseSegments.iterator(); + int startRetentionTime = chromatogramSelection.getStartRetentionTime(); + int stopRetentionTime = chromatogramSelection.getStopRetentionTime(); + NoiseSegment noiseSegment = iterator.hasNext() ? iterator.next() : null; + /* + * Range from the start of the chromatogram selection to the first noise segment + * | --- [S] + */ + if(noiseSegment != null) { + chromatogramSelection.setRangeRetentionTime(startRetentionTime, noiseSegment.getStartRetentionTime()); + IFirstDerivativeDetectorSlopes slopes = getFirstDerivativeSlopes(chromatogramSelection, windowSize, wavelengths); + rawPeaks.addAll(getRawPeaks(slopes, threshold, monitor)); + } + /* + * Ranges between the noise segments + * [S] --- [N] --- [E] + */ + while(iterator.hasNext() && noiseSegment != null) { + int startRetentionTimeSegment = noiseSegment.getStopRetentionTime(); + noiseSegment = iterator.next(); + int stopRetentionTimeSegment = noiseSegment.getStartRetentionTime(); + chromatogramSelection.setRangeRetentionTime(startRetentionTimeSegment, stopRetentionTimeSegment); + IFirstDerivativeDetectorSlopes slopes = getFirstDerivativeSlopes(chromatogramSelection, windowSize, wavelengths); + rawPeaks.addAll(getRawPeaks(slopes, threshold, monitor)); + } + /* + * Range from the last noise segment to the end of the chromatogram selection + * [E] --- | + */ + if(noiseSegment != null) { + chromatogramSelection.setRangeRetentionTime(noiseSegment.getStopRetentionTime(), stopRetentionTime); + IFirstDerivativeDetectorSlopes slopes = getFirstDerivativeSlopes(chromatogramSelection, windowSize, wavelengths); + rawPeaks.addAll(getRawPeaks(slopes, threshold, monitor)); + } + /* + * Reset the retention time range to its initial values. + */ + chromatogramSelection.setRangeRetentionTime(startRetentionTime, stopRetentionTime); + } else { + /* + * Default: no noise segments + */ + IFirstDerivativeDetectorSlopes slopes = getFirstDerivativeSlopes(chromatogramSelection, windowSize, wavelengths); + rawPeaks = getRawPeaks(slopes, peakDetectorSettings.getThreshold(), monitor); + } + List peaks = extractPeaks(rawPeaks, chromatogram, peakDetectorSettings, wavelengths); + if(peakDetectorSettings.isIndividualWavelengths()) { + String classifier = "Wavelength " + peaks.iterator().next(); + for(IChromatogramPeakWSD wsd : peaks) { + wsd.addClassifier(classifier); + } + } + extractPeaks.addAll(peaks); + } + return extractPeaks; } /** @@ -107,9 +196,12 @@ public List detectPeaks(IChromatogramSelectionWSD chromato * @param chromatogram * @return List */ - private List extractPeaks(List rawPeaks, IChromatogramWSD chromatogram, PeakDetectorSettingsWSD peakDetectorSettings) { + private List extractPeaks(List rawPeaks, IChromatogramWSD chromatogram, PeakDetectorSettingsWSD peakDetectorSettings, IMarkedWavelengths wavelengths) { List peaks = new ArrayList<>(); + Set traces = wavelengths.getWavelengths().stream().map(e -> e.intValue()).collect(Collectors.toSet()); + boolean includeBackground = peakDetectorSettings.isIncludeBackground(); + boolean optimizeBaseline = peakDetectorSettings.isOptimizeBaseline(); // IChromatogramPeakWSD peak = null; IScanRange scanRange = null; @@ -118,13 +210,19 @@ private List extractPeaks(List rawPeaks, IChroma * Build the peak and add it. */ try { + /* + * Optimize the scan range. + */ scanRange = new ScanRange(rawPeak.getStartScan(), rawPeak.getStopScan()); + if(includeBackground && optimizeBaseline) { + scanRange = optimizeBaseline(chromatogram, scanRange.getStartScan(), rawPeak.getMaximumScan(), scanRange.getStopScan(), wavelengths); + } /* * includeBackground * false: BV or VB * true: VV */ - peak = PeakBuilderWSD.createPeak(chromatogram, scanRange, peakDetectorSettings.isIncludeBackground()); + peak = PeakBuilderWSD.createPeak(chromatogram, scanRange, includeBackground, traces, wavelengths.getMode()); if(isValidPeak(peak)) { /* * Add the detector description. @@ -149,38 +247,45 @@ private List extractPeaks(List rawPeaks, IChroma * @param window * @return {@link IFirstDerivativeDetectorSlopes} */ - public static IFirstDerivativeDetectorSlopes getFirstDerivativeSlopes(IChromatogramSelectionWSD chromatogramSelection, int windowSize) { + public static IFirstDerivativeDetectorSlopes getFirstDerivativeSlopes(IChromatogramSelectionWSD chromatogramSelection, int windowSize, IMarkedWavelengths filterWavelengths) { - ITotalScanSignals signals = new TotalScanSignals(chromatogramSelection); - TotalScanSignalsModifier.normalize(signals, NORMALIZATION_BASE); - /* - * Get the start and stop scan of the chromatogram selection. - */ - IFirstDerivativeDetectorSlopes slopes = new FirstDerivativeDetectorSlopes(signals); - /* - * Fill the slope list. - */ - int startScan = signals.getStartScan(); - int stopScan = signals.getStopScan(); - // - for(int scan = startScan; scan < stopScan; scan++) { - ITotalScanSignal s1 = signals.getTotalScanSignal(scan); - ITotalScanSignal s2 = signals.getNextTotalScanSignal(scan); - if(s1 != null && s2 != null) { - IPoint p1 = new Point(s1.getRetentionTime(), s1.getTotalSignal()); - IPoint p2 = new Point(s2.getRetentionTime(), s2.getTotalSignal()); - IFirstDerivativeDetectorSlope slope = new FirstDerivativeDetectorSlope(p1, p2, s1.getRetentionTime()); - slopes.add(slope); + IChromatogramWSD chromatogram = chromatogramSelection.getChromatogram(); + try { + ITotalWavelengthSignalExtractor totalWavelengthSignalExtractor = new TotalWavelengthSignalExtractor(chromatogram); + ITotalScanSignals signals = totalWavelengthSignalExtractor.getTotalWavelengthSignals(chromatogramSelection, filterWavelengths); + TotalScanSignalsModifier.normalize(signals, NORMALIZATION_BASE); + /* + * Get the start and stop scan of the chromatogram selection. + */ + IFirstDerivativeDetectorSlopes slopes = new FirstDerivativeDetectorSlopes(signals); + /* + * Fill the slope list. + */ + int startScan = signals.getStartScan(); + int stopScan = signals.getStopScan(); + // + for(int scan = startScan; scan < stopScan; scan++) { + ITotalScanSignal s1 = signals.getTotalScanSignal(scan); + ITotalScanSignal s2 = signals.getNextTotalScanSignal(scan); + if(s1 != null && s2 != null) { + IPoint p1 = new Point(s1.getRetentionTime(), s1.getTotalSignal()); + IPoint p2 = new Point(s2.getRetentionTime(), s2.getTotalSignal()); + IFirstDerivativeDetectorSlope slope = new FirstDerivativeDetectorSlope(p1, p2, s1.getRetentionTime()); + slopes.add(slope); + } } + /* + * Moving average on the slopes + */ + if(windowSize != 0) { + slopes.calculateMovingAverage(windowSize); + } + // + return slopes; + } catch(ChromatogramIsNullException e) { + logger.warn(e.getLocalizedMessage(), e); + return null; } - /* - * Moving average on the slopes - */ - if(windowSize != 0) { - slopes.calculateMovingAverage(windowSize); - } - // - return slopes; } /** @@ -200,4 +305,72 @@ private boolean isValidPeak(IChromatogramPeakWSD peak) { } return false; } + + protected ScanRange optimizeBaseline(IChromatogramWSD chromatogram, int startScan, int centerScan, int stopScan, IMarkedWavelengths wavelengths) { + + /* + * Right and left baseline optimization + */ + int stopScanOptimized = optimizeRightBaseline(chromatogram, startScan, centerScan, stopScan, wavelengths); + int startScanOptimized = optimizeLeftBaseline(chromatogram, startScan, centerScan, stopScanOptimized, wavelengths); + // + return new ScanRange(startScanOptimized, stopScanOptimized); + } + + protected float getScanSignal(IChromatogramWSD chromatogram, int scanNumber, IMarkedWavelengths wavelengths) { + + IScan scan = chromatogram.getScan(scanNumber); + if(scan instanceof IScanWSD) { + IScanWSD scanWSD = (IScanWSD)scan; + return scanWSD.getTotalSignal(wavelengths); + } else { + return scan.getTotalSignal(); + } + } + + private int optimizeRightBaseline(IChromatogramWSD chromatogram, int startScan, int centerScan, int stopScan, IMarkedWavelengths wavelengths) { + + IPoint p1 = new Point(getRetentionTime(chromatogram, startScan), getScanSignal(chromatogram, startScan, wavelengths)); + IPoint p2 = new Point(getRetentionTime(chromatogram, stopScan), getScanSignal(chromatogram, stopScan, wavelengths)); + LinearEquation backgroundEquation = Equations.createLinearEquation(p1, p2); + /* + * Right border optimization + */ + int stopScanOptimized = stopScan; + for(int i = stopScan; i > centerScan; i--) { + float signal = getScanSignal(chromatogram, i, wavelengths); + int retentionTime = chromatogram.getScan(i).getRetentionTime(); + if(signal < backgroundEquation.calculateY(retentionTime)) { + stopScanOptimized = i; + } + } + // + return stopScanOptimized; + } + + private int optimizeLeftBaseline(IChromatogramWSD chromatogram, int startScan, int centerScan, int stopScan, IMarkedWavelengths wavelengths) { + + IPoint p1 = new Point(getRetentionTime(chromatogram, startScan), getScanSignal(chromatogram, startScan, wavelengths)); + IPoint p2 = new Point(getRetentionTime(chromatogram, stopScan), getScanSignal(chromatogram, stopScan, wavelengths)); + LinearEquation backgroundEquation = Equations.createLinearEquation(p1, p2); + /* + * Right border optimization + */ + int startScanOptimized = startScan; + for(int i = startScan; i < centerScan; i++) { + float signal = getScanSignal(chromatogram, i, wavelengths); + int retentionTime = chromatogram.getScan(i).getRetentionTime(); + if(signal < backgroundEquation.calculateY(retentionTime)) { + /* + * Create a new equation + */ + startScanOptimized = i; + p1 = new Point(getRetentionTime(chromatogram, startScanOptimized), getScanSignal(chromatogram, startScanOptimized, wavelengths)); + p2 = new Point(getRetentionTime(chromatogram, stopScan), getScanSignal(chromatogram, stopScan, wavelengths)); + backgroundEquation = Equations.createLinearEquation(p1, p2); + } + } + // + return startScanOptimized; + } } diff --git a/chemclipse/plugins/org.eclipse.chemclipse.chromatogram.xxd.peak.detector.supplier.firstderivative/src/org/eclipse/chemclipse/chromatogram/xxd/peak/detector/supplier/firstderivative/settings/PeakDetectorSettingsWSD.java b/chemclipse/plugins/org.eclipse.chemclipse.chromatogram.xxd.peak.detector.supplier.firstderivative/src/org/eclipse/chemclipse/chromatogram/xxd/peak/detector/supplier/firstderivative/settings/PeakDetectorSettingsWSD.java index cf1edde691..c709c9371a 100644 --- a/chemclipse/plugins/org.eclipse.chemclipse.chromatogram.xxd.peak.detector.supplier.firstderivative/src/org/eclipse/chemclipse/chromatogram/xxd/peak/detector/supplier/firstderivative/settings/PeakDetectorSettingsWSD.java +++ b/chemclipse/plugins/org.eclipse.chemclipse.chromatogram.xxd.peak.detector.supplier.firstderivative/src/org/eclipse/chemclipse/chromatogram/xxd/peak/detector/supplier/firstderivative/settings/PeakDetectorSettingsWSD.java @@ -9,9 +9,20 @@ * Contributors: * Dr. Philip Wenig - initial API and implementation * Matthias Mailänder - remove the window size enum + * Matthias Mailänder - add wavelength filters *******************************************************************************/ package org.eclipse.chemclipse.chromatogram.xxd.peak.detector.supplier.firstderivative.settings; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.StringUtils; +import org.eclipse.chemclipse.chromatogram.peak.detector.core.FilterMode; import org.eclipse.chemclipse.chromatogram.peak.detector.model.Threshold; import org.eclipse.chemclipse.chromatogram.wsd.peak.detector.settings.AbstractPeakDetectorWSDSettings; import org.eclipse.chemclipse.chromatogram.xxd.peak.detector.supplier.firstderivative.preferences.PreferenceSupplier; @@ -19,7 +30,13 @@ import org.eclipse.chemclipse.support.settings.IntSettingsProperty; import org.eclipse.chemclipse.support.settings.IntSettingsProperty.Validation; import org.eclipse.chemclipse.support.settings.serialization.WindowSizeDeserializer; +import org.eclipse.chemclipse.wsd.model.core.support.IMarkedWavelength; +import org.eclipse.chemclipse.wsd.model.core.support.IMarkedWavelength.WavelengthMarkMode; +import org.eclipse.chemclipse.wsd.model.core.support.IMarkedWavelengths; +import org.eclipse.chemclipse.wsd.model.core.support.MarkedWavelength; +import org.eclipse.chemclipse.wsd.model.core.support.MarkedWavelengths; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonPropertyDescription; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @@ -39,6 +56,18 @@ public class PeakDetectorSettingsWSD extends AbstractPeakDetectorWSDSettings { @IntSettingsProperty(minValue = PreferenceSupplier.MIN_WINDOW_SIZE, maxValue = PreferenceSupplier.MAX_WINDOW_SIZE, validation = Validation.ODD_NUMBER_INCLUDING_ZERO) @JsonDeserialize(using = WindowSizeDeserializer.class) private int windowSize; + @JsonProperty(value = "Use Noise-Segments", defaultValue = "false") + @JsonPropertyDescription(value = "Whether to use noise segments to decide where peaks should be detected. This can improve the sensitivity of the algorithm.") + private boolean useNoiseSegments = false; + @JsonProperty(value = "Filter Mode", defaultValue = "EXCLUDE") + private FilterMode filterMode = FilterMode.EXCLUDE; + @JsonProperty(value = "Wavelengths to filter", defaultValue = "") + private String filterWavelengths; + @JsonProperty(value = "Use Individual Wavelengths", defaultValue = "false") + @JsonPropertyDescription("Uses each wavelength in the filter-list individualy to detect peaks") + private boolean useIndividualWavelengths = false; + @JsonProperty(value = "Optimize Baseline (VV)", defaultValue = "false") + private boolean optimizeBaseline = false; public PeakDetectorSettingsWSD() { @@ -86,4 +115,91 @@ public void setMovingAverageWindowSize(int windowSize) { this.windowSize = windowSize; } + + public boolean isUseNoiseSegments() { + + return useNoiseSegments; + } + + public void setUseNoiseSegments(boolean useNoiseSegments) { + + this.useNoiseSegments = useNoiseSegments; + } + + public FilterMode getFilterMode() { + + return filterMode == null ? FilterMode.EXCLUDE : filterMode; + } + + public void setFilterMode(FilterMode filterMode) { + + this.filterMode = filterMode; + } + + static Collection parseWavelengths(String input) { + + if(StringUtils.isBlank(input)) { + return Collections.emptyList(); + } + List waveLengths = new ArrayList<>(); + String[] split = input.trim().split("[\\s.,;]+"); + for(String s : split) { + try { + waveLengths.add(new BigDecimal(s)); + } catch(NumberFormatException e) { + // invalid or empty string + } + } + return waveLengths; + } + + public boolean isIndividualWavelengths() { + + return useIndividualWavelengths; + } + + public void setUseIndividualTraces(boolean useIndividualWavelengths) { + + this.useIndividualWavelengths = useIndividualWavelengths; + } + + @JsonIgnore + public Collection getFilterWavelengths() { + + WavelengthMarkMode wavelengthMarkMode; + switch(getFilterMode()) { + case EXCLUDE: + wavelengthMarkMode = WavelengthMarkMode.INCLUDE; + break; + case INCLUDE: + wavelengthMarkMode = WavelengthMarkMode.EXCLUDE; + break; + default: + throw new IllegalArgumentException("Unsupported filter mode " + getFilterMode()); + } + Set parsedWavelengths = parseWavelengths(filterWavelengths).stream().map(e -> new MarkedWavelength(e.doubleValue())).collect(Collectors.toSet()); + if(isIndividualWavelengths()) { + List listedWavelengths = new ArrayList<>(); + for(IMarkedWavelength wavelength : parsedWavelengths) { + IMarkedWavelengths markedWavelengths = new MarkedWavelengths(wavelengthMarkMode); + markedWavelengths.add(wavelength); + listedWavelengths.add(markedWavelengths); + } + return listedWavelengths; + } else { + IMarkedWavelengths markedWavelengths = new MarkedWavelengths(wavelengthMarkMode); + markedWavelengths.addAll(parsedWavelengths); + return Collections.singleton(markedWavelengths); + } + } + + public boolean isOptimizeBaseline() { + + return optimizeBaseline; + } + + public void setOptimizeBaseline(boolean optimizeBaseline) { + + this.optimizeBaseline = optimizeBaseline; + } } diff --git a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/AbstractScanWSD.java b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/AbstractScanWSD.java index 1881b56e9b..0f48c4fb46 100644 --- a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/AbstractScanWSD.java +++ b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/AbstractScanWSD.java @@ -14,6 +14,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.Iterator; import java.util.List; import java.util.Optional; import java.util.Set; @@ -22,6 +23,7 @@ import org.eclipse.chemclipse.wsd.model.comparator.WavelengthCombinedComparator; import org.eclipse.chemclipse.wsd.model.comparator.WavelengthComparatorMode; import org.eclipse.chemclipse.wsd.model.core.implementation.ScanSignalWSD; +import org.eclipse.chemclipse.wsd.model.core.support.IMarkedWavelengths; import org.eclipse.chemclipse.wsd.model.xwc.ExtractedSingleWavelengthSignal; import org.eclipse.chemclipse.wsd.model.xwc.ExtractedWavelengthSignal; import org.eclipse.chemclipse.wsd.model.xwc.IExtractedSingleWavelengthSignal; @@ -135,6 +137,40 @@ public float getTotalSignal() { return totalSignal; } + @Override + public float getTotalSignal(IMarkedWavelengths markedWavelengths) { + + float totalSignal = 0; + /* + * If the excluded ions are null, return the total signal. + */ + if(markedWavelengths == null || markedWavelengths.isEmpty()) { + totalSignal = getTotalSignal(); + } else { + Iterator iterator = scanSignals.iterator(); + while(iterator.hasNext()) { + IScanSignalWSD scan = iterator.next(); + if(useWavelength(scan, markedWavelengths)) { + totalSignal += scan.getAbundance(); + } + } + } + return totalSignal; + } + + private static boolean useWavelength(IScanSignalWSD scan, IMarkedWavelengths filterWavelengths) { + + Set wavelengths = filterWavelengths.getWavelengths(); + switch(filterWavelengths.getMode()) { + case EXCLUDE: + return wavelengths.contains(scan.getWavelength()); + case INCLUDE: + return !wavelengths.contains(scan.getWavelength()); + default: + return true; + } + } + @Override public void adjustTotalSignal(float totalSignal) { diff --git a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/IScanWSD.java b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/IScanWSD.java index 089938abc7..277afcc5b6 100644 --- a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/IScanWSD.java +++ b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/IScanWSD.java @@ -8,6 +8,7 @@ * * Contributors: * Dr. Philip Wenig - initial API and implementation + * Matthias Mailänder - add total signal except excluded *******************************************************************************/ package org.eclipse.chemclipse.wsd.model.core; @@ -16,6 +17,7 @@ import java.util.Set; import org.eclipse.chemclipse.model.core.IScan; +import org.eclipse.chemclipse.wsd.model.core.support.IMarkedWavelengths; import org.eclipse.chemclipse.wsd.model.xwc.IExtractedSingleWavelengthSignal; import org.eclipse.chemclipse.wsd.model.xwc.IExtractedWavelengthSignal; @@ -47,11 +49,17 @@ public interface IScanWSD extends IScan { IExtractedWavelengthSignal getExtractedWavelengthSignal(); - IExtractedWavelengthSignal getExtractedWavelengthSignal(double startIon, double stopIon); + IExtractedWavelengthSignal getExtractedWavelengthSignal(double startWavelength, double stopWavelength); Optional getExtractedSingleWavelengthSignal(double wavelength); boolean hasScanSignals(); IWavelengthBounds getWavelengthBounds(); + + /** + * + * @return total intensity count (TIC) excepted excluded wavelengths + */ + float getTotalSignal(IMarkedWavelengths excludedWavelenths); } diff --git a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/AbstractMarkedWavelengths.java b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/AbstractMarkedWavelengths.java index 2036bc1806..735f44d846 100644 --- a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/AbstractMarkedWavelengths.java +++ b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/AbstractMarkedWavelengths.java @@ -16,7 +16,7 @@ import java.util.Iterator; import java.util.Set; -public class AbstractMarkedWavelengths implements IMarkedWavelengths { +public abstract class AbstractMarkedWavelengths implements IMarkedWavelengths { private Set markedWavelengths; @@ -25,6 +25,16 @@ public AbstractMarkedWavelengths() { markedWavelengths = new HashSet<>(); } + protected AbstractMarkedWavelengths(Collection wavelengths) { + + markedWavelengths = new HashSet<>(); + if(wavelengths != null) { + for(Number wavelength : wavelengths) { + markedWavelengths.add(new MarkedWavelength(wavelength.intValue())); + } + } + } + @Override public boolean add(IMarkedWavelength e) { diff --git a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/IMarkedWavelength.java b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/IMarkedWavelength.java index 861f2d6b67..032aed9db1 100644 --- a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/IMarkedWavelength.java +++ b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/IMarkedWavelength.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2018 Lablicate GmbH. + * Copyright (c) 2016, 2021 Lablicate GmbH. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -12,9 +12,40 @@ package org.eclipse.chemclipse.wsd.model.core.support; import org.eclipse.chemclipse.model.core.IMarkedSignal; +import org.eclipse.chemclipse.support.text.ILabel; public interface IMarkedWavelength extends IMarkedSignal { + enum WavelengthMarkMode implements ILabel { + + /** + * In this mode, all wavelengths in the list are considered as an exclusion, that means apply the given function to all except the given wavelengths + */ + EXCLUDE("Exclude"), + /** + * In this mode, all wavelengths in the list are considered as an inclusion, that means apply the given function to all wavelengths given + */ + INCLUDE("Include"); + + private String label = ""; + + private WavelengthMarkMode(String label) { + + this.label = label; + } + + @Override + public String label() { + + return label; + } + + public static String[][] getOptions() { + + return ILabel.getOptions(values()); + } + } + double getWavelength(); void setWavelength(double wavelength); diff --git a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/IMarkedWavelengths.java b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/IMarkedWavelengths.java index 6bddb6d3d5..e3f1abb29f 100644 --- a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/IMarkedWavelengths.java +++ b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/IMarkedWavelengths.java @@ -15,6 +15,7 @@ import java.util.Set; import org.eclipse.chemclipse.model.core.IMarkedSignals; +import org.eclipse.chemclipse.wsd.model.core.support.IMarkedWavelength.WavelengthMarkMode; public interface IMarkedWavelengths extends IMarkedSignals { @@ -43,4 +44,6 @@ public interface IMarkedWavelengths extends IMarkedSignals { */ @Deprecated void add(int wavelengthStart, int wavelengthStop); + + WavelengthMarkMode getMode(); } diff --git a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/MarkedWavelengths.java b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/MarkedWavelengths.java index 46d9d26c3d..f9677dde63 100644 --- a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/MarkedWavelengths.java +++ b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/MarkedWavelengths.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2018 Lablicate GmbH. + * Copyright (c) 2016, 2021 Lablicate GmbH. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -8,8 +8,36 @@ * * Contributors: * Dr. Philip Wenig - initial API and implementation + * Matthias Mailänder - add inclusive/exclusive mode *******************************************************************************/ package org.eclipse.chemclipse.wsd.model.core.support; +import java.util.Collection; + +import org.eclipse.chemclipse.wsd.model.core.support.IMarkedWavelength.WavelengthMarkMode; + public class MarkedWavelengths extends AbstractMarkedWavelengths implements IMarkedWavelengths { + + private WavelengthMarkMode mode; + + public MarkedWavelengths() { + + } + + public MarkedWavelengths(WavelengthMarkMode mode) { + + this.mode = mode; + } + + public MarkedWavelengths(Collection wavelengths, WavelengthMarkMode mode) { + + super(wavelengths); + this.mode = mode; + } + + @Override + public WavelengthMarkMode getMode() { + + return mode; + } } diff --git a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/PeakBuilderWSD.java b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/PeakBuilderWSD.java index 11b9661a95..fd08721726 100644 --- a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/PeakBuilderWSD.java +++ b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/core/support/PeakBuilderWSD.java @@ -40,13 +40,21 @@ import org.eclipse.chemclipse.wsd.model.core.implementation.PeakModelWSD; import org.eclipse.chemclipse.wsd.model.core.implementation.ScanSignalWSD; import org.eclipse.chemclipse.wsd.model.core.implementation.ScanWSD; +import org.eclipse.chemclipse.wsd.model.core.support.IMarkedWavelength.WavelengthMarkMode; import org.eclipse.chemclipse.wsd.model.xwc.ExtractedWavelengthSignalExtractor; import org.eclipse.chemclipse.wsd.model.xwc.IExtractedWavelengthSignal; import org.eclipse.chemclipse.wsd.model.xwc.IExtractedWavelengthSignalExtractor; import org.eclipse.chemclipse.wsd.model.xwc.IExtractedWavelengthSignals; +import org.eclipse.chemclipse.wsd.model.xwc.ITotalWavelengthSignalExtractor; +import org.eclipse.chemclipse.wsd.model.xwc.TotalWavelengthSignalExtractor; public class PeakBuilderWSD { + private PeakBuilderWSD() { + + throw new IllegalStateException("This utility class is meant to only host static functions."); + } + public static IChromatogramPeakWSD createPeak(IChromatogramWSD chromatogram, IScanRange scanRange, boolean calculatePeakIncludedBackground) throws PeakException { /* @@ -101,35 +109,66 @@ public static IChromatogramPeakWSD createPeak(IChromatogramWSD chromatogram, ISc return new ChromatogramPeakWSD(peakModel, chromatogram); } - public static IChromatogramPeakWSD createPeak(IChromatogramWSD chromatogram, IScanRange scanRange, boolean calculatePeakIncludedBackground, Set traces) throws PeakException { + public static IChromatogramPeakWSD createPeak(IChromatogramWSD chromatogram, IScanRange scanRange, boolean calculatePeakIncludedBackground, Set includedWavelengths, WavelengthMarkMode filterMode) throws PeakException { + + /* + * Get the total signals and determine the start and stop background + * abundance. + */ + ITotalScanSignals totalWavelengthSignals = getTotalIonSignals(chromatogram, scanRange, new MarkedWavelengths(includedWavelengths, filterMode)); + /* + * Retrieve the start and stop signals of the peak to calculate its + * chromatogram and eventually peak internal background, if the start + * abundance is higher than the stop abundance or vice versa. + */ + ITotalScanSignal totalWavelengthSignal = totalWavelengthSignals.getTotalScanSignal(scanRange.getStartScan()); + float startBackgroundAbundance = totalWavelengthSignal.getTotalSignal(); + totalWavelengthSignal = totalWavelengthSignals.getTotalScanSignal(scanRange.getStopScan()); + float stopBackgroundAbundance = totalWavelengthSignal.getTotalSignal(); + /* + * The abundance of base or startBackground/stopBackground (depends + * which is the lower value) is the chromatogram background.
Then a + * peak included background could be calculated or not.
This + * background is not the background of the chromatogram. It's the + * background of the peak.
Think of, a peak could be skewed, means + * it starts with an abundance of zero and stops with a higher + * abundance.
To include or exclude the background abundance in the + * IPeakModel affects the calculation of its width at different heights. + */ + IBackgroundAbundanceRange backgroundAbundanceRange; + if(calculatePeakIncludedBackground) { + backgroundAbundanceRange = new BackgroundAbundanceRange(startBackgroundAbundance, stopBackgroundAbundance); + } else { + float base = Math.min(startBackgroundAbundance, stopBackgroundAbundance); + backgroundAbundanceRange = new BackgroundAbundanceRange(base, base); + } + LinearEquation backgroundEquation = getBackgroundEquation(totalWavelengthSignals, scanRange, backgroundAbundanceRange); + /* + * Calculate the intensity values. + */ + ITotalScanSignals peakIntensityTotalIonSignals = adjustTotalScanSignals(totalWavelengthSignals, backgroundEquation); + IPeakIntensityValues peakIntensityValues = getPeakIntensityValues(peakIntensityTotalIonSignals); + IScanWSD peakScan = getPeakScan(chromatogram, peakIntensityTotalIonSignals, backgroundEquation); + /* + * Create the peak. + */ + IPeakModelWSD peakModel = new PeakModelWSD(peakScan, peakIntensityValues, backgroundAbundanceRange.getStartBackgroundAbundance(), backgroundAbundanceRange.getStopBackgroundAbundance()); + return new ChromatogramPeakWSD(peakModel, chromatogram); + } + + private static ITotalScanSignals getTotalIonSignals(IChromatogramWSD chromatogram, IScanRange scanRange, MarkedWavelengths excludedWavelengths) { + if(chromatogram == null || scanRange == null || excludedWavelengths == null) { + throw new PeakException("The given values must not be null."); + } + /* + * Try to get the signals. + */ try { - IExtractedWavelengthSignals extractedWavelengthSignals = getExtractedWavelengthSignals(chromatogram, scanRange, traces); - IExtractedWavelengthSignal extractedWavelengthSignalStart = extractedWavelengthSignals.getExtractedWavelengthSignal(scanRange.getStartScan()); - float startBackgroundAbundance = extractedWavelengthSignalStart.getTotalSignal(); - IExtractedWavelengthSignal extractedWavelengthSignalStop = extractedWavelengthSignals.getExtractedWavelengthSignal(scanRange.getStopScan()); - float stopBackgroundAbundance = extractedWavelengthSignalStop.getTotalSignal(); - /* - * The abundance of base or startBackground/stopBackground (depends - * which is the lower value) is the chromatogram background.
Then a - * peak included background could be calculated or not.
This - * background is not the background of the chromatogram. It's the - * background of the peak.
Think of, a peak could be skewed, means - * it starts with an abundance of zero and stops with a higher - * abundance.
To include or exclude the background abundance in the - * IPeakModel affects the calculation of its width at different heights. - */ - IBackgroundAbundanceRange backgroundAbundanceRange; - if(calculatePeakIncludedBackground) { - backgroundAbundanceRange = new BackgroundAbundanceRange(startBackgroundAbundance, stopBackgroundAbundance); - } else { - float base = Math.min(startBackgroundAbundance, stopBackgroundAbundance); - backgroundAbundanceRange = new BackgroundAbundanceRange(base, base); - } - // - return createPeak(chromatogram, scanRange, backgroundAbundanceRange.getStartBackgroundAbundance(), backgroundAbundanceRange.getStopBackgroundAbundance(), traces); - } catch(Exception e) { - throw new PeakException(); + ITotalWavelengthSignalExtractor totalWavelengthSignalExtractor = new TotalWavelengthSignalExtractor(chromatogram); + return totalWavelengthSignalExtractor.getTotalScanSignals(scanRange.getStartScan(), scanRange.getStopScan(), excludedWavelengths); + } catch(ChromatogramIsNullException e) { + throw new PeakException("The chromatogram must not be null."); } } diff --git a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/xwc/ITotalWavelengthSignalExtractor.java b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/xwc/ITotalWavelengthSignalExtractor.java index e53ace92f3..8fb83ca5ee 100644 --- a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/xwc/ITotalWavelengthSignalExtractor.java +++ b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/xwc/ITotalWavelengthSignalExtractor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2018 Lablicate GmbH. + * Copyright (c) 2017, 2021 Lablicate GmbH. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -14,16 +14,14 @@ import org.eclipse.chemclipse.model.signals.ITotalScanSignalExtractor; import org.eclipse.chemclipse.model.signals.ITotalScanSignals; import org.eclipse.chemclipse.wsd.model.core.selection.IChromatogramSelectionWSD; +import org.eclipse.chemclipse.wsd.model.core.support.IMarkedWavelengths; +import org.eclipse.chemclipse.wsd.model.core.support.MarkedWavelengths; -/** - * @deprecated Use {@link IExtractedSingleWavelengthSignalExtractor} instead - * - * @see {@link ISingleWavelengthSignals} - * @see {@link ISingleWavelengthSignal} - * - */ -@Deprecated public interface ITotalWavelengthSignalExtractor extends ITotalScanSignalExtractor { ITotalScanSignals getTotalWavelengthSignals(IChromatogramSelectionWSD chromatogramSelection); + + ITotalScanSignals getTotalWavelengthSignals(IChromatogramSelectionWSD chromatogramSelection, IMarkedWavelengths excludedWavelengths); + + ITotalScanSignals getTotalScanSignals(int startScan, int stopScan, MarkedWavelengths excludedWavelengths); } diff --git a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/xwc/TotalWavelengthSignalExtractor.java b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/xwc/TotalWavelengthSignalExtractor.java index 01d36ed312..d51683b2bb 100644 --- a/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/xwc/TotalWavelengthSignalExtractor.java +++ b/chemclipse/plugins/org.eclipse.chemclipse.wsd.model/src/org/eclipse/chemclipse/wsd/model/xwc/TotalWavelengthSignalExtractor.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2017, 2018 Lablicate GmbH. + * Copyright (c) 2017, 2021 Lablicate GmbH. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -8,6 +8,7 @@ * * Contributors: * Dr. Philip Wenig - initial API and implementation + * Matthias Mailänder - add support for excluded wavelengths *******************************************************************************/ package org.eclipse.chemclipse.wsd.model.xwc; @@ -20,20 +21,15 @@ import org.eclipse.chemclipse.wsd.model.core.IChromatogramWSD; import org.eclipse.chemclipse.wsd.model.core.IScanWSD; import org.eclipse.chemclipse.wsd.model.core.selection.IChromatogramSelectionWSD; +import org.eclipse.chemclipse.wsd.model.core.support.IMarkedWavelengths; +import org.eclipse.chemclipse.wsd.model.core.support.MarkedWavelengths; -/** - * @deprecated Use {@link ExtractedSingleWavelengthSignalExtractor} instead - * - * @see {@link IExtractedSingleWavelengthSignals} - * @see {@link IExtractedSingleWavelengthSignal} - * - */ -@Deprecated public class TotalWavelengthSignalExtractor extends TotalScanSignalExtractor implements ITotalWavelengthSignalExtractor { private IChromatogramWSD chromatogram; public TotalWavelengthSignalExtractor(IChromatogramWSD chromatogram) throws ChromatogramIsNullException { + super(chromatogram); this.chromatogram = chromatogram; } @@ -52,22 +48,72 @@ public ITotalScanSignals getTotalWavelengthSignals(IChromatogramSelectionWSD chr return initializeTotalWavelengthSignals(startScan, stopScan, null); } - private ITotalScanSignals initializeTotalWavelenghtSignals(int startScan, int stopScan) { + private ITotalScanSignals initializeTotalWavelengthSignals(int startScan, int stopScan, IMarkedWavelengths excludedWavelengths) { - assert (startScan <= stopScan) : "The startScan must be lower or equal the stop scan."; + if(startScan > stopScan) { + throw new IllegalArgumentException("The start scan " + startScan + " must be lower or equal the stop scan " + stopScan + "."); + } /* * Validate the scan borders. */ if(startScan < 1 || startScan > chromatogram.getNumberOfScans() || stopScan < 1 || stopScan > chromatogram.getNumberOfScans()) { return new TotalScanSignals(0, chromatogram); } + /* + * Create the total ion signals object. + */ + ITotalScanSignals signals = new TotalScanSignals(startScan, stopScan, chromatogram); /* * Add the selected scans. */ + for(int scan = startScan; scan <= stopScan; scan++) { + IScanWSD scanWSD = chromatogram.getSupplierScan(scan); + ITotalScanSignal totalWavelengthSignal = new TotalScanSignal(scanWSD.getRetentionTime(), scanWSD.getRetentionIndex(), scanWSD.getTotalSignal(excludedWavelengths)); + signals.add(totalWavelengthSignal); + } + return signals; + } + + @Override + public ITotalScanSignals getTotalWavelengthSignals(IChromatogramSelectionWSD chromatogramSelection, IMarkedWavelengths excludedWavelengths) { + + if(chromatogramSelection == null || chromatogramSelection.getChromatogram() != chromatogram) { + return new TotalScanSignals(0, chromatogram); + } + /* + * Get the start and stop scan. + */ + int startScan = chromatogram.getScanNumber(chromatogramSelection.getStartRetentionTime()); + int stopScan = chromatogram.getScanNumber(chromatogramSelection.getStopRetentionTime()); + /* + * If excludedMassFragements is null the the total ion list will be + * returned. + */ + return initializeTotalWavelengthSignals(startScan, stopScan, excludedWavelengths); + } + + @Override + public ITotalScanSignals getTotalScanSignals(int startScan, int stopScan, MarkedWavelengths excludedWavelengths) { + + if(startScan > stopScan) { + throw new IllegalArgumentException("The start scan " + startScan + " must be lower or equal the stop scan " + stopScan + "."); + } + /* + * Validate the scan borders. + */ + if(startScan < 1 || startScan > chromatogram.getNumberOfScans() || stopScan < 1 || stopScan > chromatogram.getNumberOfScans()) { + return new TotalScanSignals(0, chromatogram); + } + /* + * Create the total ion signals object. + */ ITotalScanSignals signals = new TotalScanSignals(startScan, stopScan, chromatogram); + /* + * Add the selected scans. + */ for(int scan = startScan; scan <= stopScan; scan++) { IScanWSD scanWSD = chromatogram.getSupplierScan(scan); - ITotalScanSignal totalWavelengthSignal = new TotalScanSignal(scanWSD.getRetentionTime(), scanWSD.getRetentionIndex(), scanWSD.getTotalSignal()); + ITotalScanSignal totalWavelengthSignal = new TotalScanSignal(scanWSD.getRetentionTime(), scanWSD.getRetentionIndex(), scanWSD.getTotalSignal(excludedWavelengths)); signals.add(totalWavelengthSignal); } return signals;