Skip to content

Commit 24bafd0

Browse files
author
adelepoulle
committed
Add a function to search with ellipsoid
1 parent e6c6fcf commit 24bafd0

File tree

1 file changed

+51
-10
lines changed

1 file changed

+51
-10
lines changed

src/py_eddy_tracker/observations.py

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@
2929
3030
"""
3131
from numpy import zeros, empty, nan, arange, interp, where, unique, \
32-
ma, concatenate
32+
ma, concatenate, cos, radians, isnan
3333
from netCDF4 import Dataset
34-
from py_eddy_tracker.tools import distance_matrix
34+
from py_eddy_tracker.tools import distance_matrix, distance_vector
3535
from shapely.geometry import Polygon
3636
from shapely.geos import TopologicalError
3737
from . import VAR_DESCR, VAR_DESCR_inv
@@ -280,27 +280,68 @@ def cost_function(self, records_in, records_out, distance):
280280
cost += (distance / 125) ** 2
281281
cost **= 0.5
282282
# Mask value superior at 60 % of variation
283-
return ma.array(cost, mask=cost > 0.6)
283+
# return ma.array(cost, mask=cost > 0.6)
284+
return cost
285+
286+
def circle_mask(self, other, radius=100):
287+
"""Return a mask of available link"""
288+
return self.distance(other) < radius
289+
290+
def fixed_ellipsoid_mask(self, other, minor=50, major=100, only_east=False):
291+
dist = self.distance(other)
292+
accepted = dist < minor
293+
rejected = dist > major
294+
rejected += isnan(dist)
295+
296+
# All obs we are not in rejected and accepted, there are between
297+
# two circle
298+
needs_investigation = - (rejected + accepted)
299+
index_self, index_other = where(needs_investigation)
300+
301+
nb_case = index_self.shape[0]
302+
if nb_case != 0:
303+
c_degree = ((major ** 2 - minor ** 2) ** .5) / (111.3 * cos(radians(self.obs['lat'][index_self])))
304+
305+
lon_self = self.obs['lon'][index_self]
306+
lon_left_f = lon_self - c_degree
307+
lon_right_f = lon_self + c_degree
308+
309+
dist_left_f = empty(nb_case, dtype='f8') + nan
310+
distance_vector(
311+
lon_left_f, self.obs['lat'][index_self],
312+
other.obs['lon'][index_other], other.obs['lat'][index_other],
313+
dist_left_f)
314+
dist_right_f = empty(nb_case, dtype='f8') + nan
315+
distance_vector(
316+
lon_right_f, self.obs['lat'][index_self],
317+
other.obs['lon'][index_other], other.obs['lat'][index_other],
318+
dist_right_f)
319+
dist_2a = (dist_left_f + dist_right_f) / 1000
320+
321+
accepted[index_self, index_other] = dist_2a < (2 * major)
322+
if only_east:
323+
d_lon = (other.obs['lon'][index_other] - lon_self + 180) % 360 - 180
324+
mask = d_lon < 0
325+
accepted[index_self[mask], index_other[mask]] = False
326+
return accepted
284327

285328
def tracking(self, other):
286329
"""Track obs between self and other
287330
"""
288331
dist = self.distance(other)
289332
# Links available which are close (circle area selection)
290-
mask_accept_dist = dist < 125
333+
mask_accept_dist = self.circle_mask(other, radius=125)
334+
# mask_accept_dist = self.fixed_ellipsoid_mask(other)
291335
indexs_closest = where(mask_accept_dist)
292-
cost_values = self.cost_function2(
336+
337+
cost_values = self.cost_function(
293338
self.obs[indexs_closest[0]],
294339
other.obs[indexs_closest[1]],
295340
dist[mask_accept_dist])
296341

297-
cost_mat = ma.empty(dist.shape, dtype='f4')
342+
cost_mat = ma.empty(mask_accept_dist.shape, dtype='f4')
298343
cost_mat.mask = -mask_accept_dist
299344
cost_mat[mask_accept_dist] = cost_values
300-
# Links available which respect a maximal cost
301-
# cost = dist
302-
# mask_accept_cost = cost < 100
303-
# cost = ma.array(cost, mask=-mask_accept_cost, dtype='i2')
304345

305346
mask_accept_cost = -cost_mat.mask
306347
cost = cost_mat

0 commit comments

Comments
 (0)