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

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

Adding to 'range_faces':

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