diff --git a/parm/wflow/coldstart.yaml b/parm/wflow/coldstart.yaml index f39bbd46d..ff1796720 100644 --- a/parm/wflow/coldstart.yaml +++ b/parm/wflow/coldstart.yaml @@ -102,7 +102,16 @@ metatask_run_ensemble: mem: '{% if global.DO_ENSEMBLE %}{%- for m in range(1, global.NUM_ENS_MEMBERS+1) -%}{{ "%03d "%m }}{%- endfor -%} {% else %}{{ "000"|string }}{% endif %}' task_make_ics_mem#mem#: <<: *default_task - command: '&LOAD_MODULES_RUN_TASK; "make_ics" "&JOBSdir;/JREGIONAL_MAKE_ICS"' + command: + cyclestr: + value: 'source &USHdir;/load_modules_wflow.sh {{ user.MACHINE }} ; &SCRIPTSdir;/chgres_cube.py + -c &GLOBAL_VAR_DEFNS_FP; + --cycle @Y-@m-@dT@H:@M:@S + --key-path task_make_ics + --mem #mem#' + join: + cyclestr: + value: '&LOGDIR;/{{ jobname }}_@Y@m@d@H&LOGEXT;' envars: <<: *default_vars SLASH_ENSMEM_SUBDIR: '&SLASH_ENSMEM_SUBDIR;' @@ -111,7 +120,7 @@ metatask_run_ensemble: cyclestr: value: '&LOGDIR;/{{ jobname }}_@Y@m@d@H&LOGEXT;' nodes: '{{ task_make_ics.chgres_cube.execution.batchargs.nodes }}:ppn={{ task_make_ics.chgres_cube.execution.batchargs.tasks_per_node }}' - walltime: '{{ task_make_ics.chgres_cube.execution.batchargs.walltime }}' + walltime: '{{ task_make_ics.chgres_cube.execution.batchargs.walltime }}' dependency: and: &make_ics_deps taskdep_get_extrn: @@ -144,7 +153,16 @@ metatask_run_ensemble: task_make_lbcs_mem#mem#: <<: *default_task - command: '&LOAD_MODULES_RUN_TASK; "make_lbcs" "&JOBSdir;/JREGIONAL_MAKE_LBCS"' + command: + cyclestr: + value: 'source &USHdir;/load_modules_wflow.sh {{ user.MACHINE }} ; &SCRIPTSdir;/chgres_cube.py + -c &GLOBAL_VAR_DEFNS_FP; + --cycle @Y-@m-@dT@H:@M:@S + --key-path task_make_lbcs + --mem #mem#' + join: + cyclestr: + value: '&LOGDIR;/{{ jobname }}_@Y@m@d@H&LOGEXT;' envars: <<: *default_vars SLASH_ENSMEM_SUBDIR: '&SLASH_ENSMEM_SUBDIR;' @@ -155,7 +173,7 @@ metatask_run_ensemble: cyclestr: value: '&LOGDIR;/{{ jobname }}_@Y@m@d@H&LOGEXT;' nodes: '{{ task_make_lbcs.chgres_cube.execution.batchargs.nodes }}:ppn={{ task_make_lbcs.chgres_cube.execution.batchargs.tasks_per_node }}' - walltime: '{{ task_make_lbcs.chgres_cube.execution.batchargs.walltime }}' + walltime: '{{ task_make_lbcs.chgres_cube.execution.batchargs.walltime }}' dependency: and: <<: *make_ics_deps diff --git a/parm/wflow/post.yaml b/parm/wflow/post.yaml index 7eb7ffc0a..b528341d1 100644 --- a/parm/wflow/post.yaml +++ b/parm/wflow/post.yaml @@ -12,7 +12,7 @@ metatask_run_ens_post: maxtries: '2' command: cyclestr: - value: 'source &USHdir;/load_modules_wflow.sh hera ; &SCRIPTSdir;/upp.py + value: 'source &USHdir;/load_modules_wflow.sh {{ user.MACHINE }} ; &SCRIPTSdir;/upp.py -c &GLOBAL_VAR_DEFNS_FP; --cycle @Y-@m-@dT@H:@M:@S --leadtime #fhr#:00:00 diff --git a/scripts/chgres_cube.py b/scripts/chgres_cube.py new file mode 100755 index 000000000..b75ba1ddf --- /dev/null +++ b/scripts/chgres_cube.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python +""" +The run script for chgres_cube +""" + +import datetime as dt +import logging +import os +import sys +from argparse import ArgumentParser +from copy import deepcopy +from pathlib import Path + +from uwtools.api.chgres_cube import ChgresCube +from uwtools.api.config import get_yaml_config +from uwtools.api.fs import link as uwlink +from uwtools.api.logging import use_uwtools_logger + + +def _walk_key_path(config, key_path): + """ + Navigate to the sub-config at the end of the path of given keys. + """ + keys = [] + pathstr = "" + for key in key_path: + keys.append(key) + pathstr = " -> ".join(keys) + try: + subconfig = config[key] + except KeyError: + logging.error(f"Bad config path: {pathstr}") + raise + if not isinstance(subconfig, dict): + logging.error(f"Value at {pathstr} must be a dictionary") + sys.exit(1) + config = subconfig + return config + + +def parse_args(argv): + """ + Parse arguments for the script. + """ + parser = ArgumentParser( + description="Script that runs chgres_cube via uwtools API", + ) + parser.add_argument( + "-c", + "--config-file", + metavar="PATH", + required=True, + help="Path to experiment config file.", + type=Path, + ) + parser.add_argument( + "--cycle", + help="The cycle in ISO8601 format (e.g. 2024-07-15T18)", + required=True, + type=dt.datetime.fromisoformat, + ) + parser.add_argument( + "--key-path", + help="Dot-separated path of keys leading through the config to the driver's YAML block", + metavar="KEY[.KEY...]", + required=True, + type=lambda s: s.split("."), + ) + parser.add_argument( + "--member", + default="000", + help="The 3-digit ensemble member number.", + ) + return parser.parse_args(argv) + + +# pylint: disable-next=too-many-locals, too-many-statements +def run_chgres_cube(config_file, cycle, key_path, member): + """ + Setup and run the chgres_cube Driver. + """ + expt_config = get_yaml_config(config_file) + + # The experiment config will have {{ CRES | env }} expressions in it that need to be + # dereferenced during driver initialization + cres = expt_config["workflow"]["CRES"] + os.environ["CRES"] = cres + os.environ["MEMBER"] = member + expt_config.dereference( + context={ + "cycle": cycle, + **os.environ, + **expt_config, + } + ) + chgres_cube_driver = ChgresCube( + config=config_file, + cycle=cycle, + key_path=key_path, + ) + rundir = Path(chgres_cube_driver.config["rundir"]) + logging.info(f"Will run in {rundir}") + + chgres_cube_config = _walk_key_path(expt_config, key_path) + input_type = chgres_cube_config["chgres_cube"]["namelist"]["update_values"][ + "config" + ].get("input_type") + + varsfilepath = chgres_cube_config["input_files_metadata_path"] + external_config = get_yaml_config(varsfilepath) + external_config_fns = external_config["external_model_fns"] + external_config_fhrs = external_config["external_model_fhrs"] + + # update config for ics task, run and stage data + if "task_make_ics" in key_path: + if input_type == "grib2": + os.environ["fn_grib2"] = external_config_fns[0] + else: + os.environ["fn_atm"] = external_config_fns[0] + os.environ["fn_sfc"] = external_config_fns[1] + # reinstantiate driver + expt_config_cp = get_yaml_config(deepcopy(expt_config.data)) + expt_config_cp.dereference( + context={ + "cycle": cycle, + **os.environ, + **expt_config_cp, + } + ) + chgres_cube_driver = ChgresCube( + config=expt_config_cp, + cycle=cycle, + key_path=key_path, + ) + chgres_cube_driver.run() + + # Deliver output data to a common location above the rundir. + links = {} + + output_dir = os.path.join(rundir.parent, "INPUT") + os.makedirs(output_dir, exist_ok=True) + task_get_block = _walk_key_path(expt_config_cp, {"task_get_extrn_ics"}) + task_make_block = _walk_key_path(expt_config_cp, key_path) + for i, output_fn in enumerate(task_make_block["output_file_labels"]): + input_fn = task_get_block["output_file_labels"][i] + links[output_fn] = str(rundir / input_fn) + + uwlink(target_dir=output_dir, config=links) + + # update config for lbcs task, loop run and stage data + else: + num_fhrs = len(external_config_fhrs) + + bcgrp10 = 0 + bcgrpnum10 = 1 + for ii in range(bcgrp10, num_fhrs, bcgrpnum10): + i = ii + bcgrp10 + if i < num_fhrs: + print(f"group {bcgrp10} processes member {i}") + if input_type == "grib2": + os.environ["fn_grib2"] = external_config_fns[i] + else: + os.environ["fn_atm"] = external_config_fns[i] + + lbc_spec_fhrs = external_config_fhrs[i] + lbc_offset_fhrs = expt_config["task_get_extrn_lbcs"]["envvars"][ + "EXTRN_MDL_LBCS_OFFSET_HRS" + ] + fcst_hhh = int(lbc_spec_fhrs) - int(lbc_offset_fhrs) + os.environ["fcst_hhh_FV3LAM"] = f"{fcst_hhh:03d}" + + # reinstantiate driver + expt_config_cp = get_yaml_config(deepcopy(expt_config.data)) + expt_config_cp.dereference( + context={ + "cycle": cycle, + **os.environ, + **expt_config_cp, + } + ) + chgres_cube_driver = ChgresCube( + config=expt_config_cp, + cycle=cycle, + key_path=key_path, + ) + chgres_cube_driver.run() + + # Deliver output data to a common location above the rundir. + links = {} + + task_get_block = _walk_key_path(expt_config_cp, {"task_get_extrn_lbcs"}) + task_make_block = _walk_key_path(expt_config_cp, key_path) + + output_dir = os.path.join(rundir.parent, "INPUT") + os.makedirs(output_dir, exist_ok=True) + + lbc_input_fn = task_get_block["output_file_labels"][0] + lbc_output_fn = task_make_block["output_file_labels"][0] + links[lbc_output_fn] = str(rundir / lbc_input_fn) + uwlink(target_dir=output_dir, config=links) + + # error message + if not (rundir / "runscript.chgres_cube.done").is_file(): + print("Error occurred running chgres_cube. Please see component error logs.") + sys.exit(1) + + +if __name__ == "__main__": + + use_uwtools_logger() + + args = parse_args(sys.argv[1:]) + run_chgres_cube( + config_file=args.config_file, + cycle=args.cycle, + key_path=args.key_path, + member=args.member, + ) diff --git a/scripts/exregional_get_extrn_mdl_files.sh b/scripts/exregional_get_extrn_mdl_files.sh index 554cf2cc4..8a2e1265f 100755 --- a/scripts/exregional_get_extrn_mdl_files.sh +++ b/scripts/exregional_get_extrn_mdl_files.sh @@ -240,9 +240,9 @@ fi mkdir -p ${EXTRN_MDL_STAGING_DIR} if [ $RUN_ENVIR = "nco" ]; then - EXTRN_DEFNS="${NET}.${cycle}.${EXTRN_MDL_NAME}.${ICS_OR_LBCS}.${EXTRN_MDL_VAR_DEFNS_FN}.sh" + EXTRN_DEFNS="${NET}.${cycle}.${EXTRN_MDL_NAME}.${ICS_OR_LBCS}.${EXTRN_MDL_VAR_DEFNS_FN}.yaml" else - EXTRN_DEFNS="${EXTRN_MDL_VAR_DEFNS_FN}.sh" + EXTRN_DEFNS="${EXTRN_MDL_VAR_DEFNS_FN}.yaml" fi cmd=" python3 -u ${USHdir}/retrieve_data.py \ diff --git a/ush/ccpp_suites_defaults.yaml b/ush/ccpp_suites_defaults.yaml index c7c15f09d..fa9f85347 100644 --- a/ush/ccpp_suites_defaults.yaml +++ b/ush/ccpp_suites_defaults.yaml @@ -1,3 +1,8 @@ +chgres_cube_gsd_defaults: &chgres_cube_gsd_defaults + namelist: + update_values: + config: + varmap_file: "{{ user.PARMdir }}/ufs_utils/varmap_tables/GSDphys_var_map.txt" orog_gsl_defaults: &orog_gsl_defaults config: @@ -19,18 +24,56 @@ orog_gsl_defaults: &orog_gsl_defaults rundir: "{{ task_make_orog.rundir }}/orog_gsl" FV3_RAP: + task_make_ics: + chgres_cube: + <<: *chgres_cube_gsd_defaults + task_make_lbcs: + chgres_cube: + <<: *chgres_cube_gsd_defaults task_make_orog: orog_gsl: <<: *orog_gsl_defaults FV3_HRRR: + task_make_ics: + chgres_cube: + <<: *chgres_cube_gsd_defaults + task_make_lbcs: + chgres_cube: + <<: *chgres_cube_gsd_defaults task_make_orog: orog_gsl: <<: *orog_gsl_defaults +FV3_WoFS_v0: + task_make_ics: + chgres_cube: + <<: *chgres_cube_gsd_defaults + task_make_lbcs: + chgres_cube: + <<: *chgres_cube_gsd_defaults +FV3_RRFS_v1beta: + task_make_ics: + chgres_cube: + <<: *chgres_cube_gsd_defaults + task_make_lbcs: + chgres_cube: + <<: *chgres_cube_gsd_defaults FV3_GFS_v15_thompson_mynn_lam3km: + task_make_ics: + chgres_cube: + <<: *chgres_cube_gsd_defaults + task_make_lbcs: + chgres_cube: + <<: *chgres_cube_gsd_defaults task_make_orog: orog_gsl: <<: *orog_gsl_defaults FV3_GFS_v17_p8: + task_make_ics: + chgres_cube: + <<: *chgres_cube_gsd_defaults + task_make_lbcs: + chgres_cube: + <<: *chgres_cube_gsd_defaults task_make_orog: orog_gsl: <<: *orog_gsl_defaults diff --git a/ush/config_defaults.yaml b/ush/config_defaults.yaml index 0bd7d8b4d..15bf72163 100644 --- a/ush/config_defaults.yaml +++ b/ush/config_defaults.yaml @@ -1611,6 +1611,12 @@ task_get_extrn_ics: USE_USER_STAGED_EXTRN_FILES: false EXTRN_MDL_SOURCE_BASEDIR_ICS: "" EXTRN_MDL_FILES_ICS: "" + rundir: '{{ workflow.EXPTDIR }}/{{ timevars.yyyymmddhh }}/{{ task_get_extrn_ics.envvars.EXTRN_MDL_NAME_ICS }}/for_ICS{{ "/mem%s" % ("MEMBER"|env) if global.DO_ENSEMBLE }}' + output_file_labels: + - "out.atm.tile{{ constants.TILE_RGNL }}.nc" + - "out.sfc.tile{{ constants.TILE_RGNL }}.nc" + - "gfs_ctrl.nc" + - "gfs.bndy.nc" #---------------------------- # EXTRN LBCS config parameters @@ -1692,19 +1698,14 @@ task_get_extrn_lbcs: USE_USER_STAGED_EXTRN_FILES: false EXTRN_MDL_SOURCE_BASEDIR_LBCS: "" EXTRN_MDL_FILES_LBCS: "" + rundir: '{{ workflow.EXPTDIR }}/{{ timevars.yyyymmddhh }}/{{ task_get_extrn_lbcs.envvars.EXTRN_MDL_NAME_LBCS }}/for_LBCS{{ "/mem%s" % ("MEMBER"|env) if global.DO_ENSEMBLE }}' + output_file_labels: + - "gfs.bndy.nc" #---------------------------- # MAKE ICS config parameters #----------------------------- task_make_ics: - - chgres_cube: - execution: &chgres_cube_execution - batchargs: - walltime: 00:30:00 - threads: 1 - nodes: 4 - tasks_per_node: 12 #----------------------------------------------------------------------- # KMP_AFFINITY_MAKE_ICS: # Intel Thread Affinity Interface for the make_ics task. @@ -1757,14 +1758,58 @@ task_make_ics: FVCOM_DIR: "" FVCOM_FILE: "fvcom.nc" VCOORD_FILE: "{{ workflow.FIXam }}/global_hyblev.l65.txt" + #------------------------------------------------------------------------ + input_files_metadata_path: '{{ task_get_extrn_ics.envvars.rundir }}/{{ workflow.EXTRN_MDL_VAR_DEFNS_FN }}.yaml' + chgres_cube: + execution: &chgres_cube_execution + batchargs: + nodes: 4 + tasks_per_node: 12 + walltime: 00:30:00 + envcmds: + - module use {{ user.HOMEdir }}/modulefiles + - module load build_{{ user.MACHINE|lower }}_{{ workflow.COMPILER }} + executable: "{{ user.EXECdir }}/chgres_cube" + mpicmd: '{{ platform.BATCH_RUN_CMD }}' + namelist: + update_values: + config: + convert_atm: true + convert_nst: true + convert_sfc: true + cycle_day: !int "{{ cycle.strftime('%d') }}" + cycle_hour: !int "{{ cycle.strftime('%H') }}" + cycle_mon: !int "{{ cycle.strftime('%m') }}" + data_dir_input_grid: '{{ task_get_extrn_ics.envvars.rundir }}' + external_model: "FV3GFS" + fix_dir_target_grid: "{{ workflow.FIXlam }}" + halo_blend: !int "{{ global.HALO_BLEND }}" + halo_bndy: !int "{{ constants.NH4 }}" + input_type: "gaussian_nemsio" + lai_from_climo: true + minmax_vgfrc_from_climo: true + mosaic_file_target_grid: "{{ workflow.FIXlam }}/{{ 'CRES' | env }}_mosaic.halo{{ constants.NH4 }}.nc" + nsoill_out: 4 + orog_dir_target_grid: "{{ workflow.FIXlam }}" + orog_files_target_grid: "{{ 'CRES' | env }}_oro_data.tile{{ constants.TILE_RGNL }}.halo{{ constants.NH4 }}.nc" + regional: 1 + sotyp_from_climo: true + tg3_from_soil: false + varmap_file: "{{ user.PARMdir }}/ufs_utils/varmap_tables/GFSphys_var_map.txt" + vcoord_file_target_grid: "{{ workflow.FIXam }}/global_hyblev.l65.txt" + vgtyp_from_climo: true + vgfrc_from_climo: true + rundir: '{{ task_run_fcst.rundir }}/tmp_MAKE_ICS' + output_file_labels: + - '{{ nco.NET_default }}.t{{ timevars.hh }}z{{ ".mem%s" % ("MEMBER"|env) if global.DO_ENSEMBLE }}.sfc_data.tile{{ constants.TILE_RGNL }}.halo{{ constants.NH0 }}.nc' + - '{{ nco.NET_default }}.t{{ timevars.hh }}z{{ ".mem%s" % ("MEMBER"|env) if global.DO_ENSEMBLE }}.gfs_data.tile{{ constants.TILE_RGNL }}.halo{{ constants.NH0 }}.nc' + - '{{ nco.NET_default }}.t{{ timevars.hh }}z.gfs_ctrl.nc' + - '{{ nco.NET_default }}.t{{ timevars.hh }}z{{ ".mem%s" % ("MEMBER"|env) if global.DO_ENSEMBLE }}.gfs_bndy.tile{{ constants.TILE_RGNL }}.f000.nc' #---------------------------- # MAKE LBCS config parameters #----------------------------- task_make_lbcs: - chgres_cube: - execution: - <<: *chgres_cube_execution #------------------------------------------------------------------------ # # KMP_AFFINITY_MAKE_LBCS: @@ -1786,6 +1831,33 @@ task_make_lbcs: OMP_NUM_THREADS_MAKE_LBCS: 1 OMP_STACKSIZE_MAKE_LBCS: "1024m" VCOORD_FILE: "{{ workflow.FIXam }}/global_hyblev.l65.txt" + #------------------------------------------------------------------------ + input_files_metadata_path: '{{ task_get_extrn_lbcs.envvars.rundir }}/{{ workflow.EXTRN_MDL_VAR_DEFNS_FN }}.yaml' + chgres_cube: + execution: + <<: *chgres_cube_execution + namelist: + update_values: + config: + convert_atm: true + cycle_day: !int "{{ cycle.strftime('%d') }}" + cycle_hour: !int "{{ cycle.strftime('%H') }}" + cycle_mon: !int "{{ cycle.strftime('%m') }}" + data_dir_input_grid: '{{ task_get_extrn_lbcs.envvars.rundir }}' + external_model: "FV3GFS" + fix_dir_target_grid: "{{ workflow.FIXlam }}" + halo_blend: !int "{{ global.HALO_BLEND }}" + halo_bndy: !int "{{ constants.NH4 }}" + input_type: "gaussian_nemsio" + mosaic_file_target_grid: "{{ workflow.FIXlam }}/{{ 'CRES' | env }}_mosaic.halo{{ constants.NH4 }}.nc" + orog_dir_target_grid: "{{ workflow.FIXlam }}" + orog_files_target_grid: "{{ 'CRES' | env }}_oro_data.tile{{ constants.TILE_RGNL }}.halo{{ constants.NH4 }}.nc" + regional: 2 + varmap_file: "{{ user.PARMdir }}/ufs_utils/varmap_tables/GFSphys_var_map.txt" + vcoord_file_target_grid: "{{ workflow.FIXam }}/global_hyblev.l65.txt" + rundir: '{{ task_run_fcst.rundir}}/tmp_MAKE_LBCS' + output_file_labels: + - '{{ nco.NET_default }}.t{{ timevars.hh }}z{{ ".mem%s" % ("MEMBER"|env) if global.DO_ENSEMBLE }}.gfs_bndy.tile7.f{{ "fcst_hhh_FV3LAM" | env }}.nc' #---------------------------- # IO_LAYOUT_Y FORECAST config parameters diff --git a/ush/external_model_defaults.yaml b/ush/external_model_defaults.yaml new file mode 100644 index 000000000..a57d5a583 --- /dev/null +++ b/ush/external_model_defaults.yaml @@ -0,0 +1,164 @@ +FV3GFS: + task_make_ics: + chgres_cube: + namelist: + update_values: + config: + atm_files_input_grid: "{{ 'fn_atm' | env }}" + sfc_files_input_grid: "{{ 'fn_sfc' | env }}" + tracers_input: ["spfh","clwmr","o3mr","icmr","rwmr","snmr","grle"] + tracers: ["sphum","liq_wat","o3mr","ice_wat","rainwat","snowwat","graupel"] + task_make_lbcs: + chgres_cube: + namelist: + update_values: + config: + atm_files_input_grid: "{{ 'fn_atm' | env }}" + tracers_input: ["spfh","clwmr","o3mr","icmr","rwmr","snmr","grle"] + tracers: ["sphum","liq_wat","o3mr","ice_wat","rainwat","snowwat","graupel"] + +GSMGFS: + task_make_ics: + chgres_cube: + namelist: + update_values: + config: + atm_files_input_grid: "{{ 'fn_atm' | env }}" + external_model: "GSMGFS" + convert_nst: False + input_type: "gfs_gaussian_nemsio" + sfc_files_input_grid: "{{ 'fn_sfc' | env }}" + tracers_input: ["spfh","clwmr","o3mr"] + tracers: ["sphum","liq_wat","o3mr"] + task_make_lbcs: + chgres_cube: + namelist: + update_values: + config: + atm_files_input_grid: "{{ 'fn_atm' | env }}" + convert_nst: False + external_model: "GSMGFS" + input_type: "gfs_gaussian_nemsio" + tracers_input: ["spfh","clwmr","o3mr"] + tracers: ["sphum","liq_wat","o3mr"] + +UFS-CASE-STUDY: + task_make_ics: + chgres_cube: + namelist: + update_values: + config: + atm_files_input_grid: "{{ 'fn_atm' | env }}" + external_model: "UFS-CASE-STUDY" + sfc_files_input_grid: "{{ 'fn_sfc' | env }}" + tracers_input: ["spfh","clwmr","o3mr","icmr","rwmr","snmr","grle"] + tracers: ["sphum","liq_wat","o3mr","ice_wat","rainwat","snowwat","graupel"] + task_make_lbcs: + chgres_cube: + namelist: + update_values: + config: + atm_files_input_grid: "{{ 'fn_atm' | env }}" + external_model: "UFS-CASE-STUDY" + tracers_input: ["spfh","clwmr","o3mr","icmr","rwmr","snmr","grle"] + tracers: ["sphum","liq_wat","o3mr","ice_wat","rainwat","snowwat","graupel"] + +GDAS: + task_make_ics: + chgres_cube: + namelist: + update_values: + config: + external_model: "GFS" + tg3_from_soil: True + tracers_input: ["spfh","clwmr","o3mr","icmr","rwmr","snmr","grle"] + tracers: ["sphum","liq_wat","o3mr","ice_wat","rainwat","snowwat","graupel"] + task_make_lbcs: + chgres_cube: + namelist: + update_values: + config: + atm_files_input_grid: "{{ 'fn_atm' | env }}" + external_model: "GFS" + tracers_input: ["spfh","clwmr","o3mr","icmr","rwmr","snmr","grle"] + tracers: ["sphum","liq_wat","o3mr","ice_wat","rainwat","snowwat","graupel"] + +GEFS: + task_make_ics: + chgres_cube: + namelist: + update_values: + config: + convert_nst: False + external_model: "GFS" + grib2_file_input_grid: "{{ 'fn_grib2' | env }}" + input_type: "grib2" + task_make_lbcs: + chgres_cube: + namelist: + update_values: + config: + external_model: "GFS" + grib2_file_input_grid: "{{ 'fn_grib2' | env }}" + input_type: "grib2" + +HRRR: + task_make_ics: + chgres_cube: + namelist: + update_values: + config: + convert_nst: False + external_model: "HRRR" + geogrid_file_input_grid: "{{ platform.FIXgsm }}/geo_em.d01.nc_HRRRX" + grib2_file_input_grid: "{{ 'fn_grib2' | env }}" + input_type: "grib2" + tg3_from_soil: True + task_make_lbcs: + chgres_cube: + namelist: + update_values: + config: + external_model: "HRRR" + grib2_file_input_grid: "{{ 'fn_grib2' | env }}" + input_type: "grib2" + +RAP: + task_make_ics: + chgres_cube: + namelist: + update_values: + config: + convert_nst: False + external_model: "RAP" + geogrid_file_input_grid: "{{ platform.FIXgsm }}/geo_em.d01.nc_RAPX" + grib2_file_input_grid: "{{ 'fn_grib2' | env }}" + input_type: "grib2" + tg3_from_soil: True + task_make_lbcs: + chgres_cube: + namelist: + update_values: + config: + external_model: "RAP" + grib2_file_input_grid: "{{ 'fn_grib2' | env }}" + input_type: "grib2" + +NAM: + task_make_ics: + chgres_cube: + namelist: + update_values: + config: + convert_nst: False + external_model: "NAM" + grib2_file_input_grid: "{{ 'fn_grib2' | env }}" + input_type: "grib2" + task_make_lbcs: + chgres_cube: + namelist: + update_values: + config: + external_model: "NAM" + grib2_file_input_grid: "{{ 'fn_grib2' | env }}" + input_type: "grib2" diff --git a/ush/retrieve_data.py b/ush/retrieve_data.py index 5acf9d5ce..fe20d754c 100755 --- a/ush/retrieve_data.py +++ b/ush/retrieve_data.py @@ -742,18 +742,16 @@ def write_summary_file(cla, data_store, file_templates): output_path = fill_template(cla.output_path, cla.cycle_date, mem=mem) summary_fp = os.path.join(output_path, cla.summary_file) logging.info(f"Writing a summary file to {summary_fp}") - file_contents = dedent( - f""" - DATA_SRC={data_store} - EXTRN_MDL_CDATE={cla.cycle_date.strftime('%Y%m%d%H')} - EXTRN_MDL_STAGING_DIR={output_path} - EXTRN_MDL_FNS=( {' '.join(files)} ) - EXTRN_MDL_FHRS=( {' '.join([str(i) for i in cla.fcst_hrs])} ) - """ - ) + file_contents = { + "data_source": data_store, + "external_model_cdate": cla.cycle_date.strftime('%Y%m%d%H'), + "external_model_staging_dir": output_path, + "external_model_fns": files, + "external_model_fhrs": [str(i) for i in cla.fcst_hrs] + } logging.info(f"Contents: {file_contents}") - with open(summary_fp, "w") as summary: - summary.write(file_contents) + with open(summary_fp, "w") as f: + yaml.dump(file_contents, f) def to_datetime(arg): diff --git a/ush/setup.py b/ush/setup.py index 3f962b5bf..09cddb785 100644 --- a/ush/setup.py +++ b/ush/setup.py @@ -146,6 +146,16 @@ def load_config_for_setup(ushdir, default_config_path, user_config_path): ccpp_config = get_yaml_config(ushdir / "ccpp_suites_defaults.yaml").get(ccpp_suite, {}) default_config.update_from(ccpp_config) + # Load external model-specific settings + tasks = [("task_get_extrn_ics", "EXTRN_MDL_NAME_ICS", "task_make_lbcs"), + ("task_get_extrn_lbcs", "EXTRN_MDL_NAME_LBCS", "task_make_ics")] + + for task, mdl_key, make_key in tasks: + external_mdl = default_config[task]["envvars"][mdl_key] + external_cfg = get_yaml_config(Path(ushdir, "external_model_defaults.yaml")).get(external_mdl, {}) + del external_cfg[make_key] + default_config.update_from(external_cfg) + # Set "Home" directory, the top-level ufs-srweather-app directory homedir = Path(__file__).parent.parent.resolve() default_config["user"]["HOMEdir"] = str(homedir)