/* File: DefaultVectorDataSet.java * Copyright (C) 2002-2003 The University of Iowa * * Created on October 27, 2003, 11:18 AM * by Edward West * * This file is part of the das2 library. * * das2 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.das2.dataset; import org.das2.datum.Units; import org.das2.datum.Datum; import java.util.*; /** * * @author Edward West */ public final class DefaultVectorDataSet extends AbstractVectorDataSet implements DataSet, VectorDataSet { private double[][] yValues; private String[] planeIDs; private Units[] yUnits; /** Creates a new instance of DefaultVectorDataSet * @param xTags array of double x tag values * @param xUnits units for the x tags * @param yValues array of double y values * @param yUnits untis for the y values * @param properties map of String property names to their values */ public DefaultVectorDataSet(double[] xTags, Units xUnits, double[] yValues, Units yUnits, Map properties) { this(xTags, xUnits, yValues, yUnits, null, null, properties); } /** Creates a new instance of DefaultVectorDataSet * The keys for the properties, yValuesMap, and unitsMap parameter must * consist solely of String values. If any of these key sets contain * non-string values an IllegalArgumentException will be thrown. * The key set of the yUnitsMap parameter must match exactly the key set * of the yValuesMap. If their key sets do not exactly match, an * IllegalArgumentException will be thrown. * @param xTags array of double x tag values * @param xUnits units for the x tags * @param yValues array of double y values * @param yUnits untis for the y values * @param yValuesMap map of String plane IDs to their y values * @param properties map of String property names to their values */ public DefaultVectorDataSet(double[] xTags, Units xUnits, double[] yValues, Units yUnits, Map yValuesMap, Map yUnitsMap, Map properties) { super(xTags, xUnits, yUnits, properties); if (yValuesMap == null ^ yUnitsMap == null) { throw new IllegalArgumentException("yValuesMap == null ^ yUnitsMap == null"); } if ( yValuesMap!=null ) { if (!yValuesMap.keySet().equals(yUnitsMap.keySet())) { throw new IllegalArgumentException("mismatched keySets for yValuesMap and yUnitsMap"); } for (Iterator it = yValuesMap.keySet().iterator(); it.hasNext();) { if (!(it.next() instanceof String)) { throw new IllegalArgumentException("Non-String key found in yValuesMap"); } } } int planeCount = 1 + (yValuesMap == null ? 0 : yValuesMap.size()); this.yValues = new double[planeCount][]; this.yValues[0] = (double[])yValues.clone(); this.planeIDs = new String[planeCount]; this.planeIDs[0] = ""; this.yUnits = new Units[planeCount]; this.yUnits[0] = yUnits; if (yValuesMap != null) { int index = 1; for (Iterator it = new TreeMap(yValuesMap).entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry)it.next(); String id = (String)entry.getKey(); double[] values = (double[])entry.getValue(); planeIDs[index] = id; this.yValues[index] = (double[])values.clone(); this.yUnits[index] = (Units)yUnitsMap.get(id); } } } /** Creates a DefaultVectorData set without copying or verifying the * data and units supplied. */ DefaultVectorDataSet(double[] xTags, Units xUnits, double[][] yValues, Units[] yUnits, String[] planeIDs, Map properties) { super(xTags, xUnits, yUnits[0], properties); this.yValues = yValues; this.yUnits = yUnits; this.planeIDs = planeIDs; } /** Returns the Y value for the given index into the x tags as a * Datum. * @param i index of the x tag for the requested value. * @return the value at index location i as a Datum */ public Datum getDatum(int i) { return Datum.create(yValues[0][i], getYUnits()); } /** Returns the Y value for the given index into the x tags as a * double with the given units. * @param i index of the x tag for the requested value. * @param units the units the returned value should be coverted to. * @return the value at index location i as a double. */ public double getDouble(int i, Units units) { if (yUnits[0].isFill(yValues[0][i])) { return units.getFillDouble(); } return getYUnits().getConverter(units).convert(yValues[0][i]); } /** Returns the Y value for the given index into the x tags as a * int with the given units. * @param i index of the x tag for the requested value. * @param units the units the returned value should be coverted to. * @return the value at index location i as a int. */ public int getInt(int i, Units units) { return (int)Math.round(getDouble(i, units)); } /** Returns a DataSet with the specified view as the primary * view. * @param planeID the String id of the requested plane. * @return the specified view, as a DataSet */ public DataSet getPlanarView(String planeID) { int index = -1; for (int i = 0; i < planeIDs.length; i++) { if (planeIDs[i].equals(planeID)) { index = i; break; } } if (index == -1) { return null; } else { return new PlanarViewDataSet(index); } } public String[] getPlaneIds() { String[] result= new String[planeIDs.length]; System.arraycopy( planeIDs, 0, result, 0, planeIDs.length ); return result; } private class PlanarViewDataSet extends AbstractDataSet.ViewDataSet implements VectorDataSet { private final int index; private PlanarViewDataSet(int index) { DefaultVectorDataSet.this.super(); this.index = index; } public Datum getDatum(int i) { return Datum.create(yValues[index][i], yUnits[index]); } public double getDouble(int i, Units units) { return yUnits[index].getConverter(units).convert(yValues[index][i]); } public int getInt(int i, Units units) { return (int)Math.round(getDouble(i, units)); } public Units getYUnits() { return yUnits[index]; } public DataSet getPlanarView(String planeID) { DataSet result= planeID.equals("") ? this : DefaultVectorDataSet.this.getPlanarView(planeID); if (result==null ) return DefaultVectorDataSet.this.getPlanarView( planeIDs[index] + "."+planeID ); return result; } public String[] getPlaneIds() { return new String[0] ; } public Object getProperty(String name) { Object result; if ( index==0 ) { result= DefaultVectorDataSet.this.getProperty(name); } else { result= DefaultVectorDataSet.this.getProperty(planeIDs[index] + "." + name); } return result; } @Override public Map getProperties() { Map superProps= super.getProperties(); String[] names= new String[] { PROPERTY_TITLE, PROPERTY_Y_LABEL, PROPERTY_Y_FORMAT, PROPERTY_Y_RANGE, PROPERTY_Y_SCALETYPE }; Map result= new HashMap<>(superProps); for ( String name: names ) { Object v; if ( index==0 ) { v= superProps.get( name ); } else { v= superProps.get( planeIDs[index] + "." + name ); } result.put( name, v ); } return result; } // TODO: this appears to have different logic than in ViewDataSet. This needs to be resolved. // public Map getProperties() { // throw new IllegalStateException("unimplemented"); // //return DefaultVectorDataSet.this.getProperty(planeIDs[index] + "." + name); // } public String toString() { return "DefaultVectorDataSet("+DefaultVectorDataSet.this.planeIDs[index]+") "+VectorUtil.toString(this); } } }