cdm/src/main/java/ucar/nc2/ft2/coverage/CoverageCoordAxis1D.java
protected Optional<CoverageCoordAxisBuilder> subsetBuilder(SubsetParams params) {
    if (params == null)
      return Optional.of(new CoverageCoordAxisBuilder(this));

    CoordAxisHelper helper = new CoordAxisHelper(this);

    switch (getAxisType()) {
      case GeoZ:
      case Pressure:
      case Height:
        Double dval = params.getVertCoord();
        if (dval != null)
          return Optional.of(helper.subsetClosest(dval));
        // use midpoint of interval LOOK may not always be unique
        double[] intv = params.getVertCoordIntv();
        if (intv != null)
          return Optional.of(helper.subsetClosest((intv[0]+intv[1])/2));

        double[] vertRange = params.getVertRange(); // used by WCS
        if (vertRange != null)
          return helper.subset(vertRange[0], vertRange[1], 1);

        // default is all
        break;

      case Ensemble:
        Double eval = params.getDouble(SubsetParams.ensCoord);
        if (eval != null) {
          return Optional.of(helper.subsetClosest(eval));
        }
        // default is all
        break;

      // x,y get seperately subsetted
      case GeoX:
      case GeoY:
      case Lat:
      case Lon:
        throw new IllegalArgumentException();
        // return null; // LOOK heres a case where null is "correct"

      case Time:
        if (params.isTrue(SubsetParams.timePresent))
          return Optional.of(helper.subsetLatest());

        CalendarDate date = (CalendarDate) params.get(SubsetParams.time);
        if (date != null)
          return Optional.of(helper.subsetClosest(date));

        Integer stride = (Integer) params.get(SubsetParams.timeStride);
        if (stride == null || stride < 0) stride = 1;

        CalendarDateRange dateRange = (CalendarDateRange) params.get(SubsetParams.timeRange);
        if (dateRange != null)
          return helper.subset(dateRange, stride);

        // If no time range or time point, a timeOffset can be used to specify the time point.
        /* CalendarDate timeOffsetDate = params.getTimeOffsetDate();
        if (timeOffsetDate != null) {
          return Optional.of(helper.subsetClosest(timeOffsetDate));
        } */

        // A time offset or time offset interval starts from the rundate of the offset
        Double timeOffset = params.getTimeOffset();
        CalendarDate runtime = params.getRunTime();
        if (timeOffset != null) {
          if (runtime != null) {
            date = makeDateInTimeUnits(runtime, timeOffset);
            return Optional.of(helper.subsetClosest(date));
          } else {
            return Optional.of(helper.subsetClosest(timeOffset));
          }
        }

        // If a time interval is sent, search for match.
        double[] timeOffsetIntv = params.getTimeOffsetIntv();
        if (timeOffsetIntv != null && runtime != null) {
          // double midOffset = (timeOffsetIntv[0] + timeOffsetIntv[1]) / 2;
          CalendarDate[] dateIntv = new CalendarDate[2];
          dateIntv[0] = makeDateInTimeUnits(runtime, timeOffsetIntv[0]);
          dateIntv[1] = makeDateInTimeUnits(runtime, timeOffsetIntv[1]);
          return Optional.of(helper.subsetClosest(dateIntv));
        }

        if (stride != 1)
          try {
            return Optional.of(helper.subsetByIndex(getRange().setStride(stride)));
          } catch (InvalidRangeException e) {
            return Optional.empty(e.getMessage());
          }

        // default is all
        break;

      case RunTime:
        CalendarDate rundate = (CalendarDate) params.get(SubsetParams.runtime);
        if (rundate != null)
          return Optional.of(helper.subsetClosest(rundate));

/*        CalendarDateRange rundateRange = (CalendarDateRange) params.get(SubsetParams.runtimeRange);
        if (rundateRange != null)
          return helper.subset(rundateRange, 1); */

        if (params.isTrue(SubsetParams.runtimeAll))
          break;

        // default is latest
        return Optional.of(helper.subsetLatest());

      case TimeOffset:
        Double oval = params.getDouble(SubsetParams.timeOffset);
        if (oval != null) {
          return Optional.of(helper.subsetClosest(oval));
        }

        // If a time interval is sent, search for match.
        timeOffsetIntv = params.getTimeOffsetIntv();
        if (timeOffsetIntv != null) {
          return Optional.of(helper.subsetClosest((timeOffsetIntv[0]+timeOffsetIntv[1])/2));
        }


        if (params.isTrue(SubsetParams.timeOffsetFirst)) {
          try {
            return Optional.of(helper.subsetByIndex(new Range(1)));
          } catch (InvalidRangeException e) {
            return Optional.empty(e.getMessage());
          }
        }
        // default is all
        break;
    }

    // otherwise return copy the original axis
    return Optional.of(new CoverageCoordAxisBuilder(this));
  }
protected Optional<CoverageCoordAxisBuilder> subsetBuilder(SubsetParams params) {
    if (params == null)
      return Optional.of(new CoverageCoordAxisBuilder(this));

    CoordAxisHelper helper = new CoordAxisHelper(this);

    switch (getAxisType()) {
      case GeoZ:
      case Pressure:
      case Height:
        Double dval = params.getVertCoord();
        if (dval != null)
          return Optional.of(helper.subsetClosest(dval));
        // use midpoint of interval LOOK may not always be unique
        double[] intv = params.getVertCoordIntv();
        if (intv != null)
          return Optional.of(helper.subsetClosest((intv[0]+intv[1])/2));

        double[] vertRange = params.getVertRange(); // used by WCS
        if (vertRange != null)
          return helper.subset(vertRange[0], vertRange[1], 1);

        // default is all
        break;

      case Ensemble:
        Double eval = params.getDouble(SubsetParams.ensCoord);
        if (eval != null) {
          return Optional.of(helper.subsetClosest(eval));
        }
        // default is all
        break;

      // x,y get seperately subsetted
      case GeoX:
      case GeoY:
      case Lat:
      case Lon:
        throw new IllegalArgumentException();
        // return null; // LOOK heres a case where null is "correct"

      case Time:
        if (params.isTrue(SubsetParams.timePresent))
          return Optional.of(helper.subsetLatest());

        CalendarDate date = (CalendarDate) params.get(SubsetParams.time);
        if (date != null)
          return Optional.of(helper.subsetClosest(date));

        Integer stride = (Integer) params.get(SubsetParams.timeStride);
        if (stride == null || stride < 0) stride = 1;

        CalendarDateRange dateRange = (CalendarDateRange) params.get(SubsetParams.timeRange);
        if (dateRange != null)
          return helper.subset(dateRange, stride);

        // If no time range or time point, a timeOffset can be used to specify the time point.
        /* CalendarDate timeOffsetDate = params.getTimeOffsetDate();
        if (timeOffsetDate != null) {
          return Optional.of(helper.subsetClosest(timeOffsetDate));
        } */

        // A time offset or time offset interval starts from the rundate of the offset
        Double timeOffset = params.getTimeOffset();
        CalendarDate runtime = params.getRunTime();
        if (timeOffset != null) {
          if (runtime != null) {
            date = makeDateInTimeUnits(runtime, timeOffset);
            return Optional.of(helper.subsetClosest(date));
          } else {
            return Optional.of(helper.subsetClosest(timeOffset));
          }
        }

        // If a time interval is sent, search for match.
        double[] timeOffsetIntv = params.getTimeOffsetIntv();
        if (timeOffsetIntv != null && runtime != null) {
          // double midOffset = (timeOffsetIntv[0] + timeOffsetIntv[1]) / 2;
          CalendarDate[] dateIntv = new CalendarDate[2];
          dateIntv[0] = makeDateInTimeUnits(runtime, timeOffsetIntv[0]);
          dateIntv[1] = makeDateInTimeUnits(runtime, timeOffsetIntv[1]);
          return Optional.of(helper.subsetClosest(dateIntv));
        }

        if (stride != 1)
          try {
            return Optional.of(helper.subsetByIndex(getRange().setStride(stride)));
          } catch (InvalidRangeException e) {
            return Optional.empty(e.getMessage());
          }

        // default is all
        break;

      case RunTime:
        CalendarDate rundate = (CalendarDate) params.get(SubsetParams.runtime);
        if (rundate != null)
          return Optional.of(helper.subsetClosest(rundate));

/*        CalendarDateRange rundateRange = (CalendarDateRange) params.get(SubsetParams.runtimeRange);
        if (rundateRange != null)
          return helper.subset(rundateRange, 1); */

        if (params.isTrue(SubsetParams.runtimeAll))
          break;

        // default is latest
        return Optional.of(helper.subsetLatest());

      case TimeOffset:
        Double oval = params.getDouble(SubsetParams.timeOffset);
        if (oval != null) {
          return Optional.of(helper.subsetClosest(oval));
        }

        // If a time interval is sent, search for match.
        timeOffsetIntv = params.getTimeOffsetIntv();
        if (timeOffsetIntv != null) {
          return Optional.of(helper.subsetClosest((timeOffsetIntv[0]+timeOffsetIntv[1])/2));
        }


        if (params.isTrue(SubsetParams.timeOffsetFirst)) {
          try {
            return Optional.of(helper.subsetByIndex(new Range(1)));
          } catch (InvalidRangeException e) {
            return Optional.empty(e.getMessage());
          }
        }
        // default is all
        break;
    }

    // otherwise return copy the original axis
    return Optional.of(new CoverageCoordAxisBuilder(this));
  }
LOOK  incomplete handling of subsetting params