From 94f20293a3cc0d550500a7028dd81ce9a324cc9b Mon Sep 17 00:00:00 2001 From: AntonMFernando-NOAA <167725623+AntonMFernando-NOAA@users.noreply.github.com> Date: Wed, 27 Nov 2024 02:27:47 -0500 Subject: [PATCH] Refactor gridded wave post (#3014) The gridded wave post (wavepostsbs) script currently loops over all forecast hours and acts as its own post manager. Other component post and product scripts operate on one forecast time. This PR will update the wave post to match other components, that creates a bunch of short jobs instead of one long job (per member). Resolves #2290 --- parm/config/gefs/config.base | 4 + parm/config/gfs/config.base | 4 + scripts/exgfs_wave_post_gridded_sbs.sh | 332 +++++++++++-------------- workflow/rocoto/gefs_tasks.py | 25 +- workflow/rocoto/gfs_tasks.py | 28 ++- workflow/rocoto/tasks.py | 8 +- 6 files changed, 205 insertions(+), 196 deletions(-) diff --git a/parm/config/gefs/config.base b/parm/config/gefs/config.base index acfc39db33..65bca1b377 100644 --- a/parm/config/gefs/config.base +++ b/parm/config/gefs/config.base @@ -248,6 +248,10 @@ export FHOUT_WAV=3 export FHMAX_HF_WAV=120 export FHOUT_HF_WAV=1 export FHMAX_WAV=${FHMAX_GFS} +export FHMAX_WAV_GFS=${FHMAX_GFS} +export FHMAX_HF_GFS=$(( FHMAX_HF_GFS > FHMAX_GFS ? FHMAX_GFS : FHMAX_HF_GFS )) +export FHMAX_WAV_GFS=$(( FHMAX_WAV_GFS > FHMAX_GFS ? FHMAX_GFS : FHMAX_WAV_GFS )) +export FHMAX_HF_WAV=$(( FHMAX_HF_WAV > FHMAX_WAV_GFS ? FHMAX_WAV_GFS : FHMAX_HF_WAV )) export ILPOST=1 # gempak output frequency up to F120 export FHMIN_ENKF=${FHMIN_GFS} diff --git a/parm/config/gfs/config.base b/parm/config/gfs/config.base index 91f353360f..46e27b4541 100644 --- a/parm/config/gfs/config.base +++ b/parm/config/gfs/config.base @@ -311,6 +311,10 @@ export FHMAX_HF_WAV=120 export FHOUT_HF_WAV=1 export FHMAX_WAV=${FHMAX:-9} export FHMAX_WAV_GFS=${FHMAX_GFS} +export FHMAX_HF_GFS=$(( FHMAX_HF_GFS > FHMAX_GFS ? FHMAX_GFS : FHMAX_HF_GFS )) +export FHMAX_WAV=$(( FHMAX_WAV > FHMAX ? FHMAX : FHMAX_WAV )) +export FHMAX_WAV_GFS=$(( FHMAX_WAV_GFS > FHMAX_GFS ? FHMAX_GFS : FHMAX_WAV_GFS )) +export FHMAX_HF_WAV=$(( FHMAX_HF_WAV > FHMAX_WAV_GFS ? FHMAX_WAV_GFS : FHMAX_HF_WAV )) # TODO: Change gempak to use standard out variables (#2348) export ILPOST=${FHOUT_HF_GFS} # gempak output frequency up to F120 diff --git a/scripts/exgfs_wave_post_gridded_sbs.sh b/scripts/exgfs_wave_post_gridded_sbs.sh index b0cca34bd1..a241a00d88 100755 --- a/scripts/exgfs_wave_post_gridded_sbs.sh +++ b/scripts/exgfs_wave_post_gridded_sbs.sh @@ -217,219 +217,189 @@ source "${USHgfs}/preamble.sh" set +x echo ' Making command file for sbs grib2 and GRID Interpolation ' set_trace - -# 1.a.2 Loop over forecast time to generate post files -# When executed side-by-side, serial mode (cfp when run after the fcst step) -# Contingency for RERUN=YES - if [ "${RERUN-NO}" = "YES" ]; then - fhr=$((FHRUN + FHMIN_WAV)) - if [ $FHMAX_HF_WAV -gt 0 ] && [ $FHOUT_HF_WAV -gt 0 ] && [ $fhr -lt $FHMAX_HF_WAV ]; then - FHINCG=$FHOUT_HF_WAV - else - FHINCG=$FHOUT_WAV - fi - fhr=$((fhr + FHINCG)) - else - fhr=$FHMIN_WAV - fi + fhr=$(( 10#${FHR3} )) fhrg=$fhr - sleep_interval=10 - iwaitmax=120 # Maximum loop cycles for waiting until wave component output file is ready (fails after max) - while [ $fhr -le $FHMAX_WAV ]; do + ymdh=$($NDATE $fhr ${PDY}${cyc}) + YMD=$(echo $ymdh | cut -c1-8) + HMS="$(echo $ymdh | cut -c9-10)0000" + YMDHMS=${YMD}${HMS} + FH3=$(printf %03i $fhr) - ymdh=$($NDATE $fhr ${PDY}${cyc}) - YMD=$(echo $ymdh | cut -c1-8) - HMS="$(echo $ymdh | cut -c9-10)0000" - YMDHMS=${YMD}${HMS} - FH3=$(printf %03i $fhr) - - fcmdnow=cmdfile.${FH3} - fcmdigrd=icmdfile.${FH3} - mkdir output_$YMDHMS - cd output_$YMDHMS - rm -f ${fcmdnow} ${fcmdigrd} - touch ${fcmdnow} ${fcmdigrd} + fcmdnow=cmdfile.${FH3} + fcmdigrd=icmdfile.${FH3} + mkdir output_$YMDHMS + cd output_$YMDHMS + rm -f ${fcmdnow} ${fcmdigrd} + touch ${fcmdnow} ${fcmdigrd} # Create instances of directories for gridded output - export GRIBDATA=${DATA}/output_$YMDHMS - export GRDIDATA=${DATA}/output_$YMDHMS + export GRIBDATA=${DATA}/output_$YMDHMS + export GRDIDATA=${DATA}/output_$YMDHMS # Gridded data (main part, need to be run side-by-side with forecast - - if [ $fhr = $fhrg ] - then - for wavGRD in ${waveGRD}; do - gfile="${COMIN_WAVE_HISTORY}/${WAV_MOD_TAG}.out_grd.${wavGRD}.${YMD}.${HMS}" - if ! wait_for_file "${gfile}" "${sleep_interval}" "${iwaitmax}"; then - echo " FATAL ERROR : NO RAW FIELD OUTPUT FILE out_grd.${grdID}" - echo "${WAV_MOD_TAG} post ${grdID} ${PDY} ${cycle} : field output missing." + + if [ $fhr = $fhrg ] + then + for wavGRD in ${waveGRD}; do + gfile="${COMIN_WAVE_HISTORY}/${WAV_MOD_TAG}.out_grd.${wavGRD}.${YMD}.${HMS}" + if [[ ! -s "${gfile}" ]]; then + echo " FATAL ERROR : NO RAW FIELD OUTPUT FILE ${gfile}" err=3; export err; "${errchk}" exit "${err}" fi - ${NLN} "${gfile}" "./out_grd.${wavGRD}" - done - - if [ "$DOGRI_WAV" = 'YES' ] - then - nigrd=1 - for grdID in $waveinterpGRD - do - ymdh_int=$($NDATE -${WAVHINDH} $ymdh); dt_int=3600.; n_int=9999 ; - echo "${USHgfs}/wave_grid_interp_sbs.sh $grdID $ymdh_int $dt_int $n_int > grint_$grdID.out 2>&1" >> ${fcmdigrd}.${nigrd} - if [ "$DOGRB_WAV" = 'YES' ] - then - gribFL=\'$(echo ${OUTPARS_WAV})\' - case $grdID in - glo_15mxt) GRDNAME='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; - reg025) GRDNAME='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; - glo_025) GRDNAME='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; - glo_100) GRDNAME='global' ; GRDRES=1p00 ; GRIDNR=255 ; MODNR=11 ;; - glo_200) GRDNAME='global' ; GRDRES=2p00 ; GRIDNR=255 ; MODNR=11 ;; - glo_500) GRDNAME='global' ; GRDRES=5p00 ; GRIDNR=255 ; MODNR=11 ;; - glo_30mxt) GRDNAME='global' ; GRDRES=0p50 ; GRIDNR=255 ; MODNR=11 ;; - glo_30m) GRDNAME='global' ; GRDRES=0p50 ; GRIDNR=255 ; MODNR=11 ;; - at_10m) GRDNAME='atlocn' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; - ep_10m) GRDNAME='epacif' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; - wc_10m) GRDNAME='wcoast' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; - ak_10m) GRDNAME='alaska' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; - esac - echo "${USHgfs}/wave_grib2_sbs.sh $grdID $GRIDNR $MODNR $ymdh $fhr $GRDNAME $GRDRES $gribFL > grib_$grdID.out 2>&1" >> ${fcmdigrd}.${nigrd} - fi - echo "${GRIBDATA}/${fcmdigrd}.${nigrd}" >> ${fcmdnow} - chmod 744 ${fcmdigrd}.${nigrd} - nigrd=$((nigrd+1)) - done - fi + ${NLN} "${gfile}" "./out_grd.${wavGRD}" + done - if [ "$DOGRB_WAV" = 'YES' ] - then - for grdID in ${wavepostGRD} # First concatenate grib files for sbs grids - do + if [ "$DOGRI_WAV" = 'YES' ] + then + nigrd=1 + for grdID in $waveinterpGRD + do + ymdh_int=$($NDATE -${WAVHINDH} $ymdh); dt_int=3600.; n_int=9999 ; + echo "${USHgfs}/wave_grid_interp_sbs.sh $grdID $ymdh_int $dt_int $n_int > grint_$grdID.out 2>&1" >> ${fcmdigrd}.${nigrd} + if [ "$DOGRB_WAV" = 'YES' ] + then gribFL=\'$(echo ${OUTPARS_WAV})\' case $grdID in - aoc_9km) GRDNAME='arctic' ; GRDRES=9km ; GRIDNR=255 ; MODNR=11 ;; - ant_9km) GRDNAME='antarc' ; GRDRES=9km ; GRIDNR=255 ; MODNR=11 ;; - glo_10m) GRDNAME='global' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; - gnh_10m) GRDNAME='global' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; - gsh_15m) GRDNAME='gsouth' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; - glo_15m) GRDNAME='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; - ao_20m) GRDNAME='arctic' ; GRDRES=0p33 ; GRIDNR=255 ; MODNR=11 ;; - so_20m) GRDNAME='antarc' ; GRDRES=0p33 ; GRIDNR=255 ; MODNR=11 ;; - glo_15mxt) GRDNAME='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; - reg025) GRDNAME='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; - glo_025) GRDNAME='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; - glo_100) GRDNAME='global' ; GRDRES=1p00 ; GRIDNR=255 ; MODNR=11 ;; - glo_200) GRDNAME='global' ; GRDRES=2p00 ; GRIDNR=255 ; MODNR=11 ;; - glo_500) GRDNAME='global' ; GRDRES=5p00 ; GRIDNR=255 ; MODNR=11 ;; - gwes_30m) GRDNAME='global' ; GRDRES=0p50 ; GRIDNR=255 ; MODNR=10 ;; + glo_15mxt) GRDNAME='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; + reg025) GRDNAME='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; + glo_025) GRDNAME='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; + glo_100) GRDNAME='global' ; GRDRES=1p00 ; GRIDNR=255 ; MODNR=11 ;; + glo_200) GRDNAME='global' ; GRDRES=2p00 ; GRIDNR=255 ; MODNR=11 ;; + glo_500) GRDNAME='global' ; GRDRES=5p00 ; GRIDNR=255 ; MODNR=11 ;; + glo_30mxt) GRDNAME='global' ; GRDRES=0p50 ; GRIDNR=255 ; MODNR=11 ;; + glo_30m) GRDNAME='global' ; GRDRES=0p50 ; GRIDNR=255 ; MODNR=11 ;; + at_10m) GRDNAME='atlocn' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; + ep_10m) GRDNAME='epacif' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; + wc_10m) GRDNAME='wcoast' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; + ak_10m) GRDNAME='alaska' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; esac - echo "${USHgfs}/wave_grib2_sbs.sh $grdID $GRIDNR $MODNR $ymdh $fhr $GRDNAME $GRDRES $gribFL > grib_$grdID.out 2>&1" >> ${fcmdnow} - done - fi - + echo "${USHgfs}/wave_grib2_sbs.sh $grdID $GRIDNR $MODNR $ymdh $fhr $GRDNAME $GRDRES $gribFL > grib_$grdID.out 2>&1" >> ${fcmdigrd}.${nigrd} + fi + echo "${GRIBDATA}/${fcmdigrd}.${nigrd}" >> ${fcmdnow} + chmod 744 ${fcmdigrd}.${nigrd} + nigrd=$((nigrd+1)) + done fi - if [ ${CFP_MP:-"NO"} = "YES" ]; then - nfile=0 - ifile=0 - iline=1 - ifirst='yes' - nlines=$( wc -l ${fcmdnow} | awk '{print $1}' ) - while [ $iline -le $nlines ]; do - line=$( sed -n ''$iline'p' ${fcmdnow} ) - if [ -z "$line" ]; then - break - else - if [ "$ifirst" = 'yes' ]; then - echo "#!/bin/sh" > cmdmfile.$nfile - echo "$nfile cmdmfile.$nfile" >> cmdmprog - chmod 744 cmdmfile.$nfile - fi - echo $line >> cmdmfile.$nfile - nfile=$(( nfile + 1 )) - if [ $nfile -eq $NTASKS ]; then - nfile=0 - ifirst='no' - fi - iline=$(( iline + 1 )) - fi + if [ "$DOGRB_WAV" = 'YES' ] + then + for grdID in ${wavepostGRD} # First concatenate grib files for sbs grids + do + gribFL=\'$(echo ${OUTPARS_WAV})\' + case $grdID in + aoc_9km) GRDNAME='arctic' ; GRDRES=9km ; GRIDNR=255 ; MODNR=11 ;; + ant_9km) GRDNAME='antarc' ; GRDRES=9km ; GRIDNR=255 ; MODNR=11 ;; + glo_10m) GRDNAME='global' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; + gnh_10m) GRDNAME='global' ; GRDRES=0p16 ; GRIDNR=255 ; MODNR=11 ;; + gsh_15m) GRDNAME='gsouth' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; + glo_15m) GRDNAME='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; + ao_20m) GRDNAME='arctic' ; GRDRES=0p33 ; GRIDNR=255 ; MODNR=11 ;; + so_20m) GRDNAME='antarc' ; GRDRES=0p33 ; GRIDNR=255 ; MODNR=11 ;; + glo_15mxt) GRDNAME='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; + reg025) GRDNAME='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; + glo_025) GRDNAME='global' ; GRDRES=0p25 ; GRIDNR=255 ; MODNR=11 ;; + glo_100) GRDNAME='global' ; GRDRES=1p00 ; GRIDNR=255 ; MODNR=11 ;; + glo_200) GRDNAME='global' ; GRDRES=2p00 ; GRIDNR=255 ; MODNR=11 ;; + glo_500) GRDNAME='global' ; GRDRES=5p00 ; GRIDNR=255 ; MODNR=11 ;; + gwes_30m) GRDNAME='global' ; GRDRES=0p50 ; GRIDNR=255 ; MODNR=10 ;; + esac + echo "${USHgfs}/wave_grib2_sbs.sh $grdID $GRIDNR $MODNR $ymdh $fhr $GRDNAME $GRDRES $gribFL > grib_$grdID.out 2>&1" >> ${fcmdnow} done fi - wavenproc=$(wc -l ${fcmdnow} | awk '{print $1}') - wavenproc=$(echo $((${wavenproc}<${NTASKS}?${wavenproc}:${NTASKS}))) + fi + + if [ ${CFP_MP:-"NO"} = "YES" ]; then + nfile=0 + ifile=0 + iline=1 + ifirst='yes' + nlines=$( wc -l ${fcmdnow} | awk '{print $1}' ) + while [ $iline -le $nlines ]; do + line=$( sed -n ''$iline'p' ${fcmdnow} ) + if [ -z "$line" ]; then + break + else + if [ "$ifirst" = 'yes' ]; then + echo "#!/bin/sh" > cmdmfile.$nfile + echo "$nfile cmdmfile.$nfile" >> cmdmprog + chmod 744 "cmdmfile.$nfile" + fi + echo $line >> "cmdmfile.$nfile" + nfile=$(( nfile + 1 )) + if [ "$nfile" -eq "$NTASKS" ]; then + nfile=0 + ifirst='no' + fi + iline=$(( iline + 1 )) + fi + done + fi + + wavenproc=$(wc -l ${fcmdnow} | awk '{print $1}') + wavenproc=$(echo $((${wavenproc}<${NTASKS}?${wavenproc}:${NTASKS}))) + + set +x + echo ' ' + echo " Executing the grib2_sbs scripts at : $(date)" + echo ' ------------------------------------' + echo ' ' + set_trace + + if [ "$wavenproc" -gt '1' ] + then + if [ ${CFP_MP:-"NO"} = "YES" ]; then + ${wavempexec} -n ${wavenproc} ${wave_mpmd} cmdmprog + else + ${wavempexec} ${wavenproc} ${wave_mpmd} ${fcmdnow} + fi + exit=$? + else + chmod 744 ${fcmdnow} + ./${fcmdnow} + exit=$? + fi + if [ "$exit" != '0' ] + then set +x echo ' ' - echo " Executing the grib2_sbs scripts at : $(date)" - echo ' ------------------------------------' + echo '*************************************' + echo '*** FATAL ERROR: CMDFILE FAILED ***' + echo '*************************************' + echo ' See Details Below ' echo ' ' set_trace + err=4; export err;${errchk} + exit "$err" + fi - if [ "$wavenproc" -gt '1' ] - then - if [ ${CFP_MP:-"NO"} = "YES" ]; then - ${wavempexec} -n ${wavenproc} ${wave_mpmd} cmdmprog - else - ${wavempexec} ${wavenproc} ${wave_mpmd} ${fcmdnow} - fi - exit=$? - else - chmod 744 ${fcmdnow} - ./${fcmdnow} - exit=$? - fi + rm -f out_grd.* # Remove large binary grid output files - if [ "$exit" != '0' ] - then + cd $DATA + + + if [ "$fhr" = "$fhrg" ] + then +# Check if grib2 file created + ENSTAG="" + if [ ${waveMEMB} ]; then ENSTAG=".${membTAG}${waveMEMB}" ; fi + gribchk="${RUN}wave.${cycle}${ENSTAG}.${GRDNAME}.${GRDRES}.f${FH3}.grib2" + if [ ! -s ${COMOUT_WAVE_GRID}/${gribchk} ]; then set +x echo ' ' - echo '*************************************' - echo '*** FATAL ERROR: CMDFILE FAILED ***' - echo '*************************************' + echo '********************************************' + echo "*** FATAL ERROR: $gribchk not generated " + echo '********************************************' echo ' See Details Below ' echo ' ' set_trace - err=4; export err;${errchk} - exit $err - fi - - rm -f out_grd.* # Remove large binary grid output files - - cd $DATA - - FHINCG=$(( DTFLD_WAV / 3600 )) - if [ $fhr = $fhrg ] - then -# Check if grib2 file created - ENSTAG="" - if [ ${waveMEMB} ]; then ENSTAG=".${membTAG}${waveMEMB}" ; fi - gribchk="${RUN}wave.${cycle}${ENSTAG}.${GRDNAME}.${GRDRES}.f${FH3}.grib2" - if [ ! -s ${COMOUT_WAVE_GRID}/${gribchk} ]; then - set +x - echo ' ' - echo '********************************************' - echo "*** FATAL ERROR: $gribchk not generated " - echo '********************************************' - echo ' See Details Below ' - echo ' ' - set_trace - err=5; export err;${errchk} - exit $err - fi - if [ $FHMAX_HF_WAV -gt 0 ] && [ $FHOUT_HF_WAV -gt 0 ] && [ $fhr -lt $FHMAX_HF_WAV ]; then - FHINCG=$FHOUT_HF_WAV - else - FHINCG=$FHOUT_WAV - fi - fhrg=$((fhr+FHINCG)) + err=5; export err;${errchk} + exit "$err" fi - echo $fhrg - - fhr=$fhrg #loop with out_grd stride - - done + fi # --------------------------------------------------------------------------- # # 7. Ending output diff --git a/workflow/rocoto/gefs_tasks.py b/workflow/rocoto/gefs_tasks.py index 468ce01008..ca29bcdf1e 100644 --- a/workflow/rocoto/gefs_tasks.py +++ b/workflow/rocoto/gefs_tasks.py @@ -316,13 +316,14 @@ def wavepostsbs(self): wave_post_envars = self.envars.copy() postenvar_dict = {'ENSMEM': '#member#', 'MEMDIR': 'mem#member#', + 'FHR3': '#fhr#', } for key, value in postenvar_dict.items(): wave_post_envars.append(rocoto.create_envar(name=key, value=str(value))) resources = self.get_resource('wavepostsbs') - task_name = f'gefs_wave_post_grid_mem#member#' + task_name = f'gefs_wave_post_grid_mem#member#_f#fhr#' task_dict = {'task_name': task_name, 'resources': resources, 'dependency': dependencies, @@ -334,11 +335,21 @@ def wavepostsbs(self): 'maxtries': '&MAXTRIES;' } - member_var_dict = {'member': ' '.join([str(mem).zfill(3) for mem in range(0, self.nmem + 1)])} - member_metatask_dict = {'task_name': 'gefs_wave_post_grid', - 'task_dict': task_dict, - 'var_dict': member_var_dict - } + fhrs = self._get_forecast_hours('gefs', self._configs['wavepostsbs'], 'wave') + is_replay = self._configs['wavepostsbs']['REPLAY_ICS'] + if is_replay: + fhrs = [fhr for fhr in fhrs if fhr not in [0, 1, 2]] + + fhr_var_dict = {'fhr': ' '.join([f"{fhr:03d}" for fhr in fhrs])} + + fhr_metatask_dict = {'task_name': f'gefs_wave_post_grid_#member#', + 'task_dict': task_dict, + 'var_dict': fhr_var_dict} + + member_var_dict = {'member': ' '.join([f"{mem:03d}" for mem in range(0, self.nmem + 1)])} + member_metatask_dict = {'task_name': f'gefs_wave_post_grid', + 'task_dict': fhr_metatask_dict, + 'var_dict': member_var_dict} task = rocoto.create_task(member_metatask_dict) @@ -467,7 +478,7 @@ def wavepostpnt(self): def extractvars(self): deps = [] if self.options['do_wave']: - dep_dict = {'type': 'task', 'name': 'gefs_wave_post_grid_mem#member#'} + dep_dict = {'type': 'metatask', 'name': 'gefs_wave_post_grid_#member#'} deps.append(rocoto.add_dependency(dep_dict)) if self.options['do_ocean']: dep_dict = {'type': 'metatask', 'name': 'gefs_ocean_prod_#member#'} diff --git a/workflow/rocoto/gfs_tasks.py b/workflow/rocoto/gfs_tasks.py index 616248c110..535f5ce844 100644 --- a/workflow/rocoto/gfs_tasks.py +++ b/workflow/rocoto/gfs_tasks.py @@ -1172,6 +1172,7 @@ def _atmosoceaniceprod(self, component: str): fhrs.remove(0) fhr_var_dict = {'fhr': ' '.join([f"{fhr:03d}" for fhr in fhrs])} + if component in ['ocean']: fhrs_next = fhrs[1:] + [fhrs[-1] + (fhrs[-1] - fhrs[-2])] fhr_var_dict['fhr_next'] = ' '.join([f"{fhr:03d}" for fhr in fhrs_next]) @@ -1184,17 +1185,23 @@ def _atmosoceaniceprod(self, component: str): return task def wavepostsbs(self): + deps = [] dep_dict = {'type': 'metatask', 'name': f'{self.run}_fcst'} deps.append(rocoto.add_dependency(dep_dict)) dependencies = rocoto.create_dependency(dep=deps) + wave_post_envars = self.envars.copy() + postenvar_dict = {'FHR3': '#fhr#'} + for key, value in postenvar_dict.items(): + wave_post_envars.append(rocoto.create_envar(name=key, value=str(value))) + resources = self.get_resource('wavepostsbs') - task_name = f'{self.run}_wavepostsbs' + task_name = f'{self.run}_wavepostsbs_f#fhr#' task_dict = {'task_name': task_name, 'resources': resources, 'dependency': dependencies, - 'envars': self.envars, + 'envars': wave_post_envars, 'cycledef': self.run.replace('enkf', ''), 'command': f'{self.HOMEgfs}/jobs/rocoto/wavepostsbs.sh', 'job_name': f'{self.pslot}_{task_name}_@H', @@ -1202,7 +1209,14 @@ def wavepostsbs(self): 'maxtries': '&MAXTRIES;' } - task = rocoto.create_task(task_dict) + fhrs = self._get_forecast_hours('gfs', self._configs['wavepostsbs'], 'wave') + + fhr_metatask_dict = {'fhr': ' '.join([f"{fhr:03d}" for fhr in fhrs])} + metatask_dict = {'task_name': f'{self.run}_wavepostsbs', + 'task_dict': task_dict, + 'var_dict': fhr_metatask_dict} + + task = rocoto.create_task(metatask_dict) return task @@ -1286,7 +1300,7 @@ def wavepostpnt(self): def wavegempak(self): deps = [] - dep_dict = {'type': 'task', 'name': f'{self.run}_wavepostsbs'} + dep_dict = {'type': 'metatask', 'name': f'{self.run}_wavepostsbs'} deps.append(rocoto.add_dependency(dep_dict)) dependencies = rocoto.create_dependency(dep=deps) @@ -1309,7 +1323,7 @@ def wavegempak(self): def waveawipsbulls(self): deps = [] - dep_dict = {'type': 'task', 'name': f'{self.run}_wavepostsbs'} + dep_dict = {'type': 'metatask', 'name': f'{self.run}_wavepostsbs'} deps.append(rocoto.add_dependency(dep_dict)) dep_dict = {'type': 'task', 'name': f'{self.run}_wavepostpnt'} deps.append(rocoto.add_dependency(dep_dict)) @@ -1334,7 +1348,7 @@ def waveawipsbulls(self): def waveawipsgridded(self): deps = [] - dep_dict = {'type': 'task', 'name': f'{self.run}_wavepostsbs'} + dep_dict = {'type': 'metatask', 'name': f'{self.run}_wavepostsbs'} deps.append(rocoto.add_dependency(dep_dict)) dependencies = rocoto.create_dependency(dep=deps) @@ -2271,7 +2285,7 @@ def arch(self): dep_dict = {'type': 'metatask', 'name': f'{self.run}_atmos_prod'} deps.append(rocoto.add_dependency(dep_dict)) if self.options['do_wave']: - dep_dict = {'type': 'task', 'name': f'{self.run}_wavepostsbs'} + dep_dict = {'type': 'metatask', 'name': f'{self.run}_wavepostsbs'} deps.append(rocoto.add_dependency(dep_dict)) dep_dict = {'type': 'task', 'name': f'{self.run}_wavepostpnt'} deps.append(rocoto.add_dependency(dep_dict)) diff --git a/workflow/rocoto/tasks.py b/workflow/rocoto/tasks.py index 2aee48835f..c0496a4996 100644 --- a/workflow/rocoto/tasks.py +++ b/workflow/rocoto/tasks.py @@ -152,6 +152,12 @@ def _get_forecast_hours(run, config, component='atmos') -> List[str]: local_config['FHOUT_GFS'] = config['FHOUT_ICE_GFS'] local_config['FHOUT'] = config['FHOUT_ICE'] + if component in ['wave']: + local_config['FHOUT_HF_GFS'] = config['FHOUT_HF_WAV'] + local_config['FHMAX_HF_GFS'] = config['FHMAX_HF_WAV'] + local_config['FHOUT_GFS'] = config['FHOUT_WAV'] + local_config['FHOUT'] = config['FHOUT_WAV'] + fhmin = local_config['FHMIN'] # Get a list of all forecast hours @@ -163,8 +169,8 @@ def _get_forecast_hours(run, config, component='atmos') -> List[str]: elif run in ['gfs', 'gefs']: fhmax = local_config['FHMAX_GFS'] fhout = local_config['FHOUT_GFS'] - fhmax_hf = local_config['FHMAX_HF_GFS'] fhout_hf = local_config['FHOUT_HF_GFS'] + fhmax_hf = local_config['FHMAX_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))