From be97382fce9516a5f7a149f53cdaa5d85d41bcef Mon Sep 17 00:00:00 2001 From: Elias Sadek Date: Mon, 24 Nov 2025 11:55:35 +0000 Subject: [PATCH 01/12] converted test_attributes --- .../integration/netcdf/test_attributes.py | 66 ++++++++----------- .../multiple_different_saves_on_variables.cdl | 15 ----- .../multiple_same_saves_as_global.cdl | 14 ---- .../single_saves_as_global.cdl | 11 ---- 4 files changed, 29 insertions(+), 77 deletions(-) delete mode 100644 lib/iris/tests/results/integration/netcdf/attributes/TestUmVersionAttribute/multiple_different_saves_on_variables.cdl delete mode 100644 lib/iris/tests/results/integration/netcdf/attributes/TestUmVersionAttribute/multiple_same_saves_as_global.cdl delete mode 100644 lib/iris/tests/results/integration/netcdf/attributes/TestUmVersionAttribute/single_saves_as_global.cdl diff --git a/lib/iris/tests/integration/netcdf/test_attributes.py b/lib/iris/tests/integration/netcdf/test_attributes.py index ca32060c22..6648294223 100644 --- a/lib/iris/tests/integration/netcdf/test_attributes.py +++ b/lib/iris/tests/integration/netcdf/test_attributes.py @@ -4,12 +4,7 @@ # See LICENSE in the root of the repository for full licensing details. """Integration tests for attribute-related loading and saving netcdf files.""" -# Import iris.tests first so that some things can be initialised before -# importing anything else. -import iris.tests as tests # isort:skip - from contextlib import contextmanager -from unittest import mock from cf_units import Unit import pytest @@ -17,21 +12,22 @@ import iris from iris.cube import Cube, CubeList from iris.fileformats.netcdf import CF_CONVENTIONS_VERSION +from iris.tests import _shared_utils -class TestUmVersionAttribute(tests.IrisTest): - def test_single_saves_as_global(self): +class TestUmVersionAttribute: + def test_single_saves_as_global(self, tmp_path, request): cube = Cube( [1.0], standard_name="air_temperature", units="K", attributes={"um_version": "4.3"}, ) - with self.temp_filename(".nc") as nc_path: - iris.save(cube, nc_path) - self.assertCDL(nc_path) + nc_path = tmp_path / "test.nc" + iris.save(cube, nc_path) + _shared_utils.assert_CDL(request, nc_path) - def test_multiple_same_saves_as_global(self): + def test_multiple_same_saves_as_global(self, tmp_path, request): cube_a = Cube( [1.0], standard_name="air_temperature", @@ -44,11 +40,11 @@ def test_multiple_same_saves_as_global(self): units="hPa", attributes={"um_version": "4.3"}, ) - with self.temp_filename(".nc") as nc_path: - iris.save(CubeList([cube_a, cube_b]), nc_path) - self.assertCDL(nc_path) + nc_path = tmp_path / "test.nc" + iris.save(CubeList([cube_a, cube_b]), nc_path) + _shared_utils.assert_CDL(request, nc_path) - def test_multiple_different_saves_on_variables(self): + def test_multiple_different_saves_on_variables(self, tmp_path, request): cube_a = Cube( [1.0], standard_name="air_temperature", @@ -61,19 +57,19 @@ def test_multiple_different_saves_on_variables(self): units="hPa", attributes={"um_version": "4.4"}, ) - with self.temp_filename(".nc") as nc_path: - iris.save(CubeList([cube_a, cube_b]), nc_path) - self.assertCDL(nc_path) + nc_path = tmp_path / "test.nc" + iris.save(CubeList([cube_a, cube_b]), nc_path) + _shared_utils.assert_CDL(request, nc_path) @contextmanager -def _patch_site_configuration(): +def _patch_site_configuration(mocker): def cf_patch_conventions(conventions): return ", ".join([conventions, "convention1, convention2"]) def update(config): - config["cf_profile"] = mock.Mock(name="cf_profile") - config["cf_patch"] = mock.Mock(name="cf_patch") + config["cf_profile"] = mocker.Mock(name="cf_profile") + config["cf_patch"] = mocker.Mock(name="cf_patch") config["cf_patch_conventions"] = cf_patch_conventions orig_site_config = iris.site_configuration.copy() @@ -82,8 +78,8 @@ def update(config): iris.site_configuration = orig_site_config -class TestConventionsAttributes(tests.IrisTest): - def test_patching_conventions_attribute(self): +class TestConventionsAttributes: + def test_patching_conventions_attribute(self, tmp_path, mocker): # Ensure that user defined conventions are wiped and those which are # saved patched through site_config can be loaded without an exception # being raised. @@ -95,24 +91,24 @@ def test_patching_conventions_attribute(self): ) # Patch the site configuration dictionary. - with _patch_site_configuration(), self.temp_filename(".nc") as nc_path: + nc_path = tmp_path / "test.nc" + with _patch_site_configuration(mocker): iris.save(cube, nc_path) res = iris.load_cube(nc_path) - self.assertEqual( - res.attributes["Conventions"], - "{}, {}, {}".format(CF_CONVENTIONS_VERSION, "convention1", "convention2"), + assert res.attributes["Conventions"] == "{}, {}, {}".format( + CF_CONVENTIONS_VERSION, "convention1", "convention2" ) -class TestStandardName(tests.IrisTest): - def test_standard_name_roundtrip(self): +class TestStandardName: + def test_standard_name_roundtrip(self, tmp_path): standard_name = "air_temperature detection_minimum" cube = iris.cube.Cube(1, standard_name=standard_name) - with self.temp_filename(suffix=".nc") as fout: - iris.save(cube, fout) - detection_limit_cube = iris.load_cube(fout) - self.assertEqual(detection_limit_cube.standard_name, standard_name) + fout = tmp_path / ".nc" + iris.save(cube, fout) + detection_limit_cube = iris.load_cube(fout) + assert detection_limit_cube.standard_name == standard_name class TestCalendar: @@ -126,7 +122,3 @@ def test_calendar_roundtrip(self, tmp_path): iris.save(self.cube, fout) detection_limit_cube = iris.load_cube(fout) assert detection_limit_cube.units == self.calendar - - -if __name__ == "__main__": - tests.main() diff --git a/lib/iris/tests/results/integration/netcdf/attributes/TestUmVersionAttribute/multiple_different_saves_on_variables.cdl b/lib/iris/tests/results/integration/netcdf/attributes/TestUmVersionAttribute/multiple_different_saves_on_variables.cdl deleted file mode 100644 index a22044c2d9..0000000000 --- a/lib/iris/tests/results/integration/netcdf/attributes/TestUmVersionAttribute/multiple_different_saves_on_variables.cdl +++ /dev/null @@ -1,15 +0,0 @@ -dimensions: - dim0 = 1 ; -variables: - double air_temperature(dim0) ; - air_temperature:standard_name = "air_temperature" ; - air_temperature:units = "K" ; - air_temperature:um_version = "4.3" ; - double air_pressure(dim0) ; - air_pressure:standard_name = "air_pressure" ; - air_pressure:units = "hPa" ; - air_pressure:um_version = "4.4" ; - -// global attributes: - :Conventions = "CF-1.7" ; -} diff --git a/lib/iris/tests/results/integration/netcdf/attributes/TestUmVersionAttribute/multiple_same_saves_as_global.cdl b/lib/iris/tests/results/integration/netcdf/attributes/TestUmVersionAttribute/multiple_same_saves_as_global.cdl deleted file mode 100644 index be35bfd590..0000000000 --- a/lib/iris/tests/results/integration/netcdf/attributes/TestUmVersionAttribute/multiple_same_saves_as_global.cdl +++ /dev/null @@ -1,14 +0,0 @@ -dimensions: - dim0 = 1 ; -variables: - double air_temperature(dim0) ; - air_temperature:standard_name = "air_temperature" ; - air_temperature:units = "K" ; - double air_pressure(dim0) ; - air_pressure:standard_name = "air_pressure" ; - air_pressure:units = "hPa" ; - -// global attributes: - :um_version = "4.3" ; - :Conventions = "CF-1.7" ; -} diff --git a/lib/iris/tests/results/integration/netcdf/attributes/TestUmVersionAttribute/single_saves_as_global.cdl b/lib/iris/tests/results/integration/netcdf/attributes/TestUmVersionAttribute/single_saves_as_global.cdl deleted file mode 100644 index 0399f82349..0000000000 --- a/lib/iris/tests/results/integration/netcdf/attributes/TestUmVersionAttribute/single_saves_as_global.cdl +++ /dev/null @@ -1,11 +0,0 @@ -dimensions: - dim0 = 1 ; -variables: - double air_temperature(dim0) ; - air_temperature:standard_name = "air_temperature" ; - air_temperature:units = "K" ; - -// global attributes: - :um_version = "4.3" ; - :Conventions = "CF-1.7" ; -} From 8d83c523e3fe77ac81f14d4c1e54255bd77f87a4 Mon Sep 17 00:00:00 2001 From: Elias Sadek Date: Mon, 24 Nov 2025 13:34:19 +0000 Subject: [PATCH 02/12] converted test_aux_factories --- .../integration/netcdf/test_aux_factories.py | 113 ++++++++---------- 1 file changed, 52 insertions(+), 61 deletions(-) diff --git a/lib/iris/tests/integration/netcdf/test_aux_factories.py b/lib/iris/tests/integration/netcdf/test_aux_factories.py index 4b4976bd18..20686045b6 100644 --- a/lib/iris/tests/integration/netcdf/test_aux_factories.py +++ b/lib/iris/tests/integration/netcdf/test_aux_factories.py @@ -4,17 +4,17 @@ # See LICENSE in the root of the repository for full licensing details. """Integration tests for aux-factory-related loading and saving netcdf files.""" -# Import iris.tests first so that some things can be initialised before -# importing anything else. -import iris.tests as tests # isort:skip +import pytest import iris +from iris.tests import _shared_utils from iris.tests import stock as stock -@tests.skip_data -class TestAtmosphereSigma(tests.IrisTest): - def setUp(self): +@_shared_utils.skip_data +class TestAtmosphereSigma: + @pytest.fixture(autouse=True) + def _setup(self): # Modify stock cube so it is suitable to have a atmosphere sigma # factory added to it. cube = stock.realistic_4d_no_derived() @@ -33,23 +33,24 @@ def setUp(self): cube.add_aux_factory(factory) self.cube = cube - def test_save(self): - with self.temp_filename(suffix=".nc") as filename: - iris.save(self.cube, filename) - self.assertCDL(filename) + def test_save(self, request, tmp_path): + filename = tmp_path / "fn.nc" + iris.save(self.cube, filename) + _shared_utils.assert_CDL(request, filename) - def test_save_load_loop(self): + def test_save_load_loop(self, tmp_path): # Ensure that the AtmosphereSigmaFactory is automatically loaded # when loading the file. - with self.temp_filename(suffix=".nc") as filename: - iris.save(self.cube, filename) - cube = iris.load_cube(filename, "air_potential_temperature") - assert cube.coords("air_pressure") + filename = tmp_path / "fn.nc" + iris.save(self.cube, filename) + cube = iris.load_cube(filename, "air_potential_temperature") + assert cube.coords("air_pressure") -@tests.skip_data -class TestHybridPressure(tests.IrisTest): - def setUp(self): +@_shared_utils.skip_data +class TestHybridPressure: + @pytest.fixture(autouse=True) + def _setup(self): # Modify stock cube so it is suitable to have a # hybrid pressure factory added to it. cube = stock.realistic_4d_no_derived() @@ -66,29 +67,27 @@ def setUp(self): cube.add_aux_factory(factory) self.cube = cube - def test_save(self): - with self.temp_filename(suffix=".nc") as filename: - iris.save(self.cube, filename) - self.assertCDL(filename) + def test_save(self, request, tmp_path): + filename = tmp_path / "fn.nc" + iris.save(self.cube, filename) + _shared_utils.assert_CDL(request, filename) - def test_save_load_loop(self): + def test_save_load_loop(self, tmp_path): # Tests an issue where the variable names in the formula # terms changed to the standard_names instead of the variable names # when loading a previously saved cube. - with ( - self.temp_filename(suffix=".nc") as filename, - self.temp_filename(suffix=".nc") as other_filename, - ): - iris.save(self.cube, filename) - cube = iris.load_cube(filename, "air_potential_temperature") - iris.save(cube, other_filename) - other_cube = iris.load_cube(other_filename, "air_potential_temperature") - self.assertEqual(cube, other_cube) - - -@tests.skip_data -class TestSaveMultipleAuxFactories(tests.IrisTest): - def test_hybrid_height_and_pressure(self): + filename = tmp_path / "fn.nc" + other_filename = tmp_path / "ofn.nc" + iris.save(self.cube, filename) + cube = iris.load_cube(filename, "air_potential_temperature") + iris.save(cube, other_filename) + other_cube = iris.load_cube(other_filename, "air_potential_temperature") + assert cube == other_cube + + +@_shared_utils.skip_data +class TestSaveMultipleAuxFactories: + def test_hybrid_height_and_pressure(self, request, tmp_path): cube = stock.realistic_4d() cube.add_aux_coord( iris.coords.DimCoord(1200.0, long_name="level_pressure", units="hPa") @@ -105,11 +104,11 @@ def test_hybrid_height_and_pressure(self): cube.coord("surface_air_pressure"), ) cube.add_aux_factory(factory) - with self.temp_filename(suffix=".nc") as filename: - iris.save(cube, filename) - self.assertCDL(filename) + filename = tmp_path / "fn.nc" + iris.save(cube, filename) + _shared_utils.assert_CDL(request, filename) - def test_shared_primary(self): + def test_shared_primary(self, tmp_path): cube = stock.realistic_4d() factory = iris.aux_factory.HybridHeightFactory( cube.coord("level_height"), @@ -118,37 +117,29 @@ def test_shared_primary(self): ) factory.rename("another altitude") cube.add_aux_factory(factory) - with ( - self.temp_filename(suffix=".nc") as filename, - self.assertRaisesRegex(ValueError, "multiple aux factories"), - ): + filename = tmp_path / "fn.nc" + with pytest.raises(ValueError, match="multiple aux factories"): iris.save(cube, filename) - def test_hybrid_height_cubes(self): + def test_hybrid_height_cubes(self, request, tmp_path): hh1 = stock.simple_4d_with_hybrid_height() hh1.attributes["cube"] = "hh1" hh2 = stock.simple_4d_with_hybrid_height() hh2.attributes["cube"] = "hh2" sa = hh2.coord("surface_altitude") sa.points = sa.points * 10 - with self.temp_filename(".nc") as fname: - iris.save([hh1, hh2], fname) - cubes = iris.load(fname, "air_temperature") - cubes = sorted(cubes, key=lambda cube: cube.attributes["cube"]) - self.assertCML(cubes) + filename = tmp_path / "fn.nc" + iris.save([hh1, hh2], filename) + cubes = iris.load(filename, "air_temperature") + cubes = sorted(cubes, key=lambda cube: cube.attributes["cube"]) + _shared_utils.assert_CML(request, cubes) - def test_hybrid_height_cubes_on_dimension_coordinate(self): + def test_hybrid_height_cubes_on_dimension_coordinate(self, tmp_path): hh1 = stock.hybrid_height() hh2 = stock.hybrid_height() sa = hh2.coord("surface_altitude") sa.points = sa.points * 10 emsg = "Unable to create dimensonless vertical coordinate." - with ( - self.temp_filename(".nc") as fname, - self.assertRaisesRegex(ValueError, emsg), - ): - iris.save([hh1, hh2], fname) - - -if __name__ == "__main__": - tests.main() + filename = tmp_path / "fn.nc" + with pytest.raises(ValueError, match=emsg): + iris.save([hh1, hh2], filename) From 4cdc7766769a88691ccfffd2f3f54e693a7fb12e Mon Sep 17 00:00:00 2001 From: Elias Sadek Date: Mon, 24 Nov 2025 13:36:23 +0000 Subject: [PATCH 03/12] corrected use of tmp_path in test_attributes --- lib/iris/tests/integration/netcdf/test_attributes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/iris/tests/integration/netcdf/test_attributes.py b/lib/iris/tests/integration/netcdf/test_attributes.py index 6648294223..b24538079f 100644 --- a/lib/iris/tests/integration/netcdf/test_attributes.py +++ b/lib/iris/tests/integration/netcdf/test_attributes.py @@ -105,7 +105,7 @@ class TestStandardName: def test_standard_name_roundtrip(self, tmp_path): standard_name = "air_temperature detection_minimum" cube = iris.cube.Cube(1, standard_name=standard_name) - fout = tmp_path / ".nc" + fout = tmp_path / "standard_name.nc" iris.save(cube, fout) detection_limit_cube = iris.load_cube(fout) assert detection_limit_cube.standard_name == standard_name From fda7e2f54fd7f42ce8e906f582eb611fb205dde2 Mon Sep 17 00:00:00 2001 From: Elias Sadek Date: Mon, 24 Nov 2025 13:56:53 +0000 Subject: [PATCH 04/12] coverted test_coord_systems --- .../tests/integration/netcdf/test_coord_systems.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/iris/tests/integration/netcdf/test_coord_systems.py b/lib/iris/tests/integration/netcdf/test_coord_systems.py index 9f4f272dd7..aa7b715912 100644 --- a/lib/iris/tests/integration/netcdf/test_coord_systems.py +++ b/lib/iris/tests/integration/netcdf/test_coord_systems.py @@ -4,10 +4,6 @@ # See LICENSE in the root of the repository for full licensing details. """Integration tests for coord-system-related loading and saving netcdf files.""" -# Import iris.tests first so that some things can be initialised before -# importing anything else. -import iris.tests as tests # isort:skip - import warnings import numpy as np @@ -16,8 +12,8 @@ import iris from iris.coords import DimCoord from iris.cube import Cube +from iris.tests import _shared_utils from iris.tests import stock as stock -from iris.tests._shared_utils import assert_CML from iris.tests.stock.netcdf import ncgen_from_cdl from iris.tests.unit.fileformats.netcdf.loader import test_load_cubes as tlc @@ -172,7 +168,7 @@ def multi_cs_osgb_wkt(): """ -@tests.skip_data +@_shared_utils.skip_data class TestCoordSystem: @pytest.fixture(autouse=True) def _setup(self): @@ -182,11 +178,11 @@ def _setup(self): def test_load_laea_grid(self, request): cube = iris.load_cube( - tests.get_data_path( + _shared_utils.get_data_path( ("NetCDF", "lambert_azimuthal_equal_area", "euro_air_temp.nc") ) ) - assert_CML(request, cube, ("netcdf", "netcdf_laea.cml")) + _shared_utils.assert_CML(request, cube, ("netcdf", "netcdf_laea.cml")) def test_load_datum_wkt(self, datum_wkt_cdl): expected = "OSGB 1936" From 99f0516bc9c76b9f6c55af51382acaf102a16cb3 Mon Sep 17 00:00:00 2001 From: Elias Sadek Date: Mon, 24 Nov 2025 13:58:58 +0000 Subject: [PATCH 05/12] aligned test_dataless --- lib/iris/tests/integration/netcdf/test_dataless.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/iris/tests/integration/netcdf/test_dataless.py b/lib/iris/tests/integration/netcdf/test_dataless.py index 442777ce18..d254149039 100644 --- a/lib/iris/tests/integration/netcdf/test_dataless.py +++ b/lib/iris/tests/integration/netcdf/test_dataless.py @@ -16,7 +16,7 @@ class TestDataless: @pytest.fixture(autouse=True) - def setup(self, tmp_path_factory): + def _setup(self, tmp_path_factory): ny, nx = 3, 4 self.testcube = Cube( shape=(ny, nx), From 65d46d3eefe5de0217110f5c274eb6d363724f49 Mon Sep 17 00:00:00 2001 From: Elias Sadek Date: Mon, 24 Nov 2025 14:14:26 +0000 Subject: [PATCH 06/12] aligned test_coord_systems --- lib/iris/tests/integration/netcdf/test_delayed_save.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/iris/tests/integration/netcdf/test_delayed_save.py b/lib/iris/tests/integration/netcdf/test_delayed_save.py index 4b8a5cbe5c..6473266e6f 100644 --- a/lib/iris/tests/integration/netcdf/test_delayed_save.py +++ b/lib/iris/tests/integration/netcdf/test_delayed_save.py @@ -15,7 +15,7 @@ import iris from iris.fileformats.netcdf._thread_safe_nc import default_fillvals -import iris.tests +from iris.tests import _shared_utils from iris.tests.stock import realistic_4d @@ -38,7 +38,7 @@ def all_saves_with_split_attrs(self): def output_path(self, tmp_path): # A temporary output netcdf-file path, **unique to each test call**. self.temp_output_filepath = tmp_path / "tmp.nc" - yield self.temp_output_filepath + return self.temp_output_filepath @pytest.fixture(autouse=True, scope="module") def all_vars_lazy(self): @@ -118,8 +118,8 @@ def fix_array(array): cube.add_cell_measure(cm, cm_dims) return cube - def test_realfile_loadsave_equivalence(self, save_is_delayed, output_path): - input_filepath = iris.tests.get_data_path( + def test_realfile_loadsave_equivalence(self, save_is_delayed, output_path, request): + input_filepath = _shared_utils.get_data_path( ["NetCDF", "global", "xyz_t", "GEMS_CO2_Apr2006.nc"] ) original_cubes = iris.load(input_filepath) From ade474bf5233364b7fdc9abd2a6ef8e5641b11d8 Mon Sep 17 00:00:00 2001 From: Elias Sadek Date: Tue, 25 Nov 2025 16:12:58 +0000 Subject: [PATCH 07/12] aligned test_general --- .../tests/integration/netcdf/test_general.py | 325 +++++++++--------- .../TestDatasetAndPathSaves/basic_save.cdl | 34 -- .../path_string_save_same.cdl | 34 -- .../multi_packed_multi_dtype.cdl | 68 ---- .../multi_packed_single_dtype.cdl | 70 ---- .../TestPackedData/single_packed_manual.cdl | 50 --- .../TestPackedData/single_packed_signed.cdl | 50 --- .../TestPackedData/single_packed_unsigned.cdl | 50 --- 8 files changed, 159 insertions(+), 522 deletions(-) delete mode 100644 lib/iris/tests/results/integration/netcdf/general/TestDatasetAndPathSaves/basic_save.cdl delete mode 100644 lib/iris/tests/results/integration/netcdf/general/TestDatasetAndPathSaves/path_string_save_same.cdl delete mode 100644 lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_multi_dtype.cdl delete mode 100644 lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_single_dtype.cdl delete mode 100644 lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_manual.cdl delete mode 100644 lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_signed.cdl delete mode 100644 lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_unsigned.cdl diff --git a/lib/iris/tests/integration/netcdf/test_general.py b/lib/iris/tests/integration/netcdf/test_general.py index 21afb6bc8b..6e5fcacf2d 100644 --- a/lib/iris/tests/integration/netcdf/test_general.py +++ b/lib/iris/tests/integration/netcdf/test_general.py @@ -4,16 +4,10 @@ # See LICENSE in the root of the repository for full licensing details. """Integration tests for loading and saving netcdf files.""" -# Import iris.tests first so that some things can be initialised before -# importing anything else. -import iris.tests as tests # isort:skip - from itertools import repeat import os.path from pathlib import Path import shutil -import tempfile -from unittest import mock import warnings import dask @@ -32,6 +26,7 @@ # netCDF4" check in "iris.tests.test_coding_standards.test_netcdf4_import()". import iris.fileformats.netcdf._thread_safe_nc as threadsafe_nc from iris.loading import LOAD_PROBLEMS +from iris.tests import _shared_utils import iris.warnings nc = threadsafe_nc.netCDF4 @@ -39,49 +34,50 @@ from iris.tests.stock.netcdf import ncgen_from_cdl -class TestLazySave(tests.IrisTest): - @tests.skip_data - def test_lazy_preserved_save(self): - fpath = tests.get_data_path( +class TestLazySave: + @_shared_utils.skip_data + def test_lazy_preserved_save(self, mocker, tmp_path): + fpath = _shared_utils.get_data_path( ("NetCDF", "label_and_climate", "small_FC_167_mon_19601101.nc") ) # While loading, "turn off" loading small variables as real data. - with mock.patch("iris.fileformats.netcdf.loader._LAZYVAR_MIN_BYTES", 0): - acube = iris.load_cube(fpath, "air_temperature") - self.assertTrue(acube.has_lazy_data()) + mocker.patch("iris.fileformats.netcdf.loader._LAZYVAR_MIN_BYTES", 0) + acube = iris.load_cube(fpath, "air_temperature") + assert acube.has_lazy_data() # Also check a coord with lazy points + bounds. - self.assertTrue(acube.coord("forecast_period").has_lazy_points()) - self.assertTrue(acube.coord("forecast_period").has_lazy_bounds()) - with self.temp_filename(".nc") as nc_path: - with Saver(nc_path, "NETCDF4") as saver: - saver.write(acube) + assert acube.coord("forecast_period").has_lazy_points() + assert acube.coord("forecast_period").has_lazy_bounds() + nc_path = tmp_path / "tmp.nc" + with Saver(nc_path, "NETCDF4") as saver: + saver.write(acube) # Check that cube data is not realised, also coord points + bounds. - self.assertTrue(acube.has_lazy_data()) - self.assertTrue(acube.coord("forecast_period").has_lazy_points()) - self.assertTrue(acube.coord("forecast_period").has_lazy_bounds()) + assert acube.has_lazy_data() + assert acube.coord("forecast_period").has_lazy_points() + assert acube.coord("forecast_period").has_lazy_bounds() -@tests.skip_data -class TestCellMeasures(tests.IrisTest): - def setUp(self): - self.fname = tests.get_data_path(("NetCDF", "ORCA2", "votemper.nc")) +@_shared_utils.skip_data +class TestCellMeasures: + @pytest.fixture(autouse=True) + def _setup(self): + self.fname = _shared_utils.get_data_path(("NetCDF", "ORCA2", "votemper.nc")) def test_load_raw(self): (cube,) = iris.load_raw(self.fname) - self.assertEqual(len(cube.cell_measures()), 1) - self.assertEqual(cube.cell_measures()[0].measure, "area") + assert len(cube.cell_measures()) == 1 + assert cube.cell_measures()[0].measure == "area" def test_load(self): cube = iris.load_cube(self.fname) - self.assertEqual(len(cube.cell_measures()), 1) - self.assertEqual(cube.cell_measures()[0].measure, "area") + assert len(cube.cell_measures()) == 1 + assert cube.cell_measures()[0].measure == "area" def test_merge_cell_measure_aware(self): (cube1,) = iris.load_raw(self.fname) (cube2,) = iris.load_raw(self.fname) cube2._cell_measures_and_dims[0][0].var_name = "not_areat" cubes = CubeList([cube1, cube2]).merge() - self.assertEqual(len(cubes), 2) + assert len(cubes) == 2 def test_concatenate_cell_measure_aware(self): (cube1,) = iris.load_raw(self.fname) @@ -92,8 +88,8 @@ def test_concatenate_cell_measure_aware(self): cube2._cell_measures_and_dims[0][0].var_name = "not_areat" cube2.coord("time").points = cube2.coord("time").points + 1 cubes = CubeList([cube1, cube2]).concatenate() - self.assertEqual(cubes[0]._cell_measures_and_dims, cm_and_dims) - self.assertEqual(len(cubes), 2) + assert cubes[0]._cell_measures_and_dims == cm_and_dims + assert len(cubes) == 2 def test_concatenate_cell_measure_match(self): (cube1,) = iris.load_raw(self.fname) @@ -103,35 +99,32 @@ def test_concatenate_cell_measure_match(self): cube2 = cube2[:, :, 0, 0] cube2.coord("time").points = cube2.coord("time").points + 1 cubes = CubeList([cube1, cube2]).concatenate() - self.assertEqual(cubes[0]._cell_measures_and_dims, cm_and_dims) - self.assertEqual(len(cubes), 1) + assert cubes[0]._cell_measures_and_dims == cm_and_dims + assert len(cubes) == 1 - def test_round_trip(self): + def test_round_trip(self, tmp_path): (cube,) = iris.load(self.fname) - with self.temp_filename(suffix=".nc") as filename: - iris.save(cube, filename, unlimited_dimensions=[]) - (round_cube,) = iris.load_raw(filename) - self.assertEqual(len(round_cube.cell_measures()), 1) - self.assertEqual(round_cube.cell_measures()[0].measure, "area") + filename = tmp_path / "tmp.nc" + iris.save(cube, filename, unlimited_dimensions=[]) + (round_cube,) = iris.load_raw(filename) + assert len(round_cube.cell_measures()) == 1 + assert round_cube.cell_measures()[0].measure == "area" def test_print(self): cube = iris.load_cube(self.fname) printed = cube.__str__() - self.assertIn( - ( - "Cell measures:\n" - " cell_area - - " - " x x" - ), - printed, - ) + assert ( + "Cell measures:\n" + " cell_area - - " + " x x" + ) in printed -class TestCellMethod_unknown(tests.IrisTest): - def test_unknown_method(self): +class TestCellMethod_unknown: + def test_unknown_method(self, tmp_path_factory): cube = Cube([1, 2], long_name="odd_phenomenon") cube.add_cell_method(CellMethod(method="oddity", coords=("x",))) - temp_dirpath = tempfile.mkdtemp() + temp_dirpath = tmp_path_factory.mktemp("test") try: temp_filepath = os.path.join(temp_dirpath, "tmp.nc") iris.save(cube, temp_filepath) @@ -144,12 +137,12 @@ def test_unknown_method(self): for warn in warning_messages if isinstance(warn, iris.warnings.IrisUnknownCellMethodWarning) ] - self.assertEqual(len(warning_messages), 1) + assert len(warning_messages) == 1 message = warning_messages[0].args[0] msg = ( "NetCDF variable 'odd_phenomenon' contains unknown cell method 'oddity'" ) - self.assertIn(msg, message) + assert msg in message finally: shutil.rmtree(temp_dirpath) @@ -181,11 +174,11 @@ def _get_scale_factor_add_offset(cube, datatype): return (scale_factor, add_offset) -@tests.skip_data -class TestPackedData(tests.IrisTest): - def _single_test(self, datatype, CDLfilename, manual=False): +@_shared_utils.skip_data +class TestPackedData: + def _single_test(self, datatype, CDLfilename, request, tmp_path, manual=False): # Read PP input file. - file_in = tests.get_data_path( + file_in = _shared_utils.get_data_path( ( "PP", "cf_processing", @@ -201,43 +194,48 @@ def _single_test(self, datatype, CDLfilename, manual=False): else: packspec = datatype # Write Cube to netCDF file. - with self.temp_filename(suffix=".nc") as file_out: - iris.save(cube, file_out, packing=packspec) - decimal = int(-np.log10(scale_factor)) - packedcube = iris.load_cube(file_out) - # Check that packed cube is accurate to expected precision - self.assertArrayAlmostEqual(cube.data, packedcube.data, decimal=decimal) - # Check the netCDF file against CDL expected output. - self.assertCDL( - file_out, - ( - "integration", - "netcdf", - "general", - "TestPackedData", - CDLfilename, - ), - ) + file_out = tmp_path / "tmp.nc" + iris.save(cube, file_out, packing=packspec) + decimal = int(-np.log10(scale_factor)) + packedcube = iris.load_cube(file_out) + # Check that packed cube is accurate to expected precision + _shared_utils.assert_array_almost_equal( + cube.data, packedcube.data, decimal=decimal + ) + # Check the netCDF file against CDL expected output. + _shared_utils.assert_CDL( + request, + file_out, + ( + "integration", + "netcdf", + "general", + "TestPackedData", + CDLfilename, + ), + ) - def test_single_packed_signed(self): + def test_single_packed_signed(self, request, tmp_path): """Test saving a single CF-netCDF file with packing.""" - self._single_test("i2", "single_packed_signed.cdl") + self._single_test("i2", "single_packed_signed.cdl", request, tmp_path) - def test_single_packed_unsigned(self): + def test_single_packed_unsigned(self, request, tmp_path): """Test saving a single CF-netCDF file with packing into unsigned.""" - self._single_test("u1", "single_packed_unsigned.cdl") + self._single_test("u1", "single_packed_unsigned.cdl", request, tmp_path) - def test_single_packed_manual_scale(self): + def test_single_packed_manual_scale(self, request, tmp_path): """Test saving a single CF-netCDF file. File with packing with scale factor and add_offset set manually. """ - self._single_test("i2", "single_packed_manual.cdl", manual=True) + self._single_test( + "i2", "single_packed_manual.cdl", request, tmp_path, manual=True + ) - def _multi_test(self, CDLfilename, multi_dtype=False): + def _multi_test(self, CDLfilename, request, tmp_path, multi_dtype=False): """Test saving multiple packed cubes with pack_dtype list.""" # Read PP input file. - file_in = tests.get_data_path( + file_in = _shared_utils.get_data_path( ("PP", "cf_processing", "abcza_pa19591997_daily_29.b.pp") ) cubes = iris.load(file_in) @@ -256,74 +254,77 @@ def _multi_test(self, CDLfilename, multi_dtype=False): dtypes = repeat(packspec) # Write Cube to netCDF file. - with self.temp_filename(suffix=".nc") as file_out: - iris.save(cubes, file_out, packing=packspec) - # Check the netCDF file against CDL expected output. - self.assertCDL( - file_out, - ( - "integration", - "netcdf", - "general", - "TestPackedData", - CDLfilename, - ), - ) - packedcubes = iris.load(file_out) - packedcubes.sort(key=lambda cube: cube.cell_methods[0].method) - for cube, packedcube, dtype in zip(cubes, packedcubes, dtypes): - if dtype: - sf, ao = _get_scale_factor_add_offset(cube, dtype) - decimal = int(-np.log10(sf)) - # Check that packed cube is accurate to expected precision - self.assertArrayAlmostEqual( - cube.data, packedcube.data, decimal=decimal - ) - else: - self.assertArrayEqual(cube.data, packedcube.data) - - def test_multi_packed_single_dtype(self): + file_out = tmp_path / "tmp.nc" + iris.save(cubes, file_out, packing=packspec) + # Check the netCDF file against CDL expected output. + _shared_utils.assert_CDL( + request, + file_out, + ( + "integration", + "netcdf", + "general", + "TestPackedData", + CDLfilename, + ), + ) + packedcubes = iris.load(file_out) + packedcubes.sort(key=lambda cube: cube.cell_methods[0].method) + for cube, packedcube, dtype in zip(cubes, packedcubes, dtypes): + if dtype: + sf, ao = _get_scale_factor_add_offset(cube, dtype) + decimal = int(-np.log10(sf)) + # Check that packed cube is accurate to expected precision + _shared_utils.assert_array_almost_equal( + cube.data, packedcube.data, decimal=decimal + ) + else: + _shared_utils.assert_array_equal(cube.data, packedcube.data) + + def test_multi_packed_single_dtype(self, request, tmp_path): """Test saving multiple packed cubes with the same pack_dtype.""" # Read PP input file. - self._multi_test("multi_packed_single_dtype.cdl") + self._multi_test("multi_packed_single_dtype.cdl", request, tmp_path) - def test_multi_packed_multi_dtype(self): + def test_multi_packed_multi_dtype(self, request, tmp_path): """Test saving multiple packed cubes with pack_dtype list.""" # Read PP input file. - self._multi_test("multi_packed_multi_dtype.cdl", multi_dtype=True) + self._multi_test( + "multi_packed_multi_dtype.cdl", request, tmp_path, multi_dtype=True + ) -class TestScalarCube(tests.IrisTest): - def test_scalar_cube_save_load(self): +class TestScalarCube: + def test_scalar_cube_save_load(self, tmp_path): cube = iris.cube.Cube(1, long_name="scalar_cube") - with self.temp_filename(suffix=".nc") as fout: - iris.save(cube, fout) - scalar_cube = iris.load_cube(fout) - self.assertEqual(scalar_cube.name(), "scalar_cube") + fout = tmp_path / "scalar_cube.nc" + iris.save(cube, fout) + scalar_cube = iris.load_cube(fout) + assert scalar_cube.name() == "scalar_cube" -@tests.skip_data -class TestConstrainedLoad(tests.IrisTest): - filename = tests.get_data_path( +@_shared_utils.skip_data +class TestConstrainedLoad: + filename = _shared_utils.get_data_path( ("NetCDF", "label_and_climate", "A1B-99999a-river-sep-2070-2099.nc") ) def test_netcdf_with_NameConstraint(self): constr = iris.NameConstraint(var_name="cdf_temp_dmax_tmean_abs") cubes = iris.load(self.filename, constr) - self.assertEqual(len(cubes), 1) - self.assertEqual(cubes[0].var_name, "cdf_temp_dmax_tmean_abs") + assert len(cubes) == 1 + assert cubes[0].var_name == "cdf_temp_dmax_tmean_abs" def test_netcdf_with_2_NameConstraints(self): var_names = ["cdf_temp_dmax_tmean_abs", "temp_dmax_tmean_abs"] constrs = [iris.NameConstraint(var_name=var_name) for var_name in var_names] cubes = iris.load(self.filename, constrs) - self.assertEqual(len(cubes), 2) - self.assertEqual(sorted([cube.var_name for cube in cubes]), var_names) + assert len(cubes) == 2 + assert sorted([cube.var_name for cube in cubes]) == var_names def test_netcdf_with_no_constraint(self): cubes = iris.load(self.filename) - self.assertEqual(len(cubes), 3) + assert len(cubes) == 3 class TestSkippedCoord: @@ -367,7 +368,8 @@ def create_nc_file(self, tmp_path): def test_lat_not_loaded(self): with pytest.warns(match="Not all file objects were parsed correctly"): cube = iris.load_cube(self.nc_path) - with pytest.raises(iris.exceptions.CoordinateNotFoundError): + msg = "Expected to find exactly 1" + with pytest.raises(iris.exceptions.CoordinateNotFoundError, match=msg): _ = cube.coord("lat") problems = LOAD_PROBLEMS.problems assert isinstance(problems[-2].loaded, iris.coords.DimCoord) @@ -375,11 +377,12 @@ def test_lat_not_loaded(self): assert problems[-1].loaded.name() == "latitude" -@tests.skip_data -class TestDatasetAndPathLoads(tests.IrisTest): - @classmethod - def setUpClass(cls): - cls.filepath = tests.get_data_path( +@_shared_utils.skip_data +class TestDatasetAndPathLoads: + @pytest.fixture(scope="class", autouse=True) + def _setup_class(self, request): + cls = request.cls + cls.filepath = _shared_utils.get_data_path( ["NetCDF", "global", "xyz_t", "GEMS_CO2_Apr2006.nc"] ) cls.phenom_id = "Carbon Dioxide" @@ -390,27 +393,28 @@ def test_basic_load(self): ds = nc.Dataset(self.filepath) result = iris.load_cube(ds, self.phenom_id) # It should still be open (!) - self.assertTrue(ds.isopen()) + assert ds.isopen() ds.close() # Check that result is just the same as a 'direct' load. - self.assertEqual(self.expected, result) + assert self.expected == result def test_path_string_load_same(self): # Check that loading from a Path is the same as passing a filepath string. # Apart from general utility, checks that we won't mistake a Path for a Dataset. path = Path(self.filepath) result = iris.load_cube(path, self.phenom_id) - self.assertEqual(result, self.expected) + assert self.expected == result -@tests.skip_data -class TestDatasetAndPathSaves(tests.IrisTest): - @classmethod - def setUpClass(cls): +@_shared_utils.skip_data +class TestDatasetAndPathSaves: + @pytest.fixture(scope="class", autouse=True) + def _setup_class(self, request, tmp_path_factory): + cls = request.cls # Create a temp directory for transient test files. - cls.temp_dir = tempfile.mkdtemp() - cls.testpath = tests.get_data_path( + cls.temp_dir = tmp_path_factory.mktemp("test") + cls.testpath = _shared_utils.get_data_path( ["NetCDF", "global", "xyz_t", "GEMS_CO2_Apr2006.nc"] ) # Load some test data for save testing. @@ -419,12 +423,7 @@ def setUpClass(cls): testdata = sorted(testdata, key=lambda cube: cube.name()) cls.testdata = testdata - @classmethod - def tearDownClass(cls): - # Destroy the temp directory. - shutil.rmtree(cls.temp_dir) - - def test_basic_save(self): + def test_basic_save(self, request): # test saving to a Dataset, in place of a filepath spec. # NOTE that this requires 'compute=False', as delayed saves can only operate on # a closed file. @@ -433,7 +432,7 @@ def test_basic_save(self): filepath_direct = f"{self.temp_dir}/tmp_direct.nc" iris.save(self.testdata, filepath_direct) # Check against test-specific CDL result file. - self.assertCDL(filepath_direct) + _shared_utils.assert_CDL(request, filepath_direct) # Save same data indirectly via a netcdf dataset. filepath_indirect = f"{self.temp_dir}/tmp_indirect.nc" @@ -444,19 +443,17 @@ def test_basic_save(self): # Do some very basic sanity checks on the resulting Dataset. # It should still be open (!) - self.assertTrue(nc_dataset.isopen()) - self.assertEqual( - ["time", "levelist", "latitude", "longitude"], - list(nc_dataset.dimensions), + assert nc_dataset.isopen() + assert ["time", "levelist", "latitude", "longitude"] == list( + nc_dataset.dimensions ) - self.assertEqual( - ["co2", "time", "levelist", "latitude", "longitude", "lnsp"], - list(nc_dataset.variables), + assert ["co2", "time", "levelist", "latitude", "longitude", "lnsp"] == list( + nc_dataset.variables, ) nc_dataset.close() # Check the saved file against the same CDL as the 'normal' save. - self.assertCDL(filepath_indirect) + _shared_utils.assert_CDL(request, filepath_indirect) # Confirm that cube content is however not yet written. ds = nc.Dataset(filepath_indirect) @@ -484,7 +481,7 @@ def test_computed_delayed_save__fail(self): with pytest.raises(ValueError, match=msg): iris.save(self.testdata, nc_dataset, saver="nc") - def test_path_string_save_same(self): + def test_path_string_save_same(self, request): # Ensure that save to a Path is the same as passing a filepath string. # Apart from general utility, checks that we won't mistake a Path for a Dataset. tempfile_fromstr = f"{self.temp_dir}/tmp_fromstr.nc" @@ -492,18 +489,18 @@ def test_path_string_save_same(self): tempfile_frompath = f"{self.temp_dir}/tmp_frompath.nc" path = Path(tempfile_frompath) iris.save(self.testdata, path) - self.assertCDL(tempfile_fromstr) - self.assertCDL(tempfile_frompath) + _shared_utils.assert_CDL(request, tempfile_fromstr) + _shared_utils.assert_CDL(request, tempfile_frompath) -@tests.skip_data -class TestWarningRepeats(tests.IrisTest): +@_shared_utils.skip_data +class TestWarningRepeats: def test_warning_repeats(self): """Confirm Iris load does not break Python duplicate warning handling.""" # units.nc is designed for testing Iris' 'ignoring invalid units' # warning; it contains two variables with invalid units, producing two # unique warnings (due to two different messages). - file_path = tests.get_data_path(("NetCDF", "testing", "units.nc")) + file_path = _shared_utils.get_data_path(("NetCDF", "testing", "units.nc")) def _raise_warning() -> None: # Contain in function so warning always has identical line number. @@ -530,7 +527,3 @@ def _raise_warning() -> None: _ = iris.load(file_path) _raise_warning() assert len(record) == 3 - - -if __name__ == "__main__": - tests.main() diff --git a/lib/iris/tests/results/integration/netcdf/general/TestDatasetAndPathSaves/basic_save.cdl b/lib/iris/tests/results/integration/netcdf/general/TestDatasetAndPathSaves/basic_save.cdl deleted file mode 100644 index 133c886d87..0000000000 --- a/lib/iris/tests/results/integration/netcdf/general/TestDatasetAndPathSaves/basic_save.cdl +++ /dev/null @@ -1,34 +0,0 @@ -dimensions: - latitude = 181 ; - levelist = 60 ; - longitude = 360 ; - time = 1 ; -variables: - double co2(time, levelist, latitude, longitude) ; - co2:long_name = "Carbon Dioxide" ; - co2:units = "kg kg**-1" ; - int time(time) ; - time:axis = "T" ; - time:units = "hours since 1900-01-01 00:00:0.0" ; - time:standard_name = "time" ; - time:long_name = "time" ; - time:calendar = "standard" ; - int levelist(levelist) ; - levelist:long_name = "model_level_number" ; - float latitude(latitude) ; - latitude:axis = "Y" ; - latitude:units = "degrees_north" ; - latitude:standard_name = "latitude" ; - latitude:long_name = "latitude" ; - float longitude(longitude) ; - longitude:axis = "X" ; - longitude:units = "degrees_east" ; - longitude:standard_name = "longitude" ; - longitude:long_name = "longitude" ; - double lnsp(time, levelist, latitude, longitude) ; - lnsp:long_name = "Logarithm of surface pressure" ; - -// global attributes: - :history = "2009-08-25 13:46:31 GMT by mars2netcdf-0.92" ; - :Conventions = "CF-1.7" ; -} diff --git a/lib/iris/tests/results/integration/netcdf/general/TestDatasetAndPathSaves/path_string_save_same.cdl b/lib/iris/tests/results/integration/netcdf/general/TestDatasetAndPathSaves/path_string_save_same.cdl deleted file mode 100644 index 133c886d87..0000000000 --- a/lib/iris/tests/results/integration/netcdf/general/TestDatasetAndPathSaves/path_string_save_same.cdl +++ /dev/null @@ -1,34 +0,0 @@ -dimensions: - latitude = 181 ; - levelist = 60 ; - longitude = 360 ; - time = 1 ; -variables: - double co2(time, levelist, latitude, longitude) ; - co2:long_name = "Carbon Dioxide" ; - co2:units = "kg kg**-1" ; - int time(time) ; - time:axis = "T" ; - time:units = "hours since 1900-01-01 00:00:0.0" ; - time:standard_name = "time" ; - time:long_name = "time" ; - time:calendar = "standard" ; - int levelist(levelist) ; - levelist:long_name = "model_level_number" ; - float latitude(latitude) ; - latitude:axis = "Y" ; - latitude:units = "degrees_north" ; - latitude:standard_name = "latitude" ; - latitude:long_name = "latitude" ; - float longitude(longitude) ; - longitude:axis = "X" ; - longitude:units = "degrees_east" ; - longitude:standard_name = "longitude" ; - longitude:long_name = "longitude" ; - double lnsp(time, levelist, latitude, longitude) ; - lnsp:long_name = "Logarithm of surface pressure" ; - -// global attributes: - :history = "2009-08-25 13:46:31 GMT by mars2netcdf-0.92" ; - :Conventions = "CF-1.7" ; -} diff --git a/lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_multi_dtype.cdl b/lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_multi_dtype.cdl deleted file mode 100644 index 8a8f481492..0000000000 --- a/lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_multi_dtype.cdl +++ /dev/null @@ -1,68 +0,0 @@ -dimensions: - bnds = 2 ; - latitude = 73 ; - longitude = 96 ; - time = 360 ; -variables: - short air_temperature(time, latitude, longitude) ; - air_temperature:scale_factor = 0.00242575f ; - air_temperature:add_offset = 261.648f ; - air_temperature:standard_name = "air_temperature" ; - air_temperature:units = "K" ; - air_temperature:um_stash_source = "m01s03i236" ; - air_temperature:cell_methods = "time: maximum (interval: 1 hour)" ; - air_temperature:grid_mapping = "latitude_longitude" ; - air_temperature:coordinates = "forecast_period forecast_reference_time height" ; - int latitude_longitude ; - latitude_longitude:grid_mapping_name = "latitude_longitude" ; - latitude_longitude:longitude_of_prime_meridian = 0. ; - latitude_longitude:earth_radius = 6371229. ; - double time(time) ; - time:axis = "T" ; - time:bounds = "time_bnds" ; - time:units = "hours since 1970-01-01 00:00:00" ; - time:standard_name = "time" ; - time:calendar = "360_day" ; - double time_bnds(time, bnds) ; - float latitude(latitude) ; - latitude:axis = "Y" ; - latitude:units = "degrees_north" ; - latitude:standard_name = "latitude" ; - float longitude(longitude) ; - longitude:axis = "X" ; - longitude:units = "degrees_east" ; - longitude:standard_name = "longitude" ; - double forecast_period(time) ; - forecast_period:bounds = "forecast_period_bnds" ; - forecast_period:units = "hours" ; - forecast_period:standard_name = "forecast_period" ; - double forecast_period_bnds(time, bnds) ; - double forecast_reference_time ; - forecast_reference_time:units = "hours since 1970-01-01 00:00:00" ; - forecast_reference_time:standard_name = "forecast_reference_time" ; - forecast_reference_time:calendar = "360_day" ; - double height ; - height:units = "m" ; - height:standard_name = "height" ; - height:positive = "up" ; - float precipitation_flux(time, latitude, longitude) ; - precipitation_flux:standard_name = "precipitation_flux" ; - precipitation_flux:units = "kg m-2 s-1" ; - precipitation_flux:um_stash_source = "m01s05i216" ; - precipitation_flux:cell_methods = "time: mean (interval: 1 hour)" ; - precipitation_flux:grid_mapping = "latitude_longitude" ; - precipitation_flux:coordinates = "forecast_period forecast_reference_time" ; - ushort air_temperature_0(time, latitude, longitude) ; - air_temperature_0:scale_factor = 0.002014167f ; - air_temperature_0:add_offset = 176.7872f ; - air_temperature_0:standard_name = "air_temperature" ; - air_temperature_0:units = "K" ; - air_temperature_0:um_stash_source = "m01s03i236" ; - air_temperature_0:cell_methods = "time: minimum (interval: 1 hour)" ; - air_temperature_0:grid_mapping = "latitude_longitude" ; - air_temperature_0:coordinates = "forecast_period forecast_reference_time height" ; - -// global attributes: - :source = "Data from Met Office Unified Model" ; - :Conventions = "CF-1.7" ; -} diff --git a/lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_single_dtype.cdl b/lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_single_dtype.cdl deleted file mode 100644 index 3f2c909ce8..0000000000 --- a/lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_single_dtype.cdl +++ /dev/null @@ -1,70 +0,0 @@ -dimensions: - bnds = 2 ; - latitude = 73 ; - longitude = 96 ; - time = 360 ; -variables: - short air_temperature(time, latitude, longitude) ; - air_temperature:scale_factor = 0.00242575f ; - air_temperature:add_offset = 261.648f ; - air_temperature:standard_name = "air_temperature" ; - air_temperature:units = "K" ; - air_temperature:um_stash_source = "m01s03i236" ; - air_temperature:cell_methods = "time: maximum (interval: 1 hour)" ; - air_temperature:grid_mapping = "latitude_longitude" ; - air_temperature:coordinates = "forecast_period forecast_reference_time height" ; - int latitude_longitude ; - latitude_longitude:grid_mapping_name = "latitude_longitude" ; - latitude_longitude:longitude_of_prime_meridian = 0. ; - latitude_longitude:earth_radius = 6371229. ; - double time(time) ; - time:axis = "T" ; - time:bounds = "time_bnds" ; - time:units = "hours since 1970-01-01 00:00:00" ; - time:standard_name = "time" ; - time:calendar = "360_day" ; - double time_bnds(time, bnds) ; - float latitude(latitude) ; - latitude:axis = "Y" ; - latitude:units = "degrees_north" ; - latitude:standard_name = "latitude" ; - float longitude(longitude) ; - longitude:axis = "X" ; - longitude:units = "degrees_east" ; - longitude:standard_name = "longitude" ; - double forecast_period(time) ; - forecast_period:bounds = "forecast_period_bnds" ; - forecast_period:units = "hours" ; - forecast_period:standard_name = "forecast_period" ; - double forecast_period_bnds(time, bnds) ; - double forecast_reference_time ; - forecast_reference_time:units = "hours since 1970-01-01 00:00:00" ; - forecast_reference_time:standard_name = "forecast_reference_time" ; - forecast_reference_time:calendar = "360_day" ; - double height ; - height:units = "m" ; - height:standard_name = "height" ; - height:positive = "up" ; - short precipitation_flux(time, latitude, longitude) ; - precipitation_flux:scale_factor = 2.989738e-08f ; - precipitation_flux:add_offset = 0.0009796774f ; - precipitation_flux:standard_name = "precipitation_flux" ; - precipitation_flux:units = "kg m-2 s-1" ; - precipitation_flux:um_stash_source = "m01s05i216" ; - precipitation_flux:cell_methods = "time: mean (interval: 1 hour)" ; - precipitation_flux:grid_mapping = "latitude_longitude" ; - precipitation_flux:coordinates = "forecast_period forecast_reference_time" ; - short air_temperature_0(time, latitude, longitude) ; - air_temperature_0:scale_factor = 0.002014167f ; - air_temperature_0:add_offset = 242.7874f ; - air_temperature_0:standard_name = "air_temperature" ; - air_temperature_0:units = "K" ; - air_temperature_0:um_stash_source = "m01s03i236" ; - air_temperature_0:cell_methods = "time: minimum (interval: 1 hour)" ; - air_temperature_0:grid_mapping = "latitude_longitude" ; - air_temperature_0:coordinates = "forecast_period forecast_reference_time height" ; - -// global attributes: - :source = "Data from Met Office Unified Model" ; - :Conventions = "CF-1.7" ; -} diff --git a/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_manual.cdl b/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_manual.cdl deleted file mode 100644 index 83e7329575..0000000000 --- a/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_manual.cdl +++ /dev/null @@ -1,50 +0,0 @@ -dimensions: - bnds = 2 ; - latitude = 73 ; - longitude = 96 ; -variables: - short air_temperature(latitude, longitude) ; - air_temperature:scale_factor = 0.001198068f ; - air_temperature:add_offset = 267.4006f ; - air_temperature:standard_name = "air_temperature" ; - air_temperature:units = "K" ; - air_temperature:um_stash_source = "m01s03i236" ; - air_temperature:cell_methods = "time: mean (interval: 6 hour)" ; - air_temperature:grid_mapping = "latitude_longitude" ; - air_temperature:coordinates = "forecast_period forecast_reference_time height time" ; - int latitude_longitude ; - latitude_longitude:grid_mapping_name = "latitude_longitude" ; - latitude_longitude:longitude_of_prime_meridian = 0. ; - latitude_longitude:earth_radius = 6371229. ; - float latitude(latitude) ; - latitude:axis = "Y" ; - latitude:units = "degrees_north" ; - latitude:standard_name = "latitude" ; - float longitude(longitude) ; - longitude:axis = "X" ; - longitude:units = "degrees_east" ; - longitude:standard_name = "longitude" ; - double forecast_period ; - forecast_period:bounds = "forecast_period_bnds" ; - forecast_period:units = "hours" ; - forecast_period:standard_name = "forecast_period" ; - double forecast_period_bnds(bnds) ; - double forecast_reference_time ; - forecast_reference_time:units = "hours since 1970-01-01 00:00:00" ; - forecast_reference_time:standard_name = "forecast_reference_time" ; - forecast_reference_time:calendar = "standard" ; - double height ; - height:units = "m" ; - height:standard_name = "height" ; - height:positive = "up" ; - double time ; - time:bounds = "time_bnds" ; - time:units = "hours since 1970-01-01 00:00:00" ; - time:standard_name = "time" ; - time:calendar = "standard" ; - double time_bnds(bnds) ; - -// global attributes: - :source = "Data from Met Office Unified Model" ; - :Conventions = "CF-1.7" ; -} diff --git a/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_signed.cdl b/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_signed.cdl deleted file mode 100644 index 83e7329575..0000000000 --- a/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_signed.cdl +++ /dev/null @@ -1,50 +0,0 @@ -dimensions: - bnds = 2 ; - latitude = 73 ; - longitude = 96 ; -variables: - short air_temperature(latitude, longitude) ; - air_temperature:scale_factor = 0.001198068f ; - air_temperature:add_offset = 267.4006f ; - air_temperature:standard_name = "air_temperature" ; - air_temperature:units = "K" ; - air_temperature:um_stash_source = "m01s03i236" ; - air_temperature:cell_methods = "time: mean (interval: 6 hour)" ; - air_temperature:grid_mapping = "latitude_longitude" ; - air_temperature:coordinates = "forecast_period forecast_reference_time height time" ; - int latitude_longitude ; - latitude_longitude:grid_mapping_name = "latitude_longitude" ; - latitude_longitude:longitude_of_prime_meridian = 0. ; - latitude_longitude:earth_radius = 6371229. ; - float latitude(latitude) ; - latitude:axis = "Y" ; - latitude:units = "degrees_north" ; - latitude:standard_name = "latitude" ; - float longitude(longitude) ; - longitude:axis = "X" ; - longitude:units = "degrees_east" ; - longitude:standard_name = "longitude" ; - double forecast_period ; - forecast_period:bounds = "forecast_period_bnds" ; - forecast_period:units = "hours" ; - forecast_period:standard_name = "forecast_period" ; - double forecast_period_bnds(bnds) ; - double forecast_reference_time ; - forecast_reference_time:units = "hours since 1970-01-01 00:00:00" ; - forecast_reference_time:standard_name = "forecast_reference_time" ; - forecast_reference_time:calendar = "standard" ; - double height ; - height:units = "m" ; - height:standard_name = "height" ; - height:positive = "up" ; - double time ; - time:bounds = "time_bnds" ; - time:units = "hours since 1970-01-01 00:00:00" ; - time:standard_name = "time" ; - time:calendar = "standard" ; - double time_bnds(bnds) ; - -// global attributes: - :source = "Data from Met Office Unified Model" ; - :Conventions = "CF-1.7" ; -} diff --git a/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_unsigned.cdl b/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_unsigned.cdl deleted file mode 100644 index 7b9114309e..0000000000 --- a/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_unsigned.cdl +++ /dev/null @@ -1,50 +0,0 @@ -dimensions: - bnds = 2 ; - latitude = 73 ; - longitude = 96 ; -variables: - ubyte air_temperature(latitude, longitude) ; - air_temperature:scale_factor = 0.3079035f ; - air_temperature:add_offset = 228.1423f ; - air_temperature:standard_name = "air_temperature" ; - air_temperature:units = "K" ; - air_temperature:um_stash_source = "m01s03i236" ; - air_temperature:cell_methods = "time: mean (interval: 6 hour)" ; - air_temperature:grid_mapping = "latitude_longitude" ; - air_temperature:coordinates = "forecast_period forecast_reference_time height time" ; - int latitude_longitude ; - latitude_longitude:grid_mapping_name = "latitude_longitude" ; - latitude_longitude:longitude_of_prime_meridian = 0. ; - latitude_longitude:earth_radius = 6371229. ; - float latitude(latitude) ; - latitude:axis = "Y" ; - latitude:units = "degrees_north" ; - latitude:standard_name = "latitude" ; - float longitude(longitude) ; - longitude:axis = "X" ; - longitude:units = "degrees_east" ; - longitude:standard_name = "longitude" ; - double forecast_period ; - forecast_period:bounds = "forecast_period_bnds" ; - forecast_period:units = "hours" ; - forecast_period:standard_name = "forecast_period" ; - double forecast_period_bnds(bnds) ; - double forecast_reference_time ; - forecast_reference_time:units = "hours since 1970-01-01 00:00:00" ; - forecast_reference_time:standard_name = "forecast_reference_time" ; - forecast_reference_time:calendar = "standard" ; - double height ; - height:units = "m" ; - height:standard_name = "height" ; - height:positive = "up" ; - double time ; - time:bounds = "time_bnds" ; - time:units = "hours since 1970-01-01 00:00:00" ; - time:standard_name = "time" ; - time:calendar = "standard" ; - double time_bnds(bnds) ; - -// global attributes: - :source = "Data from Met Office Unified Model" ; - :Conventions = "CF-1.7" ; -} From 877072f30114f971334f2bdad74ade636fe8f58d Mon Sep 17 00:00:00 2001 From: Elias Sadek Date: Tue, 25 Nov 2025 16:30:54 +0000 Subject: [PATCH 08/12] aligned test_self_ref --- .../netcdf/test_self_referencing.py | 43 ++++++------------- 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/lib/iris/tests/integration/netcdf/test_self_referencing.py b/lib/iris/tests/integration/netcdf/test_self_referencing.py index b2b9b6d4e1..1f0183374c 100644 --- a/lib/iris/tests/integration/netcdf/test_self_referencing.py +++ b/lib/iris/tests/integration/netcdf/test_self_referencing.py @@ -4,25 +4,20 @@ # See LICENSE in the root of the repository for full licensing details. """Integration tests for iris#3367 - loading a self-referencing NetCDF file.""" -# Import iris.tests first so that some things can be initialised before -# importing anything else. -import iris.tests as tests # isort:skip - -import os -import tempfile -from unittest import mock - import numpy as np +import pytest import iris from iris.fileformats.netcdf import _thread_safe_nc +from iris.tests import _shared_utils from iris.warnings import IrisCfMissingVarWarning -@tests.skip_data -class TestCMIP6VolcelloLoad(tests.IrisTest): - def setUp(self): - self.fname = tests.get_data_path( +@_shared_utils.skip_data +class TestCMIP6VolcelloLoad: + @pytest.fixture(autouse=True) + def _setup(self): + self.fname = _shared_utils.get_data_path( ( "NetCDF", "volcello", @@ -43,22 +38,18 @@ def test_cmip6_volcello_load_issue_3367(self): "referenced by netCDF variable %r" % (areacello_str, volcello_str) ) - with mock.patch("warnings.warn") as warn: + with pytest.warns(IrisCfMissingVarWarning, match=expected_msg): # ensure file loads without failure cube = iris.load_cube(self.fname) - warn.assert_has_calls( - [mock.call(expected_msg, category=IrisCfMissingVarWarning)] - ) # extra check to ensure correct variable was found assert cube.standard_name == "ocean_volume" -class TestSelfReferencingVarLoad(tests.IrisTest): - def setUp(self): - self.temp_dir_path = os.path.join( - tempfile.mkdtemp(), "issue_3367_volcello_test_file.nc" - ) +class TestSelfReferencingVarLoad: + @pytest.fixture(autouse=True) + def _setup(self, tmp_path): + self.temp_dir_path = tmp_path / "issue_3367_volcello_test_file.nc" dataset = _thread_safe_nc.DatasetWrapper(self.temp_dir_path, "w") dataset.createDimension("lat", 4) @@ -110,17 +101,9 @@ def test_self_referencing_load_issue_3367(self): "referenced by netCDF variable %r" % (areacello_str, volcello_str) ) - with mock.patch("warnings.warn") as warn: + with pytest.warns(IrisCfMissingVarWarning, match=expected_msg): # ensure file loads without failure cube = iris.load_cube(self.temp_dir_path) - warn.assert_called_with(expected_msg, category=IrisCfMissingVarWarning) # extra check to ensure correct variable was found assert cube.standard_name == "ocean_volume" - - def tearDown(self): - os.remove(self.temp_dir_path) - - -if __name__ == "__main__": - tests.main() From 0cd0beebc2a4c98ef720a4bab4fdf4c5ebe5f13a Mon Sep 17 00:00:00 2001 From: Elias Sadek Date: Wed, 26 Nov 2025 13:41:32 +0000 Subject: [PATCH 09/12] added cdl files --- .../multiple_different_saves_on_variables.cdl | 15 ++++ .../multiple_same_saves_as_global.cdl | 14 ++++ .../single_saves_as_global.cdl | 11 +++ .../DatasetAndPathSaves/basic_save.cdl | 34 +++++++++ .../path_string_save_same.cdl | 34 +++++++++ .../multi_packed_multi_dtype.cdl | 68 ++++++++++++++++++ .../multi_packed_single_dtype.cdl | 70 +++++++++++++++++++ .../TestPackedData/single_packed_manual.cdl | 50 +++++++++++++ .../TestPackedData/single_packed_signed.cdl | 50 +++++++++++++ .../TestPackedData/single_packed_unsigned.cdl | 50 +++++++++++++ 10 files changed, 396 insertions(+) create mode 100644 lib/iris/tests/results/integration/netcdf/attributes/UmVersionAttribute/multiple_different_saves_on_variables.cdl create mode 100644 lib/iris/tests/results/integration/netcdf/attributes/UmVersionAttribute/multiple_same_saves_as_global.cdl create mode 100644 lib/iris/tests/results/integration/netcdf/attributes/UmVersionAttribute/single_saves_as_global.cdl create mode 100644 lib/iris/tests/results/integration/netcdf/general/DatasetAndPathSaves/basic_save.cdl create mode 100644 lib/iris/tests/results/integration/netcdf/general/DatasetAndPathSaves/path_string_save_same.cdl create mode 100644 lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_multi_dtype.cdl create mode 100644 lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_single_dtype.cdl create mode 100644 lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_manual.cdl create mode 100644 lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_signed.cdl create mode 100644 lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_unsigned.cdl diff --git a/lib/iris/tests/results/integration/netcdf/attributes/UmVersionAttribute/multiple_different_saves_on_variables.cdl b/lib/iris/tests/results/integration/netcdf/attributes/UmVersionAttribute/multiple_different_saves_on_variables.cdl new file mode 100644 index 0000000000..a22044c2d9 --- /dev/null +++ b/lib/iris/tests/results/integration/netcdf/attributes/UmVersionAttribute/multiple_different_saves_on_variables.cdl @@ -0,0 +1,15 @@ +dimensions: + dim0 = 1 ; +variables: + double air_temperature(dim0) ; + air_temperature:standard_name = "air_temperature" ; + air_temperature:units = "K" ; + air_temperature:um_version = "4.3" ; + double air_pressure(dim0) ; + air_pressure:standard_name = "air_pressure" ; + air_pressure:units = "hPa" ; + air_pressure:um_version = "4.4" ; + +// global attributes: + :Conventions = "CF-1.7" ; +} diff --git a/lib/iris/tests/results/integration/netcdf/attributes/UmVersionAttribute/multiple_same_saves_as_global.cdl b/lib/iris/tests/results/integration/netcdf/attributes/UmVersionAttribute/multiple_same_saves_as_global.cdl new file mode 100644 index 0000000000..be35bfd590 --- /dev/null +++ b/lib/iris/tests/results/integration/netcdf/attributes/UmVersionAttribute/multiple_same_saves_as_global.cdl @@ -0,0 +1,14 @@ +dimensions: + dim0 = 1 ; +variables: + double air_temperature(dim0) ; + air_temperature:standard_name = "air_temperature" ; + air_temperature:units = "K" ; + double air_pressure(dim0) ; + air_pressure:standard_name = "air_pressure" ; + air_pressure:units = "hPa" ; + +// global attributes: + :um_version = "4.3" ; + :Conventions = "CF-1.7" ; +} diff --git a/lib/iris/tests/results/integration/netcdf/attributes/UmVersionAttribute/single_saves_as_global.cdl b/lib/iris/tests/results/integration/netcdf/attributes/UmVersionAttribute/single_saves_as_global.cdl new file mode 100644 index 0000000000..0399f82349 --- /dev/null +++ b/lib/iris/tests/results/integration/netcdf/attributes/UmVersionAttribute/single_saves_as_global.cdl @@ -0,0 +1,11 @@ +dimensions: + dim0 = 1 ; +variables: + double air_temperature(dim0) ; + air_temperature:standard_name = "air_temperature" ; + air_temperature:units = "K" ; + +// global attributes: + :um_version = "4.3" ; + :Conventions = "CF-1.7" ; +} diff --git a/lib/iris/tests/results/integration/netcdf/general/DatasetAndPathSaves/basic_save.cdl b/lib/iris/tests/results/integration/netcdf/general/DatasetAndPathSaves/basic_save.cdl new file mode 100644 index 0000000000..133c886d87 --- /dev/null +++ b/lib/iris/tests/results/integration/netcdf/general/DatasetAndPathSaves/basic_save.cdl @@ -0,0 +1,34 @@ +dimensions: + latitude = 181 ; + levelist = 60 ; + longitude = 360 ; + time = 1 ; +variables: + double co2(time, levelist, latitude, longitude) ; + co2:long_name = "Carbon Dioxide" ; + co2:units = "kg kg**-1" ; + int time(time) ; + time:axis = "T" ; + time:units = "hours since 1900-01-01 00:00:0.0" ; + time:standard_name = "time" ; + time:long_name = "time" ; + time:calendar = "standard" ; + int levelist(levelist) ; + levelist:long_name = "model_level_number" ; + float latitude(latitude) ; + latitude:axis = "Y" ; + latitude:units = "degrees_north" ; + latitude:standard_name = "latitude" ; + latitude:long_name = "latitude" ; + float longitude(longitude) ; + longitude:axis = "X" ; + longitude:units = "degrees_east" ; + longitude:standard_name = "longitude" ; + longitude:long_name = "longitude" ; + double lnsp(time, levelist, latitude, longitude) ; + lnsp:long_name = "Logarithm of surface pressure" ; + +// global attributes: + :history = "2009-08-25 13:46:31 GMT by mars2netcdf-0.92" ; + :Conventions = "CF-1.7" ; +} diff --git a/lib/iris/tests/results/integration/netcdf/general/DatasetAndPathSaves/path_string_save_same.cdl b/lib/iris/tests/results/integration/netcdf/general/DatasetAndPathSaves/path_string_save_same.cdl new file mode 100644 index 0000000000..133c886d87 --- /dev/null +++ b/lib/iris/tests/results/integration/netcdf/general/DatasetAndPathSaves/path_string_save_same.cdl @@ -0,0 +1,34 @@ +dimensions: + latitude = 181 ; + levelist = 60 ; + longitude = 360 ; + time = 1 ; +variables: + double co2(time, levelist, latitude, longitude) ; + co2:long_name = "Carbon Dioxide" ; + co2:units = "kg kg**-1" ; + int time(time) ; + time:axis = "T" ; + time:units = "hours since 1900-01-01 00:00:0.0" ; + time:standard_name = "time" ; + time:long_name = "time" ; + time:calendar = "standard" ; + int levelist(levelist) ; + levelist:long_name = "model_level_number" ; + float latitude(latitude) ; + latitude:axis = "Y" ; + latitude:units = "degrees_north" ; + latitude:standard_name = "latitude" ; + latitude:long_name = "latitude" ; + float longitude(longitude) ; + longitude:axis = "X" ; + longitude:units = "degrees_east" ; + longitude:standard_name = "longitude" ; + longitude:long_name = "longitude" ; + double lnsp(time, levelist, latitude, longitude) ; + lnsp:long_name = "Logarithm of surface pressure" ; + +// global attributes: + :history = "2009-08-25 13:46:31 GMT by mars2netcdf-0.92" ; + :Conventions = "CF-1.7" ; +} diff --git a/lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_multi_dtype.cdl b/lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_multi_dtype.cdl new file mode 100644 index 0000000000..8a8f481492 --- /dev/null +++ b/lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_multi_dtype.cdl @@ -0,0 +1,68 @@ +dimensions: + bnds = 2 ; + latitude = 73 ; + longitude = 96 ; + time = 360 ; +variables: + short air_temperature(time, latitude, longitude) ; + air_temperature:scale_factor = 0.00242575f ; + air_temperature:add_offset = 261.648f ; + air_temperature:standard_name = "air_temperature" ; + air_temperature:units = "K" ; + air_temperature:um_stash_source = "m01s03i236" ; + air_temperature:cell_methods = "time: maximum (interval: 1 hour)" ; + air_temperature:grid_mapping = "latitude_longitude" ; + air_temperature:coordinates = "forecast_period forecast_reference_time height" ; + int latitude_longitude ; + latitude_longitude:grid_mapping_name = "latitude_longitude" ; + latitude_longitude:longitude_of_prime_meridian = 0. ; + latitude_longitude:earth_radius = 6371229. ; + double time(time) ; + time:axis = "T" ; + time:bounds = "time_bnds" ; + time:units = "hours since 1970-01-01 00:00:00" ; + time:standard_name = "time" ; + time:calendar = "360_day" ; + double time_bnds(time, bnds) ; + float latitude(latitude) ; + latitude:axis = "Y" ; + latitude:units = "degrees_north" ; + latitude:standard_name = "latitude" ; + float longitude(longitude) ; + longitude:axis = "X" ; + longitude:units = "degrees_east" ; + longitude:standard_name = "longitude" ; + double forecast_period(time) ; + forecast_period:bounds = "forecast_period_bnds" ; + forecast_period:units = "hours" ; + forecast_period:standard_name = "forecast_period" ; + double forecast_period_bnds(time, bnds) ; + double forecast_reference_time ; + forecast_reference_time:units = "hours since 1970-01-01 00:00:00" ; + forecast_reference_time:standard_name = "forecast_reference_time" ; + forecast_reference_time:calendar = "360_day" ; + double height ; + height:units = "m" ; + height:standard_name = "height" ; + height:positive = "up" ; + float precipitation_flux(time, latitude, longitude) ; + precipitation_flux:standard_name = "precipitation_flux" ; + precipitation_flux:units = "kg m-2 s-1" ; + precipitation_flux:um_stash_source = "m01s05i216" ; + precipitation_flux:cell_methods = "time: mean (interval: 1 hour)" ; + precipitation_flux:grid_mapping = "latitude_longitude" ; + precipitation_flux:coordinates = "forecast_period forecast_reference_time" ; + ushort air_temperature_0(time, latitude, longitude) ; + air_temperature_0:scale_factor = 0.002014167f ; + air_temperature_0:add_offset = 176.7872f ; + air_temperature_0:standard_name = "air_temperature" ; + air_temperature_0:units = "K" ; + air_temperature_0:um_stash_source = "m01s03i236" ; + air_temperature_0:cell_methods = "time: minimum (interval: 1 hour)" ; + air_temperature_0:grid_mapping = "latitude_longitude" ; + air_temperature_0:coordinates = "forecast_period forecast_reference_time height" ; + +// global attributes: + :source = "Data from Met Office Unified Model" ; + :Conventions = "CF-1.7" ; +} diff --git a/lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_single_dtype.cdl b/lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_single_dtype.cdl new file mode 100644 index 0000000000..3f2c909ce8 --- /dev/null +++ b/lib/iris/tests/results/integration/netcdf/general/TestPackedData/multi_packed_single_dtype.cdl @@ -0,0 +1,70 @@ +dimensions: + bnds = 2 ; + latitude = 73 ; + longitude = 96 ; + time = 360 ; +variables: + short air_temperature(time, latitude, longitude) ; + air_temperature:scale_factor = 0.00242575f ; + air_temperature:add_offset = 261.648f ; + air_temperature:standard_name = "air_temperature" ; + air_temperature:units = "K" ; + air_temperature:um_stash_source = "m01s03i236" ; + air_temperature:cell_methods = "time: maximum (interval: 1 hour)" ; + air_temperature:grid_mapping = "latitude_longitude" ; + air_temperature:coordinates = "forecast_period forecast_reference_time height" ; + int latitude_longitude ; + latitude_longitude:grid_mapping_name = "latitude_longitude" ; + latitude_longitude:longitude_of_prime_meridian = 0. ; + latitude_longitude:earth_radius = 6371229. ; + double time(time) ; + time:axis = "T" ; + time:bounds = "time_bnds" ; + time:units = "hours since 1970-01-01 00:00:00" ; + time:standard_name = "time" ; + time:calendar = "360_day" ; + double time_bnds(time, bnds) ; + float latitude(latitude) ; + latitude:axis = "Y" ; + latitude:units = "degrees_north" ; + latitude:standard_name = "latitude" ; + float longitude(longitude) ; + longitude:axis = "X" ; + longitude:units = "degrees_east" ; + longitude:standard_name = "longitude" ; + double forecast_period(time) ; + forecast_period:bounds = "forecast_period_bnds" ; + forecast_period:units = "hours" ; + forecast_period:standard_name = "forecast_period" ; + double forecast_period_bnds(time, bnds) ; + double forecast_reference_time ; + forecast_reference_time:units = "hours since 1970-01-01 00:00:00" ; + forecast_reference_time:standard_name = "forecast_reference_time" ; + forecast_reference_time:calendar = "360_day" ; + double height ; + height:units = "m" ; + height:standard_name = "height" ; + height:positive = "up" ; + short precipitation_flux(time, latitude, longitude) ; + precipitation_flux:scale_factor = 2.989738e-08f ; + precipitation_flux:add_offset = 0.0009796774f ; + precipitation_flux:standard_name = "precipitation_flux" ; + precipitation_flux:units = "kg m-2 s-1" ; + precipitation_flux:um_stash_source = "m01s05i216" ; + precipitation_flux:cell_methods = "time: mean (interval: 1 hour)" ; + precipitation_flux:grid_mapping = "latitude_longitude" ; + precipitation_flux:coordinates = "forecast_period forecast_reference_time" ; + short air_temperature_0(time, latitude, longitude) ; + air_temperature_0:scale_factor = 0.002014167f ; + air_temperature_0:add_offset = 242.7874f ; + air_temperature_0:standard_name = "air_temperature" ; + air_temperature_0:units = "K" ; + air_temperature_0:um_stash_source = "m01s03i236" ; + air_temperature_0:cell_methods = "time: minimum (interval: 1 hour)" ; + air_temperature_0:grid_mapping = "latitude_longitude" ; + air_temperature_0:coordinates = "forecast_period forecast_reference_time height" ; + +// global attributes: + :source = "Data from Met Office Unified Model" ; + :Conventions = "CF-1.7" ; +} diff --git a/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_manual.cdl b/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_manual.cdl new file mode 100644 index 0000000000..83e7329575 --- /dev/null +++ b/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_manual.cdl @@ -0,0 +1,50 @@ +dimensions: + bnds = 2 ; + latitude = 73 ; + longitude = 96 ; +variables: + short air_temperature(latitude, longitude) ; + air_temperature:scale_factor = 0.001198068f ; + air_temperature:add_offset = 267.4006f ; + air_temperature:standard_name = "air_temperature" ; + air_temperature:units = "K" ; + air_temperature:um_stash_source = "m01s03i236" ; + air_temperature:cell_methods = "time: mean (interval: 6 hour)" ; + air_temperature:grid_mapping = "latitude_longitude" ; + air_temperature:coordinates = "forecast_period forecast_reference_time height time" ; + int latitude_longitude ; + latitude_longitude:grid_mapping_name = "latitude_longitude" ; + latitude_longitude:longitude_of_prime_meridian = 0. ; + latitude_longitude:earth_radius = 6371229. ; + float latitude(latitude) ; + latitude:axis = "Y" ; + latitude:units = "degrees_north" ; + latitude:standard_name = "latitude" ; + float longitude(longitude) ; + longitude:axis = "X" ; + longitude:units = "degrees_east" ; + longitude:standard_name = "longitude" ; + double forecast_period ; + forecast_period:bounds = "forecast_period_bnds" ; + forecast_period:units = "hours" ; + forecast_period:standard_name = "forecast_period" ; + double forecast_period_bnds(bnds) ; + double forecast_reference_time ; + forecast_reference_time:units = "hours since 1970-01-01 00:00:00" ; + forecast_reference_time:standard_name = "forecast_reference_time" ; + forecast_reference_time:calendar = "standard" ; + double height ; + height:units = "m" ; + height:standard_name = "height" ; + height:positive = "up" ; + double time ; + time:bounds = "time_bnds" ; + time:units = "hours since 1970-01-01 00:00:00" ; + time:standard_name = "time" ; + time:calendar = "standard" ; + double time_bnds(bnds) ; + +// global attributes: + :source = "Data from Met Office Unified Model" ; + :Conventions = "CF-1.7" ; +} diff --git a/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_signed.cdl b/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_signed.cdl new file mode 100644 index 0000000000..83e7329575 --- /dev/null +++ b/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_signed.cdl @@ -0,0 +1,50 @@ +dimensions: + bnds = 2 ; + latitude = 73 ; + longitude = 96 ; +variables: + short air_temperature(latitude, longitude) ; + air_temperature:scale_factor = 0.001198068f ; + air_temperature:add_offset = 267.4006f ; + air_temperature:standard_name = "air_temperature" ; + air_temperature:units = "K" ; + air_temperature:um_stash_source = "m01s03i236" ; + air_temperature:cell_methods = "time: mean (interval: 6 hour)" ; + air_temperature:grid_mapping = "latitude_longitude" ; + air_temperature:coordinates = "forecast_period forecast_reference_time height time" ; + int latitude_longitude ; + latitude_longitude:grid_mapping_name = "latitude_longitude" ; + latitude_longitude:longitude_of_prime_meridian = 0. ; + latitude_longitude:earth_radius = 6371229. ; + float latitude(latitude) ; + latitude:axis = "Y" ; + latitude:units = "degrees_north" ; + latitude:standard_name = "latitude" ; + float longitude(longitude) ; + longitude:axis = "X" ; + longitude:units = "degrees_east" ; + longitude:standard_name = "longitude" ; + double forecast_period ; + forecast_period:bounds = "forecast_period_bnds" ; + forecast_period:units = "hours" ; + forecast_period:standard_name = "forecast_period" ; + double forecast_period_bnds(bnds) ; + double forecast_reference_time ; + forecast_reference_time:units = "hours since 1970-01-01 00:00:00" ; + forecast_reference_time:standard_name = "forecast_reference_time" ; + forecast_reference_time:calendar = "standard" ; + double height ; + height:units = "m" ; + height:standard_name = "height" ; + height:positive = "up" ; + double time ; + time:bounds = "time_bnds" ; + time:units = "hours since 1970-01-01 00:00:00" ; + time:standard_name = "time" ; + time:calendar = "standard" ; + double time_bnds(bnds) ; + +// global attributes: + :source = "Data from Met Office Unified Model" ; + :Conventions = "CF-1.7" ; +} diff --git a/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_unsigned.cdl b/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_unsigned.cdl new file mode 100644 index 0000000000..7b9114309e --- /dev/null +++ b/lib/iris/tests/results/integration/netcdf/general/TestPackedData/single_packed_unsigned.cdl @@ -0,0 +1,50 @@ +dimensions: + bnds = 2 ; + latitude = 73 ; + longitude = 96 ; +variables: + ubyte air_temperature(latitude, longitude) ; + air_temperature:scale_factor = 0.3079035f ; + air_temperature:add_offset = 228.1423f ; + air_temperature:standard_name = "air_temperature" ; + air_temperature:units = "K" ; + air_temperature:um_stash_source = "m01s03i236" ; + air_temperature:cell_methods = "time: mean (interval: 6 hour)" ; + air_temperature:grid_mapping = "latitude_longitude" ; + air_temperature:coordinates = "forecast_period forecast_reference_time height time" ; + int latitude_longitude ; + latitude_longitude:grid_mapping_name = "latitude_longitude" ; + latitude_longitude:longitude_of_prime_meridian = 0. ; + latitude_longitude:earth_radius = 6371229. ; + float latitude(latitude) ; + latitude:axis = "Y" ; + latitude:units = "degrees_north" ; + latitude:standard_name = "latitude" ; + float longitude(longitude) ; + longitude:axis = "X" ; + longitude:units = "degrees_east" ; + longitude:standard_name = "longitude" ; + double forecast_period ; + forecast_period:bounds = "forecast_period_bnds" ; + forecast_period:units = "hours" ; + forecast_period:standard_name = "forecast_period" ; + double forecast_period_bnds(bnds) ; + double forecast_reference_time ; + forecast_reference_time:units = "hours since 1970-01-01 00:00:00" ; + forecast_reference_time:standard_name = "forecast_reference_time" ; + forecast_reference_time:calendar = "standard" ; + double height ; + height:units = "m" ; + height:standard_name = "height" ; + height:positive = "up" ; + double time ; + time:bounds = "time_bnds" ; + time:units = "hours since 1970-01-01 00:00:00" ; + time:standard_name = "time" ; + time:calendar = "standard" ; + double time_bnds(bnds) ; + +// global attributes: + :source = "Data from Met Office Unified Model" ; + :Conventions = "CF-1.7" ; +} From da3ae4f8bbf4f99ffe84692a4e8a05d19b231253 Mon Sep 17 00:00:00 2001 From: Elias Sadek Date: Wed, 26 Nov 2025 14:06:09 +0000 Subject: [PATCH 10/12] ...and the rest --- .../aux_factories/AtmosphereSigma/save.cdl | 62 +++++++++++++++ .../aux_factories/HybridPressure/save.cdl | 66 ++++++++++++++++ .../hybrid_height_and_pressure.cdl | 78 ++++++++++++++++++ .../hybrid_height_cubes.cml | 79 +++++++++++++++++++ 4 files changed, 285 insertions(+) create mode 100644 lib/iris/tests/results/integration/netcdf/aux_factories/AtmosphereSigma/save.cdl create mode 100644 lib/iris/tests/results/integration/netcdf/aux_factories/HybridPressure/save.cdl create mode 100644 lib/iris/tests/results/integration/netcdf/aux_factories/SaveMultipleAuxFactories/hybrid_height_and_pressure.cdl create mode 100644 lib/iris/tests/results/integration/netcdf/aux_factories/SaveMultipleAuxFactories/hybrid_height_cubes.cml diff --git a/lib/iris/tests/results/integration/netcdf/aux_factories/AtmosphereSigma/save.cdl b/lib/iris/tests/results/integration/netcdf/aux_factories/AtmosphereSigma/save.cdl new file mode 100644 index 0000000000..762226192c --- /dev/null +++ b/lib/iris/tests/results/integration/netcdf/aux_factories/AtmosphereSigma/save.cdl @@ -0,0 +1,62 @@ +dimensions: + bnds = 2 ; + grid_latitude = 100 ; + grid_longitude = 100 ; + model_level_number = 70 ; + time = 6 ; +variables: + float air_potential_temperature(time, model_level_number, grid_latitude, grid_longitude) ; + air_potential_temperature:standard_name = "air_potential_temperature" ; + air_potential_temperature:units = "K" ; + air_potential_temperature:grid_mapping = "rotated_latitude_longitude" ; + air_potential_temperature:coordinates = "forecast_period ptop sigma surface_air_pressure" ; + int rotated_latitude_longitude ; + rotated_latitude_longitude:grid_mapping_name = "rotated_latitude_longitude" ; + rotated_latitude_longitude:longitude_of_prime_meridian = 0. ; + rotated_latitude_longitude:earth_radius = 6371229. ; + rotated_latitude_longitude:grid_north_pole_latitude = 37.5 ; + rotated_latitude_longitude:grid_north_pole_longitude = 177.5 ; + rotated_latitude_longitude:north_pole_grid_longitude = 0. ; + double time(time) ; + time:axis = "T" ; + time:units = "hours since 1970-01-01 00:00:00" ; + time:standard_name = "time" ; + time:calendar = "standard" ; + int model_level_number(model_level_number) ; + model_level_number:axis = "Z" ; + model_level_number:units = "1" ; + model_level_number:standard_name = "model_level_number" ; + model_level_number:positive = "up" ; + float grid_latitude(grid_latitude) ; + grid_latitude:axis = "Y" ; + grid_latitude:bounds = "grid_latitude_bnds" ; + grid_latitude:units = "degrees" ; + grid_latitude:standard_name = "grid_latitude" ; + float grid_latitude_bnds(grid_latitude, bnds) ; + float grid_longitude(grid_longitude) ; + grid_longitude:axis = "X" ; + grid_longitude:bounds = "grid_longitude_bnds" ; + grid_longitude:units = "degrees" ; + grid_longitude:standard_name = "grid_longitude" ; + float grid_longitude_bnds(grid_longitude, bnds) ; + double forecast_period ; + forecast_period:units = "hours" ; + forecast_period:standard_name = "forecast_period" ; + double ptop ; + ptop:units = "Pa" ; + float sigma(model_level_number) ; + sigma:bounds = "sigma_bnds" ; + sigma:units = "1" ; + sigma:long_name = "sigma" ; + sigma:standard_name = "atmosphere_sigma_coordinate" ; + sigma:axis = "Z" ; + sigma:formula_terms = "ptop: ptop sigma: sigma ps: surface_air_pressure" ; + float sigma_bnds(model_level_number, bnds) ; + float surface_air_pressure(grid_latitude, grid_longitude) ; + surface_air_pressure:units = "Pa" ; + surface_air_pressure:standard_name = "surface_air_pressure" ; + +// global attributes: + :source = "Iris test case" ; + :Conventions = "CF-1.7" ; +} diff --git a/lib/iris/tests/results/integration/netcdf/aux_factories/HybridPressure/save.cdl b/lib/iris/tests/results/integration/netcdf/aux_factories/HybridPressure/save.cdl new file mode 100644 index 0000000000..6fed33430a --- /dev/null +++ b/lib/iris/tests/results/integration/netcdf/aux_factories/HybridPressure/save.cdl @@ -0,0 +1,66 @@ +dimensions: + bnds = 2 ; + grid_latitude = 100 ; + grid_longitude = 100 ; + model_level_number = 70 ; + time = 6 ; +variables: + float air_potential_temperature(time, model_level_number, grid_latitude, grid_longitude) ; + air_potential_temperature:standard_name = "air_potential_temperature" ; + air_potential_temperature:units = "K" ; + air_potential_temperature:grid_mapping = "rotated_latitude_longitude" ; + air_potential_temperature:coordinates = "forecast_period level_pressure sigma surface_air_pressure" ; + int rotated_latitude_longitude ; + rotated_latitude_longitude:grid_mapping_name = "rotated_latitude_longitude" ; + rotated_latitude_longitude:longitude_of_prime_meridian = 0. ; + rotated_latitude_longitude:earth_radius = 6371229. ; + rotated_latitude_longitude:grid_north_pole_latitude = 37.5 ; + rotated_latitude_longitude:grid_north_pole_longitude = 177.5 ; + rotated_latitude_longitude:north_pole_grid_longitude = 0. ; + double time(time) ; + time:axis = "T" ; + time:units = "hours since 1970-01-01 00:00:00" ; + time:standard_name = "time" ; + time:calendar = "standard" ; + int model_level_number(model_level_number) ; + model_level_number:axis = "Z" ; + model_level_number:units = "1" ; + model_level_number:standard_name = "model_level_number" ; + model_level_number:positive = "up" ; + float grid_latitude(grid_latitude) ; + grid_latitude:axis = "Y" ; + grid_latitude:bounds = "grid_latitude_bnds" ; + grid_latitude:units = "degrees" ; + grid_latitude:standard_name = "grid_latitude" ; + float grid_latitude_bnds(grid_latitude, bnds) ; + float grid_longitude(grid_longitude) ; + grid_longitude:axis = "X" ; + grid_longitude:bounds = "grid_longitude_bnds" ; + grid_longitude:units = "degrees" ; + grid_longitude:standard_name = "grid_longitude" ; + float grid_longitude_bnds(grid_longitude, bnds) ; + double forecast_period ; + forecast_period:units = "hours" ; + forecast_period:standard_name = "forecast_period" ; + float level_pressure(model_level_number) ; + level_pressure:bounds = "level_pressure_bnds" ; + level_pressure:units = "Pa" ; + level_pressure:long_name = "level_pressure" ; + level_pressure:positive = "up" ; + level_pressure:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate" ; + level_pressure:axis = "Z" ; + level_pressure:formula_terms = "ap: level_pressure b: sigma ps: surface_air_pressure" ; + float level_pressure_bnds(model_level_number, bnds) ; + float sigma(model_level_number) ; + sigma:bounds = "sigma_bnds" ; + sigma:units = "1" ; + sigma:long_name = "sigma" ; + float sigma_bnds(model_level_number, bnds) ; + float surface_air_pressure(grid_latitude, grid_longitude) ; + surface_air_pressure:units = "Pa" ; + surface_air_pressure:standard_name = "surface_air_pressure" ; + +// global attributes: + :source = "Iris test case" ; + :Conventions = "CF-1.7" ; +} diff --git a/lib/iris/tests/results/integration/netcdf/aux_factories/SaveMultipleAuxFactories/hybrid_height_and_pressure.cdl b/lib/iris/tests/results/integration/netcdf/aux_factories/SaveMultipleAuxFactories/hybrid_height_and_pressure.cdl new file mode 100644 index 0000000000..d813ab98dc --- /dev/null +++ b/lib/iris/tests/results/integration/netcdf/aux_factories/SaveMultipleAuxFactories/hybrid_height_and_pressure.cdl @@ -0,0 +1,78 @@ +dimensions: + bnds = 2 ; + grid_latitude = 100 ; + grid_longitude = 100 ; + model_level_number = 70 ; + time = 6 ; +variables: + float air_potential_temperature(time, model_level_number, grid_latitude, grid_longitude) ; + air_potential_temperature:standard_name = "air_potential_temperature" ; + air_potential_temperature:units = "K" ; + air_potential_temperature:grid_mapping = "rotated_latitude_longitude" ; + air_potential_temperature:coordinates = "forecast_period level_height level_pressure sigma surface_air_pressure surface_altitude unknown_scalar" ; + int rotated_latitude_longitude ; + rotated_latitude_longitude:grid_mapping_name = "rotated_latitude_longitude" ; + rotated_latitude_longitude:longitude_of_prime_meridian = 0. ; + rotated_latitude_longitude:earth_radius = 6371229. ; + rotated_latitude_longitude:grid_north_pole_latitude = 37.5 ; + rotated_latitude_longitude:grid_north_pole_longitude = 177.5 ; + rotated_latitude_longitude:north_pole_grid_longitude = 0. ; + double time(time) ; + time:axis = "T" ; + time:units = "hours since 1970-01-01 00:00:00" ; + time:standard_name = "time" ; + time:calendar = "standard" ; + int model_level_number(model_level_number) ; + model_level_number:axis = "Z" ; + model_level_number:units = "1" ; + model_level_number:standard_name = "model_level_number" ; + model_level_number:positive = "up" ; + float grid_latitude(grid_latitude) ; + grid_latitude:axis = "Y" ; + grid_latitude:bounds = "grid_latitude_bnds" ; + grid_latitude:units = "degrees" ; + grid_latitude:standard_name = "grid_latitude" ; + float grid_latitude_bnds(grid_latitude, bnds) ; + float grid_longitude(grid_longitude) ; + grid_longitude:axis = "X" ; + grid_longitude:bounds = "grid_longitude_bnds" ; + grid_longitude:units = "degrees" ; + grid_longitude:standard_name = "grid_longitude" ; + float grid_longitude_bnds(grid_longitude, bnds) ; + double forecast_period ; + forecast_period:units = "hours" ; + forecast_period:standard_name = "forecast_period" ; + float level_height(model_level_number) ; + level_height:bounds = "level_height_bnds" ; + level_height:units = "m" ; + level_height:long_name = "level_height" ; + level_height:positive = "up" ; + level_height:standard_name = "atmosphere_hybrid_height_coordinate" ; + level_height:axis = "Z" ; + level_height:formula_terms = "a: level_height b: sigma orog: surface_altitude" ; + float level_height_bnds(model_level_number, bnds) ; + double level_pressure ; + level_pressure:units = "hPa" ; + level_pressure:long_name = "level_pressure" ; + level_pressure:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate" ; + level_pressure:axis = "Z" ; + level_pressure:formula_terms = "ap: level_pressure b: unknown_scalar ps: surface_air_pressure" ; + double unknown_scalar ; + unknown_scalar:units = "1" ; + unknown_scalar:long_name = "other sigma" ; + float sigma(model_level_number) ; + sigma:bounds = "sigma_bnds" ; + sigma:units = "1" ; + sigma:long_name = "sigma" ; + float sigma_bnds(model_level_number, bnds) ; + double surface_air_pressure ; + surface_air_pressure:units = "hPa" ; + surface_air_pressure:long_name = "surface_air_pressure" ; + float surface_altitude(grid_latitude, grid_longitude) ; + surface_altitude:units = "m" ; + surface_altitude:standard_name = "surface_altitude" ; + +// global attributes: + :source = "Iris test case" ; + :Conventions = "CF-1.7" ; +} diff --git a/lib/iris/tests/results/integration/netcdf/aux_factories/SaveMultipleAuxFactories/hybrid_height_cubes.cml b/lib/iris/tests/results/integration/netcdf/aux_factories/SaveMultipleAuxFactories/hybrid_height_cubes.cml new file mode 100644 index 0000000000..4530b366ba --- /dev/null +++ b/lib/iris/tests/results/integration/netcdf/aux_factories/SaveMultipleAuxFactories/hybrid_height_cubes.cml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 20c723206639788f919bef12cb16100237e3c28a Mon Sep 17 00:00:00 2001 From: Elias Sadek Date: Wed, 26 Nov 2025 14:15:05 +0000 Subject: [PATCH 11/12] deleted redundant cml --- .../TestAtmosphereSigma/save.cdl | 62 --------- .../aux_factories/TestHybridPressure/save.cdl | 66 --------- .../hybrid_height_and_pressure.cdl | 78 ----------- .../hybrid_height_cubes.cml | 131 ------------------ 4 files changed, 337 deletions(-) delete mode 100644 lib/iris/tests/results/integration/netcdf/aux_factories/TestAtmosphereSigma/save.cdl delete mode 100644 lib/iris/tests/results/integration/netcdf/aux_factories/TestHybridPressure/save.cdl delete mode 100644 lib/iris/tests/results/integration/netcdf/aux_factories/TestSaveMultipleAuxFactories/hybrid_height_and_pressure.cdl delete mode 100644 lib/iris/tests/results/integration/netcdf/aux_factories/TestSaveMultipleAuxFactories/hybrid_height_cubes.cml diff --git a/lib/iris/tests/results/integration/netcdf/aux_factories/TestAtmosphereSigma/save.cdl b/lib/iris/tests/results/integration/netcdf/aux_factories/TestAtmosphereSigma/save.cdl deleted file mode 100644 index 762226192c..0000000000 --- a/lib/iris/tests/results/integration/netcdf/aux_factories/TestAtmosphereSigma/save.cdl +++ /dev/null @@ -1,62 +0,0 @@ -dimensions: - bnds = 2 ; - grid_latitude = 100 ; - grid_longitude = 100 ; - model_level_number = 70 ; - time = 6 ; -variables: - float air_potential_temperature(time, model_level_number, grid_latitude, grid_longitude) ; - air_potential_temperature:standard_name = "air_potential_temperature" ; - air_potential_temperature:units = "K" ; - air_potential_temperature:grid_mapping = "rotated_latitude_longitude" ; - air_potential_temperature:coordinates = "forecast_period ptop sigma surface_air_pressure" ; - int rotated_latitude_longitude ; - rotated_latitude_longitude:grid_mapping_name = "rotated_latitude_longitude" ; - rotated_latitude_longitude:longitude_of_prime_meridian = 0. ; - rotated_latitude_longitude:earth_radius = 6371229. ; - rotated_latitude_longitude:grid_north_pole_latitude = 37.5 ; - rotated_latitude_longitude:grid_north_pole_longitude = 177.5 ; - rotated_latitude_longitude:north_pole_grid_longitude = 0. ; - double time(time) ; - time:axis = "T" ; - time:units = "hours since 1970-01-01 00:00:00" ; - time:standard_name = "time" ; - time:calendar = "standard" ; - int model_level_number(model_level_number) ; - model_level_number:axis = "Z" ; - model_level_number:units = "1" ; - model_level_number:standard_name = "model_level_number" ; - model_level_number:positive = "up" ; - float grid_latitude(grid_latitude) ; - grid_latitude:axis = "Y" ; - grid_latitude:bounds = "grid_latitude_bnds" ; - grid_latitude:units = "degrees" ; - grid_latitude:standard_name = "grid_latitude" ; - float grid_latitude_bnds(grid_latitude, bnds) ; - float grid_longitude(grid_longitude) ; - grid_longitude:axis = "X" ; - grid_longitude:bounds = "grid_longitude_bnds" ; - grid_longitude:units = "degrees" ; - grid_longitude:standard_name = "grid_longitude" ; - float grid_longitude_bnds(grid_longitude, bnds) ; - double forecast_period ; - forecast_period:units = "hours" ; - forecast_period:standard_name = "forecast_period" ; - double ptop ; - ptop:units = "Pa" ; - float sigma(model_level_number) ; - sigma:bounds = "sigma_bnds" ; - sigma:units = "1" ; - sigma:long_name = "sigma" ; - sigma:standard_name = "atmosphere_sigma_coordinate" ; - sigma:axis = "Z" ; - sigma:formula_terms = "ptop: ptop sigma: sigma ps: surface_air_pressure" ; - float sigma_bnds(model_level_number, bnds) ; - float surface_air_pressure(grid_latitude, grid_longitude) ; - surface_air_pressure:units = "Pa" ; - surface_air_pressure:standard_name = "surface_air_pressure" ; - -// global attributes: - :source = "Iris test case" ; - :Conventions = "CF-1.7" ; -} diff --git a/lib/iris/tests/results/integration/netcdf/aux_factories/TestHybridPressure/save.cdl b/lib/iris/tests/results/integration/netcdf/aux_factories/TestHybridPressure/save.cdl deleted file mode 100644 index 6fed33430a..0000000000 --- a/lib/iris/tests/results/integration/netcdf/aux_factories/TestHybridPressure/save.cdl +++ /dev/null @@ -1,66 +0,0 @@ -dimensions: - bnds = 2 ; - grid_latitude = 100 ; - grid_longitude = 100 ; - model_level_number = 70 ; - time = 6 ; -variables: - float air_potential_temperature(time, model_level_number, grid_latitude, grid_longitude) ; - air_potential_temperature:standard_name = "air_potential_temperature" ; - air_potential_temperature:units = "K" ; - air_potential_temperature:grid_mapping = "rotated_latitude_longitude" ; - air_potential_temperature:coordinates = "forecast_period level_pressure sigma surface_air_pressure" ; - int rotated_latitude_longitude ; - rotated_latitude_longitude:grid_mapping_name = "rotated_latitude_longitude" ; - rotated_latitude_longitude:longitude_of_prime_meridian = 0. ; - rotated_latitude_longitude:earth_radius = 6371229. ; - rotated_latitude_longitude:grid_north_pole_latitude = 37.5 ; - rotated_latitude_longitude:grid_north_pole_longitude = 177.5 ; - rotated_latitude_longitude:north_pole_grid_longitude = 0. ; - double time(time) ; - time:axis = "T" ; - time:units = "hours since 1970-01-01 00:00:00" ; - time:standard_name = "time" ; - time:calendar = "standard" ; - int model_level_number(model_level_number) ; - model_level_number:axis = "Z" ; - model_level_number:units = "1" ; - model_level_number:standard_name = "model_level_number" ; - model_level_number:positive = "up" ; - float grid_latitude(grid_latitude) ; - grid_latitude:axis = "Y" ; - grid_latitude:bounds = "grid_latitude_bnds" ; - grid_latitude:units = "degrees" ; - grid_latitude:standard_name = "grid_latitude" ; - float grid_latitude_bnds(grid_latitude, bnds) ; - float grid_longitude(grid_longitude) ; - grid_longitude:axis = "X" ; - grid_longitude:bounds = "grid_longitude_bnds" ; - grid_longitude:units = "degrees" ; - grid_longitude:standard_name = "grid_longitude" ; - float grid_longitude_bnds(grid_longitude, bnds) ; - double forecast_period ; - forecast_period:units = "hours" ; - forecast_period:standard_name = "forecast_period" ; - float level_pressure(model_level_number) ; - level_pressure:bounds = "level_pressure_bnds" ; - level_pressure:units = "Pa" ; - level_pressure:long_name = "level_pressure" ; - level_pressure:positive = "up" ; - level_pressure:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate" ; - level_pressure:axis = "Z" ; - level_pressure:formula_terms = "ap: level_pressure b: sigma ps: surface_air_pressure" ; - float level_pressure_bnds(model_level_number, bnds) ; - float sigma(model_level_number) ; - sigma:bounds = "sigma_bnds" ; - sigma:units = "1" ; - sigma:long_name = "sigma" ; - float sigma_bnds(model_level_number, bnds) ; - float surface_air_pressure(grid_latitude, grid_longitude) ; - surface_air_pressure:units = "Pa" ; - surface_air_pressure:standard_name = "surface_air_pressure" ; - -// global attributes: - :source = "Iris test case" ; - :Conventions = "CF-1.7" ; -} diff --git a/lib/iris/tests/results/integration/netcdf/aux_factories/TestSaveMultipleAuxFactories/hybrid_height_and_pressure.cdl b/lib/iris/tests/results/integration/netcdf/aux_factories/TestSaveMultipleAuxFactories/hybrid_height_and_pressure.cdl deleted file mode 100644 index d813ab98dc..0000000000 --- a/lib/iris/tests/results/integration/netcdf/aux_factories/TestSaveMultipleAuxFactories/hybrid_height_and_pressure.cdl +++ /dev/null @@ -1,78 +0,0 @@ -dimensions: - bnds = 2 ; - grid_latitude = 100 ; - grid_longitude = 100 ; - model_level_number = 70 ; - time = 6 ; -variables: - float air_potential_temperature(time, model_level_number, grid_latitude, grid_longitude) ; - air_potential_temperature:standard_name = "air_potential_temperature" ; - air_potential_temperature:units = "K" ; - air_potential_temperature:grid_mapping = "rotated_latitude_longitude" ; - air_potential_temperature:coordinates = "forecast_period level_height level_pressure sigma surface_air_pressure surface_altitude unknown_scalar" ; - int rotated_latitude_longitude ; - rotated_latitude_longitude:grid_mapping_name = "rotated_latitude_longitude" ; - rotated_latitude_longitude:longitude_of_prime_meridian = 0. ; - rotated_latitude_longitude:earth_radius = 6371229. ; - rotated_latitude_longitude:grid_north_pole_latitude = 37.5 ; - rotated_latitude_longitude:grid_north_pole_longitude = 177.5 ; - rotated_latitude_longitude:north_pole_grid_longitude = 0. ; - double time(time) ; - time:axis = "T" ; - time:units = "hours since 1970-01-01 00:00:00" ; - time:standard_name = "time" ; - time:calendar = "standard" ; - int model_level_number(model_level_number) ; - model_level_number:axis = "Z" ; - model_level_number:units = "1" ; - model_level_number:standard_name = "model_level_number" ; - model_level_number:positive = "up" ; - float grid_latitude(grid_latitude) ; - grid_latitude:axis = "Y" ; - grid_latitude:bounds = "grid_latitude_bnds" ; - grid_latitude:units = "degrees" ; - grid_latitude:standard_name = "grid_latitude" ; - float grid_latitude_bnds(grid_latitude, bnds) ; - float grid_longitude(grid_longitude) ; - grid_longitude:axis = "X" ; - grid_longitude:bounds = "grid_longitude_bnds" ; - grid_longitude:units = "degrees" ; - grid_longitude:standard_name = "grid_longitude" ; - float grid_longitude_bnds(grid_longitude, bnds) ; - double forecast_period ; - forecast_period:units = "hours" ; - forecast_period:standard_name = "forecast_period" ; - float level_height(model_level_number) ; - level_height:bounds = "level_height_bnds" ; - level_height:units = "m" ; - level_height:long_name = "level_height" ; - level_height:positive = "up" ; - level_height:standard_name = "atmosphere_hybrid_height_coordinate" ; - level_height:axis = "Z" ; - level_height:formula_terms = "a: level_height b: sigma orog: surface_altitude" ; - float level_height_bnds(model_level_number, bnds) ; - double level_pressure ; - level_pressure:units = "hPa" ; - level_pressure:long_name = "level_pressure" ; - level_pressure:standard_name = "atmosphere_hybrid_sigma_pressure_coordinate" ; - level_pressure:axis = "Z" ; - level_pressure:formula_terms = "ap: level_pressure b: unknown_scalar ps: surface_air_pressure" ; - double unknown_scalar ; - unknown_scalar:units = "1" ; - unknown_scalar:long_name = "other sigma" ; - float sigma(model_level_number) ; - sigma:bounds = "sigma_bnds" ; - sigma:units = "1" ; - sigma:long_name = "sigma" ; - float sigma_bnds(model_level_number, bnds) ; - double surface_air_pressure ; - surface_air_pressure:units = "hPa" ; - surface_air_pressure:long_name = "surface_air_pressure" ; - float surface_altitude(grid_latitude, grid_longitude) ; - surface_altitude:units = "m" ; - surface_altitude:standard_name = "surface_altitude" ; - -// global attributes: - :source = "Iris test case" ; - :Conventions = "CF-1.7" ; -} diff --git a/lib/iris/tests/results/integration/netcdf/aux_factories/TestSaveMultipleAuxFactories/hybrid_height_cubes.cml b/lib/iris/tests/results/integration/netcdf/aux_factories/TestSaveMultipleAuxFactories/hybrid_height_cubes.cml deleted file mode 100644 index 975488f656..0000000000 --- a/lib/iris/tests/results/integration/netcdf/aux_factories/TestSaveMultipleAuxFactories/hybrid_height_cubes.cml +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From edf132d173107cb347fe2b8639fa71eb75f35ca3 Mon Sep 17 00:00:00 2001 From: Elias Sadek Date: Tue, 2 Dec 2025 15:45:46 +0000 Subject: [PATCH 12/12] removed unnecessary try-except clause, and shutils import --- .../tests/integration/netcdf/test_general.py | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/lib/iris/tests/integration/netcdf/test_general.py b/lib/iris/tests/integration/netcdf/test_general.py index 6e5fcacf2d..fa544a1d67 100644 --- a/lib/iris/tests/integration/netcdf/test_general.py +++ b/lib/iris/tests/integration/netcdf/test_general.py @@ -7,7 +7,6 @@ from itertools import repeat import os.path from pathlib import Path -import shutil import warnings import dask @@ -125,26 +124,21 @@ def test_unknown_method(self, tmp_path_factory): cube = Cube([1, 2], long_name="odd_phenomenon") cube.add_cell_method(CellMethod(method="oddity", coords=("x",))) temp_dirpath = tmp_path_factory.mktemp("test") - try: - temp_filepath = os.path.join(temp_dirpath, "tmp.nc") - iris.save(cube, temp_filepath) - with warnings.catch_warnings(record=True) as warning_records: - iris.load(temp_filepath) - # Filter to get the warning we are interested in. - warning_messages = [record.message for record in warning_records] - warning_messages = [ - warn - for warn in warning_messages - if isinstance(warn, iris.warnings.IrisUnknownCellMethodWarning) - ] - assert len(warning_messages) == 1 - message = warning_messages[0].args[0] - msg = ( - "NetCDF variable 'odd_phenomenon' contains unknown cell method 'oddity'" - ) - assert msg in message - finally: - shutil.rmtree(temp_dirpath) + temp_filepath = os.path.join(temp_dirpath, "tmp.nc") + iris.save(cube, temp_filepath) + with warnings.catch_warnings(record=True) as warning_records: + iris.load(temp_filepath) + # Filter to get the warning we are interested in. + warning_messages = [record.message for record in warning_records] + warning_messages = [ + warn + for warn in warning_messages + if isinstance(warn, iris.warnings.IrisUnknownCellMethodWarning) + ] + assert len(warning_messages) == 1 + message = warning_messages[0].args[0] + msg = "NetCDF variable 'odd_phenomenon' contains unknown cell method 'oddity'" + assert msg in message def _get_scale_factor_add_offset(cube, datatype):