Skip to content

Commit 7ce7bf1

Browse files
committed
Add nearest interp method
1 parent 8af2190 commit 7ce7bf1

File tree

5 files changed

+48
-9
lines changed

5 files changed

+48
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111
- Acces at dataset variable like attribute, and lifetime/age are available for all observations
1212
- Add **EddyInfos** application to get general information about eddies dataset
1313
- Add method to inspect contour rejection (which are not in eddies)
14+
- Grid interp could be "nearest" or "bilinear"
1415
### Changed
1516

1617
### Removed

src/py_eddy_tracker/dataset/grid.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1842,13 +1842,14 @@ def regrid(self, other, grid_name, new_name=None):
18421842
# self.variables_description[new_name]['infos'] = False
18431843
# self.variables_description[new_name]['kwargs']['dimensions'] = ...
18441844

1845-
def interp(self, grid_name, lons, lats):
1845+
def interp(self, grid_name, lons, lats, method="bilinear"):
18461846
"""
18471847
Compute z over lons, lats
18481848
18491849
:param str grid_name: Grid to be interpolated
18501850
:param lons: new x
18511851
:param lats: new y
1852+
:param str method: Could be 'bilinear' or 'nearest'
18521853
18531854
:return: new z
18541855
"""
@@ -1857,7 +1858,9 @@ def interp(self, grid_name, lons, lats):
18571858
m = g.mask
18581859
else:
18591860
m = ones(g.shape) if g.mask else zeros(g.shape)
1860-
return interp2d_geo(self.x_c, self.y_c, g, m, lons, lats)
1861+
return interp2d_geo(
1862+
self.x_c, self.y_c, g, m, lons, lats, nearest=method == "nearest"
1863+
)
18611864

18621865

18631866
@njit(cache=True, fastmath=True)

src/py_eddy_tracker/generic.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ def cumsum_by_track(field, track):
177177

178178

179179
@njit(cache=True, fastmath=True)
180-
def interp2d_geo(x_g, y_g, z_g, m_g, x, y):
180+
def interp2d_geo(x_g, y_g, z_g, m_g, x, y, nearest=False):
181181
"""
182182
For geographic grid, test of cicularity.
183183
@@ -187,6 +187,7 @@ def interp2d_geo(x_g, y_g, z_g, m_g, x, y):
187187
:param array m_g: Boolean grid, True if value is masked
188188
:param array x: coordinate where interpolate z
189189
:param array y: coordinate where interpolate z
190+
:param bool nearest: if true we will take nearest pixel
190191
:return: z interpolated
191192
:rtype: array
192193
"""
@@ -223,9 +224,21 @@ def interp2d_geo(x_g, y_g, z_g, m_g, x, y):
223224
if m_g[i0, j0] or m_g[i0, j1] or m_g[i1, j0] or m_g[i1, j1]:
224225
z[i] = nan
225226
else:
226-
z[i] = (z00 * (1 - xd) + (z10 * xd)) * (1 - yd) + (
227-
z01 * (1 - xd) + z11 * xd
228-
) * yd
227+
if nearest:
228+
if xd <= 0.5:
229+
if yd <= 0.5:
230+
z[i] = z00
231+
else:
232+
z[i] = z01
233+
else:
234+
if yd <= 0.5:
235+
z[i] = z10
236+
else:
237+
z[i] = z11
238+
else:
239+
z[i] = (z00 * (1 - xd) + (z10 * xd)) * (1 - yd) + (
240+
z01 * (1 - xd) + z11 * xd
241+
) * yd
229242
return z
230243

231244

src/py_eddy_tracker/observations/observation.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1934,12 +1934,12 @@ def interp_grid(
19341934
:param grid_object: Handler of grid to interp
19351935
:type grid_object: py_eddy_tracker.dataset.grid.RegularGridDataset
19361936
:param str varname: Name of variable to use
1937-
:param str method: 'center', 'mean', 'max', 'min'
1937+
:param str method: 'center', 'mean', 'max', 'min', 'nearest'
19381938
:param str dtype: if None we use var dtype
19391939
:param bool intern: Use extern or intern contour
19401940
"""
1941-
if method == "center":
1942-
return grid_object.interp(varname, self.longitude, self.latitude)
1941+
if method in ("center", "nearest"):
1942+
return grid_object.interp(varname, self.longitude, self.latitude, method)
19431943
elif method in ("min", "max", "mean", "count"):
19441944
x0 = grid_object.x_bounds[0]
19451945
x_name, y_name = self.intern(False if intern is None else intern)

tests/test_grid.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from matplotlib.path import Path
2+
from numpy import array, ma
23
from pytest import approx
34

45
from py_eddy_tracker.data import get_path
@@ -53,3 +54,24 @@ def test_bounds():
5354
x0, x1, y0, y1 = G.bounds
5455
assert x0 == -1 / 120.0 and x1 == 360 - 1 / 120
5556
assert y0 == approx(-90 - 1 / 120.0) and y1 == approx(90 - 1 / 120)
57+
58+
59+
def test_interp():
60+
# Fake grid
61+
g = RegularGridDataset.with_array(
62+
coordinates=("x", "y"),
63+
datas=dict(
64+
z=ma.array(((0, 1), (2, 3)), dtype="f4"),
65+
x=array((0, 20)),
66+
y=array((0, 10)),
67+
),
68+
centered=True,
69+
)
70+
x0, y0 = array((10,)), array((5,))
71+
x1, y1 = array((15,)), array((5,))
72+
# Interp nearest
73+
assert g.interp("z", x0, y0, method="nearest") == 0
74+
assert g.interp("z", x1, y1, method="nearest") == 2
75+
# Interp bilinear
76+
assert g.interp("z", x0, y0) == 1.5
77+
assert g.interp("z", x1, y1) == 2

0 commit comments

Comments
 (0)