Skip to content

Commit a729628

Browse files
committed
Fix and restucture MOM supergrid logic for OM2 and OM3
1 parent 915f669 commit a729628

File tree

2 files changed

+244
-226
lines changed

2 files changed

+244
-226
lines changed

src/access_moppy/ocean.py

Lines changed: 41 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -35,32 +35,12 @@ def __init__(
3535
self.supergrid = None # To be defined in subclasses
3636
self.grid_info = None
3737
self.grid_type = None
38-
39-
def _get_coord_sets(self):
40-
"""A abstract method to get the coordinate sets for the grid type."""
41-
raise NotImplementedError("Subclasses must implement _get_coord_sets.")
38+
self.symmetric = None
39+
self.arakawa = None
4240

4341
def infer_grid_type(self):
44-
"""Infer the grid type (T, U, V, Q) based on present coordinates."""
45-
coord_sets = self._get_coord_sets()
46-
present_coords = set(self.ds.coords)
47-
# Find which grid type matches the present coordinates
48-
# handle "x" and "y" separately to allow for mixed grids
49-
grid_dict = {}
50-
for coord in present_coords:
51-
if coord.startswith("x") and coord.endswith("_ocean"):
52-
for grid, required in coord_sets.items():
53-
if coord in required:
54-
grid_dict["x"] = grid
55-
if coord.startswith("y") and coord.endswith("_ocean"):
56-
for grid, required in coord_sets.items():
57-
if coord in required:
58-
grid_dict["y"] = grid
59-
60-
if set(grid_dict.keys()) == {"x", "y"}:
61-
return grid_dict
62-
else:
63-
raise ValueError("Could not infer grid type from dataset coordinates.")
42+
"""A abstract method to infer the grid type and memory mode based on present coordinates."""
43+
raise NotImplementedError("Subclasses must implement infer_grid_type.")
6444

6545
def _get_dim_rename(self):
6646
"""A abstract method to get the dimension renaming mapping for the grid type."""
@@ -100,7 +80,7 @@ def select_and_process_variables(self):
10080
"time", "lev", "j", "i"
10181
)
10282

103-
self.grid_type = self.infer_grid_type()
83+
self.grid_type, self.symmetric = self.infer_grid_type()
10484
# Drop all other data variables except the CMOR variable
10585
self.ds = self.ds[[self.cmor_name]]
10686

@@ -118,7 +98,9 @@ def select_and_process_variables(self):
11898

11999
def update_attributes(self):
120100
grid_type = self.grid_type
121-
self.grid_info = self.supergrid.extract_grid(grid_type)
101+
arakawa = self.arakawa
102+
symmetric = self.symmetric
103+
self.grid_info = self.supergrid.extract_grid(grid_type, arakawa, symmetric)
122104

123105
self.ds = self.ds.assign_coords(
124106
{
@@ -201,22 +183,25 @@ def __init__(
201183
)
202184

203185
nominal_resolution = cmip6_vocab._get_nominal_resolution()
204-
# OM2 uses B-grid
205-
self.supergrid = Supergrid_bgrid(nominal_resolution)
186+
self.supergrid = Supergrid(nominal_resolution)
206187
self.grid_info = None
207188
self.grid_type = None
189+
self.symmetric = None # MOM5 does not have configurable memory modes
190+
self.arakawa = "B" # ACCESS-OM2 MOM5 uses B-grid
208191

209-
def _get_coord_sets(self):
210-
"""Get the coordinate sets for the grid type."""
211-
if self.vocab.source_id == "ACCESS-OM2":
212-
return {
192+
def infer_grid_type(self):
193+
"""Infer the grid type (T, U, V, Q) and memory mode based on present coordinates."""
194+
grid_types = {
213195
"T": {"xt_ocean", "yt_ocean"},
214196
"U": {"xu_ocean", "yu_ocean"},
215-
"V": {"xv_ocean", "yv_ocean"},
216-
"Q": {"xq_ocean", "yq_ocean"},
217197
}
218-
else:
219-
raise ValueError(f"Unsupported source_id: {self.vocab.source_id}")
198+
present_coords = set(self.ds.coords)
199+
200+
for type_, coords in grid_types.items():
201+
if coords.issubset(present_coords):
202+
return type_, None
203+
204+
raise ValueError("Could not infer grid type from dataset coordinates.")
220205

221206
def _get_dim_rename(self):
222207
"""Get the dimension renaming mapping for the grid type."""
@@ -226,10 +211,6 @@ def _get_dim_rename(self):
226211
"yt_ocean": "j",
227212
"xu_ocean": "i",
228213
"yu_ocean": "j",
229-
"xq_ocean": "i",
230-
"yq_ocean": "j",
231-
"xv_ocean": "i",
232-
"yv_ocean": "j",
233214
"st_ocean": "lev", # depth level
234215
}
235216
else:
@@ -258,22 +239,30 @@ def __init__(
258239
)
259240

260241
nominal_resolution = cmip6_vocab._get_nominal_resolution()
261-
# OM3 uses C-grid, call
262-
self.supergrid = Supergrid_cgrid(nominal_resolution)
242+
self.supergrid = Supergrid(nominal_resolution)
263243
self.grid_info = None
264244
self.grid_type = None
245+
self.symmetric = None
246+
self.arakawa = "C" # ACCESS-OM3 MOM6 uses C-grid
265247

266-
def _get_coord_sets(self):
267-
"""Get the coordinate sets for the grid type."""
268-
if self.vocab.source_id == "ACCESS-OM3":
269-
return {
248+
def infer_grid_type(self):
249+
"""Infer the grid type (T, U, V, Q) and memory mode based on present coordinates."""
250+
grid_types = {
270251
"T": {"xh", "yh"},
271-
"U": {"xu", "yu"},
272-
"V": {"xv", "yv"},
273-
"Q": {"xq", "yq"},
274-
}
275-
else:
276-
raise ValueError(f"Unsupported source_id: {self.vocab.source_id}")
252+
"U": {"xq", "yh"},
253+
"V": {"xh", "yq"},
254+
"C": {"xq", "yq"},
255+
}
256+
present_coords = set(self.ds.coords)
257+
258+
# TODO: Currently assume MOM6 always uses symmetric memory mode.
259+
# We may need to revisit this.
260+
symmetric=True
261+
for type_, coords in grid_types.items():
262+
if coords.issubset(present_coords):
263+
return type_, symmetric
264+
265+
raise ValueError("Could not infer grid type from dataset coordinates.")
277266

278267
def _get_dim_rename(self):
279268
"""Get the dimension renaming mapping for the grid type."""

0 commit comments

Comments
 (0)