From 2b489fcb3986c207d9e647b8c3d423f8bb1f8c7f Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Sun, 18 Feb 2024 13:20:41 +0000 Subject: [PATCH 1/9] attempt at making ocn/ice output seperate from atm output --- parm/config/gefs/config.base.emc.dyn | 3 ++- parm/config/gefs/config.fcst | 1 + parm/config/gfs/config.base.emc.dyn | 4 +++- parm/config/gfs/config.fcst | 1 + parm/ufs/fv3/diag_table | 4 ++-- ush/forecast_predet.sh | 4 ++-- ush/parsing_namelists_CICE.sh | 2 +- ush/parsing_namelists_FV3.sh | 10 +++++++++- ush/python/pygfs/task/oceanice_products.py | 2 +- workflow/rocoto/gfs_tasks.py | 1 + 10 files changed, 23 insertions(+), 9 deletions(-) diff --git a/parm/config/gefs/config.base.emc.dyn b/parm/config/gefs/config.base.emc.dyn index 051a2188c3..0b19da2a36 100644 --- a/parm/config/gefs/config.base.emc.dyn +++ b/parm/config/gefs/config.base.emc.dyn @@ -220,9 +220,10 @@ export gfs_cyc=@gfs_cyc@ # 0: no GFS cycle, 1: 00Z only, 2: 00Z and 12Z only, 4: export FHMIN_GFS=0 export FHMIN=${FHMIN_GFS} export FHMAX_GFS=@FHMAX_GFS@ -export FHOUT_GFS=6 # Must be 6 for S2S until #1629 is addressed; 3 for ops +export FHOUT_GFS=6 export FHMAX_HF_GFS=0 export FHOUT_HF_GFS=1 +export FHOUT_OCNICE_GFS=6 if (( gfs_cyc != 0 )); then export STEP_GFS=$(( 24 / gfs_cyc )) else diff --git a/parm/config/gefs/config.fcst b/parm/config/gefs/config.fcst index 6a2a852e0b..dc4f70ecfe 100644 --- a/parm/config/gefs/config.fcst +++ b/parm/config/gefs/config.fcst @@ -27,6 +27,7 @@ export FHMAX=${FHMAX_GFS} export FHOUT=${FHOUT_GFS} export FHMAX_HF=${FHMAX_HF_GFS} export FHOUT_HF=${FHOUT_HF_GFS} +export FHOUT_OCNICE_GFS=${FHOUT_OCNICE} # Get task specific resources source "${EXPDIR}/config.resources" fcst diff --git a/parm/config/gfs/config.base.emc.dyn b/parm/config/gfs/config.base.emc.dyn index 16aed843ba..5c02b000ef 100644 --- a/parm/config/gfs/config.base.emc.dyn +++ b/parm/config/gfs/config.base.emc.dyn @@ -248,6 +248,7 @@ fi export FHMIN=0 export FHMAX=9 export FHOUT=3 # Will be changed to 1 in config.base if (DOHYBVAR set to NO and l4densvar set to false) +export FHOUT_OCNICE=3 # Cycle to run EnKF (set to BOTH for both gfs and gdas) export EUPD_CYC="gdas" @@ -258,9 +259,10 @@ export gfs_cyc=@gfs_cyc@ # 0: no GFS cycle, 1: 00Z only, 2: 00Z and 12Z only, 4: # GFS output and frequency export FHMIN_GFS=0 export FHMAX_GFS=@FHMAX_GFS@ -export FHOUT_GFS=6 # Must be 6 for S2S until #1629 is addressed; 3 for ops +export FHOUT_GFS=3 # Must be 6 for S2S until #1629 is addressed; 3 for ops export FHMAX_HF_GFS=0 export FHOUT_HF_GFS=1 +export FHOUT_OCNICE_GFS=6 if (( gfs_cyc != 0 )); then export STEP_GFS=$(( 24 / gfs_cyc )) else diff --git a/parm/config/gfs/config.fcst b/parm/config/gfs/config.fcst index d2e2664e9c..c03c97e56f 100644 --- a/parm/config/gfs/config.fcst +++ b/parm/config/gfs/config.fcst @@ -30,6 +30,7 @@ case ${RUN} in export FHOUT=${FHOUT_GFS} export FHMAX_HF=${FHMAX_HF_GFS} export FHOUT_HF=${FHOUT_HF_GFS} + export FHOUT_OCNICE=${FHOUT_OCNICE_GFS} ;; *gdas) export FHMAX_HF=0 diff --git a/parm/ufs/fv3/diag_table b/parm/ufs/fv3/diag_table index b972b3470c..47106cb294 100644 --- a/parm/ufs/fv3/diag_table +++ b/parm/ufs/fv3/diag_table @@ -1,7 +1,7 @@ "fv3_history", 0, "hours", 1, "hours", "time" "fv3_history2d", 0, "hours", 1, "hours", "time" -"ocn%4yr%2mo%2dy%2hr", 6, "hours", 1, "hours", "time", 6, "hours", "1901 1 1 0 0 0" -"ocn_daily%4yr%2mo%2dy", 1, "days", 1, "days", "time", 1, "days", "1901 1 1 0 0 0" +"ocn%4yr%2mo%2dy%2hr", @[FHOUT_OCNICE], "hours", 1, "hours", "time", @[FHOUT_OCNICE], "hours", "@[SYEAR] @[SMONTH] @[SDAY] @[CHOUR] 0 0" +"ocn_daily%4yr%2mo%2dy", 1, "days", 1, "days", "time", 1, "days", "@[SYEAR] @[SMONTH] @[SDAY] @[CHOUR] 0 0" ############## # Ocean fields diff --git a/ush/forecast_predet.sh b/ush/forecast_predet.sh index 1aaa1a4b9d..ab02270b46 100755 --- a/ush/forecast_predet.sh +++ b/ush/forecast_predet.sh @@ -229,7 +229,7 @@ CICE_predet(){ # Convert output settings into an explicit list for CICE # Ignore "not used" warning # shellcheck disable=SC2034 - CICE_OUTPUT_FH=$(seq -s ' ' "${FHMIN}" "${FHOUT}" "${FHMAX}") + CICE_OUTPUT_FH=$(seq -s ' ' "${FHMIN}" "${FHOUT_OCNICE}" "${FHMAX}") } @@ -247,7 +247,7 @@ MOM6_predet(){ # Convert output settings into an explicit list for MOM6 # Ignore "not used" warning # shellcheck disable=SC2034 - MOM6_OUTPUT_FH=$(seq -s ' ' "${FHMIN}" "${FHOUT}" "${FHMAX}") + MOM6_OUTPUT_FH=$(seq -s ' ' "${FHMIN}" "${FHOUT_OCNICE}" "${FHMAX}") } diff --git a/ush/parsing_namelists_CICE.sh b/ush/parsing_namelists_CICE.sh index 3f1798d3e9..2dab096d16 100755 --- a/ush/parsing_namelists_CICE.sh +++ b/ush/parsing_namelists_CICE.sh @@ -62,7 +62,7 @@ local CICE_RESTART_FILE="cice_model.res" local CICE_DUMPFREQ="y" # "h","d","m" or "y" for restarts at intervals of "hours", "days", "months" or "years" local CICE_DUMPFREQ_N=10000 # Set this to a really large value, as cice, mom6 and cmeps restart interval is controlled by ufs.configure local CICE_DIAGFREQ=6 -local CICE_HISTFREQ_N="0, 0, ${FHOUT}, 1, 1" +local CICE_HISTFREQ_N="0, 0, ${FHOUT_OCNICE}, 1, 1" if [[ "${RUN}" =~ "gdas" ]]; then local CICE_HIST_AVG=".false., .false., .false., .false., .false." # DA needs instantaneous else diff --git a/ush/parsing_namelists_FV3.sh b/ush/parsing_namelists_FV3.sh index 83e0c10525..c57666598f 100755 --- a/ush/parsing_namelists_FV3.sh +++ b/ush/parsing_namelists_FV3.sh @@ -33,7 +33,15 @@ if [[ -n "${AERO_DIAG_TABLE:-}" ]]; then cat "${AERO_DIAG_TABLE}" fi cat "${DIAG_TABLE_APPEND}" -} >> diag_table +} >> diag_table_template + +local template=diag_table_template +local SYEAR=${current_cycle:0:4} +local SMONTH=${current_cycle:4:2} +local SDAY=${current_cycle:6:2} +local CHOUR=${current_cycle:8:2} +source "${HOMEgfs}/ush/atparse.bash" +atparse < "${template}" >> "diag_table" # copy data table diff --git a/ush/python/pygfs/task/oceanice_products.py b/ush/python/pygfs/task/oceanice_products.py index 968acb0750..c865a9f408 100644 --- a/ush/python/pygfs/task/oceanice_products.py +++ b/ush/python/pygfs/task/oceanice_products.py @@ -61,7 +61,7 @@ def __init__(self, config: Dict[str, Any]) -> None: # TODO: This is a bit of a hack, but it works for now # FIXME: find a better way to provide the averaging period # This will be different for ocean and ice, so when they are made flexible, this will need to be addressed - avg_period = f"{self.config.FORECAST_HOUR-self.config.FHOUT_GFS:03d}-{self.config.FORECAST_HOUR:03d}" + avg_period = f"{self.config.FORECAST_HOUR-self.config.FHOUT_OCNICE_GFS:03d}-{self.config.FORECAST_HOUR:03d}" localdict = AttrDict( {'component': self.config.COMPONENT, diff --git a/workflow/rocoto/gfs_tasks.py b/workflow/rocoto/gfs_tasks.py index 83623f42d2..58a802bb2e 100644 --- a/workflow/rocoto/gfs_tasks.py +++ b/workflow/rocoto/gfs_tasks.py @@ -936,6 +936,7 @@ def _get_ufs_postproc_grps(cdump, config, component='atmos'): if component in ['ocean', 'ice']: local_config['FHMAX_HF_GFS'] = config['FHMAX_GFS'] local_config['FHOUT_HF_GFS'] = config['FHOUT_GFS'] + local_config['FHOUT_GFS']=config['FHOUT_OCNICE_GFS'] fhrs = Tasks._get_forecast_hours(cdump, local_config) From 6667b4a6160612bf922d91f2b92d3bd0081b1009 Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Sun, 18 Feb 2024 13:54:03 +0000 Subject: [PATCH 2/9] adjust how workflow for ocn ice post fhr are being calculated --- workflow/rocoto/gfs_tasks.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/workflow/rocoto/gfs_tasks.py b/workflow/rocoto/gfs_tasks.py index 58a802bb2e..a63889e42a 100644 --- a/workflow/rocoto/gfs_tasks.py +++ b/workflow/rocoto/gfs_tasks.py @@ -935,8 +935,10 @@ def _get_ufs_postproc_grps(cdump, config, component='atmos'): # Ocean/Ice components do not have a HF output option like the atmosphere if component in ['ocean', 'ice']: local_config['FHMAX_HF_GFS'] = config['FHMAX_GFS'] - local_config['FHOUT_HF_GFS'] = config['FHOUT_GFS'] + local_config['FHOUT_HF_GFS'] = config['FHOUT_OCNICE_GFS'] local_config['FHOUT_GFS']=config['FHOUT_OCNICE_GFS'] + local_config['FHOUT_GFS']=config['FHOUT_OCNICE_GFS'] + local_config['FHOUT']=config['FHOUT_OCNICE'] fhrs = Tasks._get_forecast_hours(cdump, local_config) From ff7a3c87811599ec7d5046d7b9d5ca353b1568be Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Tue, 20 Feb 2024 16:54:03 +0000 Subject: [PATCH 3/9] surpress warning --- ush/parsing_namelists_FV3.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ush/parsing_namelists_FV3.sh b/ush/parsing_namelists_FV3.sh index c57666598f..88a0065076 100755 --- a/ush/parsing_namelists_FV3.sh +++ b/ush/parsing_namelists_FV3.sh @@ -9,6 +9,8 @@ ## This script is a direct execution. ##### +# Disable variable not used warnings +# shellcheck disable=SC2034 FV3_namelists(){ # setup the tables From af70cf3132e6124e1b7debab0e4105a6326fe0a1 Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Tue, 20 Feb 2024 16:54:59 +0000 Subject: [PATCH 4/9] Update workflow/rocoto/gfs_tasks.py Co-authored-by: Rahul Mahajan --- workflow/rocoto/gfs_tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow/rocoto/gfs_tasks.py b/workflow/rocoto/gfs_tasks.py index a63889e42a..f0876d1c02 100644 --- a/workflow/rocoto/gfs_tasks.py +++ b/workflow/rocoto/gfs_tasks.py @@ -938,7 +938,7 @@ def _get_ufs_postproc_grps(cdump, config, component='atmos'): local_config['FHOUT_HF_GFS'] = config['FHOUT_OCNICE_GFS'] local_config['FHOUT_GFS']=config['FHOUT_OCNICE_GFS'] local_config['FHOUT_GFS']=config['FHOUT_OCNICE_GFS'] - local_config['FHOUT']=config['FHOUT_OCNICE'] + local_config['FHOUT'] = config['FHOUT_OCNICE'] fhrs = Tasks._get_forecast_hours(cdump, local_config) From 02d8cc20d74ec59ae67253886db66c04eaaea904 Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Tue, 20 Feb 2024 16:55:40 +0000 Subject: [PATCH 5/9] fix pycode style --- workflow/rocoto/gfs_tasks.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workflow/rocoto/gfs_tasks.py b/workflow/rocoto/gfs_tasks.py index f0876d1c02..646d67cf67 100644 --- a/workflow/rocoto/gfs_tasks.py +++ b/workflow/rocoto/gfs_tasks.py @@ -936,8 +936,8 @@ def _get_ufs_postproc_grps(cdump, config, component='atmos'): if component in ['ocean', 'ice']: local_config['FHMAX_HF_GFS'] = config['FHMAX_GFS'] local_config['FHOUT_HF_GFS'] = config['FHOUT_OCNICE_GFS'] - local_config['FHOUT_GFS']=config['FHOUT_OCNICE_GFS'] - local_config['FHOUT_GFS']=config['FHOUT_OCNICE_GFS'] + local_config['FHOUT_GFS'] = config['FHOUT_OCNICE_GFS'] + local_config['FHOUT_GFS'] = config['FHOUT_OCNICE_GFS'] local_config['FHOUT'] = config['FHOUT_OCNICE'] fhrs = Tasks._get_forecast_hours(cdump, local_config) From 9e21b6f692f10bc443d970381ce5a59aecf57b0a Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Tue, 20 Feb 2024 16:56:19 +0000 Subject: [PATCH 6/9] remove duplicate --- workflow/rocoto/gfs_tasks.py | 1 - 1 file changed, 1 deletion(-) diff --git a/workflow/rocoto/gfs_tasks.py b/workflow/rocoto/gfs_tasks.py index 646d67cf67..caa4003f8c 100644 --- a/workflow/rocoto/gfs_tasks.py +++ b/workflow/rocoto/gfs_tasks.py @@ -937,7 +937,6 @@ def _get_ufs_postproc_grps(cdump, config, component='atmos'): local_config['FHMAX_HF_GFS'] = config['FHMAX_GFS'] local_config['FHOUT_HF_GFS'] = config['FHOUT_OCNICE_GFS'] local_config['FHOUT_GFS'] = config['FHOUT_OCNICE_GFS'] - local_config['FHOUT_GFS'] = config['FHOUT_OCNICE_GFS'] local_config['FHOUT'] = config['FHOUT_OCNICE'] fhrs = Tasks._get_forecast_hours(cdump, local_config) From c6352f3884bb863c73575c9564447ba6691daf6a Mon Sep 17 00:00:00 2001 From: Jessica Meixner Date: Tue, 20 Feb 2024 17:36:58 +0000 Subject: [PATCH 7/9] fix gefs config fcst --- parm/config/gefs/config.fcst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parm/config/gefs/config.fcst b/parm/config/gefs/config.fcst index dc4f70ecfe..74a84e1173 100644 --- a/parm/config/gefs/config.fcst +++ b/parm/config/gefs/config.fcst @@ -27,7 +27,7 @@ export FHMAX=${FHMAX_GFS} export FHOUT=${FHOUT_GFS} export FHMAX_HF=${FHMAX_HF_GFS} export FHOUT_HF=${FHOUT_HF_GFS} -export FHOUT_OCNICE_GFS=${FHOUT_OCNICE} +export FHOUT_OCNICE=${FHOUT_OCNICE_GFS} # Get task specific resources source "${EXPDIR}/config.resources" fcst From 59f8132d379b7b76154d3a97c8ed563fe417b2ab Mon Sep 17 00:00:00 2001 From: "Walter.Kolczynski" Date: Tue, 20 Feb 2024 11:58:34 -0600 Subject: [PATCH 8/9] Move component modification of output times The forecast hour list used to create the rocoto product metatasks were being made in the groups function instead of the forecast hour list function. --- workflow/rocoto/gfs_tasks.py | 16 +--------------- workflow/rocoto/tasks.py | 28 ++++++++++++++++++++-------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/workflow/rocoto/gfs_tasks.py b/workflow/rocoto/gfs_tasks.py index caa4003f8c..dd5b0cd551 100644 --- a/workflow/rocoto/gfs_tasks.py +++ b/workflow/rocoto/gfs_tasks.py @@ -929,21 +929,7 @@ def atmanlprod(self): @staticmethod def _get_ufs_postproc_grps(cdump, config, component='atmos'): - # Make a local copy of the config to avoid modifying the original - local_config = config.copy() - - # Ocean/Ice components do not have a HF output option like the atmosphere - if component in ['ocean', 'ice']: - local_config['FHMAX_HF_GFS'] = config['FHMAX_GFS'] - local_config['FHOUT_HF_GFS'] = config['FHOUT_OCNICE_GFS'] - local_config['FHOUT_GFS'] = config['FHOUT_OCNICE_GFS'] - local_config['FHOUT'] = config['FHOUT_OCNICE'] - - fhrs = Tasks._get_forecast_hours(cdump, local_config) - - # ocean/ice components do not have fhr 0 as they are averaged output - if component in ['ocean', 'ice']: - fhrs.remove(0) + fhrs = Tasks._get_forecast_hours(cdump, config, component=component) nfhrs_per_grp = config.get('NFHRS_PER_GROUP', 1) ngrps = len(fhrs) // nfhrs_per_grp if len(fhrs) % nfhrs_per_grp == 0 else len(fhrs) // nfhrs_per_grp + 1 diff --git a/workflow/rocoto/tasks.py b/workflow/rocoto/tasks.py index 540f6ebe47..bfa95b8392 100644 --- a/workflow/rocoto/tasks.py +++ b/workflow/rocoto/tasks.py @@ -120,20 +120,32 @@ def _template_to_rocoto_cycstring(self, template: str, subs_dict: dict = {}) -> rocoto_conversion_dict.get) @staticmethod - def _get_forecast_hours(cdump, config) -> List[str]: - fhmin = config['FHMIN'] - fhmax = config['FHMAX'] - fhout = config['FHOUT'] + def _get_forecast_hours(cdump, config, component='atmos') -> List[str]: + # Make a local copy of the config to avoid modifying the original + local_config = config.copy() + + # Ocean/Ice components do not have a HF output option like the atmosphere + if component in ['ocean', 'ice']: + local_config['FHMAX_HF_GFS'] = config['FHMAX_GFS'] + local_config['FHOUT_HF_GFS'] = config['FHOUT_OCNICE_GFS'] + local_config['FHOUT_GFS'] = config['FHOUT_OCNICE_GFS'] + # ocean/ice components do not have fhr 0 as they are averaged output + local_config['FHMIN'] = config['FHOUT_OCNICE'] + local_config['FHOUT'] = config['FHOUT_OCNICE'] + + fhmin = local_config['FHMIN'] + fhmax = local_config['FHMAX'] + fhout = local_config['FHOUT'] # Get a list of all forecast hours fhrs = [] if cdump in ['gdas']: fhrs = list(range(fhmin, fhmax + fhout, fhout)) elif cdump in ['gfs', 'gefs']: - fhmax = config['FHMAX_GFS'] - fhout = config['FHOUT_GFS'] - fhmax_hf = config['FHMAX_HF_GFS'] - fhout_hf = config['FHOUT_HF_GFS'] + fhmax = local_config['FHMAX_GFS'] + fhout = local_config['FHOUT_GFS'] + fhmax_hf = local_config['FHMAX_HF_GFS'] + fhout_hf = local_config['FHOUT_HF_GFS'] fhrs_hf = range(fhmin, fhmax_hf + fhout_hf, fhout_hf) fhrs = list(fhrs_hf) + list(range(fhrs_hf[-1] + fhout, fhmax + fhout, fhout)) From 1e46fc9e7149e766c8807245f9698336863c7d9b Mon Sep 17 00:00:00 2001 From: "Walter.Kolczynski" Date: Tue, 20 Feb 2024 13:01:41 -0600 Subject: [PATCH 9/9] Fix the marine start time --- workflow/rocoto/tasks.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/workflow/rocoto/tasks.py b/workflow/rocoto/tasks.py index bfa95b8392..77847133a9 100644 --- a/workflow/rocoto/tasks.py +++ b/workflow/rocoto/tasks.py @@ -129,8 +129,6 @@ def _get_forecast_hours(cdump, config, component='atmos') -> List[str]: local_config['FHMAX_HF_GFS'] = config['FHMAX_GFS'] local_config['FHOUT_HF_GFS'] = config['FHOUT_OCNICE_GFS'] local_config['FHOUT_GFS'] = config['FHOUT_OCNICE_GFS'] - # ocean/ice components do not have fhr 0 as they are averaged output - local_config['FHMIN'] = config['FHOUT_OCNICE'] local_config['FHOUT'] = config['FHOUT_OCNICE'] fhmin = local_config['FHMIN'] @@ -149,6 +147,10 @@ def _get_forecast_hours(cdump, config, component='atmos') -> List[str]: fhrs_hf = range(fhmin, fhmax_hf + fhout_hf, fhout_hf) fhrs = list(fhrs_hf) + list(range(fhrs_hf[-1] + fhout, fhmax + fhout, fhout)) + # ocean/ice components do not have fhr 0 as they are averaged output + if component in ['ocean', 'ice']: + fhrs.remove(0) + return fhrs def get_resource(self, task_name):