Enable EAMxx CMORization, E3SM Diags and add ts-level vertical regrid#827
Conversation
Closes #820: replace fragile input_files.split(".") gate in e3sm_to_cmip.bash with a prc_typ-based check that honors input_component override (e.g. EAMxx runs with input_files="AVERAGE.nmonths_x1"). Addresses #817: add EAMxx-specific ncremap flags (--ps_nm=${file}/ps, --vrt_in=vert_L128.nc) when prc_typ == 'eamxx', auto-defaulted from diagnostics_base_path. New additive [ts] vert_remap_vars path produces a sibling ts_vert_remap/ directory alongside ts/, so users can use native-level and pressure-level data simultaneously. e3sm_to_cmip.bash auto-detects ts_vert_remap/ files (via readlink) and skips redundant inline regrid. Files changed: - zppy/defaults/default.ini: new [ts] vert_remap_vars, vrt_remap_file, vrt_in_file; new [e3sm_to_cmip] vrt_in_file - zppy/templates/ts.bash: post-ncclimo vert remap block - zppy/ts.py: path defaults for vrt_remap_file / vrt_in_file - zppy/templates/e3sm_to_cmip.bash: prc_typ gate, EAMxx flags, ts_vert_remap consumption - zppy/e3sm_to_cmip.py: EAMxx vrt_in_file default - examples/post.v3.eamxx.e3sm_to_cmip.cfg: example based on issue #820 Legacy [e3sm_to_cmip] interp_vars path is preserved unchanged for backward compatibility. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Renames examples/post.v3.eamxx.e3sm_to_cmip.cfg to post.v3.eamxx.cfg and merges in climo, additional ts subsections, e3sm_to_cmip land_monthly, and e3sm_diags tasks. Contributed by Shixuan Zhang. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
A prior run replaces the symlink in place via mv ${file}.plev ${file},
so on re-run the file is a real plev file with no lev/ilev dim and
ncremap fails. Bail out early when the file is no longer a symlink.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The web publish path used the subsection-resolved ${case}, which for
EAMxx cfgs that override case in [climo]/[[atm_monthly_180x360_aave]]
(to match the ncclimo input filename prefix, e.g. "1ma_ne30pg2") would
land under that short prefix instead of the canonical [default] case
name. Snapshot config["default"]["case"] into c["default_case"] and use
it for web_dir so file-prefix overrides no longer reroute publishing.
Climo file-prefix lookups and param.test_name still use the subsection
case, so file discovery is unchanged.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Enables EAMxx CMORization and e3sm_diags pipelines end-to-end, replaces the fragile input_files-prefix gate before vertical interpolation with a prc_typ-based gate, and adds an opt-in [ts] vertical-regrid path that writes pressure-level files to a sibling ts_vert_remap/ directory which e3sm_to_cmip then auto-detects to avoid redundant regridding.
Changes:
- Replace fragile
input_files.split(".")[0]gate withprc_typ in ('cam','eam','eamxx'); emit EAMxx-specificncremapflags (--ps_nm,--vrt_in) whenprc_typ=='eamxx'; auto-skip vars already vert-remapped by[ts]. - Add
[ts]parametersvert_remap_vars/vrt_remap_file/vrt_in_filewith EAMxx defaults underdiagnostics_base_path, and[ts]template logic to produce a parallelts_vert_remap/output tree. - Switch
e3sm_diagsweb publish path to${www}/{{ default_case }}/...(decoupled from subsectioncaseoverrides) and addexamples/post.v3.eamxx.cfg.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| zppy/templates/e3sm_to_cmip.bash | New prc_typ gate, ts_vert_remap symlink overlay, readlink-based skip, and EAMxx ncremap flags. |
| zppy/templates/ts.bash | New optional vertical regrid loop producing output_plev/ and ts_vert_remap/ sibling destination. |
| zppy/templates/e3sm_diags.bash | web_dir now uses {{ default_case }} instead of subsection ${case}. |
| zppy/ts.py | Defaults for new vrt_remap_file/vrt_in_file when vert_remap_vars is set. |
| zppy/e3sm_to_cmip.py | EAMxx-only default for vrt_in_file. |
| zppy/e3sm_diags.py | Propagates config['default']['case'] as default_case for the bash template. |
| zppy/defaults/default.ini | Declares new [ts] and [e3sm_to_cmip] parameters (and __many__ overrides). |
| tests/test_sections.py | Adds new params to expected section/subsection dicts. |
| examples/post.v3.eamxx.cfg | New end-to-end EAMxx example (climo, ts, e3sm_to_cmip, e3sm_diags). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
@zhangshixuan1987 this PR should enable cmorization and e3sm Diags (except dirunal cycle and TC sets) for eamxx. I needed to make changes to both zppy and your example cfg file to make things work. Could you review: https://github.com/E3SM-Project/zppy/blob/f61b71a1980b8800daa095d0f7764b563083da55/examples/post.v3.eamxx.cfg. and let me know if it looks okay? e3sm_digas results can be find here. There was an issue for start and end year for Wheeler Kiladis, I will have a rerun to create it. |
|
@zhangshixuan1987 #830 should already be taken care of by this PR, without needing to add additional parameters. |
@chengzhuzhang Then we can forget about the #830 |
|
I realized that more work needed for eamxx daily output |
Hi @chengzhuzhang, I think the cfg file looks consistent with what I have on my local use. Below are some of my comments for your reference:
All other parts look reasonable to me. Thank you @chengzhuzhang for merging this cfg example. |
|
@zhangshixuan1987 thank you for your comment. Let's check with @czender if it is reasonable to update Regarding to |
|
@zhangshixuan1987 The latest NCO snapshot, now on Chrysalis and PM, tolerates missing |
forsyth2
left a comment
There was a problem hiding this comment.
@chengzhuzhang @zhangshixuan1987 Thanks for working on this! I've done a very-high-level visual inspection, but I'd definitely like to run the integration tests. While the current tests can confirm that nothing breaks, we'd need to include a new test cfg using an EAMxx simulation as the input to check the new features. I see /pscratch/sd/z/zhan391/e3smv4_project/ne256pg2_ne256pg2.F20TR-SCREAMv1.July-1.spanc800.2xauto.acc150.n0032.test2.1 is being used in the example cfg examples/post.v3.eamxx.cfg here -- should I transfer that (or a portion of that) to Chrysalis to test? Or is there another simulation that would be good for testing?
|
@forsyth2 thanks for a review. I'm not aware if lcrc has a similar eamxx run. If a transfer is needed, we only need a portion of |
|
@chengzhuzhang Ok, I can also just run the test cfg on Perlmutter, but the node queue time can be an issue. In any case, I'll work on making a test cfg version of the example cfg here. |
|
@chengzhuzhang @chengzhuzhang : As Jill mentioned, the data has to be transferred to Chrysalis for a full test related to the code base in this pull request. I do not have a copy on Chrysalis for any of the EAMXX model output data. |
@chengzhuzhang Ok, we can do that. We at least have confidence it's working since you were able to produce example output. We just don't want to be adding too many EAMxx features without a test cfg that will confirm the code is behaving as expected. Would you prefer me to just do a deeper visual inspection on this PR and then merge it? Or should we at least run the existing tests before merging? |
|
@forsyth2 yes, we should make sure this won't break existing tests before merging. Thanks! |
Sounds good, I'll work on getting those tests started.
I made a new issue, #837, to specifically track the new test cfgs (the EAMxx one and also the legacy 3.2.0 cfgs) that we'll need to create |
| # EAM/CAM have vertical coord info embedded in the file already. | ||
| if c["prc_typ"] == "eamxx": | ||
| default_vrt_in_file = ( | ||
| f"{c['diagnostics_base_path']}/e3sm_to_cmip_data/grids/vert_L128.nc" |
There was a problem hiding this comment.
I see the code already had a reference to {c['diagnostics_base_path']}/e3sm_to_cmip_data/ a few lines above, but it does seem a little strange since e3sm_to_cmip is downstream from ts.
Claude says the following, emphasis my own:
diagnostics_base_path points to a shared data installation directory (something like /usr/share/e3sm_unified/...) that happens to be organized under a folder named e3sm_to_cmip_data/ because that's where the e3sm_to_cmip package installs its reference data files (grid descriptors, pressure-level maps, etc.). The ts task is just borrowing files from that same installed data directory — it doesn't depend on the e3sm_to_cmip task having run first.
So the path e3sm_to_cmip_data/grids/vert_L128.nc means "the vert_L128.nc file that ships with the e3sm_to_cmip software package," not "a file produced by the e3sm_to_cmip zppy task." The e3sm_to_cmip task uses the same path for the same reason.
The slight awkwardness is that ts.py now has a hard-coded dependency on the directory layout of the e3sm_to_cmip package's data installation. If that package ever reorganizes its data files, both ts.py and e3sm_to_cmip.py would need updating. It might be worth a comment in the code noting that these are static reference files from the installed package, not outputs of the downstream task.
There was a problem hiding this comment.
It might be worth a comment in the code noting that these are static reference files from the installed package, not outputs of the downstream task.
@forsyth2 Prefixing with diagnostics_base_path should already imply the data are pre-installed. I think the current approach is fine, but feel free to update if you think it improves clarity.
There was a problem hiding this comment.
Prefixing with diagnostics_base_path should already imply the data are pre-installed
Yes I suppose looking at it again, that makes sense. It was just a little confusing when I was trying to figure out which tasks had e3sm_to_cmip as a dependency. A comment might be nice, but not necessary.
|
@chengzhuzhang I'm looking into the reason for the slowdown in ncclimo HFC mode. I cannot find the original files that you are attempting to process. Please point me to the ne30pg2 EAMxx input files. Thanks. |
@czender I have been testing with files here: /pscratch/sd/z/zhan391/e3smv4_project/ne256pg2_ne256pg2.F20TR-SCREAMv1.July-1.spanc800.2xauto.acc150.n0032.test2.1/run/3ha_ne30pg2.AVERAGE.nhours_x3*nc. Thanks! |
forsyth2
left a comment
There was a problem hiding this comment.
✅ Test passed. I also tried to a deeper visual inspection of the PR; I only left some minor nitpick comments that don't necessarily need to be addressed. This should be good to merge (reminder: we'll want to implement #837 soon to actually test an EAMxx simulation).
Testing
Set up environments
lcrc_conda # Bash function to activate conda.
# Set up e3sm_to_cmip env
# https://github.com/E3SM-Project/e3sm_to_cmip/commits/master/
# There have been 2 commits since `e3sm_to_cmip v1.14.0`,
# so, we should use a dev env rather than the Unified env.
cd ~/ez/
git clone git@github.com:E3SM-Project/e3sm_to_cmip.git
cd e3sm_to_cmip
git remote -v
git remote add upstream git@github.com:E3SM-Project/e3sm_to_cmip.git
git status # Check that branch is `master`, and for "nothing to commit, working tree clean"
git fetch upstream master
git reset --hard upstream/master
git log --oneline | head -n 3
# a54c636 Extra eamxx var (#347)
# 87e6479 fix: make `--var-list` parsing tolerant to comma-separated input (#346)
# 84bd5ff Bump to v1.14.0 (#345)
# Good, matches https://github.com/E3SM-Project/e3sm_to_cmip/commits/master/
rm -rf build
conda clean --all --y
conda env create -f conda-env/dev.yml -n test-e3sm-to-cmip-master-20260526 # Use today's date
conda activate test-e3sm-to-cmip-master-20260526
python -m pip install .
# Set up e3sm_diags env
# https://github.com/E3SM-Project/e3sm_diags/commits/main/
# There has been 1 commit since `e3sm_diags v3.2.0`,
# so, we should use a dev env rather than the Unified env.
cd ~/ez/e3sm_diags
git status # Check that branch is `main`, and for "nothing to commit, working tree clean"
git fetch upstream main
git reset --hard upstream/main
git log --oneline | head -n 2
# 9d5ebf19 Add targeted image-regression and E3SM Unified CI coverage (#1053)
# ff3ef00d Bump v3.2.0 (#1056)
# Good, matches https://github.com/E3SM-Project/e3sm_diags/commits/main
rm -rf build
conda clean --all --y
conda env create -f conda-env/dev.yml -n test-e3sm-diags-main-20260526 # Use today's date
conda activate test-diags-main-20260526
python -m pip install .
# Set up MPAS-Analysis env
# https://github.com/MPAS-Dev/MPAS-Analysis/commits/develop/
# There has been 2 commits since `mpas_analysis v1.15.0`,
# so, we should use a dev env rather than the Unified env.
cd ~/ez/MPAS-Analysis
git status # Check that branch is `develop`, and for "nothing to commit, working tree clean"
git fetch upstream develop
git reset --hard upstream/develop
git log --oneline | head -n 3
# 22956fd31 Merge pull request #1150 from MPAS-Dev/dependabot/github_actions/prefix-dev/setup-pixi-0.9.6
# aac7e79b0 Bump prefix-dev/setup-pixi from 0.9.5 to 0.9.6
# f8f8a5c1e Merge pull request #1148 from xylar/update-to-1.15.0
# Good, matches https://github.com/MPAS-Dev/MPAS-Analysis/commits/develop/
rm -rf build
conda clean --all --y
conda create --name test-mpas-analysis-develop-20260526 --file dev-spec.txt
conda activate test-mpas-analysis-develop-20260526
python -m pip install .
# Set up zppy-interfaces env
# https://github.com/E3SM-Project/zppy-interfaces/commits/main
# There have been NO commits since `zppy-interfaces 0.2.1`,
# so we can keep using the Unified envzppy run
# zppy itself #################################################################
cd ~/ez/zppy
git status # Check for uncommitted changes
git fetch upstream enable-e3sm_to_cmip-eamxx
git checkout -b test-enable-e3sm_to_cmip-eamxx upstream/enable-e3sm_to_cmip-eamxx
git log --oneline # Good, matches https://github.com/E3SM-Project/zppy/pull/827/commits
rm -rf build
conda clean --all --y
conda env create -f conda/dev.yml -n test-zppy-pr827
conda activate test-zppy-pr827
python -m pip install .
pytest tests/test_*.py # 44 passed in 1.06s
conda list python # Check Python version
# python 3.14.5
# This PR changed e3sm_diags.bash and e3sm_to_cmip.bash,
# so, we will want to run the tests for those tasks and any tasks that use them.
git grep --name-only e3sm_to_cmip zppy/*.py
# zppy/__main__.py
# zppy/e3sm_to_cmip.py
# zppy/ilamb.py
# zppy/pcmdi_diags.py
# zppy/ts.py
# => ilamb, pcmdi_diags depend on e3sm_to_cmip
# ts includes e3sm_to_cmip in two file paths:
# AI suggests: So the path e3sm_to_cmip_data/grids/vert_L128.nc means "the vert_L128.nc file that ships with the e3sm_to_cmip software package," not "a file produced by the e3sm_to_cmip zppy task." The e3sm_to_cmip task uses the same path for the same reason.
git grep --name-only e3sm_diags zppy/*.py
# zppy/climo.py
# zppy/e3sm_diags.py
# zppy/e3sm_to_cmip.py
# (climo, e3sm_to_cmip are just mentioning it in a comment)
# We'll want to set tasks_to_run to be this reduced list of tasks.
# We will however run the legacy tests to make sure this EAMxx support doesn't break backwards compatiblity.
# Edit tests/integration/utils.py:TEST_SPECIFICS: Dict[str, Any] = {
# This is the NCO path.
# Keep as "" to use the production-version NCO commands.
# Set to a specific path to use development-version NCO commands.
"nco_path": "",
# These are custom environment_commands for specific tasks.
# Never set these to "", because they will print the line
# `environment_commands = ""` for the corresponding task,
# thus overriding the value set higher up in the cfg.
# That is, there will be no environment set.
# (`environment_commands = ""` only redirects to Unified
# if specified under the [default] task)
"e3sm_to_cmip_environment_commands": "source /gpfs/fs1/home/ac.forsyth2/miniforge3/etc/profile.d/conda.sh; conda activate test-e3sm-to-cmip-master-20260526",
"diags_environment_commands": "source /gpfs/fs1/home/ac.forsyth2/miniforge3/etc/profile.d/conda.sh; conda activate test-e3sm-diags-main-20260526",
"mpas_analysis_environment_commands": "source /gpfs/fs1/home/ac.forsyth2/miniforge3/etc/profile.d/conda.sh; conda activate test-mpas-analysis-develop-20260526",
"global_time_series_environment_commands": "source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh", # Keep Unified
"livvkit_environment_commands": "source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh", # Keep Unified
"pcmdi_diags_environment_commands": "source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh", # Keep Unified
# This is the environment setup for other tasks.
# Leave as "" to use the latest Unified environment.
"environment_commands": "source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh", # Keep Unified
# For a complete test, run the set of latest cfgs and at least one set of legacy cfgs
"cfgs_to_run": [
"weekly_bundles",
"weekly_comprehensive_v2",
"weekly_comprehensive_v3",
"weekly_legacy_3.1.0_bundles",
"weekly_legacy_3.1.0_comprehensive_v2",
"weekly_legacy_3.1.0_comprehensive_v3",
"weekly_legacy_3.0.0_bundles",
"weekly_legacy_3.0.0_comprehensive_v2",
"weekly_legacy_3.0.0_comprehensive_v3",
],
"tasks_to_run": [
"e3sm_diags",
# "mpas_analysis",
# "global_time_series",
"ilamb",
# "livvkit",
"pcmdi_diags",
],
"unique_id": "test_pr827_20260526",
}git diff # Diff looks good
python tests/integration/utils.py
# CFG FILES HAVE BEEN GENERATED FROM TEMPLATES WITH THESE SETTINGS:
# UNIQUE_ID=test_pr827_20260526
# nco_path=
# Reminder: `nco_path=''` => the production-version NCO commands will be used
# e3sm_to_cmip_environment_commands=source /gpfs/fs1/home/ac.forsyth2/miniforge3/etc/profile.d/conda.sh; conda activate test-e3sm-to-cmip-master-20260526
# diags_environment_commands=source /gpfs/fs1/home/ac.forsyth2/miniforge3/etc/profile.d/conda.sh; conda activate test-e3sm-diags-main-20260526
# mpas_analysis_environment_commands=source /gpfs/fs1/home/ac.forsyth2/miniforge3/etc/profile.d/conda.sh; conda activate test-mpas-analysis-develop-20260526
# global_time_series_environment_commands=source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh
# livvkit_environment_commands=source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh
# pcmdi_diags_environment_commands=source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh
# environment_commands=source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh
# Reminder: `environment_commands=''` => the latest E3SM Unified environment will be used
# For reference:
alias sq
# Perlmutter: alias sq='sqa -u forsyth'
# Compy: alias sq='sqa -u fors729'
# Chrysalis: alias sq='sqa -u ac.forsyth2'
alias sqa
# Perlmutter: alias sqa='squeue -o "%8u %.7a %.4D %.9P %8i %.2t %.10r %.10M %.10l %j" --sort=P,-t,-p'
# Compy: alias sqa='squeue -o "%8u %.7a %.4D %.9P %7i %.2t %.10r %.10M %.10l %.8Q %j" --sort=P,-t,-p'
# Chrysalis: alias sqa='squeue -o "%8u %.7a %.4D %.9P %7i %.2t %.10r %.10M %.10l %j" --sort=P,-t,-p'
sq
# No jobs currently queued
ls tests/integration/generated/test_weekly_*_chrysalis.cfg # See all cfgs
# Launch jobs from ALL cfgs; start with the most important one, comprehensive_v3
zppy -c tests/integration/generated/test_weekly_comprehensive_v3_chrysalis.cfg
zppy -c tests/integration/generated/test_weekly_bundles_chrysalis.cfg
zppy -c tests/integration/generated/test_weekly_comprehensive_v2_chrysalis.cfg
zppy -c tests/integration/generated/test_weekly_legacy_3.1.0_bundles_chrysalis.cfg
zppy -c tests/integration/generated/test_weekly_legacy_3.1.0_comprehensive_v2_chrysalis.cfg
zppy -c tests/integration/generated/test_weekly_legacy_3.1.0_comprehensive_v3_chrysalis.cfg
zppy -c tests/integration/generated/test_weekly_legacy_3.0.0_bundles_chrysalis.cfg
zppy -c tests/integration/generated/test_weekly_legacy_3.0.0_comprehensive_v2_chrysalis.cfg
zppy -c tests/integration/generated/test_weekly_legacy_3.0.0_comprehensive_v3_chrysalis.cfg
sq | wc -l # Tue 05/26 16:21 => 167 - header row = 166 jobs
# Picking up 2026-05-27 #######################################################
sq | wc -l # Wed 05/27 12:45 => 1 - header row = 0 jobsBundles part 2
# Check on bundles status
cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_bundles_output/test_pr827_20260526/v3.LR.historical_0051/post/scripts
grep -v "OK" *status # Good, no errors
cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_bundles_output/test_pr827_20260526/v3.LR.historical_0051/post/scripts
grep -v "OK" *status # Good, no errors
cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.0.0_bundles_output/test_pr827_20260526/v3.LR.historical_0051/post/scripts
grep -v "OK" *status # Good, no errors
# Now, run bundles part 2
cd ~/ez/zppy
git status
# Good, correct branch: test-enable-e3sm_to_cmip-eamxx
# Need to re-establish dev env:
bash # Run bash so we're in an isolated subshell
source ~/.bashrc
lcrc_conda
conda activate test-zppy-pr827
sq | wc -l # Wed 05/27 12:50 => 1 - header row = 0 jobs
zppy -c tests/integration/generated/test_weekly_bundles_chrysalis.cfg
zppy -c tests/integration/generated/test_weekly_legacy_3.1.0_bundles_chrysalis.cfg
zppy -c tests/integration/generated/test_weekly_legacy_3.0.0_bundles_chrysalis.cfg
sq | wc -l # Wed 05/27 12:50 => 7 - header row = 6 jobsReview finished runs
### v2 ###
cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/test_pr827_20260526/v2.LR.historical_0201/post/scripts
grep -v "OK" *status # Good, no errors
cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.0.0_comprehensive_v2_output/test_pr827_20260526/v2.LR.historical_0201/post/scripts
grep -v "OK" *status
# e3sm_diags_atm_monthly_180x360_aave_model_vs_obs_1982-1983.status:RUNNING 1223458
cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_output/test_pr827_20260526/v2.LR.historical_0201/post/scripts
grep -v "OK" *status # Good, no errors
### v3 ###
cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v3_output/test_pr827_20260526/v3.LR.historical_0051/post/scripts
grep -v "OK" *status # Good, no errors
cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.0.0_comprehensive_v3_output/test_pr827_20260526/v3.LR.historical_0051/post/scripts
grep -v "OK" *status # Good, no errors
cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v3_output/test_pr827_20260526/v3.LR.historical_0051/post/scripts
grep -v "OK" *status # Good, no errors
### bundles ###
sq | wc -l # Wed 05/27 13:00 => 1 - header row = 0 jobs
cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_bundles_output/test_pr827_20260526/v3.LR.historical_0051/post/scripts
grep -v "OK" *status # Good, still no errors
cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.0.0_bundles_output/test_pr827_20260526/v3.LR.historical_0051/post/scripts
grep -v "OK" *status # Good, still no errors
cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_bundles_output/test_pr827_20260526/v3.LR.historical_0051/post/scripts
grep -v "OK" *status # Good, still no errorsDebugging
cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.0.0_comprehensive_v2_output/test_pr827_20260526/v2.LR.historical_0201/post/scripts
grep -v "OK" *status
# e3sm_diags_atm_monthly_180x360_aave_model_vs_obs_1982-1983.status:RUNNING 1223458
tail e3sm_diags_atm_monthly_180x360_aave_model_vs_obs_1982-1983.o1223458
# 2026-05-26 21:18:37,416 [WARNING]: warnings.py(_showwarnmsg:110) >> /gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-e3sm-diags-main-20260526/lib/python3.13/site-packages/cartopy/mpl/geoaxes.py:856: UserWarning: Attempting to set identical low and high xlims makes transformation singular; automatically expanding.
# self.set_xlim([x1, x2])
# 2026-05-26 21:18:41,532 [INFO]: utils.py(_save_main_plot:122) >> Plot saved in: model_vs_obs_1982-1983/lat_lon/ERA5/ERA5-TREFHT-SON-land.png
# srun: Job step aborted: Waiting up to 92 seconds for job step to finish.
# slurmstepd: error: *** STEP 1223458.0 ON chr-0316 CANCELLED AT 2026-05-27T01:31:25 DUE TO TIME LIMIT ***
# slurmstepd: error: *** JOB 1223458 ON chr-0316 CANCELLED AT 2026-05-27T01:31:25 DUE TO TIME LIMIT ***
# srun: got SIGCONT
# srun: forcing job termination
grep "\-\-time" e3sm_diags_atm_monthly_180x360_aave_model_vs_obs_1982-1983.bash
#SBATCH --time=5:00:00
# So, it hit a 5 hour time limit that ended at 5/26 21:18 When did we start?
grep -n 2026-05-26 e3sm_diags_atm_monthly_180x360_aave_model_vs_obs_1982-1983.o1223458 | head -n 1
# 24:2026-05-26 20:32:08,708 [INFO]: e3sm_diags_driver.py(_log_diagnostic_run_info:525) >>
# We started at 20:32, so we actually ran for only about 46 minutes before hanging.
# This is the intermittent bug again.
# https://github.com/E3SM-Project/zppy/issues/822
sq | wc -l # Wed 05/27 13:01 => 1 - header row = 0 jobs
sbatch e3sm_diags_atm_monthly_180x360_aave_model_vs_obs_1982-1983.bash
sq | wc -l # Wed 05/27 15:12 => 1 - header row = 0 jobs
grep -v "OK" *status # No errors now!post/scripts directory status: One error -- e3sm_diags once again hit the intermittent bug of #822. Rerunning with sbatch, as expected, resolved the issue.
Python tests
cd ~/ez/zppy
git status
# Good, correct branch: test-enable-e3sm_to_cmip-eamxx
# Good, correct env: Unified
ls tests/integration/test_*.py
# Passing
pytest tests/integration/test_last_year.py # 1 passed in 0.81s
# Failing, but errors look expected based on the PR
pytest tests/integration/test_bash_generation.py # 1 failed in 2.52s
pytest tests/integration/test_campaign.py # 6 failed in 3.86s
pytest tests/integration/test_defaults.py # 1 failed in 1.02s
pytest tests/integration/test_bundles.py # 2 failed in 0.67s
# This is ok because we didn't actually run all the jobs,
# so there's some missing info.
salloc --nodes=1 --partition=debug --time=02:00:00 --account=e3sm
# Re-establish Unified env
bash
source ~/.bashrc
lcrc_conda
conda activate test-zppy-pr827
pytest tests/integration/test_images.py
# 1 passed in 699.34s (0:11:39)
cat test_images_summary.mdComplete summary table:
| Test name | Total images | Correct images | Missing images | Mismatched images |
|---|---|---|---|---|
| bundles_e3sm_diags | 1762 | 1762 | 0 | 0 |
| bundles_ilamb | 388 | 388 | 0 | 0 |
| comprehensive_v2_e3sm_diags | 3806 | 3806 | 0 | 0 |
| comprehensive_v2_ilamb | 776 | 776 | 0 | 0 |
| comprehensive_v3_e3sm_diags | 5369 | 5369 | 0 | 0 |
| comprehensive_v3_ilamb | 837 | 837 | 0 | 0 |
| comprehensive_v3_pcmdi_diags | 647 | 647 | 0 | 0 |
| legacy_3.1.0_bundles_e3sm_diags | 1762 | 1762 | 0 | 0 |
| legacy_3.1.0_bundles_ilamb | 388 | 388 | 0 | 0 |
| legacy_3.1.0_comprehensive_v2_e3sm_diags | 3806 | 3806 | 0 | 0 |
| legacy_3.1.0_comprehensive_v2_ilamb | 776 | 776 | 0 | 0 |
| legacy_3.1.0_comprehensive_v3_e3sm_diags | 5365 | 5365 | 0 | 0 |
| legacy_3.1.0_comprehensive_v3_ilamb | 837 | 837 | 0 | 0 |
| legacy_3.0.0_bundles_e3sm_diags | 1762 | 1762 | 0 | 0 |
| legacy_3.0.0_bundles_ilamb | 388 | 388 | 0 | 0 |
| legacy_3.0.0_comprehensive_v2_e3sm_diags | 3806 | 3806 | 0 | 0 |
| legacy_3.0.0_comprehensive_v2_ilamb | 776 | 776 | 0 | 0 |
| legacy_3.0.0_comprehensive_v3_e3sm_diags | 5365 | 5365 | 0 | 0 |
| legacy_3.0.0_comprehensive_v3_ilamb | 837 | 837 | 0 | 0 |
Results
Other than the re-run required by the #822-affected job, I didn't encounter any issues in testing. Note I only ran the jobs that would be affected by a change to e3sm_to_cmip or e3sm_diags.
| # and written to a sibling directory `ts_vert_remap/` parallel to `ts/`, so users | ||
| # can use native-level and pressure-level data at the same time. | ||
| # If empty, no vertical regrid is performed. | ||
| vert_remap_vars = string(default="") |
There was a problem hiding this comment.
It's a little inconsistent to use vrt for 2 of the parameters and vert for another. But I don't know if it's worth changing (and risking breaking something else) at this point.
There was a problem hiding this comment.
Good catch! Let me try to rename vert_remap_vars → vrt_remap_vars — aligns everything with NCO's vrt_ prefix to be consistent. Since these are newly added parameters, it would be good to fix before releasing to the users.
There was a problem hiding this comment.
@zhangshixuan1987 just a quick note on this: you may need to rename vert_remap_vars to vrt_remap_vars. This change was made to reduce variation in parameter names.
| # EAM/CAM have vertical coord info embedded in the file already. | ||
| if c["prc_typ"] == "eamxx": | ||
| default_vrt_in_file = ( | ||
| f"{c['diagnostics_base_path']}/e3sm_to_cmip_data/grids/vert_L128.nc" |
There was a problem hiding this comment.
Prefixing with diagnostics_base_path should already imply the data are pre-installed
Yes I suppose looking at it again, that makes sense. It was just a little confusing when I was trying to figure out which tasks had e3sm_to_cmip as a dependency. A comment might be nice, but not necessary.
Align all vertical-remap naming with NCO's vrt_ prefix convention, matching the existing vrt_remap_file and vrt_in_file parameters. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
@chengzhuzhang Where can I find a comparable set of EAMv3 (not EAMxx) 3-hourly files so I can compare performance? |
@czender I have been using:/global/cfs/cdirs/e3sm/www/Tutorials/2024/simulations/extendedOutput.v3.LR.historical_0101/archive/atm/hist/extendedOutput.v3.LR.historical_0101.eam.h3.*nc. Thanks! |
|
@chengzhuzhang I have discovered the cause for the slowdown of the high frequency climos (HFCs) from EAMxx relative to EAMv3: The only ways that I can think of to remedy this are:
|
|
@czender thank you so much. I should have thought about this.. In this case, saving EAMxx high-frequency data into roughly monthly files would probably only be practical at ne30 resolution. Personally, between these two options, I would lean toward selecting variables and regridding first, prior to HFC climatology... |
|
@chengzhuzhang While investigating approaches to reduce the HFC time requirement on PM, I copied the entire 10-year daily dataset of 3-hourly values to my laptop and to Chrysalis, and I repeated the timing tests on these two machines. My laptop and Chrysalis both finish the entire 10-year 3-hourly HFC climo in 3 minutes or less (on only one node!). Thus it appears the problem is specific to Perlmutter which appears to deccelerate when operating on large numbers of small files (even when on compute nodes). This is the kind of issue that @ndkeen may be able to help with. Perhaps the |
@czender Super interesting, and somewhat surprising! Since the issue appears to be machine-specific, I’ll hold off on any attempts to change zppy for now. Hopefully this can be resolved on the system side without requiring workflow changes from us. |
|
p.s. the data are in |
Summary
Objectives:
input_files.split(".")[0]gate ine3sm_to_cmip.bashthatexcluded EAMxx runs whose
input_filesdoesn't start withcam/eam/eamxx(e.g.
input_files = "AVERAGE.nmonths_x1"withinput_component = "eamxx").Replaced with a
prc_typ-based gate that honorsinput_component. Fix [Bug]: fragile component detection before vertical interpolation #820--ps_nm=${file}/ps,--vrt_in=<L128>)inside the e3sm_to_cmip vertical interpolation block, auto-emitted when
prc_typ == 'eamxx'.vrt_in_filedefaults under{diagnostics_base_path}/e3sm_to_cmip_data/grids/vert_L128.nc.[ts]parametersvrt_remap_vars,vrt_remap_file,vrt_in_file: when set, thetstaskalso writes vertically remapped files to a sibling directory
post/{component}/{grid}/ts_vrt_remap/{frequency}/{ypf}yr/alongsidets/,so users can use native-level and pressure-level data simultaneously.
e3sm_to_cmip.bashto auto-detectts_vrt_remap/files (viareadlinkon the input symlinks) and skip its inline regrid for those vars,avoiding redundant work.
examples/post.v3.eamxx.cfgdemonstrating the EAMxx pipeline end-to-end(climo, ts, e3sm_to_cmip, e3sm_diags). Contributed by @zhangshixuan1987
Results can be viewed from here.
Example configuration file is available here.
Issue resolution:
Select one: This pull request is...
Please fill out either the "Small Change" or "Big Change" section (the latter includes the numbered subsections), and delete the other.
Small Change
Big Change
1. Does this do what we want it to do?
Required:
If applicable:
2. Are the implementation details accurate & efficient?
Required:
If applicable:
zppy/conda, not just animportstatement.3. Is this well documented?
Required:
4. Is this code clean?
Required:
If applicable: