net.sf.mzmine.modules.masslistmethods.chromatogrambuilder.Chromatogram.java Source code

Java tutorial

Introduction

Here is the source code for net.sf.mzmine.modules.masslistmethods.chromatogrambuilder.Chromatogram.java

Source

/*
 * Copyright 2006-2015 The MZmine 2 Development Team
 * 
 * This file is part of MZmine 2.
 * 
 * MZmine 2 is free software; you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 * 
 * MZmine 2 is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * MZmine 2; if not, write to the Free Software Foundation, Inc., 51 Franklin
 * St, Fifth Floor, Boston, MA 02110-1301 USA
 */

package net.sf.mzmine.modules.masslistmethods.chromatogrambuilder;

import java.util.Arrays;
import java.util.Hashtable;
import java.util.Map.Entry;
import java.util.Vector;

import javax.annotation.Nonnull;

import com.google.common.collect.Range;
import com.google.common.primitives.Ints;

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.main.MZmineCore;
import net.sf.mzmine.util.MathUtils;
import net.sf.mzmine.util.ScanUtils;

/**
 * Chromatogram implementing ChromatographicPeak. 
 */
public class Chromatogram implements Feature {

    // Data file of this chromatogram
    private RawDataFile dataFile;

    // Data points of the chromatogram (map of scan number -> m/z peak)
    private Hashtable<Integer, DataPoint> dataPointsMap;

    // Chromatogram m/z, RT, height, area
    private double mz, rt, height, area;
    private Double fwhm = null, tf = null, af = null;

    // Top intensity scan, fragment scan
    private int representativeScan = -1, fragmentScan = -1;

    // Ranges of raw data points
    private Range<Double> rawDataPointsIntensityRange, rawDataPointsMZRange, rawDataPointsRTRange;

    // A set of scan numbers of a segment which is currently being connected
    private Vector<Integer> buildingSegment;

    // Keep track of last added data point
    private DataPoint lastMzPeak;

    // Number of connected segments, which have been committed by
    // commitBuildingSegment()
    private int numOfCommittedSegments = 0;

    // Isotope pattern. Null by default but can be set later by deisotoping
    // method.
    private IsotopePattern isotopePattern;
    private int charge = 0;

    // Victor Trevino
    private int minScan = Integer.MAX_VALUE;
    private int maxScan = 0;
    private double minTime = 0;
    private double maxTime = 0;
    private double mzSum = 0;
    private int mzN = 0;

    private final int scanNumbers[];

    /**
     * Initializes this Chromatogram
     */
    public Chromatogram(RawDataFile dataFile, int scanNumbers[]) {
        this.dataFile = dataFile;
        this.scanNumbers = scanNumbers;

        rawDataPointsRTRange = dataFile.getDataRTRange(1);

        dataPointsMap = new Hashtable<Integer, DataPoint>();
        buildingSegment = new Vector<Integer>(128);
    }

    /**
     * This method adds a MzPeak to this Chromatogram. All values of this
     * Chromatogram (rt, m/z, intensity and ranges) are updated on request
     * 
     * @param mzValue
     */
    public void addMzPeak(int scanNumber, DataPoint mzValue) {
        dataPointsMap.put(scanNumber, mzValue);
        lastMzPeak = mzValue;
        mzSum += mzValue.getMZ();
        mzN++;
        mz = mzSum / mzN;
        buildingSegment.add(scanNumber);

        // Victor Trevio
        if (scanNumber < minScan) {
            minScan = scanNumber;
            minTime = dataFile.getScan(minScan).getRetentionTime();
        }
        if (scanNumber > maxScan) {
            maxScan = scanNumber;
            maxTime = dataFile.getScan(maxScan).getRetentionTime();
        }
        rt = (maxTime + minTime) / 2;
    }

    public DataPoint getDataPoint(int scanNumber) {
        return dataPointsMap.get(scanNumber);
    }

    /**
     * Returns m/z value of last added data point
     */
    public DataPoint getLastMzPeak() {
        return lastMzPeak;
    }

    /**
     * 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 "Chromatogram " + MZmineCore.getConfiguration().getMZFormat().format(mz) + " m/z";
    }

    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 void finishChromatogram() {

        int allScanNumbers[] = Ints.toArray(dataPointsMap.keySet());
        Arrays.sort(allScanNumbers);

        // Calculate median m/z
        double allMzValues[] = new double[allScanNumbers.length];
        for (int i = 0; i < allScanNumbers.length; i++) {
            allMzValues[i] = dataPointsMap.get(allScanNumbers[i]).getMZ();
        }
        mz = MathUtils.calcQuantile(allMzValues, 0.5f);

        // Update raw data point ranges, height, rt and representative scan
        height = Double.MIN_VALUE;
        for (int i = 0; i < allScanNumbers.length; i++) {

            DataPoint mzPeak = dataPointsMap.get(allScanNumbers[i]);

            // Replace the MzPeak instance with an instance of SimpleDataPoint,
            // to reduce the memory usage. After we finish this Chromatogram, we
            // don't need the additional data provided by the MzPeak

            dataPointsMap.put(allScanNumbers[i], mzPeak);

            if (i == 0) {
                rawDataPointsIntensityRange = Range.singleton(mzPeak.getIntensity());
                rawDataPointsMZRange = Range.singleton(mzPeak.getMZ());
            } else {
                rawDataPointsIntensityRange = rawDataPointsIntensityRange
                        .span(Range.singleton(mzPeak.getIntensity()));
                rawDataPointsMZRange = rawDataPointsMZRange.span(Range.singleton(mzPeak.getMZ()));
            }

            if (height < mzPeak.getIntensity()) {
                height = mzPeak.getIntensity();
                rt = dataFile.getScan(allScanNumbers[i]).getRetentionTime();
                representativeScan = allScanNumbers[i];
            }
        }

        // Update area
        area = 0;
        for (int i = 1; i < allScanNumbers.length; i++) {
            // For area calculation, we use retention time in seconds
            double previousRT = dataFile.getScan(allScanNumbers[i - 1]).getRetentionTime() * 60d;
            double currentRT = dataFile.getScan(allScanNumbers[i]).getRetentionTime() * 60d;
            double previousHeight = dataPointsMap.get(allScanNumbers[i - 1]).getIntensity();
            double currentHeight = dataPointsMap.get(allScanNumbers[i]).getIntensity();
            area += (currentRT - previousRT) * (currentHeight + previousHeight) / 2;
        }

        // Update fragment scan
        fragmentScan = ScanUtils.findBestFragmentScan(dataFile, dataFile.getDataRTRange(1), rawDataPointsMZRange);

        if (fragmentScan > 0) {
            Scan fragmentScanObject = dataFile.getScan(fragmentScan);
            int precursorCharge = fragmentScanObject.getPrecursorCharge();
            if (precursorCharge > 0)
                this.charge = precursorCharge;
        }

        // Victor Trevio
        // using allScanNumbers : rawDataPointsRTRange = new
        // Range(dataFile.getScan(allScanNumbers[0]).getRetentionTime(),
        // dataFile.getScan(allScanNumbers[allScanNumbers.length-1]).getRetentionTime());
        rawDataPointsRTRange = Range.closed(minTime, maxTime); // using the
                                                               // "cached"
                                                               // values

        // Discard the fields we don't need anymore
        buildingSegment = null;
        lastMzPeak = null;

    }

    public double getBuildingSegmentLength() {
        if (buildingSegment.size() < 2)
            return 0;
        int firstScan = buildingSegment.firstElement();
        int lastScan = buildingSegment.lastElement();
        double firstRT = dataFile.getScan(firstScan).getRetentionTime();
        double lastRT = dataFile.getScan(lastScan).getRetentionTime();
        return (lastRT - firstRT);
    }

    public double getBuildingFirstTime() {
        return minTime;
    }

    public double getBuildingLastTime() {
        return maxTime;
    }

    public int getNumberOfCommittedSegments() {
        return numOfCommittedSegments;
    }

    public void removeBuildingSegment() {
        for (int scanNumber : buildingSegment)
            dataPointsMap.remove(scanNumber);
        buildingSegment.clear();
    }

    public void commitBuildingSegment() {
        buildingSegment.clear();
        numOfCommittedSegments++;
    }

    public void addDataPointsFromChromatogram(Chromatogram ch) {
        for (Entry<Integer, DataPoint> dp : ch.dataPointsMap.entrySet()) {
            addMzPeak(dp.getKey(), dp.getValue());
        }
    }

    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;
    }

}