Skip to content

Commit 9d408e5

Browse files
committed
Add moving window in iter_on, prepare tag 3.6.1
1 parent 3359eda commit 9d408e5

File tree

4 files changed

+60
-39
lines changed

4 files changed

+60
-39
lines changed

CHANGELOG.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,25 @@ and this project adheres to `Semantic Versioning <https://semver.org/spec/v2.0.0
1111
Changed
1212
^^^^^^^
1313

14+
Fixed
15+
^^^^^
16+
17+
Added
18+
^^^^^
19+
20+
21+
[3.6.1] - 2022-10-14
22+
--------------------
23+
Changed
24+
^^^^^^^
25+
1426
- Rewrite particle candidate to be easily parallelize
1527

1628
Fixed
1729
^^^^^
1830

1931
- Check strictly increasing coordinates for RegularGridDataset.
32+
- Grid mask is check to replace mask monovalue by 2D mask with fixed value
2033

2134
Added
2235
^^^^^

src/py_eddy_tracker/observations/network.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,11 +284,11 @@ def longer_than(self, nb_day_min=-1, nb_day_max=-1):
284284
nb_day_max = 1000000000000
285285
mask = zeros(self.shape, dtype="bool")
286286
t = self.time
287-
for i, b0, b1 in self.iter_on(self.track):
287+
for i, _, _ in self.iter_on(self.track):
288288
nb = i.stop - i.start
289289
if nb == 0:
290290
continue
291-
if nb_day_min <= ptp(t[i]) <= nb_day_max:
291+
if nb_day_min <= (ptp(t[i]) + 1) <= nb_day_max:
292292
mask[i] = True
293293
return self.extract_with_mask(mask)
294294

src/py_eddy_tracker/observations/observation.py

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
local_to_coordinates,
5959
reverse_index,
6060
wrap_longitude,
61+
window_index,
6162
)
6263
from ..poly import (
6364
bbox_intersection,
@@ -574,51 +575,58 @@ def __iter__(self):
574575
for obs in self.obs:
575576
yield obs
576577

577-
def iter_on(self, xname, bins=None):
578+
def iter_on(self, xname, window=None, bins=None):
578579
"""
579580
Yield observation group for each bin.
580581
581582
:param str,array xname:
583+
:param float,None window: if defined we use a moving window with value like half window
582584
:param array bins: bounds of each bin
583585
:yield array,float,float: index in self, lower bound, upper bound
584586
585587
.. minigallery:: py_eddy_tracker.EddiesObservations.iter_on
586588
"""
587589
x = self.parse_varname(xname)
588-
d = x[1:] - x[:-1]
589-
if bins is None:
590-
bins = arange(x.min(), x.max() + 2)
591-
elif not isinstance(bins, ndarray):
592-
bins = array(bins)
593-
nb_bins = len(bins) - 1
594-
595-
# Not monotonous
596-
if (d < 0).any():
597-
# If bins cover a small part of value
598-
test, translate, x = iter_mode_reduce(x, bins)
599-
# convert value in bins number
600-
i = numba_digitize(x, bins) - 1
601-
# Order by bins
602-
i_sort = i.argsort()
603-
# If in reduced mode we will translate i_sort in full array index
604-
i_sort_ = translate[i_sort] if test else i_sort
605-
# Bound for each bins in sorting view
606-
i0, i1, _ = build_index(i[i_sort])
607-
m = ~(i0 == i1)
608-
i0, i1 = i0[m], i1[m]
609-
for i0_, i1_ in zip(i0, i1):
610-
i_bins = i[i_sort[i0_]]
611-
if i_bins == -1 or i_bins == nb_bins:
612-
continue
613-
yield i_sort_[i0_:i1_], bins[i_bins], bins[i_bins + 1]
590+
if window is not None:
591+
x0 = arange(x.min(), x.max()) if bins is None else array(bins)
592+
i_ordered, first_index, last_index = window_index(x, x0, window)
593+
for x_, i0, i1 in zip(x0, first_index, last_index):
594+
yield i_ordered[i0: i1], x_ - window, x_ + window
614595
else:
615-
i = numba_digitize(x, bins) - 1
616-
i0, i1, _ = build_index(i)
617-
m = ~(i0 == i1)
618-
i0, i1 = i0[m], i1[m]
619-
for i0_, i1_ in zip(i0, i1):
620-
i_bins = i[i0_]
621-
yield slice(i0_, i1_), bins[i_bins], bins[i_bins + 1]
596+
d = x[1:] - x[:-1]
597+
if bins is None:
598+
bins = arange(x.min(), x.max() + 2)
599+
elif not isinstance(bins, ndarray):
600+
bins = array(bins)
601+
nb_bins = len(bins) - 1
602+
603+
# Not monotonous
604+
if (d < 0).any():
605+
# If bins cover a small part of value
606+
test, translate, x = iter_mode_reduce(x, bins)
607+
# convert value in bins number
608+
i = numba_digitize(x, bins) - 1
609+
# Order by bins
610+
i_sort = i.argsort()
611+
# If in reduced mode we will translate i_sort in full array index
612+
i_sort_ = translate[i_sort] if test else i_sort
613+
# Bound for each bins in sorting view
614+
i0, i1, _ = build_index(i[i_sort])
615+
m = ~(i0 == i1)
616+
i0, i1 = i0[m], i1[m]
617+
for i0_, i1_ in zip(i0, i1):
618+
i_bins = i[i_sort[i0_]]
619+
if i_bins == -1 or i_bins == nb_bins:
620+
continue
621+
yield i_sort_[i0_:i1_], bins[i_bins], bins[i_bins + 1]
622+
else:
623+
i = numba_digitize(x, bins) - 1
624+
i0, i1, _ = build_index(i)
625+
m = ~(i0 == i1)
626+
i0, i1 = i0[m], i1[m]
627+
for i0_, i1_ in zip(i0, i1):
628+
i_bins = i[i0_]
629+
yield slice(i0_, i1_), bins[i_bins], bins[i_bins + 1]
622630

623631
def align_on(self, other, var_name="time", all_ref=False, **kwargs):
624632
"""
@@ -2420,6 +2428,9 @@ def create_particles(self, step, intern=True):
24202428
xname, yname = self.intern(intern)
24212429
return create_meshed_particles(self[xname], self[yname], step)
24222430

2431+
def empty_dataset(self):
2432+
return self.new_like(self, 0)
2433+
24232434

24242435
@njit(cache=True)
24252436
def grid_count_(grid, i, j):

src/py_eddy_tracker/observations/tracking.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,6 @@ def extract_with_length(self, bounds):
437437
raise Exception("One bound must be positive")
438438
return self.extract_with_mask(track_mask.repeat(self.nb_obs_by_track))
439439

440-
def empty_dataset(self):
441-
return self.new_like(self, 0)
442-
443440
def loess_filter(self, half_window, xfield, yfield, inplace=True):
444441
track = self.track
445442
x = self.obs[xfield]

0 commit comments

Comments
 (0)