diff --git a/MOM6 b/MOM6
index c37361e..8e5ae29 160000
--- a/MOM6
+++ b/MOM6
@@ -1 +1 @@
-Subproject commit c37361ed68c2367c364db1e4d8238aca4e0c6349
+Subproject commit 8e5ae29312df6867b9f301887f55b628d498140e
diff --git a/cime_config/testdefs/testlist_mom.xml b/cime_config/testdefs/testlist_mom.xml
index 22a7f80..2d3b54e 100644
--- a/cime_config/testdefs/testlist_mom.xml
+++ b/cime_config/testdefs/testlist_mom.xml
@@ -298,4 +298,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/param_templates/MOM_input.yaml b/param_templates/MOM_input.yaml
index 04b15f8..c170715 100644
--- a/param_templates/MOM_input.yaml
+++ b/param_templates/MOM_input.yaml
@@ -3940,6 +3940,13 @@ Global:
$OCN_GRID in ["tx2_3v2", "tx2_3v3"] and $TEST: = - ( - $NTASKS_OCN // 256)
$OCN_GRID == "tx2_0v1" and $TEST: = - ( - $NTASKS_OCN // 256)
$OCN_GRID == "tx0.25v1": = - ( - $NTASKS_OCN // 128)
+ MASKTABLE:
+ description: |
+ A text file to specify n_mask, layout and mask_list.
+ datatype: string
+ value:
+ $AUTO_MASKTABLE: = f'MOM_auto_mask_table{$INST_SUFFIX}'
+ else: MOM_mask_table
GEOM_FILE:
description: |
default = ocean_geometry.nc
diff --git a/param_templates/json/MOM_input.json b/param_templates/json/MOM_input.json
index fb2e128..524631c 100644
--- a/param_templates/json/MOM_input.json
+++ b/param_templates/json/MOM_input.json
@@ -3255,6 +3255,14 @@
"$OCN_GRID == \"tx0.25v1\"": "= - ( - $NTASKS_OCN // 128)"
}
},
+ "MASKTABLE": {
+ "description": "A text file to specify n_mask, layout and mask_list.\n",
+ "datatype": "string",
+ "value": {
+ "$AUTO_MASKTABLE": "= f'MOM_auto_mask_table{$INST_SUFFIX}'",
+ "else": "MOM_mask_table"
+ }
+ },
"GEOM_FILE": {
"description": "default = ocean_geometry.nc\nThe file into which to write the ocean geometry.\n",
"datatype": "string",
diff --git a/tests/check_buildnml.py b/tests/check_buildnml.py
new file mode 100644
index 0000000..ab8bd31
--- /dev/null
+++ b/tests/check_buildnml.py
@@ -0,0 +1,110 @@
+#!/usr/bin/env python
+
+"""
+Unit test for cime_config/buildnml and MOM parameter expansion.
+Verifies MASKTABLE expansion under single-instance and multi-instance modes with AUTO_MASKTABLE True/False.
+"""
+
+import os
+import sys
+
+# Add cime_config/MOM_RPS to path
+sys.path.append(os.path.join(os.path.dirname(__file__), "..", "cime_config", "MOM_RPS"))
+from FType_MOM_params import FType_MOM_params
+
+
+def get_param_val(mom_params, varname):
+ for module in mom_params._data:
+ if varname in mom_params._data[module]:
+ return mom_params._data[module][varname]["value"]
+ return None
+
+
+def test_masktable_expansion():
+ json_path = os.path.join(
+ os.path.dirname(__file__), "..", "param_templates", "json", "MOM_input.json"
+ )
+
+ # Provide default CIME environment mock values (booleans, floats, strings) to satisfy
+ # CIME.ParamGen formulas/guards across all MOM_input.json parameters and prevent
+ # Python eval() type errors (e.g., float / str or bool vs str comparisons).
+ default_env = {
+ "OCN_GRID": "tx2_3v2",
+ "TEST": False,
+ "NTASKS_OCN": 64,
+ "DIN_LOC_ROOT": "/tmp/inputdata",
+ "CASEROOT": "/tmp/caseroot",
+ "CASEBUILD": "/tmp/casebuild",
+ "CASE": "case",
+ "SRCROOT": "/tmp/srcroot",
+ "RUNDIR": "/tmp/rundir",
+ "COMP_ROOT_DIR_OCN": "/tmp/mom",
+ "RUN_TYPE": "startup",
+ "CONTINUE_RUN": False,
+ "GET_REFCASE": False,
+ "RUN_REFCASE": "refcase",
+ "RUN_REFDATE": "0001-01-01",
+ "RUN_REFTOD": "00000",
+ "CPL_I2O_PER_CAT": False,
+ "ICE_NCAT": 5,
+ "MARBL_DIAG_MODE": "none",
+ "MOM6_INFRA_API": "FMS2",
+ "MOM6_VERTICAL_GRID": "zstar_65L",
+ "COMP_ATM": "cam",
+ "COMP_ICE": "cice",
+ "COMP_WAVE": "ww3",
+ "RESTINT": 1.0,
+ "REST_OPTION": "nmonths",
+ "REST_N": 1,
+ "REST_FREQ": "monthly",
+ "STOP_OPTION": "nmonths",
+ "STOP_N": 1,
+ "STOP_FREQ": "monthly",
+ "ATM_CO2_OPT": "constant",
+ "ATM_ALT_CO2_OPT": "constant",
+ "ATM_CO2_CONST": 280.0,
+ "ATM_ALT_CO2_CONST": 280.0,
+ "USE_MARBL_TRACERS": False,
+ "NCPL_BASE_PERIOD": "day",
+ "OCN_NCPL": 24,
+ "DT": 3600.0,
+ }
+
+ def run_reduction(auto_masktable, inst_suffix):
+ mom_params = FType_MOM_params.from_json(json_path)
+ dyn_env = {
+ "AUTO_MASKTABLE": auto_masktable,
+ "INST_SUFFIX": inst_suffix,
+ }
+ mom_params.reduce(lambda var: dyn_env.get(var, default_env.get(var, "")))
+ return get_param_val(mom_params, "MASKTABLE")
+
+ # 1. Test Single-Instance, AUTO_MASKTABLE=True
+ val1 = run_reduction(auto_masktable=True, inst_suffix="")
+ print(f"Single-instance AUTO_MASKTABLE=True MASKTABLE: {val1}")
+ assert (
+ val1 == "MOM_auto_mask_table"
+ ), f"Expected 'MOM_auto_mask_table', got '{val1}'"
+
+ # 2. Test Multi-Instance, AUTO_MASKTABLE=True (_0001)
+ val2 = run_reduction(auto_masktable=True, inst_suffix="_0001")
+ print(f"Multi-instance _0001 AUTO_MASKTABLE=True MASKTABLE: {val2}")
+ assert (
+ val2 == "MOM_auto_mask_table_0001"
+ ), f"Expected 'MOM_auto_mask_table_0001', got '{val2}'"
+
+ # 3. Test Single-Instance, AUTO_MASKTABLE=False
+ val3 = run_reduction(auto_masktable=False, inst_suffix="")
+ print(f"Single-instance AUTO_MASKTABLE=False MASKTABLE: {val3}")
+ assert val3 == "MOM_mask_table", f"Expected 'MOM_mask_table', got '{val3}'"
+
+ # 4. Test Multi-Instance, AUTO_MASKTABLE=False (_0001)
+ val4 = run_reduction(auto_masktable=False, inst_suffix="_0001")
+ print(f"Multi-instance _0001 AUTO_MASKTABLE=False MASKTABLE: {val4}")
+ assert val4 == "MOM_mask_table", f"Expected 'MOM_mask_table', got '{val4}'"
+
+ print("ALL MASKTABLE TESTS PASSED")
+
+
+if __name__ == "__main__":
+ test_masktable_expansion()