@@ -69,17 +69,18 @@ if __name__ == '__main__':
69
69
if FLG_VIRTUAL :
70
70
nb_real_obs = len (e_previous )
71
71
# If you comment this the virtual fonctionnality will be disable
72
+ logging .debug ('%d virtual obs will be add to previous' , len (virtual_obs ))
72
73
e_previous = e_previous .merge (virtual_obs )
73
74
dist_result = np .empty ((len (e_previous ), len (e_current )), dtype = 'f8' ) + np .nan
74
75
distance_matrix (
75
76
e_previous .obs ['lon' ], e_previous .obs ['lat' ],
76
77
e_current .obs ['lon' ], e_current .obs ['lat' ],
77
78
dist_result )
78
- i_previous , i_current = np .where (dist_result < 5 . )
79
+ i_previous , i_current = np .where (dist_result < 20 . )
79
80
nb_match = i_previous .shape [0 ]
80
81
81
82
logging .debug ('%d match with previous' , nb_match )
82
- correspondance = np .array (i_previous , dtype = [('in' , 'u2' ), ('out' , 'u2' ), ('id' , 'u4' ), ('virtual' , np .bool_ )])
83
+ correspondance = np .array (i_previous , dtype = [('in' , 'u2' ), ('out' , 'u2' ), ('id' , 'u4' ), ('virtual' , np .bool_ ), ( 'virtual_length' , 'u1' ) ])
83
84
correspondance ['out' ] = i_current
84
85
85
86
if FLG_VIRTUAL :
@@ -102,16 +103,36 @@ if __name__ == '__main__':
102
103
id_previous [CORRESPONDANCES [- 1 ]['out' ]] = previous_id
103
104
correspondance ['id' ] = id_previous [correspondance ['in' ]]
104
105
if FLG_VIRTUAL :
105
- # Set id for virtual
106
- correspondance ['id' ][correspondance ['virtual' ]] = \
107
- virtual_obs .obs ['track' ][correspondance ['in' ][correspondance ['virtual' ]] - nb_real_obs ]
108
- #~ correspondance['in'][correspondance['virtual']] = UINT16_MAX
106
+ nb_rebirth = correspondance ['virtual' ].sum ()
107
+ if nb_rebirth != 0 :
108
+ logging .debug ('%d re-birth due to prolongation with virtual observations' , nb_rebirth )
109
+ # Set id for virtual
110
+ correspondance ['id' ][correspondance ['virtual' ]] = \
111
+ virtual_obs .obs ['track' ][correspondance ['in' ][correspondance ['virtual' ]] - nb_real_obs ]
112
+ correspondance ['virtual_length' ][correspondance ['virtual' ]] = \
113
+ virtual_obs .obs ['segment_size' ][correspondance ['in' ][correspondance ['virtual' ]] - nb_real_obs ]
114
+ #~ correspondance['in'][correspondance['virtual']] = UINT16_MAX
115
+
109
116
110
117
# SECTION for virtual observation
118
+ nb_virtual_prolongate = 0
119
+ if FLG_VIRTUAL :
120
+ # Save previous state to count virtual obs
121
+ previous_virtual_obs = virtual_obs
122
+ virtual_dead_id = np .setdiff1d (virtual_obs .obs ['track' ], correspondance ['id' ])
123
+ list_previous_virtual_id = virtual_obs .obs ['track' ].tolist ()
124
+ i_virtual_dead_id = [list_previous_virtual_id .index (i ) for i in virtual_dead_id ]
125
+ # Virtual obs which can be prolongate
126
+ alive_virtual_obs = virtual_obs .obs ['segment_size' ][i_virtual_dead_id ] < NB_VIRTUAL_OBS_MAX_BY_SEGMENT
127
+ nb_virtual_prolongate = alive_virtual_obs .sum ()
128
+ logging .debug ('%d virtual obs will be prolongate on the next step' , nb_virtual_prolongate )
129
+
111
130
# List previous id which are not use in the next step
112
131
dead_id = np .setdiff1d (previous_id , correspondance ['id' ])
132
+ nb_dead_track = len (dead_id )
133
+ logging .debug ('%d death of real obs in this step' , nb_dead_track )
113
134
# Creation of an virtual step for dead one
114
- virtual_obs = VirtualEddiesObservations (size = len ( dead_id ) )
135
+ virtual_obs = VirtualEddiesObservations (size = nb_dead_track + nb_virtual_prolongate )
115
136
# Find mask/index on previous correspondance to extrapolate
116
137
# position
117
138
list_previous_id = previous_id .tolist ()
@@ -124,18 +145,31 @@ if __name__ == '__main__':
124
145
# Position N-1 : B
125
146
# Virtual Position : C
126
147
# New position C = B + AB
127
- virtual_obs .obs ['lon' ] = 2 * obs_b ['lon' ] - obs_a ['lon' ]
128
- virtual_obs .obs ['lat' ] = 2 * obs_b ['lat' ] - obs_a ['lat' ]
148
+ virtual_obs .obs ['dlon' ][:nb_dead_track ] = obs_b ['lon' ] - obs_a ['lon' ]
149
+ virtual_obs .obs ['dlat' ][:nb_dead_track ] = obs_b ['lat' ] - obs_a ['lat' ]
150
+ virtual_obs .obs ['lon' ][:nb_dead_track ] = obs_b ['lon' ] + virtual_obs .obs ['dlon' ][:nb_dead_track ]
151
+ virtual_obs .obs ['lat' ][:nb_dead_track ] = obs_b ['lat' ] + virtual_obs .obs ['dlat' ][:nb_dead_track ]
129
152
# Id which are prolongated
130
- virtual_obs .obs ['track' ] = dead_id
131
- FLG_VIRTUAL = True
153
+ virtual_obs .obs ['track' ][:nb_dead_track ] = dead_id
154
+ # Add previous virtual
155
+ if nb_virtual_prolongate > 0 :
156
+ obs_to_prolongate = previous_virtual_obs .obs [i_virtual_dead_id ][alive_virtual_obs ]
157
+ virtual_obs .obs ['lon' ][nb_dead_track :] = obs_to_prolongate ['lon' ] + obs_to_prolongate ['dlon' ]
158
+ virtual_obs .obs ['lat' ][nb_dead_track :] = obs_to_prolongate ['lat' ] + obs_to_prolongate ['dlat' ]
159
+ virtual_obs .obs ['track' ][nb_dead_track :] = obs_to_prolongate ['track' ]
160
+ virtual_obs .obs ['segment_size' ][nb_dead_track :] = obs_to_prolongate ['segment_size' ]
161
+ # Count
162
+ virtual_obs .obs ['segment_size' ] += 1
163
+ if NB_VIRTUAL_OBS_MAX_BY_SEGMENT > 0 :
164
+ FLG_VIRTUAL = True
132
165
# END
133
166
134
167
135
168
# new_id is equal to UINT32_MAX we must add a new ones
136
169
# we count the number of new
137
170
mask_new_id = correspondance ['id' ] == UINT32_MAX
138
171
nb_new_tracks = mask_new_id .sum ()
172
+ logging .debug ('%d birth in this step' , nb_new_tracks )
139
173
# Set new id
140
174
correspondance ['id' ][mask_new_id ] = np .arange (CURRENT_ID , CURRENT_ID + nb_new_tracks )
141
175
# Set counter
@@ -152,17 +186,24 @@ if __name__ == '__main__':
152
186
nb_obs_by_tracks = np .zeros (CURRENT_ID , dtype = 'u2' ) + 1
153
187
for correspondance in CORRESPONDANCES :
154
188
nb_obs_by_tracks [correspondance ['id' ]] += 1
155
- nb_obs_by_tracks [correspondance ['id' ][correspondance ['virtual' ]]] += 1
189
+ # When start is virtual, we don't have a previous correspondance
190
+ nb_obs_by_tracks [correspondance ['id' ][correspondance ['virtual' ]]] += correspondance ['virtual_length' ][correspondance ['virtual' ]]
156
191
192
+ # Compute index of each tracks
157
193
i_current_by_tracks = nb_obs_by_tracks .cumsum () - nb_obs_by_tracks
194
+ # Number of global obs
158
195
nb_obs = nb_obs_by_tracks .sum ()
159
196
logging .info ('%d tracks will be create' , CURRENT_ID )
160
197
logging .info ('%d observations will be join' , nb_obs )
161
198
# Start create netcdf to agglomerate all eddy
162
199
FINAL_EDDIES = TrackEddiesObservations (size = nb_obs )
163
200
201
+ # Calculate the index in each tracks, we compute in u4 and translate
202
+ # in u2 (which are limited to 65535)
203
+ logging .debug ('Compute global index array (N)' )
164
204
n = np .arange (nb_obs , dtype = 'u4' ) - i_current_by_tracks .repeat (nb_obs_by_tracks )
165
205
FINAL_EDDIES .obs ['n' ] = np .uint16 (n )
206
+ logging .debug ('Compute global track array' )
166
207
FINAL_EDDIES .obs ['track' ] = np .arange (CURRENT_ID ).repeat (nb_obs_by_tracks )
167
208
168
209
# Start loading identification again to save in the finals tracks
@@ -192,6 +233,7 @@ if __name__ == '__main__':
192
233
FINAL_EDDIES .obs [var ][index_final [m_first_obs ]] = eddies_previous .obs [var ][index_in ]
193
234
# Increment
194
235
i_current_by_tracks [i_id [m_first_obs ]] += 1
236
+ # Active this flag, we have only one first by tracks
195
237
first_obs_save_in_tracks [i_id ] = True
196
238
index_final = i_current_by_tracks [i_id ]
197
239
@@ -201,8 +243,9 @@ if __name__ == '__main__':
201
243
m_virtual = CORRESPONDANCES [i ]['virtual' ]
202
244
if m_virtual .any ():
203
245
index_virtual = index_final [m_virtual ]
204
- FINAL_EDDIES .obs ['virtual' ][index_virtual ] = 1
205
- i_current_by_tracks [i_id [m_virtual ]] += 1
246
+ # Incrementing index
247
+ i_current_by_tracks [i_id [m_virtual ]] += CORRESPONDANCES [i ]['virtual_length' ][m_virtual ]
248
+ # Get new index
206
249
index_final = i_current_by_tracks [i_id ]
207
250
208
251
# Copy all variable
@@ -214,13 +257,20 @@ if __name__ == '__main__':
214
257
i_current_by_tracks [i_id ] += 1
215
258
eddies_previous = eddies_current
216
259
217
- i = np .where (FINAL_EDDIES .obs ['virtual' ])[0 ]
260
+ # We flag obs
261
+ FINAL_EDDIES .obs ['virtual' ] = FINAL_EDDIES .obs ['time' ] == 0
262
+
263
+ # Localization of virtual observation
264
+ m_i = FINAL_EDDIES .obs ['virtual' ] == 1
265
+ # Count virtual observations
218
266
nb_virtual = FINAL_EDDIES .obs ['virtual' ].sum ()
267
+
219
268
logging .info ('%d obs are virtual (unobserved)' , nb_virtual )
220
- FINAL_EDDIES .obs ['lon' ][i ] = (FINAL_EDDIES .obs ['lon' ][i - 1 ] + FINAL_EDDIES .obs ['lon' ][i + 1 ]) / 2
221
- FINAL_EDDIES .obs ['lat' ][i ] = (FINAL_EDDIES .obs ['lat' ][i - 1 ] + FINAL_EDDIES .obs ['lat' ][i + 1 ]) / 2
222
- FINAL_EDDIES .obs ['time' ][i ] = (FINAL_EDDIES .obs ['time' ][i - 1 ] + FINAL_EDDIES .obs ['time' ][i + 1 ]) / 2
223
-
269
+ logging .info ('Start extrapolation of values for virtual observations' )
270
+ nb_obs = len (FINAL_EDDIES )
271
+ index = np .arange (nb_obs )
272
+ for var , _ in eddies_current .obs .dtype .descr :
273
+ FINAL_EDDIES .obs [var ][m_i ] = np .interp (index [m_i ], index [- m_i ], FINAL_EDDIES .obs [var ][- m_i ])
224
274
225
275
# Total running time
226
276
logging .info ('Mean duration by loop : %s' ,
0 commit comments