Skip to content

Commit

Permalink
Merge pull request #4148 from jedwards4b/jedwards/refactor_compset_na…
Browse files Browse the repository at this point in the history
…ming

Introduce a new compset naming convention which maintains backward compatibility and allows position independence.
This convention uses a three character lower case prefix to indicate the component class (tim, atm, lnd, ice, ...) followed by a : . Some examples are:

    tim:2000_atm:DATM%NYF_ocn:DOCN%SOMAQP
    tim:1850_lnd:DLND%SCPL
    atm:DATM%NYF_ice:DICE%SSMI_ocn:DOCN%DOM_rof:DROF%NYF_tim%2000

Test suite: scripts_regression_tests, cesm prealpha tests
Test baseline:
Test namelist changes:
Test status: bit for bit

Fixes #4125

User interface changes?:
  • Loading branch information
jedwards4b authored Jan 7, 2022
2 parents bc80870 + c52ffbe commit 7e63749
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/srt_nuopc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
NETCDF_C_PATH: /usr
NETCDF_FORTRAN_PATH: ${HOME}/netcdf-fortran
PNETCDF_PATH: ${HOME}/pnetcdf
ESMF_VERSION: ESMF_8_2_0_beta_snapshot_14
ESMF_VERSION: ESMF_8_3_0_beta_snapshot_05
CIME_MODEL: cesm

# Steps represent a sequence of tasks that will be executed as part of the job
Expand Down
7 changes: 6 additions & 1 deletion scripts/lib/CIME/XML/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ def _get_description_v3(self, compsetname, comp_class):
parts = opt_parts.pop(0).split("%")
reqset = set(parts)
fullset = set(parts + opt_parts)

match, complist = self._get_description_match(
compsetname, reqset, fullset, modifier_mode
)
Expand Down Expand Up @@ -258,14 +259,18 @@ def _get_description_match(self, compsetname, reqset, fullset, modifier_mode):
(False, None)
>>> obj._get_description_match("1850_CAM50%WCCM_Barn",set(["CAM50", "WCCM"]), set(["CAM50","WCCM","RCO2"]), "+")
(True, ['CAM50', 'WCCM'])
>>> obj._get_description_match("scn:1850_atm:CAM50%WCCM_Barn",set(["CAM50", "WCCM"]), set(["CAM50","WCCM","RCO2"]), "+")
(True, ['CAM50', 'WCCM'])
"""
match = False
comparts = compsetname.split("_")
matchcomplist = None

for comp in comparts:
if ":" in comp:
comp = comp.split(":")[1]
complist = comp.split("%")
cset = set(complist)

if cset == reqset or (cset > reqset and cset <= fullset):
if modifier_mode == "1":
expect(
Expand Down
32 changes: 29 additions & 3 deletions scripts/lib/CIME/case/case.py
Original file line number Diff line number Diff line change
Expand Up @@ -738,6 +738,10 @@ def _valid_compset_impl(self, compset_name, compset_alias, comp_classes, comp_ha
>>> caseroot = os.path.join(workdir, 'caseroot') # use non-existent caseroot to avoid error about not being a valid case directory in Case __init__ method
>>> Case(caseroot, read_only=False)._valid_compset_impl('2000_DATM%NYF_SLND_DICE%SSMI_DOCN%DOM_DROF%NYF_SGLC_SWAV', None, ['CPL', 'ATM', 'LND', 'ICE', 'OCN', 'ROF', 'GLC', 'WAV', 'ESP'], {'datm':1,'satm':1,'dlnd':2,'slnd':2,'dice':3,'sice':3,'docn':4,'socn':4,'drof':5,'srof':5,'sglc':6,'swav':7,'ww3':7,'sesp':8})
('2000_DATM%NYF_SLND_DICE%SSMI_DOCN%DOM_DROF%NYF_SGLC_SWAV_SESP', ['2000', 'DATM%NYF', 'SLND', 'DICE%SSMI', 'DOCN%DOM', 'DROF%NYF', 'SGLC', 'SWAV', 'SESP'])
>>> Case(caseroot, read_only=False)._valid_compset_impl('2000_DATM%NYF_SLND_DICE%SSMI_DOCN%DOM_DROF%NYF_SGLC_SWAV', None, ['CPL', 'ATM', 'LND', 'ICE', 'OCN', 'ROF', 'GLC', 'WAV', 'ESP'], {'datm':1,'satm':1,'dlnd':2,'slnd':2,'dice':3,'sice':3,'docn':4,'socn':4,'drof':5,'srof':5,'sglc':6,'swav':7,'ww3':7,'sesp':8})
('2000_DATM%NYF_SLND_DICE%SSMI_DOCN%DOM_DROF%NYF_SGLC_SWAV_SESP', ['2000', 'DATM%NYF', 'SLND', 'DICE%SSMI', 'DOCN%DOM', 'DROF%NYF', 'SGLC', 'SWAV', 'SESP'])
>>> Case(caseroot, read_only=False)._valid_compset_impl('atm:DATM%NYF_rof:DROF%NYF_scn:2000_ice:DICE%SSMI_ocn:DOCN%DOM', None, ['CPL', 'ATM', 'LND', 'ICE', 'OCN', 'ROF', 'GLC', 'WAV', 'ESP'], {'datm':1,'satm':1,'dlnd':2,'slnd':2,'dice':3,'sice':3,'docn':4,'socn':4,'drof':5,'srof':5,'sglc':6,'swav':7,'ww3':7,'sesp':8})
('2000_DATM%NYF_SLND_DICE%SSMI_DOCN%DOM_DROF%NYF_SGLC_SWAV_SESP', ['2000', 'DATM%NYF', 'SLND', 'DICE%SSMI', 'DOCN%DOM', 'DROF%NYF', 'SGLC', 'SWAV', 'SESP'])
>>> Case(caseroot, read_only=False)._valid_compset_impl('2000_DATM%NYF_DICE%SSMI_DOCN%DOM_DROF%NYF', None, ['CPL', 'ATM', 'LND', 'ICE', 'OCN', 'ROF', 'GLC', 'WAV', 'ESP'], {'datm':1,'satm':1,'dlnd':2,'slnd':2,'dice':3,'sice':3,'docn':4,'socn':4,'drof':5,'srof':5,'sglc':6,'swav':7,'ww3':7,'sesp':8})
('2000_DATM%NYF_SLND_DICE%SSMI_DOCN%DOM_DROF%NYF_SGLC_SWAV_SESP', ['2000', 'DATM%NYF', 'SLND', 'DICE%SSMI', 'DOCN%DOM', 'DROF%NYF', 'SGLC', 'SWAV', 'SESP'])
>>> Case(caseroot, read_only=False)._valid_compset_impl('2000_DICE%SSMI_DOCN%DOM_DATM%NYF_DROF%NYF', None, ['CPL', 'ATM', 'LND', 'ICE', 'OCN', 'ROF', 'GLC', 'WAV', 'ESP'], {'datm':1,'satm':1,'dlnd':2,'slnd':2,'dice':3,'sice':3,'docn':4,'socn':4,'drof':5,'srof':5,'sglc':6,'swav':7,'ww3':7,'sesp':8})
Expand All @@ -759,16 +763,32 @@ def _valid_compset_impl(self, compset_name, compset_alias, comp_classes, comp_ha
# Find the models declared in the compset
model_set = [None] * len(comp_classes)
components = compset_name.split("_")
model_set[0] = components[0]
noncomps = []
allstubs = True
colonformat = ":" in compset_name
if colonformat:
# make sure that scn: is component[0] as expected
for i in range(1, len(components)):
if components[i].startswith("scn:"):
tmp = components[0]
components[0] = components[i]
components[i] = tmp
break

model_set[0] = components[0][4:]
else:
model_set[0] = components[0]

for model in components[1:]:
match = Case.__mod_match_re__.match(model.lower())
expect(match is not None, "No model match for {}".format(model))
mod_match = match.group(1)
# Check for noncomponent appends (BGC & TEST)
if mod_match in ("bgc", "test"):
noncomps.append(model)
elif ":" in mod_match:
comp_ind = comp_hash[mod_match[4:]]
model_set[comp_ind] = model
else:
expect(mod_match in comp_hash, "Unknown model type, {}".format(model))
comp_ind = comp_hash[mod_match]
Expand All @@ -781,7 +801,10 @@ def _valid_compset_impl(self, compset_name, compset_alias, comp_classes, comp_ha
stub = "S" + comp_class
logger.info("Automatically adding {} to compset".format(stub))
model_set[comp_ind] = stub
elif model_set[comp_ind][0] != "S":
elif ":" in model_set[comp_ind]:
model_set[comp_ind] = model_set[comp_ind][4:]

if model_set[comp_ind][0] != "S":
allstubs = False

expect(
Expand All @@ -794,7 +817,6 @@ def _valid_compset_impl(self, compset_name, compset_alias, comp_classes, comp_ha
compsetname = "_".join(model_set)
for noncomp in noncomps:
compsetname = compsetname + "_" + noncomp

return compsetname, model_set

# RE to match component type name without optional piece (stuff after %).
Expand Down Expand Up @@ -894,6 +916,8 @@ def get_compset_components(self):
# the first element is always the date operator - skip it
elements = compset.split("_")[1:] # pylint: disable=maybe-no-member
for element in elements:
if ":" in element:
element = element[4:]
# ignore the possible BGC or TEST modifier
if element.startswith("BGC%") or element.startswith("TEST"):
continue
Expand Down Expand Up @@ -985,6 +1009,8 @@ def _get_component_config_data(self, files):
for i in range(1, len(self._component_classes)):
comp_class = self._component_classes[i]
comp_name = self._components[i - 1]
if ":" in comp_name:
comp_name = comp_name[4:]
root_dir_node_name = "COMP_ROOT_DIR_" + comp_class
node_name = "CONFIG_" + comp_class + "_FILE"
compatt = {"component": comp_name}
Expand Down

0 comments on commit 7e63749

Please sign in to comment.