Skip to content

Commit 20bdc6b

Browse files
committed
Migrate from_copernicusmarine to use from_sgrid_conventions
1 parent d6fc988 commit 20bdc6b

File tree

3 files changed

+26
-41
lines changed

3 files changed

+26
-41
lines changed

src/parcels/_core/fieldset.py

Lines changed: 18 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -220,46 +220,25 @@ def from_copernicusmarine(ds: xr.Dataset):
220220
ds["W"] -= ds[
221221
"W"
222222
] # Negate W to convert from up positive to down positive (as that's the direction of positive z)
223-
grid = XGrid(
224-
xgcm.Grid(
225-
ds,
226-
coords={
227-
"X": {
228-
"left": "lon",
229-
},
230-
"Y": {
231-
"left": "lat",
232-
},
233-
"Z": {
234-
"left": "depth",
235-
},
236-
"T": {
237-
"center": "time",
238-
},
239-
},
240-
autoparse_metadata=False,
241-
**_DEFAULT_XGCM_KWARGS,
242-
),
243-
mesh="spherical",
244-
)
245-
246-
fields = {}
247-
if "U" in ds.data_vars and "V" in ds.data_vars:
248-
fields["U"] = Field("U", ds["U"], grid, XLinear)
249-
fields["V"] = Field("V", ds["V"], grid, XLinear)
250-
251-
if "W" in ds.data_vars:
252-
fields["W"] = Field(
253-
"W", ds["W"], grid, XLinear
254-
) # TODO: Choose interpolator based on `location` SGRID attribute
255-
fields["UVW"] = VectorField("UVW", fields["U"], fields["V"], fields["W"])
256-
else:
257-
fields["UV"] = VectorField("UV", fields["U"], fields["V"])
258-
259-
for varname in set(ds.data_vars) - set(fields.keys()):
260-
fields[varname] = Field(varname, ds[varname], grid, XLinear)
261223

262-
return FieldSet(list(fields.values()))
224+
if "grid" in ds.cf.cf_roles:
225+
raise ValueError(
226+
"Dataset already has a 'grid' variable (according to cf_roles). Didn't expect there to be grid metadata on copernicusmarine datasets - please open an issue with more information about your dataset."
227+
)
228+
ds["grid"] = xr.DataArray(
229+
0,
230+
attrs=sgrid.Grid2DMetadata( # use dummy *_center dimensions - this is A grid data (all defined on nodes)
231+
cf_role="grid_topology",
232+
topology_dimension=2,
233+
node_dimensions=("lon", "lat"),
234+
face_dimensions=(
235+
sgrid.DimDimPadding("x_center", "lon", sgrid.Padding.LOW),
236+
sgrid.DimDimPadding("y_center", "lat", sgrid.Padding.LOW),
237+
),
238+
vertical_dimensions=(sgrid.DimDimPadding("z_center", "depth", sgrid.Padding.LOW),),
239+
).to_attrs(),
240+
)
241+
return FieldSet.from_sgrid_conventions(ds, mesh="spherical")
263242

264243
def from_fesom2(ds: ux.UxDataset):
265244
"""Create a FieldSet from a FESOM2 uxarray.UxDataset.

src/parcels/_core/utils/sgrid.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,13 @@ def parse_sgrid(ds: xr.Dataset):
378378
xgcm_coords = {}
379379
for dim_dim_padding, axis in zip(dimensions, "XYZ", strict=False):
380380
xgcm_position = SGRID_PADDING_TO_XGCM_POSITION[dim_dim_padding.padding]
381-
xgcm_coords[axis] = {"center": dim_dim_padding.dim1, xgcm_position: dim_dim_padding.dim2}
381+
382+
coords = {}
383+
for pos, dim in [("center", dim_dim_padding.dim1), (xgcm_position, dim_dim_padding.dim2)]:
384+
# only include dimensions in dataset (ignore dimensions in metadata that may not exist - e.g., due to `.isel`)
385+
if dim in ds.dims:
386+
coords[pos] = dim
387+
xgcm_coords[axis] = coords
382388

383389
return (ds, {"coords": xgcm_coords})
384390

tests/utils/test_sgrid.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ def test_parse_sgrid_2d(grid_metadata: sgrid.Grid2DMetadata):
188188
"""Test the ingestion of datasets in XGCM to ensure that it matches the SGRID metadata provided"""
189189
ds = dummy_sgrid_2d_ds(grid_metadata)
190190

191-
ds, xgcm_kwargs = sgrid.parse_sgrid(ds)
191+
_, xgcm_kwargs = sgrid.parse_sgrid(ds)
192192
grid = xgcm.Grid(ds, autoparse_metadata=False, **xgcm_kwargs)
193193

194194
for ddp, axis in zip(grid_metadata.face_dimensions, ["X", "Y"], strict=True):

0 commit comments

Comments
 (0)