/* * Copyright 1998, University Corporation for Atmospheric Research * All Rights Reserved. * See file LICENSE for copying and redistribution conditions. * * $Id: DependentRealVar.java,v 1.4 2000-04-26 15:45:24 dglo Exp $ */ package visad.data.netcdf.out; import java.io.IOException; import ucar.netcdf.Attribute; import visad.DoubleSet; import visad.FloatSet; import visad.Real; import visad.RealType; import visad.ScalarType; import visad.Set; import visad.Unit; import visad.VisADException; import visad.data.BadFormException; /** * The DependentRealVar class adapts numeric data in a VisAD data object to * a netCDF, dependent-variable, API for the purpose of exporting the data. */ class DependentRealVar extends DependentVar { /** * The fill-value object. */ private final Number fillValue; /** * Construct. * * @param real The VisAD Real object to be adapted. * @param accessor The means for accessing the individual VisAD * <code>Real</code> objects of the enclosing * VisAD data object. * @exception BadFormException The VisAD data object cannot be * adapted to a netCDF API * @exception VisADException Problem in core VisAD. * Probably some VisAD object couldn't be created. */ protected DependentRealVar(Real real, VisADAccessor accessor) throws VisADException, BadFormException { super(((ScalarType)real.getType()).getName(), getJavaClass(((RealType)real.getType()).getDefaultSet()), accessor.getDimensions(), myAttributes(real), accessor); fillValue = getFillValue(getJavaClass( ((RealType)real.getType()).getDefaultSet())); } /** * Get the netCDF attributes for a DependentRealVar. * * @param real The VisAD data object for which netCDF Attribute * must be created. * @return An array of netCDF Attributes for <code>real</code>. * @exception BadFormException The VisAD data object cannot be * adapted to a netCDF API * @exception VisADException Problem in core VisAD. * Probably some VisAD object couldn't be created. */ protected static Attribute[] myAttributes(Real real) throws VisADException, BadFormException { RealType realType = (RealType)real.getType(); Number fillNumber = getFillValue(getJavaClass( realType.getDefaultSet())); Unit unit = real.getUnit(); Attribute[] attrs; if (unit == null) attrs = new Attribute[] { new Attribute("_FillValue", fillNumber) }; else attrs = new Attribute[] { new Attribute("_FillValue", fillNumber), new Attribute("units", unit.toString()) }; return attrs; } /** * Get the class of the Java primitive type that can contain the * VisAD Set of a VisAD range value. * * @param set The VisAD Set describing the range of the variable * data. * @precondition The set is that of a range value (i.e. DoubleSet, * FloatSet, Linear1DSet, etc.). * @return The Java class corresponding to the variable data * (i.e. Double, Float, Integer, etc.). * @exception VisADException * Problem in core VisAD. Probably some VisAD object * couldn't be created. */ protected static Class getJavaClass(Set set) throws VisADException { if (set == null || set instanceof DoubleSet) return Double.TYPE; if (set instanceof FloatSet) return Float.TYPE; int nelts = set.getLength(); return nelts >= 65536 ? Integer.TYPE : nelts >= 256 ? Short.TYPE : Byte.TYPE; } /** * Return the fill-value object for a numeric netCDF variable of the * given type. * * @param type netCDF type (e.g. <code>Character.TYPE</code>, * <code>Float.TYPE</code>). * @return The default fill-value object for the given netCDF * type. * @exception BadFormException * Unknown netCDF type. */ protected static Number getFillValue(Class type) throws BadFormException { Number number; if (type.equals(Byte.TYPE)) number = new Byte(Byte.MIN_VALUE); else if (type.equals(Short.TYPE)) number = new Short((short)-32767); else if (type.equals(Integer.TYPE)) number = new Integer(-2147483647); else if (type.equals(Float.TYPE)) number = new Float(9.9692099683868690e+36); else if (type.equals(Double.TYPE)) number = new Double(9.9692099683868690e+36); else throw new BadFormException("Unknown netCDF type: " + type); return number; } /** * Return a netCDF datum identified by position. * * @param indexes The netCDF indexes of the desired datum. Includes all * adapted dimensions -- including those of all enclosing * VisAD data objects. * @return A Java Double that contains the data value or NaN if * the data is missing. * @exception IOException * Data access failure. */ public Object get(int[] indexes) throws IOException { Double value = (Double)getAccessor().get(indexes); return value.isNaN() ? fillValue : value; } }