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_read_weights(tmp_path): fn = tmp_path / 'weights.nc' grid_in = Grid.from_xarray(lon_in.T, lat_in.T) grid_out = Grid.from_xarray(lon_out.T, lat_out.T) regrid_memory = esmf_regrid_build(grid_in, grid_out, method='bilinear') esmf_regrid_build(grid_in, grid_out, method='bilinear', filename=str(fn)) w = regrid_memory.get_weights_dict(deep_copy=True) sm = read_weights(w, lon_in.size, lon_out.size) # Test Path and string to netCDF file against weights dictionary np.testing.assert_array_equal( read_weights(fn, lon_in.size, lon_out.size).todense(), sm.todense()) np.testing.assert_array_equal( read_weights(str(fn), lon_in.size, lon_out.size).todense(), sm.todense()) # Test xr.Dataset np.testing.assert_array_equal( read_weights(xr.open_dataset(fn), lon_in.size, lon_out.size).todense(), sm.todense(), ) # Test COO matrix np.testing.assert_array_equal( read_weights(sm, lon_in.size, lon_out.size).todense(), sm.todense()) # Test failures with pytest.raises(IOError): read_weights(tmp_path / 'wrong_file.nc', lon_in.size, lon_out.size) with pytest.raises(ValueError): read_weights({}, lon_in.size, lon_out.size) with pytest.raises(ValueError): ds = xr.open_dataset(fn) read_weights(ds.drop_vars('col'), lon_in.size, lon_out.size)