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

Use JCB for assembling JEDI YAML files for atmospheric GDAS #2477

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
32bd4ff
add some jcb things
danholdaway Apr 3, 2024
1edba10
do not recurse inside jcb to avoid config files in sorc
danholdaway Apr 3, 2024
f8c4dea
Use of JCB for gdas 3dvar
danholdaway Apr 8, 2024
c3d43b9
Merge remote-tracking branch 'upstream/develop' into feature/use_jcb_atm
danholdaway Apr 8, 2024
aef1289
remove left over prints
danholdaway Apr 8, 2024
8cc1422
unused import
danholdaway Apr 8, 2024
fccce33
refactor the way obs are decided
danholdaway Apr 9, 2024
8e49292
remove rogue atm file
danholdaway Apr 9, 2024
08d51f3
remove unused import
danholdaway Apr 9, 2024
a7d7b5d
letkf to jcb
danholdaway Apr 9, 2024
9945964
towards letkf gdas tests working
danholdaway Apr 9, 2024
70b0944
pynorm
danholdaway Apr 9, 2024
1d50b11
update to jcb that has external algo YAMLs
danholdaway Apr 15, 2024
5bd9b8d
keeping up with GDAS develop
danholdaway Apr 15, 2024
c8dcffb
clone jcb algo repo
danholdaway Apr 15, 2024
c784cc8
Merge remote-tracking branch 'upstream/develop' into feature/use_jcb_atm
danholdaway Apr 15, 2024
4c48dfb
more updates for jcb algos
danholdaway Apr 15, 2024
2681b64
gdas upgrade
danholdaway Apr 15, 2024
de6b1a2
Merge remote-tracking branch 'upstream/develop' into feature/use_jcb_atm
danholdaway Apr 17, 2024
324d8a7
reset gdas hash
danholdaway Apr 17, 2024
0d89f2f
update gdas hash
danholdaway Apr 23, 2024
0a920cd
Merge remote-tracking branch 'upstream/develop' into feature/use_jcb_atm
danholdaway Apr 23, 2024
70a4a33
fixes for increment step
danholdaway Apr 24, 2024
647282e
Merge remote-tracking branch 'upstream/develop' into feature/use_jcb_atm
danholdaway May 2, 2024
f0df9ba
update gdash hash
danholdaway May 6, 2024
62d72dd
Update GDASapp hash
danholdaway May 6, 2024
6d0b8b6
Move GDASapp to develop
danholdaway May 7, 2024
b743ea0
Merge remote-tracking branch 'upstream/develop' into feature/use_jcb_atm
danholdaway May 7, 2024
a04f2ca
Merge branch 'develop' into feature/use_jcb_atm
WalterKolczynski-NOAA May 8, 2024
14e2fad
Add back accidental removal of old way of building YAML
danholdaway May 8, 2024
7337d14
fix indent norm
danholdaway May 8, 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
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ parm/gdas/io
parm/gdas/ioda
parm/gdas/snow
parm/gdas/soca
parm/gdas/jcb-gdas
parm/gdas/jcb-algorithms
parm/monitor
parm/post/AEROSOL_LUTS.dat
parm/post/nam_micro_lookup.dat
Expand Down Expand Up @@ -195,3 +197,8 @@ versions/run.ver
ush/python/wxflow
workflow/wxflow
ci/scripts/wxflow

# jcb checkout and symlinks
ush/python/jcb
workflow/jcb
ci/scripts/jcb
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,7 @@
path = sorc/upp.fd
url = https://github.com/NOAA-EMC/UPP.git
ignore = dirty
[submodule "sorc/jcb"]
path = sorc/jcb
url = https://github.com/noaa-emc/jcb
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the yaml's in the jcb repo under configuration/ used?
If so, we will need to think about how to move them to parm/ for operational acceptance.
Ideally, we would install jcb as a python package, and the yamls would be part of global-workflow/gdasapp.

Copy link
Contributor Author

@danholdaway danholdaway Apr 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was tying to play around with submodules to see if jcb could not clone its submodules since in the context of global-workflow they are indeed not needed. But I was not successful. The submodule of jcb (jcb-gdas) is also a submodule of GDASapp and that would be where the configuration files that global-workflow uses actually comes in and gets linked to parm/. Perhaps we can brainstorm a better way of doing this so that jcb-gdas is not a submodule of jcb. It's like that primarily to facilitate easy testing of jcb in a standalone context but perhaps it could be done with pip dependency or some other way that I'm not thinking about.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jcb-algorithms repo has been established, moving the generic JEDI-algortithm YAMLs to the gdas parm. Now there should be no YAML files in non-parm directories that are used anywhere.

fetchRecurseSubmodules = false
10 changes: 6 additions & 4 deletions parm/config/gfs/config.atmanl
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@

echo "BEGIN: config.atmanl"

export OBS_LIST="${PARMgfs}/gdas/atm/obs/lists/gdas_prototype_3d.yaml.j2"
export JEDIYAML="${PARMgfs}/gdas/atm/variational/3dvar_drpcg.yaml.j2"
export JCB_BASE_YAML="${PARMgfs}/gdas/atm/jcb-base.yaml.j2"
export JCB_ALGO_YAML="${PARMgfs}/gdas/atm/jcb-prototype_3dvar.yaml.j2"

export STATICB_TYPE="gsibec"
export LOCALIZATION_TYPE="bump"
export INTERP_METHOD='barycentric'

if [[ ${DOHYBVAR} = "YES" ]]; then
# shellcheck disable=SC2153
export CASE_ANL=${CASE_ENS}
export BERROR_YAML="${PARMgfs}/gdas/atm/berror/hybvar_${STATICB_TYPE}.yaml.j2"
export BERROR_YAML="background_error_hybrid_${STATICB_TYPE}_${LOCALIZATION_TYPE}"
else
export CASE_ANL=${CASE}
export BERROR_YAML="${PARMgfs}/gdas/atm/berror/staticb_${STATICB_TYPE}.yaml.j2"
export BERROR_YAML="background_error_static_${STATICB_TYPE}"
fi

export CRTM_FIX_YAML="${PARMgfs}/gdas/atm_crtm_coeff.yaml.j2"
Expand Down
2 changes: 1 addition & 1 deletion parm/config/gfs/config.atmanlfv3inc
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ echo "BEGIN: config.atmanlfv3inc"
# Get task specific resources
. "${EXPDIR}/config.resources" atmanlfv3inc

export JEDIYAML=${PARMgfs}/gdas/atm/utils/fv3jedi_fv3inc_variational.yaml.j2
export JCB_ALGO=fv3jedi_fv3inc_variational
export JEDIEXE=${EXECgfs}/fv3jedi_fv3inc.x

echo "END: config.atmanlfv3inc"
5 changes: 3 additions & 2 deletions parm/config/gfs/config.atmensanl
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@

echo "BEGIN: config.atmensanl"

export OBS_LIST="${PARMgfs}/gdas/atm/obs/lists/lgetkf_prototype.yaml.j2"
export JEDIYAML="${PARMgfs}/gdas/atm/lgetkf/lgetkf.yaml.j2"
export JCB_BASE_YAML="${PARMgfs}/gdas/atm/jcb-base.yaml.j2"
export JCB_ALGO_YAML="${PARMgfs}/gdas/atm/jcb-prototype_lgetkf.yaml.j2"

export INTERP_METHOD='barycentric'

export CRTM_FIX_YAML="${PARMgfs}/gdas/atm_crtm_coeff.yaml.j2"
Expand Down
2 changes: 1 addition & 1 deletion sorc/gdas.cd
Submodule gdas.cd updated 114 files
1 change: 1 addition & 0 deletions sorc/jcb
Submodule jcb added at de7565
17 changes: 11 additions & 6 deletions sorc/link_workflow.sh
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,24 @@ if [[ "${LINK_NEST:-OFF}" == "ON" ]] ; then
source "${HOMEgfs}/versions/fix.nest.ver"
fi

# Link wxflow in ush/python, workflow and ci/scripts
# Link python pacakges in ush/python
# TODO: This will be unnecessary when these are part of the virtualenv
packages=("wxflow" "jcb")
for package in "${packages[@]}"; do
cd "${HOMEgfs}/ush/python" || exit 1
[[ -s "${package}" ]] && rm -f "${package}"
${LINK} "${HOMEgfs}/sorc/${package}/src/${package}" .
done

# Link wxflow in workflow and ci/scripts
# TODO: This will be unnecessary when wxflow is part of the virtualenv
cd "${HOMEgfs}/ush/python" || exit 1
[[ -s "wxflow" ]] && rm -f wxflow
${LINK} "${HOMEgfs}/sorc/wxflow/src/wxflow" .
cd "${HOMEgfs}/workflow" || exit 1
[[ -s "wxflow" ]] && rm -f wxflow
${LINK} "${HOMEgfs}/sorc/wxflow/src/wxflow" .
cd "${HOMEgfs}/ci/scripts" || exit 1
[[ -s "wxflow" ]] && rm -f wxflow
${LINK} "${HOMEgfs}/sorc/wxflow/src/wxflow" .


# Link fix directories
if [[ -n "${FIX_DIR}" ]]; then
if [[ ! -d "${HOMEgfs}/fix" ]]; then mkdir "${HOMEgfs}/fix" || exit 1; fi
Expand Down Expand Up @@ -228,7 +233,7 @@ fi
#------------------------------
if [[ -d "${HOMEgfs}/sorc/gdas.cd" ]]; then
cd "${HOMEgfs}/parm/gdas" || exit 1
declare -a gdasapp_comps=("aero" "atm" "io" "ioda" "snow" "soca")
declare -a gdasapp_comps=("aero" "atm" "io" "ioda" "snow" "soca" "jcb-gdas" "jcb-algorithms")
for comp in "${gdasapp_comps[@]}"; do
[[ -d "${comp}" ]] && rm -rf "${comp}"
${LINK_OR_COPY} "${HOMEgfs}/sorc/gdas.cd/parm/${comp}" .
Expand Down
38 changes: 33 additions & 5 deletions ush/python/pygfs/task/analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
from logging import getLogger
from pprint import pformat
from netCDF4 import Dataset
from typing import List, Dict, Any, Union
from typing import List, Dict, Any, Union, Optional

from jcb import render
from wxflow import (parse_j2yaml, FileHandler, rm_p, logit,
Task, Executable, WorkflowException, to_fv3time, to_YMD,
Template, TemplateConstants)
Expand Down Expand Up @@ -46,11 +47,14 @@ def initialize(self) -> None:
self.link_jediexe()

@logit(logger)
def get_jedi_config(self) -> Dict[str, Any]:
def get_jedi_config(self, algorithm: Optional[str] = None) -> Dict[str, Any]:
"""Compile a dictionary of JEDI configuration from JEDIYAML template file

Parameters
----------
algorithm (optional) : str
Name of the algorithm to use in the JEDI configuration. Will override the algorithm
set in the self.config.JCB_<>_YAML file

Returns
----------
Expand All @@ -60,7 +64,31 @@ def get_jedi_config(self) -> Dict[str, Any]:

# generate JEDI YAML file
logger.info(f"Generate JEDI YAML config: {self.task_config.jedi_yaml}")
jedi_config = parse_j2yaml(self.task_config.JEDIYAML, self.task_config, searchpath=self.gdasapp_j2tmpl_dir)

if 'JCB_BASE_YAML' in self.task_config.keys():
# Step 1: fill templates of the jcb base YAML file
jcb_config = parse_j2yaml(self.task_config.JCB_BASE_YAML, self.task_config)

# Step 2: (optional) fill templates of algorithm override YAML and merge
if 'JCB_ALGO_YAML' in self.task_config.keys():
jcb_algo_config = parse_j2yaml(self.task_config.JCB_ALGO_YAML, self.task_config)
jcb_config = {**jcb_config, **jcb_algo_config}

# If algorithm is present override the algorithm in the JEDI config
if algorithm:
jcb_config['algorithm'] = algorithm

# Step 3: generate the JEDI Yaml using JCB driving YAML
jedi_config = render(jcb_config)
elif 'JEDIYAML' in self.task_config.keys():
# Generate JEDI YAML file (without using JCB)
logger.info(f"Generate JEDI YAML config: {self.task_config.jedi_yaml}")
jedi_config = parse_j2yaml(self.task_config.JEDIYAML, self.task_config,
searchpath=self.gdasapp_j2tmpl_dir)
logger.debug(f"JEDI config:\n{pformat(jedi_config)}")
else:
raise KeyError(f"Task config must contain JCB_BASE_YAML or JEDIYAML")

logger.debug(f"JEDI config:\n{pformat(jedi_config)}")

return jedi_config
Expand All @@ -82,7 +110,7 @@ def get_obs_dict(self) -> Dict[str, Any]:
a dictionary containing the list of observation files to copy for FileHandler
"""

logger.info(f"Extracting a list of observation files from {self.task_config.JEDIYAML}")
logger.info(f"Extracting a list of observation files from Jedi config file")
observations = find_value_in_nested_dict(self.task_config.jedi_config, 'observations')
logger.debug(f"observations:\n{pformat(observations)}")

Expand Down Expand Up @@ -116,7 +144,7 @@ def get_bias_dict(self) -> Dict[str, Any]:
a dictionary containing the list of observation bias files to copy for FileHandler
"""

logger.info(f"Extracting a list of bias correction files from {self.task_config.JEDIYAML}")
logger.info(f"Extracting a list of bias correction files from Jedi config file")
observations = find_value_in_nested_dict(self.task_config.jedi_config, 'observations')
logger.debug(f"observations:\n{pformat(observations)}")

Expand Down
8 changes: 6 additions & 2 deletions ush/python/pygfs/task/atm_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ def __init__(self, config):
'APREFIX': f"{self.runtime_config.CDUMP}.t{self.runtime_config.cyc:02d}z.", # TODO: CDUMP is being replaced by RUN
'GPREFIX': f"gdas.t{self.runtime_config.previous_cycle.hour:02d}z.",
'jedi_yaml': _jedi_yaml,
'atm_obsdatain_path': f"{self.runtime_config.DATA}/obs/",
'atm_obsdataout_path': f"{self.runtime_config.DATA}/diags/",
'BKG_TSTEP': "PT1H" # Placeholder for 4D applications
}
)

Expand Down Expand Up @@ -137,8 +140,9 @@ def variational(self: Analysis) -> None:
@logit(logger)
def init_fv3_increment(self: Analysis) -> None:
# Setup JEDI YAML file
self.task_config.jedi_yaml = os.path.join(self.runtime_config.DATA, os.path.basename(self.task_config.JEDIYAML))
save_as_yaml(self.get_jedi_config(), self.task_config.jedi_yaml)
self.task_config.jedi_yaml = os.path.join(self.runtime_config.DATA,
f"{self.task_config.JCB_ALGO}.yaml")
save_as_yaml(self.get_jedi_config(self.task_config.JCB_ALGO), self.task_config.jedi_yaml)

# Link JEDI executable to run directory
self.task_config.jedi_exe = self.link_jediexe()
Expand Down
3 changes: 3 additions & 0 deletions ush/python/pygfs/task/atmens_analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ def __init__(self, config):
'APREFIX': f"{self.runtime_config.CDUMP}.t{self.runtime_config.cyc:02d}z.", # TODO: CDUMP is being replaced by RUN
'GPREFIX': f"gdas.t{self.runtime_config.previous_cycle.hour:02d}z.",
'jedi_yaml': _jedi_yaml,
'atm_obsdatain_path': f"./obs/",
'atm_obsdataout_path': f"./diags/",
'BKG_TSTEP': "PT1H" # Placeholder for 4D applications
}
)

Expand Down
Loading