From 3c0e7e0175ec05ef30508d86fdb325257e6c09b6 Mon Sep 17 00:00:00 2001 From: danielabdi-noaa <52012304+danielabdi-noaa@users.noreply.github.com> Date: Wed, 7 Sep 2022 20:29:56 -0600 Subject: [PATCH] [develop]: Use yaml format for specifying experiment parameters (#778) * Construct var_defns components from dictionary. * Bring back config_defaults.yaml * Add support for sourcing yaml file into shell script. * Remove newline for printing config, json config fix. * Make QUILTING a sub-dictionary in predef_grids * Reorganize config_defaults.yaml by task and feature. * Bug fix with QUILTING=true. * Structure a dictionary based on a template dictionary. * Convert all WE2E config files to yaml. * Take care of problematic chars when converting to shell string. * Process only selected keys of config. * Add symlinked yaml config files. * Actually use yaml config files for WE2E tests. * Delete all shell WE2E configs. * Don't check for single quotes in test description. * Make WE2E work with yaml configs. * Make yaml default config format. * Bug fix in run_WE2E script. * Add utility to check validity of yaml config file. * Add config utility interface in ush directory. * Remove unused check_expt_config_vars script. * Add description to default config. * Reorganize source_config. * Add XML as one of the config formats. * Update custom_ESGgrid config. * Bug fix due to update. * Change ensemble seed. * Change POST_OUTPUT group due to merge. * Make xml and ini configs work. * Maintain config structure down to var_defns. * Add function to load structured shell config, put description under metadata * Flatten dicts before importing env now that shell config is structured. * Support python regex for selecting dict keys. * Add capability of sourcing task specific portion of config file. * Access var_defns via env variable. * Make names of tasks consistent with ex- and j- job script names. * Append pid to temp file. * Prettify user config, don't use " in xml texts. * Compare timestamp of csv vs all files instead of directory. * Fixes for some pylint suggestions. * Convert new configs to yaml. * Format python files with black (no functional change). * More readable yaml/json formats by using more data types. Only datetime type is now in quotes. * More readable yaml config files for WE2E and default configs. * Make config_defaults itself more readable. * Correct pyyaml list indentation issue. * Fix indentation in all config files. * Use unquoted WTIME in config_defaults * Cosmotic changes. * Fix due to merge. * Make __init__.py clearer. * Fixes due to merge. * Minor edits of comments. * Remove wcoss_dell_p3 from workflow (#810) * remove wcoss_dell_p3 * remove block for tide and gyre * Replace deprecated NCAR python environment with conda on Cheyenne (#812) * Fix issue on get_extrn_lbcs when FCST_LEN_HRS>=40 with netcdf (#814) * activate b file on hpss for >40h * add a new we2e test for fcst_len_hrs>40 * reduce fcst time for we2e * Convert new test case to yaml. * Fix formatting due to merge. * Convert new test case to yaml. * Fix unittest. * Merge develop * Remove exception logic from __init__.py * Minor change to cmd concat. * Make grid gen methods return dictionary, simplifis code a lot. * Add a comment why we are suppressing yaml import exception. * Minor change to beautify unittest output. * Add status badge for functional tests. * Reorder tasks in config_default and we2e test cases to match order in FV3LAM.xml * Keep single quotes and newlines in we2e test description. * Revert back to not rounding to 10 digits Co-authored-by: Chan-Hoo.Jeon-NOAA <60152248+chan-hoo@users.noreply.github.com> Co-authored-by: Michael Kavulich --- .github/workflows/python_func_tests.yaml | 2 +- .github/workflows/python_unittests.yaml | 2 +- README.md | 1 + scripts/exregional_make_grid.sh | 2 +- scripts/exregional_make_orog.sh | 2 +- scripts/exregional_make_sfc_climo.sh | 2 +- .../WE2E/get_WE2Etest_names_subdirs_descs.sh | 165 +- tests/WE2E/run_WE2E_tests.sh | 34 +- ...id_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh | 26 - ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml | 25 + ...id_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh | 26 - ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml | 25 + ...km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh | 25 - ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml | 24 + ...km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh | 25 - ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml | 24 + ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.sh | 25 - ...cs_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.yaml | 24 + ...km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh | 25 - ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml | 24 + ..._13km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.sh | 25 - ...3km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.yaml | 24 + ...cs_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh | 25 - ..._FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml | 24 + ...V3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp.sh | 25 - ...GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp.yaml | 24 + ...s_FV3GFS_suite_GFS_2017_gfdlmp_regional.sh | 25 - ...FV3GFS_suite_GFS_2017_gfdlmp_regional.yaml | 24 + ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.sh | 25 - ...cs_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.yaml | 24 + ...km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh | 25 - ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml | 24 + ..._25km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.sh | 25 - ...5km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.yaml | 24 + ...cs_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh | 25 - ..._FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml | 24 + ...NUS_25km_ics_FV3GFS_lbcs_RAP_suite_HRRR.sh | 32 - ...S_25km_ics_FV3GFS_lbcs_RAP_suite_HRRR.yaml | 31 + ...SMGFS_lbcs_GSMGFS_suite_GFS_2017_gfdlmp.sh | 25 - ...GFS_lbcs_GSMGFS_suite_GFS_2017_gfdlmp.yaml | 24 + ..._ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v15p2.sh | 25 - ...cs_GSMGFS_lbcs_GSMGFS_suite_GFS_v15p2.yaml | 24 + ...km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v16.sh | 25 - ..._ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v16.yaml | 24 + ..._CONUS_25km_ics_NAM_lbcs_NAM_suite_HRRR.sh | 25 - ...ONUS_25km_ics_NAM_lbcs_NAM_suite_HRRR.yaml | 24 + ...25km_ics_NAM_lbcs_NAM_suite_RRFS_v1beta.sh | 25 - ...km_ics_NAM_lbcs_NAM_suite_RRFS_v1beta.yaml | 24 + ...3GFS_suite_GFS_v15_thompson_mynn_lam3km.sh | 27 - ...FS_suite_GFS_v15_thompson_mynn_lam3km.yaml | 25 + ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.sh | 25 - ...cs_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.yaml | 24 + ...km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh | 25 - ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml | 24 + ...S_3km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.sh | 25 - ...3km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.yaml | 24 + ...cs_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh | 25 - ..._FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml | 24 + ...km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh | 25 - ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml | 24 + ...mpact_13km_ics_HRRR_lbcs_RAP_suite_HRRR.sh | 28 - ...act_13km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml | 29 + ...3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh | 27 - ...m_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml | 28 + ...km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh | 25 - ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml | 24 + ...pact_25km_ics_HRRR_lbcs_HRRR_suite_HRRR.sh | 28 - ...ct_25km_ics_HRRR_lbcs_HRRR_suite_HRRR.yaml | 28 + ...km_ics_HRRR_lbcs_HRRR_suite_RRFS_v1beta.sh | 27 - ..._ics_HRRR_lbcs_HRRR_suite_RRFS_v1beta.yaml | 28 + ...mpact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.sh | 27 - ...act_25km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml | 28 + ...5km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh | 27 - ...m_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml | 28 + ...km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh | 25 - ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml | 24 + ...t_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.sh | 27 - ...3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.yaml | 28 + ...ompact_3km_ics_HRRR_lbcs_RAP_suite_HRRR.sh | 28 - ...pact_3km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml | 28 + ...3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh | 28 - ...m_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml | 29 + ...cs_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh | 54 - ..._FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml | 39 + ...cs_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh | 54 - ..._FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml | 39 + ...km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh | 25 - ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml | 24 + ...S_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.sh | 28 - ...3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.yaml | 29 + ...km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh | 27 - ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml | 26 + ...US_Ind_3km_ics_HRRR_lbcs_RAP_suite_HRRR.sh | 27 - ..._Ind_3km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml | 28 + ...3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh | 27 - ...m_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml | 28 + ...km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh | 26 - ..._ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml | 24 + ...3GFS_suite_GFS_v15_thompson_mynn_lam3km.sh | 28 - ...FS_suite_GFS_v15_thompson_mynn_lam3km.yaml | 25 + ...mpact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.sh | 29 - ...act_25km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml | 29 + .../config.GST_release_public_v1.sh | 28 - .../config.GST_release_public_v1.yaml | 26 + .../config.MET_ensemble_verification.sh | 38 - .../config.MET_ensemble_verification.yaml | 36 + .../wflow_features/config.MET_verification.sh | 33 - .../config.MET_verification.yaml | 31 + .../config.community_ensemble_008mems.sh | 31 - .../config.community_ensemble_008mems.yaml | 31 + .../config.community_ensemble_2mems.sh | 35 - .../config.community_ensemble_2mems.yaml | 34 + .../config.community_ensemble_2mems_stoch.sh | 38 - ...config.community_ensemble_2mems_stoch.yaml | 39 + .../wflow_features/config.custom_ESGgrid.sh | 65 - .../wflow_features/config.custom_ESGgrid.yaml | 53 + .../wflow_features/config.custom_GFDLgrid.sh | 94 - .../config.custom_GFDLgrid.yaml | 65 + ...rid_USE_NUM_CELLS_IN_FILENAMES_eq_FALSE.sh | 81 - ...d_USE_NUM_CELLS_IN_FILENAMES_eq_FALSE.yaml | 57 + ...grid_USE_NUM_CELLS_IN_FILENAMES_eq_TRUE.sh | 81 - ...id_USE_NUM_CELLS_IN_FILENAMES_eq_TRUE.yaml | 57 + .../wflow_features/config.deactivate_tasks.sh | 60 - .../config.deactivate_tasks.yaml | 48 + ...FV3GFS_lbcs_FV3GFS_fmt_grib2_2019061200.sh | 27 - ...3GFS_lbcs_FV3GFS_fmt_grib2_2019061200.yaml | 25 + ...FV3GFS_lbcs_FV3GFS_fmt_grib2_2019101818.sh | 29 - ...3GFS_lbcs_FV3GFS_fmt_grib2_2019101818.yaml | 27 + ...FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022518.sh | 28 - ...3GFS_lbcs_FV3GFS_fmt_grib2_2020022518.yaml | 26 + ...FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022600.sh | 28 - ...3GFS_lbcs_FV3GFS_fmt_grib2_2020022600.yaml | 26 + ...FV3GFS_lbcs_FV3GFS_fmt_grib2_2021010100.sh | 28 - ...3GFS_lbcs_FV3GFS_fmt_grib2_2021010100.yaml | 26 + ..._HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.sh | 24 - ...PSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.yaml | 22 + ...V3GFS_lbcs_FV3GFS_fmt_nemsio_2019061200.sh | 27 - ...GFS_lbcs_FV3GFS_fmt_nemsio_2019061200.yaml | 25 + ...V3GFS_lbcs_FV3GFS_fmt_nemsio_2019101818.sh | 29 - ...GFS_lbcs_FV3GFS_fmt_nemsio_2019101818.yaml | 27 + ...V3GFS_lbcs_FV3GFS_fmt_nemsio_2020022518.sh | 28 - ...GFS_lbcs_FV3GFS_fmt_nemsio_2020022518.yaml | 26 + ...V3GFS_lbcs_FV3GFS_fmt_nemsio_2020022600.sh | 28 - ...GFS_lbcs_FV3GFS_fmt_nemsio_2020022600.yaml | 26 + ...V3GFS_lbcs_FV3GFS_fmt_nemsio_2021010100.sh | 28 - ...GFS_lbcs_FV3GFS_fmt_nemsio_2021010100.yaml | 26 + ...V3GFS_lbcs_FV3GFS_fmt_netcdf_2021062000.sh | 26 - ...GFS_lbcs_FV3GFS_fmt_netcdf_2021062000.yaml | 24 + ...S_lbcs_FV3GFS_fmt_netcdf_2022060112_48h.sh | 26 - ...lbcs_FV3GFS_fmt_netcdf_2022060112_48h.yaml | 24 + ...ig.get_from_HPSS_ics_GSMGFS_lbcs_GSMGFS.sh | 24 - ....get_from_HPSS_ics_GSMGFS_lbcs_GSMGFS.yaml | 22 + .../config.get_from_HPSS_ics_HRRR_lbcs_RAP.sh | 28 - ...onfig.get_from_HPSS_ics_HRRR_lbcs_RAP.yaml | 28 + .../config.get_from_HPSS_ics_RAP_lbcs_RAP.sh | 24 - ...config.get_from_HPSS_ics_RAP_lbcs_RAP.yaml | 22 + ...OMADS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.sh | 27 - ...ADS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.yaml | 26 + .../wflow_features/config.inline_post.sh | 26 - .../wflow_features/config.inline_post.yaml | 24 + .../wflow_features/config.nco_ensemble.sh | 35 - .../wflow_features/config.nco_ensemble.yaml | 34 + .../wflow_features/config.nco_inline_post.sh | 1 - .../config.nco_inline_post.yaml | 1 + .../config.pregen_grid_orog_sfc_climo.sh | 28 - .../config.pregen_grid_orog_sfc_climo.yaml | 27 + .../config.specify_DOT_OR_USCORE.sh | 39 - .../config.specify_DOT_OR_USCORE.yaml | 35 + ...ig.specify_DT_ATMOS_LAYOUT_XY_BLOCKSIZE.sh | 32 - ....specify_DT_ATMOS_LAYOUT_XY_BLOCKSIZE.yaml | 32 + ...g.specify_EXTRN_MDL_SYSBASEDIR_ICS_LBCS.sh | 29 - ...specify_EXTRN_MDL_SYSBASEDIR_ICS_LBCS.yaml | 26 + .../config.specify_RESTART_INTERVAL.sh | 27 - .../config.specify_RESTART_INTERVAL.yaml | 25 + .../config.specify_template_filenames.sh | 30 - .../config.specify_template_filenames.yaml | 28 + .../wflow_features/config.subhourly_post.sh | 31 - .../wflow_features/config.subhourly_post.yaml | 31 + .../config.subhourly_post_ensemble_2mems.sh | 40 - .../config.subhourly_post_ensemble_2mems.yaml | 39 + .../wflow_features/config.template_vars.sh | 1 - .../wflow_features/config.template_vars.yaml | 1 + ush/UFS_plot_domains.py | 204 +- ush/bash_utils/source_config.sh | 94 + ush/calculate_cost.py | 130 +- ush/check_expt_config_vars.sh | 110 - ush/check_ruc_lsm.py | 20 +- ush/config.community.sh | 65 - ush/config.community.yaml | 50 + ush/config.nco.sh | 51 - ush/config.nco.yaml | 42 + ush/config_defaults.sh | 2027 ------------ ush/config_defaults.yaml | 2252 ++++++++++++++ ush/config_utils.py | 14 + ush/create_diag_table_file.py | 130 +- ush/create_model_configure_file.py | 424 +-- ush/fill_jinja_template.py | 150 +- ush/generate_FV3LAM_wflow.py | 1258 ++++---- ush/get_crontab_contents.py | 183 +- ush/link_fix.py | 380 +-- ush/mrms_pull_topofhour.py | 241 +- ush/predef_grid_params.yaml | 616 ++-- ush/python_utils/__init__.py | 80 +- .../check_for_preexist_dir_file.py | 26 +- ush/python_utils/check_var_valid_value.py | 10 +- ush/python_utils/config_parser.py | 470 ++- ush/python_utils/count_files.py | 8 +- ush/python_utils/create_symlink_to_file.py | 36 +- ush/python_utils/define_macos_utilities.py | 47 +- ush/python_utils/environment.py | 115 +- ush/python_utils/filesys_cmds_vrfy.py | 28 +- ush/python_utils/fv3write_parms_lambert.py | 102 +- ush/python_utils/get_charvar_from_netcdf.py | 22 +- ush/python_utils/get_elem_inds.py | 20 +- ush/python_utils/interpol_to_arbit_CRES.py | 16 +- ush/python_utils/misc.py | 50 +- ush/python_utils/print_input_args.py | 31 +- ush/python_utils/print_msg.py | 15 +- ush/python_utils/process_args.py | 46 +- ush/python_utils/run_command.py | 20 +- ush/python_utils/test_python_utils.py | 187 +- ush/python_utils/xml_parser.py | 7 +- ush/retrieve_data.py | 635 ++-- ush/set_FV3nml_ens_stoch_seeds.py | 205 +- ush/set_FV3nml_sfc_climo_filenames.py | 134 +- ush/set_cycle_dates.py | 36 +- ush/set_extrn_mdl_params.py | 35 +- ush/set_gridparams_ESGgrid.py | 96 +- ush/set_gridparams_GFDLgrid.py | 300 +- ush/set_namelist.py | 156 +- ush/set_ozone_param.py | 198 +- ush/set_predef_grid_params.py | 68 +- ush/set_thompson_mp_fix_files.py | 156 +- ush/setup.py | 2714 +++++++++-------- ush/source_util_funcs.sh | 8 + 235 files changed, 10394 insertions(+), 9414 deletions(-) delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_25km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_25km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_3km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_3km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp_regional.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp_regional.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_RAP_suite_HRRR.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_RAP_suite_HRRR.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_2017_gfdlmp.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_2017_gfdlmp.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v15p2.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v15p2.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v16.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v16.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_HRRR.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_HRRR.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_RRFS_v1beta.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_RRFS_v1beta.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_HRRR.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_HRRR.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_HRRR.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_RRFS_v1beta.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_RRFS_v1beta.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_HRRR.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_HRRR.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.yaml delete mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.sh create mode 100644 tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml delete mode 100644 tests/WE2E/test_configs/release_SRW_v1/config.GST_release_public_v1.sh create mode 100644 tests/WE2E/test_configs/release_SRW_v1/config.GST_release_public_v1.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.MET_ensemble_verification.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.MET_ensemble_verification.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.MET_verification.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.MET_verification.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.community_ensemble_008mems.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.community_ensemble_008mems.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems_stoch.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems_stoch.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.custom_ESGgrid.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.custom_ESGgrid.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_FALSE.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_FALSE.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_TRUE.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_TRUE.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.deactivate_tasks.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.deactivate_tasks.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019061200.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019061200.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019101818.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019101818.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022518.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022518.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022600.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022600.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2021010100.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2021010100.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019061200.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019061200.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019101818.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019101818.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022518.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022518.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022600.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022600.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2021010100.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2021010100.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2021062000.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2021062000.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2022060112_48h.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2022060112_48h.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_GSMGFS_lbcs_GSMGFS.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_GSMGFS_lbcs_GSMGFS.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_HRRR_lbcs_RAP.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_HRRR_lbcs_RAP.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_RAP_lbcs_RAP.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_RAP_lbcs_RAP.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_NOMADS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.get_from_NOMADS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.inline_post.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.inline_post.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.nco_ensemble.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.nco_ensemble.yaml delete mode 120000 tests/WE2E/test_configs/wflow_features/config.nco_inline_post.sh create mode 120000 tests/WE2E/test_configs/wflow_features/config.nco_inline_post.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.pregen_grid_orog_sfc_climo.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.pregen_grid_orog_sfc_climo.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.specify_DOT_OR_USCORE.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.specify_DOT_OR_USCORE.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.specify_DT_ATMOS_LAYOUT_XY_BLOCKSIZE.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.specify_DT_ATMOS_LAYOUT_XY_BLOCKSIZE.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.specify_EXTRN_MDL_SYSBASEDIR_ICS_LBCS.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.specify_EXTRN_MDL_SYSBASEDIR_ICS_LBCS.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.specify_RESTART_INTERVAL.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.specify_RESTART_INTERVAL.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.specify_template_filenames.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.specify_template_filenames.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.subhourly_post.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.subhourly_post.yaml delete mode 100644 tests/WE2E/test_configs/wflow_features/config.subhourly_post_ensemble_2mems.sh create mode 100644 tests/WE2E/test_configs/wflow_features/config.subhourly_post_ensemble_2mems.yaml delete mode 120000 tests/WE2E/test_configs/wflow_features/config.template_vars.sh create mode 120000 tests/WE2E/test_configs/wflow_features/config.template_vars.yaml create mode 100644 ush/bash_utils/source_config.sh delete mode 100644 ush/check_expt_config_vars.sh delete mode 100644 ush/config.community.sh create mode 100644 ush/config.community.yaml delete mode 100644 ush/config.nco.sh create mode 100644 ush/config.nco.yaml delete mode 100644 ush/config_defaults.sh create mode 100644 ush/config_defaults.yaml create mode 100755 ush/config_utils.py diff --git a/.github/workflows/python_func_tests.yaml b/.github/workflows/python_func_tests.yaml index 50e2f82986..80a3f191fc 100644 --- a/.github/workflows/python_func_tests.yaml +++ b/.github/workflows/python_func_tests.yaml @@ -1,4 +1,4 @@ -name: Python unittests +name: Python functional tests on: push: paths: diff --git a/.github/workflows/python_unittests.yaml b/.github/workflows/python_unittests.yaml index 65688fd387..b67039c923 100644 --- a/.github/workflows/python_unittests.yaml +++ b/.github/workflows/python_unittests.yaml @@ -1,5 +1,5 @@ name: Python unittests -on: [push, pull_request] +on: [push, pull_request, workflow_dispatch] jobs: python_unittests: diff --git a/README.md b/README.md index e0b3e9bd52..3fc5671834 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ [![Python unittests](https://github.com/ufs-community/regional_workflow/actions/workflows/python_unittests.yaml/badge.svg)](https://github.com/ufs-community/regional_workflow/actions/workflows/python_unittests.yaml) +[![Python functional tests](https://github.com/ufs-community/regional_workflow/actions/workflows/python_func_tests.yaml/badge.svg)](https://github.com/ufs-community/regional_workflow/actions/workflows/python_func_tests.yaml) # Regional Workflow diff --git a/scripts/exregional_make_grid.sh b/scripts/exregional_make_grid.sh index bc3bca1aba..73a478b421 100755 --- a/scripts/exregional_make_grid.sh +++ b/scripts/exregional_make_grid.sh @@ -587,7 +587,7 @@ halo failed." # #----------------------------------------------------------------------- # -python3 $USHDIR/link_fix.py \ +python3 $USHDIR/link_fix.py \ --path-to-defns ${GLOBAL_VAR_DEFNS_FP} \ --file-group "grid" || \ print_err_msg_exit "\ diff --git a/scripts/exregional_make_orog.sh b/scripts/exregional_make_orog.sh index e0a5b48935..6589f6aa3b 100755 --- a/scripts/exregional_make_orog.sh +++ b/scripts/exregional_make_orog.sh @@ -572,7 +572,7 @@ cd_vrfy - # #----------------------------------------------------------------------- # -python3 $USHDIR/link_fix.py \ +python3 $USHDIR/link_fix.py \ --path-to-defns ${GLOBAL_VAR_DEFNS_FP} \ --file-group "orog" || \ print_err_msg_exit "\ diff --git a/scripts/exregional_make_sfc_climo.sh b/scripts/exregional_make_sfc_climo.sh index 995b17f305..061aed0dbb 100755 --- a/scripts/exregional_make_sfc_climo.sh +++ b/scripts/exregional_make_sfc_climo.sh @@ -233,7 +233,7 @@ esac # #----------------------------------------------------------------------- # -python3 $USHDIR/link_fix.py \ +python3 $USHDIR/link_fix.py \ --path-to-defns ${GLOBAL_VAR_DEFNS_FP} \ --file-group "sfc_climo" || \ print_err_msg_exit "\ diff --git a/tests/WE2E/get_WE2Etest_names_subdirs_descs.sh b/tests/WE2E/get_WE2Etest_names_subdirs_descs.sh index 23ef0500c2..1dfe48483d 100755 --- a/tests/WE2E/get_WE2Etest_names_subdirs_descs.sh +++ b/tests/WE2E/get_WE2Etest_names_subdirs_descs.sh @@ -405,30 +405,10 @@ function get_WE2Etest_names_subdirs_descs() { var_name_at \ vars_to_extract - local grid_gen_method \ - \ - gfdlgrid_lon_t6_ctr \ - gfdlgrid_lat_t6_ctr \ - gfdlgrid_num_cells \ - gfdlgrid_stretch_fac \ - gfdlgrid_refine_ratio \ - gfdlgrid_istart_of_rgnl_dom_on_t6g \ - gfdlgrid_iend_of_rgnl_dom_on_t6g \ - gfdlgrid_jstart_of_rgnl_dom_on_t6g \ - gfdlgrid_jend_of_rgnl_dom_on_t6g \ - \ - esggrid_lon_ctr \ - esggrid_lat_ctr \ - esggrid_nx \ - esggrid_ny \ - esggrid_pazi \ - esggrid_wide_halo_width \ - esggrid_delx \ - esggrid_dely \ - \ - nx \ - ny \ - dta + local dta \ + nxny \ + dta_r \ + nxny_r # #----------------------------------------------------------------------- # @@ -591,7 +571,11 @@ information on all WE2E tests: # statement will be false. # if [ -z "${generate_csv_file}" ]; then - mod_time_subdir=$( stat --format=%Y "${subdir_fp}" ) + if [ -f "${subdir_fp}/*.yaml" ]; then + mod_time_subdir=$( stat --format=%Y "${subdir_fp}"/*.yaml | sort -n | tail -1 ) + else + mod_time_subdir="0" + fi if [ "${mod_time_subdir}" -gt "${mod_time_csv}" ]; then generate_csv_file="TRUE" print_info_msg " @@ -633,7 +617,7 @@ to generate a new CSV file: # "config.${test_name}.sh", in which case it will be equal to ${test_name}. # Otherwise, it will be a null string. # - regex_search="^config\.(.*)\.sh$" + regex_search="^config\.(.*)\.yaml$" test_name_or_null=$( printf "%s\n" "${crnt_item}" | \ sed -n -r -e "s/${regex_search}/\1/p" ) # @@ -887,7 +871,7 @@ name (test_name) is not 1: test_name = \"${test_name}\" num_occurrences = ${num_occurrences} These configuration files all have the name - \"config.${test_name}.sh\" + \"config.${test_name}.yaml\" and are located in the following category subdirectories under test_configs_basedir: subdirs = ( $( printf "\"%s\" " "${subdirs[@]}" )) @@ -995,80 +979,11 @@ configuration files of the primary WE2E tests... # leading spaces, the hash symbol, and possibly another space and append # what remains to the local variable test_desc. # - config_fn="config.${test_name}.sh" - test_desc="" - while read -r line; do - - regex_search="^[ ]*(#)([ ]{0,1})(.*)" - hash_or_null=$( printf "%s" "${line}" | \ - sed -n -r -e "s/${regex_search}/\1/p" ) -# -# If the current line is part of the file header containing the test -# description, then... -# - if [ "${hash_or_null}" = "#" ]; then -# -# Strip from the current line any leading whitespace followed by the -# hash symbol possibly followed by a single space. If what remains is -# empty, it means there are no comments on that line and it is just a -# separator line. In that case, simply add a newline to test_desc. -# Otherwise, append what remains after stripping to what test_desc -# already contains, followed by a single space in preparation for -# appending the next (stripped) line. -# - stripped_line=$( printf "%s" "${line}" | \ - sed -n -r -e "s/${regex_search}/\3/p" ) - if [ -z "${stripped_line}" ]; then - test_desc="\ -${test_desc} - -" - else - test_desc="\ -${test_desc}${stripped_line} " - fi -# -# If the current line is not part of the file header containing the test -# description, break out of the while-loop (and thus stop reading the -# file). -# - else - break - fi - - done < "${config_fn}" -# -# At this point, test_desc contains a description of the current test. -# Note that: -# -# 1) It will be empty if the configuration file for the current test -# does not contain a header describing the test. -# 2) It will contain newlines if the description header contained lines -# that start with the hash symbol and contain no other characters. -# These are used to delimit paragraphs within the description. -# 3) It may contain leading and trailing whitespace. -# -# Next, for clarity, we remove any leading and trailing whitespace using -# bash's pattern matching syntax. -# -# Note that the right-hand sides of the following two lines are NOT -# regular expressions. They are expressions that use bash's pattern -# matching syntax (gnu.org/software/bash/manual/html_node/Pattern-Matching.html, -# wiki.bash-hackers.org/syntax/pattern) used in substring removal -# (tldp.org/LDP/abs/html/string-manipulation.html). For example, -# -# ${var%%[![:space:]]*} -# -# says "remove from var its longest substring that starts with a non- -# space character". -# -# First remove leading whitespace. -# - test_desc="${test_desc#"${test_desc%%[![:space:]]*}"}" -# -# Now remove trailing whitespace. -# - test_desc="${test_desc%"${test_desc##*[![:space:]]}"}" + config_fn="config.${test_name}.yaml" + config_fp="${test_configs_basedir}/$subdir/$config_fn" + test_desc="$(config_to_yaml_str $config_fp -k "metadata")" + test_desc="${test_desc:27}" + test_desc="${test_desc::${#test_desc}-1}" # # Finally, save the description of the current test as the next element # of the array prim_test_descs. @@ -1079,10 +994,11 @@ ${test_desc}${stripped_line} " # variables specified in "vars_to_extract". Then save the value in the # arrays specified by "prim_array_names_vars_to_extract". # + config_content=$(config_to_shell_str $config_fp) for (( k=0; k<=$((num_vars_to_extract-1)); k++ )); do var_name="${vars_to_extract[$k]}" - cmd=$( grep "^[ ]*${var_name}=" "${config_fn}" ) + cmd=$( grep "^[ ]*${var_name}=" <<< "${config_content}" ) eval $cmd if [ -z "${!var_name+x}" ]; then @@ -1689,49 +1605,8 @@ containing information on all WE2E tests: fi if [ ! -z "${outvarname_test_descs}" ]; then -# -# We want to treat all characters in the test descriptions literally -# when evaluating the array specified by outvarname_test_descs below -# using the eval function because otherwise, characters such as "$", -# "(", ")", etc will be interpreted as indicating the value of a variable, -# the start of an array, the end of an array, etc, and lead to errors. -# Thus, below, when forming the array that will be passed to eval, we -# will surround each element of the local array test_descs in single -# quotes. However, the test descriptions themselves may include single -# quotes (e.g. when a description contains a phrase such as "Please see -# the User's Guide for..."). In order to treat these single quotes -# literally (as opposed to as delimiters indicating the start or end of -# array elements), we have to pass them as separate strings by replacing -# each single quote with the following series of characters: -# -# '"'"' -# -# In this, the first single quote indicates the end of the previous -# single-quoted string, the "'" indicates a string containing a literal -# single quote, and the last single quote inidicates the start of the -# next single-quoted string. -# -# For example, let's assume there are only two WE2E tests to consider. -# Assume the description of the first is -# -# Please see the User's Guide. -# -# and that of the second is: -# -# See description of ${DOT_OR_USCORE} in the configuration file. -# -# Then, if outvarname_test_descs is set to "some_array", the exact string -# we want to pass to eval is: -# -# some_array=('Please see the User'"'"'s Guide.' 'See description of ${DOT_OR_USCORE} in the configuration file.') -# - test_descs_esc_sq=() - for (( i=0; i<=$((num_tests-1)); i++ )); do - test_descs_esc_sq[$i]=$( printf "%s" "${test_descs[$i]}" | \ - sed -r -e "s/'/'\"'\"'/g" ) - done - test_descs_str="( "$( printf "'%s' " "${test_descs_esc_sq[@]}" )")" - eval ${outvarname_test_descs}="${test_descs_str}" + test_descs_str="( "$( printf "'%s' " "${test_descs[@]}" )")" + eval ${output_varname_test_descs}="${test_descs_str}" fi # #----------------------------------------------------------------------- diff --git a/tests/WE2E/run_WE2E_tests.sh b/tests/WE2E/run_WE2E_tests.sh index 605a9178a3..296deb315c 100755 --- a/tests/WE2E/run_WE2E_tests.sh +++ b/tests/WE2E/run_WE2E_tests.sh @@ -712,7 +712,7 @@ for (( i=0; i<=$((num_tests_to_run-1)); i++ )); do # Generate the full path to the current WE2E test's configuration file. # Then ensure that this file exists. # - test_config_fp="${avail_WE2E_test_configs_basedir}/${test_subdir}/config.${test_name}.sh" + test_config_fp="${avail_WE2E_test_configs_basedir}/${test_subdir}/config.${test_name}.yaml" if [ ! -f "${test_config_fp}" ]; then print_err_msg_exit "\ @@ -732,8 +732,8 @@ Please correct and rerun." # #----------------------------------------------------------------------- # - . ${ushdir}/config_defaults.sh - . ${test_config_fp} + source_config ${ushdir}/config_defaults.yaml + source_config ${test_config_fp} # #----------------------------------------------------------------------- # @@ -742,7 +742,7 @@ Please correct and rerun." # have. Once this variable is constructed, we will write its contents # to the generic configuration file that the experiment generation script # reads in (specified by the variable EXPT_CONFIG_FN in the default -# configuration file config_defaults.sh sourced above) and then run that +# configuration file config_defaults.yaml sourced above) and then run that # script to generate an experiment for the current WE2E test. # # We name the multiline variable that will contain the contents of the @@ -760,7 +760,7 @@ Please correct and rerun." # that depend on the input arguments to this script (as opposed to # variable settings in the test configuration file specified by # test_config_fp). Note that any values of these parameters specified -# in the default experiment configuration file (config_defaults.sh) +# in the default experiment configuration file (config_defaults.yaml) # or in the test configuraiton file (test_config_fp) that were sourced # above will be overwritten by the settings below. # @@ -846,7 +846,7 @@ VERBOSE=\"${VERBOSE}\"" # The following section is a copy of this WE2E test's configuration file. # " - expt_config_str=${expt_config_str}$( cat "${test_config_fp}" ) + expt_config_str=${expt_config_str}$( config_to_shell_str "${test_config_fp}" ) expt_config_str=${expt_config_str}" # # End of section from this test's configuration file. @@ -1172,14 +1172,11 @@ MAXTRIES_RUN_POST=\"${MAXTRIES_RUN_POST}\"" fi # #----------------------------------------------------------------------- -# -# Set the full path to the configuration file that the experiment -# generation script reads in. Then write the contents of expt_config_str -# to that file. -# +# Write content to a temporary config file #----------------------------------------------------------------------- # - expt_config_fp="$ushdir/${EXPT_CONFIG_FN}" + temp_file="$PWD/_config_temp_.sh" + expt_config_fp="${temp_file}" printf "%s" "${expt_config_str}" > "${expt_config_fp}" # #----------------------------------------------------------------------- @@ -1276,6 +1273,19 @@ exist or is not a directory: # #----------------------------------------------------------------------- # +# Set the full path to the configuration file that the experiment +# generation script reads in. Then write the contents of expt_config_str +# to that file. +# +#----------------------------------------------------------------------- +# + expt_config_fp="$ushdir/${EXPT_CONFIG_FN}" + ext="${EXPT_CONFIG_FN##*.}" + config_to_str "${ext}" "${temp_file}" -t "$ushdir/config_defaults.yaml" >"${expt_config_fp}" + rm -rf "${temp_file}" +# +#----------------------------------------------------------------------- +# # Call the experiment generation script to generate an experiment # directory and a rocoto workflow XML for the current WE2E test to run. # diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_25km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_25km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh deleted file mode 100644 index 34a61a6adf..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_25km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh +++ /dev/null @@ -1,26 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the CONUS_25km_GFDLgrid grid (which is a -# GFDLgrid type of grid) using the GFS_v16 suite with ICs and LBCs -# derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="CONUS_25km_GFDLgrid" -CCPP_PHYS_SUITE="FV3_GFS_v16" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_25km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_25km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml new file mode 100644 index 0000000000..4212c5edc3 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_25km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml @@ -0,0 +1,25 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the CONUS_25km_GFDLgrid grid (which is a + GFDLgrid type of grid) using the GFS_v16 suite with ICs and LBCs + derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: CONUS_25km_GFDLgrid diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_3km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_3km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh deleted file mode 100644 index a081731e50..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_3km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh +++ /dev/null @@ -1,26 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the CONUS_3km_GFDLgrid grid (which is a -# GFDLgrid type of grid) using the GFS_v16 suite with ICs and LBCs -# derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="CONUS_3km_GFDLgrid" -CCPP_PHYS_SUITE="FV3_GFS_v16" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_3km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_3km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml new file mode 100644 index 0000000000..fe94a9f456 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_CONUS_3km_GFDLgrid_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml @@ -0,0 +1,25 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the CONUS_3km_GFDLgrid grid (which is a + GFDLgrid type of grid) using the GFS_v16 suite with ICs and LBCs + derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: CONUS_3km_GFDLgrid diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh deleted file mode 100644 index 7a059e4ffd..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_AK_13km grid using the GFS_v16 -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_AK_13km" -CCPP_PHYS_SUITE="FV3_GFS_v16" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="6" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml new file mode 100644 index 0000000000..bf49c994bc --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_AK_13km grid using the GFS_v16 + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 6 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_AK_13km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh deleted file mode 100644 index d9d1151b0b..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_AK_3km grid using the GFS_v16 -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_AK_3km" -CCPP_PHYS_SUITE="FV3_GFS_v16" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="6" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml new file mode 100644 index 0000000000..3366d145ea --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_AK_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_AK_3km grid using the GFS_v16 + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 6 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_AK_3km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.sh deleted file mode 100644 index 7c6564a30f..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_13km grid using the GFS_v15p2 -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_13km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.yaml new file mode 100644 index 0000000000..449e65ed06 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_13km grid using the GFS_v15p2 + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_13km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh deleted file mode 100644 index de780b806c..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_13km grid using the GFS_v16 -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_13km" -CCPP_PHYS_SUITE="FV3_GFS_v16" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml new file mode 100644 index 0000000000..90ecb7f02a --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_13km grid using the GFS_v16 + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_13km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.sh deleted file mode 100644 index f85ed71e1f..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_13km grid using the HRRR -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_13km" -CCPP_PHYS_SUITE="FV3_HRRR" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.yaml new file mode 100644 index 0000000000..aed5c3ff37 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_13km grid using the HRRR + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_HRRR + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_13km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh deleted file mode 100644 index b759b00528..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_13km grid using the RRFS_v1beta -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_13km" -CCPP_PHYS_SUITE="FV3_RRFS_v1beta" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml new file mode 100644 index 0000000000..cda8ab16aa --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_13km grid using the RRFS_v1beta + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_RRFS_v1beta + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_13km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp.sh deleted file mode 100644 index 2f7d6ecccf..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_25km grid using the GFS_2017_gfdlmp -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_2017_gfdlmp" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp.yaml new file mode 100644 index 0000000000..d2ed1f4bc8 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_25km grid using the GFS_2017_gfdlmp + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_2017_gfdlmp + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp_regional.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp_regional.sh deleted file mode 100644 index b21cfbe2cd..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp_regional.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_25km grid using the GFS_2017_gfdlmp_regional -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_2017_gfdlmp_regional" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="6" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp_regional.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp_regional.yaml new file mode 100644 index 0000000000..9217180e42 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_2017_gfdlmp_regional.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_25km grid using the GFS_2017_gfdlmp_regional + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_2017_gfdlmp_regional + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 6 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.sh deleted file mode 100644 index 5a36d59886..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_25km grid using the GFS_v15p2 -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.yaml new file mode 100644 index 0000000000..3c311a6624 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_25km grid using the GFS_v15p2 + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh deleted file mode 100644 index 3c6841ddf0..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_25km grid using the GFS_v16 -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v16" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml new file mode 100644 index 0000000000..45588d779f --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_25km grid using the GFS_v16 + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.sh deleted file mode 100644 index d8da153c16..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_25km grid using the HRRR -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_HRRR" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.yaml new file mode 100644 index 0000000000..785bba261b --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_25km grid using the HRRR + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_HRRR + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh deleted file mode 100644 index 2b342d9eef..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_25km grid using the RRFS_v1beta -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_RRFS_v1beta" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml new file mode 100644 index 0000000000..d213f36e1b --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_25km grid using the RRFS_v1beta + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_RRFS_v1beta + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_RAP_suite_HRRR.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_RAP_suite_HRRR.sh deleted file mode 100644 index 1465641a59..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_RAP_suite_HRRR.sh +++ /dev/null @@ -1,32 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_25km grid using the HRRR -# physics suite with ICs derived from the FV3GFS and LBCs derived from -# the RAP. -# -# Note that this test specifies the file format of the FV3GFS external -# model data (from which to generate ICs) to be "grib2" as opposed to -# the default value of "nemsio". -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_HRRR" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_ICS="grib2" -EXTRN_MDL_NAME_LBCS="RAP" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200810" -DATE_LAST_CYCL="20200810" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="1" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_RAP_suite_HRRR.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_RAP_suite_HRRR.yaml new file mode 100644 index 0000000000..2055b56846 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_FV3GFS_lbcs_RAP_suite_HRRR.yaml @@ -0,0 +1,31 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_25km grid using the HRRR + physics suite with ICs derived from the FV3GFS and LBCs derived from + the RAP. + Note that this test specifies the file format of the FV3GFS external + model data (from which to generate ICs) to be "grib2" as opposed to + the default value of "nemsio". +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_HRRR + DATE_FIRST_CYCL: '20200810' + DATE_LAST_CYCL: '20200810' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: grib2 + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 1 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_2017_gfdlmp.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_2017_gfdlmp.sh deleted file mode 100644 index 7e5b304acc..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_2017_gfdlmp.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_25km grid using the GFS_2017_gfdlmp -# physics suite with ICs and LBCs derived from the GSMGFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_2017_gfdlmp" - -EXTRN_MDL_NAME_ICS="GSMGFS" -EXTRN_MDL_NAME_LBCS="GSMGFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190520" -DATE_LAST_CYCL="20190520" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="6" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_2017_gfdlmp.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_2017_gfdlmp.yaml new file mode 100644 index 0000000000..e94f0f6dc7 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_2017_gfdlmp.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_25km grid using the GFS_2017_gfdlmp + physics suite with ICs and LBCs derived from the GSMGFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_2017_gfdlmp + DATE_FIRST_CYCL: '20190520' + DATE_LAST_CYCL: '20190520' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: GSMGFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: GSMGFS + LBC_SPEC_INTVL_HRS: 6 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v15p2.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v15p2.sh deleted file mode 100644 index af3a13440f..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v15p2.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_25km grid using the GFS_v15p2 -# physics suite with ICs and LBCs derived from the GSMGFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="GSMGFS" -EXTRN_MDL_NAME_LBCS="GSMGFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190520" -DATE_LAST_CYCL="20190520" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="6" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v15p2.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v15p2.yaml new file mode 100644 index 0000000000..197c0e9fce --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v15p2.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_25km grid using the GFS_v15p2 + physics suite with ICs and LBCs derived from the GSMGFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20190520' + DATE_LAST_CYCL: '20190520' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: GSMGFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: GSMGFS + LBC_SPEC_INTVL_HRS: 6 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v16.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v16.sh deleted file mode 100644 index 616b0e7447..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v16.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_25km grid using the GFS_v16 -# physics suite with ICs and LBCs derived from the GSMGFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v16" - -EXTRN_MDL_NAME_ICS="GSMGFS" -EXTRN_MDL_NAME_LBCS="GSMGFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190520" -DATE_LAST_CYCL="20190520" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="6" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v16.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v16.yaml new file mode 100644 index 0000000000..3a3f2b8b96 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_GSMGFS_lbcs_GSMGFS_suite_GFS_v16.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_25km grid using the GFS_v16 + physics suite with ICs and LBCs derived from the GSMGFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20190520' + DATE_LAST_CYCL: '20190520' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: GSMGFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: GSMGFS + LBC_SPEC_INTVL_HRS: 6 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_HRRR.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_HRRR.sh deleted file mode 100644 index 10be9fed96..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_HRRR.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_25km grid using the HRRR -# physics suite with ICs and LBCs derived from the NAM. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_HRRR" - -EXTRN_MDL_NAME_ICS="NAM" -EXTRN_MDL_NAME_LBCS="NAM" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20210615" -DATE_LAST_CYCL="20210615" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_HRRR.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_HRRR.yaml new file mode 100644 index 0000000000..5122bd7012 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_HRRR.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_25km grid using the HRRR + physics suite with ICs and LBCs derived from the NAM. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_HRRR + DATE_FIRST_CYCL: '20210615' + DATE_LAST_CYCL: '20210615' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: NAM + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: NAM + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_RRFS_v1beta.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_RRFS_v1beta.sh deleted file mode 100644 index 540e5a0589..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_RRFS_v1beta.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_25km grid using the RRFS_v1beta -# physics suite with ICs and LBCs derived from the NAM. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_RRFS_v1beta" - -EXTRN_MDL_NAME_ICS="NAM" -EXTRN_MDL_NAME_LBCS="NAM" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20210615" -DATE_LAST_CYCL="20210615" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_RRFS_v1beta.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_RRFS_v1beta.yaml new file mode 100644 index 0000000000..a813a1129f --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_25km_ics_NAM_lbcs_NAM_suite_RRFS_v1beta.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_25km grid using the RRFS_v1beta + physics suite with ICs and LBCs derived from the NAM. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_RRFS_v1beta + DATE_FIRST_CYCL: '20210615' + DATE_LAST_CYCL: '20210615' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: NAM + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: NAM + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.sh deleted file mode 100644 index 03dbd2c381..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.sh +++ /dev/null @@ -1,27 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_3km grid using the GFS_v15_ -# thompson_mynn_lam3km physics suite with ICs and LBCs derived from FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_3km" -CCPP_PHYS_SUITE="FV3_GFS_v15_thompson_mynn_lam3km" - -USE_MERRA_CLIMO="TRUE" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.yaml new file mode 100644 index 0000000000..94700fac99 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.yaml @@ -0,0 +1,25 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_3km grid using the GFS_v15_ + thompson_mynn_lam3km physics suite with ICs and LBCs derived from FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15_thompson_mynn_lam3km + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_3km + USE_MERRA_CLIMO: true diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.sh deleted file mode 100644 index 528de40de1..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_3km grid using the GFS_v15p2 -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_3km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.yaml new file mode 100644 index 0000000000..3d2d26c022 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15p2.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_3km grid using the GFS_v15p2 + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_3km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh deleted file mode 100644 index cd2deecb8b..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_3km grid using the GFS_v16 -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_3km" -CCPP_PHYS_SUITE="FV3_GFS_v16" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml new file mode 100644 index 0000000000..a2b7fb31a4 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_3km grid using the GFS_v16 + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_3km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.sh deleted file mode 100644 index 0435df0a2f..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_3km grid using the HRRR -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_3km" -CCPP_PHYS_SUITE="FV3_HRRR" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.yaml new file mode 100644 index 0000000000..6a5d240303 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_HRRR.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_3km grid using the HRRR + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_HRRR + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_3km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh deleted file mode 100644 index 41f4d86a34..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUS_3km grid using the RRFS_v1beta -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_3km" -CCPP_PHYS_SUITE="FV3_RRFS_v1beta" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml new file mode 100644 index 0000000000..202e542c80 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUS_3km grid using the RRFS_v1beta + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_RRFS_v1beta + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_3km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh deleted file mode 100644 index d7c402004c..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUScompact_13km grid using the -# GFS_v16 physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_13km" -CCPP_PHYS_SUITE="FV3_GFS_v16" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml new file mode 100644 index 0000000000..8d28c47e84 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUScompact_13km grid using the + GFS_v16 physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUScompact_13km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_HRRR.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_HRRR.sh deleted file mode 100644 index 40f5e4997e..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_HRRR.sh +++ /dev/null @@ -1,28 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUScompact_13km grid using the HRRR -# physics suite with ICs derived from the HRRR and LBCs derived from the -# RAP. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_13km" -CCPP_PHYS_SUITE="FV3_HRRR" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="RAP" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200810" -DATE_LAST_CYCL="20200810" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="1" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml new file mode 100644 index 0000000000..776bf91700 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml @@ -0,0 +1,29 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUScompact_13km grid using the HRRR + physics suite with ICs derived from the HRRR and LBCs derived from the + RAP. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_HRRR + DATE_FIRST_CYCL: '20200810' + DATE_LAST_CYCL: '20200810' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 1 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUScompact_13km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh deleted file mode 100644 index afcfa32e16..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh +++ /dev/null @@ -1,27 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUScompact_13km grid using the RRFS_v1beta -# physics suite with ICs derived from the HRRR and LBCs derived from the RAP. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_13km" -CCPP_PHYS_SUITE="FV3_RRFS_v1beta" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="RAP" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200801" -DATE_LAST_CYCL="20200801" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml new file mode 100644 index 0000000000..1b9a269d22 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_13km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml @@ -0,0 +1,28 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUScompact_13km grid using the RRFS_v1beta + physics suite with ICs derived from the HRRR and LBCs derived from the RAP. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_RRFS_v1beta + DATE_FIRST_CYCL: '20200801' + DATE_LAST_CYCL: '20200801' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUScompact_13km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh deleted file mode 100644 index f5fc6384bf..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUScompact_25km grid using the -# GFS_v16 physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_25km" -CCPP_PHYS_SUITE="FV3_GFS_v16" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml new file mode 100644 index 0000000000..9e41ccb973 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUScompact_25km grid using the + GFS_v16 physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUScompact_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_HRRR.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_HRRR.sh deleted file mode 100644 index f1302d1634..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_HRRR.sh +++ /dev/null @@ -1,28 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUScompact_25km grid using the HRRR -# physics suite with ICs and LBCs derived from the HRRR. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_25km" -CCPP_PHYS_SUITE="FV3_HRRR" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="HRRR" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200810" -DATE_LAST_CYCL="20200810" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="24" -LBC_SPEC_INTVL_HRS="3" - diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_HRRR.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_HRRR.yaml new file mode 100644 index 0000000000..e0a6a0687c --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_HRRR.yaml @@ -0,0 +1,28 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUScompact_25km grid using the HRRR + physics suite with ICs and LBCs derived from the HRRR. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_HRRR + DATE_FIRST_CYCL: '20200810' + DATE_LAST_CYCL: '20200810' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 24 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: HRRR + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUScompact_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_RRFS_v1beta.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_RRFS_v1beta.sh deleted file mode 100644 index 0060e44663..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_RRFS_v1beta.sh +++ /dev/null @@ -1,27 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUScompact_25km grid using the RRFS_v1beta -# physics suite with ICs and LBCs derived from the HRRR. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_25km" -CCPP_PHYS_SUITE="FV3_RRFS_v1beta" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="HRRR" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200810" -DATE_LAST_CYCL="20200810" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="24" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_RRFS_v1beta.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_RRFS_v1beta.yaml new file mode 100644 index 0000000000..40f1ceadba --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_HRRR_suite_RRFS_v1beta.yaml @@ -0,0 +1,28 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUScompact_25km grid using the RRFS_v1beta + physics suite with ICs and LBCs derived from the HRRR. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_RRFS_v1beta + DATE_FIRST_CYCL: '20200810' + DATE_LAST_CYCL: '20200810' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 24 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: HRRR + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUScompact_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.sh deleted file mode 100644 index 3dfedb5686..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.sh +++ /dev/null @@ -1,27 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUScompact_25km grid using the HRRR -# physics suite with ICs derived from the HRRR and LBCs derived from the RAP. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_25km" -CCPP_PHYS_SUITE="FV3_HRRR" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="RAP" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200810" -DATE_LAST_CYCL="20200810" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="2" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml new file mode 100644 index 0000000000..477bc77dab --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml @@ -0,0 +1,28 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUScompact_25km grid using the HRRR + physics suite with ICs derived from the HRRR and LBCs derived from the RAP. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_HRRR + DATE_FIRST_CYCL: '20200810' + DATE_LAST_CYCL: '20200810' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 2 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUScompact_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh deleted file mode 100644 index 8fc60571db..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh +++ /dev/null @@ -1,27 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUScompact_25km grid using the RRFS_v1beta -# physics suite with ICs derived from the HRRR and LBCs derived from the RAP. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_25km" -CCPP_PHYS_SUITE="FV3_RRFS_v1beta" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="RAP" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200810" -DATE_LAST_CYCL="20200810" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="3" -LBC_SPEC_INTVL_HRS="1" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml new file mode 100644 index 0000000000..87140b99ef --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml @@ -0,0 +1,28 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUScompact_25km grid using the RRFS_v1beta + physics suite with ICs derived from the HRRR and LBCs derived from the RAP. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_RRFS_v1beta + DATE_FIRST_CYCL: '20200810' + DATE_LAST_CYCL: '20200810' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 3 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 1 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUScompact_25km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh deleted file mode 100644 index 5cd9b09042..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUScompact_3km grid using the -# GFS_v16 physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_3km" -CCPP_PHYS_SUITE="FV3_GFS_v16" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml new file mode 100644 index 0000000000..0c366e0d90 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUScompact_3km grid using the + GFS_v16 physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUScompact_3km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.sh deleted file mode 100644 index 11227ea005..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.sh +++ /dev/null @@ -1,27 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUScompact_3km grid using the GFS_v15p2 -# physics suite with ICs derived from the HRRR and LBCs derived from the RAP. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_3km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="RAP" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200801" -DATE_LAST_CYCL="20200801" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.yaml new file mode 100644 index 0000000000..263fdf941d --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.yaml @@ -0,0 +1,28 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUScompact_3km grid using the GFS_v15p2 + physics suite with ICs derived from the HRRR and LBCs derived from the RAP. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20200801' + DATE_LAST_CYCL: '20200801' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUScompact_3km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_HRRR.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_HRRR.sh deleted file mode 100644 index 396ce3e150..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_HRRR.sh +++ /dev/null @@ -1,28 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUScompact_3km grid using the HRRR -# physics suite with ICs derived from the HRRR and LBCs derived from the RAP. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_3km" -CCPP_PHYS_SUITE="FV3_HRRR" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="RAP" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - - -DATE_FIRST_CYCL="20200810" -DATE_LAST_CYCL="20200810" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="1" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml new file mode 100644 index 0000000000..6857504f7a --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml @@ -0,0 +1,28 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUScompact_3km grid using the HRRR + physics suite with ICs derived from the HRRR and LBCs derived from the RAP. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_HRRR + DATE_FIRST_CYCL: '20200810' + DATE_LAST_CYCL: '20200810' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 1 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUScompact_3km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh deleted file mode 100644 index a75f8d79e6..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh +++ /dev/null @@ -1,28 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_CONUScompact_3km grid using the -# RRFS_v1beta physics suite with ICs derived from the HRRR and LBCs -# derived from the RAP. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_3km" -CCPP_PHYS_SUITE="FV3_RRFS_v1beta" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="RAP" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200801" -DATE_LAST_CYCL="20200801" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml new file mode 100644 index 0000000000..8423600ce4 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_CONUScompact_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml @@ -0,0 +1,29 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_CONUScompact_3km grid using the + RRFS_v1beta physics suite with ICs derived from the HRRR and LBCs + derived from the RAP. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_RRFS_v1beta + DATE_FIRST_CYCL: '20200801' + DATE_LAST_CYCL: '20200801' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUScompact_3km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh deleted file mode 100644 index 9e4cb594b1..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh +++ /dev/null @@ -1,54 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_NA_13km grid using the RRFS_v1beta -# physics suite with ICs and LBCs derived from the FV3GFS. -# -# Note that this test also sets various resource parameters for several -# of the rocoto tasks in order to more efficiently run the code on this -# (very large) grid. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_NA_13km" -CCPP_PHYS_SUITE="FV3_RRFS_v1beta" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="6" - -######################################################################### -# The following code/namelist/workflow setting changes are necessary to # -# run/optimize end-to-end experiments using the 3-km NA grid # -######################################################################### - -# The model should be built in 32-bit mode (64-bit will result in much -# longer run times. - -# Use k_split=2 and n_split=5, the previous namelist values (k_split=4 -# and n_split=5) will result in significantly longer run times. - -NNODES_MAKE_ICS="12" -NNODES_MAKE_LBCS="12" -PPN_MAKE_ICS="4" -PPN_MAKE_LBCS="4" -WTIME_MAKE_LBCS="01:00:00" - -NNODES_RUN_POST="6" -PPN_RUN_POST="12" - -OMP_STACKSIZE_MAKE_ICS="2048m" -OMP_STACKSIZE_RUN_FCST="2048m" - -############################################################################### diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml new file mode 100644 index 0000000000..8fa62695ce --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_13km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml @@ -0,0 +1,39 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_NA_13km grid using the RRFS_v1beta + physics suite with ICs and LBCs derived from the FV3GFS. + Note that this test also sets various resource parameters for several + of the rocoto tasks in order to more efficiently run the code on this + (very large) grid. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_RRFS_v1beta + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 6 + USE_USER_STAGED_EXTRN_FILES: true +task_make_ics: + NNODES_MAKE_ICS: 12 + PPN_MAKE_ICS: 4 + OMP_STACKSIZE_MAKE_ICS: 2048m +task_make_lbcs: + NNODES_MAKE_LBCS: 12 + PPN_MAKE_LBCS: 4 + WTIME_MAKE_LBCS: 01:00:00 +task_run_fcst: + OMP_STACKSIZE_RUN_FCST: 2048m + PREDEF_GRID_NAME: RRFS_NA_13km +task_run_post: + NNODES_RUN_POST: 6 + PPN_RUN_POST: 12 diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh deleted file mode 100644 index cd0a933e6c..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.sh +++ /dev/null @@ -1,54 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_NA_3km grid using the RRFS_v1beta -# physics suite with ICs and LBCs derived from the FV3GFS. -# -# Note that this test also sets various resource parameters for several -# of the rocoto tasks in order to more efficiently run the code on this -# (very large) grid. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_NA_3km" -CCPP_PHYS_SUITE="FV3_RRFS_v1beta" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="6" - -######################################################################### -# The following code/namelist/workflow setting changes are necessary to # -# run/optimize end-to-end experiments using the 3-km NA grid # -######################################################################### - -# The model should be built in 32-bit mode (64-bit will result in much -# longer run times. - -# Use k_split=2 and n_split=5, the previous namelist values (k_split=4 -# and n_split=5) will result in significantly longer run times. - -NNODES_MAKE_ICS="12" -NNODES_MAKE_LBCS="12" -PPN_MAKE_ICS="4" -PPN_MAKE_LBCS="4" -WTIME_MAKE_LBCS="01:00:00" - -NNODES_RUN_POST="8" -PPN_RUN_POST="12" - -OMP_STACKSIZE_MAKE_ICS="2048m" -OMP_STACKSIZE_RUN_FCST="2048m" - -############################################################################### diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml new file mode 100644 index 0000000000..18c9bc2ba1 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_NA_3km_ics_FV3GFS_lbcs_FV3GFS_suite_RRFS_v1beta.yaml @@ -0,0 +1,39 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_NA_3km grid using the RRFS_v1beta + physics suite with ICs and LBCs derived from the FV3GFS. + Note that this test also sets various resource parameters for several + of the rocoto tasks in order to more efficiently run the code on this + (very large) grid. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_RRFS_v1beta + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 6 + USE_USER_STAGED_EXTRN_FILES: true +task_make_ics: + NNODES_MAKE_ICS: 12 + PPN_MAKE_ICS: 4 + OMP_STACKSIZE_MAKE_ICS: 2048m +task_make_lbcs: + NNODES_MAKE_LBCS: 12 + PPN_MAKE_LBCS: 4 + WTIME_MAKE_LBCS: 01:00:00 +task_run_fcst: + OMP_STACKSIZE_RUN_FCST: 2048m + PREDEF_GRID_NAME: RRFS_NA_3km +task_run_post: + NNODES_RUN_POST: 8 + PPN_RUN_POST: 12 diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh deleted file mode 100644 index eac0a993a5..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh +++ /dev/null @@ -1,25 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_SUBCONUS_3km grid using the GFS_v16 -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_SUBCONUS_3km" -CCPP_PHYS_SUITE="FV3_GFS_v16" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml new file mode 100644 index 0000000000..9831759b20 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_SUBCONUS_3km grid using the GFS_v16 + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_SUBCONUS_3km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.sh deleted file mode 100644 index c5512d0ead..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.sh +++ /dev/null @@ -1,28 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the RRFS_SUBCONUS_3km grid using the GFS_v15p2 -# physics suite with ICs derived from the HRRR and LBCs derived from the -# RAP. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_SUBCONUS_3km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="RAP" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200801" -DATE_LAST_CYCL="20200801" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.yaml new file mode 100644 index 0000000000..7d712e0d33 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_RRFS_SUBCONUS_3km_ics_HRRR_lbcs_RAP_suite_GFS_v15p2.yaml @@ -0,0 +1,29 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the RRFS_SUBCONUS_3km grid using the GFS_v15p2 + physics suite with ICs derived from the HRRR and LBCs derived from the + RAP. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20200801' + DATE_LAST_CYCL: '20200801' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + PREDEF_GRID_NAME: RRFS_SUBCONUS_3km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh deleted file mode 100644 index e11ab393a3..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh +++ /dev/null @@ -1,27 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the SUBCONUS_Ind_3km grid using the GFS_v16 -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="SUBCONUS_Ind_3km" -CCPP_PHYS_SUITE="FV3_GFS_v16" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_ICS="grib2" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="grib2" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190615" -DATE_LAST_CYCL="20190615" -CYCL_HRS=( "18" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="6" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml new file mode 100644 index 0000000000..078576272a --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml @@ -0,0 +1,26 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the SUBCONUS_Ind_3km grid using the GFS_v16 + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20190615' + DATE_LAST_CYCL: '20190615' + CYCL_HRS: + - 18 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: grib2 + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 6 + FV3GFS_FILE_FMT_LBCS: grib2 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: SUBCONUS_Ind_3km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_HRRR.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_HRRR.sh deleted file mode 100644 index aa2cf6edcf..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_HRRR.sh +++ /dev/null @@ -1,27 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the SUBCONUS_Ind_3km grid using the HRRR -# physics suite with ICs derived from HRRR and LBCs derived from the RAP. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="SUBCONUS_Ind_3km" -CCPP_PHYS_SUITE="FV3_HRRR" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="RAP" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200810" -DATE_LAST_CYCL="20200810" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="6" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml new file mode 100644 index 0000000000..3237b6c53d --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml @@ -0,0 +1,28 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the SUBCONUS_Ind_3km grid using the HRRR + physics suite with ICs derived from HRRR and LBCs derived from the RAP. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_HRRR + DATE_FIRST_CYCL: '20200810' + DATE_LAST_CYCL: '20200810' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 6 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + PREDEF_GRID_NAME: SUBCONUS_Ind_3km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh deleted file mode 100644 index 82c5ef43ab..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.sh +++ /dev/null @@ -1,27 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully on the SUBCONUS_Ind_3km grid using the RRFS_v1beta -# physics suite with ICs derived from HRRR and LBCs derived from the RAP. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="SUBCONUS_Ind_3km" -CCPP_PHYS_SUITE="FV3_RRFS_v1beta" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="RAP" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200801" -DATE_LAST_CYCL="20200801" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="6" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml new file mode 100644 index 0000000000..00b45f1ef1 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_community/config.grid_SUBCONUS_Ind_3km_ics_HRRR_lbcs_RAP_suite_RRFS_v1beta.yaml @@ -0,0 +1,28 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully on the SUBCONUS_Ind_3km grid using the RRFS_v1beta + physics suite with ICs derived from HRRR and LBCs derived from the RAP. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_RRFS_v1beta + DATE_FIRST_CYCL: '20200801' + DATE_LAST_CYCL: '20200801' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 6 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + PREDEF_GRID_NAME: SUBCONUS_Ind_3km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh deleted file mode 100644 index f6d6454bde..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.sh +++ /dev/null @@ -1,26 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in nco mode completes -# successfully on the RRFS_CONUS_13km grid using the GFS_v16 physics -# suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="nco" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_13km" -CCPP_PHYS_SUITE="FV3_GFS_v16" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_ICS="grib2" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="grib2" - -DATE_FIRST_CYCL="20190615" -DATE_LAST_CYCL="20190615" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml new file mode 100644 index 0000000000..8d3841bfe1 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_13km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v16.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test is to ensure that the workflow running in nco mode completes + successfully on the RRFS_CONUS_13km grid using the GFS_v16 physics + suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: nco +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20190615' + DATE_LAST_CYCL: '20190615' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: grib2 +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + FV3GFS_FILE_FMT_LBCS: grib2 +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_13km diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.sh deleted file mode 100644 index 19b36f87f5..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.sh +++ /dev/null @@ -1,28 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in nco mode completes -# successfully on the RRFS_CONUS_3km grid using the GFS_v15_thompson_mynn_lam3km -# physics suite with ICs and LBCs derived from the FV3GFS. -# - -RUN_ENVIR="nco" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_3km" -CCPP_PHYS_SUITE="FV3_GFS_v15_thompson_mynn_lam3km" - -USE_MERRA_CLIMO="TRUE" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_ICS="grib2" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="grib2" - -DATE_FIRST_CYCL="20190615" -DATE_LAST_CYCL="20190615" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.yaml new file mode 100644 index 0000000000..90dbe92d3f --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUS_3km_ics_FV3GFS_lbcs_FV3GFS_suite_GFS_v15_thompson_mynn_lam3km.yaml @@ -0,0 +1,25 @@ +metadata: + description: |- + This test is to ensure that the workflow running in nco mode completes + successfully on the RRFS_CONUS_3km grid using the GFS_v15_thompson_mynn_lam3km + physics suite with ICs and LBCs derived from the FV3GFS. +user: + RUN_ENVIR: nco +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15_thompson_mynn_lam3km + DATE_FIRST_CYCL: '20190615' + DATE_LAST_CYCL: '20190615' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: grib2 +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + FV3GFS_FILE_FMT_LBCS: grib2 +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_3km + USE_MERRA_CLIMO: true diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.sh b/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.sh deleted file mode 100644 index e5c4e7732d..0000000000 --- a/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.sh +++ /dev/null @@ -1,29 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in nco mode completes -# successfully on the RRFS_CONUScompact_25km grid using the HRRR physics -# suite with ICs derived from the HRRR and LBCs derived from the RAP. -# - -RUN_ENVIR="nco" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_25km" -CCPP_PHYS_SUITE="FV3_HRRR" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="RAP" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200810" -DATE_LAST_CYCL="20200810" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" - -WRITE_DOPOST="TRUE" diff --git a/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml b/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml new file mode 100644 index 0000000000..445209e424 --- /dev/null +++ b/tests/WE2E/test_configs/grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml @@ -0,0 +1,29 @@ +metadata: + description: |- + This test is to ensure that the workflow running in nco mode completes + successfully on the RRFS_CONUScompact_25km grid using the HRRR physics + suite with ICs derived from the HRRR and LBCs derived from the RAP. +user: + RUN_ENVIR: nco +workflow: + CCPP_PHYS_SUITE: FV3_HRRR + DATE_FIRST_CYCL: '20200810' + DATE_LAST_CYCL: '20200810' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + WRITE_DOPOST: true + PREDEF_GRID_NAME: RRFS_CONUScompact_25km diff --git a/tests/WE2E/test_configs/release_SRW_v1/config.GST_release_public_v1.sh b/tests/WE2E/test_configs/release_SRW_v1/config.GST_release_public_v1.sh deleted file mode 100644 index 0a5cec5252..0000000000 --- a/tests/WE2E/test_configs/release_SRW_v1/config.GST_release_public_v1.sh +++ /dev/null @@ -1,28 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow successfully completes the -# Graduate Student Test (GST) included in Release 1 of the UFS SRW App. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_ICS="grib2" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="grib2" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190615" -DATE_LAST_CYCL="20190615" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="48" -LBC_SPEC_INTVL_HRS="6" - -WTIME_RUN_FCST="01:00:00" diff --git a/tests/WE2E/test_configs/release_SRW_v1/config.GST_release_public_v1.yaml b/tests/WE2E/test_configs/release_SRW_v1/config.GST_release_public_v1.yaml new file mode 100644 index 0000000000..498c0c7056 --- /dev/null +++ b/tests/WE2E/test_configs/release_SRW_v1/config.GST_release_public_v1.yaml @@ -0,0 +1,26 @@ +metadata: + description: |- + This test is to ensure that the workflow successfully completes the + Graduate Student Test (GST) included in Release 1 of the UFS SRW App. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20190615' + DATE_LAST_CYCL: '20190615' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 48 + PREEXISTING_DIR_METHOD: rename +task_run_fcst: + WTIME_RUN_FCST: 01:00:00 + PREDEF_GRID_NAME: RRFS_CONUS_25km +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: grib2 + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 6 + FV3GFS_FILE_FMT_LBCS: grib2 + USE_USER_STAGED_EXTRN_FILES: true diff --git a/tests/WE2E/test_configs/wflow_features/config.MET_ensemble_verification.sh b/tests/WE2E/test_configs/wflow_features/config.MET_ensemble_verification.sh deleted file mode 100644 index 078ce144f9..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.MET_ensemble_verification.sh +++ /dev/null @@ -1,38 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully with MET verification. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -DO_ENSEMBLE="TRUE" -NUM_ENS_MEMBERS="2" - -USE_USER_STAGED_EXTRN_FILES="TRUE" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_ICS="grib2" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="grib2" - -DATE_FIRST_CYCL="20190615" -DATE_LAST_CYCL="20190615" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="6" - -MODEL="FV3_GFS_v15p2_CONUS_25km" -RUN_TASK_VX_GRIDSTAT="TRUE" -RUN_TASK_VX_POINTSTAT="TRUE" -RUN_TASK_VX_ENSGRID="TRUE" -RUN_TASK_VX_ENSPOINT="TRUE" - -WTIME_RUN_FCST="01:00:00" diff --git a/tests/WE2E/test_configs/wflow_features/config.MET_ensemble_verification.yaml b/tests/WE2E/test_configs/wflow_features/config.MET_ensemble_verification.yaml new file mode 100644 index 0000000000..277ab2e74f --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.MET_ensemble_verification.yaml @@ -0,0 +1,36 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully with MET verification. +user: + RUN_ENVIR: community +platform: + MODEL: FV3_GFS_v15p2_CONUS_25km +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20190615' + DATE_LAST_CYCL: '20190615' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +workflow_switches: + RUN_TASK_VX_GRIDSTAT: true + RUN_TASK_VX_POINTSTAT: true + RUN_TASK_VX_ENSGRID: true + RUN_TASK_VX_ENSPOINT: true +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: grib2 + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 6 + FV3GFS_FILE_FMT_LBCS: grib2 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + WTIME_RUN_FCST: 01:00:00 + PREDEF_GRID_NAME: RRFS_CONUS_25km +global: + DO_ENSEMBLE: true + NUM_ENS_MEMBERS: 2 diff --git a/tests/WE2E/test_configs/wflow_features/config.MET_verification.sh b/tests/WE2E/test_configs/wflow_features/config.MET_verification.sh deleted file mode 100644 index 8d7cc8d4c5..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.MET_verification.sh +++ /dev/null @@ -1,33 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test is to ensure that the workflow running in community mode -# completes successfully with MET verification. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -USE_USER_STAGED_EXTRN_FILES="TRUE" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_ICS="grib2" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="grib2" - -DATE_FIRST_CYCL="20190615" -DATE_LAST_CYCL="20190615" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="6" - -MODEL="FV3_GFS_v15p2_CONUS_25km" -RUN_TASK_VX_GRIDSTAT="TRUE" -RUN_TASK_VX_POINTSTAT="TRUE" - -WTIME_RUN_FCST="01:00:00" diff --git a/tests/WE2E/test_configs/wflow_features/config.MET_verification.yaml b/tests/WE2E/test_configs/wflow_features/config.MET_verification.yaml new file mode 100644 index 0000000000..34785cf25c --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.MET_verification.yaml @@ -0,0 +1,31 @@ +metadata: + description: |- + This test is to ensure that the workflow running in community mode + completes successfully with MET verification. +user: + RUN_ENVIR: community +platform: + MODEL: FV3_GFS_v15p2_CONUS_25km +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20190615' + DATE_LAST_CYCL: '20190615' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +workflow_switches: + RUN_TASK_VX_GRIDSTAT: true + RUN_TASK_VX_POINTSTAT: true +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: grib2 + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 6 + FV3GFS_FILE_FMT_LBCS: grib2 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + WTIME_RUN_FCST: 01:00:00 + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.community_ensemble_008mems.sh b/tests/WE2E/test_configs/wflow_features/config.community_ensemble_008mems.sh deleted file mode 100644 index 922367c726..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.community_ensemble_008mems.sh +++ /dev/null @@ -1,31 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to run ensemble forecasts -# (i.e. DO_ENSEMBLE set to "TRUE") in community mode (i.e. RUN_ENVIR set -# to "community") with the number of ensemble members (NUM_ENS_MEMBERS) -# set to "008". The leading zeros in "008" should cause the ensemble -# members to be numbered "mem001", "mem002", ..., "mem008" (instead of, -# for instance, "mem1", "mem2", ..., "mem8"). -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_2017_gfdlmp" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190702" -CYCL_HRS=( "00" "12" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" - -DO_ENSEMBLE="TRUE" -NUM_ENS_MEMBERS="008" diff --git a/tests/WE2E/test_configs/wflow_features/config.community_ensemble_008mems.yaml b/tests/WE2E/test_configs/wflow_features/config.community_ensemble_008mems.yaml new file mode 100644 index 0000000000..d1e7834674 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.community_ensemble_008mems.yaml @@ -0,0 +1,31 @@ +metadata: + description: |- + This test checks the capability of the workflow to run ensemble forecasts + (i.e. DO_ENSEMBLE set to "TRUE") in community mode (i.e. RUN_ENVIR set + to "community") with the number of ensemble members (NUM_ENS_MEMBERS) + set to "008". The leading zeros in "008" should cause the ensemble + members to be numbered "mem001", "mem002", ..., "mem008" (instead of, + for instance, "mem1", "mem2", ..., "mem8"). +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_2017_gfdlmp + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190702' + CYCL_HRS: + - 0 + - 12 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km +global: + DO_ENSEMBLE: true + NUM_ENS_MEMBERS: 8 diff --git a/tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems.sh b/tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems.sh deleted file mode 100644 index c9b68006a7..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems.sh +++ /dev/null @@ -1,35 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to run ensemble forecasts -# (i.e. DO_ENSEMBLE set to "TRUE") in community mode (i.e. RUN_ENVIR set -# to "community") with the number of ensemble members (NUM_ENS_MEMBERS) -# set to "2". The lack of leading zeros in this "2" should cause the -# ensemble members to be named "mem1" and "mem2" (instead of, for instance, -# "mem01" and "mem02"). -# -# Note also that this test uses two cycle hours ("00" and "12") to test -# the capability of the workflow to run ensemble forecasts for more than -# one cycle hour in community mode. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_2017_gfdlmp" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190702" -CYCL_HRS=( "00" "12" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" - -DO_ENSEMBLE="TRUE" -NUM_ENS_MEMBERS="2" diff --git a/tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems.yaml b/tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems.yaml new file mode 100644 index 0000000000..3e7ecd221e --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems.yaml @@ -0,0 +1,34 @@ +metadata: + description: |- + This test checks the capability of the workflow to run ensemble forecasts + (i.e. DO_ENSEMBLE set to "TRUE") in community mode (i.e. RUN_ENVIR set + to "community") with the number of ensemble members (NUM_ENS_MEMBERS) + set to "2". The lack of leading zeros in this "2" should cause the + ensemble members to be named "mem1" and "mem2" (instead of, for instance, + "mem01" and "mem02"). + Note also that this test uses two cycle hours ("00" and "12") to test + the capability of the workflow to run ensemble forecasts for more than + one cycle hour in community mode. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_2017_gfdlmp + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190702' + CYCL_HRS: + - 0 + - 12 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km +global: + DO_ENSEMBLE: true + NUM_ENS_MEMBERS: 2 diff --git a/tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems_stoch.sh b/tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems_stoch.sh deleted file mode 100644 index 934de78bb7..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems_stoch.sh +++ /dev/null @@ -1,38 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to run ensemble forecasts -# (i.e. DO_ENSEMBLE set to "TRUE") in community mode (i.e. RUN_ENVIR set -# to "community") with the number of ensemble members (NUM_ENS_MEMBERS) -# set to "2" and all stochastic physics options turned on. -# The lack of leading zeros in this "2" should cause the -# ensemble members to be named "mem1" and "mem2" (instead of, for instance, -# "mem01" and "mem02"). -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="SUBCONUS_Ind_3km" -CCPP_PHYS_SUITE="FV3_HRRR" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="HRRR" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20200810" -DATE_LAST_CYCL="20200810" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="3" -LBC_SPEC_INTVL_HRS="3" - -DO_ENSEMBLE="TRUE" -NUM_ENS_MEMBERS="2" -DO_SHUM="TRUE" -DO_SPPT="TRUE" -DO_SKEB="TRUE" -DO_SPP="TRUE" diff --git a/tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems_stoch.yaml b/tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems_stoch.yaml new file mode 100644 index 0000000000..b9cf2549a9 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.community_ensemble_2mems_stoch.yaml @@ -0,0 +1,39 @@ +metadata: + description: |- + This test checks the capability of the workflow to run ensemble forecasts + (i.e. DO_ENSEMBLE set to "TRUE") in community mode (i.e. RUN_ENVIR set + to "community") with the number of ensemble members (NUM_ENS_MEMBERS) + set to "2" and all stochastic physics options turned on. + The lack of leading zeros in this "2" should cause the + ensemble members to be named "mem1" and "mem2" (instead of, for instance, + "mem01" and "mem02"). +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_HRRR + DATE_FIRST_CYCL: '20200810' + DATE_LAST_CYCL: '20200810' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 3 + PREEXISTING_DIR_METHOD: rename +task_run_fcst: + PREDEF_GRID_NAME: SUBCONUS_Ind_3km +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: HRRR + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +global: + DO_ENSEMBLE: true + NUM_ENS_MEMBERS: 2 + DO_SHUM: true + DO_SPPT: true + DO_SKEB: true + DO_SPP: true diff --git a/tests/WE2E/test_configs/wflow_features/config.custom_ESGgrid.sh b/tests/WE2E/test_configs/wflow_features/config.custom_ESGgrid.sh deleted file mode 100644 index 86b3ff0b74..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.custom_ESGgrid.sh +++ /dev/null @@ -1,65 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to have the user -# specify a new grid (as opposed to one of the predefined ones in the -# workflow) of ESGgrid type. - - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -CCPP_PHYS_SUITE="FV3_GFS_2017_gfdlmp_regional" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" -# -# Define custom grid. -# -POST_OUTPUT_DOMAIN_NAME="custom_ESGgrid" -GRID_GEN_METHOD="ESGgrid" - -ESGgrid_LON_CTR="-97.5" -ESGgrid_LAT_CTR="41.25" - -ESGgrid_DELX="25000.0" -ESGgrid_DELY="25000.0" - -ESGgrid_NX="216" -ESGgrid_NY="156" - -ESGgrid_PAZI="0.0" - -ESGgrid_WIDE_HALO_WIDTH="6" - -DT_ATMOS="40" - -LAYOUT_X="8" -LAYOUT_Y="12" -BLOCKSIZE="13" - -QUILTING="TRUE" -if [ "$QUILTING" = "TRUE" ]; then - WRTCMP_write_groups="1" - WRTCMP_write_tasks_per_group=$(( 1*LAYOUT_Y )) - WRTCMP_output_grid="lambert_conformal" - WRTCMP_cen_lon="${ESGgrid_LON_CTR}" - WRTCMP_cen_lat="${ESGgrid_LAT_CTR}" - WRTCMP_stdlat1="${ESGgrid_LAT_CTR}" - WRTCMP_stdlat2="${ESGgrid_LAT_CTR}" - WRTCMP_nx="200" - WRTCMP_ny="150" - WRTCMP_lon_lwr_left="-122.21414225" - WRTCMP_lat_lwr_left="22.41403305" - WRTCMP_dx="${ESGgrid_DELX}" - WRTCMP_dy="${ESGgrid_DELY}" -fi diff --git a/tests/WE2E/test_configs/wflow_features/config.custom_ESGgrid.yaml b/tests/WE2E/test_configs/wflow_features/config.custom_ESGgrid.yaml new file mode 100644 index 0000000000..28b65eb0ed --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.custom_ESGgrid.yaml @@ -0,0 +1,53 @@ +metadata: + description: |- + This test checks the capability of the workflow to have the user + specify a new grid (as opposed to one of the predefined ones in the + workflow) of ESGgrid type. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_2017_gfdlmp_regional + GRID_GEN_METHOD: ESGgrid + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_make_grid: + ESGgrid_LON_CTR: -97.5 + ESGgrid_LAT_CTR: 41.25 + ESGgrid_DELX: 25000.0 + ESGgrid_DELY: 25000.0 + ESGgrid_NX: 216 + ESGgrid_NY: 156 + ESGgrid_WIDE_HALO_WIDTH: 6 + ESGgrid_PAZI: 0.0 +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + DT_ATMOS: 40 + LAYOUT_X: 8 + LAYOUT_Y: 12 + BLOCKSIZE: 13 + QUILTING: true + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 12 + WRTCMP_output_grid: lambert_conformal + WRTCMP_cen_lon: -97.5 + WRTCMP_cen_lat: 41.25 + WRTCMP_lon_lwr_left: -122.21414225 + WRTCMP_lat_lwr_left: 22.41403305 + WRTCMP_stdlat1: 41.25 + WRTCMP_stdlat2: 41.25 + WRTCMP_nx: 200 + WRTCMP_ny: 150 + WRTCMP_dx: 25000.0 + WRTCMP_dy: 25000.0 +task_run_post: + POST_OUTPUT_DOMAIN_NAME: custom_ESGgrid diff --git a/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid.sh b/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid.sh deleted file mode 100644 index db148e3ab2..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid.sh +++ /dev/null @@ -1,94 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to have the user -# specify a new grid (as opposed to one of the predefined ones in the -# workflow) of GFDLgrid type. Note that this test sets the workflow -# variable -# -# GFDLgrid_USE_NUM_CELLS_IN_FILENAMES -# -# to "TRUE" (which is its default value); see the UFS SRW App's User's -# Guide for a description of this variable. -# -# The difference between this test and the one named -# -# new_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_TRUE -# -# is that this one uses almost no stretching by setting the workflow -# variable GFDLgrid_STRETCH_FAC very close to 1. Setting it exactly to -# 1 used to cause the workflow to fail because it caused the GFDL grid -# generator to assume a global grid. This bug should be rechecked, e.g. -# by setting GFDLgrid_STRETCH_FAC to exactly 1 below. If the grid -# generation succeeds, then this test can be removed. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -CCPP_PHYS_SUITE="FV3_GFS_2017_gfdlmp" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" -# -# Define custom grid. -# -POST_OUTPUT_DOMAIN_NAME="custom_GFDLgrid" -GRID_GEN_METHOD="GFDLgrid" - -GFDLgrid_LON_T6_CTR="-97.5" -GFDLgrid_LAT_T6_CTR="38.5" -GFDLgrid_STRETCH_FAC="1.0001" # Cannot be exactly 1.0 because then FV3 thinnks it's a global grid. This needs to be fixed in the ufs_weather_model repo. -GFDLgrid_NUM_CELLS="96" -GFDLgrid_REFINE_RATIO="2" - -#num_margin_cells_T6_left="9" -#GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G=$(( num_margin_cells_T6_left + 1 )) -GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G="10" - -#num_margin_cells_T6_right="9" -#GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G=$(( GFDLgrid_NUM_CELLS - num_margin_cells_T6_right )) -GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G="87" - -#num_margin_cells_T6_bottom="9" -#GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G=$(( num_margin_cells_T6_bottom + 1 )) -#GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G="10" -GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G="19" - -#num_margin_cells_T6_top="9" -#GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G=$(( GFDLgrid_NUM_CELLS - num_margin_cells_T6_top )) -#GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G="87" -GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G="78" - -GFDLgrid_USE_NUM_CELLS_IN_FILENAMES="TRUE" - -DT_ATMOS="100" - -LAYOUT_X="6" -LAYOUT_Y="6" -BLOCKSIZE="26" - -QUILTING="TRUE" -if [ "$QUILTING" = "TRUE" ]; then - WRTCMP_write_groups="1" - WRTCMP_write_tasks_per_group=$(( 1*LAYOUT_Y )) - WRTCMP_output_grid="rotated_latlon" - WRTCMP_cen_lon="${GFDLgrid_LON_T6_CTR}" - WRTCMP_cen_lat="${GFDLgrid_LAT_T6_CTR}" -# The following have not been tested... - WRTCMP_lon_lwr_left="-25.0" - WRTCMP_lat_lwr_left="-15.0" - WRTCMP_lon_upr_rght="25.0" - WRTCMP_lat_upr_rght="15.0" - WRTCMP_dlon="0.24" - WRTCMP_dlat="0.24" -fi diff --git a/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid.yaml b/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid.yaml new file mode 100644 index 0000000000..c2d9d82358 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid.yaml @@ -0,0 +1,65 @@ +metadata: + description: |- + This test checks the capability of the workflow to have the user + specify a new grid (as opposed to one of the predefined ones in the + workflow) of GFDLgrid type. Note that this test sets the workflow + variable + GFDLgrid_USE_NUM_CELLS_IN_FILENAMES + to "TRUE" (which is its default value); see the UFS SRW App's User's + Guide for a description of this variable. + The difference between this test and the one named + new_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_TRUE + is that this one uses almost no stretching by setting the workflow + variable GFDLgrid_STRETCH_FAC very close to 1. Setting it exactly to + 1 used to cause the workflow to fail because it caused the GFDL grid + generator to assume a global grid. This bug should be rechecked, e.g. + by setting GFDLgrid_STRETCH_FAC to exactly 1 below. If the grid + generation succeeds, then this test can be removed. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_2017_gfdlmp + GRID_GEN_METHOD: GFDLgrid + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_make_grid: + GFDLgrid_LON_T6_CTR: -97.5 + GFDLgrid_LAT_T6_CTR: 38.5 + GFDLgrid_NUM_CELLS: 96 + GFDLgrid_STRETCH_FAC: 1.0001 + GFDLgrid_REFINE_RATIO: 2 + GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G: 10 + GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G: 87 + GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G: 19 + GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G: 78 + GFDLgrid_USE_NUM_CELLS_IN_FILENAMES: true +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + DT_ATMOS: 100 + LAYOUT_X: 6 + LAYOUT_Y: 6 + BLOCKSIZE: 26 + QUILTING: true + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 6 + WRTCMP_output_grid: rotated_latlon + WRTCMP_cen_lon: -97.5 + WRTCMP_cen_lat: 38.5 + WRTCMP_lon_lwr_left: -25.0 + WRTCMP_lat_lwr_left: -15.0 + WRTCMP_lon_upr_rght: 25.0 + WRTCMP_lat_upr_rght: 15.0 + WRTCMP_dlon: 0.24 + WRTCMP_dlat: 0.24 +task_run_post: + POST_OUTPUT_DOMAIN_NAME: custom_GFDLgrid diff --git a/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_FALSE.sh b/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_FALSE.sh deleted file mode 100644 index ff4d928094..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_FALSE.sh +++ /dev/null @@ -1,81 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to have the user -# specify a new grid (as opposed to one of the predefined ones in the -# workflow) of GFDLgrid type. Note that this test sets the workflow -# variable -# -# GFDLgrid_USE_NUM_CELLS_IN_FILENAMES -# -# to "FALSE"; see the UFS SRW App's User's Guide for a description of -# this variable. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -CCPP_PHYS_SUITE="FV3_GFS_2017_gfdlmp" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" -# -# Define custom grid. -# -POST_OUTPUT_DOMAIN_NAME="custom_GFDLgrid" -GRID_GEN_METHOD="GFDLgrid" - -GFDLgrid_LON_T6_CTR="-97.5" -GFDLgrid_LAT_T6_CTR="38.5" -GFDLgrid_STRETCH_FAC="1.5" -GFDLgrid_NUM_CELLS="96" -GFDLgrid_REFINE_RATIO="2" - -#num_margin_cells_T6_left="9" -#GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G=$(( num_margin_cells_T6_left + 1 )) -GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G="10" - -#num_margin_cells_T6_right="9" -#GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G=$(( GFDLgrid_NUM_CELLS - num_margin_cells_T6_right )) -GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G="87" - -#num_margin_cells_T6_bottom="9" -#GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G=$(( num_margin_cells_T6_bottom + 1 )) -GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G="10" - -#num_margin_cells_T6_top="9" -#GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G=$(( GFDLgrid_NUM_CELLS - num_margin_cells_T6_top )) -GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G="87" - -GFDLgrid_USE_NUM_CELLS_IN_FILENAMES="FALSE" - -DT_ATMOS="100" - -LAYOUT_X="6" -LAYOUT_Y="6" -BLOCKSIZE="26" - -QUILTING="TRUE" -if [ "$QUILTING" = "TRUE" ]; then - WRTCMP_write_groups="1" - WRTCMP_write_tasks_per_group=$(( 1*LAYOUT_Y )) - WRTCMP_output_grid="rotated_latlon" - WRTCMP_cen_lon="${GFDLgrid_LON_T6_CTR}" - WRTCMP_cen_lat="${GFDLgrid_LAT_T6_CTR}" -# The following have not been tested... - WRTCMP_lon_lwr_left="-25.0" - WRTCMP_lat_lwr_left="-15.0" - WRTCMP_lon_upr_rght="25.0" - WRTCMP_lat_upr_rght="15.0" - WRTCMP_dlon="0.24" - WRTCMP_dlat="0.24" -fi diff --git a/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_FALSE.yaml b/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_FALSE.yaml new file mode 100644 index 0000000000..332d54e507 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_FALSE.yaml @@ -0,0 +1,57 @@ +metadata: + description: |- + This test checks the capability of the workflow to have the user + specify a new grid (as opposed to one of the predefined ones in the + workflow) of GFDLgrid type. Note that this test sets the workflow + variable + GFDLgrid_USE_NUM_CELLS_IN_FILENAMES + to "FALSE"; see the UFS SRW App's User's Guide for a description of + this variable. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_2017_gfdlmp + GRID_GEN_METHOD: GFDLgrid + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_make_grid: + GFDLgrid_LON_T6_CTR: -97.5 + GFDLgrid_LAT_T6_CTR: 38.5 + GFDLgrid_NUM_CELLS: 96 + GFDLgrid_STRETCH_FAC: 1.5 + GFDLgrid_REFINE_RATIO: 2 + GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G: 10 + GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G: 87 + GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G: 10 + GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G: 87 + GFDLgrid_USE_NUM_CELLS_IN_FILENAMES: false +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + DT_ATMOS: 100 + LAYOUT_X: 6 + LAYOUT_Y: 6 + BLOCKSIZE: 26 + QUILTING: true + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 6 + WRTCMP_output_grid: rotated_latlon + WRTCMP_cen_lon: -97.5 + WRTCMP_cen_lat: 38.5 + WRTCMP_lon_lwr_left: -25.0 + WRTCMP_lat_lwr_left: -15.0 + WRTCMP_lon_upr_rght: 25.0 + WRTCMP_lat_upr_rght: 15.0 + WRTCMP_dlon: 0.24 + WRTCMP_dlat: 0.24 +task_run_post: + POST_OUTPUT_DOMAIN_NAME: custom_GFDLgrid diff --git a/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_TRUE.sh b/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_TRUE.sh deleted file mode 100644 index dc5d79c2ef..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_TRUE.sh +++ /dev/null @@ -1,81 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to have the user -# specify a new grid (as opposed to one of the predefined ones in the -# workflow) of GFDLgrid type. Note that this test sets the workflow -# variable -# -# GFDLgrid_USE_NUM_CELLS_IN_FILENAMES -# -# to "TRUE" (which is its default value); see the UFS SRW App's User's -# Guide for a description of this variable. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -CCPP_PHYS_SUITE="FV3_GFS_2017_gfdlmp" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" -# -# Define custom grid. -# -POST_OUTPUT_DOMAIN_NAME="custom_GFDLgrid" -GRID_GEN_METHOD="GFDLgrid" - -GFDLgrid_LON_T6_CTR="-97.5" -GFDLgrid_LAT_T6_CTR="38.5" -GFDLgrid_STRETCH_FAC="1.5" -GFDLgrid_NUM_CELLS="96" -GFDLgrid_REFINE_RATIO="2" - -#num_margin_cells_T6_left="9" -#GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G=$(( num_margin_cells_T6_left + 1 )) -GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G="10" - -#num_margin_cells_T6_right="9" -#GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G=$(( GFDLgrid_NUM_CELLS - num_margin_cells_T6_right )) -GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G="87" - -#num_margin_cells_T6_bottom="9" -#GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G=$(( num_margin_cells_T6_bottom + 1 )) -GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G="10" - -#num_margin_cells_T6_top="9" -#GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G=$(( GFDLgrid_NUM_CELLS - num_margin_cells_T6_top )) -GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G="87" - -GFDLgrid_USE_NUM_CELLS_IN_FILENAMES="TRUE" - -DT_ATMOS="100" - -LAYOUT_X="6" -LAYOUT_Y="6" -BLOCKSIZE="26" - -QUILTING="TRUE" -if [ "$QUILTING" = "TRUE" ]; then - WRTCMP_write_groups="1" - WRTCMP_write_tasks_per_group=$(( 1*LAYOUT_Y )) - WRTCMP_output_grid="rotated_latlon" - WRTCMP_cen_lon="${GFDLgrid_LON_T6_CTR}" - WRTCMP_cen_lat="${GFDLgrid_LAT_T6_CTR}" -# The following have not been tested... - WRTCMP_lon_lwr_left="-25.0" - WRTCMP_lat_lwr_left="-15.0" - WRTCMP_lon_upr_rght="25.0" - WRTCMP_lat_upr_rght="15.0" - WRTCMP_dlon="0.24" - WRTCMP_dlat="0.24" -fi diff --git a/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_TRUE.yaml b/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_TRUE.yaml new file mode 100644 index 0000000000..e43e0d240c --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.custom_GFDLgrid__GFDLgrid_USE_NUM_CELLS_IN_FILENAMES_eq_TRUE.yaml @@ -0,0 +1,57 @@ +metadata: + description: |- + This test checks the capability of the workflow to have the user + specify a new grid (as opposed to one of the predefined ones in the + workflow) of GFDLgrid type. Note that this test sets the workflow + variable + GFDLgrid_USE_NUM_CELLS_IN_FILENAMES + to "TRUE" (which is its default value); see the UFS SRW App's User's + Guide for a description of this variable. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_2017_gfdlmp + GRID_GEN_METHOD: GFDLgrid + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_make_grid: + GFDLgrid_LON_T6_CTR: -97.5 + GFDLgrid_LAT_T6_CTR: 38.5 + GFDLgrid_NUM_CELLS: 96 + GFDLgrid_STRETCH_FAC: 1.5 + GFDLgrid_REFINE_RATIO: 2 + GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G: 10 + GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G: 87 + GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G: 10 + GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G: 87 + GFDLgrid_USE_NUM_CELLS_IN_FILENAMES: true +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + DT_ATMOS: 100 + LAYOUT_X: 6 + LAYOUT_Y: 6 + BLOCKSIZE: 26 + QUILTING: true + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 6 + WRTCMP_output_grid: rotated_latlon + WRTCMP_cen_lon: -97.5 + WRTCMP_cen_lat: 38.5 + WRTCMP_lon_lwr_left: -25.0 + WRTCMP_lat_lwr_left: -15.0 + WRTCMP_lon_upr_rght: 25.0 + WRTCMP_lat_upr_rght: 15.0 + WRTCMP_dlon: 0.24 + WRTCMP_dlat: 0.24 +task_run_post: + POST_OUTPUT_DOMAIN_NAME: custom_GFDLgrid diff --git a/tests/WE2E/test_configs/wflow_features/config.deactivate_tasks.sh b/tests/WE2E/test_configs/wflow_features/config.deactivate_tasks.sh deleted file mode 100644 index 2375a648f5..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.deactivate_tasks.sh +++ /dev/null @@ -1,60 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test has two purposes: -# -# 1) It checks that the various workflow tasks can be deactivated, i.e. -# removed from the Rocoto XML. -# 2) It checks the capability of the workflow to use "template" experiment -# variables, i.e. variables whose definitions include references to -# other variables, e.g. -# -# MY_VAR='\${ANOTHER_VAR}' -# -# Note that we do not deactivate all tasks in the workflow; we leave the -# MAKE_GRID_TN, MAKE_OROG_TN, and MAKE_SFC_CLIMO_TN activated because: -# -# 1) There is already a WE2E test that runs with these three tasks -# deactivated (that test is to ensure that pre-generated grid, -# orography, and surface climatology files can be used). -# 2) In checking the template variable capability, we want to make sure -# that the variable defintions file (GLOBAL_VAR_DEFNS_FN) generated -# does not have syntax or other errors in it by sourcing it in these -# three tasks. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" - -RUN_TASK_GET_EXTRN_ICS="FALSE" -RUN_TASK_GET_EXTRN_LBCS="FALSE" -RUN_TASK_MAKE_ICS="FALSE" -RUN_TASK_MAKE_LBCS="FALSE" -RUN_TASK_RUN_FCST="FALSE" -RUN_TASK_RUN_POST="FALSE" -# -# The following shows examples of how to define template variables. Here, -# we define RUN_CMD_UTILS, RUN_CMD_FCST, and RUN_CMD_POST as template -# variables. Note that during this test, these templates aren't actually -# expanded/used (something that would be done using bash's "eval" built-in -# command) anywhere in the scripts. They are included here only to verify -# that the test completes with some variables defined as templates. -# -RUN_CMD_UTILS='cd $yyyymmdd' -RUN_CMD_FCST='mpirun -np ${PE_MEMBER01}' -RUN_CMD_POST='echo hello $yyyymmdd' diff --git a/tests/WE2E/test_configs/wflow_features/config.deactivate_tasks.yaml b/tests/WE2E/test_configs/wflow_features/config.deactivate_tasks.yaml new file mode 100644 index 0000000000..a042538861 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.deactivate_tasks.yaml @@ -0,0 +1,48 @@ +metadata: + description: |- + This test has two purposes: + 1) It checks that the various workflow tasks can be deactivated, i.e. + removed from the Rocoto XML. + 2) It checks the capability of the workflow to use "template" experiment + variables, i.e. variables whose definitions include references to + other variables, e.g. + MY_VAR='\${ANOTHER_VAR}' + Note that we do not deactivate all tasks in the workflow; we leave the + MAKE_GRID_TN, MAKE_OROG_TN, and MAKE_SFC_CLIMO_TN activated because: + 1) There is already a WE2E test that runs with these three tasks + deactivated (that test is to ensure that pre-generated grid, + orography, and surface climatology files can be used). + 2) In checking the template variable capability, we want to make sure + that the variable defintions file (GLOBAL_VAR_DEFNS_FN) generated + does not have syntax or other errors in it by sourcing it in these + three tasks. +user: + RUN_ENVIR: community +platform: + RUN_CMD_UTILS: cd $yyyymmdd + RUN_CMD_FCST: mpirun -np ${PE_MEMBER01} + RUN_CMD_POST: echo hello $yyyymmdd +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +workflow_switches: + RUN_TASK_GET_EXTRN_ICS: false + RUN_TASK_GET_EXTRN_LBCS: false + RUN_TASK_MAKE_ICS: false + RUN_TASK_MAKE_LBCS: false + RUN_TASK_RUN_FCST: false + RUN_TASK_RUN_POST: false +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019061200.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019061200.sh deleted file mode 100644 index a835466b53..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019061200.sh +++ /dev/null @@ -1,27 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS grib2-formatted output files generated by the FV3GFS external -# model (from which ICs and LBCs will be derived) on the first cycle -# date (2019061200) on which the FV3GFS officially became operational. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="grib2" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_ICS="grib2" - -DATE_FIRST_CYCL="20190612" -DATE_LAST_CYCL="20190612" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019061200.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019061200.yaml new file mode 100644 index 0000000000..8fd81b31ef --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019061200.yaml @@ -0,0 +1,25 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS grib2-formatted output files generated by the FV3GFS external + model (from which ICs and LBCs will be derived) on the first cycle + date (2019061200) on which the FV3GFS officially became operational. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20190612' + DATE_LAST_CYCL: '20190612' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: grib2 +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + FV3GFS_FILE_FMT_LBCS: grib2 +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019101818.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019101818.sh deleted file mode 100644 index d7891e6686..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019101818.sh +++ /dev/null @@ -1,29 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS grib2-formatted output files generated by the FV3GFS external -# model (from which ICs and LBCs will be derived) on a cycle date -# (2019101818) that is about halfway between the date (2019061200) on -# which the FV3GFS officially became operational and the date (2020022600) -# on which changes to the FV3GFS output files took effect. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="grib2" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_ICS="grib2" - -DATE_FIRST_CYCL="20191018" -DATE_LAST_CYCL="20191018" -CYCL_HRS=( "18" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019101818.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019101818.yaml new file mode 100644 index 0000000000..875bd0871d --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2019101818.yaml @@ -0,0 +1,27 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS grib2-formatted output files generated by the FV3GFS external + model (from which ICs and LBCs will be derived) on a cycle date + (2019101818) that is about halfway between the date (2019061200) on + which the FV3GFS officially became operational and the date (2020022600) + on which changes to the FV3GFS output files took effect. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20191018' + DATE_LAST_CYCL: '20191018' + CYCL_HRS: + - 18 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: grib2 +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + FV3GFS_FILE_FMT_LBCS: grib2 +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022518.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022518.sh deleted file mode 100644 index a4bea4ac17..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022518.sh +++ /dev/null @@ -1,28 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS grib2-formatted output files generated by the FV3GFS external -# model (from which ICs and LBCs will be derived) on the last cycle date -# (2020022518) before changes to the FV3GFS output files took effect on -# 2020022600. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="grib2" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_ICS="grib2" - -DATE_FIRST_CYCL="20200225" -DATE_LAST_CYCL="20200225" -CYCL_HRS=( "18" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022518.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022518.yaml new file mode 100644 index 0000000000..3beafca5bb --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022518.yaml @@ -0,0 +1,26 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS grib2-formatted output files generated by the FV3GFS external + model (from which ICs and LBCs will be derived) on the last cycle date + (2020022518) before changes to the FV3GFS output files took effect on + 2020022600. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20200225' + DATE_LAST_CYCL: '20200225' + CYCL_HRS: + - 18 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: grib2 +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + FV3GFS_FILE_FMT_LBCS: grib2 +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022600.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022600.sh deleted file mode 100644 index 0f4863a0c4..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022600.sh +++ /dev/null @@ -1,28 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS grib2-formatted output files generated by the FV3GFS external -# model (from which ICs and LBCs will be derived) on the first cycle -# date (2020022600) on which changes to the FV3GFS output files took -# effect. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="grib2" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_ICS="grib2" - -DATE_FIRST_CYCL="20200226" -DATE_LAST_CYCL="20200226" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022600.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022600.yaml new file mode 100644 index 0000000000..9da488d0ba --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2020022600.yaml @@ -0,0 +1,26 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS grib2-formatted output files generated by the FV3GFS external + model (from which ICs and LBCs will be derived) on the first cycle + date (2020022600) on which changes to the FV3GFS output files took + effect. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20200226' + DATE_LAST_CYCL: '20200226' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: grib2 +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + FV3GFS_FILE_FMT_LBCS: grib2 +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2021010100.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2021010100.sh deleted file mode 100644 index 70e0130eb6..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2021010100.sh +++ /dev/null @@ -1,28 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS grib2-formatted output files generated by the FV3GFS external -# model (from which ICs and LBCs will be derived) on a cycle date -# (2021010100) that is several months in the future from the date -# (2020022600) on which changes to the FV3GFS output files took effect. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="grib2" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_ICS="grib2" - -DATE_FIRST_CYCL="20210101" -DATE_LAST_CYCL="20210101" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2021010100.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2021010100.yaml new file mode 100644 index 0000000000..027d4103a1 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_grib2_2021010100.yaml @@ -0,0 +1,26 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS grib2-formatted output files generated by the FV3GFS external + model (from which ICs and LBCs will be derived) on a cycle date + (2021010100) that is several months in the future from the date + (2020022600) on which changes to the FV3GFS output files took effect. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20210101' + DATE_LAST_CYCL: '20210101' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: grib2 +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + FV3GFS_FILE_FMT_LBCS: grib2 +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.sh deleted file mode 100644 index 17a9990c68..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.sh +++ /dev/null @@ -1,24 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS nemsio-formatted output files generated by the FV3GFS external -# model (from which ICs and LBCs will be derived). -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_2017_gfdlmp" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.yaml new file mode 100644 index 0000000000..4a32b06949 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.yaml @@ -0,0 +1,22 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS nemsio-formatted output files generated by the FV3GFS external + model (from which ICs and LBCs will be derived). +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_2017_gfdlmp + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019061200.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019061200.sh deleted file mode 100644 index 63cea83776..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019061200.sh +++ /dev/null @@ -1,27 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS nemsio-formatted output files generated by the FV3GFS external -# model (from which ICs and LBCs will be derived) on the first cycle -# date (2019061200) on which the FV3GFS officially became operational. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="nemsio" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_ICS="nemsio" - -DATE_FIRST_CYCL="20190612" -DATE_LAST_CYCL="20190612" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019061200.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019061200.yaml new file mode 100644 index 0000000000..f187395beb --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019061200.yaml @@ -0,0 +1,25 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS nemsio-formatted output files generated by the FV3GFS external + model (from which ICs and LBCs will be derived) on the first cycle + date (2019061200) on which the FV3GFS officially became operational. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20190612' + DATE_LAST_CYCL: '20190612' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: nemsio +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + FV3GFS_FILE_FMT_LBCS: nemsio +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019101818.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019101818.sh deleted file mode 100644 index cfac4ab62e..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019101818.sh +++ /dev/null @@ -1,29 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS nemsio-formatted output files generated by the FV3GFS external -# model (from which ICs and LBCs will be derived) on a cycle date -# (2019101818) that is about halfway between the date (2019061200) on -# which the FV3GFS officially became operational and the date (2020022600) -# on which changes to the FV3GFS output files took effect. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="nemsio" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_ICS="nemsio" - -DATE_FIRST_CYCL="20191018" -DATE_LAST_CYCL="20191018" -CYCL_HRS=( "18" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019101818.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019101818.yaml new file mode 100644 index 0000000000..ea7ed80195 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2019101818.yaml @@ -0,0 +1,27 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS nemsio-formatted output files generated by the FV3GFS external + model (from which ICs and LBCs will be derived) on a cycle date + (2019101818) that is about halfway between the date (2019061200) on + which the FV3GFS officially became operational and the date (2020022600) + on which changes to the FV3GFS output files took effect. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20191018' + DATE_LAST_CYCL: '20191018' + CYCL_HRS: + - 18 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: nemsio +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + FV3GFS_FILE_FMT_LBCS: nemsio +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022518.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022518.sh deleted file mode 100644 index e80507600d..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022518.sh +++ /dev/null @@ -1,28 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS nemsio-formatted output files generated by the FV3GFS external -# model (from which ICs and LBCs will be derived) on the last cycle date -# (2020022518) before changes to the FV3GFS output files took effect on -# 2020022600. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="nemsio" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_ICS="nemsio" - -DATE_FIRST_CYCL="20200225" -DATE_LAST_CYCL="20200225" -CYCL_HRS=( "18" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022518.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022518.yaml new file mode 100644 index 0000000000..43addb5d80 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022518.yaml @@ -0,0 +1,26 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS nemsio-formatted output files generated by the FV3GFS external + model (from which ICs and LBCs will be derived) on the last cycle date + (2020022518) before changes to the FV3GFS output files took effect on + 2020022600. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20200225' + DATE_LAST_CYCL: '20200225' + CYCL_HRS: + - 18 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: nemsio +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + FV3GFS_FILE_FMT_LBCS: nemsio +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022600.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022600.sh deleted file mode 100644 index 873a13bef9..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022600.sh +++ /dev/null @@ -1,28 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS nemsio-formatted output files generated by the FV3GFS external -# model (from which ICs and LBCs will be derived) on the first cycle -# date (2020022600) on which changes to the FV3GFS output files took -# effect. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="nemsio" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_ICS="nemsio" - -DATE_FIRST_CYCL="20200226" -DATE_LAST_CYCL="20200226" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022600.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022600.yaml new file mode 100644 index 0000000000..26f733ff41 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2020022600.yaml @@ -0,0 +1,26 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS nemsio-formatted output files generated by the FV3GFS external + model (from which ICs and LBCs will be derived) on the first cycle + date (2020022600) on which changes to the FV3GFS output files took + effect. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20200226' + DATE_LAST_CYCL: '20200226' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: nemsio +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + FV3GFS_FILE_FMT_LBCS: nemsio +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2021010100.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2021010100.sh deleted file mode 100644 index 53421da0f5..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2021010100.sh +++ /dev/null @@ -1,28 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS nemsio-formatted output files generated by the FV3GFS external -# model (from which ICs and LBCs will be derived) on a cycle date -# (2021010100) that is several months in the future from the date -# (2020022600) on which changes to the FV3GFS output files took effect. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="nemsio" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_ICS="nemsio" - -DATE_FIRST_CYCL="20210101" -DATE_LAST_CYCL="20210101" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2021010100.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2021010100.yaml new file mode 100644 index 0000000000..3875c78bbe --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio_2021010100.yaml @@ -0,0 +1,26 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS nemsio-formatted output files generated by the FV3GFS external + model (from which ICs and LBCs will be derived) on a cycle date + (2021010100) that is several months in the future from the date + (2020022600) on which changes to the FV3GFS output files took effect. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20210101' + DATE_LAST_CYCL: '20210101' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: nemsio +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + FV3GFS_FILE_FMT_LBCS: nemsio +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2021062000.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2021062000.sh deleted file mode 100644 index 441690e810..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2021062000.sh +++ /dev/null @@ -1,26 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS netcdf-formatted output files generated by the FV3GFS external -# model. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="netcdf" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_ICS="netcdf" - -DATE_FIRST_CYCL="20210620" -DATE_LAST_CYCL="20210620" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2021062000.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2021062000.yaml new file mode 100644 index 0000000000..e0a96c374c --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2021062000.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS netcdf-formatted output files generated by the FV3GFS external + model. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20210620' + DATE_LAST_CYCL: '20210620' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: netcdf +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + FV3GFS_FILE_FMT_LBCS: netcdf +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2022060112_48h.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2022060112_48h.sh deleted file mode 100644 index c119306516..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2022060112_48h.sh +++ /dev/null @@ -1,26 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS netcdf-formatted output files generated by the FV3GFS external -# model (FCST_LEN_HRS>=40). -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v16" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="netcdf" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_ICS="netcdf" - -DATE_FIRST_CYCL="20220601" -DATE_LAST_CYCL="20220601" -CYCL_HRS=( "12" ) - -FCST_LEN_HRS="48" -LBC_SPEC_INTVL_HRS="12" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2022060112_48h.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2022060112_48h.yaml new file mode 100644 index 0000000000..861d222c0e --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_FV3GFS_lbcs_FV3GFS_fmt_netcdf_2022060112_48h.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS netcdf-formatted output files generated by the FV3GFS external + model (FCST_LEN_HRS>=40). +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20220601' + DATE_LAST_CYCL: '20220601' + CYCL_HRS: + - 12 + FCST_LEN_HRS: 48 + PREEXISTING_DIR_METHOD: rename +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: netcdf +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 12 + FV3GFS_FILE_FMT_LBCS: netcdf diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_GSMGFS_lbcs_GSMGFS.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_GSMGFS_lbcs_GSMGFS.sh deleted file mode 100644 index 8c5c54193a..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_GSMGFS_lbcs_GSMGFS.sh +++ /dev/null @@ -1,24 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS files generated by the GSMGFS external model from which ICs and -# LBCs will be derived. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_2017_gfdlmp" - -EXTRN_MDL_NAME_ICS="GSMGFS" -EXTRN_MDL_NAME_LBCS="GSMGFS" - -DATE_FIRST_CYCL="20190520" -DATE_LAST_CYCL="20190520" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="6" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_GSMGFS_lbcs_GSMGFS.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_GSMGFS_lbcs_GSMGFS.yaml new file mode 100644 index 0000000000..feedeee067 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_GSMGFS_lbcs_GSMGFS.yaml @@ -0,0 +1,22 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS files generated by the GSMGFS external model from which ICs and + LBCs will be derived. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_2017_gfdlmp + DATE_FIRST_CYCL: '20190520' + DATE_LAST_CYCL: '20190520' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: GSMGFS +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: GSMGFS + LBC_SPEC_INTVL_HRS: 6 +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_HRRR_lbcs_RAP.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_HRRR_lbcs_RAP.sh deleted file mode 100644 index 61d4e5c9eb..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_HRRR_lbcs_RAP.sh +++ /dev/null @@ -1,28 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS files generated by the HRRR external model from which ICs (and -# the LBCs at the 0th forecast hour) will be derived and files from the -# RAP external model from which the LBCs (except for the ones at the 0th -# forecast hour) will be derived. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_25km" -CCPP_PHYS_SUITE="FV3_HRRR" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="RAP" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200801" -DATE_LAST_CYCL="20200801" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_HRRR_lbcs_RAP.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_HRRR_lbcs_RAP.yaml new file mode 100644 index 0000000000..2d8540e2d1 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_HRRR_lbcs_RAP.yaml @@ -0,0 +1,28 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS files generated by the HRRR external model from which ICs (and + the LBCs at the 0th forecast hour) will be derived and files from the + RAP external model from which the LBCs (except for the ones at the 0th + forecast hour) will be derived. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_HRRR + DATE_FIRST_CYCL: '20200801' + DATE_LAST_CYCL: '20200801' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 3 + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUScompact_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_RAP_lbcs_RAP.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_RAP_lbcs_RAP.sh deleted file mode 100644 index bed8ceb8c8..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_RAP_lbcs_RAP.sh +++ /dev/null @@ -1,24 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOAA -# HPSS files generated by the RAP external model from which ICs and LBCs -# will be derived. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_HRRR" - -EXTRN_MDL_NAME_ICS="RAP" -EXTRN_MDL_NAME_LBCS="RAP" - -DATE_FIRST_CYCL="20190520" -DATE_LAST_CYCL="20190520" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_RAP_lbcs_RAP.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_RAP_lbcs_RAP.yaml new file mode 100644 index 0000000000..923fce480f --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_HPSS_ics_RAP_lbcs_RAP.yaml @@ -0,0 +1,22 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOAA + HPSS files generated by the RAP external model from which ICs and LBCs + will be derived. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_HRRR + DATE_FIRST_CYCL: '20190520' + DATE_LAST_CYCL: '20190520' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: RAP +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 3 +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_NOMADS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.sh b/tests/WE2E/test_configs/wflow_features/config.get_from_NOMADS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.sh deleted file mode 100644 index 04efe1fa2c..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.get_from_NOMADS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.sh +++ /dev/null @@ -1,27 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to retrieve from NOMADS -# nemsio-formatted output files generated by the FV3GFS external model -# (from which ICs and LBCs will be derived). -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_2017_gfdlmp" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" - -DATE_FIRST_CYCL="20200826" -DATE_LAST_CYCL="20200826" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" - -NOMADS="TRUE" -NOMADS_file_type="NEMSIO" diff --git a/tests/WE2E/test_configs/wflow_features/config.get_from_NOMADS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.yaml b/tests/WE2E/test_configs/wflow_features/config.get_from_NOMADS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.yaml new file mode 100644 index 0000000000..fc0a3eba42 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.get_from_NOMADS_ics_FV3GFS_lbcs_FV3GFS_fmt_nemsio.yaml @@ -0,0 +1,26 @@ +metadata: + description: |- + This test checks the capability of the workflow to retrieve from NOMADS + nemsio-formatted output files generated by the FV3GFS external model + (from which ICs and LBCs will be derived). +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_2017_gfdlmp + DATE_FIRST_CYCL: '20200826' + DATE_LAST_CYCL: '20200826' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + NOMADS: true + NOMADS_file_type: NEMSIO +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + NOMADS: true + NOMADS_file_type: NEMSIO +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.inline_post.sh b/tests/WE2E/test_configs/wflow_features/config.inline_post.sh deleted file mode 100644 index e491f9b179..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.inline_post.sh +++ /dev/null @@ -1,26 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to use the inline -# post option (WRITE_DOPOST) in model_configure. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" - -WRITE_DOPOST="TRUE" diff --git a/tests/WE2E/test_configs/wflow_features/config.inline_post.yaml b/tests/WE2E/test_configs/wflow_features/config.inline_post.yaml new file mode 100644 index 0000000000..7a55883822 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.inline_post.yaml @@ -0,0 +1,24 @@ +metadata: + description: |- + This test checks the capability of the workflow to use the inline + post option (WRITE_DOPOST) in model_configure. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + WRITE_DOPOST: true + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.nco_ensemble.sh b/tests/WE2E/test_configs/wflow_features/config.nco_ensemble.sh deleted file mode 100644 index 0f43e9e1dd..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.nco_ensemble.sh +++ /dev/null @@ -1,35 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to run ensemble forecasts -# (i.e. DO_ENSEMBLE set to "TRUE") in nco mode (i.e. RUN_ENVIR set to -# "nco") with the number of ensemble members (NUM_ENS_MEMBERS) set to -# "2". The lack of leading zeros in this "2" should cause the ensemble -# members to be named "mem1" and "mem2" (instead of, for instance, "mem01" -# and "mem02"). -# -# Note also that this test uses two cycle hours ("12" and "18") to test -# the capability of the workflow to run ensemble forecasts for more than -# one cycle hour in nco mode. -# - -RUN_ENVIR="nco" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190702" -CYCL_HRS=( "00" "12" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" - -DO_ENSEMBLE="TRUE" -NUM_ENS_MEMBERS="2" diff --git a/tests/WE2E/test_configs/wflow_features/config.nco_ensemble.yaml b/tests/WE2E/test_configs/wflow_features/config.nco_ensemble.yaml new file mode 100644 index 0000000000..87b2654faa --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.nco_ensemble.yaml @@ -0,0 +1,34 @@ +metadata: + description: |- + This test checks the capability of the workflow to run ensemble forecasts + (i.e. DO_ENSEMBLE set to "TRUE") in nco mode (i.e. RUN_ENVIR set to + "nco") with the number of ensemble members (NUM_ENS_MEMBERS) set to + "2". The lack of leading zeros in this "2" should cause the ensemble + members to be named "mem1" and "mem2" (instead of, for instance, "mem01" + and "mem02"). + Note also that this test uses two cycle hours ("12" and "18") to test + the capability of the workflow to run ensemble forecasts for more than + one cycle hour in nco mode. +user: + RUN_ENVIR: nco +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190702' + CYCL_HRS: + - 0 + - 12 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km +global: + DO_ENSEMBLE: true + NUM_ENS_MEMBERS: 2 diff --git a/tests/WE2E/test_configs/wflow_features/config.nco_inline_post.sh b/tests/WE2E/test_configs/wflow_features/config.nco_inline_post.sh deleted file mode 120000 index 392d3311ac..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.nco_inline_post.sh +++ /dev/null @@ -1 +0,0 @@ -../grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.sh \ No newline at end of file diff --git a/tests/WE2E/test_configs/wflow_features/config.nco_inline_post.yaml b/tests/WE2E/test_configs/wflow_features/config.nco_inline_post.yaml new file mode 120000 index 0000000000..6ec59fe0dd --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.nco_inline_post.yaml @@ -0,0 +1 @@ +../grids_extrn_mdls_suites_nco/config.nco_grid_RRFS_CONUScompact_25km_ics_HRRR_lbcs_RAP_suite_HRRR.yaml \ No newline at end of file diff --git a/tests/WE2E/test_configs/wflow_features/config.pregen_grid_orog_sfc_climo.sh b/tests/WE2E/test_configs/wflow_features/config.pregen_grid_orog_sfc_climo.sh deleted file mode 100644 index fa1d0f06a4..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.pregen_grid_orog_sfc_climo.sh +++ /dev/null @@ -1,28 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to use pregenerated -# grid, orography, and surface climatology files. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" - -RUN_TASK_MAKE_GRID="FALSE" -RUN_TASK_MAKE_OROG="FALSE" -RUN_TASK_MAKE_SFC_CLIMO="FALSE" diff --git a/tests/WE2E/test_configs/wflow_features/config.pregen_grid_orog_sfc_climo.yaml b/tests/WE2E/test_configs/wflow_features/config.pregen_grid_orog_sfc_climo.yaml new file mode 100644 index 0000000000..2ff9af6a0c --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.pregen_grid_orog_sfc_climo.yaml @@ -0,0 +1,27 @@ +metadata: + description: |- + This test checks the capability of the workflow to use pregenerated + grid, orography, and surface climatology files. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +workflow_switches: + RUN_TASK_MAKE_GRID: false + RUN_TASK_MAKE_OROG: false + RUN_TASK_MAKE_SFC_CLIMO: false +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.specify_DOT_OR_USCORE.sh b/tests/WE2E/test_configs/wflow_features/config.specify_DOT_OR_USCORE.sh deleted file mode 100644 index 979d8e96e9..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.specify_DOT_OR_USCORE.sh +++ /dev/null @@ -1,39 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to have the character -# (DOT_OR_USCORE) in the names of the input grid and orography files -# that comes after the C-resolution be set to a user-specified value. -# For example, a grid file may be named -# -# C403${DOT_OR_USCORE}grid.tile7.halo4.nc -# -# where "C403" is the C-resolution for this specific grid and -# ${DOT_OR_USCORE} represents the contents of the workflow variable -# DOT_OR_USCORE (bash syntax). DOT_OR_USCORE is by default set to an -# underscore, but for consistency with the rest of the separators in the -# file name (as well as with the character after the C-resolution in the -# names of the surface climatology files), it should be a "." (a dot). -# The MAKE_GRID_TN and MAKE_OROG_TN tasks will name the grid and orography -# files that they create using this character. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_2017_gfdlmp" - -EXTRN_MDL_NAME_ICS="GSMGFS" -EXTRN_MDL_NAME_LBCS="GSMGFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190520" -DATE_LAST_CYCL="20190520" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="6" - -DOT_OR_USCORE="." diff --git a/tests/WE2E/test_configs/wflow_features/config.specify_DOT_OR_USCORE.yaml b/tests/WE2E/test_configs/wflow_features/config.specify_DOT_OR_USCORE.yaml new file mode 100644 index 0000000000..45db52dd9b --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.specify_DOT_OR_USCORE.yaml @@ -0,0 +1,35 @@ +metadata: + description: |- + This test checks the capability of the workflow to have the character + (DOT_OR_USCORE) in the names of the input grid and orography files + that comes after the C-resolution be set to a user-specified value. + For example, a grid file may be named + C403${DOT_OR_USCORE}grid.tile7.halo4.nc + where "C403" is the C-resolution for this specific grid and + ${DOT_OR_USCORE} represents the contents of the workflow variable + DOT_OR_USCORE (bash syntax). DOT_OR_USCORE is by default set to an + underscore, but for consistency with the rest of the separators in the + file name (as well as with the character after the C-resolution in the + names of the surface climatology files), it should be a "." (a dot). + The MAKE_GRID_TN and MAKE_OROG_TN tasks will name the grid and orography + files that they create using this character. +user: + RUN_ENVIR: community +workflow: + DOT_OR_USCORE: . + CCPP_PHYS_SUITE: FV3_GFS_2017_gfdlmp + DATE_FIRST_CYCL: '20190520' + DATE_LAST_CYCL: '20190520' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: GSMGFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: GSMGFS + LBC_SPEC_INTVL_HRS: 6 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.specify_DT_ATMOS_LAYOUT_XY_BLOCKSIZE.sh b/tests/WE2E/test_configs/wflow_features/config.specify_DT_ATMOS_LAYOUT_XY_BLOCKSIZE.sh deleted file mode 100644 index 7a10a0ec34..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.specify_DT_ATMOS_LAYOUT_XY_BLOCKSIZE.sh +++ /dev/null @@ -1,32 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to have the forecast -# model's time step (DT_ATMOS), its MPI layout (LAYOUT_X and LAYOUT_Y), -# and its cache block size be set to user-specified values. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_25km" -CCPP_PHYS_SUITE="FV3_HRRR" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="RAP" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200801" -DATE_LAST_CYCL="20200801" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" - -DT_ATMOS="100" -LAYOUT_X="10" -LAYOUT_Y="4" -BLOCKSIZE="35" diff --git a/tests/WE2E/test_configs/wflow_features/config.specify_DT_ATMOS_LAYOUT_XY_BLOCKSIZE.yaml b/tests/WE2E/test_configs/wflow_features/config.specify_DT_ATMOS_LAYOUT_XY_BLOCKSIZE.yaml new file mode 100644 index 0000000000..0557e15941 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.specify_DT_ATMOS_LAYOUT_XY_BLOCKSIZE.yaml @@ -0,0 +1,32 @@ +metadata: + description: |- + This test checks the capability of the workflow to have the forecast + model's time step (DT_ATMOS), its MPI layout (LAYOUT_X and LAYOUT_Y), + and its cache block size be set to user-specified values. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_HRRR + DATE_FIRST_CYCL: '20200801' + DATE_LAST_CYCL: '20200801' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + DT_ATMOS: 100 + LAYOUT_X: 10 + LAYOUT_Y: 4 + BLOCKSIZE: 35 + PREDEF_GRID_NAME: RRFS_CONUScompact_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.specify_EXTRN_MDL_SYSBASEDIR_ICS_LBCS.sh b/tests/WE2E/test_configs/wflow_features/config.specify_EXTRN_MDL_SYSBASEDIR_ICS_LBCS.sh deleted file mode 100644 index eca762a946..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.specify_EXTRN_MDL_SYSBASEDIR_ICS_LBCS.sh +++ /dev/null @@ -1,29 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to have the base -# directories on the system disk in which the external model files are -# located be set to user-specified values. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -FV3GFS_FILE_FMT_ICS="grib2" -EXTRN_MDL_NAME_LBCS="FV3GFS" -FV3GFS_FILE_FMT_LBCS="grib2" - -DATE_FIRST_CYCL="20210615" -DATE_LAST_CYCL="20210615" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" - -EXTRN_MDL_SYSBASEDIR_ICS="set_to_non_default_location_in_testing_script" -EXTRN_MDL_SYSBASEDIR_LBCS="set_to_non_default_location_in_testing_script" diff --git a/tests/WE2E/test_configs/wflow_features/config.specify_EXTRN_MDL_SYSBASEDIR_ICS_LBCS.yaml b/tests/WE2E/test_configs/wflow_features/config.specify_EXTRN_MDL_SYSBASEDIR_ICS_LBCS.yaml new file mode 100644 index 0000000000..0e9414e3d3 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.specify_EXTRN_MDL_SYSBASEDIR_ICS_LBCS.yaml @@ -0,0 +1,26 @@ +metadata: + description: |- + This test checks the capability of the workflow to have the base + directories on the system disk in which the external model files are + located be set to user-specified values. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20210615' + DATE_LAST_CYCL: '20210615' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: grib2 + EXTRN_MDL_SYSBASEDIR_ICS: set_to_non_default_location_in_testing_script +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + FV3GFS_FILE_FMT_LBCS: grib2 + EXTRN_MDL_SYSBASEDIR_LBCS: set_to_non_default_location_in_testing_script +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.specify_RESTART_INTERVAL.sh b/tests/WE2E/test_configs/wflow_features/config.specify_RESTART_INTERVAL.sh deleted file mode 100644 index 3051cb5a89..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.specify_RESTART_INTERVAL.sh +++ /dev/null @@ -1,27 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to have the time -# interval (RESTART_INTERVAL) at which restart files are written by the -# forecast model be set to a user-specified value. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" - -RESTART_INTERVAL="1" diff --git a/tests/WE2E/test_configs/wflow_features/config.specify_RESTART_INTERVAL.yaml b/tests/WE2E/test_configs/wflow_features/config.specify_RESTART_INTERVAL.yaml new file mode 100644 index 0000000000..4fe820f9c2 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.specify_RESTART_INTERVAL.yaml @@ -0,0 +1,25 @@ +metadata: + description: |- + This test checks the capability of the workflow to have the time + interval (RESTART_INTERVAL) at which restart files are written by the + forecast model be set to a user-specified value. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + RESTART_INTERVAL: 1 + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.specify_template_filenames.sh b/tests/WE2E/test_configs/wflow_features/config.specify_template_filenames.sh deleted file mode 100644 index 81185425c6..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.specify_template_filenames.sh +++ /dev/null @@ -1,30 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to use user-defined -# template files. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -CCPP_PHYS_SUITE="FV3_GFS_v15p2" - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -USE_USER_STAGED_EXTRN_FILES="TRUE" - -DATE_FIRST_CYCL="20190701" -DATE_LAST_CYCL="20190701" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" - -DATA_TABLE_TMPL_FN="data_table" -DIAG_TABLE_TMPL_FN="diag_table" -FIELD_TABLE_TMPL_FN="field_table" -MODEL_CONFIG_TMPL_FN="model_configure" -NEMS_CONFIG_TMPL_FN="nems.configure" diff --git a/tests/WE2E/test_configs/wflow_features/config.specify_template_filenames.yaml b/tests/WE2E/test_configs/wflow_features/config.specify_template_filenames.yaml new file mode 100644 index 0000000000..448d3a81c1 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.specify_template_filenames.yaml @@ -0,0 +1,28 @@ +metadata: + description: |- + This test checks the capability of the workflow to use user-defined + template files. +user: + RUN_ENVIR: community +workflow: + DATA_TABLE_TMPL_FN: data_table + DIAG_TABLE_TMPL_FN: diag_table + FIELD_TABLE_TMPL_FN: field_table + MODEL_CONFIG_TMPL_FN: model_configure + NEMS_CONFIG_TMPL_FN: nems.configure + CCPP_PHYS_SUITE: FV3_GFS_v15p2 + DATE_FIRST_CYCL: '20190701' + DATE_LAST_CYCL: '20190701' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + USE_USER_STAGED_EXTRN_FILES: true +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + USE_USER_STAGED_EXTRN_FILES: true +task_run_fcst: + PREDEF_GRID_NAME: RRFS_CONUS_25km diff --git a/tests/WE2E/test_configs/wflow_features/config.subhourly_post.sh b/tests/WE2E/test_configs/wflow_features/config.subhourly_post.sh deleted file mode 100644 index a1676e4d58..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.subhourly_post.sh +++ /dev/null @@ -1,31 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to have the model write -# output files and perform post-processing on a sub-hourly time interval. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_25km" -CCPP_PHYS_SUITE="FV3_RRFS_v1beta" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="RAP" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200810" -DATE_LAST_CYCL="20200810" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="3" -LBC_SPEC_INTVL_HRS="1" - -DT_ATMOS="120" - -SUB_HOURLY_POST="TRUE" -DT_SUBHOURLY_POST_MNTS="2" diff --git a/tests/WE2E/test_configs/wflow_features/config.subhourly_post.yaml b/tests/WE2E/test_configs/wflow_features/config.subhourly_post.yaml new file mode 100644 index 0000000000..01094cc05b --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.subhourly_post.yaml @@ -0,0 +1,31 @@ +metadata: + description: |- + This test checks the capability of the workflow to have the model write + output files and perform post-processing on a sub-hourly time interval. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_RRFS_v1beta + DATE_FIRST_CYCL: '20200810' + DATE_LAST_CYCL: '20200810' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 3 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 1 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + DT_ATMOS: 120 + PREDEF_GRID_NAME: RRFS_CONUScompact_25km +task_run_post: + SUB_HOURLY_POST: true + DT_SUBHOURLY_POST_MNTS: 2 diff --git a/tests/WE2E/test_configs/wflow_features/config.subhourly_post_ensemble_2mems.sh b/tests/WE2E/test_configs/wflow_features/config.subhourly_post_ensemble_2mems.sh deleted file mode 100644 index adcc37a332..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.subhourly_post_ensemble_2mems.sh +++ /dev/null @@ -1,40 +0,0 @@ -# -# TEST PURPOSE/DESCRIPTION: -# ------------------------ -# -# This test checks the capability of the workflow to run ensemble forecasts -# that require the forecast model to write output files and perform post- -# processing on a sub-hourly time interval. -# -# This test is needed in addition to the one named "subhourly_post" -# because in the jinja template file from which the rocoto workflow XML -# is generated, the code changes that were made to add the subhourly -# capability also involved changes to the ensemble capability. -# - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUScompact_25km" -CCPP_PHYS_SUITE="FV3_RRFS_v1beta" - -EXTRN_MDL_NAME_ICS="HRRR" -EXTRN_MDL_NAME_LBCS="RAP" -USE_USER_STAGED_EXTRN_FILES="TRUE" -EXTRN_MDL_FILES_ICS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) -EXTRN_MDL_FILES_LBCS=( '{yy}{jjj}{hh}00{fcst_hr:02d}00' ) - -DATE_FIRST_CYCL="20200810" -DATE_LAST_CYCL="20200810" -CYCL_HRS=( "00" ) - -FCST_LEN_HRS="3" -LBC_SPEC_INTVL_HRS="1" - -DT_ATMOS="120" - -SUB_HOURLY_POST="TRUE" -DT_SUBHOURLY_POST_MNTS="12" - -DO_ENSEMBLE="TRUE" -NUM_ENS_MEMBERS="2" diff --git a/tests/WE2E/test_configs/wflow_features/config.subhourly_post_ensemble_2mems.yaml b/tests/WE2E/test_configs/wflow_features/config.subhourly_post_ensemble_2mems.yaml new file mode 100644 index 0000000000..851843bc81 --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.subhourly_post_ensemble_2mems.yaml @@ -0,0 +1,39 @@ +metadata: + description: |- + This test checks the capability of the workflow to run ensemble forecasts + that require the forecast model to write output files and perform post- + processing on a sub-hourly time interval. + This test is needed in addition to the one named "subhourly_post" + because in the jinja template file from which the rocoto workflow XML + is generated, the code changes that were made to add the subhourly + capability also involved changes to the ensemble capability. +user: + RUN_ENVIR: community +workflow: + CCPP_PHYS_SUITE: FV3_RRFS_v1beta + DATE_FIRST_CYCL: '20200810' + DATE_LAST_CYCL: '20200810' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 3 + PREEXISTING_DIR_METHOD: rename +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: HRRR + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_ICS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: RAP + LBC_SPEC_INTVL_HRS: 1 + USE_USER_STAGED_EXTRN_FILES: true + EXTRN_MDL_FILES_LBCS: + - '{yy}{jjj}{hh}00{fcst_hr:02d}00' +task_run_fcst: + DT_ATMOS: 120 + PREDEF_GRID_NAME: RRFS_CONUScompact_25km +task_run_post: + SUB_HOURLY_POST: true + DT_SUBHOURLY_POST_MNTS: 12 +global: + DO_ENSEMBLE: true + NUM_ENS_MEMBERS: 2 diff --git a/tests/WE2E/test_configs/wflow_features/config.template_vars.sh b/tests/WE2E/test_configs/wflow_features/config.template_vars.sh deleted file mode 120000 index 80ede54374..0000000000 --- a/tests/WE2E/test_configs/wflow_features/config.template_vars.sh +++ /dev/null @@ -1 +0,0 @@ -config.deactivate_tasks.sh \ No newline at end of file diff --git a/tests/WE2E/test_configs/wflow_features/config.template_vars.yaml b/tests/WE2E/test_configs/wflow_features/config.template_vars.yaml new file mode 120000 index 0000000000..858681e99a --- /dev/null +++ b/tests/WE2E/test_configs/wflow_features/config.template_vars.yaml @@ -0,0 +1 @@ +config.deactivate_tasks.yaml \ No newline at end of file diff --git a/ush/UFS_plot_domains.py b/ush/UFS_plot_domains.py index a6e629bd15..d752c2696b 100755 --- a/ush/UFS_plot_domains.py +++ b/ush/UFS_plot_domains.py @@ -10,27 +10,27 @@ # Computational grid definitions -ESGgrid_LON_CTR=-153.0 -ESGgrid_LAT_CTR=61.0 -ESGgrid_DELX=3000.0 -ESGgrid_DELY=3000.0 -ESGgrid_NX=1344 -ESGgrid_NY=1152 +ESGgrid_LON_CTR = -153.0 +ESGgrid_LAT_CTR = 61.0 +ESGgrid_DELX = 3000.0 +ESGgrid_DELY = 3000.0 +ESGgrid_NX = 1344 +ESGgrid_NY = 1152 # Write component grid definitions -WRTCMP_nx=1340 -WRTCMP_ny=1132 -WRTCMP_lon_lwr_left=151.5 -WRTCMP_lat_lwr_left=42.360 -WRTCMP_dx=ESGgrid_DELX -WRTCMP_dy=ESGgrid_DELY +WRTCMP_nx = 1340 +WRTCMP_ny = 1132 +WRTCMP_lon_lwr_left = 151.5 +WRTCMP_lat_lwr_left = 42.360 +WRTCMP_dx = ESGgrid_DELX +WRTCMP_dy = ESGgrid_DELY # Plot-specific definitions -plot_res='i' # background map resolution +plot_res = "i" # background map resolution -#Note: Resolution can be 'c' (crude), 'l' (low), 'i' (intermediate), 'h' (high), or 'f' (full) +# Note: Resolution can be 'c' (crude), 'l' (low), 'i' (intermediate), 'h' (high), or 'f' (full) # To plot maps with higher resolution than low, # you will need to download and install the basemap-data-hires package @@ -38,138 +38,170 @@ #### END User-defined variables - -ESGgrid_width = ESGgrid_NX * ESGgrid_DELX +ESGgrid_width = ESGgrid_NX * ESGgrid_DELX ESGgrid_height = ESGgrid_NY * ESGgrid_DELY -big_grid_width=np.ceil(ESGgrid_width*1.25) -big_grid_height=np.ceil(ESGgrid_height*1.25) +big_grid_width = np.ceil(ESGgrid_width * 1.25) +big_grid_height = np.ceil(ESGgrid_height * 1.25) -WRTCMP_width = WRTCMP_nx * WRTCMP_dx +WRTCMP_width = WRTCMP_nx * WRTCMP_dx WRTCMP_height = WRTCMP_ny * WRTCMP_dy fig = plt.figure() -#ax1 = plt.axes -ax1 = plt.subplot2grid((1,1), (0,0)) +# ax1 = plt.axes +ax1 = plt.subplot2grid((1, 1), (0, 0)) -map1 = Basemap(projection='gnom', resolution=plot_res, lon_0 = ESGgrid_LON_CTR, lat_0 = ESGgrid_LAT_CTR, - width = big_grid_width, height=big_grid_height) +map1 = Basemap( + projection="gnom", + resolution=plot_res, + lon_0=ESGgrid_LON_CTR, + lat_0=ESGgrid_LAT_CTR, + width=big_grid_width, + height=big_grid_height, +) -map1.drawmapboundary(fill_color='#9999FF') -map1.fillcontinents(color='#ddaa66',lake_color='#9999FF') +map1.drawmapboundary(fill_color="#9999FF") +map1.fillcontinents(color="#ddaa66", lake_color="#9999FF") map1.drawcoastlines() -map2 = Basemap(projection='gnom', lon_0 = ESGgrid_LON_CTR, lat_0 = ESGgrid_LAT_CTR, - width = ESGgrid_width, height=ESGgrid_height) +map2 = Basemap( + projection="gnom", + lon_0=ESGgrid_LON_CTR, + lat_0=ESGgrid_LAT_CTR, + width=ESGgrid_width, + height=ESGgrid_height, +) -#map2.drawmapboundary(fill_color='#9999FF') -#map2.fillcontinents(color='#ddaa66',lake_color='#9999FF') -#map2.drawcoastlines() +# map2.drawmapboundary(fill_color='#9999FF') +# map2.fillcontinents(color='#ddaa66',lake_color='#9999FF') +# map2.drawcoastlines() -map3 = Basemap(llcrnrlon= WRTCMP_lon_lwr_left, llcrnrlat=WRTCMP_lat_lwr_left, width=WRTCMP_width, height=WRTCMP_height, - resolution=plot_res, projection='lcc', lat_0 = ESGgrid_LAT_CTR, lon_0 = ESGgrid_LON_CTR) +map3 = Basemap( + llcrnrlon=WRTCMP_lon_lwr_left, + llcrnrlat=WRTCMP_lat_lwr_left, + width=WRTCMP_width, + height=WRTCMP_height, + resolution=plot_res, + projection="lcc", + lat_0=ESGgrid_LAT_CTR, + lon_0=ESGgrid_LON_CTR, +) -#map3.drawmapboundary(fill_color='#9999FF') -#map3.fillcontinents(color='#ddaa66',lake_color='#9999FF',alpha=0.5) -#map3.drawcoastlines() +# map3.drawmapboundary(fill_color='#9999FF') +# map3.fillcontinents(color='#ddaa66',lake_color='#9999FF',alpha=0.5) +# map3.drawcoastlines() -#Draw gnomonic compute grid rectangle: +# Draw gnomonic compute grid rectangle: -lbx1, lby1 = map1(*map2(map2.xmin, map2.ymin, inverse= True)) -ltx1, lty1 = map1(*map2(map2.xmin, map2.ymax, inverse= True)) -rtx1, rty1 = map1(*map2(map2.xmax, map2.ymax, inverse= True)) -rbx1, rby1 = map1(*map2(map2.xmax, map2.ymin, inverse= True)) +lbx1, lby1 = map1(*map2(map2.xmin, map2.ymin, inverse=True)) +ltx1, lty1 = map1(*map2(map2.xmin, map2.ymax, inverse=True)) +rtx1, rty1 = map1(*map2(map2.xmax, map2.ymax, inverse=True)) +rbx1, rby1 = map1(*map2(map2.xmax, map2.ymin, inverse=True)) verts1 = [ - (lbx1, lby1), # left, bottom - (ltx1, lty1), # left, top - (rtx1, rty1), # right, top - (rbx1, rby1), # right, bottom - (lbx1, lby1), # ignored - ] - -codes2 = [Path.MOVETO, - Path.LINETO, - Path.LINETO, - Path.LINETO, - Path.CLOSEPOLY, - ] + (lbx1, lby1), # left, bottom + (ltx1, lty1), # left, top + (rtx1, rty1), # right, top + (rbx1, rby1), # right, bottom + (lbx1, lby1), # ignored +] + +codes2 = [ + Path.MOVETO, + Path.LINETO, + Path.LINETO, + Path.LINETO, + Path.CLOSEPOLY, +] path = Path(verts1, codes2) -patch = patches.PathPatch(path, facecolor='r', lw=2,alpha=0.5) +patch = patches.PathPatch(path, facecolor="r", lw=2, alpha=0.5) ax1.add_patch(patch) -#Draw lambert write grid rectangle: +# Draw lambert write grid rectangle: # Define a function to get the lambert points in the gnomonic space -def get_lambert_points(gnomonic_map, lambert_map,pps): - print("Hello from a function") - - # This function takes the lambert domain we have defined, lambert_map, as well as - # pps (the number of points to interpolate and draw for each side of the lambert "rectangle"), - # and returns an array of two lists: one a list of tuples of the 4*ppf + 4 vertices mapping the approximate shape + +def get_lambert_points(gnomonic_map, lambert_map, pps): + #print("Hello from a function") + + # This function takes the lambert domain we have defined, lambert_map, as well as + # pps (the number of points to interpolate and draw for each side of the lambert "rectangle"), + # and returns an array of two lists: one a list of tuples of the 4*ppf + 4 vertices mapping the approximate shape # of the lambert domain on the gnomonic map, the other a list of "draw" instructions to be used by # the PathPatch function - + # pps is recommended 10 or less due to time of calculation - + # Start array with bottom left point, "MOVETO" instruction - vertices = [gnomonic_map(*lambert_map(lambert_map.xmin, lambert_map.ymin, inverse= True))] + vertices = [ + gnomonic_map(*lambert_map(lambert_map.xmin, lambert_map.ymin, inverse=True)) + ] instructions = [Path.MOVETO] - + # Next generate the rest of the left side - lefty = np.linspace(lambert_map.ymin, lambert_map.ymax, num=pps+1, endpoint=False) - + lefty = np.linspace(lambert_map.ymin, lambert_map.ymax, num=pps + 1, endpoint=False) + for y in lefty[1:]: - vertices.append(tuple(gnomonic_map(*lambert_map(lambert_map.xmin, y, inverse= True)))) + vertices.append( + tuple(gnomonic_map(*lambert_map(lambert_map.xmin, y, inverse=True))) + ) instructions.append(Path.LINETO) - + # Next generate the top of the domain - topx = np.linspace(lambert_map.xmin, lambert_map.xmax, num=pps+1, endpoint=False) - + topx = np.linspace(lambert_map.xmin, lambert_map.xmax, num=pps + 1, endpoint=False) + for x in topx: - vertices.append(tuple(gnomonic_map(*lambert_map(x, lambert_map.ymax, inverse= True)))) + vertices.append( + tuple(gnomonic_map(*lambert_map(x, lambert_map.ymax, inverse=True))) + ) instructions.append(Path.LINETO) # Next generate the right side of the domain - righty = np.linspace(lambert_map.ymax, lambert_map.ymin, num=pps+1, endpoint=False) - + righty = np.linspace( + lambert_map.ymax, lambert_map.ymin, num=pps + 1, endpoint=False + ) + for y in righty: - vertices.append(tuple(gnomonic_map(*lambert_map(lambert_map.xmax, y, inverse= True)))) + vertices.append( + tuple(gnomonic_map(*lambert_map(lambert_map.xmax, y, inverse=True))) + ) instructions.append(Path.LINETO) - # Finally generate the bottom of the domain - bottomx = np.linspace(lambert_map.xmax, lambert_map.xmin, num=pps+1, endpoint=False) - + bottomx = np.linspace( + lambert_map.xmax, lambert_map.xmin, num=pps + 1, endpoint=False + ) + for x in bottomx: - vertices.append(tuple(gnomonic_map(*lambert_map(x, lambert_map.ymin, inverse= True)))) + vertices.append( + tuple(gnomonic_map(*lambert_map(x, lambert_map.ymin, inverse=True))) + ) instructions.append(Path.LINETO) # Need to replace final instruction with Path.CLOSEPOLY instructions[-1] = Path.CLOSEPOLY - print ("vertices=",vertices) - print ("instructions=",instructions) + #print("vertices=", vertices) + #print("instructions=", instructions) + + return vertices, instructions - return vertices,instructions # Call the function we just defined to generate a polygon roughly approximating the lambert "rectangle" in gnomonic space -verts3,codes3=get_lambert_points(map1, map3,10) +verts3, codes3 = get_lambert_points(map1, map3, 10) # Now draw! path = Path(verts3, codes3) -patch = patches.PathPatch(path, facecolor='w', lw=2,alpha=0.5) +patch = patches.PathPatch(path, facecolor="w", lw=2, alpha=0.5) ax1.add_patch(patch) plt.show() - - diff --git a/ush/bash_utils/source_config.sh b/ush/bash_utils/source_config.sh new file mode 100644 index 0000000000..271c462814 --- /dev/null +++ b/ush/bash_utils/source_config.sh @@ -0,0 +1,94 @@ +# +#----------------------------------------------------------------------- +# This file defines function that sources a config file (yaml/json etc) +# into the calling shell script +#----------------------------------------------------------------------- +# + +function config_to_str() { +# +#----------------------------------------------------------------------- +# +# Save current shell options (in a global array). Then set new options +# for this script/function. +# +#----------------------------------------------------------------------- +# + { save_shell_opts; set -u +x; } > /dev/null 2>&1 + +# +#----------------------------------------------------------------------- +# +# Get the full path to the file in which this script/function is located +# (scrfunc_fp), the name of that file (scrfunc_fn), and the directory in +# which the file is located (scrfunc_dir). +# +#----------------------------------------------------------------------- +# + local scrfunc_fp=$( $READLINK -f "${BASH_SOURCE[0]}" ) + local scrfunc_fn=$( basename "${scrfunc_fp}" ) + local scrfunc_dir=$( dirname "${scrfunc_fp}" ) + +# +#----------------------------------------------------------------------- +# Get the contents of a config file as shell string +#----------------------------------------------------------------------- +# + local ushdir=${scrfunc_dir%/*} + + $ushdir/config_utils.py -o $1 -c $2 "${@:3}" + +# +#----------------------------------------------------------------------- +# +# Restore the shell options saved at the beginning of this script/func- +# tion. +# +#----------------------------------------------------------------------- +# + { restore_shell_opts; } > /dev/null 2>&1 + +} + +# +#----------------------------------------------------------------------- +# Define functions for different file formats +#----------------------------------------------------------------------- +# +function config_to_shell_str() { + config_to_str shell "$@" +} +function config_to_ini_str() { + config_to_str ini "$@" +} +function config_to_yaml_str() { + config_to_str yaml "$@" +} +function config_to_json_str() { + config_to_str json "$@" +} +function config_to_xml_str() { + config_to_str xml "$@" +} + +# +#----------------------------------------------------------------------- +# Source contents of a config file to shell script +#----------------------------------------------------------------------- +# +function source_config() { + + source <( config_to_shell_str "$@" ) + +} +# +#----------------------------------------------------------------------- +# Source partial contents of a config file to shell script. +# Only those variables needed by the task are sourced +#----------------------------------------------------------------------- +# +function source_config_for_task() { + + source <( config_to_shell_str "${@:2}" -k "(^(?!task_)|$1).*" ) + +} diff --git a/ush/calculate_cost.py b/ush/calculate_cost.py index 010b892232..3fc1455c3a 100755 --- a/ush/calculate_cost.py +++ b/ush/calculate_cost.py @@ -4,103 +4,107 @@ import unittest import argparse -from python_utils import set_env_var, import_vars, export_vars, load_config_file, flatten_dict +from python_utils import ( + set_env_var, + import_vars, + export_vars, + load_config_file, + flatten_dict, +) from set_predef_grid_params import set_predef_grid_params from set_gridparams_ESGgrid import set_gridparams_ESGgrid from set_gridparams_GFDLgrid import set_gridparams_GFDLgrid + def calculate_cost(config_fn): global PREDEF_GRID_NAME, QUILTING, GRID_GEN_METHOD - #import all environment variables + # import all environment variables import_vars() - #get grid config parameters (predefined or custom) + # get grid config parameters (predefined or custom) if PREDEF_GRID_NAME: - set_env_var('QUILTING',False) + set_env_var("QUILTING", False) set_predef_grid_params() import_vars() else: cfg_u = load_config_file(config_fn) cfg_u = flatten_dict(cfg_u) import_vars(dictionary=cfg_u) - - #number of gridpoints (nx*ny) depends on grid generation method + + # number of gridpoints (nx*ny) depends on grid generation method if GRID_GEN_METHOD == "GFDLgrid": - (\ - LON_CTR,LAT_CTR,NX,NY,NHW,STRETCH_FAC, - ISTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG, - IEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG, - JSTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG, - JEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG \ - ) = \ - set_gridparams_GFDLgrid( \ - lon_of_t6_ctr=GFDLgrid_LON_T6_CTR, \ - lat_of_t6_ctr=GFDLgrid_LAT_T6_CTR, \ - res_of_t6g=GFDLgrid_NUM_CELLS, \ - stretch_factor=GFDLgrid_STRETCH_FAC, \ - refine_ratio_t6g_to_t7g=GFDLgrid_REFINE_RATIO, \ - istart_of_t7_on_t6g=GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G, \ - iend_of_t7_on_t6g=GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G, \ - jstart_of_t7_on_t6g=GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G, \ - jend_of_t7_on_t6g=GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G) + grid_params = set_gridparams_GFDLgrid( + lon_of_t6_ctr=GFDLgrid_LON_T6_CTR, + lat_of_t6_ctr=GFDLgrid_LAT_T6_CTR, + res_of_t6g=GFDLgrid_NUM_CELLS, + stretch_factor=GFDLgrid_STRETCH_FAC, + refine_ratio_t6g_to_t7g=GFDLgrid_REFINE_RATIO, + istart_of_t7_on_t6g=GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G, + iend_of_t7_on_t6g=GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G, + jstart_of_t7_on_t6g=GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G, + jend_of_t7_on_t6g=GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G, + ) elif GRID_GEN_METHOD == "ESGgrid": - (\ - LON_CTR,LAT_CTR,NX,NY,PAZI, - NHW,STRETCH_FAC,DEL_ANGLE_X_SG,DEL_ANGLE_Y_SG, - NEG_NX_OF_DOM_WITH_WIDE_HALO, - NEG_NY_OF_DOM_WITH_WIDE_HALO \ - ) = \ - set_gridparams_ESGgrid( \ - lon_ctr=ESGgrid_LON_CTR, \ - lat_ctr=ESGgrid_LAT_CTR, \ - nx=ESGgrid_NX, \ - ny=ESGgrid_NY, \ - pazi=ESGgrid_PAZI, \ - halo_width=ESGgrid_WIDE_HALO_WIDTH, \ - delx=ESGgrid_DELX, \ - dely=ESGgrid_DELY) - - cost = [DT_ATMOS, NX*NY] - - #reference grid (6-hour forecast on RRFS_CONUS_25km) - PREDEF_GRID_NAME="RRFS_CONUS_25km" + grid_params = set_gridparams_ESGgrid( + lon_ctr=ESGgrid_LON_CTR, + lat_ctr=ESGgrid_LAT_CTR, + nx=ESGgrid_NX, + ny=ESGgrid_NY, + pazi=ESGgrid_PAZI, + halo_width=ESGgrid_WIDE_HALO_WIDTH, + delx=ESGgrid_DELX, + dely=ESGgrid_DELY, + ) + + NX = grid_params["NX"] + NY = grid_params["NY"] + cost = [DT_ATMOS, NX * NY] + + # reference grid (6-hour forecast on RRFS_CONUS_25km) + PREDEF_GRID_NAME = "RRFS_CONUS_25km" export_vars() set_predef_grid_params() import_vars() - cost.extend([DT_ATMOS, ESGgrid_NX*ESGgrid_NY]) - + cost.extend([DT_ATMOS, ESGgrid_NX * ESGgrid_NY]) + return cost -#interface + +# interface if __name__ == "__main__": - parser = argparse.ArgumentParser(description=\ - 'Calculates parameters needed for calculating cost.') - parser.add_argument('--cfg','-c',dest='cfg',required=True, - help='config file containing grip params') + parser = argparse.ArgumentParser( + description="Calculates parameters needed for calculating cost." + ) + parser.add_argument( + "--cfg", + "-c", + dest="cfg", + required=True, + help="config file containing grid params", + ) args = parser.parse_args() params = calculate_cost(args.cfg) - print(' '.join(map(str,params))) + print(" ".join(map(str, params))) + class Testing(unittest.TestCase): def test_calculate_cost(self): USHDIR = os.path.dirname(os.path.abspath(__file__)) - config_fn = os.path.join(USHDIR, "config.community.sh") - params = calculate_cost(config_fn) + params = calculate_cost(None) self.assertCountEqual(params, [36, 1987440, 36, 28689]) def setUp(self): - set_env_var('DEBUG',False) - set_env_var('PREDEF_GRID_NAME',"RRFS_CONUS_3km") - set_env_var('DT_ATMOS',36) - set_env_var('LAYOUT_X',18) - set_env_var('LAYOUT_Y',36) - set_env_var('BLOCKSIZE',28) - set_env_var('QUILTING',False) - set_env_var('RADIUS_EARTH',6371200.0) - set_env_var('DEGS_PER_RADIAN',57.2957795131) - + set_env_var("DEBUG", False) + set_env_var("PREDEF_GRID_NAME", "RRFS_CONUS_3km") + set_env_var("DT_ATMOS", 36) + set_env_var("LAYOUT_X", 18) + set_env_var("LAYOUT_Y", 36) + set_env_var("BLOCKSIZE", 28) + set_env_var("QUILTING", False) + set_env_var("RADIUS_EARTH", 6371200.0) + set_env_var("DEGS_PER_RADIAN", 57.2957795131) diff --git a/ush/check_expt_config_vars.sh b/ush/check_expt_config_vars.sh deleted file mode 100644 index c55a392295..0000000000 --- a/ush/check_expt_config_vars.sh +++ /dev/null @@ -1,110 +0,0 @@ -# -#----------------------------------------------------------------------- -# -# This file defines a function that checks that all experiment variables -# set in the user-specified experiment configuration file are defined (by -# being assigned default values) in the default experiment configuration -# file. If a variable is found in the former that is not defined in the -# latter, this function exits with an error message. -# -# This check is performed in order to prevent the user from defining -# arbitrary variables in the user-specified configuration file; the -# latter should be used to specify only varaibles that have already been -# defined in the default configuration file. -# -# Arguments are as follows: -# -# default_config_fp: -# The relative or full path to the default experiment configuration file. -# -# config_fp: -# The relative or full path to the user-specified experiment configuration -# file. -# -#----------------------------------------------------------------------- -# -function check_expt_config_vars() { - - . ${scrfunc_dir}/source_util_funcs.sh - - { save_shell_opts; set -u +x; } > /dev/null 2>&1 - - local valid_args=( \ - "default_config_fp" \ - "config_fp" \ - ) - process_args valid_args "$@" - print_input_args "valid_args" - - local var_list_default \ - var_list_user \ - crnt_line \ - var_name \ - regex_search - # - # Get the list of variable definitions, first from the default experiment - # configuration file and then from the user-specified experiment - # configuration file. - # - get_bash_file_contents fp="${default_config_fp}" \ - outvarname_contents="var_list_default" - - get_bash_file_contents fp="${config_fp}" \ - outvarname_contents="var_list_user" - # - # Loop through each line/variable in var_list_user. For each line, - # extract the the name of the variable that is being set (say VAR) and - # check that this variable is set somewhere in the default configuration - # file by verifying that a line that starts with "VAR=" exists in - # var_list_default. - # - while read crnt_line; do - # - # Note that a variable name will be found only if the equal sign immediately - # follows the variable name. - # - var_name=$( printf "%s" "${crnt_line}" | $SED -n -r -e "s/^([^ =\"]*)=.*/\1/p" ) - - if [ -z "${var_name}" ]; then - - print_info_msg " -The current line (crnt_line) of the user-specified experiment configuration -file (config_fp) does not contain a variable name (i.e. var_name is empty): - config_fp = \"${config_fp}\" - crnt_line = \"${crnt_line}\" - var_name = \"${var_name}\" -Skipping to next line." - - else - # - # Use grep to search for the variable name (followed by an equal sign, - # all at the beginning of a line) in the list of variables in the default - # configuration file. - # - # Note that we use a herestring to input into grep the list of variables - # in the default configuration file. grep will return with a zero status - # if the specified string (regex_search) is not found in the default - # variables list and a nonzero status otherwise. Note also that we - # redirect the output of grep to null because we are only interested in - # its exit status. - # - regex_search="^${var_name}=" - grep "${regex_search}" <<< "${var_list_default}" > /dev/null 2>&1 || \ - print_err_msg_exit "\ -The variable (var_name) defined on the current line (crnt_line) of the -user-specified experiment configuration file (config_fp) does not appear -in the default experiment configuration file (default_config_fp): - config_fp = \"${config_fp}\" - default_config_fp = \"${default_config_fp}\" - crnt_line = \"${crnt_line}\" - var_name = \"${var_name}\" -Please assign a default value to this variable in the default configuration -file and rerun." - - fi - - done <<< "${var_list_user}" - - { restore_shell_opts; } > /dev/null 2>&1 - -} diff --git a/ush/check_ruc_lsm.py b/ush/check_ruc_lsm.py index fdf288f30a..44dc72266d 100644 --- a/ush/check_ruc_lsm.py +++ b/ush/check_ruc_lsm.py @@ -3,11 +3,16 @@ import os import unittest -from python_utils import set_env_var, print_input_args, \ - load_xml_file, has_tag_with_value +from python_utils import ( + set_env_var, + print_input_args, + load_xml_file, + has_tag_with_value, +) + def check_ruc_lsm(ccpp_phys_suite_fp): - """ This file defines a function that checks whether the RUC land surface + """This file defines a function that checks whether the RUC land surface model (LSM) parameterization is being called by the selected physics suite. Args: @@ -22,9 +27,12 @@ def check_ruc_lsm(ccpp_phys_suite_fp): has_ruc = has_tag_with_value(tree, "scheme", "lsm_ruc") return has_ruc + class Testing(unittest.TestCase): def test_check_ruc_lsm(self): - self.assertTrue( check_ruc_lsm(ccpp_phys_suite_fp=f"test_data{os.sep}suite_FV3_GSD_SAR.xml") ) - def setUp(self): - set_env_var('DEBUG',True) + self.assertTrue( + check_ruc_lsm(ccpp_phys_suite_fp=f"test_data{os.sep}suite_FV3_GSD_SAR.xml") + ) + def setUp(self): + set_env_var("DEBUG", True) diff --git a/ush/config.community.sh b/ush/config.community.sh deleted file mode 100644 index e483a4b597..0000000000 --- a/ush/config.community.sh +++ /dev/null @@ -1,65 +0,0 @@ -MACHINE="hera" -ACCOUNT="an_account" -EXPT_SUBDIR="test_community" - -COMPILER="intel" -VERBOSE="TRUE" - -RUN_ENVIR="community" -PREEXISTING_DIR_METHOD="rename" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -QUILTING="TRUE" - -DO_ENSEMBLE="FALSE" -NUM_ENS_MEMBERS="2" - -CCPP_PHYS_SUITE="FV3_GFS_v16" -FCST_LEN_HRS="12" -LBC_SPEC_INTVL_HRS="6" - -DATE_FIRST_CYCL="20190615" -DATE_LAST_CYCL="20190615" -CYCL_HRS=( "18" ) - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" - -FV3GFS_FILE_FMT_ICS="grib2" -FV3GFS_FILE_FMT_LBCS="grib2" - -WTIME_RUN_FCST="02:00:00" - -MODEL="FV3_GFS_v16_CONUS_25km" -METPLUS_PATH="path/to/METPlus" -MET_INSTALL_DIR="path/to/MET" -CCPA_OBS_DIR="/path/to/processed/CCPA/data" -MRMS_OBS_DIR="/path/to/processed/MRMS/data" -NDAS_OBS_DIR="/path/to/processed/NDAS/data" - -RUN_TASK_MAKE_GRID="TRUE" -RUN_TASK_MAKE_OROG="TRUE" -RUN_TASK_MAKE_SFC_CLIMO="TRUE" -RUN_TASK_GET_OBS_CCPA="FALSE" -RUN_TASK_GET_OBS_MRMS="FALSE" -RUN_TASK_GET_OBS_NDAS="FALSE" -RUN_TASK_VX_GRIDSTAT="FALSE" -RUN_TASK_VX_POINTSTAT="FALSE" -RUN_TASK_VX_ENSGRID="FALSE" -RUN_TASK_VX_ENSPOINT="FALSE" - -# -# Uncomment the following line in order to use user-staged external model -# files with locations and names as specified by EXTRN_MDL_SOURCE_BASEDIR_ICS/ -# LBCS and EXTRN_MDL_FILES_ICS/LBCS. -# -#USE_USER_STAGED_EXTRN_FILES="TRUE" -# -# The following is specifically for Hera. It will have to be modified -# if on another platform, using other dates, other external models, etc. -# Uncomment the following EXTRN_MDL_*_ICS/LBCS only when USE_USER_STAGED_EXTRN_FILES=TRUE -# -#EXTRN_MDL_SOURCE_BASEDIR_ICS="/scratch2/BMC/det/UFS_SRW_App/develop/input_model_data/FV3GFS/grib2/2019061518" -#EXTRN_MDL_FILES_ICS=( "gfs.t18z.pgrb2.0p25.f000" ) -#EXTRN_MDL_SOURCE_BASEDIR_LBCS="/scratch2/BMC/det/UFS_SRW_App/develop/input_model_data/FV3GFS/grib2/2019061518" -#EXTRN_MDL_FILES_LBCS=( "gfs.t18z.pgrb2.0p25.f006" "gfs.t18z.pgrb2.0p25.f012") diff --git a/ush/config.community.yaml b/ush/config.community.yaml new file mode 100644 index 0000000000..53c97a218b --- /dev/null +++ b/ush/config.community.yaml @@ -0,0 +1,50 @@ +metadata: + description: >- + Sample community config +user: + RUN_ENVIR: community + MACHINE: hera + ACCOUNT: an_account +platform: + MODEL: FV3_GFS_v16_CONUS_25km + MET_INSTALL_DIR: path/to/MET + METPLUS_PATH: path/to/METPlus + CCPA_OBS_DIR: /path/to/processed/CCPA/data + MRMS_OBS_DIR: /path/to/processed/MRMS/data + NDAS_OBS_DIR: /path/to/processed/NDAS/data +workflow: + EXPT_SUBDIR: test_community + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20190615' + DATE_LAST_CYCL: '20190615' + CYCL_HRS: + - 18 + FCST_LEN_HRS: 12 + PREEXISTING_DIR_METHOD: rename + VERBOSE: true + COMPILER: intel +workflow_switches: + RUN_TASK_MAKE_GRID: true + RUN_TASK_MAKE_OROG: true + RUN_TASK_MAKE_SFC_CLIMO: true + RUN_TASK_GET_OBS_CCPA: false + RUN_TASK_GET_OBS_MRMS: false + RUN_TASK_GET_OBS_NDAS: false + RUN_TASK_VX_GRIDSTAT: false + RUN_TASK_VX_POINTSTAT: false + RUN_TASK_VX_ENSGRID: false + RUN_TASK_VX_ENSPOINT: false +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: grib2 +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 6 + FV3GFS_FILE_FMT_LBCS: grib2 +task_run_fcst: + WTIME_RUN_FCST: 02:00:00 + QUILTING: true + PREDEF_GRID_NAME: RRFS_CONUS_25km +global: + DO_ENSEMBLE: false + NUM_ENS_MEMBERS: 2 diff --git a/ush/config.nco.sh b/ush/config.nco.sh deleted file mode 100644 index 556aa65218..0000000000 --- a/ush/config.nco.sh +++ /dev/null @@ -1,51 +0,0 @@ -MACHINE="hera" -ACCOUNT="an_account" -EXPT_SUBDIR="test_nco" - -COMPILER="intel" -VERBOSE="TRUE" - -RUN_ENVIR="nco" -PREEXISTING_DIR_METHOD="rename" - -USE_CRON_TO_RELAUNCH="TRUE" -CRON_RELAUNCH_INTVL_MNTS="3" - -PREDEF_GRID_NAME="RRFS_CONUS_25km" -QUILTING="TRUE" - -CCPP_PHYS_SUITE="FV3_GFS_v16" - -FCST_LEN_HRS="6" -LBC_SPEC_INTVL_HRS="3" - -DATE_FIRST_CYCL="20220407" -DATE_LAST_CYCL="20220407" -CYCL_HRS=( "00" ) - -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" - -FV3GFS_FILE_FMT_ICS="grib2" -FV3GFS_FILE_FMT_LBCS="grib2" - -WTIME_RUN_FCST="01:00:00" - -WRITE_DOPOST="TRUE" - -# -# Output directory: {NET}/{model_ver}/{RUN}.YYYYMMDD/ -# Output file name: {NET}.tHHz.[var_name].f###.{POST_OUTPUT_DOMAIN_NAME}.grib2 -# -POST_OUTPUT_DOMAIN_NAME="conus_25km" -NET="rrfs" -model_ver="v1.0" -RUN="rrfs_test" -# -# The following must be modified for different platforms and users. -# -COMIN="/scratch1/NCEPDEV/rstprod/com/gfs/prod" # Path to directory containing files from the external model. -DOMAIN_PREGEN_BASEDIR="/scratch2/BMC/det/UFS_SRW_App/develop/FV3LAM_pregen" # Path to directory containing the pregenerated grid, orography, and surface climatology "fixed" files to use for the experiment. -STMP="/path/to/stmp/directory" # Path to directory STMP that mostly contains input files. -PTMP="/path/to/ptmp/directory" # Path to directory PTMP in which the experiment's output files will be placed. - diff --git a/ush/config.nco.yaml b/ush/config.nco.yaml new file mode 100644 index 0000000000..df6bcf5a98 --- /dev/null +++ b/ush/config.nco.yaml @@ -0,0 +1,42 @@ +metadata: + description: >- + Sample nco config +user: + RUN_ENVIR: nco + MACHINE: hera + ACCOUNT: an_account +platform: + DOMAIN_PREGEN_BASEDIR: /scratch2/BMC/det/UFS_SRW_App/develop/FV3LAM_pregen +workflow: + USE_CRON_TO_RELAUNCH: true + CRON_RELAUNCH_INTVL_MNTS: 3 + EXPT_SUBDIR: test_nco + COMIN: /scratch1/NCEPDEV/rstprod/com/gfs/prod + NET: rrfs + model_ver: v1.0 + RUN: rrfs_test + STMP: /path/to/stmp/directory + PTMP: /path/to/ptmp/directory + CCPP_PHYS_SUITE: FV3_GFS_v16 + DATE_FIRST_CYCL: '20220407' + DATE_LAST_CYCL: '20220407' + CYCL_HRS: + - 0 + FCST_LEN_HRS: 6 + PREEXISTING_DIR_METHOD: rename + VERBOSE: true + COMPILER: intel +task_get_extrn_ics: + EXTRN_MDL_NAME_ICS: FV3GFS + FV3GFS_FILE_FMT_ICS: grib2 +task_get_extrn_lbcs: + EXTRN_MDL_NAME_LBCS: FV3GFS + LBC_SPEC_INTVL_HRS: 3 + FV3GFS_FILE_FMT_LBCS: grib2 +task_run_fcst: + WTIME_RUN_FCST: 01:00:00 + WRITE_DOPOST: true + QUILTING: true + PREDEF_GRID_NAME: RRFS_CONUS_25km +task_run_post: + POST_OUTPUT_DOMAIN_NAME: conus_25km diff --git a/ush/config_defaults.sh b/ush/config_defaults.sh deleted file mode 100644 index 6c9dc7b032..0000000000 --- a/ush/config_defaults.sh +++ /dev/null @@ -1,2027 +0,0 @@ -# -#----------------------------------------------------------------------- -# -# This file sets the experiment's configuration variables (which are -# global shell variables) to their default values. For many of these -# variables, the valid values that they may take on are defined in the -# file $USHDIR/valid_param_vals.py. -# -#----------------------------------------------------------------------- -# - -# -#----------------------------------------------------------------------- -# -# Set the RUN_ENVIR variable that is listed and described in the WCOSS -# Implementation Standards document: -# -# NCEP Central Operations -# WCOSS Implementation Standards -# January 19, 2022 -# Version 11.0.0 -# -# RUN_ENVIR is described in this document as follows: -# -# Set to "nco" if running in NCO's production environment. Used to -# distinguish between organizations. -# -# Valid values are "nco" and "community". Here, we use it to generate -# and run the experiment either in NCO mode (if RUN_ENVIR is set to "nco") -# or in community mode (if RUN_ENVIR is set to "community"). This has -# implications on the experiment variables that need to be set and the -# the directory structure used. -# -#----------------------------------------------------------------------- -# -RUN_ENVIR="nco" -# -#----------------------------------------------------------------------- -# -# mach_doc_start -# Set machine and queue parameters. Definitions: -# -# MACHINE: -# Machine on which the workflow will run. If you are NOT on a named, -# supported platform, and you want to use the Rocoto workflow manager, -# you will need set MACHINE="linux" and WORKFLOW_MANAGER="rocoto". This -# combination will assume a Slurm batch manager when generating the XML. -# Please see ush/valid_param_vals.py for a full list of supported -# platforms. -# -# MACHINE_FILE: -# Path to a configuration file with machine-specific settings. If none -# is provided, setup.sh will attempt to set the path to for a supported -# platform. -# -# ACCOUNT: -# The account under which to submit jobs to the queue. -# -# WORKFLOW_MANAGER: -# The workflow manager to use (e.g. rocoto). This is set to "none" by -# default, but if the machine name is set to a platform that supports -# rocoto, this will be overwritten and set to "rocoto". If set -# explicitly to rocoto along with the use of the MACHINE=linux target, -# the configuration layer assumes a Slurm batch manager when generating -# the XML. Valid options: "rocoto" or "none" -# -# NCORES_PER_NODE: -# The number of cores available per node on the compute platform. Set -# for supported platforms in setup.sh, but is now also configurable for -# all platforms. -# -# LMOD_PATH: -# Path to the LMOD sh file on your Linux system. Is set automatically -# for supported machines. -# -# BUILD_MOD_FN: -# Name of build module file to load before running a workflow task. If -# this is not specified by the user in the experiment configuration file -# (EXPT_CONFIG_FN), it will be set automatically for supported machines. -# -# WFLOW_MOD_FN: -# Name of workflow module file to load before (re)launching the experiment's -# ROCOTO workflow (using the "rocotorun" command). If this is not specified -# by the user in the experiment configuration file (EXPT_CONFIG_FN), it -# will be set automatically for supported machines. -# -# SCHED: -# The job scheduler to use (e.g. slurm). Set this to an empty string in -# order for the experiment generation script to set it depending on the -# machine. -# -# PARTITION_DEFAULT: -# If using the slurm job scheduler (i.e. if SCHED is set to "slurm"), -# the default partition to which to submit workflow tasks. If a task -# does not have a specific variable that specifies the partition to which -# it will be submitted (e.g. PARTITION_HPSS, PARTITION_FCST; see below), -# it will be submitted to the partition specified by this variable. If -# this is not set or is set to an empty string, it will be (re)set to a -# machine-dependent value. This is not used if SCHED is not set to -# "slurm". -# -# QUEUE_DEFAULT: -# The default queue or QOS (if using the slurm job scheduler, where QOS -# is Quality of Service) to which workflow tasks are submitted. If a -# task does not have a specific variable that specifies the queue to which -# it will be submitted (e.g. QUEUE_HPSS, QUEUE_FCST; see below), it will -# be submitted to the queue specified by this variable. If this is not -# set or is set to an empty string, it will be (re)set to a machine- -# dependent value. -# -# PARTITION_HPSS: -# If using the slurm job scheduler (i.e. if SCHED is set to "slurm"), -# the partition to which the tasks that get or create links to external -# model files [which are needed to generate initial conditions (ICs) and -# lateral boundary conditions (LBCs)] are submitted. If this is not set -# or is set to an empty string, it will be (re)set to a machine-dependent -# value. This is not used if SCHED is not set to "slurm". -# -# QUEUE_HPSS: -# The queue or QOS to which the tasks that get or create links to external -# model files [which are needed to generate initial conditions (ICs) and -# lateral boundary conditions (LBCs)] are submitted. If this is not set -# or is set to an empty string, it will be (re)set to a machine-dependent -# value. -# -# PARTITION_FCST: -# If using the slurm job scheduler (i.e. if SCHED is set to "slurm"), -# the partition to which the task that runs forecasts is submitted. If -# this is not set or set to an empty string, it will be (re)set to a -# machine-dependent value. This is not used if SCHED is not set to -# "slurm". -# -# QUEUE_FCST: -# The queue or QOS to which the task that runs a forecast is submitted. -# If this is not set or set to an empty string, it will be (re)set to a -# machine-dependent value. -# -# mach_doc_end -# -#----------------------------------------------------------------------- -# -MACHINE="BIG_COMPUTER" -MACHINE_FILE="" -ACCOUNT="project_name" -WORKFLOW_MANAGER="none" -NCORES_PER_NODE="" -LMOD_PATH="" -BUILD_MOD_FN="" -WFLOW_MOD_FN="" -SCHED="" -PARTITION_DEFAULT="" -QUEUE_DEFAULT="" -PARTITION_HPSS="" -QUEUE_HPSS="" -PARTITION_FCST="" -QUEUE_FCST="" -# -#----------------------------------------------------------------------- -# -# Set run commands for platforms without a workflow manager. These values -# will be ignored unless WORKFLOW_MANAGER="none". Definitions: -# -# RUN_CMD_UTILS: -# The run command for pre-processing utilities (shave, orog, sfc_climo_gen, -# etc.) Can be left blank for smaller domains, in which case the executables -# will run without MPI. -# -# RUN_CMD_FCST: -# The run command for the model forecast step. This will be appended to -# the end of the variable definitions file, so it can reference other -# variables. -# -# RUN_CMD_POST: -# The run command for post-processing (UPP). Can be left blank for smaller -# domains, in which case UPP will run without MPI. -# -#----------------------------------------------------------------------- -# -RUN_CMD_UTILS="mpirun -np 1" -RUN_CMD_FCST='mpirun -np \${PE_MEMBER01}' -RUN_CMD_POST="mpirun -np 1" -# -#----------------------------------------------------------------------- -# -# Set cron-associated parameters. Definitions: -# -# USE_CRON_TO_RELAUNCH: -# Flag that determines whether or not to add a line to the user's cron -# table to call the experiment launch script every CRON_RELAUNCH_INTVL_MNTS -# minutes. -# -# CRON_RELAUNCH_INTVL_MNTS: -# The interval (in minutes) between successive calls of the experiment -# launch script by a cron job to (re)launch the experiment (so that the -# workflow for the experiment kicks off where it left off). -# -#----------------------------------------------------------------------- -# -USE_CRON_TO_RELAUNCH="FALSE" -CRON_RELAUNCH_INTVL_MNTS="03" -# -#----------------------------------------------------------------------- -# -# dir_doc_start -# Set directories. Definitions: -# -# EXPT_BASEDIR: -# The base directory in which the experiment directory will be created. -# If this is not specified or if it is set to an empty string, it will -# default to ${HOMErrfs}/../expt_dirs. -# -# EXPT_SUBDIR: -# The name that the experiment directory (without the full path) will -# have. The full path to the experiment directory, which will be contained -# in the variable EXPTDIR, will be: -# -# EXPTDIR="${EXPT_BASEDIR}/${EXPT_SUBDIR}" -# -# This cannot be empty. If set to a null string here, it must be set to -# a (non-empty) value in the user-defined experiment configuration file. -# -# dir_doc_end -# -# EXEC_SUBDIR: -# The name of the subdirectory of ufs-srweather-app where executables are -# installed. -#----------------------------------------------------------------------- -# -EXPT_BASEDIR="" -EXPT_SUBDIR="" -EXEC_SUBDIR="bin" -# -#----------------------------------------------------------------------- -# -# Set variables that are only used in NCO mode (i.e. when RUN_ENVIR is -# set to "nco"). Definitions: -# -# COMIN: -# Directory containing files generated by the external model (FV3GFS, NAM, -# HRRR, etc) that the initial and lateral boundary condition generation tasks -# need in order to create initial and boundary condition files for a given -# cycle on the native FV3-LAM grid. -# -# envir, NET, model_ver, RUN: -# Standard environment variables defined in the NCEP Central Operations WCOSS -# Implementation Standards document as follows: -# -# envir: -# Set to "test" during the initial testing phase, "para" when running -# in parallel (on a schedule), and "prod" in production. -# -# NET: -# Model name (first level of com directory structure) -# -# model_ver: -# Version number of package in three digits (second level of com directory) -# -# RUN: -# Name of model run (third level of com directory structure). -# In general, same as $NET -# -# STMP: -# The beginning portion of the directory that will contain cycle-dependent -# model input files, symlinks to cycle-independent input files, and raw -# (i.e. before post-processing) forecast output files for a given cycle. -# For a cycle that starts on the date specified by yyyymmdd and hour -# specified by hh (where yyyymmdd and hh are as described above) [so that -# the cycle date (cdate) is given by cdate="${yyyymmdd}${hh}"], the -# directory in which the aforementioned files will be located is: -# -# $STMP/tmpnwprd/$RUN/$cdate -# -# PTMP: -# The beginning portion of the directory that will contain the output -# files from the post-processor (UPP) for a given cycle. For a cycle -# that starts on the date specified by yyyymmdd and hour specified by hh -# (where yyyymmdd and hh are as described above), the directory in which -# the UPP output files will be placed will be: -# -# $PTMP/com/$NET/$model_ver/$RUN.$yyyymmdd/$hh -# -#----------------------------------------------------------------------- -# -COMIN="/path/of/directory/containing/data/files/for/IC/LBCS" -STMP="/base/path/of/directory/containing/model/input/and/raw/output/files" -envir="para" -NET="rrfs" -model_ver="v1.0.0" -RUN="rrfs" -STMP="/base/path/of/directory/containing/model/input/and/raw/output/files" -PTMP="/base/path/of/directory/containing/postprocessed/output/files" -# -#----------------------------------------------------------------------- -# -# Set the separator character(s) to use in the names of the grid, mosaic, -# and orography fixed files. -# -# Ideally, the same separator should be used in the names of these fixed -# files as the surface climatology fixed files (which always use a "." -# as the separator), i.e. ideally, DOT_OR_USCORE should be set to "." -# -#----------------------------------------------------------------------- -# -DOT_OR_USCORE="_" -# -#----------------------------------------------------------------------- -# -# Set file names. Definitions: -# -# EXPT_CONFIG_FN: -# Name of the user-specified configuration file for the forecast experiment. -# -# CONSTANTS_FN: -# Name of the file containing definitions of various mathematical, physical, -# and SRW App contants. -# -# RGNL_GRID_NML_FN: -# Name of file containing the namelist settings for the code that generates -# a "ESGgrid" type of regional grid. -# -# FV3_NML_BASE_SUITE_FN: -# Name of Fortran namelist file containing the forecast model's base suite -# namelist, i.e. the portion of the namelist that is common to all physics -# suites. -# -# FV3_NML_YAML_CONFIG_FN: -# Name of YAML configuration file containing the forecast model's namelist -# settings for various physics suites. -# -# FV3_NML_BASE_ENS_FN: -# Name of Fortran namelist file containing the forecast model's base -# ensemble namelist, i.e. the the namelist file that is the starting point -# from which the namelist files for each of the enesemble members are -# generated. -# -# FV3_EXEC_FN: -# Name to use for the forecast model executable when it is copied from -# the directory in which it is created in the build step to the executables -# directory (EXECDIR; this is set during experiment generation). -# -# DIAG_TABLE_TMPL_FN: -# Name of a template file that specifies the output fields of the forecast -# model (ufs-weather-model: diag_table) followed by [dot_ccpp_phys_suite]. -# Its default value is the name of the file that the ufs weather model -# expects to read in. -# -# FIELD_TABLE_TMPL_FN: -# Name of a template file that specifies the tracers in IC/LBC files of the -# forecast model (ufs-weather-mode: field_table) followed by [dot_ccpp_phys_suite]. -# Its default value is the name of the file that the ufs weather model expects -# to read in. -# -# MODEL_CONFIG_TMPL_FN: -# Name of a template file that contains settings and configurations for the -# NUOPC/ESMF main component (ufs-weather-model: model_config). Its default -# value is the name of the file that the ufs weather model expects to read in. -# -# NEMS_CONFIG_TMPL_FN: -# Name of a template file that contains information about the various NEMS -# components and their run sequence (ufs-weather-model: nems.configure). -# Its default value is the name of the file that the ufs weather model expects -# to read in. -# -# FCST_MODEL: -# Name of forecast model (default=ufs-weather-model) -# -# WFLOW_XML_FN: -# Name of the rocoto workflow XML file that the experiment generation -# script creates and that defines the workflow for the experiment. -# -# GLOBAL_VAR_DEFNS_FN: -# Name of file (a shell script) containing the defintions of the primary -# experiment variables (parameters) defined in this default configuration -# script and in the user-specified configuration as well as secondary -# experiment variables generated by the experiment generation script. -# This file is sourced by many scripts (e.g. the J-job scripts corresponding -# to each workflow task) in order to make all the experiment variables -# available in those scripts. -# -# EXTRN_MDL_VAR_DEFNS_FN: -# Name of file (a shell script) containing the defintions of variables -# associated with the external model from which ICs or LBCs are generated. This -# file is created by the GET_EXTRN_*_TN task because the values of the variables -# it contains are not known before this task runs. The file is then sourced by -# the MAKE_ICS_TN and MAKE_LBCS_TN tasks. -# -# WFLOW_LAUNCH_SCRIPT_FN: -# Name of the script that can be used to (re)launch the experiment's rocoto -# workflow. -# -# WFLOW_LAUNCH_LOG_FN: -# Name of the log file that contains the output from successive calls to -# the workflow launch script (WFLOW_LAUNCH_SCRIPT_FN). -# -#----------------------------------------------------------------------- -# -EXPT_CONFIG_FN="config.sh" -CONSTANTS_FN="constants.sh" - -RGNL_GRID_NML_FN="regional_grid.nml" - -FV3_NML_BASE_SUITE_FN="input.nml.FV3" -FV3_NML_YAML_CONFIG_FN="FV3.input.yml" -FV3_NML_BASE_ENS_FN="input.nml.base_ens" -FV3_EXEC_FN="ufs_model" - -DATA_TABLE_TMPL_FN="" -DIAG_TABLE_TMPL_FN="" -FIELD_TABLE_TMPL_FN="" -MODEL_CONFIG_TMPL_FN="" -NEMS_CONFIG_TMPL_FN="" - -FCST_MODEL="ufs-weather-model" -WFLOW_XML_FN="FV3LAM_wflow.xml" -GLOBAL_VAR_DEFNS_FN="var_defns.sh" -EXTRN_MDL_VAR_DEFNS_FN="extrn_mdl_var_defns.sh" -WFLOW_LAUNCH_SCRIPT_FN="launch_FV3LAM_wflow.sh" -WFLOW_LAUNCH_LOG_FN="log.launch_FV3LAM_wflow" -# -#----------------------------------------------------------------------- -# -# Set forecast parameters. Definitions: -# -# DATE_FIRST_CYCL: -# Starting date of the first forecast in the set of forecasts to run. -# Format is "YYYYMMDD". Note that this does not include the hour-of-day. -# -# DATE_LAST_CYCL: -# Starting date of the last forecast in the set of forecasts to run. -# Format is "YYYYMMDD". Note that this does not include the hour-of-day. -# -# CYCL_HRS: -# An array containing the hours of the day at which to launch forecasts. -# Forecasts are launched at these hours on each day from DATE_FIRST_CYCL -# to DATE_LAST_CYCL, inclusive. Each element of this array must be a -# two-digit string representing an integer that is less than or equal to -# 23, e.g. "00", "03", "12", "23". -# -# INCR_CYCL_FREQ: -# Increment in hours for Cycle Frequency (cycl_freq). -# Default is 24, which means cycle_freq=24:00:00 -# -# FCST_LEN_HRS: -# The length of each forecast, in integer hours. -# -#----------------------------------------------------------------------- -# -DATE_FIRST_CYCL="YYYYMMDD" -DATE_LAST_CYCL="YYYYMMDD" -CYCL_HRS=( "HH1" "HH2" ) -INCR_CYCL_FREQ="24" -FCST_LEN_HRS="24" -# -#----------------------------------------------------------------------- -# -# Set model_configure parameters. Definitions: -# -# DT_ATMOS: -# The main forecast model integraton time step. As described in the -# forecast model documentation, "It corresponds to the frequency with -# which the top level routine in the dynamics is called as well as the -# frequency with which the physics is called." -# -# CPL: parameter for coupling -# (set automatically based on FCST_MODEL in ush/setup.sh) -# (ufs-weather-model:FALSE, fv3gfs_aqm:TRUE) -# -# RESTART_INTERVAL: -# frequency of the output restart files (unit:hour). -# Default=0: restart files are produced at the end of a forecast run -# For example, RESTART_INTERVAL="1": restart files are produced every hour -# with the prefix "YYYYMMDD.HHmmSS." in the RESTART directory -# -# WRITE_DOPOST: -# Flag that determines whether or not to use the inline post feature -# [i.e. calling the Unified Post Processor (UPP) from within the weather -# model]. If this is set to "TRUE", the RUN_POST_TN task is deactivated -# (i.e. RUN_TASK_RUN_POST is set to "FALSE") to avoid unnecessary -# computations. -# -#----------------------------------------------------------------------- -# -DT_ATMOS="" -RESTART_INTERVAL="0" -WRITE_DOPOST="FALSE" -# -#----------------------------------------------------------------------- -# -# Set METplus parameters. Definitions: -# -# MODEL: -# String that specifies a descriptive name for the model being verified. -# -# MET_INSTALL_DIR: -# Location to top-level directory of MET installation. -# -# METPLUS_PATH: -# Location to top-level directory of METplus installation. -# -# CCPA_OBS_DIR: -# User-specified location of top-level directory where CCPA hourly -# precipitation files used by METplus are located. This parameter needs -# to be set for both user-provided observations and for observations -# that are retrieved from the NOAA HPSS (if the user has access) via -# the get_obs_ccpa_tn task (activated in workflow by setting -# RUN_TASK_GET_OBS_CCPA="TRUE"). In the case of pulling observations -# directly from NOAA HPSS, the data retrieved will be placed in this -# directory. Please note, this path must be defind as -# /full-path-to-obs/ccpa/proc. METplus is configured to verify 01-, -# 03-, 06-, and 24-h accumulated precipitation using hourly CCPA files. -# METplus configuration files require the use of predetermined directory -# structure and file names. Therefore, if the CCPA files are user -# provided, they need to follow the anticipated naming structure: -# {YYYYMMDD}/ccpa.t{HH}z.01h.hrap.conus.gb2, where YYYY is the 4-digit -# valid year, MM the 2-digit valid month, DD the 2-digit valid day of -# the month, and HH the 2-digit valid hour of the day. In addition, a -# caveat is noted for using hourly CCPA data. There is a problem with -# the valid time in the metadata for files valid from 19 - 00 UTC (or -# files under the '00' directory). The script to pull the CCPA data -# from the NOAA HPSS has an example of how to account for this as well -# as organizing the data into a more intuitive format: -# regional_workflow/scripts/exregional_get_ccpa_files.sh. When a fix -# is provided, it will be accounted for in the -# exregional_get_ccpa_files.sh script. -# -# MRMS_OBS_DIR: -# User-specified location of top-level directory where MRMS composite -# reflectivity files used by METplus are located. This parameter needs -# to be set for both user-provided observations and for observations -# that are retrieved from the NOAA HPSS (if the user has access) via the -# get_obs_mrms_tn task (activated in workflow by setting -# RUN_TASK_GET_OBS_MRMS="TRUE"). In the case of pulling observations -# directly from NOAA HPSS, the data retrieved will be placed in this -# directory. Please note, this path must be defind as -# /full-path-to-obs/mrms/proc. METplus configuration files require the -# use of predetermined directory structure and file names. Therefore, if -# the MRMS files are user provided, they need to follow the anticipated -# naming structure: -# {YYYYMMDD}/MergedReflectivityQCComposite_00.50_{YYYYMMDD}-{HH}{mm}{SS}.grib2, -# where YYYY is the 4-digit valid year, MM the 2-digit valid month, DD -# the 2-digit valid day of the month, HH the 2-digit valid hour of the -# day, mm the 2-digit valid minutes of the hour, and SS is the two-digit -# valid seconds of the hour. In addition, METplus is configured to look -# for a MRMS composite reflectivity file for the valid time of the -# forecast being verified; since MRMS composite reflectivity files do -# not always exactly match the valid time, a script, within the main -# script to retrieve MRMS data from the NOAA HPSS, is used to identify -# and rename the MRMS composite reflectivity file to match the valid -# time of the forecast. The script to pull the MRMS data from the NOAA -# HPSS has an example of the expected file naming structure: -# regional_workflow/scripts/exregional_get_mrms_files.sh. This script -# calls the script used to identify the MRMS file closest to the valid -# time: regional_workflow/ush/mrms_pull_topofhour.py. -# -# NDAS_OBS_DIR: -# User-specified location of top-level directory where NDAS prepbufr -# files used by METplus are located. This parameter needs to be set for -# both user-provided observations and for observations that are -# retrieved from the NOAA HPSS (if the user has access) via the -# get_obs_ndas_tn task (activated in workflow by setting  -# RUN_TASK_GET_OBS_NDAS="TRUE"). In the case of pulling observations -# directly from NOAA HPSS, the data retrieved will be placed in this -# directory. Please note, this path must be defind as -# /full-path-to-obs/ndas/proc. METplus is configured to verify -# near-surface variables hourly and upper-air variables at times valid -# at 00 and 12 UTC with NDAS prepbufr files. METplus configuration files -# require the use of predetermined file names. Therefore, if the NDAS -# files are user provided, they need to follow the anticipated naming -# structure: prepbufr.ndas.{YYYYMMDDHH}, where YYYY is the 4-digit valid -# year, MM the 2-digit valid month, DD the 2-digit valid day of the -# month, and HH the 2-digit valid hour of the day. The script to pull -# the NDAS data from the NOAA HPSS has an example of how to rename the -# NDAS data into a more intuitive format with the valid time listed in -# the file name: regional_workflow/scripts/exregional_get_ndas_files.sh -# -#----------------------------------------------------------------------- -# -MODEL="" -MET_INSTALL_DIR="" -MET_BIN_EXEC="bin" -METPLUS_PATH="" -CCPA_OBS_DIR="" -MRMS_OBS_DIR="" -NDAS_OBS_DIR="" -# -#----------------------------------------------------------------------- -# -# Set initial and lateral boundary condition generation parameters. -# Definitions: -# -# EXTRN_MDL_NAME_ICS: -#`The name of the external model that will provide fields from which -# initial condition (including and surface) files will be generated for -# input into the forecast model. -# -# EXTRN_MDL_NAME_LBCS: -#`The name of the external model that will provide fields from which -# lateral boundary condition (LBC) files will be generated for input into -# the forecast model. -# -# LBC_SPEC_INTVL_HRS: -# The interval (in integer hours) with which LBC files will be generated. -# We will refer to this as the boundary update interval. Note that the -# model specified in EXTRN_MDL_NAME_LBCS must have data available at a -# frequency greater than or equal to that implied by LBC_SPEC_INTVL_HRS. -# For example, if LBC_SPEC_INTVL_HRS is set to 6, then the model must have -# data availble at least every 6 hours. It is up to the user to ensure -# that this is the case. -# -# EXTRN_MDL_ICS_OFFSET_HRS: -# Users may wish to start a forecast from a forecast of a previous cycle -# of an external model. This variable sets the number of hours earlier -# the external model started than when the FV3 forecast configured here -# should start. For example, the forecast should start from a 6 hour -# forecast of the GFS, then EXTRN_MDL_ICS_OFFSET_HRS=6. - -# EXTRN_MDL_LBCS_OFFSET_HRS: -# Users may wish to use lateral boundary conditions from a forecast that -# was started earlier than the initial time for the FV3 forecast -# configured here. This variable sets the number of hours earlier -# the external model started than when the FV3 forecast configured here -# should start. For example, the forecast should use lateral boundary -# conditions from the GFS started 6 hours earlier, then -# EXTRN_MDL_LBCS_OFFSET_HRS=6. -# Note: the default value is model-dependent and set in -# set_extrn_mdl_params.py -# -# FV3GFS_FILE_FMT_ICS: -# If using the FV3GFS model as the source of the ICs (i.e. if EXTRN_MDL_NAME_ICS -# is set to "FV3GFS"), this variable specifies the format of the model -# files to use when generating the ICs. -# -# FV3GFS_FILE_FMT_LBCS: -# If using the FV3GFS model as the source of the LBCs (i.e. if -# EXTRN_MDL_NAME_LBCS is set to "FV3GFS"), this variable specifies the -# format of the model files to use when generating the LBCs. -# -#----------------------------------------------------------------------- -# -EXTRN_MDL_NAME_ICS="FV3GFS" -EXTRN_MDL_NAME_LBCS="FV3GFS" -LBC_SPEC_INTVL_HRS="6" -EXTRN_MDL_ICS_OFFSET_HRS="0" -EXTRN_MDL_LBCS_OFFSET_HRS="" -FV3GFS_FILE_FMT_ICS="nemsio" -FV3GFS_FILE_FMT_LBCS="nemsio" -# -#----------------------------------------------------------------------- -# -# Base directories in which to search for external model files. -# -# EXTRN_MDL_SYSBASEDIR_ICS: -# Base directory on the local machine containing external model files for -# generating ICs on the native grid. The way the full path containing -# these files is constructed depends on the user-specified external model -# for ICs, i.e. EXTRN_MDL_NAME_ICS. -# -# EXTRN_MDL_SYSBASEDIR_LBCS: -# Same as EXTRN_MDL_SYSBASEDIR_ICS but for LBCs. -# -# Note that these must be defined as null strings here so that if they -# are specified by the user in the experiment configuration file, they -# remain set to those values, and if not, they get set to machine-dependent -# values. -# -#----------------------------------------------------------------------- -# -EXTRN_MDL_SYSBASEDIR_ICS='' -EXTRN_MDL_SYSBASEDIR_LBCS='' -# -#----------------------------------------------------------------------- -# -# User-staged external model directories and files. Definitions: -# -# USE_USER_STAGED_EXTRN_FILES: -# Flag that determines whether or not the workflow will look for the -# external model files needed for generating ICs and LBCs in user-specified -# directories. -# -# EXTRN_MDL_SOURCE_BASEDIR_ICS: -# Directory in which to look for external model files for generating ICs. -# If USE_USER_STAGED_EXTRN_FILES is set to "TRUE", the workflow looks in -# this directory (specifically, in a subdirectory under this directory -# named "YYYYMMDDHH" consisting of the starting date and cycle hour of -# the forecast, where YYYY is the 4-digit year, MM the 2-digit month, DD -# the 2-digit day of the month, and HH the 2-digit hour of the day) for -# the external model files specified by the array EXTRN_MDL_FILES_ICS -# (these files will be used to generate the ICs on the native FV3-LAM -# grid). This variable is not used if USE_USER_STAGED_EXTRN_FILES is -# set to "FALSE". -# -# EXTRN_MDL_FILES_ICS: -# Array containing templates of the names of the files to search for in -# the directory specified by EXTRN_MDL_SOURCE_BASEDIR_ICS. This -# variable is not used if USE_USER_STAGED_EXTRN_FILES is set to "FALSE". -# A single template should be used for each model file type that is -# meant to be used. You may use any of the Python-style templates -# allowed in the ush/retrieve_data.py script. To see the full list of -# supported templates, run that script with a -h option. Here is an example of -# setting FV3GFS nemsio input files: -# EXTRN_MDL_FILES_ICS=( gfs.t{hh}z.atmf{fcst_hr:03d}.nemsio \ -# gfs.t{hh}z.sfcf{fcst_hr:03d}.nemsio ) -# Or for FV3GFS grib files: -# EXTRN_MDL_FILES_ICS=( gfs.t{hh}z.pgrb2.0p25.f{fcst_hr:03d} ) -# -# EXTRN_MDL_SOURCE_BASEDIR_LBCS: -# Analogous to EXTRN_MDL_SOURCE_BASEDIR_ICS but for LBCs instead of ICs. -# -# EXTRN_MDL_FILES_LBCS: -# Analogous to EXTRN_MDL_FILES_ICS but for LBCs instead of ICs. -# -# EXTRN_MDL_DATA_STORES: -# A list of data stores where the scripts should look for external model -# data. The list is in priority order. If disk information is provided -# via USE_USER_STAGED_EXTRN_FILES or a known location on the platform, -# the disk location will be highest priority. Options are disk, hpss, -# aws, and nomads. -# -#----------------------------------------------------------------------- -# -USE_USER_STAGED_EXTRN_FILES="FALSE" -EXTRN_MDL_SOURCE_BASEDIR_ICS="" -EXTRN_MDL_FILES_ICS="" -EXTRN_MDL_SOURCE_BASEDIR_LBCS="" -EXTRN_MDL_FILES_LBCS="" -EXTRN_MDL_DATA_STORES="" -# -#----------------------------------------------------------------------- -# -# Set NOMADS online data associated parameters. Definitions: -# -# NOMADS: -# Flag controlling whether or not using NOMADS online data. -# -# NOMADS_file_type: -# Flag controlling the format of data. -# -#----------------------------------------------------------------------- -# -NOMADS="FALSE" -NOMADS_file_type="nemsio" -# -#----------------------------------------------------------------------- -# -# Set CCPP-associated parameters. Definitions: -# -# CCPP_PHYS_SUITE: -# The physics suite that will run using CCPP (Common Community Physics -# Package). The choice of physics suite determines the forecast model's -# namelist file, the diagnostics table file, the field table file, and -# the XML physics suite definition file that are staged in the experiment -# directory or the cycle directories under it. -# -#----------------------------------------------------------------------- -# -CCPP_PHYS_SUITE="FV3_GFS_v16" -# -#----------------------------------------------------------------------- -# -# Set GRID_GEN_METHOD. This variable specifies the method to use to -# generate a regional grid in the horizontal. The values that it can -# take on are: -# -# * "GFDLgrid": -# This setting will generate a regional grid by first generating a -# "parent" global cubed-sphere grid and then taking a portion of tile -# 6 of that global grid -- referred to in the grid generation scripts -# as "tile 7" even though it doesn't correspond to a complete tile -- -# and using it as the regional grid. Note that the forecast is run on -# only on the regional grid (i.e. tile 7, not tiles 1 through 6). -# -# * "ESGgrid": -# This will generate a regional grid using the map projection developed -# by Jim Purser of EMC. -# -# Note that: -# -# 1) If the experiment is using one of the predefined grids (i.e. if -# PREDEF_GRID_NAME is set to the name of one of the valid predefined -# grids), then GRID_GEN_METHOD will be reset to the value of -# GRID_GEN_METHOD for that grid. This will happen regardless of -# whether or not GRID_GEN_METHOD is assigned a value in the user- -# specified experiment configuration file, i.e. any value it may be -# assigned in the experiment configuration file will be overwritten. -# -# 2) If the experiment is not using one of the predefined grids (i.e. if -# PREDEF_GRID_NAME is set to a null string), then GRID_GEN_METHOD must -# be set in the experiment configuration file. Otherwise, it will -# remain set to a null string, and the experiment generation will -# fail because the generation scripts check to ensure that it is set -# to a non-empty string before creating the experiment directory. -# -#----------------------------------------------------------------------- -# -GRID_GEN_METHOD="" -# -#----------------------------------------------------------------------- -# -# Set parameters specific to the "GFDLgrid" method of generating a regional -# grid (i.e. for GRID_GEN_METHOD set to "GFDLgrid"). The following -# parameters will be used only if GRID_GEN_METHOD is set to "GFDLgrid". -# In this grid generation method: -# -# * The regional grid is defined with respect to a "parent" global cubed- -# sphere grid. Thus, all the parameters for a global cubed-sphere grid -# must be specified in order to define this parent global grid even -# though the model equations are not integrated on (they are integrated -# only on the regional grid). -# -# * GFDLgrid_NUM_CELLS is the number of grid cells in either one of the -# two horizontal directions x and y on any one of the 6 tiles of the -# parent global cubed-sphere grid. The mapping from GFDLgrid_NUM_CELLS -# to a nominal resolution (grid cell size) for a uniform global grid -# (i.e. Schmidt stretch factor GFDLgrid_STRETCH_FAC set to 1) for -# several values of GFDLgrid_NUM_CELLS is as follows: -# -# GFDLgrid_NUM_CELLS typical cell size -# ------------------ ----------------- -# 192 50 km -# 384 25 km -# 768 13 km -# 1152 8.5 km -# 3072 3.2 km -# -# Note that these are only typical cell sizes. The actual cell size on -# the global grid tiles varies somewhat as we move across a tile. -# -# * Tile 6 has arbitrarily been chosen as the tile to use to orient the -# global parent grid on the sphere (Earth). This is done by specifying -# GFDLgrid_LON_T6_CTR and GFDLgrid_LAT_T6_CTR, which are the longitude -# and latitude (in degrees) of the center of tile 6. -# -# * Setting the Schmidt stretching factor GFDLgrid_STRETCH_FAC to a value -# greater than 1 shrinks tile 6, while setting it to a value less than -# 1 (but still greater than 0) expands it. The remaining 5 tiles change -# shape as necessary to maintain global coverage of the grid. -# -# * The cell size on a given global tile depends on both GFDLgrid_NUM_CELLS -# and GFDLgrid_STRETCH_FAC (since changing GFDLgrid_NUM_CELLS changes -# the number of cells in the tile, and changing GFDLgrid_STRETCH_FAC -# modifies the shape and size of the tile). -# -# * The regional grid is embedded within tile 6 (i.e. it doesn't extend -# beyond the boundary of tile 6). Its exact location within tile 6 is -# is determined by specifying the starting and ending i and j indices -# of the regional grid on tile 6, where i is the grid index in the x -# direction and j is the grid index in the y direction. These indices -# are stored in the variables -# -# GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G -# GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G -# GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G -# GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G -# -# * In the forecast model code and in the experiment generation and workflow -# scripts, for convenience the regional grid is denoted as "tile 7" even -# though it doesn't map back to one of the 6 faces of the cube from -# which the parent global grid is generated (it maps back to only a -# subregion on face 6 since it is wholly confined within tile 6). Tile -# 6 may be referred to as the "parent" tile of the regional grid. -# -# * GFDLgrid_REFINE_RATIO is the refinement ratio of the regional grid -# (tile 7) with respect to the grid on its parent tile (tile 6), i.e. -# it is the number of grid cells along the boundary of the regional -# grid that abut one cell on tile 6. Thus, the cell size on the regional -# grid depends not only on GFDLgrid_NUM_CELLS and GFDLgrid_STRETCH_FAC -# (because the cell size on tile 6 depends on these two parameters) -# but also on GFDLgrid_REFINE_RATIO. Note that as on the tiles of the -# global grid, the cell size on the regional grid is not uniform but -# varies as we move across the grid. -# -# Definitions of parameters that need to be specified when GRID_GEN_METHOD -# is set to "GFDLgrid": -# -# GFDLgrid_LON_T6_CTR: -# Longitude of the center of tile 6 (in degrees). -# -# GFDLgrid_LAT_T6_CTR: -# Latitude of the center of tile 6 (in degrees). -# -# GFDLgrid_NUM_CELLS: -# Number of grid cells in each of the two horizontal directions (x and -# y) on each tile of the parent global grid. -# -# GFDLgrid_STRETCH_FAC: -# Stretching factor used in the Schmidt transformation applied to the -# parent cubed-sphere grid. -# -# GFDLgrid_REFINE_RATIO: -# Cell refinement ratio for the regional grid, i.e. the number of cells -# in either the x or y direction on the regional grid (tile 7) that abut -# one cell on its parent tile (tile 6). -# -# GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G: -# i-index on tile 6 at which the regional grid (tile 7) starts. -# -# GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G: -# i-index on tile 6 at which the regional grid (tile 7) ends. -# -# GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G: -# j-index on tile 6 at which the regional grid (tile 7) starts. -# -# GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G: -# j-index on tile 6 at which the regional grid (tile 7) ends. -# -# GFDLgrid_USE_NUM_CELLS_IN_FILENAMES: -# Flag that determines the file naming convention to use for grid, -# orography, and surface climatology files (or, if using pregenerated -# files, the naming convention that was used to name these files). -# These files usually start with the string "C${RES}_", where RES is an -# integer. In the global forecast model, RES is the number of grid -# cells in each of the two horizontal directions (x and y) on each tile -# of the global grid (defined here as GFDLgrid_NUM_CELLS). If this flag -# is set to "TRUE", RES will be set to GFDLgrid_NUM_CELLS just as in the -# global forecast model. If it is set to "FALSE", we calculate (in the -# grid generation task) an "equivalent global uniform cubed-sphere -# resolution" -- call it RES_EQUIV -- and then set RES equal to it. -# RES_EQUIV is the number of grid points in each of the x and y directions -# on each tile that a global UNIFORM (i.e. stretch factor of 1) cubed- -# sphere grid would have to have in order to have the same average grid -# size as the regional grid. This is a more useful indicator of the grid -# size because it takes into account the effects of GFDLgrid_NUM_CELLS, -# GFDLgrid_STRETCH_FAC, and GFDLgrid_REFINE_RATIO in determining the -# regional grid's typical grid size, whereas simply setting RES to -# GFDLgrid_NUM_CELLS doesn't take into account the effects of -# GFDLgrid_STRETCH_FAC and GFDLgrid_REFINE_RATIO on the regional grid's -# resolution. Nevertheless, some users still prefer to use -# GFDLgrid_NUM_CELLS in the file names, so we allow for that here by -# setting this flag to "TRUE". -# -# Note that: -# -# 1) If the experiment is using one of the predefined grids (i.e. if -# PREDEF_GRID_NAME is set to the name of one of the valid predefined -# grids), then: -# -# a) If the value of GRID_GEN_METHOD for that grid is "GFDLgrid", then -# these parameters will get reset to the values for that grid. -# This will happen regardless of whether or not they are assigned -# values in the user-specified experiment configuration file, i.e. -# any values they may be assigned in the experiment configuration -# file will be overwritten. -# -# b) If the value of GRID_GEN_METHOD for that grid is "ESGgrid", then -# these parameters will not be used and thus do not need to be reset -# to non-empty strings. -# -# 2) If the experiment is not using one of the predefined grids (i.e. if -# PREDEF_GRID_NAME is set to a null string), then: -# -# a) If GRID_GEN_METHOD is set to "GFDLgrid" in the user-specified -# experiment configuration file, then these parameters must be set -# in that configuration file. -# -# b) If GRID_GEN_METHOD is set to "ESGgrid" in the user-specified -# experiment configuration file, then these parameters will not be -# used and thus do not need to be reset to non-empty strings. -# -#----------------------------------------------------------------------- -# -GFDLgrid_LON_T6_CTR="" -GFDLgrid_LAT_T6_CTR="" -GFDLgrid_NUM_CELLS="" -GFDLgrid_STRETCH_FAC="" -GFDLgrid_REFINE_RATIO="" -GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G="" -GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G="" -GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G="" -GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G="" -GFDLgrid_USE_NUM_CELLS_IN_FILENAMES="" -# -#----------------------------------------------------------------------- -# -# Set parameters specific to the "ESGgrid" method of generating a regional -# grid (i.e. for GRID_GEN_METHOD set to "ESGgrid"). Definitions: -# -# ESGgrid_LON_CTR: -# The longitude of the center of the grid (in degrees). -# -# ESGgrid_LAT_CTR: -# The latitude of the center of the grid (in degrees). -# -# ESGgrid_DELX: -# The cell size in the zonal direction of the regional grid (in meters). -# -# ESGgrid_DELY: -# The cell size in the meridional direction of the regional grid (in -# meters). -# -# ESGgrid_NX: -# The number of cells in the zonal direction on the regional grid. -# -# ESGgrid_NY: -# The number of cells in the meridional direction on the regional grid. -# -# ESGgrid_WIDE_HALO_WIDTH: -# The width (in units of number of grid cells) of the halo to add around -# the regional grid before shaving the halo down to the width(s) expected -# by the forecast model. -# -# ESGgrid_PAZI: -# The rotational parameter for the ESG grid (in degrees). -# -# In order to generate grid files containing halos that are 3-cell and -# 4-cell wide and orography files with halos that are 0-cell and 3-cell -# wide (all of which are required as inputs to the forecast model), the -# grid and orography tasks first create files with halos around the regional -# domain of width ESGgrid_WIDE_HALO_WIDTH cells. These are first stored -# in files. The files are then read in and "shaved" down to obtain grid -# files with 3-cell-wide and 4-cell-wide halos and orography files with -# 0-cell-wide (i.e. no halo) and 3-cell-wide halos. For this reason, we -# refer to the original halo that then gets shaved down as the "wide" -# halo, i.e. because it is wider than the 0-cell-wide, 3-cell-wide, and -# 4-cell-wide halos that we will eventually end up with. Note that the -# grid and orography files with the wide halo are only needed as intermediates -# in generating the files with 0-cell-, 3-cell-, and 4-cell-wide halos; -# they are not needed by the forecast model. -# NOTE: Probably don't need to make ESGgrid_WIDE_HALO_WIDTH a user-specified -# variable. Just set it in the function set_gridparams_ESGgrid.py. -# -# Note that: -# -# 1) If the experiment is using one of the predefined grids (i.e. if -# PREDEF_GRID_NAME is set to the name of one of the valid predefined -# grids), then: -# -# a) If the value of GRID_GEN_METHOD for that grid is "GFDLgrid", then -# these parameters will not be used and thus do not need to be reset -# to non-empty strings. -# -# b) If the value of GRID_GEN_METHOD for that grid is "ESGgrid", then -# these parameters will get reset to the values for that grid. -# This will happen regardless of whether or not they are assigned -# values in the user-specified experiment configuration file, i.e. -# any values they may be assigned in the experiment configuration -# file will be overwritten. -# -# 2) If the experiment is not using one of the predefined grids (i.e. if -# PREDEF_GRID_NAME is set to a null string), then: -# -# a) If GRID_GEN_METHOD is set to "GFDLgrid" in the user-specified -# experiment configuration file, then these parameters will not be -# used and thus do not need to be reset to non-empty strings. -# -# b) If GRID_GEN_METHOD is set to "ESGgrid" in the user-specified -# experiment configuration file, then these parameters must be set -# in that configuration file. -# -#----------------------------------------------------------------------- -# -ESGgrid_LON_CTR="" -ESGgrid_LAT_CTR="" -ESGgrid_DELX="" -ESGgrid_DELY="" -ESGgrid_NX="" -ESGgrid_NY="" -ESGgrid_WIDE_HALO_WIDTH="" -ESGgrid_PAZI="" -# -#----------------------------------------------------------------------- -# -# Set computational parameters for the forecast. Definitions: -# -# LAYOUT_X, LAYOUT_Y: -# The number of MPI tasks (processes) to use in the two horizontal -# directions (x and y) of the regional grid when running the forecast -# model. -# -# BLOCKSIZE: -# The amount of data that is passed into the cache at a time. -# -# Here, we set these parameters to null strings. This is so that, for -# any one of these parameters: -# -# 1) If the experiment is using a predefined grid, then if the user -# sets the parameter in the user-specified experiment configuration -# file (EXPT_CONFIG_FN), that value will be used in the forecast(s). -# Otherwise, the default value of the parameter for that predefined -# grid will be used. -# -# 2) If the experiment is not using a predefined grid (i.e. it is using -# a custom grid whose parameters are specified in the experiment -# configuration file), then the user must specify a value for the -# parameter in that configuration file. Otherwise, the parameter -# will remain set to a null string, and the experiment generation -# will fail because the generation scripts check to ensure that all -# the parameters defined in this section are set to non-empty strings -# before creating the experiment directory. -# -#----------------------------------------------------------------------- -# -LAYOUT_X="" -LAYOUT_Y="" -BLOCKSIZE="" -# -#----------------------------------------------------------------------- -# -# Set write-component (quilting) parameters. Definitions: -# -# QUILTING: -# Flag that determines whether or not to use the write component for -# writing output files to disk. -# -# WRTCMP_write_groups: -# The number of write groups (i.e. groups of MPI tasks) to use in the -# write component. -# -# WRTCMP_write_tasks_per_group: -# The number of MPI tasks to allocate for each write group. -# -# PRINT_ESMF: -# Flag for whether or not to output extra (debugging) information from -# ESMF routines. Must be "TRUE" or "FALSE". Note that the write -# component uses ESMF library routines to interpolate from the native -# forecast model grid to the user-specified output grid (which is defined -# in the model configuration file MODEL_CONFIG_FN in the forecast's run -# directory). -# -#----------------------------------------------------------------------- -# -QUILTING="TRUE" -PRINT_ESMF="FALSE" - -WRTCMP_write_groups="1" -WRTCMP_write_tasks_per_group="20" - -WRTCMP_output_grid="''" -WRTCMP_cen_lon="" -WRTCMP_cen_lat="" -WRTCMP_lon_lwr_left="" -WRTCMP_lat_lwr_left="" -# -# The following are used only for the case of WRTCMP_output_grid set to -# "'rotated_latlon'". -# -WRTCMP_lon_upr_rght="" -WRTCMP_lat_upr_rght="" -WRTCMP_dlon="" -WRTCMP_dlat="" -# -# The following are used only for the case of WRTCMP_output_grid set to -# "'lambert_conformal'". -# -WRTCMP_stdlat1="" -WRTCMP_stdlat2="" -WRTCMP_nx="" -WRTCMP_ny="" -WRTCMP_dx="" -WRTCMP_dy="" -# -#----------------------------------------------------------------------- -# -# Set PREDEF_GRID_NAME. This parameter specifies a predefined regional -# grid, as follows: -# -# * If PREDEF_GRID_NAME is set to a valid predefined grid name, the grid -# generation method GRID_GEN_METHOD, the (native) grid parameters, and -# the write-component grid parameters are set to predefined values for -# the specified grid, overwriting any settings of these parameters in -# the user-specified experiment configuration file. In addition, if -# the time step DT_ATMOS and the computational parameters LAYOUT_X, -# LAYOUT_Y, and BLOCKSIZE are not specified in that configuration file, -# they are also set to predefined values for the specified grid. -# -# * If PREDEF_GRID_NAME is set to an empty string, it implies the user -# is providing the native grid parameters in the user-specified -# experiment configuration file (EXPT_CONFIG_FN). In this case, the -# grid generation method GRID_GEN_METHOD, the native grid parameters, -# and the write-component grid parameters as well as the time step -# forecast model's main time step DT_ATMOS and the computational -# parameters LAYOUT_X, LAYOUT_Y, and BLOCKSIZE must be set in that -# configuration file; otherwise, the values of all of these parameters -# in this default experiment configuration file will be used. -# -# Setting PREDEF_GRID_NAME provides a convenient method of specifying a -# commonly used set of grid-dependent parameters. The predefined grid -# parameters are specified in the script -# -# $HOMErrfs/ush/set_predef_grid_params.py -# -#----------------------------------------------------------------------- -# -PREDEF_GRID_NAME="" -# -#----------------------------------------------------------------------- -# -# Set PREEXISTING_DIR_METHOD. This variable determines the method to use -# use to deal with preexisting directories [e.g ones generated by previous -# calls to the experiment generation script using the same experiment name -# (EXPT_SUBDIR) as the current experiment]. This variable must be set to -# one of "delete", "rename", and "quit". The resulting behavior for each -# of these values is as follows: -# -# * "delete": -# The preexisting directory is deleted and a new directory (having the -# same name as the original preexisting directory) is created. -# -# * "rename": -# The preexisting directory is renamed and a new directory (having the -# same name as the original preexisting directory) is created. The new -# name of the preexisting directory consists of its original name and -# the suffix "_oldNNN", where NNN is a 3-digit integer chosen to make -# the new name unique. -# -# * "quit": -# The preexisting directory is left unchanged, but execution of the -# currently running script is terminated. In this case, the preexisting -# directory must be dealt with manually before rerunning the script. -# -#----------------------------------------------------------------------- -# -PREEXISTING_DIR_METHOD="delete" -# -#----------------------------------------------------------------------- -# -# Set flags for more detailed messages. Defintitions: -# -# VERBOSE: -# This is a flag that determines whether or not the experiment generation -# and workflow task scripts tend to print out more informational messages. -# -# DEBUG: -# This is a flag that determines whether or not very detailed debugging -# messages are printed to out. Note that if DEBUG is set to TRUE, then -# VERBOSE will also get reset to TRUE if it isn't already. -# -#----------------------------------------------------------------------- -# -VERBOSE="TRUE" -DEBUG="FALSE" -# -#----------------------------------------------------------------------- -# -# Set the names of the various rocoto workflow tasks. -# -#----------------------------------------------------------------------- -# -MAKE_GRID_TN="make_grid" -MAKE_OROG_TN="make_orog" -MAKE_SFC_CLIMO_TN="make_sfc_climo" -GET_EXTRN_ICS_TN="get_extrn_ics" -GET_EXTRN_LBCS_TN="get_extrn_lbcs" -MAKE_ICS_TN="make_ics" -MAKE_LBCS_TN="make_lbcs" -RUN_FCST_TN="run_fcst" -RUN_POST_TN="run_post" -GET_OBS="get_obs" -GET_OBS_CCPA_TN="get_obs_ccpa" -GET_OBS_MRMS_TN="get_obs_mrms" -GET_OBS_NDAS_TN="get_obs_ndas" -VX_TN="run_vx" -VX_GRIDSTAT_TN="run_gridstatvx" -VX_GRIDSTAT_REFC_TN="run_gridstatvx_refc" -VX_GRIDSTAT_RETOP_TN="run_gridstatvx_retop" -VX_GRIDSTAT_03h_TN="run_gridstatvx_03h" -VX_GRIDSTAT_06h_TN="run_gridstatvx_06h" -VX_GRIDSTAT_24h_TN="run_gridstatvx_24h" -VX_POINTSTAT_TN="run_pointstatvx" -VX_ENSGRID_TN="run_ensgridvx" -VX_ENSGRID_03h_TN="run_ensgridvx_03h" -VX_ENSGRID_06h_TN="run_ensgridvx_06h" -VX_ENSGRID_24h_TN="run_ensgridvx_24h" -VX_ENSGRID_REFC_TN="run_ensgridvx_refc" -VX_ENSGRID_RETOP_TN="run_ensgridvx_retop" -VX_ENSGRID_MEAN_TN="run_ensgridvx_mean" -VX_ENSGRID_PROB_TN="run_ensgridvx_prob" -VX_ENSGRID_MEAN_03h_TN="run_ensgridvx_mean_03h" -VX_ENSGRID_PROB_03h_TN="run_ensgridvx_prob_03h" -VX_ENSGRID_MEAN_06h_TN="run_ensgridvx_mean_06h" -VX_ENSGRID_PROB_06h_TN="run_ensgridvx_prob_06h" -VX_ENSGRID_MEAN_24h_TN="run_ensgridvx_mean_24h" -VX_ENSGRID_PROB_24h_TN="run_ensgridvx_prob_24h" -VX_ENSGRID_PROB_REFC_TN="run_ensgridvx_prob_refc" -VX_ENSGRID_PROB_RETOP_TN="run_ensgridvx_prob_retop" -VX_ENSPOINT_TN="run_enspointvx" -VX_ENSPOINT_MEAN_TN="run_enspointvx_mean" -VX_ENSPOINT_PROB_TN="run_enspointvx_prob" -# -#----------------------------------------------------------------------- -# -# Set flags (and related directories) that determine whether various -# workflow tasks should be run. Note that the MAKE_GRID_TN, MAKE_OROG_TN, -# and MAKE_SFC_CLIMO_TN are all cycle-independent tasks, i.e. if they -# are to be run, they do so only once at the beginning of the workflow -# before any cycles are run. Definitions: -# -# RUN_TASK_MAKE_GRID: -# Flag that determines whether the MAKE_GRID_TN task is to be run. If -# this is set to "TRUE", the grid generation task is run and new grid -# files are generated. If it is set to "FALSE", then the scripts look -# for pregenerated grid files in the directory specified by GRID_DIR -# (see below). -# -# GRID_DIR: -# The directory in which to look for pregenerated grid files if -# RUN_TASK_MAKE_GRID is set to "FALSE". -# -# RUN_TASK_MAKE_OROG: -# Same as RUN_TASK_MAKE_GRID but for the MAKE_OROG_TN task. -# -# OROG_DIR: -# Same as GRID_DIR but for the MAKE_OROG_TN task. -# -# RUN_TASK_MAKE_SFC_CLIMO: -# Same as RUN_TASK_MAKE_GRID but for the MAKE_SFC_CLIMO_TN task. -# -# SFC_CLIMO_DIR: -# Same as GRID_DIR but for the MAKE_SFC_CLIMO_TN task. -# -# DOMAIN_PREGEN_BASEDIR: -# The base directory containing pregenerated grid, orography, and surface -# climatology files. This is an alternative for setting GRID_DIR, -# OROG_DIR, and SFC_CLIMO_DIR individually -# -# For the pregenerated grid specified by PREDEF_GRID_NAME, -# these "fixed" files are located in: -# -# ${DOMAIN_PREGEN_BASEDIR}/${PREDEF_GRID_NAME} -# -# The workflow scripts will create a symlink in the experiment directory -# that will point to a subdirectory (having the name of the grid being -# used) under this directory. This variable should be set to a null -# string in this file, but it can be specified in the user-specified -# workflow configuration file (EXPT_CONFIG_FN). -# -# RUN_TASK_GET_EXTRN_ICS: -# Flag that determines whether the GET_EXTRN_ICS_TN task is to be run. -# -# RUN_TASK_GET_EXTRN_LBCS: -# Flag that determines whether the GET_EXTRN_LBCS_TN task is to be run. -# -# RUN_TASK_MAKE_ICS: -# Flag that determines whether the MAKE_ICS_TN task is to be run. -# -# RUN_TASK_MAKE_LBCS: -# Flag that determines whether the MAKE_LBCS_TN task is to be run. -# -# RUN_TASK_RUN_FCST: -# Flag that determines whether the RUN_FCST_TN task is to be run. -# -# RUN_TASK_RUN_POST: -# Flag that determines whether the RUN_POST_TN task is to be run. -# -# RUN_TASK_VX_GRIDSTAT: -# Flag that determines whether the grid-stat verification task is to be -# run. -# -# RUN_TASK_VX_POINTSTAT: -# Flag that determines whether the point-stat verification task is to be -# run. -# -# RUN_TASK_VX_ENSGRID: -# Flag that determines whether the ensemble-stat verification for gridded -# data task is to be run. -# -# RUN_TASK_VX_ENSPOINT: -# Flag that determines whether the ensemble point verification task is -# to be run. If this flag is set, both ensemble-stat point verification -# and point verification of ensemble-stat output is computed. -# -#----------------------------------------------------------------------- -# -RUN_TASK_MAKE_GRID="TRUE" -GRID_DIR="/path/to/pregenerated/grid/files" - -RUN_TASK_MAKE_OROG="TRUE" -OROG_DIR="/path/to/pregenerated/orog/files" - -RUN_TASK_MAKE_SFC_CLIMO="TRUE" -SFC_CLIMO_DIR="/path/to/pregenerated/surface/climo/files" - -DOMAIN_PREGEN_BASEDIR="" - -RUN_TASK_GET_EXTRN_ICS="TRUE" -RUN_TASK_GET_EXTRN_LBCS="TRUE" -RUN_TASK_MAKE_ICS="TRUE" -RUN_TASK_MAKE_LBCS="TRUE" -RUN_TASK_RUN_FCST="TRUE" -RUN_TASK_RUN_POST="TRUE" - -RUN_TASK_GET_OBS_CCPA="FALSE" -RUN_TASK_GET_OBS_MRMS="FALSE" -RUN_TASK_GET_OBS_NDAS="FALSE" -RUN_TASK_VX_GRIDSTAT="FALSE" -RUN_TASK_VX_POINTSTAT="FALSE" -RUN_TASK_VX_ENSGRID="FALSE" -RUN_TASK_VX_ENSPOINT="FALSE" -# -#----------------------------------------------------------------------- -# -# Flag that determines whether MERRA2 aerosol climatology data and -# lookup tables for optics properties are obtained -# -#----------------------------------------------------------------------- -# -USE_MERRA_CLIMO="FALSE" -# -#----------------------------------------------------------------------- -# -# Set the array parameter containing the names of all the fields that the -# MAKE_SFC_CLIMO_TN task generates on the native FV3-LAM grid. -# -#----------------------------------------------------------------------- -# -SFC_CLIMO_FIELDS=( \ -"facsf" \ -"maximum_snow_albedo" \ -"slope_type" \ -"snowfree_albedo" \ -"soil_type" \ -"substrate_temperature" \ -"vegetation_greenness" \ -"vegetation_type" \ -) -# -#----------------------------------------------------------------------- -# -# Set parameters associated with the fixed (i.e. static) files. Definitions: -# -# FIXgsm: -# System directory in which the majority of fixed (i.e. time-independent) -# files that are needed to run the FV3-LAM model are located -# -# FIXaer: -# System directory where MERRA2 aerosol climatology files are located -# -# FIXlut: -# System directory where the lookup tables for optics properties are located -# -# TOPO_DIR: -# The location on disk of the static input files used by the make_orog -# task (orog.x and shave.x). Can be the same as FIXgsm. -# -# SFC_CLIMO_INPUT_DIR: -# The location on disk of the static surface climatology input fields, used by -# sfc_climo_gen. These files are only used if RUN_TASK_MAKE_SFC_CLIMO=TRUE -# -# FNGLAC, ..., FNMSKH: -# Names of (some of the) global data files that are assumed to exist in -# a system directory specified (this directory is machine-dependent; -# the experiment generation scripts will set it and store it in the -# variable FIXgsm). These file names also appear directly in the forecast -# model's input namelist file. -# -# FIXgsm_FILES_TO_COPY_TO_FIXam: -# If not running in NCO mode, this array contains the names of the files -# to copy from the FIXgsm system directory to the FIXam directory under -# the experiment directory. Note that the last element has a dummy value. -# This last element will get reset by the workflow generation scripts to -# the name of the ozone production/loss file to copy from FIXgsm. The -# name of this file depends on the ozone parameterization being used, -# and that in turn depends on the CCPP physics suite specified for the -# experiment. Thus, the CCPP physics suite XML must first be read in to -# determine the ozone parameterizaton and then the name of the ozone -# production/loss file. These steps are carried out elsewhere (in one -# of the workflow generation scripts/functions). -# -# FV3_NML_VARNAME_TO_FIXam_FILES_MAPPING: -# This array is used to set some of the namelist variables in the forecast -# model's namelist file that represent the relative or absolute paths of -# various fixed files (the first column of the array, where columns are -# delineated by the pipe symbol "|") to the full paths to these files in -# the FIXam directory derived from the corresponding workflow variables -# containing file names (the second column of the array). -# -# FV3_NML_VARNAME_TO_SFC_CLIMO_FIELD_MAPPING: -# This array is used to set some of the namelist variables in the forecast -# model's namelist file that represent the relative or absolute paths of -# various fixed files (the first column of the array, where columns are -# delineated by the pipe symbol "|") to the full paths to surface climatology -# files (on the native FV3-LAM grid) in the FIXLAM directory derived from -# the corresponding surface climatology fields (the second column of the -# array). -# -# CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING: -# This array specifies the mapping to use between the symlinks that need -# to be created in each cycle directory (these are the "files" that FV3 -# looks for) and their targets in the FIXam directory. The first column -# of the array specifies the symlink to be created, and the second column -# specifies its target file in FIXam (where columns are delineated by the -# pipe symbol "|"). -# -#----------------------------------------------------------------------- -# -# Because the default values are dependent on the platform, we set these -# to a null string which will then be overwritten in setup.sh unless the -# user has specified a different value in config.sh -FIXgsm="" -FIXaer="" -FIXlut="" -TOPO_DIR="" -SFC_CLIMO_INPUT_DIR="" - -FNGLAC="global_glacier.2x2.grb" -FNMXIC="global_maxice.2x2.grb" -FNTSFC="RTGSST.1982.2012.monthly.clim.grb" -FNSNOC="global_snoclim.1.875.grb" -FNZORC="igbp" -FNAISC="CFSR.SEAICE.1982.2012.monthly.clim.grb" -FNSMCC="global_soilmgldas.t126.384.190.grb" -FNMSKH="seaice_newland.grb" - -FIXgsm_FILES_TO_COPY_TO_FIXam=( \ -"$FNGLAC" \ -"$FNMXIC" \ -"$FNTSFC" \ -"$FNSNOC" \ -"$FNAISC" \ -"$FNSMCC" \ -"$FNMSKH" \ -"global_climaeropac_global.txt" \ -"fix_co2_proj/global_co2historicaldata_2010.txt" \ -"fix_co2_proj/global_co2historicaldata_2011.txt" \ -"fix_co2_proj/global_co2historicaldata_2012.txt" \ -"fix_co2_proj/global_co2historicaldata_2013.txt" \ -"fix_co2_proj/global_co2historicaldata_2014.txt" \ -"fix_co2_proj/global_co2historicaldata_2015.txt" \ -"fix_co2_proj/global_co2historicaldata_2016.txt" \ -"fix_co2_proj/global_co2historicaldata_2017.txt" \ -"fix_co2_proj/global_co2historicaldata_2018.txt" \ -"fix_co2_proj/global_co2historicaldata_2019.txt" \ -"fix_co2_proj/global_co2historicaldata_2020.txt" \ -"fix_co2_proj/global_co2historicaldata_2021.txt" \ -"global_co2historicaldata_glob.txt" \ -"co2monthlycyc.txt" \ -"global_h2o_pltc.f77" \ -"global_hyblev.l65.txt" \ -"global_zorclim.1x1.grb" \ -"global_sfc_emissivity_idx.txt" \ -"global_tg3clim.2.6x1.5.grb" \ -"global_solarconstant_noaa_an.txt" \ -"global_albedo4.1x1.grb" \ -"geo_em.d01.lat-lon.2.5m.HGT_M.nc" \ -"HGT.Beljaars_filtered.lat-lon.30s_res.nc" \ -"replace_with_FIXgsm_ozone_prodloss_filename" \ -) - -# -# It is possible to remove this as a workflow variable and make it only -# a local one since it is used in only one script. -# -FV3_NML_VARNAME_TO_FIXam_FILES_MAPPING=( \ -"FNGLAC | $FNGLAC" \ -"FNMXIC | $FNMXIC" \ -"FNTSFC | $FNTSFC" \ -"FNSNOC | $FNSNOC" \ -"FNAISC | $FNAISC" \ -"FNSMCC | $FNSMCC" \ -"FNMSKH | $FNMSKH" \ -) -#"FNZORC | $FNZORC" \ - -FV3_NML_VARNAME_TO_SFC_CLIMO_FIELD_MAPPING=( \ -"FNALBC | snowfree_albedo" \ -"FNALBC2 | facsf" \ -"FNTG3C | substrate_temperature" \ -"FNVEGC | vegetation_greenness" \ -"FNVETC | vegetation_type" \ -"FNSOTC | soil_type" \ -"FNVMNC | vegetation_greenness" \ -"FNVMXC | vegetation_greenness" \ -"FNSLPC | slope_type" \ -"FNABSC | maximum_snow_albedo" \ -) - -CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING=( \ -"aerosol.dat | global_climaeropac_global.txt" \ -"co2historicaldata_2010.txt | fix_co2_proj/global_co2historicaldata_2010.txt" \ -"co2historicaldata_2011.txt | fix_co2_proj/global_co2historicaldata_2011.txt" \ -"co2historicaldata_2012.txt | fix_co2_proj/global_co2historicaldata_2012.txt" \ -"co2historicaldata_2013.txt | fix_co2_proj/global_co2historicaldata_2013.txt" \ -"co2historicaldata_2014.txt | fix_co2_proj/global_co2historicaldata_2014.txt" \ -"co2historicaldata_2015.txt | fix_co2_proj/global_co2historicaldata_2015.txt" \ -"co2historicaldata_2016.txt | fix_co2_proj/global_co2historicaldata_2016.txt" \ -"co2historicaldata_2017.txt | fix_co2_proj/global_co2historicaldata_2017.txt" \ -"co2historicaldata_2018.txt | fix_co2_proj/global_co2historicaldata_2018.txt" \ -"co2historicaldata_2019.txt | fix_co2_proj/global_co2historicaldata_2019.txt" \ -"co2historicaldata_2020.txt | fix_co2_proj/global_co2historicaldata_2020.txt" \ -"co2historicaldata_2021.txt | fix_co2_proj/global_co2historicaldata_2021.txt" \ -"co2historicaldata_glob.txt | global_co2historicaldata_glob.txt" \ -"co2monthlycyc.txt | co2monthlycyc.txt" \ -"global_h2oprdlos.f77 | global_h2o_pltc.f77" \ -"global_albedo4.1x1.grb | global_albedo4.1x1.grb" \ -"global_zorclim.1x1.grb | global_zorclim.1x1.grb" \ -"global_tg3clim.2.6x1.5.grb | global_tg3clim.2.6x1.5.grb" \ -"sfc_emissivity_idx.txt | global_sfc_emissivity_idx.txt" \ -"solarconstant_noaa_an.txt | global_solarconstant_noaa_an.txt" \ -"global_o3prdlos.f77 | " \ -) -# -#----------------------------------------------------------------------- -# -# For each workflow task, set the parameters to pass to the job scheduler -# (e.g. slurm) that will submit a job for each task to be run. These -# parameters include the number of nodes to use to run the job, the MPI -# processes per node, the maximum walltime to allow for the job to complete, -# and the maximum number of times to attempt to run each task. -# -#----------------------------------------------------------------------- -# -# Number of nodes. -# -NNODES_MAKE_GRID="1" -NNODES_MAKE_OROG="1" -NNODES_MAKE_SFC_CLIMO="2" -NNODES_GET_EXTRN_ICS="1" -NNODES_GET_EXTRN_LBCS="1" -NNODES_MAKE_ICS="4" -NNODES_MAKE_LBCS="4" -NNODES_RUN_FCST="" # This is calculated in the workflow generation scripts, so no need to set here. -NNODES_RUN_POST="2" -NNODES_GET_OBS_CCPA="1" -NNODES_GET_OBS_MRMS="1" -NNODES_GET_OBS_NDAS="1" -NNODES_VX_GRIDSTAT="1" -NNODES_VX_POINTSTAT="1" -NNODES_VX_ENSGRID="1" -NNODES_VX_ENSGRID_MEAN="1" -NNODES_VX_ENSGRID_PROB="1" -NNODES_VX_ENSPOINT="1" -NNODES_VX_ENSPOINT_MEAN="1" -NNODES_VX_ENSPOINT_PROB="1" -# -# Number of MPI processes per node. -# -PPN_MAKE_GRID="24" -PPN_MAKE_OROG="24" -PPN_MAKE_SFC_CLIMO="24" -PPN_GET_EXTRN_ICS="1" -PPN_GET_EXTRN_LBCS="1" -PPN_MAKE_ICS="12" -PPN_MAKE_LBCS="12" -PPN_RUN_FCST="" # will be calculated from NCORES_PER_NODE and OMP_NUM_THREADS in setup.sh -PPN_RUN_POST="24" -PPN_GET_OBS_CCPA="1" -PPN_GET_OBS_MRMS="1" -PPN_GET_OBS_NDAS="1" -PPN_VX_GRIDSTAT="1" -PPN_VX_POINTSTAT="1" -PPN_VX_ENSGRID="1" -PPN_VX_ENSGRID_MEAN="1" -PPN_VX_ENSGRID_PROB="1" -PPN_VX_ENSPOINT="1" -PPN_VX_ENSPOINT_MEAN="1" -PPN_VX_ENSPOINT_PROB="1" -# -# Walltimes. -# -WTIME_MAKE_GRID="00:20:00" -WTIME_MAKE_OROG="00:20:00" -WTIME_MAKE_SFC_CLIMO="00:20:00" -WTIME_GET_EXTRN_ICS="00:45:00" -WTIME_GET_EXTRN_LBCS="00:45:00" -WTIME_MAKE_ICS="00:30:00" -WTIME_MAKE_LBCS="00:30:00" -WTIME_RUN_FCST="04:30:00" -WTIME_RUN_POST="00:15:00" -WTIME_GET_OBS_CCPA="00:45:00" -WTIME_GET_OBS_MRMS="00:45:00" -WTIME_GET_OBS_NDAS="02:00:00" -WTIME_VX_GRIDSTAT="02:00:00" -WTIME_VX_POINTSTAT="01:00:00" -WTIME_VX_ENSGRID="01:00:00" -WTIME_VX_ENSGRID_MEAN="01:00:00" -WTIME_VX_ENSGRID_PROB="01:00:00" -WTIME_VX_ENSPOINT="01:00:00" -WTIME_VX_ENSPOINT_MEAN="01:00:00" -WTIME_VX_ENSPOINT_PROB="01:00:00" -# -# Maximum number of attempts. -# -MAXTRIES_MAKE_GRID="2" -MAXTRIES_MAKE_OROG="2" -MAXTRIES_MAKE_SFC_CLIMO="2" -MAXTRIES_GET_EXTRN_ICS="1" -MAXTRIES_GET_EXTRN_LBCS="1" -MAXTRIES_MAKE_ICS="1" -MAXTRIES_MAKE_LBCS="1" -MAXTRIES_RUN_FCST="1" -MAXTRIES_RUN_POST="2" -MAXTRIES_GET_OBS_CCPA="1" -MAXTRIES_GET_OBS_MRMS="1" -MAXTRIES_GET_OBS_NDAS="1" -MAXTRIES_VX_GRIDSTAT="1" -MAXTRIES_VX_GRIDSTAT_REFC="1" -MAXTRIES_VX_GRIDSTAT_RETOP="1" -MAXTRIES_VX_GRIDSTAT_03h="1" -MAXTRIES_VX_GRIDSTAT_06h="1" -MAXTRIES_VX_GRIDSTAT_24h="1" -MAXTRIES_VX_POINTSTAT="1" -MAXTRIES_VX_ENSGRID="1" -MAXTRIES_VX_ENSGRID_REFC="1" -MAXTRIES_VX_ENSGRID_RETOP="1" -MAXTRIES_VX_ENSGRID_03h="1" -MAXTRIES_VX_ENSGRID_06h="1" -MAXTRIES_VX_ENSGRID_24h="1" -MAXTRIES_VX_ENSGRID_MEAN="1" -MAXTRIES_VX_ENSGRID_PROB="1" -MAXTRIES_VX_ENSGRID_MEAN_03h="1" -MAXTRIES_VX_ENSGRID_PROB_03h="1" -MAXTRIES_VX_ENSGRID_MEAN_06h="1" -MAXTRIES_VX_ENSGRID_PROB_06h="1" -MAXTRIES_VX_ENSGRID_MEAN_24h="1" -MAXTRIES_VX_ENSGRID_PROB_24h="1" -MAXTRIES_VX_ENSGRID_PROB_REFC="1" -MAXTRIES_VX_ENSGRID_PROB_RETOP="1" -MAXTRIES_VX_ENSPOINT="1" -MAXTRIES_VX_ENSPOINT_MEAN="1" -MAXTRIES_VX_ENSPOINT_PROB="1" - -# -#----------------------------------------------------------------------- -# -# Allows an extra parameter to be passed to slurm via XML Native -# command -# -SLURM_NATIVE_CMD="" -# -#----------------------------------------------------------------------- -# -# Set parameters associated with subhourly forecast model output and -# post-processing. -# -# SUB_HOURLY_POST: -# Flag that indicates whether the forecast model will generate output -# files on a sub-hourly time interval (e.g. 10 minutes, 15 minutes, etc). -# This will also cause the post-processor to process these sub-hourly -# files. If ths is set to "TRUE", then DT_SUBHOURLY_POST_MNTS should be -# set to a value between "00" and "59". -# -# DT_SUB_HOURLY_POST_MNTS: -# Time interval in minutes between the forecast model output files. If -# SUB_HOURLY_POST is set to "TRUE", this needs to be set to a two-digit -# integer between "01" and "59". This is not used if SUB_HOURLY_POST is -# not set to "TRUE". Note that if SUB_HOURLY_POST is set to "TRUE" but -# DT_SUB_HOURLY_POST_MNTS is set to "00", SUB_HOURLY_POST will get reset -# to "FALSE" in the experiment generation scripts (there will be an -# informational message in the log file to emphasize this). -# -#----------------------------------------------------------------------- -# -SUB_HOURLY_POST="FALSE" -DT_SUBHOURLY_POST_MNTS="00" -# -#----------------------------------------------------------------------- -# -# Set parameters for customizing the post-processor (UPP). Definitions: -# -# USE_CUSTOM_POST_CONFIG_FILE: -# Flag that determines whether a user-provided custom configuration file -# should be used for post-processing the model data. If this is set to -# "TRUE", then the workflow will use the custom post-processing (UPP) -# configuration file specified in CUSTOM_POST_CONFIG_FP. Otherwise, a -# default configuration file provided in the UPP repository will be -# used. -# -# CUSTOM_POST_CONFIG_FP: -# The full path to the custom post flat file, including filename, to be -# used for post-processing. This is only used if CUSTOM_POST_CONFIG_FILE -# is set to "TRUE". -# -# POST_OUTPUT_DOMAIN_NAME: -# Domain name (in lowercase) used in constructing the names of the output -# files generated by UPP [which is called either by running the RUN_POST_TN -# task or by activating the inline post feature (WRITE_DOPOST set to "TRUE")]. -# The post output files are named as follows: -# -# $NET.tHHz.[var_name].f###.${POST_OUTPUT_DOMAIN_NAME}.grib2 -# -# If using a custom grid, POST_OUTPUT_DOMAIN_NAME must be specified by -# the user. If using a predefined grid, POST_OUTPUT_DOMAIN_NAME defaults -# to PREDEF_GRID_NAME. Note that this variable is first changed to lower -# case before being used to construct the file names. -# -#----------------------------------------------------------------------- -# -USE_CUSTOM_POST_CONFIG_FILE="FALSE" -CUSTOM_POST_CONFIG_FP="" -POST_OUTPUT_DOMAIN_NAME="" -# -#----------------------------------------------------------------------- -# -# Set parameters associated with outputting satellite fields in the UPP -# grib2 files using the Community Radiative Transfer Model (CRTM). -# -# USE_CRTM: -# Flag that defines whether external CRTM coefficient files have been -# staged by the user in order to output synthetic statellite products -# available within the UPP. If this is set to "TRUE", then the workflow -# will check for these files in the directory CRTM_DIR. Otherwise, it is -# assumed that no satellite fields are being requested in the UPP -# configuration. -# -# CRTM_DIR: -# This is the path to the top CRTM fix file directory. This is only used -# if USE_CRTM is set to "TRUE". -# -#----------------------------------------------------------------------- -# -USE_CRTM="FALSE" -CRTM_DIR="" -# -#----------------------------------------------------------------------- -# -# Set parameters associated with running ensembles. Definitions: -# -# DO_ENSEMBLE: -# Flag that determines whether to run a set of ensemble forecasts (for -# each set of specified cycles). If this is set to "TRUE", NUM_ENS_MEMBERS -# forecasts are run for each cycle, each with a different set of stochastic -# seed values. Otherwise, a single forecast is run for each cycle. -# -# NUM_ENS_MEMBERS: -# The number of ensemble members to run if DO_ENSEMBLE is set to "TRUE". -# This variable also controls the naming of the ensemble member directories. -# For example, if this is set to "8", the member directories will be named -# mem1, mem2, ..., mem8. If it is set to "08" (note the leading zero), -# the member directories will be named mem01, mem02, ..., mem08. Note, -# however, that after reading in the number of characters in this string -# (in order to determine how many leading zeros, if any, should be placed -# in the names of the member directories), the workflow generation scripts -# strip away those leading zeros. Thus, in the variable definitions file -# (GLOBAL_VAR_DEFNS_FN), this variable appear with its leading zeros -# stripped. This variable is not used if DO_ENSEMBLE is not set to "TRUE". -# -#----------------------------------------------------------------------- -# -DO_ENSEMBLE="FALSE" -NUM_ENS_MEMBERS="1" -# -#----------------------------------------------------------------------- -# -# Set default ad-hoc stochastic physics options. -# For detailed documentation of these parameters, see: -# https://stochastic-physics.readthedocs.io/en/ufs_public_release/namelist_options.html -# -#----------------------------------------------------------------------- -# -DO_SHUM="FALSE" -DO_SPPT="FALSE" -DO_SKEB="FALSE" -ISEED_SPPT="1" -ISEED_SHUM="2" -ISEED_SKEB="3" -NEW_LSCALE="TRUE" -SHUM_MAG="0.006" #Variable "shum" in input.nml -SHUM_LSCALE="150000" -SHUM_TSCALE="21600" #Variable "shum_tau" in input.nml -SHUM_INT="3600" #Variable "shumint" in input.nml -SPPT_MAG="0.7" #Variable "sppt" in input.nml -SPPT_LOGIT="TRUE" -SPPT_LSCALE="150000" -SPPT_TSCALE="21600" #Variable "sppt_tau" in input.nml -SPPT_INT="3600" #Variable "spptint" in input.nml -SPPT_SFCLIMIT="TRUE" -SKEB_MAG="0.5" #Variable "skeb" in input.nml -SKEB_LSCALE="150000" -SKEB_TSCALE="21600" #Variable "skeb_tau" in input.nml -SKEB_INT="3600" #Variable "skebint" in input.nml -SKEBNORM="1" -SKEB_VDOF="10" -USE_ZMTNBLCK="FALSE" -# -#----------------------------------------------------------------------- -# -# Set default SPP stochastic physics options. Each SPP option is an array, -# applicable (in order) to the scheme/parameter listed in SPP_VAR_LIST. -# Enter each value of the array in config.sh as shown below without commas -# or single quotes (e.g., SPP_VAR_LIST=( "pbl" "sfc" "mp" "rad" "gwd" ). -# Both commas and single quotes will be added by Jinja when creating the -# namelist. -# -# Note that SPP is currently only available for specific physics schemes -# used in the RAP/HRRR physics suite. Users need to be aware of which SDF -# is chosen when turning this option on. -# -# Patterns evolve and are applied at each time step. -# -#----------------------------------------------------------------------- -# -DO_SPP="false" -SPP_VAR_LIST=( "pbl" "sfc" "mp" "rad" "gwd" ) -SPP_MAG_LIST=( "0.2" "0.2" "0.75" "0.2" "0.2" ) #Variable "spp_prt_list" in input.nml -SPP_LSCALE=( "150000.0" "150000.0" "150000.0" "150000.0" "150000.0" ) -SPP_TSCALE=( "21600.0" "21600.0" "21600.0" "21600.0" "21600.0" ) #Variable "spp_tau" in input.nml -SPP_SIGTOP1=( "0.1" "0.1" "0.1" "0.1" "0.1") -SPP_SIGTOP2=( "0.025" "0.025" "0.025" "0.025" "0.025" ) -SPP_STDDEV_CUTOFF=( "1.5" "1.5" "2.5" "1.5" "1.5" ) -ISEED_SPP=( "4" "5" "6" "7" "8" ) -# -#----------------------------------------------------------------------- -# -# Turn on SPP in Noah or RUC LSM (support for Noah MP is in progress). -# Please be aware of the SDF that you choose if you wish to turn on LSM -# SPP. -# -# SPP in LSM schemes is handled in the &nam_sfcperts namelist block -# instead of in &nam_sppperts, where all other SPP is implemented. -# -# Perturbations to soil moisture content (SMC) are only applied at the -# first time step. -# -# LSM perturbations include SMC - soil moisture content (volume fraction), -# VGF - vegetation fraction, ALB - albedo, SAL - salinity, -# EMI - emissivity, ZOL - surface roughness (cm), and STC - soil temperature. -# -# Only five perturbations at a time can be applied currently, but all seven -# are shown below. In addition, only one unique iseed value is allowed -# at the moment, and is used for each pattern. -# -DO_LSM_SPP="false" #If true, sets lndp_type=2, lndp_model_type=2 -LSM_SPP_TSCALE=( "21600" "21600" "21600" "21600" "21600" "21600" "21600" ) -LSM_SPP_LSCALE=( "150000" "150000" "150000" "150000" "150000" "150000" "150000" ) -ISEED_LSM_SPP=( "9" ) -LSM_SPP_VAR_LIST=( "smc" "vgf" "alb" "sal" "emi" "zol" "stc" ) -LSM_SPP_MAG_LIST=( "0.017" "0.001" "0.001" "0.001" "0.001" "0.001" "0.2" ) -LSM_SPP_EACH_STEP="true" #Sets lndp_each_step=.true. -# -#----------------------------------------------------------------------- -# -# HALO_BLEND: -# Number of rows into the computational domain that should be blended -# with the LBCs. To shut halo blending off, this can be set to zero. -# -#----------------------------------------------------------------------- -# -HALO_BLEND="10" -# -#----------------------------------------------------------------------- -# -# USE_FVCOM: -# Flag set to update surface conditions in FV3-LAM with fields generated -# from the Finite Volume Community Ocean Model (FVCOM). This will -# replace lake/sea surface temperature, ice surface temperature, and ice -# placement. FVCOM data must already be interpolated to the desired -# FV3-LAM grid. This flag will be used in make_ics to modify sfc_data.nc -# after chgres_cube is run by running the routine process_FVCOM.exe -# -# FVCOM_WCSTART: -# Define if this is a "warm" start or a "cold" start. Setting this to -# "warm" will read in sfc_data.nc generated in a RESTART directory. -# Setting this to "cold" will read in the sfc_data.nc generated from -# chgres_cube in the make_ics portion of the workflow. -# -# FVCOM_DIR: -# User defined directory where FVCOM data already interpolated to FV3-LAM -# grid is located. File name in this path should be "fvcom.nc" to allow -# -# FVCOM_FILE: -# Name of file located in FVCOM_DIR that has FVCOM data interpolated to -# FV3-LAM grid. This file will be copied later to a new location and name -# changed to fvcom.nc -# -#------------------------------------------------------------------------ -# -USE_FVCOM="FALSE" -FVCOM_WCSTART="cold" -FVCOM_DIR="/user/defined/dir/to/fvcom/data" -FVCOM_FILE="fvcom.nc" -# -#----------------------------------------------------------------------- -# -# COMPILER: -# Type of compiler invoked during the build step. -# -#------------------------------------------------------------------------ -# -COMPILER="intel" -# -#----------------------------------------------------------------------- -# -# KMP_AFFINITY_*: -# From Intel: "The Intel® runtime library has the ability to bind OpenMP -# threads to physical processing units. The interface is controlled using -# the KMP_AFFINITY environment variable. Depending on the system (machine) -# topology, application, and operating system, thread affinity can have a -# dramatic effect on the application speed. -# -# Thread affinity restricts execution of certain threads (virtual execution -# units) to a subset of the physical processing units in a multiprocessor -# computer. Depending upon the topology of the machine, thread affinity can -# have a dramatic effect on the execution speed of a program." -# -# For more information, see the following link: -# https://software.intel.com/content/www/us/en/develop/documentation/cpp- -# compiler-developer-guide-and-reference/top/optimization-and-programming- -# guide/openmp-support/openmp-library-support/thread-affinity-interface- -# linux-and-windows.html -# -# OMP_NUM_THREADS_*: -# The number of OpenMP threads to use for parallel regions. -# -# OMP_STACKSIZE_*: -# Controls the size of the stack for threads created by the OpenMP -# implementation. -# -# Note that settings for the make_grid and make_orog tasks are not -# included below as they do not use parallelized code. -# -#----------------------------------------------------------------------- -# -KMP_AFFINITY_MAKE_OROG="disabled" -OMP_NUM_THREADS_MAKE_OROG="6" -OMP_STACKSIZE_MAKE_OROG="2048m" - -KMP_AFFINITY_MAKE_SFC_CLIMO="scatter" -OMP_NUM_THREADS_MAKE_SFC_CLIMO="1" -OMP_STACKSIZE_MAKE_SFC_CLIMO="1024m" - -KMP_AFFINITY_MAKE_ICS="scatter" -OMP_NUM_THREADS_MAKE_ICS="1" -OMP_STACKSIZE_MAKE_ICS="1024m" - -KMP_AFFINITY_MAKE_LBCS="scatter" -OMP_NUM_THREADS_MAKE_LBCS="1" -OMP_STACKSIZE_MAKE_LBCS="1024m" - -KMP_AFFINITY_RUN_FCST="scatter" -OMP_NUM_THREADS_RUN_FCST="2" # atmos_nthreads in model_configure -OMP_STACKSIZE_RUN_FCST="1024m" - -KMP_AFFINITY_RUN_POST="scatter" -OMP_NUM_THREADS_RUN_POST="1" -OMP_STACKSIZE_RUN_POST="1024m" -# -#----------------------------------------------------------------------- -# diff --git a/ush/config_defaults.yaml b/ush/config_defaults.yaml new file mode 100644 index 0000000000..e214d0f8ae --- /dev/null +++ b/ush/config_defaults.yaml @@ -0,0 +1,2252 @@ +#---------------------------- +# Test description +#---------------------------- +metadata: + description: >- + Default configuration for an experiment. The valid values each parameter + takes are specified in valid_param_vals.yaml + version: !!str '1.0' +#---------------------------- +# USER config parameters +#---------------------------- +user: + # + #----------------------------------------------------------------------- + # + # Set the RUN_ENVIR variable that is listed and described in the WCOSS + # Implementation Standards document: + # + # NCEP Central Operations + # WCOSS Implementation Standards + # April 19, 2022 + # Version 11.0.0 + # + # RUN_ENVIR is described in this document as follows: + # + # Set to "nco" if running in NCO's production environment. Used to + # distinguish between organizations. + # + # Valid values are "nco" and "community". Here, we use it to generate + # and run the experiment either in NCO mode (if RUN_ENVIR is set to "nco") + # or in community mode (if RUN_ENVIR is set to "community"). This has + # implications on the experiment variables that need to be set and the + # the directory structure used. + # + #----------------------------------------------------------------------- + # + RUN_ENVIR: "nco" + # + #----------------------------------------------------------------------- + # + # mach_doc_start + # Set machine and queue parameters. Definitions: + # + # MACHINE: + # Machine on which the workflow will run. If you are NOT on a named, + # supported platform, and you want to use the Rocoto workflow manager, + # you will need set MACHINE: "linux" and WORKFLOW_MANAGER: "rocoto". This + # combination will assume a Slurm batch manager when generating the XML. + # Please see ush/valid_param_vals.sh for a full list of supported + # platforms. + # + # MACHINE_FILE: + # Path to a configuration file with machine-specific settings. If none + # is provided, setup.sh will attempt to set the path to for a supported + # platform. + # + # ACCOUNT: + # The account under which to submit jobs to the queue. + # + #----------------------------------------------------------------------- + MACHINE: "BIG_COMPUTER" + MACHINE_FILE: "" + ACCOUNT: "project_name" + +#---------------------------- +# PLATFORM config parameters +#----------------------------- +platform: + # + #----------------------------------------------------------------------- + # + # WORKFLOW_MANAGER: + # The workflow manager to use (e.g. rocoto). This is set to "none" by + # default, but if the machine name is set to a platform that supports + # rocoto, this will be overwritten and set to "rocoto". If set + # explicitly to rocoto along with the use of the MACHINE=linux target, + # the configuration layer assumes a Slurm batch manager when generating + # the XML. Valid options: "rocoto" or "none" + # + # NCORES_PER_NODE: + # The number of cores available per node on the compute platform. Set + # for supported platforms in setup.sh, but is now also configurable for + # all platforms. + # + # LMOD_PATH: + # Path to the LMOD sh file on your Linux system. Is set automatically + # for supported machines. + # + # BUILD_MOD_FN: + # Name of alternative build module file to use if using an + # unsupported platform. Is set automatically for supported machines. + # + # WFLOW_MOD_FN: + # Name of alternative workflow module file to use if using an + # unsupported platform. Is set automatically for supported machines. + # + # SCHED: + # The job scheduler to use (e.g. slurm). Set this to an empty string in + # order for the experiment generation script to set it depending on the + # machine. + # + # PARTITION_DEFAULT: + # If using the slurm job scheduler (i.e. if SCHED is set to "slurm"), + # the default partition to which to submit workflow tasks. If a task + # does not have a specific variable that specifies the partition to which + # it will be submitted (e.g. PARTITION_HPSS, PARTITION_FCST; see below), + # it will be submitted to the partition specified by this variable. If + # this is not set or is set to an empty string, it will be (re)set to a + # machine-dependent value. This is not used if SCHED is not set to + # "slurm". + # + # QUEUE_DEFAULT: + # The default queue or QOS (if using the slurm job scheduler, where QOS + # is Quality of Service) to which workflow tasks are submitted. If a + # task does not have a specific variable that specifies the queue to which + # it will be submitted (e.g. QUEUE_HPSS, QUEUE_FCST; see below), it will + # be submitted to the queue specified by this variable. If this is not + # set or is set to an empty string, it will be (re)set to a machine- + # dependent value. + # + # PARTITION_HPSS: + # If using the slurm job scheduler (i.e. if SCHED is set to "slurm"), + # the partition to which the tasks that get or create links to external + # model files [which are needed to generate initial conditions (ICs) and + # lateral boundary conditions (LBCs)] are submitted. If this is not set + # or is set to an empty string, it will be (re)set to a machine-dependent + # value. This is not used if SCHED is not set to "slurm". + # + # QUEUE_HPSS: + # The queue or QOS to which the tasks that get or create links to external + # model files [which are needed to generate initial conditions (ICs) and + # lateral boundary conditions (LBCs)] are submitted. If this is not set + # or is set to an empty string, it will be (re)set to a machine-dependent + # value. + # + # PARTITION_FCST: + # If using the slurm job scheduler (i.e. if SCHED is set to "slurm"), + # the partition to which the task that runs forecasts is submitted. If + # this is not set or set to an empty string, it will be (re)set to a + # machine-dependent value. This is not used if SCHED is not set to + # "slurm". + # + # QUEUE_FCST: + # The queue or QOS to which the task that runs a forecast is submitted. + # If this is not set or set to an empty string, it will be (re)set to a + # machine-dependent value. + # + # mach_doc_end + # + #----------------------------------------------------------------------- + # + WORKFLOW_MANAGER: "none" + NCORES_PER_NODE: "" + LMOD_PATH: "" + BUILD_MOD_FN: "" + WFLOW_MOD_FN: "" + SCHED: "" + PARTITION_DEFAULT: "" + QUEUE_DEFAULT: "" + PARTITION_HPSS: "" + QUEUE_HPSS: "" + PARTITION_FCST: "" + QUEUE_FCST: "" + # + #----------------------------------------------------------------------- + # + # Set run commands for platforms without a workflow manager. These values + # will be ignored unless WORKFLOW_MANAGER: "none". Definitions: + # + # RUN_CMD_UTILS: + # The run command for pre-processing utilities (shave, orog, sfc_climo_gen, + # etc.) Can be left blank for smaller domains, in which case the executables + # will run without MPI. + # + # RUN_CMD_FCST: + # The run command for the model forecast step. This will be appended to + # the end of the variable definitions file, so it can reference other + # variables. + # + # RUN_CMD_POST: + # The run command for post-processing (UPP). Can be left blank for smaller + # domains, in which case UPP will run without MPI. + # + #----------------------------------------------------------------------- + # + RUN_CMD_UTILS: "mpirun -np 1" + RUN_CMD_FCST: "mpirun -np ${PE_MEMBER01}" + RUN_CMD_POST: "mpirun -np 1" + + # + #----------------------------------------------------------------------- + # + # Allows an extra parameter to be passed to slurm via XML Native + # command + # + SLURM_NATIVE_CMD: "" + + # + #----------------------------------------------------------------------- + # + # Set METplus parameters. Definitions: + # + # MODEL: + # String that specifies a descriptive name for the model being verified. + # + # MET_INSTALL_DIR: + # Location to top-level directory of MET installation. + # + # METPLUS_PATH: + # Location to top-level directory of METplus installation. + # + # CCPA_OBS_DIR: + # User-specified location of top-level directory where CCPA hourly + # precipitation files used by METplus are located. This parameter needs + # to be set for both user-provided observations and for observations + # that are retrieved from the NOAA HPSS (if the user has access) via + # the get_obs_ccpa_tn task (activated in workflow by setting + # RUN_TASK_GET_OBS_CCPA=true). In the case of pulling observations + # directly from NOAA HPSS, the data retrieved will be placed in this + # directory. Please note, this path must be defind as + # /full-path-to-obs/ccpa/proc. METplus is configured to verify 01-, + # 03-, 06-, and 24-h accumulated precipitation using hourly CCPA files. + # METplus configuration files require the use of predetermined directory + # structure and file names. Therefore, if the CCPA files are user + # provided, they need to follow the anticipated naming structure: + # {YYYYMMDD}/ccpa.t{HH}z.01h.hrap.conus.gb2, where YYYY is the 4-digit + # valid year, MM the 2-digit valid month, DD the 2-digit valid day of + # the month, and HH the 2-digit valid hour of the day. In addition, a + # caveat is noted for using hourly CCPA data. There is a problem with + # the valid time in the metadata for files valid from 19 - 00 UTC (or + # files under the '00' directory). The script to pull the CCPA data + # from the NOAA HPSS has an example of how to account for this as well + # as organizing the data into a more intuitive format: + # regional_workflow/scripts/exregional_get_ccpa_files.sh. When a fix + # is provided, it will be accounted for in the + # exregional_get_ccpa_files.sh script. + # + # MRMS_OBS_DIR: + # User-specified location of top-level directory where MRMS composite + # reflectivity files used by METplus are located. This parameter needs + # to be set for both user-provided observations and for observations + # that are retrieved from the NOAA HPSS (if the user has access) via the + # get_obs_mrms_tn task (activated in workflow by setting + # RUN_TASK_GET_OBS_MRMS=true). In the case of pulling observations + # directly from NOAA HPSS, the data retrieved will be placed in this + # directory. Please note, this path must be defind as + # /full-path-to-obs/mrms/proc. METplus configuration files require the + # use of predetermined directory structure and file names. Therefore, if + # the MRMS files are user provided, they need to follow the anticipated + # naming structure: + # {YYYYMMDD}/MergedReflectivityQCComposite_00.50_{YYYYMMDD}-{HH}{mm}{SS}.grib2, + # where YYYY is the 4-digit valid year, MM the 2-digit valid month, DD + # the 2-digit valid day of the month, HH the 2-digit valid hour of the + # day, mm the 2-digit valid minutes of the hour, and SS is the two-digit + # valid seconds of the hour. In addition, METplus is configured to look + # for a MRMS composite reflectivity file for the valid time of the + # forecast being verified; since MRMS composite reflectivity files do + # not always exactly match the valid time, a script, within the main + # script to retrieve MRMS data from the NOAA HPSS, is used to identify + # and rename the MRMS composite reflectivity file to match the valid + # time of the forecast. The script to pull the MRMS data from the NOAA + # HPSS has an example of the expected file naming structure: + # regional_workflow/scripts/exregional_get_mrms_files.sh. This script + # calls the script used to identify the MRMS file closest to the valid + # time: regional_workflow/ush/mrms_pull_topofhour.py. + # + # NDAS_OBS_DIR: + # User-specified location of top-level directory where NDAS prepbufr + # files used by METplus are located. This parameter needs to be set for + # both user-provided observations and for observations that are + # retrieved from the NOAA HPSS (if the user has access) via the + # get_obs_ndas_tn task (activated in workflow by setting  + # RUN_TASK_GET_OBS_NDAS=true). In the case of pulling observations + # directly from NOAA HPSS, the data retrieved will be placed in this + # directory. Please note, this path must be defind as + # /full-path-to-obs/ndas/proc. METplus is configured to verify + # near-surface variables hourly and upper-air variables at times valid + # at 00 and 12 UTC with NDAS prepbufr files. METplus configuration files + # require the use of predetermined file names. Therefore, if the NDAS + # files are user provided, they need to follow the anticipated naming + # structure: prepbufr.ndas.{YYYYMMDDHH}, where YYYY is the 4-digit valid + # year, MM the 2-digit valid month, DD the 2-digit valid day of the + # month, and HH the 2-digit valid hour of the day. The script to pull + # the NDAS data from the NOAA HPSS has an example of how to rename the + # NDAS data into a more intuitive format with the valid time listed in + # the file name: regional_workflow/scripts/exregional_get_ndas_files.sh + # + #----------------------------------------------------------------------- + # + MODEL: "" + MET_INSTALL_DIR: "" + MET_BIN_EXEC: "bin" + METPLUS_PATH: "" + CCPA_OBS_DIR: "" + MRMS_OBS_DIR: "" + NDAS_OBS_DIR: "" + # + #----------------------------------------------------------------------- + # + # DOMAIN_PREGEN_BASEDIR: + # The base directory containing pregenerated grid, orography, and surface + # climatology files. This is an alternative for setting GRID_DIR, + # OROG_DIR, and SFC_CLIMO_DIR individually + # + # For the pregenerated grid specified by PREDEF_GRID_NAME, + # these "fixed" files are located in: + # + # ${DOMAIN_PREGEN_BASEDIR}/${PREDEF_GRID_NAME} + # + # The workflow scripts will create a symlink in the experiment directory + # that will point to a subdirectory (having the name of the grid being + # used) under this directory. This variable should be set to a null + # string in this file, but it can be specified in the user-specified + # workflow configuration file (EXPT_CONFIG_FN). + # + #----------------------------------------------------------------------- + # + DOMAIN_PREGEN_BASEDIR: "" + +#---------------------------- +# WORKFLOW config parameters +#----------------------------- +workflow: + # + #----------------------------------------------------------------------- + # + # Set cron-associated parameters. Definitions: + # + # USE_CRON_TO_RELAUNCH: + # Flag that determines whether or not to add a line to the user's cron + # table to call the experiment launch script every CRON_RELAUNCH_INTVL_MNTS + # minutes. + # + # CRON_RELAUNCH_INTVL_MNTS: + # The interval (in minutes) between successive calls of the experiment + # launch script by a cron job to (re)launch the experiment (so that the + # workflow for the experiment kicks off where it left off). + # + #----------------------------------------------------------------------- + # + USE_CRON_TO_RELAUNCH: false + CRON_RELAUNCH_INTVL_MNTS: 3 + # + #----------------------------------------------------------------------- + # + # dir_doc_start + # Set directories. Definitions: + # + # EXPT_BASEDIR: + # The base directory in which the experiment directory will be created. + # If this is not specified or if it is set to an empty string, it will + # default to ${HOMErrfs}/../expt_dirs. + # + # EXPT_SUBDIR: + # The name that the experiment directory (without the full path) will + # have. The full path to the experiment directory, which will be contained + # in the variable EXPTDIR, will be: + # + # EXPTDIR: "${EXPT_BASEDIR}/${EXPT_SUBDIR}" + # + # This cannot be empty. If set to a null string here, it must be set to + # a (non-empty) value in the user-defined experiment configuration file. + # + # dir_doc_end + # + # EXEC_SUBDIR: + # The name of the subdirectory of ufs-srweather-app where executables are + # installed. + #----------------------------------------------------------------------- + # + EXPT_BASEDIR: "" + EXPT_SUBDIR: "" + EXEC_SUBDIR: "bin" + # + #----------------------------------------------------------------------- + # + # Set variables that are only used in NCO mode (i.e. when RUN_ENVIR is + # set to "nco"). Definitions: + # + # COMIN: + # Directory containing files generated by the external model (FV3GFS, NAM, + # HRRR, etc) that the initial and lateral boundary condition generation tasks + # need in order to create initial and boundary condition files for a given + # cycle on the native FV3-LAM grid. + # + # envir, NET, model_ver, RUN: + # Standard environment variables defined in the NCEP Central Operations WCOSS + # Implementation Standards document as follows: + # + # envir: + # Set to "test" during the initial testing phase, "para" when running + # in parallel (on a schedule), and "prod" in production. + # + # NET: + # Model name (first level of com directory structure) + # + # model_ver: + # Version number of package in three digits (second level of com directory) + # + # RUN: + # Name of model run (third level of com directory structure). + # In general, same as $NET + # + # STMP: + # The beginning portion of the directory that will contain cycle-dependent + # model input files, symlinks to cycle-independent input files, and raw + # (i.e. before post-processing) forecast output files for a given cycle. + # For a cycle that starts on the date specified by yyyymmdd and hour + # specified by hh (where yyyymmdd and hh are as described above) [so that + # the cycle date (cdate) is given by cdate: "${yyyymmdd}${hh}"], the + # directory in which the aforementioned files will be located is: + # + # $STMP/tmpnwprd/$RUN/$cdate + # + # PTMP: + # The beginning portion of the directory that will contain the output + # files from the post-processor (UPP) for a given cycle. For a cycle + # that starts on the date specified by yyyymmdd and hour specified by hh + # (where yyyymmdd and hh are as described above), the directory in which + # the UPP output files will be placed will be: + # + # $PTMP/com/$NET/$model_ver/$RUN.$yyyymmdd/$hh + # + #----------------------------------------------------------------------- + # + COMIN: "/path/of/directory/containing/data/files/for/IC/LBCS" + envir: "para" + NET: "rrfs" + model_ver: "v1.0.0" + RUN: "rrfs" + STMP: "/base/path/of/directory/containing/model/input/and/raw/output/files" + PTMP: "/base/path/of/directory/containing/postprocessed/output/files" + # + #----------------------------------------------------------------------- + # + # Set the separator character(s) to use in the names of the grid, mosaic, + # and orography fixed files. + # + # Ideally, the same separator should be used in the names of these fixed + # files as the surface climatology fixed files (which always use a "." + # as the separator), i.e. ideally, DOT_OR_USCORE should be set to "." + # + #----------------------------------------------------------------------- + # + DOT_OR_USCORE: "_" + # + #----------------------------------------------------------------------- + # + # Set file names. Definitions: + # + # EXPT_CONFIG_FN: + # Name of the user-specified configuration file for the forecast experiment. + # + # CONSTANTS_FN: + # Name of the file containing definitions of various mathematical, physical, + # and SRW App contants. + # + # RGNL_GRID_NML_FN: + # Name of file containing the namelist settings for the code that generates + # a "ESGgrid" type of regional grid. + # + # FV3_NML_BASE_SUITE_FN: + # Name of Fortran namelist file containing the forecast model's base suite + # namelist, i.e. the portion of the namelist that is common to all physics + # suites. + # + # FV3_NML_YAML_CONFIG_FN: + # Name of YAML configuration file containing the forecast model's namelist + # settings for various physics suites. + # + # FV3_NML_BASE_ENS_FN: + # Name of Fortran namelist file containing the forecast model's base + # ensemble namelist, i.e. the the namelist file that is the starting point + # from which the namelist files for each of the enesemble members are + # generated. + # + # FV3_EXEC_FN: + # Name to use for the forecast model executable when it is copied from + # the directory in which it is created in the build step to the executables + # directory (EXECDIR; this is set during experiment generation). + # + # DIAG_TABLE_TMPL_FN: + # Name of a template file that specifies the output fields of the forecast + # model (ufs-weather-model: diag_table) followed by [dot_ccpp_phys_suite]. + # Its default value is the name of the file that the ufs weather model + # expects to read in. + # + # FIELD_TABLE_TMPL_FN: + # Name of a template file that specifies the tracers in IC/LBC files of the + # forecast model (ufs-weather-mode: field_table) followed by [dot_ccpp_phys_suite]. + # Its default value is the name of the file that the ufs weather model expects + # to read in. + # + # MODEL_CONFIG_TMPL_FN: + # Name of a template file that contains settings and configurations for the + # NUOPC/ESMF main component (ufs-weather-model: model_config). Its default + # value is the name of the file that the ufs weather model expects to read in. + # + # NEMS_CONFIG_TMPL_FN: + # Name of a template file that contains information about the various NEMS + # components and their run sequence (ufs-weather-model: nems.configure). + # Its default value is the name of the file that the ufs weather model expects + # to read in. + # + # FCST_MODEL: + # Name of forecast model (default=ufs-weather-model) + # + # WFLOW_XML_FN: + # Name of the rocoto workflow XML file that the experiment generation + # script creates and that defines the workflow for the experiment. + # + # GLOBAL_VAR_DEFNS_FN: + # Name of file (a shell script) containing the defintions of the primary + # experiment variables (parameters) defined in this default configuration + # script and in the user-specified configuration as well as secondary + # experiment variables generated by the experiment generation script. + # This file is sourced by many scripts (e.g. the J-job scripts corresponding + # to each workflow task) in order to make all the experiment variables + # available in those scripts. + # + # EXTRN_MDL_VAR_DEFNS_FN: + # Name of file (a shell script) containing the defintions of variables + # associated with the external model from which ICs or LBCs are generated. This + # file is created by the GET_EXTRN_*_TN task because the values of the variables + # it contains are not known before this task runs. The file is then sourced by + # the MAKE_ICS_TN and MAKE_LBCS_TN tasks. + # + # WFLOW_LAUNCH_SCRIPT_FN: + # Name of the script that can be used to (re)launch the experiment's rocoto + # workflow. + # + # WFLOW_LAUNCH_LOG_FN: + # Name of the log file that contains the output from successive calls to + # the workflow launch script (WFLOW_LAUNCH_SCRIPT_FN). + # + #----------------------------------------------------------------------- + # + EXPT_CONFIG_FN: "config.yaml" + CONSTANTS_FN: "constants.sh" + + RGNL_GRID_NML_FN: "regional_grid.nml" + + FV3_NML_BASE_SUITE_FN: "input.nml.FV3" + FV3_NML_YAML_CONFIG_FN: "FV3.input.yml" + FV3_NML_BASE_ENS_FN: "input.nml.base_ens" + FV3_EXEC_FN: "ufs_model" + + DATA_TABLE_TMPL_FN: "" + DIAG_TABLE_TMPL_FN: "" + FIELD_TABLE_TMPL_FN: "" + MODEL_CONFIG_TMPL_FN: "" + NEMS_CONFIG_TMPL_FN: "" + + FCST_MODEL: "ufs-weather-model" + WFLOW_XML_FN: "FV3LAM_wflow.xml" + GLOBAL_VAR_DEFNS_FN: "var_defns.sh" + EXTRN_MDL_VAR_DEFNS_FN: "extrn_mdl_var_defns.sh" + WFLOW_LAUNCH_SCRIPT_FN: "launch_FV3LAM_wflow.sh" + WFLOW_LAUNCH_LOG_FN: "log.launch_FV3LAM_wflow" + # + #----------------------------------------------------------------------- + # + # Set CCPP-associated parameters. Definitions: + # + # CCPP_PHYS_SUITE: + # The physics suite that will run using CCPP (Common Community Physics + # Package). The choice of physics suite determines the forecast model's + # namelist file, the diagnostics table file, the field table file, and + # the XML physics suite definition file that are staged in the experiment + # directory or the cycle directories under it. + # + #----------------------------------------------------------------------- + # + CCPP_PHYS_SUITE: "FV3_GFS_v16" + # + #----------------------------------------------------------------------- + # + # Set GRID_GEN_METHOD. This variable specifies the method to use to + # generate a regional grid in the horizontal. The values that it can + # take on are: + # + # * "GFDLgrid": + # This setting will generate a regional grid by first generating a + # "parent" global cubed-sphere grid and then taking a portion of tile + # 6 of that global grid -- referred to in the grid generation scripts + # as "tile 7" even though it doesn't correspond to a complete tile -- + # and using it as the regional grid. Note that the forecast is run on + # only on the regional grid (i.e. tile 7, not tiles 1 through 6). + # + # * "ESGgrid": + # This will generate a regional grid using the map projection developed + # by Jim Purser of EMC. + # + # Note that: + # + # 1) If the experiment is using one of the predefined grids (i.e. if + # PREDEF_GRID_NAME is set to the name of one of the valid predefined + # grids), then GRID_GEN_METHOD will be reset to the value of + # GRID_GEN_METHOD for that grid. This will happen regardless of + # whether or not GRID_GEN_METHOD is assigned a value in the user- + # specified experiment configuration file, i.e. any value it may be + # assigned in the experiment configuration file will be overwritten. + # + # 2) If the experiment is not using one of the predefined grids (i.e. if + # PREDEF_GRID_NAME is set to a null string), then GRID_GEN_METHOD must + # be set in the experiment configuration file. Otherwise, it will + # remain set to a null string, and the experiment generation will + # fail because the generation scripts check to ensure that it is set + # to a non-empty string before creating the experiment directory. + # + #----------------------------------------------------------------------- + # + GRID_GEN_METHOD: "" + # + #----------------------------------------------------------------------- + # + # Set forecast parameters. Definitions: + # + # DATE_FIRST_CYCL: + # Starting date of the first forecast in the set of forecasts to run. + # Format is "YYYYMMDD". Note that this does not include the hour-of-day. + # + # DATE_LAST_CYCL: + # Starting date of the last forecast in the set of forecasts to run. + # Format is "YYYYMMDD". Note that this does not include the hour-of-day. + # + # CYCL_HRS: + # An array containing the hours of the day at which to launch forecasts. + # Forecasts are launched at these hours on each day from DATE_FIRST_CYCL + # to DATE_LAST_CYCL, inclusive. Each element of this array must be a + # two-digit string representing an integer that is less than or equal to + # 23, e.g. "00", "03", "12", "23". + # + # INCR_CYCL_FREQ: + # Increment in hours for Cycle Frequency (cycl_freq). + # Default is 24, which means cycle_freq=24:00:00 + # + # FCST_LEN_HRS: + # The length of each forecast, in integer hours. + # + #----------------------------------------------------------------------- + # + DATE_FIRST_CYCL: "YYYYMMDD" + DATE_LAST_CYCL: "YYYYMMDD" + CYCL_HRS: [ "HH1", "HH2" ] + INCR_CYCL_FREQ: 24 + FCST_LEN_HRS: 24 + # + #----------------------------------------------------------------------- + # + # Set PREEXISTING_DIR_METHOD. This variable determines the method to use + # use to deal with preexisting directories [e.g ones generated by previous + # calls to the experiment generation script using the same experiment name + # (EXPT_SUBDIR) as the current experiment]. This variable must be set to + # one of "delete", "rename", and "quit". The resulting behavior for each + # of these values is as follows: + # + # * "delete": + # The preexisting directory is deleted and a new directory (having the + # same name as the original preexisting directory) is created. + # + # * "rename": + # The preexisting directory is renamed and a new directory (having the + # same name as the original preexisting directory) is created. The new + # name of the preexisting directory consists of its original name and + # the suffix "_oldNNN", where NNN is a 3-digit integer chosen to make + # the new name unique. + # + # * "quit": + # The preexisting directory is left unchanged, but execution of the + # currently running script is terminated. In this case, the preexisting + # directory must be dealt with manually before rerunning the script. + # + #----------------------------------------------------------------------- + # + PREEXISTING_DIR_METHOD: "delete" + # + #----------------------------------------------------------------------- + # + # Set flags for more detailed messages. Defintitions: + # + # VERBOSE: + # This is a flag that determines whether or not the experiment generation + # and workflow task scripts tend to print out more informational messages. + # + # DEBUG: + # This is a flag that determines whether or not very detailed debugging + # messages are printed to out. Note that if DEBUG is set to TRUE, then + # VERBOSE will also get reset to TRUE if it isn't already. + # + #----------------------------------------------------------------------- + # + VERBOSE: true + DEBUG: false + # + #----------------------------------------------------------------------- + # + # COMPILER: + # Type of compiler invoked during the build step. + # + #------------------------------------------------------------------------ + # + COMPILER: "intel" + + #is this the right place? + GET_OBS: "get_obs" + VX_TN: "run_vx" + VX_ENSGRID_TN: "run_ensgridvx" + VX_ENSGRID_PROB_REFC_TN: "run_ensgridvx_prob_refc" + MAXTRIES_VX_ENSGRID_PROB_REFC: 1 + +#---------------------------- +# WORKFLOW SWITCHES config parameters +#----------------------------- +workflow_switches: + # + #----------------------------------------------------------------------- + # + # Set flags (and related directories) that determine whether various + # workflow tasks should be run. Note that the MAKE_GRID_TN, MAKE_OROG_TN, + # and MAKE_SFC_CLIMO_TN are all cycle-independent tasks, i.e. if they + # are to be run, they do so only once at the beginning of the workflow + # before any cycles are run. Definitions: + # + # RUN_TASK_MAKE_GRID: + # Flag that determines whether the MAKE_GRID_TN task is to be run. If + # this is set to true, the grid generation task is run and new grid + # files are generated. If it is set to false, then the scripts look + # for pregenerated grid files in the directory specified by GRID_DIR + # (see below). + # + # RUN_TASK_MAKE_OROG: + # Same as RUN_TASK_MAKE_GRID but for the MAKE_OROG_TN task. + # + # RUN_TASK_MAKE_SFC_CLIMO: + # Same as RUN_TASK_MAKE_GRID but for the MAKE_SFC_CLIMO_TN task. + # + # RUN_TASK_GET_EXTRN_ICS: + # Flag that determines whether the GET_EXTRN_ICS_TN task is to be run. + # + # RUN_TASK_GET_EXTRN_LBCS: + # Flag that determines whether the GET_EXTRN_LBCS_TN task is to be run. + # + # RUN_TASK_MAKE_ICS: + # Flag that determines whether the MAKE_ICS_TN task is to be run. + # + # RUN_TASK_MAKE_LBCS: + # Flag that determines whether the MAKE_LBCS_TN task is to be run. + # + # RUN_TASK_RUN_FCST: + # Flag that determines whether the RUN_FCST_TN task is to be run. + # + # RUN_TASK_RUN_POST: + # Flag that determines whether the RUN_POST_TN task is to be run. + # + # RUN_TASK_VX_GRIDSTAT: + # Flag that determines whether the grid-stat verification task is to be + # run. + # + # RUN_TASK_VX_POINTSTAT: + # Flag that determines whether the point-stat verification task is to be + # run. + # + # RUN_TASK_VX_ENSGRID: + # Flag that determines whether the ensemble-stat verification for gridded + # data task is to be run. + # + # RUN_TASK_VX_ENSPOINT: + # Flag that determines whether the ensemble point verification task is + # to be run. If this flag is set, both ensemble-stat point verification + # and point verification of ensemble-stat output is computed. + # + #----------------------------------------------------------------------- + # + RUN_TASK_MAKE_GRID: true + RUN_TASK_MAKE_OROG: true + RUN_TASK_MAKE_SFC_CLIMO: true + + RUN_TASK_GET_EXTRN_ICS: true + RUN_TASK_GET_EXTRN_LBCS: true + RUN_TASK_MAKE_ICS: true + RUN_TASK_MAKE_LBCS: true + RUN_TASK_RUN_FCST: true + RUN_TASK_RUN_POST: true + + RUN_TASK_GET_OBS_CCPA: false + RUN_TASK_GET_OBS_MRMS: false + RUN_TASK_GET_OBS_NDAS: false + RUN_TASK_VX_GRIDSTAT: false + RUN_TASK_VX_POINTSTAT: false + RUN_TASK_VX_ENSGRID: false + RUN_TASK_VX_ENSPOINT: false + +#---------------------------- +# MAKE GRID config parameters +#----------------------------- +task_make_grid: + MAKE_GRID_TN: "make_grid" + NNODES_MAKE_GRID: 1 + PPN_MAKE_GRID: 24 + WTIME_MAKE_GRID: 00:20:00 + MAXTRIES_MAKE_GRID: 2 + # + #----------------------------------------------------------------------- + # + # GRID_DIR: + # The directory in which to look for pregenerated grid files if + # RUN_TASK_MAKE_GRID is set to false. + # + #----------------------------------------------------------------------- + # + GRID_DIR: "/path/to/pregenerated/grid/files" + # + #----------------------------------------------------------------------- + # + # Set parameters specific to the "GFDLgrid" method of generating a regional + # grid (i.e. for GRID_GEN_METHOD set to "GFDLgrid"). The following + # parameters will be used only if GRID_GEN_METHOD is set to "GFDLgrid". + # In this grid generation method: + # + # * The regional grid is defined with respect to a "parent" global cubed- + # sphere grid. Thus, all the parameters for a global cubed-sphere grid + # must be specified in order to define this parent global grid even + # though the model equations are not integrated on (they are integrated + # only on the regional grid). + # + # * GFDLgrid_NUM_CELLS is the number of grid cells in either one of the two + # horizontal directions x and y on any one of the 6 tiles of the parent + # global cubed-sphere grid. The mapping from GFDLgrid_NUM_CELLS to a nominal + # resolution (grid cell size) for a uniform global grid (i.e. Schmidt + # stretch factor GFDLgrid_STRETCH_FAC set to 1) for several values of + # GFDLgrid_NUM_CELLS is as follows: + # + # GFDLgrid_NUM_CELLS typical cell size + # ------------ ----------------- + # 192 50 km + # 384 25 km + # 768 13 km + # 1152 8.5 km + # 3072 3.2 km + # + # Note that these are only typical cell sizes. The actual cell size on + # the global grid tiles varies somewhat as we move across a tile. + # + # * Tile 6 has arbitrarily been chosen as the tile to use to orient the + # global parent grid on the sphere (Earth). This is done by specifying + # GFDLgrid_LON_T6_CTR and GFDLgrid_LAT_T6_CTR, which are the longitude + # and latitude (in degrees) of the center of tile 6. + # + # * Setting the Schmidt stretching factor GFDLgrid_STRETCH_FAC to a value + # greater than 1 shrinks tile 6, while setting it to a value less than + # 1 (but still greater than 0) expands it. The remaining 5 tiles change + # shape as necessary to maintain global coverage of the grid. + # + # * The cell size on a given global tile depends on both GFDLgrid_NUM_CELLS and + # GFDLgrid_STRETCH_FAC (since changing GFDLgrid_NUM_CELLS changes the number + # of cells in the tile, and changing GFDLgrid_STRETCH_FAC modifies the + # shape and size of the tile). + # + # * The regional grid is embedded within tile 6 (i.e. it doesn't extend + # beyond the boundary of tile 6). Its exact location within tile 6 is + # is determined by specifying the starting and ending i and j indices + # of the regional grid on tile 6, where i is the grid index in the x + # direction and j is the grid index in the y direction. These indices + # are stored in the variables + # + # GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G + # GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G + # GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G + # GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G + # + # * In the forecast model code and in the experiment generation and workflow + # scripts, for convenience the regional grid is denoted as "tile 7" even + # though it doesn't map back to one of the 6 faces of the cube from + # which the parent global grid is generated (it maps back to only a + # subregion on face 6 since it is wholly confined within tile 6). Tile + # 6 may be referred to as the "parent" tile of the regional grid. + # + # * GFDLgrid_REFINE_RATIO is the refinement ratio of the regional grid + # (tile 7) with respect to the grid on its parent tile (tile 6), i.e. + # it is the number of grid cells along the boundary of the regional grid + # that abut one cell on tile 6. Thus, the cell size on the regional + # grid depends not only on GFDLgrid_NUM_CELLS and GFDLgrid_STRETCH_FAC (because + # the cell size on tile 6 depends on these two parameters) but also on + # GFDLgrid_REFINE_RATIO. Note that as on the tiles of the global grid, + # the cell size on the regional grid is not uniform but varies as we + # move across the grid. + # + # Definitions of parameters that need to be specified when GRID_GEN_METHOD + # is set to "GFDLgrid": + # + # GFDLgrid_LON_T6_CTR: + # Longitude of the center of tile 6 (in degrees). + # + # GFDLgrid_LAT_T6_CTR: + # Latitude of the center of tile 6 (in degrees). + # + # GFDLgrid_NUM_CELLS: + # Number of points in each of the two horizontal directions (x and y) on + # each tile of the parent global grid. Note that the name of this parameter + # is really a misnomer because although it has the stirng "RES" (for + # "resolution") in its name, it specifies number of grid cells, not grid + # size (in say meters or kilometers). However, we keep this name in order + # to remain consistent with the usage of the word "resolution" in the + # global forecast model and other auxiliary codes. + # + # GFDLgrid_STRETCH_FAC: + # Stretching factor used in the Schmidt transformation applied to the + # parent cubed-sphere grid. + # + # GFDLgrid_REFINE_RATIO: + # Cell refinement ratio for the regional grid, i.e. the number of cells + # in either the x or y direction on the regional grid (tile 7) that abut + # one cell on its parent tile (tile 6). + # + # GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G: + # i-index on tile 6 at which the regional grid (tile 7) starts. + # + # GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G: + # i-index on tile 6 at which the regional grid (tile 7) ends. + # + # GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G: + # j-index on tile 6 at which the regional grid (tile 7) starts. + # + # GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G: + # j-index on tile 6 at which the regional grid (tile 7) ends. + # + # GFDLgrid_USE_NUM_CELLS_IN_FILENAMES: + # Flag that determines the file naming convention to use for grid, orography, + # and surface climatology files (or, if using pregenerated files, the + # naming convention that was used to name these files). These files + # usually start with the string "C${RES}_", where RES is an integer. + # In the global forecast model, RES is the number of points in each of + # the two horizontal directions (x and y) on each tile of the global grid + # (defined here as GFDLgrid_NUM_CELLS). If this flag is set to true, RES will + # be set to GFDLgrid_NUM_CELLS just as in the global forecast model. If it is + # set to false, we calculate (in the grid generation task) an "equivalent + # global uniform cubed-sphere resolution" -- call it RES_EQUIV -- and + # then set RES equal to it. RES_EQUIV is the number of grid points in + # each of the x and y directions on each tile that a global UNIFORM (i.e. + # stretch factor of 1) cubed-sphere grid would have to have in order to + # have the same average grid size as the regional grid. This is a more + # useful indicator of the grid size because it takes into account the + # effects of GFDLgrid_NUM_CELLS, GFDLgrid_STRETCH_FAC, and GFDLgrid_REFINE_RATIO + # in determining the regional grid's typical grid size, whereas simply + # setting RES to GFDLgrid_NUM_CELLS doesn't take into account the effects of + # GFDLgrid_STRETCH_FAC and GFDLgrid_REFINE_RATIO on the regional grid's + # resolution. Nevertheless, some users still prefer to use GFDLgrid_NUM_CELLS + # in the file names, so we allow for that here by setting this flag to + # true. + # + # Note that: + # + # 1) If the experiment is using one of the predefined grids (i.e. if + # PREDEF_GRID_NAME is set to the name of one of the valid predefined + # grids), then: + # + # a) If the value of GRID_GEN_METHOD for that grid is "GFDLgrid", then + # these parameters will get reset to the values for that grid. + # This will happen regardless of whether or not they are assigned + # values in the user-specified experiment configuration file, i.e. + # any values they may be assigned in the experiment configuration + # file will be overwritten. + # + # b) If the value of GRID_GEN_METHOD for that grid is "ESGgrid", then + # these parameters will not be used and thus do not need to be reset + # to non-empty strings. + # + # 2) If the experiment is not using one of the predefined grids (i.e. if + # PREDEF_GRID_NAME is set to a null string), then: + # + # a) If GRID_GEN_METHOD is set to "GFDLgrid" in the user-specified + # experiment configuration file, then these parameters must be set + # in that configuration file. + # + # b) If GRID_GEN_METHOD is set to "ESGgrid" in the user-specified + # experiment configuration file, then these parameters will not be + # used and thus do not need to be reset to non-empty strings. + # + #----------------------------------------------------------------------- + # + GFDLgrid_LON_T6_CTR: "" + GFDLgrid_LAT_T6_CTR: "" + GFDLgrid_NUM_CELLS: "" + GFDLgrid_STRETCH_FAC: "" + GFDLgrid_REFINE_RATIO: "" + GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G: "" + GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G: "" + GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G: "" + GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G: "" + GFDLgrid_USE_NUM_CELLS_IN_FILENAMES: "" + # + #----------------------------------------------------------------------- + # + # Set parameters specific to the "ESGgrid" method of generating a regional + # grid (i.e. for GRID_GEN_METHOD set to "ESGgrid"). Definitions: + # + # ESGgrid_LON_CTR: + # The longitude of the center of the grid (in degrees). + # + # ESGgrid_LAT_CTR: + # The latitude of the center of the grid (in degrees). + # + # ESGgrid_DELX: + # The cell size in the zonal direction of the regional grid (in meters). + # + # ESGgrid_DELY: + # The cell size in the meridional direction of the regional grid (in + # meters). + # + # ESGgrid_NX: + # The number of cells in the zonal direction on the regional grid. + # + # ESGgrid_NY: + # The number of cells in the meridional direction on the regional grid. + # + # ESGgrid_WIDE_HALO_WIDTH: + # The width (in units of number of grid cells) of the halo to add around + # the regional grid before shaving the halo down to the width(s) expected + # by the forecast model. + # + # ESGgrid_PAZI: + # The rotational parameter for the ESG grid (in degrees). + # + # In order to generate grid files containing halos that are 3-cell and + # 4-cell wide and orography files with halos that are 0-cell and 3-cell + # wide (all of which are required as inputs to the forecast model), the + # grid and orography tasks first create files with halos around the regional + # domain of width ESGgrid_WIDE_HALO_WIDTH cells. These are first stored + # in files. The files are then read in and "shaved" down to obtain grid + # files with 3-cell-wide and 4-cell-wide halos and orography files with + # 0-cell-wide (i.e. no halo) and 3-cell-wide halos. For this reason, we + # refer to the original halo that then gets shaved down as the "wide" + # halo, i.e. because it is wider than the 0-cell-wide, 3-cell-wide, and + # 4-cell-wide halos that we will eventually end up with. Note that the + # grid and orography files with the wide halo are only needed as intermediates + # in generating the files with 0-cell-, 3-cell-, and 4-cell-wide halos; + # they are not needed by the forecast model. + # NOTE: Probably don't need to make ESGgrid_WIDE_HALO_WIDTH a user-specified + # variable. Just set it in the function set_gridparams_ESGgrid.sh. + # + # Note that: + # + # 1) If the experiment is using one of the predefined grids (i.e. if + # PREDEF_GRID_NAME is set to the name of one of the valid predefined + # grids), then: + # + # a) If the value of GRID_GEN_METHOD for that grid is "GFDLgrid", then + # these parameters will not be used and thus do not need to be reset + # to non-empty strings. + # + # b) If the value of GRID_GEN_METHOD for that grid is "ESGgrid", then + # these parameters will get reset to the values for that grid. + # This will happen regardless of whether or not they are assigned + # values in the user-specified experiment configuration file, i.e. + # any values they may be assigned in the experiment configuration + # file will be overwritten. + # + # 2) If the experiment is not using one of the predefined grids (i.e. if + # PREDEF_GRID_NAME is set to a null string), then: + # + # a) If GRID_GEN_METHOD is set to "GFDLgrid" in the user-specified + # experiment configuration file, then these parameters will not be + # used and thus do not need to be reset to non-empty strings. + # + # b) If GRID_GEN_METHOD is set to "ESGgrid" in the user-specified + # experiment configuration file, then these parameters must be set + # in that configuration file. + # + #----------------------------------------------------------------------- + # + ESGgrid_LON_CTR: "" + ESGgrid_LAT_CTR: "" + ESGgrid_DELX: "" + ESGgrid_DELY: "" + ESGgrid_NX: "" + ESGgrid_NY: "" + ESGgrid_WIDE_HALO_WIDTH: "" + ESGgrid_PAZI: "" + +#---------------------------- +# MAKE OROG config parameters +#----------------------------- +task_make_orog: + MAKE_OROG_TN: "make_orog" + NNODES_MAKE_OROG: 1 + PPN_MAKE_OROG: 24 + WTIME_MAKE_OROG: 00:20:00 + MAXTRIES_MAKE_OROG: 2 + KMP_AFFINITY_MAKE_OROG: "disabled" + OMP_NUM_THREADS_MAKE_OROG: 6 + OMP_STACKSIZE_MAKE_OROG: "2048m" + OROG_DIR: "/path/to/pregenerated/orog/files" + +#---------------------------- +# MAKE SFC CLIMO config parameters +#----------------------------- +task_make_sfc_climo: + MAKE_SFC_CLIMO_TN: "make_sfc_climo" + NNODES_MAKE_SFC_CLIMO: 2 + PPN_MAKE_SFC_CLIMO: 24 + WTIME_MAKE_SFC_CLIMO: 00:20:00 + MAXTRIES_MAKE_SFC_CLIMO: 2 + KMP_AFFINITY_MAKE_SFC_CLIMO: "scatter" + OMP_NUM_THREADS_MAKE_SFC_CLIMO: 1 + OMP_STACKSIZE_MAKE_SFC_CLIMO: "1024m" + SFC_CLIMO_DIR: "/path/to/pregenerated/surface/climo/files" + +#---------------------------- +# EXTRN ICS config parameters +#----------------------------- +task_get_extrn_ics: + GET_EXTRN_ICS_TN: "get_extrn_ics" + NNODES_GET_EXTRN_ICS: 1 + PPN_GET_EXTRN_ICS: 1 + WTIME_GET_EXTRN_ICS: 00:45:00 + MAXTRIES_GET_EXTRN_ICS: 1 + # + #----------------------------------------------------------------------- + # + # Set initial and lateral boundary condition generation parameters. + # Definitions: + # + # EXTRN_MDL_NAME_ICS: + #`The name of the external model that will provide fields from which + # initial condition (including and surface) files will be generated for + # input into the forecast model. + # + # EXTRN_MDL_ICS_OFFSET_HRS: + # Users may wish to start a forecast from a forecast of a previous cycle + # of an external model. This variable sets the number of hours earlier + # the external model started than when the FV3 forecast configured here + # should start. For example, the forecast should start from a 6 hour + # forecast of the GFS, then EXTRN_MDL_ICS_OFFSET_HRS=6. + + # FV3GFS_FILE_FMT_ICS: + # If using the FV3GFS model as the source of the ICs (i.e. if EXTRN_MDL_NAME_ICS + # is set to "FV3GFS"), this variable specifies the format of the model + # files to use when generating the ICs. + # + #----------------------------------------------------------------------- + # + EXTRN_MDL_NAME_ICS: "FV3GFS" + EXTRN_MDL_ICS_OFFSET_HRS: 0 + FV3GFS_FILE_FMT_ICS: "nemsio" + # + #----------------------------------------------------------------------- + # + # Base directories in which to search for external model files. + # + # EXTRN_MDL_SYSBASEDIR_ICS: + # Base directory on the local machine containing external model files for + # generating ICs on the native grid. The way the full path containing + # these files is constructed depends on the user-specified external model + # for ICs, i.e. EXTRN_MDL_NAME_ICS. + # + #----------------------------------------------------------------------- + # + EXTRN_MDL_SYSBASEDIR_ICS: '' + # + #----------------------------------------------------------------------- + # + # User-staged external model directories and files. Definitions: + # + # USE_USER_STAGED_EXTRN_FILES: + # Flag that determines whether or not the workflow will look for the + # external model files needed for generating LBCs in user-specified + # directories. + # + # EXTRN_MDL_SOURCE_BASEDIR_ICS: + # Directory in which to look for external model files for generating ICs. + # If USE_USER_STAGED_EXTRN_FILES is set to true, the workflow looks in + # this directory (specifically, in a subdirectory under this directory + # named "YYYYMMDDHH" consisting of the starting date and cycle hour of + # the forecast, where YYYY is the 4-digit year, MM the 2-digit month, DD + # the 2-digit day of the month, and HH the 2-digit hour of the day) for + # the external model files specified by the array EXTRN_MDL_FILES_ICS + # (these files will be used to generate the ICs on the native FV3-LAM + # grid). This variable is not used if USE_USER_STAGED_EXTRN_FILES is + # set to false. + # + # EXTRN_MDL_FILES_ICS: + # Array containing templates of the names of the files to search for in + # the directory specified by EXTRN_MDL_SOURCE_BASEDIR_ICS. This + # variable is not used if USE_USER_STAGED_EXTRN_FILES is set to false. + # A single template should be used for each model file type that is + # meant to be used. You may use any of the Python-style templates + # allowed in the ush/retrieve_data.py script. To see the full list of + # supported templates, run that script with a -h option. Here is an example of + # setting FV3GFS nemsio input files: + # EXTRN_MDL_FILES_ICS=( gfs.t{hh}z.atmf{fcst_hr:03d}.nemsio \ + # gfs.t{hh}z.sfcf{fcst_hr:03d}.nemsio ) + # Or for FV3GFS grib files: + # EXTRN_MDL_FILES_ICS=( gfs.t{hh}z.pgrb2.0p25.f{fcst_hr:03d} ) + # + # EXTRN_MDL_DATA_STORES: + # A list of data stores where the scripts should look for external model + # data. The list is in priority order. If disk information is provided + # via USE_USER_STAGED_EXTRN_FILES or a known location on the platform, + # the disk location will be highest priority. Options are disk, hpss, + # aws, and nomads. + # + #----------------------------------------------------------------------- + # + USE_USER_STAGED_EXTRN_FILES: false + EXTRN_MDL_SOURCE_BASEDIR_ICS: "" + EXTRN_MDL_FILES_ICS: "" + EXTRN_MDL_DATA_STORES: "" + # + #----------------------------------------------------------------------- + # + # Set NOMADS online data associated parameters. Definitions: + # + # NOMADS: + # Flag controlling whether or not using NOMADS online data. + # + # NOMADS_file_type: + # Flag controlling the format of data. + # + #----------------------------------------------------------------------- + # + NOMADS: false + NOMADS_file_type: "nemsio" + +#---------------------------- +# EXTRN LBCS config parameters +#----------------------------- +task_get_extrn_lbcs: + GET_EXTRN_LBCS_TN: "get_extrn_lbcs" + NNODES_GET_EXTRN_LBCS: 1 + PPN_GET_EXTRN_LBCS: 1 + WTIME_GET_EXTRN_LBCS: 00:45:00 + MAXTRIES_GET_EXTRN_LBCS: 1 + # + #----------------------------------------------------------------------- + # + # EXTRN_MDL_NAME_LBCS: + #`The name of the external model that will provide fields from which + # lateral boundary condition (LBC) files will be generated for input into + # the forecast model. + # + # LBC_SPEC_INTVL_HRS: + # The interval (in integer hours) with which LBC files will be generated. + # We will refer to this as the boundary update interval. Note that the + # model specified in EXTRN_MDL_NAME_LBCS must have data available at a + # frequency greater than or equal to that implied by LBC_SPEC_INTVL_HRS. + # For example, if LBC_SPEC_INTVL_HRS is set to 6, then the model must have + # data availble at least every 6 hours. It is up to the user to ensure + # that this is the case. + # + # EXTRN_MDL_LBCS_OFFSET_HRS: + # Users may wish to use lateral boundary conditions from a forecast that + # was started earlier than the initial time for the FV3 forecast + # configured here. This variable sets the number of hours earlier + # the external model started than when the FV3 forecast configured here + # should start. For example, the forecast should use lateral boundary + # conditions from the GFS started 6 hours earlier, then + # EXTRN_MDL_LBCS_OFFSET_HRS=6. + # Note: the default value is model-dependent and set in + # set_extrn_mdl_params.sh + # + # FV3GFS_FILE_FMT_LBCS: + # If using the FV3GFS model as the source of the LBCs (i.e. if + # EXTRN_MDL_NAME_LBCS is set to "FV3GFS"), this variable specifies the + # format of the model files to use when generating the LBCs. + # + #----------------------------------------------------------------------- + # + EXTRN_MDL_NAME_LBCS: "FV3GFS" + LBC_SPEC_INTVL_HRS: 6 + EXTRN_MDL_LBCS_OFFSET_HRS: "" + FV3GFS_FILE_FMT_LBCS: "nemsio" + #----------------------------------------------------------------------- + # + # EXTRN_MDL_SYSBASEDIR_LBCS: + # Same as EXTRN_MDL_SYSBASEDIR_ICS but for LBCs. + # + # Note that these must be defined as null strings here so that if they + # are specified by the user in the experiment configuration file, they + # remain set to those values, and if not, they get set to machine-dependent + # values. + # + #----------------------------------------------------------------------- + # + EXTRN_MDL_SYSBASEDIR_LBCS: '' + # + #----------------------------------------------------------------------- + # + # User-staged external model directories and files. Definitions: + # + # USE_USER_STAGED_EXTRN_FILES: + # Analogous to USE_USER_STAGED_EXTRN_FILES in ICS but for LBCs + # + # EXTRN_MDL_SOURCE_BASEDIR_LBCS: + # Analogous to EXTRN_MDL_SOURCE_BASEDIR_ICS but for LBCs instead of ICs. + # + # EXTRN_MDL_FILES_LBCS: + # Analogous to EXTRN_MDL_FILES_ICS but for LBCs instead of ICs. + # + # EXTRN_MDL_DATA_STORES: + # Analogous to EXTRN_MDL_DATA_STORES in ICS but for LBCs + # + #----------------------------------------------------------------------- + # + USE_USER_STAGED_EXTRN_FILES: false + EXTRN_MDL_SOURCE_BASEDIR_LBCS: "" + EXTRN_MDL_FILES_LBCS: "" + EXTRN_MDL_DATA_STORES: "" + # + #----------------------------------------------------------------------- + # Analogus to NOMADS for ICSs + #----------------------------------------------------------------------- + # + NOMADS: false + NOMADS_file_type: "nemsio" + + +#---------------------------- +# MAKE ICS config parameters +#----------------------------- +task_make_ics: + MAKE_ICS_TN: "make_ics" + NNODES_MAKE_ICS: 4 + PPN_MAKE_ICS: 12 + WTIME_MAKE_ICS: 00:30:00 + MAXTRIES_MAKE_ICS: 1 + KMP_AFFINITY_MAKE_ICS: "scatter" + OMP_NUM_THREADS_MAKE_ICS: 1 + OMP_STACKSIZE_MAKE_ICS: "1024m" + # + #----------------------------------------------------------------------- + # + # USE_FVCOM: + # Flag set to update surface conditions in FV3-LAM with fields generated + # from the Finite Volume Community Ocean Model (FVCOM). This will + # replace lake/sea surface temperature, ice surface temperature, and ice + # placement. FVCOM data must already be interpolated to the desired + # FV3-LAM grid. This flag will be used in make_ics to modify sfc_data.nc + # after chgres_cube is run by running the routine process_FVCOM.exe + # + # FVCOM_WCSTART: + # Define if this is a "warm" start or a "cold" start. Setting this to + # "warm" will read in sfc_data.nc generated in a RESTART directory. + # Setting this to "cold" will read in the sfc_data.nc generated from + # chgres_cube in the make_ics portion of the workflow. + # + # FVCOM_DIR: + # User defined directory where FVCOM data already interpolated to FV3-LAM + # grid is located. File name in this path should be "fvcom.nc" to allow + # + # FVCOM_FILE: + # Name of file located in FVCOM_DIR that has FVCOM data interpolated to + # FV3-LAM grid. This file will be copied later to a new location and name + # changed to fvcom.nc + # + #------------------------------------------------------------------------ + # + USE_FVCOM: false + FVCOM_WCSTART: "cold" + FVCOM_DIR: "/user/defined/dir/to/fvcom/data" + FVCOM_FILE: "fvcom.nc" + +#---------------------------- +# MAKE LBCS config parameters +#----------------------------- +task_make_lbcs: + MAKE_LBCS_TN: "make_lbcs" + NNODES_MAKE_LBCS: 4 + PPN_MAKE_LBCS: 12 + WTIME_MAKE_LBCS: 00:30:00 + MAXTRIES_MAKE_LBCS: 1 + KMP_AFFINITY_MAKE_LBCS: "scatter" + OMP_NUM_THREADS_MAKE_LBCS: 1 + OMP_STACKSIZE_MAKE_LBCS: "1024m" + +#---------------------------- +# FORECAST config parameters +#----------------------------- +task_run_fcst: + RUN_FCST_TN: "run_fcst" + NNODES_RUN_FCST: "" # This is calculated in the workflow generation scripts, so no need to set here. + PPN_RUN_FCST: "" # will be calculated from NCORES_PER_NODE and OMP_NUM_THREADS in setup.sh + WTIME_RUN_FCST: 04:30:00 + MAXTRIES_RUN_FCST: 1 + # + #----------------------------------------------------------------------- + # + # KMP_AFFINITY_*: + # From Intel: "The Intel® runtime library has the ability to bind OpenMP + # threads to physical processing units. The interface is controlled using + # the KMP_AFFINITY environment variable. Depending on the system (machine) + # topology, application, and operating system, thread affinity can have a + # dramatic effect on the application speed. + # + # Thread affinity restricts execution of certain threads (virtual execution + # units) to a subset of the physical processing units in a multiprocessor + # computer. Depending upon the topology of the machine, thread affinity can + # have a dramatic effect on the execution speed of a program." + # + # For more information, see the following link: + # https://software.intel.com/content/www/us/en/develop/documentation/cpp- + # compiler-developer-guide-and-reference/top/optimization-and-programming- + # guide/openmp-support/openmp-library-support/thread-affinity-interface- + # linux-and-windows.html + # + # OMP_NUM_THREADS_*: + # The number of OpenMP threads to use for parallel regions. + # + # OMP_STACKSIZE_*: + # Controls the size of the stack for threads created by the OpenMP + # implementation. + # + # Note that settings for the make_grid and make_orog tasks are not + # included below as they do not use parallelized code. + # + #----------------------------------------------------------------------- + # + KMP_AFFINITY_RUN_FCST: "scatter" + OMP_NUM_THREADS_RUN_FCST: 2 # atmos_nthreads in model_configure + OMP_STACKSIZE_RUN_FCST: "1024m" + # + #----------------------------------------------------------------------- + # + # Set model_configure parameters. Definitions: + # + # DT_ATMOS: + # The main forecast model integraton time step. As described in the + # forecast model documentation, "It corresponds to the frequency with + # which the top level routine in the dynamics is called as well as the + # frequency with which the physics is called." + # + # CPL: parameter for coupling + # (set automatically based on FCST_MODEL in ush/setup.sh) + # (ufs-weather-model:FALSE, fv3gfs_aqm:TRUE) + # + # RESTART_INTERVAL: + # frequency of the output restart files (unit:hour). + # Default=0: restart files are produced at the end of a forecast run + # For example, RESTART_INTERVAL: 1: restart files are produced every hour + # with the prefix "YYYYMMDD.HHmmSS." in the RESTART directory + # + # WRITE_DOPOST: + # Flag that determines whether or not to use the inline post feature + # [i.e. calling the Unified Post Processor (UPP) from within the weather + # model]. If this is set to true, the RUN_POST_TN task is deactivated + # (i.e. RUN_TASK_RUN_POST is set to false) to avoid unnecessary + # computations. + # + #----------------------------------------------------------------------- + # + DT_ATMOS: "" + RESTART_INTERVAL: 0 + WRITE_DOPOST: false + + # + #----------------------------------------------------------------------- + # + # Set computational parameters for the forecast. Definitions: + # + # LAYOUT_X, LAYOUT_Y: + # The number of MPI tasks (processes) to use in the two horizontal + # directions (x and y) of the regional grid when running the forecast + # model. + # + # BLOCKSIZE: + # The amount of data that is passed into the cache at a time. + # + # Here, we set these parameters to null strings. This is so that, for + # any one of these parameters: + # + # 1) If the experiment is using a predefined grid, then if the user + # sets the parameter in the user-specified experiment configuration + # file (EXPT_CONFIG_FN), that value will be used in the forecast(s). + # Otherwise, the default value of the parameter for that predefined + # grid will be used. + # + # 2) If the experiment is not using a predefined grid (i.e. it is using + # a custom grid whose parameters are specified in the experiment + # configuration file), then the user must specify a value for the + # parameter in that configuration file. Otherwise, the parameter + # will remain set to a null string, and the experiment generation + # will fail because the generation scripts check to ensure that all + # the parameters defined in this section are set to non-empty strings + # before creating the experiment directory. + # + #----------------------------------------------------------------------- + # + LAYOUT_X: "" + LAYOUT_Y: "" + BLOCKSIZE: "" + # + #----------------------------------------------------------------------- + # + # Set write-component (quilting) parameters. Definitions: + # + # QUILTING: + # Flag that determines whether or not to use the write component for + # writing output files to disk. + # + # WRTCMP_write_groups: + # The number of write groups (i.e. groups of MPI tasks) to use in the + # write component. + # + # WRTCMP_write_tasks_per_group: + # The number of MPI tasks to allocate for each write group. + # + # PRINT_ESMF: + # Flag for whether or not to output extra (debugging) information from + # ESMF routines. Must be true or false. Note that the write + # component uses ESMF library routines to interpolate from the native + # forecast model grid to the user-specified output grid (which is defined + # in the model configuration file MODEL_CONFIG_FN in the forecast's run + # directory). + # + #----------------------------------------------------------------------- + # + QUILTING: true + PRINT_ESMF: false + + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 20 + + WRTCMP_output_grid: "''" + WRTCMP_cen_lon: "" + WRTCMP_cen_lat: "" + WRTCMP_lon_lwr_left: "" + WRTCMP_lat_lwr_left: "" + # + # The following are used only for the case of WRTCMP_output_grid set to + # "'rotated_latlon'". + # + WRTCMP_lon_upr_rght: "" + WRTCMP_lat_upr_rght: "" + WRTCMP_dlon: "" + WRTCMP_dlat: "" + # + # The following are used only for the case of WRTCMP_output_grid set to + # "'lambert_conformal'". + # + WRTCMP_stdlat1: "" + WRTCMP_stdlat2: "" + WRTCMP_nx: "" + WRTCMP_ny: "" + WRTCMP_dx: "" + WRTCMP_dy: "" + # + #----------------------------------------------------------------------- + # + # Set PREDEF_GRID_NAME. This parameter specifies a predefined regional + # grid, as follows: + # + # * If PREDEF_GRID_NAME is set to a valid predefined grid name, the grid + # generation method GRID_GEN_METHOD, the (native) grid parameters, and + # the write-component grid parameters are set to predefined values for + # the specified grid, overwriting any settings of these parameters in + # the user-specified experiment configuration file. In addition, if + # the time step DT_ATMOS and the computational parameters LAYOUT_X, + # LAYOUT_Y, and BLOCKSIZE are not specified in that configuration file, + # they are also set to predefined values for the specified grid. + # + # * If PREDEF_GRID_NAME is set to an empty string, it implies the user + # is providing the native grid parameters in the user-specified + # experiment configuration file (EXPT_CONFIG_FN). In this case, the + # grid generation method GRID_GEN_METHOD, the native grid parameters, + # and the write-component grid parameters as well as the time step + # forecast model's main time step DT_ATMOS and the computational + # parameters LAYOUT_X, LAYOUT_Y, and BLOCKSIZE must be set in that + # configuration file; otherwise, the values of all of these parameters + # in this default experiment configuration file will be used. + # + # Setting PREDEF_GRID_NAME provides a convenient method of specifying a + # commonly used set of grid-dependent parameters. The predefined grid + # parameters are specified in the script + # + # $HOMErrfs/ush/set_predef_grid_params.sh + # + #----------------------------------------------------------------------- + # + PREDEF_GRID_NAME: "" + # + #----------------------------------------------------------------------- + # + # Flag that determines whether MERRA2 aerosol climatology data and + # lookup tables for optics properties are obtained + # + #----------------------------------------------------------------------- + # + USE_MERRA_CLIMO: false + # + #----------------------------------------------------------------------- + # + # Set the array parameter containing the names of all the fields that the + # MAKE_SFC_CLIMO_TN task generates on the native FV3-LAM grid. + # + #----------------------------------------------------------------------- + # + SFC_CLIMO_FIELDS: [ + "facsf", + "maximum_snow_albedo", + "slope_type", + "snowfree_albedo", + "soil_type", + "substrate_temperature", + "vegetation_greenness", + "vegetation_type" + ] + # + #----------------------------------------------------------------------- + # + # Set parameters associated with the fixed (i.e. static) files. Definitions: + # + # FIXgsm: + # System directory in which the majority of fixed (i.e. time-independent) + # files that are needed to run the FV3-LAM model are located + # + # FIXaer: + # System directory where MERRA2 aerosol climatology files are located + # + # FIXlut: + # System directory where the lookup tables for optics properties are located + # + # TOPO_DIR: + # The location on disk of the static input files used by the make_orog + # task (orog.x and shave.x). Can be the same as FIXgsm. + # + # SFC_CLIMO_INPUT_DIR: + # The location on disk of the static surface climatology input fields, used by + # sfc_climo_gen. These files are only used if RUN_TASK_MAKE_SFC_CLIMO=TRUE + # + # FNGLAC, ..., FNMSKH: + # Names of (some of the) global data files that are assumed to exist in + # a system directory specified (this directory is machine-dependent; + # the experiment generation scripts will set it and store it in the + # variable FIXgsm). These file names also appear directly in the forecast + # model's input namelist file. + # + # FIXgsm_FILES_TO_COPY_TO_FIXam: + # If not running in NCO mode, this array contains the names of the files + # to copy from the FIXgsm system directory to the FIXam directory under + # the experiment directory. Note that the last element has a dummy value. + # This last element will get reset by the workflow generation scripts to + # the name of the ozone production/loss file to copy from FIXgsm. The + # name of this file depends on the ozone parameterization being used, + # and that in turn depends on the CCPP physics suite specified for the + # experiment. Thus, the CCPP physics suite XML must first be read in to + # determine the ozone parameterizaton and then the name of the ozone + # production/loss file. These steps are carried out elsewhere (in one + # of the workflow generation scripts/functions). + # + # FV3_NML_VARNAME_TO_FIXam_FILES_MAPPING: + # This array is used to set some of the namelist variables in the forecast + # model's namelist file that represent the relative or absolute paths of + # various fixed files (the first column of the array, where columns are + # delineated by the pipe symbol "|") to the full paths to these files in + # the FIXam directory derived from the corresponding workflow variables + # containing file names (the second column of the array). + # + # FV3_NML_VARNAME_TO_SFC_CLIMO_FIELD_MAPPING: + # This array is used to set some of the namelist variables in the forecast + # model's namelist file that represent the relative or absolute paths of + # various fixed files (the first column of the array, where columns are + # delineated by the pipe symbol "|") to the full paths to surface climatology + # files (on the native FV3-LAM grid) in the FIXLAM directory derived from + # the corresponding surface climatology fields (the second column of the + # array). + # + # CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING: + # This array specifies the mapping to use between the symlinks that need + # to be created in each cycle directory (these are the "files" that FV3 + # looks for) and their targets in the FIXam directory. The first column + # of the array specifies the symlink to be created, and the second column + # specifies its target file in FIXam (where columns are delineated by the + # pipe symbol "|"). + # + #----------------------------------------------------------------------- + # + # Because the default values are dependent on the platform, we set these + # to a null string which will then be overwritten in setup.sh unless the + # user has specified a different value in config.sh + FIXgsm: "" + FIXaer: "" + FIXlut: "" + TOPO_DIR: "" + SFC_CLIMO_INPUT_DIR: "" + + FNGLAC: &FNGLAC "global_glacier.2x2.grb" + FNMXIC: &FNMXIC "global_maxice.2x2.grb" + FNTSFC: &FNTSFC "RTGSST.1982.2012.monthly.clim.grb" + FNSNOC: &FNSNOC "global_snoclim.1.875.grb" + FNZORC: &FNZORC "igbp" + FNAISC: &FNAISC "CFSR.SEAICE.1982.2012.monthly.clim.grb" + FNSMCC: &FNSMCC "global_soilmgldas.t126.384.190.grb" + FNMSKH: &FNMSKH "seaice_newland.grb" + + FIXgsm_FILES_TO_COPY_TO_FIXam: [ + *FNGLAC, + *FNMXIC, + *FNTSFC, + *FNSNOC, + *FNAISC, + *FNSMCC, + *FNMSKH, + "global_climaeropac_global.txt", + "fix_co2_proj/global_co2historicaldata_2010.txt", + "fix_co2_proj/global_co2historicaldata_2011.txt", + "fix_co2_proj/global_co2historicaldata_2012.txt", + "fix_co2_proj/global_co2historicaldata_2013.txt", + "fix_co2_proj/global_co2historicaldata_2014.txt", + "fix_co2_proj/global_co2historicaldata_2015.txt", + "fix_co2_proj/global_co2historicaldata_2016.txt", + "fix_co2_proj/global_co2historicaldata_2017.txt", + "fix_co2_proj/global_co2historicaldata_2018.txt", + "fix_co2_proj/global_co2historicaldata_2019.txt", + "fix_co2_proj/global_co2historicaldata_2020.txt", + "fix_co2_proj/global_co2historicaldata_2021.txt", + "global_co2historicaldata_glob.txt", + "co2monthlycyc.txt", + "global_h2o_pltc.f77", + "global_hyblev.l65.txt", + "global_zorclim.1x1.grb", + "global_sfc_emissivity_idx.txt", + "global_tg3clim.2.6x1.5.grb", + "global_solarconstant_noaa_an.txt", + "global_albedo4.1x1.grb", + "geo_em.d01.lat-lon.2.5m.HGT_M.nc", + "HGT.Beljaars_filtered.lat-lon.30s_res.nc", + "replace_with_FIXgsm_ozone_prodloss_filename" + ] + + # + # It is possible to remove this as a workflow variable and make it only + # a local one since it is used in only one script. + # + FV3_NML_VARNAME_TO_FIXam_FILES_MAPPING: [ + !join_str ["FNGLAC | ",*FNGLAC], + !join_str ["FNMXIC | ",*FNMXIC], + !join_str ["FNTSFC | ",*FNTSFC], + !join_str ["FNSNOC | ",*FNSNOC], + !join_str ["FNAISC | ",*FNAISC], + !join_str ["FNSMCC | ",*FNSMCC], + !join_str ["FNMSKH | ",*FNMSKH] + ] + #"FNZORC | $FNZORC", + + FV3_NML_VARNAME_TO_SFC_CLIMO_FIELD_MAPPING: [ + "FNALBC | snowfree_albedo", + "FNALBC2 | facsf", + "FNTG3C | substrate_temperature", + "FNVEGC | vegetation_greenness", + "FNVETC | vegetation_type", + "FNSOTC | soil_type", + "FNVMNC | vegetation_greenness", + "FNVMXC | vegetation_greenness", + "FNSLPC | slope_type", + "FNABSC | maximum_snow_albedo" + ] + + CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING: [ + "aerosol.dat | global_climaeropac_global.txt", + "co2historicaldata_2010.txt | fix_co2_proj/global_co2historicaldata_2010.txt", + "co2historicaldata_2011.txt | fix_co2_proj/global_co2historicaldata_2011.txt", + "co2historicaldata_2012.txt | fix_co2_proj/global_co2historicaldata_2012.txt", + "co2historicaldata_2013.txt | fix_co2_proj/global_co2historicaldata_2013.txt", + "co2historicaldata_2014.txt | fix_co2_proj/global_co2historicaldata_2014.txt", + "co2historicaldata_2015.txt | fix_co2_proj/global_co2historicaldata_2015.txt", + "co2historicaldata_2016.txt | fix_co2_proj/global_co2historicaldata_2016.txt", + "co2historicaldata_2017.txt | fix_co2_proj/global_co2historicaldata_2017.txt", + "co2historicaldata_2018.txt | fix_co2_proj/global_co2historicaldata_2018.txt", + "co2historicaldata_2019.txt | fix_co2_proj/global_co2historicaldata_2019.txt", + "co2historicaldata_2020.txt | fix_co2_proj/global_co2historicaldata_2020.txt", + "co2historicaldata_2021.txt | fix_co2_proj/global_co2historicaldata_2021.txt", + "co2historicaldata_glob.txt | global_co2historicaldata_glob.txt", + "co2monthlycyc.txt | co2monthlycyc.txt", + "global_h2oprdlos.f77 | global_h2o_pltc.f77", + "global_albedo4.1x1.grb | global_albedo4.1x1.grb", + "global_zorclim.1x1.grb | global_zorclim.1x1.grb", + "global_tg3clim.2.6x1.5.grb | global_tg3clim.2.6x1.5.grb", + "sfc_emissivity_idx.txt | global_sfc_emissivity_idx.txt", + "solarconstant_noaa_an.txt | global_solarconstant_noaa_an.txt", + "global_o3prdlos.f77 | " + ] + +#---------------------------- +# POST config parameters +#----------------------------- +task_run_post: + RUN_POST_TN: "run_post" + NNODES_RUN_POST: 2 + PPN_RUN_POST: 24 + WTIME_RUN_POST: 00:15:00 + MAXTRIES_RUN_POST: 2 + KMP_AFFINITY_RUN_POST: "scatter" + OMP_NUM_THREADS_RUN_POST: 1 + OMP_STACKSIZE_RUN_POST: "1024m" + # + #----------------------------------------------------------------------- + # + # Set parameters associated with subhourly forecast model output and + # post-processing. + # + # SUB_HOURLY_POST: + # Flag that indicates whether the forecast model will generate output + # files on a sub-hourly time interval (e.g. 10 minutes, 15 minutes, etc). + # This will also cause the post-processor to process these sub-hourly + # files. If ths is set to true, then DT_SUBHOURLY_POST_MNTS should be + # set to a value between "00" and "59". + # + # DT_SUB_HOURLY_POST_MNTS: + # Time interval in minutes between the forecast model output files. If + # SUB_HOURLY_POST is set to true, this needs to be set to a two-digit + # integer between "01" and "59". This is not used if SUB_HOURLY_POST is + # not set to true. Note that if SUB_HOURLY_POST is set to true but + # DT_SUB_HOURLY_POST_MNTS is set to "00", SUB_HOURLY_POST will get reset + # to false in the experiment generation scripts (there will be an + # informational message in the log file to emphasize this). + # + #----------------------------------------------------------------------- + # + SUB_HOURLY_POST: false + DT_SUBHOURLY_POST_MNTS: 0 + # + #----------------------------------------------------------------------- + # + # Set parameters for customizing the post-processor (UPP). Definitions: + # + # USE_CUSTOM_POST_CONFIG_FILE: + # Flag that determines whether a user-provided custom configuration file + # should be used for post-processing the model data. If this is set to + # true, then the workflow will use the custom post-processing (UPP) + # configuration file specified in CUSTOM_POST_CONFIG_FP. Otherwise, a + # default configuration file provided in the UPP repository will be + # used. + # + # CUSTOM_POST_CONFIG_FP: + # The full path to the custom post flat file, including filename, to be + # used for post-processing. This is only used if CUSTOM_POST_CONFIG_FILE + # is set to true. + # + # POST_OUTPUT_DOMAIN_NAME: + # Domain name (in lowercase) used in constructing the names of the output + # files generated by UPP [which is called either by running the RUN_POST_TN + # task or by activating the inline post feature (WRITE_DOPOST set to true)]. + # The post output files are named as follows: + # + # $NET.tHHz.[var_name].f###.${POST_OUTPUT_DOMAIN_NAME}.grib2 + # + # If using a custom grid, POST_OUTPUT_DOMAIN_NAME must be specified by + # the user. If using a predefined grid, POST_OUTPUT_DOMAIN_NAME defaults + # to PREDEF_GRID_NAME. Note that this variable is first changed to lower + # case before being used to construct the file names. + # + #----------------------------------------------------------------------- + # + USE_CUSTOM_POST_CONFIG_FILE: false + CUSTOM_POST_CONFIG_FP: "" + POST_OUTPUT_DOMAIN_NAME: "" + +#---------------------------- +# GET OBS CCPA config parameters +#----------------------------- +task_get_obs_ccpa: + GET_OBS_CCPA_TN: "get_obs_ccpa" + NNODES_GET_OBS_CCPA: 1 + PPN_GET_OBS_CCPA: 1 + WTIME_GET_OBS_CCPA: 00:45:00 + MAXTRIES_GET_OBS_CCPA: 1 + +#---------------------------- +# GET OBS MRMS config parameters +#----------------------------- +task_get_obs_mrms: + GET_OBS_MRMS_TN: "get_obs_mrms" + NNODES_GET_OBS_MRMS: 1 + PPN_GET_OBS_MRMS: 1 + WTIME_GET_OBS_MRMS: 00:45:00 + MAXTRIES_GET_OBS_MRMS: 1 + +#---------------------------- +# GET OBS NDAS config parameters +#----------------------------- +task_get_obs_ndas: + GET_OBS_NDAS_TN: "get_obs_ndas" + NNODES_GET_OBS_NDAS: 1 + PPN_GET_OBS_NDAS: 1 + WTIME_GET_OBS_NDAS: 02:00:00 + MAXTRIES_GET_OBS_NDAS: 1 + +#---------------------------- +# VX_GRIDSTAT config parameters +#----------------------------- +task_run_vx_gridstat: + VX_GRIDSTAT_TN: "run_gridstatvx" + NNODES_VX_GRIDSTAT: 1 + PPN_VX_GRIDSTAT: 1 + WTIME_VX_GRIDSTAT: 02:00:00 + MAXTRIES_VX_GRIDSTAT: 1 + +#---------------------------- +# VX_GRIDSTAT_REFC config parameters +#----------------------------- +task_run_vx_gridstat_refc: + VX_GRIDSTAT_REFC_TN: "run_gridstatvx_refc" + NNODES_VX_GRIDSTAT: 1 + PPN_VX_GRIDSTAT: 1 + WTIME_VX_GRIDSTAT: 02:00:00 + MAXTRIES_VX_GRIDSTAT_REFC: 1 + +#---------------------------- +# VX_GRIDSTAT_RETOP config parameters +#----------------------------- +task_run_vx_gridstat_retop: + VX_GRIDSTAT_RETOP_TN: "run_gridstatvx_retop" + NNODES_VX_GRIDSTAT: 1 + PPN_VX_GRIDSTAT: 1 + WTIME_VX_GRIDSTAT: 02:00:00 + MAXTRIES_VX_GRIDSTAT_RETOP: 1 + +#---------------------------- +# VX_GRIDSTAT_03h config parameters +#----------------------------- +task_run_vx_gridstat_03h: + VX_GRIDSTAT_03h_TN: "run_gridstatvx_03h" + NNODES_VX_GRIDSTAT: 1 + PPN_VX_GRIDSTAT: 1 + WTIME_VX_GRIDSTAT: 02:00:00 + MAXTRIES_VX_GRIDSTAT_03h: 1 + +#---------------------------- +# VX_GRIDSTAT_06h config parameters +#----------------------------- +task_run_vx_gridstat_06h: + VX_GRIDSTAT_06h_TN: "run_gridstatvx_06h" + NNODES_VX_GRIDSTAT: 1 + PPN_VX_GRIDSTAT: 1 + WTIME_VX_GRIDSTAT: 02:00:00 + MAXTRIES_VX_GRIDSTAT_06h: 1 + +#---------------------------- +# VX_GRIDSTAT_24h config parameters +#----------------------------- +task_run_vx_gridstat_24h: + VX_GRIDSTAT_24h_TN: "run_gridstatvx_24h" + NNODES_VX_GRIDSTAT: 1 + PPN_VX_GRIDSTAT: 1 + WTIME_VX_GRIDSTAT: 02:00:00 + MAXTRIES_VX_GRIDSTAT_24h: 1 + +#---------------------------- +# VX_POINTSTAT config parameters +#----------------------------- +task_run_vx_pointstat: + VX_POINTSTAT_TN: "run_pointstatvx" + NNODES_VX_POINTSTAT: 1 + PPN_VX_POINTSTAT: 1 + WTIME_VX_POINTSTAT: 01:00:00 + MAXTRIES_VX_POINTSTAT: 1 + +#---------------------------- +# VX_ENSGRID config parameters +#----------------------------- +task_run_vx_ensgrid: + VX_ENSGRID_03h_TN: "run_ensgridvx_03h" + MAXTRIES_VX_ENSGRID_03h: 1 + VX_ENSGRID_06h_TN: "run_ensgridvx_06h" + MAXTRIES_VX_ENSGRID_06h: 1 + VX_ENSGRID_24h_TN: "run_ensgridvx_24h" + MAXTRIES_VX_ENSGRID_24h: 1 + VX_ENSGRID_RETOP_TN: "run_ensgridvx_retop" + MAXTRIES_VX_ENSGRID_RETOP: 1 + VX_ENSGRID_PROB_RETOP_TN: "run_ensgridvx_prob_retop" + MAXTRIES_VX_ENSGRID_PROB_RETOP: 1 + NNODES_VX_ENSGRID: 1 + PPN_VX_ENSGRID: 1 + WTIME_VX_ENSGRID: 01:00:00 + MAXTRIES_VX_ENSGRID: 1 + + +#---------------------------- +# VX_ENSGRID_REFC config parameters +#----------------------------- +task_run_vx_ensgrid_refc: + VX_ENSGRID_REFC_TN: "run_ensgridvx_refc" + NNODES_VX_ENSGRID: 1 + PPN_VX_ENSGRID: 1 + WTIME_VX_ENSGRID: 01:00:00 + MAXTRIES_VX_ENSGRID_REFC: 1 + +#---------------------------- +# VX_ENSGRID_MEAN config parameters +#----------------------------- +task_run_vx_ensgrid_mean: + VX_ENSGRID_MEAN_TN: "run_ensgridvx_mean" + NNODES_VX_ENSGRID_MEAN: 1 + PPN_VX_ENSGRID_MEAN: 1 + WTIME_VX_ENSGRID_MEAN: 01:00:00 + MAXTRIES_VX_ENSGRID_MEAN: 1 + +#---------------------------- +# VX_ENSGRID_MEAN_03h config parameters +#----------------------------- +task_run_vx_ensgrid_mean_03h: + VX_ENSGRID_MEAN_03h_TN: "run_ensgridvx_mean_03h" + NNODES_VX_ENSGRID_MEAN: 1 + PPN_VX_ENSGRID_MEAN: 1 + WTIME_VX_ENSGRID_MEAN: 01:00:00 + MAXTRIES_VX_ENSGRID_MEAN_03h: 1 + +#---------------------------- +# VX_ENSGRID_MEAN_06h config parameters +#----------------------------- +task_run_vx_ensgrid_mean_06h: + VX_ENSGRID_MEAN_06h_TN: "run_ensgridvx_mean_06h" + NNODES_VX_ENSGRID_MEAN: 1 + PPN_VX_ENSGRID_MEAN: 1 + WTIME_VX_ENSGRID_MEAN: 01:00:00 + MAXTRIES_VX_ENSGRID_MEAN_06h: 1 + +#---------------------------- +# VX_ENSGRID_MEAN_24h config parameters +#----------------------------- +task_run_vx_ensgrid_mean_24h: + VX_ENSGRID_MEAN_24h_TN: "run_ensgridvx_mean_24h" + NNODES_VX_ENSGRID_MEAN: 1 + PPN_VX_ENSGRID_MEAN: 1 + WTIME_VX_ENSGRID_MEAN: 01:00:00 + MAXTRIES_VX_ENSGRID_MEAN_24h: 1 + +#---------------------------- +# VX_ENSGRID_PROB config parameters +#----------------------------- +task_run_vx_ensgrid_prob: + VX_ENSGRID_PROB_TN: "run_ensgridvx_prob" + NNODES_VX_ENSGRID_PROB: 1 + PPN_VX_ENSGRID_PROB: 1 + WTIME_VX_ENSGRID_PROB: 01:00:00 + MAXTRIES_VX_ENSGRID_PROB: 1 + +#---------------------------- +# VX_ENSGRID_PROB_03h config parameters +#----------------------------- +task_run_vx_ensgrid_prob_03h: + VX_ENSGRID_PROB_03h_TN: "run_ensgridvx_prob_03h" + NNODES_VX_ENSGRID_PROB: 1 + PPN_VX_ENSGRID_PROB: 1 + WTIME_VX_ENSGRID_PROB: 01:00:00 + MAXTRIES_VX_ENSGRID_PROB_03h: 1 + +#---------------------------- +# VX_ENSGRID_PROB_06h config parameters +#----------------------------- +task_run_vx_ensgrid_prob_06h: + VX_ENSGRID_PROB_06h_TN: "run_ensgridvx_prob_06h" + NNODES_VX_ENSGRID_PROB: 1 + PPN_VX_ENSGRID_PROB: 1 + WTIME_VX_ENSGRID_PROB: 01:00:00 + MAXTRIES_VX_ENSGRID_PROB_06h: 1 + +#---------------------------- +# VX_ENSGRID_PROB_24h config parameters +#----------------------------- +task_run_vx_ensgrid_prob_24h: + VX_ENSGRID_PROB_24h_TN: "run_ensgridvx_prob_24h" + NNODES_VX_ENSGRID_PROB: 1 + PPN_VX_ENSGRID_PROB: 1 + WTIME_VX_ENSGRID_PROB: 01:00:00 + MAXTRIES_VX_ENSGRID_PROB_24h: 1 + +#---------------------------- +# VX_ENSPOINT config parameters +#----------------------------- +task_run_vx_enspoint: + VX_ENSPOINT_TN: "run_enspointvx" + NNODES_VX_ENSPOINT: 1 + PPN_VX_ENSPOINT: 1 + WTIME_VX_ENSPOINT: 01:00:00 + MAXTRIES_VX_ENSPOINT: 1 + +#---------------------------- +# VX_ENSPOINT_MEAN config parameters +#----------------------------- +task_run_vx_enspoint_mean: + VX_ENSPOINT_MEAN_TN: "run_enspointvx_mean" + NNODES_VX_ENSPOINT_MEAN: 1 + PPN_VX_ENSPOINT_MEAN: 1 + WTIME_VX_ENSPOINT_MEAN: 01:00:00 + MAXTRIES_VX_ENSPOINT_MEAN: 1 + +#---------------------------- +# VX_ENSPOINT_PROB config parameters +#----------------------------- +task_run_vx_enspoint_prob: + VX_ENSPOINT_PROB_TN: "run_enspointvx_prob" + NNODES_VX_ENSPOINT_PROB: 1 + PPN_VX_ENSPOINT_PROB: 1 + WTIME_VX_ENSPOINT_PROB: 01:00:00 + MAXTRIES_VX_ENSPOINT_PROB: 1 + + +#---------------------------- +# global config parameters +#----------------------------- +global: + # + #----------------------------------------------------------------------- + # + # Set parameters associated with outputting satellite fields in the UPP + # grib2 files using the Community Radiative Transfer Model (CRTM). + # + # USE_CRTM: + # Flag that defines whether external CRTM coefficient files have been + # staged by the user in order to output synthetic statellite products + # available within the UPP. If this is set to true, then the workflow + # will check for these files in the directory CRTM_DIR. Otherwise, it is + # assumed that no satellite fields are being requested in the UPP + # configuration. + # + # CRTM_DIR: + # This is the path to the top CRTM fix file directory. This is only used + # if USE_CRTM is set to true. + # + #----------------------------------------------------------------------- + # + USE_CRTM: false + CRTM_DIR: "" + # + #----------------------------------------------------------------------- + # + # Set parameters associated with running ensembles. Definitions: + # + # DO_ENSEMBLE: + # Flag that determines whether to run a set of ensemble forecasts (for + # each set of specified cycles). If this is set to true, NUM_ENS_MEMBERS + # forecasts are run for each cycle, each with a different set of stochastic + # seed values. Otherwise, a single forecast is run for each cycle. + # + # NUM_ENS_MEMBERS: + # The number of ensemble members to run if DO_ENSEMBLE is set to true. + # This variable also controls the naming of the ensemble member directories. + # For example, if this is set to "8", the member directories will be named + # mem1, mem2, ..., mem8. If it is set to "08" (note the leading zero), + # the member directories will be named mem01, mem02, ..., mem08. Note, + # however, that after reading in the number of characters in this string + # (in order to determine how many leading zeros, if any, should be placed + # in the names of the member directories), the workflow generation scripts + # strip away those leading zeros. Thus, in the variable definitions file + # (GLOBAL_VAR_DEFNS_FN), this variable appear with its leading zeros + # stripped. This variable is not used if DO_ENSEMBLE is not set to true. + # + #----------------------------------------------------------------------- + # + DO_ENSEMBLE: false + NUM_ENS_MEMBERS: 1 + # + #----------------------------------------------------------------------- + # + # Set default ad-hoc stochastic physics options. + # For detailed documentation of these parameters, see: + # https://stochastic-physics.readthedocs.io/en/ufs_public_release/namelist_options.html + # + #----------------------------------------------------------------------- + # + DO_SHUM: false + DO_SPPT: false + DO_SKEB: false + ISEED_SPPT: 1 + ISEED_SHUM: 2 + ISEED_SKEB: 3 + NEW_LSCALE: true + SHUM_MAG: 0.006 #Variable "shum" in input.nml + SHUM_LSCALE: 150000 + SHUM_TSCALE: 21600 #Variable "shum_tau" in input.nml + SHUM_INT: 3600 #Variable "shumint" in input.nml + SPPT_MAG: 0.7 #Variable "sppt" in input.nml + SPPT_LOGIT: true + SPPT_LSCALE: 150000 + SPPT_TSCALE: 21600 #Variable "sppt_tau" in input.nml + SPPT_INT: 3600 #Variable "spptint" in input.nml + SPPT_SFCLIMIT: true + SKEB_MAG: 0.5 #Variable "skeb" in input.nml + SKEB_LSCALE: 150000 + SKEB_TSCALE: 21600 #Variable "skeb_tau" in input.nml + SKEB_INT: 3600 #Variable "skebint" in input.nml + SKEBNORM: 1 + SKEB_VDOF: 10 + USE_ZMTNBLCK: false + # + #----------------------------------------------------------------------- + # + # Set default SPP stochastic physics options. Each SPP option is an array, + # applicable (in order) to the scheme/parameter listed in SPP_VAR_LIST. + # Enter each value of the array in config.sh as shown below without commas + # or single quotes (e.g., SPP_VAR_LIST=( "pbl" "sfc" "mp" "rad" "gwd" ). + # Both commas and single quotes will be added by Jinja when creating the + # namelist. + # + # Note that SPP is currently only available for specific physics schemes + # used in the RAP/HRRR physics suite. Users need to be aware of which SDF + # is chosen when turning this option on. + # + # Patterns evolve and are applied at each time step. + # + #----------------------------------------------------------------------- + # + DO_SPP: false + SPP_VAR_LIST: [ "pbl", "sfc", "mp", "rad", "gwd" ] + SPP_MAG_LIST: [ 0.2, 0.2, 0.75, 0.2, 0.2 ] #Variable "spp_prt_list" in input.nml + SPP_LSCALE: [ 150000.0, 150000.0, 150000.0, 150000.0, 150000.0 ] + SPP_TSCALE: [ 21600.0, 21600.0, 21600.0, 21600.0, 21600.0 ] #Variable "spp_tau" in input.nml + SPP_SIGTOP1: [ 0.1, 0.1, 0.1, 0.1, 0.1 ] + SPP_SIGTOP2: [ 0.025, 0.025, 0.025, 0.025, 0.025 ] + SPP_STDDEV_CUTOFF: [ 1.5, 1.5, 2.5, 1.5, 1.5 ] + ISEED_SPP: [ 4, 5, 6, 7, 8 ] + # + #----------------------------------------------------------------------- + # + # Turn on SPP in Noah or RUC LSM (support for Noah MP is in progress). + # Please be aware of the SDF that you choose if you wish to turn on LSM + # SPP. + # + # SPP in LSM schemes is handled in the &nam_sfcperts namelist block + # instead of in &nam_sppperts, where all other SPP is implemented. + # + # Perturbations to soil moisture content (SMC) are only applied at the + # first time step. + # + # LSM perturbations include SMC - soil moisture content (volume fraction), + # VGF - vegetation fraction, ALB - albedo, SAL - salinity, + # EMI - emissivity, ZOL - surface roughness (cm), and STC - soil temperature. + # + # Only five perturbations at a time can be applied currently, but all seven + # are shown below. In addition, only one unique iseed value is allowed + # at the moment, and is used for each pattern. + # + DO_LSM_SPP: false #If true, sets lndp_type=2 + LSM_SPP_TSCALE: [ 21600, 21600, 21600, 21600, 21600, 21600, 21600 ] + LSM_SPP_LSCALE: [ 150000, 150000, 150000, 150000, 150000, 150000, 150000 ] + ISEED_LSM_SPP: [ 9 ] + LSM_SPP_VAR_LIST: [ "smc", "vgf", "alb", "sal", "emi", "zol", "stc" ] + LSM_SPP_MAG_LIST: [ 0.017, 0.001, 0.001, 0.001, 0.001, 0.001, 0.2 ] + # + #----------------------------------------------------------------------- + # + # HALO_BLEND: + # Number of rows into the computational domain that should be blended + # with the LBCs. To shut halo blending off, this can be set to zero. + # + #----------------------------------------------------------------------- + # + HALO_BLEND: 10 + # + #----------------------------------------------------------------------- + # diff --git a/ush/config_utils.py b/ush/config_utils.py new file mode 100755 index 0000000000..84949c7db4 --- /dev/null +++ b/ush/config_utils.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 + +""" +Interface to configuration file management utilities. +To see what it can do: + + ./config_utils --help + +""" + +from python_utils import cfg_main + +if __name__ == "__main__": + cfg_main() diff --git a/ush/create_diag_table_file.py b/ush/create_diag_table_file.py index 0ac892727f..9c5b0f2e01 100644 --- a/ush/create_diag_table_file.py +++ b/ush/create_diag_table_file.py @@ -6,14 +6,22 @@ import unittest from textwrap import dedent -from python_utils import import_vars, set_env_var, print_input_args, \ - print_info_msg, print_err_msg_exit, cfg_to_yaml_str, \ - load_shell_config +from python_utils import ( + import_vars, + set_env_var, + print_input_args, + print_info_msg, + print_err_msg_exit, + cfg_to_yaml_str, + load_shell_config, + flatten_dict, +) from fill_jinja_template import fill_jinja_template + def create_diag_table_file(run_dir): - """ Creates a diagnostic table file for each cycle to be run + """Creates a diagnostic table file for each cycle to be run Args: run_dir: run directory @@ -23,44 +31,57 @@ def create_diag_table_file(run_dir): print_input_args(locals()) - #import all environment variables + # import all environment variables import_vars() - - #create a diagnostic table file within the specified run directory - print_info_msg(f''' + + # create a diagnostic table file within the specified run directory + print_info_msg( + f''' Creating a diagnostics table file (\"{DIAG_TABLE_FN}\") in the specified run directory... - - run_dir = \"{run_dir}\"''', verbose=VERBOSE) + + run_dir = \"{run_dir}\"''', + verbose=VERBOSE, + ) diag_table_fp = os.path.join(run_dir, DIAG_TABLE_FN) - print_info_msg(f''' - + print_info_msg( + f''' + Using the template diagnostics table file: - + diag_table_tmpl_fp = {DIAG_TABLE_TMPL_FP} - + to create: - - diag_table_fp = \"{diag_table_fp}\"''', verbose=VERBOSE) - settings = { - 'starttime': CDATE, - 'cres': CRES - } + diag_table_fp = \"{diag_table_fp}\"''', + verbose=VERBOSE, + ) + + settings = {"starttime": CDATE, "cres": CRES} settings_str = cfg_to_yaml_str(settings) - print_info_msg(dedent(f''' + print_info_msg( + dedent( + f""" The variable \"settings\" specifying values to be used in the \"{DIAG_TABLE_FN}\" file has been set as follows:\n - settings =\n\n''') + settings_str,verbose=VERBOSE) + settings =\n\n""" + ) + + settings_str, + verbose=VERBOSE, + ) - #call fill jinja + # call fill jinja try: - fill_jinja_template(["-q", "-u", settings_str, "-t", DIAG_TABLE_TMPL_FP, "-o", diag_table_fp]) + fill_jinja_template( + ["-q", "-u", settings_str, "-t", DIAG_TABLE_TMPL_FP, "-o", diag_table_fp] + ) except: - print_err_msg_exit(dedent(f''' + print_err_msg_exit( + dedent( + f""" Call to python script fill_jinja_template.py to create a \"{DIAG_TABLE_FN}\" file from a jinja2 template failed. Parameters passed to this script are: Full path to template diag table file: @@ -68,47 +89,56 @@ def create_diag_table_file(run_dir): Full path to output diag table file: diag_table_fp = \"{diag_table_fp}\" Namelist settings specified on command line:\n - settings =\n\n''') + settings_str) + settings =\n\n""" + ) + + settings_str + ) return False return True + def parse_args(argv): - """ Parse command line arguments""" - parser = argparse.ArgumentParser( - description='Creates diagnostic table file.' - ) + """Parse command line arguments""" + parser = argparse.ArgumentParser(description="Creates diagnostic table file.") - parser.add_argument('-r', '--run-dir', - dest='run_dir', - required=True, - help='Run directory.') + parser.add_argument( + "-r", "--run-dir", dest="run_dir", required=True, help="Run directory." + ) - parser.add_argument('-p', '--path-to-defns', - dest='path_to_defns', - required=True, - help='Path to var_defns file.') + parser.add_argument( + "-p", + "--path-to-defns", + dest="path_to_defns", + required=True, + help="Path to var_defns file.", + ) return parser.parse_args(argv) -if __name__ == '__main__': + +if __name__ == "__main__": args = parse_args(sys.argv[1:]) cfg = load_shell_config(args.path_to_defns) + cfg = flatten_dict(cfg) import_vars(dictionary=cfg) create_diag_table_file(args.run_dir) + class Testing(unittest.TestCase): def test_create_diag_table_file(self): - path = os.path.join(os.getenv('USHDIR'), "test_data") + path = os.path.join(os.getenv("USHDIR"), "test_data") self.assertTrue(create_diag_table_file(run_dir=path)) + def setUp(self): USHDIR = os.path.dirname(os.path.abspath(__file__)) - DIAG_TABLE_FN="diag_table" - DIAG_TABLE_TMPL_FP = os.path.join(USHDIR,"templates",f"{DIAG_TABLE_FN}.FV3_GFS_v15p2") - set_env_var('DEBUG',True) - set_env_var('VERBOSE',True) - set_env_var("USHDIR",USHDIR) - set_env_var("DIAG_TABLE_FN",DIAG_TABLE_FN) - set_env_var("DIAG_TABLE_TMPL_FP",DIAG_TABLE_TMPL_FP) - set_env_var("CRES","C48") - set_env_var("CDATE","2021010106") - + DIAG_TABLE_FN = "diag_table" + DIAG_TABLE_TMPL_FP = os.path.join( + USHDIR, "templates", f"{DIAG_TABLE_FN}.FV3_GFS_v15p2" + ) + set_env_var("DEBUG", True) + set_env_var("VERBOSE", True) + set_env_var("USHDIR", USHDIR) + set_env_var("DIAG_TABLE_FN", DIAG_TABLE_FN) + set_env_var("DIAG_TABLE_TMPL_FP", DIAG_TABLE_TMPL_FP) + set_env_var("CRES", "C48") + set_env_var("CDATE", "2021010106") diff --git a/ush/create_model_configure_file.py b/ush/create_model_configure_file.py index 0ae12cd069..dd522981a1 100644 --- a/ush/create_model_configure_file.py +++ b/ush/create_model_configure_file.py @@ -7,14 +7,26 @@ from datetime import datetime from textwrap import dedent -from python_utils import import_vars, set_env_var, print_input_args, str_to_type, \ - print_info_msg, print_err_msg_exit, lowercase, cfg_to_yaml_str, \ - load_shell_config +from python_utils import ( + import_vars, + set_env_var, + print_input_args, + str_to_type, + print_info_msg, + print_err_msg_exit, + lowercase, + cfg_to_yaml_str, + load_shell_config, + flatten_dict, +) from fill_jinja_template import fill_jinja_template -def create_model_configure_file(cdate,run_dir,sub_hourly_post,dt_subhourly_post_mnts,dt_atmos): - """ Creates a model configuration file in the specified + +def create_model_configure_file( + cdate, run_dir, sub_hourly_post, dt_subhourly_post_mnts, dt_atmos +): + """Creates a model configuration file in the specified run directory Args: @@ -29,58 +41,61 @@ def create_model_configure_file(cdate,run_dir,sub_hourly_post,dt_subhourly_post_ print_input_args(locals()) - #import all environment variables + # import all environment variables import_vars() - + # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Create a model configuration file in the specified run directory. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - print_info_msg(f''' + print_info_msg( + f''' Creating a model configuration file (\"{MODEL_CONFIG_FN}\") in the specified run directory (run_dir): - run_dir = \"{run_dir}\"''', verbose=VERBOSE) + run_dir = \"{run_dir}\"''', + verbose=VERBOSE, + ) # # Extract from cdate the starting year, month, day, and hour of the forecast. # - yyyy=cdate.year - mm=cdate.month - dd=cdate.day - hh=cdate.hour + yyyy = cdate.year + mm = cdate.month + dd = cdate.day + hh = cdate.hour # # Set parameters in the model configure file. # - dot_quilting_dot=f".{lowercase(str(QUILTING))}." - dot_print_esmf_dot=f".{lowercase(str(PRINT_ESMF))}." - dot_cpl_dot=f".{lowercase(str(CPL))}." - dot_write_dopost=f".{lowercase(str(WRITE_DOPOST))}." + dot_quilting_dot = f".{lowercase(str(QUILTING))}." + dot_print_esmf_dot = f".{lowercase(str(PRINT_ESMF))}." + dot_cpl_dot = f".{lowercase(str(CPL))}." + dot_write_dopost = f".{lowercase(str(WRITE_DOPOST))}." # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Create a multiline variable that consists of a yaml-compliant string - # specifying the values that the jinja variables in the template + # specifying the values that the jinja variables in the template # model_configure file should be set to. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # settings = { - 'PE_MEMBER01': PE_MEMBER01, - 'print_esmf': dot_print_esmf_dot, - 'start_year': yyyy, - 'start_month': mm, - 'start_day': dd, - 'start_hour': hh, - 'nhours_fcst': FCST_LEN_HRS, - 'dt_atmos': DT_ATMOS, - 'cpl': dot_cpl_dot, - 'atmos_nthreads': OMP_NUM_THREADS_RUN_FCST, - 'restart_interval': RESTART_INTERVAL, - 'write_dopost': dot_write_dopost, - 'quilting': dot_quilting_dot, - 'output_grid': WRTCMP_output_grid + "PE_MEMBER01": PE_MEMBER01, + "print_esmf": dot_print_esmf_dot, + "start_year": yyyy, + "start_month": mm, + "start_day": dd, + "start_hour": hh, + "nhours_fcst": FCST_LEN_HRS, + "dt_atmos": DT_ATMOS, + "cpl": dot_cpl_dot, + "atmos_nthreads": OMP_NUM_THREADS_RUN_FCST, + "restart_interval": RESTART_INTERVAL, + "write_dopost": dot_write_dopost, + "quilting": dot_quilting_dot, + "output_grid": WRTCMP_output_grid, } # # If the write-component is to be used, then specify a set of computational @@ -88,103 +103,126 @@ def create_model_configure_file(cdate,run_dir,sub_hourly_post,dt_subhourly_post_ # (coordinate system) of the grid that the write-component will be using. # if QUILTING: - settings.update({ - 'write_groups': WRTCMP_write_groups, - 'write_tasks_per_group': WRTCMP_write_tasks_per_group, - 'cen_lon': WRTCMP_cen_lon, - 'cen_lat': WRTCMP_cen_lat, - 'lon1': WRTCMP_lon_lwr_left, - 'lat1': WRTCMP_lat_lwr_left - }) - + settings.update( + { + "write_groups": WRTCMP_write_groups, + "write_tasks_per_group": WRTCMP_write_tasks_per_group, + "cen_lon": WRTCMP_cen_lon, + "cen_lat": WRTCMP_cen_lat, + "lon1": WRTCMP_lon_lwr_left, + "lat1": WRTCMP_lat_lwr_left, + } + ) + if WRTCMP_output_grid == "lambert_conformal": - settings.update({ - 'stdlat1': WRTCMP_stdlat1, - 'stdlat2': WRTCMP_stdlat2, - 'nx': WRTCMP_nx, - 'ny': WRTCMP_ny, - 'dx': WRTCMP_dx, - 'dy': WRTCMP_dy, - 'lon2': "", - 'lat2': "", - 'dlon': "", - 'dlat': "", - }) - elif WRTCMP_output_grid == "regional_latlon" or \ - WRTCMP_output_grid == "rotated_latlon": - settings.update({ - 'lon2': WRTCMP_lon_upr_rght, - 'lat2': WRTCMP_lat_upr_rght, - 'dlon': WRTCMP_dlon, - 'dlat': WRTCMP_dlat, - 'stdlat1': "", - 'stdlat2': "", - 'nx': "", - 'ny': "", - 'dx': "", - 'dy': "" - }) + settings.update( + { + "stdlat1": WRTCMP_stdlat1, + "stdlat2": WRTCMP_stdlat2, + "nx": WRTCMP_nx, + "ny": WRTCMP_ny, + "dx": WRTCMP_dx, + "dy": WRTCMP_dy, + "lon2": "", + "lat2": "", + "dlon": "", + "dlat": "", + } + ) + elif ( + WRTCMP_output_grid == "regional_latlon" + or WRTCMP_output_grid == "rotated_latlon" + ): + settings.update( + { + "lon2": WRTCMP_lon_upr_rght, + "lat2": WRTCMP_lat_upr_rght, + "dlon": WRTCMP_dlon, + "dlat": WRTCMP_dlat, + "stdlat1": "", + "stdlat2": "", + "nx": "", + "ny": "", + "dx": "", + "dy": "", + } + ) # - # If sub_hourly_post is set to "TRUE", then the forecast model must be - # directed to generate output files on a sub-hourly interval. Do this - # by specifying the output interval in the model configuration file - # (MODEL_CONFIG_FN) in units of number of forecat model time steps (nsout). - # nsout is calculated using the user-specified output time interval - # dt_subhourly_post_mnts (in units of minutes) and the forecast model's - # main time step dt_atmos (in units of seconds). Note that nsout is - # guaranteed to be an integer because the experiment generation scripts - # require that dt_subhourly_post_mnts (after conversion to seconds) be - # evenly divisible by dt_atmos. Also, in this case, the variable output_fh - # [which specifies the output interval in hours; - # see the jinja model_config template file] is set to 0, although this + # If sub_hourly_post is set to "TRUE", then the forecast model must be + # directed to generate output files on a sub-hourly interval. Do this + # by specifying the output interval in the model configuration file + # (MODEL_CONFIG_FN) in units of number of forecat model time steps (nsout). + # nsout is calculated using the user-specified output time interval + # dt_subhourly_post_mnts (in units of minutes) and the forecast model's + # main time step dt_atmos (in units of seconds). Note that nsout is + # guaranteed to be an integer because the experiment generation scripts + # require that dt_subhourly_post_mnts (after conversion to seconds) be + # evenly divisible by dt_atmos. Also, in this case, the variable output_fh + # [which specifies the output interval in hours; + # see the jinja model_config template file] is set to 0, although this # doesn't matter because any positive of nsout will override output_fh. # - # If sub_hourly_post is set to "FALSE", then the workflow is hard-coded - # (in the jinja model_config template file) to direct the forecast model - # to output files every hour. This is done by setting (1) output_fh to 1 + # If sub_hourly_post is set to "FALSE", then the workflow is hard-coded + # (in the jinja model_config template file) to direct the forecast model + # to output files every hour. This is done by setting (1) output_fh to 1 # here, and (2) nsout to -1 here which turns off output by time step interval. # # Note that the approach used here of separating how hourly and subhourly - # output is handled should be changed/generalized/simplified such that + # output is handled should be changed/generalized/simplified such that # the user should only need to specify the output time interval (there - # should be no need to specify a flag like sub_hourly_post); the workflow - # should then be able to direct the model to output files with that time - # interval and to direct the post-processor to process those files - # regardless of whether that output time interval is larger than, equal + # should be no need to specify a flag like sub_hourly_post); the workflow + # should then be able to direct the model to output files with that time + # interval and to direct the post-processor to process those files + # regardless of whether that output time interval is larger than, equal # to, or smaller than one hour. # if sub_hourly_post: - nsout=(dt_subhourly_post_mnts*60) // dt_atmos - output_fh=0 + nsout = (dt_subhourly_post_mnts * 60) // dt_atmos + output_fh = 0 else: - output_fh=1 - nsout=-1 + output_fh = 1 + nsout = -1 - settings.update({ - 'output_fh': output_fh, - 'nsout': nsout - }) + settings.update({"output_fh": output_fh, "nsout": nsout}) settings_str = cfg_to_yaml_str(settings) - - print_info_msg(dedent(f''' - The variable \"settings\" specifying values to be used in the \"{MODEL_CONFIG_FN}\" - file has been set as follows:\n - settings =\n\n''') + settings_str,verbose=VERBOSE) + + print_info_msg( + dedent( + f""" + The variable \"settings\" specifying values to be used in the \"{MODEL_CONFIG_FN}\" + file has been set as follows:\n + settings =\n\n""" + ) + + settings_str, + verbose=VERBOSE, + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Call a python script to generate the experiment's actual MODEL_CONFIG_FN # file from the template file. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - model_config_fp=os.path.join(run_dir, MODEL_CONFIG_FN) + model_config_fp = os.path.join(run_dir, MODEL_CONFIG_FN) try: - fill_jinja_template(["-q", "-u", settings_str, "-t", MODEL_CONFIG_TMPL_FP, "-o", model_config_fp]) + fill_jinja_template( + [ + "-q", + "-u", + settings_str, + "-t", + MODEL_CONFIG_TMPL_FP, + "-o", + model_config_fp, + ] + ) except: - print_err_msg_exit(dedent(f''' + print_err_msg_exit( + dedent( + f""" Call to python script fill_jinja_template.py to create a \"{MODEL_CONFIG_FN}\" file from a jinja2 template failed. Parameters passed to this script are: Full path to template model config file: @@ -192,101 +230,123 @@ def create_model_configure_file(cdate,run_dir,sub_hourly_post,dt_subhourly_post_ Full path to output model config file: model_config_fp = \"{model_config_fp}\" Namelist settings specified on command line:\n - settings =\n\n''') + settings_str) + settings =\n\n""" + ) + + settings_str + ) return False return True + def parse_args(argv): - """ Parse command line arguments""" - parser = argparse.ArgumentParser( - description='Creates model configuration file.' - ) + """Parse command line arguments""" + parser = argparse.ArgumentParser(description="Creates model configuration file.") - parser.add_argument('-r', '--run-dir', - dest='run_dir', - required=True, - help='Run directory.') + parser.add_argument( + "-r", "--run-dir", dest="run_dir", required=True, help="Run directory." + ) - parser.add_argument('-c', '--cdate', - dest='cdate', - required=True, - help='Date string in YYYYMMDD format.') + parser.add_argument( + "-c", + "--cdate", + dest="cdate", + required=True, + help="Date string in YYYYMMDD format.", + ) - parser.add_argument('-s', '--sub-hourly-post', - dest='sub_hourly_post', - required=True, - help='Set sub hourly post to either TRUE/FALSE by passing corresponding string.') + parser.add_argument( + "-s", + "--sub-hourly-post", + dest="sub_hourly_post", + required=True, + help="Set sub hourly post to either TRUE/FALSE by passing corresponding string.", + ) - parser.add_argument('-d', '--dt-subhourly-post-mnts', - dest='dt_subhourly_post_mnts', - required=True, - help='Subhourly post minitues.') + parser.add_argument( + "-d", + "--dt-subhourly-post-mnts", + dest="dt_subhourly_post_mnts", + required=True, + help="Subhourly post minitues.", + ) - parser.add_argument('-t', '--dt-atmos', - dest='dt_atmos', - required=True, - help='Forecast model\'s main time step.') + parser.add_argument( + "-t", + "--dt-atmos", + dest="dt_atmos", + required=True, + help="Forecast model's main time step.", + ) - parser.add_argument('-p', '--path-to-defns', - dest='path_to_defns', - required=True, - help='Path to var_defns file.') + parser.add_argument( + "-p", + "--path-to-defns", + dest="path_to_defns", + required=True, + help="Path to var_defns file.", + ) return parser.parse_args(argv) -if __name__ == '__main__': + +if __name__ == "__main__": args = parse_args(sys.argv[1:]) cfg = load_shell_config(args.path_to_defns) + cfg = flatten_dict(cfg) import_vars(dictionary=cfg) - create_model_configure_file( \ - run_dir = args.run_dir, \ - cdate = str_to_type(args.cdate), \ - sub_hourly_post = str_to_type(args.sub_hourly_post), \ - dt_subhourly_post_mnts = str_to_type(args.dt_subhourly_post_mnts), \ - dt_atmos = str_to_type(args.dt_atmos) ) + create_model_configure_file( + run_dir=args.run_dir, + cdate=str_to_type(args.cdate), + sub_hourly_post=str_to_type(args.sub_hourly_post), + dt_subhourly_post_mnts=str_to_type(args.dt_subhourly_post_mnts), + dt_atmos=str_to_type(args.dt_atmos), + ) + class Testing(unittest.TestCase): def test_create_model_configure_file(self): - path = os.path.join(os.getenv('USHDIR'), "test_data") - self.assertTrue(\ - create_model_configure_file( \ - run_dir=path, - cdate=datetime(2021,1,1), - sub_hourly_post=True, - dt_subhourly_post_mnts=4, - dt_atmos=1) ) + path = os.path.join(os.getenv("USHDIR"), "test_data") + self.assertTrue( + create_model_configure_file( + run_dir=path, + cdate=datetime(2021, 1, 1), + sub_hourly_post=True, + dt_subhourly_post_mnts=4, + dt_atmos=1, + ) + ) + def setUp(self): USHDIR = os.path.dirname(os.path.abspath(__file__)) - MODEL_CONFIG_FN='model_configure' + MODEL_CONFIG_FN = "model_configure" MODEL_CONFIG_TMPL_FP = os.path.join(USHDIR, "templates", MODEL_CONFIG_FN) - set_env_var('DEBUG',True) - set_env_var('VERBOSE',True) - set_env_var('QUILTING',True) - set_env_var('PRINT_ESMF',True) - set_env_var('CPL',True) - set_env_var('WRITE_DOPOST',True) - set_env_var("USHDIR",USHDIR) - set_env_var('MODEL_CONFIG_FN',MODEL_CONFIG_FN) - set_env_var("MODEL_CONFIG_TMPL_FP",MODEL_CONFIG_TMPL_FP) - set_env_var('PE_MEMBER01',24) - set_env_var('FCST_LEN_HRS',72) - set_env_var('DT_ATMOS',1) - set_env_var('OMP_NUM_THREADS_RUN_FCST',1) - set_env_var('RESTART_INTERVAL',4) - - set_env_var('WRTCMP_write_groups',1) - set_env_var('WRTCMP_write_tasks_per_group',2) - set_env_var('WRTCMP_output_grid',"lambert_conformal") - set_env_var('WRTCMP_cen_lon',-97.5) - set_env_var('WRTCMP_cen_lat',35.0) - set_env_var('WRTCMP_stdlat1',35.0) - set_env_var('WRTCMP_stdlat2',35.0) - set_env_var('WRTCMP_nx',199) - set_env_var('WRTCMP_ny',111) - set_env_var('WRTCMP_lon_lwr_left',-121.23349066) - set_env_var('WRTCMP_lat_lwr_left',23.41731593) - set_env_var('WRTCMP_dx',3000.0) - set_env_var('WRTCMP_dy',3000.0) + set_env_var("DEBUG", True) + set_env_var("VERBOSE", True) + set_env_var("QUILTING", True) + set_env_var("PRINT_ESMF", True) + set_env_var("CPL", True) + set_env_var("WRITE_DOPOST", True) + set_env_var("USHDIR", USHDIR) + set_env_var("MODEL_CONFIG_FN", MODEL_CONFIG_FN) + set_env_var("MODEL_CONFIG_TMPL_FP", MODEL_CONFIG_TMPL_FP) + set_env_var("PE_MEMBER01", 24) + set_env_var("FCST_LEN_HRS", 72) + set_env_var("DT_ATMOS", 1) + set_env_var("OMP_NUM_THREADS_RUN_FCST", 1) + set_env_var("RESTART_INTERVAL", 4) + set_env_var("WRTCMP_write_groups", 1) + set_env_var("WRTCMP_write_tasks_per_group", 2) + set_env_var("WRTCMP_output_grid", "lambert_conformal") + set_env_var("WRTCMP_cen_lon", -97.5) + set_env_var("WRTCMP_cen_lat", 35.0) + set_env_var("WRTCMP_stdlat1", 35.0) + set_env_var("WRTCMP_stdlat2", 35.0) + set_env_var("WRTCMP_nx", 199) + set_env_var("WRTCMP_ny", 111) + set_env_var("WRTCMP_lon_lwr_left", -121.23349066) + set_env_var("WRTCMP_lat_lwr_left", 23.41731593) + set_env_var("WRTCMP_dx", 3000.0) + set_env_var("WRTCMP_dy", 3000.0) diff --git a/ush/fill_jinja_template.py b/ush/fill_jinja_template.py index 74c3489081..d7a9673f36 100755 --- a/ush/fill_jinja_template.py +++ b/ush/fill_jinja_template.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -''' +""" This utility fills in a user-supplied Jinja template from either a YAML file, or command line arguments. @@ -39,7 +39,7 @@ - The template file is required. Script fails if not provided. - Command line arguments in the -u setting override the -c settings. -''' +""" import datetime as dt import os @@ -53,66 +53,69 @@ def join(loader, node): - ''' Uses os to join a list as a path. ''' + """Uses os to join a list as a path.""" return os.path.join(*loader.construct_sequence(node)) + def to_datetime(loader, node): - ''' Converts a date string with format YYYYMMDDHH[MM[SS]] to a datetime - object. ''' + """Converts a date string with format YYYYMMDDHH[MM[SS]] to a datetime + object.""" value = loader.construct_scalar(node) val_len = len(value) - # Check that the input string contains only numbers and is expected length. if val_len not in [10, 12, 14] or not value.isnumeric(): - msg = f'{value} does not conform to input format YYYYMMDDHH[MM[SS]]' + msg = f"{value} does not conform to input format YYYYMMDDHH[MM[SS]]" raise ValueError(msg) # Use a subset of the string corresponding to the input length of the string # 2 chosen here since Y is a 4 char year. - date_format = '%Y%m%d%H%M%S'[0:val_len-2] + date_format = "%Y%m%d%H%M%S"[0 : val_len - 2] return dt.datetime.strptime(value, date_format) -yaml.add_constructor('!datetime', to_datetime, Loader=yaml.SafeLoader) -yaml.add_constructor('!join', join, Loader=yaml.SafeLoader) + +yaml.add_constructor("!datetime", to_datetime, Loader=yaml.SafeLoader) +yaml.add_constructor("!join", join, Loader=yaml.SafeLoader) + def file_exists(arg): - ''' Checks whether a file exists, and returns the path if it does. ''' + """Checks whether a file exists, and returns the path if it does.""" if not os.path.exists(arg): - msg = f'{arg} does not exist!' + msg = f"{arg} does not exist!" raise argparse.ArgumentTypeError(msg) return arg + def config_exists(arg): - ''' + """ Checks whether the config file exists and if it contains the input section. Returns the config as a Python dict. - ''' + """ if len(arg) > 2: - msg = f'{len(arg)} arguments were provided for config. Only 2 allowed!' + msg = f"{len(arg)} arguments were provided for config. Only 2 allowed!" raise argparse.ArgumentTypeError(msg) file_name = file_exists(arg[0]) section_name = arg[1] if len(arg) == 2 else None # Load the YAML file into a dictionary - with open(file_name, 'r') as fn: + with open(file_name, "r") as fn: cfg = yaml.load(fn, Loader=yaml.SafeLoader) if section_name: try: cfg = cfg[section_name] except KeyError: - msg = f'Section {section_name} does not exist in top level of {file_name}' + msg = f"Section {section_name} does not exist in top level of {file_name}" raise argparse.ArgumentTypeError(msg) return cfg @@ -120,30 +123,32 @@ def config_exists(arg): def load_config(arg): - ''' + """ Check to ensure that the provided config file exists. If it does, load it with YAML's safe loader and return the resulting dict. - ''' + """ # Check for existence of file if not os.path.exists(arg): - msg = f'{arg} does not exist!' + msg = f"{arg} does not exist!" raise argparse.ArgumentTypeError(msg) return yaml.safe_load(arg) + def load_str(arg): - ''' Load a dict string safely using YAML. Return the resulting dict. ''' + """Load a dict string safely using YAML. Return the resulting dict.""" return yaml.load(arg, Loader=yaml.SafeLoader) + def path_ok(arg): - ''' + """ Check whether the path to the file exists, and is writeable. Return the path if it passes all checks, otherwise raise an error. - ''' + """ # Get the absolute path provided by arg dir_name = os.path.abspath(os.path.dirname(arg)) @@ -152,55 +157,64 @@ def path_ok(arg): if os.path.lexists(dir_name) and os.access(dir_name, os.W_OK): return arg - msg = f'{arg} is not a writable path!' + msg = f"{arg} is not a writable path!" raise argparse.ArgumentTypeError(msg) def parse_args(argv): - ''' + """ Function maintains the arguments accepted by this script. Please see Python's argparse documenation for more information about settings of each argument. - ''' + """ - parser = argparse.ArgumentParser( - description='Fill in a Rocoto XML template.' - ) + parser = argparse.ArgumentParser(description="Fill in a Rocoto XML template.") # Optional - parser.add_argument('-c', '--config', - help='Full path to a YAML user config file, and a \ - top-level section to use (optional).', - nargs='*', - type=load_config, - ) - parser.add_argument('-q', '--quiet', - action='store_true', - help='Suppress all output', - ) - parser.add_argument('-u', '--user_config', - help='Command-line user config options in YAML-formatted string', - type=load_str, - ) + parser.add_argument( + "-c", + "--config", + help="Full path to a YAML user config file, and a \ + top-level section to use (optional).", + nargs="*", + type=load_config, + ) + parser.add_argument( + "-q", + "--quiet", + action="store_true", + help="Suppress all output", + ) + parser.add_argument( + "-u", + "--user_config", + help="Command-line user config options in YAML-formatted string", + type=load_str, + ) # Required - parser.add_argument('-t', '--xml_template', - dest='template', - help='Full path to the jinja template', - required=True, - type=file_exists, - ) - parser.add_argument('-o', '--outxml', - dest='outxml', - help='Full path to the output Rocoto XML file.', - required=True, - type=path_ok, - ) + parser.add_argument( + "-t", + "--xml_template", + dest="template", + help="Full path to the jinja template", + required=True, + type=file_exists, + ) + parser.add_argument( + "-o", + "--outxml", + dest="outxml", + help="Full path to the output Rocoto XML file.", + required=True, + type=path_ok, + ) return parser.parse_args(argv) + def update_dict(dest, newdict, quiet=False): - ''' + """ Overwrites all values in dest dictionary section with key/value pairs from newdict. Does not support multi-layer update. @@ -216,28 +230,28 @@ def update_dict(dest, newdict, quiet=False): None Result: The dest dict is updated in place. - ''' + """ if not quiet: - print('*' * 50) + print("*" * 50) for key, value in newdict.items(): if not quiet: - print(f'Overriding {key:>20} = {value}') + print(f"Overriding {key:>20} = {value}") # Set key in dict dest[key] = value if not quiet: - print('*' * 50) + print("*" * 50) def fill_jinja_template(argv): - ''' + """ Loads a Jinja template, determines its necessary undefined variables, retrives them from user supplied settings, and renders the final result. - ''' + """ # parse args cla = parse_args(argv) @@ -246,8 +260,8 @@ def fill_jinja_template(argv): # Create a Jinja Environment to load the template. env = j2.Environment(loader=j2.FileSystemLoader(cla.template)) - template_source = env.loader.get_source(env, '') - template = env.get_template('') + template_source = env.loader.get_source(env, "") + template = env.get_template("") parsed_content = env.parse(template_source) # Gather all of the undefined variables in the template. @@ -266,19 +280,19 @@ def fill_jinja_template(argv): for var in template_vars: if cfg.get(var, "NULL") == "NULL": - raise KeyError(f'{var} does not exist in user-supplied settings!') + raise KeyError(f"{var} does not exist in user-supplied settings!") if not cla.quiet: - print(f'{var:>25}: {cfg.get(var)}') + print(f"{var:>25}: {cfg.get(var)}") tvars[var] = cfg.get(var) # Fill in XML template xml_contents = template.render(**tvars) - with open(cla.outxml, 'w') as fn: + with open(cla.outxml, "w") as fn: fn.write(xml_contents) -if __name__ == '__main__': +if __name__ == "__main__": fill_jinja_template(sys.argv[1:]) diff --git a/ush/generate_FV3LAM_wflow.py b/ush/generate_FV3LAM_wflow.py index 65a3d16824..5140c8dbc8 100755 --- a/ush/generate_FV3LAM_wflow.py +++ b/ush/generate_FV3LAM_wflow.py @@ -6,12 +6,26 @@ import subprocess from multiprocessing import Process from textwrap import dedent -from datetime import datetime,timedelta +from datetime import datetime, timedelta -from python_utils import print_info_msg, print_err_msg_exit, import_vars, cp_vrfy, cd_vrfy,\ - rm_vrfy, ln_vrfy, mkdir_vrfy, mv_vrfy, run_command, date_to_str, \ - define_macos_utilities, create_symlink_to_file, check_for_preexist_dir_file, \ - cfg_to_yaml_str, find_pattern_in_str +from python_utils import ( + print_info_msg, + print_err_msg_exit, + import_vars, + cp_vrfy, + cd_vrfy, + rm_vrfy, + ln_vrfy, + mkdir_vrfy, + mv_vrfy, + run_command, + date_to_str, + define_macos_utilities, + create_symlink_to_file, + check_for_preexist_dir_file, + cfg_to_yaml_str, + find_pattern_in_str, +) from setup import setup from set_FV3nml_sfc_climo_filenames import set_FV3nml_sfc_climo_filenames @@ -19,15 +33,20 @@ from fill_jinja_template import fill_jinja_template from set_namelist import set_namelist + def python_error_handler(): - """ Error handler for missing packages """ + """Error handler for missing packages""" - print_err_msg_exit(''' + print_err_msg_exit( + """ Errors found: check your python environment - + Instructions for setting up python environments can be found on the web: https://github.com/ufs-community/ufs-srweather-app/wiki/Getting-Started - ''', stack_trace=False) + """, + stack_trace=False, + ) + # Check for non-standard python packages try: @@ -38,8 +57,9 @@ def python_error_handler(): print_info_msg(error.__class__.__name__ + ": " + str(error)) python_error_handler() + def generate_FV3LAM_wflow(): - """ Function to setup a forecast experiment and create a workflow + """Function to setup a forecast experiment and create a workflow (according to the parameters specified in the config file Args: @@ -48,31 +68,37 @@ def generate_FV3LAM_wflow(): None """ - print(dedent(''' + print( + dedent( + """ ======================================================================== ======================================================================== - + Starting experiment generation... - + ======================================================================== - ========================================================================''')) - - #set ushdir + ========================================================================""" + ) + ) + + # set ushdir ushdir = os.path.dirname(os.path.abspath(__file__)) - #check python version - major,minor,patch = platform.python_version_tuple() + # check python version + major, minor, patch = platform.python_version_tuple() if int(major) < 3 or int(minor) < 6: - print_info_msg(f''' - + print_info_msg( + f""" + Error: python version must be 3.6 or higher - python version: {major}.{minor}''') + python version: {major}.{minor}""" + ) - #define macros + # define macros define_macos_utilities() # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Source the file that defines and then calls the setup function. The # setup function in turn first sources the default configuration file @@ -81,26 +107,26 @@ def generate_FV3LAM_wflow(): # user-specified values for a subset of the experiment/workflow parame- # ters that override their default values). # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # setup() - #import all environment variables + # import all environment variables import_vars() # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set the full path to the experiment's rocoto workflow xml file. This # file will be placed at the top level of the experiment directory and # then used by rocoto to run the workflow. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # WFLOW_XML_FP = os.path.join(EXPTDIR, WFLOW_XML_FN) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Create a multiline variable that consists of a yaml-compliant string # specifying the values that the jinja variables in the template rocoto @@ -108,17 +134,19 @@ def generate_FV3LAM_wflow(): # workflow configuration file (EXPT_CONFIG_FN) or in the setup.sh script # sourced above. Then call the python script that generates the XML. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if WORKFLOW_MANAGER == "rocoto": template_xml_fp = os.path.join(TEMPLATE_DIR, WFLOW_XML_FN) - print_info_msg(f''' + print_info_msg( + f''' Creating rocoto workflow XML file (WFLOW_XML_FP) from jinja template XML file (template_xml_fp): template_xml_fp = \"{template_xml_fp}\" - WFLOW_XML_FP = \"{WFLOW_XML_FP}\"''') + WFLOW_XML_FP = \"{WFLOW_XML_FP}\"''' + ) ensmem_indx_name = "" uscore_ensmem_name = "" @@ -128,11 +156,11 @@ def generate_FV3LAM_wflow(): uscore_ensmem_name = f"_mem#{ensmem_indx_name}#" slash_ensmem_subdir = f"/mem#{ensmem_indx_name}#" - #get time string + # get time string d = DATE_FIRST_CYCL + timedelta(seconds=DT_ATMOS) time_str = d.strftime("%M:%S") - cycl_hrs_str = [ f"{c:02d}" for c in CYCL_HRS ] + cycl_hrs_str = [f"{c:02d}" for c in CYCL_HRS] cdate_first_cycl = DATE_FIRST_CYCL + timedelta(hours=CYCL_HRS[0]) # Dictionary of settings @@ -140,278 +168,288 @@ def generate_FV3LAM_wflow(): # # Parameters needed by the job scheduler. # - 'account': ACCOUNT, - 'sched': SCHED, - 'partition_default': PARTITION_DEFAULT, - 'queue_default': QUEUE_DEFAULT, - 'partition_hpss': PARTITION_HPSS, - 'queue_hpss': QUEUE_HPSS, - 'partition_fcst': PARTITION_FCST, - 'queue_fcst': QUEUE_FCST, - 'machine': MACHINE, - 'slurm_native_cmd': SLURM_NATIVE_CMD, + "account": ACCOUNT, + "sched": SCHED, + "partition_default": PARTITION_DEFAULT, + "queue_default": QUEUE_DEFAULT, + "partition_hpss": PARTITION_HPSS, + "queue_hpss": QUEUE_HPSS, + "partition_fcst": PARTITION_FCST, + "queue_fcst": QUEUE_FCST, + "machine": MACHINE, + "slurm_native_cmd": SLURM_NATIVE_CMD, # # Workflow task names. # - 'make_grid_tn': MAKE_GRID_TN, - 'make_orog_tn': MAKE_OROG_TN, - 'make_sfc_climo_tn': MAKE_SFC_CLIMO_TN, - 'get_extrn_ics_tn': GET_EXTRN_ICS_TN, - 'get_extrn_lbcs_tn': GET_EXTRN_LBCS_TN, - 'make_ics_tn': MAKE_ICS_TN, - 'make_lbcs_tn': MAKE_LBCS_TN, - 'run_fcst_tn': RUN_FCST_TN, - 'run_post_tn': RUN_POST_TN, - 'get_obs_ccpa_tn': GET_OBS_CCPA_TN, - 'get_obs_ndas_tn': GET_OBS_NDAS_TN, - 'get_obs_mrms_tn': GET_OBS_MRMS_TN, - 'vx_tn': VX_TN, - 'vx_gridstat_tn': VX_GRIDSTAT_TN, - 'vx_gridstat_refc_tn': VX_GRIDSTAT_REFC_TN, - 'vx_gridstat_retop_tn': VX_GRIDSTAT_RETOP_TN, - 'vx_gridstat_03h_tn': VX_GRIDSTAT_03h_TN, - 'vx_gridstat_06h_tn': VX_GRIDSTAT_06h_TN, - 'vx_gridstat_24h_tn': VX_GRIDSTAT_24h_TN, - 'vx_pointstat_tn': VX_POINTSTAT_TN, - 'vx_ensgrid_tn': VX_ENSGRID_TN, - 'vx_ensgrid_refc_tn': VX_ENSGRID_REFC_TN, - 'vx_ensgrid_retop_tn': VX_ENSGRID_RETOP_TN, - 'vx_ensgrid_03h_tn': VX_ENSGRID_03h_TN, - 'vx_ensgrid_06h_tn': VX_ENSGRID_06h_TN, - 'vx_ensgrid_24h_tn': VX_ENSGRID_24h_TN, - 'vx_ensgrid_mean_tn': VX_ENSGRID_MEAN_TN, - 'vx_ensgrid_prob_tn': VX_ENSGRID_PROB_TN, - 'vx_ensgrid_mean_03h_tn': VX_ENSGRID_MEAN_03h_TN, - 'vx_ensgrid_prob_03h_tn': VX_ENSGRID_PROB_03h_TN, - 'vx_ensgrid_mean_06h_tn': VX_ENSGRID_MEAN_06h_TN, - 'vx_ensgrid_prob_06h_tn': VX_ENSGRID_PROB_06h_TN, - 'vx_ensgrid_mean_24h_tn': VX_ENSGRID_MEAN_24h_TN, - 'vx_ensgrid_prob_24h_tn': VX_ENSGRID_PROB_24h_TN, - 'vx_ensgrid_prob_refc_tn': VX_ENSGRID_PROB_REFC_TN, - 'vx_ensgrid_prob_retop_tn': VX_ENSGRID_PROB_RETOP_TN, - 'vx_enspoint_tn': VX_ENSPOINT_TN, - 'vx_enspoint_mean_tn': VX_ENSPOINT_MEAN_TN, - 'vx_enspoint_prob_tn': VX_ENSPOINT_PROB_TN, + "make_grid_tn": MAKE_GRID_TN, + "make_orog_tn": MAKE_OROG_TN, + "make_sfc_climo_tn": MAKE_SFC_CLIMO_TN, + "get_extrn_ics_tn": GET_EXTRN_ICS_TN, + "get_extrn_lbcs_tn": GET_EXTRN_LBCS_TN, + "make_ics_tn": MAKE_ICS_TN, + "make_lbcs_tn": MAKE_LBCS_TN, + "run_fcst_tn": RUN_FCST_TN, + "run_post_tn": RUN_POST_TN, + "get_obs_ccpa_tn": GET_OBS_CCPA_TN, + "get_obs_ndas_tn": GET_OBS_NDAS_TN, + "get_obs_mrms_tn": GET_OBS_MRMS_TN, + "vx_tn": VX_TN, + "vx_gridstat_tn": VX_GRIDSTAT_TN, + "vx_gridstat_refc_tn": VX_GRIDSTAT_REFC_TN, + "vx_gridstat_retop_tn": VX_GRIDSTAT_RETOP_TN, + "vx_gridstat_03h_tn": VX_GRIDSTAT_03h_TN, + "vx_gridstat_06h_tn": VX_GRIDSTAT_06h_TN, + "vx_gridstat_24h_tn": VX_GRIDSTAT_24h_TN, + "vx_pointstat_tn": VX_POINTSTAT_TN, + "vx_ensgrid_tn": VX_ENSGRID_TN, + "vx_ensgrid_refc_tn": VX_ENSGRID_REFC_TN, + "vx_ensgrid_retop_tn": VX_ENSGRID_RETOP_TN, + "vx_ensgrid_03h_tn": VX_ENSGRID_03h_TN, + "vx_ensgrid_06h_tn": VX_ENSGRID_06h_TN, + "vx_ensgrid_24h_tn": VX_ENSGRID_24h_TN, + "vx_ensgrid_mean_tn": VX_ENSGRID_MEAN_TN, + "vx_ensgrid_prob_tn": VX_ENSGRID_PROB_TN, + "vx_ensgrid_mean_03h_tn": VX_ENSGRID_MEAN_03h_TN, + "vx_ensgrid_prob_03h_tn": VX_ENSGRID_PROB_03h_TN, + "vx_ensgrid_mean_06h_tn": VX_ENSGRID_MEAN_06h_TN, + "vx_ensgrid_prob_06h_tn": VX_ENSGRID_PROB_06h_TN, + "vx_ensgrid_mean_24h_tn": VX_ENSGRID_MEAN_24h_TN, + "vx_ensgrid_prob_24h_tn": VX_ENSGRID_PROB_24h_TN, + "vx_ensgrid_prob_refc_tn": VX_ENSGRID_PROB_REFC_TN, + "vx_ensgrid_prob_retop_tn": VX_ENSGRID_PROB_RETOP_TN, + "vx_enspoint_tn": VX_ENSPOINT_TN, + "vx_enspoint_mean_tn": VX_ENSPOINT_MEAN_TN, + "vx_enspoint_prob_tn": VX_ENSPOINT_PROB_TN, # # Entity used to load the module file for each GET_OBS_* task. # - 'get_obs': GET_OBS, + "get_obs": GET_OBS, # # Number of nodes to use for each task. # - 'nnodes_make_grid': NNODES_MAKE_GRID, - 'nnodes_make_orog': NNODES_MAKE_OROG, - 'nnodes_make_sfc_climo': NNODES_MAKE_SFC_CLIMO, - 'nnodes_get_extrn_ics': NNODES_GET_EXTRN_ICS, - 'nnodes_get_extrn_lbcs': NNODES_GET_EXTRN_LBCS, - 'nnodes_make_ics': NNODES_MAKE_ICS, - 'nnodes_make_lbcs': NNODES_MAKE_LBCS, - 'nnodes_run_fcst': NNODES_RUN_FCST, - 'nnodes_run_post': NNODES_RUN_POST, - 'nnodes_get_obs_ccpa': NNODES_GET_OBS_CCPA, - 'nnodes_get_obs_mrms': NNODES_GET_OBS_MRMS, - 'nnodes_get_obs_ndas': NNODES_GET_OBS_NDAS, - 'nnodes_vx_gridstat': NNODES_VX_GRIDSTAT, - 'nnodes_vx_pointstat': NNODES_VX_POINTSTAT, - 'nnodes_vx_ensgrid': NNODES_VX_ENSGRID, - 'nnodes_vx_ensgrid_mean': NNODES_VX_ENSGRID_MEAN, - 'nnodes_vx_ensgrid_prob': NNODES_VX_ENSGRID_PROB, - 'nnodes_vx_enspoint': NNODES_VX_ENSPOINT, - 'nnodes_vx_enspoint_mean': NNODES_VX_ENSPOINT_MEAN, - 'nnodes_vx_enspoint_prob': NNODES_VX_ENSPOINT_PROB, + "nnodes_make_grid": NNODES_MAKE_GRID, + "nnodes_make_orog": NNODES_MAKE_OROG, + "nnodes_make_sfc_climo": NNODES_MAKE_SFC_CLIMO, + "nnodes_get_extrn_ics": NNODES_GET_EXTRN_ICS, + "nnodes_get_extrn_lbcs": NNODES_GET_EXTRN_LBCS, + "nnodes_make_ics": NNODES_MAKE_ICS, + "nnodes_make_lbcs": NNODES_MAKE_LBCS, + "nnodes_run_fcst": NNODES_RUN_FCST, + "nnodes_run_post": NNODES_RUN_POST, + "nnodes_get_obs_ccpa": NNODES_GET_OBS_CCPA, + "nnodes_get_obs_mrms": NNODES_GET_OBS_MRMS, + "nnodes_get_obs_ndas": NNODES_GET_OBS_NDAS, + "nnodes_vx_gridstat": NNODES_VX_GRIDSTAT, + "nnodes_vx_pointstat": NNODES_VX_POINTSTAT, + "nnodes_vx_ensgrid": NNODES_VX_ENSGRID, + "nnodes_vx_ensgrid_mean": NNODES_VX_ENSGRID_MEAN, + "nnodes_vx_ensgrid_prob": NNODES_VX_ENSGRID_PROB, + "nnodes_vx_enspoint": NNODES_VX_ENSPOINT, + "nnodes_vx_enspoint_mean": NNODES_VX_ENSPOINT_MEAN, + "nnodes_vx_enspoint_prob": NNODES_VX_ENSPOINT_PROB, # # Number of cores used for a task # - 'ncores_run_fcst': PE_MEMBER01, - 'native_run_fcst': f"--cpus-per-task {OMP_NUM_THREADS_RUN_FCST} --exclusive", + "ncores_run_fcst": PE_MEMBER01, + "native_run_fcst": f"--cpus-per-task {OMP_NUM_THREADS_RUN_FCST} --exclusive", # # Number of logical processes per node for each task. If running without # threading, this is equal to the number of MPI processes per node. # - 'ppn_make_grid': PPN_MAKE_GRID, - 'ppn_make_orog': PPN_MAKE_OROG, - 'ppn_make_sfc_climo': PPN_MAKE_SFC_CLIMO, - 'ppn_get_extrn_ics': PPN_GET_EXTRN_ICS, - 'ppn_get_extrn_lbcs': PPN_GET_EXTRN_LBCS, - 'ppn_make_ics': PPN_MAKE_ICS, - 'ppn_make_lbcs': PPN_MAKE_LBCS, - 'ppn_run_fcst': PPN_RUN_FCST, - 'ppn_run_post': PPN_RUN_POST, - 'ppn_get_obs_ccpa': PPN_GET_OBS_CCPA, - 'ppn_get_obs_mrms': PPN_GET_OBS_MRMS, - 'ppn_get_obs_ndas': PPN_GET_OBS_NDAS, - 'ppn_vx_gridstat': PPN_VX_GRIDSTAT, - 'ppn_vx_pointstat': PPN_VX_POINTSTAT, - 'ppn_vx_ensgrid': PPN_VX_ENSGRID, - 'ppn_vx_ensgrid_mean': PPN_VX_ENSGRID_MEAN, - 'ppn_vx_ensgrid_prob': PPN_VX_ENSGRID_PROB, - 'ppn_vx_enspoint': PPN_VX_ENSPOINT, - 'ppn_vx_enspoint_mean': PPN_VX_ENSPOINT_MEAN, - 'ppn_vx_enspoint_prob': PPN_VX_ENSPOINT_PROB, + "ppn_make_grid": PPN_MAKE_GRID, + "ppn_make_orog": PPN_MAKE_OROG, + "ppn_make_sfc_climo": PPN_MAKE_SFC_CLIMO, + "ppn_get_extrn_ics": PPN_GET_EXTRN_ICS, + "ppn_get_extrn_lbcs": PPN_GET_EXTRN_LBCS, + "ppn_make_ics": PPN_MAKE_ICS, + "ppn_make_lbcs": PPN_MAKE_LBCS, + "ppn_run_fcst": PPN_RUN_FCST, + "ppn_run_post": PPN_RUN_POST, + "ppn_get_obs_ccpa": PPN_GET_OBS_CCPA, + "ppn_get_obs_mrms": PPN_GET_OBS_MRMS, + "ppn_get_obs_ndas": PPN_GET_OBS_NDAS, + "ppn_vx_gridstat": PPN_VX_GRIDSTAT, + "ppn_vx_pointstat": PPN_VX_POINTSTAT, + "ppn_vx_ensgrid": PPN_VX_ENSGRID, + "ppn_vx_ensgrid_mean": PPN_VX_ENSGRID_MEAN, + "ppn_vx_ensgrid_prob": PPN_VX_ENSGRID_PROB, + "ppn_vx_enspoint": PPN_VX_ENSPOINT, + "ppn_vx_enspoint_mean": PPN_VX_ENSPOINT_MEAN, + "ppn_vx_enspoint_prob": PPN_VX_ENSPOINT_PROB, # # Maximum wallclock time for each task. # - 'wtime_make_grid': WTIME_MAKE_GRID, - 'wtime_make_orog': WTIME_MAKE_OROG, - 'wtime_make_sfc_climo': WTIME_MAKE_SFC_CLIMO, - 'wtime_get_extrn_ics': WTIME_GET_EXTRN_ICS, - 'wtime_get_extrn_lbcs': WTIME_GET_EXTRN_LBCS, - 'wtime_make_ics': WTIME_MAKE_ICS, - 'wtime_make_lbcs': WTIME_MAKE_LBCS, - 'wtime_run_fcst': WTIME_RUN_FCST, - 'wtime_run_post': WTIME_RUN_POST, - 'wtime_get_obs_ccpa': WTIME_GET_OBS_CCPA, - 'wtime_get_obs_mrms': WTIME_GET_OBS_MRMS, - 'wtime_get_obs_ndas': WTIME_GET_OBS_NDAS, - 'wtime_vx_gridstat': WTIME_VX_GRIDSTAT, - 'wtime_vx_pointstat': WTIME_VX_POINTSTAT, - 'wtime_vx_ensgrid': WTIME_VX_ENSGRID, - 'wtime_vx_ensgrid_mean': WTIME_VX_ENSGRID_MEAN, - 'wtime_vx_ensgrid_prob': WTIME_VX_ENSGRID_PROB, - 'wtime_vx_enspoint': WTIME_VX_ENSPOINT, - 'wtime_vx_enspoint_mean': WTIME_VX_ENSPOINT_MEAN, - 'wtime_vx_enspoint_prob': WTIME_VX_ENSPOINT_PROB, + "wtime_make_grid": WTIME_MAKE_GRID, + "wtime_make_orog": WTIME_MAKE_OROG, + "wtime_make_sfc_climo": WTIME_MAKE_SFC_CLIMO, + "wtime_get_extrn_ics": WTIME_GET_EXTRN_ICS, + "wtime_get_extrn_lbcs": WTIME_GET_EXTRN_LBCS, + "wtime_make_ics": WTIME_MAKE_ICS, + "wtime_make_lbcs": WTIME_MAKE_LBCS, + "wtime_run_fcst": WTIME_RUN_FCST, + "wtime_run_post": WTIME_RUN_POST, + "wtime_get_obs_ccpa": WTIME_GET_OBS_CCPA, + "wtime_get_obs_mrms": WTIME_GET_OBS_MRMS, + "wtime_get_obs_ndas": WTIME_GET_OBS_NDAS, + "wtime_vx_gridstat": WTIME_VX_GRIDSTAT, + "wtime_vx_pointstat": WTIME_VX_POINTSTAT, + "wtime_vx_ensgrid": WTIME_VX_ENSGRID, + "wtime_vx_ensgrid_mean": WTIME_VX_ENSGRID_MEAN, + "wtime_vx_ensgrid_prob": WTIME_VX_ENSGRID_PROB, + "wtime_vx_enspoint": WTIME_VX_ENSPOINT, + "wtime_vx_enspoint_mean": WTIME_VX_ENSPOINT_MEAN, + "wtime_vx_enspoint_prob": WTIME_VX_ENSPOINT_PROB, # # Maximum number of tries for each task. # - 'maxtries_make_grid': MAXTRIES_MAKE_GRID, - 'maxtries_make_orog': MAXTRIES_MAKE_OROG, - 'maxtries_make_sfc_climo': MAXTRIES_MAKE_SFC_CLIMO, - 'maxtries_get_extrn_ics': MAXTRIES_GET_EXTRN_ICS, - 'maxtries_get_extrn_lbcs': MAXTRIES_GET_EXTRN_LBCS, - 'maxtries_make_ics': MAXTRIES_MAKE_ICS, - 'maxtries_make_lbcs': MAXTRIES_MAKE_LBCS, - 'maxtries_run_fcst': MAXTRIES_RUN_FCST, - 'maxtries_run_post': MAXTRIES_RUN_POST, - 'maxtries_get_obs_ccpa': MAXTRIES_GET_OBS_CCPA, - 'maxtries_get_obs_mrms': MAXTRIES_GET_OBS_MRMS, - 'maxtries_get_obs_ndas': MAXTRIES_GET_OBS_NDAS, - 'maxtries_vx_gridstat': MAXTRIES_VX_GRIDSTAT, - 'maxtries_vx_gridstat_refc': MAXTRIES_VX_GRIDSTAT_REFC, - 'maxtries_vx_gridstat_retop': MAXTRIES_VX_GRIDSTAT_RETOP, - 'maxtries_vx_gridstat_03h': MAXTRIES_VX_GRIDSTAT_03h, - 'maxtries_vx_gridstat_06h': MAXTRIES_VX_GRIDSTAT_06h, - 'maxtries_vx_gridstat_24h': MAXTRIES_VX_GRIDSTAT_24h, - 'maxtries_vx_pointstat': MAXTRIES_VX_POINTSTAT, - 'maxtries_vx_ensgrid': MAXTRIES_VX_ENSGRID, - 'maxtries_vx_ensgrid_refc': MAXTRIES_VX_ENSGRID_REFC, - 'maxtries_vx_ensgrid_retop': MAXTRIES_VX_ENSGRID_RETOP, - 'maxtries_vx_ensgrid_03h': MAXTRIES_VX_ENSGRID_03h, - 'maxtries_vx_ensgrid_06h': MAXTRIES_VX_ENSGRID_06h, - 'maxtries_vx_ensgrid_24h': MAXTRIES_VX_ENSGRID_24h, - 'maxtries_vx_ensgrid_mean': MAXTRIES_VX_ENSGRID_MEAN, - 'maxtries_vx_ensgrid_prob': MAXTRIES_VX_ENSGRID_PROB, - 'maxtries_vx_ensgrid_mean_03h': MAXTRIES_VX_ENSGRID_MEAN_03h, - 'maxtries_vx_ensgrid_prob_03h': MAXTRIES_VX_ENSGRID_PROB_03h, - 'maxtries_vx_ensgrid_mean_06h': MAXTRIES_VX_ENSGRID_MEAN_06h, - 'maxtries_vx_ensgrid_prob_06h': MAXTRIES_VX_ENSGRID_PROB_06h, - 'maxtries_vx_ensgrid_mean_24h': MAXTRIES_VX_ENSGRID_MEAN_24h, - 'maxtries_vx_ensgrid_prob_24h': MAXTRIES_VX_ENSGRID_PROB_24h, - 'maxtries_vx_ensgrid_prob_refc': MAXTRIES_VX_ENSGRID_PROB_REFC, - 'maxtries_vx_ensgrid_prob_retop': MAXTRIES_VX_ENSGRID_PROB_RETOP, - 'maxtries_vx_enspoint': MAXTRIES_VX_ENSPOINT, - 'maxtries_vx_enspoint_mean': MAXTRIES_VX_ENSPOINT_MEAN, - 'maxtries_vx_enspoint_prob': MAXTRIES_VX_ENSPOINT_PROB, + "maxtries_make_grid": MAXTRIES_MAKE_GRID, + "maxtries_make_orog": MAXTRIES_MAKE_OROG, + "maxtries_make_sfc_climo": MAXTRIES_MAKE_SFC_CLIMO, + "maxtries_get_extrn_ics": MAXTRIES_GET_EXTRN_ICS, + "maxtries_get_extrn_lbcs": MAXTRIES_GET_EXTRN_LBCS, + "maxtries_make_ics": MAXTRIES_MAKE_ICS, + "maxtries_make_lbcs": MAXTRIES_MAKE_LBCS, + "maxtries_run_fcst": MAXTRIES_RUN_FCST, + "maxtries_run_post": MAXTRIES_RUN_POST, + "maxtries_get_obs_ccpa": MAXTRIES_GET_OBS_CCPA, + "maxtries_get_obs_mrms": MAXTRIES_GET_OBS_MRMS, + "maxtries_get_obs_ndas": MAXTRIES_GET_OBS_NDAS, + "maxtries_vx_gridstat": MAXTRIES_VX_GRIDSTAT, + "maxtries_vx_gridstat_refc": MAXTRIES_VX_GRIDSTAT_REFC, + "maxtries_vx_gridstat_retop": MAXTRIES_VX_GRIDSTAT_RETOP, + "maxtries_vx_gridstat_03h": MAXTRIES_VX_GRIDSTAT_03h, + "maxtries_vx_gridstat_06h": MAXTRIES_VX_GRIDSTAT_06h, + "maxtries_vx_gridstat_24h": MAXTRIES_VX_GRIDSTAT_24h, + "maxtries_vx_pointstat": MAXTRIES_VX_POINTSTAT, + "maxtries_vx_ensgrid": MAXTRIES_VX_ENSGRID, + "maxtries_vx_ensgrid_refc": MAXTRIES_VX_ENSGRID_REFC, + "maxtries_vx_ensgrid_retop": MAXTRIES_VX_ENSGRID_RETOP, + "maxtries_vx_ensgrid_03h": MAXTRIES_VX_ENSGRID_03h, + "maxtries_vx_ensgrid_06h": MAXTRIES_VX_ENSGRID_06h, + "maxtries_vx_ensgrid_24h": MAXTRIES_VX_ENSGRID_24h, + "maxtries_vx_ensgrid_mean": MAXTRIES_VX_ENSGRID_MEAN, + "maxtries_vx_ensgrid_prob": MAXTRIES_VX_ENSGRID_PROB, + "maxtries_vx_ensgrid_mean_03h": MAXTRIES_VX_ENSGRID_MEAN_03h, + "maxtries_vx_ensgrid_prob_03h": MAXTRIES_VX_ENSGRID_PROB_03h, + "maxtries_vx_ensgrid_mean_06h": MAXTRIES_VX_ENSGRID_MEAN_06h, + "maxtries_vx_ensgrid_prob_06h": MAXTRIES_VX_ENSGRID_PROB_06h, + "maxtries_vx_ensgrid_mean_24h": MAXTRIES_VX_ENSGRID_MEAN_24h, + "maxtries_vx_ensgrid_prob_24h": MAXTRIES_VX_ENSGRID_PROB_24h, + "maxtries_vx_ensgrid_prob_refc": MAXTRIES_VX_ENSGRID_PROB_REFC, + "maxtries_vx_ensgrid_prob_retop": MAXTRIES_VX_ENSGRID_PROB_RETOP, + "maxtries_vx_enspoint": MAXTRIES_VX_ENSPOINT, + "maxtries_vx_enspoint_mean": MAXTRIES_VX_ENSPOINT_MEAN, + "maxtries_vx_enspoint_prob": MAXTRIES_VX_ENSPOINT_PROB, # # Flags that specify whether to run the preprocessing or # verification-related tasks. # - 'run_task_make_grid': RUN_TASK_MAKE_GRID, - 'run_task_make_orog': RUN_TASK_MAKE_OROG, - 'run_task_make_sfc_climo': RUN_TASK_MAKE_SFC_CLIMO, - 'run_task_get_extrn_ics': RUN_TASK_GET_EXTRN_ICS, - 'run_task_get_extrn_lbcs': RUN_TASK_GET_EXTRN_LBCS, - 'run_task_make_ics': RUN_TASK_MAKE_ICS, - 'run_task_make_lbcs': RUN_TASK_MAKE_LBCS, - 'run_task_run_fcst': RUN_TASK_RUN_FCST, - 'run_task_run_post': RUN_TASK_RUN_POST, - 'run_task_get_obs_ccpa': RUN_TASK_GET_OBS_CCPA, - 'run_task_get_obs_mrms': RUN_TASK_GET_OBS_MRMS, - 'run_task_get_obs_ndas': RUN_TASK_GET_OBS_NDAS, - 'run_task_vx_gridstat': RUN_TASK_VX_GRIDSTAT, - 'run_task_vx_pointstat': RUN_TASK_VX_POINTSTAT, - 'run_task_vx_ensgrid': RUN_TASK_VX_ENSGRID, - 'run_task_vx_enspoint': RUN_TASK_VX_ENSPOINT, + "run_task_make_grid": RUN_TASK_MAKE_GRID, + "run_task_make_orog": RUN_TASK_MAKE_OROG, + "run_task_make_sfc_climo": RUN_TASK_MAKE_SFC_CLIMO, + "run_task_get_extrn_ics": RUN_TASK_GET_EXTRN_ICS, + "run_task_get_extrn_lbcs": RUN_TASK_GET_EXTRN_LBCS, + "run_task_make_ics": RUN_TASK_MAKE_ICS, + "run_task_make_lbcs": RUN_TASK_MAKE_LBCS, + "run_task_run_fcst": RUN_TASK_RUN_FCST, + "run_task_run_post": RUN_TASK_RUN_POST, + "run_task_get_obs_ccpa": RUN_TASK_GET_OBS_CCPA, + "run_task_get_obs_mrms": RUN_TASK_GET_OBS_MRMS, + "run_task_get_obs_ndas": RUN_TASK_GET_OBS_NDAS, + "run_task_vx_gridstat": RUN_TASK_VX_GRIDSTAT, + "run_task_vx_pointstat": RUN_TASK_VX_POINTSTAT, + "run_task_vx_ensgrid": RUN_TASK_VX_ENSGRID, + "run_task_vx_enspoint": RUN_TASK_VX_ENSPOINT, # # Number of physical cores per node for the current machine. # - 'ncores_per_node': NCORES_PER_NODE, + "ncores_per_node": NCORES_PER_NODE, # # Directories and files. # - 'jobsdir': JOBSDIR, - 'logdir': LOGDIR, - 'scriptsdir': SCRIPTSDIR, - 'cycle_basedir': CYCLE_BASEDIR, - 'global_var_defns_fp': GLOBAL_VAR_DEFNS_FP, - 'load_modules_run_task_fp': LOAD_MODULES_RUN_TASK_FP, + "jobsdir": JOBSDIR, + "logdir": LOGDIR, + "scriptsdir": SCRIPTSDIR, + "cycle_basedir": CYCLE_BASEDIR, + "global_var_defns_fp": GLOBAL_VAR_DEFNS_FP, + "load_modules_run_task_fp": LOAD_MODULES_RUN_TASK_FP, # # External model information for generating ICs and LBCs. # - 'extrn_mdl_name_ics': EXTRN_MDL_NAME_ICS, - 'extrn_mdl_name_lbcs': EXTRN_MDL_NAME_LBCS, + "extrn_mdl_name_ics": EXTRN_MDL_NAME_ICS, + "extrn_mdl_name_lbcs": EXTRN_MDL_NAME_LBCS, # # Parameters that determine the set of cycles to run. # - 'date_first_cycl': date_to_str(DATE_FIRST_CYCL,format="%Y%m%d"), - 'date_last_cycl': date_to_str(DATE_LAST_CYCL,format="%Y%m%d"), - 'cdate_first_cycl': cdate_first_cycl, - 'cycl_hrs': cycl_hrs_str, - 'cycl_freq': f"{INCR_CYCL_FREQ:02d}:00:00", + "date_first_cycl": date_to_str(DATE_FIRST_CYCL, format="%Y%m%d"), + "date_last_cycl": date_to_str(DATE_LAST_CYCL, format="%Y%m%d"), + "cdate_first_cycl": cdate_first_cycl, + "cycl_hrs": cycl_hrs_str, + "cycl_freq": f"{INCR_CYCL_FREQ:02d}:00:00", # # Forecast length (same for all cycles). # - 'fcst_len_hrs': FCST_LEN_HRS, + "fcst_len_hrs": FCST_LEN_HRS, # # Inline post # - 'write_dopost': WRITE_DOPOST, + "write_dopost": WRITE_DOPOST, # # METPlus-specific information # - 'model': MODEL, - 'met_install_dir': MET_INSTALL_DIR, - 'met_bin_exec': MET_BIN_EXEC, - 'metplus_path': METPLUS_PATH, - 'vx_config_dir': VX_CONFIG_DIR, - 'metplus_conf': METPLUS_CONF, - 'met_config': MET_CONFIG, - 'ccpa_obs_dir': CCPA_OBS_DIR, - 'mrms_obs_dir': MRMS_OBS_DIR, - 'ndas_obs_dir': NDAS_OBS_DIR, + "model": MODEL, + "met_install_dir": MET_INSTALL_DIR, + "met_bin_exec": MET_BIN_EXEC, + "metplus_path": METPLUS_PATH, + "vx_config_dir": VX_CONFIG_DIR, + "metplus_conf": METPLUS_CONF, + "met_config": MET_CONFIG, + "ccpa_obs_dir": CCPA_OBS_DIR, + "mrms_obs_dir": MRMS_OBS_DIR, + "ndas_obs_dir": NDAS_OBS_DIR, # # Ensemble-related parameters. # - 'do_ensemble': DO_ENSEMBLE, - 'num_ens_members': NUM_ENS_MEMBERS, - 'ndigits_ensmem_names': f"{NDIGITS_ENSMEM_NAMES}", - 'ensmem_indx_name': ensmem_indx_name, - 'uscore_ensmem_name': uscore_ensmem_name, - 'slash_ensmem_subdir': slash_ensmem_subdir, + "do_ensemble": DO_ENSEMBLE, + "num_ens_members": NUM_ENS_MEMBERS, + "ndigits_ensmem_names": f"{NDIGITS_ENSMEM_NAMES}", + "ensmem_indx_name": ensmem_indx_name, + "uscore_ensmem_name": uscore_ensmem_name, + "slash_ensmem_subdir": slash_ensmem_subdir, # # Parameters associated with subhourly post-processed output # - 'sub_hourly_post': SUB_HOURLY_POST, - 'delta_min': DT_SUBHOURLY_POST_MNTS, - 'first_fv3_file_tstr': f"000:{time_str}" + "sub_hourly_post": SUB_HOURLY_POST, + "delta_min": DT_SUBHOURLY_POST_MNTS, + "first_fv3_file_tstr": f"000:{time_str}", } # End of "settings" variable. settings_str = cfg_to_yaml_str(settings) - print_info_msg(dedent(f''' - The variable \"settings\" specifying values of the rococo XML variables - has been set as follows: - #----------------------------------------------------------------------- - settings =\n\n''') + settings_str, verbose=VERBOSE) + print_info_msg( + dedent( + f""" + The variable \"settings\" specifying values of the rococo XML variables + has been set as follows: + #----------------------------------------------------------------------- + settings =\n\n""" + ) + + settings_str, + verbose=VERBOSE, + ) # - # Call the python script to generate the experiment's actual XML file + # Call the python script to generate the experiment's actual XML file # from the jinja template file. # try: - fill_jinja_template(["-q", "-u", settings_str, "-t", template_xml_fp, "-o", WFLOW_XML_FP]) + fill_jinja_template( + ["-q", "-u", settings_str, "-t", template_xml_fp, "-o", WFLOW_XML_FP] + ) except: - print_err_msg_exit(dedent(f''' + print_err_msg_exit( + dedent( + f""" Call to python script fill_jinja_template.py to create a rocoto workflow XML file from a template file failed. Parameters passed to this script are: @@ -420,171 +458,199 @@ def generate_FV3LAM_wflow(): Full path to output rocoto XML file: WFLOW_XML_FP = \"{WFLOW_XML_FP}\" Namelist settings specified on command line:\n - settings =\n\n''') + settings_str) + settings =\n\n""" + ) + + settings_str + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Create a symlink in the experiment directory that points to the workflow # (re)launch script. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - print_info_msg(f''' + print_info_msg( + f''' Creating symlink in the experiment directory (EXPTDIR) that points to the workflow launch script (WFLOW_LAUNCH_SCRIPT_FP): EXPTDIR = \"{EXPTDIR}\" - WFLOW_LAUNCH_SCRIPT_FP = \"{WFLOW_LAUNCH_SCRIPT_FP}\"''',verbose=VERBOSE) + WFLOW_LAUNCH_SCRIPT_FP = \"{WFLOW_LAUNCH_SCRIPT_FP}\"''', + verbose=VERBOSE, + ) - create_symlink_to_file(WFLOW_LAUNCH_SCRIPT_FP, - os.path.join(EXPTDIR,WFLOW_LAUNCH_SCRIPT_FN), - False) + create_symlink_to_file( + WFLOW_LAUNCH_SCRIPT_FP, os.path.join(EXPTDIR, WFLOW_LAUNCH_SCRIPT_FN), False + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If USE_CRON_TO_RELAUNCH is set to TRUE, add a line to the user's cron # table to call the (re)launch script every CRON_RELAUNCH_INTVL_MNTS mi- # nutes. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if USE_CRON_TO_RELAUNCH: - add_crontab_line() + add_crontab_line() # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Create the FIXam directory under the experiment directory. In NCO mode, # this will be a symlink to the directory specified in FIXgsm, while in # community mode, it will be an actual directory with files copied into # it from FIXgsm. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # First, consider NCO mode. # if RUN_ENVIR == "nco": - - ln_vrfy(f'''-fsn "{FIXgsm}" "{FIXam}"''') - # - # Resolve the target directory that the FIXam symlink points to and check - # that it exists. - # - try: - path_resolved = os.path.realpath(FIXam) - except: - path_resolved = FIXam - if not os.path.exists(path_resolved): - print_err_msg_exit(f''' - In order to be able to generate a forecast experiment in NCO mode (i.e. - when RUN_ENVIR set to \"nco\"), the path specified by FIXam after resolving - all symlinks (path_resolved) must be an existing directory (but in this - case isn't): - RUN_ENVIR = \"{RUN_ENVIR}\" - FIXam = \"{FIXam}\" - path_resolved = \"{path_resolved}\" - Please ensure that path_resolved is an existing directory and then rerun - the experiment generation script.''') + + ln_vrfy(f'''-fsn "{FIXgsm}" "{FIXam}"''') + # + # Resolve the target directory that the FIXam symlink points to and check + # that it exists. + # + try: + path_resolved = os.path.realpath(FIXam) + except: + path_resolved = FIXam + if not os.path.exists(path_resolved): + print_err_msg_exit( + f""" + In order to be able to generate a forecast experiment in NCO mode (i.e. + when RUN_ENVIR set to \"nco\"), the path specified by FIXam after resolving + all symlinks (path_resolved) must be an existing directory (but in this + case isn't): + RUN_ENVIR = \"{RUN_ENVIR}\" + FIXam = \"{FIXam}\" + path_resolved = \"{path_resolved}\" + Please ensure that path_resolved is an existing directory and then rerun + the experiment generation script.""" + ) # # Now consider community mode. # else: - - print_info_msg(f''' - Copying fixed files from system directory (FIXgsm) to a subdirectory - (FIXam) in the experiment directory: - FIXgsm = \"{FIXgsm}\" - FIXam = \"{FIXam}\"''',verbose=VERBOSE) - - check_for_preexist_dir_file(FIXam,"delete") - mkdir_vrfy("-p",FIXam) - mkdir_vrfy("-p",os.path.join(FIXam,"fix_co2_proj")) - - num_files=len(FIXgsm_FILES_TO_COPY_TO_FIXam) - for i in range(num_files): - fn=f"{FIXgsm_FILES_TO_COPY_TO_FIXam[i]}" - cp_vrfy(os.path.join(FIXgsm,fn), os.path.join(FIXam,fn)) - # - #----------------------------------------------------------------------- + + print_info_msg( + f''' + Copying fixed files from system directory (FIXgsm) to a subdirectory + (FIXam) in the experiment directory: + FIXgsm = \"{FIXgsm}\" + FIXam = \"{FIXam}\"''', + verbose=VERBOSE, + ) + + check_for_preexist_dir_file(FIXam, "delete") + mkdir_vrfy("-p", FIXam) + mkdir_vrfy("-p", os.path.join(FIXam, "fix_co2_proj")) + + num_files = len(FIXgsm_FILES_TO_COPY_TO_FIXam) + for i in range(num_files): + fn = f"{FIXgsm_FILES_TO_COPY_TO_FIXam[i]}" + cp_vrfy(os.path.join(FIXgsm, fn), os.path.join(FIXam, fn)) + # + # ----------------------------------------------------------------------- # # Copy MERRA2 aerosol climatology data. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if USE_MERRA_CLIMO: - print_info_msg(f''' + print_info_msg( + f''' Copying MERRA2 aerosol climatology data files from system directory (FIXaer/FIXlut) to a subdirectory (FIXclim) in the experiment directory: FIXaer = \"{FIXaer}\" FIXlut = \"{FIXlut}\" - FIXclim = \"{FIXclim}\"''',verbose=VERBOSE) - - check_for_preexist_dir_file(FIXclim,"delete") + FIXclim = \"{FIXclim}\"''', + verbose=VERBOSE, + ) + + check_for_preexist_dir_file(FIXclim, "delete") mkdir_vrfy("-p", FIXclim) - - cp_vrfy(os.path.join(FIXaer,"merra2.aerclim*.nc"), FIXclim) - cp_vrfy(os.path.join(FIXlut,"optics*.dat"), FIXclim) + + cp_vrfy(os.path.join(FIXaer, "merra2.aerclim*.nc"), FIXclim) + cp_vrfy(os.path.join(FIXlut, "optics*.dat"), FIXclim) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Copy templates of various input files to the experiment directory. # - #----------------------------------------------------------------------- - # - print_info_msg(f''' - Copying templates of various input files to the experiment directory...''', - verbose=VERBOSE) - - print_info_msg(f''' - Copying the template data table file to the experiment directory...''', - verbose=VERBOSE) - cp_vrfy(DATA_TABLE_TMPL_FP,DATA_TABLE_FP) - - print_info_msg(f''' - Copying the template field table file to the experiment directory...''', - verbose=VERBOSE) - cp_vrfy(FIELD_TABLE_TMPL_FP,FIELD_TABLE_FP) - - print_info_msg(f''' - Copying the template NEMS configuration file to the experiment directory...''', - verbose=VERBOSE) - cp_vrfy(NEMS_CONFIG_TMPL_FP,NEMS_CONFIG_FP) + # ----------------------------------------------------------------------- + # + print_info_msg( + f""" + Copying templates of various input files to the experiment directory...""", + verbose=VERBOSE, + ) + + print_info_msg( + f""" + Copying the template data table file to the experiment directory...""", + verbose=VERBOSE, + ) + cp_vrfy(DATA_TABLE_TMPL_FP, DATA_TABLE_FP) + + print_info_msg( + f""" + Copying the template field table file to the experiment directory...""", + verbose=VERBOSE, + ) + cp_vrfy(FIELD_TABLE_TMPL_FP, FIELD_TABLE_FP) + + print_info_msg( + f""" + Copying the template NEMS configuration file to the experiment directory...""", + verbose=VERBOSE, + ) + cp_vrfy(NEMS_CONFIG_TMPL_FP, NEMS_CONFIG_FP) # # Copy the CCPP physics suite definition file from its location in the # clone of the FV3 code repository to the experiment directory (EXPT- # DIR). # - print_info_msg(f''' + print_info_msg( + f""" Copying the CCPP physics suite definition XML file from its location in - the forecast model directory sturcture to the experiment directory...''', - verbose=VERBOSE) - cp_vrfy(CCPP_PHYS_SUITE_IN_CCPP_FP,CCPP_PHYS_SUITE_FP) + the forecast model directory sturcture to the experiment directory...""", + verbose=VERBOSE, + ) + cp_vrfy(CCPP_PHYS_SUITE_IN_CCPP_FP, CCPP_PHYS_SUITE_FP) # # Copy the field dictionary file from its location in the # clone of the FV3 code repository to the experiment directory (EXPT- # DIR). # - print_info_msg(f''' + print_info_msg( + f""" Copying the field dictionary file from its location in the forecast - model directory sturcture to the experiment directory...''', - verbose=VERBOSE) - cp_vrfy(FIELD_DICT_IN_UWM_FP,FIELD_DICT_FP) + model directory sturcture to the experiment directory...""", + verbose=VERBOSE, + ) + cp_vrfy(FIELD_DICT_IN_UWM_FP, FIELD_DICT_FP) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set parameters in the FV3-LAM namelist file. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - print_info_msg(f''' + print_info_msg( + f''' Setting parameters in weather model's namelist file (FV3_NML_FP): - FV3_NML_FP = \"{FV3_NML_FP}\"''') + FV3_NML_FP = \"{FV3_NML_FP}\"''' + ) # # Set npx and npy, which are just NX plus 1 and NY plus 1, respectively. # These need to be set in the FV3-LAM Fortran namelist file. They represent # the number of cell vertices in the x and y directions on the regional # grid. # - npx=NX+1 - npy=NY+1 + npx = NX + 1 + npy = NY + 1 # # For the physics suites that use RUC LSM, set the parameter kice to 9, # Otherwise, leave it unspecified (which means it gets set to the default @@ -593,28 +659,28 @@ def generate_FV3LAM_wflow(): # NOTE: # May want to remove kice from FV3.input.yml (and maybe input.nml.FV3). # - kice=None + kice = None if SDF_USES_RUC_LSM: - kice=9 + kice = 9 # - # Set lsoil, which is the number of input soil levels provided in the - # chgres_cube output NetCDF file. This is the same as the parameter - # nsoill_out in the namelist file for chgres_cube. [On the other hand, - # the parameter lsoil_lsm (not set here but set in input.nml.FV3 and/or + # Set lsoil, which is the number of input soil levels provided in the + # chgres_cube output NetCDF file. This is the same as the parameter + # nsoill_out in the namelist file for chgres_cube. [On the other hand, + # the parameter lsoil_lsm (not set here but set in input.nml.FV3 and/or # FV3.input.yml) is the number of soil levels that the LSM scheme in the # forecast model will run with.] Here, we use the same approach to set - # lsoil as the one used to set nsoill_out in exregional_make_ics.sh. + # lsoil as the one used to set nsoill_out in exregional_make_ics.sh. # See that script for details. # # NOTE: # May want to remove lsoil from FV3.input.yml (and maybe input.nml.FV3). # Also, may want to set lsm here as well depending on SDF_USES_RUC_LSM. # - lsoil=4 - if ( EXTRN_MDL_NAME_ICS == "HRRR" or \ - EXTRN_MDL_NAME_ICS == "RAP" ) and \ - ( SDF_USES_RUC_LSM ): - lsoil=9 + lsoil = 4 + if (EXTRN_MDL_NAME_ICS == "HRRR" or EXTRN_MDL_NAME_ICS == "RAP") and ( + SDF_USES_RUC_LSM + ): + lsoil = 9 # # Create a multiline variable that consists of a yaml-compliant string # specifying the values that the namelist variables that are physics- @@ -625,48 +691,48 @@ def generate_FV3LAM_wflow(): # IMPORTANT: # If we want a namelist variable to be removed from the namelist file, # in the "settings" variable below, we need to set its value to the - # string "null". This is equivalent to setting its value to + # string "null". This is equivalent to setting its value to # !!python/none - # in the base namelist file specified by FV3_NML_BASE_SUITE_FP or the + # in the base namelist file specified by FV3_NML_BASE_SUITE_FP or the # suite-specific yaml settings file specified by FV3_NML_YAML_CONFIG_FP. # # It turns out that setting the variable to an empty string also works # to remove it from the namelist! Which is better to use?? # settings = {} - settings['atmos_model_nml'] = { - 'blocksize': BLOCKSIZE, - 'ccpp_suite': CCPP_PHYS_SUITE + settings["atmos_model_nml"] = { + "blocksize": BLOCKSIZE, + "ccpp_suite": CCPP_PHYS_SUITE, } - settings['fv_core_nml'] = { - 'target_lon': LON_CTR, - 'target_lat': LAT_CTR, - 'nrows_blend': HALO_BLEND, - # - # Question: - # For a ESGgrid type grid, what should stretch_fac be set to? This depends - # on how the FV3 code uses the stretch_fac parameter in the namelist file. - # Recall that for a ESGgrid, it gets set in the function set_gridparams_ESGgrid(.sh) - # to something like 0.9999, but is it ok to set it to that here in the - # FV3 namelist file? - # - 'stretch_fac': STRETCH_FAC, - 'npx': npx, - 'npy': npy, - 'layout': [LAYOUT_X, LAYOUT_Y], - 'bc_update_interval': LBC_SPEC_INTVL_HRS + settings["fv_core_nml"] = { + "target_lon": LON_CTR, + "target_lat": LAT_CTR, + "nrows_blend": HALO_BLEND, + # + # Question: + # For a ESGgrid type grid, what should stretch_fac be set to? This depends + # on how the FV3 code uses the stretch_fac parameter in the namelist file. + # Recall that for a ESGgrid, it gets set in the function set_gridparams_ESGgrid(.sh) + # to something like 0.9999, but is it ok to set it to that here in the + # FV3 namelist file? + # + "stretch_fac": STRETCH_FAC, + "npx": npx, + "npy": npy, + "layout": [LAYOUT_X, LAYOUT_Y], + "bc_update_interval": LBC_SPEC_INTVL_HRS, } - settings['gfs_physics_nml'] = { - 'kice': kice or None, - 'lsoil': lsoil or None, - 'do_shum': DO_SHUM, - 'do_sppt': DO_SPPT, - 'do_skeb': DO_SKEB, - 'do_spp': DO_SPP, - 'n_var_spp': N_VAR_SPP, - 'n_var_lndp': N_VAR_LNDP, - 'lndp_type': LNDP_TYPE, - 'fhcyc': FHCYC_LSM_SPP_OR_NOT + settings["gfs_physics_nml"] = { + "kice": kice or None, + "lsoil": lsoil or None, + "do_shum": DO_SHUM, + "do_sppt": DO_SPPT, + "do_skeb": DO_SKEB, + "do_spp": DO_SPP, + "n_var_spp": N_VAR_SPP, + "n_var_lndp": N_VAR_LNDP, + "lndp_type": LNDP_TYPE, + "fhcyc": FHCYC_LSM_SPP_OR_NOT, } # # Add to "settings" the values of those namelist variables that specify @@ -678,140 +744,148 @@ def generate_FV3LAM_wflow(): # in the FIXam directory. Here, we loop through this array and process # each element to construct each line of "settings". # - dummy_run_dir=os.path.join(EXPTDIR,"any_cyc") + dummy_run_dir = os.path.join(EXPTDIR, "any_cyc") if DO_ENSEMBLE: - dummy_run_dir=os.path.join(dummy_run_dir,"any_ensmem") - - regex_search="^[ ]*([^| ]+)[ ]*[|][ ]*([^| ]+)[ ]*$" - num_nml_vars=len(FV3_NML_VARNAME_TO_FIXam_FILES_MAPPING) + dummy_run_dir = os.path.join(dummy_run_dir, "any_ensmem") + + regex_search = "^[ ]*([^| ]+)[ ]*[|][ ]*([^| ]+)[ ]*$" + num_nml_vars = len(FV3_NML_VARNAME_TO_FIXam_FILES_MAPPING) namsfc_dict = {} for i in range(num_nml_vars): - - mapping=f"{FV3_NML_VARNAME_TO_FIXam_FILES_MAPPING[i]}" - tup = find_pattern_in_str(regex_search, mapping) - nml_var_name = tup[0] - FIXam_fn = tup[1] - - fp="\"\"" - if FIXam_fn: - fp=os.path.join(FIXam,FIXam_fn) - # - # If not in NCO mode, for portability and brevity, change fp so that it - # is a relative path (relative to any cycle directory immediately under - # the experiment directory). - # - if RUN_ENVIR != "nco": - fp = os.path.relpath(os.path.realpath(fp), start=dummy_run_dir) - # - # Add a line to the variable "settings" that specifies (in a yaml-compliant - # format) the name of the current namelist variable and the value it should - # be set to. - # - namsfc_dict[nml_var_name] = fp + + mapping = f"{FV3_NML_VARNAME_TO_FIXam_FILES_MAPPING[i]}" + tup = find_pattern_in_str(regex_search, mapping) + nml_var_name = tup[0] + FIXam_fn = tup[1] + + fp = '""' + if FIXam_fn: + fp = os.path.join(FIXam, FIXam_fn) + # + # If not in NCO mode, for portability and brevity, change fp so that it + # is a relative path (relative to any cycle directory immediately under + # the experiment directory). + # + if RUN_ENVIR != "nco": + fp = os.path.relpath(os.path.realpath(fp), start=dummy_run_dir) + # + # Add a line to the variable "settings" that specifies (in a yaml-compliant + # format) the name of the current namelist variable and the value it should + # be set to. + # + namsfc_dict[nml_var_name] = fp # # Add namsfc_dict to settings # - settings['namsfc'] = namsfc_dict + settings["namsfc"] = namsfc_dict # # Use netCDF4 when running the North American 3-km domain due to file size. # if PREDEF_GRID_NAME == "RRFS_NA_3km": - settings['fms2_io_nml'] = { - 'netcdf_default_format': 'netcdf4' - } + settings["fms2_io_nml"] = {"netcdf_default_format": "netcdf4"} # # Add the relevant tendency-based stochastic physics namelist variables to - # "settings" when running with SPPT, SHUM, or SKEB turned on. If running - # with SPP or LSM SPP, set the "new_lscale" variable. Otherwise only + # "settings" when running with SPPT, SHUM, or SKEB turned on. If running + # with SPP or LSM SPP, set the "new_lscale" variable. Otherwise only # include an empty "nam_stochy" stanza. # nam_stochy_dict = {} if DO_SPPT: - nam_stochy_dict.update({ - 'iseed_sppt': ISEED_SPPT, - 'new_lscale': NEW_LSCALE, - 'sppt': SPPT_MAG, - 'sppt_logit': SPPT_LOGIT, - 'sppt_lscale': SPPT_LSCALE, - 'sppt_sfclimit': SPPT_SFCLIMIT, - 'sppt_tau': SPPT_TSCALE, - 'spptint': SPPT_INT, - 'use_zmtnblck': USE_ZMTNBLCK - }) - + nam_stochy_dict.update( + { + "iseed_sppt": ISEED_SPPT, + "new_lscale": NEW_LSCALE, + "sppt": SPPT_MAG, + "sppt_logit": SPPT_LOGIT, + "sppt_lscale": SPPT_LSCALE, + "sppt_sfclimit": SPPT_SFCLIMIT, + "sppt_tau": SPPT_TSCALE, + "spptint": SPPT_INT, + "use_zmtnblck": USE_ZMTNBLCK, + } + ) + if DO_SHUM: - nam_stochy_dict.update({ - 'iseed_shum': ISEED_SHUM, - 'new_lscale': NEW_LSCALE, - 'shum': SHUM_MAG, - 'shum_lscale': SHUM_LSCALE, - 'shum_tau': SHUM_TSCALE, - 'shumint': SHUM_INT - }) - + nam_stochy_dict.update( + { + "iseed_shum": ISEED_SHUM, + "new_lscale": NEW_LSCALE, + "shum": SHUM_MAG, + "shum_lscale": SHUM_LSCALE, + "shum_tau": SHUM_TSCALE, + "shumint": SHUM_INT, + } + ) + if DO_SKEB: - nam_stochy_dict.update({ - 'iseed_skeb': ISEED_SKEB, - 'new_lscale': NEW_LSCALE, - 'skeb': SKEB_MAG, - 'skeb_lscale': SKEB_LSCALE, - 'skebnorm': SKEBNORM, - 'skeb_tau': SKEB_TSCALE, - 'skebint': SKEB_INT, - 'skeb_vdof': SKEB_VDOF - }) - + nam_stochy_dict.update( + { + "iseed_skeb": ISEED_SKEB, + "new_lscale": NEW_LSCALE, + "skeb": SKEB_MAG, + "skeb_lscale": SKEB_LSCALE, + "skebnorm": SKEBNORM, + "skeb_tau": SKEB_TSCALE, + "skebint": SKEB_INT, + "skeb_vdof": SKEB_VDOF, + } + ) + if DO_SPP or DO_LSM_SPP: - nam_stochy_dict.update({ - 'new_lscale': NEW_LSCALE - }) + nam_stochy_dict.update({"new_lscale": NEW_LSCALE}) - settings['nam_stochy'] = nam_stochy_dict + settings["nam_stochy"] = nam_stochy_dict # - # Add the relevant SPP namelist variables to "settings" when running with + # Add the relevant SPP namelist variables to "settings" when running with # SPP turned on. Otherwise only include an empty "nam_sppperts" stanza. # nam_sppperts_dict = {} if DO_SPP: - nam_sppperts_dict = { - 'iseed_spp': ISEED_SPP, - 'spp_lscale': SPP_LSCALE, - 'spp_prt_list': SPP_MAG_LIST, - 'spp_sigtop1': SPP_SIGTOP1, - 'spp_sigtop2': SPP_SIGTOP2, - 'spp_stddev_cutoff': SPP_STDDEV_CUTOFF, - 'spp_tau': SPP_TSCALE, - 'spp_var_list': SPP_VAR_LIST - } - - settings['nam_sppperts'] = nam_sppperts_dict - # - # Add the relevant LSM SPP namelist variables to "settings" when running with + nam_sppperts_dict = { + "iseed_spp": ISEED_SPP, + "spp_lscale": SPP_LSCALE, + "spp_prt_list": SPP_MAG_LIST, + "spp_sigtop1": SPP_SIGTOP1, + "spp_sigtop2": SPP_SIGTOP2, + "spp_stddev_cutoff": SPP_STDDEV_CUTOFF, + "spp_tau": SPP_TSCALE, + "spp_var_list": SPP_VAR_LIST, + } + + settings["nam_sppperts"] = nam_sppperts_dict + # + # Add the relevant LSM SPP namelist variables to "settings" when running with # LSM SPP turned on. # nam_sfcperts_dict = {} if DO_LSM_SPP: - nam_sfcperts_dict = { - 'lndp_type': LNDP_TYPE, - 'lndp_model_type': LNDP_MODEL_TYPE, - 'lndp_tau': LSM_SPP_TSCALE, - 'lndp_lscale': LSM_SPP_LSCALE, - 'iseed_lndp': ISEED_LSM_SPP, - 'lndp_var_list': LSM_SPP_VAR_LIST, - 'lndp_prt_list': LSM_SPP_MAG_LIST - } - - settings['nam_sfcperts'] = nam_sfcperts_dict + nam_sfcperts_dict = { + "lndp_type": LNDP_TYPE, + "lndp_model_type": LNDP_MODEL_TYPE, + "lndp_tau": LSM_SPP_TSCALE, + "lndp_lscale": LSM_SPP_LSCALE, + "iseed_lndp": ISEED_LSM_SPP, + "lndp_var_list": LSM_SPP_VAR_LIST, + "lndp_prt_list": LSM_SPP_MAG_LIST, + } + + settings["nam_sfcperts"] = nam_sfcperts_dict settings_str = cfg_to_yaml_str(settings) - - print_info_msg(dedent(f''' - The variable \"settings\" specifying values of the weather model's - namelist variables has been set as follows: - - settings =\n\n''') + settings_str, verbose=VERBOSE) + + print_info_msg( + dedent( + f""" + The variable \"settings\" specifying values of the weather model's + namelist variables has been set as follows: + + settings =\n\n""" + ) + + settings_str, + verbose=VERBOSE, + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Call the set_namelist.py script to create a new FV3 namelist file (full # path specified by FV3_NML_FP) using the file FV3_NML_BASE_SUITE_FP as @@ -821,13 +895,27 @@ def generate_FV3LAM_wflow(): # and with additional physics-suite-independent modificaitons specified # in the variable "settings" set above. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # try: - set_namelist(["-q", "-n", FV3_NML_BASE_SUITE_FP, "-c", FV3_NML_YAML_CONFIG_FP, - CCPP_PHYS_SUITE, "-u", settings_str, "-o", FV3_NML_FP]) + set_namelist( + [ + "-q", + "-n", + FV3_NML_BASE_SUITE_FP, + "-c", + FV3_NML_YAML_CONFIG_FP, + CCPP_PHYS_SUITE, + "-u", + settings_str, + "-o", + FV3_NML_FP, + ] + ) except: - print_err_msg_exit(dedent(f''' + print_err_msg_exit( + dedent( + f""" Call to python script set_namelist.py to generate an FV3 namelist file failed. Parameters passed to this script are: Full path to base namelist file: @@ -839,7 +927,10 @@ def generate_FV3LAM_wflow(): Full path to output namelist file: FV3_NML_FP = \"{FV3_NML_FP}\" Namelist settings specified on command line:\n - settings =\n\n''') + settings_str) + settings =\n\n""" + ) + + settings_str + ) # # If not running the MAKE_GRID_TN task (which implies the workflow will # use pregenerated grid files), set the namelist variables specifying @@ -853,141 +944,147 @@ def generate_FV3LAM_wflow(): # configurations is not known until the grid is created. # if not RUN_TASK_MAKE_GRID: - - set_FV3nml_sfc_climo_filenames() + + set_FV3nml_sfc_climo_filenames() # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # To have a record of how this experiment/workflow was generated, copy # the experiment/workflow configuration file to the experiment directo- # ry. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - cp_vrfy(os.path.join(USHDIR,EXPT_CONFIG_FN), EXPTDIR) + cp_vrfy(os.path.join(USHDIR, EXPT_CONFIG_FN), EXPTDIR) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # For convenience, print out the commands that need to be issued on the # command line in order to launch the workflow and to check its status. # Also, print out the line that should be placed in the user's cron table # in order for the workflow to be continually resubmitted. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if WORKFLOW_MANAGER == "rocoto": - wflow_db_fn=f"{os.path.splitext(WFLOW_XML_FN)[0]}.db" - rocotorun_cmd=f"rocotorun -w {WFLOW_XML_FN} -d {wflow_db_fn} -v 10" - rocotostat_cmd=f"rocotostat -w {WFLOW_XML_FN} -d {wflow_db_fn} -v 10" - - print_info_msg(f''' + wflow_db_fn = f"{os.path.splitext(WFLOW_XML_FN)[0]}.db" + rocotorun_cmd = f"rocotorun -w {WFLOW_XML_FN} -d {wflow_db_fn} -v 10" + rocotostat_cmd = f"rocotostat -w {WFLOW_XML_FN} -d {wflow_db_fn} -v 10" + + print_info_msg( + f""" ======================================================================== ======================================================================== - + Experiment generation completed. The experiment directory is: - + EXPTDIR=\"{EXPTDIR}\" - + ======================================================================== ======================================================================== - ''') + """ + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If rocoto is required, print instructions on how to load and use it # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if WORKFLOW_MANAGER == "rocoto": - - print_info_msg(f''' - To launch the workflow, first ensure that you have a compatible version - of rocoto available. For most pre-configured platforms, rocoto can be - loaded via a module: - - > module load rocoto - - For more details on rocoto, see the User's Guide. - - To launch the workflow, first ensure that you have a compatible version - of rocoto loaded. For example, to load version 1.3.1 of rocoto, use - - > module load rocoto/1.3.1 - - (This version has been tested on hera; later versions may also work but - have not been tested.) - - To launch the workflow, change location to the experiment directory - (EXPTDIR) and issue the rocotrun command, as follows: - - > cd {EXPTDIR} - > {rocotorun_cmd} - - To check on the status of the workflow, issue the rocotostat command - (also from the experiment directory): - - > {rocotostat_cmd} - - Note that: - - 1) The rocotorun command must be issued after the completion of each - task in the workflow in order for the workflow to submit the next - task(s) to the queue. - - 2) In order for the output of the rocotostat command to be up-to-date, - the rocotorun command must be issued immediately before issuing the - rocotostat command. - - For automatic resubmission of the workflow (say every 3 minutes), the - following line can be added to the user's crontab (use \"crontab -e\" to - edit the cron table): - - */3 * * * * cd {EXPTDIR} && ./launch_FV3LAM_wflow.sh called_from_cron=\"TRUE\" - ''') + + print_info_msg( + f""" + To launch the workflow, first ensure that you have a compatible version + of rocoto available. For most pre-configured platforms, rocoto can be + loaded via a module: + + > module load rocoto + + For more details on rocoto, see the User's Guide. + + To launch the workflow, first ensure that you have a compatible version + of rocoto loaded. For example, to load version 1.3.1 of rocoto, use + + > module load rocoto/1.3.1 + + (This version has been tested on hera; later versions may also work but + have not been tested.) + + To launch the workflow, change location to the experiment directory + (EXPTDIR) and issue the rocotrun command, as follows: + + > cd {EXPTDIR} + > {rocotorun_cmd} + + To check on the status of the workflow, issue the rocotostat command + (also from the experiment directory): + + > {rocotostat_cmd} + + Note that: + + 1) The rocotorun command must be issued after the completion of each + task in the workflow in order for the workflow to submit the next + task(s) to the queue. + + 2) In order for the output of the rocotostat command to be up-to-date, + the rocotorun command must be issued immediately before issuing the + rocotostat command. + + For automatic resubmission of the workflow (say every 3 minutes), the + following line can be added to the user's crontab (use \"crontab -e\" to + edit the cron table): + + */3 * * * * cd {EXPTDIR} && ./launch_FV3LAM_wflow.sh called_from_cron=\"TRUE\" + """ + ) # # If necessary, run the NOMADS script to source external model data. # if NOMADS: - print("Getting NOMADS online data") - print(f"NOMADS_file_type= {NOMADS_file_type}") - cd_vrfy(EXPTDIR) - NOMADS_script = os.path.join(USHDIR, "NOMADS_get_extrn_mdl_files.h") - run_command(f'''{NOMADS_script} {date_to_str(DATE_FIRST_CYCL,format="%Y%m%d")} \ - {CYCL_HRS} {NOMADS_file_type} {FCST_LEN_HRS} {LBC_SPEC_INTVL_HRS}''') + print("Getting NOMADS online data") + print(f"NOMADS_file_type= {NOMADS_file_type}") + cd_vrfy(EXPTDIR) + NOMADS_script = os.path.join(USHDIR, "NOMADS_get_extrn_mdl_files.h") + run_command( + f"""{NOMADS_script} {date_to_str(DATE_FIRST_CYCL,format="%Y%m%d")} \ + {CYCL_HRS} {NOMADS_file_type} {FCST_LEN_HRS} {LBC_SPEC_INTVL_HRS}""" + ) # -#----------------------------------------------------------------------- +# ----------------------------------------------------------------------- # # Start of the script that will call the experiment/workflow generation # function defined above. # -#----------------------------------------------------------------------- +# ----------------------------------------------------------------------- # if __name__ == "__main__": # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set directories. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - ushdir=os.path.dirname(os.path.abspath(__file__)) + ushdir = os.path.dirname(os.path.abspath(__file__)) # # Set the name of and full path to the temporary file in which we will # save some experiment/workflow variables. The need for this temporary # file is explained below. # - tmp_fn="tmp" - tmp_fp=os.path.join(ushdir, tmp_fn) - rm_vrfy("-f",tmp_fp) + tmp_fn = "tmp" + tmp_fp = os.path.join(ushdir, tmp_fn) + rm_vrfy("-f", tmp_fp) # # Set the name of and full path to the log file in which the output from # the experiment/workflow generation function will be saved. # - log_fn="log.generate_FV3LAM_wflow" - log_fp=os.path.join(ushdir, log_fn) - rm_vrfy("-f",log_fp) + log_fn = "log.generate_FV3LAM_wflow" + log_fp = os.path.join(ushdir, log_fn) + rm_vrfy("-f", log_fp) # # Call the generate_FV3LAM_wflow function defined above to generate the # experiment/workflow. Note that we pipe the output of the function @@ -1002,9 +1099,9 @@ def generate_FV3LAM_wflow(): # temporary file and read them in outside the subshell later below. # def workflow_func(): - retval=1 + retval = 1 generate_FV3LAM_wflow() - retval=0 + retval = 0 run_command(f'''echo "{EXPTDIR}" >> "{tmp_fp}"''') run_command(f'''echo "{retval}" >> "{tmp_fp}"''') @@ -1013,7 +1110,7 @@ def workflow_func(): os.dup2(tee.stdin.fileno(), sys.stdout.fileno()) os.dup2(tee.stdin.fileno(), sys.stderr.fileno()) - #create workflow process + # create workflow process p = Process(target=workflow_func) p.start() p.join() @@ -1026,8 +1123,8 @@ def workflow_func(): # place in a subshell (due to the fact that we are then piping its out- # put to the "tee" command). Then remove the temporary file. # - (_,exptdir,_)=run_command(f'''sed "1q;d" "{tmp_fp}"''') - (_,retval,_)=run_command(f''' sed "2q;d" "{tmp_fp}"''') + (_, exptdir, _) = run_command(f'''sed "1q;d" "{tmp_fp}"''') + (_, retval, _) = run_command(f''' sed "2q;d" "{tmp_fp}"''') if retval: retval = int(retval) else: @@ -1039,16 +1136,17 @@ def workflow_func(): # the function to the experiment directory. # if retval == 0: - mv_vrfy(log_fp,exptdir) + mv_vrfy(log_fp, exptdir) # # If the call to the generate_FV3LAM_wflow function above was not suc- # cessful, print out an error message and exit with a nonzero return # code. # else: - print_err_msg_exit(f''' - Experiment generation failed. Check the log file from the ex- - periment/workflow generation script in the file specified by log_fp: - log_fp = \"{log_fp}\" - Stopping.''') - + print_err_msg_exit( + f""" + Experiment generation failed. Check the log file from the ex- + periment/workflow generation script in the file specified by log_fp: + log_fp = \"{log_fp}\" + Stopping.""" + ) diff --git a/ush/get_crontab_contents.py b/ush/get_crontab_contents.py index 69bdad9faa..a6d7693989 100644 --- a/ush/get_crontab_contents.py +++ b/ush/get_crontab_contents.py @@ -6,16 +6,23 @@ import argparse from datetime import datetime -from python_utils import import_vars, set_env_var, print_input_args, \ - run_command, define_macos_utilities, print_info_msg +from python_utils import ( + import_vars, + set_env_var, + print_input_args, + run_command, + define_macos_utilities, + print_info_msg, +) + def get_crontab_contents(called_from_cron): """ #----------------------------------------------------------------------- # - # This function returns the contents of the user's + # This function returns the contents of the user's # cron table as well as the command to use to manipulate the cron table - # (i.e. the "crontab" command, but on some platforms the version or + # (i.e. the "crontab" command, but on some platforms the version or # location of this may change depending on other circumstances, e.g. on # Cheyenne, this depends on whether a script that wants to call "crontab" # is itself being called from a cron job). Arguments are as follows: @@ -30,40 +37,41 @@ def get_crontab_contents(called_from_cron): # the system "crontab" command. # # outvarname_crontab_contents: - # Name of the output variable that will contain the contents of the + # Name of the output variable that will contain the contents of the # user's cron table. - # + # #----------------------------------------------------------------------- """ - + print_input_args(locals()) - #import selected env vars + # import selected env vars IMPORTS = ["MACHINE", "USER"] import_vars(env_vars=IMPORTS) - - __crontab_cmd__="crontab" + + __crontab_cmd__ = "crontab" # - # On Cheyenne, simply typing "crontab" will launch the crontab command - # at "/glade/u/apps/ch/opt/usr/bin/crontab". This is a containerized - # version of crontab that will work if called from scripts that are - # themselves being called as cron jobs. In that case, we must instead + # On Cheyenne, simply typing "crontab" will launch the crontab command + # at "/glade/u/apps/ch/opt/usr/bin/crontab". This is a containerized + # version of crontab that will work if called from scripts that are + # themselves being called as cron jobs. In that case, we must instead # call the system version of crontab at /usr/bin/crontab. # if MACHINE == "CHEYENNE": - if called_from_cron: - __crontab_cmd__="/usr/bin/crontab" - (_,__crontab_contents__,_)=run_command(f'''{__crontab_cmd__} -l''') - + if called_from_cron: + __crontab_cmd__ = "/usr/bin/crontab" + (_, __crontab_contents__, _) = run_command(f"""{__crontab_cmd__} -l""") + # replace single quotes (hopefully in comments) with double quotes __crontab_contents__ = __crontab_contents__.replace("'", '"') return __crontab_cmd__, __crontab_contents__ + def add_crontab_line(): - """ Add crontab line to cron table """ + """Add crontab line to cron table""" - #import selected env vars + # import selected env vars IMPORTS = ["MACHINE", "USER", "CRONTAB_LINE", "VERBOSE", "EXPTDIR"] import_vars(env_vars=IMPORTS) @@ -71,100 +79,123 @@ def add_crontab_line(): # Make a backup copy of the user's crontab file and save it in a file. # time_stamp = datetime.now().strftime("%F_%T") - crontab_backup_fp=os.path.join(EXPTDIR,f"crontab.bak.{time_stamp}") - print_info_msg(f''' - Copying contents of user cron table to backup file: - crontab_backup_fp = \"{crontab_backup_fp}\"''',verbose=VERBOSE) + crontab_backup_fp = os.path.join(EXPTDIR, f"crontab.bak.{time_stamp}") + print_info_msg( + f''' + Copying contents of user cron table to backup file: + crontab_backup_fp = \"{crontab_backup_fp}\"''', + verbose=VERBOSE, + ) global called_from_cron - try: called_from_cron - except: called_from_cron = False + try: + called_from_cron + except: + called_from_cron = False # Get crontab contents - crontab_cmd,crontab_contents = get_crontab_contents(called_from_cron=called_from_cron) + crontab_cmd, crontab_contents = get_crontab_contents( + called_from_cron=called_from_cron + ) # Create backup run_command(f'''printf "%s" '{crontab_contents}' > "{crontab_backup_fp}"''') - + # Add crontab line if CRONTAB_LINE in crontab_contents: - - print_info_msg(f''' - The following line already exists in the cron table and thus will not be - added: - CRONTAB_LINE = \"{CRONTAB_LINE}\"''') - + + print_info_msg( + f''' + The following line already exists in the cron table and thus will not be + added: + CRONTAB_LINE = \"{CRONTAB_LINE}\"''' + ) + else: - - print_info_msg(f''' - Adding the following line to the user's cron table in order to automatically - resubmit SRW workflow: - CRONTAB_LINE = \"{CRONTAB_LINE}\"''',verbose=VERBOSE) - - #add new line to crontab contents if it doesn't have one - NEWLINE_CHAR="" - if crontab_contents and crontab_contents[-1] != "\n": - NEWLINE_CHAR="\n" - - #add the crontab line - run_command(f'''printf "%s%b%s\n" '{crontab_contents}' '{NEWLINE_CHAR}' '{CRONTAB_LINE}' | {crontab_cmd}''') + + print_info_msg( + f''' + Adding the following line to the user's cron table in order to automatically + resubmit SRW workflow: + CRONTAB_LINE = \"{CRONTAB_LINE}\"''', + verbose=VERBOSE, + ) + + # add new line to crontab contents if it doesn't have one + NEWLINE_CHAR = "" + if crontab_contents and crontab_contents[-1] != "\n": + NEWLINE_CHAR = "\n" + + # add the crontab line + run_command( + f"""printf "%s%b%s\n" '{crontab_contents}' '{NEWLINE_CHAR}' '{CRONTAB_LINE}' | {crontab_cmd}""" + ) + def delete_crontab_line(called_from_cron): - """ Delete crontab line after job is complete i.e. either SUCCESS/FAILURE + """Delete crontab line after job is complete i.e. either SUCCESS/FAILURE but not IN PROGRESS status""" print_input_args(locals()) - - #import selected env vars + + # import selected env vars IMPORTS = ["MACHINE", "USER", "CRONTAB_LINE"] import_vars(env_vars=IMPORTS) # - # Get the full contents of the user's cron table. + # Get the full contents of the user's cron table. # - (crontab_cmd,crontab_contents) = get_crontab_contents(called_from_cron) + (crontab_cmd, crontab_contents) = get_crontab_contents(called_from_cron) # - # Remove the line in the contents of the cron table corresponding to the + # Remove the line in the contents of the cron table corresponding to the # current forecast experiment (if that line is part of the contents). # Then record the results back into the user's cron table. # - if (CRONTAB_LINE + '\n') in crontab_contents: - crontab_contents = crontab_contents.replace(CRONTAB_LINE+'\n','') + if (CRONTAB_LINE + "\n") in crontab_contents: + crontab_contents = crontab_contents.replace(CRONTAB_LINE + "\n", "") else: - crontab_contents = crontab_contents.replace(CRONTAB_LINE,'') + crontab_contents = crontab_contents.replace(CRONTAB_LINE, "") + + run_command(f"""echo '{crontab_contents}' | {crontab_cmd}""") - run_command(f'''echo '{crontab_contents}' | {crontab_cmd}''') def parse_args(argv): - """ Parse command line arguments for deleting crontab line. + """Parse command line arguments for deleting crontab line. This is needed because it is called from shell script """ - parser = argparse.ArgumentParser( - description='Crontab job manupilation program.' + parser = argparse.ArgumentParser(description="Crontab job manupilation program.") + + parser.add_argument( + "-d", + "--delete", + dest="delete", + action="store_true", + help="Delete crontab line.", ) - parser.add_argument('-d', '--delete', - dest='delete', - action='store_true', - help='Delete crontab line.') - - parser.add_argument('-c', '--called-from-cron', - dest='called_from_cron', - action='store_true', - help='Called from cron.') + parser.add_argument( + "-c", + "--called-from-cron", + dest="called_from_cron", + action="store_true", + help="Called from cron.", + ) return parser.parse_args(argv) -if __name__ == '__main__': + +if __name__ == "__main__": args = parse_args(sys.argv[1:]) if args.delete: - delete_crontab_line(args.called_from_cron) - + delete_crontab_line(args.called_from_cron) + + class Testing(unittest.TestCase): def test_get_crontab_contents(self): - crontab_cmd,crontab_contents = get_crontab_contents(called_from_cron=True) + crontab_cmd, crontab_contents = get_crontab_contents(called_from_cron=True) self.assertEqual(crontab_cmd, "crontab") + def setUp(self): - define_macos_utilities(); - set_env_var('DEBUG',False) - set_env_var('MACHINE', 'HERA') + define_macos_utilities() + set_env_var("DEBUG", False) + set_env_var("MACHINE", "HERA") diff --git a/ush/link_fix.py b/ush/link_fix.py index 56fccc8567..ea6503da0d 100755 --- a/ush/link_fix.py +++ b/ush/link_fix.py @@ -6,13 +6,25 @@ import argparse import glob -from python_utils import import_vars, set_env_var, print_input_args, \ - print_info_msg, print_err_msg_exit, create_symlink_to_file, \ - define_macos_utilities, check_var_valid_value, \ - cd_vrfy, mkdir_vrfy, find_pattern_in_str, load_shell_config +from python_utils import ( + import_vars, + set_env_var, + print_input_args, + print_info_msg, + print_err_msg_exit, + create_symlink_to_file, + define_macos_utilities, + check_var_valid_value, + flatten_dict, + cd_vrfy, + mkdir_vrfy, + find_pattern_in_str, + load_shell_config, +) + def link_fix(verbose, file_group): - """ This file defines a function that ... + """This file defines a function that ... Args: verbose: True or False file_group: could be on of ["grid", "orog", "sfc_climo"] @@ -22,30 +34,31 @@ def link_fix(verbose, file_group): print_input_args(locals()) - valid_vals_file_group=["grid", "orog", "sfc_climo"] + valid_vals_file_group = ["grid", "orog", "sfc_climo"] check_var_valid_value(file_group, valid_vals_file_group) - #import all environement variables + # import all environement variables import_vars() # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Create symlinks in the FIXLAM directory pointing to the grid files. # These symlinks are needed by the make_orog, make_sfc_climo, make_ic, # make_lbc, and/or run_fcst tasks. # - # Note that we check that each target file exists before attempting to + # Note that we check that each target file exists before attempting to # create symlinks. This is because the "ln" command will create sym- # links to non-existent targets without returning with a nonzero exit # code. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - print_info_msg(f'Creating links in the FIXLAM directory to the grid files...', - verbose=verbose) + print_info_msg( + f"Creating links in the FIXLAM directory to the grid files...", verbose=verbose + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Create globbing patterns for grid, orography, and surface climatology # files. @@ -57,7 +70,7 @@ def link_fix(verbose, file_group): # # 1) "C*.mosaic.halo${NHW}.nc" # This mosaic file for the wide-halo grid (i.e. the grid with a ${NHW}- - # cell-wide halo) is needed as an input to the orography filtering + # cell-wide halo) is needed as an input to the orography filtering # executable in the orography generation task. The filtering code # extracts from this mosaic file the name of the file containing the # grid on which it will generate filtered topography. Note that the @@ -71,28 +84,28 @@ def link_fix(verbose, file_group): # # a) C*.mosaic.halo${NHW}.nc # The script for the make_orog task extracts the name of the grid - # file from this mosaic file; this name should be + # file from this mosaic file; this name should be # "C*.grid.tile${TILE_RGNL}.halo${NHW}.nc". # # b) C*.grid.tile${TILE_RGNL}.halo${NHW}.nc - # This is the - # The script for the make_orog task passes the name of the grid - # file (extracted above from the mosaic file) to the orography + # This is the + # The script for the make_orog task passes the name of the grid + # file (extracted above from the mosaic file) to the orography # generation executable. The executable then # reads in this grid file and generates a raw orography # file on the grid. The raw orography file is initially renamed "out.oro.nc", # but for clarity, it is then renamed "C*.raw_orog.tile${TILE_RGNL}.halo${NHW}.nc". # - # c) The fixed files thirty.second.antarctic.new.bin, landcover30.fixed, + # c) The fixed files thirty.second.antarctic.new.bin, landcover30.fixed, # and gmted2010.30sec.int. # - # The orography filtering step in the make_orog task requires the + # The orography filtering step in the make_orog task requires the # following symlinks/files: # # a) C*.mosaic.halo${NHW}.nc # This is the mosaic file for the wide-halo grid. The orography # filtering executable extracts from this file the name of the grid - # file containing the wide-halo grid (which should be + # file containing the wide-halo grid (which should be # "${CRES}.grid.tile${TILE_RGNL}.halo${NHW}.nc"). The executable then # looks for this grid file IN THE DIRECTORY IN WHICH IT IS RUNNING. # Thus, before running the executable, the script creates a symlink in this run directory that @@ -100,7 +113,7 @@ def link_fix(verbose, file_group): # # b) C*.raw_orog.tile${TILE_RGNL}.halo${NHW}.nc # This is the raw orography file on the wide-halo grid. The script - # for the make_orog task copies this file to a new file named + # for the make_orog task copies this file to a new file named # "C*.filtered_orog.tile${TILE_RGNL}.halo${NHW}.nc" that will be # used as input to the orography filtering executable. The executable # will then overwrite the contents of this file with the filtered orography. @@ -126,7 +139,7 @@ def link_fix(verbose, file_group): # # 2) "C*.mosaic.halo${NH4}.nc" # This mosaic file for the grid with a 4-cell-wide halo is needed as - # an input to the surface climatology generation executable. The + # an input to the surface climatology generation executable. The # surface climatology generation code reads from this file the number # of tiles (which should be 1 for a regional grid) and the tile names. # More importantly, using the ESMF function ESMF_GridCreateMosaic(), @@ -145,123 +158,127 @@ def link_fix(verbose, file_group): # b) "C*.grid.tile${TILE_RGNL}.halo${NH4}.nc" # c) "C*.oro_data.tile${TILE_RGNL}.halo${NH4}.nc" # - # 3) + # 3) # # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # if file_group == "grid": - fns=[ - f"C*{DOT_OR_USCORE}mosaic.halo{NHW}.nc", - f"C*{DOT_OR_USCORE}mosaic.halo{NH4}.nc", - f"C*{DOT_OR_USCORE}mosaic.halo{NH3}.nc", - f"C*{DOT_OR_USCORE}grid.tile{TILE_RGNL}.halo{NHW}.nc", - f"C*{DOT_OR_USCORE}grid.tile{TILE_RGNL}.halo{NH3}.nc", - f"C*{DOT_OR_USCORE}grid.tile{TILE_RGNL}.halo{NH4}.nc" - ] - fps=[ os.path.join(GRID_DIR,itm) for itm in fns] - run_task=f"{RUN_TASK_MAKE_GRID}" + fns = [ + f"C*{DOT_OR_USCORE}mosaic.halo{NHW}.nc", + f"C*{DOT_OR_USCORE}mosaic.halo{NH4}.nc", + f"C*{DOT_OR_USCORE}mosaic.halo{NH3}.nc", + f"C*{DOT_OR_USCORE}grid.tile{TILE_RGNL}.halo{NHW}.nc", + f"C*{DOT_OR_USCORE}grid.tile{TILE_RGNL}.halo{NH3}.nc", + f"C*{DOT_OR_USCORE}grid.tile{TILE_RGNL}.halo{NH4}.nc", + ] + fps = [os.path.join(GRID_DIR, itm) for itm in fns] + run_task = f"{RUN_TASK_MAKE_GRID}" # elif file_group == "orog": - fns=[ - f"C*{DOT_OR_USCORE}oro_data.tile{TILE_RGNL}.halo{NH0}.nc", - f"C*{DOT_OR_USCORE}oro_data.tile{TILE_RGNL}.halo{NH4}.nc" - ] + fns = [ + f"C*{DOT_OR_USCORE}oro_data.tile{TILE_RGNL}.halo{NH0}.nc", + f"C*{DOT_OR_USCORE}oro_data.tile{TILE_RGNL}.halo{NH4}.nc", + ] if CCPP_PHYS_SUITE == "FV3_HRRR": - fns+=[ - f"C*{DOT_OR_USCORE}oro_data_ss.tile{TILE_RGNL}.halo{NH0}.nc", - f"C*{DOT_OR_USCORE}oro_data_ls.tile{TILE_RGNL}.halo{NH0}.nc", - ] - fps=[ os.path.join(OROG_DIR,itm) for itm in fns] - run_task=f"{RUN_TASK_MAKE_OROG}" + fns += [ + f"C*{DOT_OR_USCORE}oro_data_ss.tile{TILE_RGNL}.halo{NH0}.nc", + f"C*{DOT_OR_USCORE}oro_data_ls.tile{TILE_RGNL}.halo{NH0}.nc", + ] + fps = [os.path.join(OROG_DIR, itm) for itm in fns] + run_task = f"{RUN_TASK_MAKE_OROG}" # # The following list of symlinks (which have the same names as their # target files) need to be created made in order for the make_ics and # make_lbcs tasks (i.e. tasks involving chgres_cube) to work. # elif file_group == "sfc_climo": - num_fields=len(SFC_CLIMO_FIELDS) - fns=[None] * (2 * num_fields) + num_fields = len(SFC_CLIMO_FIELDS) + fns = [None] * (2 * num_fields) for i in range(num_fields): - ii=2*i - fns[ii]=f"C*.{SFC_CLIMO_FIELDS[i]}.tile{TILE_RGNL}.halo{NH0}.nc" - fns[ii+1]=f"C*.{SFC_CLIMO_FIELDS[i]}.tile{TILE_RGNL}.halo{NH4}.nc" - fps=[ os.path.join(SFC_CLIMO_DIR,itm) for itm in fns] - run_task=f"{RUN_TASK_MAKE_SFC_CLIMO}" + ii = 2 * i + fns[ii] = f"C*.{SFC_CLIMO_FIELDS[i]}.tile{TILE_RGNL}.halo{NH0}.nc" + fns[ii + 1] = f"C*.{SFC_CLIMO_FIELDS[i]}.tile{TILE_RGNL}.halo{NH4}.nc" + fps = [os.path.join(SFC_CLIMO_DIR, itm) for itm in fns] + run_task = f"{RUN_TASK_MAKE_SFC_CLIMO}" # # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Find all files matching the globbing patterns and make sure that they # all have the same resolution (an integer) in their names. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - i=0 - res_prev="" - res="" - fp_prev="" - + i = 0 + res_prev = "" + res = "" + fp_prev = "" + for pattern in fps: - files = glob.glob(pattern) - for fp in files: - - fn = os.path.basename(fp) - - regex_search = "^C([0-9]*).*" - res = find_pattern_in_str(regex_search, fn) - if res is None: - print_err_msg_exit(f''' - The resolution could not be extracted from the current file's name. The - full path to the file (fp) is: - fp = \"{fp}\" - This may be because fp contains the * globbing character, which would - imply that no files were found that match the globbing pattern specified - in fp.''') - else: - res = res[0] - - if ( i > 0 ) and ( res != res_prev ): - print_err_msg_exit(f''' - The resolutions (as obtained from the file names) of the previous and - current file (fp_prev and fp, respectively) are different: - fp_prev = \"{fp_prev}\" - fp = \"{fp}\" - Please ensure that all files have the same resolution.''') - - i=i+1 - fp_prev=f"{fp}" - res_prev=res - # - #----------------------------------------------------------------------- - # - # Replace the * globbing character in the set of globbing patterns with + files = glob.glob(pattern) + for fp in files: + + fn = os.path.basename(fp) + + regex_search = "^C([0-9]*).*" + res = find_pattern_in_str(regex_search, fn) + if res is None: + print_err_msg_exit( + f""" + The resolution could not be extracted from the current file's name. The + full path to the file (fp) is: + fp = \"{fp}\" + This may be because fp contains the * globbing character, which would + imply that no files were found that match the globbing pattern specified + in fp.""" + ) + else: + res = res[0] + + if (i > 0) and (res != res_prev): + print_err_msg_exit( + f""" + The resolutions (as obtained from the file names) of the previous and + current file (fp_prev and fp, respectively) are different: + fp_prev = \"{fp_prev}\" + fp = \"{fp}\" + Please ensure that all files have the same resolution.""" + ) + + i = i + 1 + fp_prev = f"{fp}" + res_prev = res + # + # ----------------------------------------------------------------------- + # + # Replace the * globbing character in the set of globbing patterns with # the resolution. This will result in a set of (full paths to) specific # files. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - fps=[ itm.replace('*',res) for itm in fps] + fps = [itm.replace("*", res) for itm in fps] # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # In creating the various symlinks below, it is convenient to work in + # In creating the various symlinks below, it is convenient to work in # the FIXLAM directory. We will change directory back to the original # later below. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - SAVE_DIR=os.getcwd() + SAVE_DIR = os.getcwd() cd_vrfy(FIXLAM) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # Use the set of full file paths generated above as the link targets to + # Use the set of full file paths generated above as the link targets to # create symlinks to these files in the FIXLAM directory. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If the task in consideration (which will be one of the pre-processing # tasks MAKE_GRID_TN, MAKE_OROG_TN, and MAKE_SFC_CLIMO_TN) was run, then @@ -269,131 +286,146 @@ def link_fix(verbose, file_group): # this case, we use relative symlinks in order the experiment directory # more portable and the symlinks more readable. However, if the task # was not run, then pregenerated grid, orography, or surface climatology - # files will be used, and those will be located in an arbitrary directory - # (specified by the user) that is somwehere outside the experiment - # directory. Thus, in this case, there isn't really an advantage to using + # files will be used, and those will be located in an arbitrary directory + # (specified by the user) that is somwehere outside the experiment + # directory. Thus, in this case, there isn't really an advantage to using # relative symlinks, so we use symlinks with absolute paths. # if run_task: - relative_link_flag=True + relative_link_flag = True else: - relative_link_flag=False - + relative_link_flag = False + for fp in fps: - fn=os.path.basename(fp) - create_symlink_to_file(fp,fn,relative_link_flag) + fn = os.path.basename(fp) + create_symlink_to_file(fp, fn, relative_link_flag) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set the C-resolution based on the resolution appearing in the file # names. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - cres=f"C{res}" + cres = f"C{res}" # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If considering grid files, create a symlink to the halo4 grid file # that does not contain the halo size in its name. This is needed by # the tasks that generate the initial and lateral boundary condition # files. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if file_group == "grid": - target=f"{cres}{DOT_OR_USCORE}grid.tile{TILE_RGNL}.halo{NH4}.nc" - symlink=f"{cres}{DOT_OR_USCORE}grid.tile{TILE_RGNL}.nc" - create_symlink_to_file(target,symlink,True) + target = f"{cres}{DOT_OR_USCORE}grid.tile{TILE_RGNL}.halo{NH4}.nc" + symlink = f"{cres}{DOT_OR_USCORE}grid.tile{TILE_RGNL}.nc" + create_symlink_to_file(target, symlink, True) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # If considering surface climatology files, create symlinks to the surface - # climatology files that do not contain the halo size in their names. + # If considering surface climatology files, create symlinks to the surface + # climatology files that do not contain the halo size in their names. # These are needed by the task that generates the initial condition files. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if file_group == "sfc_climo": - - tmp=[ f"{cres}.{itm}" for itm in SFC_CLIMO_FIELDS] - fns_sfc_climo_with_halo_in_fn=[ f"{itm}.tile{TILE_RGNL}.halo{NH4}.nc" for itm in tmp] - fns_sfc_climo_no_halo_in_fn=[ f"{itm}.tile{TILE_RGNL}.nc" for itm in tmp] - + + tmp = [f"{cres}.{itm}" for itm in SFC_CLIMO_FIELDS] + fns_sfc_climo_with_halo_in_fn = [ + f"{itm}.tile{TILE_RGNL}.halo{NH4}.nc" for itm in tmp + ] + fns_sfc_climo_no_halo_in_fn = [f"{itm}.tile{TILE_RGNL}.nc" for itm in tmp] + for i in range(num_fields): - target=f"{fns_sfc_climo_with_halo_in_fn[i]}" - symlink=f"{fns_sfc_climo_no_halo_in_fn[i]}" - create_symlink_to_file(target, symlink, True) - # - # In order to be able to specify the surface climatology file names in - # the forecast model's namelist file, in the FIXLAM directory a symlink - # must be created for each surface climatology field that has "tile1" in - # its name (and no "halo") and which points to the corresponding "tile7.halo0" - # file. - # - tmp=[ f"{cres}.{itm}" for itm in SFC_CLIMO_FIELDS ] - fns_sfc_climo_tile7_halo0_in_fn=[ f"{itm}.tile{TILE_RGNL}.halo{NH0}.nc" for itm in tmp ] - fns_sfc_climo_tile1_no_halo_in_fn=[ f"{itm}.tile1.nc" for itm in tmp ] - + target = f"{fns_sfc_climo_with_halo_in_fn[i]}" + symlink = f"{fns_sfc_climo_no_halo_in_fn[i]}" + create_symlink_to_file(target, symlink, True) + # + # In order to be able to specify the surface climatology file names in + # the forecast model's namelist file, in the FIXLAM directory a symlink + # must be created for each surface climatology field that has "tile1" in + # its name (and no "halo") and which points to the corresponding "tile7.halo0" + # file. + # + tmp = [f"{cres}.{itm}" for itm in SFC_CLIMO_FIELDS] + fns_sfc_climo_tile7_halo0_in_fn = [ + f"{itm}.tile{TILE_RGNL}.halo{NH0}.nc" for itm in tmp + ] + fns_sfc_climo_tile1_no_halo_in_fn = [f"{itm}.tile1.nc" for itm in tmp] + for i in range(num_fields): - target=f"{fns_sfc_climo_tile7_halo0_in_fn[i]}" - symlink=f"{fns_sfc_climo_tile1_no_halo_in_fn[i]}" - create_symlink_to_file(target,symlink,True) + target = f"{fns_sfc_climo_tile7_halo0_in_fn[i]}" + symlink = f"{fns_sfc_climo_tile1_no_halo_in_fn[i]}" + create_symlink_to_file(target, symlink, True) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Change directory back to original one. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # cd_vrfy(SAVE_DIR) return res - + + def parse_args(argv): - """ Parse command line arguments""" + """Parse command line arguments""" parser = argparse.ArgumentParser( - description='Creates symbolic links to FIX directories.' + description="Creates symbolic links to FIX directories." ) - parser.add_argument('-f', '--file-group', - dest='file_group', - required=True, - help='File group, could be one of ["grid", "orog", "sfc_climo"].') + parser.add_argument( + "-f", + "--file-group", + dest="file_group", + required=True, + help='File group, could be one of ["grid", "orog", "sfc_climo"].', + ) - parser.add_argument('-p', '--path-to-defns', - dest='path_to_defns', - required=True, - help='Path to var_defns file.') + parser.add_argument( + "-p", + "--path-to-defns", + dest="path_to_defns", + required=True, + help="Path to var_defns file.", + ) return parser.parse_args(argv) -if __name__ == '__main__': + +if __name__ == "__main__": args = parse_args(sys.argv[1:]) cfg = load_shell_config(args.path_to_defns) + cfg = flatten_dict(cfg) import_vars(dictionary=cfg) link_fix(VERBOSE, args.file_group) + class Testing(unittest.TestCase): def test_link_fix(self): res = link_fix(verbose=True, file_group="grid") - self.assertTrue( res == "3357") + self.assertTrue(res == "3357") + def setUp(self): define_macos_utilities() - TEST_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_data"); + TEST_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_data") FIXLAM = os.path.join(TEST_DIR, "expt", "fix_lam") - mkdir_vrfy("-p",FIXLAM) - set_env_var("FIXLAM",FIXLAM) - set_env_var("DOT_OR_USCORE","_") - set_env_var("TILE_RGNL",7) - set_env_var("NH0",0) - set_env_var("NHW",6) - set_env_var("NH4",4) - set_env_var("NH3",3) - set_env_var("GRID_DIR",TEST_DIR + os.sep + "RRFS_CONUS_3km") - set_env_var("RUN_TASK_MAKE_GRID","FALSE") - set_env_var("OROG_DIR",TEST_DIR + os.sep + "RRFS_CONUS_3km") - set_env_var("RUN_TASK_MAKE_OROG","FALSE") - set_env_var("SFC_CLIMO_DIR",TEST_DIR + os.sep + "RRFS_CONUS_3km") - set_env_var("RUN_TASK_MAKE_SFC_CLIMO","FALSE") - set_env_var("CCPP_PHYS_SUITE","FV3_GSD_SAR") + mkdir_vrfy("-p", FIXLAM) + set_env_var("FIXLAM", FIXLAM) + set_env_var("DOT_OR_USCORE", "_") + set_env_var("TILE_RGNL", 7) + set_env_var("NH0", 0) + set_env_var("NHW", 6) + set_env_var("NH4", 4) + set_env_var("NH3", 3) + set_env_var("GRID_DIR", TEST_DIR + os.sep + "RRFS_CONUS_3km") + set_env_var("RUN_TASK_MAKE_GRID", "FALSE") + set_env_var("OROG_DIR", TEST_DIR + os.sep + "RRFS_CONUS_3km") + set_env_var("RUN_TASK_MAKE_OROG", "FALSE") + set_env_var("SFC_CLIMO_DIR", TEST_DIR + os.sep + "RRFS_CONUS_3km") + set_env_var("RUN_TASK_MAKE_SFC_CLIMO", "FALSE") + set_env_var("CCPP_PHYS_SUITE", "FV3_GSD_SAR") diff --git a/ush/mrms_pull_topofhour.py b/ush/mrms_pull_topofhour.py index 3744242019..bfca98fb4e 100644 --- a/ush/mrms_pull_topofhour.py +++ b/ush/mrms_pull_topofhour.py @@ -5,84 +5,165 @@ import numpy as np import unittest -if __name__ == '__main__': - # Copy and unzip MRMS files that are closest to top of hour - # Done every hour on a 20-minute lag - - # Include option to define valid time on command line - # Used to backfill verification - #try: - valid_time = str(sys.argv[1]) - - YYYY = int(valid_time[0:4]) - MM = int(valid_time[4:6]) - DD = int(valid_time[6:8]) - HH = int(valid_time[8:19]) - - valid = datetime.datetime(YYYY,MM,DD,HH,0,0) - - #except IndexError: - # valid_time = None - - # Default to current hour if not defined on command line - #if valid_time is None: - # now = datetime.datetime.utcnow() - # YYYY = int(now.strftime('%Y')) - # MM = int(now.strftime('%m')) - # DD = int(now.strftime('%d')) - # HH = int(now.strftime('%H')) - - # valid = datetime.datetime(YYYY,MM,DD,HH,0,0) - # valid_time = valid.strftime('%Y%m%d%H') - - print('Pulling '+valid_time+' MRMS data') - - # Set up working directory - DATA_HEAD = str(sys.argv[2]) - MRMS_PROD_DIR = str(sys.argv[3]) - MRMS_PRODUCT = str(sys.argv[4]) - level = str(sys.argv[5]) - - VALID_DIR = os.path.join(DATA_HEAD,valid.strftime('%Y%m%d')) - if not os.path.exists(VALID_DIR): - os.makedirs(VALID_DIR) - os.chdir(DATA_HEAD) - - # Sort list of files for each MRMS product - print(valid.strftime('%Y%m%d')) - if valid.strftime('%Y%m%d') < '20200303': - search_path = MRMS_PROD_DIR+'/'+valid.strftime('%Y%m%d')+'/dcom/us007003/ldmdata/obs/upperair/mrms/conus/'+MRMS_PRODUCT+'/'+MRMS_PRODUCT+'*.gz' - elif valid.strftime('%Y%m%d') >= '20200303': - search_path = MRMS_PROD_DIR+'/'+valid.strftime('%Y%m%d')+'/upperair/mrms/conus/'+MRMS_PRODUCT+'/'+MRMS_PRODUCT+'*.gz' - file_list = [f for f in glob.glob(search_path)] - time_list = [file_list[x][-24:-9] for x in range(len(file_list))] - int_list = [int(time_list[x][0:8]+time_list[x][9:15]) for x in range(len(time_list))] - int_list.sort() - datetime_list = [datetime.datetime.strptime(str(x),"%Y%m%d%H%M%S") for x in int_list] - - # Find the MRMS file closest to the valid time - i = bisect.bisect_left(datetime_list,valid) - closest_timestamp = min(datetime_list[max(0, i-1): i+2], key=lambda date: abs(valid - date)) - - # Check to make sure closest file is within +/- 15 mins of top of the hour - # Copy and rename the file for future ease - difference = abs(closest_timestamp - valid) - if difference.total_seconds() <= 900: - filename1 = MRMS_PRODUCT+level+closest_timestamp.strftime('%Y%m%d-%H%M%S')+'.grib2.gz' - filename2 = MRMS_PRODUCT+level+valid.strftime('%Y%m%d-%H')+'0000.grib2.gz' - - if valid.strftime('%Y%m%d') < '20200303': - print('cp '+MRMS_PROD_DIR+'/'+valid.strftime('%Y%m%d')+'/dcom/us007003/ldmdata/obs/upperair/mrms/conus/'+MRMS_PRODUCT+'/'+filename1+' '+VALID_DIR+'/'+filename2) - - os.system('cp '+MRMS_PROD_DIR+'/'+valid.strftime('%Y%m%d')+'/dcom/us007003/ldmdata/obs/upperair/mrms/conus/'+MRMS_PRODUCT+'/'+filename1+' '+VALID_DIR+'/'+filename2) - os.system('gunzip '+VALID_DIR+'/'+filename2) - elif valid.strftime('%Y%m%d') >= '20200303': - print('cp '+MRMS_PROD_DIR+'/'+valid.strftime('%Y%m%d')+'/upperair/mrms/conus/'+MRMS_PRODUCT+'/'+filename1+' '+VALID_DIR+'/'+filename2) - - os.system('cp '+MRMS_PROD_DIR+'/'+valid.strftime('%Y%m%d')+'/upperair/mrms/conus/'+MRMS_PRODUCT+'/'+filename1+' '+VALID_DIR+'/'+filename2) - os.system('gunzip '+VALID_DIR+'/'+filename2) - -#dummy unittest +if __name__ == "__main__": + # Copy and unzip MRMS files that are closest to top of hour + # Done every hour on a 20-minute lag + + # Include option to define valid time on command line + # Used to backfill verification + # try: + valid_time = str(sys.argv[1]) + + YYYY = int(valid_time[0:4]) + MM = int(valid_time[4:6]) + DD = int(valid_time[6:8]) + HH = int(valid_time[8:19]) + + valid = datetime.datetime(YYYY, MM, DD, HH, 0, 0) + + # except IndexError: + # valid_time = None + + # Default to current hour if not defined on command line + # if valid_time is None: + # now = datetime.datetime.utcnow() + # YYYY = int(now.strftime('%Y')) + # MM = int(now.strftime('%m')) + # DD = int(now.strftime('%d')) + # HH = int(now.strftime('%H')) + + # valid = datetime.datetime(YYYY,MM,DD,HH,0,0) + # valid_time = valid.strftime('%Y%m%d%H') + + print("Pulling " + valid_time + " MRMS data") + + # Set up working directory + DATA_HEAD = str(sys.argv[2]) + MRMS_PROD_DIR = str(sys.argv[3]) + MRMS_PRODUCT = str(sys.argv[4]) + level = str(sys.argv[5]) + + VALID_DIR = os.path.join(DATA_HEAD, valid.strftime("%Y%m%d")) + if not os.path.exists(VALID_DIR): + os.makedirs(VALID_DIR) + os.chdir(DATA_HEAD) + + # Sort list of files for each MRMS product + print(valid.strftime("%Y%m%d")) + if valid.strftime("%Y%m%d") < "20200303": + search_path = ( + MRMS_PROD_DIR + + "/" + + valid.strftime("%Y%m%d") + + "/dcom/us007003/ldmdata/obs/upperair/mrms/conus/" + + MRMS_PRODUCT + + "/" + + MRMS_PRODUCT + + "*.gz" + ) + elif valid.strftime("%Y%m%d") >= "20200303": + search_path = ( + MRMS_PROD_DIR + + "/" + + valid.strftime("%Y%m%d") + + "/upperair/mrms/conus/" + + MRMS_PRODUCT + + "/" + + MRMS_PRODUCT + + "*.gz" + ) + file_list = [f for f in glob.glob(search_path)] + time_list = [file_list[x][-24:-9] for x in range(len(file_list))] + int_list = [ + int(time_list[x][0:8] + time_list[x][9:15]) for x in range(len(time_list)) + ] + int_list.sort() + datetime_list = [ + datetime.datetime.strptime(str(x), "%Y%m%d%H%M%S") for x in int_list + ] + + # Find the MRMS file closest to the valid time + i = bisect.bisect_left(datetime_list, valid) + closest_timestamp = min( + datetime_list[max(0, i - 1) : i + 2], key=lambda date: abs(valid - date) + ) + + # Check to make sure closest file is within +/- 15 mins of top of the hour + # Copy and rename the file for future ease + difference = abs(closest_timestamp - valid) + if difference.total_seconds() <= 900: + filename1 = ( + MRMS_PRODUCT + + level + + closest_timestamp.strftime("%Y%m%d-%H%M%S") + + ".grib2.gz" + ) + filename2 = MRMS_PRODUCT + level + valid.strftime("%Y%m%d-%H") + "0000.grib2.gz" + + if valid.strftime("%Y%m%d") < "20200303": + print( + "cp " + + MRMS_PROD_DIR + + "/" + + valid.strftime("%Y%m%d") + + "/dcom/us007003/ldmdata/obs/upperair/mrms/conus/" + + MRMS_PRODUCT + + "/" + + filename1 + + " " + + VALID_DIR + + "/" + + filename2 + ) + + os.system( + "cp " + + MRMS_PROD_DIR + + "/" + + valid.strftime("%Y%m%d") + + "/dcom/us007003/ldmdata/obs/upperair/mrms/conus/" + + MRMS_PRODUCT + + "/" + + filename1 + + " " + + VALID_DIR + + "/" + + filename2 + ) + os.system("gunzip " + VALID_DIR + "/" + filename2) + elif valid.strftime("%Y%m%d") >= "20200303": + print( + "cp " + + MRMS_PROD_DIR + + "/" + + valid.strftime("%Y%m%d") + + "/upperair/mrms/conus/" + + MRMS_PRODUCT + + "/" + + filename1 + + " " + + VALID_DIR + + "/" + + filename2 + ) + + os.system( + "cp " + + MRMS_PROD_DIR + + "/" + + valid.strftime("%Y%m%d") + + "/upperair/mrms/conus/" + + MRMS_PRODUCT + + "/" + + filename1 + + " " + + VALID_DIR + + "/" + + filename2 + ) + os.system("gunzip " + VALID_DIR + "/" + filename2) + +# dummy unittest class Testing(unittest.TestCase): - def test_mrms_pull_topfhour(self): - pass + def test_mrms_pull_topfhour(self): + pass diff --git a/ush/predef_grid_params.yaml b/ush/predef_grid_params.yaml index 5b3849fdd0..e4e8f77963 100644 --- a/ush/predef_grid_params.yaml +++ b/ush/predef_grid_params.yaml @@ -65,20 +65,20 @@ LAYOUT_X: 5 LAYOUT_Y: 2 BLOCKSIZE: 40 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 2 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: -97.5 - WRTCMP_cen_lat: 38.5 - WRTCMP_stdlat1: 38.5 - WRTCMP_stdlat2: 38.5 - WRTCMP_nx: 217 - WRTCMP_ny: 128 - WRTCMP_lon_lwr_left: -122.719528 - WRTCMP_lat_lwr_left: 21.138123 - WRTCMP_dx: 25000.0 - WRTCMP_dy: 25000.0 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 2 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: -97.5 + WRTCMP_cen_lat: 38.5 + WRTCMP_stdlat1: 38.5 + WRTCMP_stdlat2: 38.5 + WRTCMP_nx: 217 + WRTCMP_ny: 128 + WRTCMP_lon_lwr_left: -122.719528 + WRTCMP_lat_lwr_left: 21.138123 + WRTCMP_dx: 25000.0 + WRTCMP_dy: 25000.0 # #----------------------------------------------------------------------- # @@ -100,20 +100,20 @@ LAYOUT_X: 5 LAYOUT_Y: 2 BLOCKSIZE: 40 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 2 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: -97.5 - WRTCMP_cen_lat: 38.5 - WRTCMP_stdlat1: 38.5 - WRTCMP_stdlat2: 38.5 - WRTCMP_nx: 199 - WRTCMP_ny: 111 - WRTCMP_lon_lwr_left: -121.23349066 - WRTCMP_lat_lwr_left: 23.41731593 - WRTCMP_dx: 25000.0 - WRTCMP_dy: 25000.0 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 2 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: -97.5 + WRTCMP_cen_lat: 38.5 + WRTCMP_stdlat1: 38.5 + WRTCMP_stdlat2: 38.5 + WRTCMP_nx: 199 + WRTCMP_ny: 111 + WRTCMP_lon_lwr_left: -121.23349066 + WRTCMP_lat_lwr_left: 23.41731593 + WRTCMP_dx: 25000.0 + WRTCMP_dy: 25000.0 # #----------------------------------------------------------------------- # @@ -135,20 +135,20 @@ LAYOUT_X: 16 LAYOUT_Y: 10 BLOCKSIZE: 32 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 10 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: -97.5 - WRTCMP_cen_lat: 38.5 - WRTCMP_stdlat1: 38.5 - WRTCMP_stdlat2: 38.5 - WRTCMP_nx: 416 - WRTCMP_ny: 245 - WRTCMP_lon_lwr_left: -122.719528 - WRTCMP_lat_lwr_left: 21.138123 - WRTCMP_dx: 13000.0 - WRTCMP_dy: 13000.0 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 10 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: -97.5 + WRTCMP_cen_lat: 38.5 + WRTCMP_stdlat1: 38.5 + WRTCMP_stdlat2: 38.5 + WRTCMP_nx: 416 + WRTCMP_ny: 245 + WRTCMP_lon_lwr_left: -122.719528 + WRTCMP_lat_lwr_left: 21.138123 + WRTCMP_dx: 13000.0 + WRTCMP_dy: 13000.0 # #----------------------------------------------------------------------- # @@ -170,20 +170,20 @@ LAYOUT_X: 16 LAYOUT_Y: 10 BLOCKSIZE: 32 - # if QUILTING = TRUE - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 16 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: -97.5 - WRTCMP_cen_lat: 38.5 - WRTCMP_stdlat1: 38.5 - WRTCMP_stdlat2: 38.5 - WRTCMP_nx: 393 - WRTCMP_ny: 225 - WRTCMP_lon_lwr_left: -121.70231097 - WRTCMP_lat_lwr_left: 22.57417972 - WRTCMP_dx: 13000.0 - WRTCMP_dy: 13000.0 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 16 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: -97.5 + WRTCMP_cen_lat: 38.5 + WRTCMP_stdlat1: 38.5 + WRTCMP_stdlat2: 38.5 + WRTCMP_nx: 393 + WRTCMP_ny: 225 + WRTCMP_lon_lwr_left: -121.70231097 + WRTCMP_lat_lwr_left: 22.57417972 + WRTCMP_dx: 13000.0 + WRTCMP_dy: 13000.0 # #----------------------------------------------------------------------- # @@ -205,20 +205,20 @@ LAYOUT_X: 28 LAYOUT_Y: 28 BLOCKSIZE: 29 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 28 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: -97.5 - WRTCMP_cen_lat: 38.5 - WRTCMP_stdlat1: 38.5 - WRTCMP_stdlat2: 38.5 - WRTCMP_nx: 1799 - WRTCMP_ny: 1059 - WRTCMP_lon_lwr_left: -122.719528 - WRTCMP_lat_lwr_left: 21.138123 - WRTCMP_dx: 3000.0 - WRTCMP_dy: 3000.0 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 28 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: -97.5 + WRTCMP_cen_lat: 38.5 + WRTCMP_stdlat1: 38.5 + WRTCMP_stdlat2: 38.5 + WRTCMP_nx: 1799 + WRTCMP_ny: 1059 + WRTCMP_lon_lwr_left: -122.719528 + WRTCMP_lat_lwr_left: 21.138123 + WRTCMP_dx: 3000.0 + WRTCMP_dy: 3000.0 # #----------------------------------------------------------------------- # @@ -240,20 +240,20 @@ LAYOUT_X: 30 LAYOUT_Y: 16 BLOCKSIZE: 32 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 16 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: -97.5 - WRTCMP_cen_lat: 38.5 - WRTCMP_stdlat1: 38.5 - WRTCMP_stdlat2: 38.5 - WRTCMP_nx: 1746 - WRTCMP_ny: 1014 - WRTCMP_lon_lwr_left: -122.17364391 - WRTCMP_lat_lwr_left: 21.88588562 - WRTCMP_dx: 3000.0 - WRTCMP_dy: 3000.0 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 16 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: -97.5 + WRTCMP_cen_lat: 38.5 + WRTCMP_stdlat1: 38.5 + WRTCMP_stdlat2: 38.5 + WRTCMP_nx: 1746 + WRTCMP_ny: 1014 + WRTCMP_lon_lwr_left: -122.17364391 + WRTCMP_lat_lwr_left: 21.88588562 + WRTCMP_dx: 3000.0 + WRTCMP_dy: 3000.0 # #----------------------------------------------------------------------- # @@ -275,20 +275,20 @@ LAYOUT_X: 30 LAYOUT_Y: 24 BLOCKSIZE: 35 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 24 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: -97.5 - WRTCMP_cen_lat: 35.0 - WRTCMP_stdlat1: 35.0 - WRTCMP_stdlat2: 35.0 - WRTCMP_nx: 837 - WRTCMP_ny: 595 - WRTCMP_lon_lwr_left: -109.97410429 - WRTCMP_lat_lwr_left: 26.31459843 - WRTCMP_dx: 3000.0 - WRTCMP_dy: 3000.0 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 24 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: -97.5 + WRTCMP_cen_lat: 35.0 + WRTCMP_stdlat1: 35.0 + WRTCMP_stdlat2: 35.0 + WRTCMP_nx: 837 + WRTCMP_ny: 595 + WRTCMP_lon_lwr_left: -109.97410429 + WRTCMP_lat_lwr_left: 26.31459843 + WRTCMP_dx: 3000.0 + WRTCMP_dy: 3000.0 # #----------------------------------------------------------------------- # @@ -312,20 +312,20 @@ LAYOUT_X: 5 LAYOUT_Y: 5 BLOCKSIZE: 40 - #if QUILTING : True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 5 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: -86.16 - WRTCMP_cen_lat: 39.77 - WRTCMP_stdlat1: 39.77 - WRTCMP_stdlat2: 39.77 - WRTCMP_nx: 197 - WRTCMP_ny: 197 - WRTCMP_lon_lwr_left: -89.47120417 - WRTCMP_lat_lwr_left: 37.07809642 - WRTCMP_dx: 3000.0 - WRTCMP_dy: 3000.0 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 5 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: -86.16 + WRTCMP_cen_lat: 39.77 + WRTCMP_stdlat1: 39.77 + WRTCMP_stdlat2: 39.77 + WRTCMP_nx: 197 + WRTCMP_ny: 197 + WRTCMP_lon_lwr_left: -89.47120417 + WRTCMP_lat_lwr_left: 37.07809642 + WRTCMP_dx: 3000.0 + WRTCMP_dy: 3000.0 # #----------------------------------------------------------------------- # @@ -350,20 +350,20 @@ LAYOUT_X: 16 LAYOUT_Y: 12 BLOCKSIZE: 40 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 12 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: -161.5 - WRTCMP_cen_lat: 63.0 - WRTCMP_stdlat1: 63.0 - WRTCMP_stdlat2: 63.0 - WRTCMP_nx: 318 - WRTCMP_ny: 234 - WRTCMP_lon_lwr_left: 172.23339164 - WRTCMP_lat_lwr_left: 45.77691870 - WRTCMP_dx: 13000.0 - WRTCMP_dy: 13000.0 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 12 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: -161.5 + WRTCMP_cen_lat: 63.0 + WRTCMP_stdlat1: 63.0 + WRTCMP_stdlat2: 63.0 + WRTCMP_nx: 318 + WRTCMP_ny: 234 + WRTCMP_lon_lwr_left: 172.23339164 + WRTCMP_lat_lwr_left: 45.77691870 + WRTCMP_dx: 13000.0 + WRTCMP_dy: 13000.0 # #----------------------------------------------------------------------- # @@ -388,20 +388,20 @@ LAYOUT_X: 30 LAYOUT_Y: 17 BLOCKSIZE: 40 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 17 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: -161.5 - WRTCMP_cen_lat: 63.0 - WRTCMP_stdlat1: 63.0 - WRTCMP_stdlat2: 63.0 - WRTCMP_nx: 1379 - WRTCMP_ny: 1003 - WRTCMP_lon_lwr_left: -187.89737923 - WRTCMP_lat_lwr_left: 45.84576053 - WRTCMP_dx: 3000.0 - WRTCMP_dy: 3000.0 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 17 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: -161.5 + WRTCMP_cen_lat: 63.0 + WRTCMP_stdlat1: 63.0 + WRTCMP_stdlat2: 63.0 + WRTCMP_nx: 1379 + WRTCMP_ny: 1003 + WRTCMP_lon_lwr_left: -187.89737923 + WRTCMP_lat_lwr_left: 45.84576053 + WRTCMP_dx: 3000.0 + WRTCMP_dy: 3000.0 # #----------------------------------------------------------------------- # @@ -431,20 +431,20 @@ LAYOUT_X: 18 LAYOUT_Y: 12 BLOCKSIZE: 30 - # if QUILTING = True - WRTCMP_write_groups: "1" - WRTCMP_write_tasks_per_group: 12 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: -97.5 - WRTCMP_cen_lat: 38.5 - WRTCMP_stdlat1: 38.5 - WRTCMP_stdlat2: 38.5 - WRTCMP_nx: 301 - WRTCMP_ny: 301 - WRTCMP_lon_lwr_left: -102.3802487 - WRTCMP_lat_lwr_left: 34.3407918 - WRTCMP_dx: 3000.0 - WRTCMP_dy: 3000.0 + QUILTING: + WRTCMP_write_groups: "1" + WRTCMP_write_tasks_per_group: 12 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: -97.5 + WRTCMP_cen_lat: 38.5 + WRTCMP_stdlat1: 38.5 + WRTCMP_stdlat2: 38.5 + WRTCMP_nx: 301 + WRTCMP_ny: 301 + WRTCMP_lon_lwr_left: -102.3802487 + WRTCMP_lat_lwr_left: 34.3407918 + WRTCMP_dx: 3000.0 + WRTCMP_dy: 3000.0 # #----------------------------------------------------------------------- # @@ -476,18 +476,18 @@ LAYOUT_X: 6 LAYOUT_Y: 4 BLOCKSIZE: 36 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 4 - WRTCMP_output_grid: "rotated_latlon" - WRTCMP_cen_lon: -97.5 - WRTCMP_cen_lat: 38.5 - WRTCMP_lon_lwr_left: -24.40085141 - WRTCMP_lat_lwr_left: -19.65624142 - WRTCMP_lon_upr_rght: 24.40085141 - WRTCMP_lat_upr_rght: 19.65624142 - WRTCMP_dlon: 0.22593381 - WRTCMP_dlat: 0.22593381 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 4 + WRTCMP_output_grid: "rotated_latlon" + WRTCMP_cen_lon: -97.5 + WRTCMP_cen_lat: 38.5 + WRTCMP_lon_lwr_left: -24.40085141 + WRTCMP_lat_lwr_left: -19.65624142 + WRTCMP_lon_upr_rght: 24.40085141 + WRTCMP_lat_upr_rght: 19.65624142 + WRTCMP_dlon: 0.22593381 + WRTCMP_dlat: 0.22593381 # #----------------------------------------------------------------------- # @@ -519,18 +519,18 @@ LAYOUT_X: 30 LAYOUT_Y: 22 BLOCKSIZE: 35 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 22 - WRTCMP_output_grid: "rotated_latlon" - WRTCMP_cen_lon: -97.5 - WRTCMP_cen_lat: 38.5 - WRTCMP_lon_lwr_left: -25.23144805 - WRTCMP_lat_lwr_left: -15.82130419 - WRTCMP_lon_upr_rght: 25.23144805 - WRTCMP_lat_upr_rght: 15.82130419 - WRTCMP_dlon: 0.02665763 - WRTCMP_dlat: 0.02665763 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 22 + WRTCMP_output_grid: "rotated_latlon" + WRTCMP_cen_lon: -97.5 + WRTCMP_cen_lat: 38.5 + WRTCMP_lon_lwr_left: -25.23144805 + WRTCMP_lat_lwr_left: -15.82130419 + WRTCMP_lon_upr_rght: 25.23144805 + WRTCMP_lat_upr_rght: 15.82130419 + WRTCMP_dlon: 0.02665763 + WRTCMP_dlat: 0.02665763 # #----------------------------------------------------------------------- # @@ -552,20 +552,20 @@ LAYOUT_X: 28 LAYOUT_Y: 16 BLOCKSIZE: 24 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 24 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: -153.0 - WRTCMP_cen_lat: 61.0 - WRTCMP_stdlat1: 61.0 - WRTCMP_stdlat2: 61.0 - WRTCMP_nx: 1344 - WRTCMP_ny: 1152 - WRTCMP_lon_lwr_left: -177.0 - WRTCMP_lat_lwr_left: 42.5 - WRTCMP_dx: 3000.0 - WRTCMP_dy: 3000.0 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 24 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: -153.0 + WRTCMP_cen_lat: 61.0 + WRTCMP_stdlat1: 61.0 + WRTCMP_stdlat2: 61.0 + WRTCMP_nx: 1344 + WRTCMP_ny: 1152 + WRTCMP_lon_lwr_left: -177.0 + WRTCMP_lat_lwr_left: 42.5 + WRTCMP_dx: 3000.0 + WRTCMP_dy: 3000.0 # #----------------------------------------------------------------------- # @@ -587,20 +587,20 @@ LAYOUT_X: 8 LAYOUT_Y: 8 BLOCKSIZE: 27 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 8 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: -157.0 - WRTCMP_cen_lat: 20.0 - WRTCMP_stdlat1: 20.0 - WRTCMP_stdlat2: 20.0 - WRTCMP_nx: 420 - WRTCMP_ny: 348 - WRTCMP_lon_lwr_left: -162.8 - WRTCMP_lat_lwr_left: 15.2 - WRTCMP_dx: 3000.0 - WRTCMP_dy: 3000.0 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 8 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: -157.0 + WRTCMP_cen_lat: 20.0 + WRTCMP_stdlat1: 20.0 + WRTCMP_stdlat2: 20.0 + WRTCMP_nx: 420 + WRTCMP_ny: 348 + WRTCMP_lon_lwr_left: -162.8 + WRTCMP_lat_lwr_left: 15.2 + WRTCMP_dx: 3000.0 + WRTCMP_dy: 3000.0 # #----------------------------------------------------------------------- # @@ -622,20 +622,20 @@ LAYOUT_X: 16 LAYOUT_Y: 8 BLOCKSIZE: 24 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 24 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: -69.0 - WRTCMP_cen_lat: 18.0 - WRTCMP_stdlat1: 18.0 - WRTCMP_stdlat2: 18.0 - WRTCMP_nx: 576 - WRTCMP_ny: 432 - WRTCMP_lon_lwr_left: -77 - WRTCMP_lat_lwr_left: 12 - WRTCMP_dx: 3000.0 - WRTCMP_dy: 3000.0 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 24 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: -69.0 + WRTCMP_cen_lat: 18.0 + WRTCMP_stdlat1: 18.0 + WRTCMP_stdlat2: 18.0 + WRTCMP_nx: 576 + WRTCMP_ny: 432 + WRTCMP_lon_lwr_left: -77 + WRTCMP_lat_lwr_left: 12 + WRTCMP_dx: 3000.0 + WRTCMP_dy: 3000.0 # #----------------------------------------------------------------------- # @@ -657,20 +657,20 @@ LAYOUT_X: 16 LAYOUT_Y: 12 BLOCKSIZE: 27 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 24 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: 146.0 - WRTCMP_cen_lat: 15.0 - WRTCMP_stdlat1: 15.0 - WRTCMP_stdlat2: 15.0 - WRTCMP_nx: 420 - WRTCMP_ny: 348 - WRTCMP_lon_lwr_left: 140 - WRTCMP_lat_lwr_left: 10 - WRTCMP_dx: 3000.0 - WRTCMP_dy: 3000.0 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 24 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: 146.0 + WRTCMP_cen_lat: 15.0 + WRTCMP_stdlat1: 15.0 + WRTCMP_stdlat2: 15.0 + WRTCMP_nx: 420 + WRTCMP_ny: 348 + WRTCMP_lon_lwr_left: 140 + WRTCMP_lat_lwr_left: 10 + WRTCMP_dx: 3000.0 + WRTCMP_dy: 3000.0 # #----------------------------------------------------------------------- # @@ -692,18 +692,18 @@ LAYOUT_X: 5 LAYOUT_Y: 5 BLOCKSIZE: 6 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 32 - WRTCMP_output_grid: "regional_latlon" - WRTCMP_cen_lon: -62.0 - WRTCMP_cen_lat: 25.0 - WRTCMP_lon_lwr_left: -114.5 - WRTCMP_lat_lwr_left: -5.0 - WRTCMP_lon_upr_rght: -9.5 - WRTCMP_lat_upr_rght: 55.0 - WRTCMP_dlon: 0.25 - WRTCMP_dlat: 0.25 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 32 + WRTCMP_output_grid: "regional_latlon" + WRTCMP_cen_lon: -62.0 + WRTCMP_cen_lat: 25.0 + WRTCMP_lon_lwr_left: -114.5 + WRTCMP_lat_lwr_left: -5.0 + WRTCMP_lon_upr_rght: -9.5 + WRTCMP_lat_upr_rght: 55.0 + WRTCMP_dlon: 0.25 + WRTCMP_dlat: 0.25 # #----------------------------------------------------------------------- # @@ -725,18 +725,18 @@ LAYOUT_X: 19 LAYOUT_Y: 12 BLOCKSIZE: 35 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 32 - WRTCMP_output_grid: "regional_latlon" - WRTCMP_cen_lon: -62.0 - WRTCMP_cen_lat: 25.0 - WRTCMP_lon_lwr_left: -114.5 - WRTCMP_lat_lwr_left: -5.0 - WRTCMP_lon_upr_rght: -9.5 - WRTCMP_lat_upr_rght: 55.0 - WRTCMP_dlon: 0.13 - WRTCMP_dlat: 0.13 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 32 + WRTCMP_output_grid: "regional_latlon" + WRTCMP_cen_lon: -62.0 + WRTCMP_cen_lat: 25.0 + WRTCMP_lon_lwr_left: -114.5 + WRTCMP_lat_lwr_left: -5.0 + WRTCMP_lon_upr_rght: -9.5 + WRTCMP_lat_upr_rght: 55.0 + WRTCMP_dlon: 0.13 + WRTCMP_dlat: 0.13 # #----------------------------------------------------------------------- # @@ -758,18 +758,18 @@ LAYOUT_X: 32 LAYOUT_Y: 24 BLOCKSIZE: 32 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 32 - WRTCMP_output_grid: "regional_latlon" - WRTCMP_cen_lon: -62.0 - WRTCMP_cen_lat: 25.0 - WRTCMP_lon_lwr_left: -114.5 - WRTCMP_lat_lwr_left: -5.0 - WRTCMP_lon_upr_rght: -9.5 - WRTCMP_lat_upr_rght: 55.0 - WRTCMP_dlon: 0.03 - WRTCMP_dlat: 0.03 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 32 + WRTCMP_output_grid: "regional_latlon" + WRTCMP_cen_lon: -62.0 + WRTCMP_cen_lat: 25.0 + WRTCMP_lon_lwr_left: -114.5 + WRTCMP_lat_lwr_left: -5.0 + WRTCMP_lon_upr_rght: -9.5 + WRTCMP_lat_upr_rght: 55.0 + WRTCMP_dlon: 0.03 + WRTCMP_dlat: 0.03 # #----------------------------------------------------------------------- # @@ -791,20 +791,20 @@ LAYOUT_X: 2 LAYOUT_Y: 3 BLOCKSIZE: 37 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 1 - WRTCMP_output_grid: "lambert_conformal" - WRTCMP_cen_lon: -163.5 - WRTCMP_cen_lat: 62.8 - WRTCMP_stdlat1: 62.8 - WRTCMP_stdlat2: 62.8 - WRTCMP_nx: 70 - WRTCMP_ny: 45 - WRTCMP_lon_lwr_left: 172.0 - WRTCMP_lat_lwr_left: 49.0 - WRTCMP_dx: 50000.0 - WRTCMP_dy: 50000.0 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 1 + WRTCMP_output_grid: "lambert_conformal" + WRTCMP_cen_lon: -163.5 + WRTCMP_cen_lat: 62.8 + WRTCMP_stdlat1: 62.8 + WRTCMP_stdlat2: 62.8 + WRTCMP_nx: 70 + WRTCMP_ny: 45 + WRTCMP_lon_lwr_left: 172.0 + WRTCMP_lat_lwr_left: 49.0 + WRTCMP_dx: 50000.0 + WRTCMP_dy: 50000.0 # #----------------------------------------------------------------------- # @@ -826,18 +826,18 @@ LAYOUT_X: 16 LAYOUT_Y: 16 BLOCKSIZE: 30 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 16 - WRTCMP_output_grid: "rotated_latlon" - WRTCMP_cen_lon: -113.0 - WRTCMP_cen_lat: 55.0 - WRTCMP_lon_lwr_left: -61.0 - WRTCMP_lat_lwr_left: -37.0 - WRTCMP_lon_upr_rght: 61.0 - WRTCMP_lat_upr_rght: 37.0 - WRTCMP_dlon: 0.1169081 - WRTCMP_dlat: 0.1169081 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 16 + WRTCMP_output_grid: "rotated_latlon" + WRTCMP_cen_lon: -113.0 + WRTCMP_cen_lat: 55.0 + WRTCMP_lon_lwr_left: -61.0 + WRTCMP_lat_lwr_left: -37.0 + WRTCMP_lon_upr_rght: 61.0 + WRTCMP_lat_upr_rght: 37.0 + WRTCMP_dlon: 0.1169081 + WRTCMP_dlat: 0.1169081 # #----------------------------------------------------------------------- # @@ -859,16 +859,16 @@ LAYOUT_X: 20 # 40 - EMC operational configuration LAYOUT_Y: 35 # 45 - EMC operational configuration BLOCKSIZE: 28 - #if QUILTING = True - WRTCMP_write_groups: 1 - WRTCMP_write_tasks_per_group: 144 - WRTCMP_output_grid: "rotated_latlon" - WRTCMP_cen_lon: -113.0 - WRTCMP_cen_lat: 55.0 - WRTCMP_lon_lwr_left: -61.0 - WRTCMP_lat_lwr_left: -37.0 - WRTCMP_lon_upr_rght: 61.0 - WRTCMP_lat_upr_rght: 37.0 - WRTCMP_dlon: 0.025 - WRTCMP_dlat: 0.025 + QUILTING: + WRTCMP_write_groups: 1 + WRTCMP_write_tasks_per_group: 144 + WRTCMP_output_grid: "rotated_latlon" + WRTCMP_cen_lon: -113.0 + WRTCMP_cen_lat: 55.0 + WRTCMP_lon_lwr_left: -61.0 + WRTCMP_lat_lwr_left: -37.0 + WRTCMP_lon_upr_rght: 61.0 + WRTCMP_lat_upr_rght: 37.0 + WRTCMP_dlon: 0.025 + WRTCMP_dlat: 0.025 diff --git a/ush/python_utils/__init__.py b/ush/python_utils/__init__.py index 3aa90e1549..7b297432e6 100644 --- a/ush/python_utils/__init__.py +++ b/ush/python_utils/__init__.py @@ -1,25 +1,55 @@ -try: - from .misc import uppercase, lowercase, find_pattern_in_str, find_pattern_in_file, flatten_dict - from .check_for_preexist_dir_file import check_for_preexist_dir_file - from .check_var_valid_value import check_var_valid_value - from .count_files import count_files - from .create_symlink_to_file import create_symlink_to_file - from .define_macos_utilities import define_macos_utilities - from .environment import str_to_date, date_to_str, str_to_type, type_to_str, list_to_str, \ - str_to_list, set_env_var, get_env_var, import_vars, export_vars - from .filesys_cmds_vrfy import cmd_vrfy, cp_vrfy, mv_vrfy, rm_vrfy, ln_vrfy, mkdir_vrfy, cd_vrfy - from .get_elem_inds import get_elem_inds - from .interpol_to_arbit_CRES import interpol_to_arbit_CRES - from .print_input_args import print_input_args - from .print_msg import print_info_msg, print_err_msg_exit - from .process_args import process_args - from .run_command import run_command - from .get_charvar_from_netcdf import get_charvar_from_netcdf - from .xml_parser import load_xml_file, has_tag_with_value - from .config_parser import load_shell_config, cfg_to_shell_str, \ - load_json_config, cfg_to_json_str, \ - load_ini_config, cfg_to_ini_str, \ - get_ini_value, load_config_file, \ - load_yaml_config, cfg_to_yaml_str -except: - pass +from .misc import uppercase, lowercase, find_pattern_in_str, find_pattern_in_file +from .check_for_preexist_dir_file import check_for_preexist_dir_file +from .check_var_valid_value import check_var_valid_value +from .count_files import count_files +from .create_symlink_to_file import create_symlink_to_file +from .define_macos_utilities import define_macos_utilities +from .environment import ( + str_to_date, + date_to_str, + str_to_type, + type_to_str, + list_to_str, + str_to_list, + set_env_var, + get_env_var, + import_vars, + export_vars, +) +from .filesys_cmds_vrfy import ( + cmd_vrfy, + cp_vrfy, + mv_vrfy, + rm_vrfy, + ln_vrfy, + mkdir_vrfy, + cd_vrfy, +) +from .get_elem_inds import get_elem_inds +from .interpol_to_arbit_CRES import interpol_to_arbit_CRES +from .print_input_args import print_input_args +from .print_msg import print_info_msg, print_err_msg_exit +from .process_args import process_args +from .run_command import run_command +from .get_charvar_from_netcdf import get_charvar_from_netcdf +from .xml_parser import load_xml_file, has_tag_with_value +from .config_parser import ( + load_json_config, + cfg_to_json_str, + load_ini_config, + cfg_to_ini_str, + get_ini_value, + load_config_file, + load_shell_config, + cfg_to_shell_str, + load_xml_config, + cfg_to_xml_str, + flatten_dict, + structure_dict, + check_structure_dict, + update_dict, + cfg_main, + load_config_file, + load_yaml_config, + cfg_to_yaml_str, +) diff --git a/ush/python_utils/check_for_preexist_dir_file.py b/ush/python_utils/check_for_preexist_dir_file.py index 97c709cf0f..fc67447fb5 100644 --- a/ush/python_utils/check_for_preexist_dir_file.py +++ b/ush/python_utils/check_for_preexist_dir_file.py @@ -6,8 +6,9 @@ from .check_var_valid_value import check_var_valid_value from .filesys_cmds_vrfy import rm_vrfy, mv_vrfy + def check_for_preexist_dir_file(path, method): - """ Check for a preexisting directory or file and, if present, deal with it + """Check for a preexisting directory or file and, if present, deal with it according to the specified method Args: @@ -17,23 +18,26 @@ def check_for_preexist_dir_file(path, method): None """ - check_var_valid_value(method, ['delete', 'rename', 'quit']) + check_var_valid_value(method, ["delete", "rename", "quit"]) if os.path.exists(path): - if method == 'delete': - rm_vrfy(' -rf ', path) - elif method == 'rename': + if method == "delete": + rm_vrfy(" -rf ", path) + elif method == "rename": now = datetime.now() d = now.strftime("_old_%Y%m%d_%H%M%S") new_path = path + d - print_info_msg(f''' + print_info_msg( + f""" Specified directory or file already exists: {path} Moving (renaming) preexisting directory or file to: - {new_path}''') - mv_vrfy(path, new_path) + {new_path}""" + ) + mv_vrfy(path, new_path) else: - print_err_msg_exit(f''' + print_err_msg_exit( + f""" Specified directory or file already exists - {path}''') - + {path}""" + ) diff --git a/ush/python_utils/check_var_valid_value.py b/ush/python_utils/check_var_valid_value.py index 0a033b7249..10d8365cb6 100644 --- a/ush/python_utils/check_var_valid_value.py +++ b/ush/python_utils/check_var_valid_value.py @@ -2,8 +2,9 @@ from .print_msg import print_err_msg_exit + def check_var_valid_value(var, values, err_msg=None): - """ Check if specified variable has a valid value + """Check if specified variable has a valid value Args: var: the variable @@ -15,7 +16,8 @@ def check_var_valid_value(var, values, err_msg=None): if var not in values: if err_msg is not None: - err_msg = f'The value specified in var = {var} is not supported.' - print_err_msg_exit(err_msg + f'{var} must be set to one of the following:\n {values}') + err_msg = f"The value specified in var = {var} is not supported." + print_err_msg_exit( + err_msg + f"{var} must be set to one of the following:\n {values}" + ) return True - diff --git a/ush/python_utils/config_parser.py b/ush/python_utils/config_parser.py index b343551bfd..7095d7a956 100644 --- a/ush/python_utils/config_parser.py +++ b/ush/python_utils/config_parser.py @@ -1,6 +1,5 @@ #!/usr/bin/env python3 - """ This file provides utilities for processing different configuration file formats. Supported formats include: @@ -8,21 +7,33 @@ b) JSON c) SHELL d) INI + e) XML Typical usage involves first loading the config file, then using the dictionary returnded by load_config to make queries. + """ import argparse + +# +# Note: Yaml maynot be available in which case we suppress +# the exception, so that we can have other functionality +# provided by this module. +# try: import yaml -except: +except ModuleNotFoundError: pass +# The rest of the formats: JSON/SHELL/INI/XML do not need +# external pakcages import json -import sys import os +import re from textwrap import dedent import configparser +import xml.etree.ElementTree as ET +from xml.dom import minidom from .environment import list_to_str, str_to_list from .print_msg import print_err_msg_exit @@ -32,55 +43,104 @@ # YAML ########## def load_yaml_config(config_file): - """ Safe load a yaml file """ + """Safe load a yaml file""" try: - with open(config_file,'r') as f: + with open(config_file, "r") as f: cfg = yaml.safe_load(f) except yaml.YAMLError as e: - print_err_msg_exit(e) + print_err_msg_exit(str(e)) return cfg + +try: + + class custom_dumper(yaml.Dumper): + """Custom yaml dumper to correct list indentation""" + + def increase_indent(self, flow=False, indentless=False): + return super(custom_dumper, self).increase_indent(flow, False) + + def str_presenter(dumper, data): + if len(data.splitlines()) > 1: + return dumper.represent_scalar('tag:yaml.org,2002:str', data, style='|') + return dumper.represent_scalar('tag:yaml.org,2002:str', data) + + yaml.add_representer(str, str_presenter) + +except NameError: + pass + + def cfg_to_yaml_str(cfg): - """ Get contents of config file as a yaml string """ + """Get contents of config file as a yaml string""" + + return yaml.dump( + cfg, Dumper=custom_dumper, sort_keys=False, default_flow_style=False + ) - return yaml.dump(cfg, sort_keys=False, default_flow_style=False) def join_str(loader, node): - """ Custom tag hangler to join strings """ + """Custom tag hangler to join strings""" seq = loader.construct_sequence(node) - return ''.join([str(i) for i in seq]) + return "".join([str(i) for i in seq]) + try: - yaml.add_constructor('!join_str', join_str, Loader=yaml.SafeLoader) -except: + yaml.add_constructor("!join_str", join_str, Loader=yaml.SafeLoader) +except NameError: pass ########## # JSON ########## def load_json_config(config_file): - """ Load json config file """ + """Load json config file""" try: - with open(config_file,'r') as f: + with open(config_file, "r") as f: cfg = json.load(f) - except: - print_err_msg_exit(e) + except json.JSONDecodeError as e: + print_err_msg_exit(str(e)) return cfg - + + def cfg_to_json_str(cfg): - """ Get contents of config file as a json string """ + """Get contents of config file as a json string""" + + return json.dumps(cfg, sort_keys=False, indent=4) + "\n" - return json.dumps(cfg, sort_keys=False, indent=4) ########## # SHELL ########## -def load_shell_config(config_file): - """ Loads old style shell config files. +def load_shell_as_ini_config(file_name, return_string=1): + """Load shell config file with embedded structure in comments""" + + # read contents and replace comments as sections + with open(file_name, "r") as file: + cfg = file.read() + cfg = cfg.replace("# [", "[") + cfg = cfg.replace("\\\n", " ") + + # write content to temp file and load it as ini + temp_file = os.path.join(os.getcwd(), "_temp." + str(os.getpid()) + ".ini") + with open(temp_file, "w") as file: + file.write(cfg) + + # load it as a structured ini file + try: + cfg = load_ini_config(temp_file, return_string) + finally: + os.remove(temp_file) + + return cfg + + +def load_shell_config(config_file, return_string=0): + """Loads old style shell config files. We source the config script in a subshell and gets the variables it sets Args: @@ -89,11 +149,19 @@ def load_shell_config(config_file): dictionary that should be equivalent to one obtained from parsing a yaml file. """ + # First try to load it as a structured shell config file + try: + cfg = load_shell_as_ini_config(config_file, return_string) + return cfg + except: + pass + # Save env vars before and after sourcing the scipt and then # do a diff to get variables specifically defined/updated in the script # Method sounds brittle but seems to work ok so far pid = os.getpid() - code = dedent(f''' #!/bin/bash + code = dedent( + f""" #!/bin/bash t1="./t1.{pid}" t2="./t2.{pid}" (set -o posix; set) > $t1 @@ -101,115 +169,353 @@ def load_shell_config(config_file): (set -o posix; set) > $t2 diff $t1 $t2 | grep "> " | cut -c 3- rm -rf $t1 $t2 - ''') - (_,config_str,_) = run_command(code) + """ + ) + (_, config_str, _) = run_command(code) lines = config_str.splitlines() - - #build the dictionary + + # build the dictionary cfg = {} for l in lines: idx = l.find("=") k = l[:idx] - v = str_to_list(l[idx+1:]) + v = str_to_list(l[idx + 1 :], return_string) cfg[k] = v return cfg -def cfg_to_shell_str(cfg): - """ Get contents of config file as shell script string""" - shell_str = '' - for k,v in cfg.items(): - if isinstance(v,dict): - shell_str += f"# [{k}]\n" - shell_str += cfg_to_shell_str(v) +def cfg_to_shell_str(cfg, kname=None): + """Get contents of config file as shell script string""" + + shell_str = "" + for k, v in cfg.items(): + if isinstance(v, dict): + if kname: + n_kname = f"{kname}.{k}" + else: + n_kname = f"{k}" + shell_str += f"# [{n_kname}]\n" + shell_str += cfg_to_shell_str(v, n_kname) shell_str += "\n" continue + # others v1 = list_to_str(v) - if isinstance(v,list): - shell_str += f'{k}={v1}\n' + if isinstance(v, list): + shell_str += f"{k}={v1}\n" else: + # replace some problematic chars + v1 = v1.replace("'", '"') + v1 = v1.replace("\n", " ") + # end problematic shell_str += f"{k}='{v1}'\n" return shell_str + ########## # INI ########## -def load_ini_config(config_file): - """ Load a config file with a format similar to Microsoft's INI files""" +def load_ini_config(config_file, return_string=0): + """Load a config file with a format similar to Microsoft's INI files""" if not os.path.exists(config_file): - print_err_msg_exit(f''' + print_err_msg_exit( + f''' The specified configuration file does not exist: - \"{config_file}\"''') - - config = configparser.ConfigParser() + \"{config_file}\"''' + ) + + config = configparser.RawConfigParser() + config.optionxform = str config.read(config_file) - config_dict = {s:dict(config.items(s)) for s in config.sections()} + config_dict = {s: dict(config.items(s)) for s in config.sections()} + for _, vs in config_dict.items(): + for k, v in vs.items(): + vs[k] = str_to_list(v, return_string) return config_dict - + + def get_ini_value(config, section, key): - """ Finds the value of a property in a given section""" + """Finds the value of a property in a given section""" if not section in config: - print_err_msg_exit(f''' - Section not found: + print_err_msg_exit( + f''' + Section not found: section = \"{section}\" - valid sections = \"{config.keys()}\"''') + valid sections = \"{config.keys()}\"''' + ) else: return config[section][key] return None -def cfg_to_ini_str(cfg): - """ Get contents of config file as ini string""" - ini_str = '' - for k,v in cfg.items(): - if isinstance(v,dict): - ini_str += f"[{k}]\n" - ini_str += cfg_to_ini_str(v) +def cfg_to_ini_str(cfg, kname=None): + """Get contents of config file as ini string""" + + ini_str = "" + for k, v in cfg.items(): + if isinstance(v, dict): + if kname: + n_kname = f"{kname}.{k}" + else: + n_kname = f"{k}" + ini_str += f"[{n_kname}]\n" + ini_str += cfg_to_ini_str(v, n_kname) ini_str += "\n" continue - v1 = list_to_str(v) - if isinstance(v,list): - ini_str += f'{k}={v1}\n' + v1 = list_to_str(v, True) + if isinstance(v, list): + ini_str += f"{k}={v1}\n" else: ini_str += f"{k}='{v1}'\n" return ini_str + +########## +# XML +########## +def xml_to_dict(root, return_string): + """Convert an xml tree to dictionary""" + + cfg = {} + for child in root: + if len(list(child)) > 0: + r = xml_to_dict(child, return_string) + cfg[child.tag] = r + else: + cfg[child.tag] = str_to_list(child.text, return_string) + return cfg + + +def dict_to_xml(d, tag): + """Convert dictionary to an xml tree""" + + elem = ET.Element(tag) + for k, v in d.items(): + if isinstance(v, dict): + r = dict_to_xml(v, k) + elem.append(r) + else: + child = ET.Element(k) + child.text = list_to_str(v, True) + elem.append(child) + + return elem + + +def load_xml_config(config_file, return_string=0): + """Load xml config file""" + + tree = ET.parse(config_file) + root = tree.getroot() + cfg = xml_to_dict(root, return_string) + return cfg + + +def cfg_to_xml_str(cfg): + """Get contents of config file as a xml string""" + + root = dict_to_xml(cfg, "root") + r = ET.tostring(root, encoding="unicode") + r = minidom.parseString(r) + r = r.toprettyxml(indent=" ") + r = r.replace(""", '"') + return r + + +################## +# CONFIG utils +################## + + +def flatten_dict(dictionary, keys=None): + """Flatten a recursive dictionary (e.g.yaml/json) to be one level deep + + Args: + dictionary: the source dictionary + keys: list of keys on top level whose contents to flatten, if None all of them + Returns: + A one-level deep dictionary for the selected set of keys + """ + flat_dict = {} + for k, v in dictionary.items(): + if not keys or k in keys: + if isinstance(v, dict): + r = flatten_dict(v) + flat_dict.update(r) + else: + flat_dict[k] = v + return flat_dict + + +def structure_dict(dict_o, dict_t): + """Structure a dictionary based on a template dictionary + + Args: + dict_o: dictionary to structure (flat one level structure) + dict_t: template dictionary used for structuring + Returns: + A dictionary with contents of dict_o following structure of dict_t + """ + struct_dict = {} + for k, v in dict_t.items(): + if isinstance(v, dict): + r = structure_dict(dict_o, v) + if r: + struct_dict[k] = r + elif k in dict_o.keys(): + struct_dict[k] = dict_o[k] + return struct_dict + + +def update_dict(dict_o, dict_t): + """Update a dictionary with another + + Args: + dict_o: flat dictionary used as source + dict_t: target dictionary to update + Returns: + None + """ + for k, v in dict_t.items(): + if isinstance(v, dict): + update_dict(dict_o, v) + elif k in dict_o.keys(): + dict_t[k] = dict_o[k] + + +def check_structure_dict(dict_o, dict_t): + """Check if a dictinary's structure follows a template. + The invalid entries are printed to the screen. + + Args: + dict_o: target dictionary + dict_t: template dictionary to compare structure to + Returns: + Boolean + """ + for k, v in dict_o.items(): + if k in dict_t.keys(): + v1 = dict_t[k] + if isinstance(v, dict) and isinstance(v1, dict): + r = check_structure_dict(v, v1) + if not r: + return False + else: + print(f"INVALID ENTRY: {k}={v}") + return False + return True + + ################## # CONFIG loader ################## -def load_config_file(file_name): - """ Load config file based on file name extension """ +def load_config_file(file_name, return_string=0): + """Load config file based on file name extension""" ext = os.path.splitext(file_name)[1][1:] if ext == "sh": - return load_shell_config(file_name) - elif ext == "cfg": - return load_ini_config(file_name) - elif ext == "json": + return load_shell_config(file_name, return_string) + if ext == "ini": + return load_ini_config(file_name, return_string) + if ext == "json": return load_json_config(file_name) - else: + if ext in ["yaml", "yml"]: return load_yaml_config(file_name) + if ext == "xml": + return load_xml_config(file_name, return_string) + return None + -if __name__ == "__main__": - parser = argparse.ArgumentParser(description=\ - 'Prints contents of config file.') - parser.add_argument('--cfg','-c',dest='cfg',required=True, - help='config file to parse') - parser.add_argument('--output-type','-o',dest='out_type',required=False, - help='output format: can be any of ["shell", "yaml", "ini", "json"]') +################## +# CONFIG main +################## +def cfg_main(): + """Main function for converting and formatting between different config file formats""" + + parser = argparse.ArgumentParser( + description="Utility for managing different config formats." + ) + parser.add_argument( + "--cfg", "-c", dest="cfg", required=True, help="Config file to parse" + ) + parser.add_argument( + "--output-type", + "-o", + dest="out_type", + required=False, + help='Output format: can be any of ["shell", "yaml", "ini", "json", "xml"]', + ) + parser.add_argument( + "--flatten", + "-f", + dest="flatten", + action="store_true", + required=False, + help="Flatten resulting dictionary", + ) + parser.add_argument( + "--template-cfg", + "-t", + dest="template", + required=False, + help="Template config file used to structure a given config file", + ) + parser.add_argument( + "--keys", + "-k", + dest="keys", + nargs="+", + required=False, + help="Include only these keys of dictionary for processing.\ + Keys can be python regex expression.", + ) + parser.add_argument( + "--validate-cfg", + "-v", + dest="validate", + required=False, + help="Validation config file used to validate a given config file", + ) args = parser.parse_args() - cfg = load_config_file(args.cfg) - - if args.out_type == 'shell': - print( cfg_to_shell_str(cfg) ) - elif args.out_type == 'ini': - print( cfg_to_ini_str(cfg) ) - elif args.out_type == 'json': - print( cfg_to_json_str(cfg) ) - else: - print( cfg_to_yaml_str(cfg) ) + cfg = load_config_file(args.cfg, 2) + if args.validate: + cfg_t = load_config_file(args.validate, 1) + r = check_structure_dict(cfg, cfg_t) + if r: + print("SUCCESS") + else: + print("FAILURE") + else: + if args.template: + cfg = flatten_dict(cfg) + cfg_t = load_config_file(args.template, 1) + cfg = structure_dict(cfg, cfg_t) + + if args.keys: + keys = [] + for k in args.keys: + r = re.compile(k) + keys += list(filter(r.match, cfg.keys())) + cfg = {k: cfg[k] for k in keys} + + if args.flatten: + cfg = flatten_dict(cfg) + + # convert to string and print + if args.out_type in ["shell", "sh"]: + print(cfg_to_shell_str(cfg), end="") + elif args.out_type == "ini": + print(cfg_to_ini_str(cfg), end="") + elif args.out_type == "json": + print(cfg_to_json_str(cfg), end="") + elif args.out_type in ["yaml", "yml"]: + print(cfg_to_yaml_str(cfg), end="") + elif args.out_type == "xml": + print(cfg_to_xml_str(cfg), end="") + else: + parser.print_help() + parser.exit() diff --git a/ush/python_utils/count_files.py b/ush/python_utils/count_files.py index 2239bf7eab..36862895b7 100644 --- a/ush/python_utils/count_files.py +++ b/ush/python_utils/count_files.py @@ -1,7 +1,8 @@ import glob -def count_files(ext,dirct='.'): - """ Function that returns the number of files in the specified directory + +def count_files(ext, dirct="."): + """Function that returns the number of files in the specified directory ending with the specified file extension Args: @@ -11,6 +12,5 @@ def count_files(ext,dirct='.'): int: Number of files """ - files = glob.glob(dirct + '/*.' + ext) + files = glob.glob(dirct + "/*." + ext) return len(files) - diff --git a/ush/python_utils/create_symlink_to_file.py b/ush/python_utils/create_symlink_to_file.py index 1d078c9a8b..3a3fddb08b 100644 --- a/ush/python_utils/create_symlink_to_file.py +++ b/ush/python_utils/create_symlink_to_file.py @@ -2,14 +2,13 @@ import os -from .process_args import process_args from .print_input_args import print_input_args from .print_msg import print_err_msg_exit -from .check_var_valid_value import check_var_valid_value from .filesys_cmds_vrfy import ln_vrfy -def create_symlink_to_file(target,symlink,relative=True): - """ Create a symbolic link to the specified target file. + +def create_symlink_to_file(target, symlink, relative=True): + """Create a symbolic link to the specified target file. Args: target: target file @@ -22,28 +21,33 @@ def create_symlink_to_file(target,symlink,relative=True): print_input_args(locals()) if target is None: - print_err_msg_exit(f''' + print_err_msg_exit( + f''' The argument \"target\" specifying the target of the symbolic link that this function will create was not specified in the call to this function: - target = \"{target}\"''') + target = \"{target}\"''' + ) if symlink is None: - print_err_msg_exit(f''' + print_err_msg_exit( + f''' The argument \"symlink\" specifying the target of the symbolic link that this function will create was not specified in the call to this function: - symlink = \"{symlink}\"''') + symlink = \"{symlink}\"''' + ) if not os.path.exists(target): - print_err_msg_exit(f''' + print_err_msg_exit( + f''' Cannot create symlink to specified target file because the latter does not exist or is not a file: - target = \"{target}\"''') - - relative_flag="" + target = \"{target}\"''' + ) + + relative_flag = "" if relative: - RELATIVE_LINK_FLAG = os.getenv('RELATIVE_LINK_FLAG') + RELATIVE_LINK_FLAG = os.getenv("RELATIVE_LINK_FLAG") if RELATIVE_LINK_FLAG is not None: - relative_flag=f'{RELATIVE_LINK_FLAG}' - - ln_vrfy(f'-sf {relative_flag} {target} {symlink}') + relative_flag = f"{RELATIVE_LINK_FLAG}" + ln_vrfy(f"-sf {relative_flag} {target} {symlink}") diff --git a/ush/python_utils/define_macos_utilities.py b/ush/python_utils/define_macos_utilities.py index 2bf996b996..4a73020850 100644 --- a/ush/python_utils/define_macos_utilities.py +++ b/ush/python_utils/define_macos_utilities.py @@ -6,34 +6,39 @@ from .run_command import run_command from .environment import set_env_var + def check_darwin(cmd): - """ Check if darwin command exists """ + """Check if darwin command exists""" - (err,_,_) = run_command(f'command -v {cmd}') + (err, _, _) = run_command(f"command -v {cmd}") if err != 0: - print_err_msg_exit(f''' - For Darwin-based operating systems (MacOS), the '{cmd}' utility is required to run the UFS SRW Application. - Reference the User's Guide for more information about platform requirements. - Aborting.''') + print_err_msg_exit( + f""" + For Darwin-based operating systems (MacOS), the '{cmd}' utility is required + to run the UFS SRW Application. Reference the User's Guide for more information + about platform requirements. + + Aborting.""" + ) return True + def define_macos_utilities(): - """ Set some environment variables for Darwin systems differently + """Set some environment variables for Darwin systems differently The variables are: READLINK, SED, DATE_UTIL and LN_UTIL """ - if os.uname()[0] == 'Darwin': - if check_darwin('greadlink'): - set_env_var('READLINK','greadlink') - if check_darwin('gsed'): - set_env_var('SED','gsed') - if check_darwin('gdate'): - set_env_var('DATE_UTIL','gdate') - if check_darwin('gln'): - set_env_var('LN_UTIL','gln') + if os.uname()[0] == "Darwin": + if check_darwin("greadlink"): + set_env_var("READLINK", "greadlink") + if check_darwin("gsed"): + set_env_var("SED", "gsed") + if check_darwin("gdate"): + set_env_var("DATE_UTIL", "gdate") + if check_darwin("gln"): + set_env_var("LN_UTIL", "gln") else: - set_env_var('READLINK','readlink') - set_env_var('SED','sed') - set_env_var('DATE_UTIL','date') - set_env_var('LN_UTIL','ln') - + set_env_var("READLINK", "readlink") + set_env_var("SED", "sed") + set_env_var("DATE_UTIL", "date") + set_env_var("LN_UTIL", "ln") diff --git a/ush/python_utils/environment.py b/ush/python_utils/environment.py index 2dc6bfbd7c..5263b92346 100644 --- a/ush/python_utils/environment.py +++ b/ush/python_utils/environment.py @@ -6,8 +6,9 @@ from datetime import datetime, date from types import ModuleType + def str_to_date(s): - """ Get python datetime object from string. + """Get python datetime object from string. Args: s: a string @@ -29,8 +30,9 @@ def str_to_date(s): v = None return v + def date_to_str(d, format="%Y%m%d%H%M"): - """ Get string from python datetime object. + """Get string from python datetime object. By default it converts to YYYYMMDDHHMM format unless told otherwise by passing a different format @@ -42,26 +44,30 @@ def date_to_str(d, format="%Y%m%d%H%M"): v = d.strftime(format) return v -def str_to_type(s, just_get_me_the_string = False): - """ Check if the string contains a float, int, boolean, or just regular string. + +def str_to_type(s, return_string=0): + """Check if the string contains a float, int, boolean, datetime, or just regular string. This will be used to automatically convert environment variables to data types that are more convenient to work with. If you don't want this functionality, - pass just_get_me_the_string = True + pass return_string = 1 Args: s: a string - just_get_me_the_string: Set to True to return the string itself + return_string: Set to 1 to return the string itself + Set to 2 to return the string itself only for a datetime object Returns: - a float, int, boolean, date, or the string itself when all else fails + a float, int, boolean, datetime, or the string itself when all else fails """ - s = s.strip('"\'') - if not just_get_me_the_string: - if s.lower() in ['true','yes','yeah']: + s = s.strip("\"'") + if return_string != 1: + if s.lower() in ["true", "yes", "yeah"]: return True - elif s.lower() in ['false','no','nope']: + if s.lower() in ["false", "no", "nope"]: return False v = str_to_date(s) if v is not None: + if return_string == 2: + return s return v if s.isnumeric(): return int(s) @@ -72,27 +78,29 @@ def str_to_type(s, just_get_me_the_string = False): pass return s + def type_to_str(v): - """ Given a float/int/boolean/date or list of these types, gets a string - representing their values + """Given a float/int/boolean/date or list of these types, gets a string + representing their values Args: v: a variable of the above types Returns: a string """ - if isinstance(v,bool): - return ("TRUE" if v else "FALSE") - elif isinstance(v,int) or isinstance(v,float): + if isinstance(v, bool): + return "TRUE" if v else "FALSE" + elif isinstance(v, (int, float)): pass - elif isinstance(v,date): + elif isinstance(v, date): return date_to_str(v) elif v is None: - return '' + return "" return str(v) + def list_to_str(v, oneline=False): - """ Given a string or list of string, construct a string + """Given a string or list of string, construct a string to be used on right hand side of shell environement variables Args: @@ -100,21 +108,22 @@ def list_to_str(v, oneline=False): Returns: A string """ - if isinstance(v,str): + if isinstance(v, str): return v if isinstance(v, list): v = [type_to_str(i) for i in v] if oneline or len(v) <= 4: - shell_str = f'( "' + '" "'.join(v) + '" )' + shell_str = '( "' + '" "'.join(v) + '" )' else: - shell_str = f'( \\\n"' + '" \\\n"'.join(v) + '" \\\n)' + shell_str = '( \\\n"' + '" \\\n"'.join(v) + '" \\\n)' else: - shell_str = f'{type_to_str(v)}' + shell_str = f"{type_to_str(v)}" return shell_str -def str_to_list(v): - """ Given a string, construct a string or list of strings. + +def str_to_list(v, return_string=0): + """Given a string, construct a string or list of strings. Basically does the reverse operation of `list_to_string`. Args: @@ -122,31 +131,32 @@ def str_to_list(v): Returns: a string, list of strings or null string('') """ - - if not isinstance(v,str): + + if not isinstance(v, str): return v v = v.strip() if not v: return None - if v[0] == '(' and v[-1] == ')': + if (v[0] == "(" and v[-1] == ")") or (v[0] == "[" and v[-1] == "]"): v = v[1:-1] + v = v.replace(",", " ") tokens = shlex.split(v) lst = [] for itm in tokens: itm = itm.strip() - if itm == '': + if itm == "": continue # bash arrays could be stored with indices ([0]=hello ...) if "=" in itm: idx = itm.find("=") - itm = itm[idx+1:] - lst.append(str_to_type(itm)) + itm = itm[idx + 1 :] + lst.append(str_to_type(itm, return_string)) return lst - else: - return str_to_type(v) + return str_to_type(v, return_string) -def set_env_var(param,value): - """ Set an environment variable + +def set_env_var(param, value): + """Set an environment variable Args: param: the variable to set @@ -157,8 +167,9 @@ def set_env_var(param,value): os.environ[param] = list_to_str(value) + def get_env_var(param): - """ Get the value of an environement variable + """Get the value of an environement variable Args: param: the environement variable @@ -168,20 +179,20 @@ def get_env_var(param): if not param in os.environ: return None - else: - value = os.environ[param] - return str_to_list(value) + value = os.environ[param] + return str_to_list(value) + def import_vars(dictionary=None, target_dict=None, env_vars=None): - """ Import all (or select few) environment/dictionary variables as python global + """Import all (or select few) environment/dictionary variables as python global variables of the caller module. Call this function at the beginning of a function that uses environment variables. - Note that for read-only environmental variables, calling this function once at the - beginning should be enough. However, if the variable is modified in the module it is + Note that for read-only environmental variables, calling this function once at the + beginning should be enough. However, if the variable is modified in the module it is called from, the variable should be explicitly tagged as `global`, and then its value should be exported back to the environment with a call to export_vars() - + import_vars() # import all environment variables global MY_VAR, MY_LIST_VAR MY_PATH = "/path/to/somewhere" @@ -209,13 +220,14 @@ def import_vars(dictionary=None, target_dict=None, env_vars=None): if env_vars is None: env_vars = dictionary else: - env_vars = { k: dictionary[k] if k in dictionary else None for k in env_vars } + env_vars = {k: dictionary[k] if k in dictionary else None for k in env_vars} + + for k, v in env_vars.items(): + target_dict[k] = str_to_list(v) - for k,v in env_vars.items(): - target_dict[k] = str_to_list(v) def export_vars(dictionary=None, source_dict=None, env_vars=None): - """ Export all (or select few) global variables of the caller module's + """Export all (or select few) global variables of the caller module's to either the environement/dictionary. Call this function at the end of a function that updates environment variables. @@ -236,15 +248,14 @@ def export_vars(dictionary=None, source_dict=None, env_vars=None): if env_vars is None: env_vars = source_dict else: - env_vars = { k: source_dict[k] if k in source_dict else None for k in env_vars } + env_vars = {k: source_dict[k] if k in source_dict else None for k in env_vars} - for k,v in env_vars.items(): + for k, v in env_vars.items(): # skip functions and other unlikely variable names if callable(v): continue - if isinstance(v,ModuleType): + if isinstance(v, ModuleType): continue - if not k or k[0] == '_': + if not k or k[0] == "_": continue dictionary[k] = list_to_str(v) - diff --git a/ush/python_utils/filesys_cmds_vrfy.py b/ush/python_utils/filesys_cmds_vrfy.py index 67f1f45f9c..7cae27b7d5 100644 --- a/ush/python_utils/filesys_cmds_vrfy.py +++ b/ush/python_utils/filesys_cmds_vrfy.py @@ -3,8 +3,9 @@ import os from .print_msg import print_err_msg_exit + def cmd_vrfy(cmd, *args): - """ Execute system command + """Execute system command Args: cmd: the command @@ -13,23 +14,32 @@ def cmd_vrfy(cmd, *args): Exit code """ - for a in args: - cmd += ' ' + str(a) + cmd += " " + " ".join([str(a) for a in args]) ret = os.system(cmd) if ret != 0: print_err_msg_exit(f'System call "{cmd}" failed.') return ret + def cp_vrfy(*args): - return cmd_vrfy('cp', *args) + return cmd_vrfy("cp", *args) + + def mv_vrfy(*args): - return cmd_vrfy('mv', *args) + return cmd_vrfy("mv", *args) + + def rm_vrfy(*args): - return cmd_vrfy('rm', *args) + return cmd_vrfy("rm", *args) + + def ln_vrfy(*args): - return cmd_vrfy('ln', *args) + return cmd_vrfy("ln", *args) + + def mkdir_vrfy(*args): - return cmd_vrfy('mkdir', *args) + return cmd_vrfy("mkdir", *args) + + def cd_vrfy(*args): return os.chdir(*args) - diff --git a/ush/python_utils/fv3write_parms_lambert.py b/ush/python_utils/fv3write_parms_lambert.py index 18b4a8f359..c94400710a 100755 --- a/ush/python_utils/fv3write_parms_lambert.py +++ b/ush/python_utils/fv3write_parms_lambert.py @@ -10,39 +10,75 @@ import cartopy.crs as ccrs -#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +# @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ # # Main function to return parameters for the FV3 write component. # if __name__ == "__main__": - parser = argparse.ArgumentParser(description='Determine FV3 write component lat1/lon1 for Lamert Conformal map projection', - epilog=''' ---- Yunheng Wang (2021-07-15). - ''') - #formatter_class=CustomFormatter) - parser.add_argument('-v','--verbose', help='Verbose output', action="store_true") - parser.add_argument('-ca','--ctrlat', help='Lambert Conformal central latitude', type=float, default=38.5 ) - parser.add_argument('-co','--ctrlon', help='Lambert Conformal central longitude', type=float, default=-97.5 ) - parser.add_argument('-s1','--stdlat1',help='Lambert Conformal standard latitude1', type=float, default=38.5 ) - parser.add_argument('-s2','--stdlat2',help='Lambert Conformal standard latitude2', type=float, default=38.5 ) - parser.add_argument('-nx', help='number of grid in X direction', type=int, default=301 ) - parser.add_argument('-ny' ,help='number of grid in Y direction', type=int, default=301 ) - parser.add_argument('-dx' ,help='grid resolution in X direction (meter)',type=float, default=3000.0) - parser.add_argument('-dy' ,help='grid resolution in Y direction (meter)',type=float, default=3000.0) + parser = argparse.ArgumentParser( + description="Determine FV3 write component lat1/lon1 for Lamert Conformal map projection", + epilog=""" ---- Yunheng Wang (2021-07-15). + """, + ) + # formatter_class=CustomFormatter) + parser.add_argument("-v", "--verbose", help="Verbose output", action="store_true") + parser.add_argument( + "-ca", + "--ctrlat", + help="Lambert Conformal central latitude", + type=float, + default=38.5, + ) + parser.add_argument( + "-co", + "--ctrlon", + help="Lambert Conformal central longitude", + type=float, + default=-97.5, + ) + parser.add_argument( + "-s1", + "--stdlat1", + help="Lambert Conformal standard latitude1", + type=float, + default=38.5, + ) + parser.add_argument( + "-s2", + "--stdlat2", + help="Lambert Conformal standard latitude2", + type=float, + default=38.5, + ) + parser.add_argument( + "-nx", help="number of grid in X direction", type=int, default=301 + ) + parser.add_argument( + "-ny", help="number of grid in Y direction", type=int, default=301 + ) + parser.add_argument( + "-dx", help="grid resolution in X direction (meter)", type=float, default=3000.0 + ) + parser.add_argument( + "-dy", help="grid resolution in Y direction (meter)", type=float, default=3000.0 + ) args = parser.parse_args() if args.verbose: - print("Write component Lambert Conformal Parameters:") - print(f" cen_lat = {args.ctrlat}, cen_lon = {args.ctrlon}, stdlat1 = {args.stdlat1}, stdlat2 = {args.stdlat2}") - print(f" nx = {args.nx}, ny = {args.ny}, dx = {args.dx}, dy = {args.dy}") + print("Write component Lambert Conformal Parameters:") + print( + f" cen_lat = {args.ctrlat}, cen_lon = {args.ctrlon}, stdlat1 = {args.stdlat1}, stdlat2 = {args.stdlat2}" + ) + print(f" nx = {args.nx}, ny = {args.ny}, dx = {args.dx}, dy = {args.dy}") - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Lambert grid # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- nx1 = args.nx ny1 = args.ny @@ -52,27 +88,33 @@ ctrlat = args.ctrlat ctrlon = args.ctrlon - xctr = (nx1-1)/2*dx1 - yctr = (ny1-1)/2*dy1 + xctr = (nx1 - 1) / 2 * dx1 + yctr = (ny1 - 1) / 2 * dy1 - carr= ccrs.PlateCarree() + carr = ccrs.PlateCarree() - proj1=ccrs.LambertConformal(central_longitude=ctrlon, central_latitude=ctrlat, - false_easting=xctr, false_northing= yctr, secant_latitudes=None, - standard_parallels=(args.stdlat1, args.stdlat2), globe=None) + proj1 = ccrs.LambertConformal( + central_longitude=ctrlon, + central_latitude=ctrlat, + false_easting=xctr, + false_northing=yctr, + secant_latitudes=None, + standard_parallels=(args.stdlat1, args.stdlat2), + globe=None, + ) - lonlat1 = carr.transform_point(0.0,0.0,proj1) + lonlat1 = carr.transform_point(0.0, 0.0, proj1) if args.verbose: print() - print(f' lat1 = {lonlat1[1]}, lon1 = {lonlat1[0]}') - print('\n') + print(f" lat1 = {lonlat1[1]}, lon1 = {lonlat1[0]}") + print("\n") - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Output write component parameters # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- print() print("output_grid: 'lambert_conformal'") diff --git a/ush/python_utils/get_charvar_from_netcdf.py b/ush/python_utils/get_charvar_from_netcdf.py index c85e42e358..c5f642b03a 100644 --- a/ush/python_utils/get_charvar_from_netcdf.py +++ b/ush/python_utils/get_charvar_from_netcdf.py @@ -4,8 +4,9 @@ from .print_msg import print_err_msg_exit from .run_command import run_command + def get_charvar_from_netcdf(nc_file, nc_var_name): - """ Searches NetCDF file and extract a scalar variable + """Searches NetCDF file and extract a scalar variable Args: nc_file: Path to netCDF file @@ -13,8 +14,8 @@ def get_charvar_from_netcdf(nc_file, nc_var_name): Returns: value of the variable """ - - SED = os.getenv('SED') + + SED = os.getenv("SED") cmd = f"ncdump -v {nc_var_name} {nc_file} | \ {SED} -r -e '1,/data:/d' \ @@ -23,22 +24,25 @@ def get_charvar_from_netcdf(nc_file, nc_var_name): -e 's/.*\"(.*)\".*/\\1/' \ -e '/^$/d' \ " - (ret,nc_var_value,_) = run_command(cmd) + (ret, nc_var_value, _) = run_command(cmd) if ret != 0: - print_err_msg_exit(f''' + print_err_msg_exit( + f''' Attempt to extract the value of the NetCDF variable spcecified by nc_var_name from the file specified by nc_file failed: nc_file = \"{nc_file}\" - nc_var_name = \"{nc_var_name}\"''') + nc_var_name = \"{nc_var_name}\"''' + ) if nc_var_value is None: - print_err_msg_exit(f''' + print_err_msg_exit( + f''' In the specified NetCDF file (nc_file), the specified variable (nc_var_name) was not found: nc_file = \"{nc_file}\" nc_var_name = \"{nc_var_name}\" - nc_var_value = \"{nc_var_value}\"''') + nc_var_value = \"{nc_var_value}\"''' + ) return nc_var_value - diff --git a/ush/python_utils/get_elem_inds.py b/ush/python_utils/get_elem_inds.py index 08cbfbff70..20ac2e8967 100644 --- a/ush/python_utils/get_elem_inds.py +++ b/ush/python_utils/get_elem_inds.py @@ -3,8 +3,9 @@ from .misc import lowercase from .check_var_valid_value import check_var_valid_value + def get_elem_inds(arr, match, ret_type): - """ Function that returns indices of elements of array + """Function that returns indices of elements of array that match a given string Args: @@ -15,16 +16,13 @@ def get_elem_inds(arr, match, ret_type): A list of indices """ ret_type = lowercase(ret_type) - check_var_valid_value(ret_type, ['first', 'last', 'all']) + check_var_valid_value(ret_type, ["first", "last", "all"]) - if ret_type == 'first': - for i,e in enumerate(arr): - if e == match: - return i - elif ret_type == 'last': - for i in range(len(arr)-1, -1, -1): + if ret_type == "first": + return arr.index(match) + if ret_type == "last": + for i in range(len(arr) - 1, -1, -1): if arr[i] == match: return i - else: - return [i for i,e in enumerate(arr) if e == match] - + return None + return [i for i, e in enumerate(arr) if e == match] diff --git a/ush/python_utils/interpol_to_arbit_CRES.py b/ush/python_utils/interpol_to_arbit_CRES.py index f6ec889b24..d87e258000 100644 --- a/ush/python_utils/interpol_to_arbit_CRES.py +++ b/ush/python_utils/interpol_to_arbit_CRES.py @@ -1,7 +1,8 @@ #!/usr/bin/env python3 + def interpol_to_arbit_CRES(RES, RES_array, prop_array): - """ Function to interpolate (or extrapolate) a grid cell size-dependent property + """Function to interpolate (or extrapolate) a grid cell size-dependent property to an arbitrary cubed-sphere resolution using arrays that specify a set of property values for a corresponding set of resolutions @@ -13,7 +14,7 @@ def interpol_to_arbit_CRES(RES, RES_array, prop_array): RES_array: The name of the array containing the cubed-sphere resolutions for which corresponding property values are given (in prop_array). These are assumed to be given from smallest to largest. - + prop_array: The name of the array containing the values of the property corres- ponding to the cubed-sphere resolutions in RES_array. Returns: @@ -22,22 +23,21 @@ def interpol_to_arbit_CRES(RES, RES_array, prop_array): num_valid_RESes = len(RES_array) i_min = 0 - i_max = num_valid_RESes - 1 + i_max = num_valid_RESes - 1 if RES <= RES_array[i_min]: prop = prop_array[i_min] elif RES > RES_array[i_max]: prop = prop_array[i_max] else: - for i in range(0,num_valid_RESes-1): - if RES > RES_array[i] and RES <= RES_array[i+1]: + for i in range(0, num_valid_RESes - 1): + if RES_array[i] < RES <= RES_array[i + 1]: RES1 = RES_array[i] - RES2 = RES_array[i+1] + RES2 = RES_array[i + 1] prop1 = prop_array[i] - prop2 = prop_array[i+1] + prop2 = prop_array[i + 1] m_slope = (prop2 - prop1) / (RES2 - RES1) y_intcpt = (RES2 * prop1 - RES1 * prop2) / (RES2 - RES1) prop = m_slope * RES + y_intcpt return prop - diff --git a/ush/python_utils/misc.py b/ush/python_utils/misc.py index c299e02735..e5e320ae43 100644 --- a/ush/python_utils/misc.py +++ b/ush/python_utils/misc.py @@ -2,31 +2,33 @@ import re -def uppercase(str): - """ Function to convert a given string to uppercase + +def uppercase(s): + """Function to convert a given string to uppercase Args: - str: the string + s: the string Return: Uppercased str """ - - return str.upper() + + return s.upper() -def lowercase(str): - """ Function to convert a given string to lowercase +def lowercase(s): + """Function to convert a given string to lowercase Args: - str: the string + s: the string Return: Lowercase str """ - - return str.lower() + + return s.lower() + def find_pattern_in_str(pattern, source): - """ Find regex pattern in a string + """Find regex pattern in a string Args: pattern: regex expression @@ -35,12 +37,13 @@ def find_pattern_in_str(pattern, source): A tuple of matched groups or None """ pattern = re.compile(pattern) - for match in re.finditer(pattern,source): + for match in re.finditer(pattern, source): return match.groups() return None + def find_pattern_in_file(pattern, file_name): - """ Find regex pattern in a file + """Find regex pattern in a file Args: pattern: regex expression @@ -51,25 +54,6 @@ def find_pattern_in_file(pattern, file_name): pattern = re.compile(pattern) with open(file_name) as f: for line in f: - for match in re.finditer(pattern,line): + for match in re.finditer(pattern, line): return match.groups() return None - -def flatten_dict(dictionary,keys=None): - """ Faltten a recursive dictionary (e.g.yaml/json) to be one level deep - Args: - dictionary: the source dictionary - keys: list of keys on top level whose contents to flatten, if None all of them - Returns: - A one-level deep dictionary for the selected set of keys - """ - flat_dict = {} - for k,v in dictionary.items(): - if not keys or k in keys: - if isinstance(v,dict): - r = flatten_dict(v) - flat_dict.update(r) - else: - flat_dict[k] = v - return flat_dict - diff --git a/ush/python_utils/print_input_args.py b/ush/python_utils/print_input_args.py index 25d979eae9..3edcef3428 100644 --- a/ush/python_utils/print_input_args.py +++ b/ush/python_utils/print_input_args.py @@ -4,12 +4,12 @@ import inspect from textwrap import dedent -from .misc import lowercase from .print_msg import print_info_msg from .environment import import_vars + def print_input_args(valid_args): - """ Prints function arguments for debugging purposes + """Prints function arguments for debugging purposes Args: valid_args: dictionary of arg-value pairs @@ -20,11 +20,11 @@ def print_input_args(valid_args): # get verbosity from environment IMPORTS = ["DEBUG"] import_vars(env_vars=IMPORTS) - - if list(valid_args.keys())[0] == '__unset__': + + if list(valid_args.keys())[0] == "__unset__": valid_arg_names = {} else: - valid_arg_names = valid_args + valid_arg_names = valid_args num_valid_args = len(valid_arg_names) filename = inspect.stack()[1].filename @@ -32,21 +32,24 @@ def print_input_args(valid_args): filename_base = os.path.basename(filename) if num_valid_args == 0: - msg = dedent(f''' + msg = dedent( + f''' No arguments have been passed to function {function} in script {filename_base} located - - \"{filename}\"''') + + \"{filename}\"''' + ) else: - msg = dedent(f''' + msg = dedent( + f""" The arguments to function {function} in script {filename_base} located - + \"{filename}\" - have been set as follows:\n\n''') + have been set as follows:\n\n""" + ) - for k,v in valid_arg_names.items(): + for k, v in valid_arg_names.items(): msg = msg + f' {k}="{v}"\n' - print_info_msg(msg,verbose=DEBUG) + print_info_msg(msg, verbose=DEBUG) return num_valid_args - diff --git a/ush/python_utils/print_msg.py b/ush/python_utils/print_msg.py index 75858e5613..e943ab46da 100644 --- a/ush/python_utils/print_msg.py +++ b/ush/python_utils/print_msg.py @@ -4,7 +4,8 @@ import sys from textwrap import dedent -def print_err_msg_exit(error_msg="",stack_trace=True): + +def print_err_msg_exit(error_msg="", stack_trace=True): """Function to print out an error message to stderr and exit. It can optionally print the stack trace as well. @@ -17,12 +18,13 @@ def print_err_msg_exit(error_msg="",stack_trace=True): if stack_trace: traceback.print_stack(file=sys.stderr) - msg_footer='\nExiting with nonzero status.' + msg_footer = "\nExiting with nonzero status." print(dedent(error_msg) + msg_footer, file=sys.stderr) sys.exit(1) -def print_info_msg(info_msg,verbose=True): - """ Function to print information message to stdout, when verbose + +def print_info_msg(info_msg, verbose=True): + """Function to print information message to stdout, when verbose is set to True. It does proper "dedentation" that is needed for readability of python code. @@ -32,9 +34,8 @@ def print_info_msg(info_msg,verbose=True): Returns: True: if message is successfully printed """ - - if verbose == True: + + if verbose: print(dedent(info_msg)) return True return False - diff --git a/ush/python_utils/process_args.py b/ush/python_utils/process_args.py index 0baf0d4f9b..3eea16f034 100644 --- a/ush/python_utils/process_args.py +++ b/ush/python_utils/process_args.py @@ -1,10 +1,13 @@ #!/usr/bin/env python3 from textwrap import dedent + +from .print_msg import print_err_msg_exit from .check_var_valid_value import check_var_valid_value + def process_args(valid_args, **kwargs): - """ Function to process a list of variable name-value pairs. + """Function to process a list of variable name-value pairs. It checks whether each argument is a valid argument or not. Args: @@ -13,52 +16,59 @@ def process_args(valid_args, **kwargs): Returns: A dictionary of all valid (arg,value) pairs """ - - if valid_args[0] == '__unset__': + + if valid_args[0] == "__unset__": valid_arg_names = [] else: - valid_arg_names = valid_args + valid_arg_names = valid_args num_valid_args = len(valid_arg_names) num_arg_val_pairs = len(kwargs) if num_arg_val_pairs > num_valid_args: - print_err_msg_exit(f''' + print_err_msg_exit( + f""" The number of argument-value pairs specified on the command line (num_- arg_val_pairs) must be less than or equal to the number of valid argu- ments (num_valid_args) specified in the array valid_arg_names: num_arg_val_pairs = {num_arg_val_pairs} num_valid_args = {num_valid_args} - valid_arg_names = ( {valid_arg_names_str})''') + valid_arg_names = ( {valid_arg_names})""" + ) if num_valid_args == 0: return None values_args = [None] * num_valid_args - for i,a in enumerate(valid_args): + for i, a in enumerate(valid_args): if a is None: - print_err_msg_exit(f''' - The list of valid arguments (valid_arg_names) cannot contain empty elements, + print_err_msg_exit( + f''' + The list of valid arguments (valid_arg_names) cannot contain empty elements, but the element with index i={i} is empty: valid_arg_names = ( {valid_arg_names}) - valid_arg_names[{i}] = \"{valid_arg_names[i]}\"''') + valid_arg_names[{i}] = \"{valid_arg_names[i]}\"''' + ) - for arg_name,arg_value in kwargs.items(): - err_msg=dedent(f''' - The specified argument name (arg_name) in the current argument-value + for arg_name, arg_value in kwargs.items(): + err_msg = dedent( + f""" + The specified argument name (arg_name) in the current argument-value pair (arg_val_pair) is not valid: arg_name = \"{arg_name}\" - arg_val = \"{arg_value}\"\n''') + arg_val = \"{arg_value}\"\n""" + ) check_var_valid_value(arg_name, valid_arg_names, err_msg) idx = valid_arg_names.index(arg_name) if values_args[idx] is not None: - print_err_msg_exit(f''' + print_err_msg_exit( + f""" The current argument has already been assigned a value: arg_name = \"{arg_name}\" key_value_pair = {kwargs} - Please assign values to arguments only once on the command line.''') + Please assign values to arguments only once on the command line.""" + ) values_args[idx] = arg_value - - return dict(zip(valid_args,values_args)) + return dict(zip(valid_args, values_args)) diff --git a/ush/python_utils/run_command.py b/ush/python_utils/run_command.py index 70978bd789..3ab0fce898 100644 --- a/ush/python_utils/run_command.py +++ b/ush/python_utils/run_command.py @@ -2,24 +2,24 @@ import subprocess + def run_command(cmd): - """ Run system command in a subprocess + """Run system command in a subprocess Args: cmd: command to execute Returns: Tuple of (exit code, std_out, std_err) """ - proc = subprocess.Popen(cmd, - stdout=subprocess.PIPE, - stderr=subprocess.PIPE, - shell=True, - universal_newlines=True) + proc = subprocess.Popen( + cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=True, + universal_newlines=True, + ) std_out, std_err = proc.communicate() # strip trailing newline character - return (proc.returncode, - std_out.rstrip('\n'), - std_err.rstrip('\n')) - + return (proc.returncode, std_out.rstrip("\n"), std_err.rstrip("\n")) diff --git a/ush/python_utils/test_python_utils.py b/ush/python_utils/test_python_utils.py index 52defb1c6c..eb997c0bb3 100644 --- a/ush/python_utils/test_python_utils.py +++ b/ush/python_utils/test_python_utils.py @@ -17,132 +17,151 @@ from python_utils import * + class Testing(unittest.TestCase): def test_misc(self): - self.assertEqual( uppercase('upper'), 'UPPER' ) - self.assertEqual( lowercase('LOWER'), 'lower' ) + self.assertEqual(uppercase("upper"), "UPPER") + self.assertEqual(lowercase("LOWER"), "lower") # regex in file - pattern = f'^[ ]*(lsm_ruc)<\/scheme>[ ]*$' - FILE=f"{self.PATH}/../test_data/suite_FV3_GSD_SAR.xml" + pattern = "^[ ]*(lsm_ruc)<\/scheme>[ ]*$" + FILE = f"{self.PATH}/../test_data/suite_FV3_GSD_SAR.xml" match = find_pattern_in_file(pattern, FILE) - self.assertEqual( ("lsm_ruc",), match) + self.assertEqual(("lsm_ruc",), match) # regex in string with open(FILE) as f: content = f.read() find_pattern_in_str(pattern, content) - self.assertEqual( ("lsm_ruc",), match) + self.assertEqual(("lsm_ruc",), match) + def test_xml_parser(self): - FILE=f"{self.PATH}/../test_data/suite_FV3_GSD_SAR.xml" + FILE = f"{self.PATH}/../test_data/suite_FV3_GSD_SAR.xml" tree = load_xml_file(FILE) - self.assertTrue(has_tag_with_value(tree,"scheme","lsm_ruc")) + self.assertTrue(has_tag_with_value(tree, "scheme", "lsm_ruc")) + def test_check_for_preexist_dir_file(self): - cmd_vrfy('mkdir -p test_data/dir') - self.assertTrue( os.path.exists('test_data/dir') ) - check_for_preexist_dir_file('test_data/dir', 'rename') - dirs = glob.glob('test_data/dir_*') - self.assertEqual( len(dirs), 1) - rm_vrfy('-rf test_data/dir*') + cmd_vrfy("mkdir -p test_data/dir") + self.assertTrue(os.path.exists("test_data/dir")) + check_for_preexist_dir_file("test_data/dir", "rename") + dirs = glob.glob("test_data/dir_*") + self.assertEqual(len(dirs), 1) + rm_vrfy("-rf test_data/dir*") + def test_check_var_valid_value(self): - self.assertTrue( check_var_valid_value('rice', [ 'egg', 'spam', 'rice' ]) ) + self.assertTrue(check_var_valid_value("rice", ["egg", "spam", "rice"])) + def test_count_files(self): - (_,target_cnt,_) = run_command('ls -l *.py | wc -l') - cnt = count_files('py') + (_, target_cnt, _) = run_command("ls -l *.py | wc -l") + cnt = count_files("py") self.assertEqual(cnt, int(target_cnt)) + def test_filesys_cmds(self): - dPATH=f'{self.PATH}/test_data/dir' + dPATH = f"{self.PATH}/test_data/dir" mkdir_vrfy(dPATH) - self.assertTrue( os.path.exists(dPATH) ) - cp_vrfy(f'{self.PATH}/misc.py', f'{dPATH}/miscs.py') - self.assertTrue( os.path.exists(f'{dPATH}/miscs.py') ) - cmd_vrfy(f'rm -rf {dPATH}') - self.assertFalse( os.path.exists('tt.py') ) + self.assertTrue(os.path.exists(dPATH)) + cp_vrfy(f"{self.PATH}/misc.py", f"{dPATH}/miscs.py") + self.assertTrue(os.path.exists(f"{dPATH}/miscs.py")) + cmd_vrfy(f"rm -rf {dPATH}") + self.assertFalse(os.path.exists("tt.py")) + def test_get_charvar_from_netcdf(self): - FILE=f'{self.PATH}/test_data/sample.nc' - val = get_charvar_from_netcdf(FILE, 'pressure') - self.assertTrue( val and (val.split()[0], '955.5,')) + FILE = f"{self.PATH}/test_data/sample.nc" + val = get_charvar_from_netcdf(FILE, "pressure") + self.assertTrue(val and (val.split()[0], "955.5,")) + def test_run_command(self): - self.assertEqual( run_command('echo hello'), (0, 'hello', '') ) + self.assertEqual(run_command("echo hello"), (0, "hello", "")) + def test_get_elem_inds(self): - arr = [ 'egg', 'spam', 'egg', 'rice', 'egg'] - self.assertEqual( get_elem_inds(arr, 'egg', 'first' ) , 0 ) - self.assertEqual( get_elem_inds(arr, 'egg', 'last' ) , 4 ) - self.assertEqual( get_elem_inds(arr, 'egg', 'all' ) , [0, 2, 4] ) + arr = ["egg", "spam", "egg", "rice", "egg"] + self.assertEqual(get_elem_inds(arr, "egg", "first"), 0) + self.assertEqual(get_elem_inds(arr, "egg", "last"), 4) + self.assertEqual(get_elem_inds(arr, "egg", "all"), [0, 2, 4]) + def test_interpol_to_arbit_CRES(self): RES = 800 - RES_array = [ 5, 25, 40, 60, 80, 100, 400, 700, 1000, 1500, 2800, 3000 ] - prop_array = [ 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.65, 0.7, 1.0, 1.1, 1.2, 1.3 ] + RES_array = [5, 25, 40, 60, 80, 100, 400, 700, 1000, 1500, 2800, 3000] + prop_array = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.65, 0.7, 1.0, 1.1, 1.2, 1.3] prop = interpol_to_arbit_CRES(RES, RES_array, prop_array) self.assertAlmostEqual(prop, 0.8) + def test_create_symlink_to_file(self): - TARGET = f'{self.PATH}/test_python_utils.py' - SYMLINK = f'{self.PATH}/test_data/test_python_utils.py' - create_symlink_to_file(TARGET,SYMLINK) + TARGET = f"{self.PATH}/test_python_utils.py" + SYMLINK = f"{self.PATH}/test_data/test_python_utils.py" + create_symlink_to_file(TARGET, SYMLINK) + def test_define_macos_utilities(self): - set_env_var('MYVAR','MYVAL') - val = os.getenv('MYVAR') - self.assertEqual(val,'MYVAL') - self.assertEqual(os.getenv('SED'), - 'gsed' if os.uname() == 'Darwin' else 'sed') + set_env_var("MYVAR", "MYVAL") + val = os.getenv("MYVAR") + self.assertEqual(val, "MYVAL") + self.assertEqual(os.getenv("SED"), "gsed" if os.uname() == "Darwin" else "sed") + def test_process_args(self): - valid_args = [ "arg1", "arg2", "arg3", "arg4" ] - values = process_args( valid_args, - arg2 = "bye", arg3 = "hello", - arg4 = ["this", "is", "an", "array"] ) - self.assertEqual(values, - {'arg1': None, - 'arg2': 'bye', - 'arg3': 'hello', - 'arg4': ['this', 'is', 'an', 'array']} ) + valid_args = ["arg1", "arg2", "arg3", "arg4"] + values = process_args( + valid_args, arg2="bye", arg3="hello", arg4=["this", "is", "an", "array"] + ) + self.assertEqual( + values, + { + "arg1": None, + "arg2": "bye", + "arg3": "hello", + "arg4": ["this", "is", "an", "array"], + }, + ) + def test_print_input_args(self): - valid_args = { "arg1":1, "arg2":2, "arg3":3, "arg4":4 } - self.assertEqual( print_input_args(valid_args), 4 ) + valid_args = {"arg1": 1, "arg2": 2, "arg3": 3, "arg4": 4} + self.assertEqual(print_input_args(valid_args), 4) + def test_import_vars(self): - #test import + # test import global MYVAR - set_env_var("MYVAR","MYVAL") + set_env_var("MYVAR", "MYVAL") env_vars = ["PWD", "MYVAR"] import_vars(env_vars=env_vars) - self.assertEqual( os.path.realpath(PWD), os.path.realpath(os.getcwd()) ) - self.assertEqual(MYVAR,"MYVAL") - #test export - MYVAR="MYNEWVAL" - self.assertEqual(os.environ['MYVAR'],'MYVAL') + self.assertEqual(os.path.realpath(PWD), os.path.realpath(os.getcwd())) + self.assertEqual(MYVAR, "MYVAL") + # test export + MYVAR = "MYNEWVAL" + self.assertEqual(os.environ["MYVAR"], "MYVAL") export_vars(env_vars=env_vars) - self.assertEqual(os.environ['MYVAR'],'MYNEWVAL') - #test custom dictionary - dictionary = { "Hello": "World!" } + self.assertEqual(os.environ["MYVAR"], "MYNEWVAL") + # test custom dictionary + dictionary = {"Hello": "World!"} import_vars(dictionary=dictionary) - self.assertEqual( Hello, "World!" ) - #test array - shell_str='("1" "2") \n' + self.assertEqual(Hello, "World!") + # test array + shell_str = '("1" "2") \n' v = str_to_list(shell_str) - self.assertTrue( isinstance(v,list) ) + self.assertTrue(isinstance(v, list)) self.assertEqual(v, [1, 2]) shell_str = '( "1" "2" \n' v = str_to_list(shell_str) - self.assertFalse( isinstance(v,list) ) + self.assertFalse(isinstance(v, list)) + def test_config_parser(self): - cfg = { "HRS": [ "1", "2" ] } + cfg = {"HRS": ["1", "2"]} shell_str = cfg_to_shell_str(cfg) - self.assertEqual( shell_str, 'HRS=( "1" "2" )\n') + self.assertIn('HRS=( "1" "2" )\n', shell_str) # ini file - cfg = load_ini_config(f'{self.PATH}/test_data/Externals.cfg') - self.assertIn( \ - 'regional_workflow', - get_ini_value( \ - cfg, - 'regional_workflow', - 'repo_url')) + cfg = load_ini_config(f"{self.PATH}/test_data/Externals.cfg") + self.assertIn( + "regional_workflow", get_ini_value(cfg, "regional_workflow", "repo_url") + ) + def test_print_msg(self): - self.assertEqual( print_info_msg("Hello World!", verbose=False), False) + self.assertEqual(print_info_msg("Hello World!", verbose=False), False) + def setUp(self): - """ setUp is where we do preparation for running the unittests. + """setUp is where we do preparation for running the unittests. If you need to download files for running test cases, prepare common stuff - for all test cases etc, this is the best place to do it """ - define_macos_utilities(); - set_env_var('DEBUG','FALSE') + for all test cases etc, this is the best place to do it""" + + define_macos_utilities() + set_env_var("DEBUG", "FALSE") self.PATH = os.path.dirname(__file__) - -if __name__ == '__main__': - unittest.main() + +if __name__ == "__main__": + unittest.main() diff --git a/ush/python_utils/xml_parser.py b/ush/python_utils/xml_parser.py index 0428259c6d..a6f5add2e5 100644 --- a/ush/python_utils/xml_parser.py +++ b/ush/python_utils/xml_parser.py @@ -2,8 +2,9 @@ import xml.etree.ElementTree as ET + def load_xml_file(xml_file): - """ Loads xml file + """Loads xml file Args: xml_file: path to xml file @@ -13,8 +14,9 @@ def load_xml_file(xml_file): tree = ET.parse(xml_file) return tree + def has_tag_with_value(tree, tag, value): - """ Check if xml tree has a node with tag and value + """Check if xml tree has a node with tag and value Args: tree: the xml tree @@ -27,4 +29,3 @@ def has_tag_with_value(tree, tag, value): if node.tag == tag and node.text == value: return True return False - diff --git a/ush/retrieve_data.py b/ush/retrieve_data.py index 1257048e42..2792e7ba28 100755 --- a/ush/retrieve_data.py +++ b/ush/retrieve_data.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # pylint: disable=logging-fstring-interpolation -''' +""" This script helps users pull data from known data streams, including URLS and HPSS (only on supported NOAA platforms), or from user-supplied data locations on disk. @@ -23,7 +23,7 @@ python retrieve_data.py -h Also see the parse_args function below. -''' +""" import argparse import datetime as dt @@ -37,30 +37,30 @@ import yaml + def clean_up_output_dir(expected_subdir, local_archive, output_path, source_paths): - ''' Remove expected sub-directories and existing_archive files on + """Remove expected sub-directories and existing_archive files on disk once all files have been extracted and put into the specified - output location. ''' + output location.""" unavailable = {} # Check to make sure the files exist on disk for file_path in source_paths: local_file_path = os.path.join(output_path, file_path.lstrip("/")) if not os.path.exists(local_file_path): - logging.info(f'File does not exist: {local_file_path}') - unavailable['hpss'] = source_paths + logging.info(f"File does not exist: {local_file_path}") + unavailable["hpss"] = source_paths else: file_name = os.path.basename(file_path) expected_output_loc = os.path.join(output_path, file_name) if not local_file_path == expected_output_loc: - logging.info(f'Moving {local_file_path} to ' \ - f'{expected_output_loc}') + logging.info(f"Moving {local_file_path} to " f"{expected_output_loc}") shutil.move(local_file_path, expected_output_loc) # Clean up directories from inside archive, if they exist - if os.path.exists(expected_subdir) and expected_subdir != './': - logging.info(f'Removing {expected_subdir}') + if os.path.exists(expected_subdir) and expected_subdir != "./": + logging.info(f"Removing {expected_subdir}") os.removedirs(expected_subdir) # If an archive exists on disk, remove it @@ -69,36 +69,39 @@ def clean_up_output_dir(expected_subdir, local_archive, output_path, source_path return unavailable + def copy_file(source, destination): - ''' + """ Copy a file from a source and place it in the destination location. Return a boolean value reflecting the state of the copy. Assumes destination exists. - ''' + """ if not os.path.exists(source): - logging.info(f'File does not exist on disk \n {source}') + logging.info(f"File does not exist on disk \n {source}") return False # Using subprocess here because system copy is much faster than # python copy options. - cmd = f'cp {source} {destination}' - logging.info(f'Running command: \n {cmd}') + cmd = f"cp {source} {destination}" + logging.info(f"Running command: \n {cmd}") try: - subprocess.run(cmd, + subprocess.run( + cmd, check=True, shell=True, - ) + ) except subprocess.CalledProcessError as err: logging.info(err) return False return True + def download_file(url): - ''' + """ Download a file from a url source, and place it in a target location on disk. @@ -107,31 +110,33 @@ def download_file(url): Return: boolean value reflecting state of download. - ''' + """ # wget flags: # -c continue previous attempt # -T timeout seconds # -t number of tries - cmd = f'wget -q -c -T 30 -t 3 {url}' - logging.info(f'Running command: \n {cmd}') + cmd = f"wget -q -c -T 30 -t 3 {url}" + logging.info(f"Running command: \n {cmd}") try: - subprocess.run(cmd, + subprocess.run( + cmd, check=True, shell=True, - ) + ) except subprocess.CalledProcessError as err: logging.info(err) return False except: - logging.error('Command failed!') + logging.error("Command failed!") raise return True + def arg_list_to_range(args): - ''' + """ Given an argparse list argument, return the sequence to process. The length of the list will determine what sequence items are returned: @@ -144,7 +149,7 @@ def arg_list_to_range(args): argparse should provide a list of at least one item (nargs='+'). Must ensure that the list contains integers. - ''' + """ args = args if isinstance(args, list) else list(args) arg_len = len(args) @@ -154,9 +159,10 @@ def arg_list_to_range(args): return args + def fill_template(template_str, cycle_date, templates_only=False, **kwargs): - ''' Fill in the provided template string with date time information, + """Fill in the provided template string with date time information, and return the resulting string. Arguments: @@ -175,77 +181,81 @@ def fill_template(template_str, cycle_date, templates_only=False, **kwargs): Return: filled template string - ''' + """ # Parse keyword args - ens_group = kwargs.get('ens_group') - fcst_hr = kwargs.get('fcst_hr', 0) - mem = kwargs.get('mem', '') + ens_group = kwargs.get("ens_group") + fcst_hr = kwargs.get("fcst_hr", 0) + mem = kwargs.get("mem", "") # ----- - cycle_hour = cycle_date.strftime('%H') + cycle_hour = cycle_date.strftime("%H") + # One strategy for binning data files at NCEP is to put them into 6 # cycle bins. The archive file names include the low and high end of the # range. Set the range as would be indicated in the archive file # here. Integer division is intentional here. low_end = int(cycle_hour) // 6 * 6 - bin6 = f'{low_end:02d}-{low_end+5:02d}' + bin6 = f"{low_end:02d}-{low_end+5:02d}" # Another strategy is to bundle odd cycle hours with their next # lowest even cycle hour. Files are named only with the even hour. # Integer division is intentional here. - hh_even = f'{int(cycle_hour) // 2 * 2:02d}' + hh_even = f"{int(cycle_hour) // 2 * 2:02d}" format_values = dict( bin6=bin6, ens_group=ens_group, fcst_hr=fcst_hr, - dd=cycle_date.strftime('%d'), + dd=cycle_date.strftime("%d"), hh=cycle_hour, hh_even=hh_even, - jjj=cycle_date.strftime('%j'), + jjj=cycle_date.strftime("%j"), mem=mem, - mm=cycle_date.strftime('%m'), - yy=cycle_date.strftime('%y'), - yyyy=cycle_date.strftime('%Y'), - yyyymm=cycle_date.strftime('%Y%m'), - yyyymmdd=cycle_date.strftime('%Y%m%d'), - yyyymmddhh=cycle_date.strftime('%Y%m%d%H'), - ) + mm=cycle_date.strftime("%m"), + yy=cycle_date.strftime("%y"), + yyyy=cycle_date.strftime("%Y"), + yyyymm=cycle_date.strftime("%Y%m"), + yyyymmdd=cycle_date.strftime("%Y%m%d"), + yyyymmddhh=cycle_date.strftime("%Y%m%d%H"), + ) + if templates_only: return f'{",".join((format_values.keys()))}' return template_str.format(**format_values) + def create_target_path(target_path): - ''' + """ Append target path and create directory for ensemble members - ''' + """ if not os.path.exists(target_path): os.makedirs(target_path) return target_path + def find_archive_files(paths, file_names, cycle_date, ens_group): - ''' Given an equal-length set of archive paths and archive file + """Given an equal-length set of archive paths and archive file names, and a cycle date, check HPSS via hsi to make sure at least one set exists. Return a dict of the paths of the existing archive, along with - the item in set of paths that was found.''' + the item in set of paths that was found.""" zipped_archive_file_paths = zip(paths, file_names) - # Narrow down which HPSS files are available for this date - for list_item, (archive_path, archive_file_names) in \ - enumerate(zipped_archive_file_paths): + for list_item, (archive_path, archive_file_names) in enumerate( + zipped_archive_file_paths + ): existing_archives = {} if not isinstance(archive_file_names, list): archive_file_names = [archive_file_names] for n_fp, archive_file_name in enumerate(archive_file_names): - # Only test the first item in the list, it will tell us if this - # set exists at this date. + # Only test the first item in the list, it will tell us if this + # set exists at this date. file_path = os.path.join(archive_path, archive_file_name) file_path = fill_template(file_path, cycle_date, ens_group=ens_group) file_path = hsi_single_file(file_path) @@ -255,14 +265,15 @@ def find_archive_files(paths, file_names, cycle_date, ens_group): if existing_archives: for existing_archive in existing_archives.values(): - logging.info(f'Found HPSS file: {existing_archive}') + logging.info(f"Found HPSS file: {existing_archive}") return existing_archives, list_item - return '', 0 + return "", 0 + def get_file_templates(cla, known_data_info, data_store, use_cla_tmpl=False): - ''' Returns the file templates requested by user input, either from + """Returns the file templates requested by user input, either from the command line, or from the known data information dict. Arguments: @@ -275,29 +286,28 @@ def get_file_templates(cla, known_data_info, data_store, use_cla_tmpl=False): Returns: file_templates a list of file templates - ''' + """ - file_templates = known_data_info.get(data_store, {}).get('file_names') + file_templates = known_data_info.get(data_store, {}).get("file_names") if use_cla_tmpl: - file_templates = cla.file_templates if cla.file_templates else \ - file_templates + file_templates = cla.file_templates if cla.file_templates else file_templates if isinstance(file_templates, dict): if cla.file_type is not None: file_templates = file_templates[cla.file_type] file_templates = file_templates[cla.anl_or_fcst] if not file_templates: - msg = ('No file naming convention found. They must be provided \ - either on the command line or on in a config file.') + msg = "No file naming convention found. They must be provided \ + either on the command line or on in a config file." raise argparse.ArgumentTypeError(msg) return file_templates -def get_requested_files(cla, file_templates, input_locs, method='disk', - **kwargs): + +def get_requested_files(cla, file_templates, input_locs, method="disk", **kwargs): # pylint: disable=too-many-locals - ''' This function copies files from disk locations + """This function copies files from disk locations or downloads files from a url, depending on the option specified for user. @@ -320,72 +330,67 @@ def get_requested_files(cla, file_templates, input_locs, method='disk', Returns: unavailable a list of locations/files that were unretrievable - ''' + """ - members = kwargs.get('members', '') + members = kwargs.get("members", "") members = members if isinstance(members, list) else [members] + check_all = kwargs.get("check_all", False) - - check_all = kwargs.get('check_all', False) - - logging.info(f'Getting files named like {file_templates}') + logging.info(f"Getting files named like {file_templates}") # Make sure we're dealing with lists for input locations and file # templates. Makes it easier to loop and zip. - file_templates = file_templates if isinstance(file_templates, list) else \ - [file_templates] + file_templates = ( + file_templates if isinstance(file_templates, list) else [file_templates] + ) - input_locs = input_locs if isinstance(input_locs, list) else \ - [input_locs] + input_locs = input_locs if isinstance(input_locs, list) else [input_locs] orig_path = os.path.dirname(__file__) unavailable = [] locs_files = pair_locs_with_files(input_locs, file_templates, check_all) for mem in members: - target_path = fill_template(cla.output_path, - cla.cycle_date, - mem=mem) + target_path = fill_template(cla.output_path, cla.cycle_date, mem=mem) target_path = create_target_path(target_path) - logging.info(f'Retrieved files will be placed here: \n {target_path}') + logging.info(f"Retrieved files will be placed here: \n {target_path}") os.chdir(target_path) for fcst_hr in cla.fcst_hrs: - logging.debug(f'Looking for fhr = {fcst_hr}') + logging.debug(f"Looking for fhr = {fcst_hr}") for loc, templates in locs_files: - templates = templates if isinstance(templates, list) \ - else [templates] - + templates = templates if isinstance(templates, list) else [templates] - logging.debug(f'Looking for files like {templates}') - logging.debug(f'They should be here: {loc}') + logging.debug(f"Looking for files like {templates}") + logging.debug(f"They should be here: {loc}") template_loc = loc for tmpl_num, template in enumerate(templates): if isinstance(loc, list) and len(loc) == len(templates): template_loc = loc[tmpl_num] input_loc = os.path.join(template_loc, template) - input_loc = fill_template(input_loc, - cla.cycle_date, - fcst_hr=fcst_hr, - mem=mem, - ) - logging.debug(f'Full file path: {input_loc}') - - if method == 'disk': + input_loc = fill_template( + input_loc, + cla.cycle_date, + fcst_hr=fcst_hr, + mem=mem, + ) + logging.debug(f"Full file path: {input_loc}") + + if method == "disk": retrieved = copy_file(input_loc, target_path) - if method == 'download': + if method == "download": retrieved = download_file(input_loc) # Wait a bit before trying the next download. # Seems to reduce the occurrence of timeouts # when downloading from AWS time.sleep(15) - logging.debug(f'Retrieved status: {retrieved}') + logging.debug(f"Retrieved status: {retrieved}") if not retrieved: unavailable.append(input_loc) # Go on to the next location if the first file @@ -402,9 +407,10 @@ def get_requested_files(cla, file_templates, input_locs, method='disk', os.chdir(orig_path) return unavailable -def hsi_single_file(file_path, mode='ls'): - ''' Call hsi as a subprocess for Python and return information about +def hsi_single_file(file_path, mode="ls"): + + """Call hsi as a subprocess for Python and return information about whether the file_path was found. Arguments: @@ -412,27 +418,28 @@ def hsi_single_file(file_path, mode='ls'): mode the hsi command to run. ls is default. may also pass "get" to retrieve the file path - ''' - cmd = f'hsi {mode} {file_path}' + """ + cmd = f"hsi {mode} {file_path}" - logging.info(f'Running command \n {cmd}') + logging.info(f"Running command \n {cmd}") try: - subprocess.run(cmd, - check=True, - shell=True, - ) + subprocess.run( + cmd, + check=True, + shell=True, + ) except subprocess.CalledProcessError: - logging.warning(f'{file_path} is not available!') - return '' + logging.warning(f"{file_path} is not available!") + return "" return file_path -def hpss_requested_files(cla, file_names, store_specs, members=-1, - ens_group=-1): + +def hpss_requested_files(cla, file_names, store_specs, members=-1, ens_group=-1): # pylint: disable=too-many-locals - ''' This function interacts with the "hpss" protocol in a provided + """This function interacts with the "hpss" protocol in a provided data store specs file to download a set of files requested by the user. Depending on the type of archive file (zip or tar), it will either pull the entire file and unzip it, or attempt to pull @@ -443,15 +450,16 @@ def hpss_requested_files(cla, file_names, store_specs, members=-1, This function exepcts that the output directory exists and is writable. - ''' + """ members = [-1] if members == -1 else members - archive_paths = store_specs['archive_path'] - archive_paths = archive_paths if isinstance(archive_paths, list) \ - else [archive_paths] + archive_paths = store_specs["archive_path"] + archive_paths = ( + archive_paths if isinstance(archive_paths, list) else [archive_paths] + ) # Could be a list of lists - archive_file_names = store_specs.get('archive_file_names', {}) + archive_file_names = store_specs.get("archive_file_names", {}) if cla.file_type is not None: archive_file_names = archive_file_names[cla.file_type] @@ -461,33 +469,35 @@ def hpss_requested_files(cla, file_names, store_specs, members=-1, unavailable = {} existing_archives = {} - logging.debug(f'Will try to look for: '\ - f' {list(zip(archive_paths, archive_file_names))}') + logging.debug( + f"Will try to look for: " f" {list(zip(archive_paths, archive_file_names))}" + ) - existing_archives, which_archive = find_archive_files(archive_paths, - archive_file_names, - cla.cycle_date, - ens_group=ens_group, - ) + existing_archives, which_archive = find_archive_files( + archive_paths, + archive_file_names, + cla.cycle_date, + ens_group=ens_group, + ) - logging.debug(f'Found existing archives: {existing_archives}') + logging.debug(f"Found existing archives: {existing_archives}") if not existing_archives: - logging.warning('No archive files were found!') - unavailable['archive'] = list(zip(archive_paths, archive_file_names)) + logging.warning("No archive files were found!") + unavailable["archive"] = list(zip(archive_paths, archive_file_names)) return unavailable - logging.info(f'Files in archive are named: {file_names}') + logging.info(f"Files in archive are named: {file_names}") - archive_internal_dirs = store_specs.get('archive_internal_dir', ['']) + archive_internal_dirs = store_specs.get("archive_internal_dir", [""]) if isinstance(archive_internal_dirs, dict): - archive_internal_dirs = archive_internal_dirs.get(cla.anl_or_fcst, ['']) + archive_internal_dirs = archive_internal_dirs.get(cla.anl_or_fcst, [""]) # which_archive matters for choosing the correct file names within, # but we can safely just try all options for the # archive_internal_dir - logging.debug(f'Checking archive number {which_archive} in list.') + logging.debug(f"Checking archive number {which_archive} in list.") for archive_internal_dir_tmpl in archive_internal_dirs: for mem in members: @@ -495,43 +505,45 @@ def hpss_requested_files(cla, file_names, store_specs, members=-1, archive_internal_dir_tmpl, cla.cycle_date, mem=mem, - ) + ) - output_path = fill_template(cla.output_path, - cla.cycle_date, mem=mem) - logging.info(f'Will place files in {os.path.abspath(output_path)}') + output_path = fill_template(cla.output_path, cla.cycle_date, mem=mem) + logging.info(f"Will place files in {os.path.abspath(output_path)}") orig_path = os.path.dirname(__file__) - logging.debug(f'CWD: {os.getcwd()}') + logging.debug(f"CWD: {os.getcwd()}") os.chdir(orig_path) if mem != -1: - archive_internal_dir = fill_template(archive_internal_dir_tmpl, - cla.cycle_date, - mem=mem, - ) + archive_internal_dir = fill_template( + archive_internal_dir_tmpl, + cla.cycle_date, + mem=mem, + ) output_path = create_target_path(output_path) - logging.info(f'Will place files in {os.path.abspath(output_path)}') + logging.info(f"Will place files in {os.path.abspath(output_path)}") os.chdir(output_path) source_paths = [] for fcst_hr in cla.fcst_hrs: for file_name in file_names: - source_paths.append(fill_template( - os.path.join(archive_internal_dir, file_name), - cla.cycle_date, - fcst_hr=fcst_hr, - mem=mem, - ens_group=ens_group, - )) + source_paths.append( + fill_template( + os.path.join(archive_internal_dir, file_name), + cla.cycle_date, + fcst_hr=fcst_hr, + mem=mem, + ens_group=ens_group, + ) + ) expected = set(source_paths) unavailable = {} for existing_archive in existing_archives.values(): - if store_specs.get('archive_format', 'tar') == 'zip': + if store_specs.get("archive_format", "tar") == "zip": # Get the entire file from HPSS - existing_archive = hsi_single_file(existing_archive, mode='get') + existing_archive = hsi_single_file(existing_archive, mode="get") # Grab only the necessary files from the archive cmd = f'unzip -o {os.path.basename(existing_archive)} {" ".join(source_paths)}' @@ -539,21 +551,24 @@ def hpss_requested_files(cla, file_names, store_specs, members=-1, else: cmd = f'htar -xvf {existing_archive} {" ".join(source_paths)}' - logging.info(f'Running command \n {cmd}') - subprocess.run(cmd, - check=True, - shell=True, - ) + logging.info(f"Running command \n {cmd}") + subprocess.run( + cmd, + check=True, + shell=True, + ) # Check that files exist and Remove any data transfer artifacts. # Returns {'hpss': []}, turn that into a new dict of # sets. - unavailable[existing_archive] = set(clean_up_output_dir( - expected_subdir=archive_internal_dir, - local_archive=os.path.basename(existing_archive), - output_path=output_path, - source_paths=source_paths, - ).get('hpss', [])) + unavailable[existing_archive] = set( + clean_up_output_dir( + expected_subdir=archive_internal_dir, + local_archive=os.path.basename(existing_archive), + output_path=output_path, + source_paths=source_paths, + ).get("hpss", []) + ) # Once we go through all the archives, the union of all # "unavailable" files should equal the "expected" list of @@ -563,7 +578,6 @@ def hpss_requested_files(cla, file_names, store_specs, members=-1, # something has gone wrong. unavailable = set.union(*unavailable.values()) - # Report only the files that are truly unavailable if not expected == unavailable: return unavailable - expected @@ -572,30 +586,33 @@ def hpss_requested_files(cla, file_names, store_specs, members=-1, return {} + def load_str(arg): - ''' Load a dict string safely using YAML. Return the resulting dict. ''' + """Load a dict string safely using YAML. Return the resulting dict.""" return yaml.load(arg, Loader=yaml.SafeLoader) + def config_exists(arg): - ''' + """ Check to ensure that the provided config file exists. If it does, load it with YAML's safe loader and return the resulting dict. - ''' + """ # Check for existence of file if not os.path.exists(arg): - msg = f'{arg} does not exist!' + msg = f"{arg} does not exist!" raise argparse.ArgumentTypeError(msg) - with open(arg, 'r') as config_path: + with open(arg, "r") as config_path: cfg = yaml.load(config_path, Loader=yaml.SafeLoader) return cfg + def pair_locs_with_files(input_locs, file_templates, check_all): - ''' + """ Given a list of input locations and files, return an iterable that contains the multiple locations and file templates for files that should be searched in those locations. @@ -613,7 +630,7 @@ def pair_locs_with_files(input_locs, file_templates, check_all): The default will be to handle #1 and #2. #3 will be indicated by a flag in the yaml: "check_all: True" - ''' + """ if not check_all: @@ -625,8 +642,7 @@ def pair_locs_with_files(input_locs, file_templates, check_all): locs_files = list(zip(input_locs, file_templates)) # Case 1 above - elif len(file_templates) > len(input_locs) and \ - len(input_locs) == 1: + elif len(file_templates) > len(input_locs) and len(input_locs) == 1: locs_files = list(zip(input_locs, [file_templates])) else: @@ -641,14 +657,14 @@ def pair_locs_with_files(input_locs, file_templates, check_all): def path_exists(arg): - ''' Check whether the supplied path exists and is writeable ''' + """Check whether the supplied path exists and is writeable""" if not os.path.exists(arg): - msg = f'{arg} does not exist!' + msg = f"{arg} does not exist!" raise argparse.ArgumentTypeError(msg) - if not os.access(arg, os.X_OK|os.W_OK): - logging.error(f'{arg} is not writeable!') + if not os.access(arg, os.X_OK | os.W_OK): + logging.error(f"{arg} is not writeable!") raise argparse.ArgumentTypeError(msg) return arg @@ -656,60 +672,62 @@ def path_exists(arg): def setup_logging(debug=False): - ''' Calls initialization functions for logging package, and sets the - user-defined level for logging in the script.''' + """Calls initialization functions for logging package, and sets the + user-defined level for logging in the script.""" level = logging.WARNING if debug: level = logging.DEBUG - logging.basicConfig(format='%(levelname)s: %(message)s \n ', level=level) + logging.basicConfig(format="%(levelname)s: %(message)s \n ", level=level) if debug: - logging.info('Logging level set to DEBUG') - + logging.info("Logging level set to DEBUG") def write_summary_file(cla, data_store, file_templates): - ''' Given the command line arguments and the data store from which + """Given the command line arguments and the data store from which the data was retrieved, write a bash summary file that is needed by - the workflow elements downstream. ''' + the workflow elements downstream.""" files = [] for tmpl in file_templates: - files.extend([fill_template(tmpl, cla.cycle_date, fcst_hr=fh) for fh in cla.fcst_hrs]) + files.extend( + [fill_template(tmpl, cla.cycle_date, fcst_hr=fh) for fh in cla.fcst_hrs] + ) summary_fp = os.path.join(cla.output_path, cla.summary_file) - logging.info(f'Writing a summary file to {summary_fp}') - file_contents = dedent(f''' + 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={cla.output_path} EXTRN_MDL_FNS=( {' '.join(files)} ) EXTRN_MDL_FHRS=( {' '.join([str(i) for i in cla.fcst_hrs])} ) - ''') - logging.info(f'Contents: {file_contents}') + """ + ) + logging.info(f"Contents: {file_contents}") with open(summary_fp, "w") as summary: summary.write(file_contents) def to_datetime(arg): - ''' Return a datetime object give a string like YYYYMMDDHH. - ''' - return dt.datetime.strptime(arg, '%Y%m%d%H') + """Return a datetime object give a string like YYYYMMDDHH.""" + return dt.datetime.strptime(arg, "%Y%m%d%H") def to_lower(arg): - ''' Return a string provided by arg into all lower case. ''' + """Return a string provided by arg into all lower case.""" return arg.lower() def main(argv): # pylint: disable=too-many-branches, too-many-statements - ''' + """ Uses known location information to try the known locations and file paths in priority order. - ''' + """ cla = parse_args(argv) cla.fcst_hrs = arg_list_to_range(cla.fcst_hrs) @@ -718,68 +736,74 @@ def main(argv): cla.members = arg_list_to_range(cla.members) setup_logging(cla.debug) - print("Running script retrieve_data.py with args:\n", - f"{('-' * 80)}\n{('-' * 80)}") + print("Running script retrieve_data.py with args:\n", f"{('-' * 80)}\n{('-' * 80)}") for name, val in cla.__dict__.items(): - if name not in ['config']: + if name not in ["config"]: print(f"{name:>15s}: {val}") print(f"{('-' * 80)}\n{('-' * 80)}") - if 'disk' in cla.data_stores: + if "disk" in cla.data_stores: # Make sure a path was provided. if not cla.input_file_path: raise argparse.ArgumentTypeError( - ('You must provide an input_file_path when choosing ' \ - ' disk as a data store!')) + ( + "You must provide an input_file_path when choosing " + " disk as a data store!" + ) + ) - if 'hpss' in cla.data_stores: + if "hpss" in cla.data_stores: # Make sure hpss module is loaded try: - subprocess.run('which hsi', - check=True, - shell=True, - ) + subprocess.run( + "which hsi", + check=True, + shell=True, + ) except subprocess.CalledProcessError: - logging.error('You requested the hpss data store, but ' \ - 'the HPSS module isn\'t loaded. This data store ' \ - 'is only available on NOAA compute platforms.') + logging.error( + "You requested the hpss data store, but " + "the HPSS module isn't loaded. This data store " + "is only available on NOAA compute platforms." + ) sys.exit(1) - - known_data_info = cla.config.get(cla.external_model, {}) + known_data_info = cla.config.get(cla.external_model, {}) if not known_data_info: - msg = dedent(f'''No data stores have been defined for + msg = dedent( + f"""No data stores have been defined for {cla.external_model}! Only checking provided disk - location''') + location""" + ) if cla.input_file_path is None: - cla.data_stores = ['disk'] + cla.data_stores = ["disk"] raise KeyError(msg) logging.info(msg) unavailable = {} for data_store in cla.data_stores: - logging.info(f'Checking {data_store} for {cla.external_model}') + logging.info(f"Checking {data_store} for {cla.external_model}") store_specs = known_data_info.get(data_store, {}) - if data_store == 'disk': + if data_store == "disk": file_templates = get_file_templates( cla, known_data_info, - data_store='hpss', + data_store="hpss", use_cla_tmpl=True, - ) + ) - logging.debug(f'User supplied file names are: {file_templates}') - unavailable = get_requested_files(cla, - check_all=known_data_info.get('check_all', - False), - file_templates=file_templates, - input_locs=cla.input_file_path, - method='disk', - ) + logging.debug(f"User supplied file names are: {file_templates}") + unavailable = get_requested_files( + cla, + check_all=known_data_info.get("check_all", False), + file_templates=file_templates, + input_locs=cla.input_file_path, + method="disk", + ) elif not store_specs: - msg = (f'No information is available for {data_store}.') + msg = f"No information is available for {data_store}." raise KeyError(msg) else: @@ -788,19 +812,19 @@ def main(argv): cla, known_data_info, data_store=data_store, - ) + ) - if store_specs.get('protocol') == 'download': + if store_specs.get("protocol") == "download": unavailable = get_requested_files( cla, - check_all=known_data_info.get('check_all', False), + check_all=known_data_info.get("check_all", False), file_templates=file_templates, - input_locs=store_specs['url'], - method='download', + input_locs=store_specs["url"], + method="download", members=cla.members, - ) + ) - if store_specs.get('protocol') == 'htar': + if store_specs.get("protocol") == "htar": ens_groups = get_ens_groups(cla.members) for ens_group, members in ens_groups.items(): unavailable = hpss_requested_files( @@ -809,7 +833,7 @@ def main(argv): store_specs, members=members, ens_group=ens_group, - ) + ) if not unavailable: # All files are found. Stop looking! @@ -818,19 +842,19 @@ def main(argv): write_summary_file(cla, data_store, file_templates) break - logging.debug(f'Some unavailable files: {unavailable}') - logging.warning(f'Requested files are unavailable from {data_store}') + logging.debug(f"Some unavailable files: {unavailable}") + logging.warning(f"Requested files are unavailable from {data_store}") if unavailable: - logging.error('Could not find any of the requested files.') + logging.error("Could not find any of the requested files.") sys.exit(1) + def get_ens_groups(members): - ''' Given a list of ensemble members, return a dict with keys for + """Given a list of ensemble members, return a dict with keys for the ensemble group, and values are lists of ensemble members - requested in that group. ''' - + requested in that group.""" if members is None: return {-1: [-1]} @@ -844,120 +868,131 @@ def get_ens_groups(members): ens_groups[ens_group].append(mem) return ens_groups + def parse_args(argv): - ''' + """ Function maintains the arguments accepted by this script. Please see Python's argparse documenation for more information about settings of each argument. - ''' + """ - description=( - 'Allowable Python templates for paths, urls, and file names are '\ - ' defined in the fill_template function and include:\n' \ - f'{"-"*120}\n' \ - f'{fill_template("null", dt.datetime.now(), templates_only=True)}') + description = ( + "Allowable Python templates for paths, urls, and file names are " + " defined in the fill_template function and include:\n" + f'{"-"*120}\n' + f'{fill_template("null", dt.datetime.now(), templates_only=True)}' + ) parser = argparse.ArgumentParser( description=description, ) # Required parser.add_argument( - '--anl_or_fcst', - choices=('anl', 'fcst'), - help='Flag for whether analysis or forecast \ - files should be gathered', + "--anl_or_fcst", + choices=("anl", "fcst"), + help="Flag for whether analysis or forecast \ + files should be gathered", required=True, - ) + ) parser.add_argument( - '--config', - help='Full path to a configuration file containing paths and \ + "--config", + help="Full path to a configuration file containing paths and \ naming conventions for known data streams. The default included \ - in this repository is in ush/templates/data_locations.yml', + in this repository is in ush/templates/data_locations.yml", type=config_exists, - ) + ) parser.add_argument( - '--cycle_date', - help='Cycle date of the data to be retrieved in YYYYMMDDHH \ - format.', + "--cycle_date", + help="Cycle date of the data to be retrieved in YYYYMMDDHH \ + format.", required=True, type=to_datetime, - ) + ) parser.add_argument( - '--data_stores', - help='List of priority data_stores. Tries first list item \ - first. Choices: hpss, nomads, aws, disk', - nargs='*', + "--data_stores", + help="List of priority data_stores. Tries first list item \ + first. Choices: hpss, nomads, aws, disk", + nargs="*", required=True, type=to_lower, - ) + ) parser.add_argument( - '--external_model', - choices=('FV3GFS','GDAS', 'GEFS', 'GSMGFS', 'HRRR', 'NAM', 'RAP', 'RAPx', - 'HRRRx'), - help='External model label. This input is case-sensitive', + "--external_model", + choices=( + "FV3GFS", + "GDAS", + "GEFS", + "GSMGFS", + "HRRR", + "NAM", + "RAP", + "RAPx", + "HRRRx", + ), + help="External model label. This input is case-sensitive", required=True, - ) + ) parser.add_argument( - '--fcst_hrs', - help='A list describing forecast hours. If one argument, \ + "--fcst_hrs", + help="A list describing forecast hours. If one argument, \ one fhr will be processed. If 2 or 3 arguments, a sequence \ of forecast hours [start, stop, [increment]] will be \ processed. If more than 3 arguments, the list is processed \ - as-is.', - nargs='+', + as-is.", + nargs="+", required=True, type=int, - ) + ) parser.add_argument( - '--output_path', - help='Path to a location on disk. Path is expected to exist.', + "--output_path", + help="Path to a location on disk. Path is expected to exist.", required=True, type=os.path.abspath, - ) + ) # Optional parser.add_argument( - '--debug', - action='store_true', - help='Print debug messages', - ) + "--debug", + action="store_true", + help="Print debug messages", + ) parser.add_argument( - '--file_templates', - help='One or more file template strings defining the naming \ + "--file_templates", + help="One or more file template strings defining the naming \ convention the be used for the files retrieved from disk. If \ - not provided, the default names from hpss are used.', - nargs='*', - ) + not provided, the default names from hpss are used.", + nargs="*", + ) parser.add_argument( - '--file_type', - choices=('grib2', 'nemsio', 'netcdf'), - help='External model file format', - ) + "--file_type", + choices=("grib2", "nemsio", "netcdf"), + help="External model file format", + ) parser.add_argument( - '--input_file_path', - help='A path to data stored on disk. The path may contain \ + "--input_file_path", + help="A path to data stored on disk. The path may contain \ Python templates. File names may be supplied using the \ --file_templates flag, or the default naming convention will be \ - taken from the --config file.', - ) + taken from the --config file.", + ) parser.add_argument( - '--members', - help='A list describing ensemble members. If one argument, \ + "--members", + help="A list describing ensemble members. If one argument, \ one member will be processed. If 2 or 3 arguments, a sequence \ of members [start, stop, [increment]] will be \ processed. If more than 3 arguments, the list is processed \ - as-is.', - nargs='*', + as-is.", + nargs="*", type=int, - ) + ) parser.add_argument( - '--summary_file', - help='Name of the summary file to be written to the output \ - directory', - ) + "--summary_file", + help="Name of the summary file to be written to the output \ + directory", + ) return parser.parse_args(argv) -if __name__ == '__main__': +if __name__ == "__main__": main(sys.argv[1:]) diff --git a/ush/set_FV3nml_ens_stoch_seeds.py b/ush/set_FV3nml_ens_stoch_seeds.py index 76f30b39b0..ab7da1880b 100644 --- a/ush/set_FV3nml_ens_stoch_seeds.py +++ b/ush/set_FV3nml_ens_stoch_seeds.py @@ -7,25 +7,36 @@ from textwrap import dedent from datetime import datetime -from python_utils import print_input_args, print_info_msg, print_err_msg_exit,\ - date_to_str, mkdir_vrfy, cp_vrfy, str_to_type, \ - import_vars,set_env_var, \ - define_macos_utilities, cfg_to_yaml_str, \ - load_shell_config +from python_utils import ( + print_input_args, + print_info_msg, + print_err_msg_exit, + date_to_str, + mkdir_vrfy, + cp_vrfy, + str_to_type, + import_vars, + set_env_var, + define_macos_utilities, + cfg_to_yaml_str, + load_shell_config, + flatten_dict, +) from set_namelist import set_namelist + def set_FV3nml_ens_stoch_seeds(cdate): """ - This function, for an ensemble-enabled experiment - (i.e. for an experiment for which the workflow configuration variable + This function, for an ensemble-enabled experiment + (i.e. for an experiment for which the workflow configuration variable DO_ENSEMBLE has been set to "TRUE"), creates new namelist files with - unique stochastic "seed" parameters, using a base namelist file in the - ${EXPTDIR} directory as a template. These new namelist files are stored - within each member directory housed within each cycle directory. Files - of any two ensemble members differ only in their stochastic "seed" + unique stochastic "seed" parameters, using a base namelist file in the + ${EXPTDIR} directory as a template. These new namelist files are stored + within each member directory housed within each cycle directory. Files + of any two ensemble members differ only in their stochastic "seed" parameter values. These namelist files are generated when this file is - called as part of the RUN_FCST_TN task. + called as part of the RUN_FCST_TN task. Args: cdate @@ -39,75 +50,78 @@ def set_FV3nml_ens_stoch_seeds(cdate): import_vars() # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # For a given cycle and member, generate a namelist file with unique # seed values. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - ensmem_name=f"mem{ENSMEM_INDX}" - - fv3_nml_ensmem_fp=os.path.join(CYCLE_BASEDIR, f'{date_to_str(cdate,format="%Y%m%d%H")}{os.sep}{ensmem_name}{os.sep}{FV3_NML_FN}') - - ensmem_num=ENSMEM_INDX - - cdate_i = int(cdate.strftime('%Y%m%d%H')) + ensmem_name = f"mem{ENSMEM_INDX}" + + fv3_nml_ensmem_fp = os.path.join( + CYCLE_BASEDIR, + f'{date_to_str(cdate,format="%Y%m%d%H")}{os.sep}{ensmem_name}{os.sep}{FV3_NML_FN}', + ) + + ensmem_num = ENSMEM_INDX + + cdate_i = int(cdate.strftime("%Y%m%d%H")) settings = {} nam_stochy_dict = {} if DO_SPPT: - iseed_sppt=cdate_i*1000 + ensmem_num*10 + 1 - nam_stochy_dict.update({ - 'iseed_sppt': iseed_sppt - }) + iseed_sppt = cdate_i * 1000 + ensmem_num * 10 + 1 + nam_stochy_dict.update({"iseed_sppt": iseed_sppt}) if DO_SHUM: - iseed_shum=cdate_i*1000 + ensmem_num*10 + 2 - nam_stochy_dict.update({ - 'iseed_shum': iseed_shum - }) + iseed_shum = cdate_i * 1000 + ensmem_num * 10 + 2 + nam_stochy_dict.update({"iseed_shum": iseed_shum}) if DO_SKEB: - iseed_skeb=cdate_i*1000 + ensmem_num*10 + 3 - nam_stochy_dict.update({ - 'iseed_skeb': iseed_skeb - }) - - settings['nam_stochy'] = nam_stochy_dict - - if DO_SPP: - num_iseed_spp=len(ISEED_SPP) - iseed_spp = [None]*num_iseed_spp - for i in range(num_iseed_spp): - iseed_spp[i]=cdate_i*1000 + ensmem_num*10 + ISEED_SPP[i] - - settings['nam_sppperts'] = { - 'iseed_spp': iseed_spp - } + iseed_skeb = cdate_i * 1000 + ensmem_num * 10 + 3 + nam_stochy_dict.update({"iseed_skeb": iseed_skeb}) + + settings["nam_stochy"] = nam_stochy_dict + + if DO_SPP: + num_iseed_spp = len(ISEED_SPP) + iseed_spp = [None] * num_iseed_spp + for i in range(num_iseed_spp): + iseed_spp[i] = cdate_i * 1000 + ensmem_num * 10 + ISEED_SPP[i] + + settings["nam_sppperts"] = {"iseed_spp": iseed_spp} else: - settings['nam_sppperts'] = {} + settings["nam_sppperts"] = {} if DO_LSM_SPP: - iseed_lsm_spp=cdate_i*1000 + ensmem_num*10 + 9 + iseed_lsm_spp = cdate_i * 1000 + ensmem_num * 10 + 9 - settings['nam_sppperts'] = { - 'iseed_lndp': [iseed_lsm_spp] - } + settings["nam_sppperts"] = {"iseed_lndp": [iseed_lsm_spp]} settings_str = cfg_to_yaml_str(settings) - print_info_msg(dedent(f''' + print_info_msg( + dedent( + f""" The variable \"settings\" specifying seeds in \"{FV3_NML_FP}\" has been set as follows: - settings =\n\n''') + settings_str,verbose=VERBOSE) + settings =\n\n""" + ) + + settings_str, + verbose=VERBOSE, + ) try: - set_namelist(["-q", "-n", FV3_NML_FP, "-u", settings_str, "-o", fv3_nml_ensmem_fp]) + set_namelist( + ["-q", "-n", FV3_NML_FP, "-u", settings_str, "-o", fv3_nml_ensmem_fp] + ) except: - print_err_msg_exit(dedent(f''' + print_err_msg_exit( + dedent( + f""" Call to python script set_namelist.py to set the variables in the FV3 namelist file that specify the paths to the surface climatology files failed. Parameters passed to this script are: @@ -116,57 +130,72 @@ def set_FV3nml_ens_stoch_seeds(cdate): Full path to output namelist file: fv3_nml_ensmem_fp = \"{fv3_nml_ensmem_fp}\" Namelist settings specified on command line (these have highest precedence):\n - settings =\n\n''') + settings_str) + settings =\n\n""" + ) + + settings_str + ) + def parse_args(argv): - """ Parse command line arguments""" + """Parse command line arguments""" parser = argparse.ArgumentParser( - description='Creates stochastic seeds for an ensemble experiment.' + description="Creates stochastic seeds for an ensemble experiment." ) - parser.add_argument('-c', '--cdate', - dest='cdate', - required=True, - help='Date.') + parser.add_argument("-c", "--cdate", dest="cdate", required=True, help="Date.") - parser.add_argument('-p', '--path-to-defns', - dest='path_to_defns', - required=True, - help='Path to var_defns file.') + parser.add_argument( + "-p", + "--path-to-defns", + dest="path_to_defns", + required=True, + help="Path to var_defns file.", + ) return parser.parse_args(argv) -if __name__ == '__main__': + +if __name__ == "__main__": args = parse_args(sys.argv[1:]) cfg = load_shell_config(args.path_to_defns) + cfg = flatten_dict(cfg) import_vars(dictionary=cfg) set_FV3nml_ens_stoch_seeds(str_to_type(args.cdate)) + class Testing(unittest.TestCase): def test_set_FV3nml_ens_stoch_seeds(self): set_FV3nml_ens_stoch_seeds(cdate=self.cdate) + def setUp(self): - define_macos_utilities(); - set_env_var('DEBUG',True) - set_env_var('VERBOSE',True) - self.cdate=datetime(2021, 1, 1) + define_macos_utilities() + set_env_var("DEBUG", True) + set_env_var("VERBOSE", True) + self.cdate = datetime(2021, 1, 1) USHDIR = os.path.dirname(os.path.abspath(__file__)) - EXPTDIR = os.path.join(USHDIR,"test_data","expt"); - cp_vrfy(os.path.join(USHDIR,f'templates{os.sep}input.nml.FV3'), \ - os.path.join(EXPTDIR,'input.nml')) + EXPTDIR = os.path.join(USHDIR, "test_data", "expt") + cp_vrfy( + os.path.join(USHDIR, f"templates{os.sep}input.nml.FV3"), + os.path.join(EXPTDIR, "input.nml"), + ) for i in range(2): - mkdir_vrfy("-p", os.path.join(EXPTDIR,f'{date_to_str(self.cdate,format="%Y%m%d%H")}{os.sep}mem{i+1}')) - - set_env_var("USHDIR",USHDIR) - set_env_var("CYCLE_BASEDIR",EXPTDIR) - set_env_var("ENSMEM_INDX",2) - set_env_var("FV3_NML_FN","input.nml") - set_env_var("FV3_NML_FP",os.path.join(EXPTDIR,"input.nml")) - set_env_var("DO_SPPT",True) - set_env_var("DO_SHUM",True) - set_env_var("DO_SKEB",True) - set_env_var("DO_SPP",True) - set_env_var("DO_LSM_SPP",True) - ISEED_SPP = [ 4, 5, 6, 7, 8] - set_env_var("ISEED_SPP",ISEED_SPP) - + mkdir_vrfy( + "-p", + os.path.join( + EXPTDIR, + f'{date_to_str(self.cdate,format="%Y%m%d%H")}{os.sep}mem{i+1}', + ), + ) + + set_env_var("USHDIR", USHDIR) + set_env_var("CYCLE_BASEDIR", EXPTDIR) + set_env_var("ENSMEM_INDX", 2) + set_env_var("FV3_NML_FN", "input.nml") + set_env_var("FV3_NML_FP", os.path.join(EXPTDIR, "input.nml")) + set_env_var("DO_SHUM", True) + set_env_var("DO_SKEB", True) + set_env_var("DO_SPPT", True) + set_env_var("DO_SPP", True) + set_env_var("DO_LSM_SPP", True) + ISEED_SPP = [4, 5, 6, 7, 8] + set_env_var("ISEED_SPP", ISEED_SPP) diff --git a/ush/set_FV3nml_sfc_climo_filenames.py b/ush/set_FV3nml_sfc_climo_filenames.py index d351d33d04..a55f0575f5 100644 --- a/ush/set_FV3nml_sfc_climo_filenames.py +++ b/ush/set_FV3nml_sfc_climo_filenames.py @@ -6,13 +6,27 @@ import argparse from textwrap import dedent -from python_utils import print_input_args, print_info_msg, print_err_msg_exit,\ - check_var_valid_value,mv_vrfy,mkdir_vrfy,cp_vrfy,\ - rm_vrfy,import_vars,set_env_var,load_shell_config,\ - define_macos_utilities,find_pattern_in_str,cfg_to_yaml_str +from python_utils import ( + print_input_args, + print_info_msg, + print_err_msg_exit, + check_var_valid_value, + mv_vrfy, + mkdir_vrfy, + cp_vrfy, + rm_vrfy, + import_vars, + set_env_var, + load_shell_config, + flatten_dict, + define_macos_utilities, + find_pattern_in_str, + cfg_to_yaml_str, +) from set_namelist import set_namelist + def set_FV3nml_sfc_climo_filenames(): """ This function sets the values of the variables in @@ -56,30 +70,38 @@ def set_FV3nml_sfc_climo_filenames(): check_var_valid_value(sfc_climo_field_name, SFC_CLIMO_FIELDS) - fp = os.path.join(FIXLAM, f'{CRES}.{sfc_climo_field_name}.{suffix}') + fp = os.path.join(FIXLAM, f"{CRES}.{sfc_climo_field_name}.{suffix}") if RUN_ENVIR != "nco": fp = os.path.relpath(os.path.realpath(fp), start=dummy_run_dir) namsfc_dict[nml_var_name] = fp - - settings['namsfc_dict'] = namsfc_dict - settings_str = cfg_to_yaml_str(settings) + settings["namsfc_dict"] = namsfc_dict + settings_str = cfg_to_yaml_str(settings) - print_info_msg(dedent(f''' + print_info_msg( + dedent( + f""" The variable \"settings\" specifying values of the namelist variables - has been set as follows: - - settings =\n\n''') + settings_str, verbose=VERBOSE) + has been set as follows:\n + settings =\n\n""" + ) + + settings_str, + verbose=VERBOSE, + ) # Rename the FV3 namelist and call set_namelist - fv3_nml_base_fp = f'{FV3_NML_FP}.base' - mv_vrfy(f'{FV3_NML_FP} {fv3_nml_base_fp}') + fv3_nml_base_fp = f"{FV3_NML_FP}.base" + mv_vrfy(f"{FV3_NML_FP} {fv3_nml_base_fp}") try: - set_namelist(["-q", "-n", fv3_nml_base_fp, "-u", settings_str, "-o", FV3_NML_FP]) + set_namelist( + ["-q", "-n", fv3_nml_base_fp, "-u", settings_str, "-o", FV3_NML_FP] + ) except: - print_err_msg_exit(dedent(f''' + print_err_msg_exit( + dedent( + f""" Call to python script set_namelist.py to set the variables in the FV3 namelist file that specify the paths to the surface climatology files failed. Parameters passed to this script are: @@ -88,51 +110,62 @@ def set_FV3nml_sfc_climo_filenames(): Full path to output namelist file: FV3_NML_FP = \"{FV3_NML_FP}\" Namelist settings specified on command line (these have highest precedence):\n - settings =\n\n''') + settings_str) + settings =\n\n""" + ) + + settings_str + ) + + rm_vrfy(f"{fv3_nml_base_fp}") - rm_vrfy(f'{fv3_nml_base_fp}') def parse_args(argv): - """ Parse command line arguments""" - parser = argparse.ArgumentParser( - description='Set surface climatology fields.' + """Parse command line arguments""" + parser = argparse.ArgumentParser(description="Set surface climatology fields.") + + parser.add_argument( + "-p", + "--path-to-defns", + dest="path_to_defns", + required=True, + help="Path to var_defns file.", ) - parser.add_argument('-p', '--path-to-defns', - dest='path_to_defns', - required=True, - help='Path to var_defns file.') - return parser.parse_args(argv) -if __name__ == '__main__': + +if __name__ == "__main__": args = parse_args(sys.argv[1:]) cfg = load_shell_config(args.path_to_defns) + cfg = flatten_dict(cfg) import_vars(dictionary=cfg) set_FV3nml_sfc_climo_filenames() + class Testing(unittest.TestCase): def test_set_FV3nml_sfc_climo_filenames(self): set_FV3nml_sfc_climo_filenames() + def setUp(self): - define_macos_utilities(); - set_env_var('DEBUG',True) - set_env_var('VERBOSE',True) + define_macos_utilities() + set_env_var("DEBUG", True) + set_env_var("VERBOSE", True) USHDIR = os.path.dirname(os.path.abspath(__file__)) - EXPTDIR = os.path.join(USHDIR, "test_data", "expt"); + EXPTDIR = os.path.join(USHDIR, "test_data", "expt") FIXLAM = os.path.join(EXPTDIR, "fix_lam") - mkdir_vrfy("-p",FIXLAM) - cp_vrfy(os.path.join(USHDIR,f'templates{os.sep}input.nml.FV3'), \ - os.path.join(EXPTDIR,'input.nml')) - set_env_var("USHDIR",USHDIR) - set_env_var("EXPTDIR",EXPTDIR) - set_env_var("FIXLAM",FIXLAM) - set_env_var("DO_ENSEMBLE",False) - set_env_var("CRES","C3357") - set_env_var("RUN_ENVIR","nco") - set_env_var("FV3_NML_FP",os.path.join(EXPTDIR,"input.nml")) - - FV3_NML_VARNAME_TO_SFC_CLIMO_FIELD_MAPPING=[ + mkdir_vrfy("-p", FIXLAM) + cp_vrfy( + os.path.join(USHDIR, f"templates{os.sep}input.nml.FV3"), + os.path.join(EXPTDIR, "input.nml"), + ) + set_env_var("USHDIR", USHDIR) + set_env_var("EXPTDIR", EXPTDIR) + set_env_var("FIXLAM", FIXLAM) + set_env_var("DO_ENSEMBLE", False) + set_env_var("CRES", "C3357") + set_env_var("RUN_ENVIR", "nco") + set_env_var("FV3_NML_FP", os.path.join(EXPTDIR, "input.nml")) + + FV3_NML_VARNAME_TO_SFC_CLIMO_FIELD_MAPPING = [ "FNALBC | snowfree_albedo", "FNALBC2 | facsf", "FNTG3C | substrate_temperature", @@ -142,9 +175,9 @@ def setUp(self): "FNVMNC | vegetation_greenness", "FNVMXC | vegetation_greenness", "FNSLPC | slope_type", - "FNABSC | maximum_snow_albedo" + "FNABSC | maximum_snow_albedo", ] - SFC_CLIMO_FIELDS=[ + SFC_CLIMO_FIELDS = [ "facsf", "maximum_snow_albedo", "slope_type", @@ -152,9 +185,10 @@ def setUp(self): "soil_type", "substrate_temperature", "vegetation_greenness", - "vegetation_type" + "vegetation_type", ] - set_env_var("FV3_NML_VARNAME_TO_SFC_CLIMO_FIELD_MAPPING", - FV3_NML_VARNAME_TO_SFC_CLIMO_FIELD_MAPPING) - set_env_var("SFC_CLIMO_FIELDS",SFC_CLIMO_FIELDS) - + set_env_var( + "FV3_NML_VARNAME_TO_SFC_CLIMO_FIELD_MAPPING", + FV3_NML_VARNAME_TO_SFC_CLIMO_FIELD_MAPPING, + ) + set_env_var("SFC_CLIMO_FIELDS", SFC_CLIMO_FIELDS) diff --git a/ush/set_cycle_dates.py b/ush/set_cycle_dates.py index 69a707b972..7138cfe5b5 100644 --- a/ush/set_cycle_dates.py +++ b/ush/set_cycle_dates.py @@ -1,14 +1,15 @@ #!/usr/bin/env python3 import unittest -from datetime import datetime,timedelta,date +from datetime import datetime, timedelta, date from python_utils import print_input_args, print_err_msg_exit + def set_cycle_dates(date_start, date_end, cycle_hrs, incr_cycl_freq): - """ This file defines a function that, given the starting date (date_start, - in the form YYYYMMDD), the ending date (date_end, in the form YYYYMMDD), - and an array containing the cycle hours for each day (whose elements + """This file defines a function that, given the starting date (date_start, + in the form YYYYMMDD), the ending date (date_end, in the form YYYYMMDD), + and an array containing the cycle hours for each day (whose elements have the form HH), returns an array of cycle date-hours whose elements have the form YYYYMMDD. Here, YYYY is a four-digit year, MM is a two- digit month, DD is a two-digit day of the month, and HH is a two-digit @@ -25,30 +26,39 @@ def set_cycle_dates(date_start, date_end, cycle_hrs, incr_cycl_freq): print_input_args(locals()) - #calculate date increment + # calculate date increment if incr_cycl_freq <= 24: incr_days = 1 else: incr_days = incr_cycl_freq // 24 if incr_cycl_freq % 24 != 0: - print_err_msg_exit(f''' + print_err_msg_exit( + f''' INCR_CYCL_FREQ is not divided by 24: - INCR_CYCL_FREQ = \"{incr_cycl_freq}\"''') + INCR_CYCL_FREQ = \"{incr_cycl_freq}\"''' + ) - #iterate over days and cycles + # iterate over days and cycles all_cdates = [] d = date_start while d <= date_end: for c in cycle_hrs: dc = d + timedelta(hours=c) - v = datetime.strftime(dc,'%Y%m%d%H') + v = datetime.strftime(dc, "%Y%m%d%H") all_cdates.append(v) d += timedelta(days=incr_days) return all_cdates - + + class Testing(unittest.TestCase): def test_set_cycle_dates(self): - cdates = set_cycle_dates(date_start=datetime(2022,1,1), date_end=datetime(2022,1,4), - cycle_hrs=[6,12], incr_cycl_freq=48) - self.assertEqual(cdates, ['2022010106', '2022010112','2022010306', '2022010312']) + cdates = set_cycle_dates( + date_start=datetime(2022, 1, 1), + date_end=datetime(2022, 1, 4), + cycle_hrs=[6, 12], + incr_cycl_freq=48, + ) + self.assertEqual( + cdates, ["2022010106", "2022010112", "2022010306", "2022010312"] + ) diff --git a/ush/set_extrn_mdl_params.py b/ush/set_extrn_mdl_params.py index f4fffc5907..7d52055031 100644 --- a/ush/set_extrn_mdl_params.py +++ b/ush/set_extrn_mdl_params.py @@ -4,8 +4,9 @@ from python_utils import import_vars, export_vars, set_env_var, get_env_var + def set_extrn_mdl_params(): - """ Sets parameters associated with the external model used for initial + """Sets parameters associated with the external model used for initial conditions (ICs) and lateral boundary conditions (LBCs). Args: None @@ -13,44 +14,36 @@ def set_extrn_mdl_params(): None """ - #import all env variables + # import all env variables import_vars() global EXTRN_MDL_LBCS_OFFSET_HRS # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # Set EXTRN_MDL_LBCS_OFFSET_HRS, which is the number of hours to shift - # the starting time of the external model that provides lateral boundary + # Set EXTRN_MDL_LBCS_OFFSET_HRS, which is the number of hours to shift + # the starting time of the external model that provides lateral boundary # conditions. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if EXTRN_MDL_NAME_LBCS == "RAP": - EXTRN_MDL_LBCS_OFFSET_HRS=EXTRN_MDL_LBCS_OFFSET_HRS or "3" + EXTRN_MDL_LBCS_OFFSET_HRS = EXTRN_MDL_LBCS_OFFSET_HRS or "3" else: - EXTRN_MDL_LBCS_OFFSET_HRS=EXTRN_MDL_LBCS_OFFSET_HRS or "0" + EXTRN_MDL_LBCS_OFFSET_HRS = EXTRN_MDL_LBCS_OFFSET_HRS or "0" # export values we set above env_vars = ["EXTRN_MDL_LBCS_OFFSET_HRS"] export_vars(env_vars=env_vars) -# -#----------------------------------------------------------------------- -# -# Call the function defined above. -# -#----------------------------------------------------------------------- -# -if __name__ == "__main__": - set_extrn_mdl_params() - + + class Testing(unittest.TestCase): def test_extrn_mdl_params(self): set_extrn_mdl_params() EXTRN_MDL_LBCS_OFFSET_HRS = get_env_var("EXTRN_MDL_LBCS_OFFSET_HRS") - self.assertEqual(EXTRN_MDL_LBCS_OFFSET_HRS,3) + self.assertEqual(EXTRN_MDL_LBCS_OFFSET_HRS, 3) def setUp(self): - set_env_var("EXTRN_MDL_NAME_LBCS","RAP") - set_env_var("EXTRN_MDL_LBCS_OFFSET_HRS",None) + set_env_var("EXTRN_MDL_NAME_LBCS", "RAP") + set_env_var("EXTRN_MDL_LBCS_OFFSET_HRS", None) diff --git a/ush/set_gridparams_ESGgrid.py b/ush/set_gridparams_ESGgrid.py index 722c2f27e2..7b9350424f 100644 --- a/ush/set_gridparams_ESGgrid.py +++ b/ush/set_gridparams_ESGgrid.py @@ -1,12 +1,13 @@ #!/usr/bin/env python3 import unittest -from datetime import datetime,timedelta +from datetime import datetime, timedelta from python_utils import import_vars, set_env_var, print_input_args -def set_gridparams_ESGgrid(lon_ctr,lat_ctr,nx,ny,halo_width,delx,dely,pazi): - """ Sets the parameters for a grid that is to be generated using the "ESGgrid" + +def set_gridparams_ESGgrid(lon_ctr, lat_ctr, nx, ny, halo_width, delx, dely, pazi): + """Sets the parameters for a grid that is to be generated using the "ESGgrid" grid generation method (i.e. GRID_GEN_METHOD set to "ESGgrid"). Args: @@ -25,66 +26,71 @@ def set_gridparams_ESGgrid(lon_ctr,lat_ctr,nx,ny,halo_width,delx,dely,pazi): print_input_args(locals()) # get needed environment variables - IMPORTS = ['RADIUS_EARTH', 'DEGS_PER_RADIAN'] + IMPORTS = ["RADIUS_EARTH", "DEGS_PER_RADIAN"] import_vars(env_vars=IMPORTS) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # For a ESGgrid-type grid, the orography filtering is performed by pass- # ing to the orography filtering the parameters for an "equivalent" glo- # bal uniform cubed-sphere grid. These are the parameters that a global - # uniform cubed-sphere grid needs to have in order to have a nominal + # uniform cubed-sphere grid needs to have in order to have a nominal # grid cell size equal to that of the (average) cell size on the region- - # al grid. These globally-equivalent parameters include a resolution + # al grid. These globally-equivalent parameters include a resolution # (in units of number of cells in each of the two horizontal directions) # and a stretch factor. The equivalent resolution is calculated in the # script that generates the grid, and the stretch factor needs to be set - # to 1 because we are considering an equivalent globally UNIFORM grid. + # to 1 because we are considering an equivalent globally UNIFORM grid. # However, it turns out that with a non-symmetric regional grid (one in # which nx is not equal to ny), setting stretch_factor to 1 fails be- # cause the orography filtering program is designed for a global cubed- # sphere grid and thus assumes that nx and ny for a given tile are equal - # when stretch_factor is exactly equal to 1. - # ^^-- Why is this? Seems like symmetry btwn x and y should still hold when the stretch factor is not equal to 1. - # It turns out that the program will work if we set stretch_factor to a - # value that is not exactly 1. This is what we do below. + # when stretch_factor is exactly equal to 1. + # ^^-- Why is this? Seems like symmetry btwn x and y should still hold when the stretch factor is not equal to 1. + # It turns out that the program will work if we set stretch_factor to a + # value that is not exactly 1. This is what we do below. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - stretch_factor=0.999 # Check whether the orography program has been fixed so that we can set this to 1... + stretch_factor = 0.999 # Check whether the orography program has been fixed so that we can set this to 1... # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set parameters needed as inputs to the regional_grid grid generation # code. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # del_angle_x_sg = (delx / (2.0 * RADIUS_EARTH)) * DEGS_PER_RADIAN del_angle_y_sg = (dely / (2.0 * RADIUS_EARTH)) * DEGS_PER_RADIAN neg_nx_of_dom_with_wide_halo = -(nx + 2 * halo_width) neg_ny_of_dom_with_wide_halo = -(ny + 2 * halo_width) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # return output variables. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - return (lon_ctr,lat_ctr,nx,ny,pazi,halo_width,stretch_factor, - del_angle_x_sg, - del_angle_y_sg, - int(neg_nx_of_dom_with_wide_halo), - int(neg_ny_of_dom_with_wide_halo)) + return { + "LON_CTR": lon_ctr, + "LAT_CTR": lat_ctr, + "NX": nx, + "NY": ny, + "PAZI": pazi, + "NHW": halo_width, + "STRETCH_FAC": stretch_factor, + "DEL_ANGLE_X_SG": del_angle_x_sg, + "DEL_ANGLE_Y_SG": del_angle_y_sg, + "NEG_NX_OF_DOM_WITH_WIDE_HALO": int(neg_nx_of_dom_with_wide_halo), + "NEG_NY_OF_DOM_WITH_WIDE_HALO": int(neg_ny_of_dom_with_wide_halo), + } + class Testing(unittest.TestCase): def test_set_gridparams_ESGgrid(self): - (LON_CTR,LAT_CTR,NX,NY,PAZI,NHW,STRETCH_FAC, - DEL_ANGLE_X_SG, - DEL_ANGLE_Y_SG, - NEG_NX_OF_DOM_WITH_WIDE_HALO, - NEG_NY_OF_DOM_WITH_WIDE_HALO) = set_gridparams_ESGgrid( \ + grid_parms = set_gridparams_ESGgrid( lon_ctr=-97.5, lat_ctr=38.5, nx=1748, @@ -92,22 +98,26 @@ def test_set_gridparams_ESGgrid(self): pazi=0.0, halo_width=6, delx=3000.0, - dely=3000.0) + dely=3000.0, + ) - self.assertEqual(\ - (LON_CTR,LAT_CTR,NX,NY,PAZI,NHW,STRETCH_FAC, - round(DEL_ANGLE_X_SG,10), - round(DEL_ANGLE_Y_SG,10), - NEG_NX_OF_DOM_WITH_WIDE_HALO, - NEG_NY_OF_DOM_WITH_WIDE_HALO), - (-97.5, 38.5, 1748, 1038, 0.0, 6,0.999, - 0.0134894006, - 0.0134894006, - -1760, - -1050) + self.assertEqual( + list(grid_parms.values()), + [ + -97.5, + 38.5, + 1748, + 1038, + 0.0, + 6, + 0.999, + 0.013489400626200717, + 0.013489400626200717, + -1760, + -1050, + ], ) def setUp(self): - set_env_var('RADIUS_EARTH',6371200.0) - set_env_var('DEGS_PER_RADIAN',57.2957795131) - + set_env_var("RADIUS_EARTH", 6371200.0) + set_env_var("DEGS_PER_RADIAN", 57.2957795131) diff --git a/ush/set_gridparams_GFDLgrid.py b/ush/set_gridparams_GFDLgrid.py index 40a74d8105..f7999591d7 100644 --- a/ush/set_gridparams_GFDLgrid.py +++ b/ush/set_gridparams_GFDLgrid.py @@ -2,8 +2,14 @@ import unittest -from python_utils import import_vars, set_env_var, print_input_args, \ - print_info_msg, print_err_msg_exit +from python_utils import ( + import_vars, + set_env_var, + print_input_args, + print_info_msg, + print_err_msg_exit, +) + def prime_factors(n): i = 2 @@ -18,11 +24,19 @@ def prime_factors(n): factors.append(n) return factors -def set_gridparams_GFDLgrid(lon_of_t6_ctr, lat_of_t6_ctr, res_of_t6g, stretch_factor, - refine_ratio_t6g_to_t7g, - istart_of_t7_on_t6g, iend_of_t7_on_t6g, - jstart_of_t7_on_t6g, jend_of_t7_on_t6g): - """ Sets the parameters for a grid that is to be generated using the "GFDLgrid" + +def set_gridparams_GFDLgrid( + lon_of_t6_ctr, + lat_of_t6_ctr, + res_of_t6g, + stretch_factor, + refine_ratio_t6g_to_t7g, + istart_of_t7_on_t6g, + iend_of_t7_on_t6g, + jstart_of_t7_on_t6g, + jend_of_t7_on_t6g, +): + """Sets the parameters for a grid that is to be generated using the "GFDLgrid" grid generation method (i.e. GRID_GEN_METHOD set to "ESGgrid"). Args: @@ -30,7 +44,7 @@ def set_gridparams_GFDLgrid(lon_of_t6_ctr, lat_of_t6_ctr, res_of_t6g, stretch_fa lat_of_t6_ctr res_of_t6g stretch_factor - refine_ratio_t6g_to_t7g + refine_ratio_t6g_to_t7g istart_of_t7_on_t6g iend_of_t7_on_t6g jstart_of_t7_on_t6g @@ -42,27 +56,27 @@ def set_gridparams_GFDLgrid(lon_of_t6_ctr, lat_of_t6_ctr, res_of_t6g, stretch_fa print_input_args(locals()) # get needed environment variables - IMPORTS = ['VERBOSE', 'RUN_ENVIR', 'NH4'] + IMPORTS = ["VERBOSE", "RUN_ENVIR", "NH4"] import_vars(env_vars=IMPORTS) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # To simplify the grid setup, we require that tile 7 be centered on tile + # To simplify the grid setup, we require that tile 7 be centered on tile # 6. Note that this is not really a restriction because tile 6 can al- - # ways be moved so that it is centered on tile 7 [the location of tile 6 - # doesn't really matter because for a regional setup, the forecast model + # ways be moved so that it is centered on tile 7 [the location of tile 6 + # doesn't really matter because for a regional setup, the forecast model # will only run on tile 7 (not on tiles 1-6)]. # - # We now check that tile 7 is centered on tile 6 by checking (1) that - # the number of cells (on tile 6) between the left boundaries of these - # two tiles is equal to that between their right boundaries and (2) that + # We now check that tile 7 is centered on tile 6 by checking (1) that + # the number of cells (on tile 6) between the left boundaries of these + # two tiles is equal to that between their right boundaries and (2) that # the number of cells (on tile 6) between the bottom boundaries of these - # two tiles is equal to that between their top boundaries. If not, we - # print out an error message and exit. If so, we set the longitude and + # two tiles is equal to that between their top boundaries. If not, we + # print out an error message and exit. If so, we set the longitude and # latitude of the center of tile 7 to those of tile 6 and continue. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # nx_of_t6_on_t6g = res_of_t6g @@ -75,13 +89,14 @@ def set_gridparams_GFDLgrid(lon_of_t6_ctr, lat_of_t6_ctr, res_of_t6g, stretch_fa # GFDLgrid type grids (tile 7) symmetric about tile 6. if RUN_ENVIR != "nco": if num_left_margin_cells_on_t6g != num_right_margin_cells_on_t6g: - print_err_msg_exit(f''' + print_err_msg_exit( + f""" In order for tile 7 to be centered in the x direction on tile 6, the x- direction tile 6 cell indices at which tile 7 starts and ends (given by - istart_of_t7_on_t6g and iend_of_t7_on_t6g, respectively) must be set - such that the number of tile 6 cells in the margin between the left + istart_of_t7_on_t6g and iend_of_t7_on_t6g, respectively) must be set + such that the number of tile 6 cells in the margin between the left boundaries of tiles 6 and 7 (given by num_left_margin_cells_on_t6g) is - equal to that in the margin between their right boundaries (given by + equal to that in the margin between their right boundaries (given by num_right_margin_cells_on_t6g): istart_of_t7_on_t6g = {istart_of_t7_on_t6g} iend_of_t7_on_t6g = {iend_of_t7_on_t6g} @@ -90,7 +105,8 @@ def set_gridparams_GFDLgrid(lon_of_t6_ctr, lat_of_t6_ctr, res_of_t6g, stretch_fa Note that the total number of cells in the x-direction on tile 6 is gi- ven by: nx_of_t6_on_t6g = {nx_of_t6_on_t6g} - Please reset istart_of_t7_on_t6g and iend_of_t7_on_t6g and rerun.''') + Please reset istart_of_t7_on_t6g and iend_of_t7_on_t6g and rerun.""" + ) num_bot_margin_cells_on_t6g = jstart_of_t7_on_t6g - 1 num_top_margin_cells_on_t6g = ny_of_t6_on_t6g - jend_of_t7_on_t6g @@ -99,13 +115,14 @@ def set_gridparams_GFDLgrid(lon_of_t6_ctr, lat_of_t6_ctr, res_of_t6g, stretch_fa # GFDLgrid type grids (tile 7) symmetric about tile 6. if RUN_ENVIR != "nco": if num_bot_margin_cells_on_t6g != num_top_margin_cells_on_t6g: - print_err_msg_exit(f''' + print_err_msg_exit( + f""" In order for tile 7 to be centered in the y direction on tile 6, the y- direction tile 6 cell indices at which tile 7 starts and ends (given by - jstart_of_t7_on_t6g and jend_of_t7_on_t6g, respectively) must be set - such that the number of tile 6 cells in the margin between the left + jstart_of_t7_on_t6g and jend_of_t7_on_t6g, respectively) must be set + such that the number of tile 6 cells in the margin between the left boundaries of tiles 6 and 7 (given by num_left_margin_cells_on_t6g) is - equal to that in the margin between their right boundaries (given by + equal to that in the margin between their right boundaries (given by num_right_margin_cells_on_t6g): jstart_of_t7_on_t6g = {jstart_of_t7_on_t6g} jend_of_t7_on_t6g = {jend_of_t7_on_t6g} @@ -114,12 +131,13 @@ def set_gridparams_GFDLgrid(lon_of_t6_ctr, lat_of_t6_ctr, res_of_t6g, stretch_fa Note that the total number of cells in the y-direction on tile 6 is gi- ven by: ny_of_t6_on_t6g = {ny_of_t6_on_t6g} - Please reset jstart_of_t7_on_t6g and jend_of_t7_on_t6g and rerun.''') + Please reset jstart_of_t7_on_t6g and jend_of_t7_on_t6g and rerun.""" + ) lon_of_t7_ctr = lon_of_t6_ctr lat_of_t7_ctr = lat_of_t6_ctr # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # The grid generation script grid_gen_scr called below in turn calls the # make_hgrid utility/executable to construct the regional grid. make_- @@ -161,14 +179,14 @@ def set_gridparams_GFDLgrid(lon_of_t6_ctr, lat_of_t6_ctr, res_of_t6g, stretch_fa # odd while the ending indices must be even; the above expressions sa- # tisfy this requirement.) We perfrom these calculations next. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - istart_of_t7_on_t6sg = 2*istart_of_t7_on_t6g - 1 - iend_of_t7_on_t6sg = 2*iend_of_t7_on_t6g - jstart_of_t7_on_t6sg = 2*jstart_of_t7_on_t6g - 1 - jend_of_t7_on_t6sg = 2*jend_of_t7_on_t6g + istart_of_t7_on_t6sg = 2 * istart_of_t7_on_t6g - 1 + iend_of_t7_on_t6sg = 2 * iend_of_t7_on_t6g + jstart_of_t7_on_t6sg = 2 * jstart_of_t7_on_t6g - 1 + jend_of_t7_on_t6sg = 2 * jend_of_t7_on_t6g # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If we simply pass to make_hgrid the index limits of the regional grid # on the tile 6 supergrid calculated above, make_hgrid will generate a @@ -232,12 +250,14 @@ def set_gridparams_GFDLgrid(lon_of_t6_ctr, lat_of_t6_ctr, res_of_t6g, stretch_fa # the regional grid with wide halo on the tile 6 supergrid and then ad- # justing the latter to satisfy certain conditions. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # halo_width_on_t7g = NH4 + 1 - halo_width_on_t6sg = (2*halo_width_on_t7g + refine_ratio_t6g_to_t7g - 1)/refine_ratio_t6g_to_t7g + halo_width_on_t6sg = ( + 2 * halo_width_on_t7g + refine_ratio_t6g_to_t7g - 1 + ) / refine_ratio_t6g_to_t7g # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # With an initial value of halo_width_on_t6sg now available, we can obtain the # tile 6 supergrid index limits of the regional domain (including the @@ -252,14 +272,14 @@ def set_gridparams_GFDLgrid(lon_of_t6_ctr, lat_of_t6_ctr, res_of_t6g, stretch_fa # # We calculate these next. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # istart_of_t7_with_halo_on_t6sg = int(istart_of_t7_on_t6sg - halo_width_on_t6sg) iend_of_t7_with_halo_on_t6sg = int(iend_of_t7_on_t6sg + halo_width_on_t6sg) jstart_of_t7_with_halo_on_t6sg = int(jstart_of_t7_on_t6sg - halo_width_on_t6sg) jend_of_t7_with_halo_on_t6sg = int(jend_of_t7_on_t6sg + halo_width_on_t6sg) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # As for the regional grid without a halo, the regional grid with a wide # halo that make_hgrid will generate must be such that grid cells on @@ -273,21 +293,21 @@ def set_gridparams_GFDLgrid(lon_of_t6_ctr, lat_of_t6_ctr, res_of_t6g, stretch_fa # (which ensures that there will be at least halo_width_on_t7g halo cells along the # right and top boundaries). # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if istart_of_t7_with_halo_on_t6sg % 2 == 0: istart_of_t7_with_halo_on_t6sg = istart_of_t7_with_halo_on_t6sg - 1 - + if iend_of_t7_with_halo_on_t6sg % 2 == 1: iend_of_t7_with_halo_on_t6sg = iend_of_t7_with_halo_on_t6sg + 1 - + if jstart_of_t7_with_halo_on_t6sg % 2 == 0: jstart_of_t7_with_halo_on_t6sg = jstart_of_t7_with_halo_on_t6sg - 1 - + if jend_of_t7_with_halo_on_t6sg % 2 == 1: jend_of_t7_with_halo_on_t6sg = jend_of_t7_with_halo_on_t6sg + 1 # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Now that the starting and ending tile 6 supergrid indices of the re- # gional grid with the wide halo have been calculated (and adjusted), we @@ -300,58 +320,65 @@ def set_gridparams_GFDLgrid(lon_of_t6_ctr, lat_of_t6_ctr, res_of_t6g, stretch_fa # These are the final values of these quantities that are guaranteed to # correspond to the starting and ending indices on the tile 6 supergrid. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - print_info_msg(f''' - Original values of the halo width on the tile 6 supergrid and on the + print_info_msg( + f""" + Original values of the halo width on the tile 6 supergrid and on the tile 7 grid are: halo_width_on_t6sg = {halo_width_on_t6sg} - halo_width_on_t7g = {halo_width_on_t7g}''', verbose=VERBOSE) - + halo_width_on_t7g = {halo_width_on_t7g}""", + verbose=VERBOSE, + ) + halo_width_on_t6sg = istart_of_t7_on_t6sg - istart_of_t7_with_halo_on_t6sg - halo_width_on_t6g = halo_width_on_t6sg//2 - halo_width_on_t7g = int(halo_width_on_t6g*refine_ratio_t6g_to_t7g) - - print_info_msg(f''' - Values of the halo width on the tile 6 supergrid and on the tile 7 grid + halo_width_on_t6g = halo_width_on_t6sg // 2 + halo_width_on_t7g = int(halo_width_on_t6g * refine_ratio_t6g_to_t7g) + + print_info_msg( + f""" + Values of the halo width on the tile 6 supergrid and on the tile 7 grid AFTER adjustments are: halo_width_on_t6sg = {halo_width_on_t6sg} - halo_width_on_t7g = {halo_width_on_t7g}''', verbose=VERBOSE) + halo_width_on_t7g = {halo_width_on_t7g}""", + verbose=VERBOSE, + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Calculate the number of cells that the regional domain (without halo) # has in each of the two horizontal directions (say x and y). We denote - # these by nx_of_t7_on_t7g and ny_of_t7_on_t7g, respectively. These + # these by nx_of_t7_on_t7g and ny_of_t7_on_t7g, respectively. These # will be needed in the "shave" steps in the grid generation task of the # workflow. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # nx_of_t7_on_t6sg = iend_of_t7_on_t6sg - istart_of_t7_on_t6sg + 1 - nx_of_t7_on_t6g = nx_of_t7_on_t6sg/2 - nx_of_t7_on_t7g = int(nx_of_t7_on_t6g*refine_ratio_t6g_to_t7g) - + nx_of_t7_on_t6g = nx_of_t7_on_t6sg / 2 + nx_of_t7_on_t7g = int(nx_of_t7_on_t6g * refine_ratio_t6g_to_t7g) + ny_of_t7_on_t6sg = jend_of_t7_on_t6sg - jstart_of_t7_on_t6sg + 1 - ny_of_t7_on_t6g = ny_of_t7_on_t6sg/2 - ny_of_t7_on_t7g = int(ny_of_t7_on_t6g*refine_ratio_t6g_to_t7g) + ny_of_t7_on_t6g = ny_of_t7_on_t6sg / 2 + ny_of_t7_on_t7g = int(ny_of_t7_on_t6g * refine_ratio_t6g_to_t7g) # # The following are set only for informational purposes. # - nx_of_t6_on_t6sg = 2*nx_of_t6_on_t6g - ny_of_t6_on_t6sg = 2*ny_of_t6_on_t6g - + nx_of_t6_on_t6sg = 2 * nx_of_t6_on_t6g + ny_of_t6_on_t6sg = 2 * ny_of_t6_on_t6g + prime_factors_nx_of_t7_on_t7g = prime_factors(nx_of_t7_on_t7g) prime_factors_ny_of_t7_on_t7g = prime_factors(ny_of_t7_on_t7g) - - print_info_msg(f''' - The number of cells in the two horizontal directions (x and y) on the + + print_info_msg( + f""" + The number of cells in the two horizontal directions (x and y) on the parent tile's (tile 6) grid and supergrid are: nx_of_t6_on_t6g = {nx_of_t6_on_t6g} ny_of_t6_on_t6g = {ny_of_t6_on_t6g} nx_of_t6_on_t6sg = {nx_of_t6_on_t6sg} ny_of_t6_on_t6sg = {ny_of_t6_on_t6sg} - + The number of cells in the two horizontal directions on the tile 6 grid and supergrid that the regional domain (tile 7) WITHOUT A HALO encompas- ses are: @@ -359,107 +386,114 @@ def set_gridparams_GFDLgrid(lon_of_t6_ctr, lat_of_t6_ctr, res_of_t6g, stretch_fa ny_of_t7_on_t6g = {ny_of_t7_on_t6g} nx_of_t7_on_t6sg = {nx_of_t7_on_t6sg} ny_of_t7_on_t6sg = {ny_of_t7_on_t6sg} - + The starting and ending i and j indices on the tile 6 grid used to gene- rate this regional grid are: istart_of_t7_on_t6g = {istart_of_t7_on_t6g} iend_of_t7_on_t6g = {iend_of_t7_on_t6g} jstart_of_t7_on_t6g = {jstart_of_t7_on_t6g} jend_of_t7_on_t6g = {jend_of_t7_on_t6g} - + The corresponding starting and ending i and j indices on the tile 6 su- pergrid are: istart_of_t7_on_t6sg = {istart_of_t7_on_t6sg} iend_of_t7_on_t6sg = {iend_of_t7_on_t6sg} jstart_of_t7_on_t6sg = {jstart_of_t7_on_t6sg} jend_of_t7_on_t6sg = {jend_of_t7_on_t6sg} - + The refinement ratio (ratio of the number of cells in tile 7 that abut a single cell in tile 6) is: refine_ratio_t6g_to_t7g = {refine_ratio_t6g_to_t7g} - + The number of cells in the two horizontal directions on the regional do- main's (i.e. tile 7's) grid WITHOUT A HALO are: nx_of_t7_on_t7g = {nx_of_t7_on_t7g} ny_of_t7_on_t7g = {ny_of_t7_on_t7g} - + The prime factors of nx_of_t7_on_t7g and ny_of_t7_on_t7g are (useful for determining an MPI task layout): prime_factors_nx_of_t7_on_t7g: {prime_factors_nx_of_t7_on_t7g} - prime_factors_ny_of_t7_on_t7g: {prime_factors_ny_of_t7_on_t7g}''', verbose=VERBOSE) + prime_factors_ny_of_t7_on_t7g: {prime_factors_ny_of_t7_on_t7g}""", + verbose=VERBOSE, + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # For informational purposes, calculate the number of cells in each di- # rection on the regional grid including the wide halo (of width halo_- # width_on_t7g cells). We denote these by nx_of_t7_with_halo_on_t7g and # ny_of_t7_with_halo_on_t7g, respectively. # - #----------------------------------------------------------------------- - # - nx_of_t7_with_halo_on_t6sg = iend_of_t7_with_halo_on_t6sg - istart_of_t7_with_halo_on_t6sg + 1 - nx_of_t7_with_halo_on_t6g = nx_of_t7_with_halo_on_t6sg/2 - nx_of_t7_with_halo_on_t7g = nx_of_t7_with_halo_on_t6g*refine_ratio_t6g_to_t7g - - ny_of_t7_with_halo_on_t6sg = jend_of_t7_with_halo_on_t6sg - jstart_of_t7_with_halo_on_t6sg + 1 - ny_of_t7_with_halo_on_t6g = ny_of_t7_with_halo_on_t6sg/2 - ny_of_t7_with_halo_on_t7g = ny_of_t7_with_halo_on_t6g*refine_ratio_t6g_to_t7g - - print_info_msg(f''' + # ----------------------------------------------------------------------- + # + nx_of_t7_with_halo_on_t6sg = ( + iend_of_t7_with_halo_on_t6sg - istart_of_t7_with_halo_on_t6sg + 1 + ) + nx_of_t7_with_halo_on_t6g = nx_of_t7_with_halo_on_t6sg / 2 + nx_of_t7_with_halo_on_t7g = nx_of_t7_with_halo_on_t6g * refine_ratio_t6g_to_t7g + + ny_of_t7_with_halo_on_t6sg = ( + jend_of_t7_with_halo_on_t6sg - jstart_of_t7_with_halo_on_t6sg + 1 + ) + ny_of_t7_with_halo_on_t6g = ny_of_t7_with_halo_on_t6sg / 2 + ny_of_t7_with_halo_on_t7g = ny_of_t7_with_halo_on_t6g * refine_ratio_t6g_to_t7g + + print_info_msg( + f""" nx_of_t7_with_halo_on_t7g = {nx_of_t7_with_halo_on_t7g} (istart_of_t7_with_halo_on_t6sg = {istart_of_t7_with_halo_on_t6sg}, - iend_of_t7_with_halo_on_t6sg = {iend_of_t7_with_halo_on_t6sg})''', verbose=VERBOSE) - - print_info_msg(f''' + iend_of_t7_with_halo_on_t6sg = {iend_of_t7_with_halo_on_t6sg})""", + verbose=VERBOSE, + ) + + print_info_msg( + f""" ny_of_t7_with_halo_on_t7g = {ny_of_t7_with_halo_on_t7g} (jstart_of_t7_with_halo_on_t6sg = {jstart_of_t7_with_halo_on_t6sg}, - jend_of_t7_with_halo_on_t6sg = {jend_of_t7_with_halo_on_t6sg})''', verbose=VERBOSE) + jend_of_t7_with_halo_on_t6sg = {jend_of_t7_with_halo_on_t6sg})""", + verbose=VERBOSE, + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Return output variables. # - #----------------------------------------------------------------------- - # - return (lon_of_t7_ctr, lat_of_t7_ctr, nx_of_t7_on_t7g, ny_of_t7_on_t7g, - halo_width_on_t7g, stretch_factor, - istart_of_t7_with_halo_on_t6sg, - iend_of_t7_with_halo_on_t6sg, - jstart_of_t7_with_halo_on_t6sg, - jend_of_t7_with_halo_on_t6sg) + # ----------------------------------------------------------------------- + # + return { + "LON_CTR": lon_of_t7_ctr, + "LAT_CTR": lat_of_t7_ctr, + "NX": nx_of_t7_on_t7g, + "NY": ny_of_t7_on_t7g, + "NHW": halo_width_on_t7g, + "STRETCH_FAC": stretch_factor, + "ISTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG": istart_of_t7_with_halo_on_t6sg, + "IEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG": iend_of_t7_with_halo_on_t6sg, + "JSTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG": jstart_of_t7_with_halo_on_t6sg, + "JEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG": jend_of_t7_with_halo_on_t6sg, + } + class Testing(unittest.TestCase): def test_set_gridparams_GFDLgrid(self): - (LON_CTR,LAT_CTR,NX,NY,NHW,STRETCH_FAC, - ISTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG, - IEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG, - JSTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG, - JEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG) = set_gridparams_GFDLgrid( \ - lon_of_t6_ctr=-97.5, \ - lat_of_t6_ctr=38.5, \ - res_of_t6g=96, \ - stretch_factor=1.4, \ - refine_ratio_t6g_to_t7g=3, \ - istart_of_t7_on_t6g=13, \ - iend_of_t7_on_t6g=84, \ - jstart_of_t7_on_t6g=17, \ - jend_of_t7_on_t6g=80) - - self.assertEqual(\ - (LON_CTR,LAT_CTR,NX,NY,NHW,STRETCH_FAC, - ISTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG, - IEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG, - JSTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG, - JEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG), - (-97.5,38.5,216,192,6,1.4, - 21, - 172, - 29, - 164) + grid_params = set_gridparams_GFDLgrid( + lon_of_t6_ctr=-97.5, + lat_of_t6_ctr=38.5, + res_of_t6g=96, + stretch_factor=1.4, + refine_ratio_t6g_to_t7g=3, + istart_of_t7_on_t6g=13, + iend_of_t7_on_t6g=84, + jstart_of_t7_on_t6g=17, + jend_of_t7_on_t6g=80, ) - def setUp(self): - set_env_var('DEBUG',True) - set_env_var('VERBOSE',True) - set_env_var('NH4', 4) + self.assertEqual( + list(grid_params.values()), + [-97.5, 38.5, 216, 192, 6, 1.4, 21, 172, 29, 164], + ) + def setUp(self): + set_env_var("DEBUG", True) + set_env_var("VERBOSE", True) + set_env_var("NH4", 4) diff --git a/ush/set_namelist.py b/ush/set_namelist.py index 84c61975ec..90594dff98 100755 --- a/ush/set_namelist.py +++ b/ush/set_namelist.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 -''' +""" This utility updates a Fortran namelist file using the f90nml package. The settings that are modified are supplied via command line YAML-formatted string and/or YAML configuration files. @@ -64,7 +64,7 @@ - Given a user namelist and a base namelist, the script can dump the difference in the two to a YAML file that can be included as a section in the supported configs. -''' +""" import argparse import collections @@ -77,10 +77,10 @@ def config_exists(arg): - ''' + """ Checks whether the config file exists and if it contains the input section. Returns the arg as provided if checks are passed. - ''' + """ # Agument is expected to be a 2-item list of file name and internal section # name. @@ -90,43 +90,46 @@ def config_exists(arg): file_exists(file_name) # Load the YAML file into a dictionary - with open(file_name, 'r') as fn: + with open(file_name, "r") as fn: cfg = yaml.load(fn, Loader=yaml.Loader) # Grab only the section that is specified by the user try: cfg = cfg[section_name] except KeyError: - msg = f'Section {section_name} does not exist in top level of {file_name}' + msg = f"Section {section_name} does not exist in top level of {file_name}" raise argparse.ArgumentTypeError(msg) return [cfg, section_name] + def file_exists(arg): - ''' Check for existence of file ''' + """Check for existence of file""" if not os.path.exists(arg): - msg = f'{arg} does not exist!' + msg = f"{arg} does not exist!" raise argparse.ArgumentTypeError(msg) return arg + def load_config(arg): - ''' + """ Check to ensure that the provided config file exists. If it does, load it with YAML's safe loader and return the resulting dict. - ''' + """ return yaml.safe_load(arg) + def path_ok(arg): - ''' + """ Check whether the path to the file exists, and is writeable. Return the path if it passes all checks, otherwise raise an error. - ''' + """ # Get the absolute path provided by arg dir_name = os.path.abspath(os.path.dirname(arg)) @@ -135,71 +138,87 @@ def path_ok(arg): if os.path.lexists(dir_name) and os.access(dir_name, os.W_OK): return arg - msg = f'{arg} is not a writable path!' + msg = f"{arg} is not a writable path!" raise argparse.ArgumentTypeError(msg) + def parse_args(argv): - ''' + """ Function maintains the arguments accepted by this script. Please see Python's argparse documenation for more information about settings of each argument. - ''' + """ parser = argparse.ArgumentParser( - description='Update a Fortran namelist with user-defined settings.' + description="Update a Fortran namelist with user-defined settings." ) # Required - parser.add_argument('-o', '--outfile', - help='Required: Full path to output file. This is a \ - namelist by default.', - required=True, - type=path_ok, - ) + parser.add_argument( + "-o", + "--outfile", + help="Required: Full path to output file. This is a \ + namelist by default.", + required=True, + type=path_ok, + ) # Optional - parser.add_argument('-c', '--config', - help='Full path to a YAML config file containing multiple \ - configurations, and the top-level section to use. Optional.', - metavar=('[FILE,', 'SECTION]'), - nargs=2, - ) - parser.add_argument('-i', '--input_nml', - help='Path to a user namelist. Use with -n and \ - -t yaml to get a YAML file to use with workflow.', - type=file_exists, - ) - parser.add_argument('-n', '--basenml', - dest='nml', - help='Full path to the input Fortran namelist. Optional.', - type=file_exists, - ) - parser.add_argument('-t', '--type', - choices=['nml', 'yaml'], - default='nml', - help='Output file type.', - ) - parser.add_argument('-u', '--user_config', - help='Command-line user config options in YAML-formatted \ + parser.add_argument( + "-c", + "--config", + help="Full path to a YAML config file containing multiple \ + configurations, and the top-level section to use. Optional.", + metavar=("[FILE,", "SECTION]"), + nargs=2, + ) + parser.add_argument( + "-i", + "--input_nml", + help="Path to a user namelist. Use with -n and \ + -t yaml to get a YAML file to use with workflow.", + type=file_exists, + ) + parser.add_argument( + "-n", + "--basenml", + dest="nml", + help="Full path to the input Fortran namelist. Optional.", + type=file_exists, + ) + parser.add_argument( + "-t", + "--type", + choices=["nml", "yaml"], + default="nml", + help="Output file type.", + ) + parser.add_argument( + "-u", + "--user_config", + help="Command-line user config options in YAML-formatted \ string. These options will override any provided in an \ - input file. Optional.', - metavar='YAML STRING', - type=load_config, - ) + input file. Optional.", + metavar="YAML STRING", + type=load_config, + ) # Flags - parser.add_argument('-q', '--quiet', - action='store_true', - help='If provided, suppress all output.', - ) + parser.add_argument( + "-q", + "--quiet", + action="store_true", + help="If provided, suppress all output.", + ) return parser.parse_args(argv) + def dict_diff(dict1, dict2): - ''' + """ Produces a dictionary of how dict2 differs from dict1 - ''' + """ diffs = {} @@ -208,7 +227,7 @@ def dict_diff(dict1, dict2): for key, val in items.items(): # If dict 2 has a different value, record the dict2 value - if val != dict2.get(sect, {}).get(key, ''): + if val != dict2.get(sect, {}).get(key, ""): if not diffs.get(sect): diffs[sect] = {} diffs[sect][key] = dict2.get(sect, {}).get(key) @@ -219,18 +238,19 @@ def dict_diff(dict1, dict2): for key, val in items.items(): # If dict1 has a diffent value than dict2, record the dict2 value - if val != dict1.get(sect, {}).get(key, ''): + if val != dict1.get(sect, {}).get(key, ""): # Check to make sure it hasn't already been recorded - if diffs.get(sect, {}).get(key, 'DNE') == 'DNE': + if diffs.get(sect, {}).get(key, "DNE") == "DNE": if not diffs.get(sect): diffs[sect] = {} diffs[sect][key] = val return diffs + def to_dict(odict): - ''' Recursively convert OrderedDict to Python dict. ''' + """Recursively convert OrderedDict to Python dict.""" if not isinstance(odict, collections.OrderedDict): return odict @@ -241,9 +261,10 @@ def to_dict(odict): ret[key] = to_dict(value) return ret + def update_dict(dest, newdict, quiet=False): - ''' + """ Overwrites all values in dest dictionary with values from newdict. Turn off print statements with queit=True. @@ -262,7 +283,7 @@ def update_dict(dest, newdict, quiet=False): Result: The dest dict is updated in place. - ''' + """ for sect, values in newdict: # If section is set to None, remove all contents from namelist @@ -271,7 +292,7 @@ def update_dict(dest, newdict, quiet=False): else: for key, value in values.items(): if not quiet: - print(f'Setting {sect}.{key} = {value}') + print(f"Setting {sect}.{key} = {value}") # Remove key from dict if config is set to None if value is None: @@ -285,9 +306,10 @@ def update_dict(dest, newdict, quiet=False): dest[sect] = {} dest[sect][key] = value + def set_namelist(argv): - ''' Using input command line arguments (cla), update a Fortran namelist file. ''' + """Using input command line arguments (cla), update a Fortran namelist file.""" # parse argumetns cla = parse_args(argv) @@ -310,11 +332,11 @@ def set_namelist(argv): update_dict(nml, cla.user_config.items(), quiet=cla.quiet) # Write the resulting file - with open(cla.outfile, 'w') as fn: - if cla.type == 'nml': + with open(cla.outfile, "w") as fn: + if cla.type == "nml": nml.write(fn, sort=True) - if cla.type == 'yaml': + if cla.type == "yaml": if cla.input_nml: input_nml = f90nml.read(cla.input_nml) @@ -329,5 +351,5 @@ def set_namelist(argv): yaml.dump(to_dict(nml.todict()), fn) -if __name__ == '__main__': +if __name__ == "__main__": set_namelist(sys.argv[1:]) diff --git a/ush/set_ozone_param.py b/ush/set_ozone_param.py index 4c9998c3ca..65bde9675d 100644 --- a/ush/set_ozone_param.py +++ b/ush/set_ozone_param.py @@ -4,29 +4,40 @@ import unittest from textwrap import dedent -from python_utils import import_vars,export_vars,set_env_var,list_to_str,\ - print_input_args, print_info_msg, print_err_msg_exit,\ - define_macos_utilities,load_xml_file,has_tag_with_value,find_pattern_in_str +from python_utils import ( + import_vars, + export_vars, + set_env_var, + list_to_str, + print_input_args, + print_info_msg, + print_err_msg_exit, + define_macos_utilities, + load_xml_file, + has_tag_with_value, + find_pattern_in_str, +) + def set_ozone_param(ccpp_phys_suite_fp): - """ Function that does the following: + """Function that does the following: (1) Determines the ozone parameterization being used by checking in the CCPP physics suite XML. - + (2) Sets the name of the global ozone production/loss file in the FIXgsm FIXgsm system directory to copy to the experiment's FIXam directory. - + (3) Resets the last element of the workflow array variable FIXgsm_FILES_TO_COPY_TO_FIXam that contains the files to copy from - FIXgsm to FIXam (this last element is initially set to a dummy + FIXgsm to FIXam (this last element is initially set to a dummy value) to the name of the ozone production/loss file set in the previous step. - - (4) Resets the element of the workflow array variable - CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING (this array contains the + + (4) Resets the element of the workflow array variable + CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING (this array contains the mapping between the symlinks to create in any cycle directory and - the files in the FIXam directory that are their targets) that - specifies the mapping for the ozone symlink/file such that the + the files in the FIXam directory that are their targets) that + specifies the mapping for the ozone symlink/file such that the target FIXam file name is set to the name of the ozone production/ loss file set above. @@ -42,10 +53,10 @@ def set_ozone_param(ccpp_phys_suite_fp): import_vars() # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Get the name of the ozone parameterization being used. There are two - # possible ozone parameterizations: + # possible ozone parameterizations: # # (1) A parameterization developed/published in 2015. Here, we refer to # this as the 2015 parameterization. If this is being used, then we @@ -53,10 +64,10 @@ def set_ozone_param(ccpp_phys_suite_fp): # # (2) A parameterization developed/published sometime after 2015. Here, # we refer to this as the after-2015 parameterization. If this is - # being used, then we set the variable ozone_param to the string + # being used, then we set the variable ozone_param to the string # "ozphys". # - # We check the CCPP physics suite definition file (SDF) to determine the + # We check the CCPP physics suite definition file (SDF) to determine the # parameterization being used. If this file contains the line # # ozphys_2015 @@ -67,112 +78,126 @@ def set_ozone_param(ccpp_phys_suite_fp): # ozphys # # then the after-2015 parameterization is being used. (The SDF should - # contain exactly one of these lines; not both nor neither; we check for - # this.) + # contain exactly one of these lines; not both nor neither; we check for + # this.) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # tree = load_xml_file(ccpp_phys_suite_fp) ozone_param = "" if has_tag_with_value(tree, "scheme", "ozphys_2015"): - fixgsm_ozone_fn="ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77" - ozone_param = "ozphys_2015" + fixgsm_ozone_fn = "ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77" + ozone_param = "ozphys_2015" elif has_tag_with_value(tree, "scheme", "ozphys"): - fixgsm_ozone_fn="global_o3prdlos.f77" - ozone_param = "ozphys" + fixgsm_ozone_fn = "global_o3prdlos.f77" + ozone_param = "ozphys" else: - print_err_msg_exit(f''' - Unknown or no ozone parameterization - specified in the CCPP physics suite file (ccpp_phys_suite_fp): - ccpp_phys_suite_fp = \"{ccpp_phys_suite_fp}\" - ozone_param = \"{ozone_param}\"''') + print_err_msg_exit( + f''' + Unknown or no ozone parameterization + specified in the CCPP physics suite file (ccpp_phys_suite_fp): + ccpp_phys_suite_fp = \"{ccpp_phys_suite_fp}\" + ozone_param = \"{ozone_param}\"''' + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set the last element of the array FIXgsm_FILES_TO_COPY_TO_FIXam to the # name of the ozone production/loss file to copy from the FIXgsm to the # FIXam directory. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - i=len(FIXgsm_FILES_TO_COPY_TO_FIXam) - 1 - FIXgsm_FILES_TO_COPY_TO_FIXam[i]=f"{fixgsm_ozone_fn}" + i = len(FIXgsm_FILES_TO_COPY_TO_FIXam) - 1 + FIXgsm_FILES_TO_COPY_TO_FIXam[i] = f"{fixgsm_ozone_fn}" # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set the element in the array CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING that # specifies the mapping between the symlink for the ozone production/loss - # file that must be created in each cycle directory and its target in the + # file that must be created in each cycle directory and its target in the # FIXam directory. The name of the symlink is alrady in the array, but - # the target is not because it depends on the ozone parameterization that + # the target is not because it depends on the ozone parameterization that # the physics suite uses. Since we determined the ozone parameterization # above, we now set the target of the symlink accordingly. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - ozone_symlink="global_o3prdlos.f77" - fixgsm_ozone_fn_is_set=False - regex_search="^[ ]*([^| ]*)[ ]*[|][ ]*([^| ]*)[ ]*$" - num_symlinks=len(CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING) - + ozone_symlink = "global_o3prdlos.f77" + fixgsm_ozone_fn_is_set = False + regex_search = "^[ ]*([^| ]*)[ ]*[|][ ]*([^| ]*)[ ]*$" + num_symlinks = len(CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING) + for i in range(num_symlinks): - mapping=CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING[i] - symlink = find_pattern_in_str(regex_search, mapping) - if symlink is not None: - symlink = symlink[0] - if symlink == ozone_symlink: - regex_search="^[ ]*([^| ]+[ ]*)[|][ ]*([^| ]*)[ ]*$" - mapping_ozone = find_pattern_in_str(regex_search, mapping)[0] - mapping_ozone=f"{mapping_ozone}| {fixgsm_ozone_fn}" - CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING[i]=f"{mapping_ozone}" - fixgsm_ozone_fn_is_set=True - break - # - #----------------------------------------------------------------------- + mapping = CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING[i] + symlink = find_pattern_in_str(regex_search, mapping) + if symlink is not None: + symlink = symlink[0] + if symlink == ozone_symlink: + regex_search = "^[ ]*([^| ]+[ ]*)[|][ ]*([^| ]*)[ ]*$" + mapping_ozone = find_pattern_in_str(regex_search, mapping)[0] + mapping_ozone = f"{mapping_ozone}| {fixgsm_ozone_fn}" + CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING[i] = f"{mapping_ozone}" + fixgsm_ozone_fn_is_set = True + break + # + # ----------------------------------------------------------------------- # # If fixgsm_ozone_fn_is_set is set to True, then the appropriate element # of the array CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING was set successfully. # In this case, print out the new version of this array. Otherwise, print # out an error message and exit. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if fixgsm_ozone_fn_is_set: - - msg=dedent(f''' - After setting the file name of the ozone production/loss file in the - FIXgsm directory (based on the ozone parameterization specified in the - CCPP suite definition file), the array specifying the mapping between - the symlinks that need to be created in the cycle directories and the - files in the FIXam directory is: - - ''') - msg+=dedent(f''' - CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING = {list_to_str(CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING)} - ''') - print_info_msg(msg,verbose=VERBOSE) - + + msg = dedent( + f""" + After setting the file name of the ozone production/loss file in the + FIXgsm directory (based on the ozone parameterization specified in the + CCPP suite definition file), the array specifying the mapping between + the symlinks that need to be created in the cycle directories and the + files in the FIXam directory is: + + """ + ) + msg += dedent( + f""" + CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING = {list_to_str(CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING)} + """ + ) + print_info_msg(msg, verbose=VERBOSE) + else: - - print_err_msg_exit(f''' - Unable to set name of the ozone production/loss file in the FIXgsm directory - in the array that specifies the mapping between the symlinks that need to - be created in the cycle directories and the files in the FIXgsm directory: - fixgsm_ozone_fn_is_set = \"{fixgsm_ozone_fn_is_set}\"''') + + print_err_msg_exit( + f''' + Unable to set name of the ozone production/loss file in the FIXgsm directory + in the array that specifies the mapping between the symlinks that need to + be created in the cycle directories and the files in the FIXgsm directory: + fixgsm_ozone_fn_is_set = \"{fixgsm_ozone_fn_is_set}\"''' + ) EXPORTS = ["CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING", "FIXgsm_FILES_TO_COPY_TO_FIXam"] export_vars(env_vars=EXPORTS) return ozone_param + class Testing(unittest.TestCase): def test_set_ozone_param(self): - self.assertEqual( "ozphys_2015", - set_ozone_param(ccpp_phys_suite_fp=f"test_data{os.sep}suite_FV3_GSD_SAR.xml") ) + self.assertEqual( + "ozphys_2015", + set_ozone_param( + ccpp_phys_suite_fp=f"test_data{os.sep}suite_FV3_GSD_SAR.xml" + ), + ) + def setUp(self): - define_macos_utilities(); - set_env_var('DEBUG',True) - set_env_var('VERBOSE',True) + define_macos_utilities() + set_env_var("DEBUG", True) + set_env_var("VERBOSE", True) CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING = [ "aerosol.dat | global_climaeropac_global.txt", @@ -194,7 +219,8 @@ def setUp(self): "global_zorclim.1x1.grb | global_zorclim.1x1.grb", "sfc_emissivity_idx.txt | global_sfc_emissivity_idx.txt", "solarconstant_noaa_an.txt | global_solarconstant_noaa_an.txt", - "global_o3prdlos.f77 | ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77"] + "global_o3prdlos.f77 | ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77", + ] FIXgsm_FILES_TO_COPY_TO_FIXam = [ "global_glacier.2x2.grb", "global_maxice.2x2.grb", @@ -225,7 +251,11 @@ def setUp(self): "global_solarconstant_noaa_an.txt", "geo_em.d01.lat-lon.2.5m.HGT_M.nc", "HGT.Beljaars_filtered.lat-lon.30s_res.nc", - "ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77"] + "ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77", + ] - set_env_var('CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING', CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING) - set_env_var('FIXgsm_FILES_TO_COPY_TO_FIXam', FIXgsm_FILES_TO_COPY_TO_FIXam) + set_env_var( + "CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING", + CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING, + ) + set_env_var("FIXgsm_FILES_TO_COPY_TO_FIXam", FIXgsm_FILES_TO_COPY_TO_FIXam) diff --git a/ush/set_predef_grid_params.py b/ush/set_predef_grid_params.py index 970187e1de..f7a56b542d 100644 --- a/ush/set_predef_grid_params.py +++ b/ush/set_predef_grid_params.py @@ -3,12 +3,22 @@ import unittest import os -from python_utils import process_args,import_vars,export_vars,set_env_var,get_env_var,\ - print_input_args,define_macos_utilities, load_config_file, \ - cfg_to_yaml_str +from python_utils import ( + process_args, + import_vars, + export_vars, + set_env_var, + get_env_var, + print_input_args, + define_macos_utilities, + load_config_file, + cfg_to_yaml_str, + flatten_dict, +) + def set_predef_grid_params(): - """ Sets grid parameters for the specified predfined grid + """Sets grid parameters for the specified predfined grid Args: None @@ -16,46 +26,58 @@ def set_predef_grid_params(): None """ # import all environement variables - IMPORTS = ['PREDEF_GRID_NAME', 'QUILTING', 'DT_ATMOS', 'LAYOUT_X', 'LAYOUT_Y', 'BLOCKSIZE'] + IMPORTS = [ + "PREDEF_GRID_NAME", + "QUILTING", + "DT_ATMOS", + "LAYOUT_X", + "LAYOUT_Y", + "BLOCKSIZE", + ] import_vars(env_vars=IMPORTS) USHDIR = os.path.dirname(os.path.abspath(__file__)) - params_dict = load_config_file(os.path.join(USHDIR,"predef_grid_params.yaml")) + params_dict = load_config_file(os.path.join(USHDIR, "predef_grid_params.yaml")) params_dict = params_dict[PREDEF_GRID_NAME] - # if QUILTING = False, skip variables that start with "WRTCMP_" + # if QUILTING = False, remove key if not QUILTING: - params_dict = {k: v for k,v in params_dict.items() \ - if not k.startswith("WRTCMP_") } + params_dict.pop("QUILTING") + else: + params_dict = flatten_dict(params_dict) # take care of special vars - special_vars = ['DT_ATMOS', 'LAYOUT_X', 'LAYOUT_Y', 'BLOCKSIZE'] + special_vars = ["DT_ATMOS", "LAYOUT_X", "LAYOUT_Y", "BLOCKSIZE"] for var in special_vars: if globals()[var] is not None: params_dict[var] = globals()[var] # export variables to environment export_vars(source_dict=params_dict) - + return params_dict + if __name__ == "__main__": params_dict = set_predef_grid_params() - print( cfg_to_shell_str(params_dict), end='' ) + print(cfg_to_shell_str(params_dict), end="") + class Testing(unittest.TestCase): def test_set_predef_grid_params(self): set_predef_grid_params() - self.assertEqual(get_env_var('GRID_GEN_METHOD'),"ESGgrid") - self.assertEqual(get_env_var('ESGgrid_LON_CTR'),-97.5) + self.assertEqual(get_env_var("GRID_GEN_METHOD"), "ESGgrid") + self.assertEqual(get_env_var("ESGgrid_LON_CTR"), -97.5) + set_env_var("QUILTING", True) + set_predef_grid_params() + self.assertEqual(get_env_var("WRTCMP_nx"), 1799) def setUp(self): - define_macos_utilities(); - set_env_var('DEBUG',False) - set_env_var('PREDEF_GRID_NAME',"RRFS_CONUS_3km") - set_env_var('DT_ATMOS',36) - set_env_var('LAYOUT_X',18) - set_env_var('LAYOUT_Y',36) - set_env_var('BLOCKSIZE',28) - set_env_var('QUILTING',False) - + define_macos_utilities() + set_env_var("DEBUG", False) + set_env_var("PREDEF_GRID_NAME", "RRFS_CONUS_3km") + set_env_var("DT_ATMOS", 36) + set_env_var("LAYOUT_X", 18) + set_env_var("LAYOUT_Y", 36) + set_env_var("BLOCKSIZE", 28) + set_env_var("QUILTING", False) diff --git a/ush/set_thompson_mp_fix_files.py b/ush/set_thompson_mp_fix_files.py index 9a1703e098..7c9ffec727 100644 --- a/ush/set_thompson_mp_fix_files.py +++ b/ush/set_thompson_mp_fix_files.py @@ -4,15 +4,25 @@ import unittest from textwrap import dedent -from python_utils import import_vars,export_vars,set_env_var,list_to_str,\ - print_input_args,print_info_msg, print_err_msg_exit,\ - define_macos_utilities,load_xml_file,has_tag_with_value +from python_utils import ( + import_vars, + export_vars, + set_env_var, + list_to_str, + print_input_args, + print_info_msg, + print_err_msg_exit, + define_macos_utilities, + load_xml_file, + has_tag_with_value, +) + def set_thompson_mp_fix_files(ccpp_phys_suite_fp, thompson_mp_climo_fn): - """ Function that first checks whether the Thompson + """Function that first checks whether the Thompson microphysics parameterization is being called by the selected physics suite. If not, it sets the output variable whose name is specified by - output_varname_sdf_uses_thompson_mp to "FALSE" and exits. If so, it + output_varname_sdf_uses_thompson_mp to "FALSE" and exits. If so, it sets this variable to "TRUE" and modifies the workflow arrays FIXgsm_FILES_TO_COPY_TO_FIXam and CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING to ensure that fixed files needed by the Thompson microphysics @@ -32,90 +42,106 @@ def set_thompson_mp_fix_files(ccpp_phys_suite_fp, thompson_mp_climo_fn): import_vars() # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Check the suite definition file to see whether the Thompson microphysics # parameterization is being used. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # tree = load_xml_file(ccpp_phys_suite_fp) sdf_uses_thompson_mp = has_tag_with_value(tree, "scheme", "mp_thompson") # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If the Thompson microphysics parameterization is being used, then... # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if sdf_uses_thompson_mp: - # - #----------------------------------------------------------------------- - # - # Append the names of the fixed files needed by the Thompson microphysics - # parameterization to the workflow array FIXgsm_FILES_TO_COPY_TO_FIXam, - # and append to the workflow array CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING - # the mappings between these files and the names of the corresponding - # symlinks that need to be created in the run directories. - # - #----------------------------------------------------------------------- - # - thompson_mp_fix_files=[ - "CCN_ACTIVATE.BIN", - "freezeH2O.dat", - "qr_acr_qg.dat", - "qr_acr_qs.dat", - "qr_acr_qgV2.dat", - "qr_acr_qsV2.dat" + # + # ----------------------------------------------------------------------- + # + # Append the names of the fixed files needed by the Thompson microphysics + # parameterization to the workflow array FIXgsm_FILES_TO_COPY_TO_FIXam, + # and append to the workflow array CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING + # the mappings between these files and the names of the corresponding + # symlinks that need to be created in the run directories. + # + # ----------------------------------------------------------------------- + # + thompson_mp_fix_files = [ + "CCN_ACTIVATE.BIN", + "freezeH2O.dat", + "qr_acr_qg.dat", + "qr_acr_qs.dat", + "qr_acr_qgV2.dat", + "qr_acr_qsV2.dat", ] - - if (EXTRN_MDL_NAME_ICS != "HRRR" and EXTRN_MDL_NAME_ICS != "RAP") or \ - (EXTRN_MDL_NAME_LBCS != "HRRR" and EXTRN_MDL_NAME_LBCS != "RAP"): - thompson_mp_fix_files.append(thompson_mp_climo_fn) - + + if (EXTRN_MDL_NAME_ICS != "HRRR" and EXTRN_MDL_NAME_ICS != "RAP") or ( + EXTRN_MDL_NAME_LBCS != "HRRR" and EXTRN_MDL_NAME_LBCS != "RAP" + ): + thompson_mp_fix_files.append(thompson_mp_climo_fn) + FIXgsm_FILES_TO_COPY_TO_FIXam.extend(thompson_mp_fix_files) - + for fix_file in thompson_mp_fix_files: - mapping=f"{fix_file} | {fix_file}" - CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING.append(mapping) - - msg=dedent(f''' - Since the Thompson microphysics parameterization is being used by this + mapping = f"{fix_file} | {fix_file}" + CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING.append(mapping) + + msg = dedent( + f""" + Since the Thompson microphysics parameterization is being used by this physics suite (CCPP_PHYS_SUITE), the names of the fixed files needed by - this scheme have been appended to the array FIXgsm_FILES_TO_COPY_TO_FIXam, - and the mappings between these files and the symlinks that need to be + this scheme have been appended to the array FIXgsm_FILES_TO_COPY_TO_FIXam, + and the mappings between these files and the symlinks that need to be created in the cycle directories have been appended to the array - CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING. After these modifications, the + CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING. After these modifications, the values of these parameters are as follows: - - ''') - msg+=dedent(f''' + + """ + ) + msg += dedent( + f""" CCPP_PHYS_SUITE = \"{CCPP_PHYS_SUITE}\" - + FIXgsm_FILES_TO_COPY_TO_FIXam = {list_to_str(FIXgsm_FILES_TO_COPY_TO_FIXam)} - ''') - msg+=dedent(f''' + """ + ) + msg += dedent( + f""" CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING = {list_to_str(CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING)} - ''') + """ + ) print_info_msg(msg) - EXPORTS = [ "CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING", "FIXgsm_FILES_TO_COPY_TO_FIXam" ] + EXPORTS = [ + "CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING", + "FIXgsm_FILES_TO_COPY_TO_FIXam", + ] export_vars(env_vars=EXPORTS) return sdf_uses_thompson_mp + class Testing(unittest.TestCase): def test_set_thompson_mp_fix_files(self): - self.assertEqual( True, - set_thompson_mp_fix_files(ccpp_phys_suite_fp=f"test_data{os.sep}suite_FV3_GSD_SAR.xml", - thompson_mp_climo_fn="Thompson_MP_MONTHLY_CLIMO.nc") ) + self.assertEqual( + True, + set_thompson_mp_fix_files( + ccpp_phys_suite_fp=f"test_data{os.sep}suite_FV3_GSD_SAR.xml", + thompson_mp_climo_fn="Thompson_MP_MONTHLY_CLIMO.nc", + ), + ) + def setUp(self): - define_macos_utilities(); - set_env_var('DEBUG',True) - set_env_var('VERBOSE',True) - set_env_var('EXTRN_MDL_NAME_ICS',"FV3GFS") - set_env_var('EXTRN_MDL_NAME_LBCS',"FV3GFS") - set_env_var('CCPP_PHYS_SUITE',"FV3_GSD_SAR") + define_macos_utilities() + set_env_var("DEBUG", True) + set_env_var("VERBOSE", True) + set_env_var("EXTRN_MDL_NAME_ICS", "FV3GFS") + set_env_var("EXTRN_MDL_NAME_LBCS", "FV3GFS") + set_env_var("CCPP_PHYS_SUITE", "FV3_GSD_SAR") CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING = [ "aerosol.dat | global_climaeropac_global.txt", @@ -137,7 +163,8 @@ def setUp(self): "global_zorclim.1x1.grb | global_zorclim.1x1.grb", "sfc_emissivity_idx.txt | global_sfc_emissivity_idx.txt", "solarconstant_noaa_an.txt | global_solarconstant_noaa_an.txt", - "global_o3prdlos.f77 | ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77"] + "global_o3prdlos.f77 | ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77", + ] FIXgsm_FILES_TO_COPY_TO_FIXam = [ "global_glacier.2x2.grb", @@ -169,8 +196,11 @@ def setUp(self): "global_solarconstant_noaa_an.txt", "geo_em.d01.lat-lon.2.5m.HGT_M.nc", "HGT.Beljaars_filtered.lat-lon.30s_res.nc", - "ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77"] - - set_env_var('CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING', CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING) - set_env_var('FIXgsm_FILES_TO_COPY_TO_FIXam', FIXgsm_FILES_TO_COPY_TO_FIXam) + "ozprdlos_2015_new_sbuvO3_tclm15_nuchem.f77", + ] + set_env_var( + "CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING", + CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING, + ) + set_env_var("FIXgsm_FILES_TO_COPY_TO_FIXam", FIXgsm_FILES_TO_COPY_TO_FIXam) diff --git a/ush/setup.py b/ush/setup.py index 6a8f35231d..5185b7a68c 100644 --- a/ush/setup.py +++ b/ush/setup.py @@ -5,11 +5,28 @@ import datetime from textwrap import dedent -from python_utils import cd_vrfy, mkdir_vrfy, rm_vrfy, check_var_valid_value,\ - lowercase,uppercase,check_for_preexist_dir_file,\ - import_vars, export_vars, get_env_var, print_info_msg,\ - print_err_msg_exit, load_config_file, cfg_to_shell_str,\ - load_shell_config, load_ini_config, get_ini_value +from python_utils import ( + cd_vrfy, + mkdir_vrfy, + rm_vrfy, + check_var_valid_value, + lowercase, + uppercase, + check_for_preexist_dir_file, + flatten_dict, + update_dict, + import_vars, + export_vars, + get_env_var, + print_info_msg, + print_err_msg_exit, + load_config_file, + cfg_to_shell_str, + cfg_to_yaml_str, + load_shell_config, + load_ini_config, + get_ini_value, +) from set_cycle_dates import set_cycle_dates from set_predef_grid_params import set_predef_grid_params @@ -21,15 +38,16 @@ from check_ruc_lsm import check_ruc_lsm from set_thompson_mp_fix_files import set_thompson_mp_fix_files + def setup(): - """ Function that sets a secondary set - of parameters needed by the various scripts that are called by the - FV3-LAM rocoto community workflow. This secondary set of parameters is + """Function that sets a secondary set + of parameters needed by the various scripts that are called by the + FV3-LAM rocoto community workflow. This secondary set of parameters is calculated using the primary set of user-defined parameters in the de- fault and custom experiment/workflow configuration scripts (whose file names are defined below). This script then saves both sets of parame- - ters in a global variable definitions file (really a bash script) in - the experiment directory. This file then gets sourced by the various + ters in a global variable definitions file (really a bash script) in + the experiment directory. This file then gets sourced by the various scripts called by the tasks in the workflow. Args: @@ -38,201 +56,211 @@ def setup(): None """ - ushdir=os.path.dirname(os.path.abspath(__file__)) + ushdir = os.path.dirname(os.path.abspath(__file__)) cd_vrfy(ushdir) # import all environment variables import_vars() # print message - print_info_msg(f''' + print_info_msg( + f""" ======================================================================== Starting function setup() in \"{os.path.basename(__file__)}\"... - ========================================================================''') + ========================================================================""" + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set the name of the configuration file containing default values for # the experiment/workflow variables. Then source the file. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - EXPT_DEFAULT_CONFIG_FN="config_defaults.sh" - cfg_d = load_config_file(os.path.join(ushdir,EXPT_DEFAULT_CONFIG_FN)) - import_vars(dictionary=cfg_d) + EXPT_DEFAULT_CONFIG_FN = "config_defaults.yaml" + cfg_d = load_config_file(os.path.join(ushdir, EXPT_DEFAULT_CONFIG_FN)) + import_vars(dictionary=flatten_dict(cfg_d)) + # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If a user-specified configuration file exists, source it. This file - # contains user-specified values for a subset of the experiment/workflow + # contains user-specified values for a subset of the experiment/workflow # variables that override their default values. Note that the user- # specified configuration file is not tracked by the repository, whereas # the default configuration file is tracked. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if os.path.exists(EXPT_CONFIG_FN): + # + # We require that the variables being set in the user-specified configu- + # ration file have counterparts in the default configuration file. This + # is so that we do not introduce new variables in the user-specified + # configuration file without also officially introducing them in the de- + # fault configuration file. Thus, before sourcing the user-specified + # configuration file, we check that all variables in the user-specified + # configuration file are also assigned default values in the default + # configuration file. + # + cfg_u = load_config_file(os.path.join(ushdir, EXPT_CONFIG_FN)) + cfg_u = flatten_dict(cfg_u) + import_vars(dictionary=cfg_u) + update_dict(cfg_u, cfg_d) + # - # We require that the variables being set in the user-specified configu- - # ration file have counterparts in the default configuration file. This - # is so that we do not introduce new variables in the user-specified - # configuration file without also officially introducing them in the de- - # fault configuration file. Thus, before sourcing the user-specified - # configuration file, we check that all variables in the user-specified - # configuration file are also assigned default values in the default - # configuration file. - # - cfg_u = load_config_file(os.path.join(ushdir,EXPT_CONFIG_FN)) - cfg_d.update(cfg_u) - if cfg_u.items() > cfg_d.items(): - print_err_msg_exit(f''' - User specified config file {EXPT_CONGIG_FN} has variables that are - not defined in the default configuration file {EXPT_DEFAULT_CONFIG_FN}''') - import_vars(dictionary=cfg_u) - - # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # Source constants.sh and save its contents to a variable for later - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - cfg_c=load_config_file(os.path.join(ushdir,CONSTANTS_FN)) - const_lines=cfg_to_shell_str(cfg_c) + cfg_c = load_config_file(os.path.join(ushdir, CONSTANTS_FN)) import_vars(dictionary=cfg_c) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If PREDEF_GRID_NAME is set to a non-empty string, set or reset parameters # according to the predefined domain specified. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # export env vars before calling another module + # export env vars before calling another module export_vars() if PREDEF_GRID_NAME: - set_predef_grid_params() - + set_predef_grid_params() + import_vars() # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Make sure different variables are set to their corresponding valid value # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global VERBOSE if DEBUG and not VERBOSE: - print_info_msg(''' - Resetting VERBOSE to \"TRUE\" because DEBUG has been set to \"TRUE\"...''') - VERBOSE=True + print_info_msg( + """ + Resetting VERBOSE to \"TRUE\" because DEBUG has been set to \"TRUE\"...""" + ) + VERBOSE = True # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set magnitude of stochastic ad-hoc schemes to -999.0 if they are not # being used. This is required at the moment, since "do_shum/sppt/skeb" # does not override the use of the scheme unless the magnitude is also # specifically set to -999.0. If all "do_shum/sppt/skeb" are set to - # "false," then none will run, regardless of the magnitude values. + # "false," then none will run, regardless of the magnitude values. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global SHUM_MAG, SKEB_MAG, SPPT_MAG if not DO_SHUM: - SHUM_MAG=-999.0 + SHUM_MAG = -999.0 if not DO_SKEB: - SKEB_MAG=-999.0 + SKEB_MAG = -999.0 if not DO_SPPT: - SPPT_MAG=-999.0 + SPPT_MAG = -999.0 # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # If running with SPP in MYNN PBL, MYNN SFC, GSL GWD, Thompson MP, or - # RRTMG, count the number of entries in SPP_VAR_LIST to correctly set - # N_VAR_SPP, otherwise set it to zero. + # If running with SPP in MYNN PBL, MYNN SFC, GSL GWD, Thompson MP, or + # RRTMG, count the number of entries in SPP_VAR_LIST to correctly set + # N_VAR_SPP, otherwise set it to zero. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global N_VAR_SPP - N_VAR_SPP=0 + N_VAR_SPP = 0 if DO_SPP: - N_VAR_SPP = len(SPP_VAR_LIST) + N_VAR_SPP = len(SPP_VAR_LIST) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # If running with Noah or RUC-LSM SPP, count the number of entries in + # If running with Noah or RUC-LSM SPP, count the number of entries in # LSM_SPP_VAR_LIST to correctly set N_VAR_LNDP, otherwise set it to zero. # Also set LNDP_TYPE to 2 for LSM SPP, otherwise set it to zero. Finally, # initialize an "FHCYC_LSM_SPP" variable to 0 and set it to 999 if LSM SPP - # is turned on. This requirement is necessary since LSM SPP cannot run with + # is turned on. This requirement is necessary since LSM SPP cannot run with # FHCYC=0 at the moment, but FHCYC cannot be set to anything less than the - # length of the forecast either. A bug fix will be submitted to + # length of the forecast either. A bug fix will be submitted to # ufs-weather-model soon, at which point, this requirement can be removed - # from regional_workflow. + # from regional_workflow. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global N_VAR_LNDP, LNDP_TYPE, LNDP_MODEL_TYPE, FHCYC_LSM_SPP_OR_NOT - N_VAR_LNDP=0 - LNDP_TYPE=0 - LNDP_MODEL_TYPE=0 - FHCYC_LSM_SPP_OR_NOT=0 + N_VAR_LNDP = 0 + LNDP_TYPE = 0 + LNDP_MODEL_TYPE = 0 + FHCYC_LSM_SPP_OR_NOT = 0 if DO_LSM_SPP: - N_VAR_LNDP=len(LSM_SPP_VAR_LIST) - LNDP_TYPE=2 - LNDP_MODEL_TYPE=2 - FHCYC_LSM_SPP_OR_NOT=999 + N_VAR_LNDP = len(LSM_SPP_VAR_LIST) + LNDP_TYPE = 2 + LNDP_MODEL_TYPE = 2 + FHCYC_LSM_SPP_OR_NOT = 999 # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # If running with SPP, confirm that each SPP-related namelist value + # If running with SPP, confirm that each SPP-related namelist value # contains the same number of entries as N_VAR_SPP (set above to be equal # to the number of entries in SPP_VAR_LIST). # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if DO_SPP: - if ( len(SPP_MAG_LIST) != N_VAR_SPP ) or \ - ( len(SPP_LSCALE) != N_VAR_SPP) or \ - ( len(SPP_TSCALE) != N_VAR_SPP) or \ - ( len(SPP_SIGTOP1) != N_VAR_SPP) or \ - ( len(SPP_SIGTOP2) != N_VAR_SPP) or \ - ( len(SPP_STDDEV_CUTOFF) != N_VAR_SPP) or \ - ( len(ISEED_SPP) != N_VAR_SPP): - print_err_msg_exit(f''' - All MYNN PBL, MYNN SFC, GSL GWD, Thompson MP, or RRTMG SPP-related namelist - variables set in {CONFIG_FN} must be equal in number of entries to what is - found in SPP_VAR_LIST: - Number of entries in SPP_VAR_LIST = \"{len(SPP_VAR_LIST)}\"''') - # - #----------------------------------------------------------------------- + if ( + (len(SPP_MAG_LIST) != N_VAR_SPP) + or (len(SPP_LSCALE) != N_VAR_SPP) + or (len(SPP_TSCALE) != N_VAR_SPP) + or (len(SPP_SIGTOP1) != N_VAR_SPP) + or (len(SPP_SIGTOP2) != N_VAR_SPP) + or (len(SPP_STDDEV_CUTOFF) != N_VAR_SPP) + or (len(ISEED_SPP) != N_VAR_SPP) + ): + print_err_msg_exit( + f''' + All MYNN PBL, MYNN SFC, GSL GWD, Thompson MP, or RRTMG SPP-related namelist + variables set in {CONFIG_FN} must be equal in number of entries to what is + found in SPP_VAR_LIST: + Number of entries in SPP_VAR_LIST = \"{len(SPP_VAR_LIST)}\"''' + ) + # + # ----------------------------------------------------------------------- # # If running with LSM SPP, confirm that each LSM SPP-related namelist # value contains the same number of entries as N_VAR_LNDP (set above to # be equal to the number of entries in LSM_SPP_VAR_LIST). # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if DO_LSM_SPP: - if ( len(LSM_SPP_MAG_LIST) != N_VAR_LNDP) or \ - ( len(LSM_SPP_LSCALE) != N_VAR_LNDP) or \ - ( len(LSM_SPP_TSCALE) != N_VAR_LNDP): - print_err_msg_exit(f''' - All Noah or RUC-LSM SPP-related namelist variables (except ISEED_LSM_SPP) - set in {CONFIG_FN} must be equal in number of entries to what is found in - SPP_VAR_LIST: - Number of entries in SPP_VAR_LIST = \"{len(LSM_SPP_VAR_LIST)}\"''') - # - # The current script should be located in the ush subdirectory of the + if ( + (len(LSM_SPP_MAG_LIST) != N_VAR_LNDP) + or (len(LSM_SPP_LSCALE) != N_VAR_LNDP) + or (len(LSM_SPP_TSCALE) != N_VAR_LNDP) + ): + print_err_msg_exit( + f''' + All Noah or RUC-LSM SPP-related namelist variables (except ISEED_LSM_SPP) + set in {CONFIG_FN} must be equal in number of entries to what is found in + SPP_VAR_LIST: + Number of entries in SPP_VAR_LIST = \"{len(LSM_SPP_VAR_LIST)}\"''' + ) + # + # The current script should be located in the ush subdirectory of the # workflow directory. Thus, the workflow directory is the one above the # directory of the current script. # - SR_WX_APP_TOP_DIR=os.path.abspath( os.path.dirname(__file__) + \ - os.sep + os.pardir + os.sep + os.pardir) - + SR_WX_APP_TOP_DIR = os.path.abspath( + os.path.dirname(__file__) + os.sep + os.pardir + os.sep + os.pardir + ) + # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set the base directories in which codes obtained from external reposi- # tories (using the manage_externals tool) are placed. Obtain the rela- @@ -242,179 +270,199 @@ def setup(): # directories. Finally, make sure that each of these directories actu- # ally exists. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # mng_extrns_cfg_fn = os.path.join(SR_WX_APP_TOP_DIR, "Externals.cfg") try: - mng_extrns_cfg_fn = os.readlink(mng_extrns_cfg_fn) + mng_extrns_cfg_fn = os.readlink(mng_extrns_cfg_fn) except: - pass - property_name="local_path" + pass + property_name = "local_path" cfg = load_ini_config(mng_extrns_cfg_fn) # # Get the path to the workflow scripts # - external_name="regional_workflow" + external_name = "regional_workflow" HOMErrfs = get_ini_value(cfg, external_name, property_name) if not HOMErrfs: - print_err_msg_exit(f''' - Externals.cfg does not contain "{external_name}".''') + print_err_msg_exit( + f""" + Externals.cfg does not contain "{external_name}".""" + ) HOMErrfs = os.path.join(SR_WX_APP_TOP_DIR, HOMErrfs) # # Get the base directory of the FV3 forecast model code. # - external_name=FCST_MODEL - UFS_WTHR_MDL_DIR = get_ini_value(cfg, external_name,property_name) + external_name = FCST_MODEL + UFS_WTHR_MDL_DIR = get_ini_value(cfg, external_name, property_name) if not UFS_WTHR_MDL_DIR: - print_err_msg_exit(f''' - Externals.cfg does not contain "{external_name}".''') + print_err_msg_exit( + f""" + Externals.cfg does not contain "{external_name}".""" + ) - UFS_WTHR_MDL_DIR=os.path.join(SR_WX_APP_TOP_DIR, UFS_WTHR_MDL_DIR) + UFS_WTHR_MDL_DIR = os.path.join(SR_WX_APP_TOP_DIR, UFS_WTHR_MDL_DIR) if not os.path.exists(UFS_WTHR_MDL_DIR): - print_err_msg_exit(f''' + print_err_msg_exit( + f""" The base directory in which the FV3 source code should be located (UFS_WTHR_MDL_DIR) does not exist: UFS_WTHR_MDL_DIR = \"{UFS_WTHR_MDL_DIR}\" Please clone the external repository containing the code in this directory, - build the executable, and then rerun the workflow.''') + build the executable, and then rerun the workflow.""" + ) # # Get the base directory of the UFS_UTILS codes. # - external_name="ufs_utils" - UFS_UTILS_DIR=get_ini_value(cfg, external_name, property_name) + external_name = "ufs_utils" + UFS_UTILS_DIR = get_ini_value(cfg, external_name, property_name) if not UFS_UTILS_DIR: - print_err_msg_exit(f''' - Externals.cfg does not contain "{external_name}".''') - - UFS_UTILS_DIR=os.path.join(SR_WX_APP_TOP_DIR, UFS_UTILS_DIR) + print_err_msg_exit( + f""" + Externals.cfg does not contain "{external_name}".""" + ) + + UFS_UTILS_DIR = os.path.join(SR_WX_APP_TOP_DIR, UFS_UTILS_DIR) if not os.path.exists(UFS_UTILS_DIR): - print_err_msg_exit(f''' + print_err_msg_exit( + f""" The base directory in which the UFS utilities source codes should be lo- cated (UFS_UTILS_DIR) does not exist: UFS_UTILS_DIR = \"{UFS_UTILS_DIR}\" Please clone the external repository containing the code in this direct- - ory, build the executables, and then rerun the workflow.''') + ory, build the executables, and then rerun the workflow.""" + ) # # Get the base directory of the UPP code. # - external_name="UPP" - UPP_DIR=get_ini_value(cfg,external_name,property_name ) + external_name = "UPP" + UPP_DIR = get_ini_value(cfg, external_name, property_name) if not UPP_DIR: - print_err_msg_exit(f''' - Externals.cfg does not contain "{external_name}".''') - - UPP_DIR=os.path.join(SR_WX_APP_TOP_DIR, UPP_DIR) + print_err_msg_exit( + f""" + Externals.cfg does not contain "{external_name}".""" + ) + + UPP_DIR = os.path.join(SR_WX_APP_TOP_DIR, UPP_DIR) if not os.path.exists(UPP_DIR): - print_err_msg_exit(f''' + print_err_msg_exit( + f""" The base directory in which the UPP source code should be located (UPP_DIR) does not exist: UPP_DIR = \"{UPP_DIR}\" Please clone the external repository containing the code in this directory, - build the executable, and then rerun the workflow.''') + build the executable, and then rerun the workflow.""" + ) # # Define some other useful paths # - global USHDIR, SCRIPTSDIR, JOBSDIR,SORCDIR, SRC_DIR, PARMDIR, MODULES_DIR, EXECDIR, TEMPLATE_DIR, \ - VX_CONFIG_DIR, METPLUS_CONF, MET_CONFIG - - USHDIR = os.path.join(HOMErrfs,"ush") - SCRIPTSDIR = os.path.join(HOMErrfs,"scripts") - JOBSDIR = os.path.join(HOMErrfs,"jobs") - SORCDIR = os.path.join(HOMErrfs,"sorc") - SRC_DIR = os.path.join(SR_WX_APP_TOP_DIR,"src") - PARMDIR = os.path.join(HOMErrfs,"parm") - MODULES_DIR = os.path.join(HOMErrfs,"modulefiles") - EXECDIR = os.path.join(SR_WX_APP_TOP_DIR,EXEC_SUBDIR) - TEMPLATE_DIR = os.path.join(USHDIR,"templates") - VX_CONFIG_DIR = os.path.join(TEMPLATE_DIR,"parm") - METPLUS_CONF = os.path.join(TEMPLATE_DIR,"parm","metplus") - MET_CONFIG = os.path.join(TEMPLATE_DIR,"parm","met") - - # - #----------------------------------------------------------------------- + global USHDIR, SCRIPTSDIR, JOBSDIR, SORCDIR, SRC_DIR, PARMDIR, MODULES_DIR + global EXECDIR, TEMPLATE_DIR, VX_CONFIG_DIR, METPLUS_CONF, MET_CONFIG + + USHDIR = os.path.join(HOMErrfs, "ush") + SCRIPTSDIR = os.path.join(HOMErrfs, "scripts") + JOBSDIR = os.path.join(HOMErrfs, "jobs") + SORCDIR = os.path.join(HOMErrfs, "sorc") + SRC_DIR = os.path.join(SR_WX_APP_TOP_DIR, "src") + PARMDIR = os.path.join(HOMErrfs, "parm") + MODULES_DIR = os.path.join(HOMErrfs, "modulefiles") + EXECDIR = os.path.join(SR_WX_APP_TOP_DIR, EXEC_SUBDIR) + TEMPLATE_DIR = os.path.join(USHDIR, "templates") + VX_CONFIG_DIR = os.path.join(TEMPLATE_DIR, "parm") + METPLUS_CONF = os.path.join(TEMPLATE_DIR, "parm", "metplus") + MET_CONFIG = os.path.join(TEMPLATE_DIR, "parm", "met") + + # + # ----------------------------------------------------------------------- # # Source the machine config file containing architechture information, # queue names, and supported input file paths. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - global MACHINE - global MACHINE_FILE - global FIXgsm, FIXaer, FIXlut, TOPO_DIR, SFC_CLIMO_INPUT_DIR, DOMAIN_PREGEN_BASEDIR, \ - RELATIVE_LINK_FLAG, WORKFLOW_MANAGER, NCORES_PER_NODE, SCHED, \ - QUEUE_DEFAULT, QUEUE_HPSS, QUEUE_FCST, \ - PARTITION_DEFAULT, PARTITION_HPSS, PARTITION_FCST + global MACHINE, MACHINE_FILE + global FIXgsm, FIXaer, FIXlut, TOPO_DIR, SFC_CLIMO_INPUT_DIR, DOMAIN_PREGEN_BASEDIR + global RELATIVE_LINK_FLAG, WORKFLOW_MANAGER, NCORES_PER_NODE, SCHED, QUEUE_DEFAULT + global QUEUE_HPSS, QUEUE_FCST, PARTITION_DEFAULT, PARTITION_HPSS, PARTITION_FCST MACHINE = uppercase(MACHINE) - RELATIVE_LINK_FLAG="--relative" - MACHINE_FILE=MACHINE_FILE or os.path.join(USHDIR,"machine",f"{lowercase(MACHINE)}.sh") + RELATIVE_LINK_FLAG = "--relative" + MACHINE_FILE = MACHINE_FILE or os.path.join( + USHDIR, "machine", f"{lowercase(MACHINE)}.sh" + ) machine_cfg = load_shell_config(MACHINE_FILE) import_vars(dictionary=machine_cfg) - + if not NCORES_PER_NODE: - print_err_msg_exit(f""" - NCORES_PER_NODE has not been specified in the file {MACHINE_FILE} - Please ensure this value has been set for your desired platform. """) - + print_err_msg_exit( + f""" + NCORES_PER_NODE has not been specified in the file {MACHINE_FILE} + Please ensure this value has been set for your desired platform. """ + ) + if not (FIXgsm and FIXaer and FIXlut and TOPO_DIR and SFC_CLIMO_INPUT_DIR): - print_err_msg_exit(f''' - One or more fix file directories have not been specified for this machine: - MACHINE = \"{MACHINE}\" - FIXgsm = \"{FIXgsm or ""} - FIXaer = \"{FIXaer or ""} - FIXlut = \"{FIXlut or ""} - TOPO_DIR = \"{TOPO_DIR or ""} - SFC_CLIMO_INPUT_DIR = \"{SFC_CLIMO_INPUT_DIR or ""} - DOMAIN_PREGEN_BASEDIR = \"{DOMAIN_PREGEN_BASEDIR or ""} - You can specify the missing location(s) in config.sh''') - - # - #----------------------------------------------------------------------- - # - # Set the names of the build and workflow module files (if not - # already specified by the user). These are the files that need to be - # sourced before building the component SRW App codes and running various + print_err_msg_exit( + f""" + One or more fix file directories have not been specified for this machine: + MACHINE = \"{MACHINE}\" + FIXgsm = \"{FIXgsm or ""} + FIXaer = \"{FIXaer or ""} + FIXlut = \"{FIXlut or ""} + TOPO_DIR = \"{TOPO_DIR or ""} + SFC_CLIMO_INPUT_DIR = \"{SFC_CLIMO_INPUT_DIR or ""} + DOMAIN_PREGEN_BASEDIR = \"{DOMAIN_PREGEN_BASEDIR or ""} + You can specify the missing location(s) in config.sh""" + ) + + # + # ----------------------------------------------------------------------- + # + # Set the names of the build and workflow module files (if not + # already specified by the user). These are the files that need to be + # sourced before building the component SRW App codes and running various # workflow scripts, respectively. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global WFLOW_MOD_FN, BUILD_MOD_FN - machine=lowercase(MACHINE) - WFLOW_MOD_FN=WFLOW_MOD_FN or f"wflow_{machine}" - BUILD_MOD_FN=BUILD_MOD_FN or f"build_{machine}_{COMPILER}" + machine = lowercase(MACHINE) + WFLOW_MOD_FN = WFLOW_MOD_FN or f"wflow_{machine}" + BUILD_MOD_FN = BUILD_MOD_FN or f"build_{machine}_{COMPILER}" # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Calculate a default value for the number of processes per node for the - # RUN_FCST_TN task. Then set PPN_RUN_FCST to this default value if + # RUN_FCST_TN task. Then set PPN_RUN_FCST to this default value if # PPN_RUN_FCST is not already specified by the user. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global PPN_RUN_FCST ppn_run_fcst_default = NCORES_PER_NODE // OMP_NUM_THREADS_RUN_FCST - PPN_RUN_FCST=PPN_RUN_FCST or ppn_run_fcst_default + PPN_RUN_FCST = PPN_RUN_FCST or ppn_run_fcst_default # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If we are using a workflow manager check that the ACCOUNT variable is # not empty. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if WORKFLOW_MANAGER != "none": if not ACCOUNT: - print_err_msg_exit(f''' + print_err_msg_exit( + f''' The variable ACCOUNT cannot be empty if you are using a workflow manager: ACCOUNT = \"ACCOUNT\" - WORKFLOW_MANAGER = \"WORKFLOW_MANAGER\"''') + WORKFLOW_MANAGER = \"WORKFLOW_MANAGER\"''' + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set the grid type (GTYPE). In general, in the FV3 code, this can take # on one of the following values: "global", "stretch", "nest", and "re- @@ -423,369 +471,413 @@ def setup(): # are only interested in a regional grid, GTYPE must be set to "region- # al". # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global TILE_RGNL, GTYPE - GTYPE="regional" - TILE_RGNL="7" + GTYPE = "regional" + TILE_RGNL = "7" - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set USE_MERRA_CLIMO to either "TRUE" or "FALSE" so we don't # have to consider other valid values later on. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- global USE_MERRA_CLIMO if CCPP_PHYS_SUITE == "FV3_GFS_v15_thompson_mynn_lam3km": - USE_MERRA_CLIMO=True + USE_MERRA_CLIMO = True # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set CPL to TRUE/FALSE based on FCST_MODEL. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global CPL if FCST_MODEL == "ufs-weather-model": - CPL=False + CPL = False elif FCST_MODEL == "fv3gfs_aqm": - CPL=True + CPL = True else: - print_err_msg_exit(f''' - The coupling flag CPL has not been specified for this value of FCST_MODEL: - FCST_MODEL = \"{FCST_MODEL}\"''') + print_err_msg_exit( + f''' + The coupling flag CPL has not been specified for this value of FCST_MODEL: + FCST_MODEL = \"{FCST_MODEL}\"''' + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Make sure RESTART_INTERVAL is set to an integer value if present # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - if not isinstance(RESTART_INTERVAL,int): - print_err_msg_exit(f''' - RESTART_INTERVAL must be set to an integer number of hours. - RESTART_INTERVAL = \"{RESTART_INTERVAL}\"''') + if not isinstance(RESTART_INTERVAL, int): + print_err_msg_exit( + f''' + RESTART_INTERVAL must be set to an integer number of hours. + RESTART_INTERVAL = \"{RESTART_INTERVAL}\"''' + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # Check that DATE_FIRST_CYCL and DATE_LAST_CYCL are strings consisting + # Check that DATE_FIRST_CYCL and DATE_LAST_CYCL are strings consisting # of exactly 8 digits. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - if not isinstance(DATE_FIRST_CYCL,datetime.date): - print_err_msg_exit(f''' - DATE_FIRST_CYCL must be a string consisting of exactly 8 digits of the - form \"YYYYMMDD\", where YYYY is the 4-digit year, MM is the 2-digit - month, and DD is the 2-digit day-of-month. - DATE_FIRST_CYCL = \"{DATE_FIRST_CYCL}\"''') - - if not isinstance(DATE_LAST_CYCL,datetime.date): - print_err_msg_exit(f''' - DATE_LAST_CYCL must be a string consisting of exactly 8 digits of the - form \"YYYYMMDD\", where YYYY is the 4-digit year, MM is the 2-digit - month, and DD is the 2-digit day-of-month. - DATE_LAST_CYCL = \"{DATE_LAST_CYCL}\"''') + if not isinstance(DATE_FIRST_CYCL, datetime.date): + print_err_msg_exit( + f''' + DATE_FIRST_CYCL must be a string consisting of exactly 8 digits of the + form \"YYYYMMDD\", where YYYY is the 4-digit year, MM is the 2-digit + month, and DD is the 2-digit day-of-month. + DATE_FIRST_CYCL = \"{DATE_FIRST_CYCL}\"''' + ) + + if not isinstance(DATE_LAST_CYCL, datetime.date): + print_err_msg_exit( + f''' + DATE_LAST_CYCL must be a string consisting of exactly 8 digits of the + form \"YYYYMMDD\", where YYYY is the 4-digit year, MM is the 2-digit + month, and DD is the 2-digit day-of-month. + DATE_LAST_CYCL = \"{DATE_LAST_CYCL}\"''' + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Check that all elements of CYCL_HRS are strings consisting of exactly # 2 digits that are between "00" and "23", inclusive. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - i=0 + i = 0 for CYCL in CYCL_HRS: - if CYCL < 0 or CYCL > 23: - print_err_msg_exit(f''' - Each element of CYCL_HRS must be an integer between \"00\" and \"23\", in- - clusive (including a leading \"0\", if necessary), specifying an hour-of- - day. Element #{i} of CYCL_HRS (where the index of the first element is 0) - does not have this form: - CYCL_HRS = {CYCL_HRS} - CYCL_HRS[{i}] = \"{CYCL_HRS[i]}\"''') - - i=i+1 - # - #----------------------------------------------------------------------- + if CYCL < 0 or CYCL > 23: + print_err_msg_exit( + f''' + Each element of CYCL_HRS must be an integer between \"00\" and \"23\", in- + clusive (including a leading \"0\", if necessary), specifying an hour-of- + day. Element #{i} of CYCL_HRS (where the index of the first element is 0) + does not have this form: + CYCL_HRS = {CYCL_HRS} + CYCL_HRS[{i}] = \"{CYCL_HRS[i]}\"''' + ) + + i = i + 1 + # + # ----------------------------------------------------------------------- # Check cycle increment for cycle frequency (cycl_freq). # only if INCR_CYCL_FREQ < 24. - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if INCR_CYCL_FREQ < 24 and i > 1: - cycl_intv=(24//i) - if cycl_intv != INCR_CYCL_FREQ: - print_err_msg_exit(f''' - The number of CYCL_HRS does not match with that expected by INCR_CYCL_FREQ: - INCR_CYCL_FREQ = {INCR_CYCL_FREQ} - cycle interval by the number of CYCL_HRS = {cycl_intv} - CYCL_HRS = {CYCL_HRS} ''') - - for itmp in range(1,i): - itm1=itmp-1 - cycl_next_itmp=CYCL_HRS[itm1] + INCR_CYCL_FREQ - if cycl_next_itmp != CYCL_HRS[itmp]: - print_err_msg_exit(f''' - Element {itmp} of CYCL_HRS does not match with the increment of cycle - frequency INCR_CYCL_FREQ: - CYCL_HRS = {CYCL_HRS} - INCR_CYCL_FREQ = {INCR_CYCL_FREQ} - CYCL_HRS[{itmp}] = \"{CYCL_HRS[itmp]}\"''') - # - #----------------------------------------------------------------------- - # - # Call a function to generate the array ALL_CDATES containing the cycle + cycl_intv = 24 // i + if cycl_intv != INCR_CYCL_FREQ: + print_err_msg_exit( + f""" + The number of CYCL_HRS does not match with that expected by INCR_CYCL_FREQ: + INCR_CYCL_FREQ = {INCR_CYCL_FREQ} + cycle interval by the number of CYCL_HRS = {cycl_intv} + CYCL_HRS = {CYCL_HRS} """ + ) + + for itmp in range(1, i): + itm1 = itmp - 1 + cycl_next_itmp = CYCL_HRS[itm1] + INCR_CYCL_FREQ + if cycl_next_itmp != CYCL_HRS[itmp]: + print_err_msg_exit( + f''' + Element {itmp} of CYCL_HRS does not match with the increment of cycle + frequency INCR_CYCL_FREQ: + CYCL_HRS = {CYCL_HRS} + INCR_CYCL_FREQ = {INCR_CYCL_FREQ} + CYCL_HRS[{itmp}] = \"{CYCL_HRS[itmp]}\"''' + ) + # + # ----------------------------------------------------------------------- + # + # Call a function to generate the array ALL_CDATES containing the cycle # dates/hours for which to run forecasts. The elements of this array - # will have the form YYYYMMDDHH. They are the starting dates/times of + # will have the form YYYYMMDDHH. They are the starting dates/times of # the forecasts that will be run in the experiment. Then set NUM_CYCLES # to the number of elements in this array. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - ALL_CDATES = set_cycle_dates( \ - date_start=DATE_FIRST_CYCL, - date_end=DATE_LAST_CYCL, - cycle_hrs=CYCL_HRS, - incr_cycl_freq=INCR_CYCL_FREQ) - - NUM_CYCLES=len(ALL_CDATES) - + ALL_CDATES = set_cycle_dates( + date_start=DATE_FIRST_CYCL, + date_end=DATE_LAST_CYCL, + cycle_hrs=CYCL_HRS, + incr_cycl_freq=INCR_CYCL_FREQ, + ) + + NUM_CYCLES = len(ALL_CDATES) + if NUM_CYCLES > 90: - ALL_CDATES=None - print_info_msg(f''' - Too many cycles in ALL_CDATES to list, redefining in abbreviated form." - ALL_CDATES="{DATE_FIRST_CYCL}{CYCL_HRS[0]}...{DATE_LAST_CYCL}{CYCL_HRS[-1]}''') + ALL_CDATES = None + print_info_msg( + f""" + Too many cycles in ALL_CDATES to list, redefining in abbreviated form." + ALL_CDATES="{DATE_FIRST_CYCL}{CYCL_HRS[0]}...{DATE_LAST_CYCL}{CYCL_HRS[-1]}""" + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If using a custom post configuration file, make sure that it exists. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if USE_CUSTOM_POST_CONFIG_FILE: - if not os.path.exists(CUSTOM_POST_CONFIG_FP): - print_err_msg_exit(f''' - The custom post configuration specified by CUSTOM_POST_CONFIG_FP does not - exist: - CUSTOM_POST_CONFIG_FP = \"{CUSTOM_POST_CONFIG_FP}\"''') + if not os.path.exists(CUSTOM_POST_CONFIG_FP): + print_err_msg_exit( + f''' + The custom post configuration specified by CUSTOM_POST_CONFIG_FP does not + exist: + CUSTOM_POST_CONFIG_FP = \"{CUSTOM_POST_CONFIG_FP}\"''' + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If using external CRTM fix files to allow post-processing of synthetic # satellite products from the UPP, then make sure the fix file directory # exists. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if USE_CRTM: - if not os.path.exists(CRTM_DIR): - print_err_msg_exit(f''' - The external CRTM fix file directory specified by CRTM_DIR does not exist: - CRTM_DIR = \"{CRTM_DIR}\"''') + if not os.path.exists(CRTM_DIR): + print_err_msg_exit( + f''' + The external CRTM fix file directory specified by CRTM_DIR does not exist: + CRTM_DIR = \"{CRTM_DIR}\"''' + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # The forecast length (in integer hours) cannot contain more than 3 cha- # racters. Thus, its maximum value is 999. Check whether the specified # forecast length exceeds this maximum value. If so, print out a warn- # ing and exit this script. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - fcst_len_hrs_max=999 + fcst_len_hrs_max = 999 if FCST_LEN_HRS > fcst_len_hrs_max: - print_err_msg_exit(f''' - Forecast length is greater than maximum allowed length: - FCST_LEN_HRS = {FCST_LEN_HRS} - fcst_len_hrs_max = {fcst_len_hrs_max}''') + print_err_msg_exit( + f""" + Forecast length is greater than maximum allowed length: + FCST_LEN_HRS = {FCST_LEN_HRS} + fcst_len_hrs_max = {fcst_len_hrs_max}""" + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Check whether the forecast length (FCST_LEN_HRS) is evenly divisible # by the BC update interval (LBC_SPEC_INTVL_HRS). If not, print out a # warning and exit this script. If so, generate an array of forecast # hours at which the boundary values will be updated. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - rem=FCST_LEN_HRS%LBC_SPEC_INTVL_HRS - + rem = FCST_LEN_HRS % LBC_SPEC_INTVL_HRS + if rem != 0: - print_err_msg_exit(f''' - The forecast length (FCST_LEN_HRS) is not evenly divisible by the lateral - boundary conditions update interval (LBC_SPEC_INTVL_HRS): - FCST_LEN_HRS = {FCST_LEN_HRS} - LBC_SPEC_INTVL_HRS = {LBC_SPEC_INTVL_HRS} - rem = FCST_LEN_HRS%%LBC_SPEC_INTVL_HRS = {rem}''') - # - #----------------------------------------------------------------------- - # - # Set the array containing the forecast hours at which the lateral + print_err_msg_exit( + f""" + The forecast length (FCST_LEN_HRS) is not evenly divisible by the lateral + boundary conditions update interval (LBC_SPEC_INTVL_HRS): + FCST_LEN_HRS = {FCST_LEN_HRS} + LBC_SPEC_INTVL_HRS = {LBC_SPEC_INTVL_HRS} + rem = FCST_LEN_HRS%%LBC_SPEC_INTVL_HRS = {rem}""" + ) + # + # ----------------------------------------------------------------------- + # + # Set the array containing the forecast hours at which the lateral # boundary conditions (LBCs) need to be updated. Note that this array # does not include the 0-th hour (initial time). # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - LBC_SPEC_FCST_HRS=[ i for i in range(LBC_SPEC_INTVL_HRS, \ - LBC_SPEC_INTVL_HRS + FCST_LEN_HRS, \ - LBC_SPEC_INTVL_HRS ) ] + LBC_SPEC_FCST_HRS = [ + i + for i in range( + LBC_SPEC_INTVL_HRS, LBC_SPEC_INTVL_HRS + FCST_LEN_HRS, LBC_SPEC_INTVL_HRS + ) + ] # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # Check to make sure that various computational parameters needed by the - # forecast model are set to non-empty values. At this point in the - # experiment generation, all of these should be set to valid (non-empty) + # Check to make sure that various computational parameters needed by the + # forecast model are set to non-empty values. At this point in the + # experiment generation, all of these should be set to valid (non-empty) # values. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if not DT_ATMOS: - print_err_msg_exit(f''' - The forecast model main time step (DT_ATMOS) is set to a null string: - DT_ATMOS = {DT_ATMOS} - Please set this to a valid numerical value in the user-specified experiment - configuration file (EXPT_CONFIG_FP) and rerun: - EXPT_CONFIG_FP = \"{EXPT_CONFIG_FP}\"''') - + print_err_msg_exit( + f''' + The forecast model main time step (DT_ATMOS) is set to a null string: + DT_ATMOS = {DT_ATMOS} + Please set this to a valid numerical value in the user-specified experiment + configuration file (EXPT_CONFIG_FP) and rerun: + EXPT_CONFIG_FP = \"{EXPT_CONFIG_FP}\"''' + ) + if not LAYOUT_X: - print_err_msg_exit(f''' - The number of MPI processes to be used in the x direction (LAYOUT_X) by - the forecast job is set to a null string: - LAYOUT_X = {LAYOUT_X} - Please set this to a valid numerical value in the user-specified experiment - configuration file (EXPT_CONFIG_FP) and rerun: - EXPT_CONFIG_FP = \"{EXPT_CONFIG_FP}\"''') - + print_err_msg_exit( + f''' + The number of MPI processes to be used in the x direction (LAYOUT_X) by + the forecast job is set to a null string: + LAYOUT_X = {LAYOUT_X} + Please set this to a valid numerical value in the user-specified experiment + configuration file (EXPT_CONFIG_FP) and rerun: + EXPT_CONFIG_FP = \"{EXPT_CONFIG_FP}\"''' + ) + if not LAYOUT_Y: - print_err_msg_exit(f''' - The number of MPI processes to be used in the y direction (LAYOUT_Y) by - the forecast job is set to a null string: - LAYOUT_Y = {LAYOUT_Y} - Please set this to a valid numerical value in the user-specified experiment - configuration file (EXPT_CONFIG_FP) and rerun: - EXPT_CONFIG_FP = \"{EXPT_CONFIG_FP}\"''') - + print_err_msg_exit( + f''' + The number of MPI processes to be used in the y direction (LAYOUT_Y) by + the forecast job is set to a null string: + LAYOUT_Y = {LAYOUT_Y} + Please set this to a valid numerical value in the user-specified experiment + configuration file (EXPT_CONFIG_FP) and rerun: + EXPT_CONFIG_FP = \"{EXPT_CONFIG_FP}\"''' + ) + if not BLOCKSIZE: - print_err_msg_exit(f''' - The cache size to use for each MPI task of the forecast (BLOCKSIZE) is - set to a null string: - BLOCKSIZE = {BLOCKSIZE} - Please set this to a valid numerical value in the user-specified experiment - configuration file (EXPT_CONFIG_FP) and rerun: - EXPT_CONFIG_FP = \"{EXPT_CONFIG_FP}\"''') - # - #----------------------------------------------------------------------- + print_err_msg_exit( + f''' + The cache size to use for each MPI task of the forecast (BLOCKSIZE) is + set to a null string: + BLOCKSIZE = {BLOCKSIZE} + Please set this to a valid numerical value in the user-specified experiment + configuration file (EXPT_CONFIG_FP) and rerun: + EXPT_CONFIG_FP = \"{EXPT_CONFIG_FP}\"''' + ) + # + # ----------------------------------------------------------------------- # # If performing sub-hourly model output and post-processing, check that # the output interval DT_SUBHOURLY_POST_MNTS (in minutes) is specified # correctly. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global SUB_HOURLY_POST if SUB_HOURLY_POST: - # - # Check that DT_SUBHOURLY_POST_MNTS is between 0 and 59, inclusive. - # - if DT_SUBHOURLY_POST_MNTS < 0 or DT_SUBHOURLY_POST_MNTS > 59: - print_err_msg_exit(f''' - When performing sub-hourly post (i.e. SUB_HOURLY_POST set to \"TRUE\"), - DT_SUBHOURLY_POST_MNTS must be set to an integer between 0 and 59, - inclusive but in this case is not: - SUB_HOURLY_POST = \"{SUB_HOURLY_POST}\" - DT_SUBHOURLY_POST_MNTS = \"{DT_SUBHOURLY_POST_MNTS}\"''') - # - # Check that DT_SUBHOURLY_POST_MNTS (after converting to seconds) is - # evenly divisible by the forecast model's main time step DT_ATMOS. - # - rem=( DT_SUBHOURLY_POST_MNTS*60 % DT_ATMOS ) - if rem != 0: - print_err_msg_exit(f''' - When performing sub-hourly post (i.e. SUB_HOURLY_POST set to \"TRUE\"), - the time interval specified by DT_SUBHOURLY_POST_MNTS (after converting - to seconds) must be evenly divisible by the time step DT_ATMOS used in - the forecast model, i.e. the remainder (rem) must be zero. In this case, - it is not: - SUB_HOURLY_POST = \"{SUB_HOURLY_POST}\" - DT_SUBHOURLY_POST_MNTS = \"{DT_SUBHOURLY_POST_MNTS}\" - DT_ATMOS = \"{DT_ATMOS}\" - rem = (DT_SUBHOURLY_POST_MNTS*60) %% DT_ATMOS = {rem} - Please reset DT_SUBHOURLY_POST_MNTS and/or DT_ATMOS so that this remainder - is zero.''') - # - # If DT_SUBHOURLY_POST_MNTS is set to 0 (with SUB_HOURLY_POST set to - # True), then we're not really performing subhourly post-processing. - # In this case, reset SUB_HOURLY_POST to False and print out an - # informational message that such a change was made. - # - if DT_SUBHOURLY_POST_MNTS == 0: - print_info_msg(f''' - When performing sub-hourly post (i.e. SUB_HOURLY_POST set to \"TRUE\"), - DT_SUBHOURLY_POST_MNTS must be set to a value greater than 0; otherwise, - sub-hourly output is not really being performed: - SUB_HOURLY_POST = \"{SUB_HOURLY_POST}\" - DT_SUBHOURLY_POST_MNTS = \"{DT_SUBHOURLY_POST_MNTS}\" - Resetting SUB_HOURLY_POST to \"FALSE\". If you do not want this, you - must set DT_SUBHOURLY_POST_MNTS to something other than zero.''') - SUB_HOURLY_POST=False - # - #----------------------------------------------------------------------- - # - # If the base directory (EXPT_BASEDIR) in which the experiment subdirectory - # (EXPT_SUBDIR) will be located does not start with a "/", then it is - # either set to a null string or contains a relative directory. In both - # cases, prepend to it the absolute path of the default directory under - # which the experiment directories are placed. If EXPT_BASEDIR was set - # to a null string, it will get reset to this default experiment directory, - # and if it was set to a relative directory, it will get reset to an - # absolute directory that points to the relative directory under the - # default experiment directory. Then create EXPT_BASEDIR if it doesn't + # + # Check that DT_SUBHOURLY_POST_MNTS is between 0 and 59, inclusive. + # + if DT_SUBHOURLY_POST_MNTS < 0 or DT_SUBHOURLY_POST_MNTS > 59: + print_err_msg_exit( + f''' + When performing sub-hourly post (i.e. SUB_HOURLY_POST set to \"TRUE\"), + DT_SUBHOURLY_POST_MNTS must be set to an integer between 0 and 59, + inclusive but in this case is not: + SUB_HOURLY_POST = \"{SUB_HOURLY_POST}\" + DT_SUBHOURLY_POST_MNTS = \"{DT_SUBHOURLY_POST_MNTS}\"''' + ) + # + # Check that DT_SUBHOURLY_POST_MNTS (after converting to seconds) is + # evenly divisible by the forecast model's main time step DT_ATMOS. + # + rem = DT_SUBHOURLY_POST_MNTS * 60 % DT_ATMOS + if rem != 0: + print_err_msg_exit( + f""" + When performing sub-hourly post (i.e. SUB_HOURLY_POST set to \"TRUE\"), + the time interval specified by DT_SUBHOURLY_POST_MNTS (after converting + to seconds) must be evenly divisible by the time step DT_ATMOS used in + the forecast model, i.e. the remainder (rem) must be zero. In this case, + it is not: + SUB_HOURLY_POST = \"{SUB_HOURLY_POST}\" + DT_SUBHOURLY_POST_MNTS = \"{DT_SUBHOURLY_POST_MNTS}\" + DT_ATMOS = \"{DT_ATMOS}\" + rem = (DT_SUBHOURLY_POST_MNTS*60) %% DT_ATMOS = {rem} + Please reset DT_SUBHOURLY_POST_MNTS and/or DT_ATMOS so that this remainder + is zero.""" + ) + # + # If DT_SUBHOURLY_POST_MNTS is set to 0 (with SUB_HOURLY_POST set to + # True), then we're not really performing subhourly post-processing. + # In this case, reset SUB_HOURLY_POST to False and print out an + # informational message that such a change was made. + # + if DT_SUBHOURLY_POST_MNTS == 0: + print_info_msg( + f""" + When performing sub-hourly post (i.e. SUB_HOURLY_POST set to \"TRUE\"), + DT_SUBHOURLY_POST_MNTS must be set to a value greater than 0; otherwise, + sub-hourly output is not really being performed: + SUB_HOURLY_POST = \"{SUB_HOURLY_POST}\" + DT_SUBHOURLY_POST_MNTS = \"{DT_SUBHOURLY_POST_MNTS}\" + Resetting SUB_HOURLY_POST to \"FALSE\". If you do not want this, you + must set DT_SUBHOURLY_POST_MNTS to something other than zero.""" + ) + SUB_HOURLY_POST = False + # + # ----------------------------------------------------------------------- + # + # If the base directory (EXPT_BASEDIR) in which the experiment subdirectory + # (EXPT_SUBDIR) will be located does not start with a "/", then it is + # either set to a null string or contains a relative directory. In both + # cases, prepend to it the absolute path of the default directory under + # which the experiment directories are placed. If EXPT_BASEDIR was set + # to a null string, it will get reset to this default experiment directory, + # and if it was set to a relative directory, it will get reset to an + # absolute directory that points to the relative directory under the + # default experiment directory. Then create EXPT_BASEDIR if it doesn't # already exist. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global EXPT_BASEDIR if (not EXPT_BASEDIR) or (EXPT_BASEDIR[0] != "/"): - if not EXPT_BASEDIR: - EXPT_BASEDIR = "" - EXPT_BASEDIR = os.path.join(SR_WX_APP_TOP_DIR,"..","expt_dirs",EXPT_BASEDIR) + if not EXPT_BASEDIR: + EXPT_BASEDIR = "" + EXPT_BASEDIR = os.path.join(SR_WX_APP_TOP_DIR, "..", "expt_dirs", EXPT_BASEDIR) try: - EXPT_BASEDIR = os.path.realpath(EXPT_BASEDIR) + EXPT_BASEDIR = os.path.realpath(EXPT_BASEDIR) except: - pass + pass EXPT_BASEDIR = os.path.abspath(EXPT_BASEDIR) - + mkdir_vrfy(f' -p "{EXPT_BASEDIR}"') # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If the experiment subdirectory name (EXPT_SUBDIR) is set to an empty # string, print out an error message and exit. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if not EXPT_SUBDIR: - print_err_msg_exit(f''' - The name of the experiment subdirectory (EXPT_SUBDIR) cannot be empty: - EXPT_SUBDIR = \"{EXPT_SUBDIR}\"''') + print_err_msg_exit( + f''' + The name of the experiment subdirectory (EXPT_SUBDIR) cannot be empty: + EXPT_SUBDIR = \"{EXPT_SUBDIR}\"''' + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set the full path to the experiment directory. Then check if it already # exists and if so, deal with it as specified by PREEXISTING_DIR_METHOD. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global EXPTDIR EXPTDIR = os.path.join(EXPT_BASEDIR, EXPT_SUBDIR) - check_for_preexist_dir_file(EXPTDIR,PREEXISTING_DIR_METHOD) + check_for_preexist_dir_file(EXPTDIR, PREEXISTING_DIR_METHOD) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set other directories, some of which may depend on EXPTDIR (depending - # on whether we're running in NCO or community mode, i.e. whether RUN_ENVIR + # on whether we're running in NCO or community mode, i.e. whether RUN_ENVIR # is set to "nco" or "community"). Definitions: # # LOGDIR: @@ -797,7 +889,7 @@ def setup(): # usually much coarser than the native FV3-LAM grid). # # FIXclim: - # This is the directory that will contain the MERRA2 aerosol climatology + # This is the directory that will contain the MERRA2 aerosol climatology # data file and lookup tables for optics properties # # FIXLAM: @@ -810,19 +902,19 @@ def setup(): # be placed. # # COMROOT: - # In NCO mode, this is the full path to the "com" directory under which + # In NCO mode, this is the full path to the "com" directory under which # output from the RUN_POST_TN task will be placed. Note that this output # is not placed directly under COMROOT but several directories further # down. More specifically, for a cycle starting at yyyymmddhh, it is at # # $COMROOT/$NET/$envir/$RUN.$yyyymmdd/$hh # - # Below, we set COMROOT in terms of PTMP as COMROOT="$PTMP/com". COMOROOT + # Below, we set COMROOT in terms of PTMP as COMROOT="$PTMP/com". COMOROOT # is not used by the workflow in community mode. # # COMOUT_BASEDIR: - # In NCO mode, this is the base directory directly under which the output - # from the RUN_POST_TN task will be placed, i.e. it is the cycle-independent + # In NCO mode, this is the base directory directly under which the output + # from the RUN_POST_TN task will be placed, i.e. it is the cycle-independent # portion of the RUN_POST_TN task's output directory. It is given by # # $COMROOT/$NET/$model_ver @@ -832,46 +924,58 @@ def setup(): # POST_OUTPUT_DOMAIN_NAME: # The PREDEF_GRID_NAME is set by default. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - global LOGDIR, FIXam, FIXclim, FIXLAM, CYCLE_BASEDIR, \ - COMROOT, COMOUT_BASEDIR, POST_OUTPUT_DOMAIN_NAME + global LOGDIR, FIXam, FIXclim, FIXLAM, CYCLE_BASEDIR, COMROOT + global COMOUT_BASEDIR, POST_OUTPUT_DOMAIN_NAME LOGDIR = os.path.join(EXPTDIR, "log") - + FIXam = os.path.join(EXPTDIR, "fix_am") FIXclim = os.path.join(EXPTDIR, "fix_clim") FIXLAM = os.path.join(EXPTDIR, "fix_lam") - + if RUN_ENVIR == "nco": - - CYCLE_BASEDIR = os.path.join(STMP, "tmpnwprd", RUN) - check_for_preexist_dir_file(CYCLE_BASEDIR,PREEXISTING_DIR_METHOD) - COMROOT = os.path.join(PTMP, "com") - COMOUT_BASEDIR = os.path.join(COMROOT, NET, model_ver) - check_for_preexist_dir_file(COMOUT_BASEDIR,PREEXISTING_DIR_METHOD) - - else: - - CYCLE_BASEDIR=EXPTDIR - COMROOT="" - COMOUT_BASEDIR="" - if POST_OUTPUT_DOMAIN_NAME is None: - if PREDEF_GRID_NAME is None: - print_err_msg_exit(f''' - The domain name used in naming the run_post output files - (POST_OUTPUT_DOMAIN_NAME) has not been set: - POST_OUTPUT_DOMAIN_NAME = \"{POST_OUTPUT_DOMAIN_NAME}\" - If this experiment is not using a predefined grid (i.e. if - PREDEF_GRID_NAME is set to a null string), POST_OUTPUT_DOMAIN_NAME - must be set in the configuration file (\"{EXPT_CONFIG_FN}\"). ''') + CYCLE_BASEDIR = os.path.join(STMP, "tmpnwprd", RUN) + check_for_preexist_dir_file(CYCLE_BASEDIR, PREEXISTING_DIR_METHOD) + COMROOT = os.path.join(PTMP, "com") + COMOUT_BASEDIR = os.path.join(COMROOT, NET, model_ver) + check_for_preexist_dir_file(COMOUT_BASEDIR, PREEXISTING_DIR_METHOD) + + else: - POST_OUTPUT_DOMAIN_NAME = PREDEF_GRID_NAME + CYCLE_BASEDIR = EXPTDIR + COMROOT = "" + COMOUT_BASEDIR = "" - POST_OUTPUT_DOMAIN_NAME = lowercase(POST_OUTPUT_DOMAIN_NAME) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- + # + # + # If POST_OUTPUT_DOMAIN_NAME has not been specified by the user, set it + # to PREDEF_GRID_NAME (which won't be empty if using a predefined grid). + # Then change it to lowercase. Finally, ensure that it does not end up + # getting set to an empty string. + # + # ----------------------------------------------------------------------- + # + POST_OUTPUT_DOMAIN_NAME = POST_OUTPUT_DOMAIN_NAME or PREDEF_GRID_NAME + POST_OUTPUT_DOMAIN_NAME = lowercase(POST_OUTPUT_DOMAIN_NAME) + + if POST_OUTPUT_DOMAIN_NAME is None: + if PREDEF_GRID_NAME is None: + print_err_msg_exit( + f""" + The domain name used in naming the run_post output files + (POST_OUTPUT_DOMAIN_NAME) has not been set: + POST_OUTPUT_DOMAIN_NAME = \"{POST_OUTPUT_DOMAIN_NAME}\" + If this experiment is not using a predefined grid (i.e. if + PREDEF_GRID_NAME is set to a null string), POST_OUTPUT_DOMAIN_NAME + must be set in the configuration file (\"{EXPT_CONFIG_FN}\"). """ + ) + # + # ----------------------------------------------------------------------- # # The FV3 forecast model needs the following input files in the run di- # rectory to start a forecast: @@ -887,73 +991,75 @@ def setup(): # # (7) The CCPP physics suite definition file # - # The workflow contains templates for the first six of these files. + # The workflow contains templates for the first six of these files. # Template files are versions of these files that contain placeholder - # (i.e. dummy) values for various parameters. The experiment/workflow - # generation scripts copy these templates to appropriate locations in + # (i.e. dummy) values for various parameters. The experiment/workflow + # generation scripts copy these templates to appropriate locations in # the experiment directory (either the top of the experiment directory # or one of the cycle subdirectories) and replace the placeholders in - # these copies by actual values specified in the experiment/workflow + # these copies by actual values specified in the experiment/workflow # configuration file (or derived from such values). The scripts then # use the resulting "actual" files as inputs to the forecast model. # # Note that the CCPP physics suite defintion file does not have a cor- # responding template file because it does not contain any values that # need to be replaced according to the experiment/workflow configura- - # tion. If using CCPP, this file simply needs to be copied over from + # tion. If using CCPP, this file simply needs to be copied over from # its location in the forecast model's directory structure to the ex- # periment directory. # # Below, we first set the names of the templates for the first six files - # listed above. We then set the full paths to these template files. + # listed above. We then set the full paths to these template files. # Note that some of these file names depend on the physics suite while # others do not. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - global DATA_TABLE_TMPL_FN, DIAG_TABLE_TMPL_FN, FIELD_TABLE_TMPL_FN, \ - MODEL_CONFIG_TMPL_FN, NEMS_CONFIG_TMPL_FN - global DATA_TABLE_TMPL_FP, DIAG_TABLE_TMPL_FP, FIELD_TABLE_TMPL_FP, \ - MODEL_CONFIG_TMPL_FP, NEMS_CONFIG_TMPL_FP - global FV3_NML_BASE_SUITE_FP, FV3_NML_YAML_CONFIG_FP,FV3_NML_BASE_ENS_FP + global DATA_TABLE_TMPL_FN, DIAG_TABLE_TMPL_FN, FIELD_TABLE_TMPL_FN, MODEL_CONFIG_TMPL_FN, NEMS_CONFIG_TMPL_FN + global DATA_TABLE_TMPL_FP, DIAG_TABLE_TMPL_FP, FIELD_TABLE_TMPL_FP, MODEL_CONFIG_TMPL_FP, NEMS_CONFIG_TMPL_FP + global FV3_NML_BASE_SUITE_FP, FV3_NML_YAML_CONFIG_FP, FV3_NML_BASE_ENS_FP - dot_ccpp_phys_suite_or_null=f".{CCPP_PHYS_SUITE}" - - # Names of input files that the forecast model (ufs-weather-model) expects - # to read in. These should only be changed if the input file names in the + dot_ccpp_phys_suite_or_null = f".{CCPP_PHYS_SUITE}" + + # Names of input files that the forecast model (ufs-weather-model) expects + # to read in. These should only be changed if the input file names in the # forecast model code are changed. - #---------------------------------- + # ---------------------------------- DATA_TABLE_FN = "data_table" DIAG_TABLE_FN = "diag_table" FIELD_TABLE_FN = "field_table" MODEL_CONFIG_FN = "model_configure" NEMS_CONFIG_FN = "nems.configure" - #---------------------------------- + # ---------------------------------- DATA_TABLE_TMPL_FN = DATA_TABLE_TMPL_FN or DATA_TABLE_FN - DIAG_TABLE_TMPL_FN = f"{DIAG_TABLE_TMPL_FN or DIAG_TABLE_FN}{dot_ccpp_phys_suite_or_null}" - FIELD_TABLE_TMPL_FN = f"{FIELD_TABLE_TMPL_FN or FIELD_TABLE_FN}{dot_ccpp_phys_suite_or_null}" + DIAG_TABLE_TMPL_FN = ( + f"{DIAG_TABLE_TMPL_FN or DIAG_TABLE_FN}{dot_ccpp_phys_suite_or_null}" + ) + FIELD_TABLE_TMPL_FN = ( + f"{FIELD_TABLE_TMPL_FN or FIELD_TABLE_FN}{dot_ccpp_phys_suite_or_null}" + ) MODEL_CONFIG_TMPL_FN = MODEL_CONFIG_TMPL_FN or MODEL_CONFIG_FN NEMS_CONFIG_TMPL_FN = NEMS_CONFIG_TMPL_FN or NEMS_CONFIG_FN - DATA_TABLE_TMPL_FP = os.path.join(TEMPLATE_DIR,DATA_TABLE_TMPL_FN) - DIAG_TABLE_TMPL_FP = os.path.join(TEMPLATE_DIR,DIAG_TABLE_TMPL_FN) - FIELD_TABLE_TMPL_FP = os.path.join(TEMPLATE_DIR,FIELD_TABLE_TMPL_FN) - FV3_NML_BASE_SUITE_FP = os.path.join(TEMPLATE_DIR,FV3_NML_BASE_SUITE_FN) - FV3_NML_YAML_CONFIG_FP = os.path.join(TEMPLATE_DIR,FV3_NML_YAML_CONFIG_FN) - FV3_NML_BASE_ENS_FP = os.path.join(EXPTDIR,FV3_NML_BASE_ENS_FN) - MODEL_CONFIG_TMPL_FP = os.path.join(TEMPLATE_DIR,MODEL_CONFIG_TMPL_FN) - NEMS_CONFIG_TMPL_FP = os.path.join(TEMPLATE_DIR,NEMS_CONFIG_TMPL_FN) + DATA_TABLE_TMPL_FP = os.path.join(TEMPLATE_DIR, DATA_TABLE_TMPL_FN) + DIAG_TABLE_TMPL_FP = os.path.join(TEMPLATE_DIR, DIAG_TABLE_TMPL_FN) + FIELD_TABLE_TMPL_FP = os.path.join(TEMPLATE_DIR, FIELD_TABLE_TMPL_FN) + FV3_NML_BASE_SUITE_FP = os.path.join(TEMPLATE_DIR, FV3_NML_BASE_SUITE_FN) + FV3_NML_YAML_CONFIG_FP = os.path.join(TEMPLATE_DIR, FV3_NML_YAML_CONFIG_FN) + FV3_NML_BASE_ENS_FP = os.path.join(EXPTDIR, FV3_NML_BASE_ENS_FN) + MODEL_CONFIG_TMPL_FP = os.path.join(TEMPLATE_DIR, MODEL_CONFIG_TMPL_FN) + NEMS_CONFIG_TMPL_FP = os.path.join(TEMPLATE_DIR, NEMS_CONFIG_TMPL_FN) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set: # - # 1) the variable CCPP_PHYS_SUITE_FN to the name of the CCPP physics + # 1) the variable CCPP_PHYS_SUITE_FN to the name of the CCPP physics # suite definition file. - # 2) the variable CCPP_PHYS_SUITE_IN_CCPP_FP to the full path of this + # 2) the variable CCPP_PHYS_SUITE_IN_CCPP_FP to the full path of this # file in the forecast model's directory structure. - # 3) the variable CCPP_PHYS_SUITE_FP to the full path of this file in + # 3) the variable CCPP_PHYS_SUITE_FP to the full path of this file in # the experiment directory. # # Note that the experiment/workflow generation scripts will copy this @@ -961,19 +1067,23 @@ def setup(): # each cycle, the forecast launch script will create a link in the cycle # run directory to the copy of this file at CCPP_PHYS_SUITE_FP. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global CCPP_PHYS_SUITE_FN, CCPP_PHYS_SUITE_IN_CCPP_FP, CCPP_PHYS_SUITE_FP - CCPP_PHYS_SUITE_FN=f"suite_{CCPP_PHYS_SUITE}.xml" - CCPP_PHYS_SUITE_IN_CCPP_FP=os.path.join(UFS_WTHR_MDL_DIR, "FV3","ccpp","suites",CCPP_PHYS_SUITE_FN) - CCPP_PHYS_SUITE_FP=os.path.join(EXPTDIR, CCPP_PHYS_SUITE_FN) + CCPP_PHYS_SUITE_FN = f"suite_{CCPP_PHYS_SUITE}.xml" + CCPP_PHYS_SUITE_IN_CCPP_FP = os.path.join( + UFS_WTHR_MDL_DIR, "FV3", "ccpp", "suites", CCPP_PHYS_SUITE_FN + ) + CCPP_PHYS_SUITE_FP = os.path.join(EXPTDIR, CCPP_PHYS_SUITE_FN) if not os.path.exists(CCPP_PHYS_SUITE_IN_CCPP_FP): - print_err_msg_exit(f''' - The CCPP suite definition file (CCPP_PHYS_SUITE_IN_CCPP_FP) does not exist - in the local clone of the ufs-weather-model: - CCPP_PHYS_SUITE_IN_CCPP_FP = \"{CCPP_PHYS_SUITE_IN_CCPP_FP}\"''') + print_err_msg_exit( + f''' + The CCPP suite definition file (CCPP_PHYS_SUITE_IN_CCPP_FP) does not exist + in the local clone of the ufs-weather-model: + CCPP_PHYS_SUITE_IN_CCPP_FP = \"{CCPP_PHYS_SUITE_IN_CCPP_FP}\"''' + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set: # @@ -984,39 +1094,42 @@ def setup(): # 3) the variable FIELD_DICT_FP to the full path of this file in # the experiment directory. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global FIELD_DICT_FN, FIELD_DICT_IN_UWM_FP, FIELD_DICT_FP FIELD_DICT_FN = "fd_nems.yaml" - FIELD_DICT_IN_UWM_FP = os.path.join(UFS_WTHR_MDL_DIR, "tests", "parm", FIELD_DICT_FN) + FIELD_DICT_IN_UWM_FP = os.path.join( + UFS_WTHR_MDL_DIR, "tests", "parm", FIELD_DICT_FN + ) FIELD_DICT_FP = os.path.join(EXPTDIR, FIELD_DICT_FN) if not os.path.exists(FIELD_DICT_IN_UWM_FP): - print_err_msg_exit(f''' - The field dictionary file (FIELD_DICT_IN_UWM_FP) does not exist - in the local clone of the ufs-weather-model: - FIELD_DICT_IN_UWM_FP = \"{FIELD_DICT_IN_UWM_FP}\"''') + print_err_msg_exit( + f''' + The field dictionary file (FIELD_DICT_IN_UWM_FP) does not exist + in the local clone of the ufs-weather-model: + FIELD_DICT_IN_UWM_FP = \"{FIELD_DICT_IN_UWM_FP}\"''' + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Call the function that sets the ozone parameterization being used and - # modifies associated parameters accordingly. + # modifies associated parameters accordingly. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - - # export env vars before calling another module + + # export env vars before calling another module export_vars() - OZONE_PARAM = set_ozone_param( \ - ccpp_phys_suite_fp=CCPP_PHYS_SUITE_IN_CCPP_FP) + OZONE_PARAM = set_ozone_param(ccpp_phys_suite_fp=CCPP_PHYS_SUITE_IN_CCPP_FP) IMPORTS = ["CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING", "FIXgsm_FILES_TO_COPY_TO_FIXam"] import_vars(env_vars=IMPORTS) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set the full paths to those forecast model input files that are cycle- - # independent, i.e. they don't include information about the cycle's + # independent, i.e. they don't include information about the cycle's # starting day/time. These are: # # * The data table file [(1) in the list above)] @@ -1028,8 +1141,8 @@ def setup(): # scripts will place them in the main experiment directory (EXPTDIR). # The script that runs each cycle will then create links to these files # in the run directories of the individual cycles (which are subdirecto- - # ries under EXPTDIR). - # + # ries under EXPTDIR). + # # The remaining two input files to the forecast model, i.e. # # * The diagnostics table file [(2) in the list above)] @@ -1039,10 +1152,10 @@ def setup(): # versions of these two files must be generated for each cycle and then # placed directly in the run directories of the cycles (not EXPTDIR). # For this reason, the full paths to their locations vary by cycle and - # cannot be set here (i.e. they can only be set in the loop over the + # cannot be set here (i.e. they can only be set in the loop over the # cycles in the rocoto workflow XML file). # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global DATA_TABLE_FP, FIELD_TABLE_FP, FV3_NML_FN, FV3_NML_FP, NEMS_CONFIG_FP DATA_TABLE_FP = os.path.join(EXPTDIR, DATA_TABLE_FN) @@ -1051,366 +1164,379 @@ def setup(): FV3_NML_FP = os.path.join(EXPTDIR, FV3_NML_FN) NEMS_CONFIG_FP = os.path.join(EXPTDIR, NEMS_CONFIG_FN) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If USE_USER_STAGED_EXTRN_FILES is set to TRUE, make sure that the user- - # specified directories under which the external model files should be + # specified directories under which the external model files should be # located actually exist. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if USE_USER_STAGED_EXTRN_FILES: - # Check for the base directory up to the first templated field. - idx = EXTRN_MDL_SOURCE_BASEDIR_ICS.find("$") - if idx == -1: - idx=len(EXTRN_MDL_SOURCE_BASEDIR_ICS) - - if not os.path.exists(EXTRN_MDL_SOURCE_BASEDIR_ICS[:idx]): - print_err_msg_exit(f''' - The directory (EXTRN_MDL_SOURCE_BASEDIR_ICS) in which the user-staged - external model files for generating ICs should be located does not exist: - EXTRN_MDL_SOURCE_BASEDIR_ICS = \"{EXTRN_MDL_SOURCE_BASEDIR_ICS}\"''') - - idx = EXTRN_MDL_SOURCE_BASEDIR_LBCS.find("$") - if idx == -1: - idx=len(EXTRN_MDL_SOURCE_BASEDIR_LBCS) - - if not os.path.exists(EXTRN_MDL_SOURCE_BASEDIR_LBCS[:idx]): - print_err_msg_exit(f''' - The directory (EXTRN_MDL_SOURCE_BASEDIR_LBCS) in which the user-staged - external model files for generating LBCs should be located does not exist: - EXTRN_MDL_SOURCE_BASEDIR_LBCS = \"{EXTRN_MDL_SOURCE_BASEDIR_LBCS}\"''') - # - #----------------------------------------------------------------------- + # Check for the base directory up to the first templated field. + idx = EXTRN_MDL_SOURCE_BASEDIR_ICS.find("$") + if idx == -1: + idx = len(EXTRN_MDL_SOURCE_BASEDIR_ICS) + + if not os.path.exists(EXTRN_MDL_SOURCE_BASEDIR_ICS[:idx]): + print_err_msg_exit( + f''' + The directory (EXTRN_MDL_SOURCE_BASEDIR_ICS) in which the user-staged + external model files for generating ICs should be located does not exist: + EXTRN_MDL_SOURCE_BASEDIR_ICS = \"{EXTRN_MDL_SOURCE_BASEDIR_ICS}\"''' + ) + + idx = EXTRN_MDL_SOURCE_BASEDIR_LBCS.find("$") + if idx == -1: + idx = len(EXTRN_MDL_SOURCE_BASEDIR_LBCS) + + if not os.path.exists(EXTRN_MDL_SOURCE_BASEDIR_LBCS[:idx]): + print_err_msg_exit( + f''' + The directory (EXTRN_MDL_SOURCE_BASEDIR_LBCS) in which the user-staged + external model files for generating LBCs should be located does not exist: + EXTRN_MDL_SOURCE_BASEDIR_LBCS = \"{EXTRN_MDL_SOURCE_BASEDIR_LBCS}\"''' + ) + # + # ----------------------------------------------------------------------- # # Make sure that DO_ENSEMBLE is set to a valid value. Then set the names # of the ensemble members. These will be used to set the ensemble member # directories. Also, set the full path to the FV3 namelist file corresponding # to each ensemble member. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - global NDIGITS_ENSMEM_NAMES,ENSMEM_NAMES,FV3_NML_ENSMEM_FPS,NUM_ENS_MEMBERS - NDIGITS_ENSMEM_NAMES=0 - ENSMEM_NAMES=[] - FV3_NML_ENSMEM_FPS=[] + global NDIGITS_ENSMEM_NAMES, ENSMEM_NAMES, FV3_NML_ENSMEM_FPS, NUM_ENS_MEMBERS + NDIGITS_ENSMEM_NAMES = 0 + ENSMEM_NAMES = [] + FV3_NML_ENSMEM_FPS = [] if DO_ENSEMBLE: - NDIGITS_ENSMEM_NAMES=len(str(NUM_ENS_MEMBERS)) - fmt=f"0{NDIGITS_ENSMEM_NAMES}d" - for i in range(NUM_ENS_MEMBERS): - ENSMEM_NAMES.append(f"mem{fmt}".format(i+1)) - FV3_NML_ENSMEM_FPS.append(os.path.join(EXPTDIR, f"{FV3_NML_FN}_{ENSMEM_NAMES[i]}")) + NDIGITS_ENSMEM_NAMES = len(str(NUM_ENS_MEMBERS)) + fmt = f"0{NDIGITS_ENSMEM_NAMES}d" + for i in range(NUM_ENS_MEMBERS): + ENSMEM_NAMES.append(f"mem{fmt}".format(i + 1)) + FV3_NML_ENSMEM_FPS.append( + os.path.join(EXPTDIR, f"{FV3_NML_FN}_{ENSMEM_NAMES[i]}") + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set the full path to the forecast model executable. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global FV3_EXEC_FP FV3_EXEC_FP = os.path.join(EXECDIR, FV3_EXEC_FN) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # Set the full path to the script that can be used to (re)launch the + # Set the full path to the script that can be used to (re)launch the # workflow. Also, if USE_CRON_TO_RELAUNCH is set to TRUE, set the line # to add to the cron table to automatically relaunch the workflow every # CRON_RELAUNCH_INTVL_MNTS minutes. Otherwise, set the variable con- # taining this line to a null string. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global WFLOW_LAUNCH_SCRIPT_FP, WFLOW_LAUNCH_LOG_FP, CRONTAB_LINE WFLOW_LAUNCH_SCRIPT_FP = os.path.join(USHDIR, WFLOW_LAUNCH_SCRIPT_FN) WFLOW_LAUNCH_LOG_FP = os.path.join(EXPTDIR, WFLOW_LAUNCH_LOG_FN) if USE_CRON_TO_RELAUNCH: - CRONTAB_LINE=f'''*/{CRON_RELAUNCH_INTVL_MNTS} * * * * cd {EXPTDIR} && ./{WFLOW_LAUNCH_SCRIPT_FN} called_from_cron="TRUE" >> ./{WFLOW_LAUNCH_LOG_FN} 2>&1''' + CRONTAB_LINE = ( + f"""*/{CRON_RELAUNCH_INTVL_MNTS} * * * * cd {EXPTDIR} && """ + f"""./{WFLOW_LAUNCH_SCRIPT_FN} called_from_cron="TRUE" >> ./{WFLOW_LAUNCH_LOG_FN} 2>&1""" + ) else: - CRONTAB_LINE="" + CRONTAB_LINE = "" # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set the full path to the script that, for a given task, loads the # necessary module files and runs the tasks. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global LOAD_MODULES_RUN_TASK_FP LOAD_MODULES_RUN_TASK_FP = os.path.join(USHDIR, "load_modules_run_task.sh") # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Define the various work subdirectories under the main work directory. # Each of these corresponds to a different step/substep/task in the pre- # processing, as follows: # # GRID_DIR: - # Directory in which the grid files will be placed (if RUN_TASK_MAKE_GRID - # is set to True) or searched for (if RUN_TASK_MAKE_GRID is set to + # Directory in which the grid files will be placed (if RUN_TASK_MAKE_GRID + # is set to True) or searched for (if RUN_TASK_MAKE_GRID is set to # False). # # OROG_DIR: - # Directory in which the orography files will be placed (if RUN_TASK_MAKE_OROG - # is set to True) or searched for (if RUN_TASK_MAKE_OROG is set to + # Directory in which the orography files will be placed (if RUN_TASK_MAKE_OROG + # is set to True) or searched for (if RUN_TASK_MAKE_OROG is set to # False). # # SFC_CLIMO_DIR: # Directory in which the surface climatology files will be placed (if - # RUN_TASK_MAKE_SFC_CLIMO is set to True) or searched for (if + # RUN_TASK_MAKE_SFC_CLIMO is set to True) or searched for (if # RUN_TASK_MAKE_SFC_CLIMO is set to False). # - #---------------------------------------------------------------------- + # ---------------------------------------------------------------------- # global RUN_TASK_MAKE_GRID, RUN_TASK_MAKE_OROG, RUN_TASK_MAKE_SFC_CLIMO global GRID_DIR, OROG_DIR, SFC_CLIMO_DIR global RUN_TASK_VX_GRIDSTAT, RUN_TASK_VX_POINTSTAT, RUN_TASK_VX_ENSGRID # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Make sure that DO_ENSEMBLE is set to TRUE when running ensemble vx. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # if (not DO_ENSEMBLE) and (RUN_TASK_VX_ENSGRID or RUN_TASK_VX_ENSPOINT): - print_err_msg_exit(f''' - Ensemble verification can not be run unless running in ensemble mode: - DO_ENSEMBLE = \"{DO_ENSEMBLE}\" - RUN_TASK_VX_ENSGRID = \"{RUN_TASK_VX_ENSGRID}\" - RUN_TASK_VX_ENSPOINT = \"{RUN_TASK_VX_ENSPOINT}\"''') + print_err_msg_exit( + f''' + Ensemble verification can not be run unless running in ensemble mode: + DO_ENSEMBLE = \"{DO_ENSEMBLE}\" + RUN_TASK_VX_ENSGRID = \"{RUN_TASK_VX_ENSGRID}\" + RUN_TASK_VX_ENSPOINT = \"{RUN_TASK_VX_ENSPOINT}\"''' + ) if RUN_ENVIR == "nco": - - nco_fix_dir = os.path.join(DOMAIN_PREGEN_BASEDIR, PREDEF_GRID_NAME) - if not os.path.exists(nco_fix_dir): - print_err_msg_exit(f''' - The directory (nco_fix_dir) that should contain the pregenerated grid, - orography, and surface climatology files does not exist: - nco_fix_dir = \"{nco_fix_dir}\"''') - - if RUN_TASK_MAKE_GRID or \ - ( not RUN_TASK_MAKE_GRID and \ - GRID_DIR != nco_fix_dir ): - - msg=f''' - When RUN_ENVIR is set to \"nco\", the workflow assumes that pregenerated - grid files already exist in the directory - - {DOMAIN_PREGEN_BASEDIR}/{PREDEF_GRID_NAME} - - where - - DOMAIN_PREGEN_BASEDIR = \"{DOMAIN_PREGEN_BASEDIR}\" - PREDEF_GRID_NAME = \"{PREDEF_GRID_NAME}\" - - Thus, the MAKE_GRID_TN task must not be run (i.e. RUN_TASK_MAKE_GRID must - be set to \"FALSE\"), and the directory in which to look for the grid - files (i.e. GRID_DIR) must be set to the one above. Current values for - these quantities are: - - RUN_TASK_MAKE_GRID = \"{RUN_TASK_MAKE_GRID}\" - GRID_DIR = \"{GRID_DIR}\" - - Resetting RUN_TASK_MAKE_GRID to \"FALSE\" and GRID_DIR to the one above. - Reset values are: - ''' - - RUN_TASK_MAKE_GRID=False - GRID_DIR=nco_fix_dir - - msg+=f''' - RUN_TASK_MAKE_GRID = \"{RUN_TASK_MAKE_GRID}\" - GRID_DIR = \"{GRID_DIR}\" - ''' - - print_info_msg(msg) - - - if RUN_TASK_MAKE_OROG or \ - ( not RUN_TASK_MAKE_OROG and \ - OROG_DIR != nco_fix_dir ): - - msg=f''' - When RUN_ENVIR is set to \"nco\", the workflow assumes that pregenerated - orography files already exist in the directory - {DOMAIN_PREGEN_BASEDIR}/{PREDEF_GRID_NAME} - - where - - DOMAIN_PREGEN_BASEDIR = \"{DOMAIN_PREGEN_BASEDIR}\" - PREDEF_GRID_NAME = \"{PREDEF_GRID_NAME}\" - - Thus, the MAKE_OROG_TN task must not be run (i.e. RUN_TASK_MAKE_OROG must - be set to \"FALSE\"), and the directory in which to look for the orography - files (i.e. OROG_DIR) must be set to the one above. Current values for - these quantities are: - - RUN_TASK_MAKE_OROG = \"{RUN_TASK_MAKE_OROG}\" - OROG_DIR = \"{OROG_DIR}\" - - Resetting RUN_TASK_MAKE_OROG to \"FALSE\" and OROG_DIR to the one above. - Reset values are: - ''' - - RUN_TASK_MAKE_OROG=False - OROG_DIR=nco_fix_dir - - msg+=f''' - RUN_TASK_MAKE_OROG = \"{RUN_TASK_MAKE_OROG}\" - OROG_DIR = \"{OROG_DIR}\" - ''' - - print_info_msg(msg) - - - if RUN_TASK_MAKE_SFC_CLIMO or \ - ( not RUN_TASK_MAKE_SFC_CLIMO and \ - SFC_CLIMO_DIR != nco_fix_dir ): - - msg=f''' - When RUN_ENVIR is set to \"nco\", the workflow assumes that pregenerated - surface climatology files already exist in the directory - - {DOMAIN_PREGEN_BASEDIR}/{PREDEF_GRID_NAME} - - where - - DOMAIN_PREGEN_BASEDIR = \"{DOMAIN_PREGEN_BASEDIR}\" - PREDEF_GRID_NAME = \"{PREDEF_GRID_NAME}\" - - Thus, the MAKE_SFC_CLIMO_TN task must not be run (i.e. RUN_TASK_MAKE_SFC_CLIMO - must be set to \"FALSE\"), and the directory in which to look for the - surface climatology files (i.e. SFC_CLIMO_DIR) must be set to the one - above. Current values for these quantities are: - - RUN_TASK_MAKE_SFC_CLIMO = \"{RUN_TASK_MAKE_SFC_CLIMO}\" - SFC_CLIMO_DIR = \"{SFC_CLIMO_DIR}\" - - Resetting RUN_TASK_MAKE_SFC_CLIMO to \"FALSE\" and SFC_CLIMO_DIR to the - one above. Reset values are: - ''' - - RUN_TASK_MAKE_SFC_CLIMO=False - SFC_CLIMO_DIR=nco_fix_dir - - msg+=f''' - RUN_TASK_MAKE_SFC_CLIMO = \"{RUN_TASK_MAKE_SFC_CLIMO}\" - SFC_CLIMO_DIR = \"{SFC_CLIMO_DIR}\" - ''' - - print_info_msg(msg) - - if RUN_TASK_VX_GRIDSTAT: - - msg=f''' - When RUN_ENVIR is set to \"nco\", it is assumed that the verification - will not be run. - RUN_TASK_VX_GRIDSTAT = \"{RUN_TASK_VX_GRIDSTAT}\" - Resetting RUN_TASK_VX_GRIDSTAT to \"FALSE\" - Reset value is:''' - - RUN_TASK_VX_GRIDSTAT=False - - msg+=f''' - RUN_TASK_VX_GRIDSTAT = \"{RUN_TASK_VX_GRIDSTAT}\" - ''' - - print_info_msg(msg) - - if RUN_TASK_VX_POINTSTAT: - - msg=f''' - When RUN_ENVIR is set to \"nco\", it is assumed that the verification - will not be run. - RUN_TASK_VX_POINTSTAT = \"{RUN_TASK_VX_POINTSTAT}\" - Resetting RUN_TASK_VX_POINTSTAT to \"FALSE\" - Reset value is:''' - - RUN_TASK_VX_POINTSTAT=False - - msg=f''' - RUN_TASK_VX_POINTSTAT = \"{RUN_TASK_VX_POINTSTAT}\" - ''' - - print_info_msg(msg) - - if RUN_TASK_VX_ENSGRID: - - msg=f''' - When RUN_ENVIR is set to \"nco\", it is assumed that the verification - will not be run. - RUN_TASK_VX_ENSGRID = \"{RUN_TASK_VX_ENSGRID}\" - Resetting RUN_TASK_VX_ENSGRID to \"FALSE\" - Reset value is:''' - - RUN_TASK_VX_ENSGRID=False - - msg+=f''' - RUN_TASK_VX_ENSGRID = \"{RUN_TASK_VX_ENSGRID}\" - ''' - - print_info_msg(msg) - - # - #----------------------------------------------------------------------- + + nco_fix_dir = os.path.join(DOMAIN_PREGEN_BASEDIR, PREDEF_GRID_NAME) + if not os.path.exists(nco_fix_dir): + print_err_msg_exit( + f''' + The directory (nco_fix_dir) that should contain the pregenerated grid, + orography, and surface climatology files does not exist: + nco_fix_dir = \"{nco_fix_dir}\"''' + ) + + if RUN_TASK_MAKE_GRID or (not RUN_TASK_MAKE_GRID and GRID_DIR != nco_fix_dir): + + msg = f""" + When RUN_ENVIR is set to \"nco\", the workflow assumes that pregenerated + grid files already exist in the directory + + {DOMAIN_PREGEN_BASEDIR}/{PREDEF_GRID_NAME} + + where + + DOMAIN_PREGEN_BASEDIR = \"{DOMAIN_PREGEN_BASEDIR}\" + PREDEF_GRID_NAME = \"{PREDEF_GRID_NAME}\" + + Thus, the MAKE_GRID_TN task must not be run (i.e. RUN_TASK_MAKE_GRID must + be set to \"FALSE\"), and the directory in which to look for the grid + files (i.e. GRID_DIR) must be set to the one above. Current values for + these quantities are: + + RUN_TASK_MAKE_GRID = \"{RUN_TASK_MAKE_GRID}\" + GRID_DIR = \"{GRID_DIR}\" + + Resetting RUN_TASK_MAKE_GRID to \"FALSE\" and GRID_DIR to the one above. + Reset values are: + """ + + RUN_TASK_MAKE_GRID = False + GRID_DIR = nco_fix_dir + + msg += f""" + RUN_TASK_MAKE_GRID = \"{RUN_TASK_MAKE_GRID}\" + GRID_DIR = \"{GRID_DIR}\" + """ + + print_info_msg(msg) + + if RUN_TASK_MAKE_OROG or (not RUN_TASK_MAKE_OROG and OROG_DIR != nco_fix_dir): + + msg = f""" + When RUN_ENVIR is set to \"nco\", the workflow assumes that pregenerated + orography files already exist in the directory + {DOMAIN_PREGEN_BASEDIR}/{PREDEF_GRID_NAME} + + where + + DOMAIN_PREGEN_BASEDIR = \"{DOMAIN_PREGEN_BASEDIR}\" + PREDEF_GRID_NAME = \"{PREDEF_GRID_NAME}\" + + Thus, the MAKE_OROG_TN task must not be run (i.e. RUN_TASK_MAKE_OROG must + be set to \"FALSE\"), and the directory in which to look for the orography + files (i.e. OROG_DIR) must be set to the one above. Current values for + these quantities are: + + RUN_TASK_MAKE_OROG = \"{RUN_TASK_MAKE_OROG}\" + OROG_DIR = \"{OROG_DIR}\" + + Resetting RUN_TASK_MAKE_OROG to \"FALSE\" and OROG_DIR to the one above. + Reset values are: + """ + + RUN_TASK_MAKE_OROG = False + OROG_DIR = nco_fix_dir + + msg += f""" + RUN_TASK_MAKE_OROG = \"{RUN_TASK_MAKE_OROG}\" + OROG_DIR = \"{OROG_DIR}\" + """ + + print_info_msg(msg) + + if RUN_TASK_MAKE_SFC_CLIMO or ( + not RUN_TASK_MAKE_SFC_CLIMO and SFC_CLIMO_DIR != nco_fix_dir + ): + + msg = f""" + When RUN_ENVIR is set to \"nco\", the workflow assumes that pregenerated + surface climatology files already exist in the directory + + {DOMAIN_PREGEN_BASEDIR}/{PREDEF_GRID_NAME} + + where + + DOMAIN_PREGEN_BASEDIR = \"{DOMAIN_PREGEN_BASEDIR}\" + PREDEF_GRID_NAME = \"{PREDEF_GRID_NAME}\" + + Thus, the MAKE_SFC_CLIMO_TN task must not be run (i.e. RUN_TASK_MAKE_SFC_CLIMO + must be set to \"FALSE\"), and the directory in which to look for the + surface climatology files (i.e. SFC_CLIMO_DIR) must be set to the one + above. Current values for these quantities are: + + RUN_TASK_MAKE_SFC_CLIMO = \"{RUN_TASK_MAKE_SFC_CLIMO}\" + SFC_CLIMO_DIR = \"{SFC_CLIMO_DIR}\" + + Resetting RUN_TASK_MAKE_SFC_CLIMO to \"FALSE\" and SFC_CLIMO_DIR to the + one above. Reset values are: + """ + + RUN_TASK_MAKE_SFC_CLIMO = False + SFC_CLIMO_DIR = nco_fix_dir + + msg += f""" + RUN_TASK_MAKE_SFC_CLIMO = \"{RUN_TASK_MAKE_SFC_CLIMO}\" + SFC_CLIMO_DIR = \"{SFC_CLIMO_DIR}\" + """ + + print_info_msg(msg) + + if RUN_TASK_VX_GRIDSTAT: + + msg = f""" + When RUN_ENVIR is set to \"nco\", it is assumed that the verification + will not be run. + RUN_TASK_VX_GRIDSTAT = \"{RUN_TASK_VX_GRIDSTAT}\" + Resetting RUN_TASK_VX_GRIDSTAT to \"FALSE\" + Reset value is:""" + + RUN_TASK_VX_GRIDSTAT = False + + msg += f""" + RUN_TASK_VX_GRIDSTAT = \"{RUN_TASK_VX_GRIDSTAT}\" + """ + + print_info_msg(msg) + + if RUN_TASK_VX_POINTSTAT: + + msg = f""" + When RUN_ENVIR is set to \"nco\", it is assumed that the verification + will not be run. + RUN_TASK_VX_POINTSTAT = \"{RUN_TASK_VX_POINTSTAT}\" + Resetting RUN_TASK_VX_POINTSTAT to \"FALSE\" + Reset value is:""" + + RUN_TASK_VX_POINTSTAT = False + + msg = f""" + RUN_TASK_VX_POINTSTAT = \"{RUN_TASK_VX_POINTSTAT}\" + """ + + print_info_msg(msg) + + if RUN_TASK_VX_ENSGRID: + + msg = f""" + When RUN_ENVIR is set to \"nco\", it is assumed that the verification + will not be run. + RUN_TASK_VX_ENSGRID = \"{RUN_TASK_VX_ENSGRID}\" + Resetting RUN_TASK_VX_ENSGRID to \"FALSE\" + Reset value is:""" + + RUN_TASK_VX_ENSGRID = False + + msg += f""" + RUN_TASK_VX_ENSGRID = \"{RUN_TASK_VX_ENSGRID}\" + """ + + print_info_msg(msg) + + # + # ----------------------------------------------------------------------- # # Now consider community mode. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # else: - # - # If RUN_TASK_MAKE_GRID is set to False, the workflow will look for - # the pregenerated grid files in GRID_DIR. In this case, make sure that - # GRID_DIR exists. Otherwise, set it to a predefined location under the - # experiment directory (EXPTDIR). - # - if not RUN_TASK_MAKE_GRID: - if not os.path.exists(GRID_DIR): - print_err_msg_exit(f''' - The directory (GRID_DIR) that should contain the pregenerated grid files - does not exist: - GRID_DIR = \"{GRID_DIR}\"''') - else: - GRID_DIR=os.path.join(EXPTDIR,"grid") - # - # If RUN_TASK_MAKE_OROG is set to False, the workflow will look for - # the pregenerated orography files in OROG_DIR. In this case, make sure - # that OROG_DIR exists. Otherwise, set it to a predefined location under - # the experiment directory (EXPTDIR). - # - if not RUN_TASK_MAKE_OROG: - if not os.path.exists(OROG_DIR): - print_err_msg_exit(f''' - The directory (OROG_DIR) that should contain the pregenerated orography - files does not exist: - OROG_DIR = \"{OROG_DIR}\"''') - else: - OROG_DIR=os.path.join(EXPTDIR,"orog") - # - # If RUN_TASK_MAKE_SFC_CLIMO is set to False, the workflow will look - # for the pregenerated surface climatology files in SFC_CLIMO_DIR. In - # this case, make sure that SFC_CLIMO_DIR exists. Otherwise, set it to - # a predefined location under the experiment directory (EXPTDIR). - # - if not RUN_TASK_MAKE_SFC_CLIMO: - if not os.path.exists(SFC_CLIMO_DIR): - print_err_msg_exit(f''' - The directory (SFC_CLIMO_DIR) that should contain the pregenerated surface - climatology files does not exist: - SFC_CLIMO_DIR = \"{SFC_CLIMO_DIR}\"''') - else: - SFC_CLIMO_DIR=os.path.join(EXPTDIR,"sfc_climo") - - #----------------------------------------------------------------------- + # + # If RUN_TASK_MAKE_GRID is set to False, the workflow will look for + # the pregenerated grid files in GRID_DIR. In this case, make sure that + # GRID_DIR exists. Otherwise, set it to a predefined location under the + # experiment directory (EXPTDIR). + # + if not RUN_TASK_MAKE_GRID: + if not os.path.exists(GRID_DIR): + print_err_msg_exit( + f''' + The directory (GRID_DIR) that should contain the pregenerated grid files + does not exist: + GRID_DIR = \"{GRID_DIR}\"''' + ) + else: + GRID_DIR = os.path.join(EXPTDIR, "grid") + # + # If RUN_TASK_MAKE_OROG is set to False, the workflow will look for + # the pregenerated orography files in OROG_DIR. In this case, make sure + # that OROG_DIR exists. Otherwise, set it to a predefined location under + # the experiment directory (EXPTDIR). + # + if not RUN_TASK_MAKE_OROG: + if not os.path.exists(OROG_DIR): + print_err_msg_exit( + f''' + The directory (OROG_DIR) that should contain the pregenerated orography + files does not exist: + OROG_DIR = \"{OROG_DIR}\"''' + ) + else: + OROG_DIR = os.path.join(EXPTDIR, "orog") + # + # If RUN_TASK_MAKE_SFC_CLIMO is set to False, the workflow will look + # for the pregenerated surface climatology files in SFC_CLIMO_DIR. In + # this case, make sure that SFC_CLIMO_DIR exists. Otherwise, set it to + # a predefined location under the experiment directory (EXPTDIR). + # + if not RUN_TASK_MAKE_SFC_CLIMO: + if not os.path.exists(SFC_CLIMO_DIR): + print_err_msg_exit( + f''' + The directory (SFC_CLIMO_DIR) that should contain the pregenerated surface + climatology files does not exist: + SFC_CLIMO_DIR = \"{SFC_CLIMO_DIR}\"''' + ) + else: + SFC_CLIMO_DIR = os.path.join(EXPTDIR, "sfc_climo") + + # ----------------------------------------------------------------------- # # Set cycle-independent parameters associated with the external models # from which we will obtain the ICs and LBCs. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # export env vars before calling another module + # export env vars before calling another module export_vars() set_extrn_mdl_params() @@ -1418,217 +1544,220 @@ def setup(): IMPORTS = ["EXTRN_MDL_LBCS_OFFSET_HRS"] import_vars(env_vars=IMPORTS) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # Set parameters according to the type of horizontal grid generation - # method specified. First consider GFDL's global-parent-grid based + # Set parameters according to the type of horizontal grid generation + # method specified. First consider GFDL's global-parent-grid based # method. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - global LON_CTR,LAT_CTR,NX,NY,NHW,STRETCH_FAC,\ - ISTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG,\ - IEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG,\ - JSTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG,\ - JEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG - global PAZI,DEL_ANGLE_X_SG,DEL_ANGLE_Y_SG,\ - NEG_NX_OF_DOM_WITH_WIDE_HALO,\ - NEG_NY_OF_DOM_WITH_WIDE_HALO + global LON_CTR, LAT_CTR, NX, NY, NHW, STRETCH_FAC if GRID_GEN_METHOD == "GFDLgrid": - - (\ - LON_CTR,LAT_CTR,NX,NY,NHW,STRETCH_FAC, - ISTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG, - IEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG, - JSTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG, - JEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG \ - ) = \ - set_gridparams_GFDLgrid( \ - lon_of_t6_ctr=GFDLgrid_LON_T6_CTR, \ - lat_of_t6_ctr=GFDLgrid_LAT_T6_CTR, \ - res_of_t6g=GFDLgrid_NUM_CELLS, \ - stretch_factor=GFDLgrid_STRETCH_FAC, \ - refine_ratio_t6g_to_t7g=GFDLgrid_REFINE_RATIO, \ - istart_of_t7_on_t6g=GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G, \ - iend_of_t7_on_t6g=GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G, \ - jstart_of_t7_on_t6g=GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G, \ - jend_of_t7_on_t6g=GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G) - # - #----------------------------------------------------------------------- + grid_params = set_gridparams_GFDLgrid( + lon_of_t6_ctr=GFDLgrid_LON_T6_CTR, + lat_of_t6_ctr=GFDLgrid_LAT_T6_CTR, + res_of_t6g=GFDLgrid_NUM_CELLS, + stretch_factor=GFDLgrid_STRETCH_FAC, + refine_ratio_t6g_to_t7g=GFDLgrid_REFINE_RATIO, + istart_of_t7_on_t6g=GFDLgrid_ISTART_OF_RGNL_DOM_ON_T6G, + iend_of_t7_on_t6g=GFDLgrid_IEND_OF_RGNL_DOM_ON_T6G, + jstart_of_t7_on_t6g=GFDLgrid_JSTART_OF_RGNL_DOM_ON_T6G, + jend_of_t7_on_t6g=GFDLgrid_JEND_OF_RGNL_DOM_ON_T6G, + ) + # + # ----------------------------------------------------------------------- # # Now consider Jim Purser's map projection/grid generation method. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # elif GRID_GEN_METHOD == "ESGgrid": - - (\ - LON_CTR,LAT_CTR,NX,NY,PAZI, - NHW,STRETCH_FAC,DEL_ANGLE_X_SG,DEL_ANGLE_Y_SG, - NEG_NX_OF_DOM_WITH_WIDE_HALO, - NEG_NY_OF_DOM_WITH_WIDE_HALO \ - ) = \ - set_gridparams_ESGgrid( \ - lon_ctr=ESGgrid_LON_CTR, \ - lat_ctr=ESGgrid_LAT_CTR, \ - nx=ESGgrid_NX, \ - ny=ESGgrid_NY, \ - pazi=ESGgrid_PAZI, \ - halo_width=ESGgrid_WIDE_HALO_WIDTH, \ - delx=ESGgrid_DELX, \ - dely=ESGgrid_DELY) - - # - #----------------------------------------------------------------------- - # - # Create a new experiment directory. Note that at this point we are + grid_params = set_gridparams_ESGgrid( + lon_ctr=ESGgrid_LON_CTR, + lat_ctr=ESGgrid_LAT_CTR, + nx=ESGgrid_NX, + ny=ESGgrid_NY, + pazi=ESGgrid_PAZI, + halo_width=ESGgrid_WIDE_HALO_WIDTH, + delx=ESGgrid_DELX, + dely=ESGgrid_DELY, + ) + # + # ----------------------------------------------------------------------- + # + # Otherwise + # + # ----------------------------------------------------------------------- + # + else: + grid_params = { + "LON_CTR": LON_CTR, + "LAT_CTR": LAT_CTR, + "NX": NX, + "NY": NY, + "NHW": NHW, + "STRETCH_FAC": STRETCH_FAC, + } + + + # Extract the basic grid params from the dictionary + (LON_CTR, LAT_CTR, NX, NY, NHW, STRETCH_FAC) = ( + grid_params[k] for k in ["LON_CTR", "LAT_CTR", "NX", "NY", "NHW", "STRETCH_FAC"] + ) + + # + # ----------------------------------------------------------------------- + # + # Create a new experiment directory. Note that at this point we are # guaranteed that there is no preexisting experiment directory. For # platforms with no workflow manager, we need to create LOGDIR as well, # since it won't be created later at runtime. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # mkdir_vrfy(f' -p "{EXPTDIR}"') mkdir_vrfy(f' -p "{LOGDIR}"') # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If not running the MAKE_GRID_TN, MAKE_OROG_TN, and/or MAKE_SFC_CLIMO # tasks, create symlinks under the FIXLAM directory to pregenerated grid, - # orography, and surface climatology files. In the process, also set + # orography, and surface climatology files. In the process, also set # RES_IN_FIXLAM_FILENAMES, which is the resolution of the grid (in units # of number of grid points on an equivalent global uniform cubed-sphere # grid) used in the names of the fixed files in the FIXLAM directory. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # mkdir_vrfy(f' -p "{FIXLAM}"') - RES_IN_FIXLAM_FILENAMES="" + RES_IN_FIXLAM_FILENAMES = "" # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If the grid file generation task in the workflow is going to be skipped # (because pregenerated files are available), create links in the FIXLAM # directory to the pregenerated grid files. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # export env vars export_vars() # link fix files - res_in_grid_fns="" + res_in_grid_fns = "" if not RUN_TASK_MAKE_GRID: - - res_in_grid_fns = link_fix( \ - verbose=VERBOSE, \ - file_group="grid") - RES_IN_FIXLAM_FILENAMES=res_in_grid_fns + res_in_grid_fns = link_fix(verbose=VERBOSE, file_group="grid") + + RES_IN_FIXLAM_FILENAMES = res_in_grid_fns # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # If the orography file generation task in the workflow is going to be # skipped (because pregenerated files are available), create links in # the FIXLAM directory to the pregenerated orography files. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - res_in_orog_fns="" + res_in_orog_fns = "" if not RUN_TASK_MAKE_OROG: - - res_in_orog_fns = link_fix( \ - verbose=VERBOSE, \ - file_group="orog") - - if not RES_IN_FIXLAM_FILENAMES and \ - ( res_in_orog_fns != RES_IN_FIXLAM_FILENAMES): - print_err_msg_exit(f''' - The resolution extracted from the orography file names (res_in_orog_fns) - does not match the resolution in other groups of files already consi- - dered (RES_IN_FIXLAM_FILENAMES): - res_in_orog_fns = {res_in_orog_fns} - RES_IN_FIXLAM_FILENAMES = {RES_IN_FIXLAM_FILENAMES}''') - else: - RES_IN_FIXLAM_FILENAMES=res_in_orog_fns - # - #----------------------------------------------------------------------- + + res_in_orog_fns = link_fix(verbose=VERBOSE, file_group="orog") + + if not RES_IN_FIXLAM_FILENAMES and (res_in_orog_fns != RES_IN_FIXLAM_FILENAMES): + print_err_msg_exit( + f""" + The resolution extracted from the orography file names (res_in_orog_fns) + does not match the resolution in other groups of files already consi- + dered (RES_IN_FIXLAM_FILENAMES): + res_in_orog_fns = {res_in_orog_fns} + RES_IN_FIXLAM_FILENAMES = {RES_IN_FIXLAM_FILENAMES}""" + ) + else: + RES_IN_FIXLAM_FILENAMES = res_in_orog_fns + # + # ----------------------------------------------------------------------- # # If the surface climatology file generation task in the workflow is # going to be skipped (because pregenerated files are available), create # links in the FIXLAM directory to the pregenerated surface climatology # files. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - res_in_sfc_climo_fns="" + res_in_sfc_climo_fns = "" if not RUN_TASK_MAKE_SFC_CLIMO: - - res_in_sfc_climo_fns = link_fix( \ - verbose=VERBOSE, \ - file_group="sfc_climo") - - if RES_IN_FIXLAM_FILENAMES and \ - res_in_sfc_climo_fns != RES_IN_FIXLAM_FILENAMES: - print_err_msg_exit(f''' - The resolution extracted from the surface climatology file names (res_- - in_sfc_climo_fns) does not match the resolution in other groups of files - already considered (RES_IN_FIXLAM_FILENAMES): - res_in_sfc_climo_fns = {res_in_sfc_climo_fns} - RES_IN_FIXLAM_FILENAMES = {RES_IN_FIXLAM_FILENAMES}''') - else: - RES_IN_FIXLAM_FILENAMES=res_in_sfc_climo_fns - # - #----------------------------------------------------------------------- - # - # The variable CRES is needed in constructing various file names. If - # not running the make_grid task, we can set it here. Otherwise, it + + res_in_sfc_climo_fns = link_fix(verbose=VERBOSE, file_group="sfc_climo") + + if RES_IN_FIXLAM_FILENAMES and res_in_sfc_climo_fns != RES_IN_FIXLAM_FILENAMES: + print_err_msg_exit( + f""" + The resolution extracted from the surface climatology file names (res_- + in_sfc_climo_fns) does not match the resolution in other groups of files + already considered (RES_IN_FIXLAM_FILENAMES): + res_in_sfc_climo_fns = {res_in_sfc_climo_fns} + RES_IN_FIXLAM_FILENAMES = {RES_IN_FIXLAM_FILENAMES}""" + ) + else: + RES_IN_FIXLAM_FILENAMES = res_in_sfc_climo_fns + # + # ----------------------------------------------------------------------- + # + # The variable CRES is needed in constructing various file names. If + # not running the make_grid task, we can set it here. Otherwise, it # will get set to a valid value by that task. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global CRES - CRES="" + CRES = "" if not RUN_TASK_MAKE_GRID: - CRES=f"C{RES_IN_FIXLAM_FILENAMES}" + CRES = f"C{RES_IN_FIXLAM_FILENAMES}" # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Make sure that WRITE_DOPOST is set to a valid value. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global RUN_TASK_RUN_POST if WRITE_DOPOST: - # Turn off run_post - RUN_TASK_RUN_POST=False - - # Check if SUB_HOURLY_POST is on - if SUB_HOURLY_POST: - print_err_msg_exit(f''' - SUB_HOURLY_POST is NOT available with Inline Post yet.''') + # Turn off run_post + RUN_TASK_RUN_POST = False + + # Check if SUB_HOURLY_POST is on + if SUB_HOURLY_POST: + print_err_msg_exit( + f""" + SUB_HOURLY_POST is NOT available with Inline Post yet.""" + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Calculate PE_MEMBER01. This is the number of MPI tasks used for the # forecast, including those for the write component if QUILTING is set # to True. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global PE_MEMBER01 - PE_MEMBER01=LAYOUT_X*LAYOUT_Y + PE_MEMBER01 = LAYOUT_X * LAYOUT_Y if QUILTING: - PE_MEMBER01 = PE_MEMBER01 + WRTCMP_write_groups*WRTCMP_write_tasks_per_group - - print_info_msg(f''' + PE_MEMBER01 = PE_MEMBER01 + WRTCMP_write_groups * WRTCMP_write_tasks_per_group + + print_info_msg( + f""" The number of MPI tasks for the forecast (including those for the write component if it is being used) are: - PE_MEMBER01 = {PE_MEMBER01}''', verbose=VERBOSE) + PE_MEMBER01 = {PE_MEMBER01}""", + verbose=VERBOSE, + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Calculate the number of nodes (NNODES_RUN_FCST) to request from the job # scheduler for the forecast task (RUN_FCST_TN). This is just PE_MEMBER01 @@ -1646,59 +1775,60 @@ def setup(): # # NNODES_RUN_FCST = (PE_MEMBER01 + PPN_RUN_FCST - 1)/PPN_RUN_FCST # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global NNODES_RUN_FCST - NNODES_RUN_FCST= (PE_MEMBER01 + PPN_RUN_FCST - 1)//PPN_RUN_FCST - + NNODES_RUN_FCST = (PE_MEMBER01 + PPN_RUN_FCST - 1) // PPN_RUN_FCST + # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Call the function that checks whether the RUC land surface model (LSM) - # is being called by the physics suite and sets the workflow variable + # is being called by the physics suite and sets the workflow variable # SDF_USES_RUC_LSM to True or False accordingly. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # global SDF_USES_RUC_LSM - SDF_USES_RUC_LSM = check_ruc_lsm( \ - ccpp_phys_suite_fp=CCPP_PHYS_SUITE_IN_CCPP_FP) + SDF_USES_RUC_LSM = check_ruc_lsm(ccpp_phys_suite_fp=CCPP_PHYS_SUITE_IN_CCPP_FP) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Set the name of the file containing aerosol climatology data that, if - # necessary, can be used to generate approximate versions of the aerosol - # fields needed by Thompson microphysics. This file will be used to - # generate such approximate aerosol fields in the ICs and LBCs if Thompson + # necessary, can be used to generate approximate versions of the aerosol + # fields needed by Thompson microphysics. This file will be used to + # generate such approximate aerosol fields in the ICs and LBCs if Thompson # MP is included in the physics suite and if the exteranl model for ICs # or LBCs does not already provide these fields. Also, set the full path # to this file. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - THOMPSON_MP_CLIMO_FN="Thompson_MP_MONTHLY_CLIMO.nc" - THOMPSON_MP_CLIMO_FP=os.path.join(FIXam,THOMPSON_MP_CLIMO_FN) + THOMPSON_MP_CLIMO_FN = "Thompson_MP_MONTHLY_CLIMO.nc" + THOMPSON_MP_CLIMO_FP = os.path.join(FIXam, THOMPSON_MP_CLIMO_FN) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Call the function that, if the Thompson microphysics parameterization # is being called by the physics suite, modifies certain workflow arrays # to ensure that fixed files needed by this parameterization are copied # to the FIXam directory and appropriate symlinks to them are created in # the run directories. This function also sets the workflow variable - # SDF_USES_THOMPSON_MP that indicates whether Thompson MP is called by + # SDF_USES_THOMPSON_MP that indicates whether Thompson MP is called by # the physics suite. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - SDF_USES_THOMPSON_MP = set_thompson_mp_fix_files( \ - ccpp_phys_suite_fp=CCPP_PHYS_SUITE_IN_CCPP_FP, \ - thompson_mp_climo_fn=THOMPSON_MP_CLIMO_FN) + SDF_USES_THOMPSON_MP = set_thompson_mp_fix_files( + ccpp_phys_suite_fp=CCPP_PHYS_SUITE_IN_CCPP_FP, + thompson_mp_climo_fn=THOMPSON_MP_CLIMO_FN, + ) - IMPORTS = [ "CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING", "FIXgsm_FILES_TO_COPY_TO_FIXam" ] + IMPORTS = ["CYCLEDIR_LINKS_TO_FIXam_FILES_MAPPING", "FIXgsm_FILES_TO_COPY_TO_FIXam"] import_vars(env_vars=IMPORTS) + # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Generate the shell script that will appear in the experiment directory # (EXPTDIR) and will contain definitions of variables needed by the va- @@ -1712,8 +1842,8 @@ def setup(): # ming it to the name specified by GLOBAL_VAR_DEFNS_FN. # # 2) Resetting the default variable values in this file to their current - # values. This is necessary because these variables may have been - # reset by the user-specified configuration file (if one exists in + # values. This is necessary because these variables may have been + # reset by the user-specified configuration file (if one exists in # USHDIR) and/or by this setup script, e.g. because predef_domain is # set to a valid non-empty value. # @@ -1725,473 +1855,367 @@ def setup(): # First, set the full path to the variable definitions file and copy the # default configuration script into it. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # update dictionary with globals() values - update_dict = {k: globals()[k] for k in cfg_d.keys() if k in globals() } - cfg_d.update(update_dict) - - # write the updated default dictionary + # global variable definition file path global GLOBAL_VAR_DEFNS_FP - GLOBAL_VAR_DEFNS_FP=os.path.join(EXPTDIR,GLOBAL_VAR_DEFNS_FN) - all_lines=cfg_to_shell_str(cfg_d) + GLOBAL_VAR_DEFNS_FP = os.path.join(EXPTDIR, GLOBAL_VAR_DEFNS_FN) - with open(GLOBAL_VAR_DEFNS_FP,'w') as f: - msg = f""" # - # - #----------------------------------------------------------------------- - #----------------------------------------------------------------------- - # Section 1: - # This section contains definitions of the various constants defined in - # the file {CONSTANTS_FN}. - #----------------------------------------------------------------------- - #----------------------------------------------------------------------- - # - """ - f.write(dedent(msg)) - f.write(const_lines) - - msg = f""" # - #----------------------------------------------------------------------- - #----------------------------------------------------------------------- - # Section 2: - # This section contains (most of) the primary experiment variables, i.e. - # those variables that are defined in the default configuration file - # (config_defaults.sh) and that can be reset via the user-specified - # experiment configuration file (config.sh). - #----------------------------------------------------------------------- - #----------------------------------------------------------------------- - # - """ - f.write(dedent(msg)) - f.write(all_lines) - - # print info message - msg=dedent(f''' - Before updating default values of experiment variables to user-specified - values, the variable \"line_list\" contains: + # update dictionary with globals() values + update_dict(globals(), cfg_d) - ''') + # constants section + cfg_d["constants"] = cfg_c - msg +=dedent(f''' - {all_lines}''') + # grid params + cfg_d["grid_params"] = grid_params - print_info_msg(msg,verbose=DEBUG) # - # print info message - # - print_info_msg(f''' - Generating the global experiment variable definitions file specified by - GLOBAL_VAR_DEFNS_FN: - GLOBAL_VAR_DEFNS_FN = \"{GLOBAL_VAR_DEFNS_FN}\" - Full path to this file is: - GLOBAL_VAR_DEFNS_FP = \"{GLOBAL_VAR_DEFNS_FP}\" - For more detailed information, set DEBUG to \"TRUE\" in the experiment - configuration file (\"{EXPT_CONFIG_FN}\").''') - - # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Append additional variable definitions (and comments) to the variable # definitions file. These variables have been set above using the vari- # ables in the default and local configuration scripts. These variables # are needed by various tasks/scripts in the workflow. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - msg = f""" - # - #----------------------------------------------------------------------- - #----------------------------------------------------------------------- - # Section 2: - # This section defines variables that have been derived from the primary - # set of experiment variables above (we refer to these as \"derived\" or - # \"secondary\" variables). - #----------------------------------------------------------------------- - #----------------------------------------------------------------------- - # - """ - with open(GLOBAL_VAR_DEFNS_FP,'a') as f: - f.write(dedent(msg)) - settings = { # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # Full path to workflow (re)launch script, its log file, and the line - # that gets added to the cron table to launch this script if the flag + # Full path to workflow (re)launch script, its log file, and the line + # that gets added to the cron table to launch this script if the flag # USE_CRON_TO_RELAUNCH is set to \"TRUE\". # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - 'WFLOW_LAUNCH_SCRIPT_FP': WFLOW_LAUNCH_SCRIPT_FP, - 'WFLOW_LAUNCH_LOG_FP': WFLOW_LAUNCH_LOG_FP, - 'CRONTAB_LINE': CRONTAB_LINE, + "WFLOW_LAUNCH_SCRIPT_FP": WFLOW_LAUNCH_SCRIPT_FP, + "WFLOW_LAUNCH_LOG_FP": WFLOW_LAUNCH_LOG_FP, + "CRONTAB_LINE": CRONTAB_LINE, # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Directories. # - #----------------------------------------------------------------------- - # - 'SR_WX_APP_TOP_DIR': SR_WX_APP_TOP_DIR, - 'HOMErrfs': HOMErrfs, - 'USHDIR': USHDIR, - 'SCRIPTSDIR': SCRIPTSDIR, - 'JOBSDIR': JOBSDIR, - 'SORCDIR': SORCDIR, - 'SRC_DIR': SRC_DIR, - 'PARMDIR': PARMDIR, - 'MODULES_DIR': MODULES_DIR, - 'EXECDIR': EXECDIR, - 'FIXam': FIXam, - 'FIXclim': FIXclim, - 'FIXLAM': FIXLAM, - 'FIXgsm': FIXgsm, - 'FIXaer': FIXaer, - 'FIXlut': FIXlut, - 'COMROOT': COMROOT, - 'COMOUT_BASEDIR': COMOUT_BASEDIR, - 'TEMPLATE_DIR': TEMPLATE_DIR, - 'VX_CONFIG_DIR': VX_CONFIG_DIR, - 'METPLUS_CONF': METPLUS_CONF, - 'MET_CONFIG': MET_CONFIG, - 'UFS_WTHR_MDL_DIR': UFS_WTHR_MDL_DIR, - 'UFS_UTILS_DIR': UFS_UTILS_DIR, - 'SFC_CLIMO_INPUT_DIR': SFC_CLIMO_INPUT_DIR, - 'TOPO_DIR': TOPO_DIR, - 'UPP_DIR': UPP_DIR, - - 'EXPTDIR': EXPTDIR, - 'LOGDIR': LOGDIR, - 'CYCLE_BASEDIR': CYCLE_BASEDIR, - 'GRID_DIR': GRID_DIR, - 'OROG_DIR': OROG_DIR, - 'SFC_CLIMO_DIR': SFC_CLIMO_DIR, - - 'NDIGITS_ENSMEM_NAMES': NDIGITS_ENSMEM_NAMES, - 'ENSMEM_NAMES': ENSMEM_NAMES, - 'FV3_NML_ENSMEM_FPS': FV3_NML_ENSMEM_FPS, - # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- + # + "SR_WX_APP_TOP_DIR": SR_WX_APP_TOP_DIR, + "HOMErrfs": HOMErrfs, + "USHDIR": USHDIR, + "SCRIPTSDIR": SCRIPTSDIR, + "JOBSDIR": JOBSDIR, + "SORCDIR": SORCDIR, + "SRC_DIR": SRC_DIR, + "PARMDIR": PARMDIR, + "MODULES_DIR": MODULES_DIR, + "EXECDIR": EXECDIR, + "FIXam": FIXam, + "FIXclim": FIXclim, + "FIXLAM": FIXLAM, + "FIXgsm": FIXgsm, + "FIXaer": FIXaer, + "FIXlut": FIXlut, + "COMROOT": COMROOT, + "COMOUT_BASEDIR": COMOUT_BASEDIR, + "TEMPLATE_DIR": TEMPLATE_DIR, + "VX_CONFIG_DIR": VX_CONFIG_DIR, + "METPLUS_CONF": METPLUS_CONF, + "MET_CONFIG": MET_CONFIG, + "UFS_WTHR_MDL_DIR": UFS_WTHR_MDL_DIR, + "UFS_UTILS_DIR": UFS_UTILS_DIR, + "SFC_CLIMO_INPUT_DIR": SFC_CLIMO_INPUT_DIR, + "TOPO_DIR": TOPO_DIR, + "UPP_DIR": UPP_DIR, + "EXPTDIR": EXPTDIR, + "LOGDIR": LOGDIR, + "CYCLE_BASEDIR": CYCLE_BASEDIR, + "GRID_DIR": GRID_DIR, + "OROG_DIR": OROG_DIR, + "SFC_CLIMO_DIR": SFC_CLIMO_DIR, + "NDIGITS_ENSMEM_NAMES": NDIGITS_ENSMEM_NAMES, + "ENSMEM_NAMES": ENSMEM_NAMES, + "FV3_NML_ENSMEM_FPS": FV3_NML_ENSMEM_FPS, + # + # ----------------------------------------------------------------------- # # Files. # - #----------------------------------------------------------------------- - # - 'GLOBAL_VAR_DEFNS_FP': GLOBAL_VAR_DEFNS_FP, - - 'DATA_TABLE_FN': DATA_TABLE_FN, - 'DIAG_TABLE_FN': DIAG_TABLE_FN, - 'FIELD_TABLE_FN': FIELD_TABLE_FN, - 'MODEL_CONFIG_FN': MODEL_CONFIG_FN, - 'NEMS_CONFIG_FN': NEMS_CONFIG_FN, - - 'DATA_TABLE_TMPL_FN': DATA_TABLE_TMPL_FN, - 'DIAG_TABLE_TMPL_FN': DIAG_TABLE_TMPL_FN, - 'FIELD_TABLE_TMPL_FN': FIELD_TABLE_TMPL_FN, - 'MODEL_CONFIG_TMPL_FN': MODEL_CONFIG_TMPL_FN, - 'NEMS_CONFIG_TMPL_FN': NEMS_CONFIG_TMPL_FN, - - 'DATA_TABLE_TMPL_FP': DATA_TABLE_TMPL_FP, - 'DIAG_TABLE_TMPL_FP': DIAG_TABLE_TMPL_FP, - 'FIELD_TABLE_TMPL_FP': FIELD_TABLE_TMPL_FP, - 'FV3_NML_BASE_SUITE_FP': FV3_NML_BASE_SUITE_FP, - 'FV3_NML_YAML_CONFIG_FP': FV3_NML_YAML_CONFIG_FP, - 'FV3_NML_BASE_ENS_FP': FV3_NML_BASE_ENS_FP, - 'MODEL_CONFIG_TMPL_FP': MODEL_CONFIG_TMPL_FP, - 'NEMS_CONFIG_TMPL_FP': NEMS_CONFIG_TMPL_FP, - - 'CCPP_PHYS_SUITE_FN': CCPP_PHYS_SUITE_FN, - 'CCPP_PHYS_SUITE_IN_CCPP_FP': CCPP_PHYS_SUITE_IN_CCPP_FP, - 'CCPP_PHYS_SUITE_FP': CCPP_PHYS_SUITE_FP, - - 'FIELD_DICT_FN': FIELD_DICT_FN, - 'FIELD_DICT_IN_UWM_FP': FIELD_DICT_IN_UWM_FP, - 'FIELD_DICT_FP': FIELD_DICT_FP, - - 'DATA_TABLE_FP': DATA_TABLE_FP, - 'FIELD_TABLE_FP': FIELD_TABLE_FP, - 'FV3_NML_FN': FV3_NML_FN, # This may not be necessary... - 'FV3_NML_FP': FV3_NML_FP, - 'NEMS_CONFIG_FP': NEMS_CONFIG_FP, - - 'FV3_EXEC_FP': FV3_EXEC_FP, - - 'LOAD_MODULES_RUN_TASK_FP': LOAD_MODULES_RUN_TASK_FP, - - 'THOMPSON_MP_CLIMO_FN': THOMPSON_MP_CLIMO_FN, - 'THOMPSON_MP_CLIMO_FP': THOMPSON_MP_CLIMO_FP, - # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- + # + "GLOBAL_VAR_DEFNS_FP": GLOBAL_VAR_DEFNS_FP, + "DATA_TABLE_FN": DATA_TABLE_FN, + "DIAG_TABLE_FN": DIAG_TABLE_FN, + "FIELD_TABLE_FN": FIELD_TABLE_FN, + "MODEL_CONFIG_FN": MODEL_CONFIG_FN, + "NEMS_CONFIG_FN": NEMS_CONFIG_FN, + "DATA_TABLE_TMPL_FN": DATA_TABLE_TMPL_FN, + "DIAG_TABLE_TMPL_FN": DIAG_TABLE_TMPL_FN, + "FIELD_TABLE_TMPL_FN": FIELD_TABLE_TMPL_FN, + "MODEL_CONFIG_TMPL_FN": MODEL_CONFIG_TMPL_FN, + "NEMS_CONFIG_TMPL_FN": NEMS_CONFIG_TMPL_FN, + "DATA_TABLE_TMPL_FP": DATA_TABLE_TMPL_FP, + "DIAG_TABLE_TMPL_FP": DIAG_TABLE_TMPL_FP, + "FIELD_TABLE_TMPL_FP": FIELD_TABLE_TMPL_FP, + "FV3_NML_BASE_SUITE_FP": FV3_NML_BASE_SUITE_FP, + "FV3_NML_YAML_CONFIG_FP": FV3_NML_YAML_CONFIG_FP, + "FV3_NML_BASE_ENS_FP": FV3_NML_BASE_ENS_FP, + "MODEL_CONFIG_TMPL_FP": MODEL_CONFIG_TMPL_FP, + "NEMS_CONFIG_TMPL_FP": NEMS_CONFIG_TMPL_FP, + "CCPP_PHYS_SUITE_FN": CCPP_PHYS_SUITE_FN, + "CCPP_PHYS_SUITE_IN_CCPP_FP": CCPP_PHYS_SUITE_IN_CCPP_FP, + "CCPP_PHYS_SUITE_FP": CCPP_PHYS_SUITE_FP, + "FIELD_DICT_FN": FIELD_DICT_FN, + "FIELD_DICT_IN_UWM_FP": FIELD_DICT_IN_UWM_FP, + "FIELD_DICT_FP": FIELD_DICT_FP, + "DATA_TABLE_FP": DATA_TABLE_FP, + "FIELD_TABLE_FP": FIELD_TABLE_FP, + "FV3_NML_FN": FV3_NML_FN, # This may not be necessary... + "FV3_NML_FP": FV3_NML_FP, + "NEMS_CONFIG_FP": NEMS_CONFIG_FP, + "FV3_EXEC_FP": FV3_EXEC_FP, + "LOAD_MODULES_RUN_TASK_FP": LOAD_MODULES_RUN_TASK_FP, + "THOMPSON_MP_CLIMO_FN": THOMPSON_MP_CLIMO_FN, + "THOMPSON_MP_CLIMO_FP": THOMPSON_MP_CLIMO_FP, + # + # ----------------------------------------------------------------------- # # Flag for creating relative symlinks (as opposed to absolute ones). # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - 'RELATIVE_LINK_FLAG': RELATIVE_LINK_FLAG, + "RELATIVE_LINK_FLAG": RELATIVE_LINK_FLAG, # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # Parameters that indicate whether or not various parameterizations are + # Parameters that indicate whether or not various parameterizations are # included in and called by the physics suite. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - 'SDF_USES_RUC_LSM': SDF_USES_RUC_LSM, - 'SDF_USES_THOMPSON_MP': SDF_USES_THOMPSON_MP, + "SDF_USES_RUC_LSM": SDF_USES_RUC_LSM, + "SDF_USES_THOMPSON_MP": SDF_USES_THOMPSON_MP, # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Grid configuration parameters needed regardless of grid generation # method used. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - 'GTYPE': GTYPE, - 'TILE_RGNL': TILE_RGNL, - - 'LON_CTR': LON_CTR, - 'LAT_CTR': LAT_CTR, - 'NX': NX, - 'NY': NY, - 'NHW': NHW, - 'STRETCH_FAC': STRETCH_FAC, - - 'RES_IN_FIXLAM_FILENAMES': RES_IN_FIXLAM_FILENAMES, + "GTYPE": GTYPE, + "TILE_RGNL": TILE_RGNL, + "RES_IN_FIXLAM_FILENAMES": RES_IN_FIXLAM_FILENAMES, # # If running the make_grid task, CRES will be set to a null string during # the grid generation step. It will later be set to an actual value after # the make_grid task is complete. # - 'CRES': CRES + "CRES": CRES, } # - #----------------------------------------------------------------------- - # - # Append to the variable definitions file the defintions of grid parame- - # ters that are specific to the grid generation method used. - # - #----------------------------------------------------------------------- - # - if GRID_GEN_METHOD == "GFDLgrid": - # - #----------------------------------------------------------------------- - # - # Grid configuration parameters for a regional grid generated from a - # global parent cubed-sphere grid. This is the method originally - # suggested by GFDL since it allows GFDL's nested grid generator to be - # used to generate a regional grid. However, for large regional domains, - # it results in grids that have an unacceptably large range of cell sizes - # (i.e. ratio of maximum to minimum cell size is not sufficiently close - # to 1). - # - #----------------------------------------------------------------------- - # - settings.update({ - 'ISTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG': ISTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG, - 'IEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG': IEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG, - 'JSTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG': JSTART_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG, - 'JEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG': JEND_OF_RGNL_DOM_WITH_WIDE_HALO_ON_T6SG - }) - elif GRID_GEN_METHOD == "ESGgrid": - # - #----------------------------------------------------------------------- - # - # Grid configuration parameters for a regional grid generated independently - # of a global parent grid. This method was developed by Jim Purser of - # EMC and results in very uniform grids (i.e. ratio of maximum to minimum - # cell size is very close to 1). - # - #----------------------------------------------------------------------- - # - settings.update({ - 'DEL_ANGLE_X_SG': DEL_ANGLE_X_SG, - 'DEL_ANGLE_Y_SG': DEL_ANGLE_Y_SG, - 'NEG_NX_OF_DOM_WITH_WIDE_HALO': NEG_NX_OF_DOM_WITH_WIDE_HALO, - 'NEG_NY_OF_DOM_WITH_WIDE_HALO': NEG_NY_OF_DOM_WITH_WIDE_HALO, - 'PAZI': PAZI or '' - }) - # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # Continue appending variable definitions to the variable definitions + # Continue appending variable definitions to the variable definitions # file. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - settings.update({ - # - #----------------------------------------------------------------------- - # - # Flag in the \"{MODEL_CONFIG_FN}\" file for coupling the ocean model to - # the weather model. - # - #----------------------------------------------------------------------- - # - 'CPL': CPL, - # - #----------------------------------------------------------------------- - # - # Name of the ozone parameterization. The value this gets set to depends - # on the CCPP physics suite being used. - # - #----------------------------------------------------------------------- - # - 'OZONE_PARAM': OZONE_PARAM, - # - #----------------------------------------------------------------------- - # - # If USE_USER_STAGED_EXTRN_FILES is set to \"FALSE\", this is the system - # directory in which the workflow scripts will look for the files generated - # by the external model specified in EXTRN_MDL_NAME_ICS. These files will - # be used to generate the input initial condition and surface files for - # the FV3-LAM. - # - #----------------------------------------------------------------------- - # - 'EXTRN_MDL_SYSBASEDIR_ICS': EXTRN_MDL_SYSBASEDIR_ICS, - # - #----------------------------------------------------------------------- - # - # If USE_USER_STAGED_EXTRN_FILES is set to \"FALSE\", this is the system - # directory in which the workflow scripts will look for the files generated - # by the external model specified in EXTRN_MDL_NAME_LBCS. These files - # will be used to generate the input lateral boundary condition files for - # the FV3-LAM. - # - #----------------------------------------------------------------------- - # - 'EXTRN_MDL_SYSBASEDIR_LBCS': EXTRN_MDL_SYSBASEDIR_LBCS, - # - #----------------------------------------------------------------------- - # - # Shift back in time (in units of hours) of the starting time of the ex- - # ternal model specified in EXTRN_MDL_NAME_LBCS. - # - #----------------------------------------------------------------------- - # - 'EXTRN_MDL_LBCS_OFFSET_HRS': EXTRN_MDL_LBCS_OFFSET_HRS, - # - #----------------------------------------------------------------------- - # - # Boundary condition update times (in units of forecast hours). Note that - # LBC_SPEC_FCST_HRS is an array, even if it has only one element. - # - #----------------------------------------------------------------------- - # - 'LBC_SPEC_FCST_HRS': LBC_SPEC_FCST_HRS, - # - #----------------------------------------------------------------------- - # - # The number of cycles for which to make forecasts and the list of - # starting dates/hours of these cycles. - # - #----------------------------------------------------------------------- - # - 'NUM_CYCLES': NUM_CYCLES, - 'ALL_CDATES': ALL_CDATES, - # - #----------------------------------------------------------------------- - # - # Parameters that determine whether FVCOM data will be used, and if so, - # their location. - # - # If USE_FVCOM is set to \"TRUE\", then FVCOM data (in the file FVCOM_FILE - # located in the directory FVCOM_DIR) will be used to update the surface - # boundary conditions during the initial conditions generation task - # (MAKE_ICS_TN). - # - #----------------------------------------------------------------------- - # - 'USE_FVCOM': USE_FVCOM, - 'FVCOM_DIR': FVCOM_DIR, - 'FVCOM_FILE': FVCOM_FILE, - # - #----------------------------------------------------------------------- - # - # Computational parameters. - # - #----------------------------------------------------------------------- - # - 'NCORES_PER_NODE': NCORES_PER_NODE, - 'PE_MEMBER01': PE_MEMBER01, - # - #----------------------------------------------------------------------- - # - # IF DO_SPP is set to "TRUE", N_VAR_SPP specifies the number of physics - # parameterizations that are perturbed with SPP. If DO_LSM_SPP is set to - # "TRUE", N_VAR_LNDP specifies the number of LSM parameters that are - # perturbed. LNDP_TYPE determines the way LSM perturbations are employed - # and FHCYC_LSM_SPP_OR_NOT sets FHCYC based on whether LSM perturbations - # are turned on or not. - # - #----------------------------------------------------------------------- - # - 'N_VAR_SPP': N_VAR_SPP, - 'N_VAR_LNDP': N_VAR_LNDP, - 'LNDP_TYPE': LNDP_TYPE, - 'LNDP_MODEL_TYPE': LNDP_MODEL_TYPE, - 'FHCYC_LSM_SPP_OR_NOT': FHCYC_LSM_SPP_OR_NOT - }) + settings.update( + { + # + # ----------------------------------------------------------------------- + # + # Flag in the \"{MODEL_CONFIG_FN}\" file for coupling the ocean model to + # the weather model. + # + # ----------------------------------------------------------------------- + # + "CPL": CPL, + # + # ----------------------------------------------------------------------- + # + # Name of the ozone parameterization. The value this gets set to depends + # on the CCPP physics suite being used. + # + # ----------------------------------------------------------------------- + # + "OZONE_PARAM": OZONE_PARAM, + # + # ----------------------------------------------------------------------- + # + # If USE_USER_STAGED_EXTRN_FILES is set to \"FALSE\", this is the system + # directory in which the workflow scripts will look for the files generated + # by the external model specified in EXTRN_MDL_NAME_ICS. These files will + # be used to generate the input initial condition and surface files for + # the FV3-LAM. + # + # ----------------------------------------------------------------------- + # + "EXTRN_MDL_SYSBASEDIR_ICS": EXTRN_MDL_SYSBASEDIR_ICS, + # + # ----------------------------------------------------------------------- + # + # If USE_USER_STAGED_EXTRN_FILES is set to \"FALSE\", this is the system + # directory in which the workflow scripts will look for the files generated + # by the external model specified in EXTRN_MDL_NAME_LBCS. These files + # will be used to generate the input lateral boundary condition files for + # the FV3-LAM. + # + # ----------------------------------------------------------------------- + # + "EXTRN_MDL_SYSBASEDIR_LBCS": EXTRN_MDL_SYSBASEDIR_LBCS, + # + # ----------------------------------------------------------------------- + # + # Shift back in time (in units of hours) of the starting time of the ex- + # ternal model specified in EXTRN_MDL_NAME_LBCS. + # + # ----------------------------------------------------------------------- + # + "EXTRN_MDL_LBCS_OFFSET_HRS": EXTRN_MDL_LBCS_OFFSET_HRS, + # + # ----------------------------------------------------------------------- + # + # Boundary condition update times (in units of forecast hours). Note that + # LBC_SPEC_FCST_HRS is an array, even if it has only one element. + # + # ----------------------------------------------------------------------- + # + "LBC_SPEC_FCST_HRS": LBC_SPEC_FCST_HRS, + # + # ----------------------------------------------------------------------- + # + # The number of cycles for which to make forecasts and the list of + # starting dates/hours of these cycles. + # + # ----------------------------------------------------------------------- + # + "NUM_CYCLES": NUM_CYCLES, + "ALL_CDATES": ALL_CDATES, + # + # ----------------------------------------------------------------------- + # + # Parameters that determine whether FVCOM data will be used, and if so, + # their location. + # + # If USE_FVCOM is set to \"TRUE\", then FVCOM data (in the file FVCOM_FILE + # located in the directory FVCOM_DIR) will be used to update the surface + # boundary conditions during the initial conditions generation task + # (MAKE_ICS_TN). + # + # ----------------------------------------------------------------------- + # + "USE_FVCOM": USE_FVCOM, + "FVCOM_DIR": FVCOM_DIR, + "FVCOM_FILE": FVCOM_FILE, + # + # ----------------------------------------------------------------------- + # + # Computational parameters. + # + # ----------------------------------------------------------------------- + # + "NCORES_PER_NODE": NCORES_PER_NODE, + "PE_MEMBER01": PE_MEMBER01, + # + # ----------------------------------------------------------------------- + # + # IF DO_SPP is set to "TRUE", N_VAR_SPP specifies the number of physics + # parameterizations that are perturbed with SPP. If DO_LSM_SPP is set to + # "TRUE", N_VAR_LNDP specifies the number of LSM parameters that are + # perturbed. LNDP_TYPE determines the way LSM perturbations are employed + # and FHCYC_LSM_SPP_OR_NOT sets FHCYC based on whether LSM perturbations + # are turned on or not. + # + # ----------------------------------------------------------------------- + # + "N_VAR_SPP": N_VAR_SPP, + "N_VAR_LNDP": N_VAR_LNDP, + "LNDP_TYPE": LNDP_TYPE, + "LNDP_MODEL_TYPE": LNDP_MODEL_TYPE, + "FHCYC_LSM_SPP_OR_NOT": FHCYC_LSM_SPP_OR_NOT, + } + ) + + # write derived settings + cfg_d["derived"] = settings # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # Now write all settings we collacted so far to var_defns file + # Now write everything to var_defns.sh file # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - with open(GLOBAL_VAR_DEFNS_FP,'a') as f: - f.write(cfg_to_shell_str(settings)) + + # print content of var_defns if DEBUG=True + all_lines = cfg_to_yaml_str(cfg_d) + print_info_msg(all_lines, verbose=DEBUG) + + # print info message + print_info_msg( + f""" + Generating the global experiment variable definitions file specified by + GLOBAL_VAR_DEFNS_FN: + GLOBAL_VAR_DEFNS_FN = \"{GLOBAL_VAR_DEFNS_FN}\" + Full path to this file is: + GLOBAL_VAR_DEFNS_FP = \"{GLOBAL_VAR_DEFNS_FP}\" + For more detailed information, set DEBUG to \"TRUE\" in the experiment + configuration file (\"{EXPT_CONFIG_FN}\").""" + ) + + with open(GLOBAL_VAR_DEFNS_FP, "a") as f: + f.write(cfg_to_shell_str(cfg_d)) # export all global variables back to the environment export_vars() # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Check validity of parameters in one place, here in the end. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - # update dictionary with globals() values - update_dict = {k: globals()[k] for k in cfg_d.keys() if k in globals() } - cfg_d.update(update_dict) - # loop through cfg_d and check validity of params cfg_v = load_config_file("valid_param_vals.yaml") - for k,v in cfg_d.items(): + cfg_d = flatten_dict(cfg_d) + for k, v in cfg_d.items(): if v == None: continue - vkey = 'valid_vals_' + k + vkey = "valid_vals_" + k if (vkey in cfg_v) and not (v in cfg_v[vkey]): - print_err_msg_exit(f''' + print_err_msg_exit( + f""" The variable {k}={v} in {EXPT_DEFAULT_CONFIG_FN} or {EXPT_CONFIG_FN} does not have a valid value. Possible values are: - {k} = {cfg_v[vkey]}''') + {k} = {cfg_v[vkey]}""" + ) # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # # Print message indicating successful completion of script. # - #----------------------------------------------------------------------- + # ----------------------------------------------------------------------- # - print_info_msg(f''' + print_info_msg( + f""" ======================================================================== Function setup() in \"{os.path.basename(__file__)}\" completed successfully!!! - ========================================================================''') - + ========================================================================""" + ) + + # -#----------------------------------------------------------------------- +# ----------------------------------------------------------------------- # # Call the function defined above. # -#----------------------------------------------------------------------- +# ----------------------------------------------------------------------- # if __name__ == "__main__": setup() - diff --git a/ush/source_util_funcs.sh b/ush/source_util_funcs.sh index fd03d9cad5..78913b2b11 100644 --- a/ush/source_util_funcs.sh +++ b/ush/source_util_funcs.sh @@ -229,6 +229,14 @@ function source_util_funcs() { #----------------------------------------------------------------------- # . ${bashutils_dir}/get_bash_file_contents.sh +# +#----------------------------------------------------------------------- +# +# Source the file containing the function that sources config files +# +#----------------------------------------------------------------------- +# + . ${bashutils_dir}/source_config.sh } source_util_funcs