climate-ref-esmvaltool 0.7.0__tar.gz → 0.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/PKG-INFO +2 -1
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/pyproject.toml +2 -1
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/diagnostics/base.py +19 -2
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/diagnostics/cloud_radiative_effects.py +15 -2
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/diagnostics/ecs.py +3 -3
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/diagnostics/enso.py +46 -26
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/diagnostics/regional_historical_changes.py +32 -12
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/diagnostics/sea_ice_area_basic.py +36 -37
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/diagnostics/tcr.py +2 -2
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/diagnostics/tcre.py +2 -2
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/diagnostics/zec.py +2 -2
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/.gitignore +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/LICENCE +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/NOTICE +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/README.md +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/__init__.py +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/_version.py +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/dataset_registry/data.txt +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/diagnostics/__init__.py +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/diagnostics/climate_at_global_warming_levels.py +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/diagnostics/climate_drivers_for_fire.py +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/diagnostics/cloud_scatterplots.py +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/diagnostics/example.py +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/diagnostics/sea_ice_sensitivity.py +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/py.typed +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/recipe.py +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/recipes.txt +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/requirements/conda-lock.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/requirements/environment.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/types.py +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/integration/test_diagnostics.py +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_climate_at_global_warming_levels.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_climate_drivers_for_fire.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_cloud_radiative_effects.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_cloud_scatterplots_cli_ta.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_cloud_scatterplots_clivi_lwcre.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_cloud_scatterplots_clt_swcre.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_cloud_scatterplots_clwvi_pr.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_cloud_scatterplots_reference.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_enso_basic_climatology.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_enso_characteristics.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_equilibrium_climate_sensitivity.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_global_mean_timeseries.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_regional_historical_annual_cycle.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_regional_historical_timeseries.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_regional_historical_trend.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_sea_ice_area_basic.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_sea_ice_sensitivity.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_transient_climate_response.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_transient_climate_response_emissions.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/recipes/recipe_zero_emission_commitment.yml +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/test_base.py +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/test_recipes.py +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/test_diagnostic.py +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/test_provider.py +0 -0
- {climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/test_recipe.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: climate-ref-esmvaltool
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: ESMValTool diagnostic provider for the Rapid Evaluation Framework
|
|
5
5
|
Author-email: ESMValTool development team <esmvaltool-dev@listserv.dfn.de>, Jared Lewis <jared.lewis@climate-resource.com>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -19,6 +19,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
19
19
|
Classifier: Topic :: Scientific/Engineering
|
|
20
20
|
Requires-Python: >=3.11
|
|
21
21
|
Requires-Dist: climate-ref-core
|
|
22
|
+
Requires-Dist: netcdf4>=1.7.2
|
|
22
23
|
Requires-Dist: pooch>=1.8
|
|
23
24
|
Requires-Dist: pyyaml
|
|
24
25
|
Requires-Dist: xarray>=2023.3.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "climate-ref-esmvaltool"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.8.0"
|
|
4
4
|
description = "ESMValTool diagnostic provider for the Rapid Evaluation Framework"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
authors = [
|
|
@@ -24,6 +24,7 @@ classifiers = [
|
|
|
24
24
|
]
|
|
25
25
|
dependencies = [
|
|
26
26
|
"climate-ref-core",
|
|
27
|
+
"netcdf4>=1.7.2",
|
|
27
28
|
"pooch >= 1.8",
|
|
28
29
|
"pyyaml",
|
|
29
30
|
"xarray >= 2023.3.0",
|
|
@@ -4,6 +4,8 @@ from collections.abc import Iterable
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from typing import ClassVar
|
|
6
6
|
|
|
7
|
+
import netCDF4
|
|
8
|
+
import numpy as np
|
|
7
9
|
import pandas
|
|
8
10
|
import xarray as xr
|
|
9
11
|
import yaml
|
|
@@ -23,6 +25,18 @@ from climate_ref_esmvaltool.recipe import load_recipe, prepare_climate_data
|
|
|
23
25
|
from climate_ref_esmvaltool.types import MetricBundleArgs, OutputBundleArgs, Recipe
|
|
24
26
|
|
|
25
27
|
|
|
28
|
+
def mask_fillvalues(array: np.ndarray) -> np.ma.MaskedArray: # type: ignore[type-arg]
|
|
29
|
+
"""Convert netCDF4 fill values in an array to a mask."""
|
|
30
|
+
# Workaround for https://github.com/pydata/xarray/issues/2742
|
|
31
|
+
defaults = {np.dtype(k): v for k, v in netCDF4.default_fillvals.items()}
|
|
32
|
+
return np.ma.masked_equal(array, defaults[array.dtype]) # type: ignore[no-untyped-call,no-any-return]
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def fillvalues_to_nan(array: np.ndarray) -> np.ndarray: # type: ignore[type-arg]
|
|
36
|
+
"""Convert netCDF4 fill values in an array to NaN."""
|
|
37
|
+
return mask_fillvalues(array).filled(np.nan) # type: ignore[no-untyped-call,no-any-return]
|
|
38
|
+
|
|
39
|
+
|
|
26
40
|
class ESMValToolDiagnostic(CommandLineDiagnostic):
|
|
27
41
|
"""ESMValTool Diagnostic base class."""
|
|
28
42
|
|
|
@@ -213,7 +227,9 @@ class ESMValToolDiagnostic(CommandLineDiagnostic):
|
|
|
213
227
|
# Add the plots and data files
|
|
214
228
|
series = []
|
|
215
229
|
plot_suffixes = {".png", ".jpg", ".pdf", ".ps"}
|
|
216
|
-
for
|
|
230
|
+
# Sort metadata files for stable processing
|
|
231
|
+
metadata_files = sorted(result_dir.glob("run/*/*/diagnostic_provenance.yml"))
|
|
232
|
+
for metadata_file in metadata_files:
|
|
217
233
|
metadata = yaml.safe_load(metadata_file.read_text(encoding="utf-8"))
|
|
218
234
|
for filename in metadata:
|
|
219
235
|
caption = metadata[filename].get("caption", "")
|
|
@@ -300,6 +316,7 @@ class ESMValToolDiagnostic(CommandLineDiagnostic):
|
|
|
300
316
|
attributes[f"value_{attr}"] = dataset[series_def.values_name].attrs[attr]
|
|
301
317
|
if attr in dataset[series_def.index_name].attrs:
|
|
302
318
|
attributes[f"index_{attr}"] = dataset[series_def.index_name].attrs[attr]
|
|
319
|
+
# TODO: Handle masked values in the index
|
|
303
320
|
index = dataset[series_def.index_name].values.tolist()
|
|
304
321
|
if hasattr(index[0], "calendar"):
|
|
305
322
|
attributes["calendar"] = index[0].calendar
|
|
@@ -310,7 +327,7 @@ class ESMValToolDiagnostic(CommandLineDiagnostic):
|
|
|
310
327
|
series.append(
|
|
311
328
|
SeriesMetricValue(
|
|
312
329
|
dimensions={**input_selectors, **series_def.dimensions},
|
|
313
|
-
values=dataset[series_def.values_name].values.tolist(),
|
|
330
|
+
values=fillvalues_to_nan(dataset[series_def.values_name].values).tolist(),
|
|
314
331
|
index=index,
|
|
315
332
|
index_name=series_def.index_name,
|
|
316
333
|
attributes=attributes,
|
|
@@ -61,13 +61,26 @@ class CloudRadiativeEffects(ESMValToolDiagnostic):
|
|
|
61
61
|
series = tuple(
|
|
62
62
|
SeriesDefinition(
|
|
63
63
|
file_pattern=f"plot_profiles/plot/variable_vs_lat_{var_name}_*.nc",
|
|
64
|
-
sel={"dim0": 0}, # Select the model
|
|
65
|
-
dimensions={"statistic":
|
|
64
|
+
sel={"dim0": 0}, # Select the model.
|
|
65
|
+
dimensions={"variable_id": var_name, "statistic": "zonal mean"},
|
|
66
66
|
values_name=var_name,
|
|
67
67
|
index_name="lat",
|
|
68
68
|
attributes=[],
|
|
69
69
|
)
|
|
70
70
|
for var_name in ["lwcre", "swcre"]
|
|
71
|
+
) + tuple(
|
|
72
|
+
SeriesDefinition(
|
|
73
|
+
file_pattern=f"plot_profiles/plot/variable_vs_lat_{var_name}_*.nc",
|
|
74
|
+
sel={"dim0": i}, # Select the observation.
|
|
75
|
+
dimensions={"variable_id": var_name, "statistic": "zonal mean", "reference_source_id": source_id},
|
|
76
|
+
values_name=var_name,
|
|
77
|
+
index_name="lat",
|
|
78
|
+
attributes=[],
|
|
79
|
+
)
|
|
80
|
+
for var_name in ["lwcre", "swcre"]
|
|
81
|
+
for i, source_id in enumerate(
|
|
82
|
+
["CERES-EBAF-Ed4.2", "ESACCI-CLOUD-AVHRR-AMPM-fv3.0", "ISCCP-FH"], start=1
|
|
83
|
+
)
|
|
71
84
|
)
|
|
72
85
|
|
|
73
86
|
@staticmethod
|
|
@@ -14,7 +14,7 @@ from climate_ref_core.diagnostics import DataRequirement
|
|
|
14
14
|
from climate_ref_core.metric_values.typing import SeriesDefinition
|
|
15
15
|
from climate_ref_core.pycmec.metric import CMECMetric, MetricCV
|
|
16
16
|
from climate_ref_core.pycmec.output import CMECOutput
|
|
17
|
-
from climate_ref_esmvaltool.diagnostics.base import ESMValToolDiagnostic
|
|
17
|
+
from climate_ref_esmvaltool.diagnostics.base import ESMValToolDiagnostic, fillvalues_to_nan
|
|
18
18
|
from climate_ref_esmvaltool.recipe import dataframe_to_recipe
|
|
19
19
|
from climate_ref_esmvaltool.types import MetricBundleArgs, OutputBundleArgs, Recipe
|
|
20
20
|
|
|
@@ -139,9 +139,9 @@ class EquilibriumClimateSensitivity(ESMValToolDiagnostic):
|
|
|
139
139
|
) -> tuple[CMECMetric, CMECOutput]:
|
|
140
140
|
"""Format the result."""
|
|
141
141
|
ecs_ds = xarray.open_dataset(result_dir / "work" / "ecs" / "calculate" / "ecs.nc")
|
|
142
|
-
ecs = float(ecs_ds["ecs"].values[0])
|
|
142
|
+
ecs = float(fillvalues_to_nan(ecs_ds["ecs"].values)[0])
|
|
143
143
|
lambda_ds = xarray.open_dataset(result_dir / "work" / "ecs" / "calculate" / "lambda.nc")
|
|
144
|
-
lambda_ = float(lambda_ds["lambda"].values[0])
|
|
144
|
+
lambda_ = float(fillvalues_to_nan(lambda_ds["lambda"].values)[0])
|
|
145
145
|
|
|
146
146
|
# Update the diagnostic bundle arguments with the computed diagnostics.
|
|
147
147
|
metric_args[MetricCV.DIMENSIONS.value] = {
|
|
@@ -67,55 +67,75 @@ class ENSOBasicClimatology(ESMValToolDiagnostic):
|
|
|
67
67
|
series = (
|
|
68
68
|
tuple(
|
|
69
69
|
SeriesDefinition(
|
|
70
|
-
file_pattern=f"diagnostic_metrics/plot_script/{
|
|
71
|
-
dimensions=
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
70
|
+
file_pattern=f"diagnostic_metrics/plot_script/{source_id}_eq_{var_name}_bias.nc",
|
|
71
|
+
dimensions=(
|
|
72
|
+
{
|
|
73
|
+
"statistic": (
|
|
74
|
+
f"zonal bias in the time-mean {var_name} structure across the equatorial Pacific"
|
|
75
|
+
),
|
|
76
|
+
}
|
|
77
|
+
| ({} if source_id == "{source_id}" else {"reference_source_id": source_id})
|
|
78
|
+
),
|
|
76
79
|
values_name="tos" if var_name == "sst" else var_name,
|
|
77
80
|
index_name="lon",
|
|
78
81
|
attributes=[],
|
|
79
82
|
)
|
|
80
|
-
for var_name in
|
|
83
|
+
for var_name in ("pr", "sst", "tauu")
|
|
84
|
+
for source_id in ("{source_id}", "GPCP-V2.3", "TROPFLUX")
|
|
81
85
|
)
|
|
82
86
|
+ tuple(
|
|
83
87
|
SeriesDefinition(
|
|
84
88
|
file_pattern=f"diagnostic_metrics/plot_script/{{source_id}}_eq_{var_name}_seacycle.nc",
|
|
85
|
-
dimensions=
|
|
86
|
-
|
|
87
|
-
"
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
dimensions=(
|
|
90
|
+
{
|
|
91
|
+
"statistic": (
|
|
92
|
+
"zonal bias in the amplitude of the mean seasonal cycle of "
|
|
93
|
+
f"{var_name} in the equatorial Pacific"
|
|
94
|
+
),
|
|
95
|
+
}
|
|
96
|
+
| ({} if source_id == "{source_id}" else {"reference_source_id": source_id})
|
|
97
|
+
),
|
|
91
98
|
values_name="tos" if var_name == "sst" else var_name,
|
|
92
99
|
index_name="lon",
|
|
93
100
|
attributes=[],
|
|
94
101
|
)
|
|
95
|
-
for var_name in
|
|
102
|
+
for var_name in ("pr", "sst", "tauu")
|
|
103
|
+
for source_id in ("{source_id}", "GPCP-V2.3", "TROPFLUX")
|
|
96
104
|
)
|
|
97
|
-
+ (
|
|
105
|
+
+ tuple(
|
|
98
106
|
SeriesDefinition(
|
|
99
107
|
file_pattern="diagnostic_metrics/plot_script/{source_id}_pr_double.nc",
|
|
100
|
-
dimensions=
|
|
101
|
-
|
|
102
|
-
|
|
108
|
+
dimensions=(
|
|
109
|
+
{
|
|
110
|
+
"statistic": (
|
|
111
|
+
"meridional bias in the time-mean pr structure across the eastern Pacific"
|
|
112
|
+
),
|
|
113
|
+
}
|
|
114
|
+
| ({} if source_id == "{source_id}" else {"reference_source_id": source_id})
|
|
115
|
+
),
|
|
103
116
|
values_name="pr",
|
|
104
117
|
index_name="lat",
|
|
105
118
|
attributes=[],
|
|
106
|
-
)
|
|
119
|
+
)
|
|
120
|
+
for source_id in ("{source_id}", "GPCP-V2.3")
|
|
121
|
+
)
|
|
122
|
+
+ tuple(
|
|
107
123
|
SeriesDefinition(
|
|
108
124
|
file_pattern="diagnostic_metrics/plot_script/*_pr_double_seacycle.nc",
|
|
109
|
-
dimensions=
|
|
110
|
-
|
|
111
|
-
"
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
125
|
+
dimensions=(
|
|
126
|
+
{
|
|
127
|
+
"statistic": (
|
|
128
|
+
"meridional bias in the amplitude of the mean seasonal "
|
|
129
|
+
"pr cycle in the eastern Pacific"
|
|
130
|
+
),
|
|
131
|
+
}
|
|
132
|
+
| ({} if source_id == "{source_id}" else {"reference_source_id": source_id})
|
|
133
|
+
),
|
|
115
134
|
values_name="pr",
|
|
116
135
|
index_name="lat",
|
|
117
136
|
attributes=[],
|
|
118
|
-
)
|
|
137
|
+
)
|
|
138
|
+
for source_id in ("{source_id}", "GPCP-V2.3")
|
|
119
139
|
)
|
|
120
140
|
)
|
|
121
141
|
|
|
@@ -16,7 +16,7 @@ from climate_ref_core.diagnostics import DataRequirement
|
|
|
16
16
|
from climate_ref_core.metric_values.typing import SeriesDefinition
|
|
17
17
|
from climate_ref_core.pycmec.metric import CMECMetric, MetricCV
|
|
18
18
|
from climate_ref_core.pycmec.output import CMECOutput
|
|
19
|
-
from climate_ref_esmvaltool.diagnostics.base import ESMValToolDiagnostic
|
|
19
|
+
from climate_ref_esmvaltool.diagnostics.base import ESMValToolDiagnostic, fillvalues_to_nan
|
|
20
20
|
from climate_ref_esmvaltool.recipe import dataframe_to_recipe
|
|
21
21
|
from climate_ref_esmvaltool.types import MetricBundleArgs, OutputBundleArgs, Recipe
|
|
22
22
|
|
|
@@ -87,6 +87,15 @@ def normalize_region(region: str) -> str:
|
|
|
87
87
|
return region.replace("&", "-and-").replace("/", "-and-")
|
|
88
88
|
|
|
89
89
|
|
|
90
|
+
REFERENCE_DATASETS = {
|
|
91
|
+
"hus": "ERA-5",
|
|
92
|
+
"pr": "GPCP-V2.3",
|
|
93
|
+
"psl": "ERA-5",
|
|
94
|
+
"tas": "HadCRUT5-5.0.1.0-analysis",
|
|
95
|
+
"ua": "ERA-5",
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
|
|
90
99
|
class RegionalHistoricalAnnualCycle(ESMValToolDiagnostic):
|
|
91
100
|
"""
|
|
92
101
|
Plot regional historical annual cycle of climate variables.
|
|
@@ -166,13 +175,21 @@ class RegionalHistoricalAnnualCycle(ESMValToolDiagnostic):
|
|
|
166
175
|
SeriesDefinition(
|
|
167
176
|
file_pattern=f"anncyc-{region}/allplots/*_{var_name}_*.nc",
|
|
168
177
|
sel={"dim0": 0}, # Select the model and not the observation.
|
|
169
|
-
dimensions=
|
|
178
|
+
dimensions=(
|
|
179
|
+
{
|
|
180
|
+
"region": region,
|
|
181
|
+
"variable_id": var_name,
|
|
182
|
+
"statistic": "mean",
|
|
183
|
+
}
|
|
184
|
+
| ({} if i == 0 else {"reference_source_id": REFERENCE_DATASETS[var_name]})
|
|
185
|
+
),
|
|
170
186
|
values_name=var_name,
|
|
171
187
|
index_name="month_number",
|
|
172
188
|
attributes=[],
|
|
173
189
|
)
|
|
174
190
|
for var_name in variables
|
|
175
191
|
for region in REGIONS
|
|
192
|
+
for i in range(2)
|
|
176
193
|
)
|
|
177
194
|
|
|
178
195
|
@staticmethod
|
|
@@ -292,15 +309,15 @@ class RegionalHistoricalTimeSeries(RegionalHistoricalAnnualCycle):
|
|
|
292
309
|
series = tuple(
|
|
293
310
|
SeriesDefinition(
|
|
294
311
|
file_pattern=f"{diagnostic}-{region}/allplots/*_{var_name}_*.nc",
|
|
295
|
-
sel={"dim0":
|
|
296
|
-
dimensions=
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
if diagnostic == "timeseries_abs"
|
|
301
|
-
|
|
302
|
-
)
|
|
303
|
-
|
|
312
|
+
sel={"dim0": i},
|
|
313
|
+
dimensions=(
|
|
314
|
+
{
|
|
315
|
+
"region": region,
|
|
316
|
+
"variable_id": var_name,
|
|
317
|
+
"statistic": ("mean" if diagnostic == "timeseries_abs" else "mean anomaly"),
|
|
318
|
+
}
|
|
319
|
+
| ({} if i == 0 else {"reference_source_id": REFERENCE_DATASETS[var_name]})
|
|
320
|
+
),
|
|
304
321
|
values_name=var_name,
|
|
305
322
|
index_name="time",
|
|
306
323
|
attributes=[],
|
|
@@ -308,6 +325,7 @@ class RegionalHistoricalTimeSeries(RegionalHistoricalAnnualCycle):
|
|
|
308
325
|
for var_name in variables
|
|
309
326
|
for region in REGIONS
|
|
310
327
|
for diagnostic in ["timeseries_abs", "timeseries"]
|
|
328
|
+
for i in range(2)
|
|
311
329
|
)
|
|
312
330
|
|
|
313
331
|
|
|
@@ -425,7 +443,9 @@ class RegionalHistoricalTrend(ESMValToolDiagnostic):
|
|
|
425
443
|
variable_id = next(iter(ds.data_vars.keys()))
|
|
426
444
|
metric_args[MetricCV.DIMENSIONS.value]["variable_id"][variable_id] = {}
|
|
427
445
|
metric_args[MetricCV.RESULTS.value][variable_id] = {}
|
|
428
|
-
for region_value, trend_value in zip(
|
|
446
|
+
for region_value, trend_value in zip(
|
|
447
|
+
ds.shape_id.astype(str).values, fillvalues_to_nan(ds[variable_id].values)
|
|
448
|
+
):
|
|
429
449
|
region = region_value.strip()
|
|
430
450
|
trend = float(trend_value)
|
|
431
451
|
if region not in metric_args[MetricCV.DIMENSIONS.value]["region"]:
|
|
@@ -13,6 +13,16 @@ from climate_ref_esmvaltool.diagnostics.base import ESMValToolDiagnostic
|
|
|
13
13
|
from climate_ref_esmvaltool.recipe import dataframe_to_recipe
|
|
14
14
|
from climate_ref_esmvaltool.types import Recipe
|
|
15
15
|
|
|
16
|
+
REGIONS = {
|
|
17
|
+
"nh": "Northern Hemisphere",
|
|
18
|
+
"sh": "Southern Hemisphere",
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
MONTHS = {
|
|
22
|
+
"nh": "September",
|
|
23
|
+
"sh": "February",
|
|
24
|
+
}
|
|
25
|
+
|
|
16
26
|
|
|
17
27
|
class SeaIceAreaBasic(ESMValToolDiagnostic):
|
|
18
28
|
"""
|
|
@@ -49,51 +59,40 @@ class SeaIceAreaBasic(ESMValToolDiagnostic):
|
|
|
49
59
|
# TODO: Use OSI-450-nh and OSI-450-sh from obs4MIPs once available.
|
|
50
60
|
)
|
|
51
61
|
facets = ()
|
|
52
|
-
series = (
|
|
62
|
+
series = tuple(
|
|
53
63
|
SeriesDefinition(
|
|
54
|
-
file_pattern="siarea_min/allplots/
|
|
55
|
-
sel={"dim0":
|
|
56
|
-
dimensions=
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
),
|
|
64
|
-
SeriesDefinition(
|
|
65
|
-
file_pattern="siarea_min/allplots/timeseries_sea_ice_area_sh_*.nc",
|
|
66
|
-
sel={"dim0": 0}, # Select the model and not the observations.
|
|
67
|
-
dimensions={
|
|
68
|
-
"region": "Southern Hemisphere",
|
|
69
|
-
"statistic": "February sea ice area",
|
|
70
|
-
},
|
|
64
|
+
file_pattern=f"siarea_min/allplots/timeseries_sea_ice_area_{region}_*.nc",
|
|
65
|
+
sel={"dim0": i},
|
|
66
|
+
dimensions=(
|
|
67
|
+
{
|
|
68
|
+
"region": REGIONS[region],
|
|
69
|
+
"statistic": f"{MONTHS[region]} sea ice area",
|
|
70
|
+
}
|
|
71
|
+
| ({} if i == 0 else {"reference_source_id": f"OSI-450-{region}"})
|
|
72
|
+
),
|
|
71
73
|
values_name="siconc",
|
|
72
74
|
index_name="time",
|
|
73
75
|
attributes=[],
|
|
74
|
-
)
|
|
76
|
+
)
|
|
77
|
+
for region in REGIONS
|
|
78
|
+
for i in range(2)
|
|
79
|
+
) + tuple(
|
|
75
80
|
SeriesDefinition(
|
|
76
|
-
file_pattern="siarea_seas/allplots/
|
|
77
|
-
sel={"dim0":
|
|
78
|
-
dimensions=
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
),
|
|
86
|
-
SeriesDefinition(
|
|
87
|
-
file_pattern="siarea_seas/allplots/annual_cycle_sea_ice_area_sh_*.nc",
|
|
88
|
-
sel={"dim0": 0}, # Select the model and not the observations.
|
|
89
|
-
dimensions={
|
|
90
|
-
"region": "Southern Hemisphere",
|
|
91
|
-
"statistic": "20-year average seasonal cycle of the sea ice area,",
|
|
92
|
-
},
|
|
81
|
+
file_pattern=f"siarea_seas/allplots/annual_cycle_sea_ice_area_{region}_*.nc",
|
|
82
|
+
sel={"dim0": i},
|
|
83
|
+
dimensions=(
|
|
84
|
+
{
|
|
85
|
+
"region": REGIONS[region],
|
|
86
|
+
"statistic": "20-year average seasonal cycle of the sea ice area",
|
|
87
|
+
}
|
|
88
|
+
| ({} if i == 0 else {"reference_source_id": f"OSI-450-{region}"})
|
|
89
|
+
),
|
|
93
90
|
values_name="siconc",
|
|
94
91
|
index_name="month_number",
|
|
95
92
|
attributes=[],
|
|
96
|
-
)
|
|
93
|
+
)
|
|
94
|
+
for region in REGIONS
|
|
95
|
+
for i in range(2)
|
|
97
96
|
)
|
|
98
97
|
|
|
99
98
|
@staticmethod
|
|
@@ -14,7 +14,7 @@ from climate_ref_core.diagnostics import DataRequirement
|
|
|
14
14
|
from climate_ref_core.metric_values.typing import SeriesDefinition
|
|
15
15
|
from climate_ref_core.pycmec.metric import CMECMetric, MetricCV
|
|
16
16
|
from climate_ref_core.pycmec.output import CMECOutput
|
|
17
|
-
from climate_ref_esmvaltool.diagnostics.base import ESMValToolDiagnostic
|
|
17
|
+
from climate_ref_esmvaltool.diagnostics.base import ESMValToolDiagnostic, fillvalues_to_nan
|
|
18
18
|
from climate_ref_esmvaltool.recipe import dataframe_to_recipe
|
|
19
19
|
from climate_ref_esmvaltool.types import MetricBundleArgs, OutputBundleArgs, Recipe
|
|
20
20
|
|
|
@@ -117,7 +117,7 @@ class TransientClimateResponse(ESMValToolDiagnostic):
|
|
|
117
117
|
) -> tuple[CMECMetric, CMECOutput]:
|
|
118
118
|
"""Format the result."""
|
|
119
119
|
tcr_ds = xarray.open_dataset(result_dir / "work" / "tcr" / "calculate" / "tcr.nc")
|
|
120
|
-
tcr = float(tcr_ds["tcr"].values[0])
|
|
120
|
+
tcr = float(fillvalues_to_nan(tcr_ds["tcr"].values)[0])
|
|
121
121
|
|
|
122
122
|
# Update the diagnostic bundle arguments with the computed diagnostics.
|
|
123
123
|
metric_args[MetricCV.DIMENSIONS.value] = {
|
|
@@ -13,7 +13,7 @@ from climate_ref_core.datasets import ExecutionDatasetCollection, FacetFilter, S
|
|
|
13
13
|
from climate_ref_core.diagnostics import DataRequirement
|
|
14
14
|
from climate_ref_core.pycmec.metric import CMECMetric, MetricCV
|
|
15
15
|
from climate_ref_core.pycmec.output import CMECOutput
|
|
16
|
-
from climate_ref_esmvaltool.diagnostics.base import ESMValToolDiagnostic
|
|
16
|
+
from climate_ref_esmvaltool.diagnostics.base import ESMValToolDiagnostic, fillvalues_to_nan
|
|
17
17
|
from climate_ref_esmvaltool.recipe import dataframe_to_recipe
|
|
18
18
|
from climate_ref_esmvaltool.types import MetricBundleArgs, OutputBundleArgs, Recipe
|
|
19
19
|
|
|
@@ -123,7 +123,7 @@ class TransientClimateResponseEmissions(ESMValToolDiagnostic):
|
|
|
123
123
|
) -> tuple[CMECMetric, CMECOutput]:
|
|
124
124
|
"""Format the result."""
|
|
125
125
|
tcre_ds = xarray.open_dataset(result_dir / "work" / "tcre" / "calculate_tcre" / "tcre.nc")
|
|
126
|
-
tcre = float(tcre_ds["tcre"].values[0])
|
|
126
|
+
tcre = float(fillvalues_to_nan(tcre_ds["tcre"].values)[0])
|
|
127
127
|
|
|
128
128
|
# Update the diagnostic bundle arguments with the computed diagnostics.
|
|
129
129
|
metric_args[MetricCV.DIMENSIONS.value] = {
|
|
@@ -14,7 +14,7 @@ from climate_ref_core.diagnostics import DataRequirement
|
|
|
14
14
|
from climate_ref_core.metric_values.typing import SeriesDefinition
|
|
15
15
|
from climate_ref_core.pycmec.metric import CMECMetric, MetricCV
|
|
16
16
|
from climate_ref_core.pycmec.output import CMECOutput
|
|
17
|
-
from climate_ref_esmvaltool.diagnostics.base import ESMValToolDiagnostic
|
|
17
|
+
from climate_ref_esmvaltool.diagnostics.base import ESMValToolDiagnostic, fillvalues_to_nan
|
|
18
18
|
from climate_ref_esmvaltool.recipe import dataframe_to_recipe
|
|
19
19
|
from climate_ref_esmvaltool.types import MetricBundleArgs, OutputBundleArgs, Recipe
|
|
20
20
|
|
|
@@ -104,7 +104,7 @@ class ZeroEmissionCommitment(ESMValToolDiagnostic):
|
|
|
104
104
|
) -> tuple[CMECMetric, CMECOutput]:
|
|
105
105
|
"""Format the result."""
|
|
106
106
|
zec_ds = xarray.open_dataset(result_dir / "work" / "zec" / "zec" / "zec_50.nc")
|
|
107
|
-
zec = float(zec_ds["zec"].values[0])
|
|
107
|
+
zec = float(fillvalues_to_nan(zec_ds["zec"].values)[0])
|
|
108
108
|
|
|
109
109
|
# Update the diagnostic bundle arguments with the computed diagnostics.
|
|
110
110
|
metric_args[MetricCV.DIMENSIONS.value] = {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/__init__.py
RENAMED
|
File without changes
|
{climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/_version.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/py.typed
RENAMED
|
File without changes
|
{climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/recipe.py
RENAMED
|
File without changes
|
{climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/recipes.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/src/climate_ref_esmvaltool/types.py
RENAMED
|
File without changes
|
{climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/integration/test_diagnostics.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/test_base.py
RENAMED
|
File without changes
|
{climate_ref_esmvaltool-0.7.0 → climate_ref_esmvaltool-0.8.0}/tests/unit/diagnostics/test_recipes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|