Skip to content

Commit 893d7a9

Browse files
authored
Merge branch 'AntSimi:master' into master
2 parents af2aadb + 8fe5bf1 commit 893d7a9

File tree

4 files changed

+46
-12
lines changed

4 files changed

+46
-12
lines changed

.readthedocs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ python:
99
install:
1010
- method: pip
1111
path: .
12+
sphinx:
13+
configuration: doc/conf.py

src/py_eddy_tracker/appli/gui.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from matplotlib.animation import FuncAnimation
1212
from matplotlib.axes import Axes
1313
from matplotlib.collections import LineCollection
14-
from numpy import arange, where
14+
from numpy import arange, where, nan
1515

1616
from .. import EddyParser
1717
from ..gui import GUI
@@ -58,7 +58,10 @@ def setup(
5858
self.kw_label["fontweight"] = kwargs.pop("fontweight", "demibold")
5959
# To text each visible eddy
6060
if field_txt:
61-
self.field_txt = self.eddy[field_txt]
61+
if isinstance(field_txt,str):
62+
self.field_txt = self.eddy[field_txt]
63+
else :
64+
self.field_txt=field_txt
6265
if field_color:
6366
# To color each visible eddy
6467
self.field_color = self.eddy[field_color].astype("f4")

src/py_eddy_tracker/generic.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,6 @@ def build_circle(x0, y0, r):
615615
return x_norm * r + x0, y_norm * r + y0
616616

617617

618-
@njit(cache=True)
619618
def window_index(x, x0, half_window=1):
620619
"""
621620
Give for a fixed half_window each start and end index for each x0, in
@@ -626,7 +625,12 @@ def window_index(x, x0, half_window=1):
626625
:param float half_window: half window
627626
"""
628627
# Sort array, bounds will be sort also
629-
i_ordered = x.argsort()
628+
i_ordered = x.argsort(kind="mergesort")
629+
return window_index_(x, i_ordered, x0, half_window)
630+
631+
632+
@njit(cache=True)
633+
def window_index_(x, i_ordered, x0, half_window=1):
630634
nb_x, nb_pt = x.size, x0.size
631635
first_index = empty(nb_pt, dtype=i_ordered.dtype)
632636
last_index = empty(nb_pt, dtype=i_ordered.dtype)

src/py_eddy_tracker/observations/network.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
from glob import glob
66
import logging
77
import time
8-
8+
from datetime import timedelta, datetime
9+
import os
910
import netCDF4
1011
from numba import njit, types as nb_types
1112
from numba.typed import List
@@ -16,6 +17,7 @@
1617
bincount,
1718
bool_,
1819
concatenate,
20+
1921
empty,
2022
nan,
2123
ones,
@@ -120,13 +122,15 @@ def __repr__(self):
120122
period = (self.period[1] - self.period[0]) / 365.25
121123
nb_by_network = self.network_size()
122124
nb_trash = 0 if self.ref_index != 0 else nb_by_network[0]
125+
lifetime=self.lifetime
123126
big = 50_000
124127
infos = [
125128
f"Atlas with {self.nb_network} networks ({self.nb_network / period:0.0f} networks/year),"
126129
f" {self.nb_segment} segments ({self.nb_segment / period:0.0f} segments/year), {len(self)} observations ({len(self) / period:0.0f} observations/year)",
127130
f" {m_event.size} merging ({m_event.size / period:0.0f} merging/year), {s_event.size} splitting ({s_event.size / period:0.0f} splitting/year)",
128131
f" with {(nb_by_network > big).sum()} network with more than {big} obs and the biggest have {nb_by_network.max()} observations ({nb_by_network[nb_by_network > big].sum()} observations cumulate)",
129132
f" {nb_trash} observations in trash",
133+
f" {lifetime.max()} days max of lifetime",
130134
]
131135
return "\n".join(infos)
132136

@@ -201,6 +205,13 @@ def ref_segment_track_index(self):
201205
@property
202206
def ref_index(self):
203207
return self.index_network[2]
208+
209+
@property
210+
def lifetime(self):
211+
"""Return lifetime for each observation"""
212+
lt=self.networks_period.astype("int")
213+
nb_by_network=self.network_size()
214+
return lt.repeat(nb_by_network)
204215

205216
def network_segment_size(self, id_networks=None):
206217
"""Get number of segment by network
@@ -226,12 +237,15 @@ def network_size(self, id_networks=None):
226237
i = id_networks - self.index_network[2]
227238
return self.index_network[1][i] - self.index_network[0][i]
228239

240+
@property
229241
def networks_period(self):
230242
"""
231243
Return period for each network
232244
"""
233245
return get_period_with_index(self.time, *self.index_network[:2])
234246

247+
248+
235249
def unique_segment_to_id(self, id_unique):
236250
"""Return id network and id segment for a unique id
237251
@@ -281,7 +295,7 @@ def astype(self, cls):
281295
new[k][:] = self[k][:]
282296
new.sign_type = self.sign_type
283297
return new
284-
298+
285299
def longer_than(self, nb_day_min=-1, nb_day_max=-1):
286300
"""
287301
Select network on time duration
@@ -1132,23 +1146,29 @@ def segment_track_array(self):
11321146
self._segment_track_array = build_unique_array(self.segment, self.track)
11331147
return self._segment_track_array
11341148

1135-
def birth_event(self):
1149+
def birth_event(self, only_index=False):
11361150
"""Extract birth events."""
11371151
i_start, _, _ = self.index_segment_track
11381152
indices = i_start[self.previous_obs[i_start] == -1]
11391153
if self.first_is_trash():
11401154
indices = indices[1:]
1141-
return self.extract_event(indices)
1142-
1155+
if only_index:
1156+
return indices
1157+
else :
1158+
return self.extract_event(indices)
1159+
11431160
generation_event = birth_event
11441161

1145-
def death_event(self):
1162+
def death_event(self, only_index=False):
11461163
"""Extract death events."""
11471164
_, i_stop, _ = self.index_segment_track
11481165
indices = i_stop[self.next_obs[i_stop - 1] == -1] - 1
11491166
if self.first_is_trash():
11501167
indices = indices[1:]
1151-
return self.extract_event(indices)
1168+
if only_index:
1169+
return indices
1170+
else :
1171+
return self.extract_event(indices)
11521172

11531173
dissipation_event = death_event
11541174

@@ -1459,7 +1479,7 @@ def plot(self, ax, ref=None, color_cycle=None, **kwargs):
14591479
j += 1
14601480
return mappables
14611481

1462-
def remove_dead_end(self, nobs=3, ndays=0, recursive=0, mask=None):
1482+
def remove_dead_end(self, nobs=3, ndays=0, recursive=0, mask=None, return_mask=False):
14631483
"""
14641484
Remove short segments that don't connect several segments
14651485
@@ -1485,6 +1505,8 @@ def remove_dead_end(self, nobs=3, ndays=0, recursive=0, mask=None):
14851505
)
14861506
# get mask for selected obs
14871507
m = ~self.segment_mask(segments_keep)
1508+
if return_mask:
1509+
return ~m
14881510
self.track[m] = 0
14891511
self.segment[m] = 0
14901512
self.previous_obs[m] = -1
@@ -1502,6 +1524,8 @@ def remove_dead_end(self, nobs=3, ndays=0, recursive=0, mask=None):
15021524
self.sort()
15031525
if recursive > 0:
15041526
self.remove_dead_end(nobs, ndays, recursive - 1)
1527+
1528+
15051529

15061530
def extract_segment(self, segments, absolute=False):
15071531
"""Extract given segments
@@ -2042,6 +2066,7 @@ def group_observations(self, min_overlap=0.2, minimal_area=False, **kwargs):
20422066
results, nb_obs = list(), list()
20432067
# To display print only in INFO
20442068
display_iteration = logger.getEffectiveLevel() == logging.INFO
2069+
20452070
for i, filename in enumerate(self.filenames):
20462071
if display_iteration:
20472072
print(f"{filename} compared to {self.window} next", end="\r")

0 commit comments

Comments
 (0)