Skip to content

Commit 57b99ea

Browse files
jlenhschlunma
andauthored
Fix handling of the time coordinate in outputs of recipe_ref_fire.yml (#4538)
Co-authored-by: Manuel Schlund <32543114+schlunma@users.noreply.github.com>
1 parent aedc108 commit 57b99ea

3 files changed

Lines changed: 79 additions & 44 deletions

File tree

doc/sphinx/source/recipes/recipe_ref_fire.rst

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,22 +63,26 @@ User settings in recipe
6363

6464
*Required settings for script*
6565

66-
* var_order: list of climate drivers in the order corresponding to the one
66+
* `var_order`: list of climate drivers in the order corresponding to the one
6767
specified in the corresponding file from the confire_param directory.
6868

6969
*Optional settings for script*
7070

71-
* confire_param: path to the directory containing the required files to run
71+
* `confire_param`: path to the directory containing the required files to run
7272
the ConFire model or Zenodo URL to retrieve files from a Zenodo archive.
7373
If custom files are used, the corresponding directory needs to be present
7474
inside the auxiliary data directory defined inside the user configuration.
7575
This defaults to the original Zenodo archive otherwise.
76-
* remove_vpd_files: Removing or not the computed vapor pressure deficit files.
76+
* `remove_vpd_files`: Removing or not the computed vapor pressure deficit files.
7777
It will only apply if the vapor pressure deficit is part of var_order.
78-
This defaults to False.
79-
* remove_confire_files: Removing or not the files produced during the ConFire
78+
This defaults to `False`.
79+
* `remove_confire_files`: Removing or not the files produced during the ConFire
8080
model evaluation.
81-
This defaults to False.
81+
This defaults to `False`.
82+
* `keep_original_time`: Keeping or not the time coordinate (origin, calendar)
83+
from the input. If not, then it defaults to: unit
84+
`"days since 1850-01-01 00:00:00"` and calendar `"proleptic_gregorian"`.
85+
This defaults to `False`.
8286

8387
*Required settings for variables*
8488

esmvaltool/diag_scripts/fire/diagnostic_run_confire.py

Lines changed: 66 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -151,47 +151,57 @@ def _select_key_or_default(
151151

152152

153153
# /libs/iris_plus.py
154-
def _sort_time(
155-
cube: iris.cube.Cube,
156-
field: str,
157-
filename: str,
158-
) -> iris.cube.Cube:
159-
"""Sort time dimension in the iris cube.
154+
def make_sort_time_callback(*, keep_original_time: bool):
155+
"""Create a _sort_time callback with configurable time coordinate."""
160156

161-
Parameters
162-
----------
163-
cube: iris cube
164-
Input cube.
165-
field: str
166-
Variable name in cube.
167-
filename: str
168-
Filename of cube.
157+
def _sort_time(
158+
cube: iris.cube.Cube,
159+
field: str,
160+
filename: str,
161+
) -> iris.cube.Cube:
162+
"""Sort time dimension in the iris cube.
169163
170-
Returns
171-
-------
172-
cube: iris cube
173-
Cube with sorted and added time dimensions.
174-
"""
175-
logger.debug("Sorting time for variable %s in cube %s", field, filename)
176-
177-
cube.coord("time").bounds = None
178-
tcoord = cube.coord("time")
179-
tcoord.units = cf_units.Unit(tcoord.units.origin, calendar="gregorian")
180-
tcoord.convert_units("days since 1661-01-01 00:00:00")
181-
tcoord.units = cf_units.Unit(
182-
tcoord.units.origin,
183-
calendar="proleptic_gregorian",
184-
)
185-
cube.remove_coord("time")
186-
cube.add_dim_coord(tcoord, 0)
164+
Parameters
165+
----------
166+
cube: iris cube
167+
Input cube.
168+
field: str
169+
Variable name in cube.
170+
filename: str
171+
Filename of cube.
187172
188-
if not cube.coords("year"):
189-
iris.coord_categorisation.add_year(cube, "time")
173+
Returns
174+
-------
175+
cube: iris cube
176+
Cube with sorted and added time dimensions.
177+
"""
178+
logger.debug(
179+
"Sorting time for variable %s in cube %s",
180+
field,
181+
filename,
182+
)
183+
184+
cube.coord("time").bounds = None
185+
tcoord = cube.coord("time")
186+
if not keep_original_time:
187+
tcoord.units = cf_units.Unit(
188+
"days since 1850-01-01 00:00:00",
189+
calendar="proleptic_gregorian",
190+
)
191+
cube.remove_coord("time")
192+
cube.add_dim_coord(tcoord, 0)
193+
194+
if not cube.coords("month"):
195+
iris.coord_categorisation.add_month_number(
196+
cube,
197+
"time",
198+
name="month",
199+
)
190200

191-
if not cube.coords("month"):
192-
iris.coord_categorisation.add_month_number(cube, "time", name="month")
201+
if not cube.coords("year"):
202+
iris.coord_categorisation.add_year(cube, "time")
193203

194-
return cube
204+
return _sort_time
195205

196206

197207
def _insert_data_into_cube(
@@ -412,6 +422,7 @@ def _read_variable_from_netcdf(
412422
make_flat: bool = False,
413423
return_time_points: bool = False,
414424
return_extent: bool = False,
425+
keep_original_time: bool,
415426
verbose: bool = True,
416427
) -> iris.cube.Cube:
417428
"""Read data from a netCDF file.
@@ -440,6 +451,9 @@ def _read_variable_from_netcdf(
440451
time_series: list
441452
List comtaining range of years. If making flat and
442453
returned a time series, checks if that time series contains year.
454+
keep_original_time: bool
455+
If True, keep time coordinate from inputs, otherwise replace by
456+
Unit("days since 1850-01-01 00:00:00", calendar="proleptic_gregorian")
443457
444458
Returns
445459
-------
@@ -457,15 +471,19 @@ def _read_variable_from_netcdf(
457471
if isinstance(filename, str):
458472
dataset = iris.load_raw(
459473
Path(directory) / filename,
460-
callback=_sort_time,
474+
callback=make_sort_time_callback(
475+
keep_original_time=keep_original_time,
476+
),
461477
)
462478
else:
463479
# Fallback for CMIP7 data for tasmax
464480
var = "tas" if "tasmax/tas_tmaxavg" in filename[0] else filename[1]
465481
dataset = iris.load_raw(
466482
Path(directory) / filename[0],
467483
var,
468-
callback=_sort_time,
484+
callback=make_sort_time_callback(
485+
keep_original_time=keep_original_time,
486+
),
469487
)
470488
dataset = dataset[0]
471489

@@ -565,6 +583,7 @@ def _read_all_data_from_netcdf(
565583
add_1s_columne: bool = False,
566584
x_normalise01: bool = False,
567585
check_mask: bool = True,
586+
keep_original_time: bool,
568587
**kw: dict,
569588
) -> tuple[np.array]:
570589
"""Read data from netCDF files.
@@ -596,6 +615,9 @@ def _read_all_data_from_netcdf(
596615
you dont want. This could be different in some circumstances.
597616
frac_random_sample: int
598617
fraction of data to be returned
618+
keep_original_time: bool
619+
If True, keep time coordinate from inputs, otherwise replace by
620+
Unit("days since 1850-01-01 00:00:00", calendar="proleptic_gregorian")
599621
args: tuple
600622
See _read_variable_from_netcdf comments.
601623
kw: dict
@@ -615,6 +637,7 @@ def _read_all_data_from_netcdf(
615637
return_time_points=True,
616638
return_extent=True,
617639
verbose=False,
640+
keep_original_time=keep_original_time,
618641
**kw,
619642
)
620643

@@ -626,6 +649,7 @@ def _read_all_data_from_netcdf(
626649
time_points=time_points,
627650
extent=extent,
628651
verbose=False,
652+
keep_original_time=keep_original_time,
629653
**kw,
630654
)
631655

@@ -642,6 +666,7 @@ def _read_all_data_from_netcdf(
642666
make_flat=True,
643667
time_points=time_points,
644668
extent=extent,
669+
keep_original_time=keep_original_time,
645670
**kw,
646671
)
647672

@@ -880,6 +905,7 @@ def _get_parameters(config: dict) -> tuple:
880905
"""
881906
work_dir = config["work_dir"]
882907
confire_param = config["confire_param_dir"]
908+
keep_original_time = config["keep_original_time"]
883909
# **Define Paths for Parameter Files and for outputs**
884910
output_dir = work_dir + "/ConFire_outputs/"
885911
# Parameter files (traces, scalers, and other model parameters)
@@ -901,12 +927,14 @@ def _get_parameters(config: dict) -> tuple:
901927
x_filename_list=nc_files,
902928
scalers=scalers,
903929
directory=nc_dir,
930+
keep_original_time=keep_original_time,
904931
)
905932
# Load a sample cube (used for inserting data)
906933
eg_cube = _read_variable_from_netcdf(
907934
nc_files[0],
908935
directory=nc_dir,
909936
verbose=False,
937+
keep_original_time=keep_original_time,
910938
)
911939
# **Extract Model Parameters**
912940
logger.info("Loading ConFire model parameters...")

esmvaltool/diag_scripts/fire/fire_diagnostic.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,9 @@ def main(cfg: dict) -> None:
346346
# default is False
347347
if "remove_confire_files" not in cfg:
348348
cfg["remove_confire_files"] = False
349+
# Keeping or not the original time coordinates and calendar form the inputs
350+
# Default is False
351+
cfg.setdefault("keep_original_time", False)
349352

350353
for model_dataset, group in datasets.items():
351354
# 'model_dataset' is the name of the model dataset.

0 commit comments

Comments
 (0)