def test_mistmatched_mesh(): """ Test the calling of :func:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. Checks that an error is raised when the regridder is called with a cube whose mesh does not match the one used for initialisation. """ n_lons = 6 n_lats = 5 lon_bounds = (-180, 180) lat_bounds = (-90, 90) tgt = _grid_cube(n_lons, n_lats, lon_bounds, lat_bounds, circular=True) src = _gridlike_mesh_cube(n_lons, n_lats) other_loc = _gridlike_mesh_cube(n_lons, n_lats, location="node") other_src = _flat_mesh_cube() rg = MeshToGridESMFRegridder(src, tgt) with pytest.raises(ValueError) as excinfo: _ = rg(tgt) expected_message = "The given cube is not defined on a mesh." assert expected_message in str(excinfo.value) with pytest.raises(ValueError) as excinfo: _ = rg(other_loc) expected_message = ("The given cube is not defined on a the same " "mesh location as this regridder.") assert expected_message in str(excinfo.value) with pytest.raises(ValueError) as excinfo: _ = rg(other_src) expected_message = ( "The given cube is not defined on the same source mesh as this regridder." ) assert expected_message in str(excinfo.value)
def test_invalid_method(): """ Test initialisation of :func:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. Checks that an error is raised when method is invalid. """ n_lons = 6 n_lats = 5 lon_bounds = (-180, 180) lat_bounds = (-90, 90) face_src = _gridlike_mesh_cube(n_lons, n_lats, location="face") edge_src = _gridlike_mesh_cube(n_lons, n_lats, location="edge") node_src = _gridlike_mesh_cube(n_lons, n_lats, location="node") tgt = _grid_cube(n_lons, n_lats, lon_bounds, lat_bounds, circular=True) with pytest.raises(ValueError): _ = MeshToGridESMFRegridder(face_src, tgt, method="other") with pytest.raises(ValueError) as excinfo: _ = MeshToGridESMFRegridder(node_src, tgt, method="conservative") expected_message = ( "Conservative regridding requires a source cube located on " "the face of a cube, target cube had the node location.") assert expected_message in str(excinfo.value) with pytest.raises(ValueError) as excinfo: _ = MeshToGridESMFRegridder(edge_src, tgt, method="bilinear") expected_message = ( "Bilinear regridding requires a source cube with a node " "or face location, target cube had the edge location.") assert expected_message in str(excinfo.value)
def test_invalid_args(): """ Test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_rectilinear`. Tests that an appropriate error is raised when arguments are invalid. """ n_lons = 6 n_lats = 5 lon_bounds = (-180, 180) lat_bounds = (-90, 90) node_src = _gridlike_mesh_cube(n_lons, n_lats, location="node") edge_src = _gridlike_mesh_cube(n_lons, n_lats, location="edge") face_src = _gridlike_mesh_cube(n_lons, n_lats, location="face") tgt = _grid_cube(n_lons, n_lats, lon_bounds, lat_bounds, circular=True) with pytest.raises(ValueError): _ = regrid_unstructured_to_rectilinear(tgt, tgt, method="bilinear") with pytest.raises(ValueError): _ = regrid_unstructured_to_rectilinear(face_src, tgt, method="other") with pytest.raises(ValueError) as excinfo: _ = regrid_unstructured_to_rectilinear(node_src, tgt, method="conservative") expected_message = ( "Conservative regridding requires a source cube located on " "the face of a cube, target cube had the node location.") assert expected_message in str(excinfo.value) with pytest.raises(ValueError) as excinfo: _ = regrid_unstructured_to_rectilinear(edge_src, tgt, method="bilinear") expected_message = ( "Bilinear regridding requires a source cube with a node " "or face location, target cube had the edge location.") assert expected_message in str(excinfo.value)
def test_invalid_resolution(): """ Test initialisation of :func:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. Checks that an error is raised when the resolution is invalid. """ n_lons = 6 n_lats = 5 lon_bounds = (-180, 180) lat_bounds = (-90, 90) src = _gridlike_mesh_cube(n_lons, n_lats, location="face") tgt = _grid_cube(n_lons, n_lats, lon_bounds, lat_bounds, circular=True) with pytest.raises(ValueError) as excinfo: _ = MeshToGridESMFRegridder(src, tgt, method="conservative", resolution=-1) expected_message = "resolution must be a positive integer." assert expected_message in str(excinfo.value) with pytest.raises(ValueError) as excinfo: _ = MeshToGridESMFRegridder(src, tgt, method="bilinear", resolution=4) expected_message = "resolution can only be set for conservative regridding." assert expected_message in str(excinfo.value)
def test_bilinear(): """ Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.regrid_unstructured_to_rectilinear`. Tests with the bilinear method. """ n_lons = 6 n_lats = 5 lon_bounds = (-180, 180) lat_bounds = (-90, 90) src = _gridlike_mesh_cube(n_lons, n_lats, location="node") tgt = _grid_cube(n_lons, n_lats, lon_bounds, lat_bounds, circular=True) # Ensure data in the target grid is different to the expected data. # i.e. target grid data is all zero, expected data is all one tgt.data[:] = 0 src = _add_metadata(src) src.data[:] = 1 # Ensure all data in the source is one. result = regrid_unstructured_to_rectilinear(src, tgt, method="bilinear") expected_data = np.ones([n_lats, n_lons]) expected_cube = _add_metadata(tgt) # Lenient check for data. assert np.allclose(expected_data, result.data) # Check metadata and scalar coords. expected_cube.data = result.data assert expected_cube == result
def _make_mesh_to_grid_regridder(method="conservative", resolution=None, grid_dims=1, circular=True): src_lons = 3 src_lats = 4 tgt_lons = 5 tgt_lats = 6 lon_bounds = (-180, 180) lat_bounds = (-90, 90) if grid_dims == 1: tgt = _grid_cube(tgt_lons, tgt_lats, lon_bounds, lat_bounds, circular=circular) else: tgt = _curvilinear_cube(tgt_lons, tgt_lats, lon_bounds, lat_bounds) tgt.coord("longitude").var_name = "longitude" tgt.coord("latitude").var_name = "latitude" if method == "bilinear": location = "node" else: location = "face" src = _gridlike_mesh_cube(src_lons, src_lats, location=location) rg = MeshToGridESMFRegridder(src, tgt, method=method, mdtol=0.5, resolution=resolution) return rg, src
def test_bilinear(): """ Basic test for :func:`esmf_regrid.experimental.unstructured_scheme.GridToMeshESMFRegridder`. Tests with method="bilinear". """ n_lons = 6 n_lats = 5 lon_bounds = (-180, 180) lat_bounds = (-90, 90) src = _grid_cube(n_lons, n_lats, lon_bounds, lat_bounds, circular=True) face_tgt = _gridlike_mesh_cube(n_lons, n_lats, location="face") node_tgt = _gridlike_mesh_cube(n_lons, n_lats, location="node") src = _add_metadata(src) src.data[:] = 1 # Ensure all data in the source is one. face_regridder = GridToMeshESMFRegridder(src, face_tgt, method="bilinear") node_regridder = GridToMeshESMFRegridder(src, node_tgt, method="bilinear") assert face_regridder.regridder.method == "bilinear" assert node_regridder.regridder.method == "bilinear" face_expected_data = np.ones_like(face_tgt.data) node_expected_data = np.ones_like(node_tgt.data) face_result = face_regridder(src) node_result = node_regridder(src) # Lenient check for data. assert np.allclose(face_expected_data, face_result.data) assert np.allclose(node_expected_data, node_result.data) # Check metadata and scalar coords. face_expected_cube = _add_metadata(face_tgt) node_expected_cube = _add_metadata(node_tgt) face_expected_cube.data = face_result.data node_expected_cube.data = node_result.data assert face_expected_cube == face_result assert node_expected_cube == node_result
def test_default_mdtol(): """ Test initialisation of :func:`esmf_regrid.experimental.unstructured_scheme.MeshToGridESMFRegridder`. Checks that default mdtol values are as expected. """ n_lons = 6 n_lats = 5 lon_bounds = (-180, 180) lat_bounds = (-90, 90) src = _gridlike_mesh_cube(n_lons, n_lats) tgt = _grid_cube(n_lons, n_lats, lon_bounds, lat_bounds, circular=True) rg_con = MeshToGridESMFRegridder(src, tgt, method="conservative") assert rg_con.mdtol == 1 rg_bi = MeshToGridESMFRegridder(src, tgt, method="bilinear") assert rg_bi.mdtol == 0