com.act.lcms.db.io.writer.PlateCompositionWriter.java Source code

Java tutorial

Introduction

Here is the source code for com.act.lcms.db.io.writer.PlateCompositionWriter.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.db.io.writer;

import com.act.lcms.db.io.DB;
import com.act.lcms.db.model.DeliveredStrainWell;
import com.act.lcms.db.model.InductionWell;
import com.act.lcms.db.model.LCMSWell;
import com.act.lcms.db.model.Plate;
import com.act.lcms.db.model.PregrowthWell;
import com.act.lcms.db.model.StandardWell;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;

public class PlateCompositionWriter {
    public static final String PLATE_TYPE_96_WELLS = "plate_96_well";
    public static final String PLATE_TYPE_96_WELLS_BLOCK = "block_96_well";
    public static final String PLATE_TYPE_24_WELLS = "plate_24_well";
    public static final String PLATE_TYPE_24_WELLS_BLOCK = "block_24_well";

    public static final Integer PLATE_DIM_96_WELL_X = 12;
    public static final Integer PLATE_DIM_96_WELL_Y = 8;
    public static final Integer PLATE_DIM_24_WELL_X = 6;
    public static final Integer PLATE_DIM_24_WELL_Y = 4;

    public static final List<String> PLATE_LABELS_SAMPLE_WELLS = Arrays.asList("msid", "composition", "chemical",
            "note");
    public static final List<String> PLATE_LABELS_STANDARD_WELLS = Arrays.asList("chemical", "media");
    public static final List<String> PLATE_LABELS_INDUCTION_WELLS = Arrays.asList("msid", "chemical_source",
            "composition", "chemical", "strain_source", "note", "growth");
    public static final List<String> PLATE_LABELS_PREGROWTH_WELLS = Arrays.asList("source_plate", "msid",
            "composition", "source_well", "note", "growth");

    public void writeLCMSWellComposition(PrintWriter w, Plate plate, List<LCMSWell> wells) throws IOException {
        switch (plate.getPlateType()) {
        case PLATE_TYPE_96_WELLS:
        case PLATE_TYPE_96_WELLS_BLOCK:
            String[][][] tables = new String[4][PLATE_DIM_96_WELL_Y][PLATE_DIM_96_WELL_X];
            for (LCMSWell well : wells) {
                int y = well.getPlateRow();
                int x = well.getPlateColumn();
                // TODO: should we use a map for this instead to make the table name -> data correspondence clearer?
                tables[0][y][x] = well.getMsid();
                tables[1][y][x] = well.getComposition();
                tables[2][y][x] = well.getChemical();
                tables[3][y][x] = well.getNote();
            }

            for (int i = 0; i < PLATE_LABELS_SAMPLE_WELLS.size(); i++) {
                write96CellTable(w, PLATE_LABELS_SAMPLE_WELLS.get(i), tables[i]);
            }
            break;
        default:
            // TODO: use a better exception type here.
            throw new RuntimeException(String.format("Found unexpected plate type: %s", plate.getPlateType()));
        }
    }

    public void writeStandardWellComposition(PrintWriter w, Plate plate, List<StandardWell> wells)
            throws IOException {
        switch (plate.getPlateType()) {
        case PLATE_TYPE_96_WELLS:
        case PLATE_TYPE_96_WELLS_BLOCK:
            String[][][] tables = new String[2][PLATE_DIM_96_WELL_Y][PLATE_DIM_96_WELL_X];
            for (StandardWell well : wells) {
                int y = well.getPlateRow();
                int x = well.getPlateColumn();
                // TODO: should we use a map for this instead to make the table name -> data correspondence clearer?
                tables[0][y][x] = well.getChemical();
                tables[1][y][x] = well.getMedia();
                // TODO: add notes when we expect them.
            }

            for (int i = 0; i < PLATE_LABELS_STANDARD_WELLS.size(); i++) {
                write96CellTable(w, PLATE_LABELS_STANDARD_WELLS.get(i), tables[i]);
            }
            break;
        default:
            // TODO: use a better exception type here.
            throw new RuntimeException(String.format("Found unexpected plate type: %s", plate.getPlateType()));
        }
    }

    public void writeDeliveredStrainWellComposition(PrintWriter w, Plate plate, List<DeliveredStrainWell> wells)
            throws IOException {
        switch (plate.getPlateType()) {
        case PLATE_TYPE_96_WELLS:
        case PLATE_TYPE_96_WELLS_BLOCK:
            // Strain files don't use normal plate tables.
            w.println(">>wells\tmsid\tcomposition");
            for (DeliveredStrainWell well : wells) {
                w.println(StringUtils.join(new String[] { well.getWell(), well.getMsid(), well.getComposition() },
                        "\t"));
            }
            w.println();
            break;
        default:
            // TODO: use a better exception type here.
            throw new RuntimeException(String.format("Found unexpected plate type: %s", plate.getPlateType()));
        }
    }

    public void writeInductionWellComposition(PrintWriter w, Plate plate, List<InductionWell> wells)
            throws IOException {
        switch (plate.getPlateType()) {
        case PLATE_TYPE_24_WELLS:
        case PLATE_TYPE_24_WELLS_BLOCK:
            String[][][] tables = new String[7][PLATE_DIM_24_WELL_Y][PLATE_DIM_24_WELL_X];
            for (InductionWell well : wells) {
                int y = well.getPlateRow();
                int x = well.getPlateColumn();
                tables[0][y][x] = well.getMsid();
                tables[1][y][x] = well.getChemicalSource();
                tables[2][y][x] = well.getComposition();
                tables[3][y][x] = well.getChemical();
                tables[4][y][x] = well.getStrainSource();
                tables[5][y][x] = well.getNote();
                tables[6][y][x] = well.getGrowth() == null ? "" : well.getGrowth().toString();
            }

            for (int i = 0; i < PLATE_LABELS_INDUCTION_WELLS.size(); i++) {
                write24CellTable(w, PLATE_LABELS_INDUCTION_WELLS.get(i), tables[i]);
            }
            break;
        default:
            // TODO: use a better exception type here.
            throw new RuntimeException(String.format("Found unexpected plate type: %s", plate.getPlateType()));
        }
    }

    public void writePregrowthWellComposition(PrintWriter w, Plate plate, List<PregrowthWell> wells)
            throws IOException {
        switch (plate.getPlateType()) {
        case PLATE_TYPE_24_WELLS:
        case PLATE_TYPE_24_WELLS_BLOCK:
            String[][][] tables = new String[6][PLATE_DIM_24_WELL_Y][PLATE_DIM_24_WELL_X];
            for (PregrowthWell well : wells) {
                int y = well.getPlateRow();
                int x = well.getPlateColumn();
                tables[0][y][x] = well.getSourcePlate();
                tables[1][y][x] = well.getMsid();
                tables[2][y][x] = well.getComposition();
                tables[3][y][x] = well.getSourceWell();
                tables[4][y][x] = well.getNote();
                tables[5][y][x] = well.getGrowth() == null ? "" : well.getGrowth().toString();
            }

            for (int i = 0; i < PLATE_LABELS_PREGROWTH_WELLS.size(); i++) {
                write24CellTable(w, PLATE_LABELS_PREGROWTH_WELLS.get(i), tables[i]);
            }
            break;
        default:
            // TODO: use a better exception type here.
            throw new RuntimeException(String.format("Found unexpected plate type: %s", plate.getPlateType()));
        }
    }

    protected void writePlateAttributes(PrintWriter w, Plate plate) throws IOException {
        w.format(">%s\t%s\n", "name", plate.getName());
        w.format(">%s\t%s\n", "description", plate.getDescription());
        w.format(">%s\t%s\n", "barcode", plate.getBarcode());
        w.println(">schema\tplate\n");
        w.format(">%s\t%s\n", "location", plate.getLocation());
        w.format(">%s\t%s\n", "plate_type", plate.getPlateType());
        if (plate.getSolvent() != null) {
            w.format(">%s\t%s\n", "solvent", plate.getSolvent());
        }
        w.format(">%s\t%d\n", "temperature", plate.getTemperature());
        w.println();
    }

    protected void write96CellTable(PrintWriter w, String tableName, String[][] values) {
        writeCellTable(w, tableName, values, PLATE_DIM_96_WELL_X, PLATE_DIM_96_WELL_Y);
    }

    protected void write24CellTable(PrintWriter w, String tableName, String[][] values) {
        writeCellTable(w, tableName, values, PLATE_DIM_24_WELL_X, PLATE_DIM_24_WELL_Y);
    }

    protected void writeCellTable(PrintWriter w, String tableName, String[][] values, int expectedXDim,
            int expectedYDim) {
        StringBuilder headerBuilder = new StringBuilder(String.format(">>%s", tableName));
        for (int i = 0; i < expectedXDim; i++) {
            // Columns are one-indexed in composition tables.
            headerBuilder.append(String.format("\t%d", i + 1));
        }
        w.println(headerBuilder.toString());

        if (values.length != expectedYDim) {
            throw new RuntimeException(String.format(
                    "ERROR: found incorrect row dimension for 96 well plate.  Expected %d, but got %d.\n",
                    expectedYDim, values.length));
        }

        char rowName = 'A';
        for (int i = 0; i < values.length; i++) {
            if (values[i].length != expectedXDim) {
                throw new RuntimeException(String.format(
                        "ERROR: found incorrect column dimension for 96 well plate.  Expected %d, but got %d.\n",
                        expectedXDim, values.length));
            }
            w.format("%c\t%s\n", rowName, StringUtils.join(values[i], '\t'));
            rowName++;
        }
        w.println();
    }

    public void writePlateCompositionByBarcode(DB db, String plateBarcode, Writer dest) throws Exception {
        Plate p = Plate.getPlateByBarcode(db, plateBarcode);
        writePlateComposition(db, p, dest);
    }

    public void writePlateCompositionByName(DB db, String name, Writer dest) throws Exception {
        Plate p = Plate.getPlateByName(db, name);
        writePlateComposition(db, p, dest);
    }

    public void writePlateComposition(DB db, Plate p, Writer dest) throws Exception {
        PlateCompositionWriter writer = new PlateCompositionWriter();
        PrintWriter w = new PrintWriter(dest, true);
        writePlateAttributes(w, p);

        switch (p.getContentType()) {
        case LCMS:
            List<LCMSWell> LCMSWells = LCMSWell.getInstance().getByPlateId(db, p.getId());
            writer.writeLCMSWellComposition(w, p, LCMSWells);
            break;
        case STANDARD:
            List<StandardWell> stdWells = StandardWell.getInstance().getByPlateId(db, p.getId());
            writer.writeStandardWellComposition(w, p, stdWells);
            break;
        case DELIVERED_STRAIN:
            List<DeliveredStrainWell> strainWells = DeliveredStrainWell.getInstance().getByPlateId(db, p.getId());
            writer.writeDeliveredStrainWellComposition(w, p, strainWells);
            break;
        case INDUCTION:
            List<InductionWell> inductionWells = InductionWell.getInstance().getByPlateId(db, p.getId());
            writer.writeInductionWellComposition(w, p, inductionWells);
            break;
        case PREGROWTH:
            List<PregrowthWell> pregrowthWells = PregrowthWell.getInstance().getByPlateId(db, p.getId());
            writer.writePregrowthWellComposition(w, p, pregrowthWells);
            break;
        default:
            throw new RuntimeException(String.format("Unrecognized table type: %s", p.getContentType()));
        }
    }
}