Climate indices computation package based on Xarray with extensive climate analysis capabilities
Comprehensive statistical downscaling and bias correction methods for climate model post-processing.
Important Note: The SDBA (Statistical Downscaling and Bias Adjustment) functionality has been moved to a separate xsdba package. While still accessible through xclim.sdba for backward compatibility, users are encouraged to use xsdba directly.
Legacy import (with deprecation warning):
from xclim import sdbaRecommended import:
import xsdba as sdba
# or
from xsdba import EmpiricalQuantileMapping, DetrendedQuantileMappingCore bias correction algorithms for correcting systematic errors in climate model simulations.
class EmpiricalQuantileMapping:
"""
Empirical Quantile Mapping bias adjustment method.
Corrects the distribution of climate model data to match observed
distribution using empirical quantile mapping.
"""
def __init__(self, nquantiles=50, kind="additive", **kwargs):
"""
Parameters:
- nquantiles: int, number of quantiles for mapping (default 50)
- kind: str, adjustment kind ("additive", "multiplicative")
- **kwargs: additional method parameters
"""
def train(self, ref, hist, **kwargs):
"""
Train the bias adjustment model.
Parameters:
- ref: xr.DataArray, reference (observed) data for training
- hist: xr.DataArray, historical model data for training
- **kwargs: additional training parameters
Returns:
self: Trained bias adjustment object
"""
def adjust(self, sim, **kwargs):
"""
Apply bias adjustment to simulation data.
Parameters:
- sim: xr.DataArray, simulation data to adjust
- **kwargs: additional adjustment parameters
Returns:
xr.DataArray: Bias-adjusted simulation data
"""
class DetrendedQuantileMapping:
"""
Detrended Quantile Mapping for preserving climate change signals.
Separates trend from variability, applies quantile mapping to
variability, then adds back the trend.
"""
def __init__(self, nquantiles=50, kind="additive", **kwargs):
"""
Parameters:
- nquantiles: int, number of quantiles for mapping
- kind: str, adjustment kind ("additive", "multiplicative")
- **kwargs: additional method parameters
"""
class QuantileDeltaMapping:
"""
Quantile Delta Mapping preserving relative changes.
Adjusts model quantiles while preserving the relative change
between historical and future periods.
"""
def __init__(self, nquantiles=50, kind="multiplicative", **kwargs):
"""
Parameters:
- nquantiles: int, number of quantiles for mapping
- kind: str, adjustment kind ("additive", "multiplicative")
- **kwargs: additional method parameters
"""
class PrincipalComponents:
"""
Principal Component Analysis based bias adjustment.
Uses PCA to adjust multivariate climate data while preserving
spatial and temporal correlations.
"""
def __init__(self, n_components=None, **kwargs):
"""
Parameters:
- n_components: int, number of principal components to retain
- **kwargs: additional PCA parameters
"""
class LOCI:
"""
Local Intensity Scaling bias adjustment method.
Adjusts wet-day precipitation intensities based on local
scaling factors.
"""
def __init__(self, thresh="0.05 mm/day", **kwargs):
"""
Parameters:
- thresh: str, wet day threshold
- **kwargs: additional LOCI parameters
"""
class Scaling:
"""
Simple scaling bias adjustment method.
Applies additive or multiplicative scaling factors
based on mean bias between model and observations.
"""
def __init__(self, kind="additive", **kwargs):
"""
Parameters:
- kind: str, scaling kind ("additive", "multiplicative")
- **kwargs: additional scaling parameters
"""Statistical measures for evaluating bias adjustment performance and model skill.
def bias(obs, sim, **kwargs):
"""
Calculate bias between observations and simulations.
Parameters:
- obs: xr.DataArray, observed data
- sim: xr.DataArray, simulated data
- **kwargs: additional calculation parameters
Returns:
xr.DataArray: Bias values (sim - obs)
"""
def relative_bias(obs, sim, **kwargs):
"""
Calculate relative bias as percentage.
Parameters:
- obs: xr.DataArray, observed data
- sim: xr.DataArray, simulated data
- **kwargs: additional calculation parameters
Returns:
xr.DataArray: Relative bias values as percentage
"""
def correlation(obs, sim, **kwargs):
"""
Calculate correlation coefficient between obs and sim.
Parameters:
- obs: xr.DataArray, observed data
- sim: xr.DataArray, simulated data
- **kwargs: additional calculation parameters
Returns:
xr.DataArray: Correlation coefficients
"""
def mae(obs, sim, **kwargs):
"""
Calculate Mean Absolute Error.
Parameters:
- obs: xr.DataArray, observed data
- sim: xr.DataArray, simulated data
- **kwargs: additional calculation parameters
Returns:
xr.DataArray: Mean absolute error values
"""
def rmse(obs, sim, **kwargs):
"""
Calculate Root Mean Square Error.
Parameters:
- obs: xr.DataArray, observed data
- sim: xr.DataArray, simulated data
- **kwargs: additional calculation parameters
Returns:
xr.DataArray: Root mean square error values
"""
def taylor_stats(obs, sim, **kwargs):
"""
Calculate Taylor diagram statistics.
Parameters:
- obs: xr.DataArray, observed data
- sim: xr.DataArray, simulated data
- **kwargs: additional calculation parameters
Returns:
dict: Dictionary with correlation, standard deviation ratio, and RMSE
"""Trend removal and restoration methods for climate change signal preservation.
class LoessDetrend:
"""
LOESS (locally weighted regression) detrending method.
Removes smooth trends using locally weighted polynomial regression.
"""
def __init__(self, f=0.2, niter=1, **kwargs):
"""
Parameters:
- f: float, smoothing parameter (0-1)
- niter: int, number of iterations
- **kwargs: additional LOESS parameters
"""
def fit(self, data, **kwargs):
"""
Fit detrending model to data.
Parameters:
- data: xr.DataArray, input data with time dimension
- **kwargs: additional fitting parameters
Returns:
self: Fitted detrending object
"""
def detrend(self, data, **kwargs):
"""
Remove trend from data.
Parameters:
- data: xr.DataArray, input data to detrend
- **kwargs: additional detrending parameters
Returns:
xr.DataArray: Detrended data
"""
def retrend(self, data, trend, **kwargs):
"""
Add trend back to detrended data.
Parameters:
- data: xr.DataArray, detrended data
- trend: xr.DataArray, trend to add back
- **kwargs: additional parameters
Returns:
xr.DataArray: Retrended data
"""
class PolyDetrend:
"""
Polynomial detrending method.
Removes polynomial trends of specified degree.
"""
def __init__(self, degree=1, **kwargs):
"""
Parameters:
- degree: int, polynomial degree for detrending
- **kwargs: additional polynomial parameters
"""Advanced bias adjustment utilities for multivariate and high-dimensional climate data.
def stack_variables(datasets, rechunk=True):
"""
Stack multiple climate variables for multivariate adjustment.
Parameters:
- datasets: dict, mapping variable names to xr.DataArray objects
- rechunk: bool, whether to rechunk stacked data (default True)
Returns:
xr.DataArray: Stacked multivariate data array
"""
def unstack_variables(stacked_data, reference_datasets):
"""
Unstack multivariate data back to individual variables.
Parameters:
- stacked_data: xr.DataArray, stacked multivariate data
- reference_datasets: dict, reference datasets for unstacking template
Returns:
dict: Mapping variable names to unstacked xr.DataArray objects
"""
def apply_correction(x, correction_factors, **kwargs):
"""
Apply correction factors to climate data.
Parameters:
- x: xr.DataArray, input data to correct
- correction_factors: xr.DataArray, correction factors
- **kwargs: additional application parameters
Returns:
xr.DataArray: Corrected data
"""
def interp_on_quantiles(newx, xq, yq, **kwargs):
"""
Interpolate values based on quantile mapping.
Parameters:
- newx: array-like, new values to interpolate
- xq: array-like, quantile values from source distribution
- yq: array-like, quantile values from target distribution
- **kwargs: interpolation parameters
Returns:
array-like: Interpolated values
"""Climate statistical property calculations for bias adjustment validation.
def annual_cycle_amplitude(data, **kwargs):
"""
Calculate amplitude of annual temperature cycle.
Parameters:
- data: xr.DataArray, daily or monthly climate data
- **kwargs: additional calculation parameters
Returns:
xr.DataArray: Annual cycle amplitude
"""
def annual_cycle_phase(data, **kwargs):
"""
Calculate phase of annual cycle (timing of maximum).
Parameters:
- data: xr.DataArray, daily or monthly climate data
- **kwargs: additional calculation parameters
Returns:
xr.DataArray: Day of year of annual maximum
"""
def spell_length_distribution(data, threshold, op=">=", **kwargs):
"""
Calculate distribution of spell lengths above/below threshold.
Parameters:
- data: xr.DataArray, daily climate data
- threshold: float, threshold value for spell detection
- op: str, comparison operator (">=", "<=", ">", "<")
- **kwargs: additional parameters
Returns:
xr.DataArray: Spell length distribution statistics
"""
def transition_probabilities(data, threshold, **kwargs):
"""
Calculate wet-to-dry and dry-to-wet transition probabilities.
Parameters:
- data: xr.DataArray, daily precipitation data
- threshold: float, wet day threshold
- **kwargs: additional calculation parameters
Returns:
dict: Dictionary with transition probability arrays
"""import xarray as xr
from xclim import sdba
# Load climate data
ref = xr.open_dataset("observations.nc").pr # Reference observations
hist = xr.open_dataset("model_historical.nc").pr # Historical model
sim = xr.open_dataset("model_future.nc").pr # Future projections
# Initialize bias adjustment method
QM = sdba.EmpiricalQuantileMapping(nquantiles=100, kind="multiplicative")
# Train the adjustment
QM.train(ref, hist)
# Apply adjustment to future projections
sim_adjusted = QM.adjust(sim)# Use detrended quantile mapping for temperature
tas_ref = xr.open_dataset("observations.nc").tas
tas_hist = xr.open_dataset("model_historical.nc").tas
tas_sim = xr.open_dataset("model_future.nc").tas
# Initialize detrended method
DQM = sdba.DetrendedQuantileMapping(
nquantiles=50,
kind="additive",
trend_preservation="multiplicative"
)
# Train and apply
DQM.train(tas_ref, tas_hist)
tas_adjusted = DQM.adjust(tas_sim)# Multivariate adjustment of temperature and precipitation
variables = {
"tas": tas_hist,
"pr": pr_hist
}
ref_vars = {
"tas": tas_ref,
"pr": pr_ref
}
# Stack variables for multivariate processing
stacked_hist = sdba.stack_variables(variables)
stacked_ref = sdba.stack_variables(ref_vars)
# Apply PCA-based adjustment
PCA = sdba.PrincipalComponents(n_components=10)
PCA.train(stacked_ref, stacked_hist)
# Adjust future data
sim_vars = {"tas": tas_sim, "pr": pr_sim}
stacked_sim = sdba.stack_variables(sim_vars)
stacked_adjusted = PCA.adjust(stacked_sim)
# Unstack back to individual variables
adjusted_vars = sdba.unstack_variables(stacked_adjusted, sim_vars)from xclim.sdba import measures
# Calculate performance metrics
bias_val = measures.bias(tas_ref, tas_hist)
rmse_val = measures.rmse(tas_ref, tas_hist)
corr_val = measures.correlation(tas_ref, tas_hist)
# Taylor diagram statistics
taylor_stats = measures.taylor_stats(tas_ref, tas_hist)
print(f"Correlation: {taylor_stats['correlation']}")
print(f"Std ratio: {taylor_stats['std_ratio']}")
# Before and after adjustment comparison
bias_before = measures.bias(tas_ref, tas_hist)
bias_after = measures.bias(tas_ref, tas_adjusted)
print(f"Bias reduction: {abs(bias_after) < abs(bias_before)}")from xclim.sdba import properties
# Compare annual cycles
amp_obs = properties.annual_cycle_amplitude(tas_ref)
amp_model = properties.annual_cycle_amplitude(tas_adjusted)
# Check spell length distributions for precipitation
spell_dist_obs = properties.spell_length_distribution(
pr_ref, threshold=1.0, op=">="
)
spell_dist_model = properties.spell_length_distribution(
pr_adjusted, threshold=1.0, op=">="
)
# Transition probabilities for precipitation
trans_prob_obs = properties.transition_probabilities(pr_ref, threshold=1.0)
trans_prob_model = properties.transition_probabilities(pr_adjusted, threshold=1.0)