ML Bias Correction
We trained a machine-learning model to predict that error, and the result is a single global field you can apply to the simulations yourself.
The correction field
You’ll find it in the quality assurance collection Data Catalogue.
The function
import numpy as np
def apply_bias_correction(wtd, average_wtd, bias, protect_depth=0.1, ramp_width=4.9):
"""Correct a simulated water table depth with the ML bias field.
wtd the water table depth you want to correct, in metres below the
surface. Any time resolution, or none at all.
average_wtd the long-term historical average depth for the same simulation,
also in metres below the surface.
bias the `bias` variable from ml_bias_correction.nc, in metres, on
the same grid as `wtd`.
Comes back the same shape as `wtd`.
"""
ramp_factor = ((average_wtd - protect_depth) / ramp_width).clip(min=0.0, max=1.0)
# Cap the adjustment at half the long-term depth in either direction.
limit = np.abs(average_wtd / 2)
delta = (bias * ramp_factor).clip(min=-limit, max=limit)
return wtd + deltaApplying it
You need three:
The simulation you want to correct - any wtd product from the Data Access page.
Its long-term average. This has to be the historical average for the same forcing: wtd_reference_gswp3-w5e5_average_1960_2019.nc
The bias field, on your grid. Reindex it rather than hoping it already lines up:
import xarray as xr
import zarr
# The annual and monthly products are deposited as zipped Zarr stores, the
# averages as NetCDF; both carry a length-one `model` dimension.
sim = xr.open_zarr(
zarr.storage.ZipStore("wtd_annual_2015_2100_ssp370_gfdl-esm4.zarr.zip", mode="r")
).isel(model=0, drop=True)
average = xr.open_dataset(
"wtd_average_1960_2014_historical_gfdl-esm4.nc"
).isel(model=0, drop=True)
bias = xr.open_dataset("ml_bias_correction.nc")["bias"].reindex(
latitude=sim.latitude,
longitude=sim.longitude,
layer=sim.layer,
method="nearest",
)
corrected = apply_bias_correction(sim["wtd"], average["wtd"], bias)