diff --git a/.zenodo.json b/.zenodo.json index df7a49977d..bb00d5471d 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -200,6 +200,10 @@ "affiliation": "BSC, Spain", "name": "Martin-Martinez, Eneko", "orcid": "0000-0002-9213-7818" + }, + { + "affiliation": "DLR, Germany", + "name": "Cammarano, Diego" } ], "description": "ESMValCore: A community tool for pre-processing data from Earth system models in CMIP and running analysis scripts.", diff --git a/CITATION.cff b/CITATION.cff index d188af5d39..b7c116e3e5 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -204,6 +204,10 @@ authors: family-names: Martin-Martinez given-names: Eneko orcid: "https://orcid.org/0000-0002-9213-7818" + - + affiliation: "DLR, Germany" + family-names: Cammarano + given-names: Diego cff-version: 1.2.0 date-released: 2023-12-19 diff --git a/esmvalcore/cmor/_fixes/icon/_base_fixes.py b/esmvalcore/cmor/_fixes/icon/_base_fixes.py index 94ada2e25b..2fcdbeaf3d 100644 --- a/esmvalcore/cmor/_fixes/icon/_base_fixes.py +++ b/esmvalcore/cmor/_fixes/icon/_base_fixes.py @@ -462,3 +462,12 @@ def _set_range_in_0_360(lon_coord): lon_coord.points = (lon_coord.core_points() + 360.0) % 360.0 if lon_coord.has_bounds(): lon_coord.bounds = (lon_coord.core_bounds() + 360.0) % 360.0 + + +class NegateData(IconFix): + """Base fix to negate data.""" + + def fix_data(self, cube): + """Fix data.""" + cube.data = -cube.core_data() + return cube diff --git a/esmvalcore/cmor/_fixes/icon/icon.py b/esmvalcore/cmor/_fixes/icon/icon.py index 2e1dfd3bb3..39562b5db1 100644 --- a/esmvalcore/cmor/_fixes/icon/icon.py +++ b/esmvalcore/cmor/_fixes/icon/icon.py @@ -15,7 +15,7 @@ from esmvalcore.iris_helpers import add_leading_dim_to_cube, date2num -from ._base_fixes import IconFix +from ._base_fixes import IconFix, NegateData logger = logging.getLogger(__name__) @@ -512,3 +512,9 @@ def fix_metadata(self, cubes): ) cube.var_name = self.vardef.short_name return CubeList([cube]) + + +Hfls = NegateData + + +Hfss = NegateData diff --git a/tests/integration/cmor/_fixes/icon/test_icon.py b/tests/integration/cmor/_fixes/icon/test_icon.py index ab823cb846..4f9f4c4c02 100644 --- a/tests/integration/cmor/_fixes/icon/test_icon.py +++ b/tests/integration/cmor/_fixes/icon/test_icon.py @@ -14,7 +14,7 @@ import esmvalcore.cmor._fixes.icon.icon from esmvalcore.cmor._fixes.fix import GenericFix from esmvalcore.cmor._fixes.icon._base_fixes import IconFix -from esmvalcore.cmor._fixes.icon.icon import AllVars, Clwvi +from esmvalcore.cmor._fixes.icon.icon import AllVars, Clwvi, Hfls, Hfss from esmvalcore.cmor.fix import Fix from esmvalcore.cmor.table import CoordinateInfo, get_var_info from esmvalcore.config import CFG @@ -147,6 +147,15 @@ def fix_metadata(cubes, mip, short_name, session=None): return cubes +def fix_data(cube, mip, short_name, session=None): + """Fix data of cube.""" + fix = get_fix(mip, short_name, session=session) + cube = fix.fix_data(cube) + fix = get_allvars_fix(mip, short_name, session=session) + cube = fix.fix_data(cube) + return cube + + def check_ta_metadata(cubes): """Check ta metadata.""" assert len(cubes) == 1 @@ -2209,3 +2218,63 @@ def test_fix_height_alt16(bounds, simple_unstructured_cube): np.testing.assert_allclose(alt16.bounds, expected_bnds) else: assert alt16.bounds is None + + +# Test hfls (for extra fix) + + +def test_get_hfls_fix(): + """Test getting of fix.""" + fix = Fix.get_fixes('ICON', 'ICON', 'Amon', 'hfls') + assert fix == [Hfls(None), AllVars(None), GenericFix(None)] + + +def test_hfls_fix(cubes_regular_grid): + """Test fix.""" + cubes = CubeList([cubes_regular_grid[0].copy()]) + cubes[0].var_name = 'hfls' + cubes[0].units = 'W m-2' + + fixed_cubes = fix_metadata(cubes, 'Amon', 'hfls') + + assert len(fixed_cubes) == 1 + cube = fixed_cubes[0] + assert cube.var_name == 'hfls' + assert cube.standard_name == 'surface_upward_latent_heat_flux' + assert cube.long_name == 'Surface Upward Latent Heat Flux' + assert cube.units == 'W m-2' + assert cube.attributes['positive'] == 'up' + + fixed_cube = fix_data(cube, 'Amon', 'hfls') + + np.testing.assert_allclose(fixed_cube.data, [[[0.0, -1.0], [-2.0, -3.0]]]) + + +# Test hfss (for extra fix) + + +def test_get_hfss_fix(): + """Test getting of fix.""" + fix = Fix.get_fixes('ICON', 'ICON', 'Amon', 'hfss') + assert fix == [Hfss(None), AllVars(None), GenericFix(None)] + + +def test_hfss_fix(cubes_regular_grid): + """Test fix.""" + cubes = CubeList([cubes_regular_grid[0].copy()]) + cubes[0].var_name = 'hfss' + cubes[0].units = 'W m-2' + + fixed_cubes = fix_metadata(cubes, 'Amon', 'hfss') + + assert len(fixed_cubes) == 1 + cube = fixed_cubes[0] + assert cube.var_name == 'hfss' + assert cube.standard_name == 'surface_upward_sensible_heat_flux' + assert cube.long_name == 'Surface Upward Sensible Heat Flux' + assert cube.units == 'W m-2' + assert cube.attributes['positive'] == 'up' + + fixed_cube = fix_data(cube, 'Amon', 'hfss') + + np.testing.assert_allclose(fixed_cube.data, [[[0.0, -1.0], [-2.0, -3.0]]])