From 0462c22e03d40c48f74705a7f9d4cbe4e2c366e8 Mon Sep 17 00:00:00 2001 From: Wyatt Sieminski Date: Fri, 23 Oct 2026 15:01:18 +0000 Subject: [PATCH 1/9] fixed _get_offsets_dictionary --- src/parcels/interpolators/_xinterpolators.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/parcels/interpolators/_xinterpolators.py b/src/parcels/interpolators/_xinterpolators.py index 390a655c5..0d9a7dc4e 100644 --- a/src/parcels/interpolators/_xinterpolators.py +++ b/src/parcels/interpolators/_xinterpolators.py @@ -2,6 +2,7 @@ from __future__ import annotations +from tkinter import Pack from typing import TYPE_CHECKING, Literal import numpy as np @@ -100,10 +101,10 @@ def _get_offsets_dictionary(grid: XGrid) -> dict[ptyping.CfAxisSpatial, Literal[ offsets = {} metadata = grid.sgrid_metadata for fnp, axis in zip(metadata.face_dimensions, ["X", "Y"], strict=False): - offsets[axis] = 1 if fnp.padding == sgrid.Padding.LOW else 0 + offsets[axis] = 1 if (fnp.padding == sgrid.Padding.LOW or fnp.padding == sgrid.Padding.BOTH) else 0 if metadata.vertical_dimensions is not None: fnp_z = metadata.vertical_dimensions[0] - offsets["Z"] = 1 if fnp_z.padding == sgrid.Padding.LOW else 0 + offsets["Z"] = 1 if (fnp_z.padding == sgrid.Padding.LOW or fnp_z.padding == sgrid.Padding.BOTH) else 0 else: offsets["Z"] = 0 return offsets From 12666c80666fecaabb5e8ed51e7391542b935371 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 23 Oct 2026 15:03:12 +0000 Subject: [PATCH 2/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/parcels/interpolators/_xinterpolators.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/parcels/interpolators/_xinterpolators.py b/src/parcels/interpolators/_xinterpolators.py index 0d9a7dc4e..abcc49ee8 100644 --- a/src/parcels/interpolators/_xinterpolators.py +++ b/src/parcels/interpolators/_xinterpolators.py @@ -2,7 +2,6 @@ from __future__ import annotations -from tkinter import Pack from typing import TYPE_CHECKING, Literal import numpy as np From 231e4661b00706e8681abece5cae8a8667c0fd9c Mon Sep 17 00:00:00 2001 From: Wyatt Sieminski Date: Fri, 23 Oct 2026 15:04:04 +0000 Subject: [PATCH 3/9] remove random pyright import --- src/parcels/interpolators/_xinterpolators.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/parcels/interpolators/_xinterpolators.py b/src/parcels/interpolators/_xinterpolators.py index 0d9a7dc4e..abcc49ee8 100644 --- a/src/parcels/interpolators/_xinterpolators.py +++ b/src/parcels/interpolators/_xinterpolators.py @@ -2,7 +2,6 @@ from __future__ import annotations -from tkinter import Pack from typing import TYPE_CHECKING, Literal import numpy as np From 490c9f82daf37ad866672c282bacf378058ce576 Mon Sep 17 00:00:00 2001 From: Wyatt Sieminski Date: Fri, 23 Oct 2026 15:39:18 +0000 Subject: [PATCH 4/9] Fix test_fesom2_square_delaunay_uniform_z_coordinate_eval() --- tests/test_uxarray_fieldset.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_uxarray_fieldset.py b/tests/test_uxarray_fieldset.py index ba9ecd74e..c851b02dc 100644 --- a/tests/test_uxarray_fieldset.py +++ b/tests/test_uxarray_fieldset.py @@ -16,6 +16,7 @@ from parcels._datasets.unstructured.generic import datasets as datasets_unstructured from parcels.interpolators import ( UxConstantFaceConstantZC, + UxLinearNodeConstantZC, UxLinearNodeLinearZF, ) from tests.utils import create_uxgrid_from_triangulation @@ -49,7 +50,7 @@ def test_fesom_fieldset(ds_fesom_channel, fieldset_fesom_channel): assert (fieldset_fesom_channel.V.data == ds_fesom_channel.V).all() -@pytest.mark.xfail(reason="#2674 - 'p' interpolator is not being selected properly") +# @pytest.mark.xfail(reason="#2674 - 'p' interpolator is not being selected properly") def test_fesom2_square_delaunay_uniform_z_coordinate_eval(): """ Test the evaluation of a fieldset with a FESOM2 square Delaunay grid and uniform z-coordinate. @@ -58,12 +59,12 @@ def test_fesom2_square_delaunay_uniform_z_coordinate_eval(): """ ds = datasets_unstructured["fesom2_square_delaunay_uniform_z_coordinate"] ds = convert.fesom_to_ugrid(ds) - fieldset = FieldSet.from_ugrid_conventions(ds) + fieldset = FieldSet.from_ugrid_conventions(ds, mesh="flat") assert isinstance(fieldset.U.interp_method, UxConstantFaceConstantZC) assert isinstance(fieldset.V.interp_method, UxConstantFaceConstantZC) assert isinstance(fieldset.W.interp_method, UxLinearNodeLinearZF) - assert isinstance(fieldset.p.interp_method, UxLinearNodeLinearZF) + assert isinstance(fieldset.p.interp_method, UxLinearNodeConstantZC) (u, v, w) = fieldset.UVW.eval(t=[0.0], z=[1.0], y=[30.0], x=[30.0]) assert np.allclose([u.item(), v.item(), w.item()], [1.0, 1.0, 0.0], rtol=1e-3, atol=1e-6) From 0d37c47ae59cc34cf6f8d963b2c745f6b113b222 Mon Sep 17 00:00:00 2001 From: Wyatt Sieminski Date: Fri, 23 Oct 2026 15:52:27 +0000 Subject: [PATCH 5/9] Remove commented out xfail ine --- tests/test_uxarray_fieldset.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_uxarray_fieldset.py b/tests/test_uxarray_fieldset.py index c851b02dc..1a1aa6909 100644 --- a/tests/test_uxarray_fieldset.py +++ b/tests/test_uxarray_fieldset.py @@ -50,7 +50,6 @@ def test_fesom_fieldset(ds_fesom_channel, fieldset_fesom_channel): assert (fieldset_fesom_channel.V.data == ds_fesom_channel.V).all() -# @pytest.mark.xfail(reason="#2674 - 'p' interpolator is not being selected properly") def test_fesom2_square_delaunay_uniform_z_coordinate_eval(): """ Test the evaluation of a fieldset with a FESOM2 square Delaunay grid and uniform z-coordinate. From f4e30d76df5077e41719c00eb05a1e8b185510a9 Mon Sep 17 00:00:00 2001 From: Wyatt Sieminski Date: Fri, 23 Oct 2026 15:55:01 +0000 Subject: [PATCH 6/9] Revert _uxinterpolators.py to main --- src/parcels/interpolators/_xinterpolators.py | 24 ++++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/parcels/interpolators/_xinterpolators.py b/src/parcels/interpolators/_xinterpolators.py index abcc49ee8..d7cf24961 100644 --- a/src/parcels/interpolators/_xinterpolators.py +++ b/src/parcels/interpolators/_xinterpolators.py @@ -100,10 +100,10 @@ def _get_offsets_dictionary(grid: XGrid) -> dict[ptyping.CfAxisSpatial, Literal[ offsets = {} metadata = grid.sgrid_metadata for fnp, axis in zip(metadata.face_dimensions, ["X", "Y"], strict=False): - offsets[axis] = 1 if (fnp.padding == sgrid.Padding.LOW or fnp.padding == sgrid.Padding.BOTH) else 0 + offsets[axis] = 1 if fnp.padding == sgrid.Padding.LOW else 0 if metadata.vertical_dimensions is not None: fnp_z = metadata.vertical_dimensions[0] - offsets["Z"] = 1 if (fnp_z.padding == sgrid.Padding.LOW or fnp_z.padding == sgrid.Padding.BOTH) else 0 + offsets["Z"] = 1 if fnp_z.padding == sgrid.Padding.LOW else 0 else: offsets["Z"] = 0 return offsets @@ -179,7 +179,7 @@ def interp( _xlinear = XLinear() u = _xlinear.interp(particle_positions, grid_positions, vectorfield.U) v = _xlinear.interp(particle_positions, grid_positions, vectorfield.V) - if vectorfield.grid._mesh.is_spherical(): + if vectorfield.grid.mesh.is_spherical(): u /= vectorfield.grid.deg2m * np.cos(np.deg2rad(particle_positions["y"])) v /= vectorfield.grid.deg2m @@ -227,21 +227,21 @@ def interp( px = np.array([grid.lon[yi, xi], grid.lon[yi, xi + 1], grid.lon[yi + 1, xi + 1], grid.lon[yi + 1, xi]]) py = np.array([grid.lat[yi, xi], grid.lat[yi, xi + 1], grid.lat[yi + 1, xi + 1], grid.lat[yi + 1, xi]]) - if grid._mesh.is_spherical(): + if grid.mesh.is_spherical(): px = ((px + 180.0) % 360.0) - 180.0 px[1:] = np.where(px[1:] - px[0] > 180, px[1:] - 360, px[1:]) px[1:] = np.where(-px[1:] + px[0] > 180, px[1:] + 360, px[1:]) c1 = i_u._geodetic_distance( - py[0], py[1], px[0], px[1], grid._mesh, np.einsum("ij,ji->i", i_u.phi2D_lin(0.0, xsi), py), grid.deg2m + py[0], py[1], px[0], px[1], grid.mesh, np.einsum("ij,ji->i", i_u.phi2D_lin(0.0, xsi), py), grid.deg2m ) c2 = i_u._geodetic_distance( - py[1], py[2], px[1], px[2], grid._mesh, np.einsum("ij,ji->i", i_u.phi2D_lin(eta, 1.0), py), grid.deg2m + py[1], py[2], px[1], px[2], grid.mesh, np.einsum("ij,ji->i", i_u.phi2D_lin(eta, 1.0), py), grid.deg2m ) c3 = i_u._geodetic_distance( - py[2], py[3], px[2], px[3], grid._mesh, np.einsum("ij,ji->i", i_u.phi2D_lin(1.0, xsi), py), grid.deg2m + py[2], py[3], px[2], px[3], grid.mesh, np.einsum("ij,ji->i", i_u.phi2D_lin(1.0, xsi), py), grid.deg2m ) c4 = i_u._geodetic_distance( - py[3], py[0], px[3], px[0], grid._mesh, np.einsum("ij,ji->i", i_u.phi2D_lin(eta, 0.0), py), grid.deg2m + py[3], py[0], px[3], px[0], grid.mesh, np.einsum("ij,ji->i", i_u.phi2D_lin(eta, 0.0), py), grid.deg2m ) npart = len(xsi) @@ -287,7 +287,7 @@ def _compute_corner_data(data, y_levels, x_levels, z_levels=None) -> np.ndarray: V1 = corner_data[1, :] * c3 Vvel = (1 - eta) * V0 + eta * V1 - if grid._mesh.is_spherical(): + if grid.mesh.is_spherical(): jac = i_u._compute_jacobian_determinant(py, px, eta, xsi) * grid.deg2m else: jac = i_u._compute_jacobian_determinant(py, px, eta, xsi) @@ -308,7 +308,7 @@ def _compute_corner_data(data, y_levels, x_levels, z_levels=None) -> np.ndarray: u = u.compute() v = v.compute() - if grid._mesh.is_spherical(): + if grid.mesh.is_spherical(): conversion = grid.deg2m * np.cos(np.deg2rad(particle_positions["y"])) u /= conversion v /= conversion @@ -435,7 +435,7 @@ def is_land(ti: int, zi: int, yi: int, xi: int): f_u[land] = f_u[land] * (1 - b * eta[land]) / (1 - eta[land]) u = u * f_u - if vectorfield.grid._mesh.is_spherical(): + if vectorfield.grid.mesh.is_spherical(): u /= 1852 * 60 * np.cos(np.deg2rad(particle_positions["y"])) f_v = np.ones_like(eta) @@ -452,7 +452,7 @@ def is_land(ti: int, zi: int, yi: int, xi: int): f_v[land] = f_v[land] * (1 - b * xsi[land]) / (1 - xsi[land]) v = v * f_v - if vectorfield.grid._mesh.is_spherical(): + if vectorfield.grid.mesh.is_spherical(): v /= 1852 * 60 if vectorfield.W: From 1954ce05024361de7cb8d5a0d878cf0ea8b983b7 Mon Sep 17 00:00:00 2001 From: Wyatt Sieminski Date: Fri, 23 Oct 2026 18:21:28 +0000 Subject: [PATCH 7/9] Change to use FlatMesh() --- tests/test_uxarray_fieldset.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_uxarray_fieldset.py b/tests/test_uxarray_fieldset.py index 1a1aa6909..c73ba81db 100644 --- a/tests/test_uxarray_fieldset.py +++ b/tests/test_uxarray_fieldset.py @@ -12,6 +12,7 @@ convert, ) from parcels._core.model import UnstructuredModelData +from parcels._core.basegrid import FlatMesh from parcels._datasets.unstructured.generated import sigma_coordinate_lattice_dataset from parcels._datasets.unstructured.generic import datasets as datasets_unstructured from parcels.interpolators import ( @@ -58,7 +59,7 @@ def test_fesom2_square_delaunay_uniform_z_coordinate_eval(): """ ds = datasets_unstructured["fesom2_square_delaunay_uniform_z_coordinate"] ds = convert.fesom_to_ugrid(ds) - fieldset = FieldSet.from_ugrid_conventions(ds, mesh="flat") + fieldset = FieldSet.from_ugrid_conventions(ds, mesh=FlatMesh()) assert isinstance(fieldset.U.interp_method, UxConstantFaceConstantZC) assert isinstance(fieldset.V.interp_method, UxConstantFaceConstantZC) From 394d1f29b0b981ef71a732624ea989378044ddf9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 23 Oct 2026 18:23:11 +0000 Subject: [PATCH 8/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/test_uxarray_fieldset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_uxarray_fieldset.py b/tests/test_uxarray_fieldset.py index 17b5575ec..d5a5d9ded 100644 --- a/tests/test_uxarray_fieldset.py +++ b/tests/test_uxarray_fieldset.py @@ -11,9 +11,9 @@ UxGrid, convert, ) +from parcels._core.basegrid import FlatMesh from parcels._core.mesh import FlatMesh, SphericalMesh from parcels._core.model import UnstructuredModelData -from parcels._core.basegrid import FlatMesh from parcels._datasets.unstructured.generated import sigma_coordinate_lattice_dataset from parcels._datasets.unstructured.generic import datasets as datasets_unstructured from parcels.interpolators import ( From f8794714906258e11b363d660c24d8f7aa80e033 Mon Sep 17 00:00:00 2001 From: Wyatt Sieminski Date: Fri, 23 Oct 2026 18:28:11 +0000 Subject: [PATCH 9/9] Remove double import of FlatMesh --- tests/test_uxarray_fieldset.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_uxarray_fieldset.py b/tests/test_uxarray_fieldset.py index d5a5d9ded..24fb170d3 100644 --- a/tests/test_uxarray_fieldset.py +++ b/tests/test_uxarray_fieldset.py @@ -11,7 +11,6 @@ UxGrid, convert, ) -from parcels._core.basegrid import FlatMesh from parcels._core.mesh import FlatMesh, SphericalMesh from parcels._core.model import UnstructuredModelData from parcels._datasets.unstructured.generated import sigma_coordinate_lattice_dataset