def test_regrid(): # use conservative regridding as an example, # since it is the most well-tested studied one in papers # TODO: possible to break this long test into smaller tests? # not easy due to strong dependencies. grid_in = esmf_grid(lon_in.T, lat_in.T) grid_out = esmf_grid(lon_out.T, lat_out.T) # no corner info yet, should not be able to use conservative with pytest.raises(ValueError): esmf_regrid_build(grid_in, grid_out, 'conservative') # now add corners add_corner(grid_in, lon_b_in.T, lat_b_in.T) add_corner(grid_out, lon_b_out.T, lat_b_out.T) # also write to file for scipy regridding filename = 'test_weights.nc' if os.path.exists(filename): os.remove(filename) regrid = esmf_regrid_build(grid_in, grid_out, 'conservative', filename=filename) assert regrid.regrid_method is ESMF.RegridMethod.CONSERVE # apply regridding using ESMPy's native method data_out_esmpy = esmf_regrid_apply(regrid, data_in.T).T rel_err = (data_out_esmpy - data_ref) / data_ref # relative error assert np.max(np.abs(rel_err)) < 0.05 # apply regridding using scipy weights = read_weights(filename, lon_in.size, lon_out.size) shape_in = lon_in.shape shape_out = lon_out.shape data_out_scipy = apply_weights(weights, data_in, shape_in, shape_out) # must be exactly the same as esmpy's result! # TODO: this fails once but I cannot replicate it. # Maybe assert_equal is too strict for scipy vs esmpy comparision assert_equal(data_out_scipy, data_out_esmpy) # finally, test broadcasting with scipy # TODO: need to test broadcasting with ESMPy backend? # We only use Scipy in frontend, and ESMPy is just for backend benchmark # However, it is useful to compare performance and show scipy is 3x faster data4D_out = apply_weights(weights, data4D_in, shape_in, shape_out) # data over broadcasting dimensions should agree assert_almost_equal(data4D_in.mean(axis=(2, 3)), data4D_out.mean(axis=(2, 3)), decimal=10) # clean-up esmf_regrid_finalize(regrid) os.remove(filename)
def test_esmf_extrapolation(): grid_in = esmf_grid(lon_in.T, lat_in.T) grid_out = esmf_grid(lon_out.T, lat_out.T) regrid = esmf_regrid_build(grid_in, grid_out, 'bilinear') data_out_esmpy = esmf_regrid_apply(regrid, data_in.T).T # without extrapolation, the first and last lines/columns = 0 assert data_out_esmpy[0, 0] == 0 regrid = esmf_regrid_build(grid_in, grid_out, 'bilinear', extrap_method='inverse_dist', extrap_num_src_pnts=3, extrap_dist_exponent=1) data_out_esmpy = esmf_regrid_apply(regrid, data_in.T).T # the 3 closest points in data_in are 2.010, 2.005, and 1.992. The result should be roughly equal to 2.0 assert np.round(data_out_esmpy[0, 0], 1) == 2.0
def test_regrid_periodic_correct(): # only need to specific periodic for input grid grid_in = Grid.from_xarray(lon_in.T, lat_in.T, periodic=True) grid_out = Grid.from_xarray(lon_out.T, lat_out.T) assert grid_in.num_peri_dims == 1 assert grid_in.periodic_dim == 0 # the first axis, longitude regrid = esmf_regrid_build(grid_in, grid_out, 'bilinear') data_out_esmpy = esmf_regrid_apply(regrid, data_in.T).T rel_err = (data_out_esmpy - data_ref) / data_ref # relative error assert np.max(np.abs(rel_err)) < 0.065 # clean-up esmf_regrid_finalize(regrid)
def test_regrid_periodic_wrong(): # not using periodic grid grid_in = esmf_grid(lon_in.T, lat_in.T) grid_out = esmf_grid(lon_out.T, lat_out.T) assert grid_in.num_peri_dims == 0 assert grid_in.periodic_dim is None regrid = esmf_regrid_build(grid_in, grid_out, 'bilinear') data_out_esmpy = esmf_regrid_apply(regrid, data_in.T).T rel_err = (data_out_esmpy - data_ref)/data_ref # relative error assert np.max(np.abs(rel_err)) == 1.0 # some data will be missing # clean-up esmf_regrid_finalize(regrid)