movie_nemo_zoom_box.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. #!/usr/bin/env python
  2. # B a r a K u d a
  3. #
  4. # Prepare 2D maps (monthly) that will later become a GIF animation!
  5. # NEMO output and observations needed
  6. #
  7. # L. Brodeau, May 2018
  8. import sys
  9. import os
  10. from string import replace
  11. import numpy as nmp
  12. from netCDF4 import Dataset
  13. import matplotlib as mpl
  14. mpl.use('Agg')
  15. import matplotlib.pyplot as plt
  16. import matplotlib.colors as colors
  17. import warnings
  18. warnings.filterwarnings("ignore")
  19. import datetime
  20. import barakuda_colmap as bcm
  21. import barakuda_tool as bt
  22. vmn = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ]
  23. CNEMO = 'eNATL60'
  24. #CNEMO = 'NATL60'
  25. #CNEMO = 'NANUK025'
  26. color_top = 'white'
  27. #color_top = 'k'
  28. #jt0 = 248
  29. jt0 = 0
  30. i2=0
  31. j2=0
  32. l_show_lsm = True
  33. l_do_ice = True
  34. l_show_cb = True
  35. l_show_dt = True
  36. l_log_field = False
  37. l_pow_field = False
  38. l_annotate_name = False
  39. l_apply_lap = False
  40. if CNEMO == 'eNATL60':
  41. Ni0 = 8354-1
  42. Nj0 = 4729-1
  43. l_do_ice = False
  44. l_show_cb = False
  45. l_show_dt = False
  46. #cdt = '1h'; cbox = 'zoom1' ; i1=Ni0-2560 ; j1=Nj0/2-1440 ; i2=Ni0 ; j2=Nj0/2 ; rfact_zoom = 1. ; vcb = [0.5, 0.875, 0.485, 0.02] ; font_rat = 0.5*rfact_zoom
  47. cdt = '1h'; cbox = 'ALL' ; i1=0 ; j1=0 ; i2=Ni0 ; j2=Nj0 ; rfact_zoom = 0.3047 ; vcb = [0.5, 0.875, 0.485, 0.02] ; font_rat = 0.5*rfact_zoom
  48. x_date = 350 ; y_date = 7 ; # where to put the date
  49. if CNEMO == 'NATL60':
  50. #l_pow_field = True ; pow_field = 1.5
  51. l_do_ice = False
  52. l_show_cb = False
  53. l_show_dt = False
  54. #cdt = '1h'; cbox = 'zoom1' ; i1 = 1800 ; j1 = 950 ; i2 = i1+1920 ; j2 = j1+1080 ; rfact_zoom = 1. ; vcb = [0.5, 0.875, 0.485, 0.02] ; font_rat = 0.5*rfact_zoom ; l_show_lsm = False
  55. cdt = '1h'; cbox = 'zoom1' ; i1 = 1800 ; j1 = 950 ; i2 = i1+2560 ; j2 = j1+1440 ; rfact_zoom = 1. ; vcb = [0.5, 0.875, 0.485, 0.02] ; font_rat = 0.5*rfact_zoom
  56. x_date = 350 ; y_date = 7 ; # where to put the date
  57. if CNEMO == 'NANUK025':
  58. l_do_ice = True
  59. cdt = '3h'; cbox = 'ALL' ; i1 = 0 ; j1 = 0 ; i2 = 492 ; j2 = 614 ; rfact_zoom = 2. ; vcb = [0.5, 0.875, 0.485, 0.02] ; font_rat = 0.5*rfact_zoom
  60. x_date = 350 ; y_date = 7 ; # where to put the date
  61. nx_res = i2-i1
  62. ny_res = j2-j1
  63. print ' i1,i2,j1,j2 =>', i1,i2,j1,j2
  64. yx_ratio = float(ny_res)/float(nx_res)
  65. nxr = int(rfact_zoom*nx_res) ; # widt image (in pixels)
  66. nyr = int(rfact_zoom*ny_res) ; # height image (in pixels)
  67. dpi = 110
  68. rh = round(float(nxr)/float(dpi),3) ; # width of figure as for figure...
  69. fig_type='png'
  70. narg = len(sys.argv)
  71. if narg < 5: print 'Usage: '+sys.argv[0]+' <file> <variable> <LSM_file> <YYYYMMDD (start)>'; sys.exit(0)
  72. cf_in = sys.argv[1] ; cv_in=sys.argv[2] ; cf_lsm=sys.argv[3] ; cf_date0=sys.argv[4]
  73. cyr0=cf_date0[0:4]
  74. cmn0=cf_date0[4:6]
  75. cdd0=cf_date0[6:8]
  76. # Ice:
  77. if l_do_ice:
  78. cv_ice = 'siconc'
  79. cf_ice = replace(cf_in, 'grid_T', 'icemod')
  80. rmin_ice = 0.5
  81. cpal_ice = 'ncview_bw'
  82. vcont_ice = nmp.arange(rmin_ice, 1.05, 0.05)
  83. if cv_in in ['sosstsst','tos']:
  84. cfield = 'SST'
  85. #tmin=0. ; tmax=25. ; df = 1. ; cpal_fld = 'ncview_nrl'
  86. tmin=4. ; tmax=20. ; df = 1. ; cpal_fld = 'PuBu'
  87. cunit = r'SST ($^{\circ}$C)'
  88. cb_jump = 2
  89. if cv_in == 'sossheig':
  90. cfield = 'SSH'
  91. #tmin=-0.5 ; tmax=0.5 ; df = 0.05
  92. tmin=-1.2 ; tmax=2.3 ; df = 0.05 ; l_apply_lap = True
  93. #cpal_fld = 'ncview_jaisnc'
  94. #cpal_fld = 'PuBu'
  95. #cpal_fld = 'RdBu'
  96. #cpal_fld = 'BrBG'
  97. #
  98. #cpal_fld = 'on3' ; tmin=-1.2 ; tmax=2.3 ; df = 0.05 ; l_apply_lap = True
  99. cpal_fld = 'on2' ; tmin=-1.2 ; tmax=1.2 ; df = 0.05 ; l_apply_lap = True
  100. cunit = r'SSH (m)'
  101. cb_jump = 1
  102. elif cv_in == 'somxl010':
  103. cfield == 'MLD'
  104. tmin=50. ; tmax=1500. ; df = 50.
  105. cpal_fld = 'viridis_r'
  106. if l_do_ice: bt.chck4f(cf_ice)
  107. bt.chck4f(cf_in)
  108. id_fld = Dataset(cf_in)
  109. vtime = id_fld.variables['time_counter'][:]
  110. id_fld.close()
  111. Nt = len(vtime)
  112. if l_show_lsm or l_apply_lap:
  113. bt.chck4f(cf_lsm)
  114. id_lsm = Dataset(cf_lsm)
  115. nb_dim = len(id_lsm.variables['tmask'].dimensions)
  116. if l_show_lsm:
  117. if nb_dim==4: XMSK = id_lsm.variables['tmask'][0,0,j1:j2,i1:i2]
  118. if nb_dim==3: XMSK = id_lsm.variables['tmask'][0,j1:j2,i1:i2]
  119. if nb_dim==2: XMSK = id_lsm.variables['tmask'][j1:j2,i1:i2]
  120. (nj,ni) = nmp.shape(XMSK)
  121. if l_apply_lap:
  122. XE1T2 = id_lsm.variables['e1t'][0,j1:j2,i1:i2]
  123. XE2T2 = id_lsm.variables['e2t'][0,j1:j2,i1:i2]
  124. (nj,ni) = nmp.shape(XE1T2)
  125. XE1T2 = XE1T2*XE1T2
  126. XE2T2 = XE2T2*XE2T2
  127. id_lsm.close()
  128. if l_show_lsm: pmsk = nmp.ma.masked_where(XMSK[:,:] > 0.2, XMSK[:,:]*0.+40.)
  129. #font_rat
  130. #params = { 'font.family':'Ubuntu',
  131. params = { 'font.family':'Helvetica Neue',
  132. 'font.weight': 'normal',
  133. 'font.size': int(12.*font_rat),
  134. 'legend.fontsize': int(12.*font_rat),
  135. 'xtick.labelsize': int(12.*font_rat),
  136. 'ytick.labelsize': int(12.*font_rat),
  137. 'axes.labelsize': int(12.*font_rat) }
  138. mpl.rcParams.update(params)
  139. cfont_clb = { 'fontname':'Helvetica Neue', 'fontweight':'medium', 'fontsize':int(12.*font_rat), 'color':color_top }
  140. cfont_date = { 'fontname':'Ubuntu Mono', 'fontweight':'normal', 'fontsize':int(14.*font_rat), 'color':'w' }
  141. cfont_mail = { 'fontname':'Times New Roman', 'fontweight':'normal', 'fontstyle':'italic', 'fontsize':int(14.*font_rat), 'color':'0.8'}
  142. cfont_titl = { 'fontname':'Helvetica Neue', 'fontweight':'light', 'fontsize':int(30.*font_rat), 'color':'w' }
  143. # Colormaps for fields:
  144. pal_fld = bcm.chose_colmap(cpal_fld)
  145. if l_log_field:
  146. norm_fld = colors.LogNorm( vmin = tmin, vmax = tmax, clip = False)
  147. if l_pow_field:
  148. norm_fld = colors.PowerNorm(gamma=pow_field, vmin = tmin, vmax = tmax, clip = False)
  149. else:
  150. norm_fld = colors.Normalize(vmin = tmin, vmax = tmax, clip = False)
  151. if l_show_lsm:
  152. pal_lsm = bcm.chose_colmap('land_dark')
  153. norm_lsm = colors.Normalize(vmin = 0., vmax = 1., clip = False)
  154. if l_do_ice:
  155. pal_ice = bcm.chose_colmap(cpal_ice)
  156. norm_ice = colors.Normalize(vmin = rmin_ice, vmax = 1, clip = False)
  157. if cdt == '3h':
  158. dt = 3
  159. elif cdt == '1h':
  160. dt = 1
  161. else:
  162. print 'ERROR: unknown dt!'
  163. print ' *** Dimension image:', rh*float(dpi), rh*yx_ratio*float(dpi),'\n'
  164. ntpd = 24/dt
  165. jd = int(cdd0) - 1
  166. jm = int(cmn0)
  167. for jt in range(jt0,Nt):
  168. jh = (jt*dt)%24
  169. jdc = (jt*dt)/24 + 1
  170. if jt%ntpd == 0: jd = jd + 1
  171. if jd == vmn[jm-1]+1 and (jt)%ntpd == 0 :
  172. jd = 1
  173. jm = jm + 1
  174. ch = '%2.2i'%(jh)
  175. #cdc= '%3.3i'%(jdc)
  176. cd = '%3.3i'%(jd)
  177. cm = '%2.2i'%(jm)
  178. #print '\n\n *** jt, ch, cd, cm =>', jt, ch, cd, cm
  179. ct = str(datetime.datetime.strptime(cyr0+'-'+cm+'-'+cd+' '+ch, '%Y-%m-%j %H'))
  180. ct=ct[:5]+cm+ct[7:] #lolo bug !!! need to do that to get the month and not "01"
  181. print ' ct = ', ct
  182. cday = ct[:10] ; print ' *** cday :', cday
  183. chour = ct[11:13] ; print ' *** chour :', chour
  184. cfig = 'figs/zoom_'+cv_in+'_NEMO'+'_'+cday+'_'+chour+'_'+cpal_fld+'.'+fig_type
  185. fig = plt.figure(num = 1, figsize=(rh,rh*yx_ratio), dpi=None, facecolor='w', edgecolor='0.5')
  186. #ax = plt.axes([0.065, 0.05, 0.9, 1.], axisbg = '0.5')
  187. ax = plt.axes([0., 0., 1., 1.], axisbg = '0.5')
  188. vc_fld = nmp.arange(tmin, tmax + df, df)
  189. print "Reading record #"+str(jt)+" of "+cv_in+" in "+cf_in
  190. id_fld = Dataset(cf_in)
  191. XFLD = id_fld.variables[cv_in][jt,j1:j2,i1:i2] ; # t, y, x
  192. id_fld.close()
  193. print "Done!"
  194. if l_apply_lap:
  195. lx = nmp.zeros((nj,ni))
  196. ly = nmp.zeros((nj,ni))
  197. lx[:,1:ni-1] = 1.E9*(XFLD[:,2:ni] -2.*XFLD[:,1:ni-1] + XFLD[:,0:ni-2])/XE1T2[:,1:ni-1]
  198. ly[1:nj-1,:] = 1.E9*(XFLD[2:nj,:] -2.*XFLD[1:nj-1,:] + XFLD[0:nj-2,:])/XE2T2[1:nj-1,:]
  199. XFLD[:,:] = lx[:,:] + ly[:,:]
  200. del lx, ly
  201. if not l_show_lsm and jt == jt0: ( nj , ni ) = nmp.shape(XFLD)
  202. print ' *** dimension of array => ', ni, nj
  203. print "Ploting"
  204. cf = plt.imshow(XFLD[:,:], cmap = pal_fld, norm = norm_fld, interpolation='none')
  205. del XFLD
  206. print "Done!"
  207. # Ice
  208. if not cfield == 'MLD' and l_do_ice:
  209. print "Reading record #"+str(jt)+" of "+cv_ice+" in "+cf_ice
  210. id_ice = Dataset(cf_ice)
  211. XICE = id_ice.variables[cv_ice][jt,:,:] ; # t, y, x
  212. id_ice.close()
  213. print "Done!"
  214. #XM[:,:] = XMSK[:,:]
  215. #bt.drown(XICE, XM, k_ew=2, nb_max_inc=10, nb_smooth=10)
  216. #ci = plt.contourf(XICE[:,:], vcont_ice, cmap = pal_ice, norm = norm_ice) #
  217. pice = nmp.ma.masked_where(XICE < rmin_ice, XICE)
  218. ci = plt.imshow(pice, cmap = pal_ice, norm = norm_ice, interpolation='none') ; del pice, ci
  219. del XICE
  220. if l_show_lsm: cm = plt.imshow(pmsk, cmap = pal_lsm, norm = norm_lsm, interpolation='none')
  221. plt.axis([ 0, ni, 0, nj])
  222. #plt.title('NEMO: '+cfield+', coupled '+CNEMO+', '+cday+' '+chour+':00', **cfont_title)
  223. if l_show_cb:
  224. ax2 = plt.axes(vcb)
  225. clb = mpl.colorbar.ColorbarBase(ax2, ticks=vc_fld, cmap=pal_fld, norm=norm_fld, orientation='horizontal', extend='both')
  226. if cb_jump > 1:
  227. cb_labs = [] ; cpt = 0
  228. for rr in vc_fld:
  229. if cpt % cb_jump == 0:
  230. if df >= 1.: cb_labs.append(str(int(rr)))
  231. if df < 1.: cb_labs.append(str(rr))
  232. else:
  233. cb_labs.append(' ')
  234. cpt = cpt + 1
  235. clb.ax.set_xticklabels(cb_labs)
  236. clb.set_label(cunit, **cfont_clb)
  237. clb.ax.yaxis.set_tick_params(color=color_top) ; # set colorbar tick color
  238. clb.outline.set_edgecolor(color_top) ; # set colorbar edgecolor
  239. plt.setp(plt.getp(clb.ax.axes, 'xticklabels'), color=color_top) ; # set colorbar ticklabels
  240. del cf
  241. if l_show_dt: ax.annotate('Date: '+cday+' '+chour+':00', xy=(1, 4), xytext=(x_date, y_date), **cfont_date)
  242. #ax.annotate('laurent.brodeau@ocean-next.fr', xy=(1, 4), xytext=(x_date+150, 20), **cfont_mail)
  243. xl = float(nxr)/20./rfact_zoom
  244. yl = float(nyr)/1.2/rfact_zoom
  245. if l_annotate_name:
  246. ax.annotate(CNEMO, xy=(1, 4), xytext=(xl, yl), **cfont_titl)
  247. plt.savefig(cfig, dpi=dpi, orientation='portrait', facecolor='k')
  248. print cfig+' created!\n'
  249. plt.close(1)
  250. del cm, fig, ax
  251. if l_show_cb: del clb