com.act.lcms.v2.fullindex.BuilderTest.java Source code

Java tutorial

Introduction

Here is the source code for com.act.lcms.v2.fullindex.BuilderTest.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.fullindex;

import com.act.lcms.LCMSSpectrum;
import com.act.utils.MockRocksDBAndHandles;
import org.apache.commons.lang3.tuple.Pair;
import org.junit.Before;
import org.junit.Test;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

public class BuilderTest {
    public static final double FP_TOLERANCE = 0.000001;

    public static final double[] TIMES = { 1.0, 2.0, 3.0 };
    public static final double[][] MZS = { { 100.000, 100.005, 100.010 }, { 100.005, 100.010, 100.015 },
            { 100.010, 100.015, 100.020 }, };
    public static final double[][] INTENSITIES = { { 1.0, 2.0, 3.0 }, { 10.0, 20.0, 30.0 },
            { 100.0, 200.0, 300.0 }, };

    public static final List<MZWindow> MZ_WINDOWS = new ArrayList<MZWindow>() {
        {
            add(new MZWindow(0, 100.000));
            add(new MZWindow(1, 100.010));
            add(new MZWindow(2, 100.020));
        }
    };
    public Map<Integer, MZWindow> windowIdsToWindows = new HashMap<Integer, MZWindow>() {
        {
            for (MZWindow window : MZ_WINDOWS) {
                put(window.getIndex(), window);
            }
        }
    };

    public static MockRocksDBAndHandles<ColumnFamilies> populateTestDB() throws Exception {
        List<LCMSSpectrum> spectra = new ArrayList<>(TIMES.length);
        for (int i = 0; i < TIMES.length; i++) {
            List<Pair<Double, Double>> mzIntensities = new ArrayList<>();
            double totalIntensity = 0.0;
            for (int j = 0; j < MZS[i].length; j++) {
                mzIntensities.add(Pair.of(MZS[i][j], INTENSITIES[i][j]));
                totalIntensity += INTENSITIES[i][j];
            }
            spectra.add(new LCMSSpectrum(i, TIMES[i], "s", mzIntensities, null, null, null, i, totalIntensity));
        }

        MockRocksDBAndHandles<ColumnFamilies> testDB = new MockRocksDBAndHandles<>(ColumnFamilies.values());
        Builder builder = new Builder(testDB);
        builder.extractTriples(spectra.iterator(), MZ_WINDOWS);
        builder.writeWindowsToDB(MZ_WINDOWS);
        return testDB;
    }

    public MockRocksDBAndHandles<ColumnFamilies> fakeDB;

    @Before
    public void setup() throws Exception {
        fakeDB = populateTestDB();
    }

    @Test
    public void testExtractTriples() throws Exception {
        // Verify all TMzI triples are stored correctly.
        Map<Long, TMzI> deserializedTriples = new HashMap<>();
        assertEquals("All triples should have entries in the DB", 9,
                fakeDB.getFakeDB().get(ColumnFamilies.ID_TO_TRIPLE).size());
        for (Map.Entry<List<Byte>, byte[]> entry : fakeDB.getFakeDB().get(ColumnFamilies.ID_TO_TRIPLE).entrySet()) {
            Long id = ByteBuffer.wrap(fakeDB.byteListToArray(entry.getKey())).getLong();
            TMzI triple = TMzI.readNextFromByteBuffer(ByteBuffer.wrap(entry.getValue()));
            Float expectedTime = Double.valueOf(TIMES[id.intValue() / 3]).floatValue();
            Double expectedMZ = MZS[id.intValue() / 3][id.intValue() % 3];
            Float expectedIntensity = Double.valueOf(INTENSITIES[id.intValue() / 3][id.intValue() % 3])
                    .floatValue();

            assertEquals("Time matches expected", expectedTime, triple.getTime(), FP_TOLERANCE); // No error expected
            assertEquals("M/z matches expected", expectedMZ, triple.getMz(), FP_TOLERANCE);
            assertEquals("Intensity matches expected", expectedIntensity, triple.getIntensity(), FP_TOLERANCE);

            deserializedTriples.put(id, triple);
        }

        for (Map.Entry<List<Byte>, byte[]> entry : fakeDB.getFakeDB().get(ColumnFamilies.WINDOW_ID_TO_TRIPLES)
                .entrySet()) {
            int windowId = ByteBuffer.wrap(fakeDB.byteListToArray(entry.getKey())).getInt();
            MZWindow window = windowIdsToWindows.get(windowId);

            List<Long> tmziIds = new ArrayList<>(entry.getValue().length / Long.BYTES);
            ByteBuffer valBuffer = ByteBuffer.wrap(entry.getValue());
            while (valBuffer.hasRemaining()) {
                tmziIds.add(valBuffer.getLong());
            }

            for (Long tripleId : tmziIds) {
                TMzI triple = deserializedTriples.get(tripleId);
                assertTrue("Triple m/z falls within range of containing window",
                        triple.getMz() >= window.getMin() && triple.getMz() <= window.getMax());
            }
        }

        for (Map.Entry<List<Byte>, byte[]> entry : fakeDB.getFakeDB().get(ColumnFamilies.TIMEPOINT_TO_TRIPLES)
                .entrySet()) {
            float time = ByteBuffer.wrap(fakeDB.byteListToArray(entry.getKey())).getFloat();

            List<Long> tmziIds = new ArrayList<>(entry.getValue().length / Long.BYTES);
            ByteBuffer valBuffer = ByteBuffer.wrap(entry.getValue());
            while (valBuffer.hasRemaining()) {
                tmziIds.add(valBuffer.getLong());
            }

            for (Long tripleId : tmziIds) {
                TMzI triple = deserializedTriples.get(tripleId);
                assertEquals("Triple time matches key time", time, triple.getTime(), FP_TOLERANCE);
            }
        }
    }

    @Test
    public void testAppendOrRealloc() throws Exception {
        ByteBuffer dest = ByteBuffer.allocate(4);
        assertEquals("Initial buffer capacity matches expected", 4, dest.capacity());
        dest = Utils.appendOrRealloc(dest, ByteBuffer.wrap(new byte[] { 'a', 'b', 'c', 'd' })); // No need to flip w/ wrap().
        assertEquals("Post-append (fits) buffer capacity matches expected", 4, dest.capacity());
        assertEquals("Post-append (fits) buffer position matches expected", 4, dest.position());
        dest = Utils.appendOrRealloc(dest, ByteBuffer.wrap(new byte[] { 'e' }));
        assertEquals("Post-append (too large) buffer capacity has doubled", 8, dest.capacity());
        assertEquals("Post-append (too large) buffer position matches expected", 5, dest.position());
        dest = Utils.appendOrRealloc(dest, ByteBuffer.wrap(new byte[] { 'f', 'g', 'h' }));
        assertEquals("Post-append (fits) buffer capacity matches expected", 8, dest.capacity());
        assertEquals("Post-append (fits) buffer position matches expected", 8, dest.position());
        dest = Utils.appendOrRealloc(dest, ByteBuffer.wrap(new byte[] { 'i' }));
        assertEquals("Post-append (too large) buffer capacity has doubled", 16, dest.capacity());
        assertEquals("Post-append (too large) buffer position matches expected", 9, dest.position());

    }
}