def apply(self, srcData, dstData, rootPe=None, missingValue=None, **args): """ Regrid source to destination @param srcData array (input) @param dstData array (output) @param rootPe if other than None, then results will be MPI gathered @param missingValue if not None, then data mask will be interpolated and data value set to missingValue when masked """ # assuming the axes are the slowly varying indices srcHorizShape = srcData.shape[-self.nGridDims:] dstHorizShape = dstData.shape[-self.nGridDims:] srcDataMaskFloat = None dstDataMaskFloat = None dstMask = None if missingValue is not None: srcDataMaskFloat = numpy.zeros(srcHorizShape, srcData.dtype) dstDataMaskFloat = numpy.zeros(dstHorizShape, dstData.dtype) nonHorizShape = srcData.shape[:-self.nGridDims] if len(nonHorizShape) == 0: # # no axis... just call apply # # adjust for masking if missingValue is not None: srcDataMaskFloat[:] = (srcData == missingValue) # set field values to zero where missing, we'll add the mask # contribution later indata = numpy.array(srcData * (1 - (srcDataMaskFloat == 1)), dtype=srcData.dtype) # interpolate mask self.tool.apply(srcDataMaskFloat, dstDataMaskFloat, rootPe=rootPe, globalIndexing=True, **args) if re.search('conserv', self.regridMethod.lower(), re.I): dstMask = numpy.array((dstDataMaskFloat > 1 - EPS), numpy.int32) else: dstMask = numpy.array((dstDataMaskFloat > 0), numpy.int32) # Initialize output to missin_value dstData[:] = missingValue # interpolate the data self.tool.apply(indata, dstData, rootPe=rootPe, globalIndexing=True, **args) # add missing values dstData *= (1 - dstMask) dstData += dstMask * missingValue else: # no masking, just interpolate the data self.tool.apply(srcData, dstData, rootPe=rootPe, globalIndexing=True, **args) else: nonHorizShape2 = dstData.shape[:-self.nGridDims] if not numpy.all(nonHorizShape2 == nonHorizShape): msg = 'mvGenericRegrid.apply: axes detected ' msg += 'but %s != %s ' % (str(nonHorizShape2), str(nonHorizShape)) raise regrid2.RegridError(msg) # # iterate over all axes # # create containers to hold input/output values # (a copy is essential here) zros = '[' + ('0,' * len(nonHorizShape)) + '...]' indata = numpy.array(eval('srcData' + zros)) outdata = numpy.array(eval('dstData' + zros)) # now iterate over all non lat/lon coordinates for it in MultiArrayIter(nonHorizShape): indices = it.getIndices() slce = '[' slce += reduce(operator.add, ['%d,' % i for i in indices]) slce += '...]' indata = eval('srcData' + slce) # adjust for masking if missingValue is not None: srcDataMaskFloat[:] = (indata == missingValue) # set field values to zero where missing, we'll add the mask # contribution later indata *= (1 - (srcDataMaskFloat == 1)) # srcDataMaskFloatData = srcDataMaskFloat * numpy.random.rand(srcHorizShape[0],srcHorizShape[1])*100 # interpolate mask self.tool.apply(srcDataMaskFloat, dstDataMaskFloat, rootPe=rootPe, globalIndexing=True, srcDataMask=(1 - srcDataMaskFloat), **args) if re.search('conserv', self.regridMethod.lower(), re.I): # cell interpolation dstMask = numpy.array((dstDataMaskFloat > 1 - EPS), numpy.int32) else: # nodal interpolation dstMask = numpy.array((dstDataMaskFloat > 0), numpy.int32) # interpolate the data, using the appropriate tool self.tool.apply(indata, outdata, rootPe=rootPe, globalIndexing=True, srcDataMask=srcDataMaskFloat, **args) # apply missing value contribution if missingValue is not None: # add mask contribution outdata *= (1 - dstMask) outdata += dstMask * missingValue # fill in dstData exec('dstData' + slce + ' = outdata')
def __init__(self, srcGrid, dstGrid, dtype, regridMethod, regridTool, srcGridMask=None, srcBounds=None, srcGridAreas=None, dstGridMask=None, dstBounds=None, dstGridAreas=None, **args): """ Constructor. @param srcGrid list of numpy arrays, source horizontal coordinates @param dstGrid list of numpy arrays, destination horizontal coordinate @param dtype numpy data type for src/dst data @param regridMethod linear (bi, tri,...) default or conservative @param regridTool currently either 'libcf' or 'esmf' @param srcGridMask array of same shape as srcGrid @param srcBounds list of numpy arrays of same shape as srcGrid @param srcGridAreas array of same shape as srcGrid @param dstGridMask array of same shape as dstGrid @param dstBounds list of numpy arrays of same shape as dstGrid @param dstGridAreas array of same shape as dstGrid @param **args additional arguments to be passed to the specific tool 'libcf': mkCyclic={True, False}, handleCut={True,False} 'esmf': periodicity={0,1}, coordSys={'deg', 'cart'}, ... """ self.nGridDims = len(srcGrid) self.regridMethod = regridMethod if len(srcGrid) != len(dstGrid): msg = 'mvGenericRegrid.__init__: mismatch in number of dims' msg += ' len(srcGrid) = %d != len(dstGrid) = %d' % \ (self.nGridDims, len(dstGrid)) raise regrid2.RegridError(msg) # parse the options if re.search('libcf', regridTool.lower()) or \ re.search('gsreg', regridTool.lower()): # LibCF self.tool = regrid2.LibCFRegrid(srcGrid, dstGrid, srcGridMask=srcGridMask, srcBounds=srcBounds, **args) elif re.search('esm', regridTool.lower()): # ESMF staggerLoc = args.get('staggerLoc', 'center') if 'staggerLoc' in args: del args['staggerLoc'] periodicity = args.get('periodicity', guessPeriodicity(srcBounds)) if 'periodicity' in args: del args['periodicity'] coordSys = args.get('coordSys', 'deg') if 'coordSys' in args: del args['coordSys'] # Get the shapes self.srcGridShape = srcGrid[0].shape self.dstGridShape = dstGrid[0].shape self.hasSrcBounds = False self.hasDstBounds = False if srcBounds is not None: self.hasSrcBounds = True if dstBounds is not None: self.hasDstBounds = True self.srcGridAreasShape = None self.dstGridAreasShape = None if srcGridAreas is not None: self.srcGridAreasShape = srcGridAreas[0].shape if dstGridAreas is not None: self.dstGridAreasShape = dstGridAreas[0].shape # Initialize self.tool = regrid2.ESMFRegrid( self.srcGridShape, self.dstGridShape, dtype=dtype, regridMethod=regridMethod, staggerLoc=staggerLoc, periodicity=periodicity, coordSys=coordSys, hasSrcBounds=self.hasSrcBounds, hasDstBounds=self.hasDstBounds, srcGridAreasShape=self.srcGridAreasShape, dstGridAreasShape=self.dstGridAreasShape, **args) self.tool.setCoords(srcGrid, dstGrid, srcGridMask=srcGridMask, srcBounds=srcBounds, srcGridAreas=srcGridAreas, dstGridMask=dstGridMask, dstBounds=dstBounds, dstGridAreas=dstGridAreas, globalIndexing=True, **args) else: msg = """mvGenericRegrid.__init__: ERROR unrecognized tool %s, valid choices are: 'libcf', 'esmf'""" % regridTool raise regrid2.RegridError(msg)
def __init__(self, srcGrid, dstGrid, dtype, regridMethod, regridTool, srcGridMask=None, srcBounds=None, srcGridAreas=None, dstGridMask=None, dstBounds=None, dstGridAreas=None, **args): """ """ self.nGridDims = len(srcGrid) self.regridMethod = regridMethod if len(srcGrid) != len(dstGrid): msg = 'mvGenericRegrid.__init__: mismatch in number of dims' msg += ' len(srcGrid) = %d != len(dstGrid) = %d' % \ (self.nGridDims, len(dstGrid)) raise regrid2.RegridError(msg) # parse the options if re.search('libcf', regridTool.lower()) or \ re.search('gsreg', regridTool.lower()): # LibCF self.tool = regrid2.LibCFRegrid(srcGrid, dstGrid, srcGridMask=srcGridMask, srcBounds=srcBounds, **args) elif re.search('esm', regridTool.lower()): # ESMF staggerLoc = args.get('staggerLoc', 'center') if 'staggerLoc' in args: del args['staggerLoc'] periodicity = args.get('periodicity', guessPeriodicity(srcBounds)) if 'periodicity' in args: del args['periodicity'] coordSys = args.get('coordSys', 'deg') if 'coordSys' in args: del args['coordSys'] # Get the shapes self.srcGridShape = srcGrid[0].shape self.dstGridShape = dstGrid[0].shape self.hasSrcBounds = False self.hasDstBounds = False if srcBounds is not None: self.hasSrcBounds = True if dstBounds is not None: self.hasDstBounds = True self.srcGridAreasShape = None self.dstGridAreasShape = None if srcGridAreas is not None: self.srcGridAreasShape = srcGridAreas[0].shape if dstGridAreas is not None: self.dstGridAreasShape = dstGridAreas[0].shape # Initialize self.tool = regrid2.ESMFRegrid( self.srcGridShape, self.dstGridShape, dtype=dtype, regridMethod=regridMethod, staggerLoc=staggerLoc, periodicity=periodicity, coordSys=coordSys, hasSrcBounds=self.hasSrcBounds, hasDstBounds=self.hasDstBounds, srcGridAreasShape=self.srcGridAreasShape, dstGridAreasShape=self.dstGridAreasShape, **args) self.tool.setCoords(srcGrid, dstGrid, srcGridMask=srcGridMask, srcBounds=srcBounds, srcGridAreas=srcGridAreas, dstGridMask=dstGridMask, dstBounds=dstBounds, dstGridAreas=dstGridAreas, globalIndexing=True, **args) else: msg = """mvGenericRegrid.__init__: ERROR unrecognized tool %s, valid choices are: 'libcf', 'esmf'""" % regridTool raise regrid2.RegridError(msg)