def process_command_line(argv): help_string = 'mpirun -np 6 cub2latlon.py -i <inputfile> -o <outputfile> --nlats <lats> --nlons <lons> --vars <vars> [--debug]' try: opts, args = getopt.getopt(argv, "hi:o:d", ["ifile=","ofile=","nlons=","nlats=","vars=","debug"]) except getopt.GetoptError: print help_string ESMF.finalize(ESMF.ESMF_END_ABORT) sys.exit(2) params = {} params['debug'] = False for opt, arg in opts: if opt == '-h': print help_string ESMF.finalize() elif opt in ("-i", "--ifile"): params['ifile'] = arg elif opt in ("-o", "--ofile"): params['ofile'] = arg elif opt in ("--nlats"): params['nlats'] = int(arg) elif opt in ("--nlons"): params['nlons'] = int(arg) elif opt in ("--vars"): params['vars'] = arg.split(",") elif opt in ("-d" "--debug"): params['debug'] = True return params
def regrid_2d(field, src_lats, src_lons, dest_lats, dest_lons, src_mask, dest_mask): """ Use this method to regrid a 2d field. """ assert(len(field.shape) == 2) src_grid = self.create_grid(src_lats, src_lons, src_mask) dest_grid = self.create_grid(dest_lats, dest_lons, dest_mask) src_field = ESMF.field(src_grid, 'src_field') src_field[:] = field[:] dest_field = ESMF.field(dest_grid, 'dest_field') dest_field[:] = 0 regrid_func = ESMF.Regrid(src_field, dest_field, src_mask_values=np.array([1]), dest_mask_values=np.array([1]), regrid_method=ESMF.RegridMethod., unmapped_action=ESMF.UnmappedAction.ERROR) dest_field = regrid_func(src_field, dest_field) return dest_field
def createAtmosFileUV(grdROMS, modelpath, atmospath, startdate, enddate, useESMF, myformat, abbreviation, mytype, gridtype): # Setup years = [(int(startdate.year) + kk) for kk in range(1 + int(enddate.year) - int(startdate.year))] # Create the objects for source and destination grids # Get the "Fraction of sfc area covered by ocean nor = atmospath + "NRCP45AERCN_f19_g16_CLE_02.cam2.h0.2006-01.nc" cdf = Dataset(nor, "r") OCENFRAC = cdf.variables["OCNFRAC"][:] cdf.close() Fill = -999.0 grdMODEL = grd.grdClass(nor, mytype, mytype, useESMF, 'atmos') # Create the outputfile outfilename = abbreviation + '_windUV_' + str(mytype) + '_' + str( startdate.year) + '_to_' + str(enddate.year) + '.nc' IOatmos.createNetCDFFileUV(grdROMS, outfilename, myformat, mytype) # Setup ESMF for interpolation (calculates weights) grdMODEL.fieldSrc = ESMF.Field(grdMODEL.esmfgrid, "fieldSrc", staggerloc=ESMF.StaggerLoc.CENTER) grdMODEL.fieldDst_rho = ESMF.Field(grdROMS.esmfgrid, "fieldDst", staggerloc=ESMF.StaggerLoc.CENTER) grdMODEL.regridSrc2Dst_rho = ESMF.Regrid( grdMODEL.fieldSrc, grdMODEL.fieldDst_rho, regrid_method=ESMF.RegridMethod.BILINEAR)
def setupESMF(noresmfile, romsgridfile): esmgrid = ESMF.Grid(filename=noresmfile, filetype=ESMF.FileFormat.GRIDSPEC, is_sphere=True, coord_names=['lat', 'lon'], add_mask=False) romsgrid = ESMF.Grid(filename=romsgridfile, filetype=ESMF.FileFormat.GRIDSPEC, is_sphere=True, coord_names=['lat_rho', 'lon_rho'], add_mask=False) fieldSrc = ESMF.Field(esmgrid, "fieldSrc", staggerloc=ESMF.StaggerLoc.CENTER) fieldDst = ESMF.Field(romsgrid, "fieldDst", staggerloc=ESMF.StaggerLoc.CENTER) regridSrc2Dst = ESMF.Regrid(fieldSrc, fieldDst, regrid_method=ESMF.RegridMethod.BILINEAR, unmapped_action=ESMF.UnmappedAction.IGNORE) return regridSrc2Dst, fieldSrc, fieldDst
def create_locstream_spherical_16(coord_sys=ESMF.CoordSys.SPH_DEG, domask=False): """ :param coord_sys: the coordinate system of the LocStream :param domask: a boolean to tell whether or not to add a mask :return: LocStream """ if ESMF.pet_count() != 1: raise ValueError("processor count must be 1 to use this function") locstream = ESMF.LocStream(16, coord_sys=coord_sys) deg_rad = pi if coord_sys == ESMF.CoordSys.SPH_DEG: deg_rad = 180 locstream["ESMF:Lon"] = [ 0.0, 0.5 * deg_rad, 1.5 * deg_rad, 2 * deg_rad, 0.0, 0.5 * deg_rad, 1.5 * deg_rad, 2 * deg_rad, 0.0, 0.5 * deg_rad, 1.5 * deg_rad, 2 * deg_rad, 0.0, 0.5 * deg_rad, 1.5 * deg_rad, 2 * deg_rad ] locstream["ESMF:Lat"] = [ deg_rad / -2.0, deg_rad / -2.0, deg_rad / -2.0, deg_rad / -2.0, -0.25 * deg_rad, -0.25 * deg_rad, -0.25 * deg_rad, -0.25 * deg_rad, 0.25 * deg_rad, 0.25 * deg_rad, 0.25 * deg_rad, 0.25 * deg_rad, deg_rad / 2.0, deg_rad / 2.0, deg_rad / 2.0, deg_rad / 2.0 ] if domask: locstream["ESMF:Mask"] = np.array( [1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], dtype=np.int32) return locstream
def main(): comm = MPI.COMM_WORLD assert comm.Get_size() == ESMF.pet_count() ESMF.Manager(debug=True) # find input forcings dir_date = os.environ["FORCING_BEGIN_DATE"] if len(dir_date) == 12: # remove minutes dir_date = dir_date[:-2] input_path = Path(os.environ["FORCING_OUTPUT_DIR"]) / dir_date if ESMF.local_pet() == 0: print(f"Starting FECPP in {input_path}") schism_mesh = Path(os.environ["SCHISM_ESMFMESH"]) app = CoastalPreprocessorApp(input_path, Path(os.environ["GEOGRID_FILE"]), schism_mesh=schism_mesh) app.regrid_all_files( output_path_transformer=lambda x: x.with_suffix(".latlon.nc"), var_filter=SeaLevelPressure, file_filter="**/*LDASIN_DOMAIN*")
def interp_to_caltrawl(var): im_all = [] sourcefield.data[...] = var.squeeze() # LOOP OVER EACH SHAPE IN SHAPEFILE for ns in range(nshapes): #for ns in range(20): s = sf.shape(ns) bbox = [coord for coord in s.bbox] # EXTRACT CORNER COORDINATES shp_lons = np.array((bbox[0], bbox[2])) shp_lats = np.array((bbox[3], bbox[1])) # IF INSIDE MAP SUBDOMAIN if ((lon_bnds[plot_num,0]<shp_lons[0]<lon_bnds[plot_num,1]) or \ (lon_bnds[plot_num,0]<shp_lons[1]<lon_bnds[plot_num,1])) and \ ((lat_bnds[plot_num,0]<shp_lats[0]<lat_bnds[plot_num,1]) or \ (lat_bnds[plot_num,0]<shp_lats[1]<lat_bnds[plot_num,1])): # DEFINE CENTRAL POINT c_lon = np.mean(shp_lons) c_lat = np.mean(shp_lats) # DEFINE SURROUNDING (FAKE) GRID POINTS x = [2 * bbox[0] - c_lon, c_lon, 2 * bbox[2] - c_lon] y = [2 * bbox[1] - c_lat, c_lat, 2 * bbox[3] - c_lat] Xn, Yn = np.meshgrid(x, y) dest_lon[...] = Xn dest_lat[...] = Yn # DEFINE INTERPOLATION FUNCTION destfield = ESMF.Field(destgrid, name='CAtrawl_delta') regrid = ESMF.Regrid(sourcefield, destfield, regrid_method=ESMF.RegridMethod.BILINEAR, unmapped_action=ESMF.UnmappedAction.IGNORE) # INTERPOLATE TO SINGLE BOX destfield = regrid(sourcefield, destfield) # EXTRACT CENTER VALUE c_val = destfield.data[1, 1] #print ns, c_val if c_val > 100: c_val = np.nan # plot each pcolor grid cell im_p = m.pcolormesh(shp_lons, shp_lats, c_val * np.ones((2, 2)), vmin=0, vmax=4, cmap='nipy_spectral', edgecolors='k', zorder=map_order) # add to list of images im_all.append(im_p) return im_all
def test_esmpy_normalisation(): """ Integration test for :meth:`~esmf_regrid.esmf_regridder.Regridder`. Checks against ESMF to ensure results are consistent. """ src_data = np.array( [ [1.0, 1.0], [1.0, 0.0], [1.0, 0.0], ], ) src_mask = np.array( [ [True, False], [False, False], [False, False], ] ) src_array = ma.array(src_data, mask=src_mask) lon, lat, lon_bounds, lat_bounds = make_grid_args(2, 3) src_grid = GridInfo(lon, lat, lon_bounds, lat_bounds) src_esmpy_grid = src_grid._make_esmf_grid() src_esmpy_grid.add_item(ESMF.GridItem.MASK, staggerloc=ESMF.StaggerLoc.CENTER) src_esmpy_grid.mask[0][...] = src_mask src_field = ESMF.Field(src_esmpy_grid) src_field.data[...] = src_data lon, lat, lon_bounds, lat_bounds = make_grid_args(3, 2) tgt_grid = GridInfo(lon, lat, lon_bounds, lat_bounds) tgt_field = tgt_grid.make_esmf_field() regridder = Regridder(src_grid, tgt_grid) regridding_kwargs = { "ignore_degenerate": True, "regrid_method": ESMF.RegridMethod.CONSERVE, "unmapped_action": ESMF.UnmappedAction.IGNORE, "factors": True, "src_mask_values": [1], } esmpy_fracarea_regridder = ESMF.Regrid( src_field, tgt_field, norm_type=ESMF.NormType.FRACAREA, **regridding_kwargs ) esmpy_dstarea_regridder = ESMF.Regrid( src_field, tgt_field, norm_type=ESMF.NormType.DSTAREA, **regridding_kwargs ) tgt_field_dstarea = esmpy_dstarea_regridder(src_field, tgt_field) result_esmpy_dstarea = tgt_field_dstarea.data result_dstarea = regridder.regrid(src_array, norm_type="dstarea") assert ma.allclose(result_esmpy_dstarea, result_dstarea) tgt_field_fracarea = esmpy_fracarea_regridder(src_field, tgt_field) result_esmpy_fracarea = tgt_field_fracarea.data result_fracarea = regridder.regrid(src_array, norm_type="fracarea") assert ma.allclose(result_esmpy_fracarea, result_fracarea)
def __init__(self, lon_obs, lat_obs, grid=None, lon_grid=None, lat_grid=None, from_global=True, coord_names=['lon', 'lat'], dim_names=['lon', 'lat']): ''' construct the source grid ESMF from xarray or numpy.array lon_obs : numpy array lat_obs : numpy array grid : xarray dataset lon_grid : numpy array lat_grid : numpy array from_global : bool coord_names : list dim_names : list ''' self.lon_obs = lon_obs self.lat_obs = lat_obs if grid is not None: # get lon and lat from xarray dataset # assert type(grid) == 'xarray.core.dataset.Dataset' lon_raw = grid[coord_names[0]].values lat_raw = grid[coord_names[1]].values else: # assert type(lon) == numpy.array # assert type(lat) == numpy.array # lon and lat are passed as numpy array # make them 2d arrays, if needed lon_raw = lon_grid lat_raw = lat_grid if len(lon_raw.shape) == 1: lon_src, lat_src = _np.meshgrid(lon_raw, lat_raw) else: lon_src = lon_raw lat_src = lat_raw ny, nx = lon_src.shape # construct the ESMF grid object self.model_grid = _ESMF.Grid(_np.array([nx, ny])) self.model_grid.add_coords(staggerloc=[_ESMF.StaggerLoc.CENTER]) self.model_grid.coords[_ESMF.StaggerLoc.CENTER] self.model_grid.coords[_ESMF.StaggerLoc.CENTER][0][:] = lon_src.T self.model_grid.coords[_ESMF.StaggerLoc.CENTER][1][:] = lat_src.T self.model_grid.is_sphere = from_global # import obs location into ESMF locstream object self.nobs = len(lon_obs) self.locstream_obs = _ESMF.LocStream(self.nobs, coord_sys=_ESMF.CoordSys.SPH_DEG) self.locstream_obs["ESMF:Lon"] = lon_obs[:] self.locstream_obs["ESMF:Lat"] = lat_obs[:] return None
def __init__(self, maxIndex): self.grid = ESMF.Grid(maxIndex, num_peri_dims=0, coord_sys=COORDSYS, staggerloc=[CENTER]) self.field = ESMF.Field(self.grid, name='srcField1', staggerloc=CENTER, typekind=R4)
def create_source_grid(self, filename, from_global, coord_names, x_coords=None, y_coords=None, autocrop=True): ''' create ESMF grid object for source grid ''' # new way to create source grid # TO DO : move into separate function, has to be called before drown # so that we know the periodicity # Allow to provide lon/lat from existing array if x_coords is not None and y_coords is not None: lon_src = x_coords lat_src = y_coords else: lons = _ncdf.read_field(filename, coord_names[0]) lats = _ncdf.read_field(filename, coord_names[1]) if len(lons.shape) == 1: lon_src, lat_src = _np.meshgrid(lons, lats) else: lon_src = lons lat_src = lats # autocrop if autocrop: imin_src, imax_src, jmin_src, jmax_src = \ _lc.find_subset(self.grid_target,lon_src,lat_src) lon_src = lon_src[jmin_src:jmax_src, imin_src:imax_src] lat_src = lat_src[jmin_src:jmax_src, imin_src:imax_src] ny_src, nx_src = lon_src.shape if not autocrop: imin_src = 0 imax_src = nx_src jmin_src = 0 jmax_src = ny_src if from_global and not autocrop: gridsrc = _ESMF.Grid(_np.array([nx_src, ny_src]), num_peri_dims=1) self.gtype = 1 # 1 = periodic for drown NCL self.kew = 0 # 0 = periodic for drown sosie else: gridsrc = _ESMF.Grid(_np.array([nx_src, ny_src])) self.gtype = 0 # 1 = non periodic for drown NCL self.kew = -1 # -1 = non periodic for drown sosie gridsrc.add_coords(staggerloc=[_ESMF.StaggerLoc.CENTER]) gridsrc.coords[_ESMF.StaggerLoc.CENTER][0][:] = lon_src.T gridsrc.coords[_ESMF.StaggerLoc.CENTER][1][:] = lat_src.T # original from RD #self.gridsrc = _ESMF.Grid(filename=filename,filetype=_ESMF.FileFormat.GRIDSPEC,\ #is_sphere=from_global,coord_names=coord_names) return gridsrc, imin_src, imax_src, jmin_src, jmax_src
def ccs_roms_region(lat, lon): # CCS ROMS GRID # without pyroms fid = nc.Dataset( '/glade/p/work/edrenkar/Inputs/Grid/CCS_grd_high_res_bathy_jerlov.nc') r_lat = fid.variables['lat_rho'][:] r_lon = fid.variables['lon_rho'][:] sourcegrid = ESMF.Grid(np.array(r_lon.shape), staggerloc=ESMF.StaggerLoc.CENTER, coord_sys=ESMF.CoordSys.SPH_DEG) # CESM GRID lon[lon > 180] = lon[lon > 180] - 360 destgrid = ESMF.Grid(np.array(lon.shape), staggerloc=ESMF.StaggerLoc.CENTER, coord_sys=ESMF.CoordSys.SPH_DEG) ## POINTERS source_lon = sourcegrid.get_coords(0) source_lat = sourcegrid.get_coords(1) dest_lon = destgrid.get_coords(0) dest_lat = destgrid.get_coords(1) ## FILLS source_lon[...] = r_lon source_lat[...] = r_lat dest_lon[...] = lon dest_lat[...] = lat sourcefield = ESMF.Field(sourcegrid, name='CCS ROMS') destfield = ESMF.Field(destgrid, name='CESM Sub') sourcefield.data[...] = fid.variables['mask_rho'][:].squeeze() regrid = ESMF.Regrid(sourcefield, destfield, regrid_method=ESMF.RegridMethod.BILINEAR, unmapped_action=ESMF.UnmappedAction.IGNORE) destfield = regrid(sourcefield, destfield) return_val = destfield.data # CONVERTING TO 1/0 boolean for mask_where: TRUE (1) where you want to mask return_val[return_val < .5] = 0 # FALSE (initially land and ocean outside ROMS domain) return_val[ return_val > .5] = 1 # TRUE (initially water inside ROMS domain) # CHECK NUMBER OF POINTS USED vs. TOTAL CESM SUB-DOMAIN # print 'ROMS OCEAN:', np.sum(return_val) # print 'CESM SIZE:', return_val.shape[0]*return_val.shape[1] return_val = -1 * return_val + 1 # REVERSE MASK VALUES FOR where_mask return_val2 = return_val.astype(np.bool) # MAKE BOOLEAN return return_val2
def createData(filename, fieldname, coord_names): # read the netcdf file header nc = netCDF4.Dataset(filename) # get the local cell array sizes cellDims = numpy.array(nc.variables[coord_names['lat_bounds']].shape[:2], numpy.int32) # create the ESMF grid grid = ESMF.Grid(max_index=cellDims, coord_sys=ESMF.api.constants.CoordSys.SPH_DEG) #, num_peri_dims=1, periodic_dim=1) # create coordinates grid.add_coords(staggerloc=ESMF.StaggerLoc.CORNER, coord_dim=LAT_INDEX) grid.add_coords(staggerloc=ESMF.StaggerLoc.CORNER, coord_dim=LON_INDEX) # get the local start/end index sets and set the point coordinates iBeg0 = grid.lower_bounds[ESMF.StaggerLoc.CORNER][LON_INDEX] iEnd0 = grid.upper_bounds[ESMF.StaggerLoc.CORNER][LON_INDEX] iBeg1 = grid.lower_bounds[ESMF.StaggerLoc.CORNER][LAT_INDEX] iEnd1 = grid.upper_bounds[ESMF.StaggerLoc.CORNER][LAT_INDEX] # read the bound coordinates boundLats = nc.variables[coord_names['lat_bounds']][iBeg0:iEnd0 - 1, iBeg1:iEnd1 - 1, :] boundLons = nc.variables[coord_names['lon_bounds']][iBeg0:iEnd0 - 1, iBeg1:iEnd1 - 1, :] pointSizes = (boundLats.shape[0] + 1, boundLats.shape[1] + 1) # fill in the lat-lon ar the cell corner points lats = numpy.zeros(pointSizes, numpy.float64) lons = numpy.zeros(pointSizes, numpy.float64) lats[:-1, :-1] = boundLats[..., 0] lats[-1, :-1] = boundLats[-1, :, 1] lats[-1, -1] = boundLats[-1, -1, 2] lats[:-1, -1] = boundLats[:, -1, 3] lons[:-1, :-1] = boundLons[..., 0] lons[-1, :-1] = boundLons[-1, :, 1] lons[-1, -1] = boundLons[-1, -1, 2] lons[:-1, -1] = boundLons[:, -1, 3] coordLatsPoint = grid.get_coords(coord_dim=LAT_INDEX, staggerloc=ESMF.StaggerLoc.CORNER) coordLonsPoint = grid.get_coords(coord_dim=LON_INDEX, staggerloc=ESMF.StaggerLoc.CORNER) # set the ESMF coordinates coordLatsPoint[:] = lats coordLonsPoint[:] = lons # create and set the field, cell centred field = ESMF.Field(grid, staggerloc=ESMF.StaggerLoc.CENTER) # read the cell centred data and set the field. Note that we need to use the point dims field.data[...] = nc.variables[fieldname][iBeg0:iEnd0, iBeg1:iEnd1] return grid, field
def setupESMFInterpolationWeights(confM2R): if confM2R.useesmf: print("=>Creating the interpolation weights and indexes using ESMF (this may take some time....):") print(" -> regridSrc2Dst at RHO points") confM2R.grdMODEL.fieldSrc_rho = ESMF.Field(confM2R.grdMODEL.esmfgrid, "fieldSrc", staggerloc=ESMF.StaggerLoc.CENTER) confM2R.grdMODEL.fieldDst_rho = ESMF.Field(confM2R.grdROMS.esmfgrid, "fieldDst", staggerloc=ESMF.StaggerLoc.CENTER) confM2R.grdMODEL.regridSrc2Dst_rho = ESMF.Regrid(confM2R.grdMODEL.fieldSrc_rho, confM2R.grdMODEL.fieldDst_rho, regrid_method=ESMF.RegridMethod.BILINEAR, unmapped_action=ESMF.UnmappedAction.IGNORE) print(" -> regridSrc2Dst at U points") confM2R.grdMODEL.fieldSrc_u = ESMF.Field(confM2R.grdMODEL.esmfgrid_u, "fieldSrc", staggerloc=ESMF.StaggerLoc.CENTER) confM2R.grdMODEL.fieldDst_u = ESMF.Field(confM2R.grdROMS.esmfgrid_u, "fieldDst_u", staggerloc=ESMF.StaggerLoc.CENTER) confM2R.grdMODEL.regridSrc2Dst_u = ESMF.Regrid(confM2R.grdMODEL.fieldSrc_u, confM2R.grdMODEL.fieldDst_u, regrid_method=ESMF.RegridMethod.BILINEAR, unmapped_action=ESMF.UnmappedAction.IGNORE) print(" -> regridSrc2Dst at V points") confM2R.grdMODEL.fieldSrc_v = ESMF.Field(confM2R.grdMODEL.esmfgrid_v, "fieldSrc", staggerloc=ESMF.StaggerLoc.CENTER) confM2R.grdMODEL.fieldDst_v = ESMF.Field(confM2R.grdROMS.esmfgrid_v, "fieldDst_v", staggerloc=ESMF.StaggerLoc.CENTER) confM2R.grdMODEL.regridSrc2Dst_v = ESMF.Regrid(confM2R.grdMODEL.fieldSrc_v, confM2R.grdMODEL.fieldDst_v, regrid_method=ESMF.RegridMethod.BILINEAR, unmapped_action=ESMF.UnmappedAction.IGNORE)
def create_locstream_16_parallel(domask=False): """ :param domask: a boolean to tell whether or not to add a mask :return: LocStream """ if ESMF.pet_count() is not 4: raise ValueError("processor count must be 4 to use this function") locstream = None if ESMF.local_pet() is 0: locstream = ESMF.LocStream(4) locstream["ESMF:X"] = [0.0, 1.5, 0.0, 1.5] locstream["ESMF:Y"] = [0.0, 0.0, 1.5, 1.5] if domask: locstream["ESMF:Mask"] = [1, 0, 0, 1] elif ESMF.local_pet() is 1: locstream = ESMF.LocStream(4) locstream["ESMF:X"] = [2.5, 4.0, 2.5, 4.0] locstream["ESMF:Y"] = [0.0, 0.0, 1.5, 1.5] if domask: locstream["ESMF:Mask"] = [1, 1, 1, 1] elif ESMF.local_pet() is 2: locstream = ESMF.LocStream(4) locstream["ESMF:X"] = [0.0, 1.5, 0.0, 1.5] locstream["ESMF:Y"] = [2.5, 2.5, 4.0, 4.0] if domask: locstream["ESMF:Mask"] = [1, 1, 1, 1] elif ESMF.local_pet() is 3: locstream = ESMF.LocStream(4) locstream["ESMF:X"] = [2.5, 4.0, 2.5, 4.0] locstream["ESMF:Y"] = [2.5, 2.5, 4.0, 4.0] if domask: locstream["ESMF:Mask"] = [1, 1, 1, 1] return locstream
def test_create_merged_weight_file(self): import ESMF path_src = self.get_temporary_file_path('src.nc') path_dst = self.get_temporary_file_path('dst.nc') src_grid = create_gridxy_global(resolution=30.0, wrapped=False, crs=Spherical()) dst_grid = create_gridxy_global(resolution=35.0, wrapped=False, crs=Spherical()) src_grid.write(path_src) dst_grid.write(path_dst) # Split source and destination grids --------------------------------------------------------------------------- gs = GridChunker(src_grid, dst_grid, (2, 2), check_contains=False, allow_masked=True, paths=self.fixture_paths, genweights=True) gs.write_chunks() # Merge weight files ------------------------------------------------------------------------------------------- merged_weight_filename = self.get_temporary_file_path( 'merged_weights.nc') gs.create_merged_weight_file(merged_weight_filename) # Generate a global weight file using ESMF --------------------------------------------------------------------- global_weights_filename = self.get_temporary_file_path( 'global_weights.nc') srcgrid = ESMF.Grid(filename=path_src, filetype=ESMF.FileFormat.GRIDSPEC, add_corner_stagger=True) dstgrid = ESMF.Grid(filename=path_dst, filetype=ESMF.FileFormat.GRIDSPEC, add_corner_stagger=True) srcfield = ESMF.Field(grid=srcgrid) dstfield = ESMF.Field(grid=dstgrid) _ = ESMF.Regrid(srcfield=srcfield, dstfield=dstfield, filename=global_weights_filename, regrid_method=ESMF.RegridMethod.CONSERVE) # Test merged and global weight files are equivalent ----------------------------------------------------------- self.assertWeightFilesEquivalent(global_weights_filename, merged_weight_filename)
def createData(filename, prefix): # use iris to read in the data # then pass the array to the ESMF API cubes = iris.load(filename) cubePoint, cubeCell = None, None # find the point and cell cubes for cb in cubes: if cb.var_name == 'pointData': cubePoint = cb if cb.var_name == 'cellData': cubeCell = cb coordsPoint = cubePoint.coords() xPoint = coordsPoint[0].points yPoint = coordsPoint[1].points # create the ESMF grid object xIndex, yIndex = 0, 1 cellDims = numpy.array([xPoint.shape[0] - 1, xPoint.shape[1] - 1]) grid = ESMF.Grid(max_index=cellDims, coord_sys=ESMF.api.constants.CoordSys.CART ) #SPH_DEG) #, num_peri_dims=1, periodic_dim=1) grid.add_coords(staggerloc=ESMF.StaggerLoc.CORNER, coord_dim=xIndex) grid.add_coords(staggerloc=ESMF.StaggerLoc.CORNER, coord_dim=yIndex) coordXPoint = grid.get_coords(coord_dim=xIndex, staggerloc=ESMF.StaggerLoc.CORNER) coordYPoint = grid.get_coords(coord_dim=yIndex, staggerloc=ESMF.StaggerLoc.CORNER) # get the local start/end index sets and set the point coordinates iBegX = grid.lower_bounds[ESMF.StaggerLoc.CORNER][xIndex] iEndX = grid.upper_bounds[ESMF.StaggerLoc.CORNER][xIndex] iBegY = grid.lower_bounds[ESMF.StaggerLoc.CORNER][yIndex] iEndY = grid.upper_bounds[ESMF.StaggerLoc.CORNER][yIndex] coordXPoint[...] = xPoint[iBegX:iEndX, iBegY:iEndY] coordYPoint[...] = yPoint[iBegX:iEndX, iBegY:iEndY] # local sizes nodeDims = (iEndX - iBegX, iEndY - iBegY) # create and set the field field = ESMF.Field(grid, staggerloc=ESMF.StaggerLoc.CENTER) field.data[...] = cubeCell.data[:] return { 'emsf_grid': grid, 'esmf_field': field, 'xPoint': xPoint, 'yPoint': yPoint, 'data': cubeCell.data, 'dims': nodeDims }
def define_esmf_field(ifile, data_onlevel, name): """Define ESMF field from netCDF file.""" grid_obs = ESMF.Grid(filename=ifile, filetype=ESMF.FileFormat.GRIDSPEC) mask_obs = grid_obs.add_item(ESMF.GridItem.MASK) mask_obs[:] = data_onlevel.mask.astype('int').T esmf_field = ESMF.Field( grid_obs, staggerloc=ESMF.StaggerLoc.CENTER, name=name, ) return esmf_field
def createData(filename, fieldname): # read the netcdf file header nc = netCDF4.Dataset(filename) var = nc.variables[fieldname] coordNames = var.coordinates.split(' ') # find the name of the curvilinear lat and lon coords latName, lonName = '', '' for c in coordNames: coord = nc.variables[c] if coord.standard_name == b'latitude': latName = c if coord.standard_name == b'longitude': lonName = c lats = nc.variables[latName][:] lons = nc.variables[lonName][:] # create the ESMF grid cellDims = numpy.array(lats.shape, numpy.int32) - 1 grid = ESMF.Grid(max_index=cellDims, coord_sys=ESMF.api.constants.CoordSys.SPH_DEG) #, num_peri_dims=1, periodic_dim=1) # create coordinates grid.add_coords(staggerloc=ESMF.StaggerLoc.CORNER, coord_dim=LAT_INDEX) grid.add_coords(staggerloc=ESMF.StaggerLoc.CORNER, coord_dim=LON_INDEX) # get the local start/end index sets and set the point coordinates iBeg0 = grid.lower_bounds[ESMF.StaggerLoc.CORNER][LON_INDEX] iEnd0 = grid.upper_bounds[ESMF.StaggerLoc.CORNER][LON_INDEX] iBeg1 = grid.lower_bounds[ESMF.StaggerLoc.CORNER][LAT_INDEX] iEnd1 = grid.upper_bounds[ESMF.StaggerLoc.CORNER][LAT_INDEX] coordLatsPoint = grid.get_coords(coord_dim=LAT_INDEX, staggerloc=ESMF.StaggerLoc.CORNER) coordLonsPoint = grid.get_coords(coord_dim=LON_INDEX, staggerloc=ESMF.StaggerLoc.CORNER) # set the ESMF coordinates coordLatsPoint[:] = lats coordLonsPoint[:] = lons # create and set the field, cell centred field = ESMF.Field(grid, staggerloc=ESMF.StaggerLoc.CORNER) # read the cell centred data and set the field. Note that we need to use the point dims data = var[:] if len(data.shape) == 2: field.data[...] = data[iBeg0:iEnd0, iBeg1:iEnd1] elif len(data.shape) == 3: field.data[...] = data[args.time, iBeg0:iEnd0, iBeg1:iEnd1] else: field.data[...] = data[args.time, args.level, iBeg0:iEnd0, iBeg1:iEnd1] return grid, field
def interp_to_caltrawl(var): im_all=[] sourcefield.data[...] = var.squeeze() # LOOP OVER EACH SHAPE IN SHAPEFILE for ns in range(nshapes): #for ns in range(20): s = sf.shape(ns) bbox = [coord for coord in s.bbox] # EXTRACT CORNER COORDINATES shp_lons = np.array((bbox[0], bbox[2])) shp_lats = np.array((bbox[3], bbox[1])) # IF INSIDE MAP SUBDOMAIN if ((lon_bnds[plot_num,0]<shp_lons[0]<lon_bnds[plot_num,1]) or \ (lon_bnds[plot_num,0]<shp_lons[1]<lon_bnds[plot_num,1])) and \ ((lat_bnds[plot_num,0]<shp_lats[0]<lat_bnds[plot_num,1]) or \ (lat_bnds[plot_num,0]<shp_lats[1]<lat_bnds[plot_num,1])): Xn, Yn = np.meshgrid(shp_lons, shp_lats) dest_lon[...] = Xn dest_lat[...] = Yn # DEFINE INTERPOLATION FUNCTION destfield = ESMF.Field(destgrid, name = 'CAtrawl_delta') # DEFINE INTERPOLATION FUNCTION regrid = ESMF.Regrid(sourcefield, destfield, regrid_method = ESMF.RegridMethod.CONSERVE, src_mask_values=np.array([0], dtype=np.int32), src_frac_field=srcfracfield, norm_type=ESMF.NormType.FRACAREA, unmapped_action = ESMF.UnmappedAction.IGNORE) #regrid = ESMF.Regrid(sourcefield, destfield, regrid_method = ESMF.RegridMethod.BILINEAR, # unmapped_action = ESMF.UnmappedAction.IGNORE) # INTERPOLATE TO SINGLE BOX destfield = regrid(sourcefield, destfield) # EXTRACT CENTER VALUE c_val = destfield.data[0,0] #print np.sum(srcfracfield.data) if np.sum(srcfracfield.data) == 0.: #print 'MEEP' c_val=np.nan if c_val>100: c_val=np.nan # plot each pcolor grid cell im_p = m.pcolormesh(shp_lons,shp_lats,c_val*np.ones((2,2)),vmin=1.5,vmax=4.5,cmap='nipy_spectral',edgecolors='k',zorder=map_order) # add to list of images im_all.append(im_p) return im_all
def test_disjoint_polygons(self): """Test mesh regridding with the source destination containing disjoint polygons.""" ESMF.Manager(debug=True) self.set_debug(True) path_shp = os.path.join(self.path_bin, 'three_polygons', 'three_polygons.shp') path_out_nc = self.get_temporary_file_path('ugrid.nc') path_source_nc = self.get_temporary_file_path('source.nc') mesh_name = 'mesh' self.log.debug('creating source netcdf') row = np.linspace(-1, 1, 10) col = np.linspace(-1, 1, 10) self.create_source_netcdf_data(path_source_nc, row=row, col=col) ops = OcgOperations(dataset={'uri': path_source_nc}, output_format='shp', snippet=True, prefix='source_shp', dir_output=self.path_current_tmp) ops.execute() self.log.debug('creating ugrid file: {}'.format(path_out_nc)) gm = GeometryManager('SPECIAL', path=path_shp) geoms = [r['geom'] for r in gm.iter_records()] mp = MultiPolygon(geoms) # mp = box(-0.25, -0.25, 0.25, 0.25) records = [{'geom': mp, 'properties': {'UGID': 123}}] gm = GeometryManager('UGID', records=records, allow_multipart=True) fm = get_flexible_mesh(gm, mesh_name, False, False) fm.save_as_netcdf(path_out_nc, kwargs_dataset={'format': 'NETCDF3_CLASSIC'}) self.log.debug('getting source field') srcgrid = ESMF.Grid(filename=path_source_nc, filetype=ESMF.FileFormat.GRIDSPEC, coord_names=['longitude', 'latitude'], add_corner_stagger=True) srcfield = get_field_src(srcgrid, path_source_nc, 'pr') self.log.debug('getting destination grid') dstgrid = ESMF.Mesh(filename=path_out_nc, filetype=ESMF.FileFormat.UGRID, meshname=mesh_name) self.log.debug('getting destination field') dstfield = ESMF.Field(dstgrid, "dstfield", meshloc=ESMF.MeshLoc.ELEMENT, ndbounds=[srcfield.data.shape[0]]) self.log.debug('creating regrid object') regrid = ESMF.Regrid(srcfield, dstfield, regrid_method=ESMF.RegridMethod.CONSERVE, unmapped_action=ESMF.UnmappedAction.ERROR) # "zero_region" only weighted data will be touched. self.log.debug('executing regrid') dstfield = regrid(srcfield, dstfield, zero_region=ESMF.Region.SELECT) self.assertEqual(dstfield.data.shape, (366, 1)) print dstfield.data self.log.debug('success')
def test1(self): if has_mpi: comm = MPI.COMM_WORLD pe1 = comm.Get_rank() nprocs1 = comm.Get_size() else: pe1 = 0 nprocs1 = 1 pe2 = ESMF.local_pet() nprocs2 = ESMF.pet_count() print(("Hello ESMPy World from PET (processor) {0}!".format(ESMF.local_pet()))) self.assertEqual(pe1, pe2) self.assertEqual(nprocs1, nprocs2)
def createData(filename, prefix): # use iris to read in the data # then pass the array to the ESMF API pointCube = iris.load( filename, iris.Constraint(cube_func=lambda c: c.var_name == 'pointData'))[0] cellCube = iris.load( filename, iris.Constraint(cube_func=lambda c: c.var_name == 'cellData'))[0] coords = pointCube.coords() lats = coords[0].points lons = coords[1].points # NOTE fortran ordering here # create the ESMF grid object cellDims = numpy.array([len(lons) - 1, len(lats) - 1]) grid = ESMF.Grid(max_index=cellDims) grid.add_coords(staggerloc=ESMF.StaggerLoc.CORNER, coord_dim=LAT_INDEX) grid.add_coords(staggerloc=ESMF.StaggerLoc.CORNER, coord_dim=LON_INDEX) coordLat = grid.get_coords(coord_dim=LAT_INDEX, staggerloc=ESMF.StaggerLoc.CORNER) coordLon = grid.get_coords(coord_dim=LON_INDEX, staggerloc=ESMF.StaggerLoc.CORNER) # get the local start/end index sets iBegLat = grid.lower_bounds[ESMF.StaggerLoc.CORNER][LAT_INDEX] iEndLat = grid.upper_bounds[ESMF.StaggerLoc.CORNER][LAT_INDEX] iBegLon = grid.lower_bounds[ESMF.StaggerLoc.CORNER][LON_INDEX] iEndLon = grid.upper_bounds[ESMF.StaggerLoc.CORNER][LON_INDEX] # set the coordinates coordLat[...] = numpy.outer( numpy.ones((iEndLon - iBegLon, ), coordLon.dtype), lats[iBegLat:iEndLat]) coordLon[...] = numpy.outer( lons[iBegLon:iEndLon], numpy.ones((iEndLat - iBegLat, ), coordLon.dtype)) # create field field = ESMF.Field(grid, name="air_temperature", staggerloc=ESMF.StaggerLoc.CENTER) field.data[...] = cellCube.data.transpose() nodeDims = (iEndLon - iBegLon, iEndLat - iBegLat) return grid, field, nodeDims
def esmf_regrid(source, sourcegrd, ds_out, poles, name): # Convert data array into ESMF.Grid format print("Processing", name) grdshape = xr.DataArray.transpose(sourcegrd['lat']).shape #esmfgrid = ESMF.Grid(np.array(grdshape), staggerloc=ESMF.StaggerLoc.CENTER, coord_sys=ESMF.CoordSys.SPH_DEG, # pole_kind=poles['ds_in'], num_peri_dims=1, periodic_dim=0, pole_dim=1) esmfgrid = ESMF.Grid(np.array(grdshape), staggerloc=ESMF.StaggerLoc.CENTER, coord_sys=ESMF.CoordSys.SPH_DEG, num_peri_dims=1, periodic_dim=0, pole_dim=1) esmf_lon = esmfgrid.get_coords(0) esmf_lat = esmfgrid.get_coords(1) esmf_lon[...] = xr.DataArray.transpose(sourcegrd['lon']).values esmf_lat[...] = xr.DataArray.transpose(sourcegrd['lat']).values sourcefield = ESMF.Field(esmfgrid, name=name) data = np.squeeze(xr.DataArray.transpose(source).values) sourcefield.data[...] = data[:, :] # Regrid each variable type separately #destgrid = ESMF.Grid(np.array(xr.DataArray.transpose(ds_out['lat']).shape), staggerloc=ESMF.StaggerLoc.CENTER, coord_sys=ESMF.CoordSys.SPH_DEG, # pole_kind=poles['ds_out'], num_peri_dims=1, periodic_dim=0, pole_dim=1) destgrid = ESMF.Grid(np.array(xr.DataArray.transpose(ds_out['lat']).shape), staggerloc=ESMF.StaggerLoc.CENTER, coord_sys=ESMF.CoordSys.SPH_DEG, num_peri_dims=1, periodic_dim=0, pole_dim=1) dest_lon = destgrid.get_coords(0) dest_lat = destgrid.get_coords(1) dest_lon[...] = xr.DataArray.transpose(ds_out['lon']).values dest_lat[...] = xr.DataArray.transpose(ds_out['lat']).values destfield = ESMF.Field(destgrid, name='name') regrid = ESMF.Regrid(sourcefield, destfield, regrid_method=ESMF.RegridMethod.BILINEAR, unmapped_action=ESMF.UnmappedAction.IGNORE) destfield = regrid(sourcefield, destfield) eslat = np.squeeze(destfield.grid.coords[0][0][:, 0]) eslon = np.squeeze(destfield.grid.coords[0][1][0, :]) xrgrid = xr.DataArray(destfield.data, dims=['lat', 'lon'], coords={ 'lat': eslat, 'lon': eslon }, name=destfield.name) return xr.DataArray.transpose(xrgrid)
def __init__(self, esmfGrid, name, datatype, staggerloc=CENTER): """ Creator for structured ESMF Field @param esmfGrid instance of an ESMF @param name field name (must be unique) @param datatype data type, one of 'float64', 'float32', 'int64', or 'int32' (or equivalent numpy dtype) @param staggerloc ESMF.StaggerLoc.CENTER ESMF.StaggerLoc.CORNER """ # field object self.field = None # the local processor rank self.pe = 0 # the number of processors self.nprocs = 1 # associated grid self.grid = esmfGrid # staggering self.staggerloc = staggerloc # communicator self.comm = None try: from mpi4py import MPI self.comm = MPI.COMM_WORLD except BaseException: pass etype = None sdatatype = str(datatype) # in case user passes a numpy dtype if re.search('float64', sdatatype): etype = R8 elif re.search('float32', sdatatype): etype = R4 elif re.search('int64', sdatatype): etype = I8 elif re.search('int32', sdatatype): etype = I4 else: msg = 'esmf.EsmfStructField.__init__: ERROR invalid type %s' % datatype raise RegridError(msg) self.field = ESMF.Field(grid=esmfGrid.grid, name=name, typekind=etype, staggerloc=staggerloc) vm = ESMF.ESMP_VMGetGlobal() self.pe, self.nprocs = ESMF.ESMP_VMGet(vm)
def create_field(grid, name, regrid_method=None): ''' PRECONDITIONS: A Mesh or Grid has been created, and 'name' is a string that will be used to initialize the name of a new Field. POSTCONDITIONS: A Field has been created. ''' if isinstance(grid, ESMF.Mesh): if regrid_method == ESMF.RegridMethod.CONSERVE: field = ESMF.Field(grid, name=name, meshloc=ESMF.MeshLoc.ELEMENT) else: field = ESMF.Field(grid, name=name, meshloc=ESMF.MeshLoc.NODE) else: field = ESMF.Field(grid, name=name) return field
def _make_esmf_sdo(self): info = self._as_esmf_info() ( shape, truecenterlons, truecenterlats, truecornerlons, truecornerlats, circular, areas, ) = info if circular: grid = ESMF.Grid( shape, pole_kind=[1, 1], num_peri_dims=1, periodic_dim=1, pole_dim=0, ) else: grid = ESMF.Grid(shape, pole_kind=[1, 1]) grid.add_coords(staggerloc=ESMF.StaggerLoc.CORNER) grid_corner_x = grid.get_coords(0, staggerloc=ESMF.StaggerLoc.CORNER) grid_corner_x[:] = truecornerlons grid_corner_y = grid.get_coords(1, staggerloc=ESMF.StaggerLoc.CORNER) grid_corner_y[:] = truecornerlats # Grid center points are added here, this is not necessary for # conservative area weighted regridding if self.center: grid.add_coords(staggerloc=ESMF.StaggerLoc.CENTER) grid_center_x = grid.get_coords(0, staggerloc=ESMF.StaggerLoc.CENTER) grid_center_x[:] = truecenterlons grid_center_y = grid.get_coords(1, staggerloc=ESMF.StaggerLoc.CENTER) grid_center_y[:] = truecenterlats if areas is not None: grid.add_item(ESMF.GridItem.AREA, staggerloc=ESMF.StaggerLoc.CENTER) grid_areas = grid.get_item(ESMF.GridItem.AREA, staggerloc=ESMF.StaggerLoc.CENTER) grid_areas[:] = areas.T return grid
def test_create_merged_weight_file_unstructured(self): import ESMF # Create an isomorphic source UGRID file. ufile = self.get_temporary_file_path('ugrid.nc') resolution = 10. self.fixture_regular_ugrid_file(ufile, resolution, crs=Spherical()) src_grid = RequestDataset(ufile, driver=DriverNetcdfUGRID, grid_abstraction='point').get().grid self.assertEqual(src_grid.abstraction, 'point') # Create a logically rectangular destination grid file. dst_grid = self.get_gridxy_global(resolution=20., crs=Spherical()) dst_path = self.get_temporary_file_path('dst.nc') dst_grid.parent.write(dst_path) # Create the grid chunks. gs = GridChunker(src_grid, dst_grid, (3, 3), check_contains=False, src_grid_resolution=10., paths=self.fixture_paths, genweights=True) gs.write_chunks() # Merge weight files. mwf = self.get_temporary_file_path('merged_weight_file.nc') gs.create_merged_weight_file(mwf) # Generate a global weight file using ESMF. global_weights_filename = self.get_temporary_file_path( 'global_weights.nc') srcgrid = ESMF.Mesh(filename=ufile, filetype=ESMF.FileFormat.UGRID, meshname=VariableName.UGRID_HOST_VARIABLE) dstgrid = ESMF.Grid(filename=dst_path, filetype=ESMF.FileFormat.GRIDSPEC, add_corner_stagger=True) srcfield = ESMF.Field(grid=srcgrid, meshloc=ESMF.MeshLoc.ELEMENT) dstfield = ESMF.Field(grid=dstgrid) _ = ESMF.Regrid(srcfield=srcfield, dstfield=dstfield, filename=global_weights_filename, regrid_method=ESMF.RegridMethod.CONSERVE) # Test merged and global weight files are equivalent. self.assertWeightFilesEquivalent(global_weights_filename, mwf)
def setUpClass(cls): # Pre-initialise ESMF, just to avoid warnings about no logfile. # NOTE: noisy if logging is off, and no control of filepath. Boo!! if ESMF is not None: # WARNING: nosetest calls class setUp/tearDown even when "skipped". cls._emsf_logfile_path = os.path.join(os.getcwd(), 'ESMF_LogFile') ESMF.Manager(logkind=ESMF.LogKind.SINGLE, debug=False)
def regrid(f_in, f_out, default, missing): comm = MPI.COMM_WORLD any_missing = comm.allgather(missing in f_in.data) if any(any_missing): local_key = ''.join(list(rle((f_in.data==missing).flatten()))) key_list = comm.allgather(local_key) key = ''.join(key_list) if key in regridders.keys(): custom_regrid = regridders[key] else: mask[np.where(f_in.data != missing)] = 1 mask[np.where(f_in.data == missing)] = 0 custom_regrid = ESMF.Regrid(f_in, f_out, src_mask_values=np.array([0]), regrid_method=ESMF.RegridMethod.BILINEAR, line_type=ESMF.LineType.GREAT_CIRCLE, unmapped_action=ESMF.UnmappedAction.IGNORE) regridders[key] = custom_regrid f_out.data[...] = missing custom_regrid(f_in, f_out, zero_region=ESMF.Region.SELECT) else: default(f_in, f_out)
def _make_esmf_mesh(self): info = self._as_esmf_info() ( num_node, num_elem, nodeId, nodeCoord, nodeOwner, elemId, elemType, elemConn, areas, ) = info # ESMF can handle other dimensionalities, but we are unlikely # to make such a use of ESMF emesh = ESMF.Mesh(parametric_dim=2, spatial_dim=2, coord_sys=ESMF.CoordSys.SPH_DEG) emesh.add_nodes(num_node, nodeId, nodeCoord, nodeOwner) emesh.add_elements(num_elem, elemId, elemType, elemConn, element_area=areas) return emesh
def create_locstream_spherical_16_parallel(coord_sys=ESMF.CoordSys.SPH_DEG, domask=False): """ :param coord_sys: the coordinate system of the LocStream :param domask: a boolean to tell whether or not to add a mask :return: LocStream """ if ESMF.pet_count() is not 4: raise ValueError("processor count must be 4 to use this function") deg_rad = pi if coord_sys == ESMF.CoordSys.SPH_DEG: deg_rad = 180.0 locstream = None if ESMF.local_pet() is 0: locstream = ESMF.LocStream(4, coord_sys=coord_sys) locstream["ESMF:Lon"] = [0.0, 0.5*deg_rad, 0.0, 0.5*deg_rad] locstream["ESMF:Lat"] = [deg_rad/-2.0, deg_rad/-2.0, -0.25*deg_rad, -0.25*deg_rad] if domask: locstream["ESMF:Mask"] = np.array([1, 0, 1, 1], dtype=np.int32) elif ESMF.local_pet() is 1: locstream = ESMF.LocStream(4, coord_sys=coord_sys) locstream["ESMF:Lon"] = [1.5*deg_rad, 2*deg_rad, 1.5*deg_rad, 2*deg_rad] locstream["ESMF:Lat"] = [deg_rad/-2.0, deg_rad/-2.0, -0.25*deg_rad, -0.25*deg_rad] if domask: locstream["ESMF:Mask"] = np.array([0, 1, 1, 1], dtype=np.int32) elif ESMF.local_pet() is 2: locstream = ESMF.LocStream(4, coord_sys=coord_sys) locstream["ESMF:Lon"] = [0.0, 0.5*deg_rad, 0.0, 0.5*deg_rad] locstream["ESMF:Lat"] = [0.25*deg_rad, 0.25*deg_rad, deg_rad/2.0, deg_rad/2.0] if domask: locstream["ESMF:Mask"] = np.array([1, 1, 1, 1], dtype=np.int32) elif ESMF.local_pet() is 3: locstream = ESMF.LocStream(4, coord_sys=coord_sys) locstream["ESMF:Lon"] = [1.5*deg_rad, 2*deg_rad, 1.5*deg_rad, 2*deg_rad] locstream["ESMF:Lat"] = [0.25*deg_rad, 0.25*deg_rad, deg_rad/2.0, deg_rad/2.0] if domask: locstream["ESMF:Mask"] = np.array([1, 1, 1, 1], dtype=np.int32) return locstream
def create_locstream_16(domask=False): """ :param domask: a boolean to tell whether or not to add a mask :return: LocStream """ if ESMF.pet_count() is not 1: raise ValueError("processor count must be 1 to use this function") locstream = ESMF.LocStream(16) locstream["ESMF:X"] = [0.0, 1.5, 2.5, 4.0, 0.0, 1.5, 2.5, 4.0, 0.0, 1.5, 2.5, 4.0, 0.0, 1.5, 2.5, 4.0] locstream["ESMF:Y"] = [0.0, 0.0, 0.0, 0.0, 1.5, 1.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 4.0, 4.0, 4.0, 4.0] if domask: locstream["ESMF:Mask"] = [1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] return locstream
# cache_data_file(os.path.join(DD, "ll1deg_grid.nc")) import ESMF import numpy from functools import reduce # This call enables debug logging ESMF.Manager(debug=True) grid1 = "examples/data/ll1deg_grid.nc" grid = ESMF.Grid(filename=grid1, filetype=ESMF.FileFormat.SCRIP) from ESMF.test.test_api.locstream_utilities import create_locstream_spherical_16, create_locstream_spherical_16_parallel coord_sys=ESMF.CoordSys.SPH_DEG domask=True if ESMF.pet_count() == 1: locstream = create_locstream_spherical_16(coord_sys=coord_sys, domask=domask) else: if ESMF.pet_count() is not 4: raise ValueError("processor count must be 4 or 1 for this example") else: locstream = create_locstream_spherical_16_parallel(coord_sys=coord_sys, domask=domask) # create a field srcfield = ESMF.Field(locstream, name='srcfield') dstfield = ESMF.Field(grid, name='dstfield') xctfield = ESMF.Field(grid, name='xctfield') # initialize the fields [x, y] = [0, 1]
# Create a field on the centers of the destination grid. dstfield = ESMF.Field(dstgrid, name="dstfield", staggerloc=ESMF.StaggerLoc.CENTER) missing_val = 1000 dstfield.data[...] = missing_val # Regrid from source grid to destination grid. regridSrc2Dst = ESMF.Regrid(srcfield, dstfield, src_mask_values=numpy.array([2], dtype=numpy.int32), regrid_method=ESMF.RegridMethod.BILINEAR, unmapped_action=ESMF.UnmappedAction.IGNORE) dstfield = regridSrc2Dst(srcfield, dstfield, zero_region=ESMF.Region.SELECT) dgridCoordLat = dstgrid.get_coords(lat) dstmaskedlats = dgridCoordLat[numpy.where(dstfield.data == missing_val)] masked_values = dstmaskedlats.size try: # use mpi4py to collect values from mpi4py import MPI comm = MPI.COMM_WORLD masked_values = comm.reduce(dstmaskedlats.size, op=MPI.SUM) except: pass if ESMF.local_pet() == 0: assert (masked_values > 0) print("Successfully created a grid with masking and switched periodic dimensions for regridding!")
datafile = "examples/data/tasmax_day_CNRM-CM5_historical_r1i1p1_18500101-1850010.nc" gridfile = "examples/data/ll1deg_grid.nc" # Create a grid from a GRIDSPEC formatted file srcgrid = ESMF.Grid(filename=datafile, filetype=ESMF.FileFormat.GRIDSPEC) # create a field on the center stagger locations of the source grid srcfield = ESMF.Field(srcgrid, name='srcfield', staggerloc=ESMF.StaggerLoc.CENTER, ndbounds=[2]) srcfield.read(filename=datafile, variable="tasmax", ndbounds=2) # create a tripole grid dstgrid = ESMF.Grid(filename=gridfile, filetype=ESMF.FileFormat.SCRIP) # create fields on the center stagger locations of the tripole grid dstfield = ESMF.Field(dstgrid, name='dstfield', meshloc=ESMF.StaggerLoc.CENTER, ndbounds=[2]) dstfield.data[...] = 1e20 import ipdb; ipdb.set_trace() # create an object to regrid data from the source to the destination field regrid = ESMF.Regrid(srcfield, dstfield, regrid_method=ESMF.RegridMethod.BILINEAR, unmapped_action=ESMF.UnmappedAction.IGNORE) # do the regridding from source to destination field dstfield = regrid(srcfield, dstfield) # output the results from one processor only if ESMF.local_pet() is 0: print ("ESMPy Field Data Regridding Example Finished Successfully")
def validate(srcfield, dstfield, xctfield, srcfracfield=None, dstfracfield=None): # handle the destination fractions field default value csrverr = None if dstfracfield is None: dstfracfield = ESMF.Field(dstfield.grid) dstfracfield.data[:] = numpy.ones(dstfield.data.shape) # check the mass conservation in the case of conservative regridding csrv = False if ((srcfracfield is not None) and (dstfracfield is not None)): csrv = True # get the area fields srcareafield = ESMF.Field(srcfield.grid, name='srcareafield') dstareafield = ESMF.Field(dstfield.grid, name='dstareafield') srcareafield.get_area() dstareafield.get_area() csrverr = 0 srcmass = numpy.sum(numpy.abs(srcareafield.data * srcfracfield.data * srcfield.data)) # NOTE: this is a workaround for infinite values resulting from # infinite weights calculated for conservative regridding # with wonky cells in the nemo grid ind = numpy.where((dstfield.data != float('inf'))) dstmass = numpy.sum(numpy.abs(dstareafield.data[ind] * dstfield.data[ind])) if dstmass is not 0: csrverr = numpy.abs(srcmass - dstmass) / dstmass # compute the mean relative interpolation error from operator import mul # NOTE: first condition is a workaround for infinite values resulting from # infinite weights calculated for conservative regridding # with wonky cells in the nemo grid ind = numpy.where((dstfield.data != float('inf')) & (dstfield.data != 1e20) & (xctfield.data != 0) & (dstfracfield.data > .999)) num_nodes = reduce(mul, xctfield.data[ind].shape) relerr = numpy.sum(numpy.abs(dstfield.data[ind] / dstfracfield.data[ind] - xctfield.data[ind]) / numpy.abs(dstfield.data[ind])) meanrelerr = relerr / num_nodes # handle the parallel case if ESMF.pet_count() > 1: try: from mpi4py import MPI except: raise ImportError comm = MPI.COMM_WORLD meanrelerr = comm.reduce(meanrelerr, op=MPI.SUM) csrverr = comm.reduce(csrverr, op=MPI.SUM) # output the results from one processor only if ESMF.local_pet() is 0: print "ESMPy Tripole Regridding Example" print " interpolation mean relative error = {0}".format(meanrelerr) if csrv: print " mass conservation relative error = {0}".format(csrverr)
relerr += numpy.sum(numpy.abs(dstfield.data[level, timestep, :, :] / dstfracfield.data - xctfield.data[level, timestep, :, :]) / numpy.abs(xctfield.data[level, timestep, :, :])) # compute the mean relative interpolation and conservation error from operator import mul num_nodes = reduce(mul, xctfield.data.shape) meanrelerr = 0 if num_nodes is not 0: meanrelerr = relerr / num_nodes csrverr = 0 if dstmass is not 0: csrverr = numpy.abs(srcmass - dstmass) / dstmass # handle the parallel case if ESMF.pet_count() > 1: try: from mpi4py import MPI except: raise ImportError comm = MPI.COMM_WORLD relerr = comm.reduce(relerr, op=MPI.SUM) num_nodes = comm.reduce(num_nodes, op=MPI.SUM) srcmass = comm.reduce(srcmass, op=MPI.SUM) dstmass = comm.reduce(dstmass, op=MPI.SUM) # output the results from one processor only if ESMF.local_pet() is 0: meanrelerr = relerr / num_nodes csrverr = numpy.abs(srcmass - dstmass) / dstmass
import os import ESMF from ESMF.test.regrid_test.regrid_from_file_test.run_regrid_from_file_dryrun import cache_data_file grid1 = "T42_grid.nc" grid2 = "ne15np4_scrip.nc" #SCRIP prefix = 'data/' grid1 = prefix+grid1 grid2 = prefix+grid2 if ESMF.local_pet() == 0: if not os.path.exists(prefix): os.mkdir(prefix) response = cache_data_file(grid1) response = cache_data_file(grid2) # create a logically rectangular source grid for a SCRIP format file grid = ESMF.Grid(filename=grid1, \ filetype=ESMF.FileFormat.SCRIP, \ add_corner_stagger=True) # create a field on the center stagger locations of the source grid srcfield = ESMF.Field(grid, 'srcfield', staggerloc=ESMF.StaggerLoc.CENTER) # initialize the field to a constant value srcfield[...] = 25 # create an unstructured cubed-sphere destination mesh from a SCRIP format file mesh = ESMF.Mesh(filename=grid2, \ filetype=ESMF.FileFormat.SCRIP, \ convert_to_dual=False)
import ESMF # This call enables debug logging # esmpy = ESMF.Manager(debug=True) print("Hello ESMPy World from PET (processor) {0}!".format(ESMF.local_pet()))
def regrid_check(src_fname, dst_fname, regrid_method, options, itrp_mean_err, itrp_max_err, csrv_err): # print "\nregrid_weight_gen_check.py: mesh_check()" parallel = False if ESMF.pet_count() > 1: parallel = True # Settings for regrid (src_type_str, dst_type_str, src_meshname, dst_meshname, unmapped_action, pole_method_str, src_regional, dst_regional, src_missingvalue, dst_missingvalue) = parse_options(options) src_type = file_type_map[src_type_str] dst_type = file_type_map[dst_type_str] regrid_method = regrid_method_map[regrid_method] convert_to_dual = (regrid_method != ESMF.RegridMethod.CONSERVE) add_corner_stagger = (regrid_method == ESMF.RegridMethod.CONSERVE) src_is_sphere = not src_regional dst_is_sphere = not dst_regional pole_method = None pole_method_npntavg = 1 if pole_method_str: if pole_method_str in pole_method_map: pole_method = pole_method_map[pole_method_str] else: pole_method = ESMF.PoleMethod.NPNTAVG pole_method_npntavg = int(pole_method_str) src_mask = False srcgrid, src_is_mesh, src_mask = create_grid_or_mesh_from_file(src_fname, src_type, meshname=src_meshname, convert_to_dual=convert_to_dual, isSphere=src_is_sphere, add_corner_stagger=add_corner_stagger, missingvalue=src_missingvalue) dst_mask = False dstgrid, dst_is_mesh, dst_mask = create_grid_or_mesh_from_file(dst_fname, dst_type, meshname=dst_meshname, convert_to_dual=convert_to_dual, isSphere=dst_is_sphere, add_corner_stagger=add_corner_stagger, missingvalue=dst_missingvalue) # Get coordinates in radians. src_lons, src_lats = get_coords_from_grid_or_mesh(srcgrid, src_is_mesh, regrid_method) dst_lons, dst_lats = get_coords_from_grid_or_mesh(dstgrid, dst_is_mesh, regrid_method) # create Field objects on the Grids srcfield = create_field(srcgrid, 'srcfield', regrid_method=regrid_method) dstfield = create_field(dstgrid, 'dstfield', regrid_method=regrid_method) dstfield2 = create_field(dstgrid, 'dstfield_exact', regrid_method=regrid_method) #create the frac fields srcfracfield = create_field(srcgrid, 'src_frac_field', regrid_method=regrid_method) dstfracfield = create_field(dstgrid, 'dst_frac_field', regrid_method=regrid_method) # initialize the Fields to an analytic function srcfield = build_analyticfield(srcfield, src_lons, src_lats) dstfield2 = build_analyticfield(dstfield2, dst_lons, dst_lats) # run the ESMF regridding dstfield.data[...] = UNINITVAL dstfield = run_regridding(srcfield, dstfield, src_mask, dst_mask, regrid_method, unmapped_action, srcfracfield, dstfracfield, pole_method=pole_method, regrid_pole_npoints=pole_method_npntavg) srcmass = None dstmass = None if regrid_method == ESMF.RegridMethod.CONSERVE: if src_is_mesh: srcmass = compute_mass_mesh(srcfield, dofrac=True, fracfield=srcfracfield) else: srcmass = compute_mass_grid(srcfield, dofrac=True, fracfield=srcfracfield) if dst_is_mesh: dstmass = compute_mass_mesh(dstfield, uninitval=UNINITVAL) else: dstmass = compute_mass_grid(dstfield, uninitval=UNINITVAL) else: srcfracfield.destroy() dstfracfield.destroy() srcfracfield = None dstfracfield = None correct = compare_fields(dstfield, dstfield2, itrp_mean_err, itrp_max_err, csrv_err, parallel=parallel, dstfracfield=dstfracfield, mass1=srcmass, mass2=dstmass, regrid_method=regrid_method, uninitval=UNINITVAL) # Destroy ESMF objects srcfield.destroy() dstfield.destroy() dstfield2.destroy() if regrid_method == ESMF.RegridMethod.CONSERVE: srcfracfield.destroy() dstfracfield.destroy() srcgrid.destroy() dstgrid.destroy() return correct
def compare_fields(field1, field2, itrp_mean_tol, itrp_max_tol, csrv_tol, parallel=False, dstfracfield=None, mass1=None, mass2=None, regrid_method=ESMF.RegridMethod.CONSERVE, uninitval=422397696., mask_values=[0]): ''' PRECONDITIONS: Two Fields have been created and a comparison of the the values is desired between 'srcfield' and 'dstfield'. POSTCONDITIONS: The values on 'srcfield' and 'dstfield' are compared. ''' import numpy.ma as ma correct = False # verify that the fields are the same size assert field1.data.shape == field2.data.shape, 'compare_fields: Fields must be the same size!' # deal with default values for fracfield if dstfracfield is None: dstfracfield = ma.ones(field1.data.shape) # compute pointwise error measures totalErr = 0.0 max_error = 0.0 min_error = 1000000.0 num_nodes = 0 # allow fields of all dimensions field1_flat = np.ravel(field1.data) field2_flat = np.ravel(field2.data) dstfracfield_flat = np.ravel(dstfracfield.data) # setup mask, no Mask on a Mesh (yet) so need to look at the type first field2mask_flat = np.ravel(np.zeros_like(field2.data)) if type(field2.grid) is ESMF.Grid: if (field2.grid.mask[field2.staggerloc] is not None): field2mask_flat = [True if x in mask_values else False for x in field2.grid.mask[field2.staggerloc].flatten().tolist()] for i in range(field2_flat.size): if ((not field2mask_flat[i]) and (field1_flat[i] != uninitval) and (dstfracfield_flat[i] >= 0.999)): if (field2_flat.data[i] != 0.0): err = abs(field1_flat[i]/dstfracfield_flat[i] - \ field2_flat[i])/abs(field2_flat[i]) else: err = abs(field1_flat[i]/dstfracfield_flat[i] - \ field2_flat[i]) if err > 1: print(field1_flat[i], field2_flat[i], dstfracfield_flat[i]) num_nodes += 1 totalErr += err if (err > max_error): max_error = err if (err < min_error): min_error = err # gather error on processor 0 or set global variables in serial case mass1_global = 0. mass2_global = 0. if parallel: # use mpi4py to collect values from mpi4py import MPI comm = MPI.COMM_WORLD total_error_global = comm.reduce(totalErr, op=MPI.SUM) num_nodes_global = comm.reduce(num_nodes, op=MPI.SUM) max_error_global = comm.reduce(max_error, op=MPI.MAX) min_error_global = comm.reduce(min_error, op=MPI.MIN) if (mass1 is not None) and (mass2 is not None): mass1_global = comm.reduce(mass1, op=MPI.SUM) mass2_global = comm.reduce(mass2, op=MPI.SUM) else: total_error_global = totalErr num_nodes_global = num_nodes max_error_global = max_error min_error_global = min_error if (mass1 is not None) and (mass2 is not None): mass1_global = mass1 mass2_global = mass2 # compute relative error measures and compare against tolerance values itrp_mean = False itrp_max = False csrv = False if ESMF.local_pet() == 0: if mass1_global == 0.: csrv_error_global = abs(mass2_global - mass1_global) else: csrv_error_global = abs(mass2_global - mass1_global)/abs(mass1_global) # compute mean relative error if num_nodes_global != 0: total_error_global = total_error_global/num_nodes_global # determine if interpolation and conservation are up to spec if (total_error_global < itrp_mean_tol): itrp_mean = True if (max_error_global < itrp_max_tol): itrp_max = True if (csrv_error_global < csrv_tol): csrv = True # print out diagnostic information print(" Mean relative error = "+str(total_error_global)) print(" Max relative error = "+str(max_error_global)) print(" Conservation error = "+str(csrv_error_global)) #print " Min error = "+str(min_error_global) #print " srcmass = "+str(mass1_global) #print " dstmass = "+str(mass2_global) # broadcast in parallel case if parallel: itrp_mean, itrp_max, csrv = \ MPI.COMM_WORLD.bcast([itrp_mean, itrp_max, csrv],0) # print pass or fail if (itrp_mean and itrp_max and csrv): print("PET{0} - PASS".format(ESMF.local_pet())) correct = True else: print("PET{0} - FAIL".format(ESMF.local_pet())) return correct
import ESMF except: raise ImportError('The ESMF library cannot be found!') from ESMF.test.regrid_from_file.regrid_from_file_consts import DATA_SUBDIR from ESMF.test.regrid_from_file.run_regrid_from_file_dryrun import cache_data_files_for_test_cases from ESMF.test.regrid_from_file.regrid_check import regrid_check from ESMF.test.regrid_from_file.read_test_cases_from_control_file import read_control_file # Start up ESMF and run regrid test for each line of options # read from a control file. Retrieve data files for each test from a remote # server if they do not exist locally. # Start up ESMF. esmp = ESMF.Manager(debug=True) parallel = False if ESMF.pet_count() > 1: parallel = True # Read the test case parameters from the control file. test_cases = read_control_file() if (ESMF.local_pet() == 0): # Retrieve the data files needed for the test cases from the remote server. status_ok = cache_data_files_for_test_cases(test_cases) # For each test case line from the control file parse the line and call # the test subroutine. for test_case in test_cases: (src_fname, dst_fname, regrid_method, options, itrp_mean_err, itrp_max_err, csrv_err) = test_case test_str = 'Regrid %s to %s as %s with %s itrp_mean_err=%f, itrp_max_err=%f, and csrv_err=%f' % (src_fname, dst_fname, regrid_method, options, itrp_mean_err, itrp_max_err, csrv_err)
def compare_fields_grid(field1, field2, itrp_tol, csrv_tol, parallel=False, dstfracfield=None, mass1=None, mass2=None, regrid_method=ESMF.RegridMethod.CONSERVE, mask_values=[0]): ''' PRECONDITIONS: Two Fields have been created and a comparison of the the values is desired between 'field1' and 'field2'. The fields should be the same size on have rank=2 or 3. POSTCONDITIONS: The values on 'field1' and 'field2' are compared against the each other. ''' import numpy.ma as ma correct = False # verify that the fields are the same size assert field1.data.shape == field2.data.shape, 'compare_fields: Fields must be the same size!' # deal with default values for fracfield if dstfracfield is None: dstfracfield = ma.ones(field1.data.shape) # compute pointwise error measures totalErr = 0.0 max_error = 0.0 min_error = 1000000.0 num_nodes = 0 # allow fields of all dimensions field1_flat = np.ravel(field1.data) field2_flat = np.ravel(field2.data) dstfracfield_flat = np.ravel(dstfracfield.data) # TODO: test for evaluating field2mask into an array of True/False values based on field2.grid.mask if field2.grid.mask[field2.staggerloc] is not None: field2mask_flat = [True if x in mask_values else False for x in field2.grid.mask[field2.staggerloc].flatten().tolist()] else: field2mask_flat = np.ravel(np.zeros_like(field2.data)) # TODO: would be nice to add a condition to ignore where original value is unchanged for i in range(field2_flat.size): if ((not field2mask_flat[i]) and (regrid_method != ESMF.RegridMethod.CONSERVE or dstfracfield_flat[i] >= 0.999) and field2_flat[i] != 0.0): err = abs(field1_flat[i]/dstfracfield_flat[i] - \ field2_flat[i])/abs(field2_flat[i]) num_nodes += 1 totalErr += err if (err > max_error): max_error = err if (err < min_error): min_error = err # gather error on processor 0 or set global variables in serial case mass1_global = 0 mass2_global = 0 csrv_error_global = 0 if parallel: # use mpi4py to collect values from mpi4py import MPI comm = MPI.COMM_WORLD total_error_global = comm.reduce(totalErr, op=MPI.SUM) num_nodes_global = comm.reduce(num_nodes, op=MPI.SUM) max_error_global = comm.reduce(max_error, op=MPI.MAX) min_error_global = comm.reduce(min_error, op=MPI.MIN) if (mass1 and mass2): mass1_global = comm.reduce(mass1, op=MPI.SUM) mass2_global = comm.reduce(mass2, op=MPI.SUM) else: total_error_global = totalErr num_nodes_global = num_nodes max_error_global = max_error min_error_global = min_error if (mass1 and mass2): mass1_global = mass1 mass2_global = mass2 # compute relative error measures and compare against tolerance values itrp = False csrv = False if ESMF.local_pet() == 0: if mass1_global == 0: csrv_error_global = abs(mass2_global - mass1_global) else: csrv_error_global = abs(mass2_global - mass1_global)/abs(mass1_global) # compute mean relative error if num_nodes != 0: total_error_global = total_error_global/num_nodes_global # determine if interpolation and conservation are up to spec if (total_error_global < itrp_tol): itrp = True if (csrv_error_global < csrv_tol): csrv = True # print out diagnostic information print(" Mean relative error = "+str(total_error_global)) print(" Max relative error = "+str(max_error_global)) print(" Conservation error = "+str(csrv_error_global)) #print " Min error = "+str(min_error_global) #print " srcmass = "+str(mass1_global) #print " dstmass = "+str(mass2_global) # broadcast in parallel case if parallel: itrp, csrv = MPI.COMM_WORLD.bcast([itrp, csrv],0) total_error_global, csrv_error_global = \ MPI.COMM_WORLD.bcast([total_error_global, csrv_error_global], 0) # print pass or fail assert (itrp and csrv) if (itrp and csrv): print("PET{0} - PASS".format(ESMF.local_pet())) correct = True else: print("PET{0} - FAIL".format(ESMF.local_pet())) return total_error_global, csrv_error_global
import ESMF cs_grid = ESMF.Grid(tilesize=6, name="cubed_sphere") cs_lon = cs_grid.get_coords(0) cs_lat = cs_grid.get_coords(1) print str(ESMF.local_pet())+" "+str(cs_lon) print str(ESMF.local_pet())+" "+str(cs_lat)