Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions esmvaltool/diag_scripts/fire/diagnostic_run_confire.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,7 @@ def _read_variable_from_netcdf(
make_flat: bool = False,
return_time_points: bool = False,
return_extent: bool = False,
verbose: bool = True,
) -> iris.cube.Cube:
"""Read data from a netCDF file.

Expand Down Expand Up @@ -446,8 +447,9 @@ def _read_variable_from_netcdf(
if make_flat, a numpy vector of the target variable, otherwise
returns iris cube.
"""
logger.info("Opening:")
logger.info(filename)
if verbose:
logger.info("Opening:")
logger.info(filename)

if filename[0] == "~" or filename[0] == "/" or filename[0] == ".":
directory = ""
Expand Down Expand Up @@ -612,6 +614,7 @@ def _read_all_data_from_netcdf(
make_flat=True,
return_time_points=True,
return_extent=True,
verbose=False,
**kw,
)

Expand All @@ -622,6 +625,7 @@ def _read_all_data_from_netcdf(
make_flat=True,
time_points=time_points,
extent=extent,
verbose=False,
**kw,
)

Expand Down Expand Up @@ -899,7 +903,11 @@ def _get_parameters(config: dict) -> tuple:
directory=nc_dir,
)
# Load a sample cube (used for inserting data)
eg_cube = _read_variable_from_netcdf(nc_files[0], directory=nc_dir)
eg_cube = _read_variable_from_netcdf(
nc_files[0],
directory=nc_dir,
verbose=False,
)
# **Extract Model Parameters**
logger.info("Loading ConFire model parameters...")
params, params_names = _select_post_param(param_file_trace)
Expand Down
57 changes: 38 additions & 19 deletions esmvaltool/diag_scripts/fire/fire_diagnostic.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,17 @@ def setup_basename_file(
) -> str:
"""Generate the file basename for a newly computed variable.

the filename of an ancestor variable is used as template.

Example: If the ancestor filename is
CMIP6_MPI-ESM1-2-LR_Amon_historical-ssp370_r1i1p1f1_pr_gn_2010-2020.nc
then the returned basename will have the following structure
CMIP6_MPI-ESM1-2-LR_{table}_historical-ssp370_r1i1p1f1_{var}_gn_2010-2020.
The filename of an ancestor variable is used as template.

Example:
- If the ancestor filename is
CMIP6_MPI-ESM1-2-LR_Amon_historical-ssp370_r1i1p1f1_tas_gn_...
then the returned basename will have the following structure
CMIP6_MPI-ESM1-2-LR_{table}_historical-ssp370_r1i1p1f1_{var}_gn_...
- For CMIP7 data, for an ancestor filename
tas_tavg-h2m-hxy-u_mon_glb_g999_MPI-ESM1-2-LR_historical_r1i1p1f2_...
then the returned basename will have the following structure
vpd_tavg-h2m-hxy-u_mon_glb_g999_MPI-ESM1-2-LR_historical_r1i1p1f2_...

Parameters
----------
Expand All @@ -66,11 +71,18 @@ def setup_basename_file(
basename : str
Basename for the file in which the processed variable will be saved.
"""
# Recover only the filename without path and type then split elements
file = Path(filename).stem.split("_")
# Fill in variable and table
file[2] = table
file[-3] = var
# CMIP6-like case for filename convention
if table == "Amon":
# Recover only the filename without path and type then split elements
file = Path(filename).stem.split("_")
# Fill in variable and table
file[2] = table
file[-3] = var
else:
# Recover only the filename without path and type then split elements
file = Path(filename).stem.split("_")
# Fill in variable
file[0] = var
return "_".join(file)


Expand Down Expand Up @@ -279,7 +291,19 @@ def compute_vpd(
vpd.attributes["ancestors"] = provenance["ancestors"]
debug_vpd = f"vapor_pressure_deficit iris cube {vpd}"
logger.debug(debug_vpd)
basename = setup_basename_file(provenance["ancestors"][0], "vpd", "Amon")
# Differentiate filename structure for CMIP6/CMIP7 data
if "tavg-h2m-hxy" in provenance["ancestors"][0]:
basename = setup_basename_file(
provenance["ancestors"][0],
"vpd",
"atmos",
)
else:
basename = setup_basename_file(
provenance["ancestors"][0],
"vpd",
"Amon",
)
msg = f"Saving vapor_pressure_deficit in {cfg['work_dir']}/{basename}"
logger.info(msg)
filename = get_diagnostic_filename(basename, cfg, extension="nc")
Expand Down Expand Up @@ -310,12 +334,7 @@ def main(cfg: dict) -> None:
# - user-defined path to files
# - download files from a Zenodo archive
# - defaults to the path to files from ESMValTool
if "confire_param" in cfg:
if "zenodo" not in cfg["confire_param"]:
cfg["param_confire"] = (
Path(cfg["auxiliary_data_dir"]) / cfg["confire_param"]
)
else:
if "confire_param" not in cfg:
cfg["confire_param"] = "https://zenodo.org/records/14917245"
cfg["confire_param_dir"] = get_parameter_directory(cfg)

Expand All @@ -340,7 +359,6 @@ def main(cfg: dict) -> None:

vars_file = {}
for i, attributes in enumerate(group):
logger.info("Variable %s", attributes["short_name"])
# Fallback for CMIP7 data for tasmax
short_name_key = (
"tasmax"
Expand All @@ -350,6 +368,7 @@ def main(cfg: dict) -> None:
else attributes["short_name"]
)
vars_file[short_name_key] = attributes
logger.info("Variable %s", short_name_key)
# Save model information for output plot name
if i == 0:
plot_file_info = "_".join(
Expand Down
85 changes: 85 additions & 0 deletions esmvaltool/recipes/ref/recipe_ref_fire_cmip7.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# ESMValTool
---
documentation:
description: |
Recipe that plots diagnostics regarding climate drivers for fire.
The diagnostic uses code for the ConFire model from the following GitHub repository:
https://github.com/douglask3/Bayesian_fire_models/tree/AR7_REF

title: Climate drivers for fire.

authors:
- lenhardt_julien
- kelley_douglas

maintainer:
- lenhardt_julien

datasets:
- {dataset: DUMMY-MODEL, institute: MOHC, project: CMIP7, activity: CMIP,
ensemble: r1i1p1f2, exp: historical, start_year: 2013, end_year: 2014,
region: glb, grid: g999, frequency: mon}

preprocessors:

preproc: &preproc
regrid:
target_grid: 2.5x2.5
scheme: nearest
mask_landsea:
mask_out: "sea"
preproc_fraction:
<<: *preproc
convert_units:
units: 1

diagnostics:

fire_evaluation:
description: Climate drivers for fire
variables:
#Precipitation
pr:
mip: atmos
branding_suffix: tavg-u-hxy-u
preprocessor: preproc
# Maximum surface temperature
tasmax:
short_name: tas
mip: atmos
branding_suffix: tmaxavg-h2m-hxy-u
preprocessor: preproc
# Tree cover percentage
treeFrac:
mip: land
branding_suffix: tavg-u-hxy-u
preprocessor: preproc_fraction
# Vegetation cover percentage
vegFrac:
mip: land
branding_suffix: tavg-u-hxy-u
preprocessor: preproc_fraction
# Vegetation carbon mass
cVeg:
mip: land
branding_suffix: tavg-u-hxy-lnd
preprocessor: preproc
# To compute the vapor pressure deficit (vpd)
# Surface temperature
tas:
mip: atmos
branding_suffix: tavg-h2m-hxy-u
preprocessor: preproc
# Near-surface relative humidity
hurs:
mip: atmos
branding_suffix: tavg-h2m-hxy-u
preprocessor: preproc

scripts:
fire_evaluation:
script: fire/fire_diagnostic.py
# confire_param: https://zenodo.org/records/14917245
confire_param: /home/b/b381312/esmvaltool/auxiliary_data/ConFire_parameter_files/
# IMPORTANT = the order of the variables should fit the configuration files of the ConFire model run
var_order: ['pr', 'tasmax', 'treeFrac', 'vegFrac', 'vpd', 'cVeg']