From 2751720fc7216d8f2d0c221bdbfae080e55311b3 Mon Sep 17 00:00:00 2001 From: Manuel Schlund <32543114+schlunma@users.noreply.github.com> Date: Tue, 23 Jan 2024 13:32:02 +0100 Subject: [PATCH] Added special unit conversion m -> DU for total column ozone (toz) (#2270) --- doc/recipe/preprocessor.rst | 2 ++ esmvalcore/preprocessor/_units.py | 14 +++++--- .../preprocessor/_units/test_convert_units.py | 34 +++++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/doc/recipe/preprocessor.rst b/doc/recipe/preprocessor.rst index fdac9ec7da..8412ceba3f 100644 --- a/doc/recipe/preprocessor.rst +++ b/doc/recipe/preprocessor.rst @@ -2335,6 +2335,8 @@ Currently, the following special conversions are supported: * ``precipitation_flux`` (``kg m-2 s-1``) -- ``lwe_precipitation_rate`` (``mm day-1``) +* ``equivalent_thickness_at_stp_of_atmosphere_ozone_content`` (``m``) -- + ``equivalent_thickness_at_stp_of_atmosphere_ozone_content`` (``DU``) .. hint:: Names in the list correspond to ``standard_names`` of the input data. diff --git a/esmvalcore/preprocessor/_units.py b/esmvalcore/preprocessor/_units.py index 4f435b7f86..069cef1a6d 100644 --- a/esmvalcore/preprocessor/_units.py +++ b/esmvalcore/preprocessor/_units.py @@ -4,9 +4,9 @@ """ import logging -from cf_units import Unit import iris import numpy as np +from cf_units import Unit logger = logging.getLogger(__name__) @@ -21,6 +21,10 @@ ('precipitation_flux', 'kg m-2 s-1'), ('lwe_precipitation_rate', 'mm s-1'), ], + [ + ('equivalent_thickness_at_stp_of_atmosphere_ozone_content', 'm'), + ('equivalent_thickness_at_stp_of_atmosphere_ozone_content', '1e5 DU'), + ], ] @@ -41,7 +45,7 @@ def _try_special_conversions(cube, units): if (cube.standard_name == std_name and cube.units.is_convertible(special_units)): for (target_std_name, target_units) in special_case: - if target_std_name == std_name: + if target_units == special_units: continue # Step 2: find suitable target name and units @@ -79,8 +83,10 @@ def convert_units(cube, units): Currently, the following special conversions are supported: - * ``precipitation_flux`` (``kg m-2 s-1``) -- - ``lwe_precipitation_rate`` (``mm day-1``) + * ``precipitation_flux`` (``kg m-2 s-1``) -- + ``lwe_precipitation_rate`` (``mm day-1``) + * ``equivalent_thickness_at_stp_of_atmosphere_ozone_content`` (``m``) -- + ``equivalent_thickness_at_stp_of_atmosphere_ozone_content`` (``DU``) Names in the list correspond to ``standard_names`` of the input data. Conversions are allowed from each quantity to any other quantity given in a diff --git a/tests/unit/preprocessor/_units/test_convert_units.py b/tests/unit/preprocessor/_units/test_convert_units.py index 02e67143f2..c1a2a2453b 100644 --- a/tests/unit/preprocessor/_units/test_convert_units.py +++ b/tests/unit/preprocessor/_units/test_convert_units.py @@ -44,6 +44,40 @@ def test_convert_compatible_units(self): self.assertEqual(result.units, expected_units) self.assert_array_equal(result.data, expected_data) + def test_convert_ozone_content_m_to_du(self): + """Test special conversion of ozone_content.""" + self.arr.standard_name = ( + 'equivalent_thickness_at_stp_of_atmosphere_ozone_content' + ) + self.arr.units = 'm' + result = convert_units(self.arr, 'DU') + self.assertEqual( + result.standard_name, + 'equivalent_thickness_at_stp_of_atmosphere_ozone_content', + ) + self.assertEqual(result.units, 'DU') + np.testing.assert_allclose( + result.data, + [[0.0, 1e5], [2e5, 3e5]], + ) + + def test_convert_ozone_content_du_to_m(self): + """Test special conversion of ozone_content.""" + self.arr.standard_name = ( + 'equivalent_thickness_at_stp_of_atmosphere_ozone_content' + ) + self.arr.units = 'DU' + result = convert_units(self.arr, 'mm') + self.assertEqual( + result.standard_name, + 'equivalent_thickness_at_stp_of_atmosphere_ozone_content', + ) + self.assertEqual(result.units, 'mm') + np.testing.assert_allclose( + result.data, + [[0.0, 1e-2], [2e-2, 3e-2]], + ) + def test_convert_precipitation_flux(self): """Test special conversion of precipitation_flux.""" self.arr.standard_name = 'precipitation_flux'