예제 #1
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)
예제 #2
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)
예제 #3
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
예제 #4
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