Source code for xclim.core.cfchecks

# noqa: D205,D400
"""
CF-Convention checking
======================

Utilities designed to verify the compliance of metadata with the CF-Convention.
"""
import fnmatch
from typing import Sequence, Union

from .formatting import parse_cell_methods
from .options import cfcheck
from .utils import VARIABLES, ValidationError

# TODO: Implement pandas infer_freq in xarray with CFTimeIndex. >> PR pydata/xarray#4033


[docs]@cfcheck def check_valid(var, key: str, expected: Union[str, Sequence[str]]): r"""Check that a variable's attribute has one of the expected values. Raise a ValidationError otherwise.""" att = getattr(var, key, None) if att is None: raise ValidationError(f"Variable does not have a `{key}` attribute.") if isinstance(expected, str): expected = [expected] for exp in expected: if fnmatch.fnmatch(att, exp): break else: raise ValidationError( f"Variable has a non-conforming {key}. Got `{att}`, expected `{expected}`", )
[docs]def cfcheck_from_name(varname, vardata): """Perform cfchecks on a DataArray using specifications from xclim's default variables.""" data = VARIABLES[varname] if "cell_methods" in data: check_valid( vardata, "cell_methods", parse_cell_methods(data["cell_methods"]) + "*" ) if "standard_name" in data: check_valid(vardata, "standard_name", data["standard_name"])
[docs]def generate_cfcheck(*varnames): def _generated_check(*args): for varname, var in zip(varnames, args): cfcheck_from_name(varname, var) return _generated_check
[docs]def check_valid_temperature(var, units): r"""Check that variable is air temperature.""" check_valid(var, "standard_name", "air_temperature") check_valid(var, "units", units)
[docs]def check_valid_discharge(var): r"""Check that the variable is a discharge.""" check_valid(var, "standard_name", "water_volume_transport_in_river_channel") check_valid(var, "units", "m3 s-1")
[docs]def check_valid_min_temperature(var, units="K"): r"""Check that a variable is a valid daily minimum temperature.""" check_valid_temperature(var, units) check_valid(var, "cell_methods", "time: minimum within days")
[docs]def check_valid_mean_temperature(var, units="K"): r"""Check that a variable is a valid daily mean temperature.""" check_valid_temperature(var, units) check_valid(var, "cell_methods", "time: mean within days")
[docs]def check_valid_max_temperature(var, units="K"): r"""Check that a variable is a valid daily maximum temperature.""" check_valid_temperature(var, units) check_valid(var, "cell_methods", "time: maximum within days")