use of net.sf.mzmine.util.DataPointSorter in project mzmine2 by mzmine.
the class ADAPChromatogramBuilderTask method run.
/**
* @see Runnable#run()
*/
public void run() {
boolean writeChromCDF = true;
setStatus(TaskStatus.PROCESSING);
logger.info("Started chromatogram builder on " + dataFile);
scans = scanSelection.getMatchingScans(dataFile);
int[] allScanNumbers = scanSelection.getMatchingScanNumbers(dataFile);
List<Double> rtListForChromCDF = new ArrayList<Double>();
// Check if the scans are properly ordered by RT
double prevRT = Double.NEGATIVE_INFINITY;
for (Scan s : scans) {
if (isCanceled()) {
return;
}
if (writeChromCDF) {
rtListForChromCDF.add(s.getRetentionTime());
}
if (s.getRetentionTime() < prevRT) {
setStatus(TaskStatus.ERROR);
final String msg = "Retention time of scan #" + s.getScanNumber() + " is smaller then the retention time of the previous scan." + " Please make sure you only use scans with increasing retention times." + " You can restrict the scan numbers in the parameters, or you can use the Crop filter module";
setErrorMessage(msg);
return;
}
prevRT = s.getRetentionTime();
}
// Check if the scans are MS1-only or MS2-only.
int minMsLevel = Arrays.stream(scans).mapToInt(Scan::getMSLevel).min().orElseThrow(() -> new IllegalStateException("Cannot find the minimum MS level"));
int maxMsLevel = Arrays.stream(scans).mapToInt(Scan::getMSLevel).max().orElseThrow(() -> new IllegalStateException("Cannot find the maximum MS level"));
if (minMsLevel != maxMsLevel) {
MZmineCore.getDesktop().displayMessage(null, "MZmine thinks that you are running ADAP Chromatogram builder on both MS1- and MS2-scans. " + "This will likely produce wrong results. " + "Please, set the scan filter parameter to a specific MS level");
}
// Create new feature list
newPeakList = new SimplePeakList(dataFile + " " + suffix, dataFile);
// make a list of all the data points
// sort data points by intensity
// loop through list
// add data point to chromatogrm or make new one
// update mz avg and other stuff
//
// make a list of all the data points
List<ExpandedDataPoint> allMzValues = new ArrayList<ExpandedDataPoint>();
for (Scan scan : scans) {
if (isCanceled())
return;
MassList massList = scan.getMassList(massListName);
if (massList == null) {
setStatus(TaskStatus.ERROR);
setErrorMessage("Scan " + dataFile + " #" + scan.getScanNumber() + " does not have a mass list " + massListName);
return;
}
DataPoint[] mzValues = massList.getDataPoints();
if (mzValues == null) {
setStatus(TaskStatus.ERROR);
setErrorMessage("Mass list " + massListName + " does not contain m/z values for scan #" + scan.getScanNumber() + " of file " + dataFile);
return;
}
for (DataPoint mzPeak : mzValues) {
ExpandedDataPoint curDatP = new ExpandedDataPoint(mzPeak, scan.getScanNumber());
allMzValues.add(curDatP);
// corespondingScanNum.add(scan.getScanNumber());
}
}
// Integer[] simpleCorespondingScanNums = new Integer[corespondingScanNum.size()];
// corespondingScanNum.toArray(simpleCorespondingScanNums );
ExpandedDataPoint[] simpleAllMzVals = new ExpandedDataPoint[allMzValues.size()];
allMzValues.toArray(simpleAllMzVals);
// sort data points by intensity
Arrays.sort(simpleAllMzVals, new DataPointSorter(SortingProperty.Intensity, SortingDirection.Descending));
// Exit if no peaks
if (simpleAllMzVals.length == 0) {
progress = 1.0;
setStatus(TaskStatus.FINISHED);
logger.info("Finished chromatogram builder with no peaks on " + dataFile);
return;
}
double maxIntensity = simpleAllMzVals[0].getIntensity();
// count starts at 1 since we already have added one with a single point.
// Stopwatch stopwatch = Stopwatch.createUnstarted();
// stopwatch2 = Stopwatch.createUnstarted();
// Stopwatch stopwatch3 = Stopwatch.createUnstarted();
progress = 0.0;
double progressStep = (simpleAllMzVals.length > 0) ? 0.5 / simpleAllMzVals.length : 0.0;
for (ExpandedDataPoint mzPeak : simpleAllMzVals) {
progress += progressStep;
if (isCanceled()) {
return;
}
if (mzPeak == null || Double.isNaN(mzPeak.getMZ()) || Double.isNaN(mzPeak.getIntensity())) {
continue;
}
// ////////////////////////////////////////////////
Range<Double> containsPointRange = rangeSet.rangeContaining(mzPeak.getMZ());
Range<Double> toleranceRange = mzTolerance.getToleranceRange(mzPeak.getMZ());
if (containsPointRange == null) {
// skip it entierly if the intensity is not high enough
if (mzPeak.getIntensity() < minIntensityForStartChrom) {
continue;
}
// look +- mz tolerance to see if ther is a range near by.
// If there is use the proper boundry of that range for the
// new range to insure than NON OF THE RANGES OVERLAP.
Range<Double> plusRange = rangeSet.rangeContaining(toleranceRange.upperEndpoint());
Range<Double> minusRange = rangeSet.rangeContaining(toleranceRange.lowerEndpoint());
Double toBeLowerBound;
Double toBeUpperBound;
double cur_max_testing_mz = mzPeak.getMZ();
// chromatogram so that none of the points are overlapping.
if ((plusRange == null) && (minusRange == null)) {
toBeLowerBound = toleranceRange.lowerEndpoint();
toBeUpperBound = toleranceRange.upperEndpoint();
} else if ((plusRange == null) && (minusRange != null)) {
// the upper end point of the minus range will be the lower
// range of the new one
toBeLowerBound = minusRange.upperEndpoint();
toBeUpperBound = toleranceRange.upperEndpoint();
} else if ((minusRange == null) && (plusRange != null)) {
toBeLowerBound = toleranceRange.lowerEndpoint();
toBeUpperBound = plusRange.lowerEndpoint();
// double tmp_this = plusRange.upperEndpoint();
// System.out.println("tmp_this");
} else if ((minusRange != null) && (plusRange != null)) {
toBeLowerBound = minusRange.upperEndpoint();
toBeUpperBound = plusRange.lowerEndpoint();
} else {
toBeLowerBound = 0.0;
toBeUpperBound = 0.0;
}
if (toBeLowerBound < toBeUpperBound) {
Range<Double> newRange = Range.open(toBeLowerBound, toBeUpperBound);
ADAPChromatogram newChrom = new ADAPChromatogram(dataFile, allScanNumbers);
newChrom.addMzPeak(mzPeak.getScanNumber(), mzPeak);
newChrom.setHighPointMZ(mzPeak.getMZ());
rangeToChromMap.put(newRange, newChrom);
// also need to put it in the set -> this is where the range can be efficiently found.
rangeSet.add(newRange);
} else if (toBeLowerBound.equals(toBeUpperBound) && plusRange != null) {
ADAPChromatogram curChrom = rangeToChromMap.get(plusRange);
curChrom.addMzPeak(mzPeak.getScanNumber(), mzPeak);
} else
throw new IllegalStateException(String.format("Incorrect range [%f, %f] for m/z %f", toBeLowerBound, toBeUpperBound, mzPeak.getMZ()));
} else {
// In this case we do not need to update the rangeSet
ADAPChromatogram curChrom = rangeToChromMap.get(containsPointRange);
curChrom.addMzPeak(mzPeak.getScanNumber(), mzPeak);
// update the entry in the map
rangeToChromMap.put(containsPointRange, curChrom);
}
}
// System.out.println("search chroms (ms): " + stopwatch.elapsed(TimeUnit.MILLISECONDS));
// System.out.println("making new chrom (ms): " + stopwatch2.elapsed(TimeUnit.MILLISECONDS));
// finish chromatograms
Set<Range<Double>> ranges = rangeSet.asRanges();
Iterator<Range<Double>> RangeIterator = ranges.iterator();
List<ADAPChromatogram> buildingChromatograms = new ArrayList<ADAPChromatogram>();
progressStep = (ranges.size() > 0) ? 0.5 / ranges.size() : 0.0;
while (RangeIterator.hasNext()) {
if (isCanceled()) {
return;
}
progress += progressStep;
Range<Double> curRangeKey = RangeIterator.next();
ADAPChromatogram chromatogram = rangeToChromMap.get(curRangeKey);
chromatogram.finishChromatogram();
// And remove chromatograms who dont have a certian number of continous points above the
// IntensityThresh2 level.
double numberOfContinuousPointsAboveNoise = chromatogram.findNumberOfContinuousPointsAboveNoise(IntensityThresh2);
if (numberOfContinuousPointsAboveNoise < minimumScanSpan) {
// requirements");
continue;
} else {
buildingChromatograms.add(chromatogram);
}
}
ADAPChromatogram[] chromatograms = buildingChromatograms.toArray(new ADAPChromatogram[0]);
// Sort the final chromatograms by m/z
Arrays.sort(chromatograms, new PeakSorter(SortingProperty.MZ, SortingDirection.Ascending));
// Add the chromatograms to the new feature list
for (Feature finishedPeak : chromatograms) {
SimplePeakListRow newRow = new SimplePeakListRow(newPeakID);
newPeakID++;
newRow.addPeak(dataFile, finishedPeak);
newPeakList.addRow(newRow);
// finishedPeak.outputChromToFile();
}
// Add new peaklist to the project
project.addPeakList(newPeakList);
// Add quality parameters to peaks
QualityParameters.calculateQualityParameters(newPeakList);
progress = 1.0;
setStatus(TaskStatus.FINISHED);
logger.info("Finished chromatogram builder on " + dataFile);
}
use of net.sf.mzmine.util.DataPointSorter in project mzmine2 by mzmine.
the class IsotopePatternScoreCalculator method getSimilarityScore.
/**
* Returns a calculated similarity score of two isotope patterns in the range of 0 (not similar at
* all) to 1 (100% same).
*/
public static double getSimilarityScore(IsotopePattern ip1, IsotopePattern ip2, ParameterSet parameters) {
assert ip1 != null;
assert ip2 != null;
MZTolerance mzTolerance = parameters.getParameter(IsotopePatternScoreParameters.mzTolerance).getValue();
assert mzTolerance != null;
final double patternIntensity = Math.max(ip1.getHighestDataPoint().getIntensity(), ip2.getHighestDataPoint().getIntensity());
final double noiseIntensity = parameters.getParameter(IsotopePatternScoreParameters.isotopeNoiseLevel).getValue();
// Normalize the isotopes to intensity 0..1
IsotopePattern nip1 = IsotopePatternCalculator.normalizeIsotopePattern(ip1);
IsotopePattern nip2 = IsotopePatternCalculator.normalizeIsotopePattern(ip2);
// Merge the data points from both isotope patterns into a single array.
// Data points from first pattern will have positive intensities, data
// points from second pattern will have negative intensities.
ArrayList<DataPoint> mergedDataPoints = new ArrayList<DataPoint>();
for (DataPoint dp : nip1.getDataPoints()) {
if (dp.getIntensity() * patternIntensity < noiseIntensity)
continue;
mergedDataPoints.add(dp);
}
for (DataPoint dp : nip2.getDataPoints()) {
if (dp.getIntensity() * patternIntensity < noiseIntensity)
continue;
DataPoint negativeDP = new SimpleDataPoint(dp.getMZ(), dp.getIntensity() * -1);
mergedDataPoints.add(negativeDP);
}
DataPoint[] mergedDPArray = mergedDataPoints.toArray(new DataPoint[0]);
// Sort the merged data points by m/z
Arrays.sort(mergedDPArray, new DataPointSorter(SortingProperty.MZ, SortingDirection.Ascending));
// tolerance
for (int i = 0; i < mergedDPArray.length - 1; i++) {
Range<Double> toleranceRange = mzTolerance.getToleranceRange(mergedDPArray[i].getMZ());
if (!toleranceRange.contains(mergedDPArray[i + 1].getMZ()))
continue;
double summedIntensity = mergedDPArray[i].getIntensity() + mergedDPArray[i + 1].getIntensity();
double newMZ = mergedDPArray[i + 1].getMZ();
// Update the next data point and remove the current one
mergedDPArray[i + 1] = new SimpleDataPoint(newMZ, summedIntensity);
mergedDPArray[i] = null;
}
// Calculate the resulting score. Ideal score is 1, in case the final
// data point array is empty.
double result = 1;
for (DataPoint dp : mergedDPArray) {
if (dp == null)
continue;
double remainingIntensity = Math.abs(dp.getIntensity());
// intensity may be over 1
if (remainingIntensity > 1)
remainingIntensity = 1;
// Decrease the score with each remaining peak
result *= 1 - remainingIntensity;
}
return result;
}
use of net.sf.mzmine.util.DataPointSorter in project mzmine2 by mzmine.
the class MassListDeisotoper method filterIsotopes.
public static DataPoint[] filterIsotopes(DataPoint[] dataPoints, ParameterSet parameterSet) {
if (dataPoints == null || dataPoints.length == 0) {
return dataPoints;
}
MZTolerance mzTolerance = parameterSet.getParameter(MassListDeisotoperParameters.mzTolerance).getValue();
boolean monotonicShape = parameterSet.getParameter(MassListDeisotoperParameters.monotonicShape).getValue();
int maximumCharge = parameterSet.getParameter(MassListDeisotoperParameters.maximumCharge).getValue();
int[] charges = new int[maximumCharge];
for (int i = 0; i < maximumCharge; i++) charges[i] = i + 1;
// sort by intensity
dataPoints = dataPoints.clone();
Arrays.sort(dataPoints, new DataPointSorter(SortingProperty.Intensity, SortingDirection.Descending));
List<DataPoint> deisotopedDataPoints = new ArrayList<>();
for (int i = 0; i < dataPoints.length; i++) {
DataPoint aPeak = dataPoints[i];
if (aPeak == null) {
continue;
}
// Check which charge state fits best around this peak
int bestFitCharge = 0;
int bestFitScore = -1;
List<DataPoint> bestFitPeaks = null;
for (int charge : charges) {
List<DataPoint> fittedPeaks = new ArrayList<>();
fittedPeaks.add(aPeak);
fitPattern(fittedPeaks, aPeak, charge, dataPoints, DELTA, monotonicShape, mzTolerance);
int score = fittedPeaks.size();
if ((score > bestFitScore) || ((score == bestFitScore) && (bestFitCharge > charge))) {
bestFitScore = score;
bestFitCharge = charge;
bestFitPeaks = fittedPeaks;
}
}
assert bestFitPeaks != null;
// add to deisotoped
deisotopedDataPoints.add(dataPoints[i]);
// remove all
for (int j = 0; j < dataPoints.length; j++) {
if (bestFitPeaks.contains(dataPoints[j]))
dataPoints[j] = null;
}
}
return deisotopedDataPoints.toArray(new DataPoint[deisotopedDataPoints.size()]);
}
use of net.sf.mzmine.util.DataPointSorter in project mzmine2 by mzmine.
the class WaveletMassDetector method getMzPeaks.
/**
* This function searches for maximums from wavelet data points
*/
private DataPoint[] getMzPeaks(double noiseLevel, DataPoint[] originalDataPoints, DataPoint[] waveletDataPoints) {
TreeSet<DataPoint> mzPeaks = new TreeSet<DataPoint>(new DataPointSorter(SortingProperty.MZ, SortingDirection.Ascending));
Vector<DataPoint> rawDataPoints = new Vector<DataPoint>();
int peakMaxInd = 0;
int stopInd = waveletDataPoints.length - 1;
for (int ind = 0; ind <= stopInd; ind++) {
while ((ind <= stopInd) && (waveletDataPoints[ind].getIntensity() == 0)) {
ind++;
}
peakMaxInd = ind;
if (ind >= stopInd) {
break;
}
// While peak is on
while ((ind <= stopInd) && (waveletDataPoints[ind].getIntensity() > 0)) {
// Check if this is the maximum point of the peak
if (waveletDataPoints[ind].getIntensity() > waveletDataPoints[peakMaxInd].getIntensity()) {
peakMaxInd = ind;
}
rawDataPoints.add(originalDataPoints[ind]);
ind++;
}
if (ind >= stopInd) {
break;
}
rawDataPoints.add(originalDataPoints[ind]);
if (originalDataPoints[peakMaxInd].getIntensity() > noiseLevel) {
SimpleDataPoint peakDataPoint = new SimpleDataPoint(originalDataPoints[peakMaxInd].getMZ(), calcAproxIntensity(rawDataPoints));
mzPeaks.add(peakDataPoint);
}
rawDataPoints.clear();
}
return mzPeaks.toArray(new DataPoint[0]);
}
use of net.sf.mzmine.util.DataPointSorter in project mzmine2 by mzmine.
the class ExactMassDetector method getMassValues.
/**
* @see net.sf.mzmine.modules.peakpicking.threestep.massdetection.MassDetector#getMassValues(net.sf.mzmine.datamodel.Scan)
*/
public DataPoint[] getMassValues(DataPoint[] dataPoints, ParameterSet parameters) {
double noiseLevel = parameters.getParameter(ExactMassDetectorParameters.noiseLevel).getValue();
// Create a tree set of detected mzPeaks sorted by MZ in ascending order
TreeSet<ExactMzDataPoint> mzPeaks = new TreeSet<ExactMzDataPoint>(new DataPointSorter(SortingProperty.MZ, SortingDirection.Ascending));
// Create a tree set of candidate mzPeaks sorted by intensity in
// descending order.
TreeSet<ExactMzDataPoint> candidatePeaks = new TreeSet<ExactMzDataPoint>(new DataPointSorter(SortingProperty.Intensity, SortingDirection.Descending));
// First get all candidate peaks (local maximum)
getLocalMaxima(dataPoints, candidatePeaks, noiseLevel);
// starting with biggest intensity peak and so on
while (candidatePeaks.size() > 0) {
// Always take the biggest (intensity) peak
ExactMzDataPoint currentCandidate = candidatePeaks.first();
// Calculate the exact mass and update value in current candidate
// (MzPeak)
double exactMz = calculateExactMass(currentCandidate);
currentCandidate.setMZ(exactMz);
// Add this candidate to the final tree set sorted by MZ and remove
// from tree set sorted by intensity
mzPeaks.add(currentCandidate);
candidatePeaks.remove(currentCandidate);
}
// Return an array of detected MzPeaks sorted by MZ
return mzPeaks.toArray(new ExactMzDataPoint[0]);
}
Aggregations