2424
2525make_eddy_track_AVISO.py
2626
27- Version 1.4.1
27+ Version 1.4.2
2828
2929
3030Scroll down to line ~640 to get started
@@ -250,6 +250,7 @@ def get_AVISO_f_pm_pn(self):
250250 self._gof *= 4.
251251 self._gof *= np.pi
252252 self._gof /= 86400.
253+ self._f = np.copy(self._gof)
253254 self._gof = self.gravity / self._gof
254255
255256 lonu = self.half_interp(self.lonpad()[:,:-1], self.lonpad()[:,1:])
@@ -306,6 +307,34 @@ def vv2vr(vv_in, Mp, Lp):
306307 return vv2vr(vv_in, Mshp + 1, Lshp)
307308
308309
310+ def rho2u_2d(self, rho_in):
311+ '''
312+ Convert a 2D field at rho points to a field at u points
313+ '''
314+ def _r2u(rho_in, Lp):
315+ u_out = rho_in[:, :Lp - 1]
316+ u_out += rho_in[:, 1:Lp]
317+ u_out *= 0.5
318+ return np.squeeze(u_out)
319+ assert rho_in.ndim == 2, 'rho_in must be 2d'
320+ Mshp, Lshp = rho_in.shape
321+ return _r2u(rho_in, Lshp)
322+
323+
324+ def rho2v_2d(self, rho_in):
325+ '''
326+ Convert a 2D field at rho points to a field at v points
327+ '''
328+ def _r2v(rho_in, Mp):
329+ v_out = rho_in[:Mp - 1]
330+ v_out += rho_in[1:Mp]
331+ v_out *= 0.5
332+ return np.squeeze(v_out)
333+ assert rho_in.ndim == 2, 'rho_in must be 2d'
334+ Mshp, Lshp = rho_in.shape
335+ return _r2v(rho_in, Mshp)
336+
337+
309338 def uvmask(self):
310339 '''
311340 Get mask at U and V points
@@ -579,6 +608,9 @@ def umask(self): # Mask at U points
579608 def vmask(self): # Mask at V points
580609 return self._vmask
581610
611+ def f(self): # Coriolis
612+ return self._f
613+
582614 def gof(self): # Gravity / Coriolis
583615 return self._gof
584616
@@ -725,15 +757,16 @@ def pcol_2dxy(self, x, y):
725757 date_str, date_end = 19930101, 20121231 #
726758
727759 # Choose type of diagnostic: either q-parameter ('Q') or sea level anomaly ('sla')
728- # diag_type = 'Q' <<< not implemented in 1.2.0
729- diag_type = 'sla'
760+ diag_type = 'Q' # <<< not implemented in 1.2.0
761+ # diag_type = 'sla'
730762
731763
732764 # Path to directory where outputs are to be saved...
733765 #savedir = directory
734766 #savedir = '/marula/emason/aviso_eddy_tracking/pablo_exp/'
735- savedir = '/marula/emason/aviso_eddy_tracking/new_AVISO_test/'
736- #savedir = '/marula/emason/aviso_eddy_tracking/junk/'
767+ #savedir = '/marula/emason/aviso_eddy_tracking/new_AVISO_test/'
768+ #savedir = '/marula/emason/aviso_eddy_tracking/new_AVISO_SUBSAMP-3days/'
769+ savedir = '/marula/emason/aviso_eddy_tracking/junk/'
737770 #savedir = '/marula/emason/aviso_eddy_tracking/new_AVISO_test/BlackSea/'
738771 #savedir = '/path/to/save/your/outputs/'
739772
@@ -748,17 +781,15 @@ def pcol_2dxy(self, x, y):
748781 # Reference Julian day (Julian date at Jan 1, 1992)
749782 jday_ref = 2448623
750783
751- # Min and max permitted eddy radii [m]
784+ # Min and max permitted eddy radii [degrees]
785+ radmin = 0.4 # degrees (Chelton recommends ~50 km minimum)
786+ radmax = 4.461 # degrees
787+
752788 if 'Q' in diag_type:
753- Exception # Not implemented
754- radmin = 15000.
755- radmax = 250000.
756- ampmin = 0.02
789+ ampmin = 0.02 # max(abs(xi/f)) within the eddy
757790 ampmax = 100.
758791
759792 elif 'sla' in diag_type:
760- radmin = 0.4 # degrees (Chelton recommends ~50 km minimum)
761- radmax = 4.461 # degrees
762793 ampmin = 1. # cm
763794 ampmax = 150.
764795
@@ -773,11 +804,12 @@ def pcol_2dxy(self, x, y):
773804
774805
775806 # Define contours
807+ # Set Q contour spacing
776808 if 'Q' in diag_type:
777- # Set Q contour spacing
778- qparameter = np.linspace(0, 5*10**-11, 25)
809+ qparameter = np.linspace(0, 5*10**-11, 100)
810+
811+ # Set SLA contour spacing
779812 elif 'sla' in diag_type:
780- # Set SLA contour spacing
781813 #slaparameter = np.arange(-100., 101., 1.0) # cm
782814 slaparameter = np.arange(-100., 100.25, 0.25) # cm
783815
@@ -802,10 +834,10 @@ def pcol_2dxy(self, x, y):
802834 subdomain = True
803835 if the_domain in 'Global':
804836
805- lonmin = -36 . # Canary
837+ lonmin = -40 . # Canary
806838 lonmax = -5.5
807- latmin = 18 .
808- latmax = 35 .5
839+ latmin = 16 .
840+ latmax = 36 .5
809841
810842 #lonmin = -30. # BENCS
811843 #lonmax = 22.
@@ -884,7 +916,7 @@ def pcol_2dxy(self, x, y):
884916 # - shape test values
885917 # - profiles of swirl velocity from effective contour inwards
886918 # Useful for working with ARGO data
887- track_extra_variables = True
919+ track_extra_variables = False
888920
889921
890922
@@ -921,10 +953,11 @@ def pcol_2dxy(self, x, y):
921953 # The shape error can maybe be played with...
922954 shape_err = np.power(np.linspace(85., 40, qparameter.size), 2) / 100.
923955 shape_err[shape_err < 35.] = 35.
956+ hanning_passes = 5
924957
925958 elif 'sla' in diag_type:
926- shape_err = 55. * np.ones(slaparameter.size)
927- # shape_err = 1000. * np.ones(slaparameter.size)
959+ # shape_err = 55. * np.ones(slaparameter.size)
960+ shape_err = 1000. * np.ones(slaparameter.size)
928961 #shape_err = np.power(np.linspace(85., 40, slaparameter.size), 2) / 100.
929962 #shape_err[shape_err < 50.] = 50.
930963
@@ -1112,120 +1145,87 @@ def pcol_2dxy(self, x, y):
11121145
11131146 #grdmask = grd.mask()[j0:j1,i0:i1]
11141147
1148+ sla = sla_grd.get_AVISO_data(AVISO_file)
1149+
1150+ if isinstance(smoothing, str):
1151+
1152+ if 'Gaussian' in smoothing:
1153+ if 'first_record' not in locals():
1154+ print '------ applying Gaussian high-pass filter'
1155+ # Set landpoints to zero
1156+ np.place(sla, sla_grd.mask == False, 0.)
1157+ np.place(sla, sla.data == sla_grd.fillval, 0.)
1158+ # High pass filter, see
1159+ # http://stackoverflow.com/questions/6094957/high-pass-filter-for-image-processing-in-python-by-using-scipy-numpy
1160+ sla -= ndimage.gaussian_filter(sla, [mres, zres])
1161+ elif 'Hanning' in smoothing:
1162+ print '------ applying %s passes of Hanning filter' %smooth_fac
1163+ # Do smooth_fac passes of 2d Hanning filter
1164+ sla = func_hann2d_fast(sla, smooth_fac)
1165+
1166+
1167+ # Expand the landmask
1168+ sla = np.ma.masked_where(sla_grd.mask == False, sla)
1169+
1170+ # Get timing
1171+ try:
1172+ thedate = dt.num2date(rtime)[0]
1173+ except:
1174+ thedate = dt.num2date(rtime)
1175+ yr = thedate.year
1176+ mo = thedate.month
1177+ da = thedate.day
1178+
1179+ # Multiply by 0.01 for m
1180+ sla_grd.get_geostrophic_velocity(sla * 0.01)
1181+
1182+ # Remove padded boundary
1183+ sla = sla[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
1184+ #u = sla_grd.u[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
1185+ #v = sla_grd.v[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
1186+
1187+ # Calculate EKE
1188+ sla_grd.getEKE()
1189+
1190+
11151191 if 'Q' in diag_type:
1116- u, v, temp, salt, rtime = get_ROMS_data(filename, pad, record, sigma_lev,
1117- ip0, ip1, jp0, jp1, diag_type)
1118- # Sort out masking (important for subsurface fields)
1119- u = np.ma.masked_outside(u, -10., 10.)
1120- v = np.ma.masked_outside(v, -10., 10.)
1121-
1122- u.data[u.mask] = 0.
1123- v.data[v.mask] = 0.
1124- u = u.data
1125- v = v.data
1126-
1127- okubo, xi = okubo_weiss(u, v, grd.pm()[jp0:jp1,
1128- ip0:ip1],
1129- grd.pn()[jp0:jp1,
1130- ip0:ip1])
1192+
1193+ okubo, xi = okubo_weiss(sla_grd)
11311194
11321195 qparam = np.ma.multiply(-0.25, okubo) # see Kurian etal 2011
11331196
1134- # Remove padded boundary
1135- qparam = qparam[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
1136- xi = xi[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
1137- u = u[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
1138- v = v[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
1139-
1140- u = u2rho_2d(u)
1141- v = v2rho_2d(v)
1197+ #u = u[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
1198+ #v = v[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
1199+ #u = u2rho_2d(u)
1200+ #v = v2rho_2d(v)
11421201
1143- if 'smoothing' in locals():
1144-
1145- if 'Gaussian' in smoothing:
1146- qparam = ndimage.gaussian_filter(qparam, smooth_fac, 0)
1147-
1148- elif 'Hanning' in smoothing:
1149- # smooth_fac passes of 2d Hanning filter
1150- #han_time = time.time()
1151- qparam = func_hann2d_fast(qparam, smooth_fac)
1152- #print 'hanning', str(time.time() - han_time), ' seconds!'
1153- xi = func_hann2d_fast(xi, smooth_fac)
1202+ qparam = func_hann2d_fast(qparam, hanning_passes)
1203+ #xi = func_hann2d_fast(xi, hanning_passes)
11541204
11551205 # Set Q over land to zero
1156- qparam *= sla_grd.mask
1206+ qparam *= sla_grd.mask[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
11571207 #qparam = np.ma.masked_where(grdmask == False, qparam)
1158- xi *= sla_grd.mask
1159- xi = np.ma.masked_where(sla_grd.mask == False,
1160- xi / grd.f()[j0:j1,i0:i1])
1208+ xi *= sla_grd.mask[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
1209+ xi = np.ma.masked_where(sla_grd.mask[sla_grd.jup0:sla_grd.jup1,
1210+ sla_grd.iup0:sla_grd.iup1] == False,
1211+ xi / sla_grd.f()[sla_grd.jup0:sla_grd.jup1,
1212+ sla_grd.iup0:sla_grd.iup1])
1213+ # Remove padded boundary
1214+ #qparam = qparam[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
1215+ #xi = xi[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
11611216 xicopy = np.ma.copy(xi)
11621217
1163-
11641218 elif 'sla' in diag_type:
1165-
1166- sla = sla_grd.get_AVISO_data(AVISO_file)
1167-
1168- if isinstance(smoothing, str):
1169-
1170- if 'Gaussian' in smoothing:
1171- if 'first_record' not in locals():
1172- print '------ applying Gaussian high-pass filter'
1173- # Set landpoints to zero
1174- np.place(sla, sla_grd.mask == False, 0.)
1175- np.place(sla, sla.data == sla_grd.fillval, 0.)
1176- # High pass filter, see
1177- # http://stackoverflow.com/questions/6094957/high-pass-filter-for-image-processing-in-python-by-using-scipy-numpy
1178- #print 'start smoothing'
1179- sla -= ndimage.gaussian_filter(sla, [mres, zres])
1180- #print 'end smoothing'
1181- elif 'Hanning' in smoothing:
1182- print '------ applying %s passes of Hanning filter' %smooth_fac
1183- # Do smooth_fac passes of 2d Hanning filter
1184- sla = func_hann2d_fast(sla, smooth_fac)
1185-
1186-
1187- # Expand the landmask
1188- sla = np.ma.masked_where(sla_grd.mask == False, sla)
1189-
1190- # Get timing
1191- #ymd = rtime.split(' ')[0].split('-')
1192- #yr, mo, da = np.int(ymd[0]), np.int(ymd[1]), np.int(ymd[2])
1193- #rtime = dt.date2num(dt.datetime.datetime(yr, mo, da))
1194- try:
1195- thedate = dt.num2date(rtime)[0]
1196- except:
1197- thedate = dt.num2date(rtime)
1198- yr = thedate.year
1199- mo = thedate.month
1200- da = thedate.day
1201-
1202- #if sla.mask.size > 1:
1203- #umask, vmask, junk = sla_grd.uvpmask(-sla.mask)
1204- #else:
1205- #umask, vmask, junk = sla_grd.uvpmask(np.zeros_like(sla))
1206-
1207- # Multiply by 0.01 for m
1208- sla_grd.get_geostrophic_velocity(sla * 0.01)
1209-
1210- # Remove padded boundary
1211- sla = sla[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
1212- #u = sla_grd.u[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
1213- #v = sla_grd.v[sla_grd.jup0:sla_grd.jup1, sla_grd.iup0:sla_grd.iup1]
1214-
1215- # Calculate EKE
1216- sla_grd.getEKE()
1217-
1219+
12181220 A_eddy.sla = np.ma.copy(sla)
12191221 C_eddy.sla = np.ma.copy(sla)
12201222 A_eddy.slacopy = np.ma.copy(sla)
12211223 C_eddy.slacopy = np.ma.copy(sla)
1222-
1223-
1224+
12241225 # Get scalar speed
12251226 Uspd = np.hypot(sla_grd.u, sla_grd.v)
12261227 Uspd = np.ma.masked_where(sla_grd.mask[sla_grd.jup0:sla_grd.jup1,
12271228 sla_grd.iup0:sla_grd.iup1] == False, Uspd)
1228-
12291229 A_eddy.Uspd = np.ma.copy(Uspd)
12301230 C_eddy.Uspd = np.ma.copy(Uspd)
12311231
@@ -1274,18 +1274,18 @@ def pcol_2dxy(self, x, y):
12741274
12751275
12761276 # Now we loop over the CS collection
1277+ A_eddy.sign_type = 'Anticyclonic'
1278+ C_eddy.sign_type = 'Cyclonic'
12771279 if 'Q' in diag_type:
12781280 A_eddy, C_eddy = collection_loop(CS, sla_grd, rtime,
12791281 A_list_obj=A_eddy, C_list_obj=C_eddy,
12801282 xi=xi, CSxi=CSxi, verbose=verbose)
12811283
12821284 elif 'sla' in diag_type:
1283- A_eddy.sign_type = 'Anticyclonic'
12841285 A_eddy = collection_loop(A_CS, sla_grd, rtime,
12851286 A_list_obj=A_eddy, C_list_obj=None,
12861287 sign_type=A_eddy.sign_type, verbose=verbose)
12871288 # Note that C_CS is reverse order
1288- C_eddy.sign_type = 'Cyclonic'
12891289 C_eddy = collection_loop(C_CS, sla_grd, rtime,
12901290 A_list_obj=None, C_list_obj=C_eddy,
12911291 sign_type=C_eddy.sign_type, verbose=verbose)
@@ -1349,10 +1349,14 @@ def pcol_2dxy(self, x, y):
13491349 #anim_fig.join()
13501350
13511351 if 'Q' in diag_type:
1352- anim_fig = threading.Thread(name='anim_figure', target=anim_figure,
1353- args=(33, M, pMx, pMy, xicopy, cmap, rtime, diag_type, Mx, My,
1354- xi.copy(), qparam.copy(), qparameter, A_eddy, C_eddy,
1355- savedir, plt, 'Q ' + tit))
1352+ #anim_fig = threading.Thread(name='anim_figure', target=anim_figure,
1353+ #args=(33, M, pMx, pMy, xicopy, cmap, rtime, diag_type, Mx, My,
1354+ #xi.copy(), qparam.copy(), qparameter, A_eddy, C_eddy,
1355+ #savedir, plt, 'Q ' + tit))
1356+ anim_figure(A_eddy, C_eddy, Mx, My, pMx, pMy, plt.cm.RdBu_r, rtime, diag_type,
1357+ savedir, 'Q-parameter ' + tit, animax, animax_cbar,
1358+ qparam=qparam, qparameter=qparameter, xi=xi, xicopy=xicopy)
1359+
13561360 elif 'sla' in diag_type:
13571361 '''anim_fig = threading.Thread(name='anim_figure', target=anim_figure,
13581362 args=(33, M, pMx, pMy, slacopy, plt.cm.RdBu_r, rtime, diag_type, Mx, My,
0 commit comments