private int findSingleHit(double target) { int hits = 0; int idxFound = -1; int n = axis.getNcoords(); for (int i = 0; i < n; i++) { if (contains(target, i)) { hits++; idxFound = i; } } if (hits == 1) return idxFound; if (hits == 0) return -1; return -hits; }
private int findClosest(double target) { double minDiff = Double.MAX_VALUE; double useValue = Double.MIN_VALUE; int idxFound = -1; for (int i = 0; i < axis.getNcoords(); i++) { double coord = axis.getCoordMidpoint(i); double diff = Math.abs(coord - target); if (diff < minDiff || (diff == minDiff && coord > useValue)) { minDiff = diff; idxFound = i; useValue = coord; } } return idxFound; }
public CoverageCoordAxis1D(CoverageCoordAxisBuilder builder) { super(builder); if (axisType == null && builder.dependenceType == DependenceType.independent) throw new IllegalArgumentException("independent axis must have type"); // make sure range has axisType as the name String rangeName = (axisType != null) ? axisType.toString() : null; if (builder.range != null) { this.range = (rangeName != null) ? builder.range.setName(rangeName) : builder.range; } else { this.range = Range.make(rangeName, getNcoords()); } this.crange = builder.crange; }
private CoordsSet(boolean constantForecast, List<CoverageCoordAxis> axes) { this.constantForecast = constantForecast; List<CoverageCoordAxis1D> indAxes = new ArrayList<>(); int rank = 0; for (CoverageCoordAxis axis : axes) { if (axis.getDependenceType() != CoverageCoordAxis.DependenceType.dependent) // independent or scalar indAxes.add( (CoverageCoordAxis1D) axis); if (axis.getDependenceType() == CoverageCoordAxis.DependenceType.independent) rank++; } this.axes = axes; this.shape = new int[rank]; int count = 0; for (CoverageCoordAxis1D axis : indAxes) { if (axis.getDependenceType() == CoverageCoordAxis.DependenceType.independent) shape[count++] = axis.getNcoords(); } }
public double getCoordEdge2(int index) { if (index < 0 || index >= getNcoords()) throw new IllegalArgumentException("Index out of range=" + index); loadValuesIfNeeded(); switch (spacing) { case regularPoint: if (index < 0 || index >= ncoords) throw new IllegalArgumentException("Index out of range " + index); return startValue + (index + .5) * getResolution(); case regularInterval: return startValue + (index+1) * getResolution(); case irregularPoint: if (index < ncoords - 1) return (values[index] + values[index + 1]) / 2; else return values[index] + (values[index] - values[index - 1]) / 2; case contiguousInterval: return values[index + 1]; case discontiguousInterval: return values[2 * index + 1]; } throw new IllegalStateException("Unknown spacing=" + spacing); }
public double getCoordEdge1(int index) { if (index < 0 || index >= getNcoords()) throw new IllegalArgumentException("Index out of range=" + index); loadValuesIfNeeded(); switch (spacing) { case regularPoint: return startValue + (index - .5) * getResolution(); case regularInterval: return startValue + index * getResolution(); case irregularPoint: if (index > 0) return (values[index - 1] + values[index]) / 2; else return values[0] - (values[1] - values[0]) / 2; case contiguousInterval: return values[index]; case discontiguousInterval: return values[2 * index]; } throw new IllegalStateException("Unknown spacing=" + spacing); }
@Override public int[] getShape() { if (runAxis.isScalar()) return new int[] {timeOffset.getNcoords()}; else return new int[] {runAxis.getNcoords(), timeOffset.getNcoords()}; }
@Override public String getSummary() { if (axisType != AxisType.RunTime) return super.getSummary(); if (ncoords < 7) { Formatter f = new Formatter(); for (int i = 0; i < ncoords; i++) { CalendarDate cd = makeDate(getCoordMidpoint(i)); if (i > 0) f.format(", "); f.format("%s", cd); } return f.toString(); } Formatter f = new Formatter(); CalendarDate start = makeDate(getStartValue()); f.format("start=%s", start); CalendarDate end = makeDate(getEndValue()); f.format(", end=%s", end); f.format(" (npts=%d spacing=%s)", getNcoords(), getSpacing()); return f.toString(); }
@Nonnull private CoverageCoordAxisBuilder subsetValuesLatest() { int last = axis.getNcoords() - 1; double val = axis.getCoordMidpoint(last); CoverageCoordAxisBuilder builder = new CoverageCoordAxisBuilder(axis); builder.subset(1, val, val, 0.0, makeValues(last)); try { builder.setRange(new Range(last, last)); } catch (InvalidRangeException e) { throw new RuntimeException(e); // cant happen } return builder; }
public double getCoordMidpoint(int index) { if (index < 0 || index >= getNcoords()) throw new IllegalArgumentException("Index out of range=" + index); loadValuesIfNeeded(); switch (spacing) { case regularPoint: return startValue + index * getResolution(); case irregularPoint: return values[index]; case regularInterval: return startValue + (index + .5) * getResolution(); case contiguousInterval: case discontiguousInterval: return (getCoordEdge1(index) + getCoordEdge2(index)) / 2; } throw new IllegalStateException("Unknown spacing=" + spacing); }
private int findCoordElementDiscontiguousInterval(double[] target, boolean bounded) { for (int i = 0; i < axis.getNcoords(); i++) { double edge1 = axis.getCoordEdge1(i); double edge2 = axis.getCoordEdge2(i); if (Misc.nearlyEquals(edge1, target[0]) && Misc.nearlyEquals(edge2, target[1])) return i; } return -1; }
public Optional<RangeIterator> makeRange(double minValue, double maxValue, int stride) { //if (axis.getSpacing() == CoverageCoordAxis.Spacing.discontiguousInterval) // return subsetValuesDiscontinuous(minValue, maxValue, stride); double lower = axis.isAscending() ? Math.min(minValue, maxValue) : Math.max(minValue, maxValue); double upper = axis.isAscending() ? Math.max(minValue, maxValue) : Math.min(minValue, maxValue); int minIndex = findCoordElement(lower, false); int maxIndex = findCoordElement(upper, false); if (minIndex >= axis.getNcoords()) return Optional.empty(String.format("no points in subset: lower %f > end %f", lower, axis.getEndValue())); if (maxIndex < 0) return Optional.empty(String.format("no points in subset: upper %f < start %f", upper, axis.getStartValue())); if (minIndex < 0) minIndex = 0; if (maxIndex >= axis.getNcoords()) maxIndex = axis.getNcoords() - 1; int count = maxIndex - minIndex + 1; if (count <= 0) return Optional.empty("no points in subset"); try { return Optional.of(new Range(minIndex, maxIndex, stride)); } catch (InvalidRangeException e) { return Optional.empty(e.getMessage()); } }
public CoverageCoordAxis1D getTimeAxisForRun(CalendarDate rundate) { double rundateTarget = runCoord.convert(rundate); int run_index = new CoordAxisHelper(runCoord).findCoordElement(rundateTarget, false); // LOOK not Bounded return (run_index < 0 || run_index >= runCoord.getNcoords()) ? null : getTimeAxisForRun(run_index); }
private Optional<CoverageCoordAxisBuilder> subsetValues(double minValue, double maxValue, int stride) { if (axis.getSpacing() == CoverageCoordAxis.Spacing.discontiguousInterval) return subsetValuesDiscontinuous(minValue, maxValue, stride); double lower = axis.isAscending() ? Math.min(minValue, maxValue) : Math.max(minValue, maxValue); double upper = axis.isAscending() ? Math.max(minValue, maxValue) : Math.min(minValue, maxValue); int minIndex = findCoordElement(lower, false); int maxIndex = findCoordElement(upper, false); if (minIndex >= axis.getNcoords()) return Optional.empty(String.format("no points in subset: lower %f > end %f", lower, axis.getEndValue())); if (maxIndex < 0) return Optional.empty(String.format("no points in subset: upper %f < start %f", upper, axis.getStartValue())); if (minIndex < 0) minIndex = 0; if (maxIndex >= axis.getNcoords()) maxIndex = axis.getNcoords() - 1; int count = maxIndex - minIndex + 1; if (count <= 0) throw new IllegalArgumentException("no points in subset"); try { return Optional.of(subsetByIndex(new Range(minIndex, maxIndex, stride))); } catch (InvalidRangeException e) { return Optional.empty(e.getMessage()); } }
int search(double want) { if (axis.getNcoords() == 1) { return Misc.nearlyEquals(want, axis.getStartValue()) ? 0 : -1; } if (axis.isRegular()) { double fval = (want - axis.getStartValue()) / axis.getResolution(); double ival = Math.rint(fval); return Misc.nearlyEquals(fval, ival) ? (int) ival : (int) -ival - 1; // LOOK } // otherwise do a binary search return Arrays.binarySearch(axis.getValues(), want); } }
Optional<CoverageCoordAxisBuilder> subsetContaining(double want) { int index = findCoordElement(want, false); // not bounded, may not be valid index if (index < 0 || index >= axis.getNcoords()) return Optional.empty(String.format("value %f not in axis %s", want, axis.getName())); double val = axis.getCoordMidpoint(index); CoverageCoordAxisBuilder builder = new CoverageCoordAxisBuilder(axis); builder.subset(1, val, val, 0.0, makeValues(index)); try { builder.setRange(new Range(index, index)); } catch (InvalidRangeException e) { throw new RuntimeException(e); // cant happen } return Optional.of(builder); }
public List<NamedObject> getCoordValueNames(CoverageCoordAxis1D axis) { axis.loadValuesIfNeeded(); List<NamedObject> result = new ArrayList<>(); for (int i = 0; i < axis.getNcoords(); i++) { double value; switch (axis.getSpacing()) { case regularPoint: case irregularPoint: value = axis.getCoordMidpoint(i); result.add(new NamedAnything(makeDate(value), axis.getAxisType().toString())); break; case regularInterval: case contiguousInterval: case discontiguousInterval: CoordInterval coord = new CoordInterval(axis.getCoordEdge1(i), axis.getCoordEdge2(i), 3); result.add(new NamedAnything(coord, coord + " " + axis.getUnits())); break; } } return result; }
private int findCoordElementRegular(double coordValue, boolean bounded) { int n = axis.getNcoords(); if (n == 1 && bounded) return 0; double distance = coordValue - axis.getCoordEdge1(0); double exactNumSteps = distance / axis.getResolution(); //int index = (int) Math.round(exactNumSteps); // ties round to +Inf int index = (int) exactNumSteps; // truncate down if (bounded && index < 0) return 0; if (bounded && index >= n) return n - 1; // check that found point is within interval if (index >= 0 && index < n) { double lower = axis.getCoordEdge1(index); double upper = axis.getCoordEdge2(index); if (axis.isAscending()) { assert lower <= coordValue : lower + " should be le " + coordValue; assert upper >= coordValue : upper + " should be ge " + coordValue; } else { assert lower >= coordValue : lower + " should be ge " + coordValue; assert upper <= coordValue : upper + " should be le " + coordValue; } } return index; }
Assert.assertEquals(1, time.getNcoords()); CalendarDate date = time.makeDate(time.getCoordMidpoint(0)); logger.debug("date = {}", date); Assert.assertEquals(1, vert.getNcoords()); double vertCoord = vert.getCoordMidpoint(0); logger.debug("date = {}", date);
@Override public Optional<CoverageCoordAxis> subset(SubsetParams params) { if (params == null) return Optional.of(new TimeAxis2DFmrc(new CoverageCoordAxisBuilder(this))); CalendarDate rundate = (CalendarDate) params.get(SubsetParams.runtime); boolean runtimeAll = (Boolean) params.get(SubsetParams.runtimeAll); boolean latest = (rundate == null) && !runtimeAll; // default is latest int run_index = -1; if (latest) { run_index = runCoord.getNcoords() - 1; } else if (rundate != null){ double rundateTarget = runCoord.convert(rundate); CoordAxisHelper helper = new CoordAxisHelper(runCoord); run_index = helper.findCoordElement(rundateTarget, true); // LOOK Bounded } if (run_index >= 0) { CoverageCoordAxis1D time1D = getTimeAxisForRun(run_index); return time1D.subset(params); } // no subsetting needed return Optional.of(new TimeAxis2DFmrc(new CoverageCoordAxisBuilder(this))); }