Skip to content

Commit 4e2f815

Browse files
committed
Remove FieldSet.from_nemo
Update tests
1 parent 882a640 commit 4e2f815

File tree

3 files changed

+42
-48
lines changed

3 files changed

+42
-48
lines changed

src/parcels/_core/fieldset.py

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import xarray as xr
1111
import xgcm
1212

13-
from parcels import convert
1413
from parcels._core.converters import Geographic, GeographicPolar
1514
from parcels._core.field import Field, VectorField
1615
from parcels._core.utils import sgrid
@@ -248,31 +247,6 @@ def from_copernicusmarine(ds: xr.Dataset):
248247
)
249248
return FieldSet.from_sgrid_conventions(ds, mesh="spherical")
250249

251-
def from_nemo(ds: xr.Dataset):
252-
"""Create a FieldSet from a xarray.Dataset from NEMO netcdf files.
253-
254-
Parameters
255-
----------
256-
ds : xarray.Dataset
257-
xarray.Dataset as obtained from a set of NEMO netcdf files.
258-
259-
Returns
260-
-------
261-
FieldSet
262-
FieldSet object containing the fields from the dataset that can be used for a Parcels simulation.
263-
264-
Notes
265-
-----
266-
The NEMO model (https://www.nemo-ocean.eu/) is used by a variety of oceanographic institutions around the world.
267-
Output from these models may differ subtly in terms of variable names and metadata conventions.
268-
This function attempts to standardize these differences to create a Parcels FieldSet.
269-
If you encounter issues with your specific NEMO dataset, please open an issue on the Parcels GitHub repository with details about your dataset.
270-
271-
"""
272-
ds = convert.nemo_to_sgrid(ds)
273-
fieldset = FieldSet.from_sgrid_conventions(ds)
274-
return fieldset
275-
276250
def from_fesom2(ds: ux.UxDataset):
277251
"""Create a FieldSet from a FESOM2 uxarray.UxDataset.
278252
@@ -571,7 +545,7 @@ def _get_mesh_type_from_sgrid_dataset(ds_sgrid: xr.Dataset) -> Mesh:
571545

572546
sgrid_metadata = sgrid.parse_grid_attrs(grid_da.attrs)
573547

574-
fpoint_x, fpoint_y = sgrid_metadata.node_dimensions
548+
fpoint_x, fpoint_y = sgrid_metadata.node_coordinates
575549

576550
if _is_coordinate_in_degrees(ds_sgrid[fpoint_x]) ^ _is_coordinate_in_degrees(ds_sgrid[fpoint_x]):
577551
msg = (
@@ -588,7 +562,7 @@ def _is_coordinate_in_degrees(da: xr.DataArray) -> bool:
588562
match da.attrs.get("units"):
589563
case None:
590564
raise ValueError(
591-
f"Coordinate {da.name} of your dataset has no 'units' attribute - we don't know what the spatial units are."
565+
f"Coordinate {da.name!r} of your dataset has no 'units' attribute - we don't know what the spatial units are."
592566
)
593567
case "degrees":
594568
return True

src/parcels/convert.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,37 @@ def _discover_U_and_V(ds: xr.Dataset, cf_standard_names_fallbacks) -> xr.Dataset
163163
return ds
164164

165165

166-
def nemo_to_sgrid(*, coords: xr.Dataset, **fields: dict[str, xr.Dataset]):
166+
def nemo_to_sgrid(*, coords: xr.Dataset, **fields: dict[str, xr.Dataset | xr.DataArray]):
167+
# TODO: Update docstring
168+
"""Create a FieldSet from a xarray.Dataset from NEMO netcdf files.
169+
170+
Parameters
171+
----------
172+
ds : xarray.Dataset
173+
xarray.Dataset as obtained from a set of NEMO netcdf files.
174+
175+
Returns
176+
-------
177+
xarray.Dataset
178+
Dataset object following SGRID conventions to be (optionally) modified and passed to a FieldSet constructor.
179+
180+
Notes
181+
-----
182+
The NEMO model (https://www.nemo-ocean.eu/) is used by a variety of oceanographic institutions around the world.
183+
Output from these models may differ subtly in terms of variable names and metadata conventions.
184+
This function attempts to standardize these differences to create a Parcels FieldSet.
185+
If you encounter issues with your specific NEMO dataset, please open an issue on the Parcels GitHub repository with details about your dataset.
186+
187+
"""
167188
fields = fields.copy()
168189
coords = coords[["gphif", "glamf"]]
169190

170191
for name, field_da in fields.items():
171192
if isinstance(field_da, xr.Dataset):
172193
field_da = field_da[name]
173194
# TODO: logging message, warn if multiple fields are in this dataset
195+
else:
196+
field_da = field_da.rename(name)
174197

175198
match name:
176199
case "U":
@@ -179,7 +202,7 @@ def nemo_to_sgrid(*, coords: xr.Dataset, **fields: dict[str, xr.Dataset]):
179202
field_da = field_da.rename({"x": "x_center"})
180203
case _:
181204
pass
182-
205+
field_da = field_da.reset_coords(drop=True)
183206
fields[name] = field_da
184207

185208
if "time" in coords.dims:

tests/test_advection.py

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -437,14 +437,13 @@ def UpdateP(particles, fieldset): # pragma: no cover
437437

438438
def test_nemo_curvilinear_fieldset():
439439
data_folder = parcels.download_example_dataset("NemoCurvilinear_data")
440-
ds_fields = xr.open_mfdataset(
441-
data_folder.glob("*.nc4"),
442-
data_vars="minimal",
443-
coords="minimal",
444-
compat="override",
445-
)
446-
ds_fields = ds_fields.isel(time=0, z_a=0, z=0, drop=True)
447-
fieldset = parcels.FieldSet.from_nemo(ds_fields)
440+
U = xr.open_mfdataset(data_folder.glob("*U.nc4"))
441+
V = xr.open_mfdataset(data_folder.glob("*V.nc4"))
442+
coords = xr.open_dataset(data_folder / "mesh_mask.nc4")
443+
444+
ds = parcels.convert.nemo_to_sgrid(U=U, V=V, coords=coords)
445+
446+
fieldset = parcels.FieldSet.from_sgrid_conventions(ds)
448447

449448
npart = 20
450449
lonp = 30 * np.ones(npart)
@@ -470,16 +469,14 @@ def test_nemo_curvilinear_fieldset():
470469
)
471470
def test_nemo_3D_curvilinear_fieldset(kernel):
472471
data_folder = parcels.download_example_dataset("NemoNorthSeaORCA025-N006_data")
473-
ds_fields = xr.open_mfdataset(
474-
data_folder.glob("ORCA*.nc"),
475-
data_vars="minimal",
476-
coords="minimal",
477-
compat="override",
478-
)
479-
ds_coords = xr.open_dataset(data_folder / "coordinates.nc", decode_times=False)
480-
ds_coords = ds_coords.isel(time=0, drop=True)
481-
ds = xr.merge([ds_fields, ds_coords[["glamf", "gphif"]]])
482-
fieldset = parcels.FieldSet.from_nemo(ds)
472+
U = xr.open_mfdataset(data_folder.glob("*U.nc"))
473+
V = xr.open_mfdataset(data_folder.glob("*V.nc"))
474+
W = xr.open_mfdataset(data_folder.glob("*W.nc"))
475+
coords = xr.open_dataset(data_folder / "coordinates.nc", decode_times=False)
476+
477+
ds = parcels.convert.nemo_to_sgrid(U=U["uo"], V=V["vo"], W=W["wo"], coords=coords)
478+
479+
fieldset = parcels.FieldSet.from_sgrid_conventions(ds)
483480

484481
npart = 10
485482
lons_initial = np.linspace(1.9, 3.4, npart)

0 commit comments

Comments
 (0)