Skip to content

Commit 754e696

Browse files
authored
Merge pull request #208 from bouweandela/add-tcre
Add TCRE metric
2 parents 4b1f31e + ba900ea commit 754e696

7 files changed

Lines changed: 719 additions & 3 deletions

File tree

changelog/208.feature.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added Transient Climate Response to Cumulative CO2 Emissions (TCRE) metric to the ESMValTool metrics package.

packages/ref-metrics-esmvaltool/src/cmip_ref_metrics_esmvaltool/metrics/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
from cmip_ref_metrics_esmvaltool.metrics.ecs import EquilibriumClimateSensitivity
44
from cmip_ref_metrics_esmvaltool.metrics.example import GlobalMeanTimeseries
55
from cmip_ref_metrics_esmvaltool.metrics.tcr import TransientClimateResponse
6+
from cmip_ref_metrics_esmvaltool.metrics.tcre import TransientClimateResponseEmissions
67

78
__all__ = [
89
"EquilibriumClimateSensitivity",
910
"GlobalMeanTimeseries",
1011
"TransientClimateResponse",
12+
"TransientClimateResponseEmissions",
1113
]
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
from pathlib import Path
2+
3+
import pandas
4+
import xarray
5+
6+
from cmip_ref_core.constraints import (
7+
AddSupplementaryDataset,
8+
RequireContiguousTimerange,
9+
RequireFacets,
10+
RequireOverlappingTimerange,
11+
)
12+
from cmip_ref_core.datasets import FacetFilter, SourceDatasetType
13+
from cmip_ref_core.metrics import DataRequirement
14+
from cmip_ref_metrics_esmvaltool.metrics.base import ESMValToolMetric
15+
from cmip_ref_metrics_esmvaltool.recipe import dataframe_to_recipe
16+
from cmip_ref_metrics_esmvaltool.types import OutputBundle, Recipe
17+
18+
19+
class TransientClimateResponseEmissions(ESMValToolMetric):
20+
"""
21+
Calculate the global mean Transient Climate Response to Cumulative CO2 Emissions.
22+
"""
23+
24+
name = "Transient Climate Response to Cumulative CO2 Emissions"
25+
slug = "esmvaltool-transient-climate-response-emissions"
26+
base_recipe = "recipe_tcre.yml"
27+
28+
experiments = (
29+
"esm-1pctCO2",
30+
"esm-piControl",
31+
)
32+
variables = (
33+
"tas",
34+
"fco2antt",
35+
)
36+
data_requirements = (
37+
DataRequirement(
38+
source_type=SourceDatasetType.CMIP6,
39+
filters=(
40+
FacetFilter(
41+
facets={
42+
"variable_id": variables,
43+
"frequency": "mon",
44+
"experiment_id": experiments,
45+
},
46+
),
47+
FacetFilter(
48+
facets={
49+
"variable_id": "fco2antt",
50+
"experiment_id": "esm-piControl",
51+
},
52+
keep=False,
53+
),
54+
),
55+
group_by=("source_id", "member_id", "grid_label"),
56+
constraints=(
57+
RequireFacets("experiment_id", experiments),
58+
RequireFacets("variable_id", variables),
59+
RequireContiguousTimerange(group_by=("instance_id",)),
60+
RequireOverlappingTimerange(group_by=("instance_id",)),
61+
AddSupplementaryDataset.from_defaults("areacella", SourceDatasetType.CMIP6),
62+
),
63+
),
64+
)
65+
66+
@staticmethod
67+
def update_recipe(recipe: Recipe, input_files: pandas.DataFrame) -> None:
68+
"""Update the recipe."""
69+
# Prepare updated datasets section in recipe. It contains three
70+
# datasets, "tas" and "fco2antt" for the "esm-1pctCO2" and just "tas"
71+
# for the "esm-piControl" experiment.
72+
recipe_variables = dataframe_to_recipe(input_files)
73+
tas_esm_1pctCO2 = next(
74+
ds for ds in recipe_variables["tas"]["additional_datasets"] if ds["exp"] == "esm-1pctCO2"
75+
)
76+
fco2antt_esm_1pctCO2 = next(
77+
ds for ds in recipe_variables["fco2antt"]["additional_datasets"] if ds["exp"] == "esm-1pctCO2"
78+
)
79+
tas_esm_piControl = next(
80+
ds for ds in recipe_variables["tas"]["additional_datasets"] if ds["exp"] == "esm-piControl"
81+
)
82+
tas_esm_piControl["timerange"] = tas_esm_1pctCO2["timerange"]
83+
84+
recipe["diagnostics"]["tcre"]["variables"] = {
85+
"tas_esm-1pctCO2": {
86+
"short_name": "tas",
87+
"preprocessor": "global_annual_mean_anomaly",
88+
"additional_datasets": [tas_esm_1pctCO2],
89+
},
90+
"tas_esm-piControl": {
91+
"short_name": "tas",
92+
"preprocessor": "global_annual_mean_anomaly",
93+
"additional_datasets": [tas_esm_piControl],
94+
},
95+
"fco2antt": {
96+
"preprocessor": "global_cumulative_sum",
97+
"additional_datasets": [fco2antt_esm_1pctCO2],
98+
},
99+
}
100+
recipe["diagnostics"].pop("barplot")
101+
102+
@staticmethod
103+
def format_result(result_dir: Path) -> OutputBundle:
104+
"""Format the result."""
105+
tcre_file = result_dir / "work/tcre/calculate_tcre/tcre.nc"
106+
tcre = xarray.open_dataset(tcre_file)
107+
108+
source_id = tcre.dataset.values[0].decode("utf-8")
109+
cmec_output = {
110+
"DIMENSIONS": {
111+
"model": {source_id: {}},
112+
"region": {"global": {}},
113+
"metric": {"tcre": {}},
114+
"json_structure": [
115+
"model",
116+
"region",
117+
"metric",
118+
],
119+
},
120+
"RESULTS": {
121+
source_id: {"global": {"tcre": float(tcre.tcre.values[0])}},
122+
},
123+
}
124+
125+
return cmec_output

packages/ref-metrics-esmvaltool/src/cmip_ref_metrics_esmvaltool/recipe.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,15 @@ def dataframe_to_recipe(files: pd.DataFrame) -> dict[str, Any]:
113113
return variables
114114

115115

116-
_ESMVALTOOL_VERSION = "2.11.0"
116+
_ESMVALTOOL_VERSION = "2.13.0.dev10+g7883d411e"
117+
_ESMVALTOOL_COMMIT = _ESMVALTOOL_VERSION.split("+")[1][1:]
117118

118119
_RECIPES = pooch.create(
119120
path=pooch.os_cache("cmip_ref_metrics_esmvaltool"),
120-
base_url="https://raw.githubusercontent.com/ESMValGroup/ESMValTool/refs/tags/v{version}/esmvaltool/recipes/",
121-
version=_ESMVALTOOL_VERSION,
121+
# TODO: use a released version
122+
# base_url="https://raw.githubusercontent.com/ESMValGroup/ESMValTool/refs/tags/v{version}/esmvaltool/recipes/",
123+
# version=_ESMVALTOOL_VERSION,
124+
base_url=f"https://raw.githubusercontent.com/ESMValGroup/ESMValTool/{_ESMVALTOOL_COMMIT}/esmvaltool/recipes/",
122125
env="REF_METRICS_ESMVALTOOL_DATA_DIR",
123126
)
124127
_RECIPES.load_registry(importlib.resources.open_binary("cmip_ref_metrics_esmvaltool", "recipes.txt"))
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
examples/recipe_python.yml ab3f06d269bb2c1368f4dc39da9bcb232fb2adb1fa556ba769e6c16294ffb4a3
22
recipe_ecs.yml 0cc57034fcb64e32015b4ff949ece5df8cdb8c6f493618b50ceded119fb37918
33
recipe_tcr.yml 35f9ef035a4e71aff5cac5dd26c49da2162fc00291bf3b0bd16b661b7b2f606b
4+
recipe_tcre.yml 4668e357e00c515a8264ac75cb319ce558289689e10189e6f9e982886c414c94

0 commit comments

Comments
 (0)