Repository: ESMCI/cime

Issue:
Add a "case-family" argument to create_newcase
In order to complete all the simulations required for DECK, many cases will have to be run.   Each run (pi-control, 20th centruy, SSP85) will start with separate invocations of "create_newcase" with a different argument to "--case" for each simulation and that argument is recorded in the CASE variable in env_run.xml.

For constructing databases and other provenance tools, it would be useful to indicate that each case is part of something larger (in this instance, a DECK run).   The proposal is to add an optional argument like --case-family to create_newcase.  That value would be recorded in env_run.xml under CASE_FAMILY.

So you would have "create_newcase --case picontolCESM3 --case-family DECK_CESM3  --compset ....."

I'm not married to "--case-family" as the name of this argument.  "--simulation-campaign" was also suggested.



Discussion:
Yes you could add a common string to all the case names but that doesn't make it easier to parse in xml and our case names are already getting long.
@rljacob , this looks pretty easy. Should I assign to @WesCoomber ? I assume you don't want to be the one writing the code.
Yes go ahead.
Maybe --case-group would be a better name for this option.
Ideally, the valid argument list should be maintained along with the code. Allowing free-form text would still pose some of the issues we are trying to fix.
There are already rules for "case" and "case-group" can just follow those.
Oh wait you want a finite list of specific possible values for "case-group"?   I was referring to what characters are allowed in the string.
Thinking out loud:

* Defined set of choices would prevent against typos and too many arbitrary (non-official) groups which will hinder tracking official simulation campaigns.
* However, letting folks enter free-form text provides flexibility. But it shifts the quality control burden to PACE etc. to aggregate important campaigns.
There are all kinds of ways people might want to group cases so I don't think we can have a list in the source that you have to edit with a PR to add more options.   They way to make sure people doing simulation campaigns don't screw up is have double and triple checks on their case dir.
On developers telecon, we agreed this was worth doing.

@WesCoomber please make implementing this your top priority.  We need it by end of this week.   Lets use --case-group as the option name.

Resolving patch:
diff --git a/scripts/lib/CIME/case/case.py b/scripts/lib/CIME/case/case.py
--- a/scripts/lib/CIME/case/case.py
+++ b/scripts/lib/CIME/case/case.py
@@ -923,7 +923,7 @@ def configure(self, compset_name, grid_name, machine_name=None,
                   walltime=None, queue=None, output_root=None,
                   run_unsupported=False, answer=None,
                   input_dir=None, driver=None, workflowid="default",
-                  non_local=False, extra_machines_dir=None):
+                  non_local=False, extra_machines_dir=None, case_group=None):
 
         expect(check_name(compset_name, additional_chars='.'), "Invalid compset name {}".format(compset_name))
 
@@ -1101,6 +1101,9 @@ def configure(self, compset_name, grid_name, machine_name=None,
         if self.get_value("RUN_TYPE") == 'hybrid':
             self.set_value("GET_REFCASE", True)
 
+        if case_group:
+            self.set_value("CASE_GROUP", case_group)
+
         # Turn on short term archiving as cesm default setting
         model = get_model()
         self.set_model_version(model)
@@ -1635,7 +1638,7 @@ def create(self, casename, srcroot, compset_name, grid_name,
                walltime=None, queue=None, output_root=None,
                run_unsupported=False, answer=None,
                input_dir=None, driver=None, workflowid="default", non_local=False,
-               extra_machines_dir=None):
+               extra_machines_dir=None, case_group=None):
         try:
             # Set values for env_case.xml
             self.set_lookup_value("CASE", os.path.basename(casename))
@@ -1663,7 +1666,7 @@ def create(self, casename, srcroot, compset_name, grid_name,
                            run_unsupported=run_unsupported, answer=answer,
                            input_dir=input_dir, driver=driver,
                            workflowid=workflowid, non_local=non_local,
-                           extra_machines_dir=extra_machines_dir)
+                           extra_machines_dir=extra_machines_dir, case_group=case_group)
 
             self.create_caseroot()
 


Test patch: