Esempio n. 1
0
    def test_example_roundtrips(self):
        # Check that save-and-loadback leaves Iris data unchanged,
        # for data derived from each UGRID example CDL.
        for ex_name, filepath in self.example_names_paths.items():
            target_ncfile_path = str(self.temp_dir / f"{ex_name}.nc")
            # Create a netcdf file from the test CDL.
            check_call(f"ncgen {filepath} -k4 -o {target_ncfile_path}",
                       shell=True)
            # Fill in blank data-variables.
            _add_standard_data(target_ncfile_path)
            # Load the original as Iris data
            with PARSE_UGRID_ON_LOAD.context():
                orig_cubes = iris.load(target_ncfile_path)

            if "ex4" in ex_name:
                # Discard the extra formula terms component cubes
                # Saving these does not do what you expect
                orig_cubes = orig_cubes.extract("datavar")

            # Save-and-load-back to compare the Iris saved result.
            resave_ncfile_path = str(self.temp_dir / f"{ex_name}_resaved.nc")
            iris.save(orig_cubes, resave_ncfile_path)
            with PARSE_UGRID_ON_LOAD.context():
                savedloaded_cubes = iris.load(resave_ncfile_path)

            # This should match the original exactly
            # ..EXCEPT for our inability to compare meshes.
            for orig, reloaded in zip(orig_cubes, savedloaded_cubes):
                for cube in (orig, reloaded):
                    # Remove conventions attributes, which may differ.
                    cube.attributes.pop("Conventions", None)
                    # Remove var-names, which may differ.
                    cube.var_name = None

                # Compare the mesh contents (as we can't compare actual meshes)
                self.assertEqual(orig.location, reloaded.location)
                orig_mesh = orig.mesh
                reloaded_mesh = reloaded.mesh
                self.assertEqual(orig_mesh.all_coords,
                                 reloaded_mesh.all_coords)
                self.assertEqual(
                    orig_mesh.all_connectivities,
                    reloaded_mesh.all_connectivities,
                )
                # Index the cubes to replace meshes with meshcoord-derived aux coords.
                # This needs [:0] on the mesh dim, so do that on all dims.
                keys = tuple([slice(0, None)] * orig.ndim)
                orig = orig[keys]
                reloaded = reloaded[keys]
                # Resulting cubes, with collapsed mesh, should be IDENTICAL.
                self.assertEqual(orig, reloaded)
Esempio n. 2
0
 def test_non_nc(self):
     log_regex = r"Ignoring non-NetCDF file:.*"
     with self.assertLogs(logger, level="INFO", msg_regex=log_regex):
         with PARSE_UGRID_ON_LOAD.context():
             meshes = load_meshes(
                 tests.get_data_path(["PP", "simple_pp", "global.pp"]))
     self.assertDictEqual({}, meshes)
Esempio n. 3
0
 def test_no_mesh(self):
     with PARSE_UGRID_ON_LOAD.context():
         cube_list = load(
             tests.get_data_path([
                 "NetCDF", "unstructured_grid", "theta_nodal_not_ugrid.nc"
             ]))
     self.assertTrue(all([cube.mesh is None for cube in cube_list]))
Esempio n. 4
0
 def test_no_mesh(self):
     with PARSE_UGRID_ON_LOAD.context():
         meshes = load_meshes(
             tests.get_data_path([
                 "NetCDF", "unstructured_grid", "theta_nodal_not_ugrid.nc"
             ]))
     self.assertDictEqual({}, meshes)
Esempio n. 5
0
 def common_test(self, file_name, mesh_var_name):
     with PARSE_UGRID_ON_LOAD.context():
         mesh = load_mesh(
             tests.get_data_path(["NetCDF", "unstructured_grid",
                                  file_name]))
     # NOTE: cannot use CML tests as this isn't supported for non-Cubes.
     self.assertIsInstance(mesh, Mesh)
     self.assertEqual(mesh.var_name, mesh_var_name)
Esempio n. 6
0
    def test_with_data(self):
        nc_path = cdl_to_nc(self.ref_cdl)
        with PARSE_UGRID_ON_LOAD.context():
            meshes = load_meshes(nc_path)

        files = list(meshes.keys())
        self.assertEqual(1, len(files))
        file_meshes = meshes[files[0]]
        self.assertEqual(1, len(file_meshes))
        mesh = file_meshes[0]
        self.assertEqual("mesh", mesh.var_name)
Esempio n. 7
0
    def test_missing_mesh(self):
        ref_cdl = self.ref_cdl.replace('face_data:mesh = "mesh"',
                                       'face_data:mesh = "mesh2"')
        nc_path = cdl_to_nc(ref_cdl)

        # No error when mesh handling not activated.
        _ = list(load_cubes(nc_path))

        with PARSE_UGRID_ON_LOAD.context():
            log_regex = r"File does not contain mesh.*"
            with self.assertLogs(logger, level="DEBUG", msg_regex=log_regex):
                _ = list(load_cubes(nc_path))
Esempio n. 8
0
    def test_var_name(self):
        second_cdl, second_name = self.add_second_mesh()
        cdls = [self.ref_cdl, second_cdl]
        nc_paths = [cdl_to_nc(cdl) for cdl in cdls]
        with PARSE_UGRID_ON_LOAD.context():
            meshes = load_meshes(nc_paths, second_name)

        files = list(meshes.keys())
        self.assertEqual(1, len(files))
        file_meshes = meshes[files[0]]
        self.assertEqual(1, len(file_meshes))
        self.assertEqual(second_name, file_meshes[0].var_name)
Esempio n. 9
0
    def test_multi_meshes(self):
        ref_cdl, second_name = self.add_second_mesh()
        nc_path = cdl_to_nc(ref_cdl)
        with PARSE_UGRID_ON_LOAD.context():
            meshes = load_meshes(nc_path)

        files = list(meshes.keys())
        self.assertEqual(1, len(files))
        file_meshes = meshes[files[0]]
        self.assertEqual(2, len(file_meshes))
        mesh_names = [mesh.var_name for mesh in file_meshes]
        self.assertIn("mesh", mesh_names)
        self.assertIn(second_name, mesh_names)
Esempio n. 10
0
    def test_mixed_sources(self):
        url = "http://foo"
        file = TMP_DIR / f"{uuid4()}.nc"
        file.touch()
        glob = f"{TMP_DIR}/*.nc"

        with PARSE_UGRID_ON_LOAD.context():
            _ = load_meshes([url, glob])
        file_uris = [
            call[0][0] for call in self.format_agent_mock.call_args_list
        ]
        for source in (url, Path(file).name):
            self.assertIn(source, file_uris)
Esempio n. 11
0
 def setUpClass(cls):
     cls.ref_cdl = """
         netcdf mesh_test {
             dimensions:
                 node = 3 ;
                 face = 1 ;
                 vertex = 3 ;
                 levels = 2 ;
             variables:
                 int mesh ;
                     mesh:cf_role = "mesh_topology" ;
                     mesh:topology_dimension = 2 ;
                     mesh:node_coordinates = "node_x node_y" ;
                     mesh:face_coordinates = "face_x face_y" ;
                     mesh:face_node_connectivity = "face_nodes" ;
                 float node_x(node) ;
                     node_x:standard_name = "longitude" ;
                 float node_y(node) ;
                     node_y:standard_name = "latitude" ;
                 float face_x(face) ;
                     face_x:standard_name = "longitude" ;
                 float face_y(face) ;
                     face_y:standard_name = "latitude" ;
                 int face_nodes(face, vertex) ;
                     face_nodes:cf_role = "face_node_connectivity" ;
                     face_nodes:start_index = 0 ;
                 int levels(levels) ;
                 float node_data(levels, node) ;
                     node_data:coordinates = "node_x node_y" ;
                     node_data:location = "node" ;
                     node_data:mesh = "mesh" ;
                 float face_data(levels, face) ;
                     face_data:coordinates = "face_x face_y" ;
                     face_data:location = "face" ;
                     face_data:mesh = "mesh" ;
             data:
                 mesh = 0;
                 node_x = 0., 2., 1.;
                 node_y = 0., 0., 1.;
                 face_x = 0.5;
                 face_y = 0.5;
                 face_nodes = 0, 1, 2;
                 levels = 1, 2;
                 node_data = 0., 0., 0.;
                 face_data = 0.;
             }
         """
     cls.nc_path = cdl_to_nc(cls.ref_cdl)
     with PARSE_UGRID_ON_LOAD.context():
         cls.mesh_cubes = list(load_cubes(cls.nc_path))
Esempio n. 12
0
    def test_no_mesh(self):
        cdl_lines = self.ref_cdl.split("\n")
        cdl_lines = filter(
            lambda line: all(
                [s not in line for s in (':mesh = "mesh"', "mesh_topology")]),
            cdl_lines,
        )
        ref_cdl = "\n".join(cdl_lines)

        nc_path = cdl_to_nc(ref_cdl)
        with PARSE_UGRID_ON_LOAD.context():
            meshes = load_meshes(nc_path)

        self.assertDictEqual({}, meshes)
Esempio n. 13
0
    def test_no_data(self):
        cdl_lines = self.ref_cdl.split("\n")
        cdl_lines = filter(lambda line: ':mesh = "mesh"' not in line,
                           cdl_lines)
        ref_cdl = "\n".join(cdl_lines)

        nc_path = cdl_to_nc(ref_cdl)
        with PARSE_UGRID_ON_LOAD.context():
            meshes = load_meshes(nc_path)

        files = list(meshes.keys())
        self.assertEqual(1, len(files))
        file_meshes = meshes[files[0]]
        self.assertEqual(1, len(file_meshes))
        mesh = file_meshes[0]
        self.assertEqual("mesh", mesh.var_name)
Esempio n. 14
0
def ugrid_load(uris, constraints=None, callback=None):
    # TODO: remove constraint once files no longer have orphan connectivities.
    orphan_connectivities = (
        "Mesh2d_half_levels_edge_face_links",
        "Mesh2d_half_levels_face_links",
        "Mesh2d_half_levels_face_edges",
        "Mesh2d_full_levels_edge_face_links",
        "Mesh2d_full_levels_face_links",
        "Mesh2d_full_levels_face_edges",
    )
    filter_orphan_connectivities = Constraint(
        cube_func=lambda cube: cube.var_name not in orphan_connectivities)
    if constraints is None:
        constraints = filter_orphan_connectivities
    else:
        if not isinstance(constraints, Iterable):
            constraints = [constraints]
        constraints.append(filter_orphan_connectivities)

    with PARSE_UGRID_ON_LOAD.context():
        return load(uris, constraints, callback)
Esempio n. 15
0
 def test_example_result_cdls(self):
     # Snapshot the result of saving the example cases.
     for ex_name, filepath in self.example_names_paths.items():
         target_ncfile_path = str(self.temp_dir / f"{ex_name}.nc")
         # Create a netcdf file from the test CDL.
         check_call(f"ncgen {filepath} -k4 -o {target_ncfile_path}",
                    shell=True)
         # Fill in blank data-variables.
         _add_standard_data(target_ncfile_path)
         # Load as Iris data
         with PARSE_UGRID_ON_LOAD.context():
             cubes = iris.load(target_ncfile_path)
         # Re-save, to check the save behaviour.
         resave_ncfile_path = str(self.temp_dir / f"{ex_name}_resaved.nc")
         iris.save(cubes, resave_ncfile_path)
         # Check the output against a CDL snapshot.
         refdir_relpath = (
             "integration/experimental/ugrid_save/TestBasicSave/")
         reffile_name = str(Path(filepath).name).replace(".nc", ".cdl")
         reffile_path = refdir_relpath + reffile_name
         self.assertCDL(resave_ncfile_path, reference_filename=reffile_path)
Esempio n. 16
0
 def common(ret_val):
     self.load_meshes_mock.return_value = ret_val
     with self.assertRaisesRegex(ValueError, "Expecting 1 mesh.*"):
         with PARSE_UGRID_ON_LOAD.context():
             _ = load_mesh([])
Esempio n. 17
0
 def create_synthetic_test_cube(self, **create_kwargs):
     file_path = self.create_synthetic_file(**create_kwargs)
     with PARSE_UGRID_ON_LOAD.context():
         cube = load_cube(file_path)
     return cube
Esempio n. 18
0
 def test_http(self):
     url = "http://foo"
     with PARSE_UGRID_ON_LOAD.context():
         _ = load_meshes(url)
     self.format_agent_mock.assert_called_with(url, None)
Esempio n. 19
0
 def test_returns_mesh(self):
     with PARSE_UGRID_ON_LOAD.context():
         mesh = load_mesh([])
     self.assertEqual(mesh, "mesh")
Esempio n. 20
0
 def test_multi_files(self):
     files_count = 3
     nc_paths = [cdl_to_nc(self.ref_cdl) for _ in range(files_count)]
     with PARSE_UGRID_ON_LOAD.context():
         meshes = load_meshes(nc_paths)
     self.assertEqual(files_count, len(meshes))
Esempio n. 21
0
 def test_invalid_scheme(self):
     with self.assertRaisesRegex(ValueError,
                                 "Iris cannot handle the URI scheme:.*"):
         with PARSE_UGRID_ON_LOAD.context():
             _ = load_meshes("foo://bar")
Esempio n. 22
0
 def test_calls_load_meshes(self):
     args = [("file_1", "file_2"), "my_var_name"]
     with PARSE_UGRID_ON_LOAD.context():
         _ = load_mesh(args)
     self.assertTrue(self.load_meshes_mock.called_with(args))