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

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

Working version of 'range_faces' with homogenization of 'range'

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