24
24
25
25
make_eddy_track_AVISO.py
26
26
27
- Version 1.4.1
27
+ Version 1.4.2
28
28
29
29
30
30
Scroll down to line ~640 to get started
@@ -250,6 +250,7 @@ def get_AVISO_f_pm_pn(self):
250
250
self ._gof *= 4.
251
251
self ._gof *= np .pi
252
252
self ._gof /= 86400.
253
+ self ._f = np .copy (self ._gof )
253
254
self ._gof = self .gravity / self ._gof
254
255
255
256
lonu = self .half_interp (self .lonpad ()[:,:- 1 ], self .lonpad ()[:,1 :])
@@ -306,6 +307,34 @@ def vv2vr(vv_in, Mp, Lp):
306
307
return vv2vr (vv_in , Mshp + 1 , Lshp )
307
308
308
309
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
+
309
338
def uvmask (self ):
310
339
'''
311
340
Get mask at U and V points
@@ -579,6 +608,9 @@ def umask(self): # Mask at U points
579
608
def vmask (self ): # Mask at V points
580
609
return self ._vmask
581
610
611
+ def f (self ): # Coriolis
612
+ return self ._f
613
+
582
614
def gof (self ): # Gravity / Coriolis
583
615
return self ._gof
584
616
@@ -725,15 +757,16 @@ def pcol_2dxy(self, x, y):
725
757
date_str , date_end = 19930101 , 20121231 #
726
758
727
759
# 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'
730
762
731
763
732
764
# Path to directory where outputs are to be saved...
733
765
#savedir = directory
734
766
#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/'
737
770
#savedir = '/marula/emason/aviso_eddy_tracking/new_AVISO_test/BlackSea/'
738
771
#savedir = '/path/to/save/your/outputs/'
739
772
@@ -748,17 +781,15 @@ def pcol_2dxy(self, x, y):
748
781
# Reference Julian day (Julian date at Jan 1, 1992)
749
782
jday_ref = 2448623
750
783
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
+
752
788
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
757
790
ampmax = 100.
758
791
759
792
elif 'sla' in diag_type :
760
- radmin = 0.4 # degrees (Chelton recommends ~50 km minimum)
761
- radmax = 4.461 # degrees
762
793
ampmin = 1. # cm
763
794
ampmax = 150.
764
795
@@ -773,11 +804,12 @@ def pcol_2dxy(self, x, y):
773
804
774
805
775
806
# Define contours
807
+ # Set Q contour spacing
776
808
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
779
812
elif 'sla' in diag_type :
780
- # Set SLA contour spacing
781
813
#slaparameter = np.arange(-100., 101., 1.0) # cm
782
814
slaparameter = np .arange (- 100. , 100.25 , 0.25 ) # cm
783
815
@@ -802,10 +834,10 @@ def pcol_2dxy(self, x, y):
802
834
subdomain = True
803
835
if the_domain in 'Global' :
804
836
805
- lonmin = - 36 . # Canary
837
+ lonmin = - 40 . # Canary
806
838
lonmax = - 5.5
807
- latmin = 18 .
808
- latmax = 35 .5
839
+ latmin = 16 .
840
+ latmax = 36 .5
809
841
810
842
#lonmin = -30. # BENCS
811
843
#lonmax = 22.
@@ -884,7 +916,7 @@ def pcol_2dxy(self, x, y):
884
916
# - shape test values
885
917
# - profiles of swirl velocity from effective contour inwards
886
918
# Useful for working with ARGO data
887
- track_extra_variables = True
919
+ track_extra_variables = False
888
920
889
921
890
922
@@ -921,10 +953,11 @@ def pcol_2dxy(self, x, y):
921
953
# The shape error can maybe be played with...
922
954
shape_err = np .power (np .linspace (85. , 40 , qparameter .size ), 2 ) / 100.
923
955
shape_err [shape_err < 35. ] = 35.
956
+ hanning_passes = 5
924
957
925
958
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 )
928
961
#shape_err = np.power(np.linspace(85., 40, slaparameter.size), 2) / 100.
929
962
#shape_err[shape_err < 50.] = 50.
930
963
@@ -1112,120 +1145,87 @@ def pcol_2dxy(self, x, y):
1112
1145
1113
1146
#grdmask = grd.mask()[j0:j1,i0:i1]
1114
1147
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
+
1115
1191
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 )
1131
1194
1132
1195
qparam = np .ma .multiply (- 0.25 , okubo ) # see Kurian etal 2011
1133
1196
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)
1142
1201
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)
1154
1204
1155
1205
# 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 ]
1157
1207
#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]
1161
1216
xicopy = np .ma .copy (xi )
1162
1217
1163
-
1164
1218
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
+
1218
1220
A_eddy .sla = np .ma .copy (sla )
1219
1221
C_eddy .sla = np .ma .copy (sla )
1220
1222
A_eddy .slacopy = np .ma .copy (sla )
1221
1223
C_eddy .slacopy = np .ma .copy (sla )
1222
-
1223
-
1224
+
1224
1225
# Get scalar speed
1225
1226
Uspd = np .hypot (sla_grd .u , sla_grd .v )
1226
1227
Uspd = np .ma .masked_where (sla_grd .mask [sla_grd .jup0 :sla_grd .jup1 ,
1227
1228
sla_grd .iup0 :sla_grd .iup1 ] == False , Uspd )
1228
-
1229
1229
A_eddy .Uspd = np .ma .copy (Uspd )
1230
1230
C_eddy .Uspd = np .ma .copy (Uspd )
1231
1231
@@ -1274,18 +1274,18 @@ def pcol_2dxy(self, x, y):
1274
1274
1275
1275
1276
1276
# Now we loop over the CS collection
1277
+ A_eddy .sign_type = 'Anticyclonic'
1278
+ C_eddy .sign_type = 'Cyclonic'
1277
1279
if 'Q' in diag_type :
1278
1280
A_eddy , C_eddy = collection_loop (CS , sla_grd , rtime ,
1279
1281
A_list_obj = A_eddy , C_list_obj = C_eddy ,
1280
1282
xi = xi , CSxi = CSxi , verbose = verbose )
1281
1283
1282
1284
elif 'sla' in diag_type :
1283
- A_eddy .sign_type = 'Anticyclonic'
1284
1285
A_eddy = collection_loop (A_CS , sla_grd , rtime ,
1285
1286
A_list_obj = A_eddy , C_list_obj = None ,
1286
1287
sign_type = A_eddy .sign_type , verbose = verbose )
1287
1288
# Note that C_CS is reverse order
1288
- C_eddy .sign_type = 'Cyclonic'
1289
1289
C_eddy = collection_loop (C_CS , sla_grd , rtime ,
1290
1290
A_list_obj = None , C_list_obj = C_eddy ,
1291
1291
sign_type = C_eddy .sign_type , verbose = verbose )
@@ -1349,10 +1349,14 @@ def pcol_2dxy(self, x, y):
1349
1349
#anim_fig.join()
1350
1350
1351
1351
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
+
1356
1360
elif 'sla' in diag_type :
1357
1361
'''anim_fig = threading.Thread(name='anim_figure', target=anim_figure,
1358
1362
args=(33, M, pMx, pMy, slacopy, plt.cm.RdBu_r, rtime, diag_type, Mx, My,
0 commit comments