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