Thresholds and Operators Reference#

This page documents all available operators and threshold types that can be used with icclim.build_threshold() and the generic index API.

See also

Generic indices recipes for examples showing thresholds in action.

Operators#

An operator defines the comparison between a variable and a threshold value. It is expressed as a string symbol in the threshold query (e.g. "> 25 degC").

Available operators#

Symbol(s)

Short name

Long name

Usage notes

>, gt

gt

greater than

Standard strict inequality.

<, lt

lt

lower than

Standard strict inequality.

>=, =>, ge, get

get

greater or equal to

Non-strict upper bound.

<=, =<, le, let

let

lower or equal to

Non-strict lower bound.

=, ==, eq, equal

e

equal to

Exact equality.

(none)

reach

reaching

Special operator used implicitly by excess and deficit indices. Cannot be specified directly in a query string.

Examples#

from icclim import build_threshold

t1 = build_threshold("> 25 degC")         # greater than 25 °C
t2 = build_threshold("<= 0 degC")         # at or below freezing
t3 = build_threshold(">= 1 mm/day")       # wet-day filter
t4 = build_threshold("== 0 degC")         # exactly 0 °C

Threshold types#

build_threshold returns one of three concrete threshold types depending on the arguments provided.

BasicThreshold#

A fixed scalar (or list of scalars) threshold.

from icclim import build_threshold

# Single scalar
t = build_threshold(">= 30 degC")

# Multiple scalars — the index is computed once per value,
# creating a "threshold" dimension in the output.
t_multi = build_threshold(value=[25, 30, 35], operator=">=", unit="degC")

PercentileThreshold#

A percentile computed from the data itself during the run. Two flavours exist, selected by the unit string:

Unit keyword

Type

Description

doy_per

Day-of-year percentile

Percentile computed separately for each calendar day, using a rolling window (doy_window_width). Used for temperature-based ECAD indices (e.g. TX90p, WSDI).

period_per

Period percentile

Percentile computed over the full reference period (or study period when no base_period_time_range is given). Used for precipitation-based ECAD indices (e.g. R75p, R95pTOT).

from icclim import build_threshold

# 90th day-of-year percentile (like TX90p)
doy_t = build_threshold("> 90 doy_per")

# 75th period percentile, ignoring dry days (like R75pTOT)
per_t = build_threshold("> 75 period_per", threshold_min_value="1 mm/day")

# Percentile computed on a specific reference period
ref_t = build_threshold(
    "> 90 doy_per",
    base_period_time_range=["1991-01-01", "2020-12-31"],
)

Note

When base_period_time_range overlaps with the study period (in-base years), icclim applies the bootstrapping procedure described in ETCCDI guidelines to avoid artificially inflated counts.

BoundedThreshold#

Two thresholds combined with a logical link (AND or OR). Useful to express a range condition.

from icclim import build_threshold

# Temperature between 18 °C and 30 °C
bounded = build_threshold(">= 18 degC AND <= 30 degC")

# Equivalent using the & operator
low  = build_threshold(">= 18 degC")
high = build_threshold("<= 30 degC")
bounded2 = low & high

# Using explicit arguments
bounded3 = build_threshold(
    thresholds=[low, high],
    logical_link="AND",
)

# OR condition: frost OR heat stress
frost_or_heat = build_threshold("< 0 degC OR > 35 degC")

Per-grid-cell threshold (from a file or DataArray)#

A threshold dataset (e.g. pre-computed percentiles, climate normals) can be supplied directly as a path to a NetCDF/Zarr file, or as an xarray.DataArray.

import xarray as xr
from icclim import build_threshold

# From a pre-computed threshold NetCDF file
t_file = build_threshold(operator=">=", value="path/to/tasmax_90th.nc", unit="K")

# With a +5 K offset (e.g. 5 degrees warmer than the normal)
t_offset = build_threshold(
    operator=">=", value="path/to/tasmax_normal.nc", unit="K", offset=5
)

# From an xarray DataArray of pre-computed percentile doy values
import xclim.core.calendar
tasmax_ds = xr.open_dataset("path/to/tasmax.nc")
doys = xclim.core.calendar.percentile_doy(tasmax_ds.tasmax)
t_doy = build_threshold(operator=">=", value=doys)

Combining thresholds (AND/OR)#

Multiple thresholds on different variables can be combined via the in_files dictionary syntax when calling a generic index:

import icclim

# Count days when temperature is comfortable AND precipitation is light
good_weather = icclim.count_occurrences(
    in_files={
        "tasmax": {
            "study": "path/to/tasmax.nc",
            "thresholds": icclim.build_threshold(">= 15 degC AND <= 28 degC"),
        },
        "pr": {
            "study": "path/to/pr.nc",
            "thresholds": icclim.build_threshold("< 5 mm/day"),
        },
    },
)

Note

The logical link between variables (across the in_files dictionary keys) is always AND. To express an OR between two variables you must use BoundedThreshold on each variable with OR, or use the icclim.index generic API with a custom threshold list.

threshold_min_value#

For precipitation percentile thresholds, wet-day filtering is standard practice: percentiles are computed only from days with pr >= 1 mm/day. Use threshold_min_value to apply such a filter:

from icclim import build_threshold

# 95th percentile of wet days only (equivalent to R95p)
t = build_threshold("> 95 period_per", threshold_min_value="1 mm/day")

Quick-reference cheat sheet#

from icclim import build_threshold

# Plain scalar
build_threshold("> 25 degC")

# Day-of-year percentile
build_threshold("> 90 doy_per")

# Period percentile on wet days
build_threshold("> 75 period_per", threshold_min_value="1 mm/day")

# Range (bounded AND)
build_threshold(">= 18 degC AND <= 30 degC")

# Range (bounded OR)
build_threshold("< 0 degC OR > 40 degC")

# Multiple scalar values → threshold dimension in output
build_threshold(value=[0, 10, 20, 30], operator=">=", unit="degC")

# External file / DataArray threshold
build_threshold(operator=">=", value="t90_climatology.nc", unit="K")

# With offset relative to a climatology
build_threshold(operator=">", value="t_normal.nc", unit="K", offset=2)