@@ -69,17 +69,18 @@ if __name__ == '__main__':
6969 if FLG_VIRTUAL :
7070 nb_real_obs = len (e_previous )
7171 # If you comment this the virtual fonctionnality will be disable
72+ logging .debug ('%d virtual obs will be add to previous' , len (virtual_obs ))
7273 e_previous = e_previous .merge (virtual_obs )
7374 dist_result = np .empty ((len (e_previous ), len (e_current )), dtype = 'f8' ) + np .nan
7475 distance_matrix (
7576 e_previous .obs ['lon' ], e_previous .obs ['lat' ],
7677 e_current .obs ['lon' ], e_current .obs ['lat' ],
7778 dist_result )
78- i_previous , i_current = np .where (dist_result < 5 . )
79+ i_previous , i_current = np .where (dist_result < 20 . )
7980 nb_match = i_previous .shape [0 ]
8081
8182 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' ) ])
8384 correspondance ['out' ] = i_current
8485
8586 if FLG_VIRTUAL :
@@ -102,16 +103,36 @@ if __name__ == '__main__':
102103 id_previous [CORRESPONDANCES [- 1 ]['out' ]] = previous_id
103104 correspondance ['id' ] = id_previous [correspondance ['in' ]]
104105 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+
109116
110117 # 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+
111130 # List previous id which are not use in the next step
112131 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 )
113134 # 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 )
115136 # Find mask/index on previous correspondance to extrapolate
116137 # position
117138 list_previous_id = previous_id .tolist ()
@@ -124,18 +145,31 @@ if __name__ == '__main__':
124145 # Position N-1 : B
125146 # Virtual Position : C
126147 # 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 ]
129152 # 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
132165 # END
133166
134167
135168 # new_id is equal to UINT32_MAX we must add a new ones
136169 # we count the number of new
137170 mask_new_id = correspondance ['id' ] == UINT32_MAX
138171 nb_new_tracks = mask_new_id .sum ()
172+ logging .debug ('%d birth in this step' , nb_new_tracks )
139173 # Set new id
140174 correspondance ['id' ][mask_new_id ] = np .arange (CURRENT_ID , CURRENT_ID + nb_new_tracks )
141175 # Set counter
@@ -152,17 +186,24 @@ if __name__ == '__main__':
152186 nb_obs_by_tracks = np .zeros (CURRENT_ID , dtype = 'u2' ) + 1
153187 for correspondance in CORRESPONDANCES :
154188 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' ]]
156191
192+ # Compute index of each tracks
157193 i_current_by_tracks = nb_obs_by_tracks .cumsum () - nb_obs_by_tracks
194+ # Number of global obs
158195 nb_obs = nb_obs_by_tracks .sum ()
159196 logging .info ('%d tracks will be create' , CURRENT_ID )
160197 logging .info ('%d observations will be join' , nb_obs )
161198 # Start create netcdf to agglomerate all eddy
162199 FINAL_EDDIES = TrackEddiesObservations (size = nb_obs )
163200
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)' )
164204 n = np .arange (nb_obs , dtype = 'u4' ) - i_current_by_tracks .repeat (nb_obs_by_tracks )
165205 FINAL_EDDIES .obs ['n' ] = np .uint16 (n )
206+ logging .debug ('Compute global track array' )
166207 FINAL_EDDIES .obs ['track' ] = np .arange (CURRENT_ID ).repeat (nb_obs_by_tracks )
167208
168209 # Start loading identification again to save in the finals tracks
@@ -192,6 +233,7 @@ if __name__ == '__main__':
192233 FINAL_EDDIES .obs [var ][index_final [m_first_obs ]] = eddies_previous .obs [var ][index_in ]
193234 # Increment
194235 i_current_by_tracks [i_id [m_first_obs ]] += 1
236+ # Active this flag, we have only one first by tracks
195237 first_obs_save_in_tracks [i_id ] = True
196238 index_final = i_current_by_tracks [i_id ]
197239
@@ -201,8 +243,9 @@ if __name__ == '__main__':
201243 m_virtual = CORRESPONDANCES [i ]['virtual' ]
202244 if m_virtual .any ():
203245 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
206249 index_final = i_current_by_tracks [i_id ]
207250
208251 # Copy all variable
@@ -214,13 +257,20 @@ if __name__ == '__main__':
214257 i_current_by_tracks [i_id ] += 1
215258 eddies_previous = eddies_current
216259
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
218266 nb_virtual = FINAL_EDDIES .obs ['virtual' ].sum ()
267+
219268 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 ])
224274
225275 # Total running time
226276 logging .info ('Mean duration by loop : %s' ,
0 commit comments