source: lmdz_wrf/trunk/tools/diag_tools.py @ 2391

Last change on this file since 2391 was 2391, checked in by lfita, 6 years ago

Adding description

File size: 96.2 KB
Line 
1# Tools for the compute of diagnostics
2# L. Fita, CIMA. CONICET-UBA, CNRS UMI-IFAECI, Buenos Aires, Argentina
3
4# Available general pupose diagnostics (model independent) providing (varv1, varv2, ..., dimns, dimvns)
5# compute_accum: Function to compute the accumulation of a variable
6# compute_cllmh: Function to compute cllmh: low/medium/hight cloud fraction following
7#   newmicro.F90 from LMDZ compute_clt(cldfra, pres, dimns, dimvns)
8# compute_clt: Function to compute the total cloud fraction following 'newmicro.F90' from LMDZ
9# compute_clivi: Function to compute cloud-ice water path (clivi)
10# compute_clwvl: Function to compute condensed water path (clwvl)
11# compute_deaccum: Function to compute the deaccumulation of a variable
12# compute_mslp: Function to compute mslp: mean sea level pressure following p_interp.F90 from WRF
13# compute_OMEGAw: Function to transform OMEGA [Pas-1] to velocities [ms-1]
14# compute_prw: Function to compute water vapour path (prw)
15# compute_rh: Function to compute relative humidity following 'Tetens' equation (T,P) ...'
16# compute_td: Function to compute the dew point temperature
17# compute_turbulence: Function to compute the rubulence term of the Taylor's decomposition ...'
18# C_diagnostic: Class to compute generic variables
19# compute_wd: Function to compute the wind direction 3D
20# compute_wds: Function to compute the wind direction
21# compute_wss: Function to compute the wind speed
22# compute_WRFhur: Function to compute WRF relative humidity following Teten's equation
23# compute_WRFta: Function to compute WRF air temperature
24# compute_WRFtd: Function to compute WRF dew-point air temperature
25# compute_WRFua: Function to compute geographical rotated WRF x-wind
26# compute_WRFva: Function to compute geographical rotated WRF y-wind
27# compute_WRFuava: Function to compute geographical rotated WRF 3D winds
28# compute_WRFuas: Function to compute geographical rotated WRF 2-meter x-wind
29# compute_WRFvas: Function to compute geographical rotated WRF 2-meter y-wind
30# compute_WRFuasvas: Fucntion to compute geographical rotated WRF 2-meter winds
31# derivate_centered: Function to compute the centered derivate of a given field
32# Forcompute_cellbnds: Function to compute cellboundaries using wind-staggered lon,
33#   lats as intersection of their related parallels and meridians
34# Forcompute_cellbndsreg: Function to compute cellboundaries using lon, lat from a
35#   reglar lon/lat projection as intersection of their related parallels and meridians
36# Forcompute_cllmh: Function to compute cllmh: low/medium/hight cloud fraction
37#   following newmicro.F90 from LMDZ via Fortran subroutine
38# Forcompute_clt: Function to compute the total cloud fraction following
39#   'newmicro.F90' from LMDZ via a Fortran module
40# Forcompute_fog_K84: Computation of fog and visibility following Kunkel, (1984)
41# Forcompute_fog_RUC: Computation of fog and visibility following RUC method Smirnova, (2000)
42# Forcompute_fog_FRAML50: fog and visibility following Gultepe and Milbrandt, (2010)
43# Forcompute_potevap_orPM: Function to compute potential evapotranspiration following
44#   Penman-Monteith formulation implemented in ORCHIDEE
45# Forcompute_psl_ptarget: Function to compute the sea-level pressure following
46#   target_pressure value found in `p_interp.F'
47# Forcompute_range_faces: Function to compute faces [uphill, valley, downhill] of sections of a
48#   mountain rage, along a given face
49# Forcompute_zmla_gen: Function to compute the boundary layer height following a
50#   generic method with Fortran
51# Forcompute_zwind: Function to compute the wind at a given height following the
52#   power law method
53# Forcompute_zwind_log: Function to compute the wind at a given height following the
54#   logarithmic law method
55# Forcompute_zwindMO: Function to compute the wind at a given height following the
56#   Monin-Obukhov theory
57# W_diagnostic: Class to compute WRF diagnostics variables
58
59# Others just providing variable values
60# var_cllmh: Fcuntion to compute cllmh on a 1D column
61# var_clt: Function to compute the total cloud fraction following 'newmicro.F90' from
62#   LMDZ using 1D vertical column values
63# var_convini: Function returns convective initialization (pr(t) > 0.0001) in time units
64# var_hur: Function to compute relative humidity following 'August - Roche - Magnus'
65#   formula
66# var_hur_Uhus: Function to compute relative humidity following 'August-Roche-Magnus'
67#   formula using hus
68# var_hur_tas_tds: Function to compute hur relative humidity from tas and tds
69# var_mslp: Fcuntion to compute mean sea-level pressure
70# var_td: Function to compute dew-point air temperature from temperature and pressure
71#   values
72# var_td_Uhus: Function to compute dew-point air temperature from temperature and
73#   pressure values using hus
74# var_tws_S11: Function to compute Wet Bulb temperature after Stull, 2011
75# var_timemax: This function returns the time at which variable reaches its maximum in time
76#   units
77# var_timeoverthres: This function returns the time at which (varv(t) > thres) in time units
78# var_virtualTemp: This function returns virtual temperature in K,
79# var_WRFtime: Function to copmute CFtimes from WRFtime variable
80# var_wd: Function to compute the wind direction
81# var_wd: Function to compute the wind speed
82# rotational_z: z-component of the rotatinoal of horizontal vectorial field
83# turbulence_var: Function to compute the Taylor's decomposition turbulence term from
84#   a a given variable
85
86import numpy as np
87from netCDF4 import Dataset as NetCDFFile
88import os
89import re
90import nc_var_tools as ncvar
91import generic_tools as gen
92import datetime as dtime
93import module_ForDiag as fdin
94import module_ForDef as fdef
95
96main = 'diag_tools.py'
97errormsg = 'ERROR -- error -- ERROR -- error'
98warnmsg = 'WARNING -- warning -- WARNING -- warning'
99
100# Constants
101grav = fdef.module_definitions.grav
102
103# Available WRFiag
104Wavailablediags = ['hur', 'p', 'ta', 'td', 'ua', 'va', 'uas', 'vas', 'wd', 'ws', 'zg']
105
106# Available General diagnostics
107Cavailablediags = ['hur', 'hur_Uhus', 'td', 'td_Uhus', 'wd', 'ws']
108
109# Gneral information
110##
111def reduce_spaces(string):
112    """ Function to give words of a line of text removing any extra space
113    """
114    values = string.replace('\n','').split(' ')
115    vals = []
116    for val in values:
117         if len(val) > 0:
118             vals.append(val)
119
120    return vals
121
122def variable_combo(varn,combofile):
123    """ Function to provide variables combination from a given variable name
124      varn= name of the variable
125      combofile= ASCII file with the combination of variables
126        [varn] [combo]
127          [combo]: '@' separated list of variables to use to generate [varn]
128            [WRFdt] to get WRF time-step (from general attributes)
129    >>> variable_combo('WRFprls','/home/lluis/PY/diagnostics.inf')
130    deaccum@RAINNC@XTIME@prnc
131    """
132    fname = 'variable_combo'
133
134    if varn == 'h':
135        print fname + '_____________________________________________________________'
136        print variable_combo.__doc__
137        quit()
138
139    if not os.path.isfile(combofile):
140        print errormsg
141        print '  ' + fname + ": file with combinations '" + combofile +              \
142          "' does not exist!!"
143        quit(-1)
144
145    objf = open(combofile, 'r')
146
147    found = False
148    for line in objf:
149        linevals = reduce_spaces(line)
150        varnf = linevals[0]
151        combo = linevals[1].replace('\n','')
152        if varn == varnf: 
153            found = True
154            break
155
156    if not found:
157        print errormsg
158        print '  ' + fname + ": variable '" + varn + "' not found in '" + combofile +\
159          "' !!"
160        combo='ERROR'
161
162    objf.close()
163
164    return combo
165
166# Mathematical operators
167##
168def compute_accum(varv, dimns, dimvns):
169    """ Function to compute the accumulation of a variable
170    compute_accum(varv, dimnames, dimvns)
171      [varv]= values to accum (assuming [t,])
172      [dimns]= list of the name of the dimensions of the [varv]
173      [dimvns]= list of the name of the variables with the values of the
174        dimensions of [varv]
175    """
176    fname = 'compute_accum'
177
178    deacdims = dimns[:]
179    deacvdims = dimvns[:]
180
181    slicei = []
182    slicee = []
183
184    Ndims = len(varv.shape)
185    for iid in range(0,Ndims):
186        slicei.append(slice(0,varv.shape[iid]))
187        slicee.append(slice(0,varv.shape[iid]))
188
189    slicee[0] = np.arange(varv.shape[0])
190    slicei[0] = np.arange(varv.shape[0])
191    slicei[0][1:varv.shape[0]] = np.arange(varv.shape[0]-1)
192
193    vari = varv[tuple(slicei)]
194    vare = varv[tuple(slicee)]
195
196    ac = vari*0.
197    for it in range(1,varv.shape[0]):
198        ac[it,] = ac[it-1,] + vare[it,]
199
200    return ac, deacdims, deacvdims
201
202def compute_deaccum(varv, dimns, dimvns):
203    """ Function to compute the deaccumulation of a variable
204    compute_deaccum(varv, dimnames, dimvns)
205      [varv]= values to deaccum (assuming [t,])
206      [dimns]= list of the name of the dimensions of the [varv]
207      [dimvns]= list of the name of the variables with the values of the
208        dimensions of [varv]
209    """
210    fname = 'compute_deaccum'
211
212    deacdims = dimns[:]
213    deacvdims = dimvns[:]
214
215    slicei = []
216    slicee = []
217
218    Ndims = len(varv.shape)
219    for iid in range(0,Ndims):
220        slicei.append(slice(0,varv.shape[iid]))
221        slicee.append(slice(0,varv.shape[iid]))
222
223    slicee[0] = np.arange(varv.shape[0])
224    slicei[0] = np.arange(varv.shape[0])
225    slicei[0][1:varv.shape[0]] = np.arange(varv.shape[0]-1)
226
227    vari = varv[tuple(slicei)]
228    vare = varv[tuple(slicee)]
229
230    deac = vare - vari
231
232    return deac, deacdims, deacvdims
233
234def derivate_centered(var,dim,dimv):
235    """ Function to compute the centered derivate of a given field
236      centered derivate(n) = (var(n-1) + var(n+1))/(2*dn).
237    [var]= variable
238    [dim]= which dimension to compute the derivate
239    [dimv]= dimension values (can be of different dimension of [var])
240    >>> derivate_centered(np.arange(16).reshape(4,4)*1.,1,1.)
241    [[  0.   1.   2.   0.]
242     [  0.   5.   6.   0.]
243     [  0.   9.  10.   0.]
244     [  0.  13.  14.   0.]]
245    """
246
247    fname = 'derivate_centered'
248   
249    vark = var.dtype
250
251    if hasattr(dimv, "__len__"):
252# Assuming that the last dimensions of var [..., N, M] are the same of dimv [N, M]
253        if len(var.shape) != len(dimv.shape):
254            dimvals = np.zeros((var.shape), dtype=vark)
255            if len(var.shape) - len(dimv.shape) == 1:
256                for iz in range(var.shape[0]):
257                    dimvals[iz,] = dimv
258            elif len(var.shape) - len(dimv.shape) == 2:
259                for it in range(var.shape[0]):
260                    for iz in range(var.shape[1]):
261                        dimvals[it,iz,] = dimv
262            else:
263                print errormsg
264                print '  ' + fname + ': dimension difference between variable',      \
265                  var.shape,'and variable with dimension values',dimv.shape,         \
266                  ' not ready !!!'
267                quit(-1)
268        else:
269            dimvals = dimv
270    else:
271# dimension values are identical everywhere!
272# from: http://stackoverflow.com/questions/16807011/python-how-to-identify-if-a-variable-is-an-array-or-a-scalar   
273        dimvals = np.ones((var.shape), dtype=vark)*dimv
274
275    derivate = np.zeros((var.shape), dtype=vark)
276    if dim > len(var.shape) - 1:
277        print errormsg
278        print '  ' + fname + ': dimension',dim,' too big for given variable of ' +   \
279          'shape:', var.shape,'!!!'
280        quit(-1)
281
282    slicebef = []
283    sliceaft = []
284    sliceder = []
285
286    for id in range(len(var.shape)):
287        if id == dim:
288            slicebef.append(slice(0,var.shape[id]-2))
289            sliceaft.append(slice(2,var.shape[id]))
290            sliceder.append(slice(1,var.shape[id]-1))
291        else:
292            slicebef.append(slice(0,var.shape[id]))
293            sliceaft.append(slice(0,var.shape[id]))
294            sliceder.append(slice(0,var.shape[id]))
295
296    if hasattr(dimv, "__len__"):
297        derivate[tuple(sliceder)] = (var[tuple(slicebef)] + var[tuple(sliceaft)])/   \
298          ((dimvals[tuple(sliceaft)] - dimvals[tuple(slicebef)]))
299        print (dimvals[tuple(sliceaft)] - dimvals[tuple(slicebef)])
300    else:
301        derivate[tuple(sliceder)] = (var[tuple(slicebef)] + var[tuple(sliceaft)])/   \
302          (2.*dimv)
303
304#    print 'before________'
305#    print var[tuple(slicebef)]
306
307#    print 'after________'
308#    print var[tuple(sliceaft)]
309
310    return derivate
311
312def rotational_z(Vx,Vy,pos):
313    """ z-component of the rotatinoal of horizontal vectorial field
314    \/ x (Vx,Vy,Vz) = \/xVy - \/yVx
315    [Vx]= Variable component x
316    [Vy]=  Variable component y
317    [pos]= poisition of the grid points
318    >>> rotational_z(np.arange(16).reshape(4,4)*1., np.arange(16).reshape(4,4)*1., 1.)
319    [[  0.   1.   2.   0.]
320     [ -4.   0.   0.  -7.]
321     [ -8.   0.   0. -11.]
322     [  0.  13.  14.   0.]]
323    """
324
325    fname =  'rotational_z'
326
327    ndims = len(Vx.shape)
328    rot1 = derivate_centered(Vy,ndims-1,pos)
329    rot2 = derivate_centered(Vx,ndims-2,pos)
330
331    rot = rot1 - rot2
332
333    return rot
334
335# Diagnostics
336##
337def Forcompute_cape_afwa(ta, hur, pa, zg, hgt, parcelm, dimns, dimvns):
338    """ Function to compute the CAPE, CIN, ZLFC, PLFC, LI following WRF
339      'phys/module_diaf_afwa.F' methodology
340    Forcompute_cape_afwa(ta, hur, pa, hgt, zsfc, parcelm, dimns, dimvns)
341      [ta]= air-temperature values (assuming [[t],z,y,x]) [K]
342      [pa]= pressure values (assuming [[t],z,y,x]) [Pa]
343      [zg]= gopotential height (assuming [[t],z,y,x]) [gpm]
344      [hgt]= topographical height (assuming [m]
345      [parcelm]= method of air-parcel to use
346      [dimns]= list of the name of the dimensions of [pa]
347      [dimvns]= list of the name of the variables with the values of the
348        dimensions of [pa]
349    """
350    fname = 'Forcompute_cape_afwa'
351
352    psldims = dimns[:]
353    pslvdims = dimvns[:]
354
355    if len(pa.shape) == 4:
356        cape = np.zeros((pa.shape[0],pa.shape[2],pa.shape[3]), dtype=np.float)
357        cin = np.zeros((pa.shape[0],pa.shape[2],pa.shape[3]), dtype=np.float)
358        zlfc = np.zeros((pa.shape[0],pa.shape[2],pa.shape[3]), dtype=np.float)
359        plfc = np.zeros((pa.shape[0],pa.shape[2],pa.shape[3]), dtype=np.float)
360        li = np.zeros((pa.shape[0],pa.shape[2],pa.shape[3]), dtype=np.float)
361
362        dx = pa.shape[3]
363        dy = pa.shape[2]
364        dz = pa.shape[1]
365        dt = pa.shape[0]
366        psldims.pop(1)
367        pslvdims.pop(1)
368
369        pcape,pcin,pzlfc,pplfc,pli= fdin.module_fordiagnostics.compute_cape_afwa4d(  \
370          ta=ta[:].transpose(), hur=hur[:].transpose(), press=pa[:].transpose(),     \
371          zg=zg[:].transpose(), hgt=hgt.transpose(), parcelmethod=parcelm, d1=dx,    \
372          d2=dy, d3=dz, d4=dt)
373        cape = pcape.transpose()
374        cin = pcin.transpose()
375        zlfc = pzlfc.transpose()
376        plfc = pplfc.transpose()
377        li = pli.transpose()
378    else:
379        print errormsg
380        print '  ' + fname + ': rank', len(pa.shape), 'not ready !!'
381        print '  it only computes 4D [t,z,y,x] rank values'
382        quit(-1)
383
384    return cape, cin, zlfc, plfc, li, psldims, pslvdims
385
386
387
388def var_clt(cfra):
389    """ Function to compute the total cloud fraction following 'newmicro.F90' from
390      LMDZ using 1D vertical column values
391      [cldfra]= cloud fraction values (assuming [[t],z,y,x])
392    """
393    ZEPSEC=1.0E-12
394
395    fname = 'var_clt'
396
397    zclear = 1.
398    zcloud = 0.
399
400    dz = cfra.shape[0]
401    for iz in range(dz):
402        zclear =zclear*(1.-np.max([cfra[iz],zcloud]))/(1.-np.min([zcloud,1.-ZEPSEC]))
403        clt = 1. - zclear
404        zcloud = cfra[iz]
405
406    return clt
407
408def compute_clt(cldfra, dimns, dimvns):
409    """ Function to compute the total cloud fraction following 'newmicro.F90' from
410      LMDZ
411    compute_clt(cldfra, dimnames)
412      [cldfra]= cloud fraction values (assuming [[t],z,y,x])
413      [dimns]= list of the name of the dimensions of [cldfra]
414      [dimvns]= list of the name of the variables with the values of the
415        dimensions of [cldfra]
416    """
417    fname = 'compute_clt'
418
419    cltdims = dimns[:]
420    cltvdims = dimvns[:]
421
422    if len(cldfra.shape) == 4:
423        clt = np.zeros((cldfra.shape[0],cldfra.shape[2],cldfra.shape[3]),            \
424          dtype=np.float)
425        dx = cldfra.shape[3]
426        dy = cldfra.shape[2]
427        dz = cldfra.shape[1]
428        dt = cldfra.shape[0]
429        cltdims.pop(1)
430        cltvdims.pop(1)
431
432        for it in range(dt):
433            for ix in range(dx):
434                for iy in range(dy):
435                    zclear = 1.
436                    zcloud = 0.
437                    gen.percendone(it*dx*dy + ix*dy + iy, dx*dy*dt, 5, 'diagnosted')
438                    clt[it,iy,ix] = var_clt(cldfra[it,:,iy,ix])
439
440    else:
441        clt = np.zeros((cldfra.shape[1],cldfra.shape[2]), dtype=np.float)
442        dx = cldfra.shape[2]
443        dy = cldfra.shape[1]
444        dy = cldfra.shape[0]
445        cltdims.pop(0)
446        cltvdims.pop(0)
447        for ix in range(dx):
448            for iy in range(dy):
449                zclear = 1.
450                zcloud = 0.
451                gen.percendone(ix*dy + iy, dx*dy*dt, 5, 'diagnosted')
452                clt[iy,ix] = var_clt(cldfra[:,iy,ix])
453
454    return clt, cltdims, cltvdims
455
456def Forcompute_clt(cldfra, dimns, dimvns):
457    """ Function to compute the total cloud fraction following 'newmicro.F90' from
458      LMDZ via a Fortran module
459    compute_clt(cldfra, dimnames)
460      [cldfra]= cloud fraction values (assuming [[t],z,y,x])
461      [dimns]= list of the name of the dimensions of [cldfra]
462      [dimvns]= list of the name of the variables with the values of the
463        dimensions of [cldfra]
464    """
465    fname = 'Forcompute_clt'
466
467    cltdims = dimns[:]
468    cltvdims = dimvns[:]
469
470
471    if len(cldfra.shape) == 4:
472        clt = np.zeros((cldfra.shape[0],cldfra.shape[2],cldfra.shape[3]),            \
473          dtype=np.float)
474        dx = cldfra.shape[3]
475        dy = cldfra.shape[2]
476        dz = cldfra.shape[1]
477        dt = cldfra.shape[0]
478        cltdims.pop(1)
479        cltvdims.pop(1)
480
481        clt = fdin.module_fordiagnostics.compute_clt4d2(cldfra[:])
482
483    else:
484        clt = np.zeros((cldfra.shape[1],cldfra.shape[2]), dtype=np.float)
485        dx = cldfra.shape[2]
486        dy = cldfra.shape[1]
487        dy = cldfra.shape[0]
488        cltdims.pop(0)
489        cltvdims.pop(0)
490
491        clt = fdin.module_fordiagnostics.compute_clt3d1(cldfra[:])
492
493    return clt, cltdims, cltvdims
494
495def var_cllmh(cfra, p):
496    """ Fcuntion to compute cllmh on a 1D column
497    """
498
499    fname = 'var_cllmh'
500
501    ZEPSEC =1.0E-12
502    prmhc = 440.*100.
503    prmlc = 680.*100.
504
505    zclearl = 1.
506    zcloudl = 0.
507    zclearm = 1.
508    zcloudm = 0.
509    zclearh = 1.
510    zcloudh = 0.
511
512    dvz = cfra.shape[0]
513
514    cllmh = np.ones((3), dtype=np.float)
515
516    for iz in range(dvz):
517        if p[iz] < prmhc:
518            cllmh[2] = cllmh[2]*(1.-np.max([cfra[iz], zcloudh]))/(1.-                \
519              np.min([zcloudh,1.-ZEPSEC]))
520            zcloudh = cfra[iz]
521        elif p[iz] >= prmhc and p[iz] < prmlc:
522            cllmh[1] = cllmh[1]*(1.-np.max([cfra[iz], zcloudm]))/(1.-                \
523              np.min([zcloudm,1.-ZEPSEC]))
524            zcloudm = cfra[iz]
525        elif p[iz] >= prmlc:
526            cllmh[0] = cllmh[0]*(1.-np.max([cfra[iz], zcloudl]))/(1.-                \
527              np.min([zcloudl,1.-ZEPSEC]))
528            zcloudl = cfra[iz]
529
530    cllmh = 1.- cllmh
531
532    return cllmh
533
534def Forcompute_cellbnds(ulon, ulat, vlon, vlat, dimns, dimvns):
535    """ Function to compute cellboundaries using wind-staggered lon, lats as
536      intersection of their related parallels and meridians
537    compute_cellbnds(ulon, ulat, vlon, vlat, dimns, dimvns)
538      [ulon]= x-staggered longitudes (assuming [y,x+1])
539      [ulat]= x-staggered latitudes (assuming [y,x+1])
540      [vlon]= y-staggered longitudes (assuming [y+1,x])
541      [vlat]= y-staggered latitudes (assuming [y+1,x])
542      [dimns]= list of the name of the dimensions of [cldfra]
543      [dimvns]= list of the name of the variables with the values of the
544        dimensions of [ulon]
545    """
546    fname = 'Forcompute_cellbnds'
547
548    dims = dimns[:]
549    vdims = dimvns[:]
550
551    if len(ulon.shape) == 2:
552        sdx = ulon.shape[1]
553        dy = ulon.shape[0]
554        dx = vlon.shape[1]
555        sdy = vlon.shape[0]
556
557        ulont = ulon.transpose()
558        ulatt = ulat.transpose()
559        vlont = vlon.transpose()
560        vlatt = vlat.transpose()
561
562        xbndst, ybndst = fdin.module_fordiagnostics.compute_cellbnds(ulon=ulont,     \
563          ulat=ulatt, vlon=vlont, vlat=vlatt, dx=dx, dy=dy, sdx=sdx, sdy=sdy)
564    else:
565        print errormsg
566        print '  ' + fname + ": wrong rank of variables !!"
567        print '    2D matrices are expected and its found instead'
568        print '    ulon shape:', ulon.shape
569        print '    ulat shape:', ulat.shape
570        print '    vlon shape:', vlon.shape
571        print '    vlat shape:', vlat.shape
572        quit(-1)
573   
574    xbnds = xbndst.transpose()
575    ybnds = ybndst.transpose()
576
577    return xbnds, ybnds, dims, vdims
578
579
580def Forcompute_cellbndsreg(lon, lat, dimns, dimvns):
581    """ Function to compute cellboundaries using lon, lat from a reglar lon/lat
582      projection as intersection of their related parallels and meridians
583    compute_cellbnds(ulon, ulat, vlon, vlat, dimns, dimvns)
584      [ulon]= x-staggered longitudes (assuming [y,x+1])
585      [ulat]= x-staggered latitudes (assuming [y,x+1])
586      [vlon]= y-staggered longitudes (assuming [y+1,x])
587      [vlat]= y-staggered latitudes (assuming [y+1,x])
588      [dimns]= list of the name of the dimensions of [cldfra]
589      [dimvns]= list of the name of the variables with the values of the
590        dimensions of [ulon]
591    """
592    fname = 'Forcompute_cellbndsreg'
593
594    dims = dimns[:]
595    vdims = dimvns[:]
596
597    if len(lon.shape) == 2:
598        dy = lon.shape[0]
599        dx = lon.shape[1]
600
601        lont = lon.transpose()
602        latt = lat.transpose()
603
604        xbndst, ybndst = fdin.module_fordiagnostics.compute_cellbndsreg(lon=lont,    \
605          lat=latt, dx=dx, dy=dy)
606    else:
607        print errormsg
608        print '  ' + fname + ": wrong rank of variables !!"
609        print '    2D matrices are expected and its found instead'
610        print '    lon shape:', lon.shape
611        print '    lat shape:', lat.shape
612        quit(-1)
613   
614    xbnds = xbndst.transpose()
615    ybnds = ybndst.transpose()
616
617    return xbnds, ybnds, dims, vdims
618
619def Forcompute_cllmh(cldfra, pres, dimns, dimvns):
620    """ Function to compute cllmh: low/medium/hight cloud fraction following newmicro.F90 from LMDZ via Fortran subroutine
621    compute_clt(cldfra, pres, dimns, dimvns)
622      [cldfra]= cloud fraction values (assuming [[t],z,y,x])
623      [pres] = pressure field
624      [dimns]= list of the name of the dimensions of [cldfra]
625      [dimvns]= list of the name of the variables with the values of the
626        dimensions of [cldfra]
627    """
628    fname = 'Forcompute_cllmh'
629
630    cllmhdims = dimns[:]
631    cllmhvdims = dimvns[:]
632
633    if len(cldfra.shape) == 4:
634        dx = cldfra.shape[3]
635        dy = cldfra.shape[2]
636        dz = cldfra.shape[1]
637        dt = cldfra.shape[0]
638        cllmhdims.pop(1)
639        cllmhvdims.pop(1)
640
641        cllmh = fdin.module_fordiagnostics.compute_cllmh4d2(cldfra[:], pres[:])
642       
643    else:
644        dx = cldfra.shape[2]
645        dy = cldfra.shape[1]
646        dz = cldfra.shape[0]
647        cllmhdims.pop(0)
648        cllmhvdims.pop(0)
649
650        cllmh = fdin.module_fordiagnostics.compute_cllmh3d1(cldfra[:], pres[:])
651
652    return cllmh, cllmhdims, cllmhvdims
653
654def compute_cllmh(cldfra, pres, dimns, dimvns):
655    """ Function to compute cllmh: low/medium/hight cloud fraction following newmicro.F90 from LMDZ
656    compute_clt(cldfra, pres, dimns, dimvns)
657      [cldfra]= cloud fraction values (assuming [[t],z,y,x])
658      [pres] = pressure field
659      [dimns]= list of the name of the dimensions of [cldfra]
660      [dimvns]= list of the name of the variables with the values of the
661        dimensions of [cldfra]
662    """
663    fname = 'compute_cllmh'
664
665    cllmhdims = dimns[:]
666    cllmhvdims = dimvns[:]
667
668    if len(cldfra.shape) == 4:
669        dx = cldfra.shape[3]
670        dy = cldfra.shape[2]
671        dz = cldfra.shape[1]
672        dt = cldfra.shape[0]
673        cllmhdims.pop(1)
674        cllmhvdims.pop(1)
675
676        cllmh = np.ones(tuple([3, dt, dy, dx]), dtype=np.float)
677
678        for it in range(dt):
679            for ix in range(dx):
680                for iy in range(dy):
681                    gen.percendone(it*dx*dy + ix*dy + iy, dx*dy*dt, 5, 'diagnosted')
682                    cllmh[:,it,iy,ix] = var_cllmh(cldfra[it,:,iy,ix], pres[it,:,iy,ix])
683       
684    else:
685        dx = cldfra.shape[2]
686        dy = cldfra.shape[1]
687        dz = cldfra.shape[0]
688        cllmhdims.pop(0)
689        cllmhvdims.pop(0)
690
691        cllmh = np.ones(tuple([3, dy, dx]), dtype=np.float)
692
693        for ix in range(dx):
694            for iy in range(dy):
695                gen.percendone(ix*dy + iy,dx*dy, 5, 'diagnosted')
696                cllmh[:,iy,ix] = var_cllmh(cldfra[:,iy,ix], pres[:,iy,ix])
697
698    return cllmh, cllmhdims, cllmhvdims
699
700def compute_clivi(dens, qtot, dimns, dimvns):
701    """ Function to compute cloud-ice water path (clivi)
702      [dens] = density [in kgkg-1] (assuming [t],z,y,x)
703      [qtot] = added mixing ratio of all cloud-ice species in [kgkg-1] (assuming [t],z,y,x)
704      [dimns]= list of the name of the dimensions of [q]
705      [dimvns]= list of the name of the variables with the values of the
706        dimensions of [q]
707    """
708    fname = 'compute_clivi'
709
710    clividims = dimns[:]
711    clivivdims = dimvns[:]
712
713    if len(qtot.shape) == 4:
714        clividims.pop(1)
715        clivivdims.pop(1)
716    else:
717        clividims.pop(0)
718        clivivdims.pop(0)
719
720    data1 = dens*qtot
721    clivi = np.sum(data1, axis=1)
722
723    return clivi, clividims, clivivdims
724
725
726def compute_clwvl(dens, qtot, dimns, dimvns):
727    """ Function to compute condensed water path (clwvl)
728      [dens] = density [in kgkg-1] (assuming [t],z,y,x)
729      [qtot] = added mixing ratio of all cloud-water species in [kgkg-1] (assuming [t],z,y,x)
730      [dimns]= list of the name of the dimensions of [q]
731      [dimvns]= list of the name of the variables with the values of the
732        dimensions of [q]
733    """
734    fname = 'compute_clwvl'
735
736    clwvldims = dimns[:]
737    clwvlvdims = dimvns[:]
738
739    if len(qtot.shape) == 4:
740        clwvldims.pop(1)
741        clwvlvdims.pop(1)
742    else:
743        clwvldims.pop(0)
744        clwvlvdims.pop(0)
745
746    data1 = dens*qtot
747    clwvl = np.sum(data1, axis=1)
748
749    return clwvl, clwvldims, clwvlvdims
750
751def var_virtualTemp (temp,rmix):
752    """ This function returns virtual temperature in K,
753      temp: temperature [K]
754      rmix: mixing ratio in [kgkg-1]
755    """
756
757    fname = 'var_virtualTemp'
758
759    virtual=temp*(0.622+rmix)/(0.622*(1.+rmix))
760
761    return virtual
762
763def var_convini(pr, time, dimns, dimvns):
764    """ This function returns convective initialization (pr(t) > 0.0001) in time units
765      pr: precipitation fux [kgm-2s-1]
766      time: time in CF coordinates
767    """
768    fname = 'var_convini'
769
770    dt = pr.shape[0]
771    dy = pr.shape[1]
772    dx = pr.shape[2]
773
774    vardims = dimns[:]
775    varvdims = dimvns[:]
776
777    vardims.pop(0)
778    varvdims.pop(0)
779
780    prmin = 0.0001
781    convini = np.ones((dy, dx), dtype=np.float)*gen.fillValueF
782    for it in range(dt):
783# NOT working ?
784#        convini = np.where(convini == gen.fillValueF and pr[it,:,:] >= prmin,        \
785#          time[it], fillValueF)
786        for j in range(dy):
787            for i in range(dx):
788                if convini[j,i] == gen.fillValueF and pr[it,j,i] >= prmin:
789                    convini[j,i] = time[it]
790                    break
791
792    return convini, vardims, varvdims
793
794def var_timemax(varv, time, dimns, dimvns):
795    """ This function returns the time at which variable reaches its maximum in time
796        units
797      varv: values of the variable to use
798      time: time in CF coordinates
799    """
800    fname = 'var_timemax'
801
802    dt = varv.shape[0]
803    dy = varv.shape[1]
804    dx = varv.shape[2]
805
806    vardims = dimns[:]
807    varvdims = dimvns[:]
808
809    vardims.pop(0)
810    varvdims.pop(0)
811
812    timemax = np.ones((dy, dx), dtype=np.float)*gen.fillValueF
813    varmax = np.max(varv, axis=0)
814    for j in range(dy):
815        for i in range(dx):
816            it = gen.index_vec(varv[:,j,i], varmax[j,i])
817            timemax[j,i] = time[it]
818
819    return timemax, vardims, varvdims
820
821def var_timeoverthres(varv, time, thres, dimns, dimvns):
822    """ This function returns the time at which (varv(t) > thres) in time units
823      varv: values of the variable to use
824      time: time in CF coordinates
825      thres: threshold to overpass
826    """
827    fname = 'var_timeoverthres'
828
829    dt = varv.shape[0]
830    dy = varv.shape[1]
831    dx = varv.shape[2]
832
833    vardims = dimns[:]
834    varvdims = dimvns[:]
835
836    vardims.pop(0)
837    varvdims.pop(0)
838
839    timeoverthres = np.ones((dy, dx), dtype=np.float)*gen.fillValueF
840    for it in range(dt):
841        for j in range(dy):
842            for i in range(dx):
843                if timeoverthres[j,i] == gen.fillValueF and varv[it,j,i] >= thres:
844                    timeoverthres[j,i] = time[it]
845                    break
846
847    return timeoverthres, vardims, varvdims
848
849def Forcompute_zint(var, zinterlev, zweights, dimns, dimvns):
850    """ Function to compute a vertical integration of volumetric quantities
851    Forcompute_mrso(smois, dsoil, dimns, dimvns)
852      [var]= values (assuming [[t],z,y,x]) [volumetric units]
853      [zinterlev]= depth of each layer (assuming [z]) [same z units as var]
854      [zweights]= weights to apply to each level (just in case...)
855      [dimns]= list of the name of the dimensions of [smois]
856      [dimvns]= list of the name of the variables with the values of the
857        dimensions of [smois]
858    """
859    fname = 'Forcompute_zint'
860
861    vardims = dimns[:]
862    varvdims = dimvns[:]
863
864    if len(var.shape) == 4:
865        zint = np.zeros((var.shape[0],var.shape[2],var.shape[3]), dtype=np.float)
866        dx = var.shape[3]
867        dy = var.shape[2]
868        dz = var.shape[1]
869        dt = var.shape[0]
870        vardims.pop(1)
871        varvdims.pop(1)
872
873        zintvart=fdin.module_fordiagnostics.compute_zint4d(var4d=var[:].transpose(), \
874          dlev=zinterlev[:].transpose(), zweight=zweights[:].transpose(), d1=dx,     \
875          d2=dy, d3=dz, d4=dt)
876        zintvar = zintvart.transpose()
877    else:
878        print errormsg
879        print '  ' + fname + ': rank', len(var.shape), 'not ready !!'
880        print '  it only computes 4D [t,z,y,x] rank values'
881        quit(-1)
882
883    return zintvar, vardims, varvdims
884
885def var_mslp(pres, psfc, ter, tk, qv):
886    """ Function to compute mslp on a 1D column
887    """
888
889    fname = 'var_mslp'
890
891    N = 1.0
892    expon=287.04*.0065/9.81
893    pref = 40000.
894
895# First find where about 400 hPa is located
896    dz=len(pres) 
897
898    kref = -1
899    pinc = pres[0] - pres[dz-1]
900
901    if pinc < 0.:
902        for iz in range(1,dz):
903            if pres[iz-1] >= pref and pres[iz] < pref: 
904                kref = iz
905                break
906    else:
907        for iz in range(dz-1):
908            if pres[iz] >= pref and pres[iz+1] < pref: 
909                kref = iz
910                break
911
912    if kref == -1:
913        print errormsg
914        print '  ' + fname + ': no reference pressure:',pref,'found!!'
915        print '    values:',pres[:]
916        quit(-1)
917
918    mslp = 0.
919
920# We are below both the ground and the lowest data level.
921
922# First, find the model level that is closest to a "target" pressure
923# level, where the "target" pressure is delta-p less that the local
924# value of a horizontally smoothed surface pressure field.  We use
925# delta-p = 150 hPa here. A standard lapse rate temperature profile
926# passing through the temperature at this model level will be used
927# to define the temperature profile below ground.  This is similar
928# to the Benjamin and Miller (1990) method, using 
929# 700 hPa everywhere for the "target" pressure.
930
931# ptarget = psfc - 15000.
932    ptarget = 70000.
933    dpmin=1.e4
934    kupper = 0
935    if pinc > 0.:
936        for iz in range(dz-1,0,-1):
937            kupper = iz
938            dp=np.abs( pres[iz] - ptarget )
939            if dp < dpmin: exit
940            dpmin = np.min([dpmin, dp])
941    else:
942        for iz in range(dz):
943            kupper = iz
944            dp=np.abs( pres[iz] - ptarget )
945            if dp < dpmin: exit
946            dpmin = np.min([dpmin, dp])
947
948    pbot=np.max([pres[0], psfc])
949#    zbot=0.
950
951#    tbotextrap=tk(i,j,kupper,itt)*(pbot/pres_field(i,j,kupper,itt))**expon
952#    tvbotextrap=virtual(tbotextrap,qv(i,j,1,itt))
953
954#    data_out(i,j,itt,1) = (zbot+tvbotextrap/.0065*(1.-(interp_levels(1)/pbot)**expon))
955    tbotextrap = tk[kupper]*(psfc/ptarget)**expon
956    tvbotextrap = var_virtualTemp(tbotextrap, qv[kupper])
957    mslp = psfc*( (tvbotextrap+0.0065*ter)/tvbotextrap)**(1./expon)
958
959    return mslp
960
961def compute_mslp(pressure, psurface, terrain, temperature, qvapor, dimns, dimvns):
962    """ Function to compute mslp: mean sea level pressure following p_interp.F90 from WRF
963    var_mslp(pres, ter, tk, qv, dimns, dimvns)
964      [pressure]= pressure field [Pa] (assuming [[t],z,y,x])
965      [psurface]= surface pressure field [Pa]
966      [terrain]= topography [m]
967      [temperature]= temperature [K]
968      [qvapor]= water vapour mixing ratio [kgkg-1]
969      [dimns]= list of the name of the dimensions of [cldfra]
970      [dimvns]= list of the name of the variables with the values of the
971        dimensions of [pres]
972    """
973
974    fname = 'compute_mslp'
975
976    mslpdims = list(dimns[:])
977    mslpvdims = list(dimvns[:])
978
979    if len(pressure.shape) == 4:
980        mslpdims.pop(1)
981        mslpvdims.pop(1)
982    else:
983        mslpdims.pop(0)
984        mslpvdims.pop(0)
985
986    if len(pressure.shape) == 4:
987        dx = pressure.shape[3]
988        dy = pressure.shape[2]
989        dz = pressure.shape[1]
990        dt = pressure.shape[0]
991
992        mslpv = np.zeros(tuple([dt, dy, dx]), dtype=np.float)
993
994# Terrain... to 2D !
995        terval = np.zeros(tuple([dy, dx]), dtype=np.float)
996        if len(terrain.shape) == 3:
997            terval = terrain[0,:,:]
998        else:
999            terval = terrain
1000
1001        for ix in range(dx):
1002            for iy in range(dy):
1003                if terval[iy,ix] > 0.:
1004                    for it in range(dt):
1005                        mslpv[it,iy,ix] = var_mslp(pressure[it,:,iy,ix],             \
1006                          psurface[it,iy,ix], terval[iy,ix], temperature[it,:,iy,ix],\
1007                          qvapor[it,:,iy,ix])
1008
1009                        gen.percendone(it*dx*dy + ix*dy + iy, dx*dy*dt, 5, 'diagnosted')
1010                else:
1011                    mslpv[:,iy,ix] = psurface[:,iy,ix]
1012
1013    else:
1014        dx = pressure.shape[2]
1015        dy = pressure.shape[1]
1016        dz = pressure.shape[0]
1017
1018        mslpv = np.zeros(tuple([dy, dx]), dtype=np.float)
1019
1020# Terrain... to 2D !
1021        terval = np.zeros(tuple([dy, dx]), dtype=np.float)
1022        if len(terrain.shape) == 3:
1023            terval = terrain[0,:,:]
1024        else:
1025            terval = terrain
1026
1027        for ix in range(dx):
1028            for iy in range(dy):
1029                gen.percendone(ix*dy + iy,dx*dy, 5, 'diagnosted')
1030                if terval[iy,ix] > 0.:
1031                    mslpv[iy,ix] = var_mslp(pressure[:,iy,ix], psurface[iy,ix],      \
1032                      terval[iy,ix], temperature[:,iy,ix], qvapor[:,iy,ix])
1033                else:
1034                    mslpv[iy,ix] = psfc[iy,ix]
1035
1036    return mslpv, mslpdims, mslpvdims
1037
1038def Forcompute_psl_ecmwf(ps, hgt, ta1, pa2, unpa1, dimns, dimvns):
1039    """ Function to compute the sea-level pressure following Mats Hamrud and Philippe Courtier [Pa]
1040    Forcompute_psl_ptarget(ps, hgt, ta1, pa2, unpa1, dimns, dimvns)
1041      [ps]= surface pressure values (assuming [[t],y,x]) [Pa]
1042      [hgt]= opography (assuming [y,x]) [m]
1043      [ta1]= air-temperature values at first half-mass level (assuming [[t],y,x]) [K]
1044      [pa2]= pressure values at second full-mass levels (assuming [[t],y,x]) [Pa]
1045      [unpa1]= pressure values at first half-mass levels (assuming [[t],y,x]) [Pa]
1046      [dimns]= list of the name of the dimensions of [pa]
1047      [dimvns]= list of the name of the variables with the values of the
1048        dimensions of [pa]
1049    """
1050    fname = 'Forcompute_psl_ecmwf'
1051
1052    vardims = dimns[:]
1053    varvdims = dimvns[:]
1054
1055    if len(pa2.shape) == 3:
1056        psl = np.zeros((pa2.shape[0],pa2.shape[1],pa2.shape[2]), dtype=np.float)
1057        dx = pa2.shape[2]
1058        dy = pa2.shape[1]
1059        dt = pa2.shape[0]
1060        pslt= fdin.module_fordiagnostics.compute_psl_ecmwf( ps=ps[:].transpose(),    \
1061          hgt=hgt[:].transpose(), t=ta1[:].transpose(), press=pa2[:].transpose(),    \
1062          unpress=unpa1[:].transpose(), d1=dx, d2=dy, d4=dt)
1063        psl = pslt.transpose()
1064    else:
1065        print errormsg
1066        print '  ' + fname + ': rank', len(pa2.shape), 'not ready !!'
1067        print '  it only computes 3D [t,y,x] rank values'
1068        quit(-1)
1069
1070    return psl, vardims, varvdims
1071
1072def Forcompute_psl_ptarget(pa, ps, ta, hgt, qv, target_pressure, dimns, dimvns):
1073    """ Function to compute the sea-level pressure following target_pressure value
1074      found in `p_interp.F'
1075    Forcompute_psl_ptarget(pa, ps, ta, hgt, qv, dimns, dimvns)
1076      [pa]= pressure values (assuming [[t],z,y,x]) [Pa]
1077      [ps]= surface pressure values (assuming [[t],y,x]) [Pa]
1078      [ta]= air-temperature values (assuming [[t],z,y,x]) [K]
1079      [hgt]= opography (assuming [y,x]) [m]
1080      [qv]= water vapour mixing ratio (assuming [[t],z,y,x]) [kgkg-1]
1081      [dimns]= list of the name of the dimensions of [pa]
1082      [dimvns]= list of the name of the variables with the values of the
1083        dimensions of [pa]
1084    """
1085    fname = 'Forcompute_psl_ptarget'
1086
1087    psldims = dimns[:]
1088    pslvdims = dimvns[:]
1089
1090    if len(pa.shape) == 4:
1091        psl = np.zeros((pa.shape[0],pa.shape[2],pa.shape[3]), dtype=np.float)
1092        dx = pa.shape[3]
1093        dy = pa.shape[2]
1094        dz = pa.shape[1]
1095        dt = pa.shape[0]
1096        psldims.pop(1)
1097        pslvdims.pop(1)
1098
1099        pslt= fdin.module_fordiagnostics.compute_psl_ptarget4d2(                     \
1100          press=pa[:].transpose(), ps=ps[:].transpose(), hgt=hgt[:].transpose(),     \
1101          ta=ta[:].transpose(), qv=qv[:].transpose(), ptarget=target_pressure,       \
1102          d1=dx, d2=dy, d3=dz, d4=dt)
1103        psl = pslt.transpose()
1104    else:
1105        print errormsg
1106        print '  ' + fname + ': rank', len(pa.shape), 'not ready !!'
1107        print '  it only computes 4D [t,z,y,x] rank values'
1108        quit(-1)
1109
1110    return psl, psldims, pslvdims
1111
1112def Forcompute_zmla_gen(theta, qratio, zpl, hgt, dimns, dimvns):
1113    """ Function to compute the boundary layer height following a generic method
1114      with Fortran
1115    Forcompute_zmla_gen(theta, qratio, zpl, hgt, zmla, dimns, dimvns)
1116      [theta]= potential air-temperature values (assuming [[t],z,y,x]) [K]
1117      [qratio]= water mixing ratio (assuming [[t],z,y,x]) [kgkg-1]
1118      [zpl]= height from sea level (assuming [[t],z,y,x]) [m]
1119      [hgt]= topographical height (assuming [m]
1120      [zmla]= boundary layer height [m]
1121      [dimns]= list of the name of the dimensions of [theta]
1122      [dimvns]= list of the name of the variables with the values of the
1123        dimensions of [theta]
1124    """
1125    fname = 'Forcompute_zmla_gen'
1126
1127    zmladims = dimns[:]
1128    zmlavdims = dimvns[:]
1129
1130    if len(theta.shape) == 4:
1131        zmla= np.zeros((theta.shape[0],theta.shape[2],theta.shape[3]), dtype=np.float)
1132
1133        dx = theta.shape[3]
1134        dy = theta.shape[2]
1135        dz = theta.shape[1]
1136        dt = theta.shape[0]
1137        zmladims.pop(1)
1138        zmlavdims.pop(1)
1139
1140        pzmla= fdin.module_fordiagnostics.compute_zmla_generic4d(                    \
1141          tpot=theta[:].transpose(), qratio=qratio[:].transpose(),                   \
1142          z=zpl[:].transpose(), hgt=hgt.transpose(), d1=dx, d2=dy, d3=dz, d4=dt)
1143        zmla = pzmla.transpose()
1144    else:
1145        print errormsg
1146        print '  ' + fname + ': rank', len(theta.shape), 'not ready !!'
1147        print '  it only computes 4D [t,z,y,x] rank values'
1148        quit(-1)
1149
1150    return zmla, zmladims, zmlavdims
1151
1152def Forcompute_zwind(ua, va, z, uas, vas, sina, cosa, zval, dimns, dimvns):
1153    """ Function to compute the wind at a given height following the power law method
1154    Forcompute_zwind(ua, va, zsl, uas, vas, hgt, sina, cosa, zval, dimns, dimvns)
1155      [ua]= x-component of unstaggered 3D wind (assuming [[t],z,y,x]) [ms-1]
1156      [va]= y-component of unstaggered 3D wind (assuming [[t],z,y,x]) [ms-1]
1157      [z]= height above surface [m]
1158      [uas]= x-component of unstaggered 10 m wind (assuming [[t],z,y,x]) [ms-1]
1159      [vas]= y-component of unstaggered 10 m wind (assuming [[t],z,y,x]) [ms-1]
1160      [sina]= local sine of map rotation [1.]
1161      [cosa]= local cosine of map rotation [1.]
1162      [zval]= desired height for winds [m]
1163      [dimns]= list of the name of the dimensions of [ua]
1164      [dimvns]= list of the name of the variables with the values of the
1165        dimensions of [ua]
1166    """
1167    fname = 'Forcompute_zwind'
1168
1169    vardims = dimns[:]
1170    varvdims = dimvns[:]
1171
1172    if len(ua.shape) == 4:
1173        var1= np.zeros((ua.shape[0],ua.shape[2],ua.shape[3]), dtype=np.float)
1174        var2= np.zeros((ua.shape[0],ua.shape[2],ua.shape[3]), dtype=np.float)
1175
1176        dx = ua.shape[3]
1177        dy = ua.shape[2]
1178        dz = ua.shape[1]
1179        dt = ua.shape[0]
1180        vardims.pop(1)
1181        varvdims.pop(1)
1182
1183        pvar1, pvar2= fdin.module_fordiagnostics.compute_zwind4d(ua=ua.transpose(),  \
1184          va=va[:].transpose(), z=z[:].transpose(), uas=uas.transpose(),             \
1185          vas=vas.transpose(), sina=sina.transpose(), cosa=cosa.transpose(),         \
1186          zextrap=zval, d1=dx, d2=dy, d3=dz, d4=dt)
1187        var1 = pvar1.transpose()
1188        var2 = pvar2.transpose()
1189    else:
1190        print errormsg
1191        print '  ' + fname + ': rank', len(ua.shape), 'not ready !!'
1192        print '  it only computes 4D [t,z,y,x] rank values'
1193        quit(-1)
1194
1195    return var1, var2, vardims, varvdims
1196
1197def Forcompute_zwind_log(ua, va, z, uas, vas, sina, cosa, zval, dimns, dimvns):
1198    """ Function to compute the wind at a given height following the logarithmic law method
1199    Forcompute_zwind(ua, va, zsl, uas, vas, hgt, sina, cosa, zval, dimns, dimvns)
1200      [ua]= x-component of unstaggered 3D wind (assuming [[t],z,y,x]) [ms-1]
1201      [va]= y-component of unstaggered 3D wind (assuming [[t],z,y,x]) [ms-1]
1202      [z]= height above surface [m]
1203      [uas]= x-component of unstaggered 10 m wind (assuming [[t],z,y,x]) [ms-1]
1204      [vas]= y-component of unstaggered 10 m wind (assuming [[t],z,y,x]) [ms-1]
1205      [sina]= local sine of map rotation [1.]
1206      [cosa]= local cosine of map rotation [1.]
1207      [zval]= desired height for winds [m]
1208      [dimns]= list of the name of the dimensions of [ua]
1209      [dimvns]= list of the name of the variables with the values of the
1210        dimensions of [ua]
1211    """
1212    fname = 'Forcompute_zwind_log'
1213
1214    vardims = dimns[:]
1215    varvdims = dimvns[:]
1216
1217    if len(ua.shape) == 4:
1218        var1= np.zeros((ua.shape[0],ua.shape[2],ua.shape[3]), dtype=np.float)
1219        var2= np.zeros((ua.shape[0],ua.shape[2],ua.shape[3]), dtype=np.float)
1220
1221        dx = ua.shape[3]
1222        dy = ua.shape[2]
1223        dz = ua.shape[1]
1224        dt = ua.shape[0]
1225        vardims.pop(1)
1226        varvdims.pop(1)
1227
1228        pvar1, pvar2= fdin.module_fordiagnostics.compute_zwind_log4d(                \
1229          ua=ua.transpose(), va=va[:].transpose(), z=z[:].transpose(),               \
1230          uas=uas.transpose(), vas=vas.transpose(), sina=sina.transpose(),           \
1231          cosa=cosa.transpose(), zextrap=zval, d1=dx, d2=dy, d3=dz, d4=dt)
1232        var1 = pvar1.transpose()
1233        var2 = pvar2.transpose()
1234    else:
1235        print errormsg
1236        print '  ' + fname + ': rank', len(ua.shape), 'not ready !!'
1237        print '  it only computes 4D [t,z,y,x] rank values'
1238        quit(-1)
1239
1240    return var1, var2, vardims, varvdims
1241
1242def Forcompute_zwindMO(ust, znt, rmol, uas, vas, sina, cosa, zval, dimns, dimvns):
1243    """ Function to compute the wind at a given height following the Monin-Obukhov theory
1244    Forcompute_zwind(ust, znt, rmol, uas, vas, sina, cosa, zval, dimns, dimvns)
1245      [ust]: u* in similarity theory (assuming [[t],y,x]) [ms-1]
1246      [znt]: thermal time-varying roughness length (assuming [[t],y,x]) [m]
1247      [rmol]: inverse of Obukhov length (assuming [[t],y,x]) [m-1]
1248      [uas]= x-component of unstaggered 10 m wind (assuming [[t],y,x]) [ms-1]
1249      [vas]= y-component of unstaggered 10 m wind (assuming [[t],y,x]) [ms-1]
1250      [sina]= local sine of map rotation [1.]
1251      [cosa]= local cosine of map rotation [1.]
1252      [zval]= desired height for winds [m]
1253      [dimns]= list of the name of the dimensions of [uas]
1254      [dimvns]= list of the name of the variables with the values of the
1255        dimensions of [uas]
1256    """
1257    fname = 'Forcompute_zwindMO'
1258
1259    vardims = dimns[:]
1260    varvdims = dimvns[:]
1261
1262    if len(uas.shape) == 3:
1263        var1= np.zeros((uas.shape[0],uas.shape[1],uas.shape[2]), dtype=np.float)
1264        var2= np.zeros((uas.shape[0],uas.shape[1],uas.shape[2]), dtype=np.float)
1265
1266        dx = uas.shape[2]
1267        dy = uas.shape[1]
1268        dt = uas.shape[0]
1269
1270        pvar1, pvar2 = fdin.module_fordiagnostics.compute_zwindmo3d(                 \
1271          ust=ust.transpose(), znt=znt[:].transpose(), rmol=rmol[:].transpose(),     \
1272          uas=uas.transpose(), vas=vas.transpose(), sina=sina.transpose(),           \
1273          cosa=cosa.transpose(), newz=zval, d1=dx, d2=dy, d3=dt)
1274        var1 = pvar1.transpose()
1275        var2 = pvar2.transpose()
1276    else:
1277        print errormsg
1278        print '  ' + fname + ': rank', len(uas.shape), 'not ready !!'
1279        print '  it only computes 3D [t,y,x] rank values'
1280        quit(-1)
1281
1282    return var1, var2, vardims, varvdims
1283
1284def Forcompute_potevap_orPM(rho1, ust, uas, vas, tas, ps, qv1, dimns, dimvns):
1285    """ Function to compute potential evapotranspiration following Penman-Monteith
1286      formulation implemented in ORCHIDEE in src_sechiba/enerbil.f90
1287    Forcompute_potevap_orPM(rho1, uas, vas, tas, ps, qv2, qv1, dimns, dimvns)
1288      [rho1]= air-density at the first layer (assuming [[t],y,m]) [kgm-3]
1289      [ust]= u* in similarity theory (assuming [[t],y,x]) [ms-1]
1290      [uas]= x-component of unstaggered 10 m wind (assuming [[t],y,x]) [ms-1]
1291      [vas]= y-component of unstaggered 10 m wind (assuming [[t],y,x]) [ms-1]
1292      [tas]= 2m air temperature [K]
1293      [ps]= surface pressure [Pa]
1294      [qv1]= mixing ratio at the first atmospheric layer [kgkg-1]
1295      [dimns]= list of the name of the dimensions of [uas]
1296      [dimvns]= list of the name of the variables with the values of the
1297        dimensions of [uas]
1298    """
1299    fname = 'Forcompute_potevap_orPM'
1300
1301    vardims = dimns[:]
1302    varvdims = dimvns[:]
1303
1304    if len(uas.shape) == 3:
1305        var1= np.zeros((uas.shape[0],uas.shape[1],uas.shape[2]), dtype=np.float)
1306        var2= np.zeros((uas.shape[0],uas.shape[1],uas.shape[2]), dtype=np.float)
1307
1308        dx = uas.shape[2]
1309        dy = uas.shape[1]
1310        dt = uas.shape[0]
1311
1312        pvar = fdin.module_fordiagnostics.compute_potevap_orpm3d(                    \
1313          rho1=rho1.transpose(), ust=ust.transpose(), uas=uas.transpose(),           \
1314          vas=vas.transpose(), tas=tas.transpose(), ps=ps.transpose(),               \
1315          qv1=qv1.transpose(), d1=dx, d2=dy, d3=dt)
1316        var = pvar.transpose()
1317    else:
1318        print errormsg
1319        print '  ' + fname + ': rank', len(uas.shape), 'not ready !!'
1320        print '  it only computes 3D [t,y,x] rank values'
1321        quit(-1)
1322
1323    return var, vardims, varvdims
1324
1325def Forcompute_fog_K84(qcloud, qice, dimns, dimvns):
1326    """ Function to compute fog and visibility following Kunkel, (1984)
1327    Forcompute_fog_K84(qcloud, qice, dimns, dimvns)
1328      [qcloud]= cloud mixing ratio [kgk-1]
1329      [qice]= ice mixing ratio [kgk-1]
1330      [dimns]= list of the name of the dimensions of [uas]
1331      [dimvns]= list of the name of the variables with the values of the
1332        dimensions of [qcloud]
1333    """
1334    fname = 'Forcompute_fog_K84'
1335
1336    vardims = dimns[:]
1337    varvdims = dimvns[:]
1338
1339    if len(qcloud.shape) == 4:
1340        var= np.zeros((qcloud.shape[0],qcloud.shape[2],qcloud.shape[3]), dtype=np.float)
1341
1342        dx = qcloud.shape[3]
1343        dy = qcloud.shape[2]
1344        dz = qcloud.shape[1]
1345        dt = qcloud.shape[0]
1346        vardims.pop(1)
1347        varvdims.pop(1)
1348
1349        pvar1, pvar2 = fdin.module_fordiagnostics.compute_fog_k84(                   \
1350          qc=qcloud[:,0,:,:].transpose(), qi=qice[:,0,:,:].transpose(), d1=dx, d2=dy,\
1351          d3=dt)
1352        var1 = pvar1.transpose()
1353        var2 = pvar2.transpose()
1354    else:
1355        print errormsg
1356        print '  ' + fname + ': rank', len(qcloud.shape), 'not ready !!'
1357        print '  it only computes 4D [t,z,y,x] rank values'
1358        quit(-1)
1359
1360    return var1, var2, vardims, varvdims
1361
1362def Forcompute_fog_RUC(qvapor, temp, pres, dimns, dimvns):
1363    """ Function to compute fog and visibility following RUC method Smirnova, (2000)
1364    Forcompute_fog_RUC(qcloud, qice, dimns, dimvns)
1365      [qvapor]= water vapor mixing ratio [kgk-1]
1366      [temp]= temperature [K]
1367      [pres]= pressure [Pa]
1368      [dimns]= list of the name of the dimensions of [uas]
1369      [dimvns]= list of the name of the variables with the values of the
1370        dimensions of [qcloud]
1371    """
1372    fname = 'Forcompute_fog_RUC'
1373
1374    vardims = dimns[:]
1375    varvdims = dimvns[:]
1376
1377    if len(qvapor.shape) == 4:
1378        var= np.zeros((qvapor.shape[0],qvapor.shape[2],qvapor.shape[3]), dtype=np.float)
1379
1380        dx = qvapor.shape[3]
1381        dy = qvapor.shape[2]
1382        dz = qvapor.shape[1]
1383        dt = qvapor.shape[0]
1384        vardims.pop(1)
1385        varvdims.pop(1)
1386
1387        pvar1, pvar2 = fdin.module_fordiagnostics.compute_fog_ruc(                   \
1388          qv=qvapor[:,0,:,:].transpose(), ta=temp[:,0,:,:].transpose(),              \
1389          pres=pres[:,0,:,:].transpose(), d1=dx, d2=dy, d3=dt)
1390        var1 = pvar1.transpose()
1391        var2 = pvar2.transpose()
1392    elif len(qvapor.shape) == 3:
1393        var= np.zeros((qvapor.shape[0],qvapor.shape[1],qvapor.shape[2]), dtype=np.float)
1394
1395        dx = qvapor.shape[2]
1396        dy = qvapor.shape[1]
1397        dt = qvapor.shape[0]
1398
1399        pvar1, pvar2 = fdin.module_fordiagnostics.compute_fog_ruc(                   \
1400          qv=qvapor[:].transpose(), ta=temp[:].transpose(), pres=pres[:].transpose(),\
1401          d1=dx, d2=dy, d3=dt)
1402        var1 = pvar1.transpose()
1403        var2 = pvar2.transpose()
1404    else:
1405        print errormsg
1406        print '  ' + fname + ': rank', len(qcloud.shape), 'not ready !!'
1407        print '  it only computes 4D [t,z,y,x] or 3D [t,z,y,x] rank values'
1408        quit(-1)
1409
1410    return var1, var2, vardims, varvdims
1411
1412def Forcompute_fog_FRAML50(qvapor, temp, pres, dimns, dimvns):
1413    """ Function to compute fog (vis < 1km) and visibility following FRAM-L 50 % prob
1414         Gultepe, and Milbrandt, (2010), J. Appl. Meteor. Climatol.
1415    Forcompute_fog_FRAML50(qvapor, temp, pres, dimns, dimvns)
1416      [qvapor]= vapor mixing ratio [kgk-1]
1417      [temp]= temperature [K]
1418      [pres]= pressure [Pa]
1419      [dimns]= list of the name of the dimensions of [uas]
1420      [dimvns]= list of the name of the variables with the values of the
1421        dimensions of [qvapor]
1422    """
1423    fname = 'Forcompute_fog_FRAML50'
1424
1425    vardims = dimns[:]
1426    varvdims = dimvns[:]
1427
1428    if len(qvapor.shape) == 4:
1429        var= np.zeros((qvapor.shape[0],qvapor.shape[2],qvapor.shape[3]), dtype=np.float)
1430
1431        dx = qvapor.shape[3]
1432        dy = qvapor.shape[2]
1433        dz = qvapor.shape[1]
1434        dt = qvapor.shape[0]
1435        vardims.pop(1)
1436        varvdims.pop(1)
1437
1438        pvar1, pvar2 = fdin.module_fordiagnostics.compute_fog_framl50(               \
1439          qv=qvapor[:,0,:,:].transpose(), ta=temp[:,0,:,:].transpose(),              \
1440          pres=pres[:,0,:,:].transpose(), d1=dx, d2=dy, d3=dt)
1441        var1 = pvar1.transpose()
1442        var2 = pvar2.transpose()
1443    elif len(qvapor.shape) == 3:
1444        var= np.zeros((qvapor.shape[0],qvapor.shape[1],qvapor.shape[2]), dtype=np.float)
1445
1446        dx = qvapor.shape[2]
1447        dy = qvapor.shape[1]
1448        dt = qvapor.shape[0]
1449
1450        pvar1, pvar2 = fdin.module_fordiagnostics.compute_fog_framl50(               \
1451          qv=qvapor[:].transpose(), ta=temp[:].transpose(), pres=pres[:].transpose(),\
1452          d1=dx, d2=dy, d3=dt)
1453        var1 = pvar1.transpose()
1454        var2 = pvar2.transpose()
1455    else:
1456        print errormsg
1457        print '  ' + fname + ': rank', len(qvapor.shape), 'not ready !!'
1458        print '  it only computes 4D [t,z,y,x] or 3D [t,y,x] rank values'
1459        quit(-1)
1460
1461    return var1, var2, vardims, varvdims
1462
1463def Forcompute_range_faces(lon, lat, hgt, dsx, dsy, ds, face, dsfilt, dsnewrng,      \
1464  hvalleyrng, dimns, dimvns):
1465    """ Function to compute faces [uphill, valley, downhill] of sections of a mountain
1466      rage, along a given face
1467    Forcompute_range_faces(lon, lat, hgt, face, dimns, dimvns)
1468      [lon]= longitude values (assuming [y,x]) [degrees east]
1469      [lat]= latitude values (assuming [y,x]) [degrees north]
1470      [hgt]= height values (assuming [y,x]) [m]
1471      [dsx]= distance between grid points along x-axis (assuming [y,x]) [m]
1472      [dsy]= distance between grid points along y-axis (assuming [y,x]) [m]
1473      [ds]= distance between grid points (assuming [y,x]) [m]
1474      face= which face (axis along which produce slices) to use to compute the
1475        faces: WE, SN
1476      dsfilt= distance to filter orography smaller scale of it [m]
1477      dsnewrng= distance to start a new mountain range [m]
1478      hvalleyrng: maximum height of a valley to mark change of range [m]
1479      [dimns]= list of the name of the dimensions of [smois]
1480      [dimvns]= list of the name of the variables with the values of the
1481        dimensions of [smois]
1482    """
1483    fname = 'Forcompute_range_faces'
1484
1485    vardims = dimns[:]
1486    varvdims = dimvns[:]
1487
1488    if len(hgt.shape) == 2:
1489        faces = np.zeros(hgt.shape, dtype=np.float)
1490        dx = hgt.shape[1]
1491        dy = hgt.shape[0]
1492
1493        hgtmaxt, pthgtmaxt, dhgtt, peakst, valleyst, ofacest, ffacest, rngt,         \
1494          rnghgtmaxt, ptrnghgtmaxt =                                                 \
1495          fdin.module_fordiagnostics.compute_range_faces(lon=lon[:].transpose(),     \
1496          lat=lat[:].transpose(), hgt=hgt[:].transpose(), xdist=ds[:].transpose(),   \
1497          ydist=ds[:].transpose(), dist=ds[:].transpose(), face=face, dsfilt=dsfilt, \
1498          dsnewrange=dsnewrng, hvalrng=hvalleyrng, d1=dx, d2=dy)
1499
1500        hgtmax = hgtmaxt.transpose()
1501        pthgtmax = pthgtmaxt.transpose()
1502        dhgt = dhgtt.transpose()
1503        peaks = peakst.transpose()
1504        valleys = valleyst.transpose()
1505        origfaces = ofacest.transpose()
1506        filtfaces = ffacest.transpose()
1507        ranges = rngt.transpose()
1508        rangeshgtmax = rnghgtmaxt.transpose()
1509        ptrangeshgtmax = ptrnghgtmaxt.transpose()
1510
1511    else:
1512        print errormsg
1513        print '  ' + fname + ': rank', len(var.shape), 'not ready !!'
1514        print '  it only computes 2D [y,x] rank values'
1515        quit(-1)
1516
1517    return hgtmax, pthgtmax, dhgt, peaks, valleys, origfaces, filtfaces, vardims,    \
1518      varvdims, ranges, rangeshgtmax, ptrangeshgtmax
1519
1520####### ###### ##### #### ### ## # END Fortran diagnostics
1521
1522def compute_OMEGAw(omega, p, t, dimns, dimvns):
1523    """ Function to transform OMEGA [Pas-1] to velocities [ms-1]
1524      tacking: https://www.ncl.ucar.edu/Document/Functions/Contributed/omega_to_w.shtml
1525      [omega] = vertical velocity [in ms-1] (assuming [t],z,y,x)
1526      [p] = pressure in [Pa] (assuming [t],z,y,x)
1527      [t] = temperature in [K] (assuming [t],z,y,x)
1528      [dimns]= list of the name of the dimensions of [q]
1529      [dimvns]= list of the name of the variables with the values of the
1530        dimensions of [q]
1531    """
1532    fname = 'compute_OMEGAw'
1533
1534    rgas = 287.058            # J/(kg-K) => m2/(s2 K)
1535    g    = 9.80665            # m/s2
1536
1537    wdims = dimns[:]
1538    wvdims = dimvns[:]
1539
1540    rho  = p/(rgas*t)         # density => kg/m3
1541    w    = -omega/(rho*g)     
1542
1543    return w, wdims, wvdims
1544
1545def compute_prw(dens, q, dimns, dimvns):
1546    """ Function to compute water vapour path (prw)
1547      [dens] = density [in kgkg-1] (assuming [t],z,y,x)
1548      [q] = mixing ratio in [kgkg-1] (assuming [t],z,y,x)
1549      [dimns]= list of the name of the dimensions of [q]
1550      [dimvns]= list of the name of the variables with the values of the
1551        dimensions of [q]
1552    """
1553    fname = 'compute_prw'
1554
1555    prwdims = dimns[:]
1556    prwvdims = dimvns[:]
1557
1558    if len(q.shape) == 4:
1559        prwdims.pop(1)
1560        prwvdims.pop(1)
1561    else:
1562        prwdims.pop(0)
1563        prwvdims.pop(0)
1564
1565    data1 = dens*q
1566    prw = np.sum(data1, axis=1)
1567
1568    return prw, prwdims, prwvdims
1569
1570def compute_rh(p, t, q, dimns, dimvns):
1571    """ Function to compute relative humidity following 'Tetens' equation (T,P) ...'
1572      [t]= temperature (assuming [[t],z,y,x] in [K])
1573      [p] = pressure field (assuming in [hPa])
1574      [q] = mixing ratio in [kgkg-1]
1575      [dimns]= list of the name of the dimensions of [t]
1576      [dimvns]= list of the name of the variables with the values of the
1577        dimensions of [t]
1578    """
1579    fname = 'compute_rh'
1580
1581    rhdims = dimns[:]
1582    rhvdims = dimvns[:]
1583
1584    data1 = 10.*0.6112*np.exp(17.67*(t-273.16)/(t-29.65))
1585    data2 = 0.622*data1/(0.01*p-(1.-0.622)*data1)
1586
1587    rh = q/data2
1588
1589    return rh, rhdims, rhvdims
1590
1591def compute_td(p, temp, qv, dimns, dimvns):
1592    """ Function to compute the dew point temperature
1593      [p]= pressure [Pa]
1594      [temp]= temperature [C]
1595      [qv]= mixing ratio [kgkg-1]
1596      [dimns]= list of the name of the dimensions of [p]
1597      [dimvns]= list of the name of the variables with the values of the
1598        dimensions of [p]
1599    """
1600    fname = 'compute_td'
1601
1602#    print '    ' + fname + ': computing dew-point temperature from TS as t and Tetens...'
1603# tacking from: http://en.wikipedia.org/wiki/Dew_point
1604    tk = temp
1605    data1 = 10.*0.6112*np.exp(17.67*(tk-273.16)/(tk-29.65))
1606    data2 = 0.622*data1/(0.01*p-(1.-0.622)*data1)
1607
1608    rh = qv/data2
1609               
1610    pa = rh * data1
1611    td = 257.44*np.log(pa/6.1121)/(18.678-np.log(pa/6.1121))
1612
1613    tddims = dimns[:]
1614    tdvdims = dimvns[:]
1615
1616    return td, tddims, tdvdims
1617
1618def var_WRFtime(timewrfv, refdate='19491201000000', tunitsval='minutes'):
1619    """ Function to copmute CFtimes from WRFtime variable
1620      refdate= [YYYYMMDDMIHHSS] format of reference date
1621      tunitsval= CF time units
1622      timewrfv= matrix string values of WRF 'Times' variable
1623    """
1624    fname = 'var_WRFtime'
1625
1626    yrref=refdate[0:4]
1627    monref=refdate[4:6]
1628    dayref=refdate[6:8]
1629    horref=refdate[8:10]
1630    minref=refdate[10:12]
1631    secref=refdate[12:14]
1632
1633    refdateS = yrref + '-' + monref + '-' + dayref + ' ' + horref + ':' + minref +   \
1634      ':' + secref
1635
1636    dt = timewrfv.shape[0]
1637    WRFtime = np.zeros((dt), dtype=np.float)
1638
1639    for it in range(dt):
1640        wrfdates = gen.datetimeStr_conversion(timewrfv[it,:],'WRFdatetime', 'matYmdHMS')
1641        WRFtime[it] = gen.realdatetime1_CFcompilant(wrfdates, refdate, tunitsval)
1642
1643    tunits = tunitsval + ' since ' + refdateS
1644
1645    return WRFtime, tunits
1646
1647def turbulence_var(varv, dimvn, dimn):
1648    """ Function to compute the Taylor's decomposition turbulence term from a a given variable
1649      x*=<x^2>_t-(<X>_t)^2
1650    turbulence_var(varv,dimn)
1651      varv= values of the variable
1652      dimvn= names of the dimension of the variable
1653      dimn= names of the dimensions (as a dictionary with 'X', 'Y', 'Z', 'T')
1654    >>> turbulence_var(np.arange((27)).reshape(3,3,3),['time','y','x'],{'T':'time', 'Y':'y', 'X':'x'})
1655    [[ 54.  54.  54.]
1656     [ 54.  54.  54.]
1657     [ 54.  54.  54.]]
1658    """
1659    fname = 'turbulence_varv'
1660
1661    timedimid = dimvn.index(dimn['T'])
1662
1663    varv2 = varv*varv
1664
1665    vartmean = np.mean(varv, axis=timedimid)
1666    var2tmean = np.mean(varv2, axis=timedimid)
1667
1668    varvturb = var2tmean - (vartmean*vartmean)
1669
1670    return varvturb
1671
1672def compute_turbulence(v, dimns, dimvns):
1673    """ Function to compute the rubulence term of the Taylor's decomposition ...'
1674      x*=<x^2>_t-(<X>_t)^2
1675      [v]= variable (assuming [[t],z,y,x])
1676      [dimns]= list of the name of the dimensions of [v]
1677      [dimvns]= list of the name of the variables with the values of the
1678        dimensions of [v]
1679    """
1680    fname = 'compute_turbulence'
1681
1682    turbdims = dimns[:]
1683    turbvdims = dimvns[:]
1684
1685    turbdims.pop(0)
1686    turbvdims.pop(0)
1687
1688    v2 = v*v
1689
1690    vartmean = np.mean(v, axis=0)
1691    var2tmean = np.mean(v2, axis=0)
1692
1693    turb = var2tmean - (vartmean*vartmean)
1694
1695    return turb, turbdims, turbvdims
1696
1697def compute_wd(u, v, dimns, dimvns):
1698    """ Function to compute the wind direction
1699      [u]= W-E wind direction [ms-1, knot, ...]
1700      [v]= N-S wind direction [ms-1, knot, ...]
1701      [dimns]= list of the name of the dimensions of [u]
1702      [dimvns]= list of the name of the variables with the values of the
1703        dimensions of [u]
1704    """
1705    fname = 'compute_wds'
1706
1707#    print '    ' + fname + ': computing wind direction as ATAN2(v,u) ...'
1708    theta = np.arctan2(v,u)
1709    theta = np.where(theta < 0., theta + 2.*np.pi, theta)
1710
1711    var = 360.*theta/(2.*np.pi)
1712
1713    vardims = dimns[:]
1714    varvdims = dimvns[:]
1715
1716    return var, vardims, varvdims
1717
1718def compute_wds(u, v, dimns, dimvns):
1719    """ Function to compute the wind direction
1720      [u]= W-E wind direction [ms-1, knot, ...]
1721      [v]= N-S wind direction [ms-1, knot, ...]
1722      [dimns]= list of the name of the dimensions of [u]
1723      [dimvns]= list of the name of the variables with the values of the
1724        dimensions of [u]
1725    """
1726    fname = 'compute_wds'
1727
1728#    print '    ' + fname + ': computing wind direction as ATAN2(v,u) ...'
1729    theta = np.arctan2(v,u)
1730    theta = np.where(theta < 0., theta + 2.*np.pi, theta)
1731
1732    wds = 360.*theta/(2.*np.pi)
1733
1734    wdsdims = dimns[:]
1735    wdsvdims = dimvns[:]
1736
1737    return wds, wdsdims, wdsvdims
1738
1739def compute_wss(u, v, dimns, dimvns):
1740    """ Function to compute the wind speed
1741      [u]= W-E wind direction [ms-1, knot, ...]
1742      [v]= N-S wind direction [ms-1, knot, ...]
1743      [dimns]= list of the name of the dimensions of [u]
1744      [dimvns]= list of the name of the variables with the values of the
1745        dimensions of [u]
1746    """
1747    fname = 'compute_wss'
1748
1749#    print '    ' + fname + ': computing wind speed as SQRT(v**2 + u**2) ...'
1750    wss = np.sqrt(u*u + v*v)
1751
1752    wssdims = dimns[:]
1753    wssvdims = dimvns[:]
1754
1755    return wss, wssdims, wssvdims
1756
1757def timeunits_seconds(dtu):
1758    """ Function to transform a time units to seconds
1759    timeunits_seconds(timeuv)
1760      [dtu]= time units value to transform in seconds
1761    """
1762    fname='timunits_seconds'
1763
1764    if dtu == 'years':
1765        times = 365.*24.*3600.
1766    elif dtu == 'weeks':
1767        times = 7.*24.*3600.
1768    elif dtu == 'days':
1769        times = 24.*3600.
1770    elif dtu == 'hours':
1771        times = 3600.
1772    elif dtu == 'minutes':
1773        times = 60.
1774    elif dtu == 'seconds':
1775        times = 1.
1776    elif dtu == 'miliseconds':
1777        times = 1./1000.
1778    else:
1779        print errormsg
1780        print '  ' + fname  + ": time units '" + dtu + "' not ready !!"
1781        quit(-1)
1782
1783    return times
1784
1785def compute_WRFhur(t, p, qv, dimns, dimvns):
1786    """ Function to compute WRF relative humidity following Teten's equation
1787      t= orginal WRF temperature
1788      p= original WRF pressure (P + PB)
1789      formula:
1790          temp = theta*(p/p0)**(R/Cp)
1791
1792    """
1793    fname = 'compute_WRFtd'
1794
1795    tk = (t+300.)*(p/fdef.module_definitions.p0ref)**(fdef.module_definitions.rcp)
1796    data1 = 10.*0.6112*np.exp(17.67*(tk-273.16)/(tk-29.65))
1797    data2 = 0.622*data1/(0.01*p-(1.-0.622)*data1)
1798
1799    rh = qv/data2
1800               
1801    dnamesvar = ['Time','bottom_top','south_north','west_east']
1802    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
1803
1804    return rh, dnamesvar, dvnamesvar
1805
1806def compute_WRFua(u, v, sina, cosa, dimns, dimvns):
1807    """ Function to compute geographical rotated WRF 3D winds
1808      u= orginal WRF x-wind
1809      v= orginal WRF y-wind
1810      sina= original WRF local sinus of map rotation
1811      cosa= original WRF local cosinus of map rotation
1812      formula:
1813        ua = u*cosa-va*sina
1814        va = u*sina+va*cosa
1815    """
1816    fname = 'compute_WRFua'
1817
1818    var0 = u
1819    var1 = v
1820    var2 = sina
1821    var3 = cosa
1822
1823    # un-staggering variables
1824    unstgdims = [var0.shape[0], var0.shape[1], var0.shape[2], var0.shape[3]-1]
1825    ua = np.zeros(tuple(unstgdims), dtype=np.float)
1826    unstgvar0 = np.zeros(tuple(unstgdims), dtype=np.float)
1827    unstgvar1 = np.zeros(tuple(unstgdims), dtype=np.float)
1828    unstgvar0 = 0.5*(var0[:,:,:,0:var0.shape[3]-1] + var0[:,:,:,1:var0.shape[3]])
1829    unstgvar1 = 0.5*(var1[:,:,0:var1.shape[2]-1,:] + var1[:,:,1:var1.shape[2],:])
1830
1831    for iz in range(var0.shape[1]):
1832        ua[:,iz,:,:] = unstgvar0[:,iz,:,:]*var3 - unstgvar1[:,iz,:,:]*var2
1833
1834    dnamesvar = ['Time','bottom_top','south_north','west_east']
1835    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
1836
1837    return ua, dnamesvar, dvnamesvar
1838
1839def compute_WRFva(u, v, sina, cosa, dimns, dimvns):
1840    """ Function to compute geographical rotated WRF 3D winds
1841      u= orginal WRF x-wind
1842      v= orginal WRF y-wind
1843      sina= original WRF local sinus of map rotation
1844      cosa= original WRF local cosinus of map rotation
1845      formula:
1846        ua = u*cosa-va*sina
1847        va = u*sina+va*cosa
1848    """
1849    fname = 'compute_WRFva'
1850
1851    var0 = u
1852    var1 = v
1853    var2 = sina
1854    var3 = cosa
1855
1856    # un-staggering variables
1857    unstgdims = [var0.shape[0], var0.shape[1], var0.shape[2], var0.shape[3]-1]
1858    va = np.zeros(tuple(unstgdims), dtype=np.float)
1859    unstgvar0 = np.zeros(tuple(unstgdims), dtype=np.float)
1860    unstgvar1 = np.zeros(tuple(unstgdims), dtype=np.float)
1861    unstgvar0 = 0.5*(var0[:,:,:,0:var0.shape[3]-1] + var0[:,:,:,1:var0.shape[3]])
1862    unstgvar1 = 0.5*(var1[:,:,0:var1.shape[2]-1,:] + var1[:,:,1:var1.shape[2],:])
1863
1864    for iz in range(var0.shape[1]):
1865        va[:,iz,:,:] = unstgvar0[:,iz,:,:]*var2 + unstgvar1[:,iz,:,:]*var3
1866
1867    dnamesvar = ['Time','bottom_top','south_north','west_east']
1868    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
1869
1870    return va, dnamesvar, dvnamesvar
1871
1872def compute_WRFuava(u, v, sina, cosa, dimns, dimvns):
1873    """ Function to compute geographical rotated WRF 3D winds
1874      u= orginal WRF x-wind
1875      v= orginal WRF y-wind
1876      sina= original WRF local sinus of map rotation
1877      cosa= original WRF local cosinus of map rotation
1878      formula:
1879        ua = u*cosa-va*sina
1880        va = u*sina+va*cosa
1881    """
1882    fname = 'compute_WRFuava'
1883
1884    var0 = u
1885    var1 = v
1886    var2 = sina
1887    var3 = cosa
1888
1889    # un-staggering variables
1890    unstgdims = [var0.shape[0], var0.shape[1], var0.shape[2], var0.shape[3]-1]
1891    ua = np.zeros(tuple(unstgdims), dtype=np.float)
1892    va = np.zeros(tuple(unstgdims), dtype=np.float)
1893    unstgvar0 = np.zeros(tuple(unstgdims), dtype=np.float)
1894    unstgvar1 = np.zeros(tuple(unstgdims), dtype=np.float)
1895    unstgvar0 = 0.5*(var0[:,:,:,0:var0.shape[3]-1] + var0[:,:,:,1:var0.shape[3]])
1896    unstgvar1 = 0.5*(var1[:,:,0:var1.shape[2]-1,:] + var1[:,:,1:var1.shape[2],:])
1897
1898    for iz in range(var0.shape[1]):
1899        ua[:,iz,:,:] = unstgvar0[:,iz,:,:]*var3 - unstgvar1[:,iz,:,:]*var2
1900        va[:,iz,:,:] = unstgvar0[:,iz,:,:]*var2 + unstgvar1[:,iz,:,:]*var3
1901
1902    dnamesvar = ['Time','bottom_top','south_north','west_east']
1903    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
1904
1905    return ua, va, dnamesvar, dvnamesvar
1906
1907def compute_WRFuas(u10, v10, sina, cosa, dimns, dimvns):
1908    """ Function to compute geographical rotated WRF 2-meter x-wind
1909      u10= orginal WRF 10m x-wind
1910      v10= orginal WRF 10m y-wind
1911      sina= original WRF local sinus of map rotation
1912      cosa= original WRF local cosinus of map rotation
1913      formula:
1914        uas = u10*cosa-va10*sina
1915        vas = u10*sina+va10*cosa
1916    """
1917    fname = 'compute_WRFuas'
1918
1919    var0 = u10
1920    var1 = v10
1921    var2 = sina
1922    var3 = cosa
1923
1924    uas = np.zeros(var0.shape, dtype=np.float)
1925    vas = np.zeros(var0.shape, dtype=np.float)
1926
1927    uas = var0*var3 - var1*var2
1928
1929    dnamesvar = ['Time','south_north','west_east']
1930    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
1931
1932    return uas, dnamesvar, dvnamesvar
1933
1934def compute_WRFvas(u10, v10, sina, cosa, dimns, dimvns):
1935    """ Function to compute geographical rotated WRF 2-meter y-wind
1936      u10= orginal WRF 10m x-wind
1937      v10= orginal WRF 10m y-wind
1938      sina= original WRF local sinus of map rotation
1939      cosa= original WRF local cosinus of map rotation
1940      formula:
1941        uas = u10*cosa-va10*sina
1942        vas = u10*sina+va10*cosa
1943    """
1944    fname = 'compute_WRFvas'
1945
1946    var0 = u10
1947    var1 = v10
1948    var2 = sina
1949    var3 = cosa
1950
1951    uas = np.zeros(var0.shape, dtype=np.float)
1952    vas = np.zeros(var0.shape, dtype=np.float)
1953
1954    vas = var0*var2 + var1*var3
1955
1956    dnamesvar = ['Time','south_north','west_east']
1957    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
1958
1959    return vas, dnamesvar, dvnamesvar
1960
1961def compute_WRFuasvas(u10, v10, sina, cosa, dimns, dimvns):
1962    """ Function to compute geographical rotated WRF 2-meter winds
1963      u10= orginal WRF 10m x-wind
1964      v10= orginal WRF 10m y-wind
1965      sina= original WRF local sinus of map rotation
1966      cosa= original WRF local cosinus of map rotation
1967      formula:
1968        uas = u10*cosa-va10*sina
1969        vas = u10*sina+va10*cosa
1970    """
1971    fname = 'compute_WRFuasvas'
1972
1973    var0 = u10
1974    var1 = v10
1975    var2 = sina
1976    var3 = cosa
1977
1978    uas = np.zeros(var0.shape, dtype=np.float)
1979    vas = np.zeros(var0.shape, dtype=np.float)
1980
1981    uas = var0*var3 - var1*var2
1982    vas = var0*var2 + var1*var3
1983
1984    dnamesvar = ['Time','south_north','west_east']
1985    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
1986
1987    return uas, vas, dnamesvar, dvnamesvar
1988
1989def compute_WRFta(t, p, dimns, dimvns):
1990    """ Function to compute WRF air temperature
1991      t= orginal WRF temperature
1992      p= original WRF pressure (P + PB)
1993      formula:
1994          temp = theta*(p/p0)**(R/Cp)
1995
1996    """
1997    fname = 'compute_WRFta'
1998
1999    ta = (t+300.)*(p/fdef.module_definitions.p0ref)**(fdef.module_definitions.rcp)
2000
2001    dnamesvar = ['Time','bottom_top','south_north','west_east']
2002    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
2003
2004    return ta, dnamesvar, dvnamesvar
2005
2006def compute_WRFtd(t, p, qv, dimns, dimvns):
2007    """ Function to compute WRF dew-point air temperature
2008      t= orginal WRF temperature
2009      p= original WRF pressure (P + PB)
2010      formula:
2011          temp = theta*(p/p0)**(R/Cp)
2012
2013    """
2014    fname = 'compute_WRFtd'
2015
2016    tk = (t+300.)*(p/fdef.module_definitions.p0ref)**(fdef.module_definitions.rcp)
2017    data1 = 10.*0.6112*np.exp(17.67*(tk-273.16)/(tk-29.65))
2018    data2 = 0.622*data1/(0.01*p-(1.-0.622)*data1)
2019
2020    rh = qv/data2
2021               
2022    pa = rh * data1
2023    td = 257.44*np.log(pa/6.1121)/(18.678-np.log(pa/6.1121))
2024
2025    dnamesvar = ['Time','bottom_top','south_north','west_east']
2026    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
2027
2028    return td, dnamesvar, dvnamesvar
2029
2030def compute_WRFwd(u, v, sina, cosa, dimns, dimvns):
2031    """ Function to compute the wind direction
2032      u= W-E wind direction [ms-1]
2033      v= N-S wind direction [ms-1]
2034      sina= original WRF local sinus of map rotation
2035      cosa= original WRF local cosinus of map rotation
2036    """
2037    fname = 'compute_WRFwd'
2038    var0 = u
2039    var1 = v
2040    var2 = sina
2041    var3 = cosa
2042
2043    # un-staggering variables
2044    unstgdims = [var0.shape[0], var0.shape[1], var0.shape[2], var0.shape[3]-1]
2045    ua = np.zeros(tuple(unstgdims), dtype=np.float)
2046    va = np.zeros(tuple(unstgdims), dtype=np.float)
2047    unstgvar0 = np.zeros(tuple(unstgdims), dtype=np.float)
2048    unstgvar1 = np.zeros(tuple(unstgdims), dtype=np.float)
2049    unstgvar0 = 0.5*(var0[:,:,:,0:var0.shape[3]-1] + var0[:,:,:,1:var0.shape[3]])
2050    unstgvar1 = 0.5*(var1[:,:,0:var1.shape[2]-1,:] + var1[:,:,1:var1.shape[2],:])
2051
2052    for iz in range(var0.shape[1]):
2053        ua[:,iz,:,:] = unstgvar0[:,iz,:,:]*var3 - unstgvar1[:,iz,:,:]*var2
2054        va[:,iz,:,:] = unstgvar0[:,iz,:,:]*var2 + unstgvar1[:,iz,:,:]*var3
2055
2056    theta = np.arctan2(va,ua)
2057    theta = np.where(theta < 0., theta + 2.*np.pi, theta)
2058
2059    wd = 360.*theta/(2.*np.pi)
2060
2061    dnamesvar = ['Time','bottom_top','south_north','west_east']
2062    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
2063
2064    return wd
2065
2066####### Variables (as they arrive without dimensions staff)
2067
2068def var_hur(p, t, q):
2069    """ Function to compute relative humidity following 'August - Roche - Magnus' formula
2070      [t]= temperature (assuming [[t],z,y,x] in [K])
2071      [p] = pressure field (assuming in [Pa])
2072      [q] = mixing ratio in [kgkg-1]
2073      ref.: M. G. Lawrence, BAMS, 2005, 225
2074    >>> print var_rh(101300., 290., 3.)
2075    0.250250256174
2076    """
2077    fname = 'var_hur'
2078
2079    # Enthalpy of vaporization [Jkg-1]
2080    L = 2.453*10.**6
2081    # Gas constant for water vapor [JK-1Kg-1]
2082    Rv = 461.5 
2083
2084    # Computing saturated pressure
2085    #es = 10.*0.6112*np.exp(17.67*(t-273.16)/(t-29.65))
2086    #es = 6.11*np.exp(L/Rv*(1.-273./t)/273.)
2087
2088    # August - Roche - Magnus formula
2089    es = 6.1094*np.exp(17.625*(t-273.15)/((t-273.15)+243.04))
2090
2091    # Saturated mixing ratio [g/kg]
2092    ws = 0.622*es/(0.01*p-es)
2093
2094    hur = q/(ws*1000.)
2095
2096    #print 'q:', q[5,5,5,5], 't:', t[5,5,5,5], 'p:', p[5,5,5,5]
2097    #print 'es:', es[5,5,5,5], 'ws:', ws[5,5,5,5], 'hur:', hur[5,5,5,5]
2098
2099    return hur
2100
2101def var_hur_Uhus(p, t, hus):
2102    """ Function to compute relative humidity following 'August - Roche - Magnus' formula using hus
2103      [t]= temperature (assuming [[t],z,y,x] in [K])
2104      [p] = pressure field (assuming in [Pa])
2105      [hus] = specific humidty [1]
2106      ref.: M. G. Lawrence, BAMS, 2005, 225
2107    >>> print var_rh(101300., 290., 3.)
2108    0.250250256174
2109    """
2110    fname = 'var_hur_Uhus'
2111
2112    # Enthalpy of vaporization [Jkg-1]
2113    L = 2.453*10.**6
2114    # Gas constant for water vapor [JK-1Kg-1]
2115    Rv = 461.5 
2116
2117    # Computing saturated pressure
2118    #es = 10.*0.6112*np.exp(17.67*(t-273.16)/(t-29.65))
2119    #es = 6.11*np.exp(L/Rv*(1.-273./t)/273.)
2120
2121    # August - Roche - Magnus formula
2122    es = 6.1094*np.exp(17.625*(t-273.15)/((t-273.15)+243.04))
2123
2124    # Saturated mixing ratio [g/kg]
2125    ws = 0.622*es/(0.01*p-es)
2126
2127    # Mixing ratio
2128    q = hus/(1.+hus)
2129
2130    hur = q/ws
2131
2132    #print 'q:', q[5,5,5,5], 't:', t[5,5,5,5], 'p:', p[5,5,5,5]
2133    #print 'es:', es[5,5,5,5], 'ws:', ws[5,5,5,5], 'hur:', hur[5,5,5,5]
2134
2135    return hur
2136
2137def var_hur_tas_tds(tas, tds, dimns, dimvns):
2138    """ Function to compute hur relative humidity from tas and tds
2139      tas= surface temperature [K]
2140      tds= dew point temperature [K]
2141      Magnus formula with D. Bolton, 1980, Mon. Wea. Rev. values:
2142            gamma = log(hur/100) + b*tas/(c+tas)
2143            tdps = c*gamma/(b-gamma)
2144         hur = 100*expr[b(tdps/(c+tdps)-tas/(c+tas))]
2145
2146    """
2147    fname = 'compute_hur_tas_tds'
2148
2149    dnamesvar = dimns
2150    dvnamesvar = dimvns
2151
2152    tasC = tas - fdef.module_definitions.svpt0
2153    tdsC = tds - fdef.module_definitions.svpt0
2154
2155    # Magnus formula with D. Bolton, 1980, Mon. Wea. Rev. values
2156    b = 17.67
2157    c = 243.5
2158
2159    hur = np.exp(b*(tdsC/(c+tdsC)-tasC/(c+tasC)))
2160               
2161    return hur, dnamesvar, dvnamesvar
2162
2163def var_td(t, p, qv):
2164    """ Function to compute dew-point air temperature from temperature and pressure values
2165      t= temperature [K]
2166      p= pressure (Pa)
2167      formula:
2168          temp = theta*(p/p0)**(R/Cp)
2169
2170    """
2171    fname = 'compute_td'
2172
2173    tk = (t)*(p/fdef.module_definitions.p0ref)**(fdef.module_definitions.rcp)
2174    data1 = 10.*0.6112*np.exp(17.67*(tk-273.16)/(tk-29.65))
2175    data2 = 0.622*data1/(0.01*p-(1.-0.622)*data1)
2176
2177    rh = qv/data2
2178               
2179    pa = rh * data1
2180    td = 257.44*np.log(pa/6.1121)/(18.678-np.log(pa/6.1121))
2181
2182    return td
2183
2184def var_td_Uhus(t, p, hus):
2185    """ Function to compute dew-point air temperature from temperature and pressure values using hus
2186      t= temperature [K]
2187      hus= specific humidity [1]
2188      formula:
2189          temp = theta*(p/p0)**(R/Cp)
2190
2191    """
2192    fname = 'compute_td'
2193
2194    tk = (t)*(p/fdef.module_definitions.p0ref)**(fdef.module_definitions.rcp)
2195    data1 = 10.*0.6112*np.exp(17.67*(tk-273.16)/(tk-29.65))
2196    data2 = 0.622*data1/(0.01*p-(1.-0.622)*data1)
2197
2198    qv = hus/(1.+hus)
2199
2200    rh = qv/data2
2201               
2202    pa = rh * data1
2203    td = 257.44*np.log(pa/6.1121)/(18.678-np.log(pa/6.1121))
2204
2205    return td
2206
2207def var_tws_S11(ta0, hur0):
2208    """ Function to compute Wet Bulb temperature using equation after:
2209      Stull, R. (2011), J. Appl. Meteor. Climatol. 50(11):2267-2269,
2210        doi: 10.1175/JAMC-D-11-0143.1
2211      [ta]= temperature (assuming [[t],z,y,x] in [K])
2212      [hur] = relative humidity (assuming in [1])
2213    >>> var_rh_S11(293.15, 0.5)
2214    13.699341969
2215    """
2216    fname = 'var_tws_S11'
2217
2218    ta = ta0 - 273.15
2219    hur = hur0*100.
2220
2221    # Does it has any sense not in surface?
2222    tws = ta*np.arctan(0.151977*np.sqrt(hur+8.313659)) + np.arctan(ta+hur) -         \
2223      np.arctan(hur-1.676331) + 0.00391838*(hur)**(1.5)*np.arctan(0.023101*hur) -    \
2224      4.686035
2225
2226    return tws
2227
2228def var_wd(u, v):
2229    """ Function to compute the wind direction
2230      [u]= W-E wind direction [ms-1, knot, ...]
2231      [v]= N-S wind direction [ms-1, knot, ...]
2232    """
2233    fname = 'var_wd'
2234
2235    theta = np.arctan2(v,u)
2236    theta = np.where(theta < 0., theta + 2.*np.pi, theta)
2237
2238    wd = 360.*theta/(2.*np.pi)
2239
2240    return wd
2241
2242def var_ws(u, v):
2243    """ Function to compute the wind speed
2244      [u]= W-E wind direction [ms-1, knot, ...]
2245      [v]= N-S wind direction [ms-1, knot, ...]
2246    """
2247    fname = 'var_ws'
2248
2249    ws = np.sqrt(u*u + v*v)
2250
2251    return ws
2252
2253class C_diagnostic(object):
2254    """ Class to compute generic variables
2255      Cdiag: name of the diagnostic to compute
2256      ncobj: netcdf object with data
2257      sfcvars: dictionary with CF equivalencies of surface variables inside file
2258      vars3D: dictionary with CF equivalencies of 3D variables inside file
2259      dictdims: dictionary with CF equivalencies of dimensions inside file
2260        self.values = Values of the diagnostic
2261        self.dims = Dimensions of the diagnostic
2262        self.units = units of the diagnostic
2263        self.incvars = list of variables from the input netCDF object
2264    """ 
2265    def __init__(self, Cdiag, ncobj, sfcvars, vars3D, dictdims):
2266        fname = 'C_diagnostic'
2267        self.values = None
2268        self.dims = None
2269        self.incvars = ncobj.variables
2270        self.units = None
2271
2272        if Cdiag == 'hur':
2273            """ Computing relative humidity
2274            """
2275            vn = 'hur'
2276            CF3Dvars = ['ta', 'plev', 'q']
2277            for v3D in CF3Dvars:
2278                if not vars3D.has_key(v3D):
2279                    print gen.errormsg
2280                    print '  ' + fname + ": missing variable '" + v3D +              \
2281                      "' attribution to compute '" + vn + "' !!"
2282                    print '  Equivalence of 3D variables provided _______'
2283                    gen.printing_dictionary(vars3D)
2284                    quit(-1)
2285                if not self.incvars.has_key(vars3D[v3D]):
2286                    print gen.errormsg
2287                    print '  ' + fname + ": missing variable '" + vars3D[v3D] +      \
2288                      "' in input file to compute '" + vn + "' !!"
2289                    print '  available variables:', self.incvars.keys()
2290                    print '  looking for variables _______' 
2291                    gen.printing_dictionary(vars3D)
2292                    quit(-1)
2293
2294            ta = ncobj.variables[vars3D['ta']][:]
2295            p = ncobj.variables[vars3D['plev']][:]
2296            q = ncobj.variables[vars3D['q']][:]
2297
2298            if len(ta.shape) != len(p.shape):
2299                p = gen.fill_Narray(p, ta*0., filldim=[0,2,3])
2300
2301            self.values = var_hur(p, ta, q)
2302            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2303              dictdims['lon']]
2304            self.units = '1'
2305
2306        if Cdiag == 'hur_Uhus':
2307            """ Computing relative humidity using hus
2308            """
2309            vn = 'hur'
2310            CF3Dvars = ['ta', 'plev', 'hus']
2311            for v3D in CF3Dvars:
2312                if not vars3D.has_key(v3D):
2313                    print gen.errormsg
2314                    print '  ' + fname + ": missing variable '" + v3D +              \
2315                      "' attribution to compute '" + vn + "' !!"
2316                    print '  Equivalence of 3D variables provided _______'
2317                    gen.printing_dictionary(vars3D)
2318                    quit(-1)
2319                if not self.incvars.has_key(vars3D[v3D]):
2320                    print gen.errormsg
2321                    print '  ' + fname + ": missing variable '" + vars3D[v3D] +      \
2322                      "' in input file to compute '" + vn + "' !!"
2323                    print '  available variables:', self.incvars.keys()
2324                    print '  looking for variables _______' 
2325                    gen.printing_dictionary(vars3D)
2326                    quit(-1)
2327
2328            ta = ncobj.variables[vars3D['ta']][:]
2329            p = ncobj.variables[vars3D['plev']][:]
2330            hus = ncobj.variables[vars3D['hus']][:]
2331
2332            if len(ta.shape) != len(p.shape):
2333                p = gen.fill_Narray(p, ta*0., filldim=[0,2,3])
2334
2335            self.values = var_hur_Uhus(p, ta, hus)
2336            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2337              dictdims['lon']]
2338            self.units = '1'
2339
2340        elif Cdiag == 'td':
2341            """ Computing dew-point temperature
2342            """
2343            vn = 'td'
2344            CF3Dvars = ['ta', 'plev', 'q']
2345            for v3D in CF3Dvars:
2346                if not vars3D.has_key(v3D):
2347                    print gen.errormsg
2348                    print '  ' + fname + ": missing variable '" + v3D +              \
2349                      "' attribution to compute '" + vn + "' !!"
2350                    print '  Equivalence of 3D variables provided _______'
2351                    gen.printing_dictionary(vars3D)
2352                    quit(-1)
2353                if not self.incvars.has_key(vars3D[v3D]):
2354                    print gen.errormsg
2355                    print '  ' + fname + ": missing variable '" + vars3D[v3D] +      \
2356                      "' in input file to compute '" + vn + "' !!"
2357                    print '  available variables:', self.incvars.keys()
2358                    print '  looking for variables _______' 
2359                    gen.printing_dictionary(vars3D)
2360                    quit(-1)
2361
2362            ta = ncobj.variables[vars3D['ta']][:]
2363            p = ncobj.variables[vars3D['plev']][:]
2364            q = ncobj.variables[vars3D['q']][:]
2365
2366            if len(ta.shape) != len(p.shape):
2367                p = gen.fill_Narray(p, ta*0., filldim=[0,2,3])
2368
2369            self.values = var_td(ta, p, q)
2370            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2371              dictdims['lon']]
2372            self.units = 'K'
2373
2374        elif Cdiag == 'td_Uhus':
2375            """ Computing dew-point temperature
2376            """
2377            vn = 'td'
2378            CF3Dvars = ['ta', 'plev', 'hus']
2379            for v3D in CF3Dvars:
2380                if not vars3D.has_key(v3D):
2381                    print gen.errormsg
2382                    print '  ' + fname + ": missing variable '" + v3D +              \
2383                      "' attribution to compute '" + vn + "' !!"
2384                    print '  Equivalence of 3D variables provided _______'
2385                    gen.printing_dictionary(vars3D)
2386                    quit(-1)
2387                if not self.incvars.has_key(vars3D[v3D]):
2388                    print gen.errormsg
2389                    print '  ' + fname + ": missing variable '" + vars3D[v3D] +      \
2390                      "' in input file to compute '" + vn + "' !!"
2391                    print '  available variables:', self.incvars.keys()
2392                    print '  looking for variables _______' 
2393                    gen.printing_dictionary(vars3D)
2394                    quit(-1)
2395
2396            ta = ncobj.variables[vars3D['ta']][:]
2397            p = ncobj.variables[vars3D['plev']][:]
2398            hus = ncobj.variables[vars3D['hus']][:]
2399
2400            if len(ta.shape) != len(p.shape):
2401                p = gen.fill_Narray(p, ta*0., filldim=[0,2,3])
2402
2403            self.values = var_td_Uhus(ta, p, hus)
2404            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2405              dictdims['lon']]
2406            self.units = 'K'
2407
2408        elif Cdiag == 'wd':
2409            """ Computing wind direction
2410            """
2411            vn = 'wd'
2412            CF3Dvars = ['ua', 'va']
2413            for v3D in CF3Dvars:
2414                if not vars3D.has_key(v3D):
2415                    print gen.errormsg
2416                    print '  ' + fname + ": missing variable '" + v3D +              \
2417                      "self.' attribution to compute '" + vn + "' !!"
2418                    print '  Equivalence of 3D variables provided _______'
2419                    gen.printing_dictionary(vars3D)
2420                    quit(-1)
2421                if not self.incvars.has_key(vars3D[v3D]):
2422                    print gen.errormsg
2423                    print '  ' + fname + ": missing variable '" + vars3D[v3D] +      \
2424                      "' in input file to compute '" + vn + "' !!"
2425                    print '  available variables:', self.incvars.keys()
2426                    print '  looking for variables _______' 
2427                    gen.printing_dictionary(vars3D)
2428                    quit(-1)
2429   
2430            ua = ncobj.variables[vars3D['ua']][:]
2431            va = ncobj.variables[vars3D['va']][:]
2432   
2433            self.values = var_wd(ua, va)
2434            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2435              dictdims['lon']]
2436            self.units = 'degree'
2437
2438        elif Cdiag == 'ws':
2439            """ Computing wind speed
2440            """
2441            vn = 'ws'
2442            CF3Dvars = ['ua', 'va']
2443            for v3D in CF3Dvars:
2444                if not vars3D.has_key(v3D):
2445                    print gen.errormsg
2446                    print '  ' + fname + ": missing variable '" + v3D +              \
2447                      "' attribution to compute '" + vn + "' !!"
2448                    print '  Equivalence of 3D variables provided _______'
2449                    gen.printing_dictionary(vars3D)
2450                    quit(-1)
2451                if not self.incvars.has_key(vars3D[v3D]):
2452                    print gen.errormsg
2453                    print '  ' + fname + ": missing variable '" + vars3D[v3D] +      \
2454                      "' in input file to compute '" + vn + "' !!"
2455                    print '  available variables:', self.incvars.keys()
2456                    print '  looking for variables _______' 
2457                    gen.printing_dictionary(vars3D)
2458                    quit(-1)
2459
2460            ua = ncobj.variables[vars3D['ua']][:]
2461            va = ncobj.variables[vars3D['va']][:]
2462
2463            self.values = var_ws(ua, va)
2464            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2465              dictdims['lon']]
2466            self.units = ncobj.variables[vars3D['ua']].units
2467
2468        else:
2469            print gen.errormsg
2470            print '  ' + fname + ": variable '" + Wdiag + "' not ready !!"
2471            print '  available ones:', Cavailablediags
2472            quit(-1)
2473
2474class W_diagnostic(object):
2475    """ Class to compute WRF diagnostics variables
2476      Wdiag: name of the diagnostic to compute
2477      ncobj: netcdf object with data
2478      sfcvars: dictionary with CF equivalencies of surface variables inside file
2479      vars3D: dictionary with CF equivalencies of 3D variables inside file
2480      indims: list of dimensions inside file
2481      invardims: list of dimension-variables inside file
2482      dictdims: dictionary with CF equivalencies of dimensions inside file
2483        self.values = Values of the diagnostic
2484        self.dims = Dimensions of the diagnostic
2485        self.units = units of the diagnostic
2486        self.incvars = list of variables from the input netCDF object
2487    """   
2488    def __init__(self, Wdiag, ncobj, sfcvars, vars3D, indims, invardims, dictdims):
2489        fname = 'W_diagnostic'
2490
2491        self.values = None
2492        self.dims = None
2493        self.incvars = ncobj.variables
2494        self.units = None
2495
2496        if Wdiag == 'hur':
2497            """ Computing relative humidity
2498            """
2499            vn = 'hur'
2500            CF3Dvars = ['ta', 'hus']
2501            for v3D in CF3Dvars:
2502                if not vars3D.has_key(v3D):
2503                    print gen.errormsg
2504                    print '  ' + fname + ": missing variable '" + v3D +              \
2505                      "' attribution to compute '" + vn + "' !!"
2506                    print '  Equivalence of 3D variables provided _______'
2507                    gen.printing_dictionary(vars3D)
2508                    quit(-1)
2509
2510            ta = ncobj.variables['T'][:]
2511            p = ncobj.variables['P'][:] + ncobj.variables['PB'][:]
2512            hur = ncobj.variables['QVAPOR'][:]
2513   
2514            vals, dims, vdims = compute_WRFhur(ta, p, hur, indims, invardims)
2515            self.values = vals
2516            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2517              dictdims['lon']]
2518            self.units = '1'
2519
2520        elif Wdiag == 'p':
2521            """ Computing air pressure
2522            """
2523            vn = 'p'
2524
2525            self.values = ncobj.variables['PB'][:] + ncobj.variables['P'][:]
2526            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2527              dictdims['lon']]
2528            self.units = ncobj.variables['PB'].units
2529
2530        elif Wdiag == 'ta':
2531            """ Computing air temperature
2532            """
2533            vn = 'ta'
2534            CF3Dvars = ['ta']
2535            for v3D in CF3Dvars:
2536                if not vars3D.has_key(v3D):
2537                    print gen.errormsg
2538                    print '  ' + fname + ": missing variable '" + v3D +              \
2539                      "' attribution to compute '" + vn + "' !!"
2540                    print '  Equivalence of 3D variables provided _______'
2541                    gen.printing_dictionary(vars3D)
2542                    quit(-1)
2543
2544            ta = ncobj.variables['T'][:]
2545            p = ncobj.variables['P'][:] + ncobj.variables['PB'][:]
2546   
2547            vals, dims, vdims = compute_WRFta(ta, p, indims, invardims)
2548            self.values = vals
2549            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2550              dictdims['lon']]
2551            self.units = 'K'
2552
2553        elif Wdiag == 'td':
2554            """ Computing dew-point temperature
2555            """
2556            vn = 'td'
2557            CF3Dvars = ['ta', 'hus']
2558            for v3D in CF3Dvars:
2559                if not vars3D.has_key(v3D):
2560                    print gen.errormsg
2561                    print '  ' + fname + ": missing variable '" + v3D +              \
2562                      "' attribution to compute '" + vn + "' !!"
2563                    print '  Equivalence of 3D variables provided _______'
2564                    gen.printing_dictionary(vars3D)
2565                    quit(-1)
2566
2567            ta = ncobj.variables['T'][:]
2568            p = ncobj.variables['P'][:] + ncobj.variables['PB'][:]
2569            hus = ncobj.variables['QVAPOR'][:]
2570   
2571            vals, dims, vdims = compute_WRFtd(ta, p, hus, indims, invardims)
2572            self.values = vals
2573            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2574              dictdims['lon']]
2575            self.units = 'K'
2576   
2577        elif Wdiag == 'ua':
2578            """ Computing x-wind
2579            """
2580            vn = 'ua'
2581            CF3Dvars = ['ua', 'va']
2582            for v3D in CF3Dvars:
2583                if not vars3D.has_key(v3D):
2584                    print gen.errormsg
2585                    print '  ' + fname + ": missing variable '" + v3D +              \
2586                      "' attribution to compute '" + vn + "' !!"
2587                    print '  Equivalence of 3D variables provided _______'
2588                    gen.printing_dictionary(vars3D)
2589                    quit(-1)
2590
2591            ua = ncobj.variables['U'][:]
2592            va = ncobj.variables['V'][:]
2593            sina = ncobj.variables['SINALPHA'][:]
2594            cosa = ncobj.variables['COSALPHA'][:]
2595   
2596            vals, dims, vdims = compute_WRFua(ua, va, sina, cosa, indims, invardims)
2597            self.values = vals
2598            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2599              dictdims['lon']]
2600            self.units = ncobj.variables['U'].units
2601   
2602        elif Wdiag == 'uas':
2603            """ Computing 10m x-wind
2604            """
2605            vn = 'uas'
2606            CFsfcvars = ['uas', 'vas']
2607            for vsf in CFsfcvars:
2608                if not sfcvars.has_key(vsf):
2609                    print gen.errormsg
2610                    print '  ' + fname + ": missing variable '" + vsf +              \
2611                      "' attribution to compute '" + vn + "' !!"
2612                    print '  Equivalence of sfc variables provided _______'
2613                    gen.printing_dictionary(sfcvars)
2614                    quit(-1)
2615   
2616            uas = ncobj.variables['U10'][:]
2617            vas = ncobj.variables['V10'][:]
2618            sina = ncobj.variables['SINALPHA'][:]
2619            cosa = ncobj.variables['COSALPHA'][:]
2620   
2621            vals,dims,vdims = compute_WRFuas(uas, vas, sina, cosa, indims, invardims)
2622            self.values = vals
2623            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2624              dictdims['lon']]
2625            self.units = ncobj.variables['U10'].units
2626   
2627        elif Wdiag == 'va':
2628            """ Computing y-wind
2629            """
2630            vn = 'ua'
2631            CF3Dvars = ['ua', 'va']
2632            for v3D in CF3Dvars:
2633                if not vars3D.has_key(v3D):
2634                    print gen.errormsg
2635                    print '  ' + fname + ": missing variable '" + v3D +              \
2636                      "' attribution to compute '" + vn + "' !!"
2637                    print '  Equivalence of 3D variables provided _______'
2638                    gen.printing_dictionary(vars3D)
2639                    quit(-1)
2640   
2641            ua = ncobj.variables['U'][:]
2642            va = ncobj.variables['V'][:]
2643            sina = ncobj.variables['SINALPHA'][:]
2644            cosa = ncobj.variables['COSALPHA'][:]
2645   
2646            vals, dims, vdims = compute_WRFva(ua, va, sina, cosa, indims, invardims)
2647            self.values = vals
2648            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2649              dictdims['lon']]
2650            self.units = ncobj.variables['U'].units
2651   
2652        elif Wdiag == 'vas':
2653            """ Computing 10m y-wind
2654            """
2655            vn = 'uas'
2656            CFsfcvars = ['uas', 'vas']
2657            for vsf in CFsfcvars:
2658                if not sfcvars.has_key(vsf):
2659                    print gen.errormsg
2660                    print '  ' + fname + ": missing variable '" + vsf +              \
2661                      "' attribution to compute '" + vn + "' !!"
2662                    print '  Equivalence of sfc variables provided _______'
2663                    gen.printing_dictionary(sfcvars)
2664                    quit(-1)
2665   
2666            uas = ncobj.variables['U10'][:]
2667            vas = ncobj.variables['V10'][:]
2668            sina = ncobj.variables['SINALPHA'][:]
2669            cosa = ncobj.variables['COSALPHA'][:]
2670   
2671            vals,dims,vdims = compute_WRFvas(uas, vas, sina, cosa, indims, invardims)
2672            self.values = vals
2673            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2674              dictdims['lon']]
2675            self.units = ncobj.variables['U10'].units
2676
2677        elif Wdiag == 'wd':
2678            """ Computing wind direction
2679            """
2680            vn = 'wd'
2681            CF3Dvars = ['ua', 'va']
2682            for v3D in CF3Dvars:
2683                if not vars3D.has_key(v3D):
2684                    print gen.errormsg
2685                    print '  ' + fname + ": missing variable '" + v3D +              \
2686                      "' attribution to compute '" + vn + "' !!"
2687                    print '  Equivalence of 3D variables provided _______'
2688                    gen.printing_dictionary(vars3D)
2689                    quit(-1)
2690
2691            ua = ncobj.variables['U10'][:]
2692            va = ncobj.variables['V10'][:]
2693            sina = ncobj.variables['SINALPHA'][:]
2694            cosa = ncobj.variables['COSALPHA'][:]
2695   
2696            vals, dims, vdims = compute_WRFwd(ua, va, sina, cosa, indims, invardims)
2697            self.values = vals
2698            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2699              dictdims['lon']]
2700            self.units = 'degree'
2701
2702        elif Wdiag == 'ws':
2703            """ Computing wind speed
2704            """
2705            vn = 'ws'
2706            CF3Dvars = ['ua', 'va']
2707            for v3D in CF3Dvars:
2708                if not vars3D.has_key(v3D):
2709                    print gen.errormsg
2710                    print '  ' + fname + ": missing variable '" + v3D +              \
2711                      "' attribution to compute '" + vn + "' !!"
2712                    print '  Equivalence of 3D variables provided _______'
2713                    gen.printing_dictionary(vars3D)
2714                    quit(-1)
2715   
2716            ua = ncobj.variables['U10'][:]
2717            va = ncobj.variables['V10'][:]
2718   
2719            self.values = var_ws(ua, va)
2720            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2721              dictdims['lon']]
2722            self.units = ncobj.variables['U10'].units
2723
2724        elif Wdiag == 'zg':
2725            """ Computing geopotential
2726            """
2727            vn = 'zg'
2728
2729            self.values = ncobj.variables['PHB'][:] + ncobj.variables['PH'][:]
2730            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2731              dictdims['lon']]
2732            self.units = ncobj.variables['PHB'].units
2733
2734        else:
2735            print gen.errormsg
2736            print '  ' + fname + ": variable '" + Wdiag + "' not ready !!"
2737            print '  available ones:', Wavailablediags
2738            quit(-1)
Note: See TracBrowser for help on using the repository browser.