-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Make a more real-world example
- Loading branch information
1 parent
55b108c
commit d734028
Showing
7 changed files
with
460 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 83 additions & 10 deletions
93
packages/ref-metrics-example/src/ref_metrics_example/example.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,37 +1,110 @@ | ||
import json | ||
from pathlib import Path | ||
|
||
import xarray as xr | ||
from ref_core.metrics import Configuration, MetricResult, TriggerInfo | ||
|
||
|
||
def calculate_annual_mean_timeseries(dataset: Path) -> xr.Dataset: | ||
""" | ||
Calculate the annual mean timeseries for a dataset. | ||
While this function is implemented here, | ||
in most cases the metric calculation will be in the underlying benchmarking package. | ||
How the metric is calculated is up to the provider. | ||
Parameters | ||
---------- | ||
dataset | ||
A path to a CMIP6 dataset. | ||
This dataset may consist of multiple data files. | ||
Returns | ||
------- | ||
: | ||
The annual mean timeseries of the dataset | ||
""" | ||
input_files = dataset.glob("*.nc") | ||
|
||
dataset = xr.open_mfdataset(list(input_files), combine="by_coords", chunks=None) | ||
|
||
annual_mean = dataset.resample(time="YS").mean() | ||
return annual_mean.mean(dim=["lat", "lon"], keep_attrs=True) | ||
|
||
|
||
def format_cmec_output_bundle(dataset: xr.Dataset) -> dict: | ||
""" | ||
Create a simple CMEC output bundle for the dataset. | ||
Parameters | ||
---------- | ||
dataset | ||
Processed dataset | ||
Returns | ||
------- | ||
A CMEC output bundle ready to be written to disk | ||
""" | ||
cmec_output = { | ||
"DIMENSIONS": { | ||
"dimensions": { | ||
"source_id": {dataset.attrs["source_id"]: {}}, | ||
"region": {"global": {}}, | ||
"variable": {"tas": {}}, | ||
}, | ||
"json_structure": [ | ||
"model", | ||
"region", | ||
"statistic", | ||
], | ||
}, | ||
# Is the schema tracked? | ||
"SCHEMA": { | ||
"name": "CMEC-REF", | ||
"package": "example", | ||
"version": "v1", | ||
}, | ||
"RESULTS": { | ||
dataset.attrs["source_id"]: {"global": {"tas": ""}}, | ||
}, | ||
} | ||
|
||
return cmec_output | ||
|
||
|
||
class ExampleMetric: | ||
""" | ||
Example metric that does nothing but count the number of times it has been run. | ||
""" | ||
|
||
name = "example" | ||
|
||
def __init__(self) -> None: | ||
self._count = 0 | ||
|
||
def run(self, configuration: Configuration, trigger: TriggerInfo | None) -> MetricResult: | ||
""" | ||
Run a metric | ||
Parameters | ||
---------- | ||
trigger | ||
Trigger for what caused the metric to be executed. | ||
configuration | ||
Configuration object | ||
Returns | ||
------- | ||
: | ||
The result of running the metric. | ||
""" | ||
self._count += 1 | ||
if trigger is None: | ||
# TODO: This should probably raise an exception | ||
return MetricResult( | ||
output_bundle=configuration.output_directory / "output.json", | ||
successful=False, | ||
) | ||
|
||
with open(configuration.output_directory / "output.json", "w") as fh: | ||
json.dump(({"count": self._count}), fh) | ||
annual_mean_global_mean_timeseries = calculate_annual_mean_timeseries(trigger.dataset) | ||
|
||
return MetricResult( | ||
output_bundle=configuration.output_directory / "output.json", | ||
successful=True, | ||
return MetricResult.build( | ||
configuration, format_cmec_output_bundle(annual_mean_global_mean_timeseries) | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.