Skip to content
Draft
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
499c13f
Add CUPiD to the submodule checkout
ekluzek Jan 8, 2026
a0f4094
CIME assumes a certain case for CUPiD
ekluzek Jan 8, 2026
22bcd8c
Add note about the addition of CUPiD under tools
ekluzek Jan 8, 2026
133475d
Change name of the CUPiD directory so that it uses the name assumed i…
ekluzek Jan 9, 2026
99ecd8e
Update README.DIAG to use the CUPiD usermod directory
ekluzek Jan 13, 2026
9493442
Rename for clarity
ekluzek Jan 13, 2026
3d368b6
Add note about new README
ekluzek Jan 13, 2026
b21026d
Update CUPiD version to include pinned environments
ekluzek Jan 13, 2026
0ef3c92
Fix the generate issue for CUPiD
ekluzek Jan 13, 2026
675ce37
Adjust options a bit, and also change the generate step so it only ha…
ekluzek Jan 13, 2026
e870c10
Add a simple test to run CUPiD
ekluzek Jan 13, 2026
5630cbd
Add another one time thing to do
ekluzek Jan 15, 2026
e463fe7
Update to a version that is working
ekluzek Jan 15, 2026
baa6088
Turn off some options that weren't working, and add setting DOUT_S to…
ekluzek Jan 15, 2026
d8d1d4b
Shift the CUPiD test to run f19 rather than f09, and IHist rather tha…
ekluzek Jan 15, 2026
256a8d4
Merge branch 'master' into CUPiD
ekluzek Jan 15, 2026
e6c38c2
Update CUPiD to Will's land_only example version
ekluzek Jan 26, 2026
76bb364
Merge branch 'CUPiD' of github.com:ESCOMP/CTSM into CUPiD
ekluzek Jan 26, 2026
203a391
Merge tag 'ctsm5.4.011' into CUPiD
ekluzek Jan 26, 2026
91e8267
Start adding a CUPiD system test, change the CUPiD test mod to use th…
ekluzek Jan 27, 2026
8c5904d
Change the name of the cupid test, since having the _c in the testnam…
ekluzek Jan 27, 2026
714de30
Merge branch 'master' into CUPiD
ekluzek Feb 10, 2026
c2b8893
Merge branch 'CUPiD' of github.com:ESCOMP/CTSM into CUPiD
ekluzek Feb 10, 2026
04c3b25
Turn off LDF for default setup
ekluzek Feb 10, 2026
d4e5826
Simple list of archive tests for CUPiD options
ekluzek Feb 10, 2026
d333a31
Simple archive test and CUPiD testmods for the different CUPiD option…
ekluzek Feb 10, 2026
28fbcb8
Add more needed to get a full CUPiD test working
ekluzek Feb 10, 2026
a33dfea
Add setup for SMSAR and SMSCUPID tests
ekluzek Feb 10, 2026
b91b731
Correct variable names
ekluzek Feb 10, 2026
a06eb03
At least CUPID_RUN_LND needs to be on for both ILAMB or LDF
ekluzek Feb 10, 2026
95acbfc
Add a aux_cupid testlist and add a testmod for making HTML pages
ekluzek Feb 10, 2026
dc7043d
Update CUPiD to Will's latest
ekluzek Feb 11, 2026
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
12 changes: 12 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,18 @@ fxrequired = ToplevelRequired
# Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed
fxDONOTUSEurl = https://github.com/ESMCI/mpi-serial

[submodule "cupid"]
# CUPiD does model post-processing
path = tools/CUPiD
#url = https://github.com/NCAR/CUPiD.git
url = https://github.com/wwieder/CUPiD.git
#fxtag = v0.6.0
#fxtag = land_only
fxtag = 30bd428b7139873382107b0a32624a7492e28a91
fxrequired = ToplevelRequired
# Standard Fork to compare to with "git fleximod test" to ensure personal forks aren't committed
fxDONOTUSEurl = https://github.com/NCAR/CUPiD.git

[submodule "doc-builder"]
path = doc/doc-builder
url = https://github.com/ESMCI/doc-builder
Expand Down
1 change: 1 addition & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ README ------------------- This file
README.md ---------------- File that displays on github under https::/github.com/ESCOMP/CTSM.git
README.rst --------------- File that displays under the project in github
README_GITFLEXIMOD.rst --- Information on how to work with git-fleximod for CTSM
README_DIAGNOSTICS.md ---- Quickstart on using CUPiD to plot diagnostics for your CTSM case
WhatsNewInCTSM5.4.md ----- Overview document of the changes between ctsm5.3 and ctsm5.4
Copyright ---------------- CESM Copyright file
doc/UpdateChangeLog.pl --- Script to add documentation on a tag to the
Expand Down
51 changes: 51 additions & 0 deletions README.DIAGNOSTICS
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# QuickStart to Running Diagnostics of your Case with CUPiD (CESM Unified Postprocessing and Diagnostics)
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we point to the documentation for running CUPiD via the CESM workflow rather than duplicating and ending up with outdated information?
I'm thinking it would also be good for me to put the land-specific 'cheat sheet' as a docs page for component-specific example of running a STANDALONE version


[!NOTE]
Land Diagnostics Cheat Sheet is here:

This document has more details on more options and such

https://docs.google.com/document/d/1ziZWGgaj9FxgR6WRHyCAZnzIc6-4ezqfUDDpQv4MzUI/edit?tab=t.0
Copy link
Collaborator Author

Choose a reason for hiding this comment

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


## Initial setup steps to do first time

This step is something you need to do the first time you want to run CUPiD for a case.
And you only need to do it again if the CUPiD environment changes.

``` shell
# Setup the conda environments
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Here, point to the CUPiD documentation

# TODO: Make this use py_env_create?
mamba env create --yes -f tools/cupid/environments/cupid-infrastructure.yml
mamba env create --yes -f tools/cupid/environments/cupid-analysis.yml
# Check that the environment is valid
conda activate cupid-infrastructure
which cupid-diagnostics
# Should return something like:
# $HOME/conda-envs/cupid-infrastructure/bin/cupid-diagnostics
# If it returns "Command not found." something is wrong with the environment


# Now make sure the conda environments can be used by Jupyter notebooks
conda activate cupid-analysis
python -m ipykernel install --user --name=cupid-analysis
conda activate cupid-infrastructure
python -m ipykernel install --user --name=cupid-infrastructure
```

## Create your case using the CUPiD user-mod

This is similar to setting up any case, such as documented in the README and Quickstart guides.

``` shell
./create_newcase --case testIwCUPiD --res f09_t232 --compset I2000Clm60BgcCrop --user-mods-dirs clm-CUPiD
```

## Run CUPID in your case

After st_archive has run do the following. With RUN_POSTPROCESSING set to TRUE this will happen
with each case submission automatically. But, if you want to run it separately...


``` shell
./case.submit --only-job case.cupid
```
30 changes: 30 additions & 0 deletions cime_config/SystemTests/ctsm_test_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

from CIME.test_status import *

CUPID_PHASE = "CUPID"

ALL_PHASES = [
CREATE_NEWCASE_PHASE,
XML_PHASE,
SETUP_PHASE,
NAMELIST_PHASE,
SHAREDLIB_BUILD_PHASE,
MODEL_BUILD_PHASE,
SUBMIT_PHASE,
RUN_PHASE,
COMPARE_PHASE,
BASELINE_PHASE,
THROUGHPUT_PHASE,
MEMCOMP_PHASE,
MEMLEAK_PHASE,
STARCHIVE_PHASE,
CUPID_PHASE,
GENERATE_PHASE,
]

# Extend the TestStatus class to include the CUPID phase and have CUPID phase within ALL_PHASES
class CTSMTestStatus(TestStatus):

def __init__(self, case):
super().__init__(case, ALL_PHASES)
self._test_status = CTSMTestStatus(test_dir=case.get_value("CASEROOT"), test_name=self.case.get_value("CASEBASEID") )
40 changes: 40 additions & 0 deletions cime_config/SystemTests/smsar.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from CIME.SystemTests.sms import SMS
from ctsm_test_status import *


class SMSAR(SMS):
def setup_indv(
self, clean=False, test_mode=False, reset=False, keep=False, disable_git=False
):
"""
Perform an individual setup
"""
super().setup_indv(
clean=clean,
test_mode=test_mode,
reset=reset,
keep=keep,
disable_git=disable_git,
)
# Make sure the st_archiver is turned on, as CUPiD only runs after it runs
self._case.set_value("DOUT_S", True)

def run_indv(
self,
suffix="base",
st_archive=True,
cupid=True,
submit_resubmits=None,
keep_init_generated_files=False,
):
"""
Perform an individual run. Raises an EXCEPTION on fail.

Just add the CUPiD phase after the standard run.
"""
super().run_indv(
suffix=suffix,
st_archive=st_archive,
submit_resubmits=submit_resubmits,
keep_init_generated_files=keep_init_generated_files,
)
82 changes: 82 additions & 0 deletions cime_config/SystemTests/smscupid.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from CIME.SystemTests.sms import SMS
from ctsm_test_status import *


class SMSCUPID(SMS):
def __init__(self, case):
super().__init__(case)
self._test_status = CTSMTestStatus(
test_dir=self._case.get_value("CASEROOT"),
test_name=self._case.get_value("CASEBASEID"),
)

def setup_indv(
self, clean=False, test_mode=False, reset=False, keep=False, disable_git=False
):
"""
Perform an individual setup
"""
super().setup_indv(
clean=clean,
test_mode=test_mode,
reset=reset,
keep=keep,
disable_git=disable_git,
)
# Make sure the st_archiver is turned on, as CUPiD only runs after it runs
self._case.set_value("DOUT_S", True)

def run_indv(
self,
suffix="base",
st_archive=True,
cupid=True,
submit_resubmits=None,
keep_init_generated_files=False,
):
"""
Perform an individual run. Raises an EXCEPTION on fail.

Just add the CUPiD phase after the standard run.
"""
super().run_indv(
suffix=suffix,
st_archive=st_archive,
submit_resubmits=submit_resubmits,
keep_init_generated_files=keep_init_generated_files,
)
self._phase_modifying_call(CUPID_PHASE, self._cupid_case_test)

def case_test_cupid(self, testdir="cupid_test"):
# create the run directory testdir
if os.path.exists(testdir):
logger.info("Removing existing test directory {}".format(testdir))
shutil.rmtree(testdir)
# Check that the CUPid postprocessing directories and config file exist
cupid_dir = os.path.join(self._case.get_value("CASEROOT"), "cupid-postprocessing" )
notebooks_dir = os.path.join(cupid_dir, "compute_notebooks")
data_dir = os.path.join(cupid_dir, "temp_data")
for dir in [cupid_dir, notebooks_dir, data_dir]:
expect( os.isdir(dir),
"CUPiD postprocessing directory {} does not exist".format(dir) )
cupid_config = os.path.join(cupid_dir, "config.yml")
expect( os.isfile(cupid_config),
"CUPiD config file {} does not exist".format(cupid_config) )
# TODO: Add more checks about more files that should exist


# TODO: Populate the testdir with data files, config files and notebooks from the cupid-postprocessing directory

# TODO: Save various files to the baseline directory to use for BASELINE comparison

return True

def _cupid_case_test(self):
# For the st_archiver this test is under the case object
# Here we create it in this object, but probably should be moved to under the case object in CIME
result = self.test_cupid()
with self._test_status:
if result:
self._test_status.set_status(CUPID_PHASE, TEST_PASS_STATUS)
else:
self._test_status.set_status(CUPID_PHASE, TEST_FAIL_STATUS)
26 changes: 26 additions & 0 deletions cime_config/config_tests.xml
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,32 @@ This defines various CTSM-specific system tests
<HIST_N>$STOP_N</HIST_N>
</test>

<test NAME="SMSAR">
<DESC>Run a smoke startup test with st_archive on</DESC>
<INFO_DBUG>1</INFO_DBUG>
<DOUT_S>TRUE</DOUT_S>
<CONTINUE_RUN>FALSE</CONTINUE_RUN>
<STOP_OPTION>nyears</STOP_OPTION>
<STOP_N>5</STOP_N>
<REST_OPTION>never</REST_OPTION>
<HIST_OPTION>$STOP_OPTION</HIST_OPTION>
<HIST_N>$STOP_N</HIST_N>
</test>

<test NAME="SMSCUPID">
<DESC>Run a smoke startup test with CUPiD on</DESC>
<INFO_DBUG>1</INFO_DBUG>
<DOUT_S>TRUE</DOUT_S>
<CONTINUE_RUN>FALSE</CONTINUE_RUN>
<RUN_POSTPROCESSING>TRUE</RUN_POSTPROCESSING>
<!-- TODO: Add CUPID Settings -->
<STOP_OPTION>nyears</STOP_OPTION>
<STOP_N>5</STOP_N>
<REST_OPTION>never</REST_OPTION>
<HIST_OPTION>$STOP_OPTION</HIST_OPTION>
<HIST_N>$STOP_N</HIST_N>
</test>

<!--
SSP smoke CLM spinup test (only valid for CLM compsets with CLM45)
do an initial spin test (setting CLM_ACCELERATED_SPINUP to on)
Expand Down
27 changes: 27 additions & 0 deletions cime_config/testdefs/testlist_clm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,33 @@
<option name="comment">Repeat no anthropogenic compset with t232 and Crujra while the defaults have not changed</option>
</options>
</test>
<test name="SMSAR_PS" grid="f45_f45_mg37" compset="IHistClm60BgcCrujra" testmods="clm/CUPiD">
<machines>
<machine name="derecho" compiler="intel" category="aux_clm"/>
</machines>
<options>
<option name="wallclock">00:20:00</option>
<option name="comment">Simple smoke test running st_archive with CUPiD on for LND</option>
</options>
</test>
<test name="SMSAR_PS" grid="f45_f45_mg37" compset="IHistClm60BgcCrujra" testmods="clm/CUPiD_LDF">
<machines>
<machine name="derecho" compiler="intel" category="aux_clm"/>
</machines>
<options>
<option name="wallclock">00:20:00</option>
<option name="comment">Simple smoke test running st_archive with CUPiD on for the LDF</option>
</options>
</test>
<test name="SMSAR_PS" grid="f45_f45_mg37" compset="IHistClm60BgcCrujra" testmods="clm/CUPiD_ILAMB">
<machines>
<machine name="derecho" compiler="intel" category="aux_clm"/>
</machines>
<options>
<option name="wallclock">00:20:00</option>
<option name="comment">Simple smoke test running st_archive with CUPiD on for the ILAMB</option>
</options>
</test>
<test name="SMS_D_Ld5_PS" grid="f09_f09_mt232" compset="I1850Clm60BgcCrop" testmods="clm/f09_ObscureStreamOpts">
<machines>
<machine name="derecho" compiler="gnu" category="aux_clm"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
../../../../usermods_dirs/clm/CUPiD
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
./xmlchange CUPID_ILAMB=TRUE
./xmlchange CUPID_LND=FALSE

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
../../../../usermods_dirs/clm/CUPiD
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
./xmlchange CUPID_LDF=TRUE
./xmlchange CUPID_LND=FALSE

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
../../../../usermods_dirs/clm/CUPiD
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
./xmlchange CUPID_ROF=TRUE
./xmlchange CUPID_LND=FALSE

2 changes: 2 additions & 0 deletions cime_config/usermods_dirs/clm/CUPiD/README
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This usermod turns on running CUPiD to get plots and diagnostics as part of a case. It sets the most common settings
for a CTSM case.
1 change: 1 addition & 0 deletions cime_config/usermods_dirs/clm/CUPiD/include_user_mods
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
../_includes/hist_2000-2005
52 changes: 52 additions & 0 deletions cime_config/usermods_dirs/clm/CUPiD/shell_commands
Copy link
Member

@samsrabin samsrabin Jan 13, 2026

Choose a reason for hiding this comment

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

Let's go through this and figure out which of these should be default settings for ALL CTSM standalone cases—i.e., not just in this usermod. (And also—which of these are already set correctly by default without us in CTSM needing to do anything.)

Copy link
Member

Choose a reason for hiding this comment

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

Maybe in cime_config/config_component.xml. But need to check that these would only apply in a standalone CTSM checkout.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've been looking at other repositories for other things, but I see this sort of thing in config_compsets.xml for several components.

  <entries>
    <entry id="RUN_STARTDATE"> 
      <values>
        <value compset="1850_">0001-01-01</value>
      </values>
    </entry>

So it looks like that's the sort of thing that can be done. The entry is defined elsewhere, but you can set the value according to the compset as above. I think in our case we want it to be in config_component.xml, so I'll check if it can be added there.

If not we could add %CUPID as part of the CLM compset options. I don't think I like that, but it's probably something to discuss. We do have compsets that set a particular user-mod directory as part of their definition. And this would be doing that same thing here.

Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/bin/bash
# Make sure DOUT_S is turned on, as CUPiD only runs after st_archive
./xmlchange DOUT_S=TRUE

# Enable postprocessing which is what turns on running CUPiD for a case
./xmlchange RUN_POSTPROCESSING=TRUE


LND_ROOT=`./xmlquery --value COMP_ROOT_DIR_LND`

CUPID_ROOT=`./xmlquery --value CUPID_ROOT`
# When I first tried this I thought I needed the following...
if [ -z "$CUPID_ROOT" ]; then
echo "CUPID settings aren't done yet"
exit 5
fi

# For a test case, make sure DOUT_S is TRUE
# TODO: Add a proper SystemTest so this is handled correctly in the test
TEST=`./xmlquery --value TEST`
if [ "$TEST" == "TRUE" ]; then
./xmlchange DOUT_S=TRUE --file env_test.xml
fi

#
# Set CUPiD parameters for what a CTSM case needs to do
#

# Set the standard CUPiD baseline case to compare to
./xmlchange --force CUPID_BASELINE_CASE='$CASE'
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

For the base case I need to point to @wwieder base case.

/glade/campaign/cesm/development/cross-wg/diagnostic_framework/CESM_output_for_testing/ctsm5.4.002_clm6_BGCcrop_crujra_4x5_HIST/lnd/hist

make the clm6_0 physics in the ctsm5.,4.002 tag 4x5 case the base case

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Use the start and extent for the base case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Do the case as a I2000 starting 2000-2004

./xmlchange --force CUPID_BASE_STARTDATE='$RUN_STARTDATE'
./xmlchange --force CUPID_BASE_STOP_N='$STOP_N'
# TODO: Make sure STOP_OPTION is nyears
./xmlchange --force CUPID_BASE_STOP_OPTION='$STOP_OPTION'
# TODO: Have this set based on what CLM_BLDNML_OPTS has
./xmlchange CUPID_RUN_TYPE=SP
./xmlchange --force CUPID_STARTDATE='$RUN_STARTDATE'
./xmlchange --force CUPID_STOP_N='$STOP_N'
./xmlchange --force CUPID_STOP_OPTION='$STOP_OPTION'
# TODO: This should maybe be turned on as a smoke test, and to check for the appropriate files in testing
./xmlchange CUPID_GEN_HTML=TRUE
# TODO: Test with running more tasks
./xmlchange CUPID_NTASKS=1
./xmlchange CUPID_RUN_ADF=FALSE
./xmlchange CUPID_RUN_ALL=FALSE
# Use the land_only example
./xmlchange CUPID_EXAMPLE=land_only
# TODO: Get CUPiD working with LDF under CESM
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

LND without either LDF or ILAMB won't work except with a ne30 case

./xmlchange CUPID_RUN_LDF=FALSE
./xmlchange CUPID_RUN_LND=TRUE
# TODO: Test if ROF can be run
./xmlchange CUPID_RUN_ROF=TRUE
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
# Setup for a IHist case to start in 2000 and run for 5 years
./xmlchange RUN_STARTDATE=2000-01-01
./xmlchange STOP_OPTION=nyears
./xmlchange STOP_N=5
1 change: 1 addition & 0 deletions tools/CUPiD
Submodule CUPiD added at 30bd42
1 change: 1 addition & 0 deletions tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ modification of CTSM input files.
I. General directory structure:

`$CTSMROOT/tools`
CUPiD ------------ Postprocessing of cases (CESM Unified Postprocessing and Diagnostics)
mksurfdata_esmf -- Create surface datasets.

crop_calendars --- Regrid and process GGCMI sowing and harvest date files for use in CTSM.
Expand Down
Loading