From 62ffad44a3d39e2cab1a8af0e5c57cdbe94eb88b Mon Sep 17 00:00:00 2001 From: Martin Yeo Date: Fri, 19 Apr 2024 15:25:27 +0100 Subject: [PATCH] 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()