Skip to content

Commit 82ca026

Browse files
author
adelepoulle
committed
Add function to extract u profil
1 parent 4126e0b commit 82ca026

File tree

4 files changed

+111
-20
lines changed

4 files changed

+111
-20
lines changed

src/py_eddy_tracker/__init__.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,26 @@ def parse_args(self, *args, **kwargs):
213213
'scale L',
214214
)
215215
),
216+
i=dict(
217+
attr_name='i',
218+
nc_name='i',
219+
nc_type='uint16',
220+
nc_dims=('Nobs',),
221+
nc_attr=dict(
222+
long_name='longitude index in the grid of the detection',
223+
description='longitude index in the grid of the detection',
224+
)
225+
),
226+
j=dict(
227+
attr_name='j',
228+
nc_name='j',
229+
nc_type='uint16',
230+
nc_dims=('Nobs',),
231+
nc_attr=dict(
232+
long_name='latitude index in the grid of the detection',
233+
description='latitude index in the grid of the detection',
234+
)
235+
),
216236
eke=dict(
217237
attr_name='eke',
218238
nc_name='Teke',
@@ -327,7 +347,7 @@ def parse_args(self, *args, **kwargs):
327347
attr_name=None,
328348
nc_name='uavg_profile',
329349
nc_type='f4',
330-
nc_dims=('uavg_contour_count', 'Nobs',),
350+
nc_dims=('Nobs', 'NbSample'),
331351
nc_attr=dict(
332352
long_name='radial profile of uavg',
333353
description='all uavg values from effective contour inwards to '
@@ -356,6 +376,42 @@ def parse_args(self, *args, **kwargs):
356376
units='%',
357377
)
358378
),
379+
height_max_speed_contour=dict(
380+
attr_name=None,
381+
nc_name='height_max_speed_contour',
382+
nc_type='f4',
383+
nc_dims=('Nobs',),
384+
nc_attr=dict(
385+
units='m',
386+
)
387+
),
388+
height_external_contour=dict(
389+
attr_name=None,
390+
nc_name='height_external_contour',
391+
nc_type='f4',
392+
nc_dims=('Nobs',),
393+
nc_attr=dict(
394+
units='m',
395+
)
396+
),
397+
height_inner_contour=dict(
398+
attr_name=None,
399+
nc_name='height_inner_contour',
400+
nc_type='f4',
401+
nc_dims=('Nobs',),
402+
nc_attr=dict(
403+
units='m',
404+
)
405+
),
406+
nb_contour_selected=dict(
407+
attr_name=None,
408+
nc_name='nb_contour_selected',
409+
nc_type='u2',
410+
nc_dims=('Nobs',),
411+
nc_attr=dict(
412+
units='1',
413+
)
414+
),
359415
)
360416

361417
for key in VAR_DESCR.keys():

src/py_eddy_tracker/dataset/grid.py

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
"""
33
"""
44
import logging
5-
from scipy.interpolate import interp1d
65
from numpy import concatenate, int32, empty, maximum, where, array, \
76
sin, deg2rad, pi, ones, cos, ma, int8, histogram2d, arange, float_, \
87
linspace, errstate, int_, column_stack, interp, meshgrid, unique, nan
@@ -18,6 +17,11 @@
1817
from ..eddy_feature import Amplitude, get_uavg, Contours
1918

2019

20+
def raw_resample(datas, fixed_size):
21+
nb_value = datas.shape[0]
22+
return interp(arange(fixed_size), arange(nb_value) * (fixed_size - 1) / (nb_value - 1) , datas)
23+
24+
2125
def contour_iter(self, anticyclonic_search):
2226
for coll in self.collections[::1 if anticyclonic_search else -1]:
2327
yield coll
@@ -441,7 +445,7 @@ def eddy_identification(self, grid_height, uname, vname,
441445
centlat_e = y[centi, centj]
442446

443447
# centlat_e and centlon_e must be index of maximum, we will loose some inner contour, if it's not
444-
average_speed, speed_contour, inner_contour, speed_array = \
448+
max_average_speed, speed_contour, inner_contour, speed_array, i_max_speed, i_inner = \
445449
get_uavg(self, contours, centlon_e, centlat_e, current_contour, anticyclonic_search, corrected_coll_index)
446450

447451
# Use azimuth equal projection for radius
@@ -459,13 +463,31 @@ def eddy_identification(self, grid_height, uname, vname,
459463
# Instantiate new EddyObservation object
460464
properties = EddiesObservations(
461465
size=1,
462-
track_extra_variables=['shape_error_e', 'shape_error_s'],
466+
track_extra_variables=['shape_error_e', 'shape_error_s', 'height_max_speed_contour',
467+
'height_external_contour', 'height_inner_contour', 'nb_contour_selected'],
463468
track_array_variables=array_sampling,
464-
array_variables=['contour_lon_e', 'contour_lat_e', 'contour_lon_s', 'contour_lat_s']
469+
array_variables=['contour_lon_e', 'contour_lat_e', 'contour_lon_s', 'contour_lat_s', 'uavg_profile']
465470
)
471+
472+
properties.obs['height_max_speed_contour'] = contours.cvalues[i_max_speed]
473+
properties.obs['height_external_contour'] = cvalues
474+
properties.obs['height_inner_contour'] = contours.cvalues[i_inner]
475+
array_size = speed_array.shape[0]
476+
properties.obs['nb_contour_selected'] = array_size
477+
properties.obs['uavg_profile'] = raw_resample(speed_array, array_sampling)
478+
# from matplotlib import pyplot as plt
479+
# if array_size > 10:
480+
# plt.figure()
481+
# plt.plot(linspace(properties.obs['height_external_contour'],properties.obs['height_inner_contour'], speed_array.shape[0]), speed_array, 'b')
482+
# plt.axvline(properties.obs['height_inner_contour'], color='g')
483+
# plt.axvline(properties.obs['height_max_speed_contour'], color='r')
484+
# plt.axvline(properties.obs['height_external_contour'], color='k')
485+
# plt.title('%d' % array_size)
486+
# plt.ylim(0,None)
487+
# plt.show()
466488
properties.obs['amplitude'] = amp.amplitude
467489
properties.obs['radius_s'] = eddy_radius_s / 1000
468-
properties.obs['speed_radius'] = average_speed
490+
properties.obs['speed_radius'] = max_average_speed
469491
properties.obs['radius_e'] = eddy_radius_e / 1000
470492
properties.obs['shape_error_e'] = aerr
471493
properties.obs['shape_error_s'] = aerr_s
@@ -820,5 +842,7 @@ def speed_coef(self, contour):
820842
def init_speed_coef(self, uname='u', vname='v'):
821843
"""Draft
822844
"""
823-
uspd = (self.grid(uname) ** 2 + self.grid(vname) ** 2) ** .5
824-
self._speed_ev = RectBivariateSpline(self.x_c, self.y_c, uspd, kx=1, ky=1).ev
845+
speed = (self.grid(uname) ** 2 + self.grid(vname) ** 2) ** .5
846+
# Evaluation near masked value will be smoothed to 0 !!!, not perfect
847+
speed[speed.mask] = 0
848+
self._speed_ev = RectBivariateSpline(self.x_c, self.y_c, speed, kx=1, ky=1).ev

src/py_eddy_tracker/eddy_feature.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def all_pixels_below_h0(self, level):
9898
are below a given SSH threshold for cyclonic eddies.
9999
"""
100100
sla = self.data[self.ix, self.iy]
101-
if (sla > self.h_0).any():
101+
if (sla > self.h_0).any() or (hasattr(sla, 'mask') and sla.mask.any()):
102102
return False
103103
else:
104104
self._set_local_extrema(1)
@@ -126,7 +126,7 @@ def all_pixels_above_h0(self, level):
126126
are above a given SSH threshold for anticyclonic eddies.
127127
"""
128128
sla = self.data[self.ix, self.iy]
129-
if (sla < self.h_0).any():
129+
if (sla < self.h_0).any() or (hasattr(sla, 'mask') and sla.mask.any()):
130130
# i.e.,with self.amplitude == 0
131131
return False
132132
else:
@@ -335,21 +335,25 @@ def get_uavg(grid, all_contours, centlon_e, centlat_e, original_contour, anticyc
335335
Calculate geostrophic speed around successive contours
336336
Returns the average
337337
"""
338-
average_speed = grid.speed_coef(original_contour).mean()
339-
speed_array = [average_speed]
338+
max_average_speed = grid.speed_coef(original_contour).mean()
339+
speed_array = [max_average_speed]
340340
pixel_min = 1
341341

342342
eddy_contours = [original_contour]
343343
inner_contour = selected_contour = original_contour
344344
# Must start only on upper or lower contour, no need to test the two part
345-
for coll in all_contours.iter(start=level_start + 1, step=1 if anticyclonic_search else -1):
345+
step = 1 if anticyclonic_search else -1
346+
i_inner = i_max_speed = -1
347+
348+
for i, coll in enumerate(all_contours.iter(start=level_start + step, step=step)):
346349
level_contour = coll.get_nearest_path_bbox_contain_pt(centlon_e, centlat_e)
347350
# Leave loop if no contours at level
348351
if level_contour is None:
349352
break
350-
# 1. Ensure polygon_i contains point centlon_e, centlat_e
351-
if winding_number_poly(centlon_e, centlat_e, level_contour.vertices) == 0:
352-
break
353+
# 1. Ensure polygon_i contains point centlon_e, centlat_e (Maybe we loose some inner contour if eddy
354+
# core are not centered)
355+
# if winding_number_poly(centlon_e, centlat_e, level_contour.vertices) == 0:
356+
# break
353357
# 2. Ensure polygon_i is within polygon_e
354358
if not poly_contain_poly(original_contour.vertices, level_contour.vertices):
355359
break
@@ -360,11 +364,15 @@ def get_uavg(grid, all_contours, centlon_e, centlat_e, original_contour, anticyc
360364
# Interpolate uspd to seglon, seglat, then get mean
361365
level_average_speed = grid.speed_coef(level_contour).mean()
362366
speed_array.append(level_average_speed)
363-
if level_average_speed >= average_speed:
364-
average_speed = level_average_speed
367+
if level_average_speed >= max_average_speed:
368+
max_average_speed = level_average_speed
369+
i_max_speed = i
365370
selected_contour = level_contour
366371
inner_contour = level_contour
367372
eddy_contours.append(level_contour)
373+
i_inner = i
368374
for contour in eddy_contours:
369375
contour.used = True
370-
return average_speed, selected_contour, inner_contour, speed_array
376+
i_max_speed = level_start + step + step * i_max_speed
377+
i_inner = level_start + step + step * i_inner
378+
return max_average_speed, selected_contour, inner_contour, array(speed_array), i_max_speed, i_inner

src/py_eddy_tracker/observations.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ def load_from_netcdf(cls, filename):
356356
if variable == 'cyc':
357357
continue
358358
var_inv = VAR_DESCR_inv[variable]
359-
if var_inv not in cls.ELEMENTS and var_inv not in kwargs['array_variables']:
359+
if var_inv not in cls.ELEMENTS and var_inv not in kwargs.get('array_variables', list()):
360360
kwargs['track_extra_variables'].append(var_inv)
361361

362362
eddies = cls(size=nb_obs, ** kwargs)
@@ -366,6 +366,9 @@ def load_from_netcdf(cls, filename):
366366
eddies.obs[VAR_DESCR_inv[variable]
367367
] = h_nc.variables[variable][:]
368368
eddies.sign_type = h_nc.variables['cyc'][0]
369+
if eddies.sign_type == 0:
370+
logging.info('File come from another algorithm')
371+
eddies.sign_type = -1
369372
return eddies
370373

371374
@classmethod

0 commit comments

Comments
 (0)