Skip to content

Commit 8008790

Browse files
Merge pull request #2051 from OceanParcels/cleanup-vectorfield-and-uxgrid
Cleanup vectorfield and uxgrid
2 parents d6e5686 + 279211c commit 8008790

2 files changed

Lines changed: 52 additions & 29 deletions

File tree

parcels/field.py

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -309,10 +309,10 @@ def eval(self, time: datetime, z, y, x, particle=None, applyConversion=True):
309309
conversion to the result. Note that we defer to
310310
scipy.interpolate to perform spatial interpolation.
311311
"""
312-
if particle is None:
313-
_ei = None
314-
else:
315-
_ei = particle.ei[self.igrid]
312+
# if particle is None:
313+
_ei = None
314+
# else:
315+
# _ei = particle.ei[self.igrid]
316316

317317
try:
318318
tau, ti = _search_time_index(self, time)
@@ -386,6 +386,7 @@ def __init__(
386386
self.U = U
387387
self.V = V
388388
self.W = W
389+
self.grid = U.grid
389390

390391
if W is None:
391392
assert_same_time_interval((U, V))
@@ -430,41 +431,49 @@ def vector_interp_method(self, method: Callable):
430431
# and np.allclose(grid1.depth, grid2.depth)
431432
# and np.allclose(grid1.time, grid2.time)
432433
# )
433-
def _interpolate(self, time, z, y, x, ei):
434-
bcoords, _ei, ti = self._search_indices(time, z, y, x, ei=ei)
434+
def eval(self, time: datetime, z, y, x, particle=None, applyConversion=True):
435+
"""Interpolate field values in space and time.
435436
436-
if self._vector_interp_method is None:
437-
u = self.U.eval(time, z, y, x, _ei, applyConversion=False)
438-
v = self.V.eval(time, z, y, x, _ei, applyConversion=False)
439-
if "3D" in self.vector_type:
440-
w = self.W.eval(time, z, y, x, _ei, applyConversion=False)
441-
return (u, v, w)
442-
else:
443-
return (u, v, 0)
444-
else:
445-
(u, v, w) = self._vector_interp_method(ti, _ei, bcoords, time, z, y, x)
446-
return (u, v, w)
437+
We interpolate linearly in time and apply implicit unit
438+
conversion to the result. Note that we defer to
439+
scipy.interpolate to perform spatial interpolation.
440+
"""
441+
# if particle is None:
442+
_ei = None
443+
# else:
444+
# _ei = particle.ei[self.igrid]
447445

448-
def eval(self, time, z, y, x, ei=None, applyConversion=True):
449-
if ei is None:
450-
_ei = 0
451-
else:
452-
_ei = ei[self.igrid]
446+
try:
447+
tau, ti = _search_time_index(self.U, time)
448+
bcoords, _ei = self.grid.search(z, y, x, ei=_ei)
449+
if self._vector_interp_method is None:
450+
u = self.U._interp_method(self.U, ti, _ei, bcoords, tau, time, z, y, x)
451+
v = self.V._interp_method(self.V, ti, _ei, bcoords, tau, time, z, y, x)
452+
if "3D" in self.vector_type:
453+
w = self.W._interp_method(self.W, ti, _ei, bcoords, tau, time, z, y, x)
454+
else:
455+
(u, v, w) = self._vector_interp_method(self, ti, _ei, bcoords, time, z, y, x)
453456

454-
(u, v, w) = self._interpolate(time, z, y, x, _ei)
457+
# print(u,v)
458+
if applyConversion:
459+
u = self.U.units.to_target(u, z, y, x)
460+
v = self.V.units.to_target(v, z, y, x)
461+
if "3D" in self.vector_type:
462+
w = self.W.units.to_target(w, z, y, x) if self.W else 0.0
455463

456-
if applyConversion:
457-
u = self.U.units.to_target(u, z, y, x)
458-
v = self.V.units.to_target(v, z, y, x)
459464
if "3D" in self.vector_type:
460-
w = self.W.units.to_target(w, z, y, x)
465+
return (u, v, w)
466+
else:
467+
return (u, v)
461468

462-
return (u, v, w)
469+
except (FieldSamplingError, FieldOutOfBoundError, FieldOutOfBoundSurfaceError) as e:
470+
e.add_note(f"Error interpolating field '{self.name}'.")
471+
raise e
463472

464473
def __getitem__(self, key):
465474
try:
466475
if _isParticle(key):
467-
return self.eval(key.time, key.depth, key.lat, key.lon, key.ei)
476+
return self.eval(key.time, key.depth, key.lat, key.lon, key)
468477
else:
469478
return self.eval(*key)
470479
except tuple(AllParcelsErrorCodes.keys()) as error:

parcels/uxgrid.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,20 @@ def __init__(self, grid: ux.grid.Grid, z: ux.UxDataArray) -> UxGrid:
3535
raise ValueError("z must be a 1D array of vertical coordinates")
3636
self.z = z
3737

38+
@property
39+
def depth(self):
40+
"""
41+
Note
42+
----
43+
Included for compatibility with v3 codebase. May be removed in future.
44+
TODO v4: Evaluate
45+
"""
46+
try:
47+
_ = self.z.values
48+
except KeyError:
49+
return np.zeros(1)
50+
return self.z.values
51+
3852
def search(
3953
self, z: float, y: float, x: float, ei: int | None = None, search2D: bool = False
4054
) -> tuple[np.ndarray, int]:

0 commit comments

Comments
 (0)