mean_3d.py 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #!/usr/bin/env python
  2. #
  3. # B a r a K u d a
  4. #
  5. # Generate misc. spatial 3D averaging out of NEMO output files...
  6. #
  7. # L. Brodeau, november 2013
  8. #
  9. import sys
  10. import os
  11. import numpy as nmp
  12. from netCDF4 import Dataset
  13. from string import replace
  14. import barakuda_tool as bt
  15. import barakuda_orca as bo
  16. import barakuda_ncio as bnc
  17. venv_needed = {'ORCA','EXP','DIAG_D','MM_FILE','BM_FILE',
  18. 'NEMO_SAVED_FILES','NN_T','NN_S','ANNUAL_3D','TSTAMP'}
  19. vdic = bt.check_env_var(sys.argv[0], venv_needed)
  20. CONFEXP = vdic['ORCA']+'-'+vdic['EXP']
  21. if len(sys.argv) != 4:
  22. print 'Usage : sys.argv[1] <ORCA1_EXP_grid_T.nc> <year> <T or S>'; sys.exit(0)
  23. cnexec = sys.argv[0]
  24. cf_T_in = sys.argv[1]
  25. cyear = sys.argv[2] ; jyear = int(cyear); cyear = '%4.4i'%jyear
  26. cv_todo = sys.argv[3]
  27. print 'Current year is '+cyear+' !\n'
  28. if not cv_todo in ['T','S']:
  29. print 'Usage : sys.argv[1] <ORCA1_EXP_grid_T.nc> <year> <T or S>'; sys.exit(0)
  30. if cv_todo == 'T': cvar = vdic['NN_T']
  31. if cv_todo == 'S': cvar = vdic['NN_S']
  32. # Checking if the land-sea mask file is here:
  33. for cf in [vdic['MM_FILE'], vdic['BM_FILE']]:
  34. if not os.path.exists(cf):
  35. print 'Mask file '+cf+' not found'; sys.exit(0)
  36. # Reading the grid metrics:
  37. id_mm = Dataset(vdic['MM_FILE'])
  38. list_variables = id_mm.variables.keys()
  39. rmask = id_mm.variables['tmask'][0,:,:,:]
  40. xe1t = id_mm.variables['e1t'][0,:,:]
  41. xe2t = id_mm.variables['e2t'][0,:,:]
  42. # we need a 3D field for e3t, because partial steps!!!
  43. if 'e3t_0' in list_variables[:]:
  44. Xe3t = id_mm.variables['e3t_0'][0,:,:,:]
  45. else:
  46. print 'ERROR: '+cnexec+' => how do we retrieve 3D e3t???'; sys.exit(0)
  47. id_mm.close()
  48. ( nk, nj, ni ) = rmask.shape
  49. Xa = nmp.zeros((nj, ni))
  50. Xv = nmp.zeros((nk, nj, ni))
  51. Xa[:,:] = xe1t[:,:]*xe2t[:,:]
  52. del xe1t, xe2t
  53. for jk in range(nk): Xv[jk,:,:] = Xa[:,:]*Xe3t[jk,:,:]
  54. del Xe3t
  55. print 'Opening different basin masks in file '+vdic['BM_FILE']
  56. list_basin_names, list_basin_lgnms = bo.get_basin_info(vdic['BM_FILE'])
  57. nb_basins = len(list_basin_names)
  58. mask = nmp.zeros((nb_basins,nk,nj,ni))
  59. msk_tmp = nmp.zeros((nj,ni))
  60. mask[0,:,:,:] = rmask[:,:,:] ; # global
  61. id_bm = Dataset(vdic['BM_FILE'])
  62. for jb in range(1,nb_basins) :
  63. msk_tmp[:,:] = id_bm.variables['tmask'+list_basin_names[jb]][:,:]
  64. for jk in range(nk):
  65. mask[jb,jk,:,:] = msk_tmp[:,:]*rmask[jk,:,:]
  66. id_bm.close()
  67. del rmask, msk_tmp
  68. #############################################
  69. # 3D averaging for temperature and salinity #
  70. #############################################
  71. print '\n\n +++ '+cnexec+' => Starting 3D-averaging diags!'
  72. if vdic['ANNUAL_3D'] == '1y':
  73. cf_T_in = replace(cf_T_in, vdic['TSTAMP'], vdic['ANNUAL_3D'])
  74. print ' ==> USING '+vdic['ANNUAL_3D']+' file !!! =>', cf_T_in
  75. print ' ==> variable '+cvar
  76. # DATA:
  77. id_in = Dataset(cf_T_in)
  78. try:
  79. vdepth = id_in.variables['deptht'][:]
  80. except KeyError as e:
  81. vdepth = id_in.variables['olevel'][:]
  82. Xd_m = id_in.variables[cvar][:,:,:,:]
  83. id_in.close()
  84. print ' ==> variable '+cvar+' read !'
  85. j100m = bt.find_index_from_value(100. , vdepth) ; print 'j100m = ', j100m, '=> ', vdepth[j100m]
  86. j1000m = bt.find_index_from_value(1000. , vdepth) ; print 'j1000m = ', j1000m, '=> ', vdepth[j1000m]
  87. ( nt, nk0, nj0, ni0 ) = Xd_m.shape
  88. if nt != 12 and nt != 1 : print 'ERROR: '+cnexec+' => only treating monthly or annual data so far...'; sys.exit(0)
  89. if ( nk0, nj0, ni0 ) != ( nk, nj, ni ):
  90. print 'ERROR: '+cnexec+' => Field and metrics do not agree in size!'
  91. print ' ==> nk0, nj0, ni0 / nk, nj, ni = ', nk0, nj0, ni0, '/', nk, nj, ni
  92. sys.exit(0)
  93. vtime = nmp.zeros(nt)
  94. for jt in range(nt): vtime[jt] = float(jyear) + (float(jt)+0.5)*1./float(nt)
  95. print ' * Calendar: ', vtime[:]
  96. # Annual mean array for current year:
  97. Xd_y = nmp.zeros((1, nk, nj, ni))
  98. if nt == 12:
  99. Xd_y[0,:,:,:] = nmp.mean(Xd_m, axis=0)
  100. else:
  101. Xd_y[0,:,:,:] = Xd_m[0,:,:,:]
  102. joce = 0
  103. for cocean in list_basin_names[:]:
  104. colnm = list_basin_lgnms[joce]
  105. print ' ===> '+cvar+' in basin '+cocean+' ('+colnm+')'
  106. # Decrasing the domain size if possible:
  107. (i1,j1,i2,j2) = bo.shrink_domain(mask[joce,0,:,:])
  108. #(vjj , vji) = nmp.where(mask[joce,0,:,:]>0.5)
  109. #j1 = max( nmp.min(vjj)-2 , 0 )
  110. #i1 = max( nmp.min(vji)-2 , 0 )
  111. #j2 = min( nmp.max(vjj)+2 , nj-1 ) + 1
  112. #i2 = min( nmp.max(vji)+2 , ni-1 ) + 1
  113. #if (i1,j1,i2,j2) != (0,0,ni,nj): print ' ===> zooming on i1,j1 -> i2,j2:', i1,j1,'->',i2,j2
  114. # I) Montly mean for diffrent depth ranges
  115. # ========================================
  116. Vts_tot = bo.mean_3d(Xd_m[:,:,j1:j2,i1:i2], mask[joce,:,j1:j2,i1:i2], Xv[:,j1:j2,i1:i2]) ; # Top to bottom
  117. Vts_0_100 = bo.mean_3d(Xd_m[:,:j100m,j1:j2,i1:i2], mask[joce,:j100m,j1:j2,i1:i2], Xv[:j100m,j1:j2,i1:i2])
  118. Vts_100_1000 = bo.mean_3d(Xd_m[:,j100m:j1000m,j1:j2,i1:i2], mask[joce,j100m:j1000m,j1:j2,i1:i2], Xv[j100m:j1000m,j1:j2,i1:i2])
  119. Vts_1000_bot = bo.mean_3d(Xd_m[:,j1000m:,j1:j2,i1:i2], mask[joce,j1000m:,j1:j2,i1:i2], Xv[j1000m:,j1:j2,i1:i2])
  120. cf_out = vdic['DIAG_D']+'/3d_'+cvar+'_'+CONFEXP+'_'+cocean+'.nc'
  121. cv1 = cvar+'_0-bottom'
  122. cv2 = cvar+'_0-100'
  123. cv3 = cvar+'_100-1000'
  124. cv4 = cvar+'_1000-bottom'
  125. bnc.wrt_appnd_1d_series(vtime, Vts_tot, cf_out, cv1,
  126. cu_t='year', cu_d='Unknown', cln_d ='3D-average of '+cvar+': surface to bottom, '+colnm,
  127. vd2=Vts_0_100, cvar2=cv2, cln_d2='3D-average of '+cvar+': surface to 100m, '+colnm,
  128. vd3=Vts_100_1000, cvar3=cv3, cln_d3='3D-average of '+cvar+': 100m to 1000m, '+colnm,
  129. vd4=Vts_1000_bot, cvar4=cv4, cln_d4='3D-average of '+cvar+': 1000m to bottom, '+colnm)
  130. # II) Annual mean vertical profile
  131. # ================================
  132. Vf = nmp.zeros(nk)
  133. for jk in range(nk):
  134. [ rf ] = bo.mean_2d(Xd_y[:,jk,j1:j2,i1:i2], mask[joce,jk,j1:j2,i1:i2], Xa[j1:j2,i1:i2])
  135. Vf[jk] = rf
  136. # NETCDF:
  137. cf_out = vdic['DIAG_D']+'/'+cvar+'_mean_Vprofile_'+CONFEXP+'_'+cocean+'.nc'
  138. l_nc_is_new = not os.path.exists(cf_out)
  139. #
  140. # Creating/Opening output Netcdf file:
  141. if l_nc_is_new:
  142. f_out = Dataset(cf_out, 'w', format='NETCDF3_CLASSIC')
  143. else:
  144. f_out = Dataset(cf_out, 'a', format='NETCDF3_CLASSIC')
  145. if l_nc_is_new:
  146. jrec2write = 0
  147. # Creating Dimensions:
  148. f_out.createDimension('time', None)
  149. f_out.createDimension('deptht', nk)
  150. # Creating variables:
  151. id_t = f_out.createVariable('time','f4',('time',)) ; id_t.units = 'year'
  152. id_z = f_out.createVariable('deptht','f4',('deptht',)) ; id_z.units = 'm'
  153. id_v01 = f_out.createVariable(cvar ,'f4',('time','deptht',))
  154. id_v01.long_name = 'Horizontally-averaged '+cvar+': '+colnm
  155. # Writing depth vector
  156. id_z[:] = vdepth[:]
  157. id_t[jrec2write] = float(jyear)+0.5
  158. id_v01[jrec2write,:] = Vf[:]
  159. f_out.Author = 'L. Brodeau ('+cnexec+' of Barakuda)'
  160. else:
  161. vt = f_out.variables['time']
  162. jrec2write = len(vt)
  163. v01 = f_out.variables[cvar]
  164. vt[jrec2write] = float(jyear)+0.5
  165. v01[jrec2write,:] = Vf[:]
  166. f_out.close()
  167. print cf_out+' written!'
  168. print ''
  169. joce = joce + 1
  170. del Xd_m
  171. print '\n'
  172. print ' +++ '+cnexec+' => Done with 3D-averaging of variable '+cvar+'!\n'
  173. print '\n *** EXITING '+cnexec+' for year '+cyear+' and variable '+cvar+'!\n'