예제 #1
0
 def __init__(self, data, typecode=None, copy=0, savespace=0, mask=None, fill_value=None,
              axes=None, attributes=None, id=None, copyaxes=1, bounds=None):
     """Create a transient 2D axis.
     All arguments are as for TransientVariable.
     'bounds' is the bounds array, having shape (m,n,nvert) where data.shape is (m,n) and
       nvert is the max number of vertices per cell.
     """
     AbstractAxis2D.__init__(self, None, None, bounds=bounds)
     TransientVariable.__init__(self, data, typecode=typecode, copy=copy, savespace=savespace,
                                mask=mask, fill_value=fill_value, axes=axes, attributes=attributes,
                                id=id, copyaxes=copyaxes)
     if axes is not None:
         self.setBounds(bounds)
예제 #2
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def average (a, axis=None, weights=None, returned=False):
    axis = _conv_axis_arg(axis)
    ta = _makeMaskedArg(a)
    maresult = numpy.ma.average(ta, axis, weights, returned)
    axes, attributes, id, grid = _extractMetadata(a, omit=axis, omitall=(axis is None))
    if returned: maresult, wresult = maresult
    F=getattr(a,"fill_value",1.e20)
    r1 = TransientVariable(maresult, axes=axes, attributes=attributes, grid=grid, id=id,no_update_from=True, fill_value=F)
    if returned:
        F=getattr(a,"fill_value",1.e20)
        w1 = TransientVariable(wresult, axes=axes, grid=grid, id=id,no_update_from=True, fill_value=F)
        return r1, w1
    else:
        return r1
예제 #3
0
def outerproduct(a, b):
    """outerproduct(a,b) = {a[i]*b[j]}, has shape (len(a),len(b))"""
    ta = asVariable(a, writeable=1)
    tb = asVariable(b, writeable=1)
    maresult = numpy.ma.outerproduct(ta, tb)
    axes = (ta.getAxis(0), tb.getAxis(0))
    return TransientVariable(maresult, axes=axes)
예제 #4
0
def masked_values(data,
                  value,
                  rtol=1.e-5,
                  atol=1.e-8,
                  copy=1,
                  savespace=0,
                  axes=None,
                  attributes=None,
                  id=None):
    """
       masked_values(data, value, rtol=1.e-5, atol=1.e-8)
       Create a masked array; mask is None if possible.
       May share data values with original array, but not recommended.
       Masked where abs(data-value)<= atol + rtol * abs(value)
    """
    maresult = numpy.ma.masked_values(_makeMaskedArg(data),
                                      value,
                                      rtol=rtol,
                                      atol=atol,
                                      copy=copy)
    axes, attributes, id, grid = _extractMetadata(data, axes, attributes, id)
    F = getattr(data, "fill_value", 1.e20)
    return TransientVariable(maresult,
                             axes=axes,
                             attributes=attributes,
                             id=id,
                             grid=grid,
                             fill_value=F)
예제 #5
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def power (a, b, third=None):
    "a**b"
    ta = _makeMaskedArg(a)
    tb = _makeMaskedArg(b)
    maresult = numpy.ma.power(ta,tb,third)
    axes, attributes, id, grid = _extractMetadata(a)
    return TransientVariable(maresult, axes=axes, attributes=attributes, grid=grid, id=id)
예제 #6
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def right_shift (a, n):
    "Right shift n bits"
    ta = _makeMaskedArg(a)
    tb = _makeMaskedArg(n)
    maresult = numpy.ma.right_shift(ta,numpy.ma.filled(tb))
    axes, attributes, id, grid = _extractMetadata(a)
    return TransientVariable(maresult, axes=axes, attributes=attributes, grid=grid, id=id)
예제 #7
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def masked_inside(x, v1, v2):
    "x with mask of all values of x that are inside [v1,v2]"
    tx = _makeMaskedArg(x)
    maresult = numpy.ma.masked_inside(tx, v1, v2)
    axes, attributes, id, grid = _extractMetadata(x)
    F=getattr(x,"fill_value",1.e20)
    return TransientVariable(maresult, axes=axes, attributes=attributes, id=id, grid=grid, fill_value=F)
예제 #8
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def masked_not_equal(x, value):
    "masked_not_equal(x, value) = x masked where x != value"
    tx = _makeMaskedArg(x)
    maresult = numpy.ma.masked_not_equal(tx, value)
    axes, attributes, id, grid = _extractMetadata(x)
    F=getattr(x,"fill_value",1.e20)
    return TransientVariable(maresult, axes=axes, attributes=attributes, id=id, grid=grid, fill_value=F)
예제 #9
0
def compress(a, b):
    __doc__ = numpy.ma.__doc__
    import warnings
    warnings.warn(
        "arguments order for compress function has changed\nit is now: MV2.copmress(array,condition), if your code seems to not react or act wrong to a call to compress, please check this",
        Warning)
    return TransientVariable(numpy.ma.compress(a, b), copy=1)
예제 #10
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def diagonal (a, offset = 0, axis1=0, axis2 = 1):
    """diagonal(a, offset=0, axis1=0, axis2 = 1) returns the given 
       diagonals defined by the two dimensions of the array.
    """
    F=getattr(a,"fill_value",1.e20)
    return TransientVariable(numpy.ma.diagonal(_makeMaskedArg(a), 
            offset, axis1, axis2), fill_value=F)
예제 #11
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def product (a, axis = 0, dtype=None):
    "Product of elements along axis."
    ta = _makeMaskedArg(a)
    maresult = numpy.ma.product(ta, axis, dtype=dtype)
    axes, attributes, id, grid = _extractMetadata(a, omit=axis)
    F=getattr(a,"fill_value",1.e20)
    return TransientVariable(maresult, axes=axes, attributes=attributes, grid=grid, id=id, fill_value=F)
예제 #12
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def sum (a, axis = None, fill_value=0, dtype=None):
    "Sum of elements along a certain axis."
    axis = _conv_axis_arg(axis)
    ta = _makeMaskedArg(a)
    maresult = numpy.ma.sum(ta, axis, dtype=dtype)
    axes, attributes, id, grid = _extractMetadata(a, omit=axis, omitall=(axis is None))
    F=getattr(a,"fill_value",1.e20)
    return TransientVariable(maresult, axes=axes, attributes=attributes, grid=grid, id=id, fill_value=F)
예제 #13
0
 def __call__(self, a):
     axes, attributes, id, grid = _extractMetadata(a)
     maresult = self.mafunc(_makeMaskedArg(a))
     return TransientVariable(maresult,
                              axes=axes,
                              attributes=attributes,
                              id=id,
                              grid=grid)
예제 #14
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def where (condition, x, y):
    "where(condition, x, y) is x where condition is true, y otherwise" 
##    axes = commonDomain(x,y)
##    grid = commonGrid(x,y,axes)
    maresult = numpy.ma.where(condition, _makeMaskedArg(x), _makeMaskedArg(y))
    axes, attributes, id, grid = _extractMetadata(condition)
    F=getattr(x,"fill_value",1.e20)
    return TransientVariable(maresult, axes=axes, attributes=attributes, grid=grid, id=id, fill_value=F)
예제 #15
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def min (a, axis=None):
    axis = _conv_axis_arg(axis)
    ta = _makeMaskedArg(a)
    maresult = numpy.ma.min(ta, axis)
    axes, attributes, id, grid = _extractMetadata(a, omit=axis, omitall=(axis is None))
    F=getattr(a,"fill_value",1.e20)
    r1 = TransientVariable(maresult, axes=axes, attributes=attributes, grid=grid, id=id,no_update_from=True, fill_value=F)
    return r1
예제 #16
0
def concatenate(arrays, axis=0, axisid=None, axisattributes=None):
    """Concatenate the arrays along the given axis. Give the extended axis the id and
    attributes provided - by default, those of the first array."""

    tarrays = [_makeMaskedArg(a) for a in arrays]
    maresult = numpy.ma.concatenate(arrays, axis=axis)
    if len(arrays) > 1:
        varattributes = None
        varid = None
        axes = commonDomain(tarrays[0], tarrays[1], omit=axis)
        grid = commonGrid(tarrays[0], tarrays[1], axes)
        for i in range(len(arrays) - 2):
            if axes is None:
                break
            axes = commonAxes(tarrays[i + 2], axes, omit=axis)
            grid = commonGrid1(a, grid, axes)
    else:
        axes = tarrays[0].getAxisList()
        varattributes = tarrays[0].attributes
        varid = tarrays[0].id
        if (isinstance(tarrays[0], TransientVariable)):
            grid = tarrays[0].getGrid()
        else:
            grid = None
    if axes is not None:
        if axisid is None:
            axisid = tarrays[0].getAxis(axis).id
        allunitsequal = True
        try:
            allunits = tarrays[0].getAxis(axis).units
        except:
            allunits = None
        for t in tarrays[1:]:
            try:
                tunits = t.getAxis(axis).units
            except:
                tunits = None
            if tunits != allunits:
                allunitsequal = False
        if allunitsequal:
            if axisattributes is None:
                axisattributes = tarrays[0].getAxis(axis).attributes
            axes[axis] = axisConcatenate([t.getAxis(axis) for t in tarrays],
                                         axisid, axisattributes)

    # If the grid doesn't match the axislist (e.g., catenation was on latitude) then omit it.
    if grid is not None:
        for item in grid.getAxisList():
            if item not in axes:
                grid = None
    F = getattr(arrays[0], "fill_value", 1.e20)
    return TransientVariable(maresult,
                             axes=axes,
                             attributes=varattributes,
                             id=varid,
                             grid=grid,
                             fill_value=F)
예제 #17
0
 def accumulate(self, target, axis=0):
     ttarget = _makeMaskedArg(target)
     maresult = self.mafunc.accumulate(ttarget, axis=axis)
     axes, attributes, id, grid = _extractMetadata(target, omit=axis)
     return TransientVariable(maresult,
                              axes=axes,
                              attributes=attributes,
                              id=id,
                              grid=grid)
예제 #18
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
 def __call__ (self, a, b):
     id = "variable_%i" % TransientVariable.variable_count
     TransientVariable.variable_count+=1
     axes = commonDomain(a,b)
     grid = commonGrid(a,b,axes)
     ta = _makeMaskedArg(a)
     tb = _makeMaskedArg(b)
     maresult = self.mafunc(ta,tb)
     return TransientVariable(maresult, axes=axes, grid=grid,no_update_from=True,id=id)
예제 #19
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def masked_equal(x, value):
    """masked_equal(x, value) = x masked where x == value
       For floating point consider masked_values(x, value) instead.
    """
    tx = _makeMaskedArg(x)
    maresult = numpy.ma.masked_equal(tx, value)
    axes, attributes, id, grid = _extractMetadata(x)
    F=getattr(x,"fill_value",1.e20)
    return TransientVariable(maresult, axes=axes, attributes=attributes, id=id, grid=grid, fill_value=F)
예제 #20
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def masked_array (a, mask=None, fill_value=None, axes=None, attributes=None, id=None):
    """masked_array(a, mask=None) = 
       array(a, mask=mask, copy=0, fill_value=fill_value)
       Use fill_value(a) if None.
    """
    maresult = numpy.ma.masked_array(_makeMaskedArg(a), mask=mask, fill_value=fill_value)
    axes, attributes, id, grid = _extractMetadata(a, axes, attributes, id)
    F=getattr(a,"fill_value",1.e20)
    return TransientVariable(maresult, axes=axes, attributes=attributes, id=id, grid=grid, fill_value=F)
예제 #21
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def reshape (a, newshape, axes=None, attributes=None, id=None, grid=None):
    ignore, attributes, id, ignore = _extractMetadata(a, axes, attributes, id)
    if axes is not None:
        axesshape = [len(item) for item in axes]
        if axesshape!=list(newshape):
            raise CDMSError, 'axes must be shaped %s'%`newshape`
    ta = _makeMaskedArg(a)
    maresult = numpy.ma.reshape(ta, newshape)
    F=getattr(a,"fill_value",1.e20)
    return TransientVariable(maresult, axes=axes, attributes=attributes, id=id, grid=grid, no_update_from=True, fill_value=F)
예제 #22
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def argsort (x, axis = -1, fill_value=None):
    """Treating masked values as if they have the value fill_value,
       return sort indices for sorting along given axis.
       if fill_value is None, use fill_value(x)
    """        
    tx = _makeMaskedArg(x)
    maresult = numpy.ma.argsort(tx,axis=axis,fill_value=fill_value)
    axes, attributes, id, grid = _extractMetadata(x)
    F=getattr(x,"fill_value",1.e20)
    return TransientVariable(maresult, axes=axes, attributes=attributes, id=id, grid=grid, fill_value=F)
예제 #23
0
def choose(indices, t):
    """Returns an array shaped like indices containing elements chosen
      from t.
      If an element of t is the special element masked, any element
      of the result that "chooses" that element is masked.

      The result has only the default axes.
    """
    maresult = numpy.ma.choose(indices, map(_makeMaskedArg, t))
    return TransientVariable(maresult)
예제 #24
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def masked_where(condition, x, copy=1):
    """Return x as an array masked where condition is true. 
       Also masked where x or condition masked.
    """
    tx = _makeMaskedArg(x)
    tcondition = _makeMaskedArg(condition)
    maresult = numpy.ma.masked_where(tcondition, tx, copy)
    axes, attributes, id, grid = _extractMetadata(x)
    F=getattr(x,"fill_value",1.e20)
    return TransientVariable(maresult, axes=axes, attributes=attributes, id=id, grid=grid, fill_value=F)
예제 #25
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def count (a, axis = None):
    "Count of the non-masked elements in a, or along a certain axis."   
    if axis is None:
        return numpy.ma.count(a,axis)
    else:
        ta = _makeMaskedArg(a)
        maresult = numpy.ma.count(ta,axis)
        axes, attributes, id, grid = _extractMetadata(a,omit=axis)
        F=getattr(a,"fill_value",1.e20)
        return TransientVariable(maresult, axes=axes, attributes=attributes, grid=grid, id=id, fill_value=F)
예제 #26
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def sort (a, axis=-1):
    ta = _makeMaskedArg(a)
    maresult = numpy.ma.sort(a.asma(), axis)
    axes, attributes, id, grid = _extractMetadata(a)
    sortaxis = axes[axis]
    if (grid is not None) and (sortaxis in grid.getAxisList()):
        grid = None
    axes[axis] = TransientAxis(numpy.arange(len(sortaxis)))
    F=getattr(a,"fill_value",1.e20)
    return TransientVariable(maresult, axes=axes, attributes=attributes, grid=grid, id=id, fill_value=F)
예제 #27
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def arrayrange(start, stop=None, step=1, typecode=None, axis=None, attributes=None, id=None, dtype=None):
    """Just like range() except it returns a variable whose type can be specfied
    by the keyword argument typecode. The axis of the result variable may be specified.
    """
    dtype = _convdtype(dtype, typecode)
    if stop is None:
        maresult = numpy.ma.arange(start, step=step, dtype=dtype)
    else:
        maresult = numpy.ma.arange(start, stop=stop, step=step, dtype=dtype)
    return TransientVariable(maresult, axes=(axis,), attributes=attributes, id=id)
예제 #28
0
def masked_outside(x, v1, v2):
    "x with mask of all values of x that are outside [v1,v2]"
    tx = _makeMaskedArg(x)
    maresult = numpy.ma.masked_outside(tx, v1, v2)
    axes, attributes, id, grid = _extractMetadata(x)
    return TransientVariable(maresult,
                             axes=axes,
                             attributes=attributes,
                             id=id,
                             grid=grid)
예제 #29
0
def masked_less_equal(x, value):
    "masked_less_equal(x, value) = x masked where x <= value"
    tx = _makeMaskedArg(x)
    maresult = numpy.ma.masked_less_equal(tx, value)
    axes, attributes, id, grid = _extractMetadata(x)
    return TransientVariable(maresult,
                             axes=axes,
                             attributes=attributes,
                             id=id,
                             grid=grid)
예제 #30
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def asarray(data, typecode=None, dtype=None):
    """asarray(data, typecode=None, dtype=None) is equivalent to array(data, dtype=None, copy=0)
       Returns data if dtype is None or data is a MaskedArray of the same dtype.
       typecode arg is for backward compatibility.
    """
    dtype = _convdtype(dtype, typecode)
    if isinstance(data, AbstractVariable) and (dtype is None or sctype2char(dtype) == data.dtype.char):
        return data
    else:
        F=getattr(data,"fill_value",1.e20)
        return TransientVariable(data, dtype=dtype, copy=0, fill_value=F)
예제 #31
0
파일: MV2.py 프로젝트: NCPP/uvcdat-devel
def resize (a, new_shape, axes=None, attributes=None, id=None, grid=None):
    """resize(a, new_shape) returns a new array with the specified shape.
    The original array's total size can be any size."""
    ignore, attributes, id, ignore = _extractMetadata(a, axes, attributes, id)
    if axes is not None:
        axesshape = [len(item) for item in axes]
        if axesshape!=list(new_shape):
            raise CDMSError, 'axes must be shaped %s'%`newshape`
    ta = _makeMaskedArg(a)
    maresult = numpy.ma.resize(ta, new_shape)
    F=getattr(a,"fill_value",1.e20)
    return TransientVariable(maresult, axes=axes, attributes=attributes, id=id, grid=grid, fill_value=F)
예제 #32
0
    def subRegion (self, *specs, **keys):

        speclist = self._process_specs (specs, keys)
        slicelist = self.reg_specs2slices (speclist)

        squeeze = keys.get ('squeeze', 0)
        raw = keys.get('raw',0)
        order = keys.get('order', None)
        grid = keys.get('grid', None)
        raweasy = raw==1 and order is None and grid is None
        if grid is not None and order is None:
            order = grid.getOrder()


        # Check if any slice wraps around.

        wrapdim = -1
        
        axes = []

        circulardim = None
        
        for idim in range(len(slicelist)):
            item = slicelist[idim]
            axis = self.getAxis(idim)
            axislen = len(axis)

            if(axis.isCircular()): circulardim=idim

            wraptest1 = ( axis.isCircular() and speclist[idim] != unspecified)
            start, stop = item.start, item.stop
            wraptest2 = not ((start is None or (0<=start<axislen)) and (stop is None or (0<=stop<=axislen)))

            if ( wraptest1 and wraptest2):
                if wrapdim >= 0:
                    raise CDMSError, "Too many dimensions wrap around."
                wrapdim = idim
                break
                    
        else:

            # No wraparound, just read the data

            # redo the speclist -> slice if passed circular test but not wrapped test

            if(circulardim is not None):
                slicelist = self.reg_specs2slices (speclist,force=circulardim)
                
            d = {'raw':raw, 
                 'squeeze':squeeze,
                 'order':order,
                 'grid':grid,
                }
            return self.subSlice(*slicelist, **d)

        #
        #  get the general wrap slice (indices that are neg -> pos and vica versa)
        #

        wrapslice = slicelist[wrapdim]
        wrapaxis = self.getAxis(wrapdim)
        length = len(wrapaxis)

        #
        # shift the wrap slice to the positive side and calc number of cycles shifted
        #

        wb=wrapslice.start
        we=wrapslice.stop
        ws=wrapslice.step
        size=length
        cycle=self.getAxis(wrapdim).getModulo()

        #
        # ncycle:
        #   number of cycles for slicing purposes and
        #   resetting world coordinate from the positive only direction
        #
        # ncyclesrev:
        #    resetting the world coordinate for reversed direction
        #
        
        ncycles=0
        ncyclesrev=0

        if(ws>0):

            if(wb>0):
                ncycles=1
                while(wb>=0):
                    wb=wb-size
                    we=we-size
                    ncycles=ncycles-1
            else:
                ncycles=0
                while(wb<0):
                    wb=wb+size
                    we=we+size
                    ncycles=ncycles+1
                    
            if(wb < 0):
                wb=wb+size
                we=we+size
                
        #  reversed direction
        
        else:

            # do the ncycles for resetting world coordinate
            wbrev=wb
            werev=we
            werevNoneTest=0
            if(werev is None):
                werev=0
                werevNoneTest=1

            ncycleRevStart=1
            if(wbrev > 0):
                ncyclesrev=ncycleRevStart
                while(wbrev>=0):
                    wbrev=wbrev-size
                    werev=werev-size
                    ncyclesrev=ncyclesrev-1
            else:
                ncyclesrev=0
                while(wbrev<0):
                    wbrev=wbrev+size
                    werev=werev+size
                    ncyclesrev=ncyclesrev+1

            while(werev < 0):
                wbrev=wbrev+size
                werev=werev+size

            # number of cycles to make the slice positive
            while( we<0 and we != None ):
                wb=wb+size
                we=we+size
                ncycles=ncycles+1

            wb=wbrev
            we=werev
            if(werevNoneTest): we=None
            
        wrapslice=slice(wb,we,ws)
        
        #
        #  calc the actual positive slices and create data array
        #

        donew=1

        if(donew):

            wraps = splitSliceExt(wrapslice, length)

            for kk in range(0,len(wraps)):
                sl=wraps[kk]
                
                slicelist[wrapdim] = sl

                if(kk == 0):
                    ar1 = self.getSlice(squeeze=0, *slicelist)
                    result=ar1
                else:
                    ar2 = self.getSlice(squeeze=0, *slicelist)
                    result = numpy.ma.concatenate((result,ar2),axis=wrapdim)

        else:

            wrap1, wrap2 = splitSlice(wrapslice, length)
            slicelist[wrapdim] = wrap1
            ar1 = self.getSlice(squeeze=0, *slicelist)
            slicelist[wrapdim] = wrap2
            ar2 = self.getSlice(squeeze=0, *slicelist)
            result = numpy.ma.concatenate((ar1,ar2),axis=wrapdim)


        if raweasy:
            return self._returnArray(result, squeeze)

        #----------------------------------------------------------------------
        #
        #  set ALL the axes (transient variable)
        #
        #----------------------------------------------------------------------

        wrapspec=speclist[wrapdim]
        
        axes = []
        for i in range(self.rank()):
            if squeeze and numpy.ma.size(result, i) == 1: continue

            sl = slicelist[i]

            if i == wrapdim:

                axis = self.getAxis(i).subAxis(wb, we, ws)
                
                if(ws > 0):
                    delta_beg_wrap_dimvalue = ncycles*cycle
                else:
                    delta_beg_wrap_dimvalue = ncyclesrev*cycle

                axis.setBounds(axis.getBounds() - delta_beg_wrap_dimvalue)
                
                axis[:]= (axis[:] - delta_beg_wrap_dimvalue).astype(axis.typecode())

            else:
                axis = self.getAxis(i).subaxis(sl.start, sl.stop, sl.step)
            axes.append(axis)

        result = self._returnArray(result, squeeze)
        result = TransientVariable(result,
                                 copy=0, 
                                 fill_value = self.missing_value,
                                 axes=axes,
                                 attributes=self.attributes,
                                 id = self.id)
        if grid is not None:
            order2 = grid.getOrder()
            if order is None:
                order = order2
            elif order != order2:
                raise CDMSError, 'grid, order options not compatible.'
            
        result = result.reorder(order).regrid(grid)
        if raw == 0:
            return result
        else:
            return result.getSlice(squeeze=0, raw=1)
예제 #33
0
    def subSlice (self, *specs, **keys):
        speclist = self._process_specs (specs, keys)
        numericSqueeze = keys.get('numericSqueeze',0)

        # Get a list of single-index specs
        if numericSqueeze:
            singles = self._single_specs(specs)
        else:
            singles = None
        slicelist = self.specs2slices(speclist,force=1)
        d = self.expertSlice (slicelist)
        squeeze = keys.get ('squeeze', 0)
        raw = keys.get('raw',0)
        order = keys.get('order', None)
        grid = keys.get('grid', None)
        forceaxes = keys.get('forceaxes', None) # Force result to have these axes
        raweasy = raw==1 and order is None and grid is None
        if not raweasy:
            if forceaxes is None:
                axes = []
                allaxes = [None]*self.rank()
                for i in range(self.rank()):
                   slice = slicelist[i]
                   if squeeze and numpy.ma.size(d, i) == 1:
                       continue
                   elif numericSqueeze and i in singles:
                       continue
                   # Don't wrap square-bracket slices
                   axis = self.getAxis(i).subaxis(slice.start, slice.stop, slice.step, wrap=(numericSqueeze==0))
                   axes.append(axis)
                   allaxes[i] = axis
            else:
                axes = forceaxes

            # Slice the grid, if non-rectilinear. Don't carry rectilinear grids, since
            # they can be inferred from the domain.
            selfgrid = self.getGrid()
            if selfgrid is None or isinstance(selfgrid, AbstractRectGrid):
                resultgrid = None
            else:
                alist = [item[0] for item in self.getDomain()]
                gridslices, newaxes = selfgrid.getGridSlices(alist, allaxes, slicelist)

                # If one of the grid axes was squeezed, the result grid is None
                if None in newaxes:
                    resultgrid = None
                else:
                    resultgrid = apply(selfgrid.subSlice, gridslices, {'forceaxes': newaxes})

        resultArray = self._returnArray(d, squeeze, singles=singles)
        if self.isEncoded():
            resultArray  = self.decode(resultArray)
            newmissing = resultArray.fill_value
        else:
            newmissing = self.getMissing()

        if raweasy:
            return resultArray
        elif len(axes)>0:

            # If forcing use of input axes, make sure they are not copied.
            # Same if the grid is not rectilinear - this is when forceaxes is set.
            copyaxes = (forceaxes is None) and (resultgrid is None)
            result = TransientVariable(resultArray, 
                                     copy=0,
                                     fill_value = newmissing,
                                     axes=axes,
                                     copyaxes = copyaxes,
                                     grid = resultgrid,
                                     attributes=self.attributes,
                                     id = self.id)
            if grid is not None:
                order2 = grid.getOrder()
                if order is None:
                    order = order2
                elif order != order2:
                    raise CDMSError, 'grid, order options not compatible.'
            result = result.reorder(order).regrid(grid)
            if raw == 0:
                return result
            else:
                return result.getSlice(squeeze=0, raw=1)

        else:               # Return numpy.ma for zero rank, so that __cmp__ works.
            return resultArray