vignettes/articles/esg-dictionaries.Rmd
esg-dictionaries.Rmd
library(epwshiftr)
workflow_root <- file.path(tempdir(), "epwshiftr-esg-dictionaries")
if (dir.exists(workflow_root)) {
unlink(workflow_root, recursive = TRUE)
}
dir.create(workflow_root, recursive = TRUE, showWarnings = FALSE)
options(
epwshiftr.dir_cache = file.path(workflow_root, "cache")
)
show_rows <- function(x, n = 8L) {
utils::head(data.table::as.data.table(x), n)
}ESG projects describe model output through controlled vocabularies. Some projects also publish request-table metadata that describes valid relationships between fields such as activities, experiments, variables, tables, and frequencies.
EsgDict is epwshiftr’s project-aware dictionary object.
The main future EPW workflow can
run without manual dictionary code, but dictionaries are the best first
check when you want to validate request values before sending a live
ESGF query.
EsgDict$new(project = "CMIP6") creates an empty
dictionary object. $build() downloads upstream
controlled-vocabulary and request-table sources, parses them, and builds
normalized indices used by options() and
check().
This article uses a fresh article-local source directory so the output comes from a live upstream build.
After a build, the dictionary records where its source data came from, which versions were used, source timestamps where available, and when the local dictionary was built.
dict$project()
#> [1] "CMIP6"
dict$profile()
#> [1] "cmip6"
dict$sources()
#> $vocab
#> $vocab$repo
#> [1] "WCRP-CMIP/CMIP6_CVs"
#>
#> $vocab$tag
#> [1] "6.2.60.0"
#>
#> $vocab$commit
#> [1] "78a465a7dabb01e357928ea223bc5da871a6e6dc"
#>
#> $vocab$source_dir
#> [1] "/private/var/folders/8f/t8sk2pps6135xbp47cs8qb2r0000gn/T/Rtmp3Hed7X/epwshiftr-esg-dictionaries/sources/CMIP6/vocab/6.2.60.0"
#>
#>
#> $request
#> $request$repo
#> [1] "PCMDI/cmip6-cmor-tables"
#>
#> $request$tag
#> [1] "6.9.33"
#>
#> $request$commit
#> [1] "c8810526268e8cb13f2b37aba6af377e15644561"
#>
#> $request$source_dir
#> [1] "/private/var/folders/8f/t8sk2pps6135xbp47cs8qb2r0000gn/T/Rtmp3Hed7X/epwshiftr-esg-dictionaries/sources/CMIP6/request/6.9.33"
dict$version()
#> $vocab
#> [1] '6.2.60.0'
#>
#> $request
#> [1] '1.0.33'
dict$timestamp()
#> $vocab
#> [1] "2025-09-04 23:01:22 UTC"
#>
#> $drs
#> [1] "2025-09-02 22:42:23 UTC"
#>
#> $activity_id
#> [1] "2018-03-06 00:39:09 UTC"
#>
#> $experiment_id
#> [1] "2020-12-15 20:25:59 UTC"
#>
#> $frequency
#> [1] "2021-05-24 14:48:15 UTC"
#>
#> $grid_label
#> [1] "2017-09-09 01:12:00 UTC"
#>
#> $institution_id
#> [1] "2022-08-16 04:41:00 UTC"
#>
#> $nominal_resolution
#> [1] "2016-11-15 23:04:00 UTC"
#>
#> $realm
#> [1] "2017-04-18 19:03:00 UTC"
#>
#> $required_global_attributes
#> [1] "2019-12-19 23:32:17 UTC"
#>
#> $source_id
#> [1] "2025-04-18 23:28:35 UTC"
#>
#> $source_type
#> [1] "2017-09-09 00:57:00 UTC"
#>
#> $sub_experiment_id
#> [1] "2019-06-17 18:01:51 UTC"
#>
#> $table_id
#> [1] "2017-01-13 16:27:00 UTC"
dict$built_time()
#> [1] "2026-06-25 02:14:54 CST"capabilities() is the fastest way to see whether a
project dictionary has vocabulary data, request metadata, and relation
indices.
dict$capabilities()
#> $vocab
#> [1] TRUE
#>
#> $request
#> [1] TRUE
#>
#> $relations
#> [1] "variable" "activity_experiment" "activity_source"
dict$fields()
#> [1] "activity_id" "experiment_id" "frequency"
#> [4] "grid_label" "institution_id" "mip_era"
#> [7] "nominal_resolution" "project" "realm"
#> [10] "source_id" "source_type" "sub_experiment_id"
#> [13] "table_id" "variable_id" "variant_label"
dict$relation_fields()
#> $variable
#> [1] "variable_id" "table_id" "frequency" "realm"
#>
#> $activity_experiment
#> [1] "activity_id" "experiment_id" "sub_experiment_id"
#>
#> $activity_source
#> [1] "activity_id" "source_id" "institution_id"CMIP6 includes request-table metadata, so it can answer both value questions and many cross-field legality questions.
The raw vocabulary payload is available through $get(),
but most workflows should use normalized fields and indices.
index_names <- names(dict$indices())
index_names
#> [1] "values" "variable" "activity_experiment"
#> [4] "activity_source"
show_rows(dict$indices("values"), 12L)
#> field value
#> <char> <char>
#> 1: project CMIP6
#> 2: mip_era CMIP6
#> 3: variant_label <NA>
#> 4: activity_id AerChemMIP
#> 5: activity_id C4MIP
#> 6: activity_id CDRMIP
#> 7: activity_id CFMIP
#> 8: activity_id CMIP
#> 9: activity_id CORDEX
#> 10: activity_id DAMIP
#> 11: activity_id DCPP
#> 12: activity_id DynVarMIP
#> description
#> <char>
#> 1: CMIP6 project
#> 2: CMIP6 project
#> 3: CMIP6 realization-initialization-physics-forcing member label
#> 4: Aerosols and Chemistry Model Intercomparison Project
#> 5: Coupled Climate Carbon Cycle Model Intercomparison Project
#> 6: Carbon Dioxide Removal Model Intercomparison Project
#> 7: Cloud Feedback Model Intercomparison Project
#> 8: CMIP DECK: 1pctCO2, abrupt4xCO2, amip, esm-piControl, esm-historical, historical, and piControl experiments
#> 9: Coordinated Regional Climate Downscaling Experiment
#> 10: Detection and Attribution Model Intercomparison Project
#> 11: Decadal Climate Prediction Project
#> 12: Dynamics and Variability Model Intercomparison Project
#> pattern source
#> <char> <char>
#> 1: <NA> constant
#> 2: <NA> constant
#> 3: ^r\\d+i\\d+p\\d+f\\d+$ pattern
#> 4: <NA> vocab
#> 5: <NA> vocab
#> 6: <NA> vocab
#> 7: <NA> vocab
#> 8: <NA> vocab
#> 9: <NA> vocab
#> 10: <NA> vocab
#> 11: <NA> vocab
#> 12: <NA> vocab
if ("variable" %in% index_names) {
show_rows(dict$indices("variable"), 12L)
}
#> variable_id table_id frequency realm
#> <char> <char> <char> <char>
#> 1: clt 3hr 3hr atmos
#> 2: hfls 3hr 3hr atmos
#> 3: hfss 3hr 3hr atmos
#> 4: huss 3hr 3hrPt atmos
#> 5: mrro 3hr 3hr land
#> 6: mrsos 3hr 3hrPt land
#> 7: pr 3hr 3hr atmos
#> 8: prc 3hr 3hr atmos
#> 9: prsn 3hr 3hr atmos
#> 10: ps 3hr 3hrPt atmos
#> 11: rlds 3hr 3hr atmos
#> 12: rldscs 3hr 3hr atmos
#> long_name units
#> <char> <char>
#> 1: Total Cloud Cover Percentage %
#> 2: Surface Upward Latent Heat Flux W m-2
#> 3: Surface Upward Sensible Heat Flux W m-2
#> 4: Near-Surface Specific Humidity 1
#> 5: Total Runoff kg m-2 s-1
#> 6: Moisture in Upper Portion of Soil Column kg m-2
#> 7: Precipitation kg m-2 s-1
#> 8: Convective Precipitation kg m-2 s-1
#> 9: Snowfall Flux kg m-2 s-1
#> 10: Surface Air Pressure Pa
#> 11: Surface Downwelling Longwave Radiation W m-2
#> 12: Surface Downwelling Clear-Sky Longwave Radiation W m-2$get() is useful when you need the source-level payload
for a specific field or request table.
show_rows(dict$get("experiment_id"), 8L)
#> experiment_id
#> <char>
#> 1: 1pctCO2
#> 2: 1pctCO2-4xext
#> 3: 1pctCO2-bgc
#> 4: 1pctCO2-cdr
#> 5: 1pctCO2-rad
#> 6: 1pctCO2Ndep
#> 7: 1pctCO2Ndep-bgc
#> 8: 1pctCO2to4x-withism
#> experiment
#> <char>
#> 1: 1 percent per year increase in CO2
#> 2: extension from year 140 of 1pctCO2 with 4xCO2
#> 3: biogeochemically-coupled version of 1 percent per year increasing CO2 experiment
#> 4: 1 percent per year decrease in CO2 from 4xCO2
#> 5: radiatively-coupled version of 1 percent per year increasing CO2 experiment
#> 6: 1 percent per year increasing CO2 experiment with increasing N-deposition
#> 7: biogeochemically-coupled version of 1 percent per year increasing CO2 experiment with increasing N-deposition
#> 8: simulation with interactive ice sheet forced by 1 percent per year increase in CO2 to 4xCO2 (subsequently held fixed)
#> description
#> <char>
#> 1: DECK: 1pctCO2
#> 2: branched from 1pctCO2 run at year 140 and run with CO2 fixed at 4x pre-industrial concentration
#> 3: Biogeochemically-coupled specified concentration simulation in which CO2 increases at a rate of 1% per year until quadrupling
#> 4: 1 percent per year decrease in CO2 (immediately after reaching 4xCO2 in the 1pctCO2 simulation); then held constant at pre-industrial level (part of the CDR-reversibility experiment)
#> 5: Radiatively-coupled specified concentration simulation in which CO2 increases at a rate of 1% per year until quadrupling
#> 6: Fully-coupled specified concentration simulation in which CO2 increases at a rate of 1% per year until quadrupling, plus an additional scenario of anthropogenic nitrogen deposition
#> 7: Biogeochemically-coupled specified concentration simulation in which CO2 increases at a rate of 1% per year until quadrupling, plus an additional scenario of anthropogenic nitrogen deposition
#> 8: Idealized 1%/yr CO2 increase to 4xC02 over 140yrs and kept constant at 4xCO2 for an additional 200 to 400 yrs simulation that includes interactive ice sheets
#> tier start_year end_year min_number_yrs_per_sim required_model_components
#> <int> <int> <int> <int> <list>
#> 1: 1 NA NA 150 AOGCM
#> 2: 1 NA NA 210 AOGCM
#> 3: 1 NA NA 150 AOGCM,BGC
#> 4: 1 NA NA 200 AOGCM,BGC
#> 5: 2 NA NA 150 AOGCM,BGC
#> 6: 2 NA NA 150 AOGCM,BGC
#> 7: 2 NA NA 150 AOGCM,BGC
#> 8: 1 NA NA 350 AOGCM,ISM
#> parent_experiment_id sub_experiment_id activity_id parent_activity_id
#> <list> <list> <list> <list>
#> 1: piControl none CMIP CMIP
#> 2: 1pctCO2 none ISMIP6 CMIP
#> 3: piControl none C4MIP CMIP
#> 4: 1pctCO2 none CDRMIP CMIP
#> 5: piControl none C4MIP CMIP
#> 6: piControl none C4MIP CMIP
#> 7: piControl none C4MIP CMIP
#> 8: piControl-withism none ISMIP6 ISMIP6
#> additional_allowed_model_components
#> <list>
#> 1: AER,CHEM,BGC
#> 2: AER,CHEM,BGC
#> 3: AER,CHEM
#> 4: AER,CHEM
#> 5: AER,CHEM
#> 6: AER,CHEM
#> 7: AER,CHEM
#> 8: AER,CHEM,BGC
request_payload <- dict$get("request")
show_rows(request_payload[, c(
"variable", "table_id", "frequency", "long_name", "units"
), with = FALSE], 8L)
#> variable table_id frequency long_name
#> <char> <char> <char> <char>
#> 1: clt 3hr 3hr Total Cloud Cover Percentage
#> 2: hfls 3hr 3hr Surface Upward Latent Heat Flux
#> 3: hfss 3hr 3hr Surface Upward Sensible Heat Flux
#> 4: huss 3hr 3hrPt Near-Surface Specific Humidity
#> 5: mrro 3hr 3hr Total Runoff
#> 6: mrsos 3hr 3hrPt Moisture in Upper Portion of Soil Column
#> 7: pr 3hr 3hr Precipitation
#> 8: prc 3hr 3hr Convective Precipitation
#> units
#> <char>
#> 1: %
#> 2: W m-2
#> 3: W m-2
#> 4: 1
#> 5: kg m-2 s-1
#> 6: kg m-2
#> 7: kg m-2 s-1
#> 8: kg m-2 s-1
names(request_payload)
#> [1] "variable" "table_id" "modeling_realm" "standard_name"
#> [5] "long_name" "frequency" "units" "cell_methods"
#> [9] "cell_measures" "comment" "dimensions" "out_name"
#> [13] "type" "positive" "valid_min" "valid_max"
#> [17] "ok_min_mean_abs" "ok_max_mean_abs"$options() lists valid values for a field. Constraints
narrow the result when a relation index is available.
show_rows(dict$options("experiment_id", activity_id = "ScenarioMIP"), 12L)
#> field value
#> <char> <char>
#> 1: experiment_id rcp26-cmip5
#> 2: experiment_id rcp45-cmip5
#> 3: experiment_id rcp60-cmip5
#> 4: experiment_id rcp85-cmip5
#> 5: experiment_id ssp119
#> 6: experiment_id ssp126
#> 7: experiment_id ssp245
#> 8: experiment_id ssp370
#> 9: experiment_id ssp434
#> 10: experiment_id ssp460
#> 11: experiment_id ssp534-over
#> 12: experiment_id ssp585
#> description
#> <char>
#> 1: future scenario with low radiative forcing by the end of century. Following RCP2.6 global forcing pathway. Concentration-driven (CMIP5-era [2006-2100] forcing)
#> 2: future scenario with low-medium radiative forcing by the end of century. Following RCP4.5 global forcing pathway. Concentration-driven (CMIP5-era [2006-2100] forcing)
#> 3: future scenario with medium radiative forcing by the end of century. Following RCP6.0 global forcing pathway. Concentration-driven (CMIP5-era [2006-2100] forcing)
#> 4: future scenario with high radiative forcing by the end of century. Following RCP8.5 global forcing pathway. Concentration-driven (CMIP5-era [2006-2100] forcing)
#> 5: Future scenario with low radiative forcing throughout reaching about 1.9 W/m2 in 2100 based on SSP1. Concentration-driven
#> 6: Future scenario with low radiative forcing by the end of century. Following approximately RCP2.6 global forcing pathway but with new forcing based on SSP1. Concentration-driven. As a tier 2 option, this simulation should be extended to year 2300
#> 7: Future scenario with medium radiative forcing by the end of century. Following approximately RCP4.5 global forcing pathway but with new forcing based on SSP2. Concentration-driven
#> 8: Future scenario with high radiative forcing by the end of century. Reaches about 7.0 W/m2 by 2100; fills gap in RCP forcing pathways between 6.0 and 8.5 W/m2. Concentration-driven
#> 9: Future scenario with low radiative forcing by the end of century. Reaches about 3.4 W/m2 by 2100; fills gap in RCP forcing pathways between 4.5 and 2.6 W/m2. Concentration-driven
#> 10: Future scenario with medium radiative forcing by the end of century. Following approximately RCP6.0 global forcing pathway but with new forcing based on SSP4. Concentration-driven
#> 11: 21st century overshoot scenario relative to SSP5_34. Branches from SSP5_85 at 2040 with emissions reduced to zero by 2070 and negative thereafter. This simulation should optionally be extended to year 2300
#> 12: Future scenario with high radiative forcing by the end of century. Following approximately RCP8.5 global forcing pathway but with new forcing based on SSP5. Concentration-driven. As a tier 2 option, this simulation should be extended to year 2300
#> pattern source
#> <char> <char>
#> 1: <NA> vocab
#> 2: <NA> vocab
#> 3: <NA> vocab
#> 4: <NA> vocab
#> 5: <NA> vocab
#> 6: <NA> vocab
#> 7: <NA> vocab
#> 8: <NA> vocab
#> 9: <NA> vocab
#> 10: <NA> vocab
#> 11: <NA> vocab
#> 12: <NA> vocab
show_rows(dict$options("variable_id", table_id = "Amon"), 12L)
#> field value description pattern source
#> <char> <char> <char> <char> <char>
#> 1: variable_id clt <NA> <NA> request
#> 2: variable_id hfls <NA> <NA> request
#> 3: variable_id hfss <NA> <NA> request
#> 4: variable_id huss <NA> <NA> request
#> 5: variable_id pr <NA> <NA> request
#> 6: variable_id prc <NA> <NA> request
#> 7: variable_id prsn <NA> <NA> request
#> 8: variable_id ps <NA> <NA> request
#> 9: variable_id rlds <NA> <NA> request
#> 10: variable_id rldscs <NA> <NA> request
#> 11: variable_id rlus <NA> <NA> request
#> 12: variable_id rsds <NA> <NA> request
show_rows(dict$options("table_id", variable_id = "tas"), 12L)
#> field value description pattern source
#> <char> <char> <char> <char> <char>
#> 1: table_id 3hr <NA> <NA> vocab
#> 2: table_id 6hrPlev <NA> <NA> vocab
#> 3: table_id 6hrPlevPt <NA> <NA> vocab
#> 4: table_id AERhr <NA> <NA> vocab
#> 5: table_id Amon <NA> <NA> vocab
#> 6: table_id CFsubhr <NA> <NA> vocab
#> 7: table_id Esubhr <NA> <NA> vocab
#> 8: table_id ImonAnt <NA> <NA> vocab
#> 9: table_id ImonGre <NA> <NA> vocab
#> 10: table_id day <NA> <NA> vocabThe top-level helper uses a supplied dictionary or the package-level
default dictionary. Supplying dict = makes the example
explicit.
show_rows(
esgdict_option("experiment_id", activity_id = "ScenarioMIP", dict = dict),
12L
)
#> field value
#> <char> <char>
#> 1: experiment_id rcp26-cmip5
#> 2: experiment_id rcp45-cmip5
#> 3: experiment_id rcp60-cmip5
#> 4: experiment_id rcp85-cmip5
#> 5: experiment_id ssp119
#> 6: experiment_id ssp126
#> 7: experiment_id ssp245
#> 8: experiment_id ssp370
#> 9: experiment_id ssp434
#> 10: experiment_id ssp460
#> 11: experiment_id ssp534-over
#> 12: experiment_id ssp585
#> description
#> <char>
#> 1: future scenario with low radiative forcing by the end of century. Following RCP2.6 global forcing pathway. Concentration-driven (CMIP5-era [2006-2100] forcing)
#> 2: future scenario with low-medium radiative forcing by the end of century. Following RCP4.5 global forcing pathway. Concentration-driven (CMIP5-era [2006-2100] forcing)
#> 3: future scenario with medium radiative forcing by the end of century. Following RCP6.0 global forcing pathway. Concentration-driven (CMIP5-era [2006-2100] forcing)
#> 4: future scenario with high radiative forcing by the end of century. Following RCP8.5 global forcing pathway. Concentration-driven (CMIP5-era [2006-2100] forcing)
#> 5: Future scenario with low radiative forcing throughout reaching about 1.9 W/m2 in 2100 based on SSP1. Concentration-driven
#> 6: Future scenario with low radiative forcing by the end of century. Following approximately RCP2.6 global forcing pathway but with new forcing based on SSP1. Concentration-driven. As a tier 2 option, this simulation should be extended to year 2300
#> 7: Future scenario with medium radiative forcing by the end of century. Following approximately RCP4.5 global forcing pathway but with new forcing based on SSP2. Concentration-driven
#> 8: Future scenario with high radiative forcing by the end of century. Reaches about 7.0 W/m2 by 2100; fills gap in RCP forcing pathways between 6.0 and 8.5 W/m2. Concentration-driven
#> 9: Future scenario with low radiative forcing by the end of century. Reaches about 3.4 W/m2 by 2100; fills gap in RCP forcing pathways between 4.5 and 2.6 W/m2. Concentration-driven
#> 10: Future scenario with medium radiative forcing by the end of century. Following approximately RCP6.0 global forcing pathway but with new forcing based on SSP4. Concentration-driven
#> 11: 21st century overshoot scenario relative to SSP5_34. Branches from SSP5_85 at 2040 with emissions reduced to zero by 2070 and negative thereafter. This simulation should optionally be extended to year 2300
#> 12: Future scenario with high radiative forcing by the end of century. Following approximately RCP8.5 global forcing pathway but with new forcing based on SSP5. Concentration-driven. As a tier 2 option, this simulation should be extended to year 2300
#> pattern source
#> <char> <char>
#> 1: <NA> vocab
#> 2: <NA> vocab
#> 3: <NA> vocab
#> 4: <NA> vocab
#> 5: <NA> vocab
#> 6: <NA> vocab
#> 7: <NA> vocab
#> 8: <NA> vocab
#> 9: <NA> vocab
#> 10: <NA> vocab
#> 11: <NA> vocab
#> 12: <NA> vocab$check() validates known values and known relationships
before the request goes to ESGF.
request_check <- dict$check(
activity_id = "ScenarioMIP",
experiment_id = "ssp585",
source_id = "MPI-ESM1-2-LR",
variant_label = "r1i1p1f1",
table_id = "Amon",
variable_id = epw_morph_variables("recommended")
)
show_rows(request_check, 20L)
#> field value valid type rule source
#> <char> <char> <lgcl> <char> <char> <char>
#> 1: activity_id ScenarioMIP TRUE value field_value vocab
#> 2: experiment_id ssp585 TRUE value field_value vocab
#> 3: source_id MPI-ESM1-2-LR TRUE value field_value vocab
#> 4: variant_label r1i1p1f1 TRUE value field_value pattern
#> 5: table_id Amon TRUE value field_value vocab
#> 6: variable_id tas TRUE value field_value request
#> 7: variable_id hurs TRUE value field_value request
#> 8: variable_id psl TRUE value field_value request
#> 9: variable_id rlds TRUE value field_value request
#> 10: variable_id rsds TRUE value field_value request
#> 11: variable_id sfcWind TRUE value field_value request
#> 12: variable_id clt TRUE value field_value request
#> constraint_fields message suggestions compatible_values
#> <list> <char> <list> <list>
#> 1: <NA>
#> 2: <NA>
#> 3: <NA>
#> 4: <NA>
#> 5: <NA>
#> 6: <NA>
#> 7: <NA>
#> 8: <NA>
#> 9: <NA>
#> 10: <NA>
#> 11: <NA>
#> 12: <NA>Suggestions are useful for typographical errors or aliases that do not match the project vocabulary.
show_rows(
dict$check(
experiment_id = "ssp58",
table_id = "Amon",
variable_id = "tas",
suggest = TRUE,
error = FALSE
),
12L
)
#> field value valid type rule source constraint_fields
#> <char> <char> <lgcl> <char> <char> <char> <list>
#> 1: experiment_id ssp58 FALSE value field_value vocab
#> 2: table_id Amon TRUE value field_value vocab
#> 3: variable_id tas TRUE value field_value request
#> message suggestions
#> <char> <list>
#> 1: `ssp58` is not a valid `experiment_id`. ssp585,ssp119,ssp126,ssp245,ssp370
#> 2: <NA>
#> 3: <NA>
#> compatible_values
#> <list>
#> 1:
#> 2:
#> 3:The same check is available through esgdict_check().
show_rows(
esgdict_check(
activity_id = "ScenarioMIP",
experiment_id = "ssp585",
variable_id = "tas",
table_id = "Amon",
dict = dict
)
)
#> field value valid type rule source
#> <char> <char> <lgcl> <char> <char> <char>
#> 1: activity_id ScenarioMIP TRUE value field_value vocab
#> 2: experiment_id ssp585 TRUE value field_value vocab
#> 3: variable_id tas TRUE value field_value request
#> 4: table_id Amon TRUE value field_value vocab
#> constraint_fields message suggestions compatible_values
#> <list> <char> <list> <list>
#> 1: <NA>
#> 2: <NA>
#> 3: <NA>
#> 4: <NA>Saved dictionaries are schema-validated JSON files. Use this when you want a known dictionary snapshot beside a project store or a reviewable analysis artifact.
dict_path <- file.path(workflow_root, "cmip6-dict-live.json")
dict$save(dict_path)
#> [1] "/var/folders/8f/t8sk2pps6135xbp47cs8qb2r0000gn/T//Rtmp3Hed7X/epwshiftr-esg-dictionaries/cmip6-dict-live.json"
restored <- EsgDict$new(project = "CMIP6")
restored$load(dict_path)
restored$status()
#> [1] "loaded"
restored$version()
#> $vocab
#> [1] '6.2.60.0'
#>
#> $request
#> [1] '1.0.33'
identical(restored$fields(), dict$fields())
#> [1] TRUEThe dictionary object is project-aware. Projects without registered request metadata still use the same object shape, but their capabilities and relation checks reflect what is available upstream.
cmip6plus_source_dir <- file.path(workflow_root, "sources", "CMIP6PLUS")
cmip6plus <- EsgDict$new(project = "CMIP6PLUS")
cmip6plus$build(
source_dir = cmip6plus_source_dir,
use_cache = FALSE
)
cmip6plus$project()
#> [1] "CMIP6PLUS"
cmip6plus$sources()
#> $vocab
#> $vocab$repo
#> [1] "WCRP-CMIP/CMIP6Plus_CVs"
#>
#> $vocab$tag
#> [1] "esgvoc"
#>
#> $vocab$commit
#> [1] NA
#>
#> $vocab$source_dir
#> [1] "/private/var/folders/8f/t8sk2pps6135xbp47cs8qb2r0000gn/T/Rtmp3Hed7X/epwshiftr-esg-dictionaries/sources/CMIP6PLUS/vocab/esgvoc"
#>
#>
#> $request
#> NULL
cmip6plus$capabilities()
#> $vocab
#> [1] TRUE
#>
#> $request
#> [1] FALSE
#>
#> $relations
#> character(0)
cmip6plus$relation_fields()
#> $activity_experiment
#> [1] "activity_id" "experiment_id" "sub_experiment_id"
#>
#> $activity_source
#> [1] "activity_id" "source_id" "institution_id"CV-only projects can still list fields and validate individual values. Relationship checks degrade according to the available indices instead of pretending that CMIP6 request metadata applies to every project.
utils::head(cmip6plus$fields(), 20L)
#> [1] "_archive" "activity_id" "calendar"
#> [4] "citation_url" "conventions" "creation_date"
#> [7] "cv" "data_specs_version" "experiment_id"
#> [10] "forcing_index" "frequency" "further_info_url"
#> [13] "grid_label" "initialization_index" "institution_id"
#> [16] "license" "member_id" "mip_era"
#> [19] "nominal_resolution" "physics_index"
if ("activity_id" %in% cmip6plus$fields()) {
show_rows(cmip6plus$options("activity_id"), 12L)
}
#> field value description pattern source
#> <char> <char> <char> <char> <char>
#> 1: activity_id ceresmip <NA> <NA> vocab
#> 2: activity_id cmip <NA> <NA> vocab
#> 3: activity_id dcpp <NA> <NA> vocab
#> 4: activity_id lesfmip <NA> <NA> vocab
#> 5: activity_id methanemip <NA> <NA> vocab
#> 6: activity_id ramip <NA> <NA> vocab
#> 7: activity_id scenariomip <NA> <NA> vocab
#> 8: activity_id tbimip <NA> <NA> vocab
#> 9: activity_id tipmip <NA> <NA> vocab
if ("experiment_id" %in% cmip6plus$fields()) {
show_rows(cmip6plus$options("experiment_id"), 12L)
}
#> field value description pattern source
#> <char> <char> <char> <char> <char>
#> 1: experiment_id 1pctco2 <NA> <NA> vocab
#> 2: experiment_id abrupt-4xco2 <NA> <NA> vocab
#> 3: experiment_id amip-aer <NA> <NA> vocab
#> 4: experiment_id amip-ghg <NA> <NA> vocab
#> 5: experiment_id amip-nat <NA> <NA> vocab
#> 6: experiment_id amip-noaer <NA> <NA> vocab
#> 7: experiment_id amip-noghg <NA> <NA> vocab
#> 8: experiment_id amip-nudge <NA> <NA> vocab
#> 9: experiment_id amip-slcf <NA> <NA> vocab
#> 10: experiment_id amip-sst <NA> <NA> vocab
#> 11: experiment_id amip <NA> <NA> vocab
#> 12: experiment_id dcppa-assim <NA> <NA> vocabshift_datasets() contacts ESGF.