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

Last change on this file since 2296 was 2277, checked in by lfita, 7 years ago

Adding:

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