Building Climate Scenarios
This guide describes a practical ClimateTools workflow for building climate scenarios from observations and climate-model simulations.
A typical scenario workflow has four parts:
- Choose and prepare the observational reference.
- Prepare historical and future climate-model simulations.
- Interpolate all datasets to a common grid.
- Bias-correct the model time series and compute derived products.
Scenario Inputs
At minimum, you usually need:
- an observational or reanalysis reference series (
obs) - a model historical series for the calibration period (
reforraw_train) - a model future or validation series to correct (
futorraw_val)
These may come from separate files or separate variables in the same dataset.
using ClimateTools
using YAXArrays
obs = Cube(open_dataset("obs_tasmax.nc"))
hist = Cube(open_dataset("gcm_hist_tasmax.nc"))
fut = Cube(open_dataset("gcm_ssp245_tasmax.nc"))Step 1: Check Time Axes and Calendars
Before interpolation or bias correction, inspect the time coordinates.
lookup(obs, :time)
lookup(hist, :time)
lookup(fut, :time)Important checks:
- Do
obsandhistcover the same calibration period? - Do the datasets use leap days consistently?
- Are calendars compatible enough for the chosen bias-correction method?
ClimateTools bias-correction functions already handle common leap-day alignment cases by dropping February 29 where needed.
Step 2: Select a Common Spatial Domain
If you only need a regional scenario, subset first. This reduces cost and makes diagnostics easier.
using Dates
using DimensionalData
obs_sub = obs[time=DateTime(1981, 1, 1)..DateTime(2010, 12, 31)]
hist_sub = hist[time=DateTime(1981, 1, 1)..DateTime(2010, 12, 31)]You can also subset spatially with bounding boxes or polygons; see Data and Subsetting.
Step 3: Interpolate to a Common Grid
Bias correction is easiest to reason about when the observational reference and the simulation use the same grid.
For regular grids, build a reusable regridder:
regridder = Regridder(hist_sub, obs_sub; method="bilinear")
hist_rg = regrid(hist_sub, regridder)
fut_rg = regrid(fut, regridder)If your source model uses a rotated pole or curvilinear grid, use the dataset-aware regridding path described on Interpolation and Regridding.
Step 4: Choose a Bias-Correction Method
ClimateTools exposes several correction methods with different objectives.
Quantile mapping: qqmap
Use qqmap when you want a day-of-year-based distributional correction.
qq = qqmap(obs_sub, hist_rg, fut_rg;
method="additive",
detrend=true,
window=15,
rankn=50)Typical use:
- temperature with
method="additive" - precipitation with
method="multiplicative"
Bulk quantile mapping: qqmap_bulk
Use qqmap_bulk when you want a single bulk correction over the whole calibration sample rather than a day-of-year windowed correction.
Extreme-value correction: biascorrect_extremes
Use biascorrect_extremes when you want quantile mapping plus an explicit correction of the upper tail, especially for variables where extreme behavior matters for impacts analysis.
dext = biascorrect_extremes(obs_sub, hist_rg, fut_rg; detrend=false)Time Variability Correction: tvc
Use tvc when your main objective is to correct covariance across time scales while preserving the time-event sequence of the model series.
tvc_out = tvc(obs_sub, hist_rg, fut_rg;
scales=[365, 183, 92, 46, 23, 12, 6, 3, 2],
eig_floor=1e-8)This method is especially relevant when persistence, low-frequency variability, or heatwave-type behavior matters as much as marginal distributions.
Step 5: Validate the Corrected Scenario
Do not stop at a successful function call. A climate scenario should be checked against the observational reference.
Recommended checks:
- compare mean and standard deviation during the calibration period
- compare annual summaries such as
annualmax,annualmean, or wet-day counts - inspect a few representative grid cells or regional aggregates
- verify that regridding and bias correction did not introduce widespread missing values
obs_txx = tx_max(obs_sub)
qq_txx = tx_max(qq)More guidance is on Validation and Diagnostics.
Step 6: Compute Scenario Products
Once the scenario is corrected, derive the quantities needed by the application.
Examples:
txx = tx_max(qq)
heatwaves = heat_wave_frequency(tasmin_corrected, qq; thresh_tasmin=22.0, thresh_tasmax=30.0)
rx5day = max_n_day_precipitation_amount(pr_corrected; window=5)Decision Guide
Use this rough rule of thumb:
qqmap: default choice for day-of-year distribution correctionqqmap_bulk: simple bulk correction without seasonal groupingbiascorrect_extremes: when upper-tail behavior is centraltvc: when time-scale covariance and persistence matter
Common Failure Modes
Watch for the following before trusting a scenario:
- observations and historical simulations do not overlap in time
- datasets are on different grids and were not regridded first
- variable units are inconsistent across data sources
- large NaN masks propagate into the corrected field
- rotated-grid datasets were passed as plain cubes instead of datasets
See Troubleshooting for concrete examples.