Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for pressure coordinate name variants plus enforce units to be hPa #1106

Merged
merged 5 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions src/CSET/operators/read.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ def callback(cube: iris.cube.Cube, field, filename: str):
_lfric_time_coord_fix_callback(cube, field, filename)
_longitude_fix_callback(cube, field, filename)
_fix_spatial_coord_name_callback(cube)
_fix_pressure_coord_name_callback(cube)
_fix_pressure_coord_callback(cube)

return callback

Expand Down Expand Up @@ -408,20 +408,26 @@ def _fix_spatial_coord_name_callback(cube: iris.cube.Cube):
cube.coord(x_name).rename("grid_longitude")


def _fix_pressure_coord_name_callback(cube: iris.cube.Cube):
"""Rename pressure_level coordinate to pressure if it exists.
def _fix_pressure_coord_callback(cube: iris.cube.Cube):
"""Rename pressure coordinate to 'pressure' if it exists and ensure hPa units.
jwarner8 marked this conversation as resolved.
Show resolved Hide resolved

This problem was raised because the AIFS model data from ECMWF
defines the pressure coordinate with the name 'pressure_level' rather
than compliant CF coordinate names
than compliant CF coordinate names.

Additionally, set the units of pressure to be hPa.
jwarner8 marked this conversation as resolved.
Show resolved Hide resolved
"""
# We only want to modify instances where the coordinate system is actually
# latitude/longitude, and not touch the cube if the coordinate system is say
# meters.
jwarner8 marked this conversation as resolved.
Show resolved Hide resolved
for coord in cube.dim_coords:
if coord.name() == "pressure_level":
if coord.name() in ["pressure_level", "pressure_levels"]:
coord.rename("pressure")

for coord in cube.dim_coords:
if coord.name() == "pressure":
cube.coord("pressure").convert_units("hPa")
jwarner8 marked this conversation as resolved.
Show resolved Hide resolved
jwarner8 marked this conversation as resolved.
Show resolved Hide resolved


def _check_input_files(input_paths: list[str], filename_pattern: str) -> list[Path]:
"""Get an iterable of files to load, and check that they all exist.
Expand Down
12 changes: 10 additions & 2 deletions tests/operators/test_read.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,17 +245,25 @@ def test_lfric_time_coord_fix_callback_no_time():
assert len(cube.coords("time")) == 0


def test_pressure_coord_fix_callback():
def test_pressure_coord_name_fix_callback():
"""Check that pressure_level is renamed to pressure if it exists."""
cube = iris.load_cube("tests/test_data/transect_test_umpl.nc")
cube.coord("pressure").rename("pressure_level")
read._fix_pressure_coord_name_callback(cube)
read._fix_pressure_coord_callback(cube)
assert (
repr(cube.coords())
== "[<DimCoord: time / (hours since 1970-01-01 00:00:00) [...] shape(2,)>, <DimCoord: pressure / (hPa) [ 100., 150., ..., 950., 1000.] shape(16,)>, <DimCoord: latitude / (degrees) [-10.98, -10.94, ..., -10.82, -10.78] shape(6,)>, <DimCoord: longitude / (degrees) [19.02, 19.06, ..., 19.18, 19.22] shape(6,)>, <DimCoord: forecast_reference_time / (hours since 1970-01-01 00:00:00) [...]>, <AuxCoord: forecast_period / (hours) [15., 18.] shape(2,)>]"
)


def test_pressure_coord_unit_fix_callback():
"""Check that pressure level units are hPa."""
cube = iris.load_cube("tests/test_data/transect_test_umpl.nc")
jwarner8 marked this conversation as resolved.
Show resolved Hide resolved
cube.coord("pressure").convert_units("Pa")
read._fix_pressure_coord_callback(cube)
assert repr(str(cube.coord("pressure").units)) == "'hPa'"
jwarner8 marked this conversation as resolved.
Show resolved Hide resolved


def test_spatial_coord_rename_callback():
"""Check that spatial coord gets renamed if it is not grid_latitude."""
# This cube contains 'latitude' and 'longitude'
Expand Down