Skip to content

Commit 95eed0a

Browse files
Update NEMO ingestion code (#2549)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 57e90fe commit 95eed0a

File tree

2 files changed

+39
-19
lines changed

2 files changed

+39
-19
lines changed

src/parcels/convert.py

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from __future__ import annotations
1414

1515
import typing
16+
import warnings
1617
from typing import cast
1718

1819
import numpy as np
@@ -24,16 +25,32 @@
2425
if typing.TYPE_CHECKING:
2526
import uxarray as ux
2627

27-
_NEMO_EXPECTED_COORDS = ["glamf", "gphif"]
28-
29-
_NEMO_DIMENSION_COORD_NAMES = ["x", "y", "time", "x", "x_center", "y", "y_center", "depth", "glamf", "gphif"]
28+
_NEMO_EXPECTED_COORDS = [
29+
"glamf",
30+
"gphif",
31+
] # "depthw" # TODO: Depthw needs to be available if the data has a depth dim. Refactor the whole convert module, this can surely all be handled better.
32+
33+
_NEMO_DIMENSION_COORD_NAMES = [
34+
"x",
35+
"y",
36+
"time",
37+
"x",
38+
"x_center",
39+
"y",
40+
"y_center",
41+
"depth",
42+
"depth_center",
43+
"glamf",
44+
"gphif",
45+
]
3046

3147
_NEMO_AXIS_VARNAMES = {
3248
"x": "X",
3349
"x_center": "X",
3450
"y": "Y",
3551
"y_center": "Y",
3652
"depth": "Z",
53+
"depth_center": "Z",
3754
"time": "T",
3855
}
3956

@@ -95,16 +112,18 @@ def _pick_expected_coords(coords: xr.Dataset, expected_coord_names: list[str]) -
95112

96113

97114
def _maybe_bring_other_depths_to_depth(ds):
98-
if "depth" in ds.coords:
99-
for var in ds.data_vars:
100-
for old_depth in ["depthu", "depthv", "deptht", "depthw"]:
101-
if old_depth in ds[var].dims:
102-
ds[var] = ds[var].assign_coords(**{old_depth: ds["depth"].values}).rename({old_depth: "depth"})
103-
return ds
104-
115+
for var in ds.data_vars:
116+
for old_depth, target in [
117+
("depthu", "depth_center"),
118+
("depthv", "depth_center"),
119+
("deptht", "depth_center"),
120+
("depthw", "depth"),
121+
]:
122+
if old_depth in ds[var].dims:
123+
ds[var] = ds[var].rename({old_depth: target})
105124

106-
def _maybe_create_depth_dim(ds):
107125
if "depth" not in ds.dims:
126+
warnings.warn("No depth dimension found in your dataset. Assuming no depth (i.e., surface data).", stacklevel=1)
108127
ds = ds.expand_dims({"depth": [0]})
109128
ds["depth"] = xr.DataArray([0], dims=["depth"])
110129
return ds
@@ -286,17 +305,18 @@ def nemo_to_sgrid(*, fields: dict[str, xr.Dataset | xr.DataArray], coords: xr.Da
286305
if coords.sizes["time"] != 1:
287306
raise ValueError("Time dimension in coords must be length 1 (i.e., no time-varying grid).")
288307
coords = coords.isel(time=0).drop("time")
289-
if len(coords.dims) == 3:
308+
309+
if (
310+
len(coords.dims) == 3
311+
): #! This should really be looking at the dimensionality of the lons and lats arrays. Currently having 2D lon lat and 1D depth triggers this `if` clause
290312
for dim, len_ in coords.sizes.items():
291313
if len_ == 1:
292314
# TODO: log statement about selecting along z dim of 1
293315
coords = coords.isel({dim: 0})
294-
if len(coords.dims) != 2:
295-
raise ValueError("Expected coordsinates to be 2 dimensional")
296-
316+
# if len(coords.dims) != 2: #! This should really be looking at the dimensionality of the lons and lats arrays. Currently having 2D lon lat and 1D depth triggers this `if` clause
317+
# raise ValueError("Expected coordinates to be 2 dimensional")
297318
ds = xr.merge(list(fields.values()) + [coords])
298319
ds = _maybe_rename_variables(ds, _NEMO_VARNAMES_MAPPING)
299-
ds = _maybe_create_depth_dim(ds)
300320
ds = _maybe_bring_other_depths_to_depth(ds)
301321
ds = _drop_unused_dimensions_and_coords(ds, _NEMO_DIMENSION_COORD_NAMES)
302322
ds = _assign_dims_as_coords(ds, _NEMO_DIMENSION_COORD_NAMES)
@@ -332,7 +352,7 @@ def nemo_to_sgrid(*, fields: dict[str, xr.Dataset | xr.DataArray], coords: xr.Da
332352
sgrid.FaceNodePadding("x_center", "x", sgrid.Padding.LOW),
333353
sgrid.FaceNodePadding("y_center", "y", sgrid.Padding.LOW),
334354
),
335-
vertical_dimensions=(sgrid.FaceNodePadding("z_center", "depth", sgrid.Padding.HIGH),),
355+
vertical_dimensions=(sgrid.FaceNodePadding("depth_center", "depth", sgrid.Padding.HIGH),),
336356
).to_attrs(),
337357
)
338358

@@ -525,7 +545,7 @@ def copernicusmarine_to_sgrid(
525545
sgrid.FaceNodePadding("x_center", "lon", sgrid.Padding.LOW),
526546
sgrid.FaceNodePadding("y_center", "lat", sgrid.Padding.LOW),
527547
),
528-
vertical_dimensions=(sgrid.FaceNodePadding("z_center", "depth", sgrid.Padding.LOW),),
548+
vertical_dimensions=(sgrid.FaceNodePadding("depth_center", "depth", sgrid.Padding.LOW),),
529549
).to_attrs(),
530550
)
531551

tests/test_convert.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def test_nemo_to_sgrid():
2323
"node_dimensions": "x y",
2424
"face_dimensions": "x_center:x (padding:low) y_center:y (padding:low)",
2525
"node_coordinates": "lon lat",
26-
"vertical_dimensions": "z_center:depth (padding:high)",
26+
"vertical_dimensions": "depth_center:depth (padding:high)",
2727
}
2828

2929
meta = sgrid.parse_grid_attrs(ds["grid"].attrs)

0 commit comments

Comments
 (0)