Example #1
0
    def test_identical_remapping(self, input_dir, output_dir):
        """
        Remap between two identical grids
        """

        my_dir = os.path.dirname(os.path.realpath(__file__))
        cmd = [os.path.join(my_dir, '../', 'remapweights.py')]

        mom_hgrid = os.path.join(input_dir, 'grid_spec.nc')
        mom_mask = os.path.join(input_dir, 'grid_spec.nc')

        output = os.path.join(output_dir, 'MOM_MOM_conserve.nc')

        args = [
            'MOM', 'MOM', '--src_grid', mom_hgrid, '--dest_grid', mom_hgrid,
            '--output', output
        ]
        ret = sp.call(cmd + args)
        assert ret == 0
        assert os.path.exists(output)

        # Only use these to pull out the dimensions of the grids.
        mom = MomGrid.fromfile(mom_hgrid, mask_file=mom_mask)

        src = np.empty_like(mom.x_t)
        for i in range(src.shape[0]):
            src[i, :] = i

        remap(src, output, src.shape)
Example #2
0
def main():

    parser = argparse.ArgumentParser()
    parser.add_argument('woa_input', help='The WOA input file.')
    parser.add_argument('ocean_hgrid',
                        help='The horizontal MOM grid definition to remap to')
    parser.add_argument(
        'old_salt_sfc_restore',
        help='The old salt sfc restoring file. Needed for metadata.')
    parser.add_argument('output', help='salt_sfc_restore.nc file for MOM5')
    parser.add_argument(
        '--interpolation_weights',
        default=None,
        help='Interpolation weights, file if not given this will be created.')
    parser.add_argument('--method',
                        default='patch',
                        help="""
                        Interpolation method, passed to ESMF_RegridWeightGen."""
                        )
    parser.add_argument('--npes',
                        default=None,
                        help="""
                        The number of PEs to use. Default is 1/2 of available."""
                        )

    args = parser.parse_args()

    if args.npes is None:
        import multiprocessing as mp
        args.npes = mp.cpu_count() // 2

    src_grid = WoaGrid(args.woa_input, calc_areas=False)
    dest_grid = MomGrid.fromfile(args.ocean_hgrid, calc_areas=False)
    dest_res = (dest_grid.num_lat_points, dest_grid.num_lon_points)

    if args.interpolation_weights is None:
        weights = create_weights(src_grid, dest_grid, args.npes, args.method)
    else:
        weights = args.interpolation_weights

    with nc.Dataset(args.woa_input) as f:
        src = f.variables['so'][:]

    dest = np.zeros((src.shape[0], dest_res[0], dest_res[1]))

    for t in range(src.shape[0]):
        smooth_src = smooth2d(src[t, :, :])
        dest[t, :, :] = remap(smooth_src, weights, dest_res)

        if 'conserve' in args.method:
            rel_err = calc_regridding_err(weights, smooth_src, dest[t, :, :])
            print('relative error {}'.format(rel_err))
            assert rel_err < 1e-14

    shutil.copyfile(args.old_salt_sfc_restore, args.output)
    with nc.Dataset(args.output, 'r+') as f:
        f.variables['salt'][:] = dest
Example #3
0
    def test_convert_mom_to_cice(self, input_dir, output_dir):
        """
        Read in a MOM grid and write out a cice grid at the same resolution.
        """

        mask = os.path.join(input_dir, 'ocean_01_mask.nc')
        hgrid = os.path.join(input_dir, 'ocean_01_hgrid.nc')
        mom = MomGrid.fromfile(hgrid, mask_file=mask)
        cice = CiceGrid.fromgrid(mom)
        grid_file = os.path.join(output_dir, 'grid.nc')
        mask_file = os.path.join(output_dir, 'kmt.nc')
        cice.write(grid_file, mask_file)
Example #4
0
def get_grid(filename):

    try:
        grid = MomGrid.fromfile(filename)
        return grid
    except KeyError as e:
        print("Not a mom grid: ", type(e), str(e))

    try:
        grid = WoaGrid(filename)
        return grid
    except KeyError as e:
        print("Not a WOA grid: ", type(e), str(e))
Example #5
0
def main():

    parser = argparse.ArgumentParser()
    parser.add_argument('woa_input', help='The WOA input file.')
    parser.add_argument('ocean_hgrid',
                        help='The horizontal MOM grid definition to remap to')
    parser.add_argument('old_salt_sfc_restore',
                        help='The old salt sfc restoring file. Needed for metadata.')
    parser.add_argument('output', help='salt_sfc_restore.nc file for MOM5')
    parser.add_argument('--interpolation_weights', default=None,
                        help='Interpolation weights, file if not given this will be created.')
    parser.add_argument('--method', default='patch', help="""
                        Interpolation method, passed to ESMF_RegridWeightGen.""")
    parser.add_argument('--npes', default=None, help="""
                        The number of PEs to use. Default is 1/2 of available.""")


    args = parser.parse_args()

    if args.npes is None:
        import multiprocessing as mp
        args.npes = mp.cpu_count() // 2

    src_grid = WoaGrid(args.woa_input, calc_areas=False)
    dest_grid = MomGrid.fromfile(args.ocean_hgrid, calc_areas=False)
    dest_res = (dest_grid.num_lat_points, dest_grid.num_lon_points)

    if args.interpolation_weights is None:
        weights = create_weights(src_grid, dest_grid, args.npes, 'conserve')
    else:
        weights = args.interpolation_weights

    with nc.Dataset(args.woa_input) as f:
        src = f.variables['so'][:]

    dest = np.zeros((src.shape[0], dest_res[0], dest_res[1]))

    for t in range(src.shape[0]):
        smooth_src = smooth2d(src[t, :, :])
        dest[t, :, :] = remap(smooth_src, weights, dest_res)

        if 'conserve' in args.method:
            rel_err = calc_regridding_err(weights, smooth_src, dest[t, :, :])
            print('relative error {}'.format(rel_err))
            assert rel_err < 1e-14

    shutil.copyfile(args.old_salt_sfc_restore, args.output)
    with nc.Dataset(args.output, 'r+') as f:
        import pdb
        pdb.set_trace()
        f.variables['salt'][:] = dest
Example #6
0
def remap_to_tenth(input_dir, output_dir, src_field, weights=None):
    """
    Remap MOM quarter degree to MOM tenth.

    This is used to remap OASIS and CICE restarts.
    """

    quarter_hgrid = os.path.join(input_dir, 'ocean_hgrid.nc')
    quarter_mask = os.path.join(input_dir, 'ocean_mask.nc')
    mom_quarter = MomGrid.fromfile(quarter_hgrid, mask_file=quarter_mask)

    tenth_hgrid = os.path.join(input_dir, 'ocean_01_hgrid.nc')
    tenth_mask = os.path.join(input_dir, 'ocean_01_mask.nc')
    mom_tenth = MomGrid.fromfile(tenth_hgrid)

    # The src_field has land points, fill these in to avoid masking mess.
    new_src_field = fill_mask_with_nearest_neighbour(src_field,
                                                     mom_quarter.mask_t)

    if weights is None:
        my_dir = os.path.dirname(os.path.realpath(__file__))

        weights = os.path.join(output_dir, 'MOM025_MOM10th_conserve.nc')
        cmd = [os.path.join(my_dir, '../', 'remapweights.py')]
        args = [
            'MOM', 'MOM', '--src_grid', quarter_hgrid, '--dest_grid',
            tenth_hgrid, '--dest_mask', tenth_mask, '--method', 'conserve',
            '--output', weights
        ]
        ret = sp.call(cmd + args)
        assert ret == 0

    assert os.path.exists(weights)

    dest_field = remap(new_src_field, weights,
                       (mom_tenth.num_lat_points, mom_tenth.num_lon_points))

    return dest_field, weights
Example #7
0
def remap_atm_to_ocean(input_dir,
                       output_dir,
                       mom_hgrid,
                       mom_mask,
                       src=None,
                       method='conserve',
                       core2_or_jra='CORE2'):

    my_dir = os.path.dirname(os.path.realpath(__file__))
    cmd = [os.path.join(my_dir, '../', 'remapweights.py')]

    if core2_or_jra == 'CORE2':
        atm_hgrid = os.path.join(input_dir, 't_10.0001.nc')
        atm_grid = Core2Grid(atm_hgrid)
    elif core2_or_jra == 'JRA55':
        atm_hgrid = os.path.join(input_dir, 't_10.1984.30Jun2016.nc')
        atm_grid = Jra55Grid(atm_hgrid)
    elif core2_or_jra == 'JRA55_river':
        atm_hgrid = os.path.join(input_dir, 'RYF.runoff_all.1984_1985.nc')
        atm_grid = Jra55RiverGrid(atm_hgrid)
    else:
        assert False

    weights = os.path.join(output_dir, 'ATM_MOM_conserve.nc')

    t0 = time.time()
    args = [
        core2_or_jra, 'MOM', '--src_grid', atm_hgrid, '--dest_grid', mom_hgrid,
        '--dest_mask', mom_mask, '--method', method, '--output', weights
    ]
    ret = sp.call(cmd + args)
    t1 = time.time()
    assert ret == 0
    assert os.path.exists(weights)

    # Only use these to pull out the dimensions of the grids.
    mom = MomGrid.fromfile(mom_hgrid, mask_file=mom_mask)

    if src is None:
        src = np.empty_like(atm_grid.x_t)
        for i in range(src.shape[0]):
            src[i, :] = i

    dest = remap(src, weights, (mom.num_lat_points, mom.num_lon_points))
    return src, dest, weights, t1 - t0
Example #8
0
def main():

    parser = argparse.ArgumentParser()
    parser.add_argument('ocean_hgrid', help='ocean_mask.nc file')
    parser.add_argument('ocean_mask', help='ocean_hgrid.nc file')

    args = parser.parse_args()

    mom = MomGrid.fromfile(args.ocean_hgrid, mask_file=args.ocean_mask)

    # FIXME:
    # MOM dx is at the cell centre while HTN is on the Northern boundary
    # MOM dy is at the cell centre while HTE is on the Eastern boundary
    cice = CiceGrid.fromgrid(mom)

    grid_file = os.path.join('grid.nc')
    mask_file = os.path.join('kmt.nc')
    cice.write(grid_file, mask_file)
def factory(model_name,
            model_hgrid,
            model_mask,
            model_rows=None,
            model_cols=None):

    if model_name == 'MOM':
        model_grid = MomGrid.fromfile(model_hgrid, mask_file=model_mask)
    elif model_name == 'WOA':
        model_grid = WoaGrid(model_hgrid, mask_file=model_mask)
    elif model_name == 'CICE':
        model_grid = CiceGrid.fromfile(model_hgrid, mask_file=model_mask)
    elif model_name == 'NEMO':
        model_grid = NemoGrid(model_hgrid, mask_file=model_mask)
    elif model_name == 'SPE':
        if model_rows is None:
            model_rows = 64
        if model_cols is None:
            model_rows = 128
        model_grid = T42Grid(model_cols,
                             model_rows,
                             1,
                             model_mask,
                             description='Spectral')
    elif model_name == 'FVO':
        if model_rows is None:
            model_rows = 64
        if model_cols is None:
            model_rows = 128
        model_grid = FV300Grid(model_cols,
                               model_rows,
                               1,
                               model_mask,
                               description='FV')
    elif model_name == 'CORE2':
        model_grid = Core2Grid(model_hgrid)
    elif model_name == 'JRA55':
        model_grid = Jra55Grid(model_hgrid)
    else:
        assert False

    return model_grid
Example #10
0
    def test_remap_restarts_tenth(self, input_dir, output_dir):
        """
        Remap restarts from 0.25 to 0.1 degree.
        """

        # Input file are at a 1/4 degree.
        files = [
            'monthly_sstsss.nc', 'i2o.nc', 'i2a.nc', 'o2i.nc', 'u_star.nc'
        ]

        mom = MomGrid.fromfile(os.path.join(input_dir, 'ocean_01_hgrid.nc'))

        weights = None
        for fname in files:
            with nc.Dataset(os.path.join(output_dir, fname), 'w') as fd:
                with nc.Dataset(os.path.join(input_dir, fname), 'r') as fs:

                    assert 'ny' in fs.dimensions
                    assert 'nx' in fs.dimensions

                    fd.createDimension('ny', mom.num_lat_points)
                    fd.createDimension('nx', mom.num_lon_points)

                    for vname in fs.variables:
                        if vname == 'time':
                            continue

                        vd = fd.createVariable(vname, 'f8', ('ny', 'nx'))

                        if len(fs.variables[vname].shape) == 3:
                            src = fs.variables[vname][0, :, :]
                        else:
                            src = fs.variables[vname][:, :]

                        vd[:], weights = remap_to_tenth(
                            input_dir, output_dir, src, weights)

        for fname in files:
            assert os.path.exists(os.path.join(output_dir, fname))
def main():

    parser = argparse.ArgumentParser()
    parser.add_argument('input_dir',
                        help="""
                        The ACCESS-OM2 input directory.""")
    parser.add_argument('jra55_input',
                        help="""
                        The JRA55 input directory.""")
    parser.add_argument('--atm',
                        default=None,
                        help="""
                        Atmosphere grid to regrid from, can be one of:
                        CORE2, JRA55, JRA55_runoff""")
    parser.add_argument('--ocean',
                        default=None,
                        help="""
                        Ocean grid to regrid to, can be one of:
                        MOM1, MOM01, MOM025""")
    parser.add_argument('--method',
                        default=None,
                        help="""
                        The interpolation method to use.""")
    parser.add_argument('--npes',
                        default=1,
                        help="""
                        The number of PEs to use.""")

    args = parser.parse_args()
    atm_options = ['JRA55', 'JRA55_runoff', 'CORE2']
    ocean_options = ['MOM1', 'MOM025', 'MOM01']
    method_options = ['patch', 'conserve2nd']

    if args.atm is None:
        args.atm = atm_options
    else:
        if args.atm not in atm_options:
            print("Error: bad atm grid.", file=sys.stderr)
            parser.print_help()
            return 1
        args.atm = [args.atm]

    if args.ocean is None:
        args.ocean = ocean_options
    else:
        if args.ocean not in ocean_options:
            print("Error: bad atm grid.", file=sys.stderr)
            parser.print_help()
            return 1
        args.ocean = [args.ocean]

    if args.method is None:
        args.method = method_options
    else:
        args.method = [args.method]

    grid_file_dict = find_grid_defs(args.input_dir, args.jra55_input)

    for ocean in args.ocean:
        for atm in args.atm:
            for method in args.method:

                if atm == 'CORE2':
                    src_grid = Core2Grid(grid_file_dict[atm])
                elif atm == 'JRA55':
                    src_grid = Jra55Grid(grid_file_dict[atm])
                else:
                    src_grid = Jra55RiverGrid(grid_file_dict[atm])
                umask_file = grid_file_dict[ocean][1]
                dest_grid = MomGrid.fromfile(grid_file_dict[ocean][0],
                                             mask_file=umask_file)

                weights = create_weights(src_grid, dest_grid, args.npes,
                                         method)
                weights = convert_to_scrip_output(weights)

                shutil.move(weights, '{}_{}_{}.nc'.format(atm, ocean, method))

    return 0
Example #12
0
def remap_to_mom(input_file,
                 mom_hgrid,
                 mom_mask,
                 output_file,
                 method='conserve',
                 varname='runoff',
                 verbose=False,
                 clobber=False):
    """
    Remapping JRA and check that it is conservative.

    It will be necessary to use a destination mask. We want to move all
    points from src into unmasked parts of the destination.
    """

    if verbose: print("Opening input file: {}".format(input_file))

    oasis_grids_dir = os.environ["OASIS_GRIDS_DIR"]
    cmd = [os.path.join(oasis_grids_dir, 'remapweights.py')]

    # input_grid = Jra55Grid(input_file)

    output_dir = os.path.dirname(output_file)

    if verbose: print("Output directory: {}".format(output_dir))

    weights = os.path.join(output_dir, 'JRA_MOM_conserve.nc')

    if not os.path.exists(weights):

        args = [
            'JRA55', 'MOM', '--src_grid', input_file, '--dest_grid', mom_hgrid,
            '--dest_mask', mom_mask, '--method', method, '--output', weights
        ]

        if verbose:
            print("Generating weights file : {} using\n{}".format(
                weights, " ".join(cmd + args)))

        ret = sp.call(cmd + args)
        assert ret == 0
        assert os.path.exists(weights)

    # Only use these to pull out the dimensions of the grids.
    mom = MomGrid.fromfile(mom_hgrid, mask_file=mom_mask)

    with nc.Dataset(input_file) as f:

        var = f.variables[varname]

        if "time" in f.variables:
            time = f.variables["time"]
            time_units = time.units
        else:
            time = numpy.arange(0, var.shape[0])
            time_units = "days since 1900-01-01"

        create_mom_output(mom, output_file, time_units)

        for idx in range(var.shape[0]):

            src = var[idx, :]

            if verbose:
                print("Remapping using weights for index: {}".format(idx))
            dest = remap(src, weights,
                         (mom.num_lat_points, mom.num_lon_points))

            rel_err = calc_regridding_err(weights, src, dest)
            print('ESMF relative error {}'.format(rel_err))

            write_mom_output(output_file, varname, var.long_name, var.units,
                             dest, idx, time[idx])
Example #13
0
def main():

    parser = argparse.ArgumentParser()
    parser.add_argument('input_dir',
                        help="""
                        The ACCESS-OM2 input directory.""")
    parser.add_argument('jra55_input',
                        help="""
                        The JRA55 input directory.""")
    parser.add_argument('core_input',
                        help="""
                        The CORE input directory.""")
    parser.add_argument('--atm',
                        default=None,
                        help="""
                        Atmosphere grid to regrid from, can be one of:
                        CORE2, JRA55, JRA55_runoff, Daitren_runoff""")
    parser.add_argument('--ocean',
                        default=None,
                        help="""
                        Ocean grid to regrid to, can be one of:
                        MOM1, MOM01, MOM025""")
    parser.add_argument('--method',
                        default=None,
                        help="""
                        The interpolation method to use, can be patch, conserve or conserve2nd"""
                        )
    parser.add_argument('--npes',
                        default=None,
                        help="""
                        The number of PEs to use.""")
    parser.add_argument('--unmask_dest',
                        action='store_true',
                        help='Ignore destination grid mask')

    args = parser.parse_args()
    atm_options = ['JRA55', 'JRA55_runoff', 'CORE2', 'Daitren_runoff']
    ocean_options = ['MOM1', 'MOM025', 'MOM01']
    method_options = ['patch', 'conserve', 'conserve2nd']

    if args.atm is None:
        args.atm = atm_options
    else:
        if args.atm not in atm_options:
            print("Error: bad atm grid.", file=sys.stderr)
            parser.print_help()
            return 1
        args.atm = [args.atm]

    if args.ocean is None:
        args.ocean = ocean_options
    else:
        if args.ocean not in ocean_options:
            print("Error: bad atm grid.", file=sys.stderr)
            parser.print_help()
            return 1
        args.ocean = [args.ocean]

    if args.method is None:
        args.method = method_options
    else:
        args.method = [args.method]

    if args.npes is None:
        import multiprocessing as mp
        args.npes = mp.cpu_count() // 2

    grid_file_dict = find_grid_defs(args.input_dir, args.jra55_input,
                                    args.core_input)

    for ocean in args.ocean:
        umask_file = grid_file_dict[ocean][1]
        dest_grid = MomGrid.fromfile(grid_file_dict[ocean][0],
                                     mask_file=umask_file)
        for atm in args.atm:

            if atm == 'CORE2':
                src_grid = Core2Grid(grid_file_dict[atm])
            elif atm == 'Daitren_runoff':
                src_grid = DaitrenRunoffGrid(grid_file_dict[atm])
            elif atm == 'JRA55':
                src_grid = Jra55Grid(grid_file_dict[atm])
            elif atm == 'JRA55_runoff':
                src_grid = Jra55RiverGrid(grid_file_dict[atm],
                                          calc_areas=False)
            else:
                print('Unrecognised atmosphere grid: {}'.format(atm))
                return 1

            for method in args.method:

                weights = create_weights(src_grid,
                                         dest_grid,
                                         args.npes,
                                         method,
                                         unmasked_dest=args.unmask_dest)
                if not weights:
                    return 1
                weights = convert_to_scrip_output(weights)
                if not weights:
                    return 1

                shutil.move(weights, '{}_{}_{}.nc'.format(atm, ocean, method))

    return 0
Example #14
0
def main():

    parser = argparse.ArgumentParser()
    parser.add_argument('input_dir', help="""
                        The ACCESS-OM2 input directory.""")
    parser.add_argument('jra55_input', help="""
                        The JRA55 input directory.""")
    parser.add_argument('core_input', help="""
                        The CORE input directory.""")
    parser.add_argument('--atm', default=None, help="""
                        Atmosphere grid to regrid from, can be one of:
                        CORE2, JRA55, JRA55_runoff, Daitren_runoff""")
    parser.add_argument('--ocean', default=None, help="""
                        Ocean grid to regrid to, can be one of:
                        MOM1, MOM01, MOM025""")
    parser.add_argument('--method', default=None, help="""
                        The interpolation method to use, can be patch or conserve2nd""")
    parser.add_argument('--npes', default=None, help="""
                        The number of PEs to use.""")

    args = parser.parse_args()
    atm_options = ['JRA55', 'JRA55_runoff', 'CORE2', 'Daitren_runoff']
    ocean_options = ['MOM1', 'MOM025', 'MOM01']
    method_options = ['patch', 'conserve2nd']

    if args.atm is None:
        args.atm = atm_options
    else:
        if args.atm not in atm_options:
            print("Error: bad atm grid.", file=sys.stderr)
            parser.print_help()
            return 1
        args.atm = [args.atm]

    if args.ocean is None:
        args.ocean = ocean_options
    else:
        if args.ocean not in ocean_options:
            print("Error: bad atm grid.", file=sys.stderr)
            parser.print_help()
            return 1
        args.ocean = [args.ocean]

    if args.method is None:
        args.method = method_options
    else:
        args.method = [args.method]

    if args.npes is None:
        import multiprocessing as mp
        args.npes = mp.cpu_count() // 2

    grid_file_dict = find_grid_defs(args.input_dir, args.jra55_input, args.core_input)

    for ocean in args.ocean:
        umask_file = grid_file_dict[ocean][1]
        dest_grid = MomGrid.fromfile(grid_file_dict[ocean][0],
                                     mask_file=umask_file)
        for atm in args.atm:

            if atm == 'CORE2':
                src_grid = Core2Grid(grid_file_dict[atm])
            elif atm == 'Daitren_runoff':
                src_grid = DaitrenRunoffGrid(grid_file_dict[atm])
            elif atm == 'JRA55':
                src_grid = Jra55Grid(grid_file_dict[atm])
            elif atm == 'JRA55_runoff':
                src_grid = Jra55RiverGrid(grid_file_dict[atm], calc_areas=False)
            else:
                print('Unrecognised atmosphere grid: {}'.format(atm))
                return 1

            for method in args.method:

                weights = create_weights(src_grid, dest_grid, args.npes,
                                         method)
                if not weights:
                    return 1
                weights = convert_to_scrip_output(weights)
                if not weights:
                    return 1

                shutil.move(weights, '{}_{}_{}.nc'.format(atm, ocean, method))

    return 0