diff --git a/jobs/JGLOBAL_ARCHIVE b/jobs/JGLOBAL_ARCHIVE index 00ca73ceb7..e6c016e703 100755 --- a/jobs/JGLOBAL_ARCHIVE +++ b/jobs/JGLOBAL_ARCHIVE @@ -17,6 +17,7 @@ YMD=${PDY} HH=${cyc} generate_com -rx COM_ATMOS_ANALYSIS COM_ATMOS_BUFR COM_ATMO COM_ICE_HISTORY COM_ICE_INPUT COM_ICE_RESTART \ COM_OBS COM_TOP \ COM_OCEAN_HISTORY COM_OCEAN_INPUT COM_OCEAN_RESTART COM_OCEAN_XSECT COM_OCEAN_2D COM_OCEAN_3D \ + COM_OCEAN_ANALYSIS \ COM_WAVE_GRID COM_WAVE_HISTORY COM_WAVE_STATION \ COM_ATMOS_OZNMON COM_ATMOS_RADMON COM_ATMOS_MINMON diff --git a/jobs/JGLOBAL_FORECAST b/jobs/JGLOBAL_FORECAST index 7fb0fbe4f7..e42c81eaa4 100755 --- a/jobs/JGLOBAL_FORECAST +++ b/jobs/JGLOBAL_FORECAST @@ -61,13 +61,13 @@ fi if [[ ${DO_OCN} == "YES" ]]; then YMD=${PDY} HH=${cyc} generate_com -rx COM_MED_RESTART COM_OCEAN_RESTART COM_OCEAN_INPUT \ COM_OCEAN_HISTORY COM_OCEAN_ANALYSIS - RUN=${CDUMP} YMD="${gPDY}" HH="${gcyc}" generate_com -rx \ + RUN=${rCDUMP} YMD="${gPDY}" HH="${gcyc}" generate_com -rx \ COM_OCEAN_RESTART_PREV:COM_OCEAN_RESTART_TMPL fi if [[ ${DO_ICE} == "YES" ]]; then YMD=${PDY} HH=${cyc} generate_com -rx COM_ICE_HISTORY COM_ICE_INPUT COM_ICE_RESTART - RUN=${CDUMP} YMD="${gPDY}" HH="${gcyc}" generate_com -rx \ + RUN=${rCDUMP} YMD="${gPDY}" HH="${gcyc}" generate_com -rx \ COM_ICE_RESTART_PREV:COM_ICE_RESTART_TMPL fi diff --git a/jobs/JGLOBAL_STAGE_IC b/jobs/JGLOBAL_STAGE_IC index 437c8f40a0..317231871e 100755 --- a/jobs/JGLOBAL_STAGE_IC +++ b/jobs/JGLOBAL_STAGE_IC @@ -3,6 +3,10 @@ source "${HOMEgfs}/ush/preamble.sh" source "${HOMEgfs}/ush/jjob_header.sh" -e "stage_ic" -c "base stage_ic" +# Restart conditions for GFS cycle come from GDAS +# shellcheck disable=SC2153 +rCDUMP=${CDUMP} +[[ ${CDUMP} = "gfs" ]] && export rCDUMP="gdas" # Execute the Script "${HOMEgfs}/scripts/exglobal_stage_ic.sh" diff --git a/parm/config/gefs/config.base.emc.dyn b/parm/config/gefs/config.base.emc.dyn index 3d17421408..b62c921ed0 100644 --- a/parm/config/gefs/config.base.emc.dyn +++ b/parm/config/gefs/config.base.emc.dyn @@ -40,6 +40,7 @@ export FIXreg2grb2=${HOMEgfs}/fix/reg2grb2 export PACKAGEROOT="@PACKAGEROOT@" # TODO: set via prod_envir in Ops export COMROOT="@COMROOT@" # TODO: set via prod_envir in Ops export COMINsyn="@COMINsyn@" +export BASE_CPLIC="@BASE_CPLIC@" # USER specific paths export HOMEDIR="@HOMEDIR@" diff --git a/parm/config/gefs/config.coupled_ic b/parm/config/gefs/config.coupled_ic deleted file mode 100644 index 50fab283b5..0000000000 --- a/parm/config/gefs/config.coupled_ic +++ /dev/null @@ -1,43 +0,0 @@ -#! /usr/bin/env bash - -########## config.coupled_ic ########## - -echo "BEGIN: config.coupled_ic" - -# Get task specific resources -source ${EXPDIR}/config.resources coupled_ic - -if [[ "${machine}" == "WCOSS2" ]]; then - export BASE_CPLIC="/lfs/h2/emc/couple/noscrub/Jiande.Wang/IC" -elif [[ "${machine}" == "HERA" ]]; then - export BASE_CPLIC="/scratch1/NCEPDEV/climate/role.ufscpara/IC" -elif [[ "${machine}" == "ORION" ]]; then - export BASE_CPLIC="/work/noaa/global/glopara/data/ICSDIR/prototype_ICs" -elif [[ "${machine}" == "S4" ]]; then - export BASE_CPLIC="/data/prod/glopara/coupled_ICs" -elif [[ "${machine}" == "JET" ]]; then - export BASE_CPLIC="/mnt/lfs4/HFIP/hfv3gfs/glopara/data/ICSDIR/prototype_ICs" -fi - - -case "${CASE}" in - "C384") - #C384 and P8 ICs - export CPL_ATMIC=GEFS-NoahMP-aerosols-p8c - export CPL_ICEIC=CPC - export CPL_OCNIC=CPC3Dvar - export CPL_WAVIC=GEFSwave20210528v2 - ;; - "C768") - export CPL_ATMIC=HR1 - export CPL_ICEIC=HR1 - export CPL_OCNIC=HR1 - export CPL_WAVIC=HR1 - ;; - *) - echo "Unrecognized case: ${1}" - exit 1 - ;; -esac - -echo "END: config.coupled_ic" diff --git a/parm/config/gefs/config.resources b/parm/config/gefs/config.resources index 33156a768a..74e9854084 100644 --- a/parm/config/gefs/config.resources +++ b/parm/config/gefs/config.resources @@ -8,7 +8,7 @@ if [[ $# -ne 1 ]]; then echo "Must specify an input task argument to set resource variables!" echo "argument can be any one of the following:" - echo "coupled_ic aerosol_init" + echo "stage_ic aerosol_init" echo "sfcanl analcalc analdiag fcst post vrfy fit2obs metp arch echgres" echo "ecen esfc efcs epos earc" echo "init_chem mom6ic ocnpost" @@ -416,12 +416,12 @@ elif [[ ${step} = "arch" || ${step} = "earc" ]]; then eval "export memory_${step}=50GB" fi -elif [[ ${step} = "coupled_ic" ]]; then +elif [[ ${step} = "stage_ic" ]]; then - export wtime_coupled_ic="00:15:00" - export npe_coupled_ic=1 - export npe_node_coupled_ic=1 - export nth_coupled_ic=1 + export wtime_stage_ic="00:15:00" + export npe_stage_ic=1 + export npe_node_stage_ic=1 + export nth_stage_ic=1 export is_exclusive=True elif [[ ${step} = "ecen" ]]; then diff --git a/parm/config/gefs/config.stage_ic b/parm/config/gefs/config.stage_ic new file mode 100644 index 0000000000..e2bb0af2b8 --- /dev/null +++ b/parm/config/gefs/config.stage_ic @@ -0,0 +1,23 @@ +#! /usr/bin/env bash + +########## config.stage_ic ########## + +echo "BEGIN: config.stage_ic" + +# Get task specific resources +source "${EXPDIR}/config.resources" stage_ic + +case "${CASE}" in + "C48") + export CPL_ATMIC="gefs_test" + export CPL_ICEIC="gefs_test" + export CPL_OCNIC="gefs_test" + export CPL_WAVIC="gefs_test" + ;; + *) + echo "FATAL ERROR Unrecognized resolution: ${CASE}" + exit 1 + ;; +esac + +echo "END: config.stage_ic" diff --git a/parm/config/gfs/config.stage_ic b/parm/config/gfs/config.stage_ic index 4e29c3306e..6d081b3fe0 100644 --- a/parm/config/gfs/config.stage_ic +++ b/parm/config/gfs/config.stage_ic @@ -9,22 +9,22 @@ source "${EXPDIR}/config.resources" stage_ic case "${CASE}" in "C48" | "C96") - export CPL_ATMIC=workflowtest - export CPL_ICEIC=workflowtest - export CPL_OCNIC=workflowtest - export CPL_WAVIC=workflowtest + export CPL_ATMIC="workflow_${CASE}_refactored" + export CPL_ICEIC="workflow_${CASE}_refactored" + export CPL_OCNIC="workflow_${CASE}_refactored" + export CPL_WAVIC="workflow_${CASE}_refactored" ;; "C384") - export CPL_ATMIC=GEFS-NoahMP-aerosols-p8c - export CPL_ICEIC=CPC - export CPL_OCNIC=CPC3Dvar - export CPL_WAVIC=GEFSwave20210528v2 + export CPL_ATMIC=GEFS-NoahMP-aerosols-p8c_refactored + export CPL_ICEIC=CPC_refactored + export CPL_OCNIC=CPC3Dvar_refactored + export CPL_WAVIC=GEFSwave20210528v2_refactored ;; "C768") - export CPL_ATMIC=HR2 - export CPL_ICEIC=HR1 - export CPL_OCNIC=HR1 - export CPL_WAVIC=HR1 + export CPL_ATMIC=HR2_refactored + export CPL_ICEIC=HR1_refactored + export CPL_OCNIC=HR1_refactored + export CPL_WAVIC=HR1_refactored ;; *) echo "FATAL ERROR Unrecognized resolution: ${CASE}" diff --git a/scripts/exglobal_archive.sh b/scripts/exglobal_archive.sh index 54323a0dd0..dcc864e223 100755 --- a/scripts/exglobal_archive.sh +++ b/scripts/exglobal_archive.sh @@ -238,7 +238,7 @@ if [[ ${HPSSARCH} = "YES" || ${LOCALARCH} = "YES" ]]; then #gdasocean if [ "${DO_OCN}" = "YES" ]; then - targrp_list="${targrp_list} gdasocean" + targrp_list="${targrp_list} gdasocean gdasocean_analysis" fi #gdasice diff --git a/scripts/exglobal_stage_ic.sh b/scripts/exglobal_stage_ic.sh index e42a4943d4..43812adc89 100755 --- a/scripts/exglobal_stage_ic.sh +++ b/scripts/exglobal_stage_ic.sh @@ -1,4 +1,4 @@ -#! /usr/bin/env bash +#!/usr/bin/env bash source "${HOMEgfs}/ush/preamble.sh" @@ -8,99 +8,89 @@ GDATE=$(date --utc -d "${PDY} ${cyc} - ${assim_freq} hours" +%Y%m%d%H) gPDY="${GDATE:0:8}" gcyc="${GDATE:8:2}" +MEMDIR_ARRAY=() +if [[ "${RUN}" == "gefs" ]]; then + # Populate the member_dirs array based on the value of NMEM_ENS + for ((ii = 0; ii <= "${NMEM_ENS}"; ii++)); do + MEMDIR_ARRAY+=("mem$(printf "%03d" "${ii}")") + done +else + MEMDIR_ARRAY+=("") +fi + # Initialize return code err=0 -error_message(){ - echo "FATAL ERROR: Unable to copy ${1} to ${2} (Error code ${3})" +error_message() { + echo "FATAL ERROR: Unable to copy ${1} to ${2} (Error code ${3})" } ############################################################### -# Start staging - -# Stage the FV3 initial conditions to ROTDIR (cold start) -YMD=${PDY} HH=${cyc} generate_com -r COM_ATMOS_INPUT -[[ ! -d "${COM_ATMOS_INPUT}" ]] && mkdir -p "${COM_ATMOS_INPUT}" -source="${BASE_CPLIC}/${CPL_ATMIC}/${PDY}${cyc}/${CDUMP}/${CASE}/INPUT/gfs_ctrl.nc" -target="${COM_ATMOS_INPUT}/gfs_ctrl.nc" -${NCP} "${source}" "${target}" -rc=$? -(( rc != 0 )) && error_message "${source}" "${target}" "${rc}" -err=$((err + rc)) -for ftype in gfs_data sfc_data; do - for tt in $(seq 1 6); do - source="${BASE_CPLIC}/${CPL_ATMIC}/${PDY}${cyc}/${CDUMP}/${CASE}/INPUT/${ftype}.tile${tt}.nc" - target="${COM_ATMOS_INPUT}/${ftype}.tile${tt}.nc" - ${NCP} "${source}" "${target}" - rc=$? - (( rc != 0 )) && error_message "${source}" "${target}" "${rc}" - err=$((err + rc)) - done -done - -# Stage ocean initial conditions to ROTDIR (warm start) -if [[ "${DO_OCN:-}" = "YES" ]]; then - YMD=${gPDY} HH=${gcyc} generate_com -r COM_OCEAN_RESTART - [[ ! -d "${COM_OCEAN_RESTART}" ]] && mkdir -p "${COM_OCEAN_RESTART}" - source="${BASE_CPLIC}/${CPL_OCNIC}/${PDY}${cyc}/ocn/${OCNRES}/MOM.res.nc" - target="${COM_OCEAN_RESTART}/${PDY}.${cyc}0000.MOM.res.nc" - ${NCP} "${source}" "${target}" +for MEMDIR in "${MEMDIR_ARRAY[@]}"; do + # Stage the FV3 initial conditions to ROTDIR (cold start) + YMD=${PDY} HH=${cyc} generate_com COM_ATMOS_INPUT + [[ ! -d "${COM_ATMOS_INPUT}" ]] && mkdir -p "${COM_ATMOS_INPUT}" + src="${BASE_CPLIC}/${CPL_ATMIC}/${PDY}${cyc}/${MEMDIR}/atmos/gfs_ctrl.nc" + tgt="${COM_ATMOS_INPUT}/gfs_ctrl.nc" + ${NCP} "${src}" "${tgt}" rc=$? - (( rc != 0 )) && error_message "${source}" "${target}" "${rc}" + ((rc != 0)) && error_message "${src}" "${tgt}" "${rc}" err=$((err + rc)) - case "${OCNRES}" in - "500" | "100") # Only 5 degree or 1 degree ocean does not have MOM.res_[1-4].nc files - ;; - "025") # Only 1/4 degree ocean has MOM.res_[1-4].nc files - for nn in $(seq 1 4); do - source="${BASE_CPLIC}/${CPL_OCNIC}/${PDY}${cyc}/ocn/${OCNRES}/MOM.res_${nn}.nc" - if [[ -f "${source}" ]]; then - target="${COM_OCEAN_RESTART}/${PDY}.${cyc}0000.MOM.res_${nn}.nc" - ${NCP} "${source}" "${target}" - rc=$? - (( rc != 0 )) && error_message "${source}" "${target}" "${rc}" - err=$((err + rc)) - fi - done - ;; - *) - echo "FATAL ERROR: Unsupported ocean resolution ${OCNRES}" - rc=1 + for ftype in gfs_data sfc_data; do + for ((tt = 1; tt <= 6; tt++)); do + src="${BASE_CPLIC}/${CPL_ATMIC}/${PDY}${cyc}/${MEMDIR}/atmos/${ftype}.tile${tt}.nc" + tgt="${COM_ATMOS_INPUT}/${ftype}.tile${tt}.nc" + ${NCP} "${src}" "${tgt}" + rc=$? + tgt="${COM_ATMOS_INPUT}/${ftype}.tile${tt}.nc" + ${NCP} "${src}" "${tgt}" + rc=$? + ((rc != 0)) && error_message "${src}" "${tgt}" "${rc}" err=$((err + rc)) - ;; - esac -fi - -# Stage ice initial conditions to ROTDIR (warm start) -if [[ "${DO_ICE:-}" = "YES" ]]; then - YMD=${gPDY} HH=${gcyc} generate_com -r COM_ICE_RESTART - [[ ! -d "${COM_ICE_RESTART}" ]] && mkdir -p "${COM_ICE_RESTART}" - ICERESdec=$(echo "${ICERES}" | awk '{printf "%0.2f", $1/100}') - source="${BASE_CPLIC}/${CPL_ICEIC}/${PDY}${cyc}/ice/${ICERES}/cice5_model_${ICERESdec}.res_${PDY}${cyc}.nc" - target="${COM_ICE_RESTART}/${PDY}.${cyc}0000.cice_model.res.nc" - ${NCP} "${source}" "${target}" - rc=$? - (( rc != 0 )) && error_message "${source}" "${target}" "${rc}" - err=$((err + rc)) -fi + done + done -# Stage the WW3 initial conditions to ROTDIR (warm start; TODO: these should be placed in $RUN.$gPDY/$gcyc) -if [[ "${DO_WAVE:-}" = "YES" ]]; then - YMD=${PDY} HH=${cyc} generate_com -r COM_WAVE_RESTART - [[ ! -d "${COM_WAVE_RESTART}" ]] && mkdir -p "${COM_WAVE_RESTART}" - for grdID in ${waveGRD}; do # TODO: check if this is a bash array; if so adjust - source="${BASE_CPLIC}/${CPL_WAVIC}/${PDY}${cyc}/wav/${grdID}/${PDY}.${cyc}0000.restart.${grdID}" - target="${COM_WAVE_RESTART}/${PDY}.${cyc}0000.restart.${grdID}" - ${NCP} "${source}" "${target}" + # Stage ocean initial conditions to ROTDIR (warm start) + if [[ "${DO_OCN:-}" = "YES" ]]; then + RUN=${rCDUMP} YMD=${gPDY} HH=${gcyc} generate_com COM_OCEAN_RESTART + [[ ! -d "${COM_OCEAN_RESTART}" ]] && mkdir -p "${COM_OCEAN_RESTART}" + src="${BASE_CPLIC}/${CPL_OCNIC}/${PDY}${cyc}/${MEMDIR}/ocean/${PDY}.${cyc}0000.MOM.res.nc" + tgt="${COM_OCEAN_RESTART}/${PDY}.${cyc}0000.MOM.res.nc" + ${NCP} "${src}" "${tgt}" rc=$? - (( rc != 0 )) && error_message "${source}" "${target}" "${rc}" + ((rc != 0)) && error_message "${src}" "${tgt}" "${rc}" err=$((err + rc)) - done -fi + fi + # Stage ice initial conditions to ROTDIR (warm start) + if [[ "${DO_ICE:-}" = "YES" ]]; then + RUN=${rCDUMP} YMD=${gPDY} HH=${gcyc} generate_com COM_ICE_RESTART + [[ ! -d "${COM_ICE_RESTART}" ]] && mkdir -p "${COM_ICE_RESTART}" + src="${BASE_CPLIC}/${CPL_ICEIC}/${PDY}${cyc}/${MEMDIR}/ice/${PDY}.${cyc}0000.cice_model.res.nc" + tgt="${COM_ICE_RESTART}/${PDY}.${cyc}0000.cice_model.res.nc" + ${NCP} "${src}" "${tgt}" + rc=$? + ((rc != 0)) && error_message "${src}" "${tgt}" "${rc}" + err=$((err + rc)) + fi + + # Stage the WW3 initial conditions to ROTDIR (warm start; TODO: these should be placed in $RUN.$gPDY/$gcyc) + if [[ "${DO_WAVE:-}" = "YES" ]]; then + YMD=${PDY} HH=${cyc} generate_com COM_WAVE_RESTART + [[ ! -d "${COM_WAVE_RESTART}" ]] && mkdir -p "${COM_WAVE_RESTART}" + for grdID in ${waveGRD}; do # TODO: check if this is a bash array; if so adjust + src="${BASE_CPLIC}/${CPL_WAVIC}/${PDY}${cyc}/${MEMDIR}/wave/${PDY}.${cyc}0000.restart.${grdID}" + tgt="${COM_WAVE_RESTART}/${PDY}.${cyc}0000.restart.${grdID}" + ${NCP} "${src}" "${tgt}" + rc=$? + ((rc != 0)) && error_message "${src}" "${tgt}" "${rc}" + err=$((err + rc)) + done + fi +done # for MEMDIR in "${MEMDIR_ARRAY[@]}"; do ############################################################### # Check for errors and exit if any of the above failed -if [[ "${err}" -ne 0 ]] ; then +if [[ "${err}" -ne 0 ]]; then echo "FATAL ERROR: Unable to copy ICs from ${BASE_CPLIC} to ${ROTDIR}; ABORT!" exit "${err}" fi diff --git a/ush/hpssarch_gen.sh b/ush/hpssarch_gen.sh index 09bce41a9e..9b0232cdbe 100755 --- a/ush/hpssarch_gen.sh +++ b/ush/hpssarch_gen.sh @@ -508,6 +508,8 @@ if [[ ${type} == "gdas" ]]; then touch gdasocean.txt rm -rf gdasocean_restart.txt touch gdasocean_restart.txt + rm -rf gdasocean_analysis.txt + touch gdasocean_analysis.txt head="gdas.t${cyc}z." @@ -522,6 +524,13 @@ if [[ ${type} == "gdas" ]]; then echo "${COM_MED_RESTART/${ROTDIR}\//}/*" } >> gdasocean_restart.txt + { + echo "${COM_OCEAN_ANALYSIS/${ROTDIR}\//}/${head}*" + echo "${COM_OCEAN_ANALYSIS/${ROTDIR}\//}/gdas.t??z.ocngrid.nc" + echo "${COM_OCEAN_ANALYSIS/${ROTDIR}\//}/diags" + echo "${COM_OCEAN_ANALYSIS/${ROTDIR}\//}/yaml" + } >> gdasocean_analysis.txt + fi if [[ ${DO_ICE} = "YES" ]]; then diff --git a/workflow/applications/gefs.py b/workflow/applications/gefs.py index a46451bd3e..8ac4cdc18e 100644 --- a/workflow/applications/gefs.py +++ b/workflow/applications/gefs.py @@ -14,7 +14,7 @@ def _get_app_configs(self): """ Returns the config_files that are involved in gefs """ - configs = ['fcst'] + configs = ['stage_ic', 'fcst'] if self.nens > 0: configs += ['efcs'] @@ -32,7 +32,7 @@ def _update_base(base_in): def get_task_names(self): - tasks = ['fcst'] + tasks = ['stage_ic', 'fcst'] if self.nens > 0: tasks += ['efcs'] diff --git a/workflow/hosts/hera.yaml b/workflow/hosts/hera.yaml index 61270b7b27..31911f2d21 100644 --- a/workflow/hosts/hera.yaml +++ b/workflow/hosts/hera.yaml @@ -1,6 +1,6 @@ BASE_GIT: '/scratch1/NCEPDEV/global/glopara/git' DMPDIR: '/scratch1/NCEPDEV/global/glopara/dump' -BASE_CPLIC: '/scratch1/NCEPDEV/climate/role.ufscpara/IC' +BASE_CPLIC: '/scratch1/NCEPDEV/global/glopara/data/ICSDIR/prototype_ICs' PACKAGEROOT: '/scratch1/NCEPDEV/global/glopara/nwpara' COMROOT: '/scratch1/NCEPDEV/global/glopara/com' COMINsyn: '${COMROOT}/gfs/prod/syndat' diff --git a/workflow/hosts/wcoss2.yaml b/workflow/hosts/wcoss2.yaml index 2a301064db..41e1044eff 100644 --- a/workflow/hosts/wcoss2.yaml +++ b/workflow/hosts/wcoss2.yaml @@ -1,6 +1,6 @@ BASE_GIT: '/lfs/h2/emc/global/save/emc.global/git' DMPDIR: '/lfs/h2/emc/dump/noscrub/dump' -BASE_CPLIC: '/lfs/h2/emc/couple/noscrub/Jiande.Wang/IC' +BASE_CPLIC: '/lfs/h2/emc/global/noscrub/emc.global/data/ICSDIR/prototype_ICs' PACKAGEROOT: '${PACKAGEROOT:-"/lfs/h1/ops/prod/packages"}' COMROOT: '${COMROOT:-"/lfs/h1/ops/prod/com"}' COMINsyn: '${COMROOT}/gfs/v16.3/syndat' diff --git a/workflow/rocoto/gefs_tasks.py b/workflow/rocoto/gefs_tasks.py index b0c56bdb66..c5dae3a13d 100644 --- a/workflow/rocoto/gefs_tasks.py +++ b/workflow/rocoto/gefs_tasks.py @@ -8,9 +8,64 @@ class GEFSTasks(Tasks): def __init__(self, app_config: AppConfig, cdump: str) -> None: super().__init__(app_config, cdump) + def stage_ic(self): + + cpl_ic = self._configs['stage_ic'] + + deps = [] + + # Atm ICs + if self.app_config.do_atm: + prefix = f"{cpl_ic['BASE_CPLIC']}/{cpl_ic['CPL_ATMIC']}/@Y@m@d@H/mem000/atmos" + for file in ['gfs_ctrl.nc'] + \ + [f'{datatype}_data.tile{tile}.nc' + for datatype in ['gfs', 'sfc'] + for tile in range(1, self.n_tiles + 1)]: + data = f"{prefix}/{file}" + dep_dict = {'type': 'data', 'data': data} + deps.append(rocoto.add_dependency(dep_dict)) + + # Ocean ICs + if self.app_config.do_ocean: + ocn_res = f"{self._base.get('OCNRES', '025'):03d}" + prefix = f"{cpl_ic['BASE_CPLIC']}/{cpl_ic['CPL_OCNIC']}/@Y@m@d@H/mem000/ocean" + data = f"{prefix}/@Y@m@d.@H0000.MOM.res.nc" + dep_dict = {'type': 'data', 'data': data} + deps.append(rocoto.add_dependency(dep_dict)) + if ocn_res in ['025']: + # 0.25 degree ocean model also has these additional restarts + for res in [f'res_{res_index}' for res_index in range(1, 4)]: + data = f"{prefix}/@Y@m@d.@H0000.MOM.{res}.nc" + dep_dict = {'type': 'data', 'data': data} + deps.append(rocoto.add_dependency(dep_dict)) + + # Ice ICs + if self.app_config.do_ice: + prefix = f"{cpl_ic['BASE_CPLIC']}/{cpl_ic['CPL_ICEIC']}/@Y@m@d@H/mem000/ice" + data = f"{prefix}/@Y@m@d.@H0000.cice_model.res.nc" + dep_dict = {'type': 'data', 'data': data} + deps.append(rocoto.add_dependency(dep_dict)) + + # Wave ICs + if self.app_config.do_wave: + prefix = f"{cpl_ic['BASE_CPLIC']}/{cpl_ic['CPL_WAVIC']}/@Y@m@d@H/mem000/wave" + for wave_grid in self._configs['waveinit']['waveGRD'].split(): + data = f"{prefix}/{wave_grid}/@Y@m@d.@H0000.restart.{wave_grid}" + dep_dict = {'type': 'data', 'data': data} + deps.append(rocoto.add_dependency(dep_dict)) + + dependencies = rocoto.create_dependency(dep_condition='and', dep=deps) + + resources = self.get_resource('stage_ic') + task = create_wf_task('stage_ic', resources, cdump=self.cdump, envar=self.envars, dependency=dependencies) + + return task + def fcst(self): # TODO: Add real dependencies dependencies = [] + dep_dict = {'type': 'task', 'name': f'{self.cdump}stage_ic'} + dependencies.append(rocoto.add_dependency(dep_dict)) resources = self.get_resource('fcst') task = create_wf_task('fcst', resources, cdump=self.cdump, envar=self.envars, dependency=dependencies) @@ -18,8 +73,9 @@ def fcst(self): return task def efcs(self): - # TODO: Add real dependencies dependencies = [] + dep_dict = {'type': 'task', 'name': f'{self.cdump}stage_ic'} + dependencies.append(rocoto.add_dependency(dep_dict)) efcsenvars = self.envars.copy() efcsenvars.append(rocoto.create_envar(name='ENSGRP', value='#grp#')) diff --git a/workflow/rocoto/gfs_tasks.py b/workflow/rocoto/gfs_tasks.py index 20a2bffe5d..99a24de908 100644 --- a/workflow/rocoto/gfs_tasks.py +++ b/workflow/rocoto/gfs_tasks.py @@ -23,13 +23,12 @@ def stage_ic(self): # Atm ICs if self.app_config.do_atm: - atm_res = self._base.get('CASE', 'C384') - prefix = f"{cpl_ic['BASE_CPLIC']}/{cpl_ic['CPL_ATMIC']}/@Y@m@d@H/{self.cdump}" + prefix = f"{cpl_ic['BASE_CPLIC']}/{cpl_ic['CPL_ATMIC']}/@Y@m@d@H/atmos" for file in ['gfs_ctrl.nc'] + \ [f'{datatype}_data.tile{tile}.nc' for datatype in ['gfs', 'sfc'] for tile in range(1, self.n_tiles + 1)]: - data = f"{prefix}/{atm_res}/INPUT/{file}" + data = f"{prefix}/{file}" dep_dict = {'type': 'data', 'data': data} deps.append(rocoto.add_dependency(dep_dict)) else: # data-atmosphere @@ -42,31 +41,29 @@ def stage_ic(self): # Ocean ICs if self.app_config.do_ocean: ocn_res = f"{self._base.get('OCNRES', '025'):03d}" - prefix = f"{cpl_ic['BASE_CPLIC']}/{cpl_ic['CPL_OCNIC']}/@Y@m@d@H/ocn" - data = f"{prefix}/{ocn_res}/MOM.res.nc" + prefix = f"{cpl_ic['BASE_CPLIC']}/{cpl_ic['CPL_OCNIC']}/@Y@m@d@H/ocean" + data = f"{prefix}/@Y@m@d.@H0000.MOM.res.nc" dep_dict = {'type': 'data', 'data': data} deps.append(rocoto.add_dependency(dep_dict)) if ocn_res in ['025']: # 0.25 degree ocean model also has these additional restarts for res in [f'res_{res_index}' for res_index in range(1, 4)]: - data = f"{prefix}/{ocn_res}/MOM.{res}.nc" + data = f"{prefix}/@Y@m@d.@H0000.MOM.{res}.nc" dep_dict = {'type': 'data', 'data': data} deps.append(rocoto.add_dependency(dep_dict)) # Ice ICs if self.app_config.do_ice: - ice_res = f"{self._base.get('ICERES', '025'):03d}" - ice_res_dec = f'{float(ice_res) / 100:.2f}' prefix = f"{cpl_ic['BASE_CPLIC']}/{cpl_ic['CPL_ICEIC']}/@Y@m@d@H/ice" - data = f"{prefix}/{ice_res}/cice5_model_{ice_res_dec}.res_@Y@m@d@H.nc" + data = f"{prefix}/@Y@m@d.@H0000.cice_model.res.nc" dep_dict = {'type': 'data', 'data': data} deps.append(rocoto.add_dependency(dep_dict)) # Wave ICs if self.app_config.do_wave: - prefix = f"{cpl_ic['BASE_CPLIC']}/{cpl_ic['CPL_WAVIC']}/@Y@m@d@H/wav" + prefix = f"{cpl_ic['BASE_CPLIC']}/{cpl_ic['CPL_WAVIC']}/@Y@m@d@H/wave" for wave_grid in self._configs['waveinit']['waveGRD'].split(): - data = f"{prefix}/{wave_grid}/@Y@m@d.@H0000.restart.{wave_grid}" + data = f"{prefix}/@Y@m@d.@H0000.restart.{wave_grid}" dep_dict = {'type': 'data', 'data': data} deps.append(rocoto.add_dependency(dep_dict)) @@ -366,7 +363,7 @@ def landanl(self): def ocnanalprep(self): - ocean_hist_path = self._template_to_rocoto_cycstring(self._base["COM_OCEAN_HISTORY_TMPL"]) + ocean_hist_path = self._template_to_rocoto_cycstring(self._base["COM_OCEAN_HISTORY_TMPL"], {'RUN': 'gdas'}) deps = [] data = f'{ocean_hist_path}/gdas.t@Hz.ocnf009.nc' diff --git a/workflow/setup_expt.py b/workflow/setup_expt.py index a9810ec3f2..a808cafd91 100755 --- a/workflow/setup_expt.py +++ b/workflow/setup_expt.py @@ -232,16 +232,7 @@ def fill_COMROT_forecasts(host, inputs): """ Implementation of 'fill_COMROT' for forecast-only mode """ - if inputs.system in ['gfs']: - print('forecast-only mode treats ICs differently and cannot be staged here') - elif inputs.system in ['gefs']: # Temporarily copy ICs from icsdir into COM for testing - print('temporary hack to stage gefs ICs for testing') - comrot = os.path.join(inputs.comrot, inputs.pslot) - idatestr = datetime_to_YMDH(inputs.idate) - current_cycle_dir = f"gefs.{idatestr[:8]}" - cmd = f"cp -as {inputs.icsdir}/{current_cycle_dir} {comrot}/{current_cycle_dir}" - os.system(cmd) - return + print('forecast-only mode treats ICs differently and cannot be staged here') def fill_EXPDIR(inputs):