Skip to content

Commit 653ee9c

Browse files
jlenhschlunma
andauthored
Modify ERA5 fixes to support data produced by the new GRIB to netcdf converter version of ECMWF (#3030)
Co-authored-by: Manuel Schlund <32543114+schlunma@users.noreply.github.com>
1 parent 9e24b51 commit 653ee9c

File tree

2 files changed

+58
-2
lines changed

2 files changed

+58
-2
lines changed

esmvalcore/cmor/_fixes/native6/era5.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import logging
55

66
import numpy as np
7+
from cf_units import Unit
78
from iris.cube import CubeList
89
from iris.util import reverse
910

@@ -515,7 +516,7 @@ def fix_metadata(self, cubes):
515516
class AllVars(Fix):
516517
"""Fixes for all variables."""
517518

518-
def _fix_coordinates( # noqa: C901
519+
def _fix_coordinates( # noqa: C901,PLR0912
519520
self,
520521
cube,
521522
):
@@ -540,13 +541,22 @@ def _fix_coordinates( # noqa: C901
540541
]
541542
coord = cube.coord(axis=axis)
542543
if axis == "T":
543-
coord.convert_units("days since 1850-1-1 00:00:00.0")
544+
coord.convert_units(
545+
Unit(
546+
"days since 1850-1-1 00:00:00.0",
547+
calendar=coord.units.calendar,
548+
),
549+
)
544550
if axis in ("X", "Y", "Z"):
545551
coord.convert_units(coord_def.units)
546552
coord.standard_name = coord_def.standard_name
547553
coord.var_name = coord_def.out_name
548554
coord.long_name = coord_def.long_name
549555
coord.points = coord.core_points().astype("float64")
556+
# For now, remove "stored_direction" attribute introduced by the
557+
# new netCDF converter from ECMWF for ERA5 data if missing.
558+
if coord.name() == "latitude":
559+
coord.attributes.pop("stored_direction", None)
550560
if (
551561
not coord.has_bounds()
552562
and len(coord.core_points()) > 1

tests/integration/cmor/_fixes/native6/test_era5.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,17 @@ def _era5_latitude():
7272
)
7373

7474

75+
def _era5_latitude_w_direction():
76+
return DimCoord(
77+
np.array([90.0, 0.0, -90.0]),
78+
standard_name="latitude",
79+
long_name="latitude",
80+
var_name="latitude",
81+
units=Unit("degrees"),
82+
attributes={"stored_direction": "decreasing"},
83+
)
84+
85+
7586
def _era5_longitude():
7687
return DimCoord(
7788
np.array([0, 180, 359.75]),
@@ -1577,3 +1588,38 @@ def test_unstructured_grid(unstructured_grid_cubes):
15771588
assert lon.bounds is None
15781589

15791590
assert fixed_cube.attributes["GRIB_PARAM"] == "(1, 1)"
1591+
1592+
1593+
@pytest.fixture
1594+
def cube_latitude_w_direction():
1595+
"""Sample cube with latitude coordinate with direction."""
1596+
time = DimCoord(
1597+
[-31, 0, 31],
1598+
standard_name="time",
1599+
units="days since 1850-01-01",
1600+
)
1601+
cube = Cube(
1602+
_era5_data("mon"),
1603+
standard_name="air_temperature",
1604+
units="K",
1605+
dim_coords_and_dims=[
1606+
(time, 0),
1607+
(_era5_latitude_w_direction(), 1),
1608+
(_era5_longitude(), 2),
1609+
],
1610+
)
1611+
return CubeList([cube])
1612+
1613+
1614+
def test_latitude_w_direction(cube_latitude_w_direction):
1615+
"""Test removal of latitude stored_direction attribute."""
1616+
fixed_cubes = fix_metadata(
1617+
cube_latitude_w_direction,
1618+
"tas",
1619+
"native6",
1620+
"era5",
1621+
"Amon",
1622+
)
1623+
assert len(fixed_cubes) == 1
1624+
fixed_cube = fixed_cubes[0]
1625+
assert fixed_cube.coord("latitude") == _cmor_latitude()

0 commit comments

Comments
 (0)