Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
2 changes: 1 addition & 1 deletion modules/data.atmosphere/R/Ameriflux_met_ensemble.R
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ AmeriFlux_met_ensemble <- function(site_id,
verbose = verbose
)

fill_vars <- coverage_results$fill_vars
fill_vars <- coverage_results$fill_vars_cds

if (length(fill_vars) > 0) {
start_year <- lubridate::year(as.Date(start_date))
Expand Down
5 changes: 4 additions & 1 deletion modules/data.atmosphere/R/check_met_coverage_for_fallback.R
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,11 @@ check_met_coverage_for_fallback <- function(cf_file,
fill_vars <- c(fill_vars, "volumetric_soil_water_layer_1")
}

fill_vars_cf <- unname(cds_to_cf_varnames(fill_vars))

list(
fill_vars = fill_vars,
fill_vars_cds = fill_vars,
fill_vars_cf = fill_vars_cf,
coverage = list(
rg = rg_coverage,
par = par_coverage,
Expand Down
104 changes: 104 additions & 0 deletions modules/data.atmosphere/R/era5_cf_varname_map.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#' ERA5 CDS-to-CF variable name map
#'
#' Internal mapping between ERA5 CDS variable names and CF standard names
#' produced by extract.nc.ERA5().
#'
#' Only variables relevant to the AmeriFlux gap-fill fallback pipeline are
#' included. Variables not listed here are not handled by this pipeline.
#'
#' @noRd
era5_cds_to_cf_varnames <- c(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please let me know if this doesn't make sense, but it seems like it would be simpler and more generally useful to

translate_met_varnames <- function(vars, from, to, table = pecan_standard_met_table) {
  lookup <- table |>
    dplyr::select(dplyr::all_of(c(from, to))) |>
    dplyr::filter(!is.na(.data[[from]]), .data[[from]] != "")

  result <- lookup[[to]]
  names(result) <- lookup[[from]]

  result[vars]
}

then if it is useful (not clear if it is, but simple enough), developers can create <from>_to_<to>_varnames. functions as needed.

"surface_solar_radiation_downwards" =
"surface_downwelling_shortwave_flux_in_air",
"volumetric_soil_water_layer_1" =
"volume_fraction_of_condensed_water_in_soil"
)

#' Translate ERA5 CDS variable names to CF standard names
#'
#' @description
#' Translate ERA5 CDS variable names to CF standard names.
#'
#' @param cds_vars Character vector of ERA5 CDS API variable names.
#'
#' @return Named character vector the same length as `cds_vars`. Names are
#' the input CDS names; values are the corresponding CF standard names as
#' written by [extract.nc.ERA5()]. Any input name absent from the internal
#' map produces a [PEcAn.logger::logger.warn()] and an `NA` at that
#' position. Returns `character(0)` when `cds_vars` is empty.
#'
#' @details
#' Covers only the ERA5 variables used in the AmeriFlux gap-fill fallback
#' pipeline. Unknown names are warned and returned as `NA` rather than
#' silently dropped so that callers encounter the failure immediately instead
#' of producing a silent no-fill condition downstream.
#'
#' @seealso [cf_to_cds_varnames()]
#' @noRd
cds_to_cf_varnames <- function(cds_vars) {
if (length(cds_vars) == 0L) {
return(character(0))
}

result <- era5_cds_to_cf_varnames[cds_vars]
unknown <- cds_vars[is.na(result)]

if (length(unknown) > 0L) {
msg <- paste(
"cds_to_cf_varnames: no CF mapping for CDS variable(s):",
paste(unknown, collapse = ", "),
"returning NA for those entries"
)
warning(msg, call. = FALSE)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only the PEcAn.logger call is required, it will pass to the appropriate function (warning in this case). and it handles the outer paste internally (the inner one with collapse = may need to stay.

PEcAn.logger::logger.warn(msg)

}

result
}


#' Translate CF standard variable names to ERA5 CDS names
#'
#' @param cf_vars Character vector of CF standard variable names.
#'
#' @return Named character vector the same length as `cf_vars`. Names are
#' the input CF names; values are the corresponding CDS API names. Any
#' input name absent from the internal map produces a
#' [PEcAn.logger::logger.warn()] and an `NA` at that position. Returns
#' `character(0)` when `cf_vars` is empty.
#'
#' @details
#' Reverse of [cds_to_cf_varnames()]. Covers only the ERA5 variables used in
#' the AmeriFlux gap-fill fallback pipeline. Unknown names warn and return
#' `NA` rather than being silently dropped.
#'
#' @seealso [cds_to_cf_varnames()]
#' @noRd
cf_to_cds_varnames <- function(cf_vars) {
if (length(cf_vars) == 0L) {
return(character(0))
}

# Reverse map built at call time — one source of truth in
# era5_cds_to_cf_varnames; no second hardcoded vector to keep in sync.
reverse_map <- stats::setNames(
names(era5_cds_to_cf_varnames),
unname(era5_cds_to_cf_varnames)
)

result <- reverse_map[cf_vars]
unknown <- cf_vars[is.na(result)]

if (length(unknown) > 0L) {
msg <- paste(
"cf_to_cds_varnames: no CDS mapping for CF variable(s):",
paste(unknown, collapse = ", "),
"- returning NA for those entries"
)
warning(msg, call. = FALSE)
PEcAn.logger::logger.warn(msg)
}

result
}
Loading
Loading