From 62ffad44a3d39e2cab1a8af0e5c57cdbe94eb88b Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Fri, 19 Apr 2024 15:25:27 +0100 Subject: [PATCH 1/3] Handle missing keys for GDT10 Mercator. --- iris_grib/_load_convert.py | 25 ++++++++++++++ iris_grib/_save_rules.py | 3 ++ .../test_grid_definition_template_10.py | 34 +++++++++++++++++-- 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/iris_grib/_load_convert.py b/iris_grib/_load_convert.py index c4ea31ec..a03175dc 100644 --- a/iris_grib/_load_convert.py +++ b/iris_grib/_load_convert.py @@ -810,10 +810,35 @@ def grid_definition_template_10(section, metadata): # intersects the Earth standard_parallel = section["LaD"] * _GRID_ACCURACY_IN_DEGREES + if section["orientationOfTheGrid"] and not np.isclose( + section["orientationOfTheGrid"], 0 + ): + # Could support in future by using the ObliqueMercator class. + message = ( + f"{section['orientationOfTheGrid']=} . iris-grib only supports " + "0.0 orientation for grid definition template 10." + ) + raise TranslationError(message) + cs = icoord_systems.Mercator(standard_parallel=standard_parallel, ellipsoid=geog_cs) # Create the X and Y coordinates. x_coord, y_coord, scan = _calculate_proj_coords_from_grid_lengths(section, cs) + final_x_point = x_coord.points[-1] + final_y_point = y_coord.points[-1] + if not ( + np.isclose(section["longitudeOfLastGridPoint"], final_x_point) + and np.isclose(section["latitudeOfLastGridPoint"], final_y_point) + ): + message = ( + "File grid definition inconsistent. Grid specification produces " + f"{final_x_point=}, {final_y_point=}. But " + f"{section['longitudeOfLastGridPoint']=} , " + f"{section['latitudeOfLastGridPoint']=} .\n\n" + "(Grid specification for Longitude: Di, Ni, " + "longitudeOfFirstGridPoint, scanningMode. Latitude uses: Dj, Nj)" + ) + warnings.warn(message) # Determine the lat/lon dimensions. y_dim, x_dim = 0, 1 diff --git a/iris_grib/_save_rules.py b/iris_grib/_save_rules.py index a47bd453..e261800a 100644 --- a/iris_grib/_save_rules.py +++ b/iris_grib/_save_rules.py @@ -539,6 +539,9 @@ def grid_definition_template_10(cube, grib): 0x1 << _RESOLUTION_AND_COMPONENTS_GRID_WINDS_BIT, ) + # We don't save "orientationOfTheGrid" since we can't represent it - + # would need a future handling of the Iris ObliqueMercator class. + def grid_definition_template_12(cube, grib): """ diff --git a/iris_grib/tests/unit/load_convert/test_grid_definition_template_10.py b/iris_grib/tests/unit/load_convert/test_grid_definition_template_10.py index 093f7507..22e657ce 100644 --- a/iris_grib/tests/unit/load_convert/test_grid_definition_template_10.py +++ b/iris_grib/tests/unit/load_convert/test_grid_definition_template_10.py @@ -12,6 +12,8 @@ # before importing anything else. import iris_grib.tests as tests +import warnings + import numpy as np import iris.coord_systems @@ -37,10 +39,10 @@ def section_3(self): "Ni": 181, "Nj": 213, "latitudeOfFirstGridPoint": 2351555, - "latitudeOfLastGridPoint": 25088204, + "latitudeOfLastGridPoint": 2797793.1090371446, "LaD": 14000000, "longitudeOfFirstGridPoint": 114990304, - "longitudeOfLastGridPoint": 135009712, + "longitudeOfLastGridPoint": 14566918.990644248, "resolutionAndComponentFlags": 56, "scanningMode": 64, "Di": 12000000, @@ -83,6 +85,34 @@ def test(self): expected = self.expected(y_dim=0, x_dim=1) self.assertEqual(metadata, expected) + def test_last_point_warning(self): + section = self.section_3() + metadata = empty_metadata() + + # No warnings expected with the standard values. + with warnings.catch_warnings(): + warnings.simplefilter("error") + grid_definition_template_10(section, metadata) + + # Warning expected if specified last point does not agree with the + # generated one. + section["longitudeOfLastGridPoint"] = 0 + expected_message = ( + "File grid definition inconsistent. Grid specification produces " + "final_x_point=" + ) + with self.assertWarnsRegex(UserWarning, expected_message): + grid_definition_template_10(section, metadata) + + def test_orientation_error(self): + section = self.section_3() + section["orientationOfTheGrid"] = 1 + metadata = empty_metadata() + with self.assertRaisesRegex( + iris.exceptions.TranslationError, "iris-grib only supports 0.0 orientation" + ): + grid_definition_template_10(section, metadata) + if __name__ == "__main__": tests.main() From 44437da7b520d2cfbc33d5609d99d5ba46bc6e6e Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Fri, 19 Apr 2024 15:31:37 +0100 Subject: [PATCH 2/3] Correct checking for key in section. --- iris_grib/_load_convert.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/iris_grib/_load_convert.py b/iris_grib/_load_convert.py index a03175dc..a0d3bb42 100644 --- a/iris_grib/_load_convert.py +++ b/iris_grib/_load_convert.py @@ -810,7 +810,7 @@ def grid_definition_template_10(section, metadata): # intersects the Earth standard_parallel = section["LaD"] * _GRID_ACCURACY_IN_DEGREES - if section["orientationOfTheGrid"] and not np.isclose( + if "orientationOfTheGrid" in section and not np.isclose( section["orientationOfTheGrid"], 0 ): # Could support in future by using the ObliqueMercator class. From 020b26b174bd6561d96bdd21ecbe8c6ca1204393 Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Tue, 10 Sep 2024 15:56:27 +0100 Subject: [PATCH 3/3] What's New entry. --- docs/ref/release_notes.rst | 47 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/docs/ref/release_notes.rst b/docs/ref/release_notes.rst index deed099d..287c122a 100644 --- a/docs/ref/release_notes.rst +++ b/docs/ref/release_notes.rst @@ -6,6 +6,53 @@ Release Notes ============= +What's new in iris-grib v0.21.0 +------------------------------- + +:Release: 0.21.0 +:Date: [unreleased] + +Features +^^^^^^^^ + +* `@trexfeathers `_ added checks for invalid + values in the following keys when loading grid definition template 3.10 + (mercator grids): ``orientationOfTheGrid``, ``longitudeOfLastGridPoint``, + ``latitudeOfLastGridPoint``. + `(ISSUE#118) `_, + `(PR#446) `_ + + +Bugs Fixed +^^^^^^^^^^ + +* N/A + + +Documentation +^^^^^^^^^^^^^ + +* N/A + + +Dependencies +^^^^^^^^^^^^ + +* N/A + + +Internal +^^^^^^^^ + +* N/A + + +New Contributors +^^^^^^^^^^^^^^^^ + +* N/A + + What's new in iris-grib v0.20.0 -------------------------------