com.act.lcms.v2.MassChargeCalculatorTest.java Source code

Java tutorial

Introduction

Here is the source code for com.act.lcms.v2.MassChargeCalculatorTest.java

Source

/*************************************************************************
*                                                                        *
*  This file is part of the 20n/act project.                             *
*  20n/act enables DNA prediction for synthetic biology/bioengineering.  *
*  Copyright (C) 2017 20n Labs, Inc.                                     *
*                                                                        *
*  Please direct all queries to act@20n.com.                             *
*                                                                        *
*  This program 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 3 of the License, or     *
*  (at your option) any later version.                                   *
*                                                                        *
*  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. *
*                                                                        *
*************************************************************************/

package com.act.lcms.v2;

import org.apache.commons.lang3.tuple.Pair;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

public class MassChargeCalculatorTest {
    private static final double MASS_ERROR_TOLERANCE = 0.0000001;

    // Use the fuzzy FP assertEquals over lists of values
    private static void assertEqualsWithFPErr(String msg, List<Double> expected, List<Double> actual) {
        if (expected.size() != actual.size()) {
            fail(msg + ": unequal list sizes");
        }

        for (int i = 0; i < expected.size(); i++) {
            assertEquals(msg, expected.get(i), actual.get(i), MASS_ERROR_TOLERANCE);
        }
    }

    private static void assertEqualsWithFPErr(String msg, Set<Double> expected, Set<Double> actual) {
        List<Double> expectedList = new ArrayList<>(expected);
        Collections.sort(expectedList);
        List<Double> actualList = new ArrayList<>(actual);
        Collections.sort(actualList);

        assertEqualsWithFPErr(msg, expectedList, actualList);
    }

    private static <T> void assertEqualsPairWithFPErr(String msg, List<Pair<T, Double>> expected,
            List<Pair<T, Double>> actual) {
        if (expected.size() != actual.size()) {
            fail(msg + ": unequal list sizes");
        }

        for (int i = 0; i < expected.size(); i++) {
            assertEquals(msg, expected.get(i).getLeft(), actual.get(i).getLeft());
            assertEquals(msg, expected.get(i).getRight(), actual.get(i).getRight(), MASS_ERROR_TOLERANCE);
        }
    }

    @Test
    public void testMakeMassChargeMap() throws Exception {
        List<MassChargeCalculator.MZSource> sources = Arrays.asList(
                new MassChargeCalculator.MZSource("InChI=1S/C7H7NO2/c8-6-3-1-5(2-4-6)7(9)10/h1-4H,8H2,(H,9,10)"), // PABA
                new MassChargeCalculator.MZSource("InChI=1S/C7H7NO2/c1-10-7(9)6-3-2-4-8-5-6/h2-5H,1H3")); // Something crazy.

        MassChargeCalculator.MassChargeMap massChargeMap = MassChargeCalculator.makeMassChargeMap(sources,
                new HashSet<>(Arrays.asList("M+H", "M+Na")));

        Double expectedMonoMass = 137.047679;
        List<Double> expectedIonMZs = Arrays.asList(138.054979, 160.036879); // M+H and M+Na of PABA

        // This is package private, but we'll use its ordering to speed testing.
        List<Double> actualIonMasses = massChargeMap.ionMZsSorted();
        assertEqualsWithFPErr("Unique ionic masses match expected list", expectedIonMZs, actualIonMasses);

        assertEqualsPairWithFPErr("M+H ion mz maps to source mass and ion name",
                Arrays.asList(Pair.of("M+H", expectedMonoMass)),
                massChargeMap.ionMZtoMonoMassAndIonName(actualIonMasses.get(0)));

        assertEqualsPairWithFPErr("M+Na ion mz maps to source mass and ion name",
                Arrays.asList(Pair.of("M+Na", expectedMonoMass)),
                massChargeMap.ionMZtoMonoMassAndIonName(actualIonMasses.get(1)));

        // Test reverse mapping.
        for (Double ionMZ : actualIonMasses) {
            assertEquals(String.format("Ionic masses for %f map to two MZSources", ionMZ), new HashSet<>(sources),
                    massChargeMap.ionMZToMZSources(ionMZ));
        }

        // Test iterators cover all values.
        assertEqualsWithFPErr("Iterable ionMZs match expected", new HashSet<>(expectedIonMZs),
                StreamSupport.stream(massChargeMap.ionMZIter().spliterator(), false).collect(Collectors.toSet()));

        assertEqualsWithFPErr("Iterable monoisotopic masses match expected",
                Collections.singleton(expectedMonoMass),
                StreamSupport.stream(massChargeMap.monoisotopicMassIter().spliterator(), false)
                        .collect(Collectors.toSet()));

        assertEquals("Iterable mzSources match expected", new HashSet<>(sources), StreamSupport
                .stream(massChargeMap.mzSourceIter().spliterator(), false).collect(Collectors.toSet()));
    }

    @Test
    public void testComputeMass() throws Exception {
        List<Pair<MassChargeCalculator.MZSource, Double>> testCases = Arrays.asList(
                Pair.of(new MassChargeCalculator.MZSource(
                        "InChI=1S/C8H9NO2/c1-6(10)9-7-2-4-8(11)5-3-7/h2-5,11H,1H3,(H,9,10)"), 151.063329),
                Pair.of(new MassChargeCalculator.MZSource(151.063329), 151.063329),
                Pair.of(new MassChargeCalculator.MZSource(Pair.of("APAP", 151.063329)), 151.063329));

        for (Pair<MassChargeCalculator.MZSource, Double> testCase : testCases) {
            Double actualMass = MassChargeCalculator.computeMass(testCase.getLeft());
            assertEquals(
                    String.format("(Case %d) Actual mass is within bounds: %.6f ~ %.6f", testCase.getLeft().getId(),
                            testCase.getRight(), actualMass),
                    testCase.getRight(), actualMass, MASS_ERROR_TOLERANCE);
        }
    }

}