io.github.msdk.featdet.chromatogrambuilder.HighestDataPointConnector.java Source code

Java tutorial

Introduction

Here is the source code for io.github.msdk.featdet.chromatogrambuilder.HighestDataPointConnector.java

Source

/* 
 * (C) Copyright 2015-2016 by MSDK Development Team
 *
 * This software is dual-licensed under either
 *
 * (a) the terms of the GNU Lesser General Public License version 2.1
 * as published by the Free Software Foundation
 *
 * or (per the licensee's choosing)
 *
 * (b) the terms of the Eclipse Public License v1.0 as published by
 * the Eclipse Foundation.
 */

package io.github.msdk.featdet.chromatogrambuilder;

import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Nonnull;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Preconditions;
import com.google.common.collect.Range;

import io.github.msdk.datamodel.chromatograms.Chromatogram;
import io.github.msdk.datamodel.chromatograms.ChromatogramType;
import io.github.msdk.datamodel.datastore.DataPointStore;
import io.github.msdk.datamodel.impl.MSDKObjectBuilder;
import io.github.msdk.datamodel.rawdata.ChromatographyInfo;
import io.github.msdk.datamodel.rawdata.MsScan;
import io.github.msdk.datamodel.rawdata.RawDataFile;
import io.github.msdk.datamodel.rawdata.SeparationType;
import io.github.msdk.util.DataPointSorter;
import io.github.msdk.util.DataPointSorter.SortingDirection;
import io.github.msdk.util.DataPointSorter.SortingProperty;
import io.github.msdk.util.MZTolerance;

class HighestDataPointConnector {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final @Nonnull Double noiseLevel;
    private final MZTolerance mzTolerance;
    private final double minimumTimeSpan, minimumHeight;

    private final Set<BuildingChromatogram> buildingChromatograms, connectedChromatograms;

    // Data structures
    private ChromatographyInfo rtBuffer[] = new ChromatographyInfo[10000];
    private double mzBuffer[] = new double[10000];
    private float intensityBuffer[] = new float[10000];
    private int numOfDataPoints;

    HighestDataPointConnector(@Nonnull Double noiseLevel, double minimumTimeSpan, double minimumHeight,
            MZTolerance mzTolerance) {

        this.noiseLevel = noiseLevel;
        this.mzTolerance = mzTolerance;
        this.minimumHeight = minimumHeight;
        this.minimumTimeSpan = minimumTimeSpan;

        // We use LinkedHashSet to maintain a reproducible ordering. If we use
        // plain HashSet, the resulting peak list row IDs will have different
        // order every time the method is invoked.
        buildingChromatograms = new LinkedHashSet<BuildingChromatogram>();
        connectedChromatograms = new LinkedHashSet<BuildingChromatogram>();

    }

    void addScan(RawDataFile dataFile, MsScan scan) {

        // Load data points
        mzBuffer = scan.getMzValues(mzBuffer);
        intensityBuffer = scan.getIntensityValues(intensityBuffer);
        numOfDataPoints = scan.getNumberOfDataPoints();

        // Sort m/z peaks by descending intensity
        DataPointSorter.sortDataPoints(mzBuffer, intensityBuffer, numOfDataPoints, SortingProperty.INTENSITY,
                SortingDirection.DESCENDING);

        // A set of already connected chromatograms in each iteration
        connectedChromatograms.clear();

        for (int i = 0; i < numOfDataPoints; i++) {

            if (intensityBuffer[i] < noiseLevel)
                continue;

            // Search for best chromatogram, which has the highest _last_ data
            // point
            BuildingChromatogram bestChromatogram = null;

            for (BuildingChromatogram testChrom : buildingChromatograms) {

                Range<Double> toleranceRange = mzTolerance.getToleranceRange(testChrom.getLastMz());

                if (toleranceRange.contains(mzBuffer[i])) {
                    if ((bestChromatogram == null)
                            || (testChrom.getLastIntensity() > bestChromatogram.getLastIntensity())) {
                        bestChromatogram = testChrom;
                    }
                }

            }

            // If we found best chromatogram, check if it is already connected.
            // In such case, we may discard this mass and continue. If we
            // haven't found a chromatogram, we can create a new one.
            if (bestChromatogram != null) {
                if (connectedChromatograms.contains(bestChromatogram)) {
                    continue;
                }
            } else {
                bestChromatogram = new BuildingChromatogram();
            }

            // Add this mzPeak to the chromatogram
            ChromatographyInfo rt = scan.getChromatographyInfo();
            Preconditions.checkNotNull(rt);
            bestChromatogram.addDataPoint(rt, mzBuffer[i], intensityBuffer[i]);

            // Move the chromatogram to the set of connected chromatograms
            connectedChromatograms.add(bestChromatogram);

        }

        // Process those chromatograms which were not connected to any m/z peak
        for (BuildingChromatogram testChrom : buildingChromatograms) {

            // Skip those which were connected
            if (connectedChromatograms.contains(testChrom)) {
                continue;
            }

            // Check if we just finished a long-enough segment
            if (testChrom.getBuildingSegmentLength() >= minimumTimeSpan) {
                testChrom.commitBuildingSegment();

                // Move the chromatogram to the set of connected chromatograms
                connectedChromatograms.add(testChrom);
                continue;
            }

            // Check if we have any committed segments in the chromatogram
            if (testChrom.getNumberOfCommittedSegments() > 0) {
                testChrom.removeBuildingSegment();

                // Move the chromatogram to the set of connected chromatograms
                connectedChromatograms.add(testChrom);
                continue;
            }

        }

        // All remaining chromatograms in buildingChromatograms are discarded
        // and buildingChromatograms is replaced with connectedChromatograms
        buildingChromatograms.clear();
        buildingChromatograms.addAll(connectedChromatograms);

    }

    void finishChromatograms(@Nonnull RawDataFile inputFile, @Nonnull DataPointStore dataPointStore,
            List<Chromatogram> finalList) {

        logger.debug("Finishing " + buildingChromatograms.size() + " chromatograms");

        // Iterate through current chromatograms and remove those which do not
        // contain any committed segment or long-enough building segment
        Iterator<BuildingChromatogram> chromIterator = buildingChromatograms.iterator();
        while (chromIterator.hasNext()) {

            BuildingChromatogram chromatogram = chromIterator.next();

            if (chromatogram.getBuildingSegmentLength() >= minimumTimeSpan) {
                chromatogram.commitBuildingSegment();
            } else {
                if (chromatogram.getNumberOfCommittedSegments() == 0) {
                    chromIterator.remove();
                    continue;
                } else {
                    chromatogram.removeBuildingSegment();
                }
            }

            // Remove chromatograms below minimum height
            if (chromatogram.getHeight() < minimumHeight) {
                chromIterator.remove();
            }

        }

        // All remaining chromatograms are good, so we can add them to the table
        int chromId = 1;
        for (BuildingChromatogram buildingChromatogram : buildingChromatograms) {

            // Make a new MSDK Chromatogram
            Chromatogram newChromatogram = MSDKObjectBuilder.getChromatogram(dataPointStore, chromId,
                    ChromatogramType.XIC, SeparationType.UNKNOWN);

            // Copy the data points from the BuildingChromatogram
            rtBuffer = buildingChromatogram.getRtValues(rtBuffer);
            mzBuffer = buildingChromatogram.getMzValues(mzBuffer);
            intensityBuffer = buildingChromatogram.getIntensityValues(intensityBuffer);
            int size = buildingChromatogram.size();
            newChromatogram.setDataPoints(rtBuffer, mzBuffer, intensityBuffer, size);

            // Update the final m/z value of the Chromatogram
            Double mz = buildingChromatogram.calculateMz();
            newChromatogram.setMz(mz);

            // Add the Chromatogram to the result list
            finalList.add(newChromatogram);

            // Increase the ID
            chromId++;

        }

    }

}