CMIP6 core API example¶
Shows the direct public API with one built-in core fix.
Flow: check -> dry-run -> apply -> re-check.
In [1]:
Copied!
import numpy as np
import woodpecker
from woodpecker.testing import make_cmip6
import numpy as np
import woodpecker
from woodpecker.testing import make_cmip6
Create a CMIP6-like dataset where tas is stored in Celsius instead of Kelvin.
In [2]:
Copied!
dataset = make_cmip6(overrides={"units": "degC"}, seed=7)
original_values = dataset["tas"].values.copy()
dataset
dataset = make_cmip6(overrides={"units": "degC"}, seed=7)
original_values = dataset["tas"].values.copy()
dataset
Out[2]:
<xarray.Dataset> Size: 32kB
Dimensions: (time: 12, lat: 18, lon: 36)
Coordinates:
* time (time) datetime64[s] 96B 2000-01-01 2000-02-01 ... 2000-12-01
* lat (lat) float64 144B -85.0 -75.0 -65.0 -55.0 ... 55.0 65.0 75.0 85.0
* lon (lon) float64 288B 0.0 10.0 20.0 30.0 ... 320.0 330.0 340.0 350.0
Data variables:
tas (time, lat, lon) float32 31kB 251.3 251.4 251.5 ... 249.7 249.8
Attributes: (12/15)
project_id: CMIP6
dataset_id: CMIP6.CMIP.MOHC.HadGEM3-GC31-LL.historical.r1i1p1f3....
source_file: CMIP6.CMIP.MOHC.HadGEM3-GC31-LL.historical.r1i1p1f3....
source_id: HadGEM3-GC31-LL
source_name: HadGEM3-GC31-LL
mip_era: CMIP6
... ...
variable_id: tas
table_id: Amon
units: degC
frequency: mon
grid_label: gn
nominal_resolution: 250 kmIn [3]:
Copied!
fix_ids = ["woodpecker.normalize_tas_units_to_kelvin"]
findings = woodpecker.check(dataset, fixes=fix_ids)
findings.fix_ids
fix_ids = ["woodpecker.normalize_tas_units_to_kelvin"]
findings = woodpecker.check(dataset, fixes=fix_ids)
findings.fix_ids
Out[3]:
('woodpecker.normalize_tas_units_to_kelvin',)
Dry-run previews the repair without changing the dataset.
In [4]:
Copied!
result = woodpecker.apply(dataset, fixes=findings.fix_ids, dry_run=True)
(
result.stats,
result.preview,
dataset["tas"].attrs["units"],
np.allclose(dataset["tas"].values, original_values),
)
result = woodpecker.apply(dataset, fixes=findings.fix_ids, dry_run=True)
(
result.stats,
result.preview,
dataset["tas"].attrs["units"],
np.allclose(dataset["tas"].values, original_values),
)
Out[4]:
({'attempted': 1,
'changed': 1,
'persist_attempted': 0,
'persisted': 0,
'persist_failed': 0,
'preview': [{'path': 'HadGEM3-GC31-LL',
'fix_id': 'woodpecker.normalize_tas_units_to_kelvin',
'name': 'Normalize tas-like units to Kelvin',
'labels': ['risk.value_transformation'],
'label_titles': ['careful: value transformation'],
'label_metadata': [{'id': 'risk.value_transformation',
'title': 'careful: value transformation',
'description': 'Transforms data or coordinate values.',
'category': 'risk-medium'}],
'changed': True}]},
({'path': 'HadGEM3-GC31-LL',
'fix_id': 'woodpecker.normalize_tas_units_to_kelvin',
'name': 'Normalize tas-like units to Kelvin',
'labels': ['risk.value_transformation'],
'label_titles': ['careful: value transformation'],
'label_metadata': [{'id': 'risk.value_transformation',
'title': 'careful: value transformation',
'description': 'Transforms data or coordinate values.',
'category': 'risk-medium'}],
'changed': True},),
'degC',
True)
Apply the fix in memory and re-check.
In [5]:
Copied!
write = woodpecker.apply(dataset, fixes=findings.fix_ids, dry_run=False)
(
write.stats,
dataset["tas"].attrs["units"],
np.allclose(dataset["tas"].values, original_values + 273.15),
)
write = woodpecker.apply(dataset, fixes=findings.fix_ids, dry_run=False)
(
write.stats,
dataset["tas"].attrs["units"],
np.allclose(dataset["tas"].values, original_values + 273.15),
)
Out[5]:
({'attempted': 1,
'changed': 1,
'persist_attempted': 1,
'persisted': 1,
'persist_failed': 0,
'preview': [{'path': 'HadGEM3-GC31-LL',
'fix_id': 'woodpecker.normalize_tas_units_to_kelvin',
'name': 'Normalize tas-like units to Kelvin',
'labels': ['risk.value_transformation'],
'label_titles': ['careful: value transformation'],
'label_metadata': [{'id': 'risk.value_transformation',
'title': 'careful: value transformation',
'description': 'Transforms data or coordinate values.',
'category': 'risk-medium'}],
'changed': True}]},
'K',
True)
In [6]:
Copied!
recheck = woodpecker.check(dataset, fixes=fix_ids)
bool(recheck)
recheck = woodpecker.check(dataset, fixes=fix_ids)
bool(recheck)
Out[6]:
False