public static CEConstraint getUniversal(DapDataset dmr) {
   CEConstraint u = universals.get(dmr);
   if (u == null) {
     try {
       u = new Universal(dmr);
       universals.put(dmr, u);
     } catch (DapException de) {
       throw new IllegalArgumentException("DapDataSet has no universal");
     }
   }
   return u;
 }
  /**
   * Compute dimension related information using slicing and redef info. In effect, this is where
   * projection constraints are applied
   *
   * <p>Assume that the constraint compiler has given us the following info:
   *
   * <ol>
   *   <li>A list of the variables to include.
   *   <li>A pair (DapDimension,Slice) for each redef
   *   <li>For each variable in #1, a list of slices taken from the constraint expression
   * </ol>
   *
   * <p>Two products will be produced.
   *
   * <ol>
   *   <li>The variables map will be modified so that the slices properly reflect any original or
   *       redef dimensions.
   *   <li>A set, dimrefs, of all referenced original dimensions.
   * </ol>
   *
   * <p>The processing is as follows
   *
   * <ol>
   *   <li>For each redef create a new redef dimension
   *   <li>For each variable:
   *       <ol>
   *         <li>if the variable is scalar, do nothing.
   *         <li>if the variable has no associated slices, then make its new dimensions be the
   *             original dimensions.
   *         <li>otherwise, walk the slices and create new dimensions from them; use redefs where
   *             indicated
   *         <li>
   *       </ol>
   * </ol>
   */
  protected void computedimensions() throws DapException {
    // Build the redefmap
    for (DapDimension key : redefslice.keySet()) {
      Slice slice = redefslice.get(key);
      DapDimension newdim = (DapDimension) key.clone();
      newdim.setSize(slice.getCount());
      redef.put(key, newdim);
    }

    // Process each variable
    for (int i = 0; i < segments.size(); i++) {
      Segment seg = segments.get(i);
      if (seg.var.getRank() == 0) continue;
      List<Slice> slices = seg.slices;
      List<DapDimension> orig = seg.var.getDimensions();
      List<DapDimension> newdims = new ArrayList<>();
      // If the slice list is short then pad it with
      // default slices
      if (slices == null) slices = new ArrayList<Slice>();
      while (slices.size() < orig.size()) // pad
      {
        slices.add(new Slice().setConstrained(false));
      }
      assert (slices != null && slices.size() == orig.size());
      for (int j = 0; j < slices.size(); j++) {
        Slice slice = slices.get(j);
        DapDimension dim0 = orig.get(j);
        DapDimension newdim = redef.get(dim0);
        if (newdim == null) newdim = dim0;
        // fill in the undefined last value
        slice.setMaxSize(newdim.getSize());
        slice.finish();

        Slice newslice = null;
        if (slice.isConstrained()) {
          // Construct an anonymous dimension for this slice
          newdim = new DapDimension(slice.getCount());
        } else { // replace with a new slice from the dim
          newslice = new Slice(newdim);
          if (newslice != null) {
            // track set of referenced non-anonymous dimensions
            if (!dimrefs.contains(dim0)) dimrefs.add(dim0);
            slices.set(j, newslice);
          }
        }
        // record the dimension per variable
        newdims.add(newdim);
      }
      seg.setDimset(newdims);
    }
  }
 public DapDimension getRedefDim(DapDimension orig) {
   return redef.get(orig);
 }
 public static void release(DapDataset dmr) {
   universals.remove(dmr);
 }