Skip to content

Processor: BiasAdjustModelToStation

Registry key: bias_adjust_model_to_station  |  Priority: 60  |  Category: Data Refinement

Apply quantile delta mapping (QDM) bias adjustment to gridded climate model data using HDP (Historical Data Platform) weather station observations as the training reference. Output is bias-adjusted at the requested station locations, with a station dimension (and lat/lon/elevation coordinates along it) on a single data variable, rather than one data variable per station.

Algorithm

flowchart TD
    Start([execute]) --> DictCheck{result is dict?}
    DictCheck -->|Yes| ExecDict[_execute_dict<br/>per-key recursion]
    DictCheck -->|No| LoadObs[_load_station_data<br/>HDP reference]
    LoadObs --> TypeCheck{Dataset / DataArray?}
    TypeCheck -->|Yes| ProcSingle[_process_single_dataset]
    TypeCheck -->|No| TypeErr[raise TypeError]

    ExecDict --> ProcSingle
    ProcSingle --> Preproc[_preprocess_hdp<br/>rename, unit check, attrs]
    Preproc --> BiasAdjust[_bias_adjust_model_data<br/>QDM via xclim]
    BiasAdjust --> UpdateCtx[update_context]
    UpdateCtx --> End([Output: Dataset with a 'station' dimension])

    click Start "https://github.com/cal-adapt/climakitae/blob/main/climakitae/new_core/processors/bias_adjust_model_to_station.py" "execute"
    click ExecDict "https://github.com/cal-adapt/climakitae/blob/main/climakitae/new_core/processors/bias_adjust_model_to_station.py" "_execute_dict"
    click LoadObs "https://github.com/cal-adapt/climakitae/blob/main/climakitae/new_core/processors/bias_adjust_model_to_station.py" "_load_station_data"
    click ProcSingle "https://github.com/cal-adapt/climakitae/blob/main/climakitae/new_core/processors/bias_adjust_model_to_station.py" "_process_single_dataset"
    click Preproc "https://github.com/cal-adapt/climakitae/blob/main/climakitae/new_core/processors/bias_adjust_model_to_station.py" "_preprocess_hdp"
    click BiasAdjust "https://github.com/cal-adapt/climakitae/blob/main/climakitae/new_core/processors/bias_adjust_model_to_station.py" "_bias_adjust_model_data"
    click UpdateCtx "https://github.com/cal-adapt/climakitae/blob/main/climakitae/new_core/processors/bias_adjust_model_to_station.py" "update_context"

Parameters

The processor takes a dict:

Key Type Default Description
stations list[str] [] HDP station_id values to bias-adjust against (e.g. "ASOSAWOS_69007093217"). Required for non-trivial use.
historical_slice tuple[int, int] (1980, 2014) Years used as the training period. Must overlap each station's actual observational coverage, which varies per HDP station.
window int 90 Window size (days) for seasonal grouping in QDM.
nquantiles int 20 Number of quantiles for the QDM mapping.
group str "time.dayofyear" Temporal grouping passed to xclim QDM.
kind str "+" Adjustment kind: "+" (additive) or "*" (multiplicative).

Requirements

  • Activity ID: WRF (dynamical downscaling). LOCA2 already includes statistical bias adjustment at the watershed level and is not the intended input.
  • Variable: Designed for hourly t2 (temperature, matched to HDP's tas) or dew_point (dewpoint, matched to HDP's tdps, or tdps_derived where tdps isn't available). Not every HDP network provides every variable — requesting a station from a network known not to provide the needed variable is rejected up front.
  • Time coverage: Input must overlap the requested historical training period (default 1980–2014). HDP station coverage varies widely by station, from a few years to multiple decades.
  • Multiple networks: Requested stations may span multiple HDP networks in a single call.
  • Calendar: All inputs are converted to a noleap calendar internally for consistency.

Example

from climakitae.new_core.user_interface import ClimateData

data = (ClimateData()
    .catalog("cadcat")
    .activity_id("WRF")
    .institution_id("UCLA")
    .variable_id("t2")
    .table_id("1hr")
    .grid_label("d03")
    .processes({
        "time_slice": ("1980-01-01", "2050-12-31"),
        "bias_adjust_model_to_station": {"stations": ["KSAC"]},
    })
    .get())

# Result: single data variable with a 'station' dimension, time-sliced to requested range.

Code References

Method Link to Code Purpose
__init__ View on Github Read configuration dict with defaults
_preprocess_hdp View on Github Rename / unit-check / attribute the raw HDP station slice
_load_station_data View on Github Resolve station IDs against the HDP catalog, load HDP subset, return reference Dataset
_bias_adjust_model_data View on Github Build QDM (xclim) train/adjust, vectorized across all stations at once
_process_single_dataset View on Github Load reference, run vectorized QDM across stations, return dataset with a station dimension
_execute_dict View on Github Recursive dict path
execute View on Github Dispatcher: dict / Dataset / DataArray
update_context View on Github Record stations and QDM parameters in new_attrs
set_data_accessor View on Github Receive DataCatalog reference (used by _load_station_data)

Earlier docs implied an early "activity_id == WRF" guard with line numbers in the 80–145 range. Those line numbers do not exist in the source — the file's first method (__init__) starts at line 148. The activity-id constraint is enforced by data availability rather than an explicit early-return check.

See also