@@ -311,7 +311,7 @@ def sort(self, order=("track", "segment", "time")):
311
311
"""
312
312
sort observations
313
313
314
- :param tuple order: order or sorting. Passed to `np .argsort`
314
+ :param tuple order: order or sorting. Passed to :func:`numpy .argsort`
315
315
"""
316
316
317
317
index_order = self .obs .argsort (order = order )
@@ -485,39 +485,78 @@ def segment_relative_order(self, seg_origine):
485
485
d [i0 :i1 ] = v
486
486
return d
487
487
488
- def relative (self , i_obs , order = 2 , direct = True , only_past = False , only_future = False ):
488
+ def relatives (self , obs , order = 2 ):
489
489
"""
490
- Extract the segments at a certain order from one observation .
490
+ Extract the segments at a certain order from multiple observations .
491
491
492
- :param list obs: indice of observation for relative computation
492
+ :param iterable,int obs: indices of observation for relatives computation. Can be one observation (int) or collection of observations (iterable(int))
493
493
:param int order: order of relatives wanted. 0 means only observations in obs, 1 means direct relatives, ...
494
494
495
495
:return: all segments relatives
496
496
:rtype: EddiesObservations
497
497
"""
498
+ segment = self .segment_track_array
499
+ previous_obs , next_obs = self .previous_obs , self .next_obs
498
500
499
- d = self .segment_relative_order (self .segment [i_obs ])
500
- m = (d <= order ) * (d != - 1 )
501
- return self .extract_with_mask (m )
501
+ segments_connexion = dict ()
502
502
503
- def relatives ( self , obs , order = 2 , direct = True , only_past = False , only_future = False ):
504
- """
505
- Extract the segments at a certain order from multiple observations.
503
+ for i_slice , seg , _ in self . iter_on ( segment ):
504
+ if i_slice . start == i_slice . stop :
505
+ continue
506
506
507
- :param list obs: indices of observation for relatives computation
508
- :param int order: order of relatives wanted. 0 means only observations in obs, 1 means direct relatives, ...
507
+ i_p , i_n = previous_obs [ i_slice . start ], next_obs [ i_slice . stop - 1 ]
508
+ p_seg , n_seg = segment [ i_p ], segment [ i_n ]
509
509
510
- :return: all segments relatives
511
- :rtype: EddiesObservations
512
- """
510
+ # dumping slice into dict
511
+ if seg not in segments_connexion :
512
+ segments_connexion [seg ] = [i_slice , []]
513
+ else :
514
+ segments_connexion [seg ][0 ] = i_slice
513
515
514
- mask = zeros (self .segment .shape , dtype = bool )
515
516
516
- for i_obs in obs :
517
- d = self .segment_relative_order (self .segment [i_obs ])
518
- mask += (d <= order ) * (d != - 1 )
517
+ if i_p != - 1 :
519
518
520
- return self .extract_with_mask (mask )
519
+ if p_seg not in segments_connexion :
520
+ segments_connexion [p_seg ] = [None , []]
521
+
522
+ # backward
523
+ segments_connexion [seg ][1 ].append (p_seg )
524
+ segments_connexion [p_seg ][1 ].append (seg )
525
+
526
+ if i_n != - 1 :
527
+ if n_seg not in segments_connexion :
528
+ segments_connexion [n_seg ] = [None , []]
529
+
530
+ # forward
531
+ segments_connexion [seg ][1 ].append (n_seg )
532
+ segments_connexion [n_seg ][1 ].append (seg )
533
+
534
+
535
+ i_obs = (
536
+ [obs ]
537
+ if not hasattr (obs , "__iter__" )
538
+ else obs
539
+ )
540
+ import numpy as np
541
+
542
+ distance = zeros (segment .size , dtype = np .uint16 ) - 1
543
+
544
+ def loop (seg , dist = 1 ):
545
+ i_slice , links = segments_connexion [seg ]
546
+ d = distance [i_slice .start ]
547
+
548
+ if dist < d and dist <= order :
549
+ distance [i_slice ] = dist
550
+ for _seg in links :
551
+ loop (_seg , dist + 1 )
552
+
553
+ for indice in i_obs :
554
+ loop (segment [indice ], 0 )
555
+
556
+ return self .extract_with_mask (distance <= order )
557
+
558
+ # keep old names, for backward compatibility
559
+ relative = relatives
521
560
522
561
def close_network (self , other , nb_obs_min = 10 , ** kwargs ):
523
562
"""
0 commit comments