Skip to content

Commit e50d3fa

Browse files
committed
- allow to dissociate network which group several
- add method to know if a network is fully connected
1 parent 3c92d82 commit e50d3fa

File tree

1 file changed

+69
-3
lines changed

1 file changed

+69
-3
lines changed

src/py_eddy_tracker/observations/network.py

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,26 @@ def load_contour(self, filename):
6161

6262
class NetworkObservations(EddiesObservations):
6363

64-
__slots__ = tuple()
64+
__slots__ = ("_index_network",)
6565

6666
NOGROUP = 0
6767

68+
def __init__(self, *args, **kwargs):
69+
super().__init__(*args, **kwargs)
70+
self._index_network = None
71+
72+
def network_slice(self, id_network):
73+
"""
74+
Return slice for one network
75+
76+
:param int id_network: id to identify network
77+
"""
78+
if self._index_network is None:
79+
self._index_network = build_index(self.track)
80+
i = id_network - self._index_network[2]
81+
i_start, i_stop = self._index_network[0][i], self._index_network[1][i]
82+
return slice(i_start, i_stop)
83+
6884
@property
6985
def elements(self):
7086
elements = super().elements
@@ -461,9 +477,56 @@ def spliting_event(self):
461477
indices.append(i.start)
462478
return self.extract_event(list(set(indices)))
463479

480+
def dissociate_network(self):
481+
"""
482+
Dissociate network with no known interaction (spliting/merging)
483+
"""
484+
self.only_one_network()
485+
tags = self.tag_segment()
486+
# FIXME : Ok if only one network
487+
self.track[:] = tags[self.segment - 1]
488+
489+
self.obs.sort(order=("track", "segment", "time"))
490+
self._index_network = None
491+
492+
# FIXME
493+
# n & p must be re-index
494+
# n, p = self.next_obs[mask], self.previous_obs[mask]
495+
# we add 2 for -1 index return index -1
496+
# translate = -ones(len(self) + 1, dtype="i4")
497+
# translate[:-1][mask] = arange(nb_obs)
498+
# new.next_obs[:] = translate[n]
499+
# new.previous_obs[:] = translate[p]
500+
501+
def network(self, id_network):
502+
return self.extract_with_mask(self.network_slice(id_network))
503+
504+
@classmethod
505+
def __tag_segment(cls, seg, tag, groups, connexions):
506+
if groups[seg] != 0:
507+
return
508+
groups[seg] = tag
509+
segs = connexions.get(seg + 1, None)
510+
if segs is not None:
511+
for seg in segs:
512+
cls.__tag_segment(seg - 1, tag, groups, connexions)
513+
514+
def tag_segment(self):
515+
self.only_one_network()
516+
nb = self.segment.max()
517+
sub_group = zeros(nb, dtype="u4")
518+
c = self.connexions()
519+
j = 1
520+
for i in range(nb):
521+
if sub_group[i] != 0:
522+
continue
523+
self.__tag_segment(i, j, sub_group, c)
524+
j += 1
525+
return sub_group
526+
464527
def fully_connected(self):
465528
self.only_one_network()
466-
# TODO
529+
return self.tag_segment().shape[0] == 1
467530

468531
def plot(self, ax, ref=None, color_cycle=None, **kwargs):
469532
"""
@@ -545,7 +608,10 @@ def extract_with_mask(self, mask):
545608
:return: same object with selected observations
546609
:rtype: self
547610
"""
548-
nb_obs = mask.sum()
611+
if isinstance(mask, slice):
612+
nb_obs = mask.stop - mask.start
613+
else:
614+
nb_obs = mask.sum()
549615
new = self.__class__.new_like(self, nb_obs)
550616
new.sign_type = self.sign_type
551617
if nb_obs == 0:

0 commit comments

Comments
 (0)