/* * MapperDocument.java * * Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard * * This file is part of BEAST. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership and licensing. * * BEAST 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 * of the License, or (at your option) any later version. * * BEAST 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 Lesser General Public * License along with BEAST; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ package dr.app.mapper.application; import dr.evolution.util.*; import dr.evolution.util.Date; import dr.inference.trace.TraceList; import dr.util.DataTable; import java.util.*; /** * A class to store the current mapper document (i.e. all the data) * * @author Andrew Rambaut */ public final class MapperDocument { public enum MeasurementType { INTERVAL, POINT, THRESHOLD, MISSING } public MapperDocument() { } public void addTaxa(Collection<Taxon> newTaxa) { for (Taxon taxon : newTaxa) { addTaxon(taxon); } fireTaxaChanged(); } private void addTaxon(Taxon taxon) { taxa.add(taxon); taxonMap.put(taxon.getId(), taxon); } public Taxon getTaxon(String id) { return taxonMap.get(id); } public List<Taxon> getTaxa() { return taxa; } public void addTable(DataTable<String[]> dataTable) { // column indices in table final int COLUMN_LABEL = 0; final int SERUM_STRAIN = 2; final int ROW_LABEL = 1; final int VIRUS_STRAIN = 3; final int SERUM_DATE = 4; final int VIRUS_DATE = 5; final int TITRE = 6; List<String> strainNames = new ArrayList<String>(); List<String> virusNames = new ArrayList<String>(); List<String> serumNames = new ArrayList<String>(); Map<String, Double> strainDateMap = new HashMap<String, Double>(); int thresholdCount = 0; double earliestDate = Double.POSITIVE_INFINITY; for (int i = 0; i < dataTable.getRowCount(); i++) { String[] values = dataTable.getRow(i); String columnLabel = values[COLUMN_LABEL]; String columnStrainName = values[COLUMN_LABEL]; Taxon columnStrain = getTaxon(columnStrainName); if (columnStrain == null) { columnStrain = new Taxon(columnStrainName); // double date = Double.parseDouble(values[SERUM_DATE]); // columnStrain.setDate(new Date(date, false, new Date(0.0, Units.Type.YEARS, false))); // addTaxon(columnStrain); } String rowLabel = values[ROW_LABEL]; String rowStrainName = values[VIRUS_STRAIN]; Taxon rowStrain = getTaxon(rowStrainName); if (rowStrain == null) { rowStrain = new Taxon(rowStrainName); // double date = Double.parseDouble(values[VIRUS_DATE]); // rowStrain.setDate(new Date(date, false, new Date(0.0, Units.Type.YEARS, false))); addTaxon(rowStrain); } boolean isThreshold = false; double rawTitre = Double.NaN; if (values[TITRE].length() > 0) { try { rawTitre = Double.parseDouble(values[TITRE]); } catch (NumberFormatException nfe) { // check if threshold below if (values[TITRE].contains("<")) { rawTitre = Double.parseDouble(values[TITRE].replace("<","")); isThreshold = true; thresholdCount++; } // check if threshold above if (values[TITRE].contains(">")) { throw new IllegalArgumentException("Error in measurement: unsupported greater than threshold at row " + (i+1)); } } } MeasurementType type = (isThreshold ? MeasurementType.THRESHOLD : MeasurementType.POINT); Measurement measurement = new Measurement(columnLabel, columnStrain, rowLabel, rowStrain, type, rawTitre); measurements.add(measurement); } fireTaxaChanged(); } public List<Measurement> getMeasurements() { return measurements; } private final List<Taxon> taxa = new ArrayList<Taxon>(); private final Map<String, Taxon> taxonMap = new HashMap<String, Taxon>(); private final List<TraceList> traceLists = new ArrayList<TraceList>(); private final List<Measurement> measurements = new ArrayList<Measurement>(); private final List<String> columnLabels = new ArrayList<String>(); private final List<String> rowLabels = new ArrayList<String>(); public class Measurement { private Measurement(final String column, final Taxon columnStrain, final String row, final Taxon rowStrain, final MeasurementType type, final double titre) { this.column = column; this.columnStrain = columnStrain; this.row = row; this.rowStrain = rowStrain; this.type = type; this.titre = titre; this.log2Titre = Math.log(titre) / Math.log(2); } final String column; final String row; final Taxon columnStrain; final Taxon rowStrain; final MeasurementType type; final double titre; final double log2Titre; }; // Listeners and broadcasting public void addListener(Listener listener) { listeners.add(listener); } public void removeListener(Listener listener) { listeners.remove(listener); } public void fireTaxaChanged() { for (Listener listener : listeners) { listener.taxaChanged(); } } private final List<Listener> listeners = new ArrayList<Listener>(); public interface Listener { void taxaChanged(); } }