Java tutorial
/* * Copyright 2006-2015 The MZmine 2 Development Team * * This file is part of MZmine 2. * * MZmine 2 is free software; you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * MZmine 2 is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * MZmine 2; if not, write to the Free Software Foundation, Inc., 51 Franklin * St, Fifth Floor, Boston, MA 02110-1301 USA */ package net.sf.mzmine.modules.peaklistmethods.peakpicking.deconvolution; import java.util.Arrays; import javax.annotation.Nonnull; import net.sf.mzmine.datamodel.DataPoint; import net.sf.mzmine.datamodel.Feature; import net.sf.mzmine.datamodel.IsotopePattern; import net.sf.mzmine.datamodel.RawDataFile; import net.sf.mzmine.datamodel.Scan; import net.sf.mzmine.datamodel.impl.SimpleDataPoint; import net.sf.mzmine.util.MathUtils; import net.sf.mzmine.util.PeakUtils; import net.sf.mzmine.util.ScanUtils; import com.google.common.collect.Range; /** * ResolvedPeak * */ public class ResolvedPeak implements Feature { // Data file of this chromatogram private RawDataFile dataFile; // Chromatogram m/z, RT, height, area private double mz, rt, height, area; private Double fwhm = null, tf = null, af = null; // Scan numbers private int scanNumbers[]; // We store the values of data points as double[] arrays in order to save // memory, which would be wasted by keeping a lot of instances of // SimpleDataPoint (each instance takes 16 or 32 bytes of extra memory) private double dataPointMZValues[], dataPointIntensityValues[]; // Top intensity scan, fragment scan private int representativeScan, fragmentScan; // Ranges of raw data points private Range<Double> rawDataPointsIntensityRange, rawDataPointsMZRange, rawDataPointsRTRange; // Isotope pattern. Null by default but can be set later by deisotoping // method. private IsotopePattern isotopePattern = null; private int charge = 0; /** * Initializes this peak using data points from a given chromatogram - * regionStart marks the index of the first data point (inclusive), * regionEnd marks the index of the last data point (inclusive). The * selected region MUST NOT contain any zero-intensity data points, * otherwise exception is thrown. */ public ResolvedPeak(Feature chromatogram, int regionStart, int regionEnd) { assert regionEnd > regionStart; this.dataFile = chromatogram.getDataFile(); // Make an array of scan numbers of this peak scanNumbers = new int[regionEnd - regionStart + 1]; // Note that we cannot use chromatogram.getScanNumbers() here, because // the chromatogram may already have been deconvoluted -> scan numbers // would be a subset of all scans. The regionStart and regionEnd indexes // refer to all MS1 scans, therefore we use datafile.getScanNumbers(1) int chromatogramScanNumbers[] = chromatogram.getDataFile().getScanNumbers(1); System.arraycopy(chromatogramScanNumbers, regionStart, scanNumbers, 0, regionEnd - regionStart + 1); dataPointMZValues = new double[regionEnd - regionStart + 1]; dataPointIntensityValues = new double[regionEnd - regionStart + 1]; // Set raw data point ranges, height, rt and representative scan height = Double.MIN_VALUE; for (int i = 0; i < scanNumbers.length; i++) { DataPoint dp = chromatogram.getDataPoint(scanNumbers[i]); if (dp == null) { String error = "Cannot create a resolved peak in a region with missing data points: chromatogram " + chromatogram + " scans " + chromatogramScanNumbers[regionStart] + "-" + chromatogramScanNumbers[regionEnd] + ", missing data point in scan " + scanNumbers[i]; throw new IllegalArgumentException(error); } dataPointMZValues[i] = dp.getMZ(); dataPointIntensityValues[i] = dp.getIntensity(); if (rawDataPointsIntensityRange == null) { rawDataPointsIntensityRange = Range.singleton(dp.getIntensity()); rawDataPointsRTRange = Range.singleton(dataFile.getScan(scanNumbers[i]).getRetentionTime()); rawDataPointsMZRange = Range.singleton(dp.getMZ()); } else { rawDataPointsRTRange = rawDataPointsRTRange .span(Range.singleton(dataFile.getScan(scanNumbers[i]).getRetentionTime())); rawDataPointsIntensityRange = rawDataPointsIntensityRange.span(Range.singleton(dp.getIntensity())); rawDataPointsMZRange = rawDataPointsMZRange.span(Range.singleton(dp.getMZ())); } if (height < dp.getIntensity()) { height = dp.getIntensity(); rt = dataFile.getScan(scanNumbers[i]).getRetentionTime(); representativeScan = scanNumbers[i]; } } // Calculate median m/z mz = MathUtils.calcQuantile(dataPointMZValues, 0.5f); // Update area area = 0; for (int i = 1; i < scanNumbers.length; i++) { // For area calculation, we use retention time in seconds double previousRT = dataFile.getScan(scanNumbers[i - 1]).getRetentionTime() * 60d; double currentRT = dataFile.getScan(scanNumbers[i]).getRetentionTime() * 60d; double previousHeight = dataPointIntensityValues[i - 1]; double currentHeight = dataPointIntensityValues[i]; area += (currentRT - previousRT) * (currentHeight + previousHeight) / 2; } // Update fragment scan fragmentScan = ScanUtils.findBestFragmentScan(dataFile, rawDataPointsRTRange, rawDataPointsMZRange); if (fragmentScan > 0) { Scan fragmentScanObject = dataFile.getScan(fragmentScan); int precursorCharge = fragmentScanObject.getPrecursorCharge(); if (precursorCharge > 0) this.charge = precursorCharge; } } /** * This method returns a representative datapoint of this peak in a given * scan */ public DataPoint getDataPoint(int scanNumber) { int index = Arrays.binarySearch(scanNumbers, scanNumber); if (index < 0) return null; SimpleDataPoint dp = new SimpleDataPoint(dataPointMZValues[index], dataPointIntensityValues[index]); return dp; } /** * This method returns m/z value of the chromatogram */ public double getMZ() { return mz; } /** * This method returns a string with the basic information that defines this * peak * * @return String information */ public String toString() { return PeakUtils.peakToString(this); } public double getArea() { return area; } public double getHeight() { return height; } public int getMostIntenseFragmentScanNumber() { return fragmentScan; } public @Nonnull FeatureStatus getFeatureStatus() { return FeatureStatus.DETECTED; } public double getRT() { return rt; } public @Nonnull Range<Double> getRawDataPointsIntensityRange() { return rawDataPointsIntensityRange; } public @Nonnull Range<Double> getRawDataPointsMZRange() { return rawDataPointsMZRange; } public @Nonnull Range<Double> getRawDataPointsRTRange() { return rawDataPointsRTRange; } public int getRepresentativeScanNumber() { return representativeScan; } public @Nonnull int[] getScanNumbers() { return scanNumbers; } public @Nonnull RawDataFile getDataFile() { return dataFile; } public IsotopePattern getIsotopePattern() { return isotopePattern; } public void setIsotopePattern(@Nonnull IsotopePattern isotopePattern) { this.isotopePattern = isotopePattern; } public int getCharge() { return charge; } public void setCharge(int charge) { this.charge = charge; } public Double getFWHM() { return fwhm; } public void setFWHM(Double fwhm) { this.fwhm = fwhm; } public Double getTailingFactor() { return tf; } public void setTailingFactor(Double tf) { this.tf = tf; } public Double getAsymmetryFactor() { return af; } public void setAsymmetryFactor(Double af) { this.af = af; } }