Skip to content

Commit 87189b0

Browse files
author
adelepoulle
committed
Implementation end for virtual observation
1 parent e3ddc29 commit 87189b0

File tree

3 files changed

+91
-20
lines changed

3 files changed

+91
-20
lines changed

src/py_eddy_tracker/__init__.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,27 @@ def parse_args(self, *args, **kwargs):
9393
description='cyclonic -1; anti-cyclonic +1',
9494
)
9595
),
96+
segment_size=dict(
97+
attr_name=None,
98+
nc_name=None,
99+
nc_type='byte',
100+
nc_dims=None,
101+
nc_attr=dict()
102+
),
103+
dlon=dict(
104+
attr_name=None,
105+
nc_name=None,
106+
nc_type='float64',
107+
nc_dims=None,
108+
nc_attr=dict()
109+
),
110+
dlat=dict(
111+
attr_name=None,
112+
nc_name=None,
113+
nc_type='float64',
114+
nc_dims=None,
115+
nc_attr=dict()
116+
),
96117
virtual=dict(
97118
attr_name=None,
98119
nc_name='virtual',

src/py_eddy_tracker/py_eddy_tracker_property_classes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ class VirtualEddiesObservations(EddiesObservations):
199199
@property
200200
def elements(self):
201201
elements = super(VirtualEddiesObservations, self).elements
202-
elements.extend(['track'])
202+
elements.extend(['track', 'segment_size', 'dlon', 'dlat'])
203203
return elements
204204

205205
class TrackEddiesObservations(EddiesObservations):

src/scripts/EddyTracking

Lines changed: 69 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)