diff --git a/docs/environment.yml b/docs/environment.yml index ea7494fd7..e71700ed5 100644 --- a/docs/environment.yml +++ b/docs/environment.yml @@ -2,6 +2,7 @@ name: readthedocs channels: - conda-forge dependencies: + - python=3.12 - sphinx_rtd_theme=2.0.* - sphinxcontrib-bibtex=2.6.* - tree diff --git a/docs/shared/chgres_cube.yaml b/docs/shared/chgres_cube.yaml index e7028d300..d717b7395 100644 --- a/docs/shared/chgres_cube.yaml +++ b/docs/shared/chgres_cube.yaml @@ -19,7 +19,8 @@ chgres_cube: fix_dir_target_grid: /path/to/fixdir grib2_file_input_grid: a.file.gb2 mosaic_file_target_grid: /path/to/mosaic/C432.mosaic.halo4.nc - orog_files_target_grid: /path/to/orog/C432.oro_data.tile7.halo4.nc + orog_dir_target_grid: /path/to/fixdir + orog_files_target_grid: C432.oro_data.tile7.halo4.nc sfc_files_input_grid: sfc.t{{cycle.strftime('%H') }}z.nc varmap_file: /path/to/varmap_table vcoord_file_target_grid: /path/to/global_hyblev.l65.txt diff --git a/src/uwtools/drivers/chgres_cube.py b/src/uwtools/drivers/chgres_cube.py index 1cf6dca67..6dc9594d2 100644 --- a/src/uwtools/drivers/chgres_cube.py +++ b/src/uwtools/drivers/chgres_cube.py @@ -35,7 +35,7 @@ def namelist_file(self): input_files.append(base_file) if update_values := namelist.get(STR.updatevalues): config_files = update_values["config"] - for k in ["mosaic_file_target_grid", "vcoord_file_target_grid"]: + for k in ["mosaic_file_target_grid", "varmap_file", "vcoord_file_target_grid"]: input_files.append(config_files[k]) for k in [ "atm_core_files_input_grid", @@ -43,17 +43,26 @@ def namelist_file(self): "atm_tracer_files_input_grid", "grib2_file_input_grid", "nst_files_input_grid", + "sfc_files_input_grid", + ]: + if k in config_files: + grid_path = Path(config_files["data_dir_input_grid"]) + v = config_files[k] + if isinstance(v, str): + input_files.append(grid_path / v) + else: + input_files.extend([grid_path / f for f in v]) + for k in [ "orog_files_input_grid", "orog_files_target_grid", - "sfc_files_input_grid", - "varmap_file", ]: if k in config_files: + grid_path = Path(config_files[k.replace("files", "dir")]) v = config_files[k] if isinstance(v, str): - input_files.append(v) + input_files.append(grid_path / v) else: - input_files += v + input_files.extend([grid_path / f for f in v]) yield [file(Path(input_file)) for input_file in input_files] self._create_user_updated_config( config_class=NMLConfig, diff --git a/src/uwtools/resources/jsonschema/chgres-cube.jsonschema b/src/uwtools/resources/jsonschema/chgres-cube.jsonschema index 534975325..6a584d5ea 100644 --- a/src/uwtools/resources/jsonschema/chgres-cube.jsonschema +++ b/src/uwtools/resources/jsonschema/chgres-cube.jsonschema @@ -27,12 +27,31 @@ "update_values": { "properties": { "config": { - "additionalProperties": { - "type": [ - "array", - "boolean", - "number", - "string" + "additionalProperties": false, + "dependencies": { + "atm_core_files_input_grid": [ + "data_dir_input_grid" + ], + "atm_files_input_grid": [ + "data_dir_input_grid" + ], + "atm_tracer_files_input_grid": [ + "data_dir_input_grid" + ], + "grib2_file_input_grid": [ + "data_dir_input_grid" + ], + "nst_files_input_grid": [ + "data_dir_input_grid" + ], + "orog_files_input_grid": [ + "orog_dir_input_grid" + ], + "orog_files_target_grid": [ + "orog_dir_target_grid" + ], + "sfc_files_input_grid": [ + "data_dir_input_grid" ] }, "properties": { @@ -91,13 +110,6 @@ "type": "string" }, "external_model": { - "enum": [ - "GFS", - "HRRR", - "NAM", - "RAP", - "UKMET" - ], "type": "string" }, "fix_dir_target_grid": { diff --git a/src/uwtools/tests/drivers/test_chgres_cube.py b/src/uwtools/tests/drivers/test_chgres_cube.py index 447037cca..b796005c6 100644 --- a/src/uwtools/tests/drivers/test_chgres_cube.py +++ b/src/uwtools/tests/drivers/test_chgres_cube.py @@ -48,7 +48,7 @@ def config(tmp_path): "update_values": { "config": { "atm_core_files_input_grid": [str(afile), str(afile)], - "atm_files_input_grid": str(afile), + "atm_files_input_grid": [str(afile), str(afile)], "atm_tracer_files_input_grid": str(afile), "atm_weight_file": str(afile), "convert_atm": True, @@ -59,6 +59,11 @@ def config(tmp_path): "grib2_file_input_grid": str(afile), "mosaic_file_input_grid": str(afile), "mosaic_file_target_grid": str(afile), + "orog_dir_input_grid": "/path/to/dir", + "orog_files_input_grid": [str(afile), str(afile)], + "orog_dir_target_grid": "/path/to/dir", + "orog_files_target_grid": str(afile), + "nst_files_input_grid": str(afile), "sfc_files_input_grid": str(afile), "varmap_file": str(afile), "vcoord_file_target_grid": str(afile), diff --git a/src/uwtools/tests/test_schemas.py b/src/uwtools/tests/test_schemas.py index 0cd566bbf..951d6447d 100644 --- a/src/uwtools/tests/test_schemas.py +++ b/src/uwtools/tests/test_schemas.py @@ -527,9 +527,8 @@ def test_schema_chgres_cube_namelist_update_values(chgres_cube_config, chgres_cu # Some entries are required: for key in ["mosaic_file_target_grid", "vcoord_file_target_grid"]: assert "is a required property" in errors(with_del(config, key)) - # Additional entries of namelist-compatible types are permitted: - for val in [[1, 2, 3], True, 42, 3.14, "bar"]: - assert not errors(with_set(config, val, "foo")) + # Additional top-level keys are not allowed: + assert "Additional properties are not allowed" in errors({**config, "foo": "bar"}) # Namelist values must be of the correct type: # boolean: for key in [ @@ -545,9 +544,6 @@ def test_schema_chgres_cube_namelist_update_values(chgres_cube_config, chgres_cu "wam_cold_start", ]: assert "not of type 'boolean'" in errors(with_set(config, None, key)) - # enum: - for key in ["external_model", "input_type"]: - assert "is not one of" in errors(with_set(config, None, key)) # integer: for key in [ "cycle_day", @@ -590,6 +586,7 @@ def test_schema_chgres_cube_namelist_update_values(chgres_cube_config, chgres_cu ]: assert "is not of type 'array', 'string'\n" in errors(with_set(config, None, key)) assert "is not of type 'string'\n" in errors(with_set(config, [1, 2, 3], key)) + assert not errors(with_set(config, ["foo", "bar", "baz"], key)) # esg-grid