6
6
from py_eddy_tracker import EddyParser
7
7
from glob import glob
8
8
from yaml import load as yaml_load
9
+ from py_eddy_tracker .tracking import \
10
+ Correspondance
9
11
from py_eddy_tracker .observations import \
10
12
EddiesObservations , TrackEddiesObservations , \
11
13
VirtualEddiesObservations
12
14
13
15
import logging
14
- import numpy as np
16
+ from numpy import array , arange , bool_ , uint16 , unique , setdiff1d , \
17
+ ones , zeros
15
18
import datetime as dt
16
19
17
20
18
- D2R = 0.017453292519943295
19
21
UINT32_MAX = 4294967295
20
22
UINT16_MAX = 65535
23
+ # ID limit to 4294967295
24
+ ID_DTYPE = 'u4'
25
+ # Track limit to 65535
26
+ N_DTYPE = 'u2'
27
+ # Prolongation limit to 255
28
+ VIRTUAL_DTYPE = 'u1'
21
29
22
30
23
- if __name__ == '__main__' :
31
+ def usage ():
32
+ """Usage
33
+ """
24
34
# Run using:
25
- PARSER = EddyParser (
35
+ parser = EddyParser (
26
36
"Tool to use identification step to compute tracking" )
27
- PARSER .add_argument ('yaml_file' ,
37
+ parser .add_argument ('yaml_file' ,
28
38
help = 'Yaml file to configure py-eddy-tracker' )
29
- YAML_FILE = PARSER .parse_args ().yaml_file
39
+ yaml_file = parser .parse_args ().yaml_file
30
40
31
41
# Read yaml configuration file
32
- with open (YAML_FILE , 'r' ) as stream :
33
- CONFIG = yaml_load (stream )
42
+ with open (yaml_file , 'r' ) as stream :
43
+ config = yaml_load (stream )
44
+ return config
45
+
46
+
47
+ if __name__ == '__main__' :
48
+ CONFIG = usage ()
34
49
35
50
NB_OBS_MIN = int (CONFIG ['TRACK_DURATION_MIN' ])
36
51
NB_VIRTUAL_OBS_MAX_BY_SEGMENT = int (CONFIG ['VIRTUAL_LEGNTH_MAX' ])
52
+
53
+ ACTIVE_VIRTUAL = NB_VIRTUAL_OBS_MAX_BY_SEGMENT > 0
37
54
38
55
PATTERN = CONFIG ['PATHS' ]['FILES_PATTERN' ]
39
56
FILENAMES = glob (PATTERN )
40
57
FILENAMES .sort ()
41
58
42
- e_previous = EddiesObservations .load_from_netcdf (FILENAMES [0 ])
43
-
44
59
START_TIME = dt .datetime .now ()
45
60
logging .info ('Start tracking on %d files' , len (FILENAMES ))
61
+
46
62
# To count id tracks
47
63
CURRENT_ID = 0
64
+ # Will contain all correspondance between each step
48
65
CORRESPONDANCES = []
49
66
START = True
50
67
FLG_VIRTUAL = False
68
+
69
+ # Dtype for correpondance
70
+ STANDARD_DTYPE = [
71
+ ('in' , 'u2' ),
72
+ ('out' , 'u2' ),
73
+ ('id' , ID_DTYPE )]
74
+
75
+ if ACTIVE_VIRTUAL :
76
+ STANDARD_DTYPE += [
77
+ ('virtual' , bool_ ),
78
+ ('virtual_length' , VIRTUAL_DTYPE )]
79
+
80
+ # Init
81
+ e_previous = EddiesObservations .load_from_netcdf (FILENAMES [0 ])
51
82
83
+ # We begin with second file, first one is in previous
52
84
for file_name in FILENAMES [1 :]:
53
85
logging .debug ('%s match with previous state' , file_name )
54
86
e_current = EddiesObservations .load_from_netcdf (file_name )
@@ -60,35 +92,29 @@ if __name__ == '__main__':
60
92
len (virtual_obs ))
61
93
# If you comment this the virtual fonctionnality will be disable
62
94
e_previous = e_previous .merge (virtual_obs )
63
- dist = e_previous . distance ( e_current )
64
- i_previous , i_current = np . where ( dist < 20. )
95
+
96
+ i_previous , i_current = e_previous . tracking ( e_current )
65
97
nb_match = i_previous .shape [0 ]
66
98
67
- logging .debug ('%d match with previous' , nb_match )
68
- correspondance = np .array (
69
- i_previous ,
70
- dtype = [
71
- ('in' , 'u2' ),
72
- ('out' , 'u2' ),
73
- ('id' , 'u4' ),
74
- ('virtual' , np .bool_ ),
75
- ('virtual_length' , 'u1' )])
99
+ #~ Correspondance()
100
+ correspondance = array (i_previous , dtype = STANDARD_DTYPE )
76
101
correspondance ['out' ] = i_current
77
102
78
- if FLG_VIRTUAL :
79
- correspondance ['virtual' ] = i_previous >= nb_real_obs
80
- else :
81
- correspondance ['virtual' ] = False
103
+ if ACTIVE_VIRTUAL :
104
+ if FLG_VIRTUAL :
105
+ correspondance ['virtual' ] = i_previous >= nb_real_obs
106
+ else :
107
+ correspondance ['virtual' ] = False
82
108
83
109
if START :
84
110
START = False
85
111
# Set an id for each match
86
- correspondance ['id' ] = np . arange (nb_match )
112
+ correspondance ['id' ] = arange (nb_match )
87
113
# Set counter
88
114
CURRENT_ID += nb_match
89
115
else :
90
116
# We set all id to UINT32_MAX
91
- id_previous = np . ones (len (e_previous ), dtype = 'u4' ) * UINT32_MAX
117
+ id_previous = ones (len (e_previous ), dtype = ID_DTYPE ) * UINT32_MAX
92
118
# We get old id for previously eddies tracked
93
119
previous_id = CORRESPONDANCES [- 1 ]['id' ]
94
120
id_previous [CORRESPONDANCES [- 1 ]['out' ]] = previous_id
@@ -110,7 +136,7 @@ if __name__ == '__main__':
110
136
if FLG_VIRTUAL :
111
137
# Save previous state to count virtual obs
112
138
previous_virtual_obs = virtual_obs
113
- virtual_dead_id = np . setdiff1d (virtual_obs .obs ['track' ],
139
+ virtual_dead_id = setdiff1d (virtual_obs .obs ['track' ],
114
140
correspondance ['id' ])
115
141
list_previous_virtual_id = virtual_obs .obs ['track' ].tolist ()
116
142
i_virtual_dead_id = [
@@ -122,7 +148,7 @@ if __name__ == '__main__':
122
148
'next step' , nb_virtual_prolongate )
123
149
124
150
# List previous id which are not use in the next step
125
- dead_id = np . setdiff1d (previous_id , correspondance ['id' ])
151
+ dead_id = setdiff1d (previous_id , correspondance ['id' ])
126
152
nb_dead_track = len (dead_id )
127
153
logging .debug ('%d death of real obs in this step' , nb_dead_track )
128
154
# Creation of an virtual step for dead one
@@ -163,7 +189,7 @@ if __name__ == '__main__':
163
189
] = obs_to_prolongate ['segment_size' ]
164
190
# Count
165
191
virtual_obs .obs ['segment_size' ] += 1
166
- if NB_VIRTUAL_OBS_MAX_BY_SEGMENT > 0 :
192
+ if ACTIVE_VIRTUAL :
167
193
FLG_VIRTUAL = True
168
194
# END
169
195
@@ -173,7 +199,7 @@ if __name__ == '__main__':
173
199
nb_new_tracks = mask_new_id .sum ()
174
200
logging .debug ('%d birth in this step' , nb_new_tracks )
175
201
# Set new id
176
- correspondance ['id' ][mask_new_id ] = np . arange (
202
+ correspondance ['id' ][mask_new_id ] = arange (
177
203
CURRENT_ID , CURRENT_ID + nb_new_tracks )
178
204
# Set counter
179
205
CURRENT_ID += nb_new_tracks
@@ -186,12 +212,13 @@ if __name__ == '__main__':
186
212
logging .info ('Track finish' )
187
213
logging .info ('Start merging' )
188
214
# count obs by tracks
189
- nb_obs_by_tracks = np . zeros (CURRENT_ID , dtype = 'u2' ) + 1
215
+ nb_obs_by_tracks = zeros (CURRENT_ID , dtype = N_DTYPE ) + 1
190
216
for correspondance in CORRESPONDANCES :
191
217
nb_obs_by_tracks [correspondance ['id' ]] += 1
192
- # When start is virtual, we don't have a previous correspondance
193
- nb_obs_by_tracks [correspondance ['id' ][correspondance ['virtual' ]]
194
- ] += correspondance ['virtual_length' ][correspondance ['virtual' ]]
218
+ if ACTIVE_VIRTUAL :
219
+ # When start is virtual, we don't have a previous correspondance
220
+ nb_obs_by_tracks [correspondance ['id' ][correspondance ['virtual' ]]
221
+ ] += correspondance ['virtual_length' ][correspondance ['virtual' ]]
195
222
196
223
# Compute index of each tracks
197
224
i_current_by_tracks = nb_obs_by_tracks .cumsum () - nb_obs_by_tracks
@@ -205,11 +232,11 @@ if __name__ == '__main__':
205
232
# Calculate the index in each tracks, we compute in u4 and translate
206
233
# in u2 (which are limited to 65535)
207
234
logging .debug ('Compute global index array (N)' )
208
- n = np . arange (nb_obs ,
209
- dtype = 'u4' ) - i_current_by_tracks .repeat (nb_obs_by_tracks )
210
- FINAL_EDDIES .obs ['n' ] = np . uint16 (n )
235
+ n = arange (nb_obs ,
236
+ dtype = 'u4' ) - i_current_by_tracks .repeat (nb_obs_by_tracks )
237
+ FINAL_EDDIES .obs ['n' ] = uint16 (n )
211
238
logging .debug ('Compute global track array' )
212
- FINAL_EDDIES .obs ['track' ] = np . arange (CURRENT_ID ).repeat (nb_obs_by_tracks )
239
+ FINAL_EDDIES .obs ['track' ] = arange (CURRENT_ID ).repeat (nb_obs_by_tracks )
213
240
214
241
# Start loading identification again to save in the finals tracks
215
242
# Load first file
@@ -218,8 +245,8 @@ if __name__ == '__main__':
218
245
FINAL_EDDIES .sign_type = eddies_previous .sign_type
219
246
220
247
# To know if the track start
221
- first_obs_save_in_tracks = np . zeros (i_current_by_tracks .shape ,
222
- dtype = np . bool_ )
248
+ first_obs_save_in_tracks = zeros (i_current_by_tracks .shape ,
249
+ dtype = bool_ )
223
250
224
251
for i , file_name in enumerate (FILENAMES [1 :]):
225
252
# Load current file (we begin with second one)
@@ -246,16 +273,18 @@ if __name__ == '__main__':
246
273
247
274
# Index in the current file
248
275
index_current = CORRESPONDANCES [i ]['out' ]
249
- # If the flag virtual in correspondance is active,
250
- # the previous is virtual
251
- m_virtual = CORRESPONDANCES [i ]['virtual' ]
252
- if m_virtual .any ():
253
- index_virtual = index_final [m_virtual ]
254
- # Incrementing index
255
- i_current_by_tracks [i_id [m_virtual ]
256
- ] += CORRESPONDANCES [i ]['virtual_length' ][m_virtual ]
257
- # Get new index
258
- index_final = i_current_by_tracks [i_id ]
276
+
277
+ if ACTIVE_VIRTUAL :
278
+ # If the flag virtual in correspondance is active,
279
+ # the previous is virtual
280
+ m_virtual = CORRESPONDANCES [i ]['virtual' ]
281
+ if m_virtual .any ():
282
+ index_virtual = index_final [m_virtual ]
283
+ # Incrementing index
284
+ i_current_by_tracks [i_id [m_virtual ]
285
+ ] += CORRESPONDANCES [i ]['virtual_length' ][m_virtual ]
286
+ # Get new index
287
+ index_final = i_current_by_tracks [i_id ]
259
288
260
289
# Copy all variable
261
290
for var , _ in eddies_current .obs .dtype .descr :
@@ -267,28 +296,16 @@ if __name__ == '__main__':
267
296
eddies_previous = eddies_current
268
297
269
298
# We flag obs
270
- FINAL_EDDIES .obs ['virtual' ] = FINAL_EDDIES .obs ['time' ] == 0
271
-
272
- FINAL_EDDIES .filled_by_interpolation (FINAL_EDDIES .obs ['virtual' ] == 1 )
273
- # Localization of virtual observation
274
- m_i = FINAL_EDDIES .obs ['virtual' ] == 1
275
- # Count virtual observations
276
- nb_virtual = FINAL_EDDIES .obs ['virtual' ].sum ()
277
-
278
- logging .info ('%d obs are virtual (unobserved)' , nb_virtual )
279
- logging .info ('Start extrapolation of values for virtual observations' )
280
- nb_obs = len (FINAL_EDDIES )
281
- index = np .arange (nb_obs )
282
- for var , _ in eddies_current .obs .dtype .descr :
283
- FINAL_EDDIES .obs [var ][m_i ] = np .interp (
284
- index [m_i ],
285
- index [- m_i ],
286
- FINAL_EDDIES .obs [var ][- m_i ])
299
+ if ACTIVE_VIRTUAL :
300
+ FINAL_EDDIES .obs ['virtual' ] = FINAL_EDDIES .obs ['time' ] == 0
301
+
302
+ FINAL_EDDIES .filled_by_interpolation (FINAL_EDDIES .obs ['virtual' ] == 1 )
287
303
288
304
# Total running time
305
+ FULL_TIME = dt .datetime .now () - START_TIME
289
306
logging .info ('Mean duration by loop : %s' ,
290
- ( dt . datetime . now () - START_TIME ) / (len (FILENAMES ) - 1 ))
291
- logging .info ('Duration : %s' , dt . datetime . now () - START_TIME )
307
+ FULL_TIME / (len (FILENAMES ) - 1 ))
308
+ logging .info ('Duration : %s' , FULL_TIME )
292
309
293
310
logging .info ('The longest tracks have %d observations' ,
294
311
nb_obs_by_tracks .max ())
@@ -297,6 +314,6 @@ if __name__ == '__main__':
297
314
NB_OBS_MIN , nb_obs_by_tracks .repeat (nb_obs_by_tracks ))
298
315
299
316
logging .info ('%d tracks will be saved' ,
300
- len (np . unique (SUBSET_EDDIES .obs ['track' ])))
317
+ len (unique (SUBSET_EDDIES .obs ['track' ])))
301
318
302
319
SUBSET_EDDIES .write_netcdf ()
0 commit comments