Skip to content

Commit d9e5fc7

Browse files
committed
Several optimisations:
Removed .flat[] calls Interpolations now with RectBivariateSpline Rewritten find_nearest_contour function from mpl
1 parent fa4833f commit d9e5fc7

File tree

3 files changed

+215
-50
lines changed

3 files changed

+215
-50
lines changed

make_eddy_track_AVISO.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,10 +486,12 @@ def __init__(self, AVISO_file, lonmin, lonmax, latmin, latmax, with_pad=True, us
486486
self.fillval = self.read_nc_att(AVISO_file, 'sla', '_FillValue')
487487
base_date = self.read_nc_att(AVISO_file, 'time', 'units')
488488
self.base_date = dt.date2num(parser.parse(base_date.split(' ')[2:4][0]))
489+
489490
except Exception: # old AVISO
490491
self._lon = self.read_nc(AVISO_file, 'NbLongitudes')
491492
self._lat = self.read_nc(AVISO_file, 'NbLatitudes')
492493
self.fillval = self.read_nc_att(AVISO_file, 'Grid_0001', '_FillValue')
494+
493495
if np.logical_and(lonmin < 0, lonmax <=0):
494496
self._lon -= 360.
495497
self._lon, self._lat = np.meshgrid(self._lon, self._lat)
@@ -510,6 +512,7 @@ def get_AVISO_data(self, AVISO_file):
510512
Read nc data from AVISO file
511513
'''
512514
if self.zero_crossing:
515+
513516
try: # new AVISO (2014)
514517
ssh1 = self.read_nc(AVISO_file, 'sla',
515518
indices='[:, self.jp0:self.jp1, :self.ip0]')
@@ -518,18 +521,23 @@ def get_AVISO_data(self, AVISO_file):
518521
ssh0, ssh1 = ssh0.squeeze(), ssh1.squeeze()
519522
ssh0 *= 100. # m to cm
520523
ssh1 *= 100. # m to cm
524+
521525
except Exception: # old AVISO
522526
ssh1 = self.read_nc(AVISO_file, 'Grid_0001',
523527
indices='[:self.ip0, self.jp0:self.jp1]').T
524528
ssh0 = self.read_nc(AVISO_file, 'Grid_0001',
525529
indices='[self.ip1:,self.jp0:self.jp1]').T
530+
526531
zeta = np.ma.concatenate((ssh0, ssh1), axis=1)
532+
527533
else:
534+
528535
try: # new AVISO (2014)
529536
zeta = self.read_nc(AVISO_file, 'sla',
530537
indices='[:, self.jp0:self.jp1, self.ip0:self.ip1]')
531538
zeta = zeta.squeeze()
532539
zeta *= 100. # m to cm
540+
533541
except Exception: # old AVISO
534542
zeta = self.read_nc(AVISO_file, 'Grid_0001',
535543
indices='[self.ip0:self.ip1, self.jp0:self.jp1]').T
@@ -799,10 +807,11 @@ def pcol_2dxy(self, x, y):
799807
#savedir = '/marula/emason/aviso_eddy_tracking/pablo_exp/'
800808
#savedir = '/marula/emason/aviso_eddy_tracking/new_AVISO_test/'
801809
#savedir = '/marula/emason/aviso_eddy_tracking/new_AVISO_SUBSAMP-3days/'
802-
#savedir = '/marula/emason/aviso_eddy_tracking/junk/'
810+
savedir = '/marula/emason/aviso_eddy_tracking/junk/'
803811
#savedir = '/marula/emason/aviso_eddy_tracking/new_AVISO_test/BlackSea/'
804812
#savedir = '/marula/emason/aviso_eddy_tracking/Corridor_V3_Dec2014/'
805-
savedir = '/marula/emason/aviso_eddy_tracking/CLS_test_1_acd66ba338a9/'
813+
#savedir = '/marula/emason/aviso_eddy_tracking/CLS_test_1_acd66ba338a9/'
814+
#savedir = '/marula/emason/aviso_eddy_tracking/CLS_test_2/'
806815
#savedir = '/path/to/save/your/outputs/'
807816

808817

make_eddy_tracker_list_obj.py

Lines changed: 116 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def nearest(lon_pt, lat_pt, lon2d, lat2d):
8080
return i, j
8181

8282

83-
def uniform_resample(x, y, num_fac=4, kind='linear'):
83+
def uniform_resample(x, y, num_fac=2, kind='linear'):
8484
'''
8585
Resample contours to have (nearly) equal spacing
8686
'''
@@ -89,6 +89,7 @@ def uniform_resample(x, y, num_fac=4, kind='linear'):
8989
##x = ndimage.zoom(x.copy(), 2)
9090
##y = ndimage.zoom(y.copy(), 2)
9191
#plt.plot(x, y, '.-r', lw=2)
92+
9293
# Get distances
9394
d = np.r_[0, np.cumsum(haversine_distance_vector(x[:-1],y[:-1], x[1:],y[1:]))]
9495
# Get uniform distances
@@ -98,7 +99,15 @@ def uniform_resample(x, y, num_fac=4, kind='linear'):
9899
yfunc = interpolate.interp1d(d, y, kind=kind)
99100
xnew = xfunc(d_uniform)
100101
ynew = yfunc(d_uniform)
101-
#plt.plot(xnew, ynew, '.-r', lw=2)
102+
103+
# Akima is slightly slower, but may be more accurate
104+
#xfunc = interpolate.Akima1DInterpolator(d, x)
105+
#yfunc = interpolate.Akima1DInterpolator(d, y)
106+
#xxnew = xfunc(d_uniform)
107+
#yynew = yfunc(d_uniform)
108+
109+
#plt.plot(xnew, ynew, '.-r', lw=1.5)
110+
#plt.plot(xxnew, yynew, '+-b', lw=1.)
102111
#plt.axis('image')
103112
#plt.show()
104113
return xnew, ynew
@@ -107,7 +116,104 @@ def uniform_resample(x, y, num_fac=4, kind='linear'):
107116
def strcompare(str1, str2):
108117
return str1 in str2 and str2 in str1
109118

110-
119+
120+
121+
122+
123+
124+
125+
def _find_closest_point_on_leg(p1, p2, p0):
126+
"""find closest point to p0 on line segment connecting p1 and p2"""
127+
128+
# handle degenerate case
129+
if np.all(p2 == p1):
130+
d = p0 - p1
131+
d **= 2
132+
return d.sum()
133+
134+
d21 = p2 - p1
135+
d01 = p0 - p1
136+
137+
# project on to line segment to find closest point
138+
proj = np.dot(d01, d21)
139+
proj /= np.dot(d21, d21)
140+
if proj < 0:
141+
proj = 0
142+
elif proj > 1:
143+
proj = 1
144+
pc = p1 + proj * d21
145+
146+
# find squared distance
147+
d = pc - p0
148+
d **= 2
149+
150+
return d.sum()#, pc
151+
152+
153+
def _find_closest_point_on_path(lc, point):
154+
"""
155+
lc: coordinates of vertices
156+
point: coordinates of test point
157+
"""
158+
# Find index of closest vertex for this segment
159+
ds = np.sum((lc - point[None, :])**2, 1)
160+
imin = ds.argmin()
161+
162+
dmin = np.inf
163+
closed = np.alltrue([lc[0,0] == lc[-1,0], lc[0,1] == y[-1,1]])
164+
165+
# Build list of legs before and after this vertex
166+
legs = []
167+
if imin > 0 or closed:
168+
legs.append(((imin-1) % len(lc), imin))
169+
if imin < len(lc) - 1 or closed:
170+
legs.append((imin, (imin+1) % len(lc)))
171+
172+
for leg in legs:
173+
#d, xc = _find_closest_point_on_leg(lc[leg[0]], lc[leg[1]], point)
174+
d = _find_closest_point_on_leg(lc[leg[0]], lc[leg[1]], point)
175+
if d < dmin:
176+
dmin = d
177+
178+
return dmin
179+
180+
181+
def find_nearest_contour(cont_coll, x, y, indices):
182+
"""
183+
Finds contour that is closest to a point.
184+
185+
Returns a tuple containing the contour, segment of minimum point.
186+
187+
Call signature::
188+
189+
conmin, segmin = find_nearest_contour(cont_coll, x, y, indices)
190+
"""
191+
dmin = np.inf
192+
conmin = None
193+
segmin = None
194+
195+
point = np.array([x, y])
196+
197+
for icon in indices:
198+
con = cont_coll.collections[icon]
199+
paths = con.get_paths()
200+
201+
for segNum, linepath in enumerate(paths):
202+
lc = linepath.vertices
203+
d = _find_closest_point_on_path(lc, point)
204+
205+
if d < dmin:
206+
dmin = d
207+
conmin = icon
208+
segmin = segNum
209+
210+
return conmin, segmin
211+
212+
213+
214+
215+
216+
111217

112218

113219

@@ -1087,7 +1193,7 @@ def _set_global_ellipse(self):
10871193
ew_x = np.hstack((e_verts[:e_size,0], w_verts[w_size:,0]))
10881194
ew_y = np.hstack((e_verts[:e_size,1], w_verts[w_size:,1]))
10891195
self.ellipse_path = path.Path(np.array([ew_x, ew_y]).T)
1090-
return self.ellipse_path
1196+
return self#.ellipse_path
10911197

10921198
def _set_black_sea_ellipse(self):
10931199
'''
@@ -1097,13 +1203,14 @@ def _set_black_sea_ellipse(self):
10971203
verts = self.black_sea_ellipse.get_verts()
10981204
self.ellipse_path = path.Path(np.array([verts[:,0],
10991205
verts[:,1]]).T)
1100-
1206+
return self
11011207

11021208
def get_search_ellipse(self, x, y):
11031209
'''
11041210
'''
11051211
self.x = x
11061212
self.y = y
1213+
11071214
if self.domain in ('Global', 'ROMS'):
11081215
self.rw_d[:] = self.rwv.get_rwdistance(x, y, self.days_btwn_recs)
11091216
self.rw_d_mod[:] = 1.75
@@ -1118,8 +1225,10 @@ def get_search_ellipse(self, x, y):
11181225
self.rw_d_mod *= self.rw_d
11191226
self._set_black_sea_ellipse()
11201227

1121-
else: Exception
1122-
1228+
else:
1229+
Exception
1230+
1231+
return self
11231232

11241233
def view_search_ellipse(self, Eddy):
11251234
'''

0 commit comments

Comments
 (0)