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