Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
24 changes: 24 additions & 0 deletions esmvalcore/cmor/_fixes/cordex/cnrm_cerfacs_cnrm_cm5/aladin53.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from typing import TYPE_CHECKING

import iris.coord_systems

from esmvalcore.cmor.fix import Fix

if TYPE_CHECKING:
Expand All @@ -30,3 +32,25 @@ def fix_metadata(self, cubes: Sequence[Cube]) -> Sequence[Cube]:
cube.units = "deg_C"
cube.convert_units(self.vardef.units)
return cubes


class AllVars(Fix):
"""Fixes for all variables."""

def fix_metadata(self, cubes: Sequence[Cube]) -> Sequence[Cube]:
for cube in cubes:
if self.extra_facets.get("domain") == "EUR-11":
# Set false_easting and false_northing to 0.0, as odd values
# have been observed in some files.
coord_system = iris.coord_systems.LambertConformal(
central_lat=49.5,
central_lon=10.5,
secant_latitudes=(49.5,),
)
for coord_name in [
"projection_x_coordinate",
"projection_y_coordinate",
]:
if cube.coords(coord_name):
cube.coord(coord_name).coord_system = coord_system
return cubes
13 changes: 13 additions & 0 deletions esmvalcore/cmor/_fixes/cordex/cordex_fixes.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import iris.coords
import iris.cube
import iris.exceptions
import iris.util
import numpy as np
import pyproj
from cf_units import Unit
Expand Down Expand Up @@ -293,6 +294,18 @@ def _use_standard_lambert_conformal_grid(
)
y_coord.guess_bounds()

# If the original coordinate was not monotonic, it has been downgraded
# to an auxiliary coordinate, so promote it back to a dimension
# coordinate.
iris.util.promote_aux_coord_to_dim_coord(
cube,
"projection_x_coordinate",
)
iris.util.promote_aux_coord_to_dim_coord(
cube,
"projection_y_coordinate",
)

# Define the transformation from projection coordinates to
# geographic coordinates.
transformer = pyproj.Transformer.from_crs(
Expand Down
56 changes: 56 additions & 0 deletions tests/integration/cmor/_fixes/cordex/test_cnrm_cerfacs_cnrm_cm5.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
"""Tests for the fixes for driver CNRM-CERFACS-CNRM-CM5."""

import iris
import iris.coord_systems
import iris.coords
import iris.cube
import numpy as np
import pytest

from esmvalcore.cmor._fixes.cordex.cnrm_cerfacs_cnrm_cm5 import (
Expand Down Expand Up @@ -90,6 +92,60 @@ def test_fix_aladin53_ts() -> None:
assert result.units == "K"


def test_fix_aladin53_tas() -> None:
fixes = Fix.get_fixes(
"CORDEX",
"ALADIN53",
"day",
"tas",
extra_facets={
"driver": "CNRM-CERFACS-CNRM-CM5",
"domain": "EUR-11",
},
)
assert isinstance(fixes[0], aladin53.AllVars)
wrong_coord_system = iris.coord_systems.LambertConformal(
central_lat=49.5,
central_lon=10.5,
secant_latitudes=(49.5,),
false_easting=400000.0,
false_northing=-100000.0,
)
cube = iris.cube.Cube(
np.array([0, 1.0]).reshape(1, 2),
var_name="tas",
units="K",
aux_coords_and_dims=[
(
iris.coords.AuxCoord(
[0.0],
standard_name="projection_y_coordinate",
units="m",
coord_system=wrong_coord_system,
),
(0,),
),
(
iris.coords.AuxCoord(
[0.0, 1.0],
standard_name="projection_x_coordinate",
units="m",
coord_system=wrong_coord_system,
),
(1,),
),
],
)
(result,) = fixes[0].fix_metadata([cube])
assert result.coord_system() == iris.coord_systems.LambertConformal(
central_lat=49.5,
central_lon=10.5,
secant_latitudes=(49.5,),
false_easting=0,
false_northing=0,
)


@pytest.mark.parametrize("short_name", ["pr", "tas"])
def test_get_aladin63_fix(short_name):
fix = Fix.get_fixes(
Expand Down
12 changes: 7 additions & 5 deletions tests/integration/cmor/_fixes/cordex/test_cordex_fixes.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,8 +298,12 @@ def test_lambert_conformal_grid_fix(use_standard_grid: bool) -> None:
),
1,
),
],
aux_coords_and_dims=[
# If the x coordinate is not monotonic, it may be demoted to an
# auxiliary coordinate on load.
(
iris.coords.DimCoord(
iris.coords.AuxCoord(
np.arange(0, 453),
var_name="projection_x_coordinate",
standard_name="projection_x_coordinate",
Expand All @@ -308,8 +312,6 @@ def test_lambert_conformal_grid_fix(use_standard_grid: bool) -> None:
),
2,
),
],
aux_coords_and_dims=[
(
iris.coords.AuxCoord(
np.ones((453, 453)),
Expand Down Expand Up @@ -344,8 +346,8 @@ def test_lambert_conformal_grid_fix(use_standard_grid: bool) -> None:
]:
assert len(result.coords(coord_name)) == 1

x_coord = result.coord("projection_x_coordinate")
y_coord = result.coord("projection_y_coordinate")
x_coord = result.coord("projection_x_coordinate", dim_coords=True)
y_coord = result.coord("projection_y_coordinate", dim_coords=True)
assert x_coord.units == "m"
assert y_coord.units == "m"
assert x_coord.points.dtype == np.float64
Expand Down
5 changes: 4 additions & 1 deletion tests/integration/cmor/_fixes/test_fix.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
from esmvalcore.cmor._fixes.cmip5.canesm2 import FgCo2
from esmvalcore.cmor._fixes.cmip5.cesm1_bgc import Gpp
from esmvalcore.cmor._fixes.cmip6.cesm2 import Omon, Tos
from esmvalcore.cmor._fixes.cordex.cnrm_cerfacs_cnrm_cm5.aladin53 import (
AllVars as Aladin53AllVars,
)
from esmvalcore.cmor._fixes.cordex.cnrm_cerfacs_cnrm_cm5.aladin63 import (
Tas,
)
Expand Down Expand Up @@ -53,7 +56,7 @@ def test_get_grid_fix_cordex():
"tas",
extra_facets={"driver": "CNRM-CERFACS-CNRM-CM5"},
)
assert fix == [AllVars(None), GenericFix(None)]
assert fix == [Aladin53AllVars(None), AllVars(None), GenericFix(None)]


def test_get_fixes_with_replace():
Expand Down