cdm/src/main/java/ucar/nc2/Variable.java
public Array read(int[] origin, int[] shape) throws IOException, InvalidRangeException {
    if ((origin == null) && (shape == null))
      return read();

    if (origin == null)
      return read(new Section(shape));

    if (shape == null)
      return read(new Section(origin, this.shape));

    return read(new Section(origin, shape));
  }
public Array read(int[] origin, int[] shape) throws IOException, InvalidRangeException {
    if ((origin == null) && (shape == null))
      return read();

    if (origin == null)
      return read(new Section(shape));

    if (shape == null)
      return read(new Section(origin, this.shape));

    return read(new Section(origin, shape));
  }
Read a section of the data for this Variable and return a memory resident Array.
The Array has the same element type as the Variable, and the requested shape.
Note that this does not do rank reduction, so the returned Array has the same rank
as the Variable. Use Array.reduce() for rank reduction.
<p/>
<code>assert(origin[ii] + shape[ii]*stride[ii] <= Variable.shape[ii]); </code>
<p/>

@param origin int array specifying the starting index. If null, assume all zeroes.
@param shape  int array specifying the extents in each dimension.
This becomes the shape of the returned Array.
@return the requested data in a memory-resident Array