All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ucar.nc2.dataset.CoordinateAxis Maven / Gradle / Ivy

Go to download

The NetCDF-Java Library is a Java interface to NetCDF files, as well as to many other types of scientific data formats.

There is a newer version: 4.3.22
Show newest version
/*
 * Copyright 1998-2009 University Corporation for Atmospheric Research/Unidata
 *
 * Portions of this software were developed by the Unidata Program at the
 * University Corporation for Atmospheric Research.
 *
 * Access and use of this software shall impose the following obligations
 * and understandings on the user. The user is granted the right, without
 * any fee or cost, to use, copy, modify, alter, enhance and distribute
 * this software, and any derivative works thereof, and its supporting
 * documentation for any purpose whatsoever, provided that this entire
 * notice appears in all copies of the software, derivative works and
 * supporting documentation.  Further, UCAR requests that the user credit
 * UCAR/Unidata in any publications that result from the use of this
 * software or in any product that includes this software. The names UCAR
 * and/or Unidata, however, may not be used in any advertising or publicity
 * to endorse or promote any products or commercial entity unless specific
 * written permission is obtained from UCAR/Unidata. The user also
 * understands that UCAR/Unidata is not obligated to provide the user with
 * any support, consulting, training or assistance of any kind with regard
 * to the use, operation and performance of this software nor to provide
 * the user with any updates, revisions, new versions or "bug fixes."
 *
 * THIS SOFTWARE IS PROVIDED BY UCAR/UNIDATA "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL UCAR/UNIDATA BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE ACCESS, USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package ucar.nc2.dataset;

import ucar.ma2.*;
import ucar.nc2.*;
import ucar.nc2.constants.AxisType;

import java.io.IOException;
import java.util.Formatter;

/**
 * A Coordinate Axis is a Variable that specifies one of the coordinates of a CoordinateSystem.
 * Mathematically it is a scalar function F from index space to S:
 * 
 *  F:D -> S
 *  where D is a product set of dimensions (aka index space), and S is the set of reals (R) or Strings.
 * 
*

* If its element type is char, it is considered a string-valued Coordinate Axis and rank is reduced by one, * since the outermost dimension is considered the string length: v(i, j, .., strlen). * If its element type is String, it is a string-valued Coordinate Axis. * Otherwise it is numeric-valued, and isNumeric() is true. *

* The one-dimensional case F(i) -> R is the common case which affords important optimizations. * In that case, use the subtype CoordinateAxis1D. The factory methods will return * either a CoordinateAxis1D if the variable is one-dimensional, a CoordinateAxis2D if its 2D, or a * CoordinateAxis for the general case. *

* A CoordinateAxis is optionally marked as georeferencing with an AxisType. It should have * a units string and optionally a description string. *

* A Structure cannot be a CoordinateAxis, although members of Structures can. * * @author john caron */ public class CoordinateAxis extends VariableDS { static private org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(CoordinateAxis.class); static private final int axisSizeToCache = 100 * 1000; // bytes protected NetcdfDataset ncd; // container dataset protected AxisType axisType = null; protected String positive = null; protected String boundaryRef = null; protected boolean isContiguous = true; /** * Create a coordinate axis from an existing Variable. * * @param ncd the containing dataset * @param vds an existing Variable in dataset. * @return CoordinateAxis or one of its subclasses (CoordinateAxis1D, CoordinateAxis2D, or CoordinateAxis1DTime). */ static public CoordinateAxis factory(NetcdfDataset ncd, VariableDS vds) { if ((vds.getRank() == 1) || (vds.getRank() == 2 && vds.getDataType() == DataType.CHAR)) return new CoordinateAxis1D(ncd, vds); else if (vds.getRank() == 2) return new CoordinateAxis2D(ncd, vds); else return new CoordinateAxis(ncd, vds); } /** * Create a coordinate axis from an existing Variable. * General case. * @param ncd the containing dataset * @param vds an existing Variable */ protected CoordinateAxis(NetcdfDataset ncd, VariableDS vds) { super(vds, false); this.ncd = ncd; if (vds instanceof CoordinateAxis) { CoordinateAxis axis = (CoordinateAxis) vds; this.axisType = axis.axisType; this.boundaryRef = axis.boundaryRef; this.isContiguous = axis.isContiguous; this.positive = axis.positive; } setSizeToCache(axisSizeToCache); } /** * Constructor when theres no underlying variable. You better set the values too! * * @param ds the containing dataset. * @param group the containing group; if null, use rootGroup * @param shortName axis name. * @param dataType data type * @param dims list of dimension names * @param units units of coordinates, preferably udunit compatible. * @param desc long name. */ public CoordinateAxis(NetcdfDataset ds, Group group, String shortName, DataType dataType, String dims, String units, String desc) { super(ds, group, null, shortName, dataType, dims, units, desc); this.ncd = ds; setSizeToCache(axisSizeToCache); } /** * Make a copy, with an independent cache. * @return copy of this CoordinateAxis */ public CoordinateAxis copyNoCache() { CoordinateAxis axis = new CoordinateAxis( ncd, getParentGroup(), getShortName(), getDataType(), getDimensionsString(), getUnitsString(), getDescription()); // other state axis.axisType = this.axisType; axis.boundaryRef = this.boundaryRef; axis.isContiguous = this.isContiguous; axis.positive = this.positive; axis.cache = new Variable.Cache(); // decouple cache return axis; } // for section and slice @Override protected Variable copy() { return new CoordinateAxis(this.ncd, this); } /** * Get type of axis * @return type of axis, or null if none. */ public AxisType getAxisType() { return axisType; } /** * Set type of axis, or null if none. Default is none. * * @param axisType set to this value */ public void setAxisType(AxisType axisType) { this.axisType = axisType; } @Override public String getUnitsString() { String units = super.getUnitsString(); return units == null ? "" : units; } /** * Does the axis have numeric values. * @return true if the CoordAxis is numeric, false if its string valued ("nominal"). */ public boolean isNumeric() { return (getDataType() != DataType.CHAR) && (getDataType() != DataType.STRING) && (getDataType() != DataType.STRUCTURE); } /** * If the edges are contiguous or disjoint * Caution: many datasets do not explicitly specify this info, this is often a guess; default is true. * * @return true if the edges are contiguous or false if disjoint. Assumed true unless set otherwise. */ public boolean isContiguous() { return isContiguous; } /* * Set if the edges are contiguous or disjoint. * * @param isContiguous true if the adjacent edges touch * protected void setContiguous(boolean isContiguous) { this.isContiguous = isContiguous; } */ /** * Get the direction of increasing values, used only for vertical Axes. * * @return POSITIVE_UP, POSITIVE_DOWN, or null if unknown. */ public String getPositive() { return positive; } /** * Set the direction of increasing values, used only for vertical Axes. * * @param positive POSITIVE_UP, POSITIVE_DOWN, or null if you dont know.. */ public void setPositive(String positive) { this.positive = positive; } /** * The name of this coordinate axis' boundary variable * * @return the name of this coordinate axis' boundary variable, or null if none. */ public String getBoundaryRef() { return boundaryRef; } /** * Set a reference to a boundary variable. * * @param boundaryRef the name of a boundary coordinate variable in the same dataset. */ public void setBoundaryRef(String boundaryRef) { this.boundaryRef = boundaryRef; } //////////////////////////////// private MAMath.MinMax minmax = null; private void init() { try { Array data = read(); minmax = MAMath.getMinMax(data); } catch (IOException ioe) { log.error("Error reading coordinate values ", ioe); throw new IllegalStateException(ioe); } } /** * The smallest coordinate value. Only call if isNumeric. * @return the minimum coordinate value */ public double getMinValue() { if (minmax == null) init(); return minmax.min; } /** * The largest coordinate value. Only call if isNumeric. * @return the maximum coordinate value */ public double getMaxValue() { if (minmax == null) init(); return minmax.max; } ////////////////////// /** * Get a string representation * @param buf place info here */ public void getInfo(Formatter buf) { buf.format("%-30s", getNameAndDimensions()); buf.format("%-20s", getUnitsString()); if (axisType != null) { buf.format("%-10s", axisType.toString()); } buf.format("%s", getDescription()); /* if (isNumeric) { boolean debugCoords = ucar.util.prefs.ui.Debug.isSet("Dataset/showCoordValues"); int ndigits = debugCoords ? 9 : 4; for (int i=0; i< getNumElements(); i++) { buf.append(Format.d(getCoordValue(i), ndigits)); buf.append(" "); } if (debugCoords) { buf.append("\n "); for (int i=0; i<=getNumElements(); i++) { buf.append(Format.d(getCoordEdge(i), ndigits)); buf.append(" "); } } } else { for (int i=0; i< getNumElements(); i++) { buf.append(getCoordName(i)); buf.append(" "); } } */ //buf.append("\n"); } /** * Standard sort on Coordinate Axes */ static public class AxisComparator implements java.util.Comparator { public int compare(CoordinateAxis c1, CoordinateAxis c2) { AxisType t1 = c1.getAxisType(); AxisType t2 = c2.getAxisType(); if ((t1 == null) && (t2 == null)) return c1.getName().compareTo(c2.getName()); if (t1 == null) return -1; if (t2 == null) return 1; return t1.axisOrder() - t2.axisOrder(); } public boolean equals(Object obj) { return (this == obj); } } /** * Instances which have same content are equal. */ public boolean equals(Object oo) { if (this == oo) return true; if (!(oo instanceof CoordinateAxis)) return false; if (!super.equals(oo)) return false; CoordinateAxis o = (CoordinateAxis) oo; if (getAxisType() != null) if(!getAxisType().equals(o.getAxisType())) return false; if (getPositive() != null) if(!getPositive().equals(o.getPositive())) return false; return true; } /** * Override Object.hashCode() to implement equals. */ public int hashCode() { if (hashCode == 0) { int result = super.hashCode(); if (getAxisType() != null) result = 37 * result + getAxisType().hashCode(); if (getPositive() != null) result = 37 * result + getPositive().hashCode(); hashCode = result; } return hashCode; } private int hashCode = 0; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy