diff --git a/.gitmodules b/.gitmodules index a232ef7875..0bae8190dd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -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 +#branch = land_only +fxtag = dd65b0be6d70a3158549d636ec26376f94c27d40 +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 diff --git a/README b/README index deca3cd8d2..964c228185 100644 --- a/README +++ b/README @@ -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 diff --git a/README.DIAGNOSTICS b/README.DIAGNOSTICS new file mode 100644 index 0000000000..c1075318df --- /dev/null +++ b/README.DIAGNOSTICS @@ -0,0 +1,61 @@ +# QuickStart to Running Diagnostics of your Case with CUPiD (CESM Unified Postprocessing and Diagnostics) + +[!NOTE] +Land Diagnostics Cheat Sheet is here: + +This document has more details on more options and such + +https://ncar.github.io/CUPiD/run_cesm.html + +## 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 -- or if you need to +setup the environment for a different CTSM checkout. + +``` shell +# CUPiD instructions for this is here: https://ncar.github.io/CUPiD/index.html#installing +cd tools/CUPiD +mamba env create --yes -f environments/cupid-infrastructure.yml +mamba env create --yes -f 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 + +# Instructions for the next part are here: +# https://ncar.github.io/CUPiD/index.html#note +# 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 +``` + + +#### IMPORTANT NOTE: You have to REMAKE THE CUPiD ENVIRONMENTS for a different CTSM Checkout + + + +> [!IMPORTANT] +> If you want to use CUPiD in a different clone of CTSM -- you'll need to remake the environments there. + +## 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 +``` diff --git a/cime_config/SystemTests/ctsm_test_status.py b/cime_config/SystemTests/ctsm_test_status.py new file mode 100644 index 0000000000..3b9807a02e --- /dev/null +++ b/cime_config/SystemTests/ctsm_test_status.py @@ -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") ) \ No newline at end of file diff --git a/cime_config/SystemTests/smscupid.py b/cime_config/SystemTests/smscupid.py new file mode 100644 index 0000000000..14a82f75c7 --- /dev/null +++ b/cime_config/SystemTests/smscupid.py @@ -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) diff --git a/cime_config/SystemTests/smspostproc.py b/cime_config/SystemTests/smspostproc.py new file mode 100644 index 0000000000..ce1d393feb --- /dev/null +++ b/cime_config/SystemTests/smspostproc.py @@ -0,0 +1,19 @@ +from CIME.SystemTests.sms import SMS + +class SMSPOSTPROC(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) + self._case.set_value("RUN_POSTPROCESSING", True) diff --git a/cime_config/config_tests.xml b/cime_config/config_tests.xml index c5c6749392..5b32e16829 100644 --- a/cime_config/config_tests.xml +++ b/cime_config/config_tests.xml @@ -185,6 +185,33 @@ This defines various CTSM-specific system tests $STOP_N + + Run a smoke startup test with st_archive and post-processing on + 1 + TRUE + TRUE + FALSE + nyears + 5 + never + $STOP_OPTION + $STOP_N + + + + Run a smoke startup test with CUPiD on + 1 + TRUE + FALSE + TRUE + + nyears + 5 + never + $STOP_OPTION + $STOP_N + + @@ -100,6 +101,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cime_config/testdefs/testmods_dirs/clm/CUPiD_ILAMB/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/CUPiD_ILAMB/include_user_mods new file mode 100644 index 0000000000..19fdf1b2a9 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/CUPiD_ILAMB/include_user_mods @@ -0,0 +1 @@ +../../../../usermods_dirs/clm/CUPiD diff --git a/cime_config/testdefs/testmods_dirs/clm/CUPiD_ILAMB/shell_commands b/cime_config/testdefs/testmods_dirs/clm/CUPiD_ILAMB/shell_commands new file mode 100755 index 0000000000..4979861ab3 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/CUPiD_ILAMB/shell_commands @@ -0,0 +1,3 @@ +#!/bin/bash +./xmlchange CUPID_RUN_ILAMB=TRUE + diff --git a/cime_config/testdefs/testmods_dirs/clm/CUPiD_LDF/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/CUPiD_LDF/include_user_mods new file mode 100644 index 0000000000..19fdf1b2a9 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/CUPiD_LDF/include_user_mods @@ -0,0 +1 @@ +../../../../usermods_dirs/clm/CUPiD diff --git a/cime_config/testdefs/testmods_dirs/clm/CUPiD_LDF/shell_commands b/cime_config/testdefs/testmods_dirs/clm/CUPiD_LDF/shell_commands new file mode 100755 index 0000000000..8f0a44bdf1 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/CUPiD_LDF/shell_commands @@ -0,0 +1,8 @@ +#!/bin/bash +./xmlchange CUPID_RUN_LDF=TRUE + +# Base case setttings to match the case just run +./xmlchange CUPID_BASE_STARTDATE='$RUN_STARTDATE' +./xmlchange CUPID_BASE_CLIMO_END_YEAR=2005 +./xmlchange CUPID_BASE_CLIMO_N_YEAR='$STOP_N' +./xmlchange CUPID_BASE_STOP_N='$STOP_N' diff --git a/cime_config/testdefs/testmods_dirs/clm/CUPiD_ROF/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/CUPiD_ROF/include_user_mods new file mode 100644 index 0000000000..19fdf1b2a9 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/CUPiD_ROF/include_user_mods @@ -0,0 +1 @@ +../../../../usermods_dirs/clm/CUPiD diff --git a/cime_config/testdefs/testmods_dirs/clm/CUPiD_ROF/shell_commands b/cime_config/testdefs/testmods_dirs/clm/CUPiD_ROF/shell_commands new file mode 100755 index 0000000000..5bf4cc5edf --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/CUPiD_ROF/shell_commands @@ -0,0 +1,4 @@ +#!/bin/bash +./xmlchange CUPID_RUN_ROF=TRUE +./xmlchange CUPID_RUN_LND=FALSE + diff --git a/cime_config/testdefs/testmods_dirs/clm/CUPiD_web/include_user_mods b/cime_config/testdefs/testmods_dirs/clm/CUPiD_web/include_user_mods new file mode 100644 index 0000000000..19fdf1b2a9 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/CUPiD_web/include_user_mods @@ -0,0 +1 @@ +../../../../usermods_dirs/clm/CUPiD diff --git a/cime_config/testdefs/testmods_dirs/clm/CUPiD_web/shell_commands b/cime_config/testdefs/testmods_dirs/clm/CUPiD_web/shell_commands new file mode 100755 index 0000000000..cd3b5af047 --- /dev/null +++ b/cime_config/testdefs/testmods_dirs/clm/CUPiD_web/shell_commands @@ -0,0 +1,3 @@ +#!/bin/bash +./xmlchange CUPID_GEN_HTML=TRUE + diff --git a/cime_config/usermods_dirs/clm/CUPiD/README b/cime_config/usermods_dirs/clm/CUPiD/README new file mode 100644 index 0000000000..bad4204f8f --- /dev/null +++ b/cime_config/usermods_dirs/clm/CUPiD/README @@ -0,0 +1,4 @@ +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. + +To run with CUPiD you'll need to activate the cupid-infrastructure conda environment diff --git a/cime_config/usermods_dirs/clm/CUPiD/include_user_mods b/cime_config/usermods_dirs/clm/CUPiD/include_user_mods new file mode 100644 index 0000000000..20112a70eb --- /dev/null +++ b/cime_config/usermods_dirs/clm/CUPiD/include_user_mods @@ -0,0 +1 @@ +../_includes/hist_2000-2005 diff --git a/cime_config/usermods_dirs/clm/CUPiD/shell_commands b/cime_config/usermods_dirs/clm/CUPiD/shell_commands new file mode 100755 index 0000000000..d0a8b5382d --- /dev/null +++ b/cime_config/usermods_dirs/clm/CUPiD/shell_commands @@ -0,0 +1,66 @@ +#!/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 + +# +# Set CUPiD parameters for what a CTSM case needs to do +# + +# Set the standard CUPiD baseline case to compare to +./xmlchange CUPID_BASELINE_CASE='ctsm5.4.002_clm6_BGCcrop_crujra_4x5_HIST' +# NOTE: This is currently only valid on Derecho +# TODO: Look into having this available under GDEX and available anywhere via download +./xmlchange CUPID_BASELINE_ROOT='/glade/campaign/cesm/development/cross-wg/diagnostic_framework/CESM_output_for_testing' +./xmlchange CUPID_BASE_STARTDATE='1995-01-01' +./xmlchange CUPID_BASE_CLIMO_END_YEAR=1995 +./xmlchange CUPID_BASE_CLIMO_N_YEAR=10 +./xmlchange CUPID_BASE_STOP_N=20 +./xmlchange CUPID_BASE_STOP_OPTION='nyears' + +# +# General setup based on the start and length of the case being run +# +./xmlchange CUPID_CLIMO_END_YEAR=2004 +./xmlchange CUPID_CLIMO_N_YEAR='$STOP_N' +# TODO: Have this set based on what CLM_BLDNML_OPTS has +#./xmlchange CUPID_RUN_TYPE=SP +./xmlchange CUPID_STARTDATE='$RUN_STARTDATE' +./xmlchange CUPID_STOP_N='$STOP_N' +# TODO: Check that STOP_OPTION is nyears +./xmlchange CUPID_STOP_OPTION='$STOP_OPTION' +# Put the time-series directory under the CUPID output +./xmlchange CUPID_TS_DIR='$CIME_OUTPUT_ROOT/cupid_output' + +# +# Setting for specific CUPiD diagnostics to run +# +./xmlchange CUPID_GEN_TIMESERIES=FALSE +# NOTE: Create webpages for Tutorial, for testing have this done seperately +./xmlchange CUPID_GEN_HTML=TRUE +# TODO: Test with running more tasks +#./xmlchange CUPID_NTASKS=1 +# TODO: Trigger these to be FALSE only when it is an I compset +./xmlchange CUPID_RUN_ADF=FALSE +./xmlchange CUPID_RUN_ALL=FALSE +# Use the land_only example, with LDF on and ILAMB off +./xmlchange CUPID_EXAMPLE=land_only +./xmlchange CUPID_RUN_LDF=TRUE +./xmlchange CUPID_RUN_ILAMB=FALSE +# NOTE: CUPID_RUN_LND must be set to TRUE for either LDF or ILAMB +# and you should pick one or the other as LND needs key-metrics from one or the other +./xmlchange CUPID_RUN_LND=TRUE +# TODO: Test if ROF can be run +./xmlchange CUPID_RUN_ROF=FALSE diff --git a/cime_config/usermods_dirs/clm/_includes/hist_2000-2005/shell_commands b/cime_config/usermods_dirs/clm/_includes/hist_2000-2005/shell_commands new file mode 100755 index 0000000000..b5e0ad368e --- /dev/null +++ b/cime_config/usermods_dirs/clm/_includes/hist_2000-2005/shell_commands @@ -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 diff --git a/tools/CUPiD b/tools/CUPiD new file mode 160000 index 0000000000..dd65b0be6d --- /dev/null +++ b/tools/CUPiD @@ -0,0 +1 @@ +Subproject commit dd65b0be6d70a3158549d636ec26376f94c27d40 diff --git a/tools/README.md b/tools/README.md index 3e74fd6f3e..059e546fbb 100644 --- a/tools/README.md +++ b/tools/README.md @@ -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.