climate-ref-esmvaltool 0.6.6__py3-none-any.whl → 0.7.0__py3-none-any.whl

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.
Files changed (22) hide show
  1. climate_ref_esmvaltool/diagnostics/base.py +74 -44
  2. climate_ref_esmvaltool/diagnostics/climate_at_global_warming_levels.py +37 -14
  3. climate_ref_esmvaltool/diagnostics/climate_drivers_for_fire.py +37 -15
  4. climate_ref_esmvaltool/diagnostics/cloud_radiative_effects.py +24 -18
  5. climate_ref_esmvaltool/diagnostics/cloud_scatterplots.py +19 -7
  6. climate_ref_esmvaltool/diagnostics/ecs.py +23 -2
  7. climate_ref_esmvaltool/diagnostics/enso.py +78 -8
  8. climate_ref_esmvaltool/diagnostics/example.py +11 -10
  9. climate_ref_esmvaltool/diagnostics/regional_historical_changes.py +116 -21
  10. climate_ref_esmvaltool/diagnostics/sea_ice_area_basic.py +58 -3
  11. climate_ref_esmvaltool/diagnostics/sea_ice_sensitivity.py +26 -12
  12. climate_ref_esmvaltool/diagnostics/tcr.py +14 -1
  13. climate_ref_esmvaltool/diagnostics/tcre.py +8 -10
  14. climate_ref_esmvaltool/diagnostics/zec.py +15 -1
  15. climate_ref_esmvaltool/recipe.py +9 -5
  16. {climate_ref_esmvaltool-0.6.6.dist-info → climate_ref_esmvaltool-0.7.0.dist-info}/METADATA +1 -1
  17. climate_ref_esmvaltool-0.7.0.dist-info/RECORD +30 -0
  18. climate_ref_esmvaltool-0.6.6.dist-info/RECORD +0 -30
  19. {climate_ref_esmvaltool-0.6.6.dist-info → climate_ref_esmvaltool-0.7.0.dist-info}/WHEEL +0 -0
  20. {climate_ref_esmvaltool-0.6.6.dist-info → climate_ref_esmvaltool-0.7.0.dist-info}/entry_points.txt +0 -0
  21. {climate_ref_esmvaltool-0.6.6.dist-info → climate_ref_esmvaltool-0.7.0.dist-info}/licenses/LICENCE +0 -0
  22. {climate_ref_esmvaltool-0.6.6.dist-info → climate_ref_esmvaltool-0.7.0.dist-info}/licenses/NOTICE +0 -0
@@ -17,28 +17,29 @@ class GlobalMeanTimeseries(ESMValToolDiagnostic):
17
17
  name = "Global Mean Timeseries"
18
18
  slug = "global-mean-timeseries"
19
19
  base_recipe = "examples/recipe_python.yml"
20
- series = (
21
- SeriesDefinition(
22
- file_pattern="timeseries/script1/*.nc",
23
- dimensions={},
24
- values_name="tas",
25
- index_name="time",
26
- attributes=[],
27
- ),
28
- )
29
20
 
30
21
  data_requirements = (
31
22
  DataRequirement(
32
23
  source_type=SourceDatasetType.CMIP6,
33
24
  filters=(FacetFilter(facets={"variable_id": ("tas",)}),),
34
- group_by=("instance_id",),
25
+ group_by=("source_id", "experiment_id", "member_id", "table_id", "variable_id", "grid_label"),
35
26
  constraints=(
36
27
  RequireContiguousTimerange(group_by=("instance_id",)),
37
28
  AddSupplementaryDataset.from_defaults("areacella", SourceDatasetType.CMIP6),
38
29
  ),
39
30
  ),
40
31
  )
32
+
41
33
  facets = ()
34
+ series = (
35
+ SeriesDefinition(
36
+ file_pattern="timeseries/script1/*.nc",
37
+ dimensions={"statistic": "tas annual global mean"},
38
+ values_name="tas",
39
+ index_name="time",
40
+ attributes=[],
41
+ ),
42
+ )
42
43
 
43
44
  @staticmethod
44
45
  def update_recipe(
@@ -7,8 +7,9 @@ import xarray
7
7
 
8
8
  from climate_ref_core.constraints import (
9
9
  AddSupplementaryDataset,
10
- RequireContiguousTimerange,
10
+ PartialDateTime,
11
11
  RequireFacets,
12
+ RequireTimerange,
12
13
  )
13
14
  from climate_ref_core.datasets import ExecutionDatasetCollection, FacetFilter, SourceDatasetType
14
15
  from climate_ref_core.diagnostics import DataRequirement
@@ -102,18 +103,6 @@ class RegionalHistoricalAnnualCycle(ESMValToolDiagnostic):
102
103
  "tas",
103
104
  "ua",
104
105
  )
105
- series = tuple(
106
- SeriesDefinition(
107
- file_pattern=f"anncyc-{region}/allplots/*_{var_name}_*.nc",
108
- sel={"dim0": 0}, # Select the model and not the observation.
109
- dimensions={"region": region},
110
- values_name=var_name,
111
- index_name="month_number",
112
- attributes=[],
113
- )
114
- for var_name in variables
115
- for region in REGIONS
116
- )
117
106
 
118
107
  data_requirements = (
119
108
  DataRequirement(
@@ -123,14 +112,18 @@ class RegionalHistoricalAnnualCycle(ESMValToolDiagnostic):
123
112
  facets={
124
113
  "variable_id": variables,
125
114
  "experiment_id": "historical",
126
- "frequency": "mon",
115
+ "table_id": "Amon",
127
116
  },
128
117
  ),
129
118
  ),
130
119
  group_by=("source_id", "member_id", "grid_label"),
131
120
  constraints=(
121
+ RequireTimerange(
122
+ group_by=("instance_id",),
123
+ start=PartialDateTime(1980, 1),
124
+ end=PartialDateTime(2009, 12),
125
+ ),
132
126
  RequireFacets("variable_id", variables),
133
- RequireContiguousTimerange(group_by=("instance_id",)),
134
127
  AddSupplementaryDataset.from_defaults("areacella", SourceDatasetType.CMIP6),
135
128
  ),
136
129
  ),
@@ -149,7 +142,14 @@ class RegionalHistoricalAnnualCycle(ESMValToolDiagnostic):
149
142
  ),
150
143
  ),
151
144
  group_by=("source_id",),
152
- constraints=(RequireContiguousTimerange(group_by=("instance_id",)),),
145
+ constraints=(
146
+ RequireTimerange(
147
+ group_by=("instance_id",),
148
+ start=PartialDateTime(1980, 1),
149
+ end=PartialDateTime(2009, 12),
150
+ ),
151
+ RequireFacets("variable_id", ("psl", "ua")),
152
+ ),
153
153
  # TODO: Add obs4MIPs datasets once available and working:
154
154
  #
155
155
  # obs4MIPs dataset that cannot be ingested (https://github.com/Climate-REF/climate-ref/issues/260):
@@ -160,7 +160,20 @@ class RegionalHistoricalAnnualCycle(ESMValToolDiagnostic):
160
160
  # - HadCRUT5_ground_5.0.1.0-analysis: tas
161
161
  ),
162
162
  )
163
+
163
164
  facets = ()
165
+ series = tuple(
166
+ SeriesDefinition(
167
+ file_pattern=f"anncyc-{region}/allplots/*_{var_name}_*.nc",
168
+ sel={"dim0": 0}, # Select the model and not the observation.
169
+ dimensions={"region": region, "statistic": f"{var_name} regional mean"},
170
+ values_name=var_name,
171
+ index_name="month_number",
172
+ attributes=[],
173
+ )
174
+ for var_name in variables
175
+ for region in REGIONS
176
+ )
164
177
 
165
178
  @staticmethod
166
179
  def update_recipe(
@@ -211,16 +224,88 @@ class RegionalHistoricalTimeSeries(RegionalHistoricalAnnualCycle):
211
224
  name = "Regional historical mean and anomaly of climate variables"
212
225
  slug = "regional-historical-timeseries"
213
226
  base_recipe = "ref/recipe_ref_timeseries_region.yml"
227
+
228
+ variables = (
229
+ "hus",
230
+ "pr",
231
+ "psl",
232
+ "tas",
233
+ "ua",
234
+ )
235
+
236
+ data_requirements = (
237
+ DataRequirement(
238
+ source_type=SourceDatasetType.CMIP6,
239
+ filters=(
240
+ FacetFilter(
241
+ facets={
242
+ "variable_id": variables,
243
+ "experiment_id": "historical",
244
+ "table_id": "Amon",
245
+ },
246
+ ),
247
+ ),
248
+ group_by=("source_id", "member_id", "grid_label"),
249
+ constraints=(
250
+ RequireTimerange(
251
+ group_by=("instance_id",),
252
+ start=PartialDateTime(1980, 1),
253
+ end=PartialDateTime(2014, 12),
254
+ ),
255
+ RequireFacets("variable_id", variables),
256
+ AddSupplementaryDataset.from_defaults("areacella", SourceDatasetType.CMIP6),
257
+ ),
258
+ ),
259
+ DataRequirement(
260
+ source_type=SourceDatasetType.obs4MIPs,
261
+ filters=(
262
+ FacetFilter(
263
+ facets={
264
+ "variable_id": (
265
+ "psl",
266
+ "ua",
267
+ ),
268
+ "source_id": "ERA-5",
269
+ "frequency": "mon",
270
+ },
271
+ ),
272
+ ),
273
+ group_by=("source_id",),
274
+ constraints=(
275
+ RequireTimerange(
276
+ group_by=("instance_id",),
277
+ start=PartialDateTime(1980, 1),
278
+ end=PartialDateTime(2014, 12),
279
+ ),
280
+ ),
281
+ # TODO: Add obs4MIPs datasets once available and working:
282
+ #
283
+ # obs4MIPs dataset that cannot be ingested (https://github.com/Climate-REF/climate-ref/issues/260):
284
+ # - GPCP-V2.3: pr
285
+ #
286
+ # Not yet available on obs4MIPs:
287
+ # - ERA5: hus
288
+ # - HadCRUT5_ground_5.0.1.0-analysis: tas
289
+ ),
290
+ )
291
+
214
292
  series = tuple(
215
293
  SeriesDefinition(
216
294
  file_pattern=f"{diagnostic}-{region}/allplots/*_{var_name}_*.nc",
217
295
  sel={"dim0": 0}, # Select the model and not the observation.
218
- dimensions={"region": region},
296
+ dimensions={
297
+ "region": region,
298
+ "statistic": (
299
+ f"{var_name} regional mean"
300
+ if diagnostic == "timeseries_abs"
301
+ else f"{var_name} regional mean anomaly"
302
+ ),
303
+ },
219
304
  values_name=var_name,
220
305
  index_name="time",
221
306
  attributes=[],
222
307
  )
223
- for var_name in RegionalHistoricalAnnualCycle.variables
308
+ for var_name in variables
224
309
  for region in REGIONS
225
310
  for diagnostic in ["timeseries_abs", "timeseries"]
226
311
  )
@@ -249,13 +334,17 @@ class RegionalHistoricalTrend(ESMValToolDiagnostic):
249
334
  "ua",
250
335
  ),
251
336
  "experiment_id": "historical",
252
- "frequency": "mon",
337
+ "table_id": "Amon",
253
338
  },
254
339
  ),
255
340
  ),
256
341
  group_by=("source_id", "member_id", "grid_label"),
257
342
  constraints=(
258
- RequireContiguousTimerange(group_by=("instance_id",)),
343
+ RequireTimerange(
344
+ group_by=("instance_id",),
345
+ start=PartialDateTime(1980, 1),
346
+ end=PartialDateTime(2009, 12),
347
+ ),
259
348
  AddSupplementaryDataset.from_defaults("areacella", SourceDatasetType.CMIP6),
260
349
  ),
261
350
  ),
@@ -275,7 +364,13 @@ class RegionalHistoricalTrend(ESMValToolDiagnostic):
275
364
  ),
276
365
  ),
277
366
  group_by=("source_id",),
278
- constraints=(RequireContiguousTimerange(group_by=("instance_id",)),),
367
+ constraints=(
368
+ RequireTimerange(
369
+ group_by=("instance_id",),
370
+ start=PartialDateTime(1980, 1),
371
+ end=PartialDateTime(2009, 12),
372
+ ),
373
+ ),
279
374
  # TODO: Add obs4MIPs datasets once available and working:
280
375
  #
281
376
  # obs4MIPs dataset that cannot be ingested (https://github.com/Climate-REF/climate-ref/issues/260):
@@ -2,10 +2,13 @@ import pandas
2
2
 
3
3
  from climate_ref_core.constraints import (
4
4
  AddSupplementaryDataset,
5
- RequireContiguousTimerange,
5
+ PartialDateTime,
6
+ RequireFacets,
7
+ RequireTimerange,
6
8
  )
7
9
  from climate_ref_core.datasets import FacetFilter, SourceDatasetType
8
10
  from climate_ref_core.diagnostics import DataRequirement
11
+ from climate_ref_core.metric_values.typing import SeriesDefinition
9
12
  from climate_ref_esmvaltool.diagnostics.base import ESMValToolDiagnostic
10
13
  from climate_ref_esmvaltool.recipe import dataframe_to_recipe
11
14
  from climate_ref_esmvaltool.types import Recipe
@@ -28,18 +31,70 @@ class SeaIceAreaBasic(ESMValToolDiagnostic):
28
31
  facets={
29
32
  "variable_id": "siconc",
30
33
  "experiment_id": "historical",
34
+ "table_id": "SImon",
31
35
  },
32
36
  ),
33
37
  ),
34
- group_by=("instance_id",),
38
+ group_by=("source_id", "member_id", "grid_label"),
35
39
  constraints=(
36
- RequireContiguousTimerange(group_by=("instance_id",)),
40
+ RequireTimerange(
41
+ group_by=("instance_id",),
42
+ start=PartialDateTime(1979, 1),
43
+ end=PartialDateTime(2014, 12),
44
+ ),
37
45
  AddSupplementaryDataset.from_defaults("areacello", SourceDatasetType.CMIP6),
46
+ RequireFacets("variable_id", ("siconc", "areacello")),
38
47
  ),
39
48
  ),
40
49
  # TODO: Use OSI-450-nh and OSI-450-sh from obs4MIPs once available.
41
50
  )
42
51
  facets = ()
52
+ series = (
53
+ SeriesDefinition(
54
+ file_pattern="siarea_min/allplots/timeseries_sea_ice_area_nh_*.nc",
55
+ sel={"dim0": 0}, # Select the model and not the observations.
56
+ dimensions={
57
+ "region": "Northern Hemisphere",
58
+ "statistic": "September sea ice area",
59
+ },
60
+ values_name="siconc",
61
+ index_name="time",
62
+ attributes=[],
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
+ },
71
+ values_name="siconc",
72
+ index_name="time",
73
+ attributes=[],
74
+ ),
75
+ SeriesDefinition(
76
+ file_pattern="siarea_seas/allplots/annual_cycle_sea_ice_area_nh_*.nc",
77
+ sel={"dim0": 0}, # Select the model and not the observations.
78
+ dimensions={
79
+ "region": "Northern Hemisphere",
80
+ "statistic": "20-year average seasonal cycle of the sea ice area",
81
+ },
82
+ values_name="siconc",
83
+ index_name="month_number",
84
+ attributes=[],
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
+ },
93
+ values_name="siconc",
94
+ index_name="month_number",
95
+ attributes=[],
96
+ ),
97
+ )
43
98
 
44
99
  @staticmethod
45
100
  def update_recipe(
@@ -5,8 +5,9 @@ import pandas as pd
5
5
 
6
6
  from climate_ref_core.constraints import (
7
7
  AddSupplementaryDataset,
8
- RequireContiguousTimerange,
8
+ PartialDateTime,
9
9
  RequireFacets,
10
+ RequireTimerange,
10
11
  )
11
12
  from climate_ref_core.datasets import ExecutionDatasetCollection, FacetFilter, SourceDatasetType
12
13
  from climate_ref_core.diagnostics import DataRequirement
@@ -26,31 +27,44 @@ class SeaIceSensitivity(ESMValToolDiagnostic):
26
27
  slug = "sea-ice-sensitivity"
27
28
  base_recipe = "recipe_seaice_sensitivity.yml"
28
29
 
29
- variables = (
30
- "siconc",
31
- "tas",
32
- )
33
-
34
30
  data_requirements = (
35
31
  DataRequirement(
36
32
  source_type=SourceDatasetType.CMIP6,
37
33
  filters=(
38
34
  FacetFilter(
39
35
  facets={
40
- "variable_id": variables,
36
+ "variable_id": "siconc",
37
+ "experiment_id": "historical",
38
+ "table_id": "SImon",
39
+ },
40
+ ),
41
+ FacetFilter(
42
+ facets={
43
+ "variable_id": "tas",
41
44
  "experiment_id": "historical",
45
+ "table_id": "Amon",
42
46
  },
43
47
  ),
44
48
  ),
45
49
  group_by=("experiment_id",), # this does nothing, but group_by cannot be empty
46
50
  constraints=(
51
+ RequireTimerange(
52
+ group_by=("instance_id",),
53
+ start=PartialDateTime(1979, 1),
54
+ end=PartialDateTime(2014, 12),
55
+ ),
56
+ RequireFacets(
57
+ "variable_id",
58
+ required_facets=("siconc", "tas"),
59
+ group_by=("source_id", "member_id", "grid_label"),
60
+ ),
47
61
  AddSupplementaryDataset.from_defaults("areacella", SourceDatasetType.CMIP6),
48
62
  AddSupplementaryDataset.from_defaults("areacello", SourceDatasetType.CMIP6),
49
- RequireContiguousTimerange(group_by=("instance_id",)),
50
- RequireFacets("variable_id", variables),
51
- # TODO: Add a constraint to ensure that tas, siconc and areacello
52
- # are available for each model or alternatively filter out
53
- # incomplete models below.
63
+ RequireFacets(
64
+ "variable_id",
65
+ required_facets=("areacello",),
66
+ group_by=("source_id", "grid_label"),
67
+ ),
54
68
  ),
55
69
  ),
56
70
  )
@@ -11,6 +11,7 @@ from climate_ref_core.constraints import (
11
11
  )
12
12
  from climate_ref_core.datasets import ExecutionDatasetCollection, FacetFilter, SourceDatasetType
13
13
  from climate_ref_core.diagnostics import DataRequirement
14
+ from climate_ref_core.metric_values.typing import SeriesDefinition
14
15
  from climate_ref_core.pycmec.metric import CMECMetric, MetricCV
15
16
  from climate_ref_core.pycmec.output import CMECOutput
16
17
  from climate_ref_esmvaltool.diagnostics.base import ESMValToolDiagnostic
@@ -39,19 +40,31 @@ class TransientClimateResponse(ESMValToolDiagnostic):
39
40
  facets={
40
41
  "variable_id": ("tas",),
41
42
  "experiment_id": experiments,
43
+ "table_id": "Amon",
42
44
  },
43
45
  ),
44
46
  ),
45
47
  group_by=("source_id", "member_id", "grid_label"),
46
48
  constraints=(
47
- RequireFacets("experiment_id", experiments),
48
49
  RequireContiguousTimerange(group_by=("instance_id",)),
49
50
  RequireOverlappingTimerange(group_by=("instance_id",)),
51
+ RequireFacets("experiment_id", experiments),
50
52
  AddSupplementaryDataset.from_defaults("areacella", SourceDatasetType.CMIP6),
51
53
  ),
52
54
  ),
53
55
  )
54
56
  facets = ("grid_label", "member_id", "source_id", "region", "metric")
57
+ series = (
58
+ SeriesDefinition(
59
+ file_pattern="tcr/calculate/{source_id}*.nc",
60
+ dimensions={
61
+ "statistic": "global annual mean tas anomaly relative to linear fit of piControl run",
62
+ },
63
+ values_name="tas_anomaly",
64
+ index_name="time",
65
+ attributes=[],
66
+ ),
67
+ )
55
68
 
56
69
  @staticmethod
57
70
  def update_recipe(
@@ -27,10 +27,6 @@ class TransientClimateResponseEmissions(ESMValToolDiagnostic):
27
27
  slug = "transient-climate-response-emissions"
28
28
  base_recipe = "recipe_tcre.yml"
29
29
 
30
- experiments = (
31
- "esm-1pctCO2",
32
- "esm-piControl",
33
- )
34
30
  variables = (
35
31
  "tas",
36
32
  "fco2antt",
@@ -42,29 +38,31 @@ class TransientClimateResponseEmissions(ESMValToolDiagnostic):
42
38
  FacetFilter(
43
39
  facets={
44
40
  "variable_id": variables,
45
- "frequency": "mon",
46
- "experiment_id": experiments,
41
+ "experiment_id": "esm-1pctCO2",
42
+ "table_id": "Amon",
47
43
  },
48
44
  ),
49
45
  FacetFilter(
50
46
  facets={
51
- "variable_id": "fco2antt",
47
+ "variable_id": "tas",
52
48
  "experiment_id": "esm-piControl",
49
+ "table_id": "Amon",
53
50
  },
54
- keep=False,
55
51
  ),
56
52
  ),
57
53
  group_by=("source_id", "member_id", "grid_label"),
58
54
  constraints=(
59
- RequireFacets("experiment_id", experiments),
60
- RequireFacets("variable_id", variables),
61
55
  RequireContiguousTimerange(group_by=("instance_id",)),
62
56
  RequireOverlappingTimerange(group_by=("instance_id",)),
57
+ RequireFacets("experiment_id", ("esm-1pctCO2", "esm-piControl")),
58
+ RequireFacets("variable_id", variables),
63
59
  AddSupplementaryDataset.from_defaults("areacella", SourceDatasetType.CMIP6),
64
60
  ),
65
61
  ),
66
62
  )
67
63
  facets = ("grid_label", "member_id", "source_id", "region", "metric")
64
+ # TODO: the ESMValTool diagnostic script does not save the data for the timeseries.
65
+ series = tuple()
68
66
 
69
67
  @staticmethod
70
68
  def update_recipe(
@@ -11,6 +11,7 @@ from climate_ref_core.constraints import (
11
11
  )
12
12
  from climate_ref_core.datasets import ExecutionDatasetCollection, FacetFilter, SourceDatasetType
13
13
  from climate_ref_core.diagnostics import DataRequirement
14
+ from climate_ref_core.metric_values.typing import SeriesDefinition
14
15
  from climate_ref_core.pycmec.metric import CMECMetric, MetricCV
15
16
  from climate_ref_core.pycmec.output import CMECOutput
16
17
  from climate_ref_esmvaltool.diagnostics.base import ESMValToolDiagnostic
@@ -39,19 +40,32 @@ class ZeroEmissionCommitment(ESMValToolDiagnostic):
39
40
  facets={
40
41
  "variable_id": ("tas",),
41
42
  "experiment_id": experiments,
43
+ "table_id": "Amon",
42
44
  },
43
45
  ),
44
46
  ),
45
47
  group_by=("source_id", "member_id", "grid_label"),
46
48
  constraints=(
47
- RequireFacets("experiment_id", experiments),
48
49
  RequireContiguousTimerange(group_by=("instance_id",)),
49
50
  RequireOverlappingTimerange(group_by=("instance_id",)),
51
+ RequireFacets("experiment_id", experiments),
50
52
  AddSupplementaryDataset.from_defaults("areacella", SourceDatasetType.CMIP6),
51
53
  ),
52
54
  ),
53
55
  )
54
56
  facets = ("grid_label", "member_id", "source_id", "region", "metric")
57
+ series = (
58
+ SeriesDefinition(
59
+ file_pattern="work/zec/zec/zec.nc",
60
+ sel={"dim0": 0},
61
+ dimensions={
62
+ "statistic": "zec",
63
+ },
64
+ values_name="zec",
65
+ index_name="time",
66
+ attributes=[],
67
+ ),
68
+ )
55
69
 
56
70
  @staticmethod
57
71
  def update_recipe(
@@ -87,11 +87,11 @@ def as_facets(
87
87
 
88
88
  """
89
89
  facets = {}
90
- first_row = group.iloc[0]
91
- project = first_row.instance_id.split(".", 2)[0]
90
+ project = group.iloc[0].instance_id.split(".", 2)[0]
92
91
  facets["project"] = project
93
92
  for esmvaltool_name, ref_name in FACETS[project].items():
94
- facets[esmvaltool_name] = getattr(first_row, ref_name)
93
+ values = group[ref_name].unique().tolist()
94
+ facets[esmvaltool_name] = values if len(values) > 1 else values[0]
95
95
  timerange = as_timerange(group)
96
96
  if timerange is not None:
97
97
  facets["timerange"] = timerange
@@ -100,6 +100,7 @@ def as_facets(
100
100
 
101
101
  def dataframe_to_recipe(
102
102
  files: pd.DataFrame,
103
+ group_by: tuple[str, ...] = ("instance_id",),
103
104
  equalize_timerange: bool = False,
104
105
  ) -> dict[str, Any]:
105
106
  """Convert the datasets dataframe to a recipe "variables" section.
@@ -108,14 +109,17 @@ def dataframe_to_recipe(
108
109
  ----------
109
110
  files
110
111
  The pandas dataframe describing the input files.
112
+ group_by
113
+ The columns to group the input files by.
114
+ equalize_timerange
115
+ If True, use the timerange that is covered by all datasets.
111
116
 
112
117
  Returns
113
118
  -------
114
119
  A "variables" section that can be used in an ESMValTool recipe.
115
120
  """
116
121
  variables: dict[str, Any] = {}
117
- # TODO: refine to make it possible to combine historical and scenario runs.
118
- for _, group in files.groupby("instance_id"):
122
+ for _, group in files.groupby(list(group_by)):
119
123
  facets = as_facets(group)
120
124
  short_name = facets.pop("short_name")
121
125
  if short_name not in variables:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: climate-ref-esmvaltool
3
- Version: 0.6.6
3
+ Version: 0.7.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
@@ -0,0 +1,30 @@
1
+ climate_ref_esmvaltool/__init__.py,sha256=4WHuuZJvK50Djb831ws_Y2EtFLWicwsLIxhOvRld2BE,994
2
+ climate_ref_esmvaltool/_version.py,sha256=Ed7geC_W9fxIocCdAvK1fk2k-pDt6FGOM_LEgR06-24,94
3
+ climate_ref_esmvaltool/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ climate_ref_esmvaltool/recipe.py,sha256=elf_LnZaqXzMnOsh87Kp75SqdmeqFOrcZfDE2lj-bl0,6722
5
+ climate_ref_esmvaltool/recipes.txt,sha256=X8yzdTW-TDJH5j-kJ5aq57ztZ6uvFItelVflJcTNEjs,1744
6
+ climate_ref_esmvaltool/types.py,sha256=luUMNS3LJGJEecVrHRDh5l5ElnQgz7G0auCtA_Jwnno,117
7
+ climate_ref_esmvaltool/dataset_registry/data.txt,sha256=aD5lg5x9O1mn2e9ueKefxmuBGH2OED1sqSdoeLrnIBk,24339
8
+ climate_ref_esmvaltool/diagnostics/__init__.py,sha256=GRCsqpp9XY3p9nWQII05IhfzKSSwAoTQ0vc21mlPEbo,2022
9
+ climate_ref_esmvaltool/diagnostics/base.py,sha256=gpSsVgoTV9e4oDk_WqeQf_B1DY6alWr-Q8weFxX7d7w,11886
10
+ climate_ref_esmvaltool/diagnostics/climate_at_global_warming_levels.py,sha256=hL-aXHjJZKIilUqORBu-LjOe_GYBemszkZlqJuF64rg,4136
11
+ climate_ref_esmvaltool/diagnostics/climate_drivers_for_fire.py,sha256=CadaNKAUNv7MeUNAP-4betQluAXyMTOZJx9OW7h2SwI,3041
12
+ climate_ref_esmvaltool/diagnostics/cloud_radiative_effects.py,sha256=PYxjKb035C-Va7GhHBRQVFtpY4UhzFchqHorLaoSHvU,2939
13
+ climate_ref_esmvaltool/diagnostics/cloud_scatterplots.py,sha256=XKTI6WQZALK_2k2IQIz4xcxnOHQ3I5SjscxRac7tFAY,7460
14
+ climate_ref_esmvaltool/diagnostics/ecs.py,sha256=pf39QPDIBb-d6bq7Q-L2F_rAFCmfhxrR4su6TFregQQ,5594
15
+ climate_ref_esmvaltool/diagnostics/enso.py,sha256=rselisSc-TK7rs7r1fZlhuhzCMn2ZtzhH6nXStIH95c,8265
16
+ climate_ref_esmvaltool/diagnostics/example.py,sha256=-6nsJnRJJx4E1ZHlAe_MRbdJdVSoKviPdSQgYyrVwDA,2453
17
+ climate_ref_esmvaltool/diagnostics/regional_historical_changes.py,sha256=UlGx-mdXbnJhNxC3u84g_B2v1nSi4hKHyWWHhY4WTdE,15254
18
+ climate_ref_esmvaltool/diagnostics/sea_ice_area_basic.py,sha256=lmkEvMeewkYtPALejoZ_doW5Z21cVPtEhSoIuSQGvng,5433
19
+ climate_ref_esmvaltool/diagnostics/sea_ice_sensitivity.py,sha256=F0UnoWScbBtVzgC7iMvxGMZIQDPa6uu5Oj05BIP_T0U,4790
20
+ climate_ref_esmvaltool/diagnostics/tcr.py,sha256=CUBiewN4Mnby_J8whfjD2UGI2WizQF-__FIV8DNcuWs,4663
21
+ climate_ref_esmvaltool/diagnostics/tcre.py,sha256=DHXMjvSxWszSbyvPtR46p83eSUXnUPTMgaKNMjWm8vo,5526
22
+ climate_ref_esmvaltool/diagnostics/zec.py,sha256=IvrUDX2DKF48yer482vhZ1wIRg6QRae7GfQfDvlwB8g,4409
23
+ climate_ref_esmvaltool/requirements/conda-lock.yml,sha256=XPQEC3mUJ7Yyr-UaFtbBaceA2pPP22f7JtOTmO1dBDY,596683
24
+ climate_ref_esmvaltool/requirements/environment.yml,sha256=9yDKJyQpOgNx1hbjuncjrqCjTZJ4EhGXmP7fBCI1tyI,88
25
+ climate_ref_esmvaltool-0.7.0.dist-info/METADATA,sha256=4jr4-PSMErXkzwRimg8h71ZThx-kh3eVVScEAk4YXg0,2414
26
+ climate_ref_esmvaltool-0.7.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
27
+ climate_ref_esmvaltool-0.7.0.dist-info/entry_points.txt,sha256=zhPwPv0Fu67MgdOCF8GAilZUHa9wl4T4xlkQ3HX4Sno,69
28
+ climate_ref_esmvaltool-0.7.0.dist-info/licenses/LICENCE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
29
+ climate_ref_esmvaltool-0.7.0.dist-info/licenses/NOTICE,sha256=4qTlax9aX2-mswYJuVrLqJ9jK1IkN5kSBqfVvYLF3Ws,128
30
+ climate_ref_esmvaltool-0.7.0.dist-info/RECORD,,
@@ -1,30 +0,0 @@
1
- climate_ref_esmvaltool/__init__.py,sha256=4WHuuZJvK50Djb831ws_Y2EtFLWicwsLIxhOvRld2BE,994
2
- climate_ref_esmvaltool/_version.py,sha256=Ed7geC_W9fxIocCdAvK1fk2k-pDt6FGOM_LEgR06-24,94
3
- climate_ref_esmvaltool/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- climate_ref_esmvaltool/recipe.py,sha256=m8-wWVRla2VRzkZWx2M-Okjvr0X2wUon0ZgXHcTALcw,6561
5
- climate_ref_esmvaltool/recipes.txt,sha256=X8yzdTW-TDJH5j-kJ5aq57ztZ6uvFItelVflJcTNEjs,1744
6
- climate_ref_esmvaltool/types.py,sha256=luUMNS3LJGJEecVrHRDh5l5ElnQgz7G0auCtA_Jwnno,117
7
- climate_ref_esmvaltool/dataset_registry/data.txt,sha256=aD5lg5x9O1mn2e9ueKefxmuBGH2OED1sqSdoeLrnIBk,24339
8
- climate_ref_esmvaltool/diagnostics/__init__.py,sha256=GRCsqpp9XY3p9nWQII05IhfzKSSwAoTQ0vc21mlPEbo,2022
9
- climate_ref_esmvaltool/diagnostics/base.py,sha256=nfNviO8pAftm_OlwNMzJ2cb2bb7_QaTNO-UmEfUPf6Q,10917
10
- climate_ref_esmvaltool/diagnostics/climate_at_global_warming_levels.py,sha256=mkA6WHR_GIdnYwjsaoRbWIgc4nAYD2wtgwmJ7JCsYoM,3605
11
- climate_ref_esmvaltool/diagnostics/climate_drivers_for_fire.py,sha256=CatVUeVixzeGHITJrZfa47cICI79uKxOZ9tYIK4CLKw,2198
12
- climate_ref_esmvaltool/diagnostics/cloud_radiative_effects.py,sha256=hmncLzKwZh5zTXUJb_08AVQa6JJqofKIdpdZ1RdAxTk,2865
13
- climate_ref_esmvaltool/diagnostics/cloud_scatterplots.py,sha256=TKjaQWGWx495IVH8LXGCf0OuDJk37oI0vH7c81Savgc,7169
14
- climate_ref_esmvaltool/diagnostics/ecs.py,sha256=c1VsowWSJKU0PbZR1dpQnkWSWSr2o3aUK3AGTMsGa30,4818
15
- climate_ref_esmvaltool/diagnostics/enso.py,sha256=LfaXbf0VRe14stfWXNv7OwfBEVTI7XDpmYtgIos3Dzw,5505
16
- climate_ref_esmvaltool/diagnostics/example.py,sha256=uJUBmJ9g0OBI_y8JKyH_tAV9BKC6P1Sjc2L31n03I6g,2347
17
- climate_ref_esmvaltool/diagnostics/regional_historical_changes.py,sha256=dBy-sVGCcgqKzugw5ZaF2KlsTym7QTmpR4lcF_ahS1E,12279
18
- climate_ref_esmvaltool/diagnostics/sea_ice_area_basic.py,sha256=95DL1PZfB2JoQSloh9cyLb_qeiUBSItxGC4QX5uJcRE,3253
19
- climate_ref_esmvaltool/diagnostics/sea_ice_sensitivity.py,sha256=-70cmXEi2sM6wFxUiP4sGZCGf9TrR1cvFM-8j5yeo-4,4267
20
- climate_ref_esmvaltool/diagnostics/tcr.py,sha256=MhhGMPXfkEh-IEOPNYcS2G-SgFMGkfp-FRu0TRk2jZI,4196
21
- climate_ref_esmvaltool/diagnostics/tcre.py,sha256=KiByhNnf2aicO9ysEwPvwA-VTWmo_bSKn-Za8IH8DcE,5461
22
- climate_ref_esmvaltool/diagnostics/zec.py,sha256=UvtKbzdgdREmCFH5_OIftGSrClEytbiI2q_VK5cNOfU,3998
23
- climate_ref_esmvaltool/requirements/conda-lock.yml,sha256=XPQEC3mUJ7Yyr-UaFtbBaceA2pPP22f7JtOTmO1dBDY,596683
24
- climate_ref_esmvaltool/requirements/environment.yml,sha256=9yDKJyQpOgNx1hbjuncjrqCjTZJ4EhGXmP7fBCI1tyI,88
25
- climate_ref_esmvaltool-0.6.6.dist-info/METADATA,sha256=vHod-PQNao0QkHepPatnA2QhwFydzOIQxJLYd83lqQg,2414
26
- climate_ref_esmvaltool-0.6.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
27
- climate_ref_esmvaltool-0.6.6.dist-info/entry_points.txt,sha256=zhPwPv0Fu67MgdOCF8GAilZUHa9wl4T4xlkQ3HX4Sno,69
28
- climate_ref_esmvaltool-0.6.6.dist-info/licenses/LICENCE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
29
- climate_ref_esmvaltool-0.6.6.dist-info/licenses/NOTICE,sha256=4qTlax9aX2-mswYJuVrLqJ9jK1IkN5kSBqfVvYLF3Ws,128
30
- climate_ref_esmvaltool-0.6.6.dist-info/RECORD,,