Skip to content
Draft
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
11 changes: 9 additions & 2 deletions esmvalcore/_recipe/check.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,15 @@
from pathlib import Path

from esmvalcore._task import TaskSet
from esmvalcore.config import Session
from esmvalcore.dataset import Dataset
from esmvalcore.typing import Facets


logger = logging.getLogger(__name__)


def align_metadata(step_settings: dict[str, Any]) -> None:
def align_metadata(step_settings: dict[str, Any], session: Session) -> None:
"""Check settings of preprocessor ``align_metadata``."""
project = step_settings.get("target_project")
mip = step_settings.get("target_mip")
Expand All @@ -55,7 +56,13 @@ def align_metadata(step_settings: dict[str, Any]) -> None:
return

try:
_get_var_info(project, mip, short_name)
_get_var_info(
project,
mip,
short_name,
branding_suffix=step_settings.get("branding_suffix"),
session=session,
)
except ValueError as exc:
if strict:
msg = (
Expand Down
3 changes: 2 additions & 1 deletion esmvalcore/_recipe/recipe.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ def _update_target_levels(
settings["extract_levels"]["levels"] = get_cmor_levels(
levels["cmor_table"],
levels["coordinate"],
session=dataset.session,
)
elif "dataset" in levels:
dataset_name = levels["dataset"]
Expand Down Expand Up @@ -595,7 +596,7 @@ def _update_align_metadata(
"target_short_name",
dataset.facets["short_name"],
)
check.align_metadata(settings["align_metadata"])
check.align_metadata(settings["align_metadata"], dataset.session)


def _update_extract_shape(
Expand Down
39 changes: 27 additions & 12 deletions esmvalcore/cmor/_fixes/fix.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@
import inspect
import logging
import tempfile
import warnings
from pathlib import Path
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, Self

import dask
import numpy as np
Expand All @@ -26,7 +27,7 @@
_get_single_cube,
)
from esmvalcore.cmor.fixes import get_time_bounds
from esmvalcore.cmor.table import get_var_info
from esmvalcore.cmor.table import get_tables
from esmvalcore.iris_helpers import (
has_unstructured_grid,
safe_convert_units,
Expand All @@ -53,8 +54,9 @@ class Fix:
def __init__(
self,
vardef: VariableInfo,
*,
session: Session,
extra_facets: dict | None = None,
session: Session | None = None,
frequency: str | None = None,
) -> None:
"""Initialize fix object.
Expand All @@ -63,11 +65,11 @@ def __init__(
----------
vardef:
CMOR table entry of the variable.
extra_facets:
Extra facets. For details, see :ref:`config-extra-facets`.
session:
Current session which includes configuration and directory
information.
extra_facets:
Extra facets. For details, see :ref:`config-extra-facets`.
frequency:
Expected frequency of the variable. If not given, use the one from
the CMOR table entry of the variable.
Expand Down Expand Up @@ -211,7 +213,7 @@ def get_fixes(
extra_facets: dict | None = None,
session: Session | None = None,
frequency: str | None = None,
) -> list:
) -> list[Self]:
"""Get the fixes that must be applied for a given dataset.

It will look for them at the module
Expand Down Expand Up @@ -248,15 +250,25 @@ def get_fixes(

Returns
-------
list[Fix]
:
Fixes to apply for the given data.

"""
if session is None:
warnings.warn(
"Not providing a `session` argument or using `session=None` "
"is deprecated and will no longer be supported in v2.16.0.",
DeprecationWarning,
stacklevel=2,
)
from esmvalcore.config import CFG # noqa: PLC0415

session = CFG.start_session("fix")

if extra_facets is None:
extra_facets = {}

vardef = get_var_info(
project,
vardef = get_tables(session, project).get_variable(
mip,
short_name,
branding_suffix=extra_facets.get("branding_suffix"),
Expand All @@ -271,7 +283,6 @@ def get_fixes(
fixes_modules = []
if project == "cordex":
driver = extra_facets["driver"].replace("-", "_").lower()
extra_facets["dataset"] = dataset
with contextlib.suppress(ImportError):
fixes_modules.append(
importlib.import_module(
Expand Down Expand Up @@ -374,7 +385,10 @@ def fix_metadata(self, cubes: Sequence[Cube]) -> CubeList:
Fixed cubes.

"""
# Make sure the this fix also works when no extra_facets are given
# Make sure the this fix also works when no extra_facets are given.
# Note that this never happens in practice because `"project"` and
# `"dataset"` are inserted into `extra_facets` in
# `esmvalcore.cmor.fix.fix_*`.
if "project" in self.extra_facets and "dataset" in self.extra_facets:
dataset_str = (
f"{self.extra_facets['project']}:"
Expand Down Expand Up @@ -600,7 +614,8 @@ def _fix_alternative_generic_level_coords(self, cube: Cube) -> Cube:
_get_alternative_generic_lev_coord(
cube,
coord_name,
self.vardef.table_type,
project=self.extra_facets["project"],
session=self.session,
)
)
except ValueError: # no alternatives found
Expand Down
34 changes: 19 additions & 15 deletions esmvalcore/cmor/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import logging
from typing import TYPE_CHECKING

from esmvalcore.cmor.table import CMOR_TABLES
from esmvalcore.cmor.table import get_tables

if TYPE_CHECKING:
from collections.abc import Sequence
Expand All @@ -14,25 +14,27 @@
from iris.cube import Cube

from esmvalcore.cmor.table import CoordinateInfo, VariableInfo
from esmvalcore.config import Session

logger = logging.getLogger(__name__)

_ALTERNATIVE_GENERIC_LEV_COORDS = {
"alevel": {
"CMIP5": ["alt40", "plevs"],
"CMIP6": ["alt16", "plev3"],
"obs4MIPs": ["alt16", "plev3"],
"CMIP5Info": ["alt40", "plevs"],
"CMIP6Info": ["alt16", "plev3"],
"Obs4MIPsInfo": ["alt16", "plev3"],
},
"zlevel": {
"CMIP3": ["pressure"],
"CMIP3Info": ["pressure"],
},
}


def _get_alternative_generic_lev_coord(
cube: Cube,
coord_name: str,
cmor_table_type: str,
project: str,
session: Session,
) -> tuple[CoordinateInfo, Coord]:
"""Find alternative generic level coordinate in cube.

Expand All @@ -42,10 +44,10 @@ def _get_alternative_generic_lev_coord(
Cube to be checked.
coord_name:
Name of the generic level coordinate.
cmor_table_type:
CMOR table type, e.g., CMIP3, CMIP5, CMIP6. Note: This is NOT the
project of the dataset, but rather the entry `cmor_type` in
`config-developer.yml`.
project:
Project that the dataset belongs to.
session:
The session to use.

Returns
-------
Expand All @@ -63,12 +65,16 @@ def _get_alternative_generic_lev_coord(
coord_name,
{},
)
allowed_alternatives = alternatives_for_coord.get(cmor_table_type, [])
tables = get_tables(session, project)
allowed_alternatives = alternatives_for_coord.get(
tables.__class__.__name__,
[],
)

# Check if any of the allowed alternative coordinates is present in the
# cube
for allowed_alternative in allowed_alternatives:
cmor_coord = CMOR_TABLES[cmor_table_type].coords[allowed_alternative]
cmor_coord = tables.coords[allowed_alternative]
if cube.coords(var_name=cmor_coord.out_name):
cube_coord = cube.coord(var_name=cmor_coord.out_name)
return (cmor_coord, cube_coord)
Expand All @@ -77,9 +83,7 @@ def _get_alternative_generic_lev_coord(
f"Found no valid alternative coordinate for generic level coordinate "
f"'{coord_name}'"
)
raise ValueError(
msg,
)
raise ValueError(msg)


def _get_generic_lev_coord_names(
Expand Down
Loading