Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[uwtools_integration] Integrate ics/lbcs #266

Open
wants to merge 44 commits into
base: uwtools_integration
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
6bdab4c
initial chgres_cube config
WeirAE Aug 21, 2024
46a3227
update coldstart.yaml
WeirAE Aug 21, 2024
1af2517
second pass on passing files
WeirAE Aug 27, 2024
b7884cc
progress continues adding functionality
WeirAE Sep 4, 2024
b188301
update secondary YAML logic
WeirAE Sep 5, 2024
4753089
first version edits complete
WeirAE Sep 17, 2024
93ac362
config_defaults.yaml formatting fixes
WeirAE Sep 18, 2024
e437b3d
yaml fixes to complete build
WeirAE Sep 18, 2024
bee31be
try some changes in chgres_cube.py
WeirAE Sep 18, 2024
e661d1c
add changes from PR 264
WeirAE Sep 19, 2024
7360ec1
Merge branch 'uwtools_integration' into integrate_ics_lbcs
WeirAE Sep 19, 2024
ed58157
revert unintended changes
WeirAE Sep 19, 2024
8dde45f
also revert utils.py
WeirAE Sep 19, 2024
9f16342
Revert remaining formatting
WeirAE Sep 19, 2024
d6c3786
fix local issues
WeirAE Sep 19, 2024
4eff96a
fix YAML formatting
WeirAE Sep 19, 2024
3b65a6c
Fix remaining YAML syntax issues
WeirAE Sep 19, 2024
7116141
Undo prior incorrect sync and refix YAML
WeirAE Sep 19, 2024
c310cb8
local YAML and path fixes
WeirAE Sep 20, 2024
9a0ab65
progress resolving dereferencing
WeirAE Sep 20, 2024
226d335
fixes for loop logic
WeirAE Sep 25, 2024
8a3ed18
fixes for lbcs
WeirAE Oct 7, 2024
8b7dd87
fix external model yaml issues
WeirAE Oct 7, 2024
2f709e3
Merge remote-tracking branch 'refs/remotes/origin/integrate_ics_lbcs'…
WeirAE Oct 8, 2024
b83c5af
move tracers to external_model_defaults
WeirAE Oct 10, 2024
d9701bf
significant logic changes
WeirAE Oct 15, 2024
fc59204
Fix file copy logic
WeirAE Oct 16, 2024
12fb677
fix output directories
WeirAE Oct 18, 2024
f485be8
All fundamental tests pass
WeirAE Oct 24, 2024
fccb757
fix extra files 1
WeirAE Oct 24, 2024
7bc7732
First attempt to fix erroneous changes
WeirAE Oct 24, 2024
80bca46
remove spurious uwtools directory
WeirAE Oct 24, 2024
4300a3e
Fix missing newline
WeirAE Oct 24, 2024
91e15dd
update cleaner
WeirAE Oct 24, 2024
7d81efb
Merge remote-tracking branch 'refs/remotes/origin/integrate_ics_lbcs'…
WeirAE Oct 24, 2024
25fd2b4
Apply suggestions from code review
WeirAE Oct 25, 2024
1460cff
Merge remote-tracking branch 'gsl/uwtools_integration' into integrate…
WeirAE Oct 29, 2024
0e2f6e0
add back several changes lost in conflict resolutions
WeirAE Oct 29, 2024
093fbf0
additional residual formatting fixes
WeirAE Oct 30, 2024
affa5d4
fixes for running
WeirAE Oct 30, 2024
d74b410
Additional fixes
WeirAE Oct 30, 2024
86db971
move file handling to external_model_defaults.yaml
WeirAE Oct 30, 2024
d9488d9
clean dereferencing, fix file errors
WeirAE Oct 31, 2024
fb398c0
found missing file path
WeirAE Oct 31, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions parm/wflow/coldstart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,16 @@ metatask_run_ensemble:
mem: '{% if global.DO_ENSEMBLE %}{%- for m in range(1, global.NUM_ENS_MEMBERS+1) -%}{{ "%03d "%m }}{%- endfor -%} {% else %}{{ "000"|string }}{% endif %}'
task_make_ics_mem#mem#:
<<: *default_task
command: '&LOAD_MODULES_RUN_TASK; "make_ics" "&JOBSdir;/JREGIONAL_MAKE_ICS"'
command:
cyclestr:
value: 'source &USHdir;/load_modules_wflow.sh {{ user.MACHINE }} ; &SCRIPTSdir;/chgres_cube.py
-c &GLOBAL_VAR_DEFNS_FP;
--cycle @Y-@m-@dT@H:@M:@S
--key-path task_make_ics
--mem #mem#'
join:
cyclestr:
value: '&LOGDIR;/{{ jobname }}_@Y@m@d@H&LOGEXT;'
envars:
<<: *default_vars
SLASH_ENSMEM_SUBDIR: '&SLASH_ENSMEM_SUBDIR;'
Expand All @@ -111,7 +120,7 @@ metatask_run_ensemble:
cyclestr:
value: '&LOGDIR;/{{ jobname }}_@Y@m@d@H&LOGEXT;'
nodes: '{{ task_make_ics.chgres_cube.execution.batchargs.nodes }}:ppn={{ task_make_ics.chgres_cube.execution.batchargs.tasks_per_node }}'
walltime: '{{ task_make_ics.chgres_cube.execution.batchargs.walltime }}'
walltime: '{{ task_make_ics.chgres_cube.execution.batchargs.walltime }}'
dependency:
and: &make_ics_deps
taskdep_get_extrn:
Expand Down Expand Up @@ -144,7 +153,16 @@ metatask_run_ensemble:

task_make_lbcs_mem#mem#:
<<: *default_task
command: '&LOAD_MODULES_RUN_TASK; "make_lbcs" "&JOBSdir;/JREGIONAL_MAKE_LBCS"'
command:
cyclestr:
value: 'source &USHdir;/load_modules_wflow.sh {{ user.MACHINE }} ; &SCRIPTSdir;/chgres_cube.py
-c &GLOBAL_VAR_DEFNS_FP;
--cycle @Y-@m-@dT@H:@M:@S
--key-path task_make_lbcs
--mem #mem#'
join:
cyclestr:
value: '&LOGDIR;/{{ jobname }}_@Y@m@d@H&LOGEXT;'
envars:
<<: *default_vars
SLASH_ENSMEM_SUBDIR: '&SLASH_ENSMEM_SUBDIR;'
Expand All @@ -155,7 +173,7 @@ metatask_run_ensemble:
cyclestr:
value: '&LOGDIR;/{{ jobname }}_@Y@m@d@H&LOGEXT;'
nodes: '{{ task_make_lbcs.chgres_cube.execution.batchargs.nodes }}:ppn={{ task_make_lbcs.chgres_cube.execution.batchargs.tasks_per_node }}'
walltime: '{{ task_make_lbcs.chgres_cube.execution.batchargs.walltime }}'
walltime: '{{ task_make_lbcs.chgres_cube.execution.batchargs.walltime }}'
dependency:
and:
<<: *make_ics_deps
Expand Down
2 changes: 1 addition & 1 deletion parm/wflow/post.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ metatask_run_ens_post:
maxtries: '2'
command:
cyclestr:
value: 'source &USHdir;/load_modules_wflow.sh hera ; &SCRIPTSdir;/upp.py
value: 'source &USHdir;/load_modules_wflow.sh {{ user.MACHINE }} ; &SCRIPTSdir;/upp.py
-c &GLOBAL_VAR_DEFNS_FP;
--cycle @Y-@m-@dT@H:@M:@S
--leadtime #fhr#:00:00
Expand Down
218 changes: 218 additions & 0 deletions scripts/chgres_cube.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
#!/usr/bin/env python
WeirAE marked this conversation as resolved.
Show resolved Hide resolved
"""
The run script for chgres_cube
"""

import datetime as dt
import logging
import os
import sys
from argparse import ArgumentParser
from copy import deepcopy
from pathlib import Path

from uwtools.api.chgres_cube import ChgresCube
from uwtools.api.config import get_yaml_config
from uwtools.api.fs import link as uwlink
from uwtools.api.logging import use_uwtools_logger


def _walk_key_path(config, key_path):
"""
Navigate to the sub-config at the end of the path of given keys.
"""
keys = []
pathstr = "<unknown>"
for key in key_path:
keys.append(key)
pathstr = " -> ".join(keys)
try:
subconfig = config[key]
except KeyError:
logging.error(f"Bad config path: {pathstr}")
raise
if not isinstance(subconfig, dict):
logging.error(f"Value at {pathstr} must be a dictionary")
sys.exit(1)
config = subconfig
return config


def parse_args(argv):
"""
Parse arguments for the script.
"""
parser = ArgumentParser(
description="Script that runs chgres_cube via uwtools API",
)
parser.add_argument(
"-c",
"--config-file",
metavar="PATH",
required=True,
help="Path to experiment config file.",
type=Path,
)
parser.add_argument(
"--cycle",
help="The cycle in ISO8601 format (e.g. 2024-07-15T18)",
required=True,
type=dt.datetime.fromisoformat,
)
parser.add_argument(
"--key-path",
help="Dot-separated path of keys leading through the config to the driver's YAML block",
metavar="KEY[.KEY...]",
required=True,
type=lambda s: s.split("."),
)
parser.add_argument(
"--member",
default="000",
help="The 3-digit ensemble member number.",
)
return parser.parse_args(argv)


# pylint: disable-next=too-many-locals, too-many-statements
def run_chgres_cube(config_file, cycle, key_path, member):
"""
Setup and run the chgres_cube Driver.
"""
expt_config = get_yaml_config(config_file)

# The experiment config will have {{ CRES | env }} expressions in it that need to be
# dereferenced during driver initialization
cres = expt_config["workflow"]["CRES"]
os.environ["CRES"] = cres
os.environ["MEMBER"] = member
expt_config.dereference(
context={
"cycle": cycle,
**os.environ,
**expt_config,
}
)
WeirAE marked this conversation as resolved.
Show resolved Hide resolved
chgres_cube_driver = ChgresCube(
config=config_file,
cycle=cycle,
key_path=key_path,
)
rundir = Path(chgres_cube_driver.config["rundir"])
logging.info(f"Will run in {rundir}")

chgres_cube_config = _walk_key_path(expt_config, key_path)
input_type = chgres_cube_config["chgres_cube"]["namelist"]["update_values"][
"config"
].get("input_type")

varsfilepath = chgres_cube_config["input_files_metadata_path"]
external_config = get_yaml_config(varsfilepath)
external_config_fns = external_config["external_model_fns"]
external_config_fhrs = external_config["external_model_fhrs"]

# update config for ics task, run and stage data
if "task_make_ics" in key_path:
if input_type == "grib2":
WeirAE marked this conversation as resolved.
Show resolved Hide resolved
os.environ["fn_grib2"] = external_config_fns[0]
else:
os.environ["fn_atm"] = external_config_fns[0]
os.environ["fn_sfc"] = external_config_fns[1]
# reinstantiate driver
expt_config_cp = get_yaml_config(deepcopy(expt_config.data))
expt_config_cp.dereference(
context={
"cycle": cycle,
**os.environ,
**expt_config_cp,
}
)
chgres_cube_driver = ChgresCube(
config=expt_config_cp,
cycle=cycle,
key_path=key_path,
)
chgres_cube_driver.run()

# Deliver output data to a common location above the rundir.
links = {}

output_dir = os.path.join(rundir.parent, "INPUT")
os.makedirs(output_dir, exist_ok=True)
task_get_block = _walk_key_path(expt_config_cp, {"task_get_extrn_ics"})
task_make_block = _walk_key_path(expt_config_cp, key_path)
for i, output_fn in enumerate(task_make_block["output_file_labels"]):
input_fn = task_get_block["output_file_labels"][i]
links[output_fn] = str(rundir / input_fn)

uwlink(target_dir=output_dir, config=links)

# update config for lbcs task, loop run and stage data
else:
num_fhrs = len(external_config_fhrs)

bcgrp10 = 0
bcgrpnum10 = 1
for ii in range(bcgrp10, num_fhrs, bcgrpnum10):
i = ii + bcgrp10
if i < num_fhrs:
print(f"group {bcgrp10} processes member {i}")
if input_type == "grib2":
os.environ["fn_grib2"] = external_config_fns[i]
else:
os.environ["fn_atm"] = external_config_fns[i]

lbc_spec_fhrs = external_config_fhrs[i]
lbc_offset_fhrs = expt_config["task_get_extrn_lbcs"]["envvars"][
"EXTRN_MDL_LBCS_OFFSET_HRS"
]
fcst_hhh = int(lbc_spec_fhrs) - int(lbc_offset_fhrs)
os.environ["fcst_hhh_FV3LAM"] = f"{fcst_hhh:03d}"

# reinstantiate driver
expt_config_cp = get_yaml_config(deepcopy(expt_config.data))
expt_config_cp.dereference(
context={
"cycle": cycle,
**os.environ,
**expt_config_cp,
}
)
chgres_cube_driver = ChgresCube(
config=expt_config_cp,
cycle=cycle,
key_path=key_path,
)
chgres_cube_driver.run()

# Deliver output data to a common location above the rundir.
links = {}

task_get_block = _walk_key_path(expt_config_cp, {"task_get_extrn_lbcs"})
task_make_block = _walk_key_path(expt_config_cp, key_path)

output_dir = os.path.join(rundir.parent, "INPUT")
os.makedirs(output_dir, exist_ok=True)

lbc_input_fn = task_get_block["output_file_labels"][0]
lbc_output_fn = task_make_block["output_file_labels"][0]
links[lbc_output_fn] = str(rundir / lbc_input_fn)
uwlink(target_dir=output_dir, config=links)

# error message
if not (rundir / "runscript.chgres_cube.done").is_file():
print("Error occurred running chgres_cube. Please see component error logs.")
sys.exit(1)


if __name__ == "__main__":

use_uwtools_logger()

args = parse_args(sys.argv[1:])
run_chgres_cube(
config_file=args.config_file,
cycle=args.cycle,
key_path=args.key_path,
member=args.member,
)
4 changes: 2 additions & 2 deletions scripts/exregional_get_extrn_mdl_files.sh
Original file line number Diff line number Diff line change
Expand Up @@ -240,9 +240,9 @@ fi
mkdir -p ${EXTRN_MDL_STAGING_DIR}

if [ $RUN_ENVIR = "nco" ]; then
EXTRN_DEFNS="${NET}.${cycle}.${EXTRN_MDL_NAME}.${ICS_OR_LBCS}.${EXTRN_MDL_VAR_DEFNS_FN}.sh"
EXTRN_DEFNS="${NET}.${cycle}.${EXTRN_MDL_NAME}.${ICS_OR_LBCS}.${EXTRN_MDL_VAR_DEFNS_FN}.yaml"
else
EXTRN_DEFNS="${EXTRN_MDL_VAR_DEFNS_FN}.sh"
EXTRN_DEFNS="${EXTRN_MDL_VAR_DEFNS_FN}.yaml"
fi
cmd="
python3 -u ${USHdir}/retrieve_data.py \
Expand Down
43 changes: 43 additions & 0 deletions ush/ccpp_suites_defaults.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
chgres_cube_gsd_defaults: &chgres_cube_gsd_defaults
namelist:
update_values:
config:
varmap_file: "{{ user.PARMdir }}/ufs_utils/varmap_tables/GSDphys_var_map.txt"

orog_gsl_defaults: &orog_gsl_defaults
config:
Expand All @@ -19,18 +24,56 @@ orog_gsl_defaults: &orog_gsl_defaults
rundir: "{{ task_make_orog.rundir }}/orog_gsl"

FV3_RAP:
task_make_ics:
chgres_cube:
<<: *chgres_cube_gsd_defaults
task_make_lbcs:
chgres_cube:
<<: *chgres_cube_gsd_defaults
task_make_orog:
orog_gsl:
<<: *orog_gsl_defaults
FV3_HRRR:
task_make_ics:
chgres_cube:
<<: *chgres_cube_gsd_defaults
task_make_lbcs:
chgres_cube:
<<: *chgres_cube_gsd_defaults
task_make_orog:
orog_gsl:
<<: *orog_gsl_defaults
FV3_WoFS_v0:
task_make_ics:
chgres_cube:
<<: *chgres_cube_gsd_defaults
task_make_lbcs:
chgres_cube:
<<: *chgres_cube_gsd_defaults
FV3_RRFS_v1beta:
task_make_ics:
chgres_cube:
<<: *chgres_cube_gsd_defaults
task_make_lbcs:
chgres_cube:
<<: *chgres_cube_gsd_defaults
FV3_GFS_v15_thompson_mynn_lam3km:
task_make_ics:
chgres_cube:
<<: *chgres_cube_gsd_defaults
task_make_lbcs:
chgres_cube:
<<: *chgres_cube_gsd_defaults
task_make_orog:
orog_gsl:
<<: *orog_gsl_defaults
FV3_GFS_v17_p8:
task_make_ics:
chgres_cube:
<<: *chgres_cube_gsd_defaults
task_make_lbcs:
chgres_cube:
<<: *chgres_cube_gsd_defaults
task_make_orog:
orog_gsl:
<<: *orog_gsl_defaults
Loading