Package ucar.nc2.dataset

Source Code of ucar.nc2.dataset.CoordinateAxis

/*
* 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:
* <pre>
*  F:D -> S
*  where D is a product set of dimensions (aka <i>index space</i>), and S is the set of reals (R) or Strings.
* </pre>
* <p/>
* 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 <i>isNumeric()</i> is true.
* <p/>
* 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.
* <p/>
* A CoordinateAxis is optionally marked as georeferencing with an AxisType. It should have
* a units string and optionally a description string.
* <p/>
* 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;
  }

  // causes TDS ERROR thredds.server.opendap.NcDDS:  NcDDS: Variable time1_run missing coordinate variable in hash; dataset=fmrc/NCEP/GFS/Global_onedeg/NCEP-GFS-Global_onedeg_best.ncd
  //@Override
  //public boolean isCoordinateVariable() {
  //  return true;
  //}

  /*
   * 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<CoordinateAxis> {
    public int compare(CoordinateAxis c1, CoordinateAxis c2) {

      AxisType t1 = c1.getAxisType();
      AxisType t2 = c2.getAxisType();

      if ((t1 == null) && (t2 == null))
        return c1.getShortName().compareTo(c2.getShortName());
      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;

}
TOP

Related Classes of ucar.nc2.dataset.CoordinateAxis

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.