ucar.nc2.ft.fmrc.TimeCoord Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cdm Show documentation
Show all versions of cdm Show documentation
The NetCDF-Java Library is a Java interface to NetCDF files,
as well as to many other types of scientific data formats.
The newest version!
/*
* Copyright (c) 1998 - 2010. 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.ft.fmrc;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Formatter;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import ucar.nc2.Attribute;
import ucar.nc2.constants.CF;
import ucar.nc2.dataset.CoordinateAxis1DTime;
import ucar.nc2.time.Calendar;
import ucar.nc2.time.CalendarDate;
import ucar.nc2.time.CalendarDateUnit;
import ucar.nc2.units.DateUnit;
import ucar.nc2.util.Misc;
/**
* Represents a list of offset times shared among variables
* Tracks a list of variables that all have the same list of offset times.
*/
public class TimeCoord implements Comparable {
static public final TimeCoord EMPTY = new TimeCoord(CalendarDate.of(new Date()), new double[0]);
private CalendarDate runDate;
private List gridInv; // track the grids that use this coord
private int id; // unique id for serialization
private String axisName; // time coordinate axis
// time at point has offsets, intervals have bounds
private boolean isInterval = false;
private double[] offset; // hours since runDate
private double[] bound1, bound2; // hours since runDate [ntimes,2]
TimeCoord(CalendarDate runDate) {
this.runDate = runDate;
}
TimeCoord(CalendarDate runDate, double[] offset) {
this.runDate = runDate;
this.offset = offset;
}
TimeCoord(TimeCoord from) {
this.runDate = from.runDate;
this.axisName = from.axisName;
this.offset = from.offset;
this.isInterval = from.isInterval;
this.bound1 = from.bound1;
this.bound2 = from.bound2;
this.id = from.id;
}
TimeCoord(CalendarDate runDate, CoordinateAxis1DTime axis) {
this.runDate = runDate;
this.axisName = axis.getFullName();
DateUnit unit = null;
Attribute atrCal = null;
Calendar cal = null;
try {
unit = new DateUnit(axis.getUnitsString());
atrCal = axis.findAttribute(CF.CALENDAR );
if(atrCal != null)
cal = Calendar.get((String)atrCal.getValue(0) );
else
cal = Calendar.getDefault();
} catch (Exception e) {
throw new IllegalArgumentException("Not a unit of time " + axis.getUnitsString());
}
int n = (int) axis.getSize();
if (axis.isInterval()) {
this.isInterval = true;
this.bound1 = new double[n];
this.bound2 = new double[n];
double[] orgBound1 = axis.getBound1();
double[] orgBound2 = axis.getBound2();
this.bound2 = new double[n];
for (int i = 0; i < axis.getSize(); i++) {
this.bound1[i] = getValueInHours(unit, orgBound1[i]);
this.bound2[i] = getValueInHours(unit, orgBound2[i]);
}
} else {
offset = new double[n];
for (int i = 0; i < axis.getSize(); i++) {
offset[i] = getValueInHours(cal, unit, axis.getCoordValue(i));
}
}
}
double getValueInHours(Calendar cal, DateUnit unit, double value) {
//CalendarDate d = unit.makeCalendarDate(value);
//double secs = unit.getTimeUnit().getValueInSeconds(value);
//CalendarDate d = CalendarDate.of(cal, unit.getDateOrigin().getTime() + (long)(1000*secs));
CalendarDateUnit dateUnit = CalendarDateUnit.withCalendar(cal, unit.getUnitsString() ); // this will throw exception on failure
CalendarDate d = dateUnit.makeCalendarDate(value);
return FmrcInv.getOffsetInHours(runDate, d);
}
double getValueInHours(DateUnit unit, double value) {
CalendarDate d = unit.makeCalendarDate(value);
return FmrcInv.getOffsetInHours(runDate, d);
}
void addGridInventory(GridDatasetInv.Grid grid) {
if (gridInv == null)
gridInv = new ArrayList();
gridInv.add(grid);
}
public CalendarDate getRunDate() {
return runDate;
}
public boolean isInterval() {
return isInterval;
}
/**
* The list of GridDatasetInv.Grid that use this TimeCoord
*
* @return list of GridDatasetInv.Grid that use this TimeCoord
*/
public List getGridInventory() {
return (gridInv == null) ? new ArrayList() : gridInv;
}
/**
* A unique id for this TimeCoord
*
* @return unique id for this TimeCoord
*/
public int getId() {
return id;
}
/**
* Set the unique id for this TimeCoord
*
* @param id id for this TimeCoord
*/
public void setId(int id) {
this.id = id;
}
public String getName() {
if (this == EMPTY) return "EMPTY";
return id == 0 ? "time" : "time" + id;
}
public String getAxisName() {
return axisName;
}
public int getNCoords() {
return (isInterval) ? bound1.length : offset.length;
}
/**
* The list of valid times, in units of hours since the run time
* @return list of valid times, in units of hours since the run time
*/
public double[] getOffsetTimes() {
return isInterval ? bound2 : offset;
}
public double[] getBound1() {
return bound1;
}
public double[] getBound2() {
return bound2;
}
public void setOffsetTimes(double[] offset) {
this.offset = offset;
}
public void setBounds(double[] bound1, double[] bound2) {
this.bound1 = bound1;
this.bound2 = bound2;
this.isInterval = true;
}
public void setBounds(List tinvs) {
this.bound1 = new double[tinvs.size()];
this.bound2 = new double[tinvs.size()];
int count = 0;
for (TimeCoord.Tinv tinv : tinvs) {
this.bound1[count] = tinv.b1;
this.bound2[count] = tinv.b2;
count++;
}
this.isInterval = true;
}
@Override
public String toString() {
Formatter out = new Formatter();
out.format("%-10s %-26s offsets=", getName(), runDate);
if (isInterval)
for (int i=0; i timeCoords, TimeCoord want) {
if (want == null) return null;
for (TimeCoord tc : timeCoords) {
if (want.equalsData(tc))
return tc;
}
// make a new one
TimeCoord result = new TimeCoord(want);
timeCoords.add(result);
return result;
}
/**
* Create the union of all the values in the list of TimeCoord, ignoring the TimeCoord's runDate
* @param timeCoords list of TimeCoord
* @param baseDate resulting union timeCoord uses this as a base date
* @return union TimeCoord
*/
static public TimeCoord makeUnion(List timeCoords, CalendarDate baseDate) {
if (timeCoords.size() == 0) return new TimeCoord(baseDate);
if (timeCoords.size() == 1) return timeCoords.get(0);
if (timeCoords.get(0).isInterval)
return makeUnionIntv(timeCoords, baseDate);
else
return makeUnionReg(timeCoords, baseDate);
}
static private TimeCoord makeUnionReg(List timeCoords, CalendarDate baseDate) {
// put into a set for uniqueness
Set offsets = new HashSet();
for (TimeCoord tc : timeCoords) {
if (tc.isInterval)
throw new IllegalArgumentException("Cant mix interval coordinates");
for (double off : tc.getOffsetTimes())
offsets.add(off);
}
// extract into a List
List offsetList = Arrays.asList((Double[]) offsets.toArray(new Double[offsets.size()]));
// sort and extract into double[]
Collections.sort(offsetList);
double[] offset = new double[offsetList.size()];
int count = 0;
for (double off : offsetList)
offset[count++] = off;
// make the resulting time coord
TimeCoord result = new TimeCoord(baseDate);
result.setOffsetTimes(offset);
return result;
}
static private TimeCoord makeUnionIntv(List timeCoords, CalendarDate baseDate) {
// put into a set for uniqueness
Set offsets = new HashSet();
for (TimeCoord tc : timeCoords) {
if (!tc.isInterval)
throw new IllegalArgumentException("Cant mix non-interval coordinates");
for (int i=0; i bounds = Arrays.asList((Tinv[]) offsets.toArray(new Tinv[offsets.size()]));
// sort and extract into double[] bounds arrays
Collections.sort(bounds);
int n = bounds.size();
double[] bounds1 = new double[n];
double[] bounds2 = new double[n];
for (int i=0; i {
private double b1, b2; // bounds
public Tinv(double offset) {
this.b2 = offset;
}
public Tinv(double b1, double b2) {
this.b1 = b1;
this.b2 = b2;
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Tinv)) return false;
Tinv tinv = (Tinv) o;
if (Double.compare(tinv.b1, b1) != 0) return false;
if (Double.compare(tinv.b2, b2) != 0) return false;
return true;
}
@Override
public int hashCode() {
int result;
long temp;
temp = b1 != +0.0d ? Double.doubleToLongBits(b1) : 0L; // Bloch item 9
result = (int) (temp ^ (temp >>> 32));
temp = b2 != +0.0d ? Double.doubleToLongBits(b2) : 0L;
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public int compareTo(Tinv o) {
int c1 = Double.compare(b2, o.b2);
if (c1 == 0) return Double.compare(b1, o.b1);
return c1;
}
}
/*
* Create the union of all the values in the list of TimeCoord, converting all to a common baseDate
* @param timeCoords list of TimeCoord
* @param baseDate resulting union timeCoord uses this as a base date
* @return union TimeCoord
*
static public TimeResult makeUnionConvert(List timeCoords, Date baseDate) {
Map offsetMap = new HashMap(256);
for (TimeCoord tc : timeCoords) {
double run_offset = FmrcInv.getOffsetInHours(baseDate, tc.getRunDate());
for (double offset : tc.getOffsetHours()) {
offsetMap.put(run_offset + offset, run_offset); // later ones override
}
}
Set keys = offsetMap.keySet();
int n = keys.size();
List offsetList = Arrays.asList((Double[]) keys.toArray(new Double[n]));
Collections.sort(offsetList);
int counto = 0;
double[] offs = new double[n];
double[] runoffs = new double[n];
for (Double key : offsetList) {
offs[counto] = key;
runoffs[counto] = offsetMap.get(key);
counto++;
}
return new TimeResult( baseDate, offs, runoffs);
}
static class TimeResult {
double[] offsets;
double[] runOffsets;
Date base;
TimeResult(Date base, double[] offsets, double[] runOffsets) {
this.base = base;
this.offsets = offsets;
this.runOffsets = runOffsets;
}
} */
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy