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

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

Adding 'polygons' after!

File size: 94.9 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        print 'Finished!', rngt
1499        hgtmax = hgtmaxt.transpose()
1500        pthgtmax = pthgtmaxt.transpose()
1501        dhgt = dhgtt.transpose()
1502        peaks = peakst.transpose()
1503        valleys = valleyst.transpose()
1504        origfaces = ofacest.transpose()
1505        filtfaces = ffacest.transpose()
1506        ranges = rngt.transpose()
1507        rangeshgtmax = rnghgtmaxt.transpose()
1508        ptrangeshgtmax = ptrnghgtmaxt.transpose()
1509
1510        # Homogenizing ranges
1511        Lranges = np.where(ranges != 0, True, False)
1512        print np.sum(Lranges)
1513        Lrangest = Lranges.transpose()
1514        rangest, Nrngs = fdin.module_scientific.polygons(dbg=False, boolmat=Lrangest, dx=dx, dy=dy)
1515        ranges = ranges.transpose()
1516
1517    else:
1518        print errormsg
1519        print '  ' + fname + ': rank', len(var.shape), 'not ready !!'
1520        print '  it only computes 2D [y,x] rank values'
1521        quit(-1)
1522
1523    return hgtmax, pthgtmax, dhgt, peaks, valleys, origfaces, filtfaces, vardims,    \
1524      varvdims, ranges, rangeshgtmax, ptrangeshgtmax
1525
1526####### ###### ##### #### ### ## # END Fortran diagnostics
1527
1528def compute_OMEGAw(omega, p, t, dimns, dimvns):
1529    """ Function to transform OMEGA [Pas-1] to velocities [ms-1]
1530      tacking: https://www.ncl.ucar.edu/Document/Functions/Contributed/omega_to_w.shtml
1531      [omega] = vertical velocity [in ms-1] (assuming [t],z,y,x)
1532      [p] = pressure in [Pa] (assuming [t],z,y,x)
1533      [t] = temperature in [K] (assuming [t],z,y,x)
1534      [dimns]= list of the name of the dimensions of [q]
1535      [dimvns]= list of the name of the variables with the values of the
1536        dimensions of [q]
1537    """
1538    fname = 'compute_OMEGAw'
1539
1540    rgas = 287.058            # J/(kg-K) => m2/(s2 K)
1541    g    = 9.80665            # m/s2
1542
1543    wdims = dimns[:]
1544    wvdims = dimvns[:]
1545
1546    rho  = p/(rgas*t)         # density => kg/m3
1547    w    = -omega/(rho*g)     
1548
1549    return w, wdims, wvdims
1550
1551def compute_prw(dens, q, dimns, dimvns):
1552    """ Function to compute water vapour path (prw)
1553      [dens] = density [in kgkg-1] (assuming [t],z,y,x)
1554      [q] = mixing ratio in [kgkg-1] (assuming [t],z,y,x)
1555      [dimns]= list of the name of the dimensions of [q]
1556      [dimvns]= list of the name of the variables with the values of the
1557        dimensions of [q]
1558    """
1559    fname = 'compute_prw'
1560
1561    prwdims = dimns[:]
1562    prwvdims = dimvns[:]
1563
1564    if len(q.shape) == 4:
1565        prwdims.pop(1)
1566        prwvdims.pop(1)
1567    else:
1568        prwdims.pop(0)
1569        prwvdims.pop(0)
1570
1571    data1 = dens*q
1572    prw = np.sum(data1, axis=1)
1573
1574    return prw, prwdims, prwvdims
1575
1576def compute_rh(p, t, q, dimns, dimvns):
1577    """ Function to compute relative humidity following 'Tetens' equation (T,P) ...'
1578      [t]= temperature (assuming [[t],z,y,x] in [K])
1579      [p] = pressure field (assuming in [hPa])
1580      [q] = mixing ratio in [kgkg-1]
1581      [dimns]= list of the name of the dimensions of [t]
1582      [dimvns]= list of the name of the variables with the values of the
1583        dimensions of [t]
1584    """
1585    fname = 'compute_rh'
1586
1587    rhdims = dimns[:]
1588    rhvdims = dimvns[:]
1589
1590    data1 = 10.*0.6112*np.exp(17.67*(t-273.16)/(t-29.65))
1591    data2 = 0.622*data1/(0.01*p-(1.-0.622)*data1)
1592
1593    rh = q/data2
1594
1595    return rh, rhdims, rhvdims
1596
1597def compute_td(p, temp, qv, dimns, dimvns):
1598    """ Function to compute the dew point temperature
1599      [p]= pressure [Pa]
1600      [temp]= temperature [C]
1601      [qv]= mixing ratio [kgkg-1]
1602      [dimns]= list of the name of the dimensions of [p]
1603      [dimvns]= list of the name of the variables with the values of the
1604        dimensions of [p]
1605    """
1606    fname = 'compute_td'
1607
1608#    print '    ' + fname + ': computing dew-point temperature from TS as t and Tetens...'
1609# tacking from: http://en.wikipedia.org/wiki/Dew_point
1610    tk = temp
1611    data1 = 10.*0.6112*np.exp(17.67*(tk-273.16)/(tk-29.65))
1612    data2 = 0.622*data1/(0.01*p-(1.-0.622)*data1)
1613
1614    rh = qv/data2
1615               
1616    pa = rh * data1
1617    td = 257.44*np.log(pa/6.1121)/(18.678-np.log(pa/6.1121))
1618
1619    tddims = dimns[:]
1620    tdvdims = dimvns[:]
1621
1622    return td, tddims, tdvdims
1623
1624def var_WRFtime(timewrfv, refdate='19491201000000', tunitsval='minutes'):
1625    """ Function to copmute CFtimes from WRFtime variable
1626      refdate= [YYYYMMDDMIHHSS] format of reference date
1627      tunitsval= CF time units
1628      timewrfv= matrix string values of WRF 'Times' variable
1629    """
1630    fname = 'var_WRFtime'
1631
1632    yrref=refdate[0:4]
1633    monref=refdate[4:6]
1634    dayref=refdate[6:8]
1635    horref=refdate[8:10]
1636    minref=refdate[10:12]
1637    secref=refdate[12:14]
1638
1639    refdateS = yrref + '-' + monref + '-' + dayref + ' ' + horref + ':' + minref +   \
1640      ':' + secref
1641
1642    dt = timewrfv.shape[0]
1643    WRFtime = np.zeros((dt), dtype=np.float)
1644
1645    for it in range(dt):
1646        wrfdates = gen.datetimeStr_conversion(timewrfv[it,:],'WRFdatetime', 'matYmdHMS')
1647        WRFtime[it] = gen.realdatetime1_CFcompilant(wrfdates, refdate, tunitsval)
1648
1649    tunits = tunitsval + ' since ' + refdateS
1650
1651    return WRFtime, tunits
1652
1653def turbulence_var(varv, dimvn, dimn):
1654    """ Function to compute the Taylor's decomposition turbulence term from a a given variable
1655      x*=<x^2>_t-(<X>_t)^2
1656    turbulence_var(varv,dimn)
1657      varv= values of the variable
1658      dimvn= names of the dimension of the variable
1659      dimn= names of the dimensions (as a dictionary with 'X', 'Y', 'Z', 'T')
1660    >>> turbulence_var(np.arange((27)).reshape(3,3,3),['time','y','x'],{'T':'time', 'Y':'y', 'X':'x'})
1661    [[ 54.  54.  54.]
1662     [ 54.  54.  54.]
1663     [ 54.  54.  54.]]
1664    """
1665    fname = 'turbulence_varv'
1666
1667    timedimid = dimvn.index(dimn['T'])
1668
1669    varv2 = varv*varv
1670
1671    vartmean = np.mean(varv, axis=timedimid)
1672    var2tmean = np.mean(varv2, axis=timedimid)
1673
1674    varvturb = var2tmean - (vartmean*vartmean)
1675
1676    return varvturb
1677
1678def compute_turbulence(v, dimns, dimvns):
1679    """ Function to compute the rubulence term of the Taylor's decomposition ...'
1680      x*=<x^2>_t-(<X>_t)^2
1681      [v]= variable (assuming [[t],z,y,x])
1682      [dimns]= list of the name of the dimensions of [v]
1683      [dimvns]= list of the name of the variables with the values of the
1684        dimensions of [v]
1685    """
1686    fname = 'compute_turbulence'
1687
1688    turbdims = dimns[:]
1689    turbvdims = dimvns[:]
1690
1691    turbdims.pop(0)
1692    turbvdims.pop(0)
1693
1694    v2 = v*v
1695
1696    vartmean = np.mean(v, axis=0)
1697    var2tmean = np.mean(v2, axis=0)
1698
1699    turb = var2tmean - (vartmean*vartmean)
1700
1701    return turb, turbdims, turbvdims
1702
1703def compute_wd(u, v, dimns, dimvns):
1704    """ Function to compute the wind direction
1705      [u]= W-E wind direction [ms-1, knot, ...]
1706      [v]= N-S wind direction [ms-1, knot, ...]
1707      [dimns]= list of the name of the dimensions of [u]
1708      [dimvns]= list of the name of the variables with the values of the
1709        dimensions of [u]
1710    """
1711    fname = 'compute_wds'
1712
1713#    print '    ' + fname + ': computing wind direction as ATAN2(v,u) ...'
1714    theta = np.arctan2(v,u)
1715    theta = np.where(theta < 0., theta + 2.*np.pi, theta)
1716
1717    var = 360.*theta/(2.*np.pi)
1718
1719    vardims = dimns[:]
1720    varvdims = dimvns[:]
1721
1722    return var, vardims, varvdims
1723
1724def compute_wds(u, v, dimns, dimvns):
1725    """ Function to compute the wind direction
1726      [u]= W-E wind direction [ms-1, knot, ...]
1727      [v]= N-S wind direction [ms-1, knot, ...]
1728      [dimns]= list of the name of the dimensions of [u]
1729      [dimvns]= list of the name of the variables with the values of the
1730        dimensions of [u]
1731    """
1732    fname = 'compute_wds'
1733
1734#    print '    ' + fname + ': computing wind direction as ATAN2(v,u) ...'
1735    theta = np.arctan2(v,u)
1736    theta = np.where(theta < 0., theta + 2.*np.pi, theta)
1737
1738    wds = 360.*theta/(2.*np.pi)
1739
1740    wdsdims = dimns[:]
1741    wdsvdims = dimvns[:]
1742
1743    return wds, wdsdims, wdsvdims
1744
1745def compute_wss(u, v, dimns, dimvns):
1746    """ Function to compute the wind speed
1747      [u]= W-E wind direction [ms-1, knot, ...]
1748      [v]= N-S wind direction [ms-1, knot, ...]
1749      [dimns]= list of the name of the dimensions of [u]
1750      [dimvns]= list of the name of the variables with the values of the
1751        dimensions of [u]
1752    """
1753    fname = 'compute_wss'
1754
1755#    print '    ' + fname + ': computing wind speed as SQRT(v**2 + u**2) ...'
1756    wss = np.sqrt(u*u + v*v)
1757
1758    wssdims = dimns[:]
1759    wssvdims = dimvns[:]
1760
1761    return wss, wssdims, wssvdims
1762
1763def timeunits_seconds(dtu):
1764    """ Function to transform a time units to seconds
1765    timeunits_seconds(timeuv)
1766      [dtu]= time units value to transform in seconds
1767    """
1768    fname='timunits_seconds'
1769
1770    if dtu == 'years':
1771        times = 365.*24.*3600.
1772    elif dtu == 'weeks':
1773        times = 7.*24.*3600.
1774    elif dtu == 'days':
1775        times = 24.*3600.
1776    elif dtu == 'hours':
1777        times = 3600.
1778    elif dtu == 'minutes':
1779        times = 60.
1780    elif dtu == 'seconds':
1781        times = 1.
1782    elif dtu == 'miliseconds':
1783        times = 1./1000.
1784    else:
1785        print errormsg
1786        print '  ' + fname  + ": time units '" + dtu + "' not ready !!"
1787        quit(-1)
1788
1789    return times
1790
1791def compute_WRFhur(t, p, qv, dimns, dimvns):
1792    """ Function to compute WRF relative humidity following Teten's equation
1793      t= orginal WRF temperature
1794      p= original WRF pressure (P + PB)
1795      formula:
1796          temp = theta*(p/p0)**(R/Cp)
1797
1798    """
1799    fname = 'compute_WRFtd'
1800
1801    tk = (t+300.)*(p/fdef.module_definitions.p0ref)**(fdef.module_definitions.rcp)
1802    data1 = 10.*0.6112*np.exp(17.67*(tk-273.16)/(tk-29.65))
1803    data2 = 0.622*data1/(0.01*p-(1.-0.622)*data1)
1804
1805    rh = qv/data2
1806               
1807    dnamesvar = ['Time','bottom_top','south_north','west_east']
1808    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
1809
1810    return rh, dnamesvar, dvnamesvar
1811
1812def compute_WRFua(u, v, sina, cosa, dimns, dimvns):
1813    """ Function to compute geographical rotated WRF 3D winds
1814      u= orginal WRF x-wind
1815      v= orginal WRF y-wind
1816      sina= original WRF local sinus of map rotation
1817      cosa= original WRF local cosinus of map rotation
1818      formula:
1819        ua = u*cosa-va*sina
1820        va = u*sina+va*cosa
1821    """
1822    fname = 'compute_WRFua'
1823
1824    var0 = u
1825    var1 = v
1826    var2 = sina
1827    var3 = cosa
1828
1829    # un-staggering variables
1830    unstgdims = [var0.shape[0], var0.shape[1], var0.shape[2], var0.shape[3]-1]
1831    ua = np.zeros(tuple(unstgdims), dtype=np.float)
1832    unstgvar0 = np.zeros(tuple(unstgdims), dtype=np.float)
1833    unstgvar1 = np.zeros(tuple(unstgdims), dtype=np.float)
1834    unstgvar0 = 0.5*(var0[:,:,:,0:var0.shape[3]-1] + var0[:,:,:,1:var0.shape[3]])
1835    unstgvar1 = 0.5*(var1[:,:,0:var1.shape[2]-1,:] + var1[:,:,1:var1.shape[2],:])
1836
1837    for iz in range(var0.shape[1]):
1838        ua[:,iz,:,:] = unstgvar0[:,iz,:,:]*var3 - unstgvar1[:,iz,:,:]*var2
1839
1840    dnamesvar = ['Time','bottom_top','south_north','west_east']
1841    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
1842
1843    return ua, dnamesvar, dvnamesvar
1844
1845def compute_WRFva(u, v, sina, cosa, dimns, dimvns):
1846    """ Function to compute geographical rotated WRF 3D winds
1847      u= orginal WRF x-wind
1848      v= orginal WRF y-wind
1849      sina= original WRF local sinus of map rotation
1850      cosa= original WRF local cosinus of map rotation
1851      formula:
1852        ua = u*cosa-va*sina
1853        va = u*sina+va*cosa
1854    """
1855    fname = 'compute_WRFva'
1856
1857    var0 = u
1858    var1 = v
1859    var2 = sina
1860    var3 = cosa
1861
1862    # un-staggering variables
1863    unstgdims = [var0.shape[0], var0.shape[1], var0.shape[2], var0.shape[3]-1]
1864    va = np.zeros(tuple(unstgdims), dtype=np.float)
1865    unstgvar0 = np.zeros(tuple(unstgdims), dtype=np.float)
1866    unstgvar1 = np.zeros(tuple(unstgdims), dtype=np.float)
1867    unstgvar0 = 0.5*(var0[:,:,:,0:var0.shape[3]-1] + var0[:,:,:,1:var0.shape[3]])
1868    unstgvar1 = 0.5*(var1[:,:,0:var1.shape[2]-1,:] + var1[:,:,1:var1.shape[2],:])
1869
1870    for iz in range(var0.shape[1]):
1871        va[:,iz,:,:] = unstgvar0[:,iz,:,:]*var2 + unstgvar1[:,iz,:,:]*var3
1872
1873    dnamesvar = ['Time','bottom_top','south_north','west_east']
1874    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
1875
1876    return va, dnamesvar, dvnamesvar
1877
1878def compute_WRFuava(u, v, sina, cosa, dimns, dimvns):
1879    """ Function to compute geographical rotated WRF 3D winds
1880      u= orginal WRF x-wind
1881      v= orginal WRF y-wind
1882      sina= original WRF local sinus of map rotation
1883      cosa= original WRF local cosinus of map rotation
1884      formula:
1885        ua = u*cosa-va*sina
1886        va = u*sina+va*cosa
1887    """
1888    fname = 'compute_WRFuava'
1889
1890    var0 = u
1891    var1 = v
1892    var2 = sina
1893    var3 = cosa
1894
1895    # un-staggering variables
1896    unstgdims = [var0.shape[0], var0.shape[1], var0.shape[2], var0.shape[3]-1]
1897    ua = np.zeros(tuple(unstgdims), dtype=np.float)
1898    va = np.zeros(tuple(unstgdims), dtype=np.float)
1899    unstgvar0 = np.zeros(tuple(unstgdims), dtype=np.float)
1900    unstgvar1 = np.zeros(tuple(unstgdims), dtype=np.float)
1901    unstgvar0 = 0.5*(var0[:,:,:,0:var0.shape[3]-1] + var0[:,:,:,1:var0.shape[3]])
1902    unstgvar1 = 0.5*(var1[:,:,0:var1.shape[2]-1,:] + var1[:,:,1:var1.shape[2],:])
1903
1904    for iz in range(var0.shape[1]):
1905        ua[:,iz,:,:] = unstgvar0[:,iz,:,:]*var3 - unstgvar1[:,iz,:,:]*var2
1906        va[:,iz,:,:] = unstgvar0[:,iz,:,:]*var2 + unstgvar1[:,iz,:,:]*var3
1907
1908    dnamesvar = ['Time','bottom_top','south_north','west_east']
1909    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
1910
1911    return ua, va, dnamesvar, dvnamesvar
1912
1913def compute_WRFuas(u10, v10, sina, cosa, dimns, dimvns):
1914    """ Function to compute geographical rotated WRF 2-meter x-wind
1915      u10= orginal WRF 10m x-wind
1916      v10= orginal WRF 10m y-wind
1917      sina= original WRF local sinus of map rotation
1918      cosa= original WRF local cosinus of map rotation
1919      formula:
1920        uas = u10*cosa-va10*sina
1921        vas = u10*sina+va10*cosa
1922    """
1923    fname = 'compute_WRFuas'
1924
1925    var0 = u10
1926    var1 = v10
1927    var2 = sina
1928    var3 = cosa
1929
1930    uas = np.zeros(var0.shape, dtype=np.float)
1931    vas = np.zeros(var0.shape, dtype=np.float)
1932
1933    uas = var0*var3 - var1*var2
1934
1935    dnamesvar = ['Time','south_north','west_east']
1936    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
1937
1938    return uas, dnamesvar, dvnamesvar
1939
1940def compute_WRFvas(u10, v10, sina, cosa, dimns, dimvns):
1941    """ Function to compute geographical rotated WRF 2-meter y-wind
1942      u10= orginal WRF 10m x-wind
1943      v10= orginal WRF 10m y-wind
1944      sina= original WRF local sinus of map rotation
1945      cosa= original WRF local cosinus of map rotation
1946      formula:
1947        uas = u10*cosa-va10*sina
1948        vas = u10*sina+va10*cosa
1949    """
1950    fname = 'compute_WRFvas'
1951
1952    var0 = u10
1953    var1 = v10
1954    var2 = sina
1955    var3 = cosa
1956
1957    uas = np.zeros(var0.shape, dtype=np.float)
1958    vas = np.zeros(var0.shape, dtype=np.float)
1959
1960    vas = var0*var2 + var1*var3
1961
1962    dnamesvar = ['Time','south_north','west_east']
1963    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
1964
1965    return vas, dnamesvar, dvnamesvar
1966
1967def compute_WRFuasvas(u10, v10, sina, cosa, dimns, dimvns):
1968    """ Function to compute geographical rotated WRF 2-meter winds
1969      u10= orginal WRF 10m x-wind
1970      v10= orginal WRF 10m y-wind
1971      sina= original WRF local sinus of map rotation
1972      cosa= original WRF local cosinus of map rotation
1973      formula:
1974        uas = u10*cosa-va10*sina
1975        vas = u10*sina+va10*cosa
1976    """
1977    fname = 'compute_WRFuasvas'
1978
1979    var0 = u10
1980    var1 = v10
1981    var2 = sina
1982    var3 = cosa
1983
1984    uas = np.zeros(var0.shape, dtype=np.float)
1985    vas = np.zeros(var0.shape, dtype=np.float)
1986
1987    uas = var0*var3 - var1*var2
1988    vas = var0*var2 + var1*var3
1989
1990    dnamesvar = ['Time','south_north','west_east']
1991    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
1992
1993    return uas, vas, dnamesvar, dvnamesvar
1994
1995def compute_WRFta(t, p, dimns, dimvns):
1996    """ Function to compute WRF air temperature
1997      t= orginal WRF temperature
1998      p= original WRF pressure (P + PB)
1999      formula:
2000          temp = theta*(p/p0)**(R/Cp)
2001
2002    """
2003    fname = 'compute_WRFta'
2004
2005    ta = (t+300.)*(p/fdef.module_definitions.p0ref)**(fdef.module_definitions.rcp)
2006
2007    dnamesvar = ['Time','bottom_top','south_north','west_east']
2008    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
2009
2010    return ta, dnamesvar, dvnamesvar
2011
2012def compute_WRFtd(t, p, qv, dimns, dimvns):
2013    """ Function to compute WRF dew-point air temperature
2014      t= orginal WRF temperature
2015      p= original WRF pressure (P + PB)
2016      formula:
2017          temp = theta*(p/p0)**(R/Cp)
2018
2019    """
2020    fname = 'compute_WRFtd'
2021
2022    tk = (t+300.)*(p/fdef.module_definitions.p0ref)**(fdef.module_definitions.rcp)
2023    data1 = 10.*0.6112*np.exp(17.67*(tk-273.16)/(tk-29.65))
2024    data2 = 0.622*data1/(0.01*p-(1.-0.622)*data1)
2025
2026    rh = qv/data2
2027               
2028    pa = rh * data1
2029    td = 257.44*np.log(pa/6.1121)/(18.678-np.log(pa/6.1121))
2030
2031    dnamesvar = ['Time','bottom_top','south_north','west_east']
2032    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
2033
2034    return td, dnamesvar, dvnamesvar
2035
2036def compute_WRFwd(u, v, sina, cosa, dimns, dimvns):
2037    """ Function to compute the wind direction
2038      u= W-E wind direction [ms-1]
2039      v= N-S wind direction [ms-1]
2040      sina= original WRF local sinus of map rotation
2041      cosa= original WRF local cosinus of map rotation
2042    """
2043    fname = 'compute_WRFwd'
2044    var0 = u
2045    var1 = v
2046    var2 = sina
2047    var3 = cosa
2048
2049    # un-staggering variables
2050    unstgdims = [var0.shape[0], var0.shape[1], var0.shape[2], var0.shape[3]-1]
2051    ua = np.zeros(tuple(unstgdims), dtype=np.float)
2052    va = np.zeros(tuple(unstgdims), dtype=np.float)
2053    unstgvar0 = np.zeros(tuple(unstgdims), dtype=np.float)
2054    unstgvar1 = np.zeros(tuple(unstgdims), dtype=np.float)
2055    unstgvar0 = 0.5*(var0[:,:,:,0:var0.shape[3]-1] + var0[:,:,:,1:var0.shape[3]])
2056    unstgvar1 = 0.5*(var1[:,:,0:var1.shape[2]-1,:] + var1[:,:,1:var1.shape[2],:])
2057
2058    for iz in range(var0.shape[1]):
2059        ua[:,iz,:,:] = unstgvar0[:,iz,:,:]*var3 - unstgvar1[:,iz,:,:]*var2
2060        va[:,iz,:,:] = unstgvar0[:,iz,:,:]*var2 + unstgvar1[:,iz,:,:]*var3
2061
2062    theta = np.arctan2(va,ua)
2063    theta = np.where(theta < 0., theta + 2.*np.pi, theta)
2064
2065    wd = 360.*theta/(2.*np.pi)
2066
2067    dnamesvar = ['Time','bottom_top','south_north','west_east']
2068    dvnamesvar = ncvar.var_dim_dimv(dnamesvar,dimns,dimvns)
2069
2070    return wd
2071
2072####### Variables (as they arrive without dimensions staff)
2073
2074def var_hur(p, t, q):
2075    """ Function to compute relative humidity following 'August - Roche - Magnus' formula
2076      [t]= temperature (assuming [[t],z,y,x] in [K])
2077      [p] = pressure field (assuming in [Pa])
2078      [q] = mixing ratio in [kgkg-1]
2079      ref.: M. G. Lawrence, BAMS, 2005, 225
2080    >>> print var_rh(101300., 290., 3.)
2081    0.250250256174
2082    """
2083    fname = 'var_hur'
2084
2085    # Enthalpy of vaporization [Jkg-1]
2086    L = 2.453*10.**6
2087    # Gas constant for water vapor [JK-1Kg-1]
2088    Rv = 461.5 
2089
2090    # Computing saturated pressure
2091    #es = 10.*0.6112*np.exp(17.67*(t-273.16)/(t-29.65))
2092    #es = 6.11*np.exp(L/Rv*(1.-273./t)/273.)
2093
2094    # August - Roche - Magnus formula
2095    es = 6.1094*np.exp(17.625*(t-273.15)/((t-273.15)+243.04))
2096
2097    # Saturated mixing ratio [g/kg]
2098    ws = 0.622*es/(0.01*p-es)
2099
2100    hur = q/(ws*1000.)
2101
2102    #print 'q:', q[5,5,5,5], 't:', t[5,5,5,5], 'p:', p[5,5,5,5]
2103    #print 'es:', es[5,5,5,5], 'ws:', ws[5,5,5,5], 'hur:', hur[5,5,5,5]
2104
2105    return hur
2106
2107def var_hur_Uhus(p, t, hus):
2108    """ Function to compute relative humidity following 'August - Roche - Magnus' formula using hus
2109      [t]= temperature (assuming [[t],z,y,x] in [K])
2110      [p] = pressure field (assuming in [Pa])
2111      [hus] = specific humidty [1]
2112      ref.: M. G. Lawrence, BAMS, 2005, 225
2113    >>> print var_rh(101300., 290., 3.)
2114    0.250250256174
2115    """
2116    fname = 'var_hur_Uhus'
2117
2118    # Enthalpy of vaporization [Jkg-1]
2119    L = 2.453*10.**6
2120    # Gas constant for water vapor [JK-1Kg-1]
2121    Rv = 461.5 
2122
2123    # Computing saturated pressure
2124    #es = 10.*0.6112*np.exp(17.67*(t-273.16)/(t-29.65))
2125    #es = 6.11*np.exp(L/Rv*(1.-273./t)/273.)
2126
2127    # August - Roche - Magnus formula
2128    es = 6.1094*np.exp(17.625*(t-273.15)/((t-273.15)+243.04))
2129
2130    # Saturated mixing ratio [g/kg]
2131    ws = 0.622*es/(0.01*p-es)
2132
2133    # Mixing ratio
2134    q = hus/(1.+hus)
2135
2136    hur = q/ws
2137
2138    #print 'q:', q[5,5,5,5], 't:', t[5,5,5,5], 'p:', p[5,5,5,5]
2139    #print 'es:', es[5,5,5,5], 'ws:', ws[5,5,5,5], 'hur:', hur[5,5,5,5]
2140
2141    return hur
2142
2143def var_td(t, p, qv):
2144    """ Function to compute dew-point air temperature from temperature and pressure values
2145      t= temperature [K]
2146      p= pressure (Pa)
2147      formula:
2148          temp = theta*(p/p0)**(R/Cp)
2149
2150    """
2151    fname = 'compute_td'
2152
2153    tk = (t)*(p/fdef.module_definitions.p0ref)**(fdef.module_definitions.rcp)
2154    data1 = 10.*0.6112*np.exp(17.67*(tk-273.16)/(tk-29.65))
2155    data2 = 0.622*data1/(0.01*p-(1.-0.622)*data1)
2156
2157    rh = qv/data2
2158               
2159    pa = rh * data1
2160    td = 257.44*np.log(pa/6.1121)/(18.678-np.log(pa/6.1121))
2161
2162    return td
2163
2164def var_td_Uhus(t, p, hus):
2165    """ Function to compute dew-point air temperature from temperature and pressure values using hus
2166      t= temperature [K]
2167      hus= specific humidity [1]
2168      formula:
2169          temp = theta*(p/p0)**(R/Cp)
2170
2171    """
2172    fname = 'compute_td'
2173
2174    tk = (t)*(p/fdef.module_definitions.p0ref)**(fdef.module_definitions.rcp)
2175    data1 = 10.*0.6112*np.exp(17.67*(tk-273.16)/(tk-29.65))
2176    data2 = 0.622*data1/(0.01*p-(1.-0.622)*data1)
2177
2178    qv = hus/(1.+hus)
2179
2180    rh = qv/data2
2181               
2182    pa = rh * data1
2183    td = 257.44*np.log(pa/6.1121)/(18.678-np.log(pa/6.1121))
2184
2185    return td
2186
2187def var_wd(u, v):
2188    """ Function to compute the wind direction
2189      [u]= W-E wind direction [ms-1, knot, ...]
2190      [v]= N-S wind direction [ms-1, knot, ...]
2191    """
2192    fname = 'var_wd'
2193
2194    theta = np.arctan2(v,u)
2195    theta = np.where(theta < 0., theta + 2.*np.pi, theta)
2196
2197    wd = 360.*theta/(2.*np.pi)
2198
2199    return wd
2200
2201def var_ws(u, v):
2202    """ Function to compute the wind speed
2203      [u]= W-E wind direction [ms-1, knot, ...]
2204      [v]= N-S wind direction [ms-1, knot, ...]
2205    """
2206    fname = 'var_ws'
2207
2208    ws = np.sqrt(u*u + v*v)
2209
2210    return ws
2211
2212class C_diagnostic(object):
2213    """ Class to compute generic variables
2214      Cdiag: name of the diagnostic to compute
2215      ncobj: netcdf object with data
2216      sfcvars: dictionary with CF equivalencies of surface variables inside file
2217      vars3D: dictionary with CF equivalencies of 3D variables inside file
2218      dictdims: dictionary with CF equivalencies of dimensions inside file
2219        self.values = Values of the diagnostic
2220        self.dims = Dimensions of the diagnostic
2221        self.units = units of the diagnostic
2222        self.incvars = list of variables from the input netCDF object
2223    """ 
2224    def __init__(self, Cdiag, ncobj, sfcvars, vars3D, dictdims):
2225        fname = 'C_diagnostic'
2226        self.values = None
2227        self.dims = None
2228        self.incvars = ncobj.variables
2229        self.units = None
2230
2231        if Cdiag == 'hur':
2232            """ Computing relative humidity
2233            """
2234            vn = 'hur'
2235            CF3Dvars = ['ta', 'plev', 'q']
2236            for v3D in CF3Dvars:
2237                if not vars3D.has_key(v3D):
2238                    print gen.errormsg
2239                    print '  ' + fname + ": missing variable '" + v3D +              \
2240                      "' attribution to compute '" + vn + "' !!"
2241                    print '  Equivalence of 3D variables provided _______'
2242                    gen.printing_dictionary(vars3D)
2243                    quit(-1)
2244                if not self.incvars.has_key(vars3D[v3D]):
2245                    print gen.errormsg
2246                    print '  ' + fname + ": missing variable '" + vars3D[v3D] +      \
2247                      "' in input file to compute '" + vn + "' !!"
2248                    print '  available variables:', self.incvars.keys()
2249                    print '  looking for variables _______' 
2250                    gen.printing_dictionary(vars3D)
2251                    quit(-1)
2252
2253            ta = ncobj.variables[vars3D['ta']][:]
2254            p = ncobj.variables[vars3D['plev']][:]
2255            q = ncobj.variables[vars3D['q']][:]
2256
2257            if len(ta.shape) != len(p.shape):
2258                p = gen.fill_Narray(p, ta*0., filldim=[0,2,3])
2259
2260            self.values = var_hur(p, ta, q)
2261            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2262              dictdims['lon']]
2263            self.units = '1'
2264
2265        if Cdiag == 'hur_Uhus':
2266            """ Computing relative humidity using hus
2267            """
2268            vn = 'hur'
2269            CF3Dvars = ['ta', 'plev', 'hus']
2270            for v3D in CF3Dvars:
2271                if not vars3D.has_key(v3D):
2272                    print gen.errormsg
2273                    print '  ' + fname + ": missing variable '" + v3D +              \
2274                      "' attribution to compute '" + vn + "' !!"
2275                    print '  Equivalence of 3D variables provided _______'
2276                    gen.printing_dictionary(vars3D)
2277                    quit(-1)
2278                if not self.incvars.has_key(vars3D[v3D]):
2279                    print gen.errormsg
2280                    print '  ' + fname + ": missing variable '" + vars3D[v3D] +      \
2281                      "' in input file to compute '" + vn + "' !!"
2282                    print '  available variables:', self.incvars.keys()
2283                    print '  looking for variables _______' 
2284                    gen.printing_dictionary(vars3D)
2285                    quit(-1)
2286
2287            ta = ncobj.variables[vars3D['ta']][:]
2288            p = ncobj.variables[vars3D['plev']][:]
2289            hus = ncobj.variables[vars3D['hus']][:]
2290
2291            if len(ta.shape) != len(p.shape):
2292                p = gen.fill_Narray(p, ta*0., filldim=[0,2,3])
2293
2294            self.values = var_hur_Uhus(p, ta, hus)
2295            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2296              dictdims['lon']]
2297            self.units = '1'
2298
2299        elif Cdiag == 'td':
2300            """ Computing dew-point temperature
2301            """
2302            vn = 'td'
2303            CF3Dvars = ['ta', 'plev', 'q']
2304            for v3D in CF3Dvars:
2305                if not vars3D.has_key(v3D):
2306                    print gen.errormsg
2307                    print '  ' + fname + ": missing variable '" + v3D +              \
2308                      "' attribution to compute '" + vn + "' !!"
2309                    print '  Equivalence of 3D variables provided _______'
2310                    gen.printing_dictionary(vars3D)
2311                    quit(-1)
2312                if not self.incvars.has_key(vars3D[v3D]):
2313                    print gen.errormsg
2314                    print '  ' + fname + ": missing variable '" + vars3D[v3D] +      \
2315                      "' in input file to compute '" + vn + "' !!"
2316                    print '  available variables:', self.incvars.keys()
2317                    print '  looking for variables _______' 
2318                    gen.printing_dictionary(vars3D)
2319                    quit(-1)
2320
2321            ta = ncobj.variables[vars3D['ta']][:]
2322            p = ncobj.variables[vars3D['plev']][:]
2323            q = ncobj.variables[vars3D['q']][:]
2324
2325            if len(ta.shape) != len(p.shape):
2326                p = gen.fill_Narray(p, ta*0., filldim=[0,2,3])
2327
2328            self.values = var_td(ta, p, q)
2329            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2330              dictdims['lon']]
2331            self.units = 'K'
2332
2333        elif Cdiag == 'td_Uhus':
2334            """ Computing dew-point temperature
2335            """
2336            vn = 'td'
2337            CF3Dvars = ['ta', 'plev', 'hus']
2338            for v3D in CF3Dvars:
2339                if not vars3D.has_key(v3D):
2340                    print gen.errormsg
2341                    print '  ' + fname + ": missing variable '" + v3D +              \
2342                      "' attribution to compute '" + vn + "' !!"
2343                    print '  Equivalence of 3D variables provided _______'
2344                    gen.printing_dictionary(vars3D)
2345                    quit(-1)
2346                if not self.incvars.has_key(vars3D[v3D]):
2347                    print gen.errormsg
2348                    print '  ' + fname + ": missing variable '" + vars3D[v3D] +      \
2349                      "' in input file to compute '" + vn + "' !!"
2350                    print '  available variables:', self.incvars.keys()
2351                    print '  looking for variables _______' 
2352                    gen.printing_dictionary(vars3D)
2353                    quit(-1)
2354
2355            ta = ncobj.variables[vars3D['ta']][:]
2356            p = ncobj.variables[vars3D['plev']][:]
2357            hus = ncobj.variables[vars3D['hus']][:]
2358
2359            if len(ta.shape) != len(p.shape):
2360                p = gen.fill_Narray(p, ta*0., filldim=[0,2,3])
2361
2362            self.values = var_td_Uhus(ta, p, hus)
2363            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2364              dictdims['lon']]
2365            self.units = 'K'
2366
2367        elif Cdiag == 'wd':
2368            """ Computing wind direction
2369            """
2370            vn = 'wd'
2371            CF3Dvars = ['ua', 'va']
2372            for v3D in CF3Dvars:
2373                if not vars3D.has_key(v3D):
2374                    print gen.errormsg
2375                    print '  ' + fname + ": missing variable '" + v3D +              \
2376                      "self.' attribution to compute '" + vn + "' !!"
2377                    print '  Equivalence of 3D variables provided _______'
2378                    gen.printing_dictionary(vars3D)
2379                    quit(-1)
2380                if not self.incvars.has_key(vars3D[v3D]):
2381                    print gen.errormsg
2382                    print '  ' + fname + ": missing variable '" + vars3D[v3D] +      \
2383                      "' in input file to compute '" + vn + "' !!"
2384                    print '  available variables:', self.incvars.keys()
2385                    print '  looking for variables _______' 
2386                    gen.printing_dictionary(vars3D)
2387                    quit(-1)
2388   
2389            ua = ncobj.variables[vars3D['ua']][:]
2390            va = ncobj.variables[vars3D['va']][:]
2391   
2392            self.values = var_wd(ua, va)
2393            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2394              dictdims['lon']]
2395            self.units = 'degree'
2396
2397        elif Cdiag == 'ws':
2398            """ Computing wind speed
2399            """
2400            vn = 'ws'
2401            CF3Dvars = ['ua', 'va']
2402            for v3D in CF3Dvars:
2403                if not vars3D.has_key(v3D):
2404                    print gen.errormsg
2405                    print '  ' + fname + ": missing variable '" + v3D +              \
2406                      "' attribution to compute '" + vn + "' !!"
2407                    print '  Equivalence of 3D variables provided _______'
2408                    gen.printing_dictionary(vars3D)
2409                    quit(-1)
2410                if not self.incvars.has_key(vars3D[v3D]):
2411                    print gen.errormsg
2412                    print '  ' + fname + ": missing variable '" + vars3D[v3D] +      \
2413                      "' in input file to compute '" + vn + "' !!"
2414                    print '  available variables:', self.incvars.keys()
2415                    print '  looking for variables _______' 
2416                    gen.printing_dictionary(vars3D)
2417                    quit(-1)
2418
2419            ua = ncobj.variables[vars3D['ua']][:]
2420            va = ncobj.variables[vars3D['va']][:]
2421
2422            self.values = var_ws(ua, va)
2423            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2424              dictdims['lon']]
2425            self.units = ncobj.variables[vars3D['ua']].units
2426
2427        else:
2428            print gen.errormsg
2429            print '  ' + fname + ": variable '" + Wdiag + "' not ready !!"
2430            print '  available ones:', Cavailablediags
2431            quit(-1)
2432
2433class W_diagnostic(object):
2434    """ Class to compute WRF diagnostics variables
2435      Wdiag: name of the diagnostic to compute
2436      ncobj: netcdf object with data
2437      sfcvars: dictionary with CF equivalencies of surface variables inside file
2438      vars3D: dictionary with CF equivalencies of 3D variables inside file
2439      indims: list of dimensions inside file
2440      invardims: list of dimension-variables inside file
2441      dictdims: dictionary with CF equivalencies of dimensions inside file
2442        self.values = Values of the diagnostic
2443        self.dims = Dimensions of the diagnostic
2444        self.units = units of the diagnostic
2445        self.incvars = list of variables from the input netCDF object
2446    """   
2447    def __init__(self, Wdiag, ncobj, sfcvars, vars3D, indims, invardims, dictdims):
2448        fname = 'W_diagnostic'
2449
2450        self.values = None
2451        self.dims = None
2452        self.incvars = ncobj.variables
2453        self.units = None
2454
2455        if Wdiag == 'hur':
2456            """ Computing relative humidity
2457            """
2458            vn = 'hur'
2459            CF3Dvars = ['ta', 'hus']
2460            for v3D in CF3Dvars:
2461                if not vars3D.has_key(v3D):
2462                    print gen.errormsg
2463                    print '  ' + fname + ": missing variable '" + v3D +              \
2464                      "' attribution to compute '" + vn + "' !!"
2465                    print '  Equivalence of 3D variables provided _______'
2466                    gen.printing_dictionary(vars3D)
2467                    quit(-1)
2468
2469            ta = ncobj.variables['T'][:]
2470            p = ncobj.variables['P'][:] + ncobj.variables['PB'][:]
2471            hur = ncobj.variables['QVAPOR'][:]
2472   
2473            vals, dims, vdims = compute_WRFhur(ta, p, hur, indims, invardims)
2474            self.values = vals
2475            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2476              dictdims['lon']]
2477            self.units = '1'
2478
2479        elif Wdiag == 'p':
2480            """ Computing air pressure
2481            """
2482            vn = 'p'
2483
2484            self.values = ncobj.variables['PB'][:] + ncobj.variables['P'][:]
2485            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2486              dictdims['lon']]
2487            self.units = ncobj.variables['PB'].units
2488
2489        elif Wdiag == 'ta':
2490            """ Computing air temperature
2491            """
2492            vn = 'ta'
2493            CF3Dvars = ['ta']
2494            for v3D in CF3Dvars:
2495                if not vars3D.has_key(v3D):
2496                    print gen.errormsg
2497                    print '  ' + fname + ": missing variable '" + v3D +              \
2498                      "' attribution to compute '" + vn + "' !!"
2499                    print '  Equivalence of 3D variables provided _______'
2500                    gen.printing_dictionary(vars3D)
2501                    quit(-1)
2502
2503            ta = ncobj.variables['T'][:]
2504            p = ncobj.variables['P'][:] + ncobj.variables['PB'][:]
2505   
2506            vals, dims, vdims = compute_WRFta(ta, p, indims, invardims)
2507            self.values = vals
2508            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2509              dictdims['lon']]
2510            self.units = 'K'
2511
2512        elif Wdiag == 'td':
2513            """ Computing dew-point temperature
2514            """
2515            vn = 'td'
2516            CF3Dvars = ['ta', 'hus']
2517            for v3D in CF3Dvars:
2518                if not vars3D.has_key(v3D):
2519                    print gen.errormsg
2520                    print '  ' + fname + ": missing variable '" + v3D +              \
2521                      "' attribution to compute '" + vn + "' !!"
2522                    print '  Equivalence of 3D variables provided _______'
2523                    gen.printing_dictionary(vars3D)
2524                    quit(-1)
2525
2526            ta = ncobj.variables['T'][:]
2527            p = ncobj.variables['P'][:] + ncobj.variables['PB'][:]
2528            hus = ncobj.variables['QVAPOR'][:]
2529   
2530            vals, dims, vdims = compute_WRFtd(ta, p, hus, indims, invardims)
2531            self.values = vals
2532            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2533              dictdims['lon']]
2534            self.units = 'K'
2535   
2536        elif Wdiag == 'ua':
2537            """ Computing x-wind
2538            """
2539            vn = 'ua'
2540            CF3Dvars = ['ua', 'va']
2541            for v3D in CF3Dvars:
2542                if not vars3D.has_key(v3D):
2543                    print gen.errormsg
2544                    print '  ' + fname + ": missing variable '" + v3D +              \
2545                      "' attribution to compute '" + vn + "' !!"
2546                    print '  Equivalence of 3D variables provided _______'
2547                    gen.printing_dictionary(vars3D)
2548                    quit(-1)
2549
2550            ua = ncobj.variables['U'][:]
2551            va = ncobj.variables['V'][:]
2552            sina = ncobj.variables['SINALPHA'][:]
2553            cosa = ncobj.variables['COSALPHA'][:]
2554   
2555            vals, dims, vdims = compute_WRFua(ua, va, sina, cosa, indims, invardims)
2556            self.values = vals
2557            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2558              dictdims['lon']]
2559            self.units = ncobj.variables['U'].units
2560   
2561        elif Wdiag == 'uas':
2562            """ Computing 10m x-wind
2563            """
2564            vn = 'uas'
2565            CFsfcvars = ['uas', 'vas']
2566            for vsf in CFsfcvars:
2567                if not sfcvars.has_key(vsf):
2568                    print gen.errormsg
2569                    print '  ' + fname + ": missing variable '" + vsf +              \
2570                      "' attribution to compute '" + vn + "' !!"
2571                    print '  Equivalence of sfc variables provided _______'
2572                    gen.printing_dictionary(sfcvars)
2573                    quit(-1)
2574   
2575            uas = ncobj.variables['U10'][:]
2576            vas = ncobj.variables['V10'][:]
2577            sina = ncobj.variables['SINALPHA'][:]
2578            cosa = ncobj.variables['COSALPHA'][:]
2579   
2580            vals,dims,vdims = compute_WRFuas(uas, vas, sina, cosa, indims, invardims)
2581            self.values = vals
2582            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2583              dictdims['lon']]
2584            self.units = ncobj.variables['U10'].units
2585   
2586        elif Wdiag == 'va':
2587            """ Computing y-wind
2588            """
2589            vn = 'ua'
2590            CF3Dvars = ['ua', 'va']
2591            for v3D in CF3Dvars:
2592                if not vars3D.has_key(v3D):
2593                    print gen.errormsg
2594                    print '  ' + fname + ": missing variable '" + v3D +              \
2595                      "' attribution to compute '" + vn + "' !!"
2596                    print '  Equivalence of 3D variables provided _______'
2597                    gen.printing_dictionary(vars3D)
2598                    quit(-1)
2599   
2600            ua = ncobj.variables['U'][:]
2601            va = ncobj.variables['V'][:]
2602            sina = ncobj.variables['SINALPHA'][:]
2603            cosa = ncobj.variables['COSALPHA'][:]
2604   
2605            vals, dims, vdims = compute_WRFva(ua, va, sina, cosa, indims, invardims)
2606            self.values = vals
2607            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2608              dictdims['lon']]
2609            self.units = ncobj.variables['U'].units
2610   
2611        elif Wdiag == 'vas':
2612            """ Computing 10m y-wind
2613            """
2614            vn = 'uas'
2615            CFsfcvars = ['uas', 'vas']
2616            for vsf in CFsfcvars:
2617                if not sfcvars.has_key(vsf):
2618                    print gen.errormsg
2619                    print '  ' + fname + ": missing variable '" + vsf +              \
2620                      "' attribution to compute '" + vn + "' !!"
2621                    print '  Equivalence of sfc variables provided _______'
2622                    gen.printing_dictionary(sfcvars)
2623                    quit(-1)
2624   
2625            uas = ncobj.variables['U10'][:]
2626            vas = ncobj.variables['V10'][:]
2627            sina = ncobj.variables['SINALPHA'][:]
2628            cosa = ncobj.variables['COSALPHA'][:]
2629   
2630            vals,dims,vdims = compute_WRFvas(uas, vas, sina, cosa, indims, invardims)
2631            self.values = vals
2632            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2633              dictdims['lon']]
2634            self.units = ncobj.variables['U10'].units
2635
2636        elif Wdiag == 'wd':
2637            """ Computing wind direction
2638            """
2639            vn = 'wd'
2640            CF3Dvars = ['ua', 'va']
2641            for v3D in CF3Dvars:
2642                if not vars3D.has_key(v3D):
2643                    print gen.errormsg
2644                    print '  ' + fname + ": missing variable '" + v3D +              \
2645                      "' attribution to compute '" + vn + "' !!"
2646                    print '  Equivalence of 3D variables provided _______'
2647                    gen.printing_dictionary(vars3D)
2648                    quit(-1)
2649
2650            ua = ncobj.variables['U10'][:]
2651            va = ncobj.variables['V10'][:]
2652            sina = ncobj.variables['SINALPHA'][:]
2653            cosa = ncobj.variables['COSALPHA'][:]
2654   
2655            vals, dims, vdims = compute_WRFwd(ua, va, sina, cosa, indims, invardims)
2656            self.values = vals
2657            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2658              dictdims['lon']]
2659            self.units = 'degree'
2660
2661        elif Wdiag == 'ws':
2662            """ Computing wind speed
2663            """
2664            vn = 'ws'
2665            CF3Dvars = ['ua', 'va']
2666            for v3D in CF3Dvars:
2667                if not vars3D.has_key(v3D):
2668                    print gen.errormsg
2669                    print '  ' + fname + ": missing variable '" + v3D +              \
2670                      "' attribution to compute '" + vn + "' !!"
2671                    print '  Equivalence of 3D variables provided _______'
2672                    gen.printing_dictionary(vars3D)
2673                    quit(-1)
2674   
2675            ua = ncobj.variables['U10'][:]
2676            va = ncobj.variables['V10'][:]
2677   
2678            self.values = var_ws(ua, va)
2679            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2680              dictdims['lon']]
2681            self.units = ncobj.variables['U10'].units
2682
2683        elif Wdiag == 'zg':
2684            """ Computing geopotential
2685            """
2686            vn = 'zg'
2687
2688            self.values = ncobj.variables['PHB'][:] + ncobj.variables['PH'][:]
2689            self.dims = [dictdims['time'], dictdims['plev'], dictdims['lat'],        \
2690              dictdims['lon']]
2691            self.units = ncobj.variables['PHB'].units
2692
2693        else:
2694            print gen.errormsg
2695            print '  ' + fname + ": variable '" + Wdiag + "' not ready !!"
2696            print '  available ones:', Wavailablediags
2697            quit(-1)
Note: See TracBrowser for help on using the repository browser.