ucar.nc2.ft.fmrc.FmrcInvLite Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 1998-2018 John Caron and University Corporation for Atmospheric Research/Unidata
* See LICENSE for license information.
*/
package ucar.nc2.ft.fmrc;
import thredds.featurecollection.FeatureCollectionConfig;
import ucar.nc2.time.CalendarDate;
import ucar.nc2.util.Misc;
import java.io.FileNotFoundException;
import java.util.*;
/**
* A lightweight, serializable version of FmrcInv
*
* @author caron
* @since Apr 14, 2010
*/
public class FmrcInvLite implements java.io.Serializable {
private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(FmrcInvLite.class);
private static final String BEST = "Best";
// public for debugging
public String collectionName;
public CalendarDate base; // offsets are from here
public int nruns; // runOffset[nruns]
public double[] runOffset; // run time in offset hours since base
public double[] forecastOffset; // all forecast times in offset hours since base, for "constant forecast" datasets
public double[] offsets; // all the offset values, for "constant offset" datasets
public List locationList = new ArrayList<>(); // dataset location, can be used in
// NetcdfDataset.acquireDataset()
public Map locationMap = new HashMap<>(); // quick lookup of dataset location in locationList
public List gridSets = new ArrayList<>(); // All Grids in Gridset have same time coordinate
public List invList = new ArrayList<>(); // the actual inventory
// share these, they are expensive!
public FmrcInvLite(FmrcInv fmrcInv) {
this.collectionName = fmrcInv.getName();
this.base = fmrcInv.getBaseDate();
// store forecasts as offsets instead of Dates
List forecasts = fmrcInv.getForecastTimes();
this.forecastOffset = new double[forecasts.size()];
for (int i = 0; i < forecasts.size(); i++) {
CalendarDate f = forecasts.get(i);
this.forecastOffset[i] = FmrcInv.getOffsetInHours(base, f);
}
// for each run
List fmrList = fmrcInv.getFmrInv();
nruns = fmrList.size();
runOffset = new double[nruns];
int countIndex = 0;
for (int run = 0; run < nruns; run++) {
FmrInv fmr = fmrList.get(run);
runOffset[run] = FmrcInv.getOffsetInHours(base, fmr.getRunDate());
for (GridDatasetInv inv : fmr.getInventoryList()) {
locationList.add(inv.getLocation());
locationMap.put(inv.getLocation(), countIndex);
countIndex++;
}
}
// for each RunSeq
for (FmrcInv.RunSeq runseq : fmrcInv.getRunSeqs()) {
gridSets.add(new Gridset(runseq));
}
// calc the offsets
TreeSet tree = new TreeSet<>();
for (Gridset gridset : gridSets) {
for (int run = 0; run < nruns; run++) {
double baseOffset = runOffset[run];
for (int time = 0; time < gridset.noffsets; time++) {
double offset = gridset.timeOffset[run * gridset.noffsets + time];
if (!Double.isNaN(offset))
tree.add(offset - baseOffset);
}
}
}
offsets = new double[tree.size()];
Iterator iter = tree.iterator();
for (int i = 0; i < tree.size(); i++) {
offsets[i] = iter.next();
}
}
public int findRunIndex(CalendarDate want) {
for (int i = 0; i < runOffset.length; i++)
if (want.equals(FmrcInv.makeOffsetDate(base, runOffset[i])))
return i;
return -1;
}
public List getRunDates() {
List result = new ArrayList<>(runOffset.length);
for (double off : runOffset)
result.add(FmrcInv.makeOffsetDate(base, off));
return result;
}
public List getForecastDates() {
List result = new ArrayList<>(forecastOffset.length);
for (double f : forecastOffset)
result.add(FmrcInv.makeOffsetDate(base, f));
return result;
}
// for making constant offset datasets
public double[] getForecastOffsets() {
return offsets;
}
public Gridset.Grid findGrid(String gridName) {
for (Gridset gridset : gridSets) {
for (Gridset.Grid grid : gridset.grids) {
if (gridName.equals(grid.name))
return grid;
}
}
return null;
}
public Gridset findGridset(String gridName) {
for (Gridset gridset : gridSets) {
for (Gridset.Grid grid : gridset.grids) {
if (gridName.equals(grid.name))
return gridset;
}
}
return null;
}
// debugging
public void showGridInfo(String gridName, Formatter out) {
Gridset.Grid grid = findGrid(gridName);
if (grid == null) {
out.format("Cant find grid = %s%n", gridName);
return;
}
Gridset gridset = grid.getGridset();
out.format("%n=======================================%nFmrcLite.Grid%n");
// show the 2D
out.format("2D%n run%n time ");
for (int i = 0; i < gridset.noffsets; i++)
out.format("%6d ", i);
out.format("%n");
for (int run = 0; run < nruns; run++) {
out.format("%6d", run);
for (int time = 0; time < gridset.noffsets; time++) {
out.format(" %6.0f", gridset.getTimeCoord(run, time));
}
out.format("%n");
}
out.format("%n");
Gridset.GridInventory gridInv = grid.inv;
out.format("%n=======================================%nFmrcLite.GridInventory Missing Data%n");
// show missing inventory only
for (int run = 0; run < nruns; run++) {
boolean hasMissing = false;
for (int time = 0; time < gridset.noffsets; time++)
if (gridInv.getLocation(run, time) == 0)
hasMissing = true;
if (hasMissing) {
out.format("run %6d timeIdx=", run);
for (int time = 0; time < gridset.noffsets; time++) {
if (gridInv.getLocation(run, time) == 0)
out.format(" %6d", time);
}
out.format("%n");
}
}
out.format("%n");
out.format("%n=======================================%nFmrcLite.TimeInv Best%n");
BestDatasetInventory best = new BestDatasetInventory(null);
List bestInv = gridset.timeCoordMap.get(BEST);
if (bestInv == null)
bestInv = gridset.makeBest(null);
FmrcInvLite.ValueB coords = best.getTimeCoords(gridset); // must call this to be sure data is there
// show the best
out.format(" ");
for (int i = 0; i < bestInv.size(); i++)
out.format(" %6d", i);
out.format("%n");
out.format(" coord =");
for (TimeInv inv : bestInv)
out.format(" %6.0f", inv.offset);
out.format("%n");
out.format(" run =");
for (TimeInv inv : bestInv)
out.format(" %6d", inv.runIdx);
out.format("%n");
out.format(" idx =");
for (TimeInv inv : bestInv)
out.format(" %6d", inv.timeIdx);
out.format("%n");
}
// group of Grids with the same time coordinate
public class Gridset implements java.io.Serializable {
String gridsetName;
List grids = new ArrayList<>();
int noffsets;
double[] timeOffset; // timeOffset(nruns,noffsets) in offset hours since base. this is the twoD time coordinate for
// this Gridset;
// Double.NaN for missing values; these are dense (a ragged array has missing all at end)
double[] timeBounds; // timeBounds(nruns,noffsets,2) in offset hours since base. null means not an interval time
// coordinate
Map> timeCoordMap = new HashMap<>();
Gridset(FmrcInv.RunSeq runseq) {
this.gridsetName = runseq.getName();
List timeList = runseq.getTimes();
boolean hasMissingTimes = (nruns != timeList.size()); // missing one or more variables in one or more runs
noffsets = 0;
for (TimeCoord tc : timeList)
noffsets = Math.max(noffsets, tc.getNCoords());
// noffsets = runseq.getUnionTimeCoord().getNCoords();
// this is the twoD time coordinate for this Gridset
timeOffset = new double[nruns * noffsets];
for (int i = 0; i < timeOffset.length; i++)
timeOffset[i] = Double.NaN;
if (runseq.isInterval()) {
timeBounds = new double[nruns * noffsets * 2];
for (int i = 0; i < timeBounds.length; i++)
timeBounds[i] = Double.NaN;
}
// fill twoD time coordinate from the sequence of time coordinates
int runIdx = 0;
for (TimeCoord timeCoord : timeList) {
TimeCoord tc;
if (hasMissingTimes) {
tc = timeCoord;
double tc_offset = FmrcInv.getOffsetInHours(base, tc.getRunDate());
while (true) { // incr run till we find it
double run_offset = runOffset[runIdx];
if (Misc.nearlyEquals(run_offset, tc_offset)) {
break;
}
runIdx++;
if (log.isDebugEnabled()) {
String missingDate = FmrcInv.makeOffsetDate(base, run_offset).toString();
String wantDate = tc.getRunDate().toString();
log.debug(collectionName + ": runseq missing time " + missingDate + " looking for " + wantDate
+ " for var = " + runseq.getUberGrids().get(0).getName());
}
}
} else { // common case
tc = timeList.get(runIdx);
}
double run_offset = FmrcInv.getOffsetInHours(base, tc.getRunDate());
double[] offsets = tc.getOffsetTimes();
int ntimes = offsets.length;
for (int time = 0; time < ntimes; time++) {
timeOffset[runIdx * noffsets + time] = run_offset + offsets[time]; // offset == bound2 when its an interval
}
// optionally create 2D bounds
if (runseq.isInterval()) {
double[] bound1 = tc.getBound1();
double[] bound2 = tc.getBound2();
for (int time = 0; time < ntimes; time++) {
timeBounds[2 * (runIdx * noffsets + time)] = run_offset + bound1[time];
timeBounds[2 * (runIdx * noffsets + time) + 1] = run_offset + bound2[time];
}
}
runIdx++;
}
for (FmrcInv.UberGrid ugrid : runseq.getUberGrids()) {
grids.add(new Grid(ugrid.getName(), getInventory(ugrid)));
}
}
// create GridInventory, see if it matches other Grids
private GridInventory getInventory(FmrcInv.UberGrid ugrid) {
GridInventory result = null;
GridInventory need = new GridInventory(ugrid);
// see if we already have it
for (GridInventory got : invList) {
if (got.equalData(need)) {
result = got;
break;
}
}
if (result == null) {
invList.add(need);
result = need;
}
return result;
}
double getTimeCoord(int run, int time) {
return timeOffset[run * noffsets + time];
}
private List makeBest(FeatureCollectionConfig.BestDataset bd) {
Map map = new HashMap<>();
for (int run = 0; run < nruns; run++) {
for (int time = 0; time < noffsets; time++) {
double baseOffset = timeOffset[run * noffsets + time]; // this is the offset from the global base
if (Double.isNaN(baseOffset))
continue;
double orgOffset = baseOffset - runOffset[run]; // this is the offset from its own base
if (bd != null && orgOffset < bd.greaterThan)
continue; // skip it
if (timeBounds == null)
map.put(new TimeCoord.Tinv(baseOffset), new TimeInv(run, time, baseOffset)); // later ones override
else {
double b1 = timeBounds[2 * (run * noffsets + time)];
double b2 = timeBounds[2 * (run * noffsets + time) + 1];
map.put(new TimeCoord.Tinv(b1, b2), new TimeInv(run, time, b1, b2)); // hmmmmm ????
}
}
}
Collection values = map.values();
int n = values.size();
List best = Arrays.asList((TimeInv[]) values.toArray(new TimeInv[n]));
Collections.sort(best);
timeCoordMap.put(BEST, best);
return best;
}
private List makeRun(int runIdx) {
List result = new ArrayList<>(noffsets);
for (int time = 0; time < noffsets; time++) {
double offset = timeOffset[runIdx * noffsets + time];
if (Double.isNaN(offset))
continue;
if (timeBounds == null)
result.add(new TimeInv(runIdx, time, offset));
else {
double b1 = timeBounds[2 * (runIdx * noffsets + time)];
double b2 = timeBounds[2 * (runIdx * noffsets + time) + 1];
result.add(new TimeInv(runIdx, time, b1, b2));
}
}
timeCoordMap.put("run" + runIdx, result);
return result;
}
private List makeConstantForecast(double offset) {
List result = new ArrayList<>(noffsets);
for (int run = 0; run < nruns; run++) {
for (int time = 0; time < noffsets; time++) { // search for all offsets that match - presumably 0 or 1 per run
double baseOffset = timeOffset[run * noffsets + time];
if (Double.isNaN(baseOffset))
continue;
if (Misc.nearlyEquals(baseOffset, offset))
result.add(new TimeInv(run, time, offset - timeOffset[run * noffsets])); // use offset from start of run
}
}
timeCoordMap.put("forecast" + offset, result);
return result;
}
private List makeConstantOffset(double offset) {
List result = new ArrayList<>(nruns);
for (int run = 0; run < nruns; run++) {
for (int time = 0; time < noffsets; time++) { // search for all offsets that match - presumably 0 or 1 per run
double baseOffset = getTimeCoord(run, time);
if (Double.isNaN(baseOffset))
continue;
double runOffset = baseOffset - FmrcInvLite.this.runOffset[run]; // subtract the base offset for this run
if (Misc.nearlyEquals(runOffset, offset))
result.add(new TimeInv(run, time, baseOffset));
}
}
timeCoordMap.put("offset" + offset, result);
return result;
}
public class Grid implements java.io.Serializable {
String name;
GridInventory inv; // shared
Grid(String name, GridInventory inv) {
this.name = name;
this.inv = inv;
}
Gridset getGridset() {
return Gridset.this;
}
TimeInventory.Instance getInstance(int runIdx, int timeIdx) {
int locIdx = inv.getLocation(runIdx, timeIdx);
if (locIdx == 0)
return null;
int invIndex = inv.getInvIndex(runIdx, timeIdx);
return new TimeInstance(locationList.get(locIdx - 1), invIndex);
}
} // Grid
// track inventory, shared amongst grids
public class GridInventory implements java.io.Serializable {
int[] location; // (run,time) file location (index+1 into locationList, 0 = missing)
int[] invIndex; // (run,time) time index in file = 'location'
/**
* Create 2D location, time index representing the inventory for a Grid.
*
* @param ugrid for this grid
*/
GridInventory(FmrcInv.UberGrid ugrid) {
this.location = new int[nruns * noffsets];
this.invIndex = new int[nruns * noffsets];
// loop over runDates
int gridIdx = 0;
List grids = ugrid.getRuns(); // must be sorted by rundate. extract needed info, do not
// keep reference
for (int runIdx = 0; runIdx < nruns; runIdx++) {
CalendarDate runDate = FmrcInv.makeOffsetDate(base, runOffset[runIdx]);
// do we have a grid for this runDate?
if (gridIdx >= grids.size()) {
log.debug(collectionName + ": cant find " + ugrid.getName() + " for " + runDate); // could be normal
// condition
break;
}
FmrInv.GridVariable grid = grids.get(gridIdx);
if (!grid.getRunDate().equals(runDate))
continue;
gridIdx++; // for next loop
// loop over actual inventory
for (GridDatasetInv.Grid inv : grid.getInventory()) {
double invOffset = FmrcInv.getOffsetInHours(base, inv.tc.getRunDate()); // offset of this file
for (int i = 0; i < inv.tc.getNCoords(); i++) {
int timeIdx;
if (timeBounds == null) {
timeIdx = findIndex(runIdx, invOffset + inv.tc.getOffsetTimes()[i]);
} else {
timeIdx = findBounds(runIdx, invOffset + inv.tc.getBound1()[i], invOffset + inv.tc.getBound2()[i]);
}
if (timeIdx >= 0) {
location[runIdx * noffsets + timeIdx] = findLocation(inv.getLocation()) + 1;
invIndex[runIdx * noffsets + timeIdx] = i;
}
} // loop over time coordinates
} // loop over files
} // loop over run
}
private boolean equalData(Object oo) {
GridInventory o = (GridInventory) oo;
if (o.location.length != location.length)
return false;
if (o.invIndex.length != invIndex.length)
return false;
for (int i = 0; i < location.length; i++)
if (location[i] != o.location[i])
return false;
for (int i = 0; i < invIndex.length; i++)
if (invIndex[i] != o.invIndex[i])
return false;
return true;
}
// LOOK linear search!
private int findIndex(int runIdx, double want) {
for (int j = 0; j < noffsets; j++)
if (Misc.nearlyEquals(timeOffset[runIdx * noffsets + j], want))
return j;
return -1;
}
// LOOK linear search!
private int findBounds(int runIdx, double b1, double b2) {
for (int j = 0; j < noffsets; j++)
if (Misc.nearlyEquals(timeBounds[2 * (runIdx * noffsets + j)], b1)
&& Misc.nearlyEquals(timeBounds[2 * (runIdx * noffsets + j) + 1], b2))
return j;
return -1;
}
private int findLocation(String location) {
return locationMap.get(location);
}
int getLocation(int run, int time) {
return location[run * noffsets + time];
}
int getInvIndex(int run, int time) {
return invIndex[run * noffsets + time];
}
} // GridInventory
} // Gridset
// lightweight tracker of where a Grid lives
static class TimeInstance implements TimeInventory.Instance {
String location;
int index; // time index in the file = 'location'
TimeInstance(String location, int index) {
this.location = location;
this.index = index;
}
@Override
public String getDatasetLocation() {
return location;
}
@Override
public int getDatasetIndex() {
return index;
}
@Override
public String toString() {
return "TimeInstance{" + "location='" + location + '\'' + ", index=" + index + '}';
}
}
// represents 1 time coord in a 2d time matrix, point or interval
private static class TimeInv implements Comparable {
int runIdx;
int timeIdx;
double offset; // hours since base or hours since run time
double startIntv = Double.NaN;
boolean isInterval;
TimeInv(int runIdx, int timeIdx, double b1, double b2) {
this.runIdx = runIdx;
this.timeIdx = timeIdx;
this.startIntv = b1;
this.offset = b2;
isInterval = true;
}
TimeInv(int runIdx, int timeIdx, double offset) {
this.runIdx = runIdx;
this.timeIdx = timeIdx;
this.offset = offset;
}
@Override
public int compareTo(TimeInv o) {
if (Misc.nearlyEquals(offset, o.offset))
return 0;
if (!isInterval)
return Double.compare(offset, o.offset);
if (Misc.nearlyEquals(startIntv, o.startIntv))
return 0;
return Double.compare(startIntv, o.startIntv);
}
}
// efficient representation of time coords - point or interval
public static class ValueB {
public double[] offset; // the forecast time
public double[] bounds; // bounds of interval or null. shape = (ntimes, 2)
public ValueB(List invs) {
boolean isInterval = !invs.isEmpty() && invs.get(0).isInterval;
offset = new double[invs.size()];
if (isInterval) {
bounds = new double[2 * invs.size()];
for (int i = 0; i < invs.size(); i++) {
TimeInv b = invs.get(i);
offset[i] = b.offset;
bounds[2 * i] = b.startIntv;
bounds[2 * i + 1] = b.offset; // end of interval is also the forecast time
}
} else {
for (int i = 0; i < invs.size(); i++) {
TimeInv b = invs.get(i);
offset[i] = b.offset;
}
}
}
}
// public for debugging
public TimeInventory makeBestDatasetInventory() {
return new BestDatasetInventory(null);
}
TimeInventory makeBestDatasetInventory(FeatureCollectionConfig.BestDataset bd) {
return new BestDatasetInventory(bd);
}
// public for debugging
public TimeInventory makeRunTimeDatasetInventory(CalendarDate run) throws FileNotFoundException {
return new RunTimeDatasetInventory(run);
}
// public for debugging
public TimeInventory getConstantForecastDataset(CalendarDate time) throws FileNotFoundException {
return new ConstantForecastDataset(time);
}
// public for debugging
public TimeInventory getConstantOffsetDataset(double hour) throws FileNotFoundException {
return new ConstantOffsetDataset(hour);
}
/*
* The best dataset is based on the Gridset time coordinates, rather than the GridInventory. This means that
* one can have missing values, instead of using the "next best" runtime.
* The reason for this is so that all the fields come from the same runtime.
* If we did implement NextBest, we would need to have different run_time coordinates whenever there were missing
* values,
* possible one for each variable, to accurately reflect where the data came from.
*/
class BestDatasetInventory implements TimeInventory {
FeatureCollectionConfig.BestDataset bd; // parameterized for offsets >= p. null means want all offsets
BestDatasetInventory(FeatureCollectionConfig.BestDataset bd) {
this.bd = bd;
}
@Override
public String getName() {
return (bd == null) ? BEST : bd.name;
}
@Override
public int getTimeLength(Gridset gridset) {
List best = gridset.timeCoordMap.get(getName());
if (best == null)
best = gridset.makeBest(bd);
return best.size();
}
@Override
public FmrcInvLite.ValueB getTimeCoords(Gridset gridset) {
List best = gridset.timeCoordMap.get(getName());
if (best == null)
best = gridset.makeBest(bd);
return new ValueB(best);
}
@Override
public double[] getRunTimeCoords(Gridset gridset) {
List best = gridset.timeCoordMap.get(getName());
if (best == null)
best = gridset.makeBest(bd);
double[] result = new double[best.size()];
for (int i = 0; i < best.size(); i++) {
TimeInv b = best.get(i);
result[i] = gridset.getTimeCoord(b.runIdx, 0); // the first one for the run given by runIdx
}
return result;
}
@Override
public double[] getOffsetCoords(Gridset gridset) {
List best = gridset.timeCoordMap.get(getName());
if (best == null)
best = gridset.makeBest(bd);
double[] result = new double[best.size()];
for (int i = 0; i < best.size(); i++) {
TimeInv b = best.get(i);
result[i] = b.offset - gridset.getTimeCoord(b.runIdx, 0); // offset from run start
}
return result;
}
@Override
public Instance getInstance(Gridset.Grid grid, int timeIdx) {
Gridset gridset = grid.getGridset();
List best = gridset.timeCoordMap.get(getName());
if (best == null)
best = gridset.makeBest(bd);
TimeInv b = best.get(timeIdx);
int locIdx = grid.inv.getLocation(b.runIdx, b.timeIdx);
if (locIdx == 0)
return null;
int invIndex = grid.inv.getInvIndex(b.runIdx, b.timeIdx);
return new TimeInstance(locationList.get(locIdx - 1), invIndex);
}
}
class RunTimeDatasetInventory implements TimeInventory {
int runIdx = -1;
RunTimeDatasetInventory(CalendarDate run) throws FileNotFoundException {
double offset = FmrcInv.getOffsetInHours(base, run);
for (int i = 0; i < runOffset.length; i++) {
if (Misc.nearlyEquals(runOffset[i], offset)) {
runIdx = i;
break;
}
}
if (runIdx < 0)
throw new FileNotFoundException("No run date of " + run);
}
@Override
public String getName() {
return "Run " + FmrcInv.makeOffsetDate(base, runOffset[runIdx]);
}
@Override
public int getTimeLength(Gridset gridset) {
List coords = gridset.timeCoordMap.get("run" + runIdx);
if (coords == null)
coords = gridset.makeRun(runIdx);
return coords.size();
}
@Override
public FmrcInvLite.ValueB getTimeCoords(Gridset gridset) {
List coords = gridset.timeCoordMap.get("run" + runIdx);
if (coords == null)
coords = gridset.makeRun(runIdx);
return new FmrcInvLite.ValueB(coords);
}
@Override
public double[] getRunTimeCoords(Gridset gridset) {
return null;
}
@Override
public double[] getOffsetCoords(Gridset gridset) {
List coords = gridset.timeCoordMap.get("run" + runIdx);
if (coords == null)
coords = gridset.makeRun(runIdx);
double startRun = gridset.getTimeCoord(runIdx, 0);
double[] result = new double[coords.size()];
for (int i = 0; i < coords.size(); i++) {
TimeInv b = coords.get(i);
result[i] = b.offset - startRun;
}
return result;
}
@Override
public Instance getInstance(Gridset.Grid grid, int timeIdx) {
Gridset gridset = grid.getGridset();
List coords = gridset.timeCoordMap.get("run" + runIdx);
if (coords == null)
coords = gridset.makeRun(runIdx);
TimeInv b = coords.get(timeIdx);
return grid.getInstance(b.runIdx, b.timeIdx);
}
}
class ConstantForecastDataset implements TimeInventory {
double offset;
ConstantForecastDataset(CalendarDate time) throws FileNotFoundException {
this.offset = FmrcInv.getOffsetInHours(base, time);
for (CalendarDate d : getForecastDates())
if (d.equals(time))
return; // ok
throw new FileNotFoundException("No forecast date of " + time); // we dont got it
}
@Override
public String getName() {
return "Constant Forecast " + FmrcInv.makeOffsetDate(base, offset);
}
@Override
public int getTimeLength(Gridset gridset) {
List coords = gridset.timeCoordMap.get("forecast" + offset);
if (coords == null)
coords = gridset.makeConstantForecast(offset);
return coords.size();
}
@Override
public FmrcInvLite.ValueB getTimeCoords(Gridset gridset) {
return null;
}
@Override
public double[] getRunTimeCoords(Gridset gridset) {
List coords = gridset.timeCoordMap.get("forecast" + offset);
if (coords == null)
coords = gridset.makeConstantForecast(offset);
double[] result = new double[coords.size()];
for (int i = 0; i < coords.size(); i++) {
TimeInv b = coords.get(i);
result[i] = gridset.getTimeCoord(b.runIdx, 0);
}
return result;
}
@Override
public double[] getOffsetCoords(Gridset gridset) {
List coords = gridset.timeCoordMap.get("forecast" + offset);
if (coords == null)
coords = gridset.makeConstantForecast(offset);
double[] result = new double[coords.size()];
for (int i = 0; i < coords.size(); i++) {
TimeInv b = coords.get(i);
result[i] = b.offset;
}
return result;
}
@Override
public Instance getInstance(Gridset.Grid grid, int timeIdx) {
Gridset gridset = grid.getGridset();
List coords = gridset.timeCoordMap.get("forecast" + offset);
if (coords == null)
coords = gridset.makeConstantForecast(offset);
TimeInv b = coords.get(timeIdx);
return grid.getInstance(b.runIdx, b.timeIdx);
}
}
class ConstantOffsetDataset implements TimeInventory {
double offset;
ConstantOffsetDataset(double offset) throws FileNotFoundException {
this.offset = offset;
boolean ok = false;
double[] offsets = getForecastOffsets();
for (double v : offsets) {
if (Misc.nearlyEquals(v, offset)) {
ok = true;
}
}
if (!ok)
throw new FileNotFoundException("No constant offset dataset for = " + offset);
}
@Override
public String getName() {
return "Constant Offset " + offset + " hours";
}
@Override
public int getTimeLength(Gridset gridset) {
List coords = gridset.timeCoordMap.get("offset" + offset);
if (coords == null)
coords = gridset.makeConstantOffset(offset);
return coords.size();
}
@Override
public FmrcInvLite.ValueB getTimeCoords(Gridset gridset) {
List coords = gridset.timeCoordMap.get("offset" + offset);
if (coords == null)
coords = gridset.makeConstantOffset(offset);
return new FmrcInvLite.ValueB(coords);
}
@Override
public double[] getRunTimeCoords(Gridset gridset) {
List coords = gridset.timeCoordMap.get("offset" + offset);
if (coords == null)
coords = gridset.makeConstantOffset(offset);
double[] result = new double[coords.size()];
for (int i = 0; i < coords.size(); i++) {
TimeInv b = coords.get(i);
result[i] = gridset.getTimeCoord(b.runIdx, 0);
}
return result;
}
@Override
public double[] getOffsetCoords(Gridset gridset) {
return null;
}
@Override
public Instance getInstance(Gridset.Grid grid, int timeIdx) {
Gridset gridset = grid.getGridset();
List coords = gridset.timeCoordMap.get("offset" + offset);
if (coords == null)
coords = gridset.makeConstantOffset(offset);
TimeInv b = coords.get(timeIdx);
return grid.getInstance(b.runIdx, b.timeIdx);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy