Source code for icclim.generic.registry

"""Contain the registry of generic indicators."""

from __future__ import annotations

from typing import TYPE_CHECKING

from icclim._core.constants import (
    GROUP_BY_METHOD,
    GROUP_BY_REF_AND_RESAMPLE_STUDY_METHOD,
    RESAMPLE_METHOD,
)
from icclim._core.generic.functions import (
    average,
    count_occurrences,
    deficit,
    difference_of_extremes,
    difference_of_means,
    excess,
    fraction_of_total,
    generic_sum,
    max_consecutive_occurrence,
    max_of_rolling_average,
    max_of_rolling_sum,
    maximum,
    mean_of_absolute_one_time_step_difference,
    mean_of_difference,
    min_of_rolling_average,
    min_of_rolling_sum,
    minimum,
    percentile,
    standard_deviation,
    sum_of_spell_lengths,
)
from icclim._core.generic.indicator import GenericIndicator
from icclim._core.model.registry import Registry
from icclim.exception import InvalidIcclimArgumentError

if TYPE_CHECKING:
    from icclim._core.climate_variable import ClimateVariable


def _check_single_var(
    climate_vars: list[ClimateVariable], indicator: GenericIndicator
) -> None:
    if len(climate_vars) > 1:
        msg = f"{indicator.name} can only be computed on a single variable."
        raise InvalidIcclimArgumentError(msg)


def _check_couple_of_vars(
    climate_vars: list[ClimateVariable],
    indicator: GenericIndicator,
) -> None:
    if len(climate_vars) != 2:
        msg = (
            f"{indicator.name} can only be computed on two variables sharing the same"
            f" unit (e.g. 2 temperatures). You can either provide a secondary variable"
            f" with `in_files` or `var_name`, or you can let icclim compute this"
            f" second variable as a subset of the first one using"
            f" `base_period_time_range`."
        )
        raise InvalidIcclimArgumentError(msg)


[docs] class GenericIndicatorRegistry(Registry[GenericIndicator]): """Registry of generic indicators.""" def __init__(self) -> None: super().__init__() _item_class = GenericIndicator CountOccurrences = GenericIndicator( "count_occurrences", count_occurrences, definition="Count occurrences when threshold(s) are met" " (e.g. SU, Tx90p, RR1).", ) MaxConsecutiveOccurrence = GenericIndicator( "max_consecutive_occurrence", max_consecutive_occurrence, definition="Count the maximum number of consecutive occurrences when" " threshold(s) are met (e.g. CDD, CSU, CWD).", ) SumOfSpellLengths = GenericIndicator( "sum_of_spell_lengths", sum_of_spell_lengths, definition="Sum the lengths of each consecutive occurrence spell when" " threshold(s) are met. The minimum spell length is controlled by" " `min_spell_length` (e.g. WSDI, CSDI).", ) Excess = GenericIndicator( "excess", excess, check_vars=_check_single_var, definition="Compute the excess over the given threshold. The excess is" " `sum(x[x>t] - t)` where x is the studied variable and t the threshold" " (e.g. GD4).", ) Deficit = GenericIndicator( "deficit", deficit, check_vars=_check_single_var, definition="Compute the deficit below the given threshold. The deficit is" " `sum(t - x[x<t])` where x is the studied variable and t the threshold" " (e.g. HD17).", ) FractionOfTotal = GenericIndicator( "fraction_of_total", fraction_of_total, check_vars=_check_single_var, definition="Compute the fraction of values meeting threshold(s) over the sum of" " every values (e.g. R75pTOT, R95pTOT).", ) Maximum = GenericIndicator( "maximum", maximum, definition="Maximum of values that met threshold(s), if threshold(s) are given" " (e.g. Txx, Tnx).", ) Minimum = GenericIndicator( "minimum", minimum, definition="Minimum of values that met threshold(s), if threshold(s) are given" " (e.g. Txn, Tnn).", ) Average = GenericIndicator( "average", average, definition="Average of values that met threshold(s), if threshold(s) are given" " (e.g. Tx, Tn).", ) Sum = GenericIndicator( "sum", generic_sum, definition="Sum of values that met threshold(s), if threshold(s) are given" " (e.g. PRCPTOT, RR).", ) StandardDeviation = GenericIndicator( "standard_deviation", standard_deviation, definition="Standard deviation of values that met threshold(s)," " if threshold(s) are given.", ) MaxOfRollingSum = GenericIndicator( "max_of_rolling_sum", max_of_rolling_sum, check_vars=_check_single_var, definition="Maximum of rolling sum over time dimension" " (e.g. RX5DAY: maximum 5 days window of precipitation accumulation).", ) MinOfRollingSum = GenericIndicator( "min_of_rolling_sum", min_of_rolling_sum, check_vars=_check_single_var, definition="Minimum of rolling sum over time dimension.", ) MaxOfRollingAverage = GenericIndicator( "max_of_rolling_average", max_of_rolling_average, check_vars=_check_single_var, definition="Maximum of rolling average over time dimension.", ) MinOfRollingAverage = GenericIndicator( "min_of_rolling_average", min_of_rolling_average, check_vars=_check_single_var, definition="Minimum of rolling average over time dimension.", ) MeanOfDifference = GenericIndicator( "mean_of_difference", mean_of_difference, check_vars=_check_couple_of_vars, definition="Average of the difference between two variables" ", or one variable and it's reference period values" " (e.g. DTR: `mean(tasmax - tasmin)`).", qualifiers=["compute_diff"], ) DifferenceOfExtremes = GenericIndicator( "difference_of_extremes", difference_of_extremes, check_vars=_check_couple_of_vars, definition="Difference of extremes between two variables" ", or one variable and it's reference period values." " The extremes are always `maximum` for the first variable and" " `minimum` for the second variable" " (e.g. ETR: `max(tasmax) - min(tasmin)`).", qualifiers=["compute_diff"], ) MeanOfAbsoluteOneTimeStepDifference = GenericIndicator( "mean_of_absolute_one_time_step_difference", mean_of_absolute_one_time_step_difference, check_vars=_check_couple_of_vars, definition="Average of the absolute one time step by one time step difference" " between two variables," " or one variable and it's reference period values" " (e.g. vDTR:" " `mean((tasmax[i] - tasmin[i]) - (tasmax[i-1] - tasmin[i-1])` ;" " where i is the day of measure).", qualifiers=["compute_diff"], ) DifferenceOfMeans = GenericIndicator( "difference_of_means", difference_of_means, check_vars=_check_couple_of_vars, sampling_methods=[ RESAMPLE_METHOD, GROUP_BY_METHOD, GROUP_BY_REF_AND_RESAMPLE_STUDY_METHOD, ], definition="Difference of the average between two variables" ", or one variable and it's reference period values" " (e.g. anomaly: `mean(tasmax) - mean(tasmax_ref]))`.", qualifiers=["compute_diff"], ) Percentile = GenericIndicator( "percentile", percentile, check_vars=_check_single_var, definition="Percentile of a variable.", )