123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- #!/usr/bin/env python
- #
- # B a r a K u d a
- #
- # Generate misc. spatial 3D averaging out of NEMO output files...
- #
- # L. Brodeau, november 2013
- #
- import sys
- import os
- import numpy as nmp
- from netCDF4 import Dataset
- from string import replace
- import barakuda_tool as bt
- import barakuda_orca as bo
- import barakuda_ncio as bnc
- venv_needed = {'ORCA','EXP','DIAG_D','MM_FILE','BM_FILE',
- 'NEMO_SAVED_FILES','NN_T','NN_S','ANNUAL_3D','TSTAMP'}
- vdic = bt.check_env_var(sys.argv[0], venv_needed)
- CONFEXP = vdic['ORCA']+'-'+vdic['EXP']
- if len(sys.argv) != 4:
- print 'Usage : sys.argv[1] <ORCA1_EXP_grid_T.nc> <year> <T or S>'; sys.exit(0)
- cnexec = sys.argv[0]
- cf_T_in = sys.argv[1]
- cyear = sys.argv[2] ; jyear = int(cyear); cyear = '%4.4i'%jyear
- cv_todo = sys.argv[3]
- print 'Current year is '+cyear+' !\n'
- if not cv_todo in ['T','S']:
- print 'Usage : sys.argv[1] <ORCA1_EXP_grid_T.nc> <year> <T or S>'; sys.exit(0)
- if cv_todo == 'T': cvar = vdic['NN_T']
- if cv_todo == 'S': cvar = vdic['NN_S']
- # Checking if the land-sea mask file is here:
- for cf in [vdic['MM_FILE'], vdic['BM_FILE']]:
- if not os.path.exists(cf):
- print 'Mask file '+cf+' not found'; sys.exit(0)
- # Reading the grid metrics:
- id_mm = Dataset(vdic['MM_FILE'])
- list_variables = id_mm.variables.keys()
- rmask = id_mm.variables['tmask'][0,:,:,:]
- xe1t = id_mm.variables['e1t'][0,:,:]
- xe2t = id_mm.variables['e2t'][0,:,:]
- # we need a 3D field for e3t, because partial steps!!!
- if 'e3t_0' in list_variables[:]:
- Xe3t = id_mm.variables['e3t_0'][0,:,:,:]
- else:
- print 'ERROR: '+cnexec+' => how do we retrieve 3D e3t???'; sys.exit(0)
- id_mm.close()
- ( nk, nj, ni ) = rmask.shape
- Xa = nmp.zeros((nj, ni))
- Xv = nmp.zeros((nk, nj, ni))
- Xa[:,:] = xe1t[:,:]*xe2t[:,:]
- del xe1t, xe2t
- for jk in range(nk): Xv[jk,:,:] = Xa[:,:]*Xe3t[jk,:,:]
- del Xe3t
- print 'Opening different basin masks in file '+vdic['BM_FILE']
- list_basin_names, list_basin_lgnms = bo.get_basin_info(vdic['BM_FILE'])
- nb_basins = len(list_basin_names)
- mask = nmp.zeros((nb_basins,nk,nj,ni))
- msk_tmp = nmp.zeros((nj,ni))
- mask[0,:,:,:] = rmask[:,:,:] ; # global
- id_bm = Dataset(vdic['BM_FILE'])
- for jb in range(1,nb_basins) :
- msk_tmp[:,:] = id_bm.variables['tmask'+list_basin_names[jb]][:,:]
- for jk in range(nk):
- mask[jb,jk,:,:] = msk_tmp[:,:]*rmask[jk,:,:]
- id_bm.close()
- del rmask, msk_tmp
- #############################################
- # 3D averaging for temperature and salinity #
- #############################################
- print '\n\n +++ '+cnexec+' => Starting 3D-averaging diags!'
- if vdic['ANNUAL_3D'] == '1y':
- cf_T_in = replace(cf_T_in, vdic['TSTAMP'], vdic['ANNUAL_3D'])
- print ' ==> USING '+vdic['ANNUAL_3D']+' file !!! =>', cf_T_in
- print ' ==> variable '+cvar
- # DATA:
- id_in = Dataset(cf_T_in)
- try:
- vdepth = id_in.variables['deptht'][:]
- except KeyError as e:
- vdepth = id_in.variables['olevel'][:]
- Xd_m = id_in.variables[cvar][:,:,:,:]
- id_in.close()
- print ' ==> variable '+cvar+' read !'
- j100m = bt.find_index_from_value(100. , vdepth) ; print 'j100m = ', j100m, '=> ', vdepth[j100m]
- j1000m = bt.find_index_from_value(1000. , vdepth) ; print 'j1000m = ', j1000m, '=> ', vdepth[j1000m]
- ( nt, nk0, nj0, ni0 ) = Xd_m.shape
- if nt != 12 and nt != 1 : print 'ERROR: '+cnexec+' => only treating monthly or annual data so far...'; sys.exit(0)
- if ( nk0, nj0, ni0 ) != ( nk, nj, ni ):
- print 'ERROR: '+cnexec+' => Field and metrics do not agree in size!'
- print ' ==> nk0, nj0, ni0 / nk, nj, ni = ', nk0, nj0, ni0, '/', nk, nj, ni
- sys.exit(0)
- vtime = nmp.zeros(nt)
- for jt in range(nt): vtime[jt] = float(jyear) + (float(jt)+0.5)*1./float(nt)
- print ' * Calendar: ', vtime[:]
- # Annual mean array for current year:
- Xd_y = nmp.zeros((1, nk, nj, ni))
- if nt == 12:
- Xd_y[0,:,:,:] = nmp.mean(Xd_m, axis=0)
- else:
- Xd_y[0,:,:,:] = Xd_m[0,:,:,:]
- joce = 0
- for cocean in list_basin_names[:]:
- colnm = list_basin_lgnms[joce]
- print ' ===> '+cvar+' in basin '+cocean+' ('+colnm+')'
- # Decrasing the domain size if possible:
- (i1,j1,i2,j2) = bo.shrink_domain(mask[joce,0,:,:])
- #(vjj , vji) = nmp.where(mask[joce,0,:,:]>0.5)
- #j1 = max( nmp.min(vjj)-2 , 0 )
- #i1 = max( nmp.min(vji)-2 , 0 )
- #j2 = min( nmp.max(vjj)+2 , nj-1 ) + 1
- #i2 = min( nmp.max(vji)+2 , ni-1 ) + 1
- #if (i1,j1,i2,j2) != (0,0,ni,nj): print ' ===> zooming on i1,j1 -> i2,j2:', i1,j1,'->',i2,j2
-
- # I) Montly mean for diffrent depth ranges
- # ========================================
-
- 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
- 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])
- 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])
- 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])
- cf_out = vdic['DIAG_D']+'/3d_'+cvar+'_'+CONFEXP+'_'+cocean+'.nc'
- cv1 = cvar+'_0-bottom'
- cv2 = cvar+'_0-100'
- cv3 = cvar+'_100-1000'
- cv4 = cvar+'_1000-bottom'
- bnc.wrt_appnd_1d_series(vtime, Vts_tot, cf_out, cv1,
- cu_t='year', cu_d='Unknown', cln_d ='3D-average of '+cvar+': surface to bottom, '+colnm,
- vd2=Vts_0_100, cvar2=cv2, cln_d2='3D-average of '+cvar+': surface to 100m, '+colnm,
- vd3=Vts_100_1000, cvar3=cv3, cln_d3='3D-average of '+cvar+': 100m to 1000m, '+colnm,
- vd4=Vts_1000_bot, cvar4=cv4, cln_d4='3D-average of '+cvar+': 1000m to bottom, '+colnm)
- # II) Annual mean vertical profile
- # ================================
- Vf = nmp.zeros(nk)
- for jk in range(nk):
- [ rf ] = bo.mean_2d(Xd_y[:,jk,j1:j2,i1:i2], mask[joce,jk,j1:j2,i1:i2], Xa[j1:j2,i1:i2])
- Vf[jk] = rf
- # NETCDF:
- cf_out = vdic['DIAG_D']+'/'+cvar+'_mean_Vprofile_'+CONFEXP+'_'+cocean+'.nc'
- l_nc_is_new = not os.path.exists(cf_out)
- #
- # Creating/Opening output Netcdf file:
- if l_nc_is_new:
- f_out = Dataset(cf_out, 'w', format='NETCDF3_CLASSIC')
- else:
- f_out = Dataset(cf_out, 'a', format='NETCDF3_CLASSIC')
- if l_nc_is_new:
- jrec2write = 0
- # Creating Dimensions:
- f_out.createDimension('time', None)
- f_out.createDimension('deptht', nk)
- # Creating variables:
- id_t = f_out.createVariable('time','f4',('time',)) ; id_t.units = 'year'
- id_z = f_out.createVariable('deptht','f4',('deptht',)) ; id_z.units = 'm'
- id_v01 = f_out.createVariable(cvar ,'f4',('time','deptht',))
- id_v01.long_name = 'Horizontally-averaged '+cvar+': '+colnm
- # Writing depth vector
- id_z[:] = vdepth[:]
- id_t[jrec2write] = float(jyear)+0.5
- id_v01[jrec2write,:] = Vf[:]
- f_out.Author = 'L. Brodeau ('+cnexec+' of Barakuda)'
- else:
- vt = f_out.variables['time']
- jrec2write = len(vt)
- v01 = f_out.variables[cvar]
- vt[jrec2write] = float(jyear)+0.5
- v01[jrec2write,:] = Vf[:]
- f_out.close()
- print cf_out+' written!'
- print ''
- joce = joce + 1
- del Xd_m
- print '\n'
- print ' +++ '+cnexec+' => Done with 3D-averaging of variable '+cvar+'!\n'
- print '\n *** EXITING '+cnexec+' for year '+cyear+' and variable '+cvar+'!\n'
|