de.unijena.bioinf.ChemistryBase.ms.Deviation.java Source code

Java tutorial

Introduction

Here is the source code for de.unijena.bioinf.ChemistryBase.ms.Deviation.java

Source

/*
 *  This file is part of the SIRIUS library for analyzing MS and MS/MS data
 *
 *  Copyright (C) 2013-2015 Kai Dhrkop
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along with SIRIUS.  If not, see <http://www.gnu.org/licenses/>.
 */
package de.unijena.bioinf.ChemistryBase.ms;

import com.google.common.collect.Range;
import de.unijena.bioinf.ChemistryBase.algorithm.HasParameters;
import de.unijena.bioinf.ChemistryBase.algorithm.Parameter;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

@HasParameters
public class Deviation implements Cloneable {

    private final double ppm;
    private final double absolute;

    public static Deviation fromMeasurementAndReference(double measurementMz, double referenceMz) {
        final double absMz = measurementMz - referenceMz;
        final double ppm = absMz * 1e6 / measurementMz;
        return new Deviation(ppm, absMz);
    }

    public Deviation(double ppm) {
        this.ppm = ppm;
        this.absolute = 1e-4 * ppm; // set absolute to 100 Da with given ppm
    }

    public Deviation(@Parameter("ppm") double ppm, @Parameter("absolute") double absolute) {
        this.ppm = ppm;
        this.absolute = absolute;
    }

    public Deviation multiply(int scalar) {
        return new Deviation(ppm * scalar, absolute * scalar);
    }

    public Deviation multiply(double scalar) {
        return new Deviation(ppm * scalar, absolute * scalar);
    }

    public Deviation divide(double scalar) {
        return multiply(1d / scalar);
    }

    public Deviation roundUp() {
        return new Deviation(Math.ceil(ppm / 0.2) * 0.2, Math.ceil(absolute / 0.00002) * 0.00002);
    }

    public double absoluteFor(double value) {
        return Math.max(ppm * value * 1e-6, absolute);
    }

    public boolean inErrorWindow(double center, double value) {
        final double diff = Math.abs(center - value);
        return diff <= absoluteFor(center);
    }

    public Range<Double> getRange(double mz) {
        final double abs = absoluteFor(mz);
        return Range.closed(mz - abs, mz + abs);
    }

    public double getPpm() {
        return ppm;
    }

    public double getAbsolute() {
        return absolute;
    }

    public String toString() {
        return ppm + " ppm (" + absolute + " m/z)";
    }

    private static Pattern pattern = Pattern
            .compile("(?:(.+)\\s*ppm\\s*)?(?:(?:,|\\(|)\\s*(.+?)\\s*(m\\/z|mDa|Da|u)\\s*\\)?)?");

    public static Deviation fromString(String s) {
        final Matcher m = pattern.matcher(s);
        if (!m.find())
            throw new IllegalArgumentException("Pattern should have the format <number> ppm (<number> m/z)");
        final String ppm = m.group(1);
        final String abs = m.group(2);
        final String unit = m.group(3);
        double absolute = Double.NaN;
        if (abs != null && !abs.isEmpty()) {
            assert unit != null && !unit.isEmpty();
            absolute = Double.parseDouble(abs);
            if (unit.equalsIgnoreCase("mDa"))
                absolute /= 1000;
        }
        if (ppm != null && !ppm.isEmpty()) {
            double ppmValue = Double.parseDouble(ppm);
            return Double.isNaN(absolute) ? new Deviation(ppmValue) : new Deviation(ppmValue, absolute);
        } else if (!Double.isNaN(absolute)) {
            return fromMeasurementAndReference(100 + absolute, 100);
        } else
            throw new IllegalArgumentException("Pattern should have the format <number> ppm (<number> m/z)");
    }

    public Deviation clone() {
        return new Deviation(ppm, absolute);
    }

    public static Deviation valueOf(String s) {
        return fromString(s);
    }
}