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)
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