diff --git a/.gitignore b/.gitignore index 9b38ce52f17..470ce38391d 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,8 @@ __pycache__ #nohup.out - some users do not want this to be a part of .gitignore. TODO: review against best practices .idea/ .vscode/ +.venv/ +venv/ nohup.out # Ignore editor generated backup files diff --git a/ci/cases/gfsv17/C384mx025_3DVarAOWCDA.yaml b/ci/cases/gfsv17/C384mx025_3DVarAOWCDA.yaml index 21aece76a55..e18d3913f26 100644 --- a/ci/cases/gfsv17/C384mx025_3DVarAOWCDA.yaml +++ b/ci/cases/gfsv17/C384mx025_3DVarAOWCDA.yaml @@ -3,6 +3,7 @@ experiment: mode: cycled arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: S2S resdetatmos: 384 diff --git a/ci/cases/gfsv17/C384mx025_hybAOWCDA.yaml b/ci/cases/gfsv17/C384mx025_hybAOWCDA.yaml index 57680ffd023..66f3b1b4060 100644 --- a/ci/cases/gfsv17/C384mx025_hybAOWCDA.yaml +++ b/ci/cases/gfsv17/C384mx025_hybAOWCDA.yaml @@ -3,6 +3,7 @@ experiment: mode: cycled arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: S2S resdetatmos: 384 diff --git a/ci/cases/gfsv17/marine3dvar.yaml b/ci/cases/gfsv17/marine3dvar.yaml index c2884992b63..cdb6647b58e 100644 --- a/ci/cases/gfsv17/marine3dvar.yaml +++ b/ci/cases/gfsv17/marine3dvar.yaml @@ -13,7 +13,6 @@ base: DO_VERFOZN: "YES" DO_VERFRAD: "YES" FHMAX_GFS: 240 - ACCOUNT: {{ 'HPC_ACCOUNT' | getenv }} DO_TEST_MODE: "YES" prepoceanobs: diff --git a/ci/cases/gfsv17/marinehyb.yaml b/ci/cases/gfsv17/marinehyb.yaml index 0bb0d7d6050..012d243df15 100644 --- a/ci/cases/gfsv17/marinehyb.yaml +++ b/ci/cases/gfsv17/marinehyb.yaml @@ -14,7 +14,6 @@ base: DO_VERFOZN: "YES" DO_VERFRAD: "YES" FHMAX_GFS: 240 - ACCOUNT: {{ 'HPC_ACCOUNT' | getenv }} prepoceanobs: use_exp_obs: "YES" diff --git a/ci/cases/hires/C1152_S2SW.yaml b/ci/cases/hires/C1152_S2SW.yaml index 29e1f00bbe5..8c05b129361 100644 --- a/ci/cases/hires/C1152_S2SW.yaml +++ b/ci/cases/hires/C1152_S2SW.yaml @@ -3,6 +3,7 @@ experiment: mode: forecast-only arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: S2SW resdetatmos: 1152 diff --git a/ci/cases/hires/C768_S2SW.yaml b/ci/cases/hires/C768_S2SW.yaml index ad314bb75bd..6cb17671737 100644 --- a/ci/cases/hires/C768_S2SW.yaml +++ b/ci/cases/hires/C768_S2SW.yaml @@ -3,6 +3,7 @@ experiment: mode: forecast-only arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: S2SW resdetatmos: 768 diff --git a/ci/cases/pr/C48_ATM.yaml b/ci/cases/pr/C48_ATM.yaml index 79706556e6c..18658ae5188 100644 --- a/ci/cases/pr/C48_ATM.yaml +++ b/ci/cases/pr/C48_ATM.yaml @@ -3,6 +3,7 @@ experiment: mode: forecast-only arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: ATM resdetatmos: 48 diff --git a/ci/cases/pr/C48_S2SW.yaml b/ci/cases/pr/C48_S2SW.yaml index 256299812dc..972d02ce4fc 100644 --- a/ci/cases/pr/C48_S2SW.yaml +++ b/ci/cases/pr/C48_S2SW.yaml @@ -3,6 +3,7 @@ experiment: mode: forecast-only arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: S2SW resdetatmos: 48 @@ -12,4 +13,3 @@ arguments: idate: 2021032312 edate: 2021032312 yaml: {{ HOMEgfs }}/ci/cases/yamls/gfs_defaults_ci.yaml - diff --git a/ci/cases/pr/C48_S2SWA_gefs.yaml b/ci/cases/pr/C48_S2SWA_gefs.yaml index 856759b46a6..fe2482cbb3a 100644 --- a/ci/cases/pr/C48_S2SWA_gefs.yaml +++ b/ci/cases/pr/C48_S2SWA_gefs.yaml @@ -3,6 +3,7 @@ experiment: mode: forecast-only arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: S2SWA resdetatmos: 48 diff --git a/ci/cases/pr/C48_S2SW_extended.yaml b/ci/cases/pr/C48_S2SW_extended.yaml index 06d3ffff4c0..8dd52a4a720 100644 --- a/ci/cases/pr/C48_S2SW_extended.yaml +++ b/ci/cases/pr/C48_S2SW_extended.yaml @@ -3,6 +3,7 @@ experiment: mode: forecast-only arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: S2SW resdetatmos: 48 diff --git a/ci/cases/pr/C48mx500_3DVarAOWCDA.yaml b/ci/cases/pr/C48mx500_3DVarAOWCDA.yaml index 5fb0a8a045b..768f13ce408 100644 --- a/ci/cases/pr/C48mx500_3DVarAOWCDA.yaml +++ b/ci/cases/pr/C48mx500_3DVarAOWCDA.yaml @@ -3,6 +3,7 @@ experiment: mode: cycled arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: S2SW resdetatmos: 48 diff --git a/ci/cases/pr/C48mx500_hybAOWCDA.yaml b/ci/cases/pr/C48mx500_hybAOWCDA.yaml index 3fc1e9e277d..dc06aacf0c6 100644 --- a/ci/cases/pr/C48mx500_hybAOWCDA.yaml +++ b/ci/cases/pr/C48mx500_hybAOWCDA.yaml @@ -3,6 +3,7 @@ experiment: mode: cycled arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: S2S resdetatmos: 48 diff --git a/ci/cases/pr/C96C48_hybatmDA.yaml b/ci/cases/pr/C96C48_hybatmDA.yaml index 1bbca4f6a61..22f505a147e 100644 --- a/ci/cases/pr/C96C48_hybatmDA.yaml +++ b/ci/cases/pr/C96C48_hybatmDA.yaml @@ -3,6 +3,8 @@ experiment: mode: cycled arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: ATM resdetatmos: 96 diff --git a/ci/cases/pr/C96C48_hybatmaerosnowDA.yaml b/ci/cases/pr/C96C48_hybatmaerosnowDA.yaml index 20d6a5d732a..8aab16dd932 100644 --- a/ci/cases/pr/C96C48_hybatmaerosnowDA.yaml +++ b/ci/cases/pr/C96C48_hybatmaerosnowDA.yaml @@ -3,6 +3,7 @@ experiment: mode: cycled arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: ATMA resdetatmos: 96 diff --git a/ci/cases/pr/C96C48_ufs_hybatmDA.yaml b/ci/cases/pr/C96C48_ufs_hybatmDA.yaml index 74f31a27940..82e9d5dc8dc 100644 --- a/ci/cases/pr/C96C48_ufs_hybatmDA.yaml +++ b/ci/cases/pr/C96C48_ufs_hybatmDA.yaml @@ -3,6 +3,7 @@ experiment: mode: cycled arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: ATM resdetatmos: 96 @@ -19,7 +20,6 @@ arguments: skip_ci_on_hosts: - gaeac5 - - gaeac6 - orion - hercules - awsepicglobalworkflow diff --git a/ci/cases/pr/C96_atm3DVar.yaml b/ci/cases/pr/C96_atm3DVar.yaml index 17d36d93bd0..b44ebaedd77 100644 --- a/ci/cases/pr/C96_atm3DVar.yaml +++ b/ci/cases/pr/C96_atm3DVar.yaml @@ -3,6 +3,7 @@ experiment: mode: cycled arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: ATM resdetatmos: 96 diff --git a/ci/cases/pr/C96_atm3DVar_extended.yaml b/ci/cases/pr/C96_atm3DVar_extended.yaml index 27a839f076f..e8949e78c16 100644 --- a/ci/cases/pr/C96_atm3DVar_extended.yaml +++ b/ci/cases/pr/C96_atm3DVar_extended.yaml @@ -3,6 +3,7 @@ experiment: mode: cycled arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: ATM resdetatmos: 96 diff --git a/ci/cases/pr/C96mx100_S2S.yaml b/ci/cases/pr/C96mx100_S2S.yaml index 4ce7c5e206d..0559c04cd81 100644 --- a/ci/cases/pr/C96mx100_S2S.yaml +++ b/ci/cases/pr/C96mx100_S2S.yaml @@ -3,6 +3,7 @@ experiment: mode: forecast-only arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} idate: 1994050100 edate: 1994050100 pslot: {{ 'pslot' | getenv }} diff --git a/ci/cases/sfs/C96mx100_S2S.yaml b/ci/cases/sfs/C96mx100_S2S.yaml index 448adc670d5..224e73a2a6e 100644 --- a/ci/cases/sfs/C96mx100_S2S.yaml +++ b/ci/cases/sfs/C96mx100_S2S.yaml @@ -3,6 +3,7 @@ experiment: mode: forecast-only arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} idate: 1994050100 edate: 1994050100 pslot: {{ 'pslot' | getenv }} @@ -16,4 +17,3 @@ arguments: expdir: {{ 'RUNTESTS' | getenv }}/EXPDIR icsdir: {{ 'ICSDIR_ROOT' | getenv }}/C96mx100/20240610 yaml: {{ HOMEgfs }}/ci/cases/yamls/sfs_full.yaml - diff --git a/ci/cases/weekly/C384C192_hybatmda.yaml b/ci/cases/weekly/C384C192_hybatmda.yaml index ecaea3757f6..9a2d823a58f 100644 --- a/ci/cases/weekly/C384C192_hybatmda.yaml +++ b/ci/cases/weekly/C384C192_hybatmda.yaml @@ -3,6 +3,7 @@ experiment: mode: cycled arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: ATM resdetatmos: 384 diff --git a/ci/cases/weekly/C384_S2SWA.yaml b/ci/cases/weekly/C384_S2SWA.yaml index 7bbdc446717..023dd7c2a14 100644 --- a/ci/cases/weekly/C384_S2SWA.yaml +++ b/ci/cases/weekly/C384_S2SWA.yaml @@ -3,6 +3,7 @@ experiment: mode: forecast-only arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: S2SWA resdetatmos: 384 diff --git a/ci/cases/weekly/C384_atm3DVar.yaml b/ci/cases/weekly/C384_atm3DVar.yaml index 4409a73ac11..8681a5d58ef 100644 --- a/ci/cases/weekly/C384_atm3DVar.yaml +++ b/ci/cases/weekly/C384_atm3DVar.yaml @@ -3,6 +3,7 @@ experiment: mode: cycled arguments: + account: {{ 'HPC_ACCOUNT' | getenv }} pslot: {{ 'pslot' | getenv }} app: ATM resdetatmos: 384 diff --git a/ci/cases/yamls/atmaerosnowDA_defaults_ci.yaml b/ci/cases/yamls/atmaerosnowDA_defaults_ci.yaml index 7e88abb1a0f..4e528e1b829 100644 --- a/ci/cases/yamls/atmaerosnowDA_defaults_ci.yaml +++ b/ci/cases/yamls/atmaerosnowDA_defaults_ci.yaml @@ -2,5 +2,4 @@ defaults: !INC {{ HOMEgfs }}/parm/config/gfs/yaml/defaults.yaml base: DO_JEDISNOWDA: "YES" - ACCOUNT: {{ 'HPC_ACCOUNT' | getenv }} DO_TEST_MODE: "NO" diff --git a/ci/cases/yamls/atmsoilDA_defaults_ci.yaml b/ci/cases/yamls/atmsoilDA_defaults_ci.yaml index 8ace8966323..28c4f3dc940 100644 --- a/ci/cases/yamls/atmsoilDA_defaults_ci.yaml +++ b/ci/cases/yamls/atmsoilDA_defaults_ci.yaml @@ -2,5 +2,4 @@ defaults: !INC {{ HOMEgfs }}/parm/config/gfs/yaml/defaults.yaml base: DO_GSISOILDA: "YES" - ACCOUNT: {{ 'HPC_ACCOUNT' | getenv }} DO_TEST_MODE: "NO" diff --git a/ci/cases/yamls/gefs_defaults_ci.yaml b/ci/cases/yamls/gefs_defaults_ci.yaml index a19be7713f1..03607d911e6 100644 --- a/ci/cases/yamls/gefs_defaults_ci.yaml +++ b/ci/cases/yamls/gefs_defaults_ci.yaml @@ -1,11 +1,9 @@ defaults: !INC {{ HOMEgfs }}/parm/config/gefs/yaml/defaults.yaml base: - ACCOUNT: {{ 'HPC_ACCOUNT' | getenv }} SFS_POST: "NO" FHOUT_GFS: 6 USE_OCN_ENS_PERTURB_FILES: "NO" USE_ATM_ENS_PERTURB_FILES: "NO" ocn: MOM6_INTERP_ICS: "NO" - diff --git a/ci/cases/yamls/gefs_replay_ci.yaml b/ci/cases/yamls/gefs_replay_ci.yaml index b1155aade13..8bb49f79e3b 100644 --- a/ci/cases/yamls/gefs_replay_ci.yaml +++ b/ci/cases/yamls/gefs_replay_ci.yaml @@ -1,7 +1,6 @@ defaults: !INC {{ HOMEgfs }}/parm/config/gefs/yaml/defaults.yaml base: - ACCOUNT: {{ 'HPC_ACCOUNT' | getenv }} REPLAY_ICS: "YES" FCST_BREAKPOINTS: "" FHMAX_GFS: 48 @@ -15,4 +14,3 @@ base: stage_ic: USE_OCN_ENS_PERTURB_FILES: "YES" USE_ATM_ENS_PERTURB_FILES: "YES" - diff --git a/ci/cases/yamls/gfs_defaults_ci.yaml b/ci/cases/yamls/gfs_defaults_ci.yaml index 389844e3859..fcb042e4a9a 100644 --- a/ci/cases/yamls/gfs_defaults_ci.yaml +++ b/ci/cases/yamls/gfs_defaults_ci.yaml @@ -1,7 +1,6 @@ defaults: !INC {{ HOMEgfs }}/parm/config/gfs/yaml/defaults.yaml base: - ACCOUNT: {{ 'HPC_ACCOUNT' | getenv }} DO_TEST_MODE: "YES" FETCHDIR: "/NCEPDEV/emc-global/1year/David.Grumm/test_data" DO_METP: "NO" diff --git a/ci/cases/yamls/gfs_extended_ci.yaml b/ci/cases/yamls/gfs_extended_ci.yaml index 76c19f97427..d7b83a86289 100644 --- a/ci/cases/yamls/gfs_extended_ci.yaml +++ b/ci/cases/yamls/gfs_extended_ci.yaml @@ -2,7 +2,6 @@ defaults: !INC {{ HOMEgfs }}/parm/config/gfs/yaml/defaults.yaml base: - ACCOUNT: {{ 'HPC_ACCOUNT' | getenv }} DO_GOES: "YES" DO_BUFRSND: "YES" DO_GEMPAK: "YES" diff --git a/ci/cases/yamls/gfs_metp_ci.yaml b/ci/cases/yamls/gfs_metp_ci.yaml index 2ba5f9f8f58..34c79a72119 100644 --- a/ci/cases/yamls/gfs_metp_ci.yaml +++ b/ci/cases/yamls/gfs_metp_ci.yaml @@ -1,6 +1,5 @@ defaults: !INC {{ HOMEgfs }}/parm/config/gfs/yaml/defaults.yaml base: - ACCOUNT: {{ 'HPC_ACCOUNT' | getenv }} DO_TEST_MODE: "NO" DO_METP: "YES" diff --git a/ci/cases/yamls/sfs_defaults.yaml b/ci/cases/yamls/sfs_defaults.yaml index 777849abb6b..2842b8e73fc 100644 --- a/ci/cases/yamls/sfs_defaults.yaml +++ b/ci/cases/yamls/sfs_defaults.yaml @@ -21,7 +21,6 @@ base: USE_ATM_ENS_PERTURB_FILES: "YES" HPSSARCH: "NO" LOCALARCH: "NO" - ACCOUNT: {{ 'HPC_ACCOUNT' | getenv }} fcst: TYPE: "hydro" MONO: "mono" diff --git a/ci/cases/yamls/sfs_full.yaml b/ci/cases/yamls/sfs_full.yaml index 1312d715fbb..1c8ef604a16 100644 --- a/ci/cases/yamls/sfs_full.yaml +++ b/ci/cases/yamls/sfs_full.yaml @@ -21,7 +21,6 @@ base: USE_ATM_ENS_PERTURB_FILES: "YES" HPSSARCH: "NO" LOCALARCH: "NO" - ACCOUNT: {{ 'HPC_ACCOUNT' | getenv }} fcst: TYPE: "hydro" MONO: "mono" diff --git a/ci/cases/yamls/soca_gfs_defaults_ci.yaml b/ci/cases/yamls/soca_gfs_defaults_ci.yaml index 3f5b5c0824a..e799383e328 100644 --- a/ci/cases/yamls/soca_gfs_defaults_ci.yaml +++ b/ci/cases/yamls/soca_gfs_defaults_ci.yaml @@ -1,7 +1,6 @@ defaults: !INC {{ HOMEgfs }}/parm/config/gfs/yaml/defaults.yaml base: - ACCOUNT: {{ 'HPC_ACCOUNT' | getenv }} DO_JEDIOCNVAR: "YES" DO_METP: "NO" diff --git a/ci/cases/yamls/soca_hyb_gfs_defaults_ci.yaml b/ci/cases/yamls/soca_hyb_gfs_defaults_ci.yaml index 99ca9911672..773e5016bf3 100644 --- a/ci/cases/yamls/soca_hyb_gfs_defaults_ci.yaml +++ b/ci/cases/yamls/soca_hyb_gfs_defaults_ci.yaml @@ -1,7 +1,6 @@ defaults: !INC {{ HOMEgfs }}/parm/config/gfs/yaml/defaults.yaml base: - ACCOUNT: {{ 'HPC_ACCOUNT' | getenv }} DO_JEDIOCNVAR: "YES" DOHYBVAR_OCN: "YES" DOLETKF_OCN: "YES" diff --git a/ci/cases/yamls/ufs_hybatmDA_defaults.ci.yaml b/ci/cases/yamls/ufs_hybatmDA_defaults.ci.yaml index ca165453999..f15c5885b29 100644 --- a/ci/cases/yamls/ufs_hybatmDA_defaults.ci.yaml +++ b/ci/cases/yamls/ufs_hybatmDA_defaults.ci.yaml @@ -4,7 +4,6 @@ base: DOIAU: "NO" DO_JEDIATMVAR: "YES" DO_JEDIATMENS: "YES" - ACCOUNT: {{ 'HPC_ACCOUNT' | getenv }} DO_TEST_MODE: "NO" atmanl: JCB_ALGO_YAML_VAR: "${HOMEgfs}/sorc/gdas.cd/test/gw-ci/atm/jcb-prototype_3dvar_ufs_hybatmDA.yaml.j2" diff --git a/ci/scripts/tests/test_setup.py b/ci/scripts/tests/test_setup.py index 77a36369f46..9561ed04418 100755 --- a/ci/scripts/tests/test_setup.py +++ b/ci/scripts/tests/test_setup.py @@ -16,8 +16,9 @@ def test_setup_expt(): arguments = [ "gfs", "forecast-only", "--pslot", pslot, "--app", "ATM", "--resdetatmos", "48", - "--comroot", f"{RUNDIR}", "--expdir", f"{RUNDIR}", - "--idate", "2021032312", "--edate", "2021032312", "--overwrite" + "--comroot", RUNDIR, "--expdir", RUNDIR, + "--idate", "2021032312", "--edate", "2021032312", "--overwrite", + "--account", account ] setup_expt_script = Executable(os.path.join(HOMEgfs, "workflow", "setup_expt.py")) setup_expt_script.add_default_arg(arguments) diff --git a/parm/config/gefs/config.aero b/parm/config/gefs/config.aero deleted file mode 120000 index 9cf5cce0800..00000000000 --- a/parm/config/gefs/config.aero +++ /dev/null @@ -1 +0,0 @@ -../gfs/config.aero \ No newline at end of file diff --git a/parm/config/gefs/config.aero.j2 b/parm/config/gefs/config.aero.j2 new file mode 120000 index 00000000000..cf791379998 --- /dev/null +++ b/parm/config/gefs/config.aero.j2 @@ -0,0 +1 @@ +../gfs/config.aero.j2 \ No newline at end of file diff --git a/parm/config/gefs/config.base b/parm/config/gefs/config.base.j2 similarity index 72% rename from parm/config/gefs/config.base rename to parm/config/gefs/config.base.j2 index cd830870fa8..ab5f9df0c20 100644 --- a/parm/config/gefs/config.base +++ b/parm/config/gefs/config.base.j2 @@ -6,29 +6,29 @@ echo "BEGIN: config.base" # Machine environment -export machine="@MACHINE@" +export machine="{{ MACHINE }}" # EMC parallel or NCO production export RUN_ENVIR="emc" # Account, queue, etc. -export ACCOUNT="@ACCOUNT@" -export QUEUE="@QUEUE@" -export QUEUE_SERVICE="@QUEUE_SERVICE@" -export QUEUE_DTN="@QUEUE_DTN@" -export PARTITION_BATCH="@PARTITION_BATCH@" -export PARTITION_SERVICE="@PARTITION_SERVICE@" -export PARTITION_DTN="@PARTITION_DTN@" -export RESERVATION="@RESERVATION@" -export CLUSTERS="@CLUSTERS@" -export CLUSTERS_SERVICE="@CLUSTERS_SERVICE@" -export CLUSTERS_DTN="@CLUSTERS_DTN@" +export ACCOUNT="{{ ACCOUNT }}" +export QUEUE="{{ QUEUE }}" +export QUEUE_SERVICE="{{ QUEUE_SERVICE | default('${QUEUE}') }}" +export QUEUE_DTN="{{ QUEUE_DTN | default('${QUEUE_SERVICE}') }}" +export PARTITION_BATCH="{{ PARTITION_BATCH }}" +export PARTITION_SERVICE="{{ PARTITION_SERVICE | default() }}" +export PARTITION_DTN="{{ PARTITION_DTN | default() }}" +export RESERVATION="{{ RESERVATION | default() }}" +export CLUSTERS="{{ CLUSTERS | default() }}" +export CLUSTERS_SERVICE="{{ CLUSTERS_SERVICE | default('${CLUSTERS}') }}" +export CLUSTERS_DTN="{{ CLUSTERS_DTN | default('${CLUSTERS_SERVICE}') }}" # Project to use in mass store: -export HPSS_PROJECT="@HPSS_PROJECT@" +export HPSS_PROJECT="{{ HPSS_PROJECT }}" # Directories relative to installation areas: -export HOMEgfs=@HOMEgfs@ +export HOMEgfs="{{ HOMEgfs }}" export EXECgfs=${HOMEgfs}/exec export FIXgfs=${HOMEgfs}/fix export PARMgfs=${HOMEgfs}/parm @@ -40,26 +40,26 @@ export FIXugwd=${FIXgfs}/ugwd ######################################################################## # GLOBAL static environment parameters -export PACKAGEROOT="@PACKAGEROOT@" # TODO: set via prod_envir in Ops -export COMROOT="@COMROOT@" # TODO: set via prod_envir in Ops -export COMINsyn="@COMINsyn@" +export PACKAGEROOT="{{ PACKAGEROOT }}" # TODO: set via prod_envir in Ops +export COMROOT="{{ COMROOT }}" # TODO: set via prod_envir in Ops +export COMINsyn="{{ COMINsyn }}" # USER specific paths -export HOMEDIR="@HOMEDIR@" -export STMP="@STMP@" -export PTMP="@PTMP@" -export NOSCRUB="@NOSCRUB@" +export HOMEDIR="{{ HOMEDIR }}" +export STMP="{{ STMP }}" +export PTMP="{{ PTMP }}" +export NOSCRUB="{{ NOSCRUB }}" # Base directories for various builds -export BASE_GIT="@BASE_GIT@" +export BASE_GIT="{{ BASE_GIT }}" # Base directory for staged data -export BASE_DATA="@BASE_DATA@" +export BASE_DATA="{{ BASE_DATA }}" # Toggle to turn on/off GFS downstream processing. -export DO_BUFRSND="@DO_BUFRSND@" # BUFR sounding products -export DO_GEMPAK="@DO_GEMPAK@" # GEMPAK products -export DO_AWIPS="@DO_AWIPS@" # AWIPS products +export DO_BUFRSND="{{ DO_BUFRSND }}" # BUFR sounding products +export DO_GEMPAK="{{ DO_GEMPAK }}" # GEMPAK products +export DO_AWIPS="{{ DO_AWIPS }}" # AWIPS products # NO for retrospective parallel; YES for real-time parallel # arch.sh uses REALTIME for MOS. Need to set REALTIME=YES @@ -68,8 +68,8 @@ export DO_AWIPS="@DO_AWIPS@" # AWIPS products export REALTIME="YES" # Experiment mode (cycled or forecast-only) -export MODE="@MODE@" # cycled/forecast-only -export DO_TEST_MODE="@DO_TEST_MODE@" # option to change configuration for automated testing +export MODE="{{ MODE }}" # cycled/forecast-only +export DO_TEST_MODE="{{ DO_TEST_MODE }}" # option to change configuration for automated testing #################################################### # DO NOT ADD MACHINE DEPENDENT STUFF BELOW THIS LINE @@ -85,10 +85,10 @@ export NCP="/bin/cp -p" export NMV="/bin/mv" export NLN="/bin/ln -sf" export VERBOSE="YES" -export KEEPDATA="@KEEPDATA@" +export KEEPDATA="{{ KEEPDATA }}" export DEBUG_POSTSCRIPT="NO" # PBS only; sets debug=true -export CHGRP_RSTPROD="@CHGRP_RSTPROD@" -export CHGRP_CMD="@CHGRP_CMD@" +export CHGRP_RSTPROD="{{ CHGRP_RSTPROD }}" +export CHGRP_CMD="{{ CHGRP_CMD }}" export NCDUMP="${NETCDF:-${netcdf_c_ROOT:-}}/bin/ncdump" export NCLEN="${HOMEgfs}/ush/getncdimlen" @@ -97,17 +97,17 @@ export BASE_ENV="${HOMEgfs}/env" export BASE_JOB="${HOMEgfs}/jobs/rocoto" # EXPERIMENT specific environment parameters -export SDATE=@SDATE@ -export EDATE=@EDATE@ -export EXP_WARM_START="@EXP_WARM_START@" +export SDATE="{{ SDATE }}" +export EDATE="{{ EDATE }}" +export EXP_WARM_START="{{ EXP_WARM_START }}" export assim_freq=6 -export PSLOT="@PSLOT@" -export EXPDIR="@EXPDIR@/${PSLOT}" -export ROTDIR="@COMROOT@/${PSLOT}" +export PSLOT="{{ PSLOT }}" +export EXPDIR="{{ EXPDIR }}/${PSLOT}" +export ROTDIR="{{ COMROOT }}/${PSLOT}" export ARCDIR="${NOSCRUB}/archive/${PSLOT}" -export ATARDIR="@ATARDIR@" -export FETCHDIR="@FETCHDIR@" # HPSS or local directory where IC tarball(s) can be found. +export ATARDIR="{{ ATARDIR }}" +export FETCHDIR="{{ FETCHDIR }}" # HPSS or local directory where IC tarball(s) can be found. # Commonly defined parameters in JJOBS export envir=${envir:-"prod"} @@ -132,7 +132,7 @@ export SENDDBN=${SENDDBN:-"NO"} export DBNROOT=${DBNROOT:-${UTILROOT:-}/fakedbn} # APP settings -export APP=@APP@ +export APP="{{ APP }}" # Defaults: export DO_ATM="YES" @@ -140,7 +140,7 @@ export DO_COUPLED="NO" export DO_WAVE="NO" export DO_OCN="NO" export DO_ICE="NO" -export DO_EXTRACTVARS="@DO_EXTRACTVARS@" # Option to process and extract a subset of products to save on disk +export DO_EXTRACTVARS="{{ DO_EXTRACTVARS }}" # Option to process and extract a subset of products to save on disk export DO_AERO_FCST="NO" export DOBNDPNT_WAVE="NO" # The GEFS buoys file does not currently have any boundary points export DOIBP_WAV="NO" # Option to create point outputs from input boundary points @@ -158,9 +158,9 @@ export OPS_RES="C768" # Do not change # Resolution specific parameters export LEVS=128 -export CASE="@CASECTL@" # CASE is required in GEFS to determine ocean/ice/wave resolutions -export CASE_ENS="@CASEENS@" -export OCNRES="@OCNRES@" +export CASE="{{ CASE_CTL }}" # CASE is required in GEFS to determine ocean/ice/wave resolutions +export CASE_ENS="{{ CASE_ENS }}" +export OCNRES="{{ OCNRES }}" export ICERES="${OCNRES}" # These are the currently recommended grid-combinations case "${CASE}" in @@ -225,11 +225,11 @@ export FHOUT_ICE=3 export FHOUT_AERO=3 # GFS cycle info -export INTERVAL_GFS=@INTERVAL_GFS@ # Frequency of GFS forecast -export SDATE_GFS=@SDATE_GFS@ +export INTERVAL_GFS="{{ INTERVAL_GFS }}" # Frequency of GFS forecast +export SDATE_GFS="{{ SDATE_GFS }}" # set variables needed for use with REPLAY ICs -export REPLAY_ICS=@REPLAY_ICS@ +export REPLAY_ICS="{{ REPLAY_ICS }}" if [[ "${REPLAY_ICS:-NO}" == "YES" ]]; then export OFFSET_START_HOUR=$(( assim_freq / 2 )) echo "WARNING: Replay ICs require perturbation files, ignoring any previous settings" @@ -237,22 +237,22 @@ if [[ "${REPLAY_ICS:-NO}" == "YES" ]]; then export USE_ATM_ENS_PERTURB_FILES="YES" else export OFFSET_START_HOUR=0 - export USE_OCN_ENS_PERTURB_FILES=@USE_OCN_ENS_PERTURB_FILES@ - export USE_ATM_ENS_PERTURB_FILES=@USE_ATM_ENS_PERTURB_FILES@ + export USE_OCN_ENS_PERTURB_FILES="{{ USE_OCN_ENS_PERTURB_FILES }}" + export USE_ATM_ENS_PERTURB_FILES="{{ USE_ATM_ENS_PERTURB_FILES }}" fi # GFS output and frequency export FHMIN_GFS=0 -export FHMAX_GFS="@FHMAX_GFS@" +export FHMAX_GFS="{{ FHMAX_GFS }}" # Intermediate times to stop forecast when running in segments -breakpnts="@FCST_BREAKPOINTS@" +breakpnts="{{ FCST_BREAKPOINTS }}" export FCST_SEGMENTS="${FHMIN_GFS},${breakpnts:+${breakpnts},}${FHMAX_GFS}" -export FHOUT_GFS=@FHOUT_GFS@ -export FHMAX_HF_GFS=@FHMAX_HF_GFS@ -export FHOUT_HF_GFS=@FHOUT_HF_GFS@ -export FHOUT_OCN_GFS=@FHOUT_OCN_GFS@ -export FHOUT_ICE_GFS=@FHOUT_ICE_GFS@ +export FHOUT_GFS="{{ FHOUT_GFS }}" +export FHMAX_HF_GFS="{{ FHMAX_HF_GFS }}" +export FHOUT_HF_GFS="{{ FHOUT_HF_GFS }}" +export FHOUT_OCN_GFS="{{ FHOUT_OCN_GFS }}" +export FHOUT_ICE_GFS="{{ FHOUT_ICE_GFS }}" export FHMIN_WAV=${OFFSET_START_HOUR:-0} export FHOUT_WAV=3 export FHMAX_HF_WAV=120 @@ -295,7 +295,7 @@ export DO_MERGENSST="NO" export DO_STARTMEM_FROM_JEDIICE="NO" # Hybrid related -export NMEM_ENS=@NMEM_ENS@ +export NMEM_ENS="{{ NMEM_ENS }}" # set default member number memdir for control # this will be overwridden for the perturbed members @@ -328,21 +328,21 @@ if [[ ${DONST} = "YES" ]]; then export FNTSFA=" "; fi export nst_anl=.true. # Make the nsstbufr file on the fly or use the GDA version -export MAKE_NSSTBUFR="@MAKE_NSSTBUFR@" +export MAKE_NSSTBUFR="{{ MAKE_NSSTBUFR }}" # Make the aircraft prepbufr file on the fly or use the GDA version -export MAKE_ACFTBUFR="@MAKE_ACFTBUFR@" +export MAKE_ACFTBUFR="{{ MAKE_ACFTBUFR }}" # Verification options export DO_METP="NO" # Run METPLUS jobs - set METPLUS settings in config.metp export DO_FIT2OBS="NO" # Run fit to observations package # Archiving options -export DO_ARCHCOM="@DO_ARCHCOM@" # Tar and archive the COM directories -export ARCHCOM_TO="@ARCHCOM_TO@" # Valid options are hpss, globus_hpss, and local +export DO_ARCHCOM="{{ DO_ARCHCOM }}" # Tar and archive the COM directories +export ARCHCOM_TO="{{ ARCHCOM_TO }}" # Valid options are hpss, globus_hpss, and local # Globus UUID for this machine -export CLIENT_GLOBUS_UUID='@CLIENT_GLOBUS_UUID@' +export CLIENT_GLOBUS_UUID="{{ CLIENT_GLOBUS_UUID }}" # Number of regional collectives to create soundings for export NUM_SND_COLLECTIVES=${NUM_SND_COLLECTIVES:-9} diff --git a/parm/config/gefs/config.fcst b/parm/config/gefs/config.fcst.j2 similarity index 98% rename from parm/config/gefs/config.fcst rename to parm/config/gefs/config.fcst.j2 index fd5494eecbf..10f9006932e 100644 --- a/parm/config/gefs/config.fcst +++ b/parm/config/gefs/config.fcst.j2 @@ -40,7 +40,7 @@ export FHOUT=${FHOUT_GFS} export FHOUT_HF=${FHOUT_HF_GFS} export FHOUT_OCN=${FHOUT_OCN_GFS} export FHOUT_ICE=${FHOUT_ICE_GFS} -export FHZER=@FHZER@ +export FHZER="{{ FHZER }}" # Get task specific resources source "${EXPDIR}/config.resources" fcst @@ -63,8 +63,8 @@ export FCSTEXEC="${NET}_model.x" ####################################################################### # Model configuration -export TYPE=@TYPE@ -export MONO=@MONO@ +export TYPE="{{ TYPE }}" +export MONO="{{ MONO }}" # Use stratosphere h2o physics export h2o_phys=".true." @@ -276,7 +276,7 @@ else export io_layout="1,1" fi -export reforecast=@reforecast@ +export reforecast="{{ reforecast }}" # Remember config.efcs will over-ride these values for ensemble forecasts # if these variables are re-defined there. # Otherwise, the ensemble forecast will inherit from config.fcst diff --git a/parm/config/gefs/config.ocn b/parm/config/gefs/config.ocn deleted file mode 120000 index d9ab25be5ed..00000000000 --- a/parm/config/gefs/config.ocn +++ /dev/null @@ -1 +0,0 @@ -../gfs/config.ocn \ No newline at end of file diff --git a/parm/config/gefs/config.ocn.j2 b/parm/config/gefs/config.ocn.j2 new file mode 120000 index 00000000000..ea0cee74dcc --- /dev/null +++ b/parm/config/gefs/config.ocn.j2 @@ -0,0 +1 @@ +../gfs/config.ocn.j2 \ No newline at end of file diff --git a/parm/config/gefs/config.stage_ic b/parm/config/gefs/config.stage_ic.j2 similarity index 84% rename from parm/config/gefs/config.stage_ic rename to parm/config/gefs/config.stage_ic.j2 index 0dd76679a23..e3ea01a1c23 100644 --- a/parm/config/gefs/config.stage_ic +++ b/parm/config/gefs/config.stage_ic.j2 @@ -7,8 +7,8 @@ echo "BEGIN: config.stage_ic" # Get task specific resources source "${EXPDIR}/config.resources" stage_ic -export ICSDIR="@ICSDIR@" # User provided ICSDIR; blank if not provided -export BASE_IC="@BASE_IC@" # Platform home for staged ICs +export ICSDIR="{{ ICSDIR }}" # User provided ICSDIR; blank if not provided +export BASE_IC="{{ BASE_IC }}" # Platform home for staged ICs export STAGE_IC_YAML_TMPL="${PARMgfs}/stage/master_gefs.yaml.j2" diff --git a/parm/config/gfs/config.aero b/parm/config/gfs/config.aero.j2 similarity index 95% rename from parm/config/gfs/config.aero rename to parm/config/gfs/config.aero.j2 index bbfb782636c..1d6dc07ef63 100644 --- a/parm/config/gfs/config.aero +++ b/parm/config/gfs/config.aero.j2 @@ -3,7 +3,7 @@ # UFS-Aerosols settings # Path to the input data tree -export AERO_INPUTS_DIR=@AERO_INPUTS_DIR@ +export AERO_INPUTS_DIR="{{ AERO_INPUTS_DIR }}" export AERO_DIAG_TABLE="${PARMgfs}/ufs/fv3/diag_table.aero" export AERO_FIELD_TABLE="${PARMgfs}/ufs/fv3/field_table.aero" diff --git a/parm/config/gfs/config.aeroanl b/parm/config/gfs/config.aeroanl.j2 similarity index 94% rename from parm/config/gfs/config.aeroanl rename to parm/config/gfs/config.aeroanl.j2 index 591d9490ee7..76813213a6e 100644 --- a/parm/config/gfs/config.aeroanl +++ b/parm/config/gfs/config.aeroanl.j2 @@ -31,8 +31,8 @@ export JEDI_CONFIG_YAML="${PARMgfs}/gdas/aeroanl_jedi_config.yaml.j2" export AERO_STAGE_VARIATIONAL_TMPL="${PARMgfs}/gdas/aero_stage_variational.yaml.j2" export AERO_FINALIZE_VARIATIONAL_TMPL="${PARMgfs}/gdas/aero_finalize_variational.yaml.j2" -export io_layout_x=@IO_LAYOUT_X@ -export io_layout_y=@IO_LAYOUT_Y@ +export io_layout_x="{{ IO_LAYOUT_X }}" +export io_layout_y="{{ IO_LAYOUT_Y }}" export JEDIEXE="${EXECgfs}/gdas.x" diff --git a/parm/config/gfs/config.atmanl b/parm/config/gfs/config.atmanl.j2 similarity index 75% rename from parm/config/gfs/config.atmanl rename to parm/config/gfs/config.atmanl.j2 index df35a41d893..0c35fabb5c3 100644 --- a/parm/config/gfs/config.atmanl +++ b/parm/config/gfs/config.atmanl.j2 @@ -5,10 +5,10 @@ echo "BEGIN: config.atmanl" -export JCB_ALGO_YAML_VAR=@JCB_ALGO_YAML_VAR@ -export JCB_ALGO_YAML_FV3INC=@JCB_ALGO_YAML_FV3INC@ +export JCB_ALGO_YAML_VAR="{{ JCB_ALGO_YAML_VAR }}" +export JCB_ALGO_YAML_FV3INC="{{ JCB_ALGO_YAML_FV3INC }}" -export STATICB_TYPE=@STATICB_TYPE@ +export STATICB_TYPE="{{ STATICB_TYPE }}" export LOCALIZATION_TYPE="bump" export INTERP_METHOD='barycentric' @@ -29,10 +29,10 @@ export VAR_BKG_STAGING_YAML="${PARMgfs}/gdas/staging/atm_var_bkg.yaml.j2" export BERROR_STAGING_YAML="${PARMgfs}/gdas/staging/atm_berror_${STATICB_TYPE}.yaml.j2" export FV3ENS_STAGING_YAML="${PARMgfs}/gdas/staging/atm_var_fv3ens.yaml.j2" -export layout_x_atmanl=@LAYOUT_X_ATMANL@ -export layout_y_atmanl=@LAYOUT_Y_ATMANL@ +export layout_x_atmanl="{{ LAYOUT_X_ATMANL }}" +export layout_y_atmanl="{{ LAYOUT_Y_ATMANL }}" -export io_layout_x=@IO_LAYOUT_X@ -export io_layout_y=@IO_LAYOUT_Y@ +export io_layout_x="{{ IO_LAYOUT_X }}" +export io_layout_y="{{ IO_LAYOUT_Y }}" echo "END: config.atmanl" diff --git a/parm/config/gfs/config.atmensanl b/parm/config/gfs/config.atmensanl.j2 similarity index 55% rename from parm/config/gfs/config.atmensanl rename to parm/config/gfs/config.atmensanl.j2 index 77f5e2ee867..2ab784b3a86 100644 --- a/parm/config/gfs/config.atmensanl +++ b/parm/config/gfs/config.atmensanl.j2 @@ -5,10 +5,10 @@ echo "BEGIN: config.atmensanl" -export JCB_ALGO_YAML_LETKF=@JCB_ALGO_YAML_LETKF@ -export JCB_ALGO_YAML_OBS=@JCB_ALGO_YAML_OBS@ -export JCB_ALGO_YAML_SOL=@JCB_ALGO_YAML_SOL@ -export JCB_ALGO_YAML_FV3INC=@JCB_ALGO_YAML_FV3INC@ +export JCB_ALGO_YAML_LETKF="{{ JCB_ALGO_YAML_LETKF }}" +export JCB_ALGO_YAML_OBS="{{ JCB_ALGO_YAML_OBS }}" +export JCB_ALGO_YAML_SOL="{{ JCB_ALGO_YAML_SOL }}" +export JCB_ALGO_YAML_FV3INC="{{ JCB_ALGO_YAML_FV3INC }}" export INTERP_METHOD='barycentric' @@ -18,10 +18,10 @@ export JEDI_FIX_YAML="${PARMgfs}/gdas/atm_jedi_fix.yaml.j2" export JEDI_CONFIG_YAML="${PARMgfs}/gdas/atmensanl_jedi_config.yaml.j2" export LGETKF_BKG_STAGING_YAML="${PARMgfs}/gdas/staging/atm_lgetkf_bkg.yaml.j2" -export layout_x_atmensanl=@LAYOUT_X_ATMENSANL@ -export layout_y_atmensanl=@LAYOUT_Y_ATMENSANL@ +export layout_x_atmensanl="{{ LAYOUT_X_ATMENSANL }}" +export layout_y_atmensanl="{{ LAYOUT_Y_ATMENSANL }}" -export io_layout_x=@IO_LAYOUT_X@ -export io_layout_y=@IO_LAYOUT_Y@ +export io_layout_x="{{ IO_LAYOUT_X }}" +export io_layout_y="{{ IO_LAYOUT_Y }}" echo "END: config.atmensanl" diff --git a/parm/config/gfs/config.base b/parm/config/gfs/config.base.j2 similarity index 75% rename from parm/config/gfs/config.base rename to parm/config/gfs/config.base.j2 index b76e5fed8a7..e1dae0d87de 100644 --- a/parm/config/gfs/config.base +++ b/parm/config/gfs/config.base.j2 @@ -6,29 +6,29 @@ echo "BEGIN: config.base" # Machine environment -export machine="@MACHINE@" +export machine="{{ MACHINE }}" # EMC parallel or NCO production export RUN_ENVIR="emc" # Account, queue, etc. -export ACCOUNT="@ACCOUNT@" -export QUEUE="@QUEUE@" -export QUEUE_SERVICE="@QUEUE_SERVICE@" -export QUEUE_DTN="@QUEUE_DTN@" -export PARTITION_BATCH="@PARTITION_BATCH@" -export PARTITION_SERVICE="@PARTITION_SERVICE@" -export PARTITION_DTN="@PARTITION_DTN@" -export RESERVATION="@RESERVATION@" -export CLUSTERS="@CLUSTERS@" -export CLUSTERS_SERVICE="@CLUSTERS_SERVICE@" -export CLUSTERS_DTN="@CLUSTERS_DTN@" +export ACCOUNT="{{ ACCOUNT }}" +export QUEUE="{{ QUEUE }}" +export QUEUE_SERVICE="{{ QUEUE_SERVICE | default('${QUEUE}') }}" +export QUEUE_DTN="{{ QUEUE_DTN | default('${QUEUE_SERVICE}') }}" +export PARTITION_BATCH="{{ PARTITION_BATCH }}" +export PARTITION_SERVICE="{{ PARTITION_SERVICE | default() }}" +export PARTITION_DTN="{{ PARTITION_DTN | default() }}" +export RESERVATION="{{ RESERVATION | default() }}" +export CLUSTERS="{{ CLUSTERS | default() }}" +export CLUSTERS_SERVICE="{{ CLUSTERS_SERVICE | default('${CLUSTERS}') }}" +export CLUSTERS_DTN="{{ CLUSTERS_DTN | default('${CLUSTERS_SERVICE}') }}" # Project to use in mass store: -export HPSS_PROJECT="@HPSS_PROJECT@" +export HPSS_PROJECT="{{ HPSS_PROJECT }}" # Directories relative to installation areas: -export HOMEgfs=@HOMEgfs@ +export HOMEgfs="{{ HOMEgfs }}" export EXECgfs="${HOMEgfs}/exec" export FIXgfs="${HOMEgfs}/fix" export PARMgfs="${HOMEgfs}/parm" @@ -47,38 +47,38 @@ export FIXgdas="${FIXgfs}/gdas" ######################################################################## # GLOBAL static environment parameters -export PACKAGEROOT="@PACKAGEROOT@" # TODO: set via prod_envir in Ops -export COMROOT="@COMROOT@" # TODO: set via prod_envir in Ops -export COMINsyn="@COMINsyn@" -export DMPDIR="@DMPDIR@" +export PACKAGEROOT="{{ PACKAGEROOT }}" # TODO: set via prod_envir in Ops +export COMROOT="{{ COMROOT }}" # TODO: set via prod_envir in Ops +export COMINsyn="{{ COMINsyn }}" +export DMPDIR="{{ DMPDIR }}" # Gempak from external models # Default locations are to dummy locations for testing -export COMINecmwf=@COMINecmwf@ -export COMINnam=@COMINnam@ -export COMINukmet=@COMINukmet@ +export COMINecmwf="{{ COMINecmwf }}" +export COMINnam="{{ COMINnam }}" +export COMINukmet="{{ COMINukmet }}" # USER specific paths -export HOMEDIR="@HOMEDIR@" -export STMP="@STMP@" -export PTMP="@PTMP@" -export NOSCRUB="@NOSCRUB@" +export HOMEDIR="{{ HOMEDIR }}" +export STMP="{{ STMP }}" +export PTMP="{{ PTMP }}" +export NOSCRUB="{{ NOSCRUB }}" # Base directories for various builds -export BASE_GIT="@BASE_GIT@" +export BASE_GIT="{{ BASE_GIT }}" # Base directory for staged data -export BASE_DATA="@BASE_DATA@" +export BASE_DATA="{{ BASE_DATA }}" # Toggle to turn on/off GFS downstream processing. -export DO_GOES="@DO_GOES@" # GOES products -export DO_BUFRSND="@DO_BUFRSND@" # BUFR sounding products -export DO_GEMPAK="@DO_GEMPAK@" # GEMPAK products -export DO_AWIPS="@DO_AWIPS@" # AWIPS products -export DO_NPOESS="@DO_NPOESS@" # NPOESS products -export DO_TRACKER="@DO_TRACKER@" # Hurricane track verification -export DO_GENESIS="@DO_GENESIS@" # Cyclone genesis verification -export DO_GENESIS_FSU="@DO_GENESIS_FSU@" # Cyclone genesis verification (FSU) +export DO_GOES="{{ DO_GOES }}" # GOES products +export DO_BUFRSND="{{ DO_BUFRSND }}" # BUFR sounding products +export DO_GEMPAK="{{ DO_GEMPAK }}" # GEMPAK products +export DO_AWIPS="{{ DO_AWIPS }}" # AWIPS products +export DO_NPOESS="{{ DO_NPOESS }}" # NPOESS products +export DO_TRACKER="{{ DO_TRACKER }}" # Hurricane track verification +export DO_GENESIS="{{ DO_GENESIS }}" # Cyclone genesis verification +export DO_GENESIS_FSU="{{ DO_GENESIS_FSU }}" # Cyclone genesis verification (FSU) export DO_VERFOZN="YES" # Ozone data assimilation monitoring export DO_VERFRAD="YES" # Radiance data assimilation monitoring export DO_VMINMON="YES" # GSI minimization monitoring @@ -91,8 +91,8 @@ export DO_MOS="NO" # GFS Model Output Statistics - Only su export REALTIME="YES" # Experiment mode (cycled or forecast-only) -export MODE="@MODE@" # cycled/forecast-only -export DO_TEST_MODE="@DO_TEST_MODE@" # option to change configuration for automated testing +export MODE="{{ MODE }}" # cycled/forecast-only +export DO_TEST_MODE="{{ DO_TEST_MODE }}" # option to change configuration for automated testing #################################################### # DO NOT ADD MACHINE DEPENDENT STUFF BELOW THIS LINE @@ -112,8 +112,8 @@ export NLN="/bin/ln -sf" export VERBOSE="YES" export KEEPDATA="NO" export DEBUG_POSTSCRIPT="NO" # PBS only; sets debug=true -export CHGRP_RSTPROD="@CHGRP_RSTPROD@" -export CHGRP_CMD="@CHGRP_CMD@" +export CHGRP_RSTPROD="{{ CHGRP_RSTPROD }}" +export CHGRP_CMD="{{ CHGRP_CMD }}" export NCDUMP="${NETCDF:-${netcdf_c_ROOT:-}}/bin/ncdump" export NCLEN="${HOMEgfs}/ush/getncdimlen" @@ -122,21 +122,21 @@ export BASE_ENV="${HOMEgfs}/env" export BASE_JOB="${HOMEgfs}/jobs/rocoto" # EXPERIMENT specific environment parameters -export SDATE=@SDATE@ -export EDATE=@EDATE@ -export EXP_WARM_START="@EXP_WARM_START@" +export SDATE="{{ SDATE }}" +export EDATE="{{ EDATE }}" +export EXP_WARM_START="{{ EXP_WARM_START }}" export assim_freq=6 -export PSLOT="@PSLOT@" -export EXPDIR="@EXPDIR@/${PSLOT}" -export ROTDIR="@COMROOT@/${PSLOT}" +export PSLOT="{{ PSLOT }}" +export EXPDIR="{{ EXPDIR }}/${PSLOT}" +export ROTDIR="{{ COMROOT }}/${PSLOT}" export ROTDIR_DUMP="YES" #Note: A value of "NO" does not currently work export DUMP_SUFFIX="" if [[ "${PDY}${cyc}" -ge "2019092100" && "${PDY}${cyc}" -le "2019110700" ]]; then export DUMP_SUFFIX="p" # Use dumps from NCO GFS v15.3 parallel fi export ARCDIR="${NOSCRUB}/archive/${PSLOT}" -export ATARDIR="@ATARDIR@" -export FETCHDIR="@FETCHDIR@" +export ATARDIR="{{ ATARDIR }}" +export FETCHDIR="{{ FETCHDIR }}" # Commonly defined parameters in JJOBS export envir=${envir:-"prod"} @@ -161,7 +161,7 @@ export SENDDBN=${SENDDBN:-"NO"} export DBNROOT=${DBNROOT:-${UTILROOT:-}/fakedbn} # APP settings -export APP=@APP@ +export APP="{{ APP }}" shopt -s extglob # Adjust APP based on RUN @@ -207,9 +207,9 @@ export OPS_RES="C768" # Do not change # TODO: Why is this needed and where is it # Resolution specific parameters export LEVS=128 -export CASE="@CASECTL@" -export CASE_ENS="@CASEENS@" -export OCNRES="@OCNRES@" +export CASE="{{ CASE_CTL }}" +export CASE_ENS="{{ CASE_ENS }}" +export OCNRES="{{ OCNRES }}" export ICERES="${OCNRES}" # These are the currently recommended grid-combinations @@ -293,20 +293,20 @@ export FHOUT_ICE=3 export FHOUT_AERO=3 # Cycle to run EnKF (set to BOTH for both gfs and gdas) -export EUPD_CYC="@EUPD_CYC@" +export EUPD_CYC="{{ EUPD_CYC }}" # GFS cycle info -export INTERVAL_GFS=@INTERVAL_GFS@ # Frequency of GFS forecast -export SDATE_GFS=@SDATE_GFS@ +export INTERVAL_GFS="{{ INTERVAL_GFS }}" # Frequency of GFS forecast +export SDATE_GFS="{{ SDATE_GFS }}" # GFS output and frequency export FHMIN_GFS=0 -export FHMAX_GFS="@FHMAX_GFS@" +export FHMAX_GFS="{{ FHMAX_GFS }}" # Intermediate times to stop forecast when running in segments -breakpnts="@FCST_BREAKPOINTS@" +breakpnts="{{ FCST_BREAKPOINTS }}" export FCST_SEGMENTS="${FHMIN_GFS},${breakpnts:+${breakpnts},}${FHMAX_GFS}" export FHOUT_GFS=3 # 3 for ops -export FHMAX_HF_GFS=@FHMAX_HF_GFS@ +export FHMAX_HF_GFS="{{ FHMAX_HF_GFS }}" export FHOUT_HF_GFS=1 export FHOUT_OCN_GFS=6 export FHOUT_ICE_GFS=6 @@ -346,7 +346,7 @@ export WRITE_DOPOST=".true." # WRITE_DOPOST=true, use inline POST export WRITE_NSFLIP=".true." # IAU related parameters -export DOIAU="@DOIAU@" # Enable 4DIAU for control with 3 increments +export DOIAU="{{ DOIAU }}" # Enable 4DIAU for control with 3 increments export IAUFHRS="3,6,9" export IAU_FHROT=${IAUFHRS%%,*} export IAU_DELTHRS=6 @@ -368,33 +368,33 @@ export imp_physics=8 # Shared parameters # DA engine -export DO_JEDIATMVAR="@DO_JEDIATMVAR@" -export DO_JEDIATMENS="@DO_JEDIATMENS@" -export DO_JEDIOCNVAR="@DO_JEDIOCNVAR@" -export DO_JEDISNOWDA="@DO_JEDISNOWDA@" -export DO_MERGENSST="@DO_MERGENSST@" -export DO_STARTMEM_FROM_JEDIICE="@DO_STARTMEM_FROM_JEDIICE@" +export DO_JEDIATMVAR="{{ DO_JEDIATMVAR }}" +export DO_JEDIATMENS="{{ DO_JEDIATMENS }}" +export DO_JEDIOCNVAR="{{ DO_JEDIOCNVAR }}" +export DO_JEDISNOWDA="{{ DO_JEDISNOWDA }}" +export DO_MERGENSST="{{ DO_MERGENSST }}" +export DO_STARTMEM_FROM_JEDIICE="{{ DO_STARTMEM_FROM_JEDIICE }}" # Hybrid related -export DOHYBVAR="@DOHYBVAR@" -export DOHYBVAR_OCN="@DOHYBVAR_OCN@" -export DOLETKF_OCN="@DOLETKF_OCN@" -export NMEM_ENS=@NMEM_ENS@ +export DOHYBVAR="{{ DOHYBVAR }}" +export DOHYBVAR_OCN="{{ DOHYBVAR_OCN }}" +export DOLETKF_OCN="{{ DOLETKF_OCN }}" +export NMEM_ENS="{{ NMEM_ENS }}" export SMOOTH_ENKF="NO" export l4densvar=".true." export lwrite4danl=".true." export DO_CALC_INCREMENT="NO" # Early-cycle EnKF parameters -export NMEM_ENS_GFS=30 -export NMEM_ENS_GFS_OFFSET=20 +export NMEM_ENS_GFS="{{ NMEM_ENS_GFS }}" +export NMEM_ENS_GFS_OFFSET="{{ NMEM_ENS_GFS_OFFSET }}" export DO_CALC_INCREMENT_ENKF_GFS="NO" # EnKF output frequency -if [[ ${DOHYBVAR} = "YES" ]]; then +if [[ "${DOHYBVAR}" = "YES" ]]; then export FHMIN_ENKF=3 export FHMAX_ENKF=9 - export FHMAX_ENKF_GFS=@FHMAX_ENKF_GFS@ + export FHMAX_ENKF_GFS="{{ FHMAX_ENKF_GFS }}" export FHOUT_ENKF_GFS=3 if [[ ${l4densvar} = ".true." ]]; then export FHOUT=1 @@ -440,20 +440,20 @@ else export restart_interval_gdas="6" fi -export DO_GSISOILDA=@DO_GSISOILDA@ +export DO_GSISOILDA="{{ DO_GSISOILDA }}" # turned on nsst in anal and/or fcst steps, and turn off rtgsst export DONST="YES" -if [[ ${DONST} = "YES" ]]; then export FNTSFA=" "; fi +if [[ "${DONST}" = "YES" ]]; then export FNTSFA=" "; fi # The switch to apply SST elevation correction or not export nst_anl=.true. # Make the nsstbufr file on the fly or use the GDA version -export MAKE_NSSTBUFR="@MAKE_NSSTBUFR@" +export MAKE_NSSTBUFR="{{ MAKE_NSSTBUFR }}" # Make the aircraft prepbufr file on the fly or use the GDA version -export MAKE_ACFTBUFR="@MAKE_ACFTBUFR@" +export MAKE_ACFTBUFR="{{ MAKE_ACFTBUFR }}" # Analysis increments to zero in CALCINCEXEC export INCREMENTS_TO_ZERO="'liq_wat_inc','icmr_inc','rwmr_inc','snmr_inc','grle_inc'" @@ -472,7 +472,7 @@ export binary_diag=".false." export DO_CA="YES" # Verification options -export DO_METP="@DO_METP@" # Run METPLUS jobs - set METPLUS settings in config.metp +export DO_METP="{{ DO_METP }}" # Run METPLUS jobs - set METPLUS settings in config.metp export DO_FIT2OBS="YES" # Run fit to observations package #--online archive of netcdf files for fit2obs verification @@ -482,19 +482,19 @@ if [[ "${FHMAX_FITS}" -gt "${FHMAX_GFS}" ]]; then fi # IC fetching options -# TODO replace these options with DO_FETCH and FETCH_FROM +# TODO: replace these options with DO_FETCH and FETCH_FROM export DO_FETCH_HPSS="NO" # Copy from HPSS (on HPSS-accessible machines) onto COM export DO_FETCH_LOCAL="NO" # Copy from local disk onto COM # Archiving options -export DO_ARCHCOM="@DO_ARCHCOM@" # Tar and archive the COM directories -export ARCHCOM_TO="@ARCHCOM_TO@" # Valid options are hpss, globus_hpss, and local +export DO_ARCHCOM="{{ DO_ARCHCOM }}" # Tar and archive the COM directories +export ARCHCOM_TO="{{ ARCHCOM_TO }}" # Valid options are hpss, globus_hpss, and local # Globus UUID for this machine -export CLIENT_GLOBUS_UUID='@CLIENT_GLOBUS_UUID@' +export CLIENT_GLOBUS_UUID="{{ CLIENT_GLOBUS_UUID }}" # The monitor jobs are not yet supported for JEDIATMVAR. -if [[ ${DO_JEDIATMVAR} = "YES" ]]; then +if [[ "${DO_JEDIATMVAR}" = "YES" ]]; then export DO_FIT2OBS="NO" # Run fit to observations package export DO_VERFOZN="NO" # Ozone data assimilation monitoring export DO_VERFRAD="NO" # Radiance data assimilation monitoring diff --git a/parm/config/gfs/config.esnowanl b/parm/config/gfs/config.esnowanl.j2 similarity index 94% rename from parm/config/gfs/config.esnowanl rename to parm/config/gfs/config.esnowanl.j2 index dde89704820..fb5753a3711 100644 --- a/parm/config/gfs/config.esnowanl +++ b/parm/config/gfs/config.esnowanl.j2 @@ -32,7 +32,7 @@ export ENS_APPLY_INCR_NML_TMPL="${PARMgfs}/gdas/snow/ens_apply_incr_nml.j2" export JEDI_CONFIG_YAML="${PARMgfs}/gdas/esnowanl_jedi_config.yaml.j2" -export io_layout_x=@IO_LAYOUT_X@ -export io_layout_y=@IO_LAYOUT_Y@ +export io_layout_x="{{ IO_LAYOUT_X }}" +export io_layout_y="{{ IO_LAYOUT_Y }}" echo "END: config.esnowanl" diff --git a/parm/config/gfs/config.marineanl b/parm/config/gfs/config.marineanl.j2 similarity index 78% rename from parm/config/gfs/config.marineanl rename to parm/config/gfs/config.marineanl.j2 index e3dcc4529ea..51e42221db9 100644 --- a/parm/config/gfs/config.marineanl +++ b/parm/config/gfs/config.marineanl.j2 @@ -6,13 +6,13 @@ echo "BEGIN: config.marineanl" export JEDI_CONFIG_YAML="${PARMgfs}/gdas/soca_bmat_jedi_config.yaml.j2" -export JCB_ALGO_YAML_VAR=@JCB_ALGO_YAML_VAR@ +export JCB_ALGO_YAML_VAR="{{ JCB_ALGO_YAML_VAR }}" export MARINE_OBS_YAML_DIR="${PARMgfs}/gdas/soca/obs/config" -export MARINE_OBS_LIST_YAML=@SOCA_OBS_LIST@ -export SOCA_INPUT_FIX_DIR=@SOCA_INPUT_FIX_DIR@ -export SOCA_ANL_GEOM=@SOCA_ANL_GEOM@ -export SOCA_NINNER=@SOCA_NINNER@ +export MARINE_OBS_LIST_YAML="{{ SOCA_OBS_LIST }}" +export SOCA_INPUT_FIX_DIR="{{ SOCA_INPUT_FIX_DIR }}" +export SOCA_ANL_GEOM="{{ SOCA_ANL_GEOM }}" +export SOCA_NINNER="{{ SOCA_NINNER }}" export DOMAIN_STACK_SIZE=116640000 #TODO: Make the stack size resolution dependent export SOCA_ENS_BKG_STAGE_YAML_TMPL="${PARMgfs}/gdas/soca/soca_ens_bkg_stage.yaml.j2" export SOCA_FIX_YAML_TMPL="${PARMgfs}/gdas/soca/soca_fix_stage_${OCNRES}.yaml.j2" diff --git a/parm/config/gfs/config.ocn b/parm/config/gfs/config.ocn.j2 similarity index 95% rename from parm/config/gfs/config.ocn rename to parm/config/gfs/config.ocn.j2 index f7c7559f9a5..b9669be2c8a 100644 --- a/parm/config/gfs/config.ocn +++ b/parm/config/gfs/config.ocn.j2 @@ -24,7 +24,7 @@ else export ODA_INCUPD_NHOURS="3.0" fi -MOM6_INTERP_ICS=@MOM6_INTERP_ICS@ +MOM6_INTERP_ICS="{{ MOM6_INTERP_ICS }}" if [[ "${MOM6_INTERP_ICS}" == "YES" ]]; then export MOM6_RESTART_SETTING='n' export MOM6_WARMSTART_FILE="MOM.res.nc" diff --git a/parm/config/gfs/config.prepoceanobs b/parm/config/gfs/config.prepoceanobs.j2 similarity index 67% rename from parm/config/gfs/config.prepoceanobs rename to parm/config/gfs/config.prepoceanobs.j2 index 3aeff8a3de5..cda489bc26f 100644 --- a/parm/config/gfs/config.prepoceanobs +++ b/parm/config/gfs/config.prepoceanobs.j2 @@ -4,19 +4,19 @@ echo "BEGIN: config.prepoceanobs" -export OCNOBS2IODAEXEC=${HOMEgfs}/sorc/gdas.cd/build/bin/gdas_obsprovider2ioda.x +export OCNOBS2IODAEXEC="${HOMEgfs}/sorc/gdas.cd/build/bin/gdas_obsprovider2ioda.x" -export SOCA_INPUT_FIX_DIR=@SOCA_INPUT_FIX_DIR@ +export SOCA_INPUT_FIX_DIR="{{ SOCA_INPUT_FIX_DIR }}" export MARINE_OBS_YAML_DIR="${PARMgfs}/gdas/soca/obs/config" -export OBSPREP_YAML=@OBSPREP_YAML@ -export OBS_LIST=@SOCA_OBS_LIST@ +export OBSPREP_YAML="{{ OBSPREP_YAML }}" +export OBS_LIST="{{ SOCA_OBS_LIST }}" export OBS_YAML=${OBS_LIST} # ocean analysis needs own dmpdir until standard dmpdir has full ocean obs -use_exp_obs="@use_exp_obs@" +use_exp_obs="{{ use_exp_obs }}" if [[ "${use_exp_obs}" == "YES" ]]; then - dmpdir_exp="@dmpdir_exp@" + dmpdir_exp="{{ dmpdir_exp }}" fi export DMPDIR="${dmpdir_exp:-${DMPDIR}}" diff --git a/parm/config/gfs/config.snowanl b/parm/config/gfs/config.snowanl.j2 similarity index 94% rename from parm/config/gfs/config.snowanl rename to parm/config/gfs/config.snowanl.j2 index 67a4fc012fd..02698eb9cc2 100644 --- a/parm/config/gfs/config.snowanl +++ b/parm/config/gfs/config.snowanl.j2 @@ -32,7 +32,7 @@ export JEDI_CONFIG_YAML="${PARMgfs}/gdas/snowanl_jedi_config.yaml.j2" export JEDIEXE=${EXECgfs}/gdas.x -export io_layout_x=@IO_LAYOUT_X@ -export io_layout_y=@IO_LAYOUT_Y@ +export io_layout_x="{{ IO_LAYOUT_X }}" +export io_layout_y="{{ IO_LAYOUT_Y }}" echo "END: config.snowanl" diff --git a/parm/config/gfs/config.stage_ic b/parm/config/gfs/config.stage_ic.j2 similarity index 87% rename from parm/config/gfs/config.stage_ic rename to parm/config/gfs/config.stage_ic.j2 index 3fb0663cb7b..7b7fce0e08a 100644 --- a/parm/config/gfs/config.stage_ic +++ b/parm/config/gfs/config.stage_ic.j2 @@ -10,10 +10,10 @@ source "${EXPDIR}/config.resources" stage_ic if [[ "${DO_FETCH_HPSS^^}" =~ "Y" || "${DO_FETCH_LOCAL^^}" =~ "Y" ]]; then export ICSDIR="${DATAROOT}" # fetch untars data into DATAROOT else - export ICSDIR="@ICSDIR@" # User provided ICSDIR; blank if not provided + export ICSDIR="{{ ICSDIR }}" # User provided ICSDIR; blank if not provided fi -export BASE_IC="@BASE_IC@" # Platform home for staged ICs +export BASE_IC="{{ BASE_IC }}" # Platform home for staged ICs export STAGE_IC_YAML_TMPL="${PARMgfs}/stage/master_gfs.yaml.j2" diff --git a/parm/config/gfs/yaml/defaults.yaml b/parm/config/gfs/yaml/defaults.yaml index 272be765a6c..3bc262494e4 100644 --- a/parm/config/gfs/yaml/defaults.yaml +++ b/parm/config/gfs/yaml/defaults.yaml @@ -24,6 +24,8 @@ base: DOHYBVAR_OCN: "NO" DOLETKF_OCN: "NO" DO_TEST_MODE: "NO" + NMEM_ENS_GFS: 30 + NMEM_ENS_GFS_OFFSET: 20 atmanl: JCB_ALGO_YAML_VAR: "${PARMgfs}/gdas/atm/jcb-prototype_3dvar.yaml.j2" diff --git a/parm/config/sfs/config.aero b/parm/config/sfs/config.aero deleted file mode 120000 index f5b2edb643a..00000000000 --- a/parm/config/sfs/config.aero +++ /dev/null @@ -1 +0,0 @@ -../gefs/config.aero \ No newline at end of file diff --git a/parm/config/sfs/config.aero.j2 b/parm/config/sfs/config.aero.j2 new file mode 120000 index 00000000000..03571c376e3 --- /dev/null +++ b/parm/config/sfs/config.aero.j2 @@ -0,0 +1 @@ +../gefs/config.aero.j2 \ No newline at end of file diff --git a/parm/config/sfs/config.base b/parm/config/sfs/config.base.j2 similarity index 74% rename from parm/config/sfs/config.base rename to parm/config/sfs/config.base.j2 index 1453699392a..c7151efc02e 100644 --- a/parm/config/sfs/config.base +++ b/parm/config/sfs/config.base.j2 @@ -6,24 +6,29 @@ echo "BEGIN: config.base" # Machine environment -export machine="@MACHINE@" +export machine="{{ MACHINE }}" # EMC parallel or NCO production export RUN_ENVIR="emc" # Account, queue, etc. -export ACCOUNT="@ACCOUNT@" -export QUEUE="@QUEUE@" -export QUEUE_SERVICE="@QUEUE_SERVICE@" -export PARTITION_BATCH="@PARTITION_BATCH@" -export PARTITION_SERVICE="@PARTITION_SERVICE@" -export RESERVATION="@RESERVATION@" +export ACCOUNT="{{ ACCOUNT }}" +export QUEUE="{{ QUEUE }}" +export QUEUE_SERVICE="{{ QUEUE_SERVICE | default('${QUEUE}') }}" +export QUEUE_DTN="{{ QUEUE_DTN | default('${QUEUE_SERVICE}') }}" +export PARTITION_BATCH="{{ PARTITION_BATCH }}" +export PARTITION_SERVICE="{{ PARTITION_SERVICE | default() }}" +export PARTITION_DTN="{{ PARTITION_DTN | default() }}" +export RESERVATION="{{ RESERVATION | default() }}" +export CLUSTERS="{{ CLUSTERS | default() }}" +export CLUSTERS_SERVICE="{{ CLUSTERS_SERVICE | default('${CLUSTERS}') }}" +export CLUSTERS_DTN="{{ CLUSTERS_DTN | default('${CLUSTERS_SERVICE}') }}" # Project to use in mass store: -export HPSS_PROJECT="@HPSS_PROJECT@" +export HPSS_PROJECT="{{ HPSS_PROJECT }}" # Directories relative to installation areas: -export HOMEgfs=@HOMEgfs@ +export HOMEgfs="{{ HOMEgfs }}" export EXECgfs=${HOMEgfs}/exec export FIXgfs=${HOMEgfs}/fix export PARMgfs=${HOMEgfs}/parm @@ -35,26 +40,26 @@ export FIXugwd=${FIXgfs}/ugwd ######################################################################## # GLOBAL static environment parameters -export PACKAGEROOT="@PACKAGEROOT@" # TODO: set via prod_envir in Ops -export COMROOT="@COMROOT@" # TODO: set via prod_envir in Ops -export COMINsyn="@COMINsyn@" +export PACKAGEROOT="{{ PACKAGEROOT }}" # TODO: set via prod_envir in Ops +export COMROOT="{{ COMROOT }}" # TODO: set via prod_envir in Ops +export COMINsyn="{{ COMINsyn }}" # USER specific paths -export HOMEDIR="@HOMEDIR@" -export STMP="@STMP@" -export PTMP="@PTMP@" -export NOSCRUB="@NOSCRUB@" +export HOMEDIR="{{ HOMEDIR }}" +export STMP="{{ STMP }}" +export PTMP="{{ PTMP }}" +export NOSCRUB="{{ NOSCRUB }}" # Base directories for various builds -export BASE_GIT="@BASE_GIT@" +export BASE_GIT="{{ BASE_GIT }}" # Base directory for staged data -export BASE_DATA="@BASE_DATA@" +export BASE_DATA="{{ BASE_DATA }}" # Toggle to turn on/off GFS downstream processing. -export DO_BUFRSND="@DO_BUFRSND@" # BUFR sounding products -export DO_GEMPAK="@DO_GEMPAK@" # GEMPAK products -export DO_AWIPS="@DO_AWIPS@" # AWIPS products +export DO_BUFRSND="{{ DO_BUFRSND }}" # BUFR sounding products +export DO_GEMPAK="{{ DO_GEMPAK }}" # GEMPAK products +export DO_AWIPS="{{ DO_AWIPS }}" # AWIPS products # NO for retrospective parallel; YES for real-time parallel # arch.sh uses REALTIME for MOS. Need to set REALTIME=YES @@ -63,8 +68,8 @@ export DO_AWIPS="@DO_AWIPS@" # AWIPS products export REALTIME="YES" # Experiment mode (cycled or forecast-only) -export MODE="@MODE@" # cycled/forecast-only -export DO_TEST_MODE="@DO_TEST_MODE@" # option to change configuration for automated testing +export MODE="{{ MODE }}" # cycled/forecast-only +export DO_TEST_MODE="{{ DO_TEST_MODE }}" # option to change configuration for automated testing #################################################### # DO NOT ADD MACHINE DEPENDENT STUFF BELOW THIS LINE @@ -80,10 +85,10 @@ export NCP="/bin/cp -p" export NMV="/bin/mv" export NLN="/bin/ln -sf" export VERBOSE="YES" -export KEEPDATA="@KEEPDATA@" +export KEEPDATA="{{ KEEPDATA }}" export DEBUG_POSTSCRIPT="NO" # PBS only; sets debug=true -export CHGRP_RSTPROD="@CHGRP_RSTPROD@" -export CHGRP_CMD="@CHGRP_CMD@" +export CHGRP_RSTPROD="{{ CHGRP_RSTPROD }}" +export CHGRP_CMD="{{ CHGRP_CMD }}" export NCDUMP="${NETCDF:-${netcdf_c_ROOT:-}}/bin/ncdump" export NCLEN="${HOMEgfs}/ush/getncdimlen" @@ -92,16 +97,16 @@ export BASE_ENV="${HOMEgfs}/env" export BASE_JOB="${HOMEgfs}/jobs/rocoto" # EXPERIMENT specific environment parameters -export SDATE=@SDATE@ -export EDATE=@EDATE@ -export EXP_WARM_START="@EXP_WARM_START@" +export SDATE="{{ SDATE }}" +export EDATE="{{ EDATE }}" +export EXP_WARM_START="{{ EXP_WARM_START }}" export assim_freq=6 -export PSLOT="@PSLOT@" -export EXPDIR="@EXPDIR@/${PSLOT}" -export ROTDIR="@COMROOT@/${PSLOT}" +export PSLOT="{{ PSLOT }}" +export EXPDIR="{{ EXPDIR }}/${PSLOT}" +export ROTDIR="{{ COMROOT }}/${PSLOT}" export ARCDIR="${NOSCRUB}/archive/${PSLOT}" -export ATARDIR="@ATARDIR@" +export ATARDIR="{{ ATARDIR }}" # Commonly defined parameters in JJOBS export envir=${envir:-"prod"} @@ -126,7 +131,7 @@ export SENDDBN=${SENDDBN:-"NO"} export DBNROOT=${DBNROOT:-${UTILROOT:-}/fakedbn} # APP settings -export APP=@APP@ +export APP="{{ APP }}" # Defaults: export DO_ATM="YES" @@ -134,7 +139,7 @@ export DO_COUPLED="NO" export DO_WAVE="NO" export DO_OCN="NO" export DO_ICE="NO" -export DO_EXTRACTVARS="@DO_EXTRACTVARS@" # Option to process and extract a subset of products to save on disk +export DO_EXTRACTVARS="{{ DO_EXTRACTVARS }}" # Option to process and extract a subset of products to save on disk export DO_AERO_FCST="NO" export DOBNDPNT_WAVE="NO" # The SFS buoys file does not currently have any boundary points export DOIBP_WAV="NO" # Option to create point outputs from input boundary points @@ -152,9 +157,9 @@ export OPS_RES="C768" # Do not change # Resolution specific parameters export LEVS=128 -export CASE="@CASECTL@" # CASE is required in SFS to determine ocean/ice/wave resolutions -export CASE_ENS="@CASEENS@" -export OCNRES="@OCNRES@" +export CASE="{{ CASE_CTL }}" # CASE is required in SFS to determine ocean/ice/wave resolutions +export CASE_ENS="{{ CASE_ENS }}" +export OCNRES="{{ OCNRES }}" export ICERES="${OCNRES}" # These are the currently recommended grid-combinations case "${CASE}" in @@ -219,11 +224,11 @@ export FHOUT_ICE=3 export FHOUT_AERO=3 # GFS cycle info -export INTERVAL_GFS=@INTERVAL_GFS@ # Frequency of GFS forecast -export SDATE_GFS=@SDATE_GFS@ +export INTERVAL_GFS="{{ INTERVAL_GFS }}" # Frequency of GFS forecast +export SDATE_GFS="{{ SDATE_GFS }}" # set variables needed for use with REPLAY ICs -export REPLAY_ICS=@REPLAY_ICS@ +export REPLAY_ICS="{{ REPLAY_ICS }}" if [[ "${REPLAY_ICS:-NO}" == "YES" ]]; then export OFFSET_START_HOUR=$(( assim_freq / 2 )) echo "WARNING: Replay ICs require perturbation files, ignoring any previous settings" @@ -231,22 +236,22 @@ if [[ "${REPLAY_ICS:-NO}" == "YES" ]]; then export USE_ATM_ENS_PERTURB_FILES="YES" else export OFFSET_START_HOUR=0 - export USE_OCN_ENS_PERTURB_FILES=@USE_OCN_ENS_PERTURB_FILES@ - export USE_ATM_ENS_PERTURB_FILES=@USE_ATM_ENS_PERTURB_FILES@ + export USE_OCN_ENS_PERTURB_FILES="{{ USE_OCN_ENS_PERTURB_FILES }}" + export USE_ATM_ENS_PERTURB_FILES="{{ USE_ATM_ENS_PERTURB_FILES }}" fi # GFS output and frequency export FHMIN_GFS=0 -export FHMAX_GFS="@FHMAX_GFS@" +export FHMAX_GFS="{{ FHMAX_GFS }}" # Intermediate times to stop forecast when running in segments -breakpnts="@FCST_BREAKPOINTS@" +breakpnts="{{ FCST_BREAKPOINTS }}" export FCST_SEGMENTS="${FHMIN_GFS},${breakpnts:+${breakpnts},}${FHMAX_GFS}" -export FHOUT_GFS=@FHOUT_GFS@ -export FHMAX_HF_GFS=@FHMAX_HF_GFS@ -export FHOUT_HF_GFS=@FHOUT_HF_GFS@ -export FHOUT_OCN_GFS=@FHOUT_OCN_GFS@ -export FHOUT_ICE_GFS=@FHOUT_ICE_GFS@ +export FHOUT_GFS="{{ FHOUT_GFS }}" +export FHMAX_HF_GFS="{{ FHMAX_HF_GFS }}" +export FHOUT_HF_GFS="{{ FHOUT_HF_GFS }}" +export FHOUT_OCN_GFS="{{ FHOUT_OCN_GFS }}" +export FHOUT_ICE_GFS="{{ FHOUT_ICE_GFS }}" export FHMIN_WAV=${OFFSET_START_HOUR:-0} export FHOUT_WAV=3 export FHMAX_HF_WAV=120 @@ -289,7 +294,7 @@ export DO_MERGENSST="NO" export DO_STARTMEM_FROM_JEDIICE="NO" # Hybrid related -export NMEM_ENS=@NMEM_ENS@ +export NMEM_ENS="{{ NMEM_ENS }}" # set default member number memdir for control # this will be overwridden for the perturbed members @@ -322,19 +327,19 @@ if [[ ${DONST} = "YES" ]]; then export FNTSFA=" "; fi export nst_anl=.true. # Make the nsstbufr file on the fly or use the GDA version -export MAKE_NSSTBUFR="@MAKE_NSSTBUFR@" +export MAKE_NSSTBUFR="{{ MAKE_NSSTBUFR }}" # Make the aircraft prepbufr file on the fly or use the GDA version -export MAKE_ACFTBUFR="@MAKE_ACFTBUFR@" +export MAKE_ACFTBUFR="{{ MAKE_ACFTBUFR }}" # Verification options export DO_METP="NO" # Run METPLUS jobs - set METPLUS settings in config.metp export DO_FIT2OBS="NO" # Run fit to observations package # Archiving options -export VRFYARCH="@VRFYARCH@" # save verification data locally -export HPSSARCH="@HPSSARCH@" # save data to HPSS archive -export LOCALARCH="@LOCALARCH@" # save data to local archive +export VRFYARCH="{{ VRFYARCH }}" # save verification data locally +export HPSSARCH="{{ HPSSARCH }}" # save data to HPSS archive +export LOCALARCH="{{ LOCALARCH }}" # save data to local archive if [[ ${HPSSARCH} = "YES" ]] && [[ ${LOCALARCH} = "YES" ]]; then echo "Both HPSS and local archiving selected. Please choose one or the other." exit 3 diff --git a/parm/config/sfs/config.fcst.j2 b/parm/config/sfs/config.fcst.j2 new file mode 120000 index 00000000000..fe6832ea015 --- /dev/null +++ b/parm/config/sfs/config.fcst.j2 @@ -0,0 +1 @@ +../gefs/config.fcst.j2 \ No newline at end of file diff --git a/parm/config/sfs/config.ocn b/parm/config/sfs/config.ocn deleted file mode 120000 index c2f19253fb8..00000000000 --- a/parm/config/sfs/config.ocn +++ /dev/null @@ -1 +0,0 @@ -../gefs/config.ocn \ No newline at end of file diff --git a/parm/config/sfs/config.ocn.j2 b/parm/config/sfs/config.ocn.j2 new file mode 120000 index 00000000000..4a5deb7c815 --- /dev/null +++ b/parm/config/sfs/config.ocn.j2 @@ -0,0 +1 @@ +../gefs/config.ocn.j2 \ No newline at end of file diff --git a/parm/config/sfs/config.stage_ic b/parm/config/sfs/config.stage_ic deleted file mode 120000 index 1bba74ba629..00000000000 --- a/parm/config/sfs/config.stage_ic +++ /dev/null @@ -1 +0,0 @@ -../gefs/config.stage_ic \ No newline at end of file diff --git a/parm/config/sfs/config.stage_ic.j2 b/parm/config/sfs/config.stage_ic.j2 new file mode 120000 index 00000000000..eea6fcc8ef6 --- /dev/null +++ b/parm/config/sfs/config.stage_ic.j2 @@ -0,0 +1 @@ +../gefs/config.stage_ic.j2 \ No newline at end of file diff --git a/sorc/build_compute.sh b/sorc/build_compute.sh index 2bfafac431b..0bc21317b4a 100755 --- a/sorc/build_compute.sh +++ b/sorc/build_compute.sh @@ -4,14 +4,13 @@ function _usage() { cat << EOF Builds all of the global-workflow components on compute nodes. -Usage: ${BASH_SOURCE[0]} [-h][-v][-A ] [ gfs gefs sfs gsi gdas all] +Usage: ${BASH_SOURCE[0]} [-h][-v] -A HPC_ACCOUNT [gfs gefs sfs gsi gdas all] -h: Print this help message and exit -v: Verbose mode -A: - HPC account to use for the compute-node builds - (default is \$HOMEgfs/ci/platforms/config.\$machine:\$HPC_ACCOUNT) + HPC account to use for the compute-node builds [REQUIRED] Input arguments are the system(s) to build. Valid options are @@ -30,12 +29,13 @@ verbose="NO" build_xml="build.xml" build_db="build.db" build_lock_db="build_lock.db" +HPC_ACCOUNT="UNDEFINED" OPTIND=1 while getopts ":hA:v" option; do case "${option}" in h) _usage;; - A) export HPC_ACCOUNT="${OPTARG}" ;; + A) HPC_ACCOUNT="${OPTARG}" ;; v) verbose="YES" && rocoto_verbose_opt="-v10";; :) echo "[${BASH_SOURCE[0]}]: ${option} requires an argument" @@ -56,6 +56,11 @@ else systems=$* fi +if [[ "${HPC_ACCOUNT}" == "UNDEFINED" ]]; then + echo "FATAL ERROR: -A is required, ABORT!" + _usage +fi + if [[ "${verbose}" == "YES" ]]; then set -x fi @@ -75,9 +80,9 @@ source "${HOMEgfs}/workflow/gw_setup.sh" echo "Generating build.xml for building global-workflow programs on compute nodes ..." # Catch errors manually from here out set +e -"${HOMEgfs}/workflow/build_compute.py" --yaml "${HOMEgfs}/workflow/build_opts.yaml" --systems "${systems}" +"${HOMEgfs}/workflow/build_compute.py" --account "${HPC_ACCOUNT}" --yaml "${HOMEgfs}/workflow/build_opts.yaml" --systems "${systems}" rc=$? -if (( rc != 0 )); then +if [[ "${rc}" -ne 0 ]]; then msg="FATAL ERROR: ${BASH_SOURCE[0]} failed to create 'build.xml' with error code ${rc}" echo "${msg}" echo "${msg}" > logs/error.logs @@ -126,7 +131,7 @@ while [[ "${finished}" == "false" ]]; do log_file="logs/${job}.log" echo "${log_file}" >> logs/error.logs echo "Rocoto reported that the build failed for ${job}" - fi + fi done < rocotostat.out exit 2 fi diff --git a/sorc/link_workflow.sh b/sorc/link_workflow.sh index 3beb5b086ba..fb5d16b61df 100755 --- a/sorc/link_workflow.sh +++ b/sorc/link_workflow.sh @@ -56,7 +56,7 @@ else fi # shellcheck disable=SC1091 -COMPILER="intel" source "${HOMEgfs}/sorc/gfs_utils.fd/ush/detect_machine.sh" # (sets MACHINE_ID) +COMPILER="intel" source "${HOMEgfs}/ush/detect_machine.sh" # (sets MACHINE_ID) # shellcheck disable= machine=$(echo "${MACHINE_ID}" | cut -d. -f1) diff --git a/workflow/applications/applications.py b/workflow/applications/applications.py index a869f3689ea..7ec8e58eed8 100644 --- a/workflow/applications/applications.py +++ b/workflow/applications/applications.py @@ -46,7 +46,7 @@ def __init__(self, conf: Configuration) -> None: f'{", ".join(self.VALID_MODES)}\n') self.net = base['NET'] - print(f"Generating the XML for a {self.mode}_{self.net} case") + logger.info(f"Generating the XML for a {self.mode}_{self.net} case") def _init_finalize(self, conf: Configuration): ''' diff --git a/workflow/build_compute.py b/workflow/build_compute.py index f78cb4707c3..f281a899bd4 100755 --- a/workflow/build_compute.py +++ b/workflow/build_compute.py @@ -30,9 +30,9 @@ def input_args(*argv): parser = ArgumentParser(description=description, formatter_class=ArgumentDefaultsHelpFormatter) + parser.add_argument('--account', help='HPC account to use', required=True) parser.add_argument('--yaml', help='Input YAML file', type=str, required=False, default='build_opts.yaml') - parser.add_argument('--account', help='HPC account to use; default is host-dependent', required=False, default=os.getenv('HPC_ACCOUNT')) parser.add_argument('--systems', help='System(s) to build (options: gfs, gefs, sfs, gsi, gdas, or all)', required=False, default='gfs') inputs = parser.parse_args(list(*argv) if len(argv) else None) @@ -114,7 +114,6 @@ def get_host_specs(host: Dict) -> Dict: specs = AttrDict() specs.scheduler = host.info.SCHEDULER - specs.account = host.info.ACCOUNT specs.queue = host.info.QUEUE specs.partition = partition specs.native = native @@ -125,12 +124,13 @@ def get_host_specs(host: Dict) -> Dict: def main(*argv): user_inputs = input_args(*argv) - host_specs = get_host_specs(Host()) - # Update the default host account if the user supplied one - if user_inputs.account is not None: - host_specs.account = user_inputs.account + # Gather host specs and place the user supplied account + # into the host_specs dict + host_specs = get_host_specs(Host()) + host_specs.account = user_inputs.account + # Retrieve build specificatiosn from user provided yaml build_specs = AttrDict(parse_yaml(user_inputs.yaml)) systems = user_inputs.systems.split() if "all" not in user_inputs.systems else ["all"] diff --git a/workflow/create_experiment.py b/workflow/create_experiment.py index ac24d072610..8f935ab8a5c 100755 --- a/workflow/create_experiment.py +++ b/workflow/create_experiment.py @@ -35,11 +35,14 @@ import setup_expt import setup_xml + _here = os.path.dirname(__file__) _top = os.path.abspath(os.path.join(os.path.abspath(_here), '..')) # Setup the logger -logger = Logger(logfile_path=os.environ.get("LOGFILE_PATH"), level=os.environ.get("LOGGING_LEVEL", "DEBUG"), colored_log=False) +logger = Logger(logfile_path=os.environ.get("LOGFILE_PATH"), + level=os.environ.get("LOGGING_LEVEL", "INFO"), + colored_log=os.environ.get("COLORED_LOG", True)) @logit(logger) diff --git a/workflow/hosts.py b/workflow/hosts.py index 37a7e53066f..834027beedc 100644 --- a/workflow/hosts.py +++ b/workflow/hosts.py @@ -21,11 +21,17 @@ class Host: def __init__(self, host=None): - detected_host = self.detect() + if host is not None and host not in Host.SUPPORTED_HOSTS: + raise NotImplementedError(f'{host} is not a supported host.\n' + + 'Currently supported hosts are:\n' + + f'{" | ".join(Host.SUPPORTED_HOSTS)}') + + # Detect the host if not provided + detected_host = self.detect() if host is None else host if host is not None and host != detected_host: raise ValueError( - f'detected host: "{detected_host}" does not match host: "{host}"') + f'detected host: "{detected_host}" does not match provided host: "{host}"') self.machine = detected_host self.info = self._get_info @@ -34,10 +40,18 @@ def __init__(self, host=None): @classmethod def detect(cls): - machine = 'NOTFOUND' + machine = os.getenv('MACHINE_ID', 'UNKNOWN') + pw_csp = os.getenv('PW_CSP', 'UNKNOWN') container = os.getenv('SINGULARITY_NAME', None) - pw_csp = os.getenv('PW_CSP', None) + # Detect the machine since MACHINE_ID is set, + # Additionaly, if PW_CSP is set, then the machine is a cloud machine + if machine != 'UNKNOWN': + if pw_csp != 'UNKNOWN': + machine = f"{pw_csp.upper()}PW" + return machine + + # Detect the machine since MACHINE_ID is not set if os.path.exists('/scratch1/NCEPDEV'): machine = 'HERA' elif os.path.exists('/work/noaa'): @@ -57,7 +71,7 @@ def detect(cls): elif pw_csp is not None: if pw_csp.lower() not in ['azure', 'aws', 'google']: raise ValueError( - f'NOAA cloud service provider "{pw_csp}" is not supported.') + f'cloud service provider "{pw_csp}" is not supported.') machine = f"{pw_csp.upper()}PW" if machine not in Host.SUPPORTED_HOSTS: diff --git a/workflow/hosts/awspw.yaml b/workflow/hosts/awspw.yaml index d4c3ae6b00f..105a35fd464 100644 --- a/workflow/hosts/awspw.yaml +++ b/workflow/hosts/awspw.yaml @@ -1,27 +1,30 @@ -BASE_GIT: '' #TODO: This does not yet exist. +# Paths DMPDIR: '' # TODO: This does not yet exist. +BASE_GIT: '' #TODO: This does not yet exist. +BASE_DATA: '/bucket/global-workflow-shared-data' +BASE_IC: '/bucket/global-workflow-shared-data/ICSDIR' +AERO_INPUTS_DIR: /contrib/global-workflow-shared-data/data/GEFS_ExtData/20250310 PACKAGEROOT: '' #TODO: This does not yet exist. -COMINsyn: '' #TODO: This does not yet exist. HOMEDIR: '/contrib/${USER}' STMP: '/lustre/${USER}/stmp/' PTMP: '/lustre/${USER}/ptmp/' NOSCRUB: '${HOMEDIR}' -ACCOUNT: '${USER}' +COMINsyn: '' #TODO: This does not yet exist. +# BQS properties SCHEDULER: slurm QUEUE: batch PARTITION_BATCH: compute -CHGRP_RSTPROD: 'YES' -CHGRP_CMD: 'chgrp rstprod' # TODO: This is not yet supported. +# HPSS properties HPSS_PROJECT: emc-global #TODO: See `ATARDIR` below. -BASE_DATA: '/bucket/global-workflow-shared-data' -BASE_IC: '/bucket/global-workflow-shared-data/ICSDIR' -DO_ARCHCOM: 'NO' ARCHCOM_TO: 'local' ATARDIR: '' # TODO: This will not yet work from AWS. -MAKE_NSSTBUFR: 'NO' -MAKE_ACFTBUFR: 'NO' +CHGRP_RSTPROD: 'YES' +CHGRP_CMD: 'chgrp rstprod' # TODO: This is not yet supported. +# Features +SUPPORTED_RESOLUTIONS: ['C48', 'C96', 'C192', 'C384', 'C768'] # TODO: Test and support all cubed-sphere resolutions. +DO_ARCHCOM: 'NO' DO_TRACKER: 'NO' DO_GENESIS: 'NO' DO_METP: 'NO' -SUPPORTED_RESOLUTIONS: ['C48', 'C96', 'C192', 'C384', 'C768'] # TODO: Test and support all cubed-sphere resolutions. -AERO_INPUTS_DIR: /contrib/global-workflow-shared-data/data/GEFS_ExtData/20250310 +MAKE_NSSTBUFR: 'NO' +MAKE_ACFTBUFR: 'NO' diff --git a/workflow/hosts/azurepw.yaml b/workflow/hosts/azurepw.yaml index 6b366ee0ac6..0a93914beae 100644 --- a/workflow/hosts/azurepw.yaml +++ b/workflow/hosts/azurepw.yaml @@ -1,29 +1,31 @@ -BASE_GIT: '' #TODO: This does not yet exist. +# Paths DMPDIR: '' # TODO: This does not yet exist. +BASE_GIT: '' #TODO: This does not yet exist. +BASE_DATA: '/bucket/global-workflow-shared-data' +BASE_IC: '/bucket/global-workflow-shared-data/ICSDIR' PACKAGEROOT: '' #TODO: This does not yet exist. -COMINsyn: '' #TODO: This does not yet exist. HOMEDIR: '/contrib/${USER}' STMP: '/lustre/${USER}/stmp/' PTMP: '/lustre/${USER}/ptmp/' NOSCRUB: '${HOMEDIR}' -ACCOUNT: '${USER}' +COMINsyn: '' #TODO: This does not yet exist. +# BQS properties SCHEDULER: slurm QUEUE: batch QUEUE_SERVICE: batch PARTITION_BATCH: compute PARTITION_SERVICE: compute -CHGRP_RSTPROD: 'YES' -CHGRP_CMD: 'chgrp rstprod' # TODO: This is not yet supported. +# HPSS properties HPSS_PROJECT: emc-global #TODO: See `ATARDIR` below. -BASE_DATA: '/bucket/global-workflow-shared-data' -BASE_IC: '/bucket/global-workflow-shared-data/ICSDIR' -DO_ARCHCOM: 'NO' ARCHCOM_TO: 'local' ATARDIR: '' # TODO: This will not yet work from AZURE. -MAKE_NSSTBUFR: 'NO' -MAKE_ACFTBUFR: 'NO' +CHGRP_RSTPROD: 'YES' +CHGRP_CMD: 'chgrp rstprod' # TODO: This is not yet supported. +# Features +SUPPORTED_RESOLUTIONS: ['C48', 'C96', 'C384', 'C768'] # TODO: Test and support all cubed-sphere resolutions. +DO_ARCHCOM: 'NO' DO_TRACKER: 'NO' DO_GENESIS: 'NO' -DO_METP: 'NO' -SUPPORTED_RESOLUTIONS: ['C48', 'C96', 'C384', 'C768'] # TODO: Test and support all cubed-sphere resolutions. - +DO_METP: 'NO' +MAKE_NSSTBUFR: 'NO' +MAKE_ACFTBUFR: 'NO' diff --git a/workflow/hosts/container.yaml b/workflow/hosts/container.yaml index b6912400899..b007a35c629 100644 --- a/workflow/hosts/container.yaml +++ b/workflow/hosts/container.yaml @@ -1,25 +1,28 @@ -BASE_GIT: '' +# Paths DMPDIR: '/home/${USER}' +BASE_GIT: '' PACKAGEROOT: '' -COMINsyn: '' HOMEDIR: '/home/${USER}' STMP: '/home/${USER}' PTMP: '/home/${USER}' -NOSCRUB: $HOMEDIR -SCHEDULER: none -ACCOUNT: '' +NOSCRUB: '${HOMEDIR}' +COMINsyn: '' +# BQS properties +SCHEDULER: 'none' QUEUE: '' QUEUE_SERVICE: '' PARTITION_BATCH: '' PARTITION_SERVICE: '' RESERVATION: '' CLUSTERS: '' -CHGRP_RSTPROD: 'YES' -CHGRP_CMD: 'chgrp rstprod' +# HPSS properties HPSS_PROJECT: emc-global -DO_ARCHCOM: 'NO' ARCHCOM_TO: 'local' ATARDIR: '${NOSCRUB}/archive_rotdir/${PSLOT}' +CHGRP_RSTPROD: 'YES' +CHGRP_CMD: 'chgrp rstprod' +# Features +SUPPORTED_RESOLUTIONS: ['C96', 'C48'] +DO_ARCHCOM: 'NO' MAKE_NSSTBUFR: 'NO' MAKE_ACFTBUFR: 'NO' -SUPPORTED_RESOLUTIONS: ['C96', 'C48'] diff --git a/workflow/hosts/gaeac5.yaml b/workflow/hosts/gaeac5.yaml index 03c602d4069..f670860c666 100644 --- a/workflow/hosts/gaeac5.yaml +++ b/workflow/hosts/gaeac5.yaml @@ -1,14 +1,16 @@ -BASE_GIT: '/gpfs/f5/ufs-ard/world-shared/global/glopara/data/git' +# Paths DMPDIR: '/gpfs/f5/ufs-ard/world-shared/global/glopara/data/dump' +BASE_GIT: '/gpfs/f5/ufs-ard/world-shared/global/glopara/data/git' BASE_DATA: '/gpfs/f5/ufs-ard/world-shared/global/glopara/data' BASE_IC: '/gpfs/f5/ufs-ard/world-shared/global/glopara/data/ICSDIR' +AERO_INPUTS_DIR: '/gpfs/f5/ufs-ard/world-shared/global/glopara/data/GEFS_ExtData/20250310' PACKAGEROOT: '/gpfs/f5/ufs-ard/world-shared/global/glopara/data/nwpara' -COMINsyn: '/gpfs/f5/ufs-ard/world-shared/global/glopara/data/com/gfs/prod/syndat' HOMEDIR: '/gpfs/f5/${ACCOUNT}/scratch/${USER}' STMP: '/gpfs/f5/${ACCOUNT}/scratch/${USER}' PTMP: '/gpfs/f5/${ACCOUNT}/scratch/${USER}' -NOSCRUB: $HOMEDIR -ACCOUNT: epic +NOSCRUB: '${HOMEDIR}' +COMINsyn: '/gpfs/f5/ufs-ard/world-shared/global/glopara/data/com/gfs/prod/syndat' +# BQS properties SCHEDULER: slurm QUEUE: normal QUEUE_SERVICE: normal @@ -16,20 +18,21 @@ QUEUE_DTN: 'hpss' PARTITION_BATCH: batch PARTITION_SERVICE: batch PARTITION_DTN: 'dtn_f5_f6' -RESERVATION: '' CLUSTERS: 'c5' CLUSTERS_DTN: 'es' CONSTRAINT_DTN: 'f5' -CHGRP_RSTPROD: 'NO' -CHGRP_CMD: 'chgrp rstprod' +RESERVATION: '' +# HPSS properties HPSS_PROJECT: emc-global -DO_ARCHCOM: 'NO' ARCHCOM_TO: 'local' ATARDIR: '${NOSCRUB}/archive_rotdir/${PSLOT}' -MAKE_NSSTBUFR: 'NO' -MAKE_ACFTBUFR: 'NO' +CHGRP_RSTPROD: 'NO' +CHGRP_CMD: 'chgrp rstprod' +# Features +SUPPORTED_RESOLUTIONS: ['C384', 'C192', 'C96', 'C48'] +DO_ARCHCOM: 'NO' DO_TRACKER: 'NO' DO_GENESIS: 'NO' DO_METP: 'NO' -SUPPORTED_RESOLUTIONS: ['C384', 'C192', 'C96', 'C48'] -AERO_INPUTS_DIR: '/gpfs/f5/ufs-ard/world-shared/global/glopara/data/GEFS_ExtData/20250310' +MAKE_NSSTBUFR: 'NO' +MAKE_ACFTBUFR: 'NO' diff --git a/workflow/hosts/gaeac6.yaml b/workflow/hosts/gaeac6.yaml index b69f49d0f80..5a1dc11af4e 100644 --- a/workflow/hosts/gaeac6.yaml +++ b/workflow/hosts/gaeac6.yaml @@ -1,14 +1,16 @@ -BASE_GIT: '/gpfs/f6/drsa-precip3/world-shared/role.glopara/git' +# Paths DMPDIR: '/gpfs/f6/drsa-precip3/world-shared/role.glopara/dump' +BASE_GIT: '/gpfs/f6/drsa-precip3/world-shared/role.glopara/git' BASE_DATA: '/gpfs/f6/drsa-precip3/world-shared/role.glopara/data' BASE_IC: '/gpfs/f6/drsa-precip3/world-shared/role.glopara/data/ICSDIR' +AERO_INPUTS_DIR: '/gpfs/f6/drsa-precip3/world-shared/role.glopara/data/GEFS_ExtData/20250310' PACKAGEROOT: '/gpfs/f6/drsa-precip3/world-shared/role.glopara/nwpara' -COMINsyn: '/gpfs/f6/drsa-precip3/world-shared/role.glopara/com/syndat' HOMEDIR: '/gpfs/f6/${ACCOUNT}/scratch/${USER}' STMP: '/gpfs/f6/${ACCOUNT}/scratch/${USER}' PTMP: '/gpfs/f6/${ACCOUNT}/scratch/${USER}' -NOSCRUB: $HOMEDIR -ACCOUNT: drsa-precip3 +NOSCRUB: '${HOMEDIR}' +COMINsyn: '/gpfs/f6/drsa-precip3/world-shared/role.glopara/com/syndat' +# BQS properties SCHEDULER: slurm QUEUE: normal QUEUE_SERVICE: normal @@ -16,22 +18,23 @@ QUEUE_DTN: 'hpss' PARTITION_BATCH: batch PARTITION_SERVICE: batch PARTITION_DTN: 'dtn_f5_f6' -PARTITION_CRON: 'cron_c6' -RESERVATION: '' CLUSTERS: 'c6' CLUSTERS_DTN: 'es' CONSTRAINT_DTN: 'f6' -CHGRP_RSTPROD: 'NO' -CHGRP_CMD: 'chgrp rstprod' +RESERVATION: '' +PARTITION_CRON: 'cron_c6' +USE_SCRONTAB: 'YES' +# HPSS properties HPSS_PROJECT: emc-global -DO_ARCHCOM: 'YES' ARCHCOM_TO: 'hpss' ATARDIR: '/NCEPDEV/${HPSS_PROJECT}/1year/${USER}/${machine}/scratch/${PSLOT}' -MAKE_NSSTBUFR: 'NO' -MAKE_ACFTBUFR: 'NO' +CHGRP_RSTPROD: 'NO' +CHGRP_CMD: 'chgrp rstprod' +# Features +SUPPORTED_RESOLUTIONS: ['C1152', 'C768', 'C384', 'C192', 'C96', 'C48'] +DO_ARCHCOM: 'YES' DO_TRACKER: 'YES' DO_GENESIS: 'YES' -DO_METP: 'NO' -SUPPORTED_RESOLUTIONS: ['C1152', 'C768', 'C384', 'C192', 'C96', 'C48'] -AERO_INPUTS_DIR: '/gpfs/f6/drsa-precip3/world-shared/role.glopara/data/GEFS_ExtData/20250310' -USE_SCRONTAB: 'YES' +DO_METP: 'YES' +MAKE_NSSTBUFR: 'NO' +MAKE_ACFTBUFR: 'NO' diff --git a/workflow/hosts/googlepw.yaml b/workflow/hosts/googlepw.yaml index e60bf8a8b69..448442b9376 100644 --- a/workflow/hosts/googlepw.yaml +++ b/workflow/hosts/googlepw.yaml @@ -1,26 +1,30 @@ -BASE_GIT: '' #TODO: This does not yet exist. + +# Paths DMPDIR: '' # TODO: This does not yet exist. +BASE_GIT: '' #TODO: This does not yet exist. +BASE_DATA: '/bucket/global-workflow-shared-data' +BASE_IC: '/bucket/global-workflow-shared-data/ICSDIR' PACKAGEROOT: '' #TODO: This does not yet exist. -COMINsyn: '' #TODO: This does not yet exist. HOMEDIR: '/contrib/${USER}' STMP: '/lustre/${USER}/stmp/' PTMP: '/lustre/${USER}/ptmp/' NOSCRUB: '${HOMEDIR}' -ACCOUNT: '${USER}' +COMINsyn: '' #TODO: This does not yet exist. +# BQS properties SCHEDULER: slurm QUEUE: batch PARTITION_BATCH: compute -CHGRP_RSTPROD: 'YES' -CHGRP_CMD: 'chgrp rstprod' # TODO: This is not yet supported. +# HPSS properties HPSS_PROJECT: emc-global #TODO: See `ATARDIR` below. -BASE_DATA: '/bucket/global-workflow-shared-data' -BASE_IC: '/bucket/global-workflow-shared-data/ICSDIR' -DO_ARCHCOM: 'NO' ARCHCOM_TO: 'local' ATARDIR: '' # TODO: This will not yet work from GOOGLE. -MAKE_NSSTBUFR: 'NO' -MAKE_ACFTBUFR: 'NO' +CHGRP_RSTPROD: 'YES' +CHGRP_CMD: 'chgrp rstprod' # TODO: This is not yet supported. +# Features +SUPPORTED_RESOLUTIONS: ['C48', 'C96', 'C384'] # TODO: Test and support all cubed-sphere resolutions. +DO_ARCHCOM: 'NO' DO_TRACKER: 'NO' DO_GENESIS: 'NO' DO_METP: 'NO' -SUPPORTED_RESOLUTIONS: ['C48', 'C96', 'C384'] # TODO: Test and support all cubed-sphere resolutions. +MAKE_NSSTBUFR: 'NO' +MAKE_ACFTBUFR: 'NO' diff --git a/workflow/hosts/hera.yaml b/workflow/hosts/hera.yaml index d467ca16972..449cee84a7c 100644 --- a/workflow/hosts/hera.yaml +++ b/workflow/hosts/hera.yaml @@ -1,30 +1,32 @@ -BASE_GIT: '/scratch1/NCEPDEV/global/glopara/git' +# Paths DMPDIR: '/scratch1/NCEPDEV/global/glopara/dump' +BASE_GIT: '/scratch1/NCEPDEV/global/glopara/git' BASE_DATA: '/scratch1/NCEPDEV/global/glopara/data' BASE_IC: '/scratch1/NCEPDEV/global/glopara/data/ICSDIR' +AERO_INPUTS_DIR: /scratch1/NCEPDEV/global/glopara/data/GEFS_ExtData/20250310 PACKAGEROOT: '/scratch1/NCEPDEV/global/glopara/nwpara' -COMINsyn: '/scratch1/NCEPDEV/global/glopara/com/gfs/prod/syndat' HOMEDIR: '/scratch1/NCEPDEV/global/${USER}' STMP: '/scratch1/NCEPDEV/stmp2/${USER}' PTMP: '/scratch1/NCEPDEV/stmp4/${USER}' -NOSCRUB: $HOMEDIR -ACCOUNT: fv3-cpu +NOSCRUB: '${HOMEDIR}' +COMINsyn: '/scratch1/NCEPDEV/global/glopara/com/gfs/prod/syndat' +COMINecmwf: /scratch1/NCEPDEV/global/glopara/data/external_gempak/ecmwf +COMINnam: /scratch1/NCEPDEV/global/glopara/data/external_gempak/nam +COMINukmet: /scratch1/NCEPDEV/global/glopara/data/external_gempak/ukmet +# BQS properties SCHEDULER: slurm QUEUE: batch PARTITION_BATCH: hera PARTITION_SERVICE: service -CHGRP_RSTPROD: 'YES' -CHGRP_CMD: 'chgrp rstprod' +# HPSS properties HPSS_PROJECT: emc-global -DO_ARCHCOM: 'YES' ARCHCOM_TO: 'hpss' ATARDIR: '/NCEPDEV/${HPSS_PROJECT}/1year/${USER}/${machine}/scratch/${PSLOT}' +CHGRP_RSTPROD: 'YES' +CHGRP_CMD: 'chgrp rstprod' +# Features +SUPPORTED_RESOLUTIONS: ['C1152', 'C768', 'C384', 'C192', 'C96', 'C48'] +DO_ARCHCOM: 'YES' +DO_AWIPS: 'NO' MAKE_NSSTBUFR: 'NO' MAKE_ACFTBUFR: 'NO' -DO_AWIPS: 'NO' -SUPPORTED_RESOLUTIONS: ['C1152', 'C768', 'C384', 'C192', 'C96', 'C48'] -COMINecmwf: /scratch1/NCEPDEV/global/glopara/data/external_gempak/ecmwf -COMINnam: /scratch1/NCEPDEV/global/glopara/data/external_gempak/nam -COMINukmet: /scratch1/NCEPDEV/global/glopara/data/external_gempak/ukmet -AERO_INPUTS_DIR: /scratch1/NCEPDEV/global/glopara/data/GEFS_ExtData/20250310 - diff --git a/workflow/hosts/hercules.yaml b/workflow/hosts/hercules.yaml index c3f6d7d47b8..5f2e4b1337a 100644 --- a/workflow/hosts/hercules.yaml +++ b/workflow/hosts/hercules.yaml @@ -1,31 +1,34 @@ -BASE_GIT: '/work2/noaa/global/role-global/git' +# Paths DMPDIR: '/work/noaa/rstprod/dump' +BASE_GIT: '/work2/noaa/global/role-global/git' BASE_DATA: '/work2/noaa/global/role-global/data' BASE_IC: '/work2/noaa/global/role-global/data/ICSDIR' +AERO_INPUTS_DIR: '/work2/noaa/global/role-global/data/GEFS_ExtData/20250310' PACKAGEROOT: '/work2/noaa/global/role-global/nwpara' -COMINsyn: '/work2/noaa/global/role-global/com/gfs/prod/syndat' HOMEDIR: '/work2/noaa/global/${USER}' -STMP: '/work2/noaa/stmp/${USER}/HERCULES' -PTMP: '/work2/noaa/stmp/${USER}/HERCULES' -NOSCRUB: $HOMEDIR +STMP: '/work2/noaa/stmp/${USER}/${machine^^}' +PTMP: '/work2/noaa/stmp/${USER}/${machine^^}' +NOSCRUB: '${HOMEDIR}' +COMINsyn: '/work2/noaa/global/role-global/com/gfs/prod/syndat' +COMINecmwf: '/work2/noaa/global/role-global/data/external_gempak/ecmwf' +COMINnam: '/work2/noaa/global/role-global/data/external_gempak/nam' +COMINukmet: '/work2/noaa/global/role-global/data/external_gempak/ukmet' +# BQS properties SCHEDULER: slurm -ACCOUNT: fv3-cpu QUEUE: batch PARTITION_BATCH: hercules PARTITION_SERVICE: service -CHGRP_RSTPROD: 'YES' -CHGRP_CMD: 'chgrp rstprod' +# HPSS properties HPSS_PROJECT: emc-global -DO_ARCHCOM: 'NO' ARCHCOM_TO: 'globus_hpss' -# TODO let the workflow setup scripts determine the username (HPSS differs from MSU usernames) +# TODO: let the workflow setup scripts determine the username (HPSS differs from MSU usernames) ATARDIR: '/NCEPDEV/${HPSS_PROJECT}/1year/${USER}/${machine}/scratch/${PSLOT}' +CHGRP_RSTPROD: 'YES' +CHGRP_CMD: 'chgrp rstprod' +CLIENT_GLOBUS_UUID: '869912fe-f6de-46c0-af10-b22efd84a022' +# Features +SUPPORTED_RESOLUTIONS: ['C1152', 'C768', 'C384', 'C192', 'C96', 'C48'] +DO_ARCHCOM: 'NO' +DO_AWIPS: 'NO' MAKE_NSSTBUFR: 'NO' MAKE_ACFTBUFR: 'NO' -DO_AWIPS: 'NO' -SUPPORTED_RESOLUTIONS: ['C1152', 'C768', 'C384', 'C192', 'C96', 'C48'] -COMINecmwf: '/work2/noaa/global/role-global/data/external_gempak/ecmwf' -COMINnam: '/work2/noaa/global/role-global/data/external_gempak/nam' -COMINukmet: '/work2/noaa/global/role-global/data/external_gempak/ukmet' -AERO_INPUTS_DIR: '/work2/noaa/global/role-global/data/GEFS_ExtData/20250310' -CLIENT_GLOBUS_UUID: '869912fe-f6de-46c0-af10-b22efd84a022' diff --git a/workflow/hosts/jet.yaml b/workflow/hosts/jet.yaml index b4dc5fd7e4f..34ed0f44936 100644 --- a/workflow/hosts/jet.yaml +++ b/workflow/hosts/jet.yaml @@ -1,28 +1,32 @@ -BASE_GIT: '/lfs5/HFIP/hfv3gfs/glopara/git' +# Paths DMPDIR: '/lfs5/HFIP/hfv3gfs/glopara/dump' +BASE_GIT: '/lfs5/HFIP/hfv3gfs/glopara/git' BASE_DATA: '/lfs5/HFIP/hfv3gfs/glopara/data' BASE_IC: '/mnt/lfs5/HFIP/hfv3gfs/glopara/data/ICSDIR' +AERO_INPUTS_DIR: /lfs5/HFIP/hfv3gfs/glopara/data/GEFS_ExtData/20250310 PACKAGEROOT: '/lfs5/HFIP/hfv3gfs/glopara/nwpara' -COMINsyn: '/lfs5/HFIP/hfv3gfs/glopara/com/gfs/prod/syndat' HOMEDIR: '/lfs5/HFIP/hfv3gfs/${USER}' STMP: '/lfs5/HFIP/hfv3gfs/${USER}/stmp' PTMP: '/lfs5/HFIP/hfv3gfs/${USER}/ptmp' -NOSCRUB: $HOMEDIR -ACCOUNT: hfv3gfs +NOSCRUB: '${HOMEDIR}' +COMINsyn: '/lfs5/HFIP/hfv3gfs/glopara/com/gfs/prod/syndat' +COMINecmwf: /mnt/lfs5/HFIP/hfv3gfs/glopara/data/external_gempak/ecmwf +COMINnam: /mnt/lfs5/HFIP/hfv3gfs/glopara/data/external_gempak/nam +COMINukmet: /mnt/lfs5/HFIP/hfv3gfs/glopara/data/external_gempak/ukmet +# BQS properties SCHEDULER: slurm QUEUE: batch PARTITION_BATCH: kjet PARTITION_SERVICE: service -CHGRP_RSTPROD: 'YES' -CHGRP_CMD: 'chgrp rstprod' +# HPSS properties HPSS_PROJECT: emc-global -DO_ARCHCOM: 'YES' ARCHCOM_TO: 'hpss' ATARDIR: '/NCEPDEV/${HPSS_PROJECT}/1year/${USER}/${machine}/scratch/${PSLOT}' +CHGRP_RSTPROD: 'YES' +CHGRP_CMD: 'chgrp rstprod' +# Features +SUPPORTED_RESOLUTIONS: ['C384', 'C192', 'C96', 'C48'] +DO_ARCHCOM: 'YES' +DO_AWIPS: 'NO' MAKE_NSSTBUFR: 'NO' MAKE_ACFTBUFR: 'NO' -SUPPORTED_RESOLUTIONS: ['C384', 'C192', 'C96', 'C48'] -COMINecmwf: /mnt/lfs5/HFIP/hfv3gfs/glopara/data/external_gempak/ecmwf -COMINnam: /mnt/lfs5/HFIP/hfv3gfs/glopara/data/external_gempak/nam -COMINukmet: /mnt/lfs5/HFIP/hfv3gfs/glopara/data/external_gempak/ukmet -AERO_INPUTS_DIR: /lfs5/HFIP/hfv3gfs/glopara/data/GEFS_ExtData/20250310 diff --git a/workflow/hosts/orion.yaml b/workflow/hosts/orion.yaml index 9555eb258ff..e412cb033e6 100644 --- a/workflow/hosts/orion.yaml +++ b/workflow/hosts/orion.yaml @@ -1,31 +1,34 @@ -BASE_GIT: '/work2/noaa/global/role-global/git' +# Paths DMPDIR: '/work/noaa/rstprod/dump' +BASE_GIT: '/work2/noaa/global/role-global/git' BASE_DATA: '/work2/noaa/global/role-global/data' BASE_IC: '/work2/noaa/global/role-global/data/ICSDIR' +AERO_INPUTS_DIR: '/work2/noaa/global/role-global/data/GEFS_ExtData/20250310' PACKAGEROOT: '/work2/noaa/global/role-global/nwpara' +HOMEDIR: '/work2/noaa/global/${USER}' +STMP: '/work2/noaa/stmp/${USER}/${machine^^}' +PTMP: '/work2/noaa/stmp/${USER}/${machine^^}' +NOSCRUB: '${HOMEDIR}' COMINsyn: '/work2/noaa/global/role-global/com/gfs/prod/syndat' -HOMEDIR: '/work/noaa/global/${USER}' -STMP: '/work/noaa/stmp/${USER}/ORION' -PTMP: '/work/noaa/stmp/${USER}/ORION' -NOSCRUB: $HOMEDIR +COMINecmwf: '/work2/noaa/global/role-global/data/external_gempak/ecmwf' +COMINnam: '/work2/noaa/global/role-global/data/external_gempak/nam' +COMINukmet: '/work2/noaa/global/role-global/data/external_gempak/ukmet' +# BQS properties SCHEDULER: slurm -ACCOUNT: fv3-cpu QUEUE: batch PARTITION_BATCH: orion PARTITION_SERVICE: service -CHGRP_RSTPROD: 'YES' -CHGRP_CMD: 'chgrp rstprod' +# HPSS properties HPSS_PROJECT: emc-global -DO_ARCHCOM: 'NO' ARCHCOM_TO: 'globus_hpss' -# TODO let the workflow setup scripts determine the username (HPSS differs from MSU usernames) +# TODO: let the workflow setup scripts determine the username (HPSS differs from MSU usernames) ATARDIR: '/NCEPDEV/${HPSS_PROJECT}/1year/${USER}/${machine}/scratch/${PSLOT}' +CHGRP_RSTPROD: 'YES' +CHGRP_CMD: 'chgrp rstprod' +CLIENT_GLOBUS_UUID: '869912fe-f6de-46c0-af10-b22efd84a022' +# Features +SUPPORTED_RESOLUTIONS: ['C1152', 'C768', 'C384', 'C192', 'C96', 'C48'] +DO_ARCHCOM: 'NO' +DO_AWIPS: 'NO' MAKE_NSSTBUFR: 'NO' MAKE_ACFTBUFR: 'NO' -DO_AWIPS: 'NO' -SUPPORTED_RESOLUTIONS: ['C1152', 'C768', 'C384', 'C192', 'C96', 'C48'] -COMINecmwf: '/work2/noaa/global/role-global/data/external_gempak/ecmwf' -COMINnam: '/work2/noaa/global/role-global/data/external_gempak/nam' -COMINukmet: '/work2/noaa/global/role-global/data/external_gempak/ukmet' -AERO_INPUTS_DIR: '/work2/noaa/global/role-global/data/GEFS_ExtData/20250310' -CLIENT_GLOBUS_UUID: '869912fe-f6de-46c0-af10-b22efd84a022' diff --git a/workflow/hosts/s4.yaml b/workflow/hosts/s4.yaml index c6ceedb034f..bc8c9ab1a31 100644 --- a/workflow/hosts/s4.yaml +++ b/workflow/hosts/s4.yaml @@ -1,27 +1,29 @@ -BASE_GIT: '/data/prod/glopara/git' +# Paths DMPDIR: '/data/prod/glopara/dump' +BASE_GIT: '/data/prod/glopara/git' BASE_DATA: '/data/prod/glopara' BASE_IC: '/data/prod/glopara/coupled_ICs' +AERO_INPUTS_DIR: /data/prod/glopara/GEFS_ExtData/20250310 PACKAGEROOT: '/data/prod/glopara/nwpara' -COMINsyn: '/data/prod/glopara/com/gfs/prod/syndat' HOMEDIR: '/data/users/${USER}' STMP: '/scratch/users/${USER}' PTMP: '/scratch/users/${USER}' -NOSCRUB: ${HOMEDIR} -ACCOUNT: star +NOSCRUB: '${HOMEDIR}' +COMINsyn: '/data/prod/glopara/com/gfs/prod/syndat' +# BQS properties SCHEDULER: slurm QUEUE: s4 QUEUE_SERVICE: serial PARTITION_BATCH: s4 PARTITION_SERVICE: serial -CHGRP_RSTPROD: 'NO' -CHGRP_CMD: 'ls' +# HPSS properties HPSS_PROJECT: emc-global -DO_ARCHCOM: 'NO' ARCHCOM_TO: 'local' ATARDIR: '${NOSCRUB}/archive_rotdir/${PSLOT}' +CHGRP_RSTPROD: 'NO' +CHGRP_CMD: 'ls' +# Features +SUPPORTED_RESOLUTIONS: ['C384', 'C192', 'C96', 'C48'] +DO_ARCHCOM: 'NO' MAKE_NSSTBUFR: 'YES' MAKE_ACFTBUFR: 'YES' -SUPPORTED_RESOLUTIONS: ['C384', 'C192', 'C96', 'C48'] -AERO_INPUTS_DIR: /data/prod/glopara/GEFS_ExtData/20250310 - diff --git a/workflow/hosts/wcoss2.yaml b/workflow/hosts/wcoss2.yaml index 1917c15c498..44488ecc2c8 100644 --- a/workflow/hosts/wcoss2.yaml +++ b/workflow/hosts/wcoss2.yaml @@ -1,27 +1,30 @@ -BASE_GIT: '/lfs/h2/emc/global/save/emc.global/git' +# Paths DMPDIR: '/lfs/h2/emc/dump/noscrub/dump' +BASE_GIT: '/lfs/h2/emc/global/save/emc.global/git' BASE_DATA: '/lfs/h2/emc/global/noscrub/emc.global/data' BASE_IC: '/lfs/h2/emc/global/noscrub/emc.global/data/ICSDIR' +AERO_INPUTS_DIR: /lfs/h2/emc/global/noscrub/emc.global/data/GEFS_ExtData/20250310 PACKAGEROOT: '${PACKAGEROOT:-"/lfs/h1/ops/prod/packages"}' -COMINsyn: '/lfs/h1/ops/prod/com/gfs/v16.3/syndat' HOMEDIR: '/lfs/h2/emc/global/noscrub/${USER}' STMP: '/lfs/h2/emc/stmp/${USER}' PTMP: '/lfs/h2/emc/ptmp/${USER}' -NOSCRUB: $HOMEDIR -ACCOUNT: 'GFS-DEV' +NOSCRUB: '${HOMEDIR}' +COMINsyn: '/lfs/h1/ops/prod/com/gfs/v16.3/syndat' +COMINecmwf: /lfs/h2/emc/global/noscrub/emc.global/data/external_gempak/ecmwf +COMINnam: /lfs/h2/emc/global/noscrub/emc.global/data/external_gempak/nam +COMINukmet: /lfs/h2/emc/global/noscrub/emc.global/data/external_gempak/ukmet +# BQS properties SCHEDULER: pbspro QUEUE: 'dev' QUEUE_SERVICE: 'dev_transfer' +# HPSS properties +HPSS_PROJECT: emc-global +ARCHCOM_TO: 'hpss' +ATARDIR: '/NCEPDEV/${HPSS_PROJECT}/1year/${USER}/${machine}/scratch/${PSLOT}' CHGRP_RSTPROD: 'YES' CHGRP_CMD: 'chgrp rstprod' +# Features +SUPPORTED_RESOLUTIONS: ['C1152', 'C768', 'C384', 'C192', 'C96', 'C48'] DO_ARCHCOM: 'NO' -ARCHCOM_TO: 'hpss' -HPSS_PROJECT: emc-global -ATARDIR: '/NCEPDEV/${HPSS_PROJECT}/1year/${USER}/${machine}/scratch/${PSLOT}' MAKE_NSSTBUFR: 'NO' MAKE_ACFTBUFR: 'NO' -SUPPORTED_RESOLUTIONS: ['C1152', 'C768', 'C384', 'C192', 'C96', 'C48'] -COMINecmwf: /lfs/h2/emc/global/noscrub/emc.global/data/external_gempak/ecmwf -COMINnam: /lfs/h2/emc/global/noscrub/emc.global/data/external_gempak/nam -COMINukmet: /lfs/h2/emc/global/noscrub/emc.global/data/external_gempak/ukmet -AERO_INPUTS_DIR: /lfs/h2/emc/global/noscrub/emc.global/data/GEFS_ExtData/20250310 diff --git a/workflow/requirements.txt b/workflow/requirements.txt new file mode 100644 index 00000000000..370498db9d9 --- /dev/null +++ b/workflow/requirements.txt @@ -0,0 +1,4 @@ +numpy>=1.23 +jinja2>=3.0 +pyyaml>=6.0 +pycodestyle>=2.12 diff --git a/workflow/rocoto/tasks.py b/workflow/rocoto/tasks.py index ac5cc914a22..d8ef32627fd 100644 --- a/workflow/rocoto/tasks.py +++ b/workflow/rocoto/tasks.py @@ -95,13 +95,16 @@ def _set_system_settings(self) -> None: def _validate_system_key(input_dict, key): # This helper function returns None if - # 1) the value held in 'key' matches '@' + key + '@' + # 1) the value held in 'key' matches '{{' + " "* key + " "* + '}}' # 2) the value is an empty string, or # 3) the key does not exist in the dictionary. value = input_dict.get(key, None) value = None if value == '' else value - return None if value == f'@{key}@' else value + if isinstance(value, str): + return None if value.replace(" ", "") == "{{" + key + "}}" else value + else: + return value # Check the system configuration base = self._base diff --git a/workflow/rocoto/workflow_xml.py b/workflow/rocoto/workflow_xml.py index e265a11904a..fa546b0c9e4 100644 --- a/workflow/rocoto/workflow_xml.py +++ b/workflow/rocoto/workflow_xml.py @@ -32,7 +32,7 @@ def __init__(self, app_config: AppConfig, rocoto_config: Dict) -> None: # Collect info needed to write an scrontab file self.host_info = Host().info self.use_scrontab = self.host_info.get("USE_SCRONTAB", False) - # Replace ACCOUNT with whatever is in config.base + # Add ACCOUNT to host_info, with that from config.base self.host_info.ACCOUNT = self._base['ACCOUNT'] self.HOMEgfs = self._base['HOMEgfs'] self.expdir = self._base['EXPDIR'] diff --git a/workflow/setup_expt.py b/workflow/setup_expt.py index 88958b13b67..7dbbea6e40a 100755 --- a/workflow/setup_expt.py +++ b/workflow/setup_expt.py @@ -5,21 +5,23 @@ """ import os -import glob import shutil +from logging import getLogger from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, SUPPRESS, ArgumentTypeError from hosts import Host -from wxflow import parse_j2yaml -from wxflow import AttrDict -from wxflow import to_datetime, to_timedelta, datetime_to_YMDH +from wxflow import parse_j2yaml, AttrDict, to_datetime, to_timedelta, to_YMDH, Jinja, Logger, logit _here = os.path.dirname(__file__) _top = os.path.abspath(os.path.join(os.path.abspath(_here), '..')) +# Setup the logger +logger = getLogger(__name__) + +# @logit(logger) def makedirs_if_missing(dirname): """ Creates a directory if not already present @@ -28,26 +30,15 @@ def makedirs_if_missing(dirname): os.makedirs(dirname) -def fill_expdir(inputs): +# @logit(logger) +def update_configs(host, inputs): """ - Method to copy config files from workflow to experiment directory + Method to copy config files from workflow to experiment directory and render templates INPUTS: inputs: user inputs to `setup_expt.py` """ - configdir = inputs.configdir - expdir = os.path.join(inputs.expdir, inputs.pslot) - - configs = glob.glob(f'{configdir}/config.*') - if len(configs) == 0: - raise IOError(f'no config files found in {configdir}') - for config in configs: - shutil.copy(config, expdir) - - return - - -def update_configs(host, inputs): + # @logit(logger) def _update_defaults(dict_in: dict) -> dict: # Given an input dict_in of the form # {defaults: {config_name: {var1: value1, ...}, }, config_name: {var1: value1, ...}} @@ -59,148 +50,82 @@ def _update_defaults(dict_in: dict) -> dict: defaults.update(dict_in) return defaults - # Convert the inputs to an AttrDict - data = AttrDict(host.info, **inputs.__dict__) + # map inputs_dict keys to keys used in configs + inputs_dict_remapped = map_inputs_to_configs(inputs) - # Read in the YAML file to fill out templates - data.HOMEgfs = _top + # Combine host.info and inputs_dict into a single dict, add some additional keys + host_plus_inputs_dict = AttrDict(host.info, **inputs_dict_remapped) + host_plus_inputs_dict.HOMEgfs = _top + host_plus_inputs_dict.MACHINE = host.machine.upper() + + # Read in the YAML file yaml_path = inputs.yaml if not os.path.exists(yaml_path): raise FileNotFoundError(f'YAML file does not exist, check path: {yaml_path}') - yaml_dict = parse_j2yaml(yaml_path, data) + yaml_dict = parse_j2yaml(yaml_path, host_plus_inputs_dict) # yaml_dict is in the form {defaults: {key1: val1, ...}, base: {key1: val1, ...}, ...} # _update_defaults replaces any keys/values in defaults with matching keys in base yaml_dict = _update_defaults(yaml_dict) - # Override the YAML defaults with the host-specific capabilities - # First update config.base - edit_baseconfig(host, inputs, yaml_dict) - - # Update stage config - stage_dict = { - "@ICSDIR@": inputs.icsdir - } - host_dict = get_template_dict(host.info) - stage_dict = dict(stage_dict, **host_dict) - stage_input = f'{inputs.configdir}/config.stage_ic' - stage_output = f'{inputs.expdir}/{inputs.pslot}/config.stage_ic' - edit_config(stage_input, stage_output, host_dict, stage_dict) - - # Loop over other configs and update them with defaults - for cfg in yaml_dict.keys(): - if cfg == 'base': - continue - cfg_file = f'{inputs.expdir}/{inputs.pslot}/config.{cfg}' - cfg_dict = get_template_dict(yaml_dict[cfg]) - edit_config(cfg_file, cfg_file, host_dict, cfg_dict) + # Copy the config files to the experiment directory + files = [ff for ff in os.listdir(inputs.configdir) if os.path.isfile(os.path.join(inputs.configdir, ff))] + for file in files: + if file.endswith('.j2'): # Jinja2 template; render it + logger.info(f'Jinja2 template found: {file}') + input_template = f'{inputs.configdir}/{file}' + cfg_file = file[:-3] # remove the .j2 extension + output_config = f'{inputs.expdir}/{inputs.pslot}/{cfg_file}' # output file in EXPDIR + cfg_key = '.'.join(cfg_file.split('.')[1:]) # key to look for in yaml_dict + _data = host_plus_inputs_dict.copy() + if cfg_key in yaml_dict.keys(): + _data = AttrDict(_data, **yaml_dict[cfg_key]) + Jinja(input_template, _data).save(output_config) + else: # copy the file as is + input_file = f'{inputs.configdir}/{file}' + output_config = f'{inputs.expdir}/{inputs.pslot}/{file}' + shutil.copy(input_file, output_config) return -def edit_baseconfig(host, inputs, yaml_dict): - """ - Parses and populates the templated `HOMEgfs/parm/config//config.base` - to `EXPDIR/pslot/config.base` - """ - - # Create base_dict which holds templated variables to be written to config.base - base_dict = { - "@HOMEgfs@": _top, - "@MACHINE@": host.machine.upper()} +# @logit(logger) +def map_inputs_to_configs(inputs): - if inputs.start in ["warm"]: - is_warm_start = ".true." - elif inputs.start in ["cold"]: - is_warm_start = ".false." - else: - raise ValueError(f"Invalid start type: {inputs.start}") + warm_start_map = {'warm': '.true.', 'cold': '.false.'} # Construct a dictionary from user inputs - extend_dict = { - "@PSLOT@": inputs.pslot, - "@SDATE@": datetime_to_YMDH(inputs.idate), - "@EDATE@": datetime_to_YMDH(inputs.edate), - "@CASECTL@": f'C{inputs.resdetatmos}', - "@OCNRES@": f"{int(100.*inputs.resdetocean):03d}", - "@EXPDIR@": inputs.expdir, - "@COMROOT@": inputs.comroot, - "@EXP_WARM_START@": is_warm_start, - "@MODE@": inputs.mode, - "@INTERVAL_GFS@": inputs.interval, - "@SDATE_GFS@": datetime_to_YMDH(inputs.sdate_gfs), - "@APP@": inputs.app, - "@NMEM_ENS@": getattr(inputs, 'nens', 0) - } - - if getattr(inputs, 'nens', 0) > 0: - extend_dict['@CASEENS@'] = f'C{inputs.resensatmos}' + try: + dict_out = AttrDict({ + "PSLOT": inputs.pslot, + "SDATE": to_YMDH(inputs.idate), + "EDATE": to_YMDH(inputs.edate), + "CASE_CTL": f'C{inputs.resdetatmos}', + "OCNRES": f"{int(100.*inputs.resdetocean):03d}", + "EXPDIR": inputs.expdir, + "COMROOT": inputs.comroot, + "EXP_WARM_START": warm_start_map[inputs.start], + "MODE": inputs.mode, + "INTERVAL_GFS": inputs.interval, + "SDATE_GFS": to_YMDH(inputs.sdate_gfs), + "APP": inputs.app, + "NMEM_ENS": getattr(inputs, 'nens', 0), + "ICSDIR": inputs.icsdir, + "ACCOUNT": inputs.account, + }) + except Exception as ee: + raise Exception("Error in constructing dictionary from user inputs, check inputs: ") from ee + + if dict_out.NMEM_ENS > 0: + dict_out.CASE_ENS = f'C{inputs.resensatmos}' if inputs.mode in ['cycled']: - extend_dict["@DOHYBVAR@"] = "YES" if inputs.nens > 0 else "NO" - - # Further extend/redefine base_dict with extend_dict - base_dict = dict(base_dict, **extend_dict) + dict_out.DOHYBVAR = "YES" if dict_out.NMEM_ENS > 0 else "NO" - # Add/override 'base'-specific declarations in base_dict - if 'base' in yaml_dict: - base_dict = dict(base_dict, **get_template_dict(yaml_dict['base'])) - - base_input = f'{inputs.configdir}/config.base' - base_output = f'{inputs.expdir}/{inputs.pslot}/config.base' - edit_config(base_input, base_output, host.info, base_dict) - - return - - -def edit_config(input_config, output_config, host_info, config_dict): - """ - Given a templated input_config filename, parse it based on config_dict and - host_info and write it out to the output_config filename. - """ - - # Override defaults with machine-specific capabilties - # e.g. some machines are not able to run metp jobs - host_dict = get_template_dict(host_info) - config_dict = dict(config_dict, **host_dict) - - # Read input config - with open(input_config, 'rt') as fi: - config_str = fi.read() - - # Substitute from config_dict - for key, val in config_dict.items(): - config_str = config_str.replace(key, str(val)) - - # Ensure no output_config file exists - if os.path.exists(output_config): - os.unlink(output_config) - - # Write output config - with open(output_config, 'wt') as fo: - fo.write(config_str) - - print(f'EDITED: {output_config} as per user input.') - - return - - -def get_template_dict(input_dict): - # Reads a templated input dictionary and updates the output - - output_dict = dict() - - for key, value in input_dict.items(): - # In some cases, the same config may be templated twice - # Prevent adding additional "@"s - if "@" in key: - output_dict[f'{key}'] = value - else: - output_dict[f'@{key}@'] = value - - return output_dict + return dict_out +# @logit(logger) def input_args(*argv): """ Method to collect user arguments for `setup_expt.py` @@ -366,6 +291,7 @@ def _sfs_args(parser): return inputs +# @logit(logger) def query_and_clean(dirname, force_clean=False): """ Method to query if a directory exists and gather user input for further action @@ -373,10 +299,12 @@ def query_and_clean(dirname, force_clean=False): create_dir = True if os.path.exists(dirname): - print(f'\ndirectory already exists in {dirname}') + logger.warning(f'directory already exists in:') + logger.warning(f' {dirname}') if force_clean: overwrite = "YES" - print(f'removing directory ........ {dirname}\n') + logger.warning(f'removing directory ...') + logger.warning(f' {dirname}') else: overwrite = input('Do you wish to over-write [y/N]: ') create_dir = True if overwrite in [ @@ -387,6 +315,7 @@ def query_and_clean(dirname, force_clean=False): return create_dir +# @logit(logger) def validate_user_request(host, inputs): supp_res = host.info['SUPPORTED_RESOLUTIONS'] machine = host.machine @@ -399,6 +328,7 @@ def validate_user_request(host, inputs): raise NotImplementedError(f"Supported resolutions on {machine} are:\n{', '.join(supp_res)}") +# @logit(logger) def get_ocean_resolution(resdetatmos): """ Method to determine the ocean resolution based on the atmosphere resolution @@ -414,6 +344,7 @@ def get_ocean_resolution(resdetatmos): raise KeyError(f"Ocean resolution for {resdetatmos} is not implemented") +@logit(logger, name='setup_expt.main') def main(*argv): user_inputs = input_args(*argv) @@ -440,15 +371,20 @@ def main(*argv): if create_expdir: makedirs_if_missing(expdir) - fill_expdir(user_inputs) update_configs(host, user_inputs) - print(f"*" * 100) - print(f'EXPDIR: {expdir}') - print(f'ROTDIR: {rotdir}') - print(f"*" * 100) + max_len = max(len(expdir), len(rotdir)) + 8 + logger.info(f"*" * max_len) + logger.info(f'EXPDIR: {expdir}') + logger.info(f'ROTDIR: {rotdir}') + logger.info(f"*" * max_len) if __name__ == '__main__': + # Setup the logger + logger = Logger(logfile_path=os.environ.get("LOGFILE_PATH"), + level=os.environ.get("LOGGING_LEVEL", "INFO"), + colored_log=os.environ.get("COLORED_LOG", True)) + main() diff --git a/workflow/setup_xml.py b/workflow/setup_xml.py index 3e04325ad89..ad1be5c4db4 100755 --- a/workflow/setup_xml.py +++ b/workflow/setup_xml.py @@ -4,13 +4,19 @@ """ import os +from logging import getLogger from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter from applications.application_factory import app_config_factory from rocoto.rocoto_xml_factory import rocoto_xml_factory -from wxflow import Configuration +from wxflow import Configuration, Logger, logit +# Setup the logger +logger = getLogger(__name__) + + +# @logit(logger) def input_args(*argv): """ Method to collect user arguments for `setup_xml.py` @@ -42,25 +48,27 @@ def input_args(*argv): return parser.parse_args(argv[0][0] if len(argv[0]) else None) +# @logit(logger) def check_expdir(cmd_expdir, cfg_expdir): if not os.path.samefile(cmd_expdir, cfg_expdir): - print('MISMATCH in experiment directories!') - print(f'config.base: EXPDIR = {cfg_expdir}') - print(f' input arg: --expdir = {cmd_expdir}') + logger.exception('MISMATCH in experiment directories!') + logger.error(f'config.base: EXPDIR = {cfg_expdir}') + logger.error(f' input arg: --expdir = {cmd_expdir}') raise ValueError('Abort!') -def check_dir_writable(dirPath): - if os.path.isdir(dirPath): - if os.access(dirPath, os.W_OK): +# @logit(logger) +def check_dir_writable(dir_path): + if os.path.isdir(dir_path): + if os.access(dir_path, os.W_OK): return True else: return False - elif os.path.isfile(dirPath): + elif os.path.isfile(dir_path): return False else: # Find the nearest parent directory that already exists - test_parent = os.path.dirname(dirPath) + test_parent = os.path.dirname(dir_path) if len(test_parent) == 0: return False while test_parent: @@ -74,6 +82,7 @@ def check_dir_writable(dirPath): return False +@logit(logger, name="setup_xml.main") def main(*argv): user_inputs = input_args(argv) @@ -89,8 +98,8 @@ def main(*argv): check_expdir(user_inputs.expdir, base['EXPDIR']) # Check if "HOMEDIR","STMP","PTMP" dirrctories are writable - dirKeys = ["HOMEDIR", "STMP", "PTMP"] - for dk in dirKeys: + dir_keys = ["HOMEDIR", "STMP", "PTMP"] + for dk in dir_keys: check_dir_writable(base[dk]) if not check_dir_writable(base[dk]): msg = f'The {dk} path {base[dk]} cannot be written to! Please correct this path and try again.' @@ -112,4 +121,9 @@ def main(*argv): if __name__ == '__main__': + # Setup the logger + logger = Logger(logfile_path=os.environ.get("LOGFILE_PATH"), + level=os.environ.get("LOGGING_LEVEL", "INFO"), + colored_log=os.environ.get("COLORED_LOG", True)) + main()