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

ucar.nc2.dataset.CoordinateAxis1DTime 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.nc2.units.DateUnit;
import ucar.nc2.units.DateFormatter;
import ucar.nc2.units.TimeUnit;
import ucar.nc2.Variable;
import ucar.nc2.Dimension;
import ucar.nc2.Attribute;
import ucar.nc2.util.NamedAnything;
import ucar.nc2.util.NamedObject;
import ucar.ma2.*;

import java.util.*;
import java.io.IOException;

import ucar.nc2.units.DateRange;

/**
 * A 1-dimensional Coordinate Axis representing Calendar time.
 * Its coordinate values can be represented as Dates.
 * 

* May use udunit dates, or ISO Strings. * * @author caron */ public class CoordinateAxis1DTime extends CoordinateAxis1D { private Date[] timeDates; private DateUnit dateUnit; static public CoordinateAxis1DTime factory(NetcdfDataset ncd, VariableDS org, Formatter errMessages) throws IOException { if (org.getDataType() == DataType.CHAR) { return new CoordinateAxis1DTime(ncd, org, errMessages, org.getDimension(0).getName()); } return new CoordinateAxis1DTime(ncd, org, errMessages); } /** * Constructor for CHAR variables, turn into String * * @param ncd the containing dataset * @param org the underlying Variable * @param errMessages put error messages here; may be null * @param dims list of dimensions * @throws IOException on read error * @throws IllegalArgumentException if cant convert coordinate values to a Date */ private CoordinateAxis1DTime(NetcdfDataset ncd, VariableDS org, Formatter errMessages, String dims) throws IOException { // NetcdfDataset ds, Group group, String shortName, DataType dataType, String dims, String units, String desc super(ncd, org.getParentGroup(), org.getShortName(), DataType.STRING, dims, org.getUnitsString(), org.getDescription()); this.ncd = ncd; this.orgName = org.orgName; List atts = org.getAttributes(); for (Attribute att : atts) { addAttribute(att); } //named = new ArrayList(); // declared in CoordinateAxis1D superclass int ncoords = (int) org.getSize(); int rank = org.getRank(); int strlen = org.getShape(rank - 1); ncoords /= strlen; timeDates = new Date[ncoords]; ArrayChar data = (ArrayChar) org.read(); ArrayChar.StringIterator ii = data.getStringIterator(); ArrayObject.D1 sdata = new ArrayObject.D1(String.class, ncoords); for (int i = 0; i < ncoords; i++) { String coordValue = ii.next(); Date d = DateUnit.getStandardOrISO(coordValue); if (d == null) { if (errMessages != null) errMessages.format("DateUnit cannot parse String= %s\n",coordValue); else System.out.println("DateUnit cannot parse String= " + coordValue + "\n"); throw new IllegalArgumentException(); } else { sdata.set(i, coordValue); timeDates[i] = d; } } setCachedData(sdata, true); } private CoordinateAxis1DTime(NetcdfDataset ncd, VariableDS org, Formatter errMessages) throws IOException { super(ncd, org); // named = new ArrayList(); // declared in CoordinateAxis1D superclass int ncoords = (int) org.getSize(); timeDates = new Date[ncoords]; // see if it has a valid udunits unit DateUnit dateUnit = null; String units = org.getUnitsString(); if (units != null) { try { dateUnit = new DateUnit(units); } catch (Exception e) { // not a date unit - ok to fall through } } // has a valid date unit - read data if (dateUnit != null) { Array data = org.read(); int count = 0; IndexIterator ii = data.getIndexIterator(); for (int i = 0; i < ncoords; i++) { double val = ii.getDoubleNext(); if (Double.isNaN(val)) continue; Date d = dateUnit.makeDate(val); timeDates[count++] = d; } // if we encountered NaNs, shorten it up if (count != ncoords) { Dimension localDim = new Dimension(getShortName(), count, false); setDimension(0, localDim); // set the shortened values Array shortData = Array.factory(data.getElementType(), new int[]{count}); Index ima = shortData.getIndex(); int count2 = 0; ii = data.getIndexIterator(); for (int i = 0; i < ncoords; i++) { double val = ii.getDoubleNext(); if (Double.isNaN(val)) continue; shortData.setDouble(ima.set0(count2), val); count2++; } // here we have to decouple from the original variable cache = new Cache(); setCachedData(shortData, true); // shorten up the timeDate array Date[] keep = timeDates; timeDates = new Date[count]; System.arraycopy(keep, 0, timeDates, 0, timeDates.length); } return; } // has valid date unit // see if its a String, and if we can parse the values as an ISO date if (org.getDataType() == DataType.STRING) { ArrayObject data = (ArrayObject) org.read(); IndexIterator ii = data.getIndexIterator(); for (int i = 0; i < ncoords; i++) { String coordValue = (String) ii.getObjectNext(); Date d = DateUnit.getStandardOrISO(coordValue); if (d == null) { if (errMessages != null) errMessages.format("DateUnit cannot parse String= %s\n", coordValue); else System.out.println("DateUnit cannot parse String= " + coordValue + "\n"); throw new IllegalArgumentException(); } else { timeDates[i] = d; } } return; } // hack something in here so it doesnt fail if (units != null) { try { // if in time unit, use CF convention "since 1-1-1 0:0:0" dateUnit = new DateUnit(units+" since 0001-01-01 00:00:00"); } catch (Exception e) { try { if (errMessages != null) errMessages.format("Time Coordinate must be udunits or ISO String: hack since 0001-01-01 00:00:00\n"); else System.out.println("Time Coordinate must be udunits or ISO String: hack since 0001-01-01 00:00:00\n"); dateUnit = new DateUnit("secs since 0001-01-01 00:00:00"); } catch (Exception e1) { // cant happpen } } } Array data = org.read(); IndexIterator ii = data.getIndexIterator(); for (int i = 0; i < ncoords; i++) { double val = ii.getDoubleNext(); Date d = dateUnit.makeDate(val); timeDates[i] = d; } } private CoordinateAxis1DTime(NetcdfDataset ncd, CoordinateAxis1DTime org, Date[] timeDates) { super(ncd, org); this.timeDates = timeDates; this.dateUnit = org.dateUnit; } // for section and slice @Override protected Variable copy() { return new CoordinateAxis1DTime(this.ncd, this, getTimeDates()); } /** * Get the list of times as Dates. * * @return array of java.util.Date, or null. */ public java.util.Date[] getTimeDates() { return timeDates; } public java.util.Date getTimeDate (int idx) { return timeDates[idx]; } public DateRange getDateRange() { return new DateRange(timeDates[0], timeDates[timeDates.length - 1]); } @Override public List getNames() { DateFormatter formatter = new DateFormatter(); int n = (int) getSize(); List names = new ArrayList(n); for (int i = 0; i < n; i++) { names.add(new NamedAnything(formatter.toDateTimeString(getTimeDate(i)), "date/time")); } return names; } /** * only if isRegular() LOOK REDO * * @return time unit * @throws Exception on bad unit string */ public TimeUnit getTimeResolution() throws Exception { String tUnits = getUnitsString(); StringTokenizer stoker = new StringTokenizer(tUnits); double tResolution = getIncrement(); return new TimeUnit(tResolution, stoker.nextToken()); } /** * Given a Date, find the corresponding time index on the time coordinate axis. * Can only call this is hasDate() is true. * This will return *

    *
  • i, if time(i) <= d < time(i+1). *
  • 0, if d < time(0) *
  • n-1, if d > time(n-1), where n is length of time coordinates *
* * @param d date to look for * @return corresponding time index on the time coordinate axis * @throws UnsupportedOperationException is no time axis or isDate() false */ public int findTimeIndexFromDate(java.util.Date d) { int n = timeDates.length; long m = d.getTime(); int index = 0; while (index < n) { if (m < timeDates[index].getTime()) break; index++; } return Math.max(0, index - 1); } /** * See if the given Date appears is a coordinate * * @param date test this * @return true if equals a coordinate */ public boolean hasTime(Date date) { for (Date timeDate : timeDates) { if (date.equals(timeDate)) return true; } return false; } @Override public CoordinateAxis1D section(Range r) throws InvalidRangeException { CoordinateAxis1D s = super.section(r); Date[] d = new Date[r.length()]; for (int i = r.first(), j = 0; i <= r.last(); i += r.stride(), ++j) { d[j] = timeDates[i]; } ((CoordinateAxis1DTime)s).timeDates = d; return s; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy