ucar.nc2.dataset.CoordinateAxis1DTime Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of netcdf Show documentation
Show all versions of netcdf Show documentation
The NetCDF-Java Library is a Java interface to NetCDF files,
as well as to many other types of scientific data formats.
/*
* 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