dmv.py 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. #!/usr/bin/env python
  2. # B a r a K u d a
  3. #
  4. # Generate 2D plots and maps of the Mixed layer depth
  5. #
  6. # L. Brodeau, 2014
  7. #
  8. # Computes the DMV (Deep Mixed Volume) in user-defined deep-convective mixing
  9. # regions (rectangle defined by 2 grid points) according to the method by
  10. # Brodeau & Koenigk 2015.
  11. #
  12. # Rectangular boxes must be defined in a file which name is known as the global
  13. # environment variable "FILE_DMV_BOXES"
  14. # => template: data/def_boxes_convection_ORCA1.txt
  15. #
  16. ### Reference:
  17. # L. Brodeau and T. Koenigk. Extinction of the northern oceanic deep convection in
  18. # an ensemble of climate model simulations of the 20th and 21st centuries. Climate
  19. # Dynamics, Online, 2015.
  20. # DOI: 10.1007/s00382-015-2736-5
  21. #
  22. #
  23. # List of environement variables that should be "known/set" when launching this script:
  24. #
  25. # * ORCA : global ORCA grid you use (ex: "ORCA1.L75")
  26. # * EXP : name of your NEMO experiment
  27. # * DIAG_D : full path to the directory where the diagnostics (here a netcdf file) are saved
  28. # * FILE_DMV_BOXES: full path to the ASCII file containing definition of convection boxes
  29. # => template: data/def_boxes_convection_ORCA1.txt
  30. # * MM_FILE : full path to the "mesh_mask.nc" file relevent to your ORCA !
  31. # * NN_MLD : name of the Mixed-Layer Depth variable inside the *_grid_T.nc files of your NEMO experiment
  32. # * MLD_CRIT: contains a list of all the "depth criterion to use" (wil be used for each box)
  33. # => ex: MLD_CRIT="2000,1500,1000,725,500"
  34. #
  35. ###########################################################################################
  36. import sys
  37. import numpy as nmp
  38. from netCDF4 import Dataset
  39. import barakuda_tool as bt
  40. import barakuda_ncio as bnc
  41. rdiv = 1000. ; # => result in 10^3 km^3 (DMV divided 4 times by rdiv)
  42. # Getting all required environment variables needed inside dictionary vdic:
  43. venv_needed = {'ORCA','EXP','DIAG_D','FILE_DMV_BOXES','MM_FILE','NN_MLD','MLD_CRIT'}
  44. vdic = bt.check_env_var(sys.argv[0], venv_needed)
  45. CONFEXP = vdic['ORCA']+'-'+vdic['EXP']
  46. cname_script = sys.argv[0]
  47. if len(sys.argv) != 3:
  48. print 'Usage : '+cname_script+' <ORCA1_EXP_grid_T.nc> <year>'
  49. sys.exit(0)
  50. cf_in = sys.argv[1]
  51. cyear = sys.argv[2] ; jyear = int(cyear); cyear = '%4.4i'%jyear
  52. print 'Current year is '+cyear+' !\n'
  53. # Vector containing the different z_crit:
  54. vMLD_crit = []
  55. vv = vdic['MLD_CRIT'].split(',')
  56. for cv in vv: vMLD_crit.append(float(cv))
  57. print "\n All the z_crit to use:", vMLD_crit[:]
  58. # First will read name and coordinates of rectangular boxes to treat into file FILE_DMV_BOXES
  59. ##############################################################################################
  60. vboxes, vi1, vj1, vi2, vj2 = bt.read_coor(vdic['FILE_DMV_BOXES'])
  61. nbb = len(vboxes)
  62. print ''
  63. bt.chck4f(vdic['MM_FILE'])
  64. id_mm = Dataset(vdic['MM_FILE'])
  65. zmask_orca = id_mm.variables['tmask'][0,0,:,:]
  66. ze1t_orca = id_mm.variables['e1t'] [0,:,:]
  67. ze2t_orca = id_mm.variables['e2t'] [0,:,:]
  68. id_mm.close()
  69. bt.chck4f(cf_in)
  70. id_in = Dataset(cf_in)
  71. Xmld_orca = id_in.variables[vdic['NN_MLD']][:,:,:]
  72. print '(has ',Xmld_orca.shape[0],' time snapshots)\n'
  73. xlat = id_in.variables['nav_lat'][:,:]
  74. id_in.close()
  75. [ nt, nj, ni ] = Xmld_orca.shape
  76. print 'nt, nj, ni =', nt, nj, ni
  77. # Loop along depth crtiteria:
  78. for z_crit in vMLD_crit:
  79. czcrit = str(int(z_crit))
  80. # Loop along convection boxes:
  81. for jb in range(nbb):
  82. cbox = vboxes[jb]
  83. i1 = vi1[jb]
  84. j1 = vj1[jb]
  85. i2 = vi2[jb]+1
  86. j2 = vj2[jb]+1
  87. nx_b = i2 - i1
  88. ny_b = j2 - j1
  89. print '\n *** Treating box '+cbox+' => ', i1, j1, i2-1, j2-1
  90. # NH
  91. icold = 2 ; # march
  92. ccold = 'march'
  93. ccold_ln = 'March'
  94. vinter = [0, 1, 2]
  95. cvinter = 'JFM'
  96. if xlat[j1,i1] < 0:
  97. # SH
  98. icold = 8 ; # september
  99. ccold = 'sept'
  100. ccold_ln = 'September'
  101. vinter = [6, 7, 8]
  102. cvinter = 'JAS'
  103. # Filling Convection regions arrays:
  104. # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  105. xmld = nmp.zeros((nt, ny_b, nx_b))
  106. msk_deep = nmp.zeros((nt, ny_b, nx_b))
  107. xe1t = nmp.zeros((ny_b, nx_b))
  108. xe2t = nmp.zeros((ny_b, nx_b))
  109. xtmp = nmp.zeros((ny_b, nx_b))
  110. VDMV = nmp.zeros(3)
  111. # MLD:
  112. xmld[:,:,:] = Xmld_orca[:,j1:j2,i1:i2]
  113. #E1Tb & E2T:
  114. xe1t[:,:] = ze1t_orca[j1:j2,i1:i2] / rdiv
  115. xe2t[:,:] = ze2t_orca[j1:j2,i1:i2] / rdiv
  116. # Building deep ML mask for the 3 first months:
  117. for jm in vinter:
  118. xtmp[:,:] = 0.
  119. xtmp[:,:] = zmask_orca[j1:j2,i1:i2]
  120. # Excluding points where MLD < z_crit
  121. idx1 = nmp.where(xmld[jm,:,:] < z_crit)
  122. xtmp[idx1] = 0
  123. msk_deep[jm,:,:] = xtmp[:,:]
  124. xtmp[:,:] = xe1t[:,:]*xe2t[:,:]
  125. # Deepest ML in march or september:
  126. rML_max = nmp.max(xmld[icold,:,:])
  127. # Mean ML in march or september where ML > zcrit:
  128. rd = nmp.sum(xtmp[:,:]*msk_deep[icold,:,:])
  129. if rd > 0:
  130. rML_deep_mean = nmp.sum(xmld[icold,:,:]*xtmp[:,:]*msk_deep[icold,:,:])/rd
  131. else:
  132. rML_deep_mean = 0.
  133. # DMV
  134. #####
  135. jc=-1
  136. for jm in vinter:
  137. jc=jc+1
  138. VDMV[jc] = nmp.sum((xmld[jm,:,:] - z_crit)*xtmp[:,:]*msk_deep[jm,:,:])/(rdiv*rdiv)
  139. rc_WINT = nmp.mean(VDMV)
  140. ##########################################
  141. # Writing/Appending in output netcdf file
  142. ##########################################
  143. # Appending only 1 record for 1 year into the netcdf file!
  144. cf_out = vdic['DIAG_D']+'/DMV_'+czcrit+'_box_'+cbox+'_'+CONFEXP+'.nc'
  145. cv_dmv_m = 'DMV_'+czcrit+'_'+ccold
  146. cv_dmv_jfm = 'DMV_'+czcrit+'_'+cvinter
  147. long_name1 = 'Deep Mixed Volume (crit = '+czcrit+'m) for '+ccold_ln+' on box '+cbox
  148. long_name2 = 'Deep Mixed Volume (crit = '+czcrit+'m) for '+cvinter+' on box '+cbox
  149. long_name3 = 'Deepest ML point in '+ccold_ln+' on box '+cbox
  150. long_name4 = 'Mean MLD in '+ccold_ln+' where MLD > '+czcrit+'m on box '+cbox
  151. bnc.wrt_appnd_1d_series([float(jyear)], [VDMV[2]], cf_out, cv_dmv_m, cu_t='year', cu_d='10^3 km^3', cln_d=long_name1,
  152. vd2=[rc_WINT], cvar2=cv_dmv_jfm, cln_d2=long_name2,
  153. vd3=[rML_max], cvar3='ML_max', cln_d3=long_name3, cun3='m',
  154. vd4=[rML_deep_mean], cvar4='ML_deep_mean', cln_d4=long_name4, cun4='m')
  155. print '\n Z_crit '+str(int(czcrit))+'m done!\n\n'
  156. print '\nBye!\n'