def make_analysis_polar_map(config, mesh_name, projection): # {{{ mesh_filename = '../mesh.nc' upperProj = projection[0].upper() + projection[1:] inDescriptor = MpasMeshDescriptor(mesh_filename, mesh_name) comparisonStereoWidth = config.getfloat( 'mapping_analysis', 'comparison{}StereoWidth'.format(upperProj)) comparisonStereoResolution = config.getfloat( 'mapping_analysis', 'comparison{}StereoResolution'.format(upperProj)) outDescriptor = get_polar_descriptor(Lx=comparisonStereoWidth, Ly=comparisonStereoWidth, dx=comparisonStereoResolution, dy=comparisonStereoResolution, projection=projection) outGridName = '{}x{}km_{}km_{}_stereo'.format(comparisonStereoWidth, comparisonStereoWidth, comparisonStereoResolution, upperProj) mappingFileName = 'map_{}_to_{}_bilinear.nc'.format(mesh_name, outGridName) remapper = Remapper(inDescriptor, outDescriptor, mappingFileName) mpiTasks = config.getint('main', 'nprocs') remapper.build_mapping_file(method='bilinear', mpiTasks=mpiTasks, tempdir='.')
def build_remapper(self, sourceDescriptor, destinationDescriptor, weightFileName): remapper = Remapper(sourceDescriptor, destinationDescriptor, weightFileName) remapper.build_mapping_file(method='bilinear') assert os.path.exists(remapper.mappingFileName) return remapper
def _make_mapping_file(mesh_name, outGridName, inDescriptor, outDescriptor, cores, config, logger): parallel_executable = config.get('parallel', 'parallel_executable') mappingFileName = 'map_{}_to_{}_bilinear.nc'.format(mesh_name, outGridName) remapper = Remapper(inDescriptor, outDescriptor, mappingFileName) remapper.build_mapping_file(method='bilinear', mpiTasks=cores, tempdir='.', logger=logger, esmf_parallel_exec=parallel_executable)
def make_analysis_lat_lon_map(config, mesh_name): # {{{ mesh_filename = '../mesh.nc' inDescriptor = MpasMeshDescriptor(mesh_filename, mesh_name) comparisonLatResolution = config.getfloat('mapping_analysis', 'comparisonLatResolution') comparisonLonResolution = config.getfloat('mapping_analysis', 'comparisonLonResolution') # modify the resolution of the global lat-lon grid as desired outDescriptor = get_lat_lon_descriptor(dLon=comparisonLatResolution, dLat=comparisonLonResolution) outGridName = outDescriptor.meshName mappingFileName = 'map_{}_to_{}_bilinear.nc'.format(mesh_name, outGridName) remapper = Remapper(inDescriptor, outDescriptor, mappingFileName) mpiTasks = config.getint('main', 'nprocs') remapper.build_mapping_file(method='bilinear', mpiTasks=mpiTasks, tempdir='.')
def remap_rignot(inFileName, meshFileName, meshName, outFileName, mappingDirectory='.', method='conserve', renormalizationThreshold=None, inVarName='melt_actual', mpiTasks=1): # {{{ """ Remap the Rignot et al. (2013) melt rates at 1 km resolution to an MPAS mesh Parameters ---------- inFileName : str The original Rignot et al. (2013) melt rates meshFileName : str The MPAS mesh meshName : str The name of the mesh (e.g. oEC60to30wISC), used in the name of the mapping file outFileName : str The melt rates interpolated to the MPAS mesh with ocean sensible heat fluxes added on (assuming insulating ice) mappingDirectory : str The directory where the mapping file should be stored (if it is to be computed) or where it already exists (if not) method : {'bilinear', 'neareststod', 'conserve'}, optional The method of interpolation used, see documentation for `ESMF_RegridWeightGen` for details. renormalizationThreshold : float, optional The minimum weight of a denstination cell after remapping, below which it is masked out, or ``None`` for no renormalization and masking. inVarName : {'melt_actual', 'melt_steadystate'} Whether to use the melt rate for the time period covered in Rignot et al. (2013) with observed thinning/thickening or the melt rates that would be required if ice shelves were in steady state. mpiTasks : int, optional The number of MPI tasks to use to compute the mapping file """ ds = xr.open_dataset(inFileName) lx = np.abs(1e-3 * (ds.xaxis.values[-1] - ds.xaxis.values[0])) ly = np.abs(1e-3 * (ds.yaxis.values[-1] - ds.yaxis.values[0])) inGridName = '{}x{}km_1.0km_Antarctic_stereo'.format(lx, ly) projection = pyproj.Proj('+proj=stere +lat_ts=-71.0 +lat_0=-90 +lon_0=0.0 ' '+k_0=1.0 +x_0=0.0 +y_0=0.0 +ellps=WGS84') inDescriptor = ProjectionGridDescriptor.read(projection, inFileName, xVarName='xaxis', yVarName='yaxis', meshName=inGridName) # convert to the units and variable names expected in MPAS-O rho_fw = 1000. s_per_yr = 365. * 24. * 60. * 60. latent_heat_of_fusion = 3.337e5 ds['prescribedLandIceFreshwaterFlux'] = ds[inVarName] * rho_fw / s_per_yr ds['prescribedLandIceHeatFlux'] = (latent_heat_of_fusion * ds['prescribedLandIceFreshwaterFlux']) ds = ds.drop_vars(['melt_actual', 'melt_steadystate', 'lon', 'lat']) outDescriptor = MpasMeshDescriptor(meshFileName, meshName) mappingFileName = '{}/map_{}_to_{}.nc'.format(mappingDirectory, inGridName, meshName) remapper = Remapper(inDescriptor, outDescriptor, mappingFileName) remapper.build_mapping_file(method=method, mpiTasks=mpiTasks) dsRemap = remapper.remap(ds, renormalizationThreshold=renormalizationThreshold) for field in [ 'prescribedLandIceFreshwaterFlux', 'prescribedLandIceHeatFlux' ]: # zero out the field where it's currently NaN dsRemap[field] = dsRemap[field].where(dsRemap[field].nonnull(), 0.) dsRemap.attrs['history'] = ' '.join(sys.argv) write_netcdf(dsRemap, outFileName) # }}}
def get_remapper(config, sourceDescriptor, comparisonDescriptor, mappingFilePrefix, method, logger=None): # {{{ """ Given config options and descriptions of the source and comparison grids, returns a ``pyremap.Remapper`` object that can be used to remap from source files or data sets to corresponding data sets on the comparison grid. If necessary, creates the mapping file containing weights and indices needed to perform remapping. Parameters ---------- config : instance of ``MpasAnalysisConfigParser`` Contains configuration options sourceDescriptor : ``MeshDescriptor`` subclass object A description of the source mesh or grid comparisonDescriptor : ``MeshDescriptor`` subclass object A description of the comparison grid mappingFilePrefix : str A prefix to be prepended to the mapping file name method : {'bilinear', 'neareststod', 'conserve'} The method of interpolation used. logger : ``logging.Logger``, optional A logger to which ncclimo output should be redirected Returns ------- remapper : ``pyremap.Remapper`` object A remapper that can be used to remap files or data sets from the source grid or mesh to the comparison grid. """ # Authors # ------- # Xylar Asay-Davis mappingFileName = None if not _matches_comparison(sourceDescriptor, comparisonDescriptor): # we need to remap because the grids don't match mappingBaseName = '{}_{}_to_{}_{}.nc'.format( mappingFilePrefix, sourceDescriptor.meshName, comparisonDescriptor.meshName, method) tryCustom = config.get('diagnostics', 'customDirectory') != 'none' if tryCustom: # first see if mapping files are in the custom directory mappingSubdirectory = build_config_full_path( config, 'diagnostics', 'mappingSubdirectory', baseDirectoryOption='customDirectory') mappingFileName = '{}/{}'.format(mappingSubdirectory, mappingBaseName) if not tryCustom or not os.path.exists(mappingFileName): # second see if mapping files are in the base directory mappingSubdirectory = build_config_full_path( config, 'diagnostics', 'mappingSubdirectory', baseDirectoryOption='baseDirectory') mappingFileName = '{}/{}'.format(mappingSubdirectory, mappingBaseName) if not os.path.exists(mappingFileName): # we don't have a mapping file yet, so get ready to create one # in the output subfolder if needed mappingSubdirectory = \ build_config_full_path(config, 'output', 'mappingSubdirectory') make_directories(mappingSubdirectory) mappingFileName = '{}/{}'.format(mappingSubdirectory, mappingBaseName) remapper = Remapper(sourceDescriptor, comparisonDescriptor, mappingFileName) remapper.build_mapping_file(method=method, logger=logger) return remapper # }}}
from pyremap import LatLonGridDescriptor, Remapper from mpas_analysis.shared.constants import constants inputFileName = '/media/xylar/extra_data/analysis/output/GMPAS-QU240/' \ 'remap_obs/clim/obs/mld_1.0x1.0degree.nc' obsDescriptor = LatLonGridDescriptor.read(fileName=inputFileName, latVarName='lat', lonVarName='lon') comparisonLatRes = 4. comparisonLonRes = 4. nLat = int((constants.latmax - constants.latmin) / comparisonLatRes) + 1 nLon = int((constants.lonmax - constants.lonmin) / comparisonLonRes) + 1 lat = numpy.linspace(constants.latmin, constants.latmax, nLat) lon = numpy.linspace(constants.lonmin, constants.lonmax, nLon) comparisonDescriptor = LatLonGridDescriptor.create(lat, lon, units='degrees') remapper = Remapper(obsDescriptor, comparisonDescriptor, mappingFileName='map.nc') remapper.build_mapping_file() remapper.remap_file(inputFileName, 'mld_4.0x4.0degree.nc', ['mld', 'month', 'year'], renormalize=0.05)
def _remap(config, modelFolder): res = get_res(config) hres = get_horiz_res(config) modelName = config.get('model', 'name') inFileNames = {} outFileNames = {} bothExist = True for fieldName in ['temperature', 'salinity']: inFileNames[fieldName] = \ '{}/{}_{}_interp_z.nc'.format(modelFolder, modelName, fieldName) outFileNames[fieldName] = \ '{}/{}_{}_{}.nc'.format(modelFolder, modelName, fieldName, res) if not os.path.exists(outFileNames[fieldName]): bothExist = False if bothExist: return print(' Remapping to {} grid...'.format(res)) for fieldName in inFileNames: inFileName = inFileNames[fieldName] outFileName = outFileNames[fieldName] if os.path.exists(outFileName): continue outGridFileName = 'ismip6/{}_grid.nc'.format(hres) print(' {}'.format(outFileName)) progressDir = '{}/progress_remap_{}'.format(modelFolder, fieldName) try: os.makedirs(progressDir) except OSError: pass ds = xarray.open_dataset(inFileName) if len(ds.lon.dims) == 1: inDescriptor = LatLonGridDescriptor.read(inFileName, latVarName='lat', lonVarName='lon') else: assert (len(ds.lon.dims) == 2) inDescriptor = LatLon2DGridDescriptor.read(inFileName, latVarName='lat', lonVarName='lon') inDescriptor.regional = True outDescriptor = get_polar_descriptor_from_file(outGridFileName, projection='antarctic') mappingFileName = '{}/map_{}_to_{}.nc'.format(modelName.lower(), inDescriptor.meshName, outDescriptor.meshName) remapper = Remapper(inDescriptor, outDescriptor, mappingFileName) remapper.build_mapping_file(method='bilinear') ds = ds.drop_vars(['lat', 'lon']) nt = ds.sizes['time'] widgets = [ ' ', progressbar.Percentage(), ' ', progressbar.Bar(), ' ', progressbar.ETA() ] print(f' remapping: {fieldName}') bar = progressbar.ProgressBar(widgets=widgets, maxval=nt).start() for tIndex in range(nt): progressFileName = '{}/{}_t_{}.nc'.format(progressDir, modelName, tIndex) if os.path.exists(progressFileName): bar.update(tIndex + 1) continue dsIn = ds.isel(time=tIndex) dsOut = remapper.remap(dsIn, renormalizationThreshold=0.1) dsOut = dsOut.transpose('z', 'y', 'x') for attrName in ['units', 'standard_name', 'long_name']: if attrName in ds[fieldName].attrs: dsOut[fieldName].attrs[attrName] = \ ds[fieldName].attrs[attrName] dsOut.z.attrs = ds.z.attrs dsOut.to_netcdf(progressFileName) bar.update(tIndex + 1) bar.finish() dsOut = xarray.open_mfdataset('{}/{}_t_*.nc'.format( progressDir, modelName), combine='nested', concat_dim='time') dsOut['z_bnds'] = ds.z_bnds dsOut.to_netcdf(outFileName)
inGridName = 'oQU240' # replace with the path to the desired mesh or restart file # As an example, use: # https://web.lcrc.anl.gov/public/e3sm/inputdata/ocn/mpas-o/oQU240/ocean.QU.240km.151209.nc inGridFileName = 'ocean.QU.240km.151209.nc' inDescriptor = MpasMeshDescriptor(inGridFileName, inGridName) # modify the size and resolution of the Antarctic grid as desired outDescriptor = get_polar_descriptor(Lx=6000., Ly=6000., dx=10., dy=10., projection='antarctic') outGridName = outDescriptor.meshName mappingFileName = 'map_{}_to_{}_conserve.nc'.format(inGridName, outGridName) remapper = Remapper(inDescriptor, outDescriptor, mappingFileName) # conservative remapping with 4 MPI tasks (using mpirun) remapper.build_mapping_file(method='conserve', mpiTasks=4) outFileName = 'temp_{}.nc'.format(outGridName) ds = xarray.open_dataset(inGridFileName) dsOut = xarray.Dataset() dsOut['temperature'] = ds['temperature'] dsOut = remapper.remap(dsOut) dsOut.to_netcdf(outFileName)
inDescriptor = MpasMeshDescriptor(inGridFileName, inGridName) # modify the size and resolution of the Antarctic grid as desired outDescriptor = get_polar_descriptor(Lx=6000., Ly=5000., dx=10., dy=10., projection='antarctic') outGridName = outDescriptor.meshName mappingFileName = 'map_{}_to_{}_bilinear.nc'.format(inGridName, outGridName) remapper = Remapper(inDescriptor, outDescriptor, mappingFileName) # conservative remapping with 4 MPI tasks (using mpirun) remapper.build_mapping_file(method='bilinear', mpiTasks=4) # select the SST at the initial time as an example data set srcFileName = 'temp_{}.nc'.format(inGridName) ds = xarray.open_dataset(inGridFileName) dsOut = xarray.Dataset() dsOut['temperature'] = ds['temperature'].isel(nVertLevels=0, Time=0) dsOut.to_netcdf(srcFileName) # do remapping with ncremap outFileName = 'temp_{}_file.nc'.format(outGridName) remapper.remap_file(srcFileName, outFileName) # do remapping again, this time with python remapping outFileName = 'temp_{}_array.nc'.format(outGridName) dsOut = remapper.remap(dsOut)
Ly = int((y[-1] - y[0]) / 1000.) inMeshName = '{}x{}km_{}km_Antarctic_stereo'.format(Lx, Ly, dx) projection = get_antarctic_stereographic_projection() inDescriptor = ProjectionGridDescriptor.create(projection, x, y, inMeshName) outRes = args.resolution * 1e3 nxOut = int((x[-1] - x[0]) / outRes + 0.5) + 1 nyOut = int((y[-1] - y[0]) / outRes + 0.5) + 1 xOut = x[0] + outRes * numpy.arange(nxOut) yOut = y[0] + outRes * numpy.arange(nyOut) outMeshName = '{}x{}km_{}km_Antarctic_stereo'.format(Lx, Ly, args.resolution) outDescriptor = ProjectionGridDescriptor.create(projection, xOut, yOut, outMeshName) mappingFileName = 'map_{}_to_{}_{}.nc'.format(inMeshName, outMeshName, args.method) remapper = Remapper(inDescriptor, outDescriptor, mappingFileName) remapper.build_mapping_file(method=args.method, mpiTasks=args.mpiTasks) dsOut = remapper.remap(dsIn, renormalizationThreshold=0.01) dsOut.to_netcdf(args.outFileName)