mk_zonal_average.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #!/usr/bin/env python
  2. # L. Brodeau, June 2012
  3. import sys
  4. from os.path import splitext,basename,dirname
  5. import numpy as nmp
  6. from netCDF4 import Dataset
  7. from string import replace
  8. import barakuda_tool as bt
  9. # Defaults:
  10. cv_lon = 'lon'
  11. cv_lat = 'lat'
  12. narg = len(sys.argv)
  13. if not narg in [ 5 , 7]:
  14. print '\nUsage: '+basename(sys.argv[0])+' <FILE_lat-lon.nc> <variable> <mesh_mask.nc> <mask_name> (<name_longitude> <name_latitude>)'
  15. print ' * If you do not have a mask file, use a special value of field <variable> to be'
  16. print ' considered as a mask. Example: '
  17. print ' '+basename(sys.argv[0])+' <FILE_lat-lon.nc> <variable> value -9999.\n'
  18. sys.exit(0)
  19. cf_in = sys.argv[1]
  20. cv_in = sys.argv[2]
  21. cf_msk = sys.argv[3]
  22. cv_msk = sys.argv[4]
  23. if narg == 7:
  24. cv_lon = sys.argv[5]
  25. cv_lat = sys.argv[6]
  26. print ''
  27. cn_file, cn_ext = splitext(cf_in)
  28. #cn_file = replace(cn_file, cv_in+'_', '')
  29. cpath = '.'
  30. if dirname(cf_in) != '': cpath=dirname(cf_in)
  31. cf_out = cpath+'/zonal_'+basename(cn_file)+'.nc'
  32. #print ' *[mk_zonal_average.py]* file to write: ', cf_out ; sys.exit(0)
  33. l_msk_from_val = False
  34. if cf_msk in [ 'value', 'val', 'Value' ]:
  35. l_msk_from_val = True
  36. rmv = float(cv_msk)
  37. print ' *[mk_zonal_average.py]* mask is where '+cv_in+' == '+str(rmv)
  38. else:
  39. bt.chck4f(cf_msk)
  40. f_msk = Dataset(cf_msk)
  41. Ndim = len(f_msk.variables[cv_msk].dimensions)
  42. if Ndim == 4:
  43. xmsk = f_msk.variables[cv_msk][0,0,:,:]
  44. elif Ndim == 3:
  45. xmsk = f_msk.variables[cv_msk][0,:,:]
  46. elif Ndim == 2:
  47. xmsk = f_msk.variables[cv_msk][:,:]
  48. else:
  49. print ' ERROR (mk_zonal_average.py) => weird shape for your mask array!'
  50. sys.exit(0)
  51. f_msk.close()
  52. bt.chck4f(cf_in)
  53. f_in = Dataset(cf_in)
  54. list_var = f_in.variables.keys()
  55. Ndim = len(f_in.variables[cv_lon].dimensions)
  56. cunt_lon = f_in.variables[cv_lon].units
  57. cunt_lat = f_in.variables[cv_lat].units
  58. if Ndim == 1:
  59. # Extracting the longitude and 1D array:
  60. vlon = f_in.variables[cv_lon][:]
  61. # Extracting the latitude 1D array:
  62. vlat = f_in.variables[cv_lat][:]
  63. elif Ndim == 2:
  64. # We suppose it is NEMO nav_lon and nav_lat...
  65. xlon = f_in.variables[cv_lon][:,:]
  66. xlat = f_in.variables[cv_lat][:,:]
  67. (nj0,ni0) = nmp.shape(xlon)
  68. vlon = nmp.zeros(ni0)
  69. vlat = nmp.zeros(nj0)
  70. vlon[:] = xlon[nj0/8,:]
  71. ji_lat0 = nmp.argmax(xlat[nj0-1,:])
  72. vlat[:] = xlat[:,ji_lat0]
  73. del xlon, xlat, nj0, ni0
  74. else:
  75. print ' ERROR (mk_zonal_average.py) => weird shape for your longitude array!'
  76. sys.exit(0)
  77. for cvt in [ 'time', 'time_counter' ]:
  78. if cvt in list_var:
  79. vtime = f_in.variables[cvt][:]
  80. cunt_time = f_in.variables[cvt].units
  81. #print 'TIME: ', cunt_time, '\n'
  82. # Field !!!
  83. xfield = f_in.variables[cv_in][:,:,:]
  84. cunit_field = f_in.variables[cv_in].units
  85. clgnm_field = f_in.variables[cv_in].long_name
  86. f_in.close()
  87. Nt = len(vtime)
  88. #print ' Nt = '+str(Nt)
  89. # Checking dimensions
  90. # ~~~~~~~~~~~~~~~~~~~
  91. ( Nt, nj, ni ) = xfield.shape
  92. print ' *[mk_zonal_average.py]* dimension of "'+cv_in+'" => ', ni, nj, Nt
  93. # ZONAL MEAN:
  94. if l_msk_from_val:
  95. Fzonal = bt.mk_zonal(xfield, r_mask_from_val=rmv)
  96. else:
  97. Fzonal = bt.mk_zonal(xfield, XMSK=xmsk)
  98. # Output netCDF file:
  99. #######################
  100. f_out = Dataset(cf_out, 'w',format='NETCDF3_CLASSIC')
  101. # Dimensions:
  102. f_out.createDimension('lat', nj)
  103. f_out.createDimension('time', None)
  104. # Variables
  105. id_lat = f_out.createVariable('lat','f4',('lat',))
  106. id_tim = f_out.createVariable('time','f4',('time',))
  107. id_f1 = f_out.createVariable(cv_in,'f4',('time','lat',))
  108. id_f1.units = cunit_field
  109. id_f1.long_name = clgnm_field
  110. id_f2 = f_out.createVariable(cv_in+'_mean','f4',('lat',))
  111. id_f2.units = cunit_field
  112. id_f2.long_name = clgnm_field
  113. id_f3 = f_out.createVariable(cv_in+'_anom','f4',('time','lat',))
  114. f_out.about = 'Diagnostics created with BaraKuda (https://github.com/brodeau/barakuda)'
  115. # Filling variables:
  116. id_lat[:] = vlat[:]
  117. Z_time_mean = nmp.mean(Fzonal[:,:], axis=0)
  118. for jt in range(Nt):
  119. id_tim[jt] = vtime[jt]
  120. id_f1[jt,:] = Fzonal[jt,:]
  121. id_f3[jt,:] = Fzonal[jt,:] - Z_time_mean
  122. id_f2[:] = Z_time_mean[:]
  123. f_out.close()
  124. print ' *[mk_zonal_average.py]* Wrote file '+cf_out+' !\n'