source: lmdz_wrf/trunk/tools/generic_tools.py @ 768

Last change on this file since 768 was 762, checked in by lfita, 9 years ago

Bringing back to 'nc_var_tools.py' some functions
Adding `fname' in 'writing_str_nc'

  • Property svn:executable set to *
File size: 232.9 KB
Line 
1import numpy as np
2from netCDF4 import Dataset as NetCDFFile
3import os
4import re
5import numpy.ma as ma
6
7main = 'nc_var_tools.py'
8
9errormsg='ERROR -- error -- ERROR -- error'
10warnmsg='WARNING -- warning -- WARNING -- warning'
11
12fillValue = 1.e20
13fillValueF = 1.e20
14fillValueC = '-'
15fillValueI = -99999
16fillValueI16 = -99999
17fillValueF64 = 1.e20
18fillValueI32 = -99999
19
20def values_line(line, splitv, chars):
21    """ Function to retrieve values from a line of ASCII text removing a series of characters
22      line= line of ASCII text to work with
23      splitv= character to use to split with the line
24      chars= list of characters/strings to remove
25    >>> values_line('0.0 0.0 1 [ 0 0 ]', ' ', ['[', ']'])
26    ['0.0', '0.0', '1', '0', '0']
27    """
28    fname = 'values_line'
29
30    vals = line.replace('\n', '')
31    for ic in chars:
32        vals = vals.replace(ic, '')
33
34    vals0 = vals.split(splitv)
35    vals = []
36    for val in vals0:
37        if not len(val) == 0: vals.append(val)
38
39    return vals
40
41def filexist(filen, emsg, fmsg):
42    """ Check existence of a file
43    filen= file name
44    emsg= general error message
45    fmsg= message before generic text of inexistence of file
46    """
47    if not os.path.isfile(filen):
48        print emsg
49        print '  ' + fmsg + ' file "' + filen + '" does not exist !!'
50        print emsg
51        quit(-1)   
52
53    return
54
55def reduce_spaces(string):
56    """ Function to give words of a line of text removing any extra space
57    """
58    values = string.replace('\n','').split(' ')
59    vals = []
60    for val in values:
61         if len(val) > 0:
62             vals.append(val)
63
64    return vals
65
66def reduce_tabulars(string):
67    """ Function to give words of a line of text removing any extra space and tabular separation
68    """
69    values = string.replace('\n','').split('\t')
70    vals = []
71    for val in values:
72         if len(val) > 0:
73             vals.append(val)
74
75    return vals
76
77def check_arguments(funcname,args,expectargs,char):
78    """ Function to check the number of arguments if they are coincident
79    check_arguments(funcname,Nargs,args,char)
80      funcname= name of the function/program to check
81      args= passed arguments
82      expectargs= expected arguments
83      char= character used to split the arguments
84    """
85
86    fname = 'check_arguments'
87
88    Nvals = len(args.split(char))
89    Nargs = len(expectargs.split(char))
90
91    if Nvals != Nargs:
92        print errormsg
93        print '  ' + fname + ': wrong number of arguments:',Nvals," passed to  '",   \
94          funcname, "' which requires:",Nargs,'!!'
95        print '     # given expected _______'
96        Nmax = np.max([Nvals, Nargs])
97        for ia in range(Nmax):
98            if ia > Nvals-1:
99                aval = ' '
100            else:
101                aval = args.split(char)[ia]
102            if ia > Nargs-1:
103                aexp = ' '
104            else:
105                aexp = expectargs.split(char)[ia]
106
107            print '    ', ia, aval, aexp
108        quit(-1)
109
110    return
111
112def Str_Bool(val):
113    """ Function to transform from a String value to a boolean one
114    >>> Str_Bool('True')
115    True
116    >>> Str_Bool('0')
117    False
118    >>> Str_Bool('no')
119    False
120    """
121
122    fname = 'Str_Bool'
123
124    if val == 'True' or val == 'true' or val == '1' or val == 'yes' or val == 'T' or val == 't': 
125        boolv = True
126        boolv = True
127    elif val == 'False' or val == 'false' or val == '0' or val== 'no' or val == 'F' or val == 'f':
128        boolv = False
129    else:
130        print errormsg
131        print '  ' + fname + ": value '" + val + "' not ready!!"
132        quit(-1)
133
134    return boolv
135
136def Nchar(N,string):
137    """ Function to provide 'N' times concatenated 'string'
138      N= number of copies
139      strin= string to reproduce
140    >>> Nchar(4,'#')
141    ####
142    """
143    fname = 'Nchar'
144
145    newstring=''
146    for it in range(N):
147        newstring=newstring + string
148
149    return newstring
150
151def string_dicvals_char(dictionary, string, char):
152    """ Function to provide a string taking values from a given [string] where each single character
153      coincide with the key of the dictionary [dictionary], separated by a given set of characters [char]
154      dictionary= dictionary of the values dim([c]) = {[value]}
155      string = [c1][...[cN]] String with the combination of [c]s
156      >>> dictvals = {'i': 'dimx', 'j': 'dimy', 'k': 'dimz', 't': 'dimt'}
157      >>> string_dicvals_char(dictvals, 'ijkt', ', ')
158      dimx, dimy, dimz, dimt
159    """
160    fname = 'string_dicvals_char'
161
162    Lstring = len(string)
163    newstring = ''
164    for ic in range(Lstring):
165        cc = string[ic:ic+1]
166        if not dictionary.has_key(cc):
167            print errormsg
168            print '  ' + fname + ": dictionary of values does not have character '" +\
169              cc + "' !!"
170            print '    it has:',dictionary
171
172        if ic == 0:
173            newstring = dictionary[cc]
174        else:
175            newstring = newstring + char + dictionary[cc]
176
177    return newstring
178
179def substring(stringv,pos,char):
180    """ Function to substitute a character of a given string
181      stringv= string to change
182      pos= position to change
183      char= characters to use as substitution
184    >>> substring('0123456',2,'ii')
185    01ii3456
186    """
187    fname = 'substring'
188
189# From: http://stackoverflow.com/questions/1228299/change-one-character-in-a-string-in-python
190    newstring = stringv[:pos] + char + stringv[pos+1:]
191
192    return newstring
193
194def period_information(idate, edate, totunits):
195    """ Function to provide the information of a given period idate, edate (dates in [YYYY][MM][DD][HH][MI][SS] format)
196      [idate]= initial date of the period (in [YYYY][MM][DD][HH][MI][SS] format)
197      [edate]= end date of the period (in [YYYY][MM][DD][HH][MI][SS] format)
198      [totunits]= latest number of entire temporal units to compute: 'year', 'month', 'day', 'hour', 'minute', 'second'
199
200    resultant information given as ',' list of:
201      [dT]: sign of the temporal increment ('pos', 'neg')
202      [idate]: initial date as [YYYY]:[MM]:[DD]:[HH]:[MI]:[SS]
203      [edate]: end date as [YYYY]:[MM]:[DD]:[HH]:[MI]:[SS]
204      [Nsecs]: total seconds between dates
205      [Nyears]: Number of years taken as entire units ([iYYYY]0101000000 to [eYYYY+1]0101000000)
206      [ExactYears]: Exact year-dates of the period as a '@' separated list of  [YYYY]0101000000
207      [Nmonths]: Number of months taken as entire units ([iYYYY][iMM]01000000 to [eYYYY][eMM+1]01000000)
208      [ExactMonths]: Exact mon-dates of the period as  a '@' separated list of [YYYY][MM]01000000
209      [Ndays]: Number of days taken as entire units ([iYYYY][iMM][iDD]000000 to [eYYYY][eMM][eDD+1]000000)
210      [ExactDays]: Exact day-dates of the period as  a '@' separated list of [YYYY][MM][DD]000000
211      [Nhours]: Number of hours taken as entire units ([iYYYY][iMM][iDD][iHH]0000 to [eYYYY][eMM][eDD][eHH+1]0000)
212      [ExactHours]: Exact hour-dates of the period as a '@' separated list of [YYYY][MM][DD][HH]0000
213      [Nminutes]: Number of minutes taken as entire units ([iYYYY][iMM][iDD][iHH][iMI]00 to [eYYYY][eMM][eDD][eHH][eMI+1]00)
214      [ExactMinutes]: Exact minutes-dates of the period as a '@' separated list of [YYYY][MM][DD][HH][MI]00
215      [Nsecs]: Number of minutes taken as entire units ([iYYYY][iMM][iDD][iHH][iMI][iS] to [eYYYY][eMM][eDD][eHH][eMI][eSE+1])
216      [ExactSeconds]: Exact seconds-dates of the period as a '@' separated list of [YYYY][MM][DD][HH][MI][SS]
217
218    >>> period_information( '19760217083110', '19770828000000', 'month')
219    pos,1976:02:17:08:31:10,1977:08:28:00:00:00,48180530.0,19,19760201000000@19760301000000@19760401000000@
220    19760501000000@19760601000000@19760701000000@19760801000000@19760901000000@19761001000000@19761101000000@
221    19761201000000@19770101000000@19770201000000@19770301000000@19770401000000@19770501000000@19770601000000@
222    19770701000000@19770801000000@19770901000000
223    """
224    import datetime as dt
225
226    fname = 'period_information'
227
228    if idate == 'h':
229        print fname + '_____________________________________________________________'
230        print variables_values.__doc__
231        quit()
232
233    expectargs = '[idate],[edate],[totunits]'
234 
235    check_arguments(fname,str(idate)+','+str(edate)+','+str(totunits),expectargs,',')
236
237# Checking length
238    Lidate = len(idate)
239    Ledate = len(edate)
240
241    if Lidate != Ledate:
242        print errormsg
243        print '   ' + fname + ': string dates of the period have different length !!'
244        print "    idate: '" + idate + "' (L=", Lidate, ") edate: '" + edate +       \
245          "' (L=", Ledate, ')'
246        quit(-1)
247    else:
248        if Lidate != 14:
249            print errormsg
250            print '  ' + fname + ": wrong initial date: '" + idate + "' must " +     \
251              'have 14 characters!!'
252            print '    and it has:', Lidate
253            quit(-1)
254        if Ledate != 14:
255            print errormsg
256            print '  ' + fname + ": wrong end date: '" + edate + "' must " +         \
257              'have 14 characters!!'
258            print '    and it has:', Ledate
259            quit(-1)
260
261# Checking for right order of dates
262    if int(idate) > int(edate):
263        print warnmsg
264        print '  ' + fname + ": initial date '" + idate + "' after end date '" +     \
265          edate + "' !!"
266        print "  re-sorting them!"
267        i1 = edate
268        e1 = idate
269        idate = i1
270        edate = e1
271        oinf = 'neg'
272    else:
273        oinf = 'pos'
274
275# Year, month, day, hour, minute, second initial date
276    iyrS = idate[0:4]
277    imoS = idate[4:6]
278    idaS = idate[6:8]
279    ihoS = idate[8:10]
280    imiS = idate[10:12]
281    iseS = idate[12:14]
282
283    oinf = oinf + ',' + iyrS+':'+imoS+':'+idaS+':'+ihoS+':'+imiS+':'+iseS
284
285# Year, month, day, hour, minute, second end date
286    eyrS = edate[0:4]
287    emoS = edate[4:6]
288    edaS = edate[6:8]
289    ehoS = edate[8:10]
290    emiS = edate[10:12]
291    eseS = edate[12:14]
292
293    oinf = oinf + ',' + eyrS+':'+emoS+':'+edaS+':'+ehoS+':'+emiS+':'+eseS
294
295    idateT = dt.datetime(int(iyrS),int(imoS),int(idaS),int(ihoS),int(imiS),int(iseS))
296    edateT = dt.datetime(int(eyrS),int(emoS),int(edaS),int(ehoS),int(emiS),int(eseS))
297
298# Seconds between dates
299    DT = edateT - idateT
300    Nsecs = DT.total_seconds()
301
302    oinf = oinf + ',' + str(Nsecs)
303
304# Looking for number of years tacking exact beginning of the units [iYYYY]0101000000, [eYYYY+1]0101000000
305##
306    if totunits == 'year':
307        itime = int(iyrS)
308        if edate[4:15] != '0101000000':
309            etime = int(eyrS)+1
310        else:
311            etime = int(eyrS)
312
313        itimeT = dt.datetime(itime,1,1,0,0,0)
314
315        Nyears = 1
316        ExactYears = itimeT.strftime("%Y%m%d%H%M%S")
317        it = int(iyrS)
318        while it + 1 <= etime:
319            it = it + 1
320            Nyears = Nyears + 1
321            itT = dt.datetime(it,1,1,0,0,0)
322            ExactYears = ExactYears + '@' + itT.strftime("%Y%m%d%H%M%S")
323
324        oinf = oinf + ',' + str(Nyears) + ',' + ExactYears
325
326# Looking for number of months tacking exact beginning of the units [iYYYY][iMM]01000000, [eYYYY][eMM+1]01000000
327##
328    if totunits == 'month':
329        itime = int(iyrS)*100 + int(imoS)
330        if edate[6:15] != '01000000':
331            emo1 = int(emoS)+1
332            if emo1 > 13:
333                eyr1 = str(int(eyrS) + 1)
334                emo1 = 01
335            else:
336                eyr1 = eyrS
337           
338        else:
339            eyr1 = eyrS
340            emo1 = emoS
341   
342        etime = int(eyr1)*100 + int(emo1) 
343        itimeT = dt.datetime(int(iyrS),int(imoS),1,0,0,0)
344       
345        Nmonths = 1
346        ExactMonths = itimeT.strftime("%Y%m%d%H%M%S")
347        it = itime
348        while it + 1 <= etime:
349            it = it + 1
350            Nmonths = Nmonths + 1
351            ityr = it/100
352            itmo = it - ityr*100
353            if itmo > 12:
354                ityr = ityr + 1
355                itmo = 1
356                it = ityr * 100 + itmo
357   
358            itT = dt.datetime(ityr,itmo,1,0,0,0)
359            ExactMonths = ExactMonths + '@' + itT.strftime("%Y%m%d%H%M%S")
360   
361        oinf = oinf + ',' + str(Nmonths) + ',' + ExactMonths
362
363# Looking for number of days tacking exact beginning of the units [iYYYY][iMM][iDD]000000, [eYYYY][eMM][eDD+1]000000
364##
365    if totunits == 'day':
366        itime = dt.datetime(int(iyrS),int(imoS),int(idaS),0,0,0)
367        if edate[8:15] != '000000':
368            etime = dt.datetime(int(eyrS), int(emoS), int(edaS)+1,0,0,0)
369        else:
370            etime = edateT
371   
372        Ndays = 1
373        ExactDays = itime.strftime("%Y%m%d%H%M%S")
374        it = itime
375        while it + dt.timedelta(days=1) <= etime:
376            it = it + dt.timedelta(days=1)
377            Ndays = Ndays + 1
378            ExactDays = ExactDays + '@' + it.strftime("%Y%m%d%H%M%S")
379   
380        oinf = oinf + ',' + str(Ndays) + ',' + ExactDays
381
382# Looking for number of hours tacking exact beginning of the units [iYYYY][iMM][iDD][iHH]0000, [eYYYY][eMM][eDD][iHH+1]0000
383##
384    if totunits == 'hour':
385        itime = dt.datetime(int(iyrS),int(imoS),int(idaS),int(ihoS),0,0)
386        if edate[10:15] != '0000':
387            etime = dt.datetime(int(eyrS), int(emoS), int(edaS), int(ehoS)+1,0,0)
388        else:
389            etime = edateT
390   
391        Nhours = 1
392        ExactHours = itime.strftime("%Y%m%d%H%M%S")
393        it = itime
394        while it  + dt.timedelta(hours=1) <= etime:
395            it = it + dt.timedelta(hours=1)
396            Nhours = Nhours + 1
397            ExactHours = ExactHours + '@' + it.strftime("%Y%m%d%H%M%S")
398   
399        oinf = oinf + ',' + str(Nhours) + ',' + ExactHours
400
401# Looking for number of minutes tacking exact beginning of the units [iYYYY][iMM][iDD][iHH][iMI]00, [eYYYY][eMM][eDD][iHH][iMI+1]00
402##
403    if totunits == 'minute':
404        itime = dt.datetime(int(iyrS),int(imoS),int(idaS),int(ihoS),int(imiS),0)
405        if edate[12:15] != '00':
406            etime = dt.datetime(int(eyrS), int(emoS), int(edaS), int(ehoS), int(emiS)+1,0)
407        else:
408            etime = edateT
409
410        Nminutes = 1
411        ExactMinutes = itime.strftime("%Y%m%d%H%M%S")
412        it = itime
413        while it + dt.timedelta(minutes=1) <= etime:
414            it = it + dt.timedelta(minutes=1)
415            Nminutes = Nminutes + 1
416            ExactMinutes = ExactMinutes + '@' + it.strftime("%Y%m%d%H%M%S")
417   
418        oinf = oinf + ',' + str(Nminutes) + ',' + ExactMinutes
419
420# Looking for number of seconds tacking exact beginning of the units [iYYYY][iMM][iDD][iHH][iMI][iSE],
421#   [eYYYY][eMM][eDD][iHH][iMI][iSE+1]
422##
423    if totunits == 'second':
424        itime = dt.datetime(int(iyrS),int(imoS),int(idaS),int(ihoS),int(imiS),int(iseS))
425        print 'Lluis ', edate[12:15], '00'
426        if edate[12:15] != '00':
427            etime = dt.datetime(int(eyrS), int(emoS), int(edaS), int(ehoS), int(emiS), int(eseS)+1)
428        else:
429            etime = edateT
430
431        Nseconds = 1
432        ExactSeconds = itime.strftime("%Y%m%d%H%M%S")
433        it = itime
434        while it + dt.timedelta(seconds=1) < etime:
435            it = it + dt.timedelta(seconds=1)
436            Nseconds = Nseconds + 1
437            ExactSeconds = ExactSeconds + '@' + it.strftime("%Y%m%d%H%M%S")
438   
439        oinf = oinf + ',' + str(Nseconds) + ',' + ExactSeconds
440
441    return oinf
442
443def variables_values(varName):
444    """ Function to provide values to plot the different variables values from ASCII file
445      'variables_values.dat'
446    variables_values(varName)
447      [varName]= name of the variable
448        return: [var name], [std name], [minimum], [maximum],
449          [long name]('|' for spaces), [units], [color palette] (following:
450          http://matplotlib.org/1.3.1/examples/color/colormaps_reference.html)
451     [varn]: original name of the variable
452       NOTE: It might be better doing it with an external ASII file. But then we
453         got an extra dependency...
454    >>> variables_values('WRFght')
455    ['z', 'geopotential_height', 0.0, 80000.0, 'geopotential|height', 'm2s-2', 'rainbow']
456    """
457    import subprocess as sub
458
459    fname='variables_values'
460
461    if varName == 'h':
462        print fname + '_____________________________________________________________'
463        print variables_values.__doc__
464        quit()
465
466# This does not work....
467#    folderins = sub.Popen(["pwd"], stdout=sub.PIPE)
468#    folder = list(folderins.communicate())[0].replace('\n','')
469# From http://stackoverflow.com/questions/4934806/how-can-i-find-scripts-directory-with-python
470    folder = os.path.dirname(os.path.realpath(__file__))
471
472    infile = folder + '/variables_values.dat'
473
474    if not os.path.isfile(infile):
475        print errormsg
476        print '  ' + fname + ": File '" + infile + "' does not exist !!"
477        quit(-1)
478
479# Variable name might come with a statistical surname...
480    stats=['min','max','mean','stdv', 'sum']
481
482# Variables with a statistical section on their name...
483    NOstatsvars = ['zmaxth', 'zmax_th', 'lmax_th', 'lmaxth']
484
485    ifst = False
486    if not searchInlist(NOstatsvars, varName.lower()):
487        for st in stats:
488            if varName.find(st) > -1:
489                print '    '+ fname + ": varibale '" + varName + "' with a " +       \
490                  "statistical surname: '",st,"' !!"
491                Lst = len(st)
492                LvarName = len(varName)
493                varn = varName[0:LvarName - Lst]
494                ifst = True
495                break
496    if not ifst:
497        varn = varName
498
499    ncf = open(infile, 'r')
500
501    for line in ncf:
502        if line[0:1] != '#':
503            values = line.replace('\n','').split(',')
504            if len(values) != 8:
505                print errormsg
506                print "problem in varibale:'", values[0],                            \
507                  'it should have 8 values and it has',len(values)
508                quit(-1)
509
510            if varn[0:6] == 'varDIM': 
511# Variable from a dimension (all with 'varDIM' prefix)
512                Lvarn = len(varn)
513                varvals = [varn[6:Lvarn+1], varn[6:Lvarn+1], 0., 1.,                 \
514                  "variable|from|size|of|dimension|'" + varn[6:Lvarn+1] + "'", '1',  \
515                   'rainbow']
516            else:
517                varvals = [values[1].replace(' ',''), values[2].replace(' ',''),     \
518                  np.float(values[3]), np.float(values[4]),values[5].replace(' ',''),\
519                  values[6].replace(' ',''), values[7].replace(' ','')]
520            if values[0] == varn:
521                ncf.close()
522                return varvals
523                break
524
525    print errormsg
526    print '  ' + fname + ": variable '" + varn + "' not defined !!!"
527    ncf.close()
528    quit(-1)
529
530    return 
531
532def variables_values_old(varName):
533    """ Function to provide values to plot the different variables
534    variables_values(varName)
535      [varName]= name of the variable
536        return: [var name], [std name], [minimum], [maximum],
537          [long name]('|' for spaces), [units], [color palette] (following:
538          http://matplotlib.org/1.3.1/examples/color/colormaps_reference.html)
539     [varn]: original name of the variable
540       NOTE: It might be better doing it with an external ASII file. But then we
541         got an extra dependency...
542    >>> variables_values('WRFght')
543    ['z', 'geopotential_height', 0.0, 80000.0, 'geopotential|height', 'm2s-2', 'rainbow']
544    """
545    fname='variables_values'
546
547    if varName == 'h':
548        print fname + '_____________________________________________________________'
549        print variables_values.__doc__
550        quit()
551
552# Variable name might come with a statistical surname...
553    stats=['min','max','mean','stdv', 'sum']
554
555    ifst = False
556    for st in stats:
557        if varName.find(st) > -1:
558            print '    '+ fname + ": varibale '" + varName + "' with a statistical "+\
559              " surname: '",st,"' !!"
560            Lst = len(st)
561            LvarName = len(varName)
562            varn = varName[0:LvarName - Lst]
563            ifst = True
564            break
565    if not ifst:
566        varn = varName
567
568    if varn[0:6] == 'varDIM': 
569# Variable from a dimension (all with 'varDIM' prefix)
570        Lvarn = len(varn)
571        varvals = [varn[6:Lvarn+1], varn[6:Lvarn+1], 0., 1.,                         \
572          "variable|from|size|of|dimension|'" + varn[6:Lvarn+1] + "'", '1', 'rainbox']
573    elif varn == 'a_tht' or varn == 'LA_THT':
574        varvals = ['ath', 'total_thermal_plume_cover', 0., 1.,                       \
575        'total|column|thermal|plume|cover', '1', 'YlGnBu']
576    elif varn == 'acprc' or varn == 'RAINC':
577        varvals = ['acprc', 'accumulated_cmulus_precipitation', 0., 3.e4,            \
578          'accumulated|cmulus|precipitation', 'mm', 'Blues']
579    elif varn == 'acprnc' or varn == 'RAINNC':
580        varvals = ['acprnc', 'accumulated_non-cmulus_precipitation', 0., 3.e4,       \
581          'accumulated|non-cmulus|precipitation', 'mm', 'Blues']
582    elif varn == 'bils' or varn == 'LBILS':
583        varvals = ['bils', 'surface_total_heat_flux', -100., 100.,                   \
584          'surface|total|heat|flux', 'Wm-2', 'seismic']
585    elif varn == 'landcat' or varn == 'category':
586        varvals = ['landcat', 'land_categories', 0., 22., 'land|categories', '1',    \
587          'rainbow']
588    elif varn == 'c' or varn == 'QCLOUD' or varn == 'oliq' or varn == 'OLIQ':
589        varvals = ['c', 'condensed_water_mixing_ratio', 0., 3.e-4,                   \
590          'condensed|water|mixing|ratio', 'kgkg-1', 'BuPu']
591    elif varn == 'ci' or varn == 'iwcon' or varn == 'LIWCON':
592        varvals = ['ci', 'cloud_iced_water_mixing_ratio', 0., 0.0003,                \
593         'cloud|iced|water|mixing|ratio', 'kgkg-1', 'Purples']
594    elif varn == 'cl' or varn == 'lwcon' or varn == 'LLWCON':
595        varvals = ['cl', 'cloud_liquidwater_mixing_ratio', 0., 0.0003,               \
596         'cloud|liquid|water|mixing|ratio', 'kgkg-1', 'Blues']
597    elif varn == 'cld' or varn == 'CLDFRA' or varn == 'rneb' or varn == 'lrneb' or   \
598      varn == 'LRNEB':
599        varvals = ['cld', 'cloud_area_fraction', 0., 1., 'cloud|fraction', '1',      \
600          'gist_gray']
601    elif varn == 'cldc' or varn == 'rnebcon' or varn == 'lrnebcon' or                \
602      varn == 'LRNEBCON':
603        varvals = ['cldc', 'convective_cloud_area_fraction', 0., 1.,                 \
604          'convective|cloud|fraction', '1', 'gist_gray']
605    elif varn == 'cldl' or varn == 'rnebls' or varn == 'lrnebls' or varn == 'LRNEBLS':
606        varvals = ['cldl', 'large_scale_cloud_area_fraction', 0., 1.,                \
607          'large|scale|cloud|fraction', '1', 'gist_gray']
608    elif varn == 'clt' or varn == 'CLT' or varn == 'cldt' or                         \
609      varn == 'Total cloudiness':
610        varvals = ['clt', 'cloud_area_fraction', 0., 1., 'total|cloud|cover', '1',   \
611          'gist_gray']
612    elif varn == 'cll' or varn == 'cldl' or varn == 'LCLDL' or                       \
613      varn == 'Low-level cloudiness':
614        varvals = ['cll', 'low_level_cloud_area_fraction', 0., 1.,                   \
615          'low|level|(p|>|680|hPa)|cloud|fraction', '1', 'gist_gray']
616    elif varn == 'clm' or varn == 'cldm' or varn == 'LCLDM' or                       \
617      varn == 'Mid-level cloudiness':
618        varvals = ['clm', 'mid_level_cloud_area_fraction', 0., 1.,                   \
619          'medium|level|(440|<|p|<|680|hPa)|cloud|fraction', '1', 'gist_gray']
620    elif varn == 'clh' or varn == 'cldh' or varn == 'LCLDH' or                       \
621      varn == 'High-level cloudiness':
622        varvals = ['clh', 'high_level_cloud_area_fraction', 0., 1.,                  \
623          'high|level|(p|<|440|hPa)|cloud|fraction', '1', 'gist_gray']
624    elif varn == 'clmf' or varn == 'fbase' or varn == 'LFBASE':
625        varvals = ['clmf', 'cloud_base_max_flux', -0.3, 0.3, 'cloud|base|max|flux',  \
626          'kgm-2s-1', 'seismic']
627    elif varn == 'clp' or varn == 'pbase' or varn == 'LPBASE':
628        varvals = ['clp', 'cloud_base_pressure', -0.3, 0.3, 'cloud|base|pressure',   \
629          'Pa', 'Reds']
630    elif varn == 'cpt' or varn == 'ptconv' or varn == 'LPTCONV':
631        varvals = ['cpt', 'convective_point', 0., 1., 'convective|point', '1',       \
632          'seismic']
633    elif varn == 'dqajs' or varn == 'LDQAJS':
634        varvals = ['dqajs', 'dry_adjustment_water_vapor_tendency', -0.0003, 0.0003,  \
635        'dry|adjustment|water|vapor|tendency', 'kg/kg/s', 'seismic']
636    elif varn == 'dqcon' or varn == 'LDQCON':
637        varvals = ['dqcon', 'convective_water_vapor_tendency', -3e-8, 3.e-8,         \
638        'convective|water|vapor|tendency', 'kg/kg/s', 'seismic']
639    elif varn == 'dqdyn' or varn == 'LDQDYN':
640        varvals = ['dqdyn', 'dynamics_water_vapor_tendency', -3.e-7, 3.e-7,          \
641        'dynamics|water|vapor|tendency', 'kg/kg/s', 'seismic']
642    elif varn == 'dqeva' or varn == 'LDQEVA':
643        varvals = ['dqeva', 'evaporation_water_vapor_tendency', -3.e-6, 3.e-6,       \
644        'evaporation|water|vapor|tendency', 'kg/kg/s', 'seismic']
645    elif varn == 'dqlscst' or varn == 'LDQLSCST':
646        varvals = ['dqlscst', 'stratocumulus_water_vapor_tendency', -3.e-7, 3.e-7,   \
647        'stratocumulus|water|vapor|tendency', 'kg/kg/s', 'seismic']
648    elif varn == 'dqlscth' or varn == 'LDQLSCTH': 
649        varvals = ['dqlscth', 'thermals_water_vapor_tendency', -3.e-7, 3.e-7,        \
650        'thermal|plumes|water|vapor|tendency', 'kg/kg/s', 'seismic']
651    elif varn == 'dqlsc' or varn == 'LDQLSC':
652        varvals = ['dqlsc', 'condensation_water_vapor_tendency', -3.e-6, 3.e-6,      \
653        'condensation|water|vapor|tendency', 'kg/kg/s', 'seismic']
654    elif varn == 'dqphy' or varn == 'LDQPHY':
655        varvals = ['dqphy', 'physics_water_vapor_tendency', -3.e-7, 3.e-7,           \
656        'physics|water|vapor|tendency', 'kg/kg/s', 'seismic']
657    elif varn == 'dqthe' or varn == 'LDQTHE':
658        varvals = ['dqthe', 'thermals_water_vapor_tendency', -3.e-7, 3.e-7,          \
659        'thermal|plumes|water|vapor|tendency', 'kg/kg/s', 'seismic']
660    elif varn == 'dqvdf' or varn == 'LDQVDF':
661        varvals = ['dqvdf', 'vertical_difussion_water_vapor_tendency', -3.e-8, 3.e-8,\
662        'vertical|difussion|water|vapor|tendency', 'kg/kg/s', 'seismic']
663    elif varn == 'dqwak' or varn == 'LDQWAK':
664        varvals = ['dqwak', 'wake_water_vapor_tendency', -3.e-7, 3.e-7,              \
665        'wake|water|vapor|tendency', 'kg/kg/s', 'seismic']
666    elif varn == 'dta' or varn == 'tnt' or varn == 'LTNT':
667        varvals = ['dta', 'tendency_air_temperature', -3.e-3, 3.e-3,                 \
668        'tendency|of|air|temperature', 'K/s', 'seismic']
669    elif varn == 'dtac' or varn == 'tntc' or varn == 'LTNTC':
670        varvals = ['dtac', 'moist_convection_tendency_air_temperature', -3.e-3,      \
671        3.e-3, 'moist|convection|tendency|of|air|temperature', 'K/s', 'seismic']
672    elif varn == 'dtar' or varn == 'tntr' or varn == 'LTNTR':
673        varvals = ['dtar', 'radiative_heating_tendency_air_temperature', -3.e-3,     \
674          3.e-3, 'radiative|heating|tendency|of|air|temperature', 'K/s', 'seismic']
675    elif varn == 'dtascpbl' or varn == 'tntscpbl' or varn == 'LTNTSCPBL':
676        varvals = ['dtascpbl',                                                       \
677          'stratiform_cloud_precipitation_BL_mixing_tendency_air_temperature',       \
678          -3.e-6, 3.e-6,                                                             \
679          'stratiform|cloud|precipitation|Boundary|Layer|mixing|tendency|air|'       +
680          'temperature', 'K/s', 'seismic']
681    elif varn == 'dtajs' or varn == 'LDTAJS':
682        varvals = ['dtajs', 'dry_adjustment_thermal_tendency', -3.e-5, 3.e-5,        \
683        'dry|adjustment|thermal|tendency', 'K/s', 'seismic']
684    elif varn == 'dtcon' or varn == 'LDTCON':
685        varvals = ['dtcon', 'convective_thermal_tendency', -3.e-5, 3.e-5,            \
686        'convective|thermal|tendency', 'K/s', 'seismic']
687    elif varn == 'dtdyn' or varn == 'LDTDYN':
688        varvals = ['dtdyn', 'dynamics_thermal_tendency', -3.e-4, 3.e-4,              \
689        'dynamics|thermal|tendency', 'K/s', 'seismic']
690    elif varn == 'dteva' or varn == 'LDTEVA':
691        varvals = ['dteva', 'evaporation_thermal_tendency', -3.e-3, 3.e-3,           \
692        'evaporation|thermal|tendency', 'K/s', 'seismic']
693    elif varn == 'dtlscst' or varn == 'LDTLSCST':
694        varvals = ['dtlscst', 'stratocumulus_thermal_tendency', -3.e-4, 3.e-4,       \
695        'stratocumulus|thermal|tendency', 'K/s', 'seismic']
696    elif varn == 'dtlscth' or varn == 'LDTLSCTH':
697        varvals = ['dtlscth', 'thermals_thermal_tendency', -3.e-4, 3.e-4,            \
698        'thermal|plumes|thermal|tendency', 'K/s', 'seismic']
699    elif varn == 'dtlsc' or varn == 'LDTLSC':
700        varvals = ['dtlsc', 'condensation_thermal_tendency', -3.e-3, 3.e-3,          \
701        'condensation|thermal|tendency', 'K/s', 'seismic']
702    elif varn == 'dtlwr' or varn == 'LDTLWR':
703        varvals = ['dtlwr', 'long_wave_thermal_tendency', -3.e-3, 3.e-3, \
704        'long|wave|radiation|thermal|tendency', 'K/s', 'seismic']
705    elif varn == 'dtphy' or varn == 'LDTPHY':
706        varvals = ['dtphy', 'physics_thermal_tendency', -3.e-4, 3.e-4,               \
707        'physics|thermal|tendency', 'K/s', 'seismic']
708    elif varn == 'dtsw0' or varn == 'LDTSW0':
709        varvals = ['dtsw0', 'cloudy_sky_short_wave_thermal_tendency', -3.e-4, 3.e-4, \
710        'cloudy|sky|short|wave|radiation|thermal|tendency', 'K/s', 'seismic']
711    elif varn == 'dtthe' or varn == 'LDTTHE':
712        varvals = ['dtthe', 'thermals_thermal_tendency', -3.e-4, 3.e-4,              \
713        'thermal|plumes|thermal|tendency', 'K/s', 'seismic']
714    elif varn == 'dtvdf' or varn == 'LDTVDF':
715        varvals = ['dtvdf', 'vertical_difussion_thermal_tendency', -3.e-5, 3.e-5,    \
716        'vertical|difussion|thermal|tendency', 'K/s', 'seismic']
717    elif varn == 'dtwak' or varn == 'LDTWAK':
718        varvals = ['dtwak', 'wake_thermal_tendency', -3.e-4, 3.e-4,                  \
719        'wake|thermal|tendency', 'K/s', 'seismic']
720    elif varn == 'ducon' or varn == 'LDUCON':
721        varvals = ['ducon', 'convective_eastward_wind_tendency', -3.e-3, 3.e-3,      \
722        'convective|eastward|wind|tendency', 'ms-2', 'seismic']
723    elif varn == 'dudyn' or varn == 'LDUDYN':
724        varvals = ['dudyn', 'dynamics_eastward_wind_tendency', -3.e-3, 3.e-3,        \
725        'dynamics|eastward|wind|tendency', 'ms-2', 'seismic']
726    elif varn == 'duvdf' or varn == 'LDUVDF':
727        varvals = ['duvdf', 'vertical_difussion_eastward_wind_tendency', -3.e-3,     \
728         3.e-3, 'vertical|difussion|eastward|wind|tendency', 'ms-2', 'seismic']
729    elif varn == 'dvcon' or varn == 'LDVCON':
730        varvals = ['dvcon', 'convective_difussion_northward_wind_tendency', -3.e-3,  \
731         3.e-3, 'convective|northward|wind|tendency', 'ms-2', 'seismic']
732    elif varn == 'dvdyn' or varn == 'LDVDYN':
733        varvals = ['dvdyn', 'dynamics_northward_wind_tendency', -3.e-3,              \
734         3.e-3, 'dynamics|difussion|northward|wind|tendency', 'ms-2', 'seismic']
735    elif varn == 'dvvdf' or varn == 'LDVVDF':
736        varvals = ['dvvdf', 'vertical_difussion_northward_wind_tendency', -3.e-3,    \
737         3.e-3, 'vertical|difussion|northward|wind|tendency', 'ms-2', 'seismic']
738    elif varn == 'etau' or varn == 'ZNU':
739        varvals = ['etau', 'etau', 0., 1, 'eta values on half (mass) levels', '-',   \
740        'reds']
741    elif varn == 'evspsbl' or varn == 'LEVAP' or varn == 'evap' or varn == 'SFCEVPde':
742        varvals = ['evspsbl', 'water_evaporation_flux', 0., 1.5e-4,                  \
743          'water|evaporation|flux', 'kgm-2s-1', 'Blues']
744    elif varn == 'evspsbl' or varn == 'SFCEVPde':
745        varvals = ['evspsblac', 'water_evaporation_flux_ac', 0., 1.5e-4,             \
746          'accumulated|water|evaporation|flux', 'kgm-2', 'Blues']
747    elif varn == 'g' or varn == 'QGRAUPEL':
748        varvals = ['g', 'grauepl_mixing_ratio', 0., 0.0003, 'graupel|mixing|ratio',  \
749          'kgkg-1', 'Purples']
750    elif varn == 'h2o' or varn == 'LH2O':
751        varvals = ['h2o', 'water_mass_fraction', 0., 3.e-2,                          \
752          'mass|fraction|of|water', '1', 'Blues']
753    elif varn == 'h' or varn == 'QHAIL':
754        varvals = ['h', 'hail_mixing_ratio', 0., 0.0003, 'hail|mixing|ratio',        \
755          'kgkg-1', 'Purples']
756    elif varn == 'hfls' or varn == 'LH' or varn == 'LFLAT' or varn == 'flat':
757        varvals = ['hfls', 'surface_upward_latent_heat_flux', -400., 400.,           \
758          'upward|latnt|heat|flux|at|the|surface', 'Wm-2', 'seismic']
759    elif varn == 'hfss' or varn == 'LSENS' or varn == 'sens':
760        varvals = ['hfss', 'surface_upward_sensible_heat_flux', -150., 150.,         \
761          'upward|sensible|heat|flux|at|the|surface', 'Wm-2', 'seismic']
762    elif varn == 'hus' or varn == 'WRFrh' or varn == 'LMDZrh' or varn == 'rhum' or   \
763      varn == 'LRHUM':
764        varvals = ['hus', 'specific_humidity', 0., 1., 'specific|humidty', '1',      \
765          'BuPu']
766    elif varn == 'huss' or varn == 'WRFrhs' or varn == 'LMDZrhs' or varn == 'rh2m' or\
767      varn == 'LRH2M':
768        varvals = ['huss', 'specific_humidity', 0., 1., 'specific|humidty|at|2m',    \
769          '1', 'BuPu']
770    elif varn == 'i' or varn == 'QICE':
771        varvals = ['i', 'iced_water_mixing_ratio', 0., 0.0003,                       \
772         'iced|water|mixing|ratio', 'kgkg-1', 'Purples']
773    elif varn == 'lat' or varn == 'XLAT' or varn == 'XLAT_M' or varn == 'latitude':
774        varvals = ['lat', 'latitude', -90., 90., 'latitude', 'degrees North',        \
775          'seismic']
776    elif varn == 'lcl' or varn == 's_lcl' or varn == 'ls_lcl' or varn == 'LS_LCL':
777        varvals = ['lcl', 'condensation_level', 0., 2500., 'level|of|condensation',  \
778          'm', 'Greens']
779    elif varn == 'lambdath' or varn == 'lambda_th' or varn == 'LLAMBDA_TH':
780        varvals = ['lambdath', 'thermal_plume_vertical_velocity', -30., 30.,         \
781          'thermal|plume|vertical|velocity', 'm/s', 'seismic']
782    elif varn == 'lmaxth' or varn == 'LLMAXTH':
783        varvals = ['lmaxth', 'upper_level_thermals', 0., 100., 'upper|level|thermals'\
784          , '1', 'Greens']
785    elif varn == 'lon' or varn == 'XLONG' or varn == 'XLONG_M':
786        varvals = ['lon', 'longitude', -180., 180., 'longitude', 'degrees East',     \
787          'seismic']
788    elif varn == 'longitude':
789        varvals = ['lon', 'longitude', 0., 360., 'longitude', 'degrees East',        \
790          'seismic']
791    elif varn == 'orog' or varn == 'HGT' or varn == 'HGT_M':
792        varvals = ['orog', 'orography',  0., 3000., 'surface|altitude', 'm','terrain']
793    elif varn == 'pfc' or varn == 'plfc' or varn == 'LPLFC':
794        varvals = ['pfc', 'pressure_free_convection', 100., 1100.,                   \
795          'pressure|free|convection', 'hPa', 'BuPu']
796    elif varn == 'plcl' or varn == 'LPLCL':
797        varvals = ['plcl', 'pressure_lifting_condensation_level', 700., 1100.,       \
798          'pressure|lifting|condensation|level', 'hPa', 'BuPu']
799    elif varn == 'pr' or varn == 'RAINTOT' or varn == 'precip' or                    \
800      varn == 'LPRECIP' or varn == 'Precip Totale liq+sol':
801        varvals = ['pr', 'precipitation_flux', 0., 1.e-4, 'precipitation|flux',      \
802          'kgm-2s-1', 'BuPu']
803    elif varn == 'prprof' or varn == 'vprecip' or varn == 'LVPRECIP':
804        varvals = ['prprof', 'precipitation_profile', 0., 1.e-3,                     \
805          'precipitation|profile', 'kg/m2/s', 'BuPu']
806    elif varn == 'prprofci' or varn == 'pr_con_i' or varn == 'LPR_CON_I':
807        varvals = ['prprofci', 'precipitation_profile_convective_i', 0., 1.e-3,      \
808          'precipitation|profile|convective|i', 'kg/m2/s', 'BuPu']
809    elif varn == 'prprofcl' or varn == 'pr_con_l' or varn == 'LPR_CON_L':
810        varvals = ['prprofcl', 'precipitation_profile_convective_l', 0., 1.e-3,      \
811          'precipitation|profile|convective|l', 'kg/m2/s', 'BuPu']
812    elif varn == 'prprofli' or varn == 'pr_lsc_i' or varn == 'LPR_LSC_I':
813        varvals = ['prprofli', 'precipitation_profile_large_scale_i', 0., 1.e-3,     \
814          'precipitation|profile|large|scale|i', 'kg/m2/s', 'BuPu']
815    elif varn == 'prprofll' or varn == 'pr_lsc_l' or varn == 'LPR_LSC_L':
816        varvals = ['prprofll', 'precipitation_profile_large_scale_l', 0., 1.e-3,     \
817          'precipitation|profile|large|scale|l', 'kg/m2/s', 'BuPu']
818    elif varn == 'pracc' or varn == 'ACRAINTOT':
819        varvals = ['pracc', 'precipitation_amount', 0., 100.,                        \
820          'accumulated|precipitation', 'kgm-2', 'BuPu']
821    elif varn == 'prc' or varn == 'LPLUC' or varn == 'pluc' or varn == 'WRFprc' or   \
822      varn == 'RAINCde':
823        varvals = ['prc', 'convective_precipitation_flux', 0., 2.e-4,                \
824          'convective|precipitation|flux', 'kgm-2s-1', 'Blues']
825    elif varn == 'prci' or varn == 'pr_con_i' or varn == 'LPR_CON_I':
826        varvals = ['prci', 'convective_ice_precipitation_flux', 0., 0.003,           \
827          'convective|ice|precipitation|flux', 'kgm-2s-1', 'Purples']
828    elif varn == 'prcl' or varn == 'pr_con_l' or varn == 'LPR_CON_L':
829        varvals = ['prcl', 'convective_liquid_precipitation_flux', 0., 0.003,        \
830          'convective|liquid|precipitation|flux', 'kgm-2s-1', 'Blues']
831    elif varn == 'pres' or varn == 'presnivs' or varn == 'pressure' or               \
832      varn == 'lpres' or varn == 'LPRES':
833        varvals = ['pres', 'air_pressure', 0., 103000., 'air|pressure', 'Pa',        \
834          'Blues']
835    elif varn == 'prls' or varn == 'WRFprls' or varn == 'LPLUL' or varn == 'plul' or \
836       varn == 'RAINNCde':
837        varvals = ['prls', 'large_scale_precipitation_flux', 0., 2.e-4,              \
838          'large|scale|precipitation|flux', 'kgm-2s-1', 'Blues']
839    elif varn == 'prsn' or varn == 'SNOW' or varn == 'snow' or varn == 'LSNOW':
840        varvals = ['prsn', 'snowfall', 0., 1.e-4, 'snowfall|flux', 'kgm-2s-1', 'BuPu']
841    elif varn == 'prw' or varn == 'WRFprh':
842        varvals = ['prw', 'atmosphere_water_vapor_content', 0., 10.,                 \
843          'water|vapor"path', 'kgm-2', 'Blues']
844    elif varn == 'ps' or varn == 'psfc' or varn =='PSFC' or varn == 'psol' or        \
845      varn == 'Surface Pressure':
846        varvals=['ps', 'surface_air_pressure', 85000., 105400., 'surface|pressure',  \
847          'hPa', 'cool']
848    elif varn == 'psl' or varn == 'mslp' or varn =='WRFmslp':
849        varvals=['psl', 'air_pressure_at_sea_level', 85000., 104000.,                \
850          'mean|sea|level|pressure', 'Pa', 'Greens']
851    elif varn == 'qth' or varn == 'q_th' or varn == 'LQ_TH':
852        varvals = ['qth', 'thermal_plume_total_water_content', 0., 25.,              \
853          'total|water|cotent|in|thermal|plume', 'mm', 'YlOrRd']
854    elif varn == 'r' or varn == 'QVAPOR' or varn == 'ovap' or varn == 'LOVAP':
855        varvals = ['r', 'water_mixing_ratio', 0., 0.03, 'water|mixing|ratio',        \
856          'kgkg-1', 'BuPu']
857    elif varn == 'r2' or varn == 'Q2':
858        varvals = ['r2', 'water_mixing_ratio_at_2m', 0., 0.03, 'water|mixing|' +     \
859          'ratio|at|2|m','kgkg-1', 'BuPu']
860    elif varn == 'rsds' or varn == 'SWdnSFC' or varn == 'SWdn at surface' or         \
861      varn == 'SWDOWN':
862        varvals=['rsds', 'surface_downwelling_shortwave_flux_in_air',  0., 1200.,    \
863          'downward|SW|surface|radiation', 'Wm-2' ,'Reds']
864    elif varn == 'rsdsacc':
865        varvals=['rsdsacc', 'accumulated_surface_downwelling_shortwave_flux_in_air', \
866          0., 1200., 'accumulated|downward|SW|surface|radiation', 'Wm-2' ,'Reds']
867    elif varn == 'rvor' or varn == 'WRFrvor':
868        varvals = ['rvor', 'air_relative_vorticity', -2.5E-3, 2.5E-3,                \
869          'air|relative|vorticity', 's-1', 'seismic']
870    elif varn == 'rvors' or varn == 'WRFrvors':
871        varvals = ['rvors', 'surface_air_relative_vorticity', -2.5E-3, 2.5E-3,       \
872          'surface|air|relative|vorticity', 's-1', 'seismic']
873    elif varn == 's' or varn == 'QSNOW':
874        varvals = ['s', 'snow_mixing_ratio', 0., 0.0003, 'snow|mixing|ratio',        \
875          'kgkg-1', 'Purples']
876    elif varn == 'stherm' or varn == 'LS_THERM':
877        varvals = ['stherm', 'thermals_excess', 0., 0.8, 'thermals|excess', 'K',     \
878          'Reds']
879    elif varn == 'ta' or varn == 'WRFt' or varn == 'temp' or varn == 'LTEMP' or      \
880      varn == 'Air temperature':
881        varvals = ['ta', 'air_temperature', 195., 320., 'air|temperature', 'K',      \
882          'YlOrRd']
883    elif varn == 'tah' or varn == 'theta' or varn == 'LTHETA':
884        varvals = ['tah', 'potential_air_temperature', 195., 320.,                   \
885          'potential|air|temperature', 'K', 'YlOrRd']
886    elif varn == 'tas' or varn == 'T2' or varn == 't2m' or varn == 'T2M' or          \
887      varn == 'Temperature 2m':
888        varvals = ['tas', 'air_temperature', 240., 310., 'air|temperature|at|2m', \
889          K', 'YlOrRd']
890    elif varn == 'tds' or varn == 'TH2':
891        varvals = ['tds', 'air_dew_point_temperature', 240., 310.,                   \
892          'air|dew|point|temperature|at|2m', 'K', 'YlGnBu']
893    elif varn == 'tke' or varn == 'TKE' or varn == 'tke' or varn == 'LTKE':
894        varvals = ['tke', 'turbulent_kinetic_energy', 0., 0.003,                     \
895          'turbulent|kinetic|energy', 'm2/s2', 'Reds']
896    elif varn == 'time'or varn == 'time_counter':
897        varvals = ['time', 'time', 0., 1000., 'time',                                \
898          'hours|since|1949/12/01|00:00:00', 'Reds']
899    elif varn == 'tmla' or varn == 's_pblt' or varn == 'LS_PBLT':
900        varvals = ['tmla', 'atmosphere_top_boundary_layer_temperature', 250., 330.,  \
901          'atmosphere|top|boundary|layer|temperature', 'K', 'Reds']
902    elif varn == 'ua' or varn == 'vitu' or varn == 'U' or varn == 'Zonal wind' or    \
903      varn == 'LVITU':
904        varvals = ['ua', 'eastward_wind', -30., 30., 'eastward|wind', 'ms-1',        \
905          'seismic']
906    elif varn == 'uas' or varn == 'u10m' or varn == 'U10' or varn =='Vent zonal 10m':
907        varvals = ['uas', 'eastward_wind', -30., 30., 'eastward|2m|wind',    \
908          'ms-1', 'seismic']
909    elif varn == 'va' or varn == 'vitv' or varn == 'V' or varn == 'Meridional wind'  \
910      or varn == 'LVITV':
911        varvals = ['va', 'northward_wind', -30., 30., 'northward|wind', 'ms-1',      \
912          'seismic']
913    elif varn == 'vas' or varn == 'v10m' or varn == 'V10' or                         \
914      varn =='Vent meridien 10m':
915        varvals = ['vas', 'northward_wind', -30., 30., 'northward|2m|wind', 'ms-1',  \
916          'seismic']
917    elif varn == 'wakedeltaq' or varn == 'wake_deltaq' or varn == 'lwake_deltaq' or  \
918      varn == 'LWAKE_DELTAQ':
919        varvals = ['wakedeltaq', 'wake_delta_vapor', -0.003, 0.003,                  \
920          'wake|delta|mixing|ratio', '-', 'seismic']
921    elif varn == 'wakedeltat' or varn == 'wake_deltat' or varn == 'lwake_deltat' or  \
922      varn == 'LWAKE_DELTAT':
923        varvals = ['wakedeltat', 'wake_delta_temp', -0.003, 0.003,                   \
924          'wake|delta|temperature', '-', 'seismic']
925    elif varn == 'wakeh' or varn == 'wake_h' or varn == 'LWAKE_H':
926        varvals = ['wakeh', 'wake_height', 0., 1000., 'height|of|the|wakes', 'm',    \
927          'YlOrRd']
928    elif varn == 'wakeomg' or varn == 'wake_omg' or varn == 'lwake_omg' or           \
929      varn == 'LWAKE_OMG':
930        varvals = ['wakeomg', 'wake_omega', 0., 3., 'wake|omega', \
931          '-', 'BuGn']
932    elif varn == 'wakes' or varn == 'wake_s' or varn == 'LWAKE_S':
933        varvals = ['wakes', 'wake_area_fraction', 0., 0.5, 'wake|spatial|fraction',  \
934          '1', 'BuGn']
935    elif varn == 'wa' or varn == 'W' or varn == 'Vertical wind':
936        varvals = ['wa', 'upward_wind', -10., 10., 'upward|wind', 'ms-1',            \
937          'seismic']
938    elif varn == 'wap' or varn == 'vitw' or varn == 'LVITW':
939        varvals = ['wap', 'upward_wind', -3.e-10, 3.e-10, 'upward|wind', 'mPa-1',    \
940          'seismic']
941    elif varn == 'wss' or varn == 'SPDUV':
942        varvals = ['wss', 'air_velocity',  0., 30., 'surface|horizontal|wind|speed', \
943          'ms-1', 'Reds']
944# Water budget
945# Water budget de-accumulated
946    elif varn == 'ccond' or varn == 'CCOND' or varn == 'ACCCONDde':
947        varvals = ['ccond', 'cw_cond',  0., 30.,                                     \
948          'cloud|water|condensation', 'mm', 'Reds']
949    elif varn == 'wbr' or varn == 'ACQVAPORde':
950        varvals = ['wbr', 'wbr',  0., 30., 'Water|Budget|water|wapor', 'mm', 'Blues']
951    elif varn == 'diabh' or varn == 'DIABH' or varn == 'ACDIABHde':
952        varvals = ['diabh', 'diabh',  0., 30., 'diabatic|heating', 'K', 'Reds']
953    elif varn == 'wbpw' or varn == 'WBPW' or varn == 'WBACPWde':
954        varvals = ['wbpw', 'water_budget_pw',  0., 30., 'Water|Budget|water|content',\
955           'mms-1', 'Reds']
956    elif varn == 'wbf' or varn == 'WBACF' or varn == 'WBACFde':
957        varvals = ['wbf', 'water_budget_hfcqv',  0., 30.,                       \
958          'Water|Budget|horizontal|convergence|of|water|vapour|(+,|' +   \
959          'conv.;|-,|div.)', 'mms-1', 'Reds']
960    elif varn == 'wbfc' or varn == 'WBFC' or varn == 'WBACFCde':
961        varvals = ['wbfc', 'water_budget_fc',  0., 30.,                         \
962          'Water|Budget|horizontal|convergence|of|cloud|(+,|conv.;|-,|' +\
963          'div.)', 'mms-1', 'Reds']
964    elif varn == 'wbfp' or varn == 'WBFP' or varn == 'WBACFPde':
965        varvals = ['wbfp', 'water_budget_cfp',  0., 30.,                        \
966          'Water|Budget|horizontal|convergence|of|precipitation|(+,|' +  \
967          'conv.;|-,|div.)', 'mms-1', 'Reds']
968    elif varn == 'wbz' or varn == 'WBZ' or varn == 'WBACZde':
969        varvals = ['wbz', 'water_budget_z',  0., 30.,                           \
970          'Water|Budget|vertical|convergence|of|water|vapour|(+,|conv.' +\
971          ';|-,|div.)', 'mms-1', 'Reds']
972    elif varn == 'wbc' or varn == 'WBC' or varn == 'WBACCde':
973        varvals = ['wbc', 'water_budget_c',  0., 30.,                           \
974          'Water|Budget|Cloud|water|species','mms-1', 'Reds']
975    elif varn == 'wbqvd' or varn == 'WBQVD' or varn == 'WBACQVDde':
976        varvals = ['wbqvd', 'water_budget_qvd',  0., 30.,                       \
977          'Water|Budget|water|vapour|divergence', 'mms-1', 'Reds']
978    elif varn == 'wbqvblten' or varn == 'WBQVBLTEN' or varn == 'WBACQVBLTENde':
979        varvals = ['wbqvblten', 'water_budget_qv_blten',  0., 30.,              \
980          'Water|Budget|QV|tendency|due|to|pbl|parameterization',        \
981          'kg kg-1 s-1', 'Reds']
982    elif varn == 'wbqvcuten' or varn == 'WBQVCUTEN' or varn == 'WBACQVCUTENde':
983        varvals = ['wbqvcuten', 'water_budget_qv_cuten',  0., 30.,              \
984          'Water|Budget|QV|tendency|due|to|cu|parameterization',         \
985          'kg kg-1 s-1', 'Reds']
986    elif varn == 'wbqvshten' or varn == 'WBQVSHTEN' or varn == 'WBACQVSHTENde':
987        varvals = ['wbqvshten', 'water_budget_qv_shten',  0., 30.,              \
988          'Water|Budget|QV|tendency|due|to|shallow|cu|parameterization', \
989          'kg kg-1 s-1', 'Reds']
990    elif varn == 'wbpr' or varn == 'WBP' or varn == 'WBACPde':
991        varvals = ['wbpr', 'water_budget_pr',  0., 30.,                         \
992          'Water|Budget|recipitation', 'mms-1', 'Reds']
993    elif varn == 'wbpw' or varn == 'WBPW' or varn == 'WBACPWde':
994        varvals = ['wbpw', 'water_budget_pw',  0., 30.,                         \
995          'Water|Budget|water|content', 'mms-1', 'Reds']
996    elif varn == 'wbcondt' or varn == 'WBCONDT' or varn == 'WBACCONDTde':
997        varvals = ['wbcondt', 'water_budget_condt',  0., 30.,                   \
998          'Water|Budget|condensation|and|deposition', 'mms-1', 'Reds']
999    elif varn == 'wbqcm' or varn == 'WBQCM' or varn == 'WBACQCMde':
1000        varvals = ['wbqcm', 'water_budget_qcm',  0., 30.,                       \
1001          'Water|Budget|hydrometeor|change|and|convergence', 'mms-1', 'Reds']
1002    elif varn == 'wbsi' or varn == 'WBSI' or varn == 'WBACSIde':
1003        varvals = ['wbsi', 'water_budget_si',  0., 30.,                         \
1004          'Water|Budget|hydrometeor|sink', 'mms-1', 'Reds']
1005    elif varn == 'wbso' or varn == 'WBSO' or varn == 'WBACSOde':
1006        varvals = ['wbso', 'water_budget_so',  0., 30.,                         \
1007          'Water|Budget|hydrometeor|source', 'mms-1', 'Reds']
1008# Water Budget accumulated
1009    elif varn == 'ccondac' or varn == 'ACCCOND':
1010        varvals = ['ccondac', 'cw_cond_ac',  0., 30.,                                \
1011          'accumulated|cloud|water|condensation', 'mm', 'Reds']
1012    elif varn == 'rac' or varn == 'ACQVAPOR':
1013        varvals = ['rac', 'ac_r',  0., 30., 'accumualted|water|wapor', 'mm', 'Blues']
1014    elif varn == 'diabhac' or varn == 'ACDIABH':
1015        varvals = ['diabhac', 'diabh_ac',  0., 30., 'accumualted|diabatic|heating',  \
1016          'K', 'Reds']
1017    elif varn == 'wbpwac' or varn == 'WBACPW':
1018        varvals = ['wbpwac', 'water_budget_pw_ac',  0., 30.,                         \
1019          'Water|Budget|accumulated|water|content', 'mm', 'Reds']
1020    elif varn == 'wbfac' or varn == 'WBACF':
1021        varvals = ['wbfac', 'water_budget_hfcqv_ac',  0., 30.,                       \
1022          'Water|Budget|accumulated|horizontal|convergence|of|water|vapour|(+,|' +   \
1023          'conv.;|-,|div.)', 'mm', 'Reds']
1024    elif varn == 'wbfcac' or varn == 'WBACFC':
1025        varvals = ['wbfcac', 'water_budget_fc_ac',  0., 30.,                         \
1026          'Water|Budget|accumulated|horizontal|convergence|of|cloud|(+,|conv.;|-,|' +\
1027          'div.)', 'mm', 'Reds']
1028    elif varn == 'wbfpac' or varn == 'WBACFP':
1029        varvals = ['wbfpac', 'water_budget_cfp_ac',  0., 30.,                        \
1030          'Water|Budget|accumulated|horizontal|convergence|of|precipitation|(+,|' +  \
1031          'conv.;|-,|div.)', 'mm', 'Reds']
1032    elif varn == 'wbzac' or varn == 'WBACZ':
1033        varvals = ['wbzac', 'water_budget_z_ac',  0., 30.,                           \
1034          'Water|Budget|accumulated|vertical|convergence|of|water|vapour|(+,|conv.' +\
1035          ';|-,|div.)', 'mm', 'Reds']
1036    elif varn == 'wbcac' or varn == 'WBACC':
1037        varvals = ['wbcac', 'water_budget_c_ac',  0., 30.,                           \
1038          'Water|Budget|accumulated|Cloud|water|species','mm', 'Reds']
1039    elif varn == 'wbqvdac' or varn == 'WBACQVD':
1040        varvals = ['wbqvdac', 'water_budget_qvd_ac',  0., 30.,                       \
1041          'Water|Budget|accumulated|water|vapour|divergence', 'mm', 'Reds']
1042    elif varn == 'wbqvbltenac' or varn == 'WBACQVBLTEN':
1043        varvals = ['wbqvbltenac', 'water_budget_qv_blten_ac',  0., 30.,              \
1044          'Water|Budget|accumulated|QV|tendency|due|to|pbl|parameterization',        \
1045          'kg kg-1 s-1', 'Reds']
1046    elif varn == 'wbqvcutenac' or varn == 'WBACQVCUTEN':
1047        varvals = ['wbqvcutenac', 'water_budget_qv_cuten_ac',  0., 30.,              \
1048          'Water|Budget|accumulated|QV|tendency|due|to|cu|parameterization',         \
1049          'kg kg-1 s-1', 'Reds']
1050    elif varn == 'wbqvshtenac' or varn == 'WBACQVSHTEN':
1051        varvals = ['wbqvshtenac', 'water_budget_qv_shten_ac',  0., 30.,              \
1052          'Water|Budget|accumulated|QV|tendency|due|to|shallow|cu|parameterization', \
1053          'kg kg-1 s-1', 'Reds']
1054    elif varn == 'wbprac' or varn == 'WBACP':
1055        varvals = ['wbprac', 'water_budget_pr_ac',  0., 30.,                         \
1056          'Water|Budget|accumulated|precipitation', 'mm', 'Reds']
1057    elif varn == 'wbpwac' or varn == 'WBACPW':
1058        varvals = ['wbpwac', 'water_budget_pw_ac',  0., 30.,                         \
1059          'Water|Budget|accumulated|water|content', 'mm', 'Reds']
1060    elif varn == 'wbcondtac' or varn == 'WBACCONDT':
1061        varvals = ['wbcondtac', 'water_budget_condt_ac',  0., 30.,                   \
1062          'Water|Budget|accumulated|condensation|and|deposition', 'mm', 'Reds']
1063    elif varn == 'wbqcmac' or varn == 'WBACQCM':
1064        varvals = ['wbqcmac', 'water_budget_qcm_ac',  0., 30.,                       \
1065          'Water|Budget|accumulated|hydrometeor|change|and|convergence', 'mm', 'Reds']
1066    elif varn == 'wbsiac' or varn == 'WBACSI':
1067        varvals = ['wbsiac', 'water_budget_si_ac',  0., 30.,                         \
1068          'Water|Budget|accumulated|hydrometeor|sink', 'mm', 'Reds']
1069    elif varn == 'wbsoac' or varn == 'WBACSO':
1070        varvals = ['wbsoac', 'water_budget_so_ac',  0., 30.,                         \
1071          'Water|Budget|accumulated|hydrometeor|source', 'mm', 'Reds']
1072
1073    elif varn == 'xtime' or varn == 'XTIME':
1074        varvals = ['xtime', 'time',  0., 1.e5, 'time',                               \
1075          'minutes|since|simulation|start', 'Reds']
1076    elif varn == 'x' or varn == 'X':
1077        varvals = ['x', 'x',  0., 100., 'x', '-', 'Reds']
1078    elif varn == 'y' or varn == 'Y':
1079        varvals = ['y', 'y',  0., 100., 'y', '-', 'Blues']
1080    elif varn == 'z' or varn == 'Z':
1081        varvals = ['z', 'z',  0., 100., 'z', '-', 'Greens']
1082    elif varn == 'zg' or varn == 'WRFght' or varn == 'Geopotential height' or        \
1083      varn == 'geop' or varn == 'LGEOP':
1084        varvals = ['zg', 'geopotential_height', 0., 80000., 'geopotential|height',   \
1085          'm2s-2', 'rainbow']
1086    elif varn == 'zmaxth' or varn == 'zmax_th'  or varn == 'LZMAX_TH':
1087        varvals = ['zmaxth', 'thermal_plume_height', 0., 4000.,                     \
1088          'maximum|thermals|plume|height', 'm', 'YlOrRd']
1089    elif varn == 'zmla' or varn == 's_pblh' or varn == 'LS_PBLH':
1090        varvals = ['zmla', 'atmosphere_boundary_layer_thickness', 0., 2500.,         \
1091          'atmosphere|boundary|layer|thickness', 'm', 'Blues']
1092    else:
1093        print errormsg
1094        print '  ' + fname + ": variable '" + varn + "' not defined !!!"
1095        quit(-1)
1096
1097    return varvals
1098
1099def numVector_String(vec,char):
1100    """ Function to transform a vector of numbers to a single string [char] separated
1101    numVector_String(vec,char)
1102      vec= vector with the numerical values
1103      char= single character to split the values
1104    >>> print numVector_String(np.arange(10),' ')
1105    0 1 2 3 4 5 6 7 8 9
1106    """
1107    fname = 'numVector_String'
1108
1109#    if vec == 'h':
1110#        print fname + '_____________________________________________________________'
1111#        print numVector_String.__doc__
1112#        quit()
1113
1114    Nvals = len(vec)
1115
1116    string=''
1117    for i in range(Nvals):
1118        if i == 0:
1119            string = str(vec[i])
1120        else:
1121            string = string + char + str(vec[i])
1122
1123    return string
1124
1125def index_mat(mat,val):
1126    """ Function to provide the coordinates of a given value inside a matrix
1127    index_mat(mat,val)
1128      mat= matrix with values
1129      val= value to search
1130    >>> index_mat(np.arange(27).reshape(3,3,3),22)
1131    [2 1 1]
1132    """
1133
1134    fname = 'index_mat'
1135
1136    matshape = mat.shape
1137
1138    matlist = list(mat.flatten())
1139    ifound = matlist.index(val)
1140
1141    Ndims = len(matshape)
1142    valpos = np.zeros((Ndims), dtype=int)
1143    baseprevdims = np.zeros((Ndims), dtype=int)
1144
1145    for dimid in range(Ndims):
1146        baseprevdims[dimid] = np.product(matshape[dimid+1:Ndims])
1147        if dimid == 0:
1148            alreadyplaced = 0
1149        else:
1150            alreadyplaced = np.sum(baseprevdims[0:dimid]*valpos[0:dimid])
1151        valpos[dimid] = int((ifound - alreadyplaced )/ baseprevdims[dimid])
1152
1153    return valpos
1154
1155def multi_index_mat(mat,val):
1156    """ Function to provide the multiple coordinates of a given value inside a matrix
1157    index_mat(mat,val)
1158      mat= matrix with values
1159      val= value to search
1160    >>> vals = np.ones((24), dtype=np.float).reshape(2,3,4)
1161    vals[:,:,2] = 0.
1162    vals[1,:,:] = np.pi
1163    vals[:,2,:] = -1.
1164    multi_index_mat(vals,1.)
1165    [array([0, 0, 0]), array([0, 0, 1]), array([0, 0, 3]), array([0, 1, 0]), array([0, 1, 1]), array([0, 1, 3])]
1166    """
1167    fname = 'multi_index_mat'
1168
1169    matshape = mat.shape
1170
1171    ivalpos = []
1172    matlist = list(mat.flatten())
1173    Lmatlist = len(matlist)
1174   
1175    val0 = val - val
1176    if val != val0:
1177        valdiff = val0
1178    else:
1179        valdiff = np.ones((1), dtype = type(val))
1180   
1181    ifound = 0
1182    while ifound < Lmatlist:
1183        if matlist.count(val) == 0:
1184            ifound = Lmatlist + 1
1185        else:
1186            ifound = matlist.index(val)
1187
1188            Ndims = len(matshape)
1189            valpos = np.zeros((Ndims), dtype=int)
1190            baseprevdims = np.zeros((Ndims), dtype=int)
1191
1192            for dimid in range(Ndims):
1193                baseprevdims[dimid] = np.product(matshape[dimid+1:Ndims])
1194                if dimid == 0:
1195                    alreadyplaced = 0
1196                else:
1197                    alreadyplaced = np.sum(baseprevdims[0:dimid]*valpos[0:dimid])
1198                valpos[dimid] = int((ifound - alreadyplaced )/ baseprevdims[dimid])
1199            matlist[ifound] = valdiff
1200            ivalpos.append(valpos)
1201
1202    return ivalpos
1203
1204def addfileInfile(origfile,destfile,addfile,addsign):
1205    """ Function to add the content of a file [addfile] to another one [origfile] at
1206      a given position [addsign] creating a new file called [destfile]
1207      origfile= original file
1208      destfile= destination file
1209      addfile= content of the file to add
1210      addsign= sign where to add the file
1211    """
1212    fname = 'addfileInfile'
1213
1214    if not os.path.isfile(origfile):
1215        print errormsg
1216        print '  ' + fname + ": original file '" + origfile + "' does not exist !!"
1217        quit()
1218
1219    if not os.path.isfile(addfile):
1220        print errormsg
1221        print '  ' + fname + ": adding file '" + addfile + "' does not exist !!"
1222        quit()
1223   
1224    ofile = open(origfile, 'r')
1225
1226# Inspecting flag
1227##
1228    Nfound = 0
1229    for line in ofile:
1230        if line == addsign + '\n': Nfound = Nfound + 1
1231
1232    if Nfound == 0:
1233        print errormsg
1234        print '  ' + fname + ": adding sign '" + addsign + "' not found !!"
1235        quit()
1236    print '  '+ fname + ': found', Nfound," times sign '" + addsign + "' "
1237
1238    ofile.seek(0)
1239    dfile = open(destfile, 'w')
1240
1241    for line in ofile:
1242        if line != addsign + '\n':
1243            dfile.write(line)
1244        else:
1245            afile = open(addfile,'r')
1246            for aline in afile:
1247                print aline
1248                dfile.write(aline)
1249
1250            afile.close()
1251
1252    ofile.close()
1253    dfile.close()
1254
1255    print main + " successful writting of file '" + destfile + "' !!"
1256    return
1257
1258
1259####### ###### ##### #### ### ## #
1260
1261def valmodoper(varVal, valuesS):
1262    """ Function to run the modification of a variable
1263      varVAl= matrix with the values
1264      valuesS= [modins],[[modval1],...,[modvalN]] modification instruction, value with which modify
1265        [modins]: Modifiers:
1266          sumc: add [modval1]
1267          subc: remove [modval1]
1268          mulc: multiply by [modval1]
1269          divc: divide by [modval1]
1270          lowthres: if [val] < [modval1]; val = [modval2]
1271          upthres: if [val] > [modval1]; val = [modval2]
1272          lowthres@oper: if [val] < [modval1]; val = [oper] (operation as [modval2],[modval3])
1273          upthres@oper: if [val] > [modval1]; val = [oper] (operation as [modval2],[modval3])
1274          potc: [val] ** [modval1]
1275    """
1276    fname='valmodoper'
1277
1278    if valuesS == 'h':
1279        print fname + '_____________________________________________________________'
1280        print valmodoper.__doc__
1281        quit()
1282
1283    valsS = valuesS.split(',')
1284    modins = valsS[0]
1285    modval = float(valsS[1])
1286
1287    if modins == 'sumc':
1288        varVal[:] = varVal[:] + modval
1289    elif modins == 'subc':
1290        varVal[:] = varVal[:] - modval
1291    elif modins == 'mulc':
1292        varVal[:] = varVal[:] * modval
1293    elif modins == 'divc':
1294        varVal[:] = varVal[:] / modval
1295    elif modins == 'lowthres':
1296        varVal2 = np.where(varVal[:] < float(valsS[1]), float(valsS[2]), varVal[:])
1297        varVal[:] = varVal2
1298    elif modins == 'upthres':
1299        varVal2 = np.where(varVal[:] > float(valsS[1]), float(valsS[2]), varVal[:])
1300        varVal[:] = varVal2
1301    elif modins == 'lowthres@oper':
1302        if valsS[2] == 'sumc': 
1303           varVal2 = np.where(varVal[:] < float(valsS[1]),                           \
1304             varVal[:] + float(valsS[3]), varVal[:])
1305           varVal[:] = varVal2
1306        elif valsS[2] == 'subc': 
1307           varVal2 = np.where(varVal[:] < float(valsS[1]),                           \
1308             varVal[:] - float(valsS[3]), varVal[:])
1309           varVal[:] = varVal2
1310        elif valsS[2] == 'mulc': 
1311           varVal2 = np.where(varVal[:] < float(valsS[1]),                           \
1312             varVal[:] * float(valsS[3]), varVal[:])
1313           varVal[:] = varVal2
1314        elif valsS[2] == 'divc': 
1315           varVal2 = np.where(varVal[:] < float(valsS[1]),                           \
1316             varVal[:] / float(valsS[3]), varVal[:])
1317           varVal[:] = varVal2
1318        elif valsS[2] == 'potc': 
1319           varVal2 = np.where(varVal[:] < float(valsS[1]),                           \
1320             varVal[:] ** float(valsS[3]), varVal[:])
1321           varVal[:] = varVal2
1322        else:
1323            print errormsg
1324            print '  ' + fname + ": Operation to modify values '" + modins +         \
1325              "' is not defined !!"
1326            quit(-1)
1327    elif modins == 'upthres@oper':
1328        if valsS[2] == 'sumc': 
1329           varVal2 = np.where(varVal[:] > float(valsS[1]),                           \
1330             varVal[:] + float(valsS[3]), varVal[:])
1331           varVal[:] = varVal2
1332        elif valsS[2] == 'subc': 
1333           varVal2 = np.where(varVal[:] > float(valsS[1]),                           \
1334             varVal[:] - float(valsS[3]), varVal[:])
1335           varVal[:] = varVal2
1336        elif valsS[2] == 'mulc': 
1337           varVal2 = np.where(varVal[:] > float(valsS[1]),                           \
1338             varVal[:] * float(valsS[3]), varVal[:])
1339           varVal[:] = varVal2
1340        elif valsS[2] == 'divc': 
1341           varVal2 = np.where(varVal[:] > float(valsS[1]),                           \
1342             varVal[:] / float(valsS[3]), varVal[:])
1343           varVal[:] = varVal2
1344        elif valsS[2] == 'potc': 
1345           varVal2 = np.where(varVal[:] > float(valsS[1]),                           \
1346             varVal[:] ** float(valsS[3]), varVal[:])
1347           varVal[:] = varVal2
1348        else:
1349            print errormsg
1350            print '  ' + fname + ": Operation to modify values '" + modins +         \
1351              "' is not defined !!"
1352            quit(-1)
1353    elif modins == 'potc':
1354        varVal[:] = varVal[:] ** modval
1355    else: 
1356        print errormsg
1357        print '  ' + fname + ": Operation to modify values '" + modins +             \
1358          "' is not defined !!"
1359        quit(-1)
1360
1361    return varVal
1362
1363def rangedim(end, shape):
1364    """Gives the instruction to retrieve values from a dimension of a variable
1365    >>> print rangedim(-1, 15)
1366    15
1367    """
1368    if end == -1:
1369      return shape
1370    else:
1371      return end
1372
1373def searchInlist(listname, nameFind):
1374    """ Function to search a value within a list
1375    listname = list
1376    nameFind = value to find
1377    >>> searInlist(['1', '2', '3', '5'], '5')
1378    True
1379    """
1380    for x in listname:
1381      if x == nameFind:
1382        return True
1383    return False
1384
1385def datetimeStr_datetime(StringDT):
1386    """ Function to transform a string date ([YYYY]-[MM]-[DD]_[HH]:[MI]:[SS] format) to a date object
1387    >>> datetimeStr_datetime('1976-02-17_00:00:00')
1388    1976-02-17 00:00:00
1389    """
1390    import datetime as dt
1391
1392    fname = 'datetimeStr_datetime'
1393
1394    dateD = np.zeros((3), dtype=int)
1395    timeT = np.zeros((3), dtype=int)
1396
1397    dateD[0] = int(StringDT[0:4])
1398    dateD[1] = int(StringDT[5:7])
1399    dateD[2] = int(StringDT[8:10])
1400
1401    trefT = StringDT.find(':')
1402    if not trefT == -1:
1403#        print '  ' + fname + ': refdate with time!'
1404        timeT[0] = int(StringDT[11:13])
1405        timeT[1] = int(StringDT[14:16])
1406        timeT[2] = int(StringDT[17:19])
1407
1408    if int(dateD[0]) == 0:
1409        print warnmsg
1410        print '    ' + fname + ': 0 reference year!! changing to 1'
1411        dateD[0] = 1 
1412 
1413    newdatetime = dt.datetime(dateD[0], dateD[1], dateD[2], timeT[0], timeT[1], timeT[2])
1414
1415    return newdatetime
1416
1417def dateStr_date(StringDate):
1418  """ Function to transform a string date ([YYYY]-[MM]-[DD] format) to a date object
1419  >>> dateStr_date('1976-02-17')
1420  1976-02-17
1421  """
1422  import datetime as dt
1423
1424  dateD = StringDate.split('-')
1425  if int(dateD[0]) == 0:
1426    print warnmsg
1427    print '    dateStr_date: 0 reference year!! changing to 1'
1428    dateD[0] = 1
1429  newdate = dt.date(int(dateD[0]), int(dateD[1]), int(dateD[2]))
1430  return newdate
1431
1432def timeStr_time(StringDate):
1433  """ Function to transform a string date ([HH]:[MI]:[SS] format) to a time object
1434  >>> datetimeStr_datetime('04:32:54')
1435  04:32:54
1436  """
1437  import datetime as dt
1438
1439  timeT = StringDate.split(':')
1440  if len(timeT) == 3:
1441    newtime = dt.time(int(timeT[0]), int(timeT[1]), int(timeT[2]))
1442  else:
1443    newtime = dt.time(int(timeT[0]), int(timeT[1]), 0)
1444
1445  return newtime
1446
1447def timeref_datetime(refd, timeval, tu):
1448    """ Function to transform from a [timeval] in [tu] units from the time referece [tref] to datetime object
1449    refd: time of reference (as datetime object)
1450    timeval: time value (as [tu] from [tref])
1451    tu: time units
1452    >>> timeref = date(1949,12,1,0,0,0)
1453    >>> timeref_datetime(timeref, 229784.36, hours)
1454    1976-02-17 08:21:36
1455    """
1456    import datetime as dt
1457    import numpy as np
1458
1459## Not in timedelta
1460#    if tu == 'years':
1461#        realdate = refdate + dt.timedelta(years=float(timeval))
1462#    elif tu == 'months':
1463#        realdate = refdate + dt.timedelta(months=float(timeval))
1464    if tu == 'weeks':
1465        realdate = refd + dt.timedelta(weeks=float(timeval))
1466    elif tu == 'days':
1467        realdate = refd + dt.timedelta(days=float(timeval))
1468    elif tu == 'hours':
1469        realdate = refd + dt.timedelta(hours=float(timeval))
1470    elif tu == 'minutes':
1471        realdate = refd + dt.timedelta(minutes=float(timeval))
1472    elif tu == 'seconds':
1473        realdate = refd + dt.timedelta(seconds=float(timeval))
1474    elif tu == 'milliseconds':
1475        realdate = refd + dt.timedelta(milliseconds=float(timeval))
1476    else:
1477          print errormsg
1478          print '    timeref_datetime: time units "' + tu + '" not ready!!!!'
1479          quit(-1)
1480
1481    return realdate
1482
1483def timeref_datetime_mat(refd, timeval, tu):
1484    """ Function to transform from a [timeval] in [tu] units from the time referece [tref] to matrix with: year, day, month, hour, minute, second
1485    refd: time of reference (as datetime object)
1486    timeval: time value (as [tu] from [tref])
1487    tu: time units
1488    >>> timeref = date(1949,12,1,0,0,0)
1489    >>> timeref_datetime(timeref, 229784.36, hours)
1490    [1976    2   17    8   36   21]
1491    """
1492    import datetime as dt
1493    import numpy as np
1494
1495
1496    realdates = np.zeros(6, dtype=int)
1497## Not in timedelta
1498#    if tu == 'years':
1499#        realdate = refdate + dt.timedelta(years=float(timeval))
1500#    elif tu == 'months':
1501#        realdate = refdate + dt.timedelta(months=float(timeval))
1502    if tu == 'weeks':
1503        realdate = refd + dt.timedelta(weeks=float(timeval))
1504    elif tu == 'days':
1505        realdate = refd + dt.timedelta(days=float(timeval))
1506    elif tu == 'hours':
1507        realdate = refd + dt.timedelta(hours=float(timeval))
1508    elif tu == 'minutes':
1509        realdate = refd + dt.timedelta(minutes=float(timeval))
1510    elif tunits == 'seconds':
1511        realdate = refd + dt.timedelta(seconds=float(timeval))
1512    elif tunits == 'milliseconds':
1513        realdate = refd + dt.timedelta(milliseconds=float(timeval))
1514    else:
1515          print errormsg
1516          print '    timeref_datetime: time units "' + tu + '" not ready!!!!'
1517          quit(-1)
1518
1519    realdates[0] = int(realdate.year)
1520    realdates[1] = int(realdate.month)
1521    realdates[2] = int(realdate.day)
1522    realdates[3] = int(realdate.hour)
1523    realdates[4] = int(realdate.second)
1524    realdates[5] = int(realdate.minute)
1525
1526    return realdates
1527
1528def realdatetime_CFcompilant(times, Srefdate, tunits):
1529    """ Function to transform a matrix with real time values ([year, month, day, hour, minute, second]) to a netCDF one
1530    times= matrix with times
1531    Srefdate= reference date ([YYYY][MM][DD][HH][MI][SS] format)
1532    tunits= units of time respect to Srefdate
1533    >>> realdatetime_CFcompilant(np.array([ [1976, 2, 17, 8, 20, 0], [1976, 2, 18, 8, 20, 0]], dtype=int), '19491201000000', 'hours')
1534    [ 229784.33333333  229808.33333333]
1535    """ 
1536
1537    import datetime as dt
1538    yrref=int(Srefdate[0:4])
1539    monref=int(Srefdate[4:6])
1540    dayref=int(Srefdate[6:8])
1541    horref=int(Srefdate[8:10])
1542    minref=int(Srefdate[10:12])
1543    secref=int(Srefdate[12:14])
1544 
1545    refdate=dt.datetime(yrref, monref, dayref, horref, minref, secref)
1546
1547    dimt=times.shape[0]
1548       
1549    cfdates = np.zeros((dimt), dtype=np.float64)
1550    if tunits == 'weeks':
1551        for it in range(dimt):
1552            cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate
1553            cfdates[it] = (cfdate.days + cfdate.seconds/(3600.*24.))/7.
1554    elif tunits == 'days':
1555        for it in range(dimt):
1556            cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate
1557            cfdates[it] = cfdate.days + cfdate.seconds/(3600.*24.)
1558    elif tunits == 'hours':
1559        for it in range(dimt):
1560            cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate
1561            cfdates[it] = cfdate.days*24. + cfdate.seconds/3600.
1562    elif tunits == 'minutes':
1563        for it in range(dimt):
1564            cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate
1565            cfdates[it] = cfdate.days*24.*60. + cfdate.seconds/60.
1566    elif tunits == 'seconds':
1567        for it in range(dimt):
1568            cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate
1569            cfdates[it] = cfdate.days*24.*3600. + cfdate.seconds
1570    elif tunits == 'milliseconds':
1571        for it in range(dimt):
1572            cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate
1573            cfdates[it] = cfdate.days*1000.*24.*3600. + cfdate.seconds*1000.
1574    elif tunits == 'microseconds':
1575        for it in range(dimt):
1576            cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate
1577            cfdates[it] = cfdate.days*1000000.*24.*3600. + cfdate.seconds*1000000.
1578    else:
1579        print errormsg
1580        print '  ' + fname + ': time units "' + tunits + '" is not ready!!!'
1581        quit(-1)
1582
1583    return cfdates
1584
1585def netCDFdatetime_realdatetime(units, tcalendar, times):
1586    """ Function to transfrom from netCDF CF-compilant times to real time
1587    """
1588    import datetime as dt
1589
1590    txtunits = units.split(' ')
1591    tunits = txtunits[0]
1592    Srefdate = txtunits[len(txtunits) - 1]
1593
1594# Calendar type
1595##
1596    is360 = False
1597    if tcalendar is not None:
1598      print '  netCDFdatetime_realdatetime: There is a calendar attribute'
1599      if tcalendar == '365_day' or tcalendar == 'noleap':
1600          print '    netCDFdatetime_realdatetime: No leap years!'
1601          isleapcal = False
1602      elif tcalendar == 'proleptic_gregorian' or tcalendar == 'standard' or tcalendar == 'gregorian':
1603          isleapcal = True
1604      elif tcalendar == '360_day':
1605          is360 = True
1606          isleapcal = False
1607      else:
1608          print errormsg
1609          print '    netCDFdatetime_realdatetime: Calendar "' + tcalendar + '" not prepared!'
1610          quit(-1)
1611
1612# Does reference date contain a time value [YYYY]-[MM]-[DD] [HH]:[MI]:[SS]
1613##
1614    timeval = Srefdate.find(':')
1615
1616    if not timeval == -1:
1617        print '  netCDFdatetime_realdatetime: refdate with time!'
1618        refdate = datetimeStr_datetime(txtunits[len(txtunits) - 2] + '_' + Srefdate)
1619    else:
1620        refdate = dateStr_date(Srefdate)
1621
1622    dimt = len(times)
1623#    datetype = type(dt.datetime(1972,02,01))
1624#    realdates = np.array(dimt, datetype)
1625#    print realdates
1626
1627## Not in timedelta
1628#  if tunits == 'years':
1629#    for it in range(dimt):
1630#      realdate = refdate + dt.timedelta(years=float(times[it]))
1631#      realdates[it] = int(realdate.year)
1632#  elif tunits == 'months':
1633#    for it in range(dimt):
1634#      realdate = refdate + dt.timedelta(months=float(times[it]))
1635#      realdates[it] = int(realdate.year)
1636#    realdates = []
1637    realdates = np.zeros((dimt, 6), dtype=int)
1638    if tunits == 'weeks':
1639        for it in range(dimt):
1640            realdate = refdate + dt.timedelta(weeks=float(times[it]))
1641            realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second]
1642    elif tunits == 'days':
1643        for it in range(dimt):
1644            realdate = refdate + dt.timedelta(days=float(times[it]))
1645            realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second]
1646    elif tunits == 'hours':
1647        for it in range(dimt):
1648            realdate = refdate + dt.timedelta(hours=float(times[it]))
1649#            if not isleapcal:
1650#                Nleapdays = cal.leapdays(int(refdate.year), int(realdate.year))
1651#                realdate = realdate - dt.timedelta(days=Nleapdays)
1652#            if is360:
1653#                Nyears360 = int(realdate.year) - int(refdate.year) + 1
1654#                realdate = realdate -dt.timedelta(days=Nyears360*5)
1655#            realdates[it] = realdate
1656#        realdates = refdate + dt.timedelta(hours=float(times))
1657            realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second]
1658    elif tunits == 'minutes':
1659        for it in range(dimt):
1660            realdate = refdate + dt.timedelta(minutes=float(times[it]))
1661            realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second]
1662    elif tunits == 'seconds':
1663        for it in range(dimt):
1664            realdate = refdate + dt.timedelta(seconds=float(times[it]))
1665            realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second]
1666    elif tunits == 'milliseconds':
1667        for it in range(dimt):
1668            realdate = refdate + dt.timedelta(milliseconds=float(times[it]))
1669            realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second]
1670    elif tunits == 'microseconds':
1671        for it in range(dimt):
1672            realdate = refdate + dt.timedelta(microseconds=float(times[it]))
1673            realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second]
1674    else:
1675        print errormsg
1676        print '  netCDFdatetime_realdatetime: time units "' + tunits + '" is not ready!!!'
1677        quit(-1)
1678
1679    return realdates
1680
1681def date_juliandate(refyr, TOTsecs):
1682    """ Function to transform from a total quantity of seconds since the
1683      beginning of a year to 360 days / year calendar
1684      TOTsecs= total number of seconds
1685    """
1686    fname = 'date_juliandate'
1687
1688    secsYear = 3600*24*30*12.
1689    secsMonth = 3600*24*30.
1690    secsDay = 3600*24.
1691    secsHour = 3600.
1692    secsMinute = 60.
1693
1694    rldate = np.zeros((6), dtype=int)
1695    rldate[0] = refyr
1696    if TOTsecs > secsYear:
1697        rldate[0] = refyr + int(TOTsecs/secsYear) + 1
1698        TOTsecs = TOTsecs - int(TOTsecs/secsYear)*secsYear
1699
1700    if np.mod(TOTsecs,secsMonth) == 0:
1701        rldate[1] = int(TOTsecs/secsMonth)
1702    else:
1703        rldate[1] = int(TOTsecs/secsMonth) + 1
1704    TOTsecs = TOTsecs - int(TOTsecs/secsMonth)*secsMonth
1705
1706    if np.mod(TOTsecs,secsDay) == 0:
1707        rldate[2] = int(TOTsecs/secsDay)
1708    else:
1709        rldate[2] = int(TOTsecs/secsDay) + 1
1710    TOTsecs = TOTsecs - int(TOTsecs/secsDay)*secsDay
1711
1712    if np.mod(TOTsecs,secsHour) == 0:
1713        rldate[3] = int(TOTsecs/secsHour)
1714    else:
1715        rldate[3] = int(TOTsecs/secsHour) + 1
1716    TOTsecs = TOTsecs - int(TOTsecs/secsHour)*secsHour
1717
1718    if np.mod(TOTsecs,secsMinute) == 0:
1719        rldate[4] = int(TOTsecs/secsMinute)
1720    else:
1721        rldate[4] = int(TOTsecs/secsMinute) + 1
1722    TOTsecs = TOTsecs - int(TOTsecs/secsMinute)*secsMinute
1723
1724    rldate[5] = TOTsecs
1725
1726#    print refyr,TOTsecs,':',rldate
1727#    quit()
1728
1729    return rldate
1730
1731def CFtimes_datetime(ncfile, tname):
1732    """ Provide date/time array from a file with a series of netCDF CF-compilant time variable
1733    ncfile = netCDF file name
1734    tname = name of the variable time in [ncfile]
1735    output:
1736      array(dimt, 0) = year
1737      array(dimt, 1) = month
1738      array(dimt, 2) = day
1739      array(dimt, 3) = hour
1740      array(dimt, 4) = minute
1741      array(dimt, 5) = second
1742    """
1743    import datetime as dt
1744    fname = 'CFtimes_datetime'
1745
1746    times = ncfile.variables[tname]
1747    timevals = times[:]
1748
1749    attvar = times.ncattrs()
1750    if not searchInlist(attvar, 'units'):
1751        print errormsg
1752        print '  ' + fname + ": '" + tname + "' does not have attribute: 'units'"
1753        quit(-1)
1754    else:
1755        units = times.getncattr('units')
1756 
1757    txtunits = units.split(' ')
1758    tunits = txtunits[0]
1759    Srefdate = txtunits[len(txtunits) - 1]
1760# Does reference date contain a time value [YYYY]-[MM]-[DD] [HH]:[MI]:[SS]
1761##
1762    timeval = Srefdate.find(':')
1763
1764    if not timeval == -1:
1765#        print '  refdate with time!'
1766        refdate = datetimeStr_datetime(txtunits[len(txtunits) - 2] + '_' + Srefdate)
1767    else:
1768        refdate = dateStr_date(Srefdate)
1769
1770    dimt = len(timevals)
1771    realdates = np.zeros((dimt, 6), dtype=int)
1772
1773    secsDay=3600*24.
1774
1775# Checking calendar!
1776##
1777    y360 = False
1778    daycal360 = ['earth_360d', '360d', '360days', '360_day']
1779    if searchInlist(attvar, 'calendar'):
1780        calendar = times.getncattr('calendar')
1781        if searchInlist(daycal360,calendar):
1782            print warnmsg
1783            print '  ' + fname + ': calendar of 12 months of 30 days !!'
1784            y360 = True
1785
1786## Not in timedelta
1787#    if tunits == 'years':
1788#        for it in range(dimt):
1789#            realdate = refdate + dt.timedelta(years=float(times[it]))
1790#            realdates[it] = int(realdate.year)
1791#    elif tunits == 'months':
1792#        for it in range(dimt):
1793#            realdate = refdate + dt.timedelta(months=float(times[it]))
1794#            realdates[it] = int(realdate.year)
1795    if y360:
1796        if tunits == 'weeks':
1797            for it in range(dimt):
1798                deltat = dt.timedelta(weeks=float(times[it]))
1799                Tsecs = deltat.days*secsDay + deltat.seconds + deltat.microseconds/1000.
1800                realdates[it,:] = date_juliandate(refdate.year,Tsecs)
1801        elif tunits == 'days':
1802            for it in range(dimt):
1803                deltat = dt.timedelta(days=float(times[it]))
1804                Tsecs = deltat.days*secsDay + deltat.seconds + deltat.microseconds/1000.
1805                realdates[it,:] = date_juliandate(refdate.year,Tsecs)
1806        elif tunits == 'hours':
1807           for it in range(dimt):
1808                realdate = dt.timedelta(hours=float(times[it]))
1809                Tsecs = deltat.days*secsDay + deltat.seconds + deltat.microseconds/1000.
1810                realdates[it,:] = date_juliandate(refdate.year,Tsecs)
1811        elif tunits == 'minutes':
1812           for it in range(dimt):
1813                realdate = dt.timedelta(minutes=float(times[it]))
1814                Tsecs = deltat.days*secsDay + deltat.seconds + deltat.microseconds/1000.
1815                realdates[it,:] = date_juliandate(refdate.year,Tsecs)
1816        elif tunits == 'seconds':
1817           for it in range(dimt):
1818                realdate = dt.timedelta(seconds=float(times[it]))
1819                Tsecs = deltat.days*secsDay + deltat.seconds + deltat.microseconds/1000.
1820                realdates[it,:] = date_juliandate(refdate.year,Tsecs)
1821        elif tunits == 'miliseconds':
1822           for it in range(dimt):
1823                realdate = dt.timedelta(miliseconds=float(times[it]))
1824                Tsecs = deltat.days*secsDay + deltat.seconds + deltat.microseconds/1000.
1825                realdates[it,:] = date_juliandate(refdate.year,Tsecs)
1826        else:
1827              print errormsg
1828              print '    CFtimes_datetime: time units "' + tunits + '" not ready!!!!'
1829              quit(-1)
1830    else:
1831        if tunits == 'weeks':
1832            for it in range(dimt):
1833                realdate = refdate + dt.timedelta(weeks=float(times[it]))
1834                realdates[it,0] = int(realdate.year)
1835                realdates[it,1] = int(realdate.month)
1836                realdates[it,2] = int(realdate.day)
1837                realdates[it,3] = int(realdate.hour)
1838                realdates[it,4] = int(realdate.second)
1839                realdates[it,5] = int(realdate.minute)
1840        elif tunits == 'days':
1841            for it in range(dimt):
1842                realdate = refdate + dt.timedelta(days=float(times[it]))
1843                realdates[it,0] = int(realdate.year)
1844                realdates[it,1] = int(realdate.month)
1845                realdates[it,2] = int(realdate.day)
1846                realdates[it,3] = int(realdate.hour)
1847                realdates[it,4] = int(realdate.second)
1848                realdates[it,5] = int(realdate.minute)
1849        elif tunits == 'hours':
1850           for it in range(dimt):
1851                realdate = refdate + dt.timedelta(hours=float(times[it]))
1852                realdates[it,0] = int(realdate.year)
1853                realdates[it,1] = int(realdate.month)
1854                realdates[it,2] = int(realdate.day)
1855                realdates[it,3] = int(realdate.hour)
1856                realdates[it,4] = int(realdate.second)
1857                realdates[it,5] = int(realdate.minute)
1858        elif tunits == 'minutes':
1859           for it in range(dimt):
1860                realdate = refdate + dt.timedelta(minutes=float(times[it]))
1861                realdates[it,0] = int(realdate.year)
1862                realdates[it,1] = int(realdate.month)
1863                realdates[it,2] = int(realdate.day)
1864                realdates[it,3] = int(realdate.hour)
1865                realdates[it,4] = int(realdate.second)
1866                realdates[it,5] = int(realdate.minute)
1867        elif tunits == 'seconds':
1868           for it in range(dimt):
1869                realdate = refdate + dt.timedelta(seconds=float(times[it]))
1870                realdates[it,0] = int(realdate.year)
1871                realdates[it,1] = int(realdate.month)
1872                realdates[it,2] = int(realdate.day)
1873                realdates[it,3] = int(realdate.hour)
1874                realdates[it,4] = int(realdate.second)
1875                realdates[it,5] = int(realdate.minute)
1876        elif tunits == 'milliseconds':
1877           for it in range(dimt):
1878                realdate = refdate + dt.timedelta(milliseconds=float(times[it]))
1879                realdates[it,0] = int(realdate.year)
1880                realdates[it,1] = int(realdate.month)
1881                realdates[it,2] = int(realdate.day)
1882                realdates[it,3] = int(realdate.hour)
1883                realdates[it,4] = int(realdate.second)
1884                realdates[it,5] = int(realdate.minute)
1885        else:
1886              print errormsg
1887              print '    CFtimes_datetime: time units "' + tunits + '" not ready!!!!'
1888              quit(-1)
1889   
1890    return realdates
1891
1892class statsValWeigthed(object):
1893  """Weigthed Statistics class providing:
1894  vals = values (can be a matrix)
1895  wgs = weights (can be a matrix)
1896  self.meanv: mean weigthed value
1897  self.mean2v: mean quadratic weigthed value
1898  self.stdv: weigthed standard deviation
1899  self.Nokvalue non None values of a list of values
1900  self.meanwgt: mean of the weigths
1901  self.mean2wgt: cuadratic mean of the weigths
1902  self.stdwgt: standard deviation of the weigths
1903  """
1904
1905  def __init__(self, vals, wgs):
1906    if vals is None:
1907      self.Nv = None
1908      self.meanv = None
1909      self.mean2v = None
1910      self.stdv = None
1911      self.Nokvalues = None
1912      self.meanwgt = None
1913      self.mean2wgt = None
1914      self.stdwgt = None
1915    else:
1916      values = vals.flatten() 
1917      weights = wgs.flatten()
1918      self.Nv=len(values)
1919      self.meanv=0.
1920      self.mean2v=0.
1921      self.stdv=0.
1922      self.meanwgt = 0.
1923      self.mean2wgt = 0.
1924      self.stdwgt = 0.
1925      self.Nokvalues = 0
1926
1927      for inum in range(self.Nv):
1928        if not values[inum] is None:
1929          self.Nokvalues = self.Nokvalues + 1
1930          self.meanv = self.meanv+values[inum]*weights[inum]
1931          self.mean2v = self.mean2v+values[inum]*weights[inum]*values[inum]
1932          self.meanwgt = self.meanwgt+weights[inum]
1933          self.mean2wgt = self.mean2wgt+weights[inum]*weights[inum]
1934
1935      self.meanv = self.meanv/float(self.meanwgt)
1936      self.mean2v = self.mean2v/float(self.meanwgt)
1937      self.stdv = np.sqrt(self.mean2v-self.meanv*self.meanv)
1938      self.meanwgt = self.meanwgt/float(self.Nokvalues)
1939      self.mean2wgt = self.mean2wgt/float(self.Nokvalues)
1940      self.stdwgt = np.sqrt(self.mean2wgt-self.meanwgt*self.meanwgt)
1941
1942    return
1943
1944class statsValWeighted_missVal(object):
1945  """Weighted Statistics taking into account a missing value class providing:
1946  vals = values (can be a matrix)
1947  wgs = weights (can be a matrix)
1948  missVal= missing value
1949  self.meanv: mean weigthed value
1950  self.mean2v: mean quadratic weigthed value
1951  self.stdv: weigthed standard deviation
1952  self.Nokvalue non None values of a list of values
1953  self.meanwgt: mean of the weigths
1954  self.mean2wgt: cuadratic mean of the weigths
1955  self.stdwgt: standard deviation of the weigths
1956  self.quantilesv: quantiles of the weighted values
1957  """
1958
1959  def __init__(self, vals, wgs, missVal):
1960
1961    fname='statsValWeigthed_missVal'
1962    if vals is None:
1963      self.Nv = None
1964      self.meanv = None
1965      self.mean2v = None
1966      self.stdv = None
1967      self.Nokvalues = None
1968      self.meanwgt = None
1969      self.mean2wgt = None
1970      self.stdwgt = None
1971      self.quantilesv = None
1972    else:   
1973      Npt = 1
1974      for idim in range(len(vals.shape)):
1975        Npt = Npt * vals.shape[idim]
1976      if np.sum(vals >= missVal) == Npt:
1977          print errormsg
1978          print '  ' + fname + ' all values get missing!!'
1979          print errormsg
1980          quit(-1)
1981      vals0 = np.where(vals >= missVal, None, vals)
1982      values = vals0.flatten() 
1983      weights = wgs.flatten()
1984      self.Nv=Npt
1985      self.meanv=0.
1986      self.mean2v=0.
1987      self.stdv=0.
1988      self.meanwgt = 0.
1989      self.mean2wgt = 0.
1990      self.stdwgt = 0.
1991      self.Nokvalues = 0
1992
1993      valswgt = values
1994      for inum in range(self.Nv):
1995        if not values[inum] is None:
1996          self.Nokvalues = self.Nokvalues + 1
1997          valswgt[inum] = valswgt[inum]*weights[inum]
1998          self.meanv = self.meanv+values[inum]*weights[inum]
1999          self.mean2v = self.mean2v+values[inum]*weights[inum]*values[inum]
2000          self.meanwgt = self.meanwgt+weights[inum]
2001          self.mean2wgt = self.mean2wgt+weights[inum]*weights[inum]
2002
2003      self.meanv = self.meanv/float(self.meanwgt)
2004      self.mean2v = self.mean2v/float(self.meanwgt)
2005      self.stdv = np.sqrt(self.mean2v-self.meanv*self.meanv)
2006      valswgt = valswgt/np.float(self.meanwgt)
2007      self.meanwgt = self.meanwgt/float(self.Nokvalues)
2008      self.mean2wgt = self.mean2wgt/float(self.Nokvalues)
2009      self.stdwgt = np.sqrt(self.mean2wgt-self.meanwgt*self.meanwgt)
2010      valsq=Quantiles(valswgt, 20)
2011      self.quantilesv=valsq.quantilesv
2012
2013    return
2014
2015class stats2Val(object):
2016  """two variables Statistics class providing:
2017  vals1 = variable 1
2018  vals2 = variable 2
2019  power = power of the polynomial fitting to apply between both variables
2020  self.min[var], self.max[var], self.mean[var], self.mean2[var], self.std[var] of
2021    [var] = var1+var2[v1Av2], var1-var2[v1Sv2], var1/var2[v1Dv2], var1*var2[v1Pv2]
2022  self.Nokvalues1: number of correct values of variable 1
2023  self.Nokvalues2: number of correct values of variable 2
2024  self.Nokvalues12: number of correct coincident values of variable 1 and variable 2
2025  self.mae=mean(abs(var1-var2))
2026  self.rmse=sqrt((var1-var2)**2)
2027  self.correlation (and p-value)
2028  self.linRegress: linear regression [trend, intercept, regression coefficient, p_value, standard error]
2029  self.polRegress: polinomial Regresion  of degree [power] [coef**[power], coef**[power-1], ...., coef**0]
2030  """
2031
2032  def __init__(self, vals1, vals2, power):
2033    import numpy as np
2034    from scipy import stats as sts
2035
2036    if vals1 is None:
2037      self.Nv = None
2038      self.Nokvalues1 = None
2039      self.Nokvalues2 = None
2040      self.Nokvalues12 = None
2041      self.NDvalNone = None
2042      self.minv1Av2 = None
2043      self.maxv1Av2 = None
2044      self.meanv1Av2 = None
2045      self.mean2v1Av2 = None
2046      self.stdv1Av2 = None
2047      self.minv1Sv2 = None
2048      self.maxv1Sv2 = None
2049      self.meanv1Sv2 = None
2050      self.mean2v1Sv2 = None
2051      self.stdv1Sv2 = None
2052      self.minv1Dv2 = None
2053      self.maxv1Dv2 = None
2054      self.meanv1Dv2 = None
2055      self.mean2v1Dv2 = None
2056      self.stdv1Dv2 = None
2057      self.minv1Pv2 = None
2058      self.maxv1Pv2 = None
2059      self.meanv1Pv2 = None
2060      self.mean2v1Pv2 = None
2061      self.stdv1Pv2 = None
2062      self.mae = None
2063      self.rmse = None
2064      self.corr = None
2065      self.linRegress = None
2066      self.polRegress = None
2067      self.polRegressResidual = None
2068      self.polRegressRes = None
2069      self.polRegressSingVal = None
2070    else:
2071      values1 = vals1.flatten() 
2072      values2 = vals2.flatten() 
2073
2074      if not len(values1) == len(values2):
2075        print errormsg
2076        print '    stats2Val: lengths of variables differ!! Lvar1: ', len(values1), ' Lvar2: ',len(values2),' statistics between them can not be computed!'
2077        quit(-1)
2078
2079      self.Nv=len(values1)
2080      self.minv1Av2=10000000000.
2081      self.maxv1Av2=-self.minv1Av2
2082      self.meanv1Av2=0.
2083      self.mean2v1Av2=0.
2084      self.stdv1Av2=0.
2085      self.minv1Sv2=self.minv1Av2
2086      self.maxv1Sv2=-self.minv1Av2
2087      self.meanv1Sv2=0.
2088      self.mean2v1Sv2=0.
2089      self.stdv1Sv2=0.
2090      self.minv1Dv2=self.minv1Av2
2091      self.maxv1Dv2=-self.minv1Av2
2092      self.meanv1Dv2=0.
2093      self.mean2v1Dv2=0.
2094      self.stdv1Dv2=0.
2095      self.minv1Pv2=self.minv1Av2
2096      self.maxv1Pv2=-self.minv1Av2
2097      self.meanv1Pv2=0.
2098      self.mean2v1Pv2=0.
2099      self.stdv1Pv2=0.
2100      self.mae = 0.
2101      self.rmse = 0.
2102      self.corr = np.array([0., 0.])
2103      self.linRegress = np.zeros(5, float)
2104      self.polRegress = np.zeros(power+1, float)
2105      self.polRegressResidual = 0.
2106      self.polRegressSingVal = np.zeros(power+1, float)
2107
2108# v1 [+ / - / / / *] v2
2109##
2110      self.Nokvalues1 = 0
2111      self.Nokvalues2 = 0
2112      self.Nokvalues12 = 0
2113      self.NDvalNone = 0
2114      for inum in range(self.Nv):
2115        if not values1[inum] is None:
2116          self.Nokvalues1 = self.Nokvalues1 + 1
2117        if not values2[inum] is None:
2118          self.Nokvalues2 = self.Nokvalues2 + 1
2119        if not values1[inum] is None and not values2[inum] is None:
2120          self.Nokvalues12 = self.Nokvalues12 + 1
2121          Aval = values1[inum] + values2[inum]
2122          Sval = values1[inum] - values2[inum]
2123          Pval = values1[inum] * values2[inum]
2124          if np.isinf(values1[inum] / values2[inum]) or np.isnan(values1[inum] / values2[inum]):
2125            if self.NDvalNone < 1:
2126               print warnmsg
2127               print '      stats2Val: val1/val2 inf or Nan!!!!'
2128            Dval = None
2129            self.NDvalNone = self.NDvalNone + 1
2130          else:
2131            Dval = values1[inum] / values2[inum]
2132
2133          self.mae = self.mae + abs(Sval)
2134          self.rmse = self.rmse + Sval**2
2135
2136          if Aval < self.minv1Av2:
2137            self.minv1Av2 = Aval
2138          if Aval > self.maxv1Av2:
2139            self.maxv1Av2 = Aval
2140          if Sval < self.minv1Sv2:
2141            self.minv1Sv2 = Sval
2142          if Sval > self.maxv1Sv2:
2143            self.maxv1Sv2 = Sval
2144          if not Dval is None and Dval < self.minv1Dv2:
2145            self.minv1Dv2 = Dval
2146          if not Dval is None and  Dval > self.maxv1Dv2:
2147            self.maxv1Dv2 = Dval
2148          if Pval < self.minv1Pv2:
2149            self.minv1Pv2 = Pval
2150          if Pval > self.maxv1Pv2:
2151            self.maxv1Pv2 = Pval
2152
2153          self.meanv1Av2 = self.meanv1Av2+Aval
2154          self.mean2v1Av2 = self.mean2v1Av2+Aval*Aval
2155          self.meanv1Sv2 = self.meanv1Sv2+Sval
2156          self.mean2v1Sv2 = self.mean2v1Sv2+Sval*Sval
2157          if not Dval is None:
2158            self.meanv1Dv2 = self.meanv1Dv2+Dval
2159            self.mean2v1Dv2 = self.mean2v1Dv2+Dval*Dval
2160          self.meanv1Pv2 = self.meanv1Pv2+Pval
2161          self.mean2v1Pv2 = self.mean2v1Pv2+Pval*Pval
2162
2163##      print 'Nokvalues1: ', self.Nokvalues1, 'Nokvalues2: ', self.Nokvalues2, 'Nokvalues12: ', float(self.Nokvalues12), 'NDvalNone: ',self.NDvalNone
2164      self.meanv1Av2 = self.meanv1Av2/float(self.Nokvalues12)
2165      self.mean2v1Av2 = self.mean2v1Av2/float(self.Nokvalues12)
2166      self.stdv1Av2 = np.sqrt(self.mean2v1Av2-self.meanv1Av2*self.meanv1Av2)
2167      self.meanv1Sv2 = self.meanv1Sv2/float(self.Nokvalues12)
2168      self.mean2v1Sv2 = self.mean2v1Sv2/float(self.Nokvalues12)
2169      self.stdv1Sv2 = np.sqrt(self.mean2v1Sv2-self.meanv1Sv2*self.meanv1Sv2)
2170      if self.Nokvalues12 - self.NDvalNone == 0:
2171          self.meanv1Dv2 = None
2172          self.mean2v1Dv2 = None
2173          self.stdv1Dv2 = None
2174          print warnmsg
2175          print '      stats2Val: all values of val1/val2 are None!'
2176      else:
2177          self.meanv1Dv2 = self.meanv1Dv2/(float(self.Nokvalues12 - self.NDvalNone))
2178          self.mean2v1Dv2 = self.mean2v1Dv2/(float(self.Nokvalues12 - self.NDvalNone))
2179          self.stdv1Dv2 = np.sqrt(self.mean2v1Dv2-self.meanv1Dv2*self.meanv1Dv2)
2180      self.meanv1Pv2 = self.meanv1Pv2/float(self.Nokvalues12)
2181      self.mean2v1Pv2 = self.mean2v1Pv2/float(self.Nokvalues12)
2182      self.stdv1Pv2 = np.sqrt(self.mean2v1Pv2-self.meanv1Pv2*self.meanv1Pv2)
2183
2184      self.mae = self.mae/self.Nokvalues12
2185      self.rmse = np.sqrt(self.rmse/self.Nokvalues12)
2186
2187      self.corr = sts.pearsonr(values1, values2)
2188
2189      self.linRegress[0], self.linRegress[1], self.linRegress[2], self.linRegress[3], self.linRegress[4] = sts.linregress(values1, values2)
2190
2191      polyfitvals=np.polyfit(values1, values2, power, full = True)
2192
2193      self.polRegress = polyfitvals[0]
2194      self.polRegressRes = polyfitvals[1]
2195      self.polRegressSingVal = polyfitvals[3]
2196
2197    return
2198
2199class stats2Val_missVal(object):
2200  """two variables Statistics taking into account a missing value class providing:
2201  vals1 = variable 1
2202  vals2 = variable 2
2203  missVal = missing value
2204  power = power of the polynomial fitting to apply between both variables
2205  self.min[var], self.max[var], self.mean[var], self.mean2[var], self.std[var] of
2206    [var] = var1+var2[v1Av2], var1-var2[v1Sv2], var1/var2[v1Dv2], var1*var2[v1Pv2]
2207  self.Nokvalues1: number of correct values of variable 1
2208  self.Nokvalues2: number of correct values of variable 2
2209  self.Nokvalues12: number of correct coincident values of variable 1 and variable 2
2210  self.mae=mean(abs(var1-var2))
2211  self.rmse=sqrt((var1-var2)**2)
2212  self.correlation (and p-value)
2213  self.linRegress: linear regression [trend, intercept, regression coefficient, p_value, standard error]
2214  self.polRegress: polinomial Regresion  of degree [power] [coef**[power], coef**[power-1], ...., coef**0]
2215  """
2216
2217  def __init__(self, vals1, vals2, power, missVal):
2218    import numpy as np
2219    from scipy import stats as sts
2220
2221    fname='stats2Val_missVal'
2222    if vals1 is None:
2223      self.Nv = None
2224      self.Nokvalues1 = None
2225      self.Nokvalues2 = None
2226      self.Nokvalues12 = None
2227      self.NDvalNone = None
2228      self.minv1Av2 = None
2229      self.maxv1Av2 = None
2230      self.meanv1Av2 = None
2231      self.mean2v1Av2 = None
2232      self.stdv1Av2 = None
2233      self.minv1Sv2 = None
2234      self.maxv1Sv2 = None
2235      self.meanv1Sv2 = None
2236      self.mean2v1Sv2 = None
2237      self.stdv1Sv2 = None
2238      self.minv1Dv2 = None
2239      self.maxv1Dv2 = None
2240      self.meanv1Dv2 = None
2241      self.mean2v1Dv2 = None
2242      self.stdv1Dv2 = None
2243      self.minv1Pv2 = None
2244      self.maxv1Pv2 = None
2245      self.meanv1Pv2 = None
2246      self.mean2v1Pv2 = None
2247      self.stdv1Pv2 = None
2248      self.mae = None
2249      self.rmse = None
2250      self.corr = None
2251      self.linRegress = None
2252      self.polRegress = None
2253      self.polRegressResidual = None
2254      self.polRegressRes = None
2255      self.polRegressSingVal = None
2256    else:
2257      Npt1 = 1
2258      for idim in range(len(vals1.shape)):
2259        Npt1 = Npt1 * vals1.shape[idim]
2260      if np.sum(vals1 >= missVal) == Npt1:
2261          print errormsg
2262          print '  ' + fname + ' all values 1 get missing!!'
2263          print errormsg
2264          quit(-1)
2265      Npt2 = 1
2266      for idim in range(len(vals2.shape)):
2267        Npt2 = Npt2 * vals2.shape[idim]
2268      if np.sum(vals2 >= missVal) == Npt2:
2269          print errormsg
2270          print '  ' + fname + ' all values 2 get missing!!'
2271          print errormsg
2272          quit(-1)
2273      vals10 = np.where(abs(vals1) >= missVal, None, vals1)
2274      vals20 = np.where(abs(vals2) >= missVal, None, vals2)
2275      values1 = vals10.flatten() 
2276      values2 = vals20.flatten() 
2277
2278      if not len(values1) == len(values2):
2279        print errormsg
2280        print '    stats2Val: lengths of variables differ!! Lvar1: ', len(values1), ' Lvar2: ',len(values2),' statistics between them can not be computed!'
2281        quit(-1)
2282
2283      self.Nv=Npt1
2284      self.minv1Av2=10000000000.
2285      self.maxv1Av2=-self.minv1Av2
2286      self.meanv1Av2=0.
2287      self.mean2v1Av2=0.
2288      self.stdv1Av2=0.
2289      self.minv1Sv2=self.minv1Av2
2290      self.maxv1Sv2=-self.minv1Av2
2291      self.meanv1Sv2=0.
2292      self.mean2v1Sv2=0.
2293      self.stdv1Sv2=0.
2294      self.minv1Dv2=self.minv1Av2
2295      self.maxv1Dv2=-self.minv1Av2
2296      self.meanv1Dv2=0.
2297      self.mean2v1Dv2=0.
2298      self.stdv1Dv2=0.
2299      self.minv1Pv2=self.minv1Av2
2300      self.maxv1Pv2=-self.minv1Av2
2301      self.meanv1Pv2=0.
2302      self.mean2v1Pv2=0.
2303      self.stdv1Pv2=0.
2304      self.mae = 0.
2305      self.rmse = 0.
2306      self.corr = np.array([0., 0.])
2307      self.linRegress = np.zeros(5, float)
2308      self.polRegress = np.zeros(power+1, float)
2309      self.polRegressResidual = 0.
2310      self.polRegressSingVal = np.zeros(power+1, float)
2311
2312# v1 [+ / - / / / *] v2
2313##
2314      self.Nokvalues1 = 0
2315      self.Nokvalues2 = 0
2316      self.Nokvalues12 = 0
2317      self.NDvalNone = 0
2318      for inum in range(self.Nv):
2319        if not values1[inum] is None:
2320          self.Nokvalues1 = self.Nokvalues1 + 1
2321        if not values2[inum] is None:
2322          self.Nokvalues2 = self.Nokvalues2 + 1
2323        if not values1[inum] is None and not values2[inum] is None:
2324          self.Nokvalues12 = self.Nokvalues12 + 1
2325          Aval = values1[inum] + values2[inum]
2326          Sval = values1[inum] - values2[inum]
2327          Pval = values1[inum] * values2[inum]
2328          if np.isinf(values1[inum] / values2[inum]) or np.isnan(values1[inum] / values2[inum]):
2329            if self.NDvalNone < 1:
2330               print warnmsg
2331               print '      stats2Val: val1/val2 inf or Nan!!!!'
2332            Dval = None
2333            self.NDvalNone = self.NDvalNone + 1
2334          else:
2335            Dval = values1[inum] / values2[inum]
2336
2337          self.mae = self.mae + abs(Sval)
2338          self.rmse = self.rmse + Sval**2
2339
2340          if Aval < self.minv1Av2:
2341            self.minv1Av2 = Aval
2342          if Aval > self.maxv1Av2:
2343            self.maxv1Av2 = Aval
2344          if Sval < self.minv1Sv2:
2345            self.minv1Sv2 = Sval
2346          if Sval > self.maxv1Sv2:
2347            self.maxv1Sv2 = Sval
2348          if not Dval is None and Dval < self.minv1Dv2:
2349            self.minv1Dv2 = Dval
2350          if not Dval is None and  Dval > self.maxv1Dv2:
2351            self.maxv1Dv2 = Dval
2352          if Pval < self.minv1Pv2:
2353            self.minv1Pv2 = Pval
2354          if Pval > self.maxv1Pv2:
2355            self.maxv1Pv2 = Pval
2356
2357          self.meanv1Av2 = self.meanv1Av2+Aval
2358          self.mean2v1Av2 = self.mean2v1Av2+Aval*Aval
2359          self.meanv1Sv2 = self.meanv1Sv2+Sval
2360          self.mean2v1Sv2 = self.mean2v1Sv2+Sval*Sval
2361          if not Dval is None:
2362            self.meanv1Dv2 = self.meanv1Dv2+Dval
2363            self.mean2v1Dv2 = self.mean2v1Dv2+Dval*Dval
2364          self.meanv1Pv2 = self.meanv1Pv2+Pval
2365          self.mean2v1Pv2 = self.mean2v1Pv2+Pval*Pval
2366
2367##      print 'Nokvalues1: ', self.Nokvalues1, 'Nokvalues2: ', self.Nokvalues2, 'Nokvalues12: ', float(self.Nokvalues12), 'NDvalNone: ',self.NDvalNone
2368      self.meanv1Av2 = self.meanv1Av2/float(self.Nokvalues12)
2369      self.mean2v1Av2 = self.mean2v1Av2/float(self.Nokvalues12)
2370      self.stdv1Av2 = np.sqrt(self.mean2v1Av2-self.meanv1Av2*self.meanv1Av2)
2371      self.meanv1Sv2 = self.meanv1Sv2/float(self.Nokvalues12)
2372      self.mean2v1Sv2 = self.mean2v1Sv2/float(self.Nokvalues12)
2373      self.stdv1Sv2 = np.sqrt(self.mean2v1Sv2-self.meanv1Sv2*self.meanv1Sv2)
2374      if self.Nokvalues12 - self.NDvalNone == 0:
2375          self.meanv1Dv2 = None
2376          self.mean2v1Dv2 = None
2377          self.stdv1Dv2 = None
2378          print warnmsg
2379          print '      stats2Val: all values of val1/val2 are None!'
2380      else:
2381          self.meanv1Dv2 = self.meanv1Dv2/(float(self.Nokvalues12 - self.NDvalNone))
2382          self.mean2v1Dv2 = self.mean2v1Dv2/(float(self.Nokvalues12 - self.NDvalNone))
2383          self.stdv1Dv2 = np.sqrt(self.mean2v1Dv2-self.meanv1Dv2*self.meanv1Dv2)
2384      self.meanv1Pv2 = self.meanv1Pv2/float(self.Nokvalues12)
2385      self.mean2v1Pv2 = self.mean2v1Pv2/float(self.Nokvalues12)
2386      self.stdv1Pv2 = np.sqrt(self.mean2v1Pv2-self.meanv1Pv2*self.meanv1Pv2)
2387
2388      self.mae = self.mae/self.Nokvalues12
2389      self.rmse = np.sqrt(self.rmse/self.Nokvalues12)
2390
2391      vals1Nomiss = np.ones(len(values1), dtype=bool)
2392      vals2Nomiss = np.ones(len(values1), dtype=bool)
2393
2394      for i in range(len(values1)):
2395          if values1[i] is None:
2396              vals1Nomiss[i] = False
2397
2398      for i in range(len(values2)):
2399          if values2[i] is None:
2400              vals2Nomiss[i] = False
2401
2402      v1 = np.array(values1[vals1Nomiss], dtype=float)
2403      v2 = np.array(values2[vals2Nomiss], dtype=float)
2404
2405      if not v1.shape == v2.shape:
2406          print errormsg
2407          print '  ' + fname + ': variables without missing values v1: ',v1.shape , ' and v2: ',v2.shape ,' do not have the same shape! '
2408          print errormsg
2409          quit(-1)
2410
2411      self.corr = sts.pearsonr(v1, v2)
2412
2413      self.linRegress[0], self.linRegress[1], self.linRegress[2], self.linRegress[3], self.linRegress[4] = sts.linregress(v1, v2)
2414
2415      polyfitvals=np.polyfit(v1, v2, power, full = True)
2416
2417      self.polRegress = polyfitvals[0]
2418      self.polRegressRes = polyfitvals[1]
2419      self.polRegressSingVal = polyfitvals[3]
2420
2421    return
2422
2423def mask_2masked(vals1, vals2):
2424    """ Function to provide the boolean matrix (in opposite way as it is in the mask) as combination of mask from to masked matrices
2425    """
2426    import numpy.ma as ma
2427    fname = 'mask_2masked'
2428
2429#    if len(vals1.shape) != len(vals2.shape):
2430#        print errormsg
2431#        print '  ' + fname + ' matrix 1 :', len(vals1.shape), ' and matrix 2 ', len(vals2.shape), ' have different size!'
2432#        print errormsg
2433#        quit(-1)
2434
2435#    for idim in range(len(vals1.shape)):
2436#        if vals1.shape[idim] != vals2.shape[idim]:
2437#            print errormsg
2438#            print '  ' + fname + ' dimension ', idim,' from matrix 1 :', vals1.shape[idim], ' and matrix 2 ', \
2439#                vals2.shape[idim], ' have different size!'
2440#            print errormsg
2441#            quit(-1)
2442
2443    if type(vals1) == type(ma.array(1)):
2444        mask1array=np.where(ma.getmaskarray(vals1) == False, True, False)
2445    else:
2446        mask1array=np.ones(vals1.shape, dtype=bool)
2447
2448    if type(vals2) == type(ma.array(1)):
2449        mask2array=np.where(ma.getmaskarray(vals2) == False, True, False)
2450    else:
2451        mask2array=np.ones(vals2.shape, dtype=bool)
2452
2453    mask12 = mask1array*mask2array
2454
2455    return mask12
2456
2457def mask_pearsonr(xvals, yvals):
2458    """ Function to compute a pearson correlation from mask matrices
2459    """
2460    from scipy import stats as sts
2461    fillVal = 1.e20
2462    maskxy = mask_2masked(xvals, yvals)
2463
2464    if np.sum(maskxy) > 1:
2465        pearsonr = sts.pearsonr(xvals[maskxy], yvals[maskxy])
2466        if np.isnan(pearsonr[0]) or np.isnan(pearsonr[1]): 
2467           pearsonr = ( fillVal, fillVal)
2468    else:
2469        pearsonr = (fillVal, fillVal)
2470
2471    return pearsonr
2472
2473def mask_quantiles(maskmat, Nquants):
2474    """ Function to provide the quantiles of a masked array 20 for %5 bins (21 in total)
2475    """
2476    import numpy.ma as ma
2477
2478    fillValue = 1.e20
2479
2480    sortmat = maskmat.flatten().copy()
2481    sortmat.sort()
2482    quants = np.zeros(Nquants+1, dtype=type(maskmat[0]))
2483    Nv = ma.size(maskmat)
2484    NoMask=maskmat.count()
2485
2486    if NoMask < Nquants:
2487        quants[:] = fillValue
2488    else:
2489        for iq in range(Nquants):
2490            quants[iq] = sortmat[int((NoMask-1)*iq/(Nquants))]
2491
2492        quants[Nquants] = sortmat[NoMask-1]
2493
2494    return quants
2495
2496def percendone(nvals,tot,percen,msg):
2497    """ Function to provide the percentage of an action across the matrix
2498    nvals=number of values
2499    tot=total number of values
2500    percen=percentage frequency for which the message is wanted
2501    msg= message
2502    """
2503    from sys import stdout
2504
2505    num = int(tot * percen/100)
2506    if (nvals%num == 0): 
2507        print '\r        ' + msg + '{0:8.3g}'.format(nvals*100./tot) + ' %',
2508        stdout.flush()
2509
2510    return ''
2511
2512def mask_linregres(vals1, vals2):
2513    """ Function to compute a linear regression from masked data
2514    vals1: x-values for the regresion
2515    vals2: y-values for the regresion
2516    """
2517    import numpy.ma as ma
2518
2519    fname = 'mask_linregres'
2520
2521    missval1 = vals1.get_fill_value()   
2522    missval2 = vals2.get_fill_value()   
2523
2524    vals10 = np.where(abs(vals1) >= abs(missval1*0.9), None, vals1)
2525    vals20 = np.where(abs(vals2) >= abs(missval2*0.9), None, vals2)
2526
2527    values1 = vals10.flatten() 
2528    values2 = vals20.flatten() 
2529
2530    vals1Nomiss = np.ones(len(values1), dtype=bool)
2531    vals2Nomiss = np.ones(len(values2), dtype=bool)
2532
2533    for i in range(len(values1)):
2534        if values1[i] is None:
2535            vals1Nomiss[i] = False
2536    for i in range(len(values2)):
2537        if values2[i] is None:
2538            vals2Nomiss[i] = False
2539
2540    v1 = np.array(values1[vals1Nomiss], dtype=float)
2541    v2 = np.array(values2[vals2Nomiss], dtype=float)
2542
2543    if len(v1) != len(v2):
2544        print errormsg
2545        print fname + ': length of masked matrices mat1:',len(v1),'and mat2:',len(v2),'does not match!'
2546        print errormsg
2547        quit(-1)
2548
2549    linregres = np.array(sts.linregress(v1, v2), dtype= np.float64)
2550
2551    return linregres
2552
2553def mask_space_stats(maskmat,statsvals,dim):
2554    """ Function to give back the multi-dimensional statisitcs of a given masked array
2555    maskmat=multidimensional masked array
2556    statsvals=[statn]:[values]
2557      [statn]: statistics to do:
2558        'quant', quantiles
2559      [values]: value for the statistics: Nquantiles
2560    dim= dimension to run the statistics
2561    """
2562    from sys import stdout
2563
2564    fname = 'mask_space_stats'
2565
2566    statn=statsvals.split(':')[0]
2567    if len(statsvals.split(':')) > 1:
2568        values=statsvals.split(':')[1]
2569
2570    maskshape = maskmat.shape
2571    Ndims = len(maskshape)
2572    if statn == 'quant':
2573        if len(statsvals.split(':')) == 1:
2574            print errormsg
2575            print fname + ': statistics "' + statn + '" requires a value!!!'
2576            print errormsg
2577            quit(-1)
2578        Nquants=int(values)
2579        if Ndims == 2:
2580            if dim == 0:
2581                statval = np.ones((21, maskshape[1]), dtype=np.float64)*fillValue
2582                for i in range(maskshape[1]):
2583                   percendone(i, maskshape[1], 5, 'quantiles')
2584                   statval[:,i] = mask_quantiles(maskmat[:,i],Nquants)
2585            if dim == 1:
2586                statval = np.ones((21, maskshape[0]), dtype=np.float64)*fillValue
2587                for i in range(maskshape[0]):
2588                   percendone(i, maskshape[0], 5, 'quantiles')
2589                   statval[:,i] = mask_quantiles(statval[i,:],Nquants)
2590        elif Ndims == 3:
2591            if dim == 0:
2592                statval = np.ones((21, maskshape[1], maskshape[2]), dtype=np.float64)*fillValue
2593                for i in range(maskshape[1]):
2594                    for j in range(maskshape[2]):
2595                        percendone(i*maskshape[2] + j, maskshape[1]*maskshape[2], 5, 'quantiles')
2596                        statval[:,i,j] = mask_quantiles(maskmat[:,i,j],Nquants)
2597            if dim == 1:
2598                statval = np.ones((21, maskshape[0], maskshape[2]), dtype=np.float64)*fillValue
2599                for i in range(maskshape[0]):
2600                    for j in range(maskshape[2]):
2601                        percendone(i*maskshape[2] + j, maskshape[0]*maskshape[2], 5, 'quantiles')
2602                        statval[:,i,j] = mask_quantiles(maskmat[i,:,j],Nquants)
2603            if dim == 2:
2604                statval = np.ones((21, maskshape[0], maskshape[1]), dtype=np.float64)*fillValue
2605                for i in range(maskshape[0]):
2606                    for j in range(maskshape[1]):
2607                        percendone(i*maskshape[1] + j, maskshape[0]*maskshape[1], 5, 'quantiles')
2608                        statval[:,i,j] = mask_quantiles(maskmat[i,j,:],Nquants)
2609        elif Ndims == 4:
2610            if dim == 0:
2611                statval = np.ones((21, maskshape[1], maskshape[2], maskshape[3]), dtype=np.float64)*fillValue
2612                for i in range(maskshape[1]):
2613                    for j in range(maskshape[2]):
2614                        for k in range(maskshape[3]):
2615                            percendone(i*maskshape[1]*maskshape[2] + j*maskshape[2] + k, maskshape[1]*maskshape[2]*maskshape[3], 5, 'quantiles')
2616                            statval[:,i,j,k] = mask_quantiles(maskmat[:,i,j,k],Nquants)
2617            if dim == 1:
2618                statval = np.ones((21, maskshape[0], maskshape[2], maskshape[3]), dtype=np.float64)*fillValue
2619                for i in range(maskshape[0]):
2620                    for j in range(maskshape[2]):
2621                        for k in range(maskshape[3]):
2622                            percendone(i*maskshape[0]*maskshape[2] + j*maskshape[2] + k, maskshape[0]*maskshape[2]*maskshape[3], 5, 'quantiles')
2623                            statval[:,i,j,k] = mask_quantiles(maskmat[i,:,j,k],Nquants)
2624            if dim == 2:
2625                statval = np.ones((21, maskshape[0], maskshape[1], maskshape[3]), dtype=np.float64)*fillValue
2626                for i in range(maskshape[0]):
2627                    for j in range(maskshape[1]):
2628                        for k in range(maskshape[3]):
2629                            percendone(i*maskshape[0]*maskshape[1] + j*maskshape[1] + k, maskshape[0]*maskshape[1]*maskshape[3], 5, 'quantiles')
2630                            statval[:,i,j,k] = mask_quantiles(maskmat[i,j,:,k],Nquants)
2631            if dim == 3:
2632                statval = np.ones((21, maskshape[0], maskshape[1], maskshape[2]), dtype=np.float64)*fillValue
2633                for i in range(maskshape[0]):
2634                    for j in range(maskshape[1]):
2635                        for k in range(maskshape[2]):
2636                            percendone(i*maskshape[0]*maskshape[1] + j*maskshape[1] + k, maskshape[0]*maskshape[1]*maskshape[2], 5, 'quantiles')
2637                            statval[:,i,j,k] = mask_quantiles(maskmat[i,j,k,:],Nquants)
2638        else:
2639            print errormsg
2640            print fname + ': size of matrix ', Ndims,'not ready!!!'
2641            print errormsg
2642            quit(-1)
2643
2644    else:
2645        print errormsg
2646        print fname + ':  statistics "' + statn + '" not ready!!!!'
2647        print errormsg
2648        quit(-1)
2649
2650    print stdout.write("\n")
2651   
2652    return statval
2653
2654class statsVal(object):
2655  """Statistics class providing
2656  vals = variable
2657  self.Nv = number of values
2658  self.minv = minimum value
2659  self.maxv = maximum value
2660  self.meanv = mean value
2661  self.mean2v = cuadratic mean value
2662  self.stdv = standard deviation value
2663  self.Nokvalues = number of correct values of variable
2664  self.quantilesv = quantiles (%5 bins) of the variable
2665  """
2666
2667  def __init__(self, vals):
2668    if vals is None:
2669      self.Nv = None
2670      self.minv = None
2671      self.maxv = None
2672      self.meanv = None
2673      self.mean2v = None
2674      self.stdv = None
2675      self.Nokvalues = None
2676      self.quantilesv = None
2677    else:
2678      values = vals.flatten() 
2679      self.Nv=len(values)
2680      self.minv=10000000000.
2681      self.maxv=-100000000.
2682      self.meanv=0.
2683      self.mean2v=0.
2684      self.stdv=0.
2685
2686      sortedvalues = sorted(values)
2687
2688      self.Nokvalues = 0
2689      for inum in range(self.Nv):
2690        if not values[inum] is None:
2691          self.Nokvalues = self.Nokvalues + 1
2692          if values[inum] < self.minv:
2693            self.minv = values[inum]
2694          if values[inum] > self.maxv:
2695            self.maxv = values[inum]
2696
2697          self.meanv = self.meanv+values[inum]
2698          self.mean2v = self.mean2v+values[inum]*values[inum]
2699
2700      self.meanv = self.meanv/float(self.Nokvalues)
2701      self.mean2v = self.mean2v/float(self.Nokvalues)
2702      self.stdv = np.sqrt(self.mean2v-self.meanv*self.meanv)
2703      self.quantilesv = []
2704      for iq in range(20):
2705        self.quantilesv.append(sortedvalues[int((self.Nv-1)*iq/20)])
2706
2707      self.quantilesv.append(sortedvalues[self.Nv-1])
2708      self.medianv = self.quantilesv[10]
2709
2710    return
2711
2712class Quantiles(object):
2713    """ Class to provide quantiles from a given arrayof values
2714    """
2715
2716    def __init__(self, values, Nquants):
2717        import numpy.ma as ma
2718
2719        if values is None:
2720            self.quantilesv = None
2721
2722        else:
2723            self.quantilesv = []
2724
2725            vals0 = values.flatten()
2726            Nvalues = len(vals0)
2727            vals = ma.masked_equal(vals0, None)
2728            Nvals=len(vals.compressed())
2729
2730            sortedvals = sorted(vals.compressed())
2731            for iq in range(Nquants):
2732                self.quantilesv.append(sortedvals[int((Nvals-1)*iq/Nquants)])
2733
2734            self.quantilesv.append(sortedvals[Nvals-1])
2735
2736        return
2737
2738class statsVal_missVal(object):
2739  """Statistics class tacking into account a missing value providing
2740  vals = variable
2741  missval = missing value
2742  self.Nv = number of values
2743  self.minv = minimum value
2744  self.maxv = maximum value
2745  self.meanv = mean value
2746  self.mean2v = cuadratic mean value
2747  self.stdv = standard deviation value
2748  self.Nokvalues = number of correct values of variable
2749  self.quantilesv = quantiles (%5 bins) of the variable
2750  """
2751
2752  def __init__(self, vals, missVal):
2753    fname='statsVal_missVal'
2754 
2755    if vals is None:
2756      self.Nv = None
2757      self.minv = None
2758      self.maxv = None
2759      self.meanv = None
2760      self.mean2v = None
2761      self.stdv = None
2762      self.Nokvalues = None
2763      self.quantilesv = None
2764    else:
2765      Npt = 1
2766      for idim in range(len(vals.shape)):
2767        Npt = Npt * vals.shape[idim]
2768      if np.sum(vals >= missVal) == Npt:
2769          print errormsg
2770          print '  ' + fname + ' all values get missing!!'
2771          print errormsg
2772          quit(-1)
2773
2774      vals1 = np.where(abs(vals) >= missVal, None, vals)
2775      vals0 = np.where(np.isnan(vals1), None, vals1)
2776
2777      values = vals0.flatten() 
2778      self.Nv=Npt
2779      self.minv=10000000000.
2780      self.maxv=-100000000.
2781      self.meanv=0.
2782      self.mean2v=0.
2783      self.stdv=0.
2784
2785      sortedvalues = sorted(values)
2786
2787      self.Nokvalues = 0
2788      for inum in range(self.Nv):
2789        if not values[inum] is None:
2790          self.Nokvalues = self.Nokvalues + 1
2791          if values[inum] < self.minv:
2792            self.minv = values[inum]
2793          if values[inum] > self.maxv:
2794            self.maxv = values[inum]
2795
2796          self.meanv = self.meanv+values[inum]
2797          self.mean2v = self.mean2v+values[inum]*values[inum]
2798
2799      self.meanv = self.meanv/float(self.Nokvalues)
2800      self.mean2v = self.mean2v/float(self.Nokvalues)
2801      self.stdv = np.sqrt(self.mean2v-self.meanv*self.meanv)
2802      self.quantilesv = []
2803      for iq in range(20):
2804        self.quantilesv.append(sortedvalues[int((self.Nv-1)*iq/20)])
2805
2806      self.quantilesv.append(sortedvalues[self.Nv-1])
2807      self.medianv = self.quantilesv[10]
2808
2809    return
2810
2811def printing_class(classobj):
2812    """ Function to print all the values of a given class
2813    """
2814
2815    valscls = vars(classobj)
2816    for attrcls in valscls:
2817        print attrcls, ':', valscls[attrcls]
2818
2819    return
2820
2821def fmtprinting_class(classobj):
2822    """ Function to print all the values of a given class
2823    """
2824
2825    valscls = vars(classobj)
2826    for attrcls in valscls:
2827        print '@' + attrcls + '@', ':', valscls[attrcls]
2828
2829    return
2830
2831def cycl_incr(cyclval,cycle,ninc):
2832    """ Function to increment a cyclic value [cyclval] with a cycle [cycle] a given number [ninc] of times
2833    >>> cycl_incr(1,4,1)
2834    2
2835    >>> cycl_incr(3,4,1)
2836    0
2837    >>> cycl_incr(1,4,10)
2838    3
2839    """
2840
2841    if ninc >= cycle:
2842        print 'cycl_incr: WARNING -- warning -- WARNING -- warning'
2843        print '    given increment: ', ninc,' is larger than the cycle !!'
2844        ninc = ninc - cycle*int(ninc/cycle)
2845        print '    reducing it to: ', ninc
2846
2847    val=cyclval + ninc
2848    if val >= cycle:
2849        val=cyclval + ninc - cycle
2850
2851    return val
2852
2853def times_4seasons(tvals, integrity):
2854    """ Function to split a time series in matricial date format ([:,year,mon,day,hour,minute,second]) in the four stations DJF,MAM,JJA,SON
2855    tvals= matrix withe times as [:,year,mon,day,hour,minute,second]
2856    integrity= only give values for entire seasons [True, 3 months for the season], or just split the values by seasons [False]
2857    """
2858    fillVal=1.e20
2859
2860#    print tvals
2861
2862    dt=tvals.shape[0]
2863    seasons=np.ones((dt,4),dtype=bool)
2864    seasons=seasons*False
2865
2866    monseas=[12,3,6,9]
2867    firstseas=False
2868
2869    for it in range(dt):
2870        if not firstseas:
2871            if integrity:
2872                for iseas in range(4):
2873                    if tvals[it,1] == monseas[iseas]:
2874                        nseas=iseas
2875                        seasons[it,nseas]=True
2876                        firstseas=True
2877                        begseas=it
2878            else:
2879                for iseas in range(4):
2880                    for imon in range(3):
2881                        if tvals[it,1] == cycl_incr(monseas[iseas],12,imon):
2882                            nseas=iseas
2883                            seasons[it,nseas]=True
2884                            firstseas=True                   
2885        else:
2886            newseas=cycl_incr(nseas,4,1)
2887            if tvals[it,1] == monseas[newseas]:
2888                seasons[it,newseas] = True
2889                nseas=newseas
2890                begseas=it
2891            else:
2892                seasons[it,nseas] = True
2893
2894    endseas = it
2895##    print 'Last season: ',nseas,' beginnig: ',begseas,' ending: ',endseas
2896
2897# Checking integrity of last season (has to have 3 months)
2898##
2899    if integrity:
2900        fullseas=True
2901        Nmon=np.unique(tvals[begseas:endseas+1,1])
2902        for it in range(begseas,endseas): fullseas=fullseas*seasons[it,nseas]
2903        if len(Nmon) < 3 or not fullseas:
2904            seasons[begseas:endseas+1,nseas] = False
2905
2906    return seasons
2907
2908def realdatetime_CFcompilant(times, Srefdate, tunits):
2909    """ Function to transform a matrix with real time values ([year, month, day, hour, minute, second]) to a netCDF one
2910    times= matrix with times
2911    Srefdate= reference date ([YYYY][MM][DD][HH][MI][SS] format)
2912    tunits= units of time respect to Srefdate
2913    >>> realdatetime_CFcompilant(np.array([ [1976, 2, 17, 8, 20, 0], [1976, 2, 18, 8, 20, 0]], dtype=int), '19491201000000', 'hours')
2914    [ 229784.33333333  229808.33333333]
2915    """ 
2916
2917    import datetime as dt
2918    yrref=int(Srefdate[0:4])
2919    monref=int(Srefdate[4:6])
2920    dayref=int(Srefdate[6:8])
2921    horref=int(Srefdate[8:10])
2922    minref=int(Srefdate[10:12])
2923    secref=int(Srefdate[12:14])
2924 
2925    refdate=dt.datetime(yrref, monref, dayref, horref, minref, secref)
2926
2927    dimt=times.shape[0]
2928       
2929    cfdates = np.zeros((dimt), dtype=np.float64)
2930    if tunits == 'weeks':
2931        for it in range(dimt):
2932            cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate
2933            cfdates[it] = (cfdate.days + cfdate.seconds/(3600.*24.))/7.
2934    elif tunits == 'days':
2935        for it in range(dimt):
2936            cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate
2937            cfdates[it] = cfdate.days + cfdate.seconds/(3600.*24.)
2938    elif tunits == 'hours':
2939        for it in range(dimt):
2940            cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate
2941            cfdates[it] = cfdate.days*24. + cfdate.seconds/3600.
2942    elif tunits == 'minutes':
2943        for it in range(dimt):
2944            cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate
2945            cfdates[it] = cfdate.days*24.*60. + cfdate.seconds/60.
2946    elif tunits == 'seconds':
2947        for it in range(dimt):
2948            cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate
2949            cfdates[it] = cfdate.days*24.*3600. + cfdate.seconds
2950    elif tunits == 'milliseconds':
2951        for it in range(dimt):
2952            cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate
2953            cfdates[it] = cfdate.days*1000.*24.*3600. + cfdate.seconds*1000.
2954    elif tunits == 'microseconds':
2955        for it in range(dimt):
2956            cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate
2957            cfdates[it] = cfdate.days*1000000.*24.*3600. + cfdate.seconds*1000000.
2958    else:
2959        print errormsg
2960        print '  ' + fname + ': time units "' + tunits + '" is not ready!!!'
2961        quit(-1)
2962
2963    return cfdates
2964
2965def realdatetime1_CFcompilant(time, Srefdate, tunits):
2966    """ Function to transform a matrix with a real time value ([year, month, day,
2967      hour, minute, second]) to a netCDF one
2968        time= matrix with time
2969        Srefdate= reference date ([YYYY][MM][DD][HH][MI][SS] format)
2970        tunits= units of time respect to Srefdate
2971    >>> realdatetime1_CFcompilant([1976, 2, 17, 8, 20, 0], '19491201000000', 'hours')
2972    229784.33333333
2973    """ 
2974
2975    import datetime as dt
2976    yrref=int(Srefdate[0:4])
2977    monref=int(Srefdate[4:6])
2978    dayref=int(Srefdate[6:8])
2979    horref=int(Srefdate[8:10])
2980    minref=int(Srefdate[10:12])
2981    secref=int(Srefdate[12:14])
2982 
2983    refdate=dt.datetime(yrref, monref, dayref, horref, minref, secref)
2984
2985    if tunits == 'weeks':
2986        cfdate = dt.datetime(time[0],time[1],time[2],time[3],time[4],time[5])-refdate
2987        cfdates = (cfdate.days + cfdate.seconds/(3600.*24.))/7.
2988    elif tunits == 'days':
2989        cfdate = dt.datetime(time[0],time[1],time[2],time[3],time[4],time[5]) - refdate
2990        cfdates = cfdate.days + cfdate.seconds/(3600.*24.)
2991    elif tunits == 'hours':
2992        cfdate = dt.datetime(time[0],time[1],time[2],time[3],time[4],time[5]) - refdate
2993        cfdates = cfdate.days*24. + cfdate.seconds/3600.
2994    elif tunits == 'minutes':
2995        cfdate = dt.datetime(time[0],time[1],time[2],time[3],time[4],time[5]) - refdate
2996        cfdates = cfdate.days*24.*60. + cfdate.seconds/60.
2997    elif tunits == 'seconds':
2998        cfdate = dt.datetime(time[0],time[1],time[2],time[3],time[4],time[5]) - refdate
2999        cfdates = cfdate.days*24.*3600. + cfdate.seconds
3000    elif tunits == 'milliseconds':
3001        cfdate = dt.datetime(time[0],time[1],time[2],time[3],time[4],time[5]) - refdate
3002        cfdates = cfdate.days*1000.*24.*3600. + cfdate.seconds*1000.
3003    elif tunits == 'microseconds':
3004        cfdate = dt.datetime(time[0],time[1],time[2],time[3],time[4],times[5]) - refdate
3005        cfdates = cfdate.days*1000000.*24.*3600. + cfdate.seconds*1000000.
3006    else:
3007        print errormsg
3008        print '  ' + fname + ': time units "' + tunits + '" is not ready!!!'
3009        quit(-1)
3010
3011    return cfdates
3012
3013def netCDFdatetime_realdatetime(units, tcalendar, times):
3014    """ Function to transfrom from netCDF CF-compilant times to real time
3015    [units]= CF time units [tunits] since [YYYY]-[MM]-[HH] [[HH]:[MI]:[SS]]
3016    [tcalendar]= time calendar
3017    [times]= CF time values
3018    """
3019    import datetime as dt
3020
3021    txtunits = units.split(' ')
3022    tunits = txtunits[0]
3023    Srefdate = txtunits[len(txtunits) - 1]
3024
3025# Calendar type
3026##
3027    is360 = False
3028    if tcalendar is not None:
3029      print '  netCDFdatetime_realdatetime: There is a calendar attribute'
3030      if tcalendar == '365_day' or tcalendar == 'noleap':
3031          print '    netCDFdatetime_realdatetime: No leap years!'
3032          isleapcal = False
3033      elif tcalendar == 'proleptic_gregorian' or tcalendar == 'standard' or tcalendar == 'gregorian':
3034          isleapcal = True
3035      elif tcalendar == '360_day':
3036          is360 = True
3037          isleapcal = False
3038      else:
3039          print errormsg
3040          print '    netCDFdatetime_realdatetime: Calendar "' + tcalendar + '" not prepared!'
3041          quit(-1)
3042
3043# Does reference date contain a time value [YYYY]-[MM]-[DD] [HH]:[MI]:[SS]
3044##
3045    timeval = Srefdate.find(':')
3046
3047    if not timeval == -1:
3048        print '  netCDFdatetime_realdatetime: refdate with time!'
3049        refdate = datetimeStr_datetime(txtunits[len(txtunits) - 2] + '_' + Srefdate)
3050    else:
3051        refdate = dateStr_date(Srefdate)
3052
3053    dimt = len(times)
3054#    datetype = type(dt.datetime(1972,02,01))
3055#    realdates = np.array(dimt, datetype)
3056#    print realdates
3057
3058## Not in timedelta
3059#  if tunits == 'years':
3060#    for it in range(dimt):
3061#      realdate = refdate + dt.timedelta(years=float(times[it]))
3062#      realdates[it] = int(realdate.year)
3063#  elif tunits == 'months':
3064#    for it in range(dimt):
3065#      realdate = refdate + dt.timedelta(months=float(times[it]))
3066#      realdates[it] = int(realdate.year)
3067#    realdates = []
3068    realdates = np.zeros((dimt, 6), dtype=int)
3069    if tunits == 'weeks':
3070        for it in range(dimt):
3071            realdate = refdate + dt.timedelta(weeks=float(times[it]))
3072            realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second]
3073    elif tunits == 'days':
3074        for it in range(dimt):
3075            realdate = refdate + dt.timedelta(days=float(times[it]))
3076            realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second]
3077    elif tunits == 'hours':
3078        for it in range(dimt):
3079            realdate = refdate + dt.timedelta(hours=float(times[it]))
3080#            if not isleapcal:
3081#                Nleapdays = cal.leapdays(int(refdate.year), int(realdate.year))
3082#                realdate = realdate - dt.timedelta(days=Nleapdays)
3083#            if is360:
3084#                Nyears360 = int(realdate.year) - int(refdate.year) + 1
3085#                realdate = realdate -dt.timedelta(days=Nyears360*5)
3086#            realdates[it] = realdate
3087#        realdates = refdate + dt.timedelta(hours=float(times))
3088            realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second]
3089    elif tunits == 'minutes':
3090        for it in range(dimt):
3091            realdate = refdate + dt.timedelta(minutes=float(times[it]))
3092            realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second]
3093    elif tunits == 'seconds':
3094        for it in range(dimt):
3095            realdate = refdate + dt.timedelta(seconds=float(times[it]))
3096            realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second]
3097    elif tunits == 'milliseconds':
3098        for it in range(dimt):
3099            realdate = refdate + dt.timedelta(milliseconds=float(times[it]))
3100            realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second]
3101    elif tunits == 'microseconds':
3102        for it in range(dimt):
3103            realdate = refdate + dt.timedelta(microseconds=float(times[it]))
3104            realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second]
3105    else:
3106        print errormsg
3107        print '  netCDFdatetime_realdatetime: time units "' + tunits + '" is not ready!!!'
3108        quit(-1)
3109
3110    return realdates
3111
3112class cls_yearly_means(object):
3113    """ Class to compute the yearly mean of a time series of values
3114      tvals=time values (year, month, day, hour, minute, second) format
3115      values=time-series of values
3116      dateref= reference date [YYYY][MM][DD][HH][MI][SS] format
3117      tunits= time units
3118      self.dimt = Number of values
3119      self.yrv = yearly mean values
3120      self.yrt = years of the mean values
3121    >>> timesv = netCDFdatetime_realdatetime('days since 1949-12-01 00:00:00', 'standard', np.arange(1129))
3122    >>> valuesv = np.zeros((1129), dtype=np.float)
3123    >>> valuesv[0:31] = 0.
3124    >>> valuesv[31:394] = 1.
3125    >>> valuesv[395:761] = 2.
3126    >>> valuesv[761:1127] = 3.
3127    >>> valuesv[1127:1129] = 4.
3128
3129    >>> yrlmeans = cls_yearly_means(timesv, valuesv, '19491201000000', 'days')
3130    >>> print yrlmeans.dimt,yrlmeans.yrv, yrlmeans.yrt
3131    5 [ 0.  1.  2.  3.  4.] [ 1949.  1950.  1951.  1952.  1953.]
3132    """
3133    def __init__(self, tvals, values, dateref, tunits):
3134
3135        import numpy.ma as ma
3136        fillVal=1.e20
3137        fname = 'cls_yearly_means'
3138
3139        if tvals is None:
3140            self.dimt = None
3141            self.yrv = None
3142            self.yrt = None
3143
3144        elif tvals == 'h':
3145            print fname + '_____________________________________________________________'
3146            print cls_yearly_means.__doc__
3147            quit()
3148
3149        else:
3150            dt=len(values)
3151            if dt > 0:
3152                years = np.unique(tvals[:,0])
3153                Nyrs = len(years)
3154                yrmean = np.zeros((Nyrs), dtype=np.float)
3155                yrt = np.zeros((Nyrs), dtype=np.float)
3156
3157                iiyr = tvals[0,0]
3158                yrmean[0] = values[0]
3159                yrt[0] = iiyr
3160                iit = 0
3161                for iyr in range(Nyrs):
3162                    nvals = 1
3163                    for it in range(iit+1,dt):
3164#                        print iyr, iiyr, it, tvals[it,0],':',values[it],'->',yrmean[iyr]
3165                        if tvals[it,0] == iiyr:
3166                            yrmean[iyr] = yrmean[iyr] + values[it]
3167                            nvals = nvals + 1
3168                        else:
3169                            yrmean[iyr] = yrmean[iyr] / (nvals*1.)
3170                            iiyr = tvals[it,0]
3171                            yrmean[iyr + 1] = values[it]
3172                            yrt[iyr+1] = iiyr
3173                            iit = it
3174                            break
3175
3176                yrmean[Nyrs-1] = yrmean[Nyrs-1]/nvals
3177                self.dimt = Nyrs
3178                self.yrv = yrmean
3179                self.yrt = yrt
3180            else:
3181                print errormsg
3182                print '  ' + fname + ': No values passed!'
3183                print '    values:', values
3184                quit(-1)
3185
3186        return
3187
3188class cls_seasonal_means(object):
3189    """ Class to compute the seasonal mean of a time series of values
3190    tvals=time values (year, month, day, hour, minute, second) format
3191    values=time-series of values
3192    dateref= reference date [YYYY][MM][DD][HH][MI][SS] format
3193    tunits= time units
3194    self.dimt = Number of values
3195    self.seasv = seasonal mean values
3196    self.seast = seasonal time mean values
3197    """
3198    def __init__(self, tvals, values, dateref, tunits):
3199
3200        import numpy.ma as ma
3201        fillVal=1.e20
3202        fname = 'cls_seasonal_means'
3203
3204        if tvals is None:
3205            self.dimt = None
3206            self.seasv = None
3207            self.seast = None
3208
3209        else:
3210            tseasons=times_4seasons(tvals, True)
3211
3212            dt=len(values)
3213            seasvals=np.ones((dt/12,4), dtype=np.float64)*fillVal
3214            seastimes=np.zeros((dt/12,4), dtype=np.float64)
3215            dates = realdatetime_CFcompilant(tvals, dateref, tunits)
3216
3217            for iseas in range(4):
3218                for it in range(dt):
3219                    if tseasons[it,iseas]:
3220                        tfirstseas=int(it/11)
3221                        firstseas=True
3222##                        print '  first time-step of season ', iseas, ' is: ',it,' position: ',tfirstseas
3223                        break
3224                for itt in range(it, dt-1,12):
3225                    seasvals[int(itt/12),iseas]=(values[itt] + values[itt+1] + values[itt+2])/3.
3226                    seastimes[int(itt/12),iseas]=dates[itt] + (dates[itt+2] - dates[itt])/2.
3227##                    print itt, values[itt], values[itt+1], values[itt+2], '--->', seasvals[int(itt/12),iseas]
3228
3229            self.dimt = dt/12
3230            self.seasv = ma.masked_equal(seasvals, fillVal)
3231            self.seast = ma.masked_equal(seastimes, fillVal)
3232
3233        return
3234
3235class cls_seasonal_accums(object):
3236    """ Class to compute the seasonal accumulations of a time series of values
3237    tvals=time values (year, month, day, hour, minute, second) format
3238    values=time-series of values
3239    dateref= reference date [YYYY][MM][DD][HH][MI][SS] format
3240    tunits= time units
3241    self.dimt = Number of values
3242    self.seasv = seasonal mean values
3243    self.seast = seasonal time mean values
3244    """
3245    def __init__(self, tvals, values, dateref, tunits):
3246        import numpy.ma as ma
3247        fillVal=1.e20
3248
3249        if tvals is None:
3250            self.dimt = None
3251            self.seasv = None
3252            self.seast = None
3253
3254        else:
3255            tseasons=times_4seasons(tvals, True)
3256
3257            dt=len(values)
3258            seasvals=np.ones((dt/12,4), dtype=np.float64)*fillVal
3259            seastimes=np.zeros((dt/12,4), dtype=np.float64)
3260            dates = realdatetime_CFcompilant(tvals, dateref, tunits)
3261
3262            for iseas in range(4):
3263                for it in range(dt):
3264                    if tseasons[it,iseas]:
3265                        tfirstseas=int(it/11)
3266                        firstseas=True
3267#                        print '  first time-step of season ', iseas, ' is: ',it,' position: ',tfirstseas
3268                        break
3269                for itt in range(it, dt-1,12):
3270                    seasvals[int(itt/12),iseas]=values[itt] + values[itt+1] + values[itt+2]
3271                    seastimes[int(itt/12),iseas]=dates[itt] + (dates[itt+2] - dates[itt])/2.
3272
3273            self.dimt = dt/12
3274            self.seasv = ma.masked_equal(seasvals, fillVal)
3275            self.seast = ma.masked_equal(seastimes, fillVal)
3276
3277        return
3278
3279def seasonal_means(tvals, values):
3280    """ Function to compute the seasonal mean of a time series of values
3281    tvals=time values (year, month, day, hour, minute, second) format
3282    values=time-series of values
3283    """
3284    fillVal=1.e20
3285
3286    tseasons=times_4seasons(tvals, True)
3287
3288    dt=len(values)
3289    seasvals=np.ones((dt/4,4), dtype=np.float64)
3290    seasvals=seasvals*fillVal
3291
3292    for iseas in range(4):
3293        for it in range(dt):
3294            if tseasons[it,iseas]:
3295                tfirstseas=int(it/11)
3296                firstseas=True
3297#                print '  first time-step of season ', iseas, ' is: ',it,' position: ',tfirstseas
3298                break
3299        for itt in range(it, dt-1,12):
3300            seasvals[int(itt/12),iseas]=(values[itt] + values[itt+1] + values[itt+2])/3.
3301
3302    return seasvals
3303
3304def seasonal_accum(tvals, values):
3305    """ Function to compute the seasonal accumulation of a time series of values
3306    tvals=time values (year, month, day, hour, minute, second) format
3307    values=time-series of values
3308    """
3309    fillVal=1.e20
3310
3311    tseasons=times_4seasons(tvals, True)
3312
3313    dt=len(values)
3314    seasvals=np.ones((dt/4,4), dtype=np.float64)
3315    seasvals=seasvals*fillVal
3316
3317    for iseas in range(4):
3318        for it in range(dt):
3319            if tseasons[it,iseas]:
3320                tfirstseas=int(it/11)
3321                firstseas=True
3322#                print '  first time-step of season ', iseas, ' is: ',it,' position: ',tfirstseas
3323                break
3324        for itt in range(it, dt-1,12):
3325            seasvals[int(itt/11),iseas]=values[itt] + values[itt+1] + values[itt+2]
3326
3327    return seasvals
3328
3329def load_variable_lastdims(var, prevdims, Nlastdims):
3330    """ Function to load the last [Nlastdims] dimensions of a variable [var] at the other dimensions at [prevdims]
3331    >>> load_variable_lastdims(np.array(range(5*5*5)).reshape(5,5,5), [1,2], 1)
3332    [35 36 37 38 39]
3333    """
3334    fname='load_variable_lastdims'
3335
3336    dims=var.shape
3337    Ndims=len(dims)
3338
3339    Nprevdims = len(prevdims)
3340    if not Nprevdims + Nlastdims == Ndims:
3341        print erromsg
3342        print '  ' + fname + ': number of dimensions previous (',Nprevdim,') and last (',Nlastdims, ') does not match with variable size: ',Ndims,' !!!!'
3343        print errormsg
3344        quit(-1)
3345
3346    if Nlastdims > Ndims-1:
3347        print errormsg
3348        print '  ' + fname + ': number of last dimensions ', Nlastdims,' >= than the number of dimensions of the variable ', Ndims,' !!!!'
3349        print errormsg
3350        quit(-1)
3351
3352    if Ndims == 1:
3353        loadvar = var[:]
3354    elif Ndims == 2:
3355        loadvar = var[prevdims[0], :]
3356    elif Ndims == 3:
3357        if Nlastdims == 1:
3358            loadvar = var[prevdims[0], prevdims[1], :]
3359        else:
3360            loadvar = var[prevdims[0], :, :]
3361    elif Ndims == 4:
3362        if Nlastdims == 1:
3363            loadvar = var[prevdims[0], prevdims[1], prevdims[2], :]
3364        elif Nlastdims == 2:
3365            loadvar = var[prevdims[0], prevdims[1], :, :]
3366        else:
3367            loadvar = var[prevdims[0], :, :, :]
3368    elif Ndims == 5:
3369        if Nlastdims == 1:
3370            loadvar = var[prevdims[0], prevdims[1], prevdims[2], prevdims[3], :]
3371        elif Nlastdims == 2:
3372            loadvar = var[prevdims[0], prevdims[1], prevdims[2], :, :]
3373        elif Nlastdims == 3:
3374            loadvar = var[prevdims[0], prevdims[1], :, :, :]
3375        else:
3376            loadvar = var[prevdims[0], :, :, :, :]
3377    elif Ndims == 6:
3378        if Nlastdims == 1:
3379            loadvar = var[prevdims[0], prevdims[1], prevdims[2], prevdims[3], prevdims[4], :]
3380        elif Nlastdims == 2:
3381            loadvar = var[prevdims[0], prevdims[1], prevdims[2], prevdims[3], :, :]
3382        elif Nlastdims == 3:
3383            loadvar = var[prevdims[0], prevdims[1], prevdims[2], :, :, :]
3384        elif Nlastdims == 4:
3385            loadvar = var[prevdims[0], prevdims[1], :, :, :, :]
3386        else:
3387            loadvar = var[prevdims[0], :, :, :, :]
3388    else:
3389        print errormsg
3390        print '  ' + fname + ' variable size ', Ndims, ' not ready!!!'
3391        print errormsg
3392        quit(-1)
3393
3394    return loadvar
3395
3396def indices_mask(mask):
3397    """ Function to retrieve the indices from a 2D mask
3398    mask= 2D mask matrix
3399    mat=np.array(range(100), dtype=float).reshape((10,10))
3400    >>> mask1= mat >= 45.
3401    >>> mask2= mat <= 55.
3402    >>> mask = mask1 * mask2
3403    indices_mask(mask)
3404    [[4 5]
3405    [4 6]
3406    [4 7]
3407    [4 8]
3408    [4 9]
3409    [5 0]
3410    [5 1]
3411    [5 2]
3412    [5 3]
3413    [5 4]
3414    [5 5]]
3415    """
3416    dy=mask.shape[0]
3417    dx=mask.shape[1]
3418
3419    Nptmask = np.sum(mask)
3420    maskindices = np.zeros((Nptmask,2), dtype=int)
3421    ij=0
3422    for j in range(dy):
3423        for i in range(dx):
3424            if mask[j,i] == True:
3425                maskindices[ij,0] = j
3426                maskindices[ij,1] = i
3427                ij = ij + 1
3428
3429    return maskindices
3430
3431def typemod(value, typeval):
3432    """ Function to give back a value in a given dtype
3433    >>> print(typemod(8.2223, 'np.float64'))
3434    <type 'numpy.float64'>
3435    >>> print(typemod(8.2223, 'tuple'))
3436    <type 'tuple'>
3437    """
3438    fname='typemod'
3439
3440    if typeval == 'int':
3441        return int(value)
3442    elif typeval == 'long':
3443        return long(value)
3444    elif typeval == 'float':
3445        return float(value)
3446    elif typeval == 'complex':
3447        return complex(value)
3448    elif typeval == 'str':
3449        return str(value)
3450    elif typeval == 'bool':
3451        return bool(value)
3452    elif typeval == 'list':
3453        newval = []
3454        newval.append(value)
3455        return newval
3456    elif typeval == 'dic':
3457        newval = {}
3458        newval[value] = value
3459        return newval
3460    elif typeval == 'tuple':
3461        newv = []
3462        newv.append(value)
3463        newval = tuple(newv)
3464        return newval
3465    elif typeval == 'np.int8':
3466        return np.int8(value)
3467    elif typeval == 'np.int16':
3468        return np.int16(value)
3469    elif typeval == 'np.int32':
3470        return np.int32(value)
3471    elif typeval == 'np.int64':
3472        return np.int64(value)
3473    elif typeval == 'np.uint8':
3474        return np.uint8(value)
3475    elif typeval == 'np.uint16':
3476        return np.uint16(value)
3477    elif typeval == 'np.np.uint32':
3478        return np.uint32(value)
3479    elif typeval == 'np.uint64':
3480        return np.uint64(value)
3481    elif typeval == 'np.float':
3482        return np.float(value)
3483    elif typeval == 'np.float16':
3484        return np.float16(value)
3485    elif typeval == 'np.float32':
3486        return np.float32(value)
3487    elif typeval == 'float32':
3488        return np.float32(value)
3489    elif typeval == 'np.float64':
3490        return np.float64(value)
3491    elif typeval == 'float64':
3492        return np.float64(value)
3493    elif typeval == 'np.complex':
3494        return np.complex(value)
3495    elif typeval == 'np.complex64':
3496        return np.complex64(value)
3497    elif typeval == 'np.complex128':
3498        return np.complex128(value)
3499    else:
3500        print errormsg
3501        print fname + ':  data type "' + typeval + '" is not ready !'
3502        print errormsg
3503        quit(-1)
3504
3505    return
3506
3507def diffdate_units(diffdate, units):
3508    """ Function to transform a difference of dates to a certain units
3509    diffdate = difference of dates (as timedelta)
3510    units = units to transform: 'weeks', 'days', 'hours', 'minutes', 'seconds', 'miliseconds', 'nanoseconds'
3511    >>> diffdate_units(dt.datetime(1976, 2, 17, 8, 32, 5) - dt.datetime(1949, 12, 1, 0, 0, 0), 'seconds')
3512    827224325.0
3513    """
3514    fname = 'diffdate_units'
3515
3516    if units == 'weeks':
3517        diffunits = diffdate.days/7. + diffdate.seconds/(3600.*24.*7.)
3518    elif units == 'days':
3519        diffunits = diffdate.days + diffdate.seconds/(3600.*24.)
3520    elif units == 'hours':
3521        diffunits = diffdate.days*24. + diffdate.seconds/(3600.)
3522    elif units == 'minutes':
3523        diffunits = diffdate.days*24.*60. + diffdate.seconds/(60.)
3524    elif units == 'seconds':
3525        diffunits = diffdate.days*24.*3600. + diffdate.seconds
3526    elif units == 'miliseconds':
3527        diffunits = diffdate.days*24.*3600.*1000. + diffdate.seconds*1000.
3528    elif units == 'nanoseconds':
3529        diffunits = diffdate.days*24.*3600.*1000000. + diffdate.seconds*1000000.
3530    else:
3531        print errormsg
3532        print fname + ': time units "' + units + '" not ready!!!'
3533        print errormsg
3534        quit(-1)
3535
3536    return diffunits
3537
3538def days_month(year,month):
3539    """ Function to give the number of days of a month of a given year
3540    >>> days_month(1976,2)
3541    29
3542    """
3543    import datetime as dt
3544
3545    date1=dt.date(year,month,1)
3546    date2=dt.date(year,month+1,1)
3547
3548    diffdate = date2-date1
3549    return diffdate.days
3550
3551def mid_period(yr1,mon1,day1,hour1,min1,sec1,yr2,mon2,day2,hour2,min2,sec2):
3552    """ Function to give the mid poiint of a period
3553    >>> mid_period(1976,2,1,0,0,0,1976,3,1,0,0,0)
3554    [1976    2   15   12    0    0]
3555    """
3556    import datetime as dt
3557
3558    date1=dt.datetime(yr1,mon1,day1,hour1,min1,sec1)
3559    date2=dt.datetime(yr2,mon2,day2,hour2,min2,sec2)
3560
3561    diffdate = date2-date1
3562    diffseconds = diffdate.days*24*3600 + diffdate.seconds
3563    diff2 = dt.timedelta(seconds=diffseconds/2)
3564    datenew = date1 + diff2
3565    datenewvals = np.array([datenew.year, datenew.month, datenew.day, datenew.hour,  \
3566      datenew.minute, datenew.second])
3567
3568    return datenewvals
3569
3570def days_year(year):
3571    """ Function to give the number of days of a year
3572    >>> days_year(1976)
3573    366
3574    """
3575    import datetime as dt
3576
3577    date1=dt.date(year,1,1)
3578    date2=dt.date(year+1,1,1)
3579
3580    diffdate = date2-date1
3581    return diffdate.days
3582
3583def days_period(yeari,yearf):
3584    """ Function to give the number of days for a period
3585    >>> days_period(1976,1980)
3586    1827
3587    """
3588
3589    ndays=0   
3590    for iyr in range(yearf-yeari+1):
3591        ndays=ndays+days_year(yeari+iyr)
3592
3593    return ndays
3594
3595class ysubsetstats(object):
3596    """ Class to compute multi-year statistics of a given subset of values
3597    values= values to use
3598    dates=dates of the values in matrix format ([year], [month], [day], [hour], [minute], [second])
3599    sec=section to use for the period='year', 'month', 'day', 'hour', 'minute', 'second'
3600    vali=initial value of the period
3601    valf=final value of the period
3602    Nq= number of quantiles (20 for 5% bins, it is going to produce 21 values)
3603    missval= missing value
3604      self.Nvalues = Number of non masked values
3605      self.min = minimum non masked value
3606      self.max = maximum non masked value
3607      self.mean = mean non masked value
3608      self.mean2 = quandratic mean non masked value
3609      self.stdev = standard deviation non masked value
3610      self.quantiles = quantiles non masked value
3611    """ 
3612    def __init__(self, values, dates, sec, vali, valf, Nq, missVal):
3613        import numpy.ma as ma
3614
3615        fname = 'ysubsetstats'
3616 
3617        if values is None:
3618            self.Nvalues = None
3619            self.min = None
3620
3621            self.max = None
3622            self.mean = None
3623            self.mean2 = None
3624            self.stdev = None
3625            self.quantiles = None
3626
3627        else:
3628            Nvalues = len(values)
3629            Ndates = len(dates)
3630
3631            if Nvalues != Ndates:
3632                print errormsg
3633                print fname + ': number of values ', Nvalues,' does not coincide with the number of dates ',Ndates, '!!!!!!'
3634                print errormsg
3635                quit(-1)
3636
3637            initialsub = np.zeros(Nvalues, dtype=bool)
3638            endsub = initialsub.copy()
3639
3640            if missVal > 0.:
3641                valuesmask = ma.masked_greater_equal(values, missVal*0.9)
3642            else:
3643                valuesmask = ma.masked_less_equal(values, missVal*0.9)
3644
3645            if sec == 'year':
3646                isec = 0
3647            elif sec == 'month':
3648                isec = 1
3649            elif sec == 'day':
3650                isec = 2
3651            elif sec == 'hour':
3652                isec = 3
3653            elif sec == 'minute':
3654                isec = 4
3655            elif sec == 'second':
3656                isec = 5
3657            else:
3658                print errormsg
3659                print fname + ': sction "' + sec + '" not ready!!!!'
3660                print errormsg
3661                quit(-1)
3662   
3663            if vali < valf:
3664                timesmaskperi = ma.masked_less(dates[:,isec], vali)
3665                timesmaskperf = ma.masked_greater(dates[:,isec], valf)
3666            else:
3667                timesmaskperi = ma.masked_less(dates[:,isec], valf)
3668                timesmaskperf = ma.masked_greater(dates[:,isec], vali)
3669
3670            finalmask = valuesmask.mask+timesmaskperi.mask+timesmaskperf.mask
3671            finalvalues = ma.array(values, mask=finalmask)
3672
3673            finalvalues2 = finalvalues*finalvalues
3674
3675            self.Nvalues = finalvalues.count()
3676            self.min = finalvalues.min()
3677            self.max = finalvalues.max()
3678            self.mean = finalvalues.mean()
3679            self.mean2 = finalvalues2.mean()
3680            self.stdev = finalvalues.std()
3681            self.quantiles = mask_quantiles(finalvalues, Nq) 
3682
3683        return
3684
3685def give_fix1dim_values(mat,iddim,dimval):
3686    """ Function to return matrix values when one dimension has been removed at a
3687      given value
3688    mat = matrix
3689    iddim = dimesion to remove (starting from 0 tacking the right most)
3690    dimval = value of the dimension
3691
3692    >>> matrix = np.array( (range(27)), dtype=np.float).reshape(3,3,3)
3693    give_fix1dim_values(matrix,2,2)
3694    [[[  0.   1.   2.]
3695      [  3.   4.   5.]
3696      [  6.   7.   8.]]
3697
3698     [[  9.  10.  11.]
3699      [ 12.  13.  14.]
3700      [ 15.  16.  17.]]]
3701    """
3702    fname='give_fix1dim_values'
3703
3704# Not working ma.squeeze
3705##    import numpy.ma as ma
3706##    print ma.squeeze(mat, axis = (idim,))
3707   
3708    matshape = mat.shape
3709    mattype = mat.dtype
3710    matmask = np.ones( tuple(matshape), dtype=bool)
3711
3712    zerodims=np.ones( (6), dtype=int)
3713    Ndims = len(matshape)
3714    if Ndims > 6: 
3715        print errmsg
3716        print '  ' + fname + ' number of dimensions: ',Ndims,' not ready!!!!!'
3717        quit(-1)
3718
3719    zerodims[5-Ndims+1:6] = matshape
3720
3721    newdims = list(matshape)
3722    newdims[Ndims-1-iddim] = matshape[iddim]-1
3723
3724    mask = np.ones(tuple(zerodims), dtype=bool)
3725    vals = np.zeros(tuple(zerodims), dtype=mattype)
3726    vals[0:zerodims[0],0:zerodims[1],0:zerodims[2],0:zerodims[3],0:zerodims[4],
3727      0:zerodims[5]] = mat
3728
3729    for i5 in range(zerodims[5]):
3730        for i4 in range(zerodims[4]):
3731            for i3 in range(zerodims[3]):
3732                for i2 in range(zerodims[2]):
3733                    for i1 in range(zerodims[1]):
3734                        for i0 in range(zerodims[0]):
3735#                            print 'iddim:',iddim,'dimval:',dimval,'-->',i0,i1,i2,i3,i4,i5
3736                            if iddim == 5 and dimval == i0:
3737                                mask[i0,i1,i2,i3,i4,i5] = False
3738                            elif iddim == 4 and dimval == i1:
3739                                mask[i0,i1,i2,i3,i4,i5] = False
3740                            elif iddim == 3 and dimval == i2:
3741                                mask[i0,i1,i2,i3,i4,i5] = False
3742                            elif iddim == 2 and dimval == i3:
3743                                mask[i0,i1,i2,i3,i4,i5] = False
3744                            elif iddim == 1 and dimval == i4:
3745                                mask[i0,i1,i2,i3,i4,i5] = False
3746                            elif iddim == 0 and dimval == i5:
3747                                mask[i0,i1,i2,i3,i4,i5] = False
3748
3749    newmat = vals[mask].reshape(tuple(newdims))
3750#    print 'newmat dim:',iddim,'val:',dimval,':',newdims,'______'
3751#    print newmat
3752   
3753    return newmat
3754
3755def portion_fix1dim_values(mat,iddim,dimval):
3756    """ Function to return that portion of the matrix values when one dimension has
3757      been removed at a given value
3758    mat = matrix
3759    iddim = dimesion to remove (starting from 0 tacking the right most)
3760    dimval = value of the dimension
3761
3762    >>> matrix = np.array( (range(27)), dtype=np.float).reshape(3,3,3)
3763    portion_fix1dim_values(matrix,2,2)
3764    [[ 18.  19.  20.]
3765     [ 21.  22.  23.]
3766     [ 24.  25.  26.]]
3767    """
3768    fname='portion_fix1dim_values'
3769
3770# Not working ma.squeeze
3771##    import numpy.ma as ma
3772##    print ma.squeeze(mat, axis = (idim,))
3773   
3774    matshape = mat.shape
3775    mattype = mat.dtype
3776    matmask = np.zeros( tuple(matshape), dtype=bool)
3777
3778    zerodims=np.ones( (6), dtype=int)
3779    Ndims = len(matshape)
3780
3781    if Ndims > 6: 
3782        print errmsg
3783        print '  ' + fname + ' number of dimensions: ',Ndims,' not ready!!!!!'
3784        quit(-1)
3785
3786    zerodims[5-Ndims+1:6] = matshape
3787
3788    newdims = []
3789    for idim in range(Ndims):
3790        if idim != iddim:
3791            newdims.append(matshape[idim])
3792
3793    newdims.reverse()
3794
3795    mask = np.zeros(tuple(zerodims), dtype=bool)
3796    vals = np.zeros(tuple(zerodims), dtype=mattype)
3797    vals[0:zerodims[0],0:zerodims[1],0:zerodims[2],0:zerodims[3],0:zerodims[4],
3798      0:zerodims[5]] = mat
3799
3800    for i5 in range(zerodims[5]):
3801        for i4 in range(zerodims[4]):
3802            for i3 in range(zerodims[3]):
3803                for i2 in range(zerodims[2]):
3804                    for i1 in range(zerodims[1]):
3805                        for i0 in range(zerodims[0]):
3806#                            print 'iddim:',iddim,'dimval:',dimval,'-->',i0,i1,i2,i3,i4,i5
3807                            if iddim == 5 and dimval == i0:
3808                                mask[i0,i1,i2,i3,i4,i5] = True
3809                            elif iddim == 4 and dimval == i1:
3810                                mask[i0,i1,i2,i3,i4,i5] = True
3811                            elif iddim == 3 and dimval == i2:
3812                                mask[i0,i1,i2,i3,i4,i5] = True
3813                            elif iddim == 2 and dimval == i3:
3814                                mask[i0,i1,i2,i3,i4,i5] = True
3815                            elif iddim == 1 and dimval == i4:
3816                                mask[i0,i1,i2,i3,i4,i5] = True
3817                            elif iddim == 0 and dimval == i5:
3818                                mask[i0,i1,i2,i3,i4,i5] = True
3819
3820#    print 'newmat dim:',iddim,'val:',dimval,':',newdims,'______'
3821    newmat = vals[mask].reshape(tuple(newdims))
3822#    print newmat
3823   
3824    return newmat
3825
3826def retype(val, vtype):
3827    """ Function to transform a value to a given type
3828    retype(val, vtype)
3829      [val]= value
3830      [vtype]= type to transform
3831    >>> retype(0, type(True))
3832    False
3833    """
3834
3835    fname = 'retype'
3836
3837    if val == 'h':
3838        print fname + '_____________________________________________________________'
3839        print retype.__doc__
3840        quit()
3841
3842    if vtype == type(int(1)):
3843        newval = int(val)
3844    elif vtype == type(float(1)):
3845        newval = float(val)
3846#    elif vtype == type(float32(1)):
3847#        newval = float32(val)
3848    elif vtype == type(np.int(1)):
3849        typeinf = np.iinfo(np.int)
3850        if (abs(np.float64(val)) > typeinf.max):
3851            print warnmsg
3852            print '  ' + fname + ': value to transform ', val,' overpasses type:',   \
3853               vtype,' limits!!'
3854            print '  Changing value to kind largest allowed value:', typeinf.max
3855            newval = abs(np.float64(val))/np.float64(val) * np.int(typeinf.max)
3856        else:
3857            newval = np.int(val)
3858    elif vtype == type(np.int16(1)):
3859        typeinf = np.iinfo(np.int16)
3860        if (abs(np.float64(val)) > typeinf.max):
3861            print warnmsg
3862            print '  ' + fname + ': value to transform ', val,' overpasses type:',   \
3863               vtype,' limits!!'
3864            print '  Changing value to kind largest allowed value:', typeinf.max
3865            newval = abs(np.float64(val))/np.float64(val) * np.int16(typeinf.max)
3866        else:
3867            newval = np.int16(val)
3868    elif vtype == type(np.int32(1)):
3869        typeinf = np.iinfo(np.int32)
3870        if (np.abs(np.float64(val)) > typeinf.max):
3871            print warnmsg
3872            print '  ' + fname + ': value to transform ', val,' overpasses type:',   \
3873               vtype,' limits!!'
3874            print '  Changing value to kind largest allowed value:', typeinf.max
3875            newval = abs(np.float64(val))/np.float64(val) * np.int32(typeinf.max)
3876        else:
3877            newval = np.int32(np.float64(val))
3878    elif vtype == type(np.int64(1)):
3879        newval = np.int64(val)
3880    elif vtype == type(np.float(1)):
3881        newval = np.float(val)
3882#    elif vtype == type(np.float16(1)):
3883#        newval = np.float16(val)
3884    elif vtype == type(np.float32(1)):
3885        newval = np.float32(val)
3886    elif vtype == type(np.float64(1)):
3887        newval = np.float64(val)
3888    elif vtype == type(True):
3889        if val == 0:
3890            newval = False
3891        else:
3892            newval = True
3893    elif vtype == '|S1':
3894        newval = str(val)
3895    else:
3896        print errormsg
3897        print '  ' + fname + ': variable type "', vtype, '" not ready!!!'
3898        quit(-1)
3899
3900    return newval
3901
3902class stats_space2D(object):
3903    """spatial statistics for a 2D file:
3904      vals= variable ro check (assuming var[t,dy,dx])
3905        self.minv[t]: spatial minimum at each time-step
3906        self.maxv[t]: spatial maximum at each time-step
3907        self.meanv[t]: spatial mean at each time-step
3908        self.mean2v[t]: spatial quadratic mean at each time-step
3909        self.stdv[t]: spatial standard deviation at each time-step
3910        self.anomv[t]: spatial anomaly from the whole mean at each time-step
3911    """
3912 
3913    def __init__(self, vals):
3914        from scipy import stats as sts
3915        fname = 'stats_space2D'
3916
3917        if vals1 == 'h':
3918            print fname + '_____________________________________________________________'
3919            print stats_space2Dvars.__doc__
3920            quit()
3921
3922        if vals1 is None:
3923            self.minv = None
3924            self.maxv = None
3925            self.meanv = None
3926            self.mean2v = None
3927            self.stdv = None
3928        else:
3929            dimt = vals.shape[0]
3930            stats=np.zeros((dimt,5), dtype=np.float)
3931            absmean = np.mean(vals)
3932
3933            for it in range(dimt):
3934                stats[it,0]=np.min(vals[it,:,:])
3935                stats[it,1]=np.max(vals[it,:,:])
3936                stats[it,2]=np.mean(vals[it,:,:])
3937                stats[it,3]=np.mean(vals[it,:,:]*vals[it,:,:])
3938                stats[it,4]=absmean - stats[it,2]
3939
3940            stats = np.where(stats > 0.1*fillValue, fillValue, stats)
3941            stats = np.where(stats is nan, fillValue, stats)
3942            stats = np.where(stats is np.inf, fillValue, stats)
3943            stats = np.where(stats is None, fillValue, stats)
3944
3945            self.minv=stats[:,0]
3946            self.maxv=stats[:,1]
3947            self.meanv=stats[:,2]
3948            self.mean2v=stats[:,3]
3949            self.stdv=np.sqrt(stats[:,3]-stats[:,2]*stats[:,2])
3950            self.anomv=stats[:,4]
3951
3952        return
3953
3954class stats_space2Dvars(object):
3955    """spatial statistics beween 2 2D files:
3956    valsA = variable 1 (assuming var[t,dy,dx])
3957    valsB = variable 2 (assuming var[t,dy,dx])
3958    self.min[t,var], self.max[t,var], self.mean[t,var], self.mean2[t,var],
3959      self.std[t,var]
3960      [var] = var1+var2[v1Av2], var1-var2[v1Sv2], var1/var2[v1Dv2], var1*var2[v1Pv2]
3961
3962    self.mae=mean[t,abs(var1-var2)]
3963    self.correlation=correlation[var1,var2] (and p-value)
3964    self.bias=[t,mean(var1)-mean(var2)]
3965    self.meancorrelation=correlation[mean(var1),mean(var2)] (and p-value)
3966    """
3967
3968    def __init__(self, vals1, vals2):
3969        from scipy import stats as sts
3970        fname = 'stats_space2Dvars'
3971
3972        if vals1 == 'h':
3973            print fname + '_____________________________________________________________'
3974            print stats_space2Dvars.__doc__
3975            quit()
3976
3977        if vals1 is None:
3978            self.minv1Av2 = None
3979            self.maxv1Av2 = None
3980            self.meanv1Av2 = None
3981            self.mean2v1Av2 = None
3982            self.stdv1Av2 = None
3983            self.minv1Sv2 = None
3984            self.maxv1Sv2 = None
3985            self.meanv1Sv2 = None
3986            self.mean2v1Sv2 = None
3987            self.stdv1Sv2 = None
3988            self.minv1Dv2 = None
3989            self.maxv1Dv2 = None
3990            self.meanv1Dv2 = None
3991            self.mean2v1Dv2 = None
3992            self.stdv1Dv2 = None
3993            self.minv1Pv2 = None
3994            self.maxv1Pv2 = None
3995            self.meanv1Pv2 = None
3996            self.mean2v1Pv2 = None
3997            self.stdv1Pv2 = None
3998            self.mae = None
3999            self.corr = None
4000        else:
4001            dimt = vals1.shape[0]
4002            stats=np.zeros((dimt,26), dtype=np.float)
4003            meanvals1 = np.zeros((dimt), dtype=np.float)
4004            meanvals2 = np.zeros((dimt), dtype=np.float)
4005   
4006            for it in range(dimt):
4007                v1 = vals1[it,:,:].flatten() 
4008                v2 = vals2[it,:,:].flatten() 
4009
4010# add
4011                vs = v1 + v2
4012                stats[it,0] = np.min(vs)
4013                stats[it,1] = np.max(vs)
4014                stats[it,2] = np.mean(vs)
4015                stats[it,3] = np.mean(vs*vs)
4016                stats[it,4] = np.sqrt(stats[it,3] - stats[it,2]*stats[it,2])
4017# sub
4018                stats[it,20] = np.mean(np.abs(v1-v2))
4019                vs = v1 - v2
4020                stats[it,5] = np.min(vs)
4021                stats[it,6] = np.max(vs)
4022                stats[it,7] = np.mean(vs)
4023                stats[it,8] = np.mean(vs*vs)
4024                stats[it,9] = np.sqrt(stats[it,8] - stats[it,7]*stats[it,7])
4025
4026# mul
4027                vs = v1 * v2
4028                stats[it,10] = np.min(vs)
4029                stats[it,11] = np.max(vs)
4030                stats[it,12] = np.mean(vs)
4031                stats[it,13] = np.mean(vs*vs)
4032                stats[it,14] = np.sqrt(stats[it,13] - stats[it,12]*stats[it,12])
4033# div
4034                vs = v1 / v2
4035                stats[it,15] = np.min(vs)
4036                stats[it,16] = np.max(vs)
4037                stats[it,17] = np.mean(vs)
4038                stats[it,18] = np.mean(vs*vs)
4039                stats[it,19] = np.sqrt(stats[it,18] - stats[it,17]*stats[it,17])
4040# corr
4041                stats[it,21], stats[it,22] = mask_pearsonr(v1, v2)
4042
4043# Mean values
4044                meanvals1[it] = np.mean(v1)
4045                meanvals2[it] = np.mean(v2)
4046                stats[it,23] =  meanvals1[it] - meanvals2[it]
4047           
4048            stats = np.where(stats > 0.1*fillValue, fillValue, stats)
4049            stats = np.where(stats is np.nan, fillValue, stats)
4050            stats = np.where(stats is np.inf, fillValue, stats)
4051            stats = np.where(stats is None, fillValue, stats)
4052
4053            self.minv1Av2 = stats[:,0]
4054            self.maxv1Av2 = stats[:,1]
4055            self.meanv1Av2 = stats[:,2]
4056            self.meanv21Av2 = stats[:,3]
4057            self.stdv1Av2 = stats[:,4]
4058
4059            self.minv1Sv2 = stats[:,5]
4060            self.maxv1Sv2 = stats[:,6]
4061            self.meanv1Sv2 = stats[:,7]
4062            self.meanv21Sv2 = stats[:,8]
4063            self.stdv1Sv2 = stats[:,9]
4064
4065            self.minv1Pv2 = stats[:,10]
4066            self.maxv1Pv2 = stats[:,11]
4067            self.meanv1Pv2 = stats[:,12]
4068            self.meanv21Pv2 = stats[:,13]
4069            self.stdv1Pv2 = stats[:,14]
4070
4071            self.minv1Dv2 = stats[:,15]
4072            self.maxv1Dv2 = stats[:,16]
4073            self.meanv1Dv2 = stats[:,17]
4074            self.meanv21Dv2 = stats[:,18]
4075            self.stdv1Dv2 = stats[:,19]
4076
4077            self.mae = stats[:,20]
4078            self.corr = stats[:,21]
4079            self.p_value = stats[:,22]
4080
4081            self.bias = stats[:,23]
4082            self.meancorr, self.meanp_value = sts.pearsonr(meanvals1, meanvals2)
4083
4084        return
4085
4086class stats_time2D(object):
4087    """temporal statistics for a 2D file:
4088      vals= variable ro check (assuming var[t,dy,dx])
4089        self.minv[t]: temporal minimum at each grid point
4090        self.maxv[t]: temporal maximum at each grid point
4091        self.meanv[t]: temporal mean at each grid point
4092        self.mean2v[t]: temporal quadratic mean at each grid point
4093        self.stdv[t]: temporal standard deviation at each grid point
4094        self.anomv[t]: temporal anomaly from the whole mean at each grid point
4095    """
4096 
4097    def __init__(self, vals):
4098        from scipy import stats as sts
4099        fname = 'stats_time2D'
4100
4101        if vals1 == 'h':
4102            print fname + '_____________________________________________________________'
4103            print stats_time2Dvars.__doc__
4104            quit()
4105
4106        if vals1 is None:
4107            self.minv = None
4108            self.maxv = None
4109            self.meanv = None
4110            self.mean2v = None
4111            self.stdv = None
4112        else:
4113            dimx = vals.shape[2]
4114            dimy = vals.shape[1]
4115            stats=np.zeros((dimy,dimx,5), dtype=np.float)
4116            absmean = np.mean(vals,axis=0)
4117
4118            stats[:,:,0]=np.min(vals, axis=0)
4119            stats[:,:,1]=np.max(vals, axis=0)
4120            stats[:,:,2]=np.mean(vals, axis=0)
4121            stats[:,:,3]=np.mean(vals*vals, axis=0)
4122            stats[:,:,4]=absmean - stats[:,:,2]
4123
4124            stats = np.where(stats > 0.1*fillValue, fillValue, stats)
4125            stats = np.where(stats is np.nan, fillValue, stats)
4126            stats = np.where(stats is np.inf, fillValue, stats)
4127            stats = np.where(stats is None, fillValue, stats)
4128
4129            self.minv=stats[:,:,0]
4130            self.maxv=stats[:,:,1]
4131            self.meanv=stats[:,:,2]
4132            self.mean2v=stats[:,:,3]
4133            self.stdv=np.sqrt(stats[:,:,3]-stats[:,:,2]*stats[:,:,2])
4134            self.anomv=stats[:,:,4]
4135
4136        return
4137
4138class stats_time2Dvars(object):
4139    """temporal statistics beween 2 2D files:
4140    valsA = variable 1 (assuming var[t,dy,dx])
4141    valsB = variable 2 (assuming var[t,dy,dx])
4142    self.min[dy,dx,var], self.max[dy,dx,var], self.mean[dy,dx,var],
4143      self.mean2[dy,dx,var], self.std[dy,dx,var]
4144      [var] = var1+var2[v1Av2], var1-var2[v1Sv2], var1/var2[v1Dv2], var1*var2[v1Pv2]
4145
4146    self.mae=mean[dy,dx,abs(var1-var2)]
4147    self.correlation=correlation[var1,var2] (and p-value)
4148    self.bias=[dy,dx,mean(var1)-mean(var2)]
4149    self.meancorrelation=correlation[mean(var1),mean(var2)] (and p-value)
4150    """
4151
4152    def __init__(self, vals1, vals2):
4153        from scipy import stats as sts
4154        fname = 'stats_time2Dvars'
4155
4156        if vals1 == 'h':
4157            print fname + '_____________________________________________________________'
4158            print stats_time2Dvars.__doc__
4159            quit()
4160
4161        if vals1 is None:
4162            self.minv1Av2 = None
4163            self.maxv1Av2 = None
4164            self.meanv1Av2 = None
4165            self.mean2v1Av2 = None
4166            self.stdv1Av2 = None
4167            self.minv1Sv2 = None
4168            self.maxv1Sv2 = None
4169            self.meanv1Sv2 = None
4170            self.mean2v1Sv2 = None
4171            self.stdv1Sv2 = None
4172            self.minv1Dv2 = None
4173            self.maxv1Dv2 = None
4174            self.meanv1Dv2 = None
4175            self.mean2v1Dv2 = None
4176            self.stdv1Dv2 = None
4177            self.minv1Pv2 = None
4178            self.maxv1Pv2 = None
4179            self.meanv1Pv2 = None
4180            self.mean2v1Pv2 = None
4181            self.stdv1Pv2 = None
4182            self.mae = None
4183            self.corr = None
4184        else:
4185            dimx = vals1.shape[1]
4186            dimy = vals1.shape[1]
4187            stats=np.zeros((dimy,dimx,24), dtype=np.float)
4188            meanvals1 = np.zeros((dimy,dimx), dtype=np.float)
4189            meanvals2 = np.zeros((dimy,dimx), dtype=np.float)
4190# add
4191            vs = vals1 + vals2
4192            stats[:,:,0] = np.min(vs,axis=0)
4193            stats[:,:,1] = np.max(vs,axis=0)
4194            stats[:,:,2] = np.mean(vs,axis=0)
4195            stats[:,:,3] = np.mean(vs*vs,axis=0)
4196            stats[:,:,4] = np.sqrt(stats[:,:,3] - stats[:,:,2]*stats[:,:,2])
4197# sub
4198            stats[:,:,20] = np.mean(np.abs(vals1-vals2), axis=0)
4199            vs = vals1 - vals2
4200            stats[:,:,5] = np.min(vs,axis=0)
4201            stats[:,:,6] = np.max(vs,axis=0)
4202            stats[:,:,7] = np.mean(vs,axis=0)
4203            stats[:,:,8] = np.mean(vs*vs,axis=0)
4204            stats[:,:,9] = np.sqrt(stats[:,:,8] - stats[:,:,7]*stats[:,:,7])
4205# mul
4206            vs = vals1 * vals2
4207            stats[:,:,10] = np.min(vs,axis=0)
4208            stats[:,:,11] = np.max(vs,axis=0)
4209            stats[:,:,12] = np.mean(vs,axis=0)
4210            stats[:,:,13] = np.mean(vs*vs,axis=0)
4211            stats[:,:,14] = np.sqrt(stats[:,:,13] - stats[:,:,12]*stats[:,:,12])
4212# div
4213            vs = vals1 / vals2
4214            stats[:,:,15] = np.min(vs,axis=0)
4215            stats[:,:,16] = np.max(vs,axis=0)
4216            stats[:,:,17] = np.mean(vs,axis=0)
4217            stats[:,:,18] = np.mean(vs*vs,axis=0)
4218            stats[:,:,19] = np.sqrt(stats[:,:,18] - stats[:,:,17]*stats[:,:,17])
4219
4220
4221# Mean values
4222            meanvals1[:,:] = np.mean(vals1,axis=0)
4223            meanvals2[:,:] = np.mean(vals2,axis=0)
4224            stats[:,:,23] =  meanvals1[:,:] - meanvals2[:,:]
4225           
4226# corr
4227            self.meancorr, self.meanp_value = sts.pearsonr(meanvals1.flatten(), meanvals2.flatten())
4228
4229            for j in range(dimy):
4230                for i in range(dimx):
4231                    stats[j,i,21], stats[j,i,22] = sts.pearsonr(vals1[:,j,i], vals2[:,j,i])
4232
4233            stats = np.where(stats > 0.1*fillValue, fillValue, stats)
4234            stats = np.where(stats is np.nan, fillValue, stats)
4235            stats = np.where(stats is np.inf, fillValue, stats)
4236            stats = np.where(stats is None, fillValue, stats)
4237
4238            self.minv1Av2 = stats[:,:,0]
4239            self.maxv1Av2 = stats[:,:,1]
4240            self.meanv1Av2 = stats[:,:,2]
4241            self.meanv21Av2 = stats[:,:,3]
4242            self.stdv1Av2 = stats[:,:,4]
4243
4244            self.minv1Sv2 = stats[:,:,5]
4245            self.maxv1Sv2 = stats[:,:,6]
4246            self.meanv1Sv2 = stats[:,:,7]
4247            self.meanv21Sv2 = stats[:,:,8]
4248            self.stdv1Sv2 = stats[:,:,9]
4249
4250            self.minv1Pv2 = stats[:,:,10]
4251            self.maxv1Pv2 = stats[:,:,11]
4252            self.meanv1Pv2 = stats[:,:,12]
4253            self.meanv21Pv2 = stats[:,:,13]
4254            self.stdv1Pv2 = stats[:,:,14]
4255
4256            self.minv1Dv2 = stats[:,:,15]
4257            self.maxv1Dv2 = stats[:,:,16]
4258            self.meanv1Dv2 = stats[:,:,17]
4259            self.meanv21Dv2 = stats[:,:,18]
4260            self.stdv1Dv2 = stats[:,:,19]
4261
4262            self.mae = stats[:,:,20]
4263            self.corr = stats[:,:,21]
4264            self.p_value = stats[:,:,22]
4265
4266            self.bias = stats[:,:,23]
4267
4268        return
4269
4270#vals1 = np.arange(27).reshape(3,3,3)*1.
4271#vals2 = np.arange(1,28).reshape(3,3,3)*1.
4272
4273#printing_class(stats_time2Dvars(vals1,vals2))
4274
4275def file_nlines(filen,char):
4276    """ Function to provide the number of lines of a file
4277    filen= name of the file
4278    char= character as no line
4279    >>> file_nlines('trajectory.dat','#')
4280    49
4281    """
4282    fname = 'file_nlines'
4283
4284    if not os.path.isfile(filen):
4285        print errormsg
4286        print '  ' + fname + ' file: "' + filen + '" does not exist !!'
4287        quit(-1)
4288
4289    fo = open(filen,'r')
4290
4291    nlines=0
4292    for line in fo: 
4293        if line[0:1] != char: nlines = nlines + 1
4294
4295    fo.close()
4296
4297    return nlines
4298
4299def datetimeStr_conversion(StringDT,typeSi,typeSo):
4300    """ Function to transform a string date to an another date object
4301    StringDT= string with the date and time
4302    typeSi= type of datetime string input
4303    typeSo= type of datetime string output
4304      [typeSi/o]
4305        'cfTime': [time],[units]; ]time in CF-convention format [units] = [tunits] since [refdate]
4306        'matYmdHMS': numerical vector with [[YYYY], [MM], [DD], [HH], [MI], [SS]]
4307        'YmdHMS': [YYYY][MM][DD][HH][MI][SS] format
4308        'Y-m-d_H:M:S': [YYYY]-[MM]-[DD]_[HH]:[MI]:[SS] format
4309        'Y-m-d H:M:S': [YYYY]-[MM]-[DD] [HH]:[MI]:[SS] format
4310        'Y/m/d H-M-S': [YYYY]/[MM]/[DD] [HH]-[MI]-[SS] format
4311        'WRFdatetime': [Y], [Y], [Y], [Y], '-', [M], [M], '-', [D], [D], '_', [H],
4312          [H], ':', [M], [M], ':', [S], [S]
4313    >>> datetimeStr_conversion('1976-02-17_08:32:05','Y-m-d_H:M:S','matYmdHMS')
4314    [1976    2   17    8   32    5]
4315    >>> datetimeStr_conversion(str(137880)+',minutes since 1979-12-01_00:00:00','cfTime','Y/m/d H-M-S')
4316    1980/03/05 18-00-00
4317    """
4318    import datetime as dt
4319
4320    fname = 'datetimeStr_conversion'
4321
4322    if StringDT[0:1] == 'h':
4323        print fname + '_____________________________________________________________'
4324        print datetimeStr_conversion.__doc__
4325        quit()
4326
4327    if typeSi == 'cfTime':
4328        timeval = np.float(StringDT.split(',')[0])
4329        tunits = StringDT.split(',')[1].split(' ')[0]
4330        Srefdate = StringDT.split(',')[1].split(' ')[2]
4331
4332# Does reference date contain a time value [YYYY]-[MM]-[DD] [HH]:[MI]:[SS]
4333##
4334        yrref=Srefdate[0:4]
4335        monref=Srefdate[5:7]
4336        dayref=Srefdate[8:10]
4337
4338        trefT = Srefdate.find(':')
4339        if not trefT == -1:
4340#            print '  ' + fname + ': refdate with time!'
4341            horref=Srefdate[11:13]
4342            minref=Srefdate[14:16]
4343            secref=Srefdate[17:19]
4344            refdate = datetimeStr_datetime( yrref + '-' + monref + '-' + dayref +    \
4345              '_' + horref + ':' + minref + ':' + secref)
4346        else:
4347            refdate = datetimeStr_datetime( yrref + '-' + monref + '-' + dayref +    \
4348              + '_00:00:00')
4349
4350        if tunits == 'weeks':
4351            newdate = refdate + dt.timedelta(weeks=float(timeval))
4352        elif tunits == 'days':
4353            newdate = refdate + dt.timedelta(days=float(timeval))
4354        elif tunits == 'hours':
4355            newdate = refdate + dt.timedelta(hours=float(timeval))
4356        elif tunits == 'minutes':
4357            newdate = refdate + dt.timedelta(minutes=float(timeval))
4358        elif tunits == 'seconds':
4359            newdate = refdate + dt.timedelta(seconds=float(timeval))
4360        elif tunits == 'milliseconds':
4361            newdate = refdate + dt.timedelta(milliseconds=float(timeval))
4362        else:
4363              print errormsg
4364              print '    timeref_datetime: time units "' + tunits + '" not ready!!!!'
4365              quit(-1)
4366
4367        yr = newdate.year
4368        mo = newdate.month
4369        da = newdate.day
4370        ho = newdate.hour
4371        mi = newdate.minute
4372        se = newdate.second
4373    elif typeSi == 'matYmdHMS':
4374        yr = StringDT[0]
4375        mo = StringDT[1]
4376        da = StringDT[2]
4377        ho = StringDT[3]
4378        mi = StringDT[4]
4379        se = StringDT[5]
4380    elif typeSi == 'YmdHMS':
4381        yr = int(StringDT[0:4])
4382        mo = int(StringDT[4:6])
4383        da = int(StringDT[6:8])
4384        ho = int(StringDT[8:10])
4385        mi = int(StringDT[10:12])
4386        se = int(StringDT[12:14])
4387    elif typeSi == 'Y-m-d_H:M:S':
4388        dateDT = StringDT.split('_')
4389        dateD = dateDT[0].split('-')
4390        timeT = dateDT[1].split(':')
4391        yr = int(dateD[0])
4392        mo = int(dateD[1])
4393        da = int(dateD[2])
4394        ho = int(timeT[0])
4395        mi = int(timeT[1])
4396        se = int(timeT[2])
4397    elif typeSi == 'Y-m-d H:M:S':
4398        dateDT = StringDT.split(' ')
4399        dateD = dateDT[0].split('-')
4400        timeT = dateDT[1].split(':')
4401        yr = int(dateD[0])
4402        mo = int(dateD[1])
4403        da = int(dateD[2])
4404        ho = int(timeT[0])
4405        mi = int(timeT[1])
4406        se = int(timeT[2])
4407    elif typeSi == 'Y/m/d H-M-S':
4408        dateDT = StringDT.split(' ')
4409        dateD = dateDT[0].split('/')
4410        timeT = dateDT[1].split('-')
4411        yr = int(dateD[0])
4412        mo = int(dateD[1])
4413        da = int(dateD[2])
4414        ho = int(timeT[0])
4415        mi = int(timeT[1])
4416        se = int(timeT[2])
4417    elif typeSi == 'WRFdatetime':
4418        yr = int(StringDT[0])*1000 + int(StringDT[1])*100 + int(StringDT[2])*10 +    \
4419          int(StringDT[3])
4420        mo = int(StringDT[5])*10 + int(StringDT[6])
4421        da = int(StringDT[8])*10 + int(StringDT[9])
4422        ho = int(StringDT[11])*10 + int(StringDT[12])
4423        mi = int(StringDT[14])*10 + int(StringDT[15])
4424        se = int(StringDT[17])*10 + int(StringDT[18])
4425    else:
4426        print errormsg
4427        print '  ' + fname + ': type of String input date "' + typeSi +              \
4428          '" not ready !!!!'
4429        quit(-1)
4430
4431    if typeSo == 'matYmdHMS':
4432        dateYmdHMS = np.zeros((6), dtype=int)
4433        dateYmdHMS[0] =  yr
4434        dateYmdHMS[1] =  mo
4435        dateYmdHMS[2] =  da
4436        dateYmdHMS[3] =  ho
4437        dateYmdHMS[4] =  mi
4438        dateYmdHMS[5] =  se
4439    elif typeSo == 'YmdHMS':
4440        dateYmdHMS = str(yr).zfill(4) + str(mo).zfill(2) + str(da).zfill(2) +        \
4441          str(ho).zfill(2) + str(mi).zfill(2) + str(se).zfill(2)
4442    elif typeSo == 'Y-m-d_H:M:S':
4443        dateYmdHMS = str(yr).zfill(4) + '-' + str(mo).zfill(2) + '-' +               \
4444          str(da).zfill(2) + '_' + str(ho).zfill(2) + ':' + str(mi).zfill(2) + ':' + \
4445          str(se).zfill(2)
4446    elif typeSo == 'Y-m-d H:M:S':
4447        dateYmdHMS = str(yr).zfill(4) + '-' + str(mo).zfill(2) + '-' +               \
4448          str(da).zfill(2) + ' ' + str(ho).zfill(2) + ':' + str(mi).zfill(2) + ':' + \
4449          str(se).zfill(2)
4450    elif typeSo == 'Y/m/d H-M-S':
4451        dateYmdHMS = str(yr).zfill(4) + '/' + str(mo).zfill(2) + '/' +               \
4452          str(da).zfill(2) + ' ' + str(ho).zfill(2) + '-' + str(mi).zfill(2) + '-' + \
4453          str(se).zfill(2) 
4454    elif typeSo == 'WRFdatetime':
4455        dateYmdHMS = []
4456        yM = yr/1000
4457        yC = (yr-yM*1000)/100
4458        yD = (yr-yM*1000-yC*100)/10
4459        yU = yr-yM*1000-yC*100-yD*10
4460
4461        mD = mo/10
4462        mU = mo-mD*10
4463       
4464        dD = da/10
4465        dU = da-dD*10
4466
4467        hD = ho/10
4468        hU = ho-hD*10
4469
4470        miD = mi/10
4471        miU = mi-miD*10
4472
4473        sD = se/10
4474        sU = se-sD*10
4475
4476        dateYmdHMS.append(str(yM))
4477        dateYmdHMS.append(str(yC))
4478        dateYmdHMS.append(str(yD))
4479        dateYmdHMS.append(str(yU))
4480        dateYmdHMS.append('-')
4481        dateYmdHMS.append(str(mD))
4482        dateYmdHMS.append(str(mU))
4483        dateYmdHMS.append('-')
4484        dateYmdHMS.append(str(dD))
4485        dateYmdHMS.append(str(dU))
4486        dateYmdHMS.append('_')
4487        dateYmdHMS.append(str(hD))
4488        dateYmdHMS.append(str(hU))
4489        dateYmdHMS.append(':')
4490        dateYmdHMS.append(str(miD))
4491        dateYmdHMS.append(str(miU))
4492        dateYmdHMS.append(':')
4493        dateYmdHMS.append(str(sD))
4494        dateYmdHMS.append(str(sU))
4495    else:
4496        print errormsg
4497        print '  ' + fname + ': type of output date "' + typeSo + '" not ready !!!!'
4498        quit(-1)
4499
4500    return dateYmdHMS
4501
4502def table_tex(tablevals, colnames, rownames, of):
4503    """ Function to write into a LaTeX tabukar from a table of values
4504      tablevals = (ncol nrow) of values
4505      colnames = list with ncol labels for the columns
4506      rownames = list with nrow labels for the rows
4507      of= object ASCII file to write the table
4508    """
4509    errormsg = 'ERROR -- error -- ERROR -- error'
4510
4511    fname = 'table_tex'
4512
4513    Ncol = tablevals.shape[0]
4514    Nrow = tablevals.shape[1]
4515
4516    if Ncol + 1 != len(colnames):
4517        print errormsg
4518        print '  ' + fname + ': wrong number of column names!!'
4519        print '    data has:', Ncol, 'and you provided:', len(colnames)
4520        print '    remember to provide one more for the label of the rows!'
4521        print '    you provide:',colnames
4522        quit(-1)
4523
4524    if Nrow != len(rownames):
4525        print errormsg
4526        print '  ' + fname + ': wrong number of row names!!'
4527        print '    data has:', Nrow, 'and you provided:', len(rownames)
4528        print '    you provide:',rownames
4529        quit(-1)
4530
4531    colcs = ''
4532    colns = ''
4533    for icol in colnames:
4534        colcs = colcs + 'c'
4535        if icol == colnames[0]:
4536            colns = ' {\\bfseries{' + icol + '}}'
4537        else:
4538            colns = colns + ' & {\\bfseries{' + icol + '}}'
4539
4540    of.write('\n')
4541    of.write("%Automatically written file from function '" + fname + "'\n")
4542    of.write('\\begin{tabular}{l'+colcs+'}\n')
4543    of.write(colns + ' \\\\ \\hline\n')
4544
4545    ir = 0
4546    for irow in rownames:
4547        rowns = '{\\bfseries{' + irow + '}}'
4548        for ic in range(Ncol):
4549            rowns = rowns + ' & ' + str(tablevals[ic,ir])
4550        rowns = rowns + ' \\\\'
4551
4552        of.write(rowns + '\n')
4553        ir = ir + 1
4554
4555    of.write('\\end{tabular}\n')
4556
4557    return
4558
4559def radius_dist(dx,dy,ptx,pty):
4560    """ Function to generate a matrix with the distance at a given point
4561    radius_dist(dx,dy,ptx,pty)
4562      [dx/y]: dimension of the matrix
4563      [ptx/y]: grid point coordinates of the point
4564    >>> radius_dist(3,5,2,2)
4565    [[ 1.41421356  1.          1.41421356  2.23606798  3.16227766]
4566     [ 1.          0.          1.          2.          3.        ]
4567     [ 1.41421356  1.          1.41421356  2.23606798  3.16227766]]
4568    """
4569
4570    fname = 'radius_dist'
4571
4572    if ptx < 0 or ptx > dx-1 or pty < 0 or pty > dy-1:
4573        print errormsg
4574        print '  ' + fname + ': wrong point coordinates:',dx,',',dy,'for matrix;',dx \
4575         ,'x',dy
4576        quit(-1)
4577
4578    xdist =  np.zeros((dx,dy), dtype=np.float)
4579    ydist =  np.zeros((dx,dy), dtype=np.float)
4580    dist =  np.zeros((dx,dy), dtype=np.float)
4581
4582    for ix in range(dx):
4583        xdist[ix,:] = np.float(ix-ptx)
4584    for iy in range(dy):
4585        ydist[:,iy] = np.float(iy-pty)
4586
4587    dist = np.sqrt(xdist*xdist + ydist*ydist)
4588
4589    return dist
4590
4591def lonlat2D(lon,lat):
4592    """ Function to return lon, lat 2D matrices from any lon,lat matrix
4593      lon= matrix with longitude values
4594      lat= matrix with latitude values
4595    """
4596    fname = 'lonlat2D'
4597
4598    if len(lon.shape) != len(lat.shape):
4599        print errormsg
4600        print '  ' + fname + ': longitude values with shape:', lon.shape,            \
4601          'is different that latitude values with shape:', lat.shape, '(dif. size) !!'
4602        quit(-1)
4603
4604    if len(lon.shape) == 3:
4605        lonvv = lon[0,:,:]
4606        latvv = lat[0,:,:]
4607    elif len(lon.shape) == 2:
4608        lonvv = lon[:]
4609        latvv = lat[:]
4610    elif len(lon.shape) == 1:
4611        lonlatv = np.meshgrid(lon[:],lat[:])
4612        lonvv = lonlatv[0]
4613        latvv = lonlatv[1]
4614
4615    return lonvv, latvv
4616
4617
4618def interpolate_locs(locs,coords,kinterp):
4619    """ Function to provide interpolate locations on a given axis
4620    interpolate_locs(locs,axis,kinterp)
4621      locs= locations to interpolate
4622      coords= axis values with the reference of coordinates
4623      kinterp: kind of interpolation
4624        'lin': linear
4625    >>> coordinates = np.arange((10), dtype=np.float)
4626    >>> values = np.array([-1.2, 2.4, 5.6, 7.8, 12.0])
4627    >>> interpolate_locs(values,coordinates,'lin')
4628    [ -1.2   2.4   5.6   7.8  13. ]
4629    >>> coordinates[0] = 0.5
4630    >>> coordinates[2] = 2.5
4631    >>> interpolate_locs(values,coordinates,'lin')
4632    [ -3.4          1.93333333   5.6          7.8         13.        ]
4633    """
4634
4635    fname = 'interpolate_locs'
4636
4637    if locs == 'h':
4638        print fname + '_____________________________________________________________'
4639        print interpolate_locs.__doc__
4640        quit()
4641
4642    Nlocs = locs.shape[0]
4643    Ncoords = coords.shape[0]
4644
4645    dcoords = coords[Ncoords-1] - coords[0]
4646
4647    intlocs = np.zeros((Nlocs), dtype=np.float)
4648    minc = np.min(coords)
4649    maxc = np.max(coords)
4650
4651    for iloc in range(Nlocs):
4652        for icor in range(Ncoords-1):
4653            if locs[iloc] < minc and dcoords > 0.:
4654                a = 0.
4655                b = 1. / (coords[1] - coords[0])
4656                c = coords[0]
4657            elif locs[iloc] > maxc and dcoords > 0.:
4658                a = (Ncoords-1)*1.
4659                b = 1. / (coords[Ncoords-1] - coords[Ncoords-2])
4660                c = coords[Ncoords-2]
4661            elif locs[iloc] < minc and dcoords < 0.:
4662                a = (Ncoords-1)*1.
4663                b = 1. / (coords[Ncoords-1] - coords[Ncoords-2])
4664                c = coords[Ncoords-2]
4665            elif locs[iloc] > maxc and dcoords < 0.:
4666                a = 0.
4667                b = 1. / (coords[1] - coords[0])
4668                c = coords[0]
4669            elif locs[iloc] >= coords[icor] and locs[iloc] < coords[icor+1] and dcoords > 0.:
4670                a = icor*1.
4671                b = 1. / (coords[icor+1] - coords[icor])
4672                c = coords[icor]
4673                print coords[icor], locs[iloc], coords[icor+1], ':', icor, '->', a, b
4674            elif locs[iloc] <= coords[icor] and locs[iloc] > coords[icor+1] and dcoords < 0.:
4675                a = icor*1.
4676                b = 1. / (coords[icor+1] - coords[icor])
4677                c = coords[icor]
4678
4679        if kinterp == 'lin':
4680            intlocs[iloc] = a + (locs[iloc] - c)*b
4681        else:
4682            print errormsg
4683            print '  ' + fname + ": interpolation kind '" + kinterp + "' not ready !!!!!"
4684            quit(-1)
4685
4686    return intlocs
4687
4688def vertical_interpolation2D(varb,vart,zorigvals,znewval,kinterp):
4689    """ Function to vertically integrate a 3D variable
4690    vertical_interpolation2D(varb,vart,zorigvals,znewval)
4691      varb= values at the base of the interval of interpolation (2D field)
4692      vart= values at the top of the interval of interpolation (2D field)
4693      zorigvals= pair of original values (2, 2D field)
4694      znewval= new value to interpolate
4695      Possible cases:
4696        zorigvals[0,:,:] <= znewval < zorigvals[1,:,:]
4697        znewval <= zorigvals[0,:,:] < zorigvals[1,:,:]
4698        zorigvals[0,:,:] < zorigvals[1,:,:] <= znewval
4699      kinterp: kind of interpolation
4700        'lin': linear
4701    >>> dx=5
4702    >>> dy=7
4703    >>> vals1 = np.ones((dy,dx), dtype=np.float)
4704    >>> vals2 = np.ones((dy,dx), dtype=np.float)*2.
4705
4706    >>> zbase = np.zeros((2,dy,dx), dtype=np.float)
4707    >>> zbase[0,:,:] = 0.5
4708    >>> zbase[1,:,:] = 1.
4709
4710    >>> vertical_interpolation2D(vals1,vals2, zbase, newz,'lin')
4711    [[ 1.5  1.5  1.5  1.5  1.5]
4712     [ 1.5  1.5  1.5  1.5  1.5]
4713     [ 1.5  1.5  1.5  1.5  1.5]
4714     [ 1.5  1.5  1.5  1.5  1.5]
4715     [ 1.5  1.5  1.5  1.5  1.5]
4716     [ 1.5  1.5  1.5  1.5  1.5]
4717     [ 1.5  1.5  1.5  1.5  1.5]]
4718    """
4719
4720    fname = 'vertical_interpolation2D'
4721
4722    if varb == 'h':
4723        print fname + '_____________________________________________________________'
4724        print vertical_interpolation2D.__doc__
4725        quit()
4726
4727    newvar = np.zeros((varb.shape), dtype=np.float)
4728    if kinterp == 'lin':
4729##        print '  ' + fname + ' Vertical linear interpolation at',znewval
4730# Standard linear interpolation (y = a + b*incz)
4731#   a = zorig[0], b = (vart-varb)/(zorig[1]-zorig[0])), incz = znewval - zorig[0]
4732        a = varb
4733        b = np.where(zorigvals[1,:,:] == zorigvals[0,:,:], 0.,                       \
4734          (vart - varb)/(zorigvals[1,:,:] - zorigvals[0,:,:]))
4735        incz = np.ones((varb.shape), dtype=np.float)*znewval - zorigvals[0,:,:]
4736
4737        newvar = a + b*incz
4738# Too code for not be used... but maybe?
4739#        dx=varb.shape[1]
4740#        dy=varb.shape[0]
4741#        for j in range(dy):
4742#            for i in range(dx):
4743#                  if zorigvals[1,j,i] == zorigvals[0,j,i]: print 'equals!',          \
4744#                    zorigvals[1,j,i], zorigvals[0,j,i],':',newvar[j,i],'@',vart[j,i]
4745#                  if zorigvals[0,j,i] != zorigvals[0,j,i]: print '0 Nan',            \
4746#                    zorigvals[0,j,i],':',newvar[j,i],'@',vart[j,i]
4747#                  if zorigvals[1,j,i] != zorigvals[1,j,i]: print '1 Nan',            \
4748#                    zorigvals[1,j,i],':',newvar[j,i],'@',vart[j,i]
4749#                  if zorigvals[0,j,i] is None: print '0 None', zorigvals[0,j,i],':', \
4750#                    newvar[j,i],'@',vart[j,i]
4751#                  if zorigvals[1,j,i] is None: print '1 None', zorigvals[1,j,i],':', \
4752#                    newvar[j,i],'@',vart[j,i]
4753    else:
4754        print errormsg
4755        print '  ' + fname + ": interpolation kind '" + kinterp + "' not ready !!!!!"
4756        quit(-1)
4757
4758    return newvar
4759
4760#dx=5
4761#dy=7
4762#vals1 = np.ones((dy,dx), dtype=np.float)
4763#vals2 = np.ones((dy,dx), dtype=np.float)*2.
4764
4765#zbase = np.zeros((2,dy,dx), dtype=np.float)
4766#zbase[0,:,:] = 0.5
4767#for i in range(dx):
4768#    for j in range(dy):
4769#        zbase[1,j,i] = np.sqrt((j-dy/2.)**2. + (i-dx/2.)**2.) /                      \
4770#          np.sqrt((dy/2.)**2.+(dy/2.)**2.) + 1.
4771
4772#zbase[1,:,:] = 1.
4773
4774#newz = 0.75
4775
4776#print vertical_interpolation2D(vals1,vals2, zbase, newz,'lin')
4777
4778def vertical_interpolation(varb,vart,zorigvals,znewval,kinterp):
4779    """ Function to vertically integrate a 1D variable
4780    vertical_interpolation(varb,vart,zorigvals,znewval)
4781      varb= values at the base of the interval of interpolation
4782      vart= values at the top of the interval of interpolation
4783      zorigvals= pair of original values (2)
4784      znewval= new value to interpolate
4785      Possible cases:
4786        zorigvals[0,:] <= znewval < zorigvals[1,:]
4787        znewval <= zorigvals[0,:] < zorigvals[1,:]
4788        zorigvals[0,:] < zorigvals[1,:] <= znewval
4789      kinterp: kind of interpolation
4790        'lin': linear
4791    >>> dx=5
4792    >>> vals1 = np.ones((dx), dtype=np.float)
4793    >>> vals2 = np.ones((dx), dtype=np.float)*2.
4794
4795    >>> zbase = np.zeros((2,dx), dtype=np.float)
4796    >>> zbase[0,:] = 0.5
4797    >>> for i in range(dx):
4798    >>>     zbase[1,i] = i + 1.
4799
4800    >>> newz = 0.75
4801    >>> vertical_interpolation2D(vals1,vals2, zbase, newz,'lin')
4802    [ 1.5         1.16666667  1.1         1.07142857  1.05555556]
4803    """
4804
4805    fname = 'vertical_interpolation'
4806
4807    if varb == 'h':
4808        print fname + '_____________________________________________________________'
4809        print vertical_interpolation.__doc__
4810        quit()
4811
4812    newvar = np.zeros((varb.shape), dtype=np.float)
4813    if kinterp == 'lin':
4814##        print '  ' + fname + ' Vertical linear interpolation at',znewval
4815# Standard linear interpolation (y = a + b*incz)
4816#   a = zorig[0], b = (vart-varb)/(zorig[1]-zorig[0])), incz = znewval - zorig[0]
4817        a = varb
4818        b = np.where(zorigvals[1,:] == zorigvals[0,:], 0.,                           \
4819          (vart - varb)/(zorigvals[1,:] - zorigvals[0,:]))
4820        incz = np.ones((varb.shape), dtype=np.float)*znewval - zorigvals[0,:]
4821
4822        newvar = a + b*incz
4823    else:
4824        print errormsg
4825        print '  ' + fname + ": interpolation kind '" + kinterp + "' not ready !!!!!"
4826        quit(-1)
4827
4828    return newvar
4829
4830def interpolate_3D(zorigvs, varv, zintvs, kint):
4831    """ Function to interpolate a 3D variable
4832    interpolate_3D(zintvs, varv, zorigvals)
4833      zorigvs= original 3D z values
4834      varv= 3D variable to interpolate
4835      zintvs= new series of z values to interpolate
4836      kint= kind of interpolation
4837        'lin': linear
4838    """
4839    fname = 'interpolate_3D'
4840
4841    if zorigvs == 'h':
4842        print fname + '_____________________________________________________________'
4843        print interpolate_3D.__doc__
4844        quit()
4845
4846    Ninv = len(zintvs)
4847    dimv = varv.shape
4848
4849# Sense of the original z-variable
4850    Lzorig = zorigvs.shape[0]
4851    incz = zorigvs[Lzorig-1,0,0] - zorigvs[0,0,0]
4852
4853    varin = np.zeros((Ninv,dimv[1],dimv[2]), dtype=np.float)
4854
4855    for ilev in range(Ninv):
4856#        print ' vertical interpolate level: ',zintvs[ilev]
4857        valinf = np.zeros((dimv[1], dimv[2]), dtype=np.float)
4858        valsup = np.zeros((dimv[1], dimv[2]), dtype=np.float)
4859        zorigv = np.zeros((2,dimv[1], dimv[2]), dtype=np.float)
4860        for j in range(valinf.shape[0]):
4861            for i in range(valinf.shape[1]):
4862               
4863                if np.min(zorigvs[:,j,i]) > zintvs[ilev] and incz > 0.:
4864                    valinf[j,i] = varv[0,j,i]
4865                    valsup[j,i] = varv[1,j,i]
4866                    zorigv[0,j,i] = zorigvs[0,j,i]
4867                    zorigv[1,j,i] = zorigvs[1,j,i]
4868                elif np.max(zorigvs[:,j,i]) < zintvs[ilev] and incz < 0.:
4869                    valinf[j,i] = varv[0,j,i]
4870                    valsup[j,i] = varv[1,j,i]
4871                    zorigv[0,j,i] = zorigvs[0,j,i]
4872                    zorigv[1,j,i] = zorigvs[1,j,i]
4873                elif np.max(zorigvs[:,j,i]) < zintvs[ilev] and incz > 0.:
4874                    valinf[j,i] = varv[Lzorig-2,j,i]
4875                    valsup[j,i] = varv[Lzorig-1,j,i]
4876                    zorigv[0,j,i] = zorigvs[Lzorig-2,j,i]
4877                    zorigv[1,j,i] = zorigvs[Lzorig-1,j,i]
4878                elif np.min(zorigvs[:,j,i]) > zintvs[ilev] and incz < 0.:
4879                    valinf[j,i] = varv[Lzorig-2,j,i]
4880                    valsup[j,i] = varv[Lzorig-1,j,i]
4881                    zorigv[0,j,i] = zorigvs[Lzorig-2,j,i]
4882                    zorigv[1,j,i] = zorigvs[Lzorig-1,j,i]
4883#                    print 'top: ',i,j,':',zorigv[0,j,i], zintvs[ilev], zorigv[1,j,i]
4884                else:
4885                    for z in range(Lzorig-1):
4886                        if (zorigvs[z,j,i]-zintvs[ilev])*(zorigvs[z+1,j,i]-          \
4887                          zintvs[ilev]) <= 0.:
4888                            valinf[j,i] = varv[z,j,i]
4889                            valsup[j,i] = varv[z+1,j,i]
4890                            zorigv[0,j,i] = zorigvs[z,j,i]
4891                            zorigv[1,j,i] = zorigvs[z+1,j,i]
4892                            break
4893
4894#        print 'zorigvs: ',zorigvs[:,0,0]
4895#        print '  valinf:', valinf[0,0]
4896#        print '  valsup:', valsup[0,0]
4897#        print '  zorigv 0:',zorigv[0,0,0]
4898#        print '  zorigv 1:',zorigv[1,0,0]
4899
4900        varin[ilev,:,:] = vertical_interpolation2D(valinf,valsup,zorigv,             \
4901          zintvs[ilev], kint)
4902#        print '  varin:',varin[ilev,0,0]
4903#        quit()
4904
4905#    quit()
4906    return varin
4907
4908def interpolate_2D(zorigvs0, varv0, zdim, zintvs, kint):
4909    """ Function to interpolate a 2D variable
4910    interpolate_2D(zintvs, varv, zorigvals)
4911      zorigvs= original 2D z values
4912      varv= 2D variable to interpolate
4913      zdim= number of the dimension with the z-values
4914      zintvs= new series of z values to interpolate
4915      kint= kind of interpolation
4916        'lin': linear
4917    """
4918    fname = 'interpolate_2D'
4919
4920    if zorigvs0 == 'h':
4921        print fname + '_____________________________________________________________'
4922        print interpolate_2D.__doc__
4923        quit()
4924
4925    Ninv = len(zintvs)
4926    if zdim == 0:
4927        varv = varv0
4928        zorigvs = zorigvs0
4929    else:
4930        varv = np.transpose(varv0)
4931        zorigvs = np.transpose(zorigvs0)
4932
4933    dimv = varv.shape
4934
4935# Sense of the original z-variable
4936    Lzorig = zorigvs.shape[0]
4937    incz = zorigvs[Lzorig-1,0] - zorigvs[0,0]
4938
4939    varin = np.zeros((Ninv,dimv[1]), dtype=np.float)
4940
4941    for ilev in range(Ninv):
4942        valinf = np.zeros((dimv[1]), dtype=np.float)
4943        valsup = np.zeros((dimv[1]), dtype=np.float)
4944        zorigv = np.zeros((2,dimv[1]), dtype=np.float)
4945        for i in range(valinf.shape[0]):   
4946            if np.min(zorigvs[:,i]) > zintvs[ilev] and incz > 0.:
4947                valinf[i] = varv[0,i]
4948                valsup[i] = varv[1,i]
4949                zorigv[0,i] = zorigvs[0,i]
4950                zorigv[1,i] = zorigvs[1,i]
4951            elif np.max(zorigvs[:,i]) < zintvs[ilev] and incz < 0.:
4952                valinf[i] = varv[0,i]
4953                valsup[i] = varv[1,i]
4954                zorigv[0,i] = zorigvs[0,i]
4955                zorigv[1,i] = zorigvs[1,i]
4956            elif np.max(zorigvs[:,i]) < zintvs[ilev] and incz > 0.:
4957                valinf[i] = varv[Lzorig-2,i]
4958                valsup[i] = varv[Lzorig-1,i]
4959                zorigv[0,i] = zorigvs[Lzorig-2,i]
4960                zorigv[1,i] = zorigvs[Lzorig-1,i]
4961            elif np.min(zorigvs[:,i]) > zintvs[ilev] and incz < 0.:
4962                valinf[i] = varv[Lzorig-2,i]
4963                valsup[i] = varv[Lzorig-1,i]
4964                zorigv[0,i] = zorigvs[Lzorig-2,i]
4965                zorigv[1,i] = zorigvs[Lzorig-1,i]
4966            else:
4967                for z in range(Lzorig-1):
4968                    if (zorigvs[z,i]-zintvs[ilev])*(zorigvs[z+1,i]-                  \
4969                      zintvs[ilev]) <= 0.:
4970                        valinf[i] = varv[z,i]
4971                        valsup[i] = varv[z+1,i]
4972                        zorigv[0,i] = zorigvs[z,i]
4973                        zorigv[1,i] = zorigvs[z+1,i]
4974                        break
4975
4976        varin[ilev,:] = vertical_interpolation(valinf,valsup,zorigv,                 \
4977          zintvs[ilev], kint)
4978
4979    if zdim == 0:
4980        varin0 = varin
4981    else:
4982        varin0 = np.transpose(varin)
4983
4984    return varin0
4985
4986def list_toVec(listv, kind):
4987    """ Function to transform from a list of values to a vector
4988    list_toVec(listv, kind)
4989      listv= list with the values
4990      kind= kind of values
4991      >>> list_toVec(['1', 2, '3', 4, 5, '6.9', 7, 9], 'npfloat')
4992      [ 1.   2.   3.   4.   5.   6.9  7.   9. ]
4993    """
4994
4995    fname = 'list_toVec'
4996
4997    if listv == 'h':
4998        print fname + '_____________________________________________________________'
4999        print list_toVec.__doc__
5000        quit()
5001
5002    Nvals = len(listv)
5003
5004    if kind == 'npfloat':
5005        vecv = np.zeros((Nvals), dtype=np.float)
5006        for iv in range(Nvals):
5007            vecv[iv] = np.float(listv[iv])
5008    else:
5009        print errormsg
5010        print '  ' + fname + ': type of value "' + kind + '" not ready!!'
5011        quit(-1)
5012
5013    return vecv
5014
5015def running_mean(values, run):
5016    """ Function to compute a running mean of a series of values
5017      running_mean(vals, int)
5018      [vals]: series of values
5019      [run]: interval to use to compute the running mean
5020        NOTE: resultant size would be the same but with None except at [run/2,size(vals)-run/2]
5021      >>> running_mean(np.arange(100),10)
5022      [None None None None None 4.5 5.5 6.5 7.5 8.5 9.5 10.5 11.5 12.5 13.5 14.5
5023       15.5 16.5 17.5 18.5 19.5 20.5 21.5 22.5 23.5 24.5 25.5 26.5 27.5 28.5 29.5
5024       30.5 31.5 32.5 33.5 34.5 35.5 36.5 37.5 38.5 39.5 40.5 41.5 42.5 43.5 44.5
5025       45.5 46.5 47.5 48.5 49.5 50.5 51.5 52.5 53.5 54.5 55.5 56.5 57.5 58.5 59.5
5026       60.5 61.5 62.5 63.5 64.5 65.5 66.5 67.5 68.5 69.5 70.5 71.5 72.5 73.5 74.5
5027       75.5 76.5 77.5 78.5 79.5 80.5 81.5 82.5 83.5 84.5 85.5 86.5 87.5 88.5 89.5
5028       90.5 91.5 92.5 93.5 None None None None None]
5029    """
5030    fname = 'running_mean'
5031
5032    if values == 'h':
5033        print fname + '_____________________________________________________________'
5034        print running_mean.__doc__
5035        quit()
5036
5037    runmean = np.ones((len(values)), dtype=np.float)*fillValue
5038
5039    for ip in range(run/2,len(values)-run/2):
5040        runmean[ip] = np.mean(values[ip-run/2:ip+run/2])
5041
5042    runmean = np.where(runmean == fillValue, None, runmean)
5043
5044    return runmean
5045
5046def files_folder(folder,headfile):
5047    """ Function to retrieve a list of files from a folder [fold] and head [headfile]
5048    >>> files_folder('/media/data2/etudes/WRF_LMDZ/WL_HyMeX_HighRes/medic950116/',
5049      'wrfout_d03')
5050    ['wrfout_d03_1995-01-13_02:00:00', 'wrfout_d03_1995-01-13_04:00:00', 'wrfout_d03_1995-01-13_06:00:00',
5051     'wrfout_d03_1995-01-13_06:15:00', 'wrfout_d03_1995-01-13_08:15:00', 'wrfout_d03_1995-01-13_10:15:00',
5052     'wrfout_d03_1995-01-13_12:15:00', 'wrfout_d03_1995-01-13_14:15:00', 'wrfout_d03_1995-01-13_16:15:00',     
5053     (...)
5054     'wrfout_d03_1995-01-17_18:15:00', 'wrfout_d03_1995-01-17_20:15:00', 'wrfout_d03_1995-01-17_22:15:00']
5055    """
5056    import subprocess as sub
5057    fname = 'files_folder'
5058
5059    if folder == 'h':
5060        print fname + '_____________________________________________________________'
5061        print files_folder.__doc__
5062        quit()
5063
5064#    ins = folder + "/" + headfile + "*"
5065    ins = folder + "/"
5066    print 'ins:',ins
5067    files = sub.Popen(["/bin/ls","-1",ins], stdout=sub.PIPE)
5068    fileslist = files.communicate()
5069    listfiles0 = str(fileslist).split('\\n')
5070
5071# Filtering output
5072    Lheader=len(headfile)
5073    listfiles = []
5074    for ifile in listfiles0:
5075        if ifile[0:Lheader] == headfile:
5076            listfiles.append(ifile)
5077
5078    return listfiles
5079
5080def count_cond(var, val, con):
5081    """ Function to count values of a variable which attain a condition
5082      [var]= variable
5083      [val]= value
5084      [con]= statistics/condition
5085        'eq': equal than [val]
5086        'neq': not equal than [val]
5087        'lt': less than [val]
5088        'le': less and equal than [val]
5089        'gt': greater than [val]
5090        'ge': greater and equal than [val]
5091        'in': inside the range [val[0]] <= [var] <= [val[1]] (where [val]=[val1, val2]
5092        'out': inside the range [val[0]] > [var]; [val[1]] < [var] (where [val]=[val1, val2]
5093      >>> vals = np.arange(100)
5094      >>> count_cond(vals,50,'eq')
5095      1
5096      >>> count_cond(vals,50,'neq')
5097      99
5098      >>> count_cond(vals,50,'lt')
5099      50
5100      >>> count_cond(vals,50,'le')
5101      51
5102      >>> count_cond(vals,50,'gt')
5103      49
5104      >>> count_cond(vals,50,'ge')
5105      50
5106      >>> count_cond(vals,[25,75],'in')
5107      51
5108      >>> count_cond(vals,[25,75],'out')
5109      49
5110    """
5111    fname = 'count_cond'
5112
5113    cons = ['eq', 'neq', 'lt', 'le', 'gt', 'ge', 'in', 'out']
5114
5115    if con == 'eq':
5116        Nvals = np.sum(var == val)
5117    elif con == 'neq':
5118        Nvals = np.sum(var != val)
5119    elif con == 'lt':
5120        Nvals = np.sum(var < val)
5121    elif con == 'le':
5122        Nvals = np.sum(var <= val)
5123    elif con == 'gt':
5124        Nvals = np.sum(var > val)
5125    elif con == 'ge':
5126        Nvals = np.sum(var >= val)
5127    elif con == 'in':
5128        if len(val) != 2:
5129            print errormsg
5130            print '  ' + fname + ": for condition '" + con + "' we must have two " + \
5131              " values!!" 
5132            print '  we have:',  val
5133            quit(-1)
5134        Nvals = np.sum((var >= val[0])*(var <= val[1]))
5135    elif con == 'out':
5136        if len(val) != 2:
5137            print errormsg
5138            print '  ' + fname + ": for condition '" + con + "' we must have two " + \
5139              " values!!" 
5140            print '  we have:',  val
5141            quit(-1)
5142        Nvals = np.sum((var < val[0])+(var > val[1]))
5143    else:
5144        print errormsg
5145        print '  ' + fname + ": condition '" + con + "' not ready!!"
5146        print '  only ready:', cons
5147        quit(-1)
5148
5149    return Nvals
5150
5151def coincident_CFtimes(tvalB, tunitA, tunitB):
5152    """ Function to make coincident times for two different sets of CFtimes
5153    tvalB= time values B
5154    tunitA= time units times A to which we want to make coincidence
5155    tunitB= time units times B
5156    >>> coincident_CFtimes(np.arange(10),'seconds since 1949-12-01 00:00:00',
5157      'hours since 1949-12-01 00:00:00')
5158    [     0.   3600.   7200.  10800.  14400.  18000.  21600.  25200.  28800.  32400.]
5159    >>> coincident_CFtimes(np.arange(10),'seconds since 1949-12-01 00:00:00',
5160      'hours since 1979-12-01 00:00:00')
5161    [  9.46684800e+08   9.46688400e+08   9.46692000e+08   9.46695600e+08
5162       9.46699200e+08   9.46702800e+08   9.46706400e+08   9.46710000e+08
5163       9.46713600e+08   9.46717200e+08]
5164    """
5165    import datetime as dt
5166    fname = 'coincident_CFtimes'
5167
5168    trefA = tunitA.split(' ')[2] + ' ' + tunitA.split(' ')[3]
5169    trefB = tunitB.split(' ')[2] + ' ' + tunitB.split(' ')[3]
5170    tuA = tunitA.split(' ')[0]
5171    tuB = tunitB.split(' ')[0]
5172
5173    if tuA != tuB:
5174        if tuA == 'microseconds':
5175            if tuB == 'microseconds':
5176                tB = tvalB*1.
5177            elif tuB == 'seconds':
5178                tB = tvalB*10.e6
5179            elif tuB == 'minutes':
5180                tB = tvalB*60.*10.e6
5181            elif tuB == 'hours':
5182                tB = tvalB*3600.*10.e6
5183            elif tuB == 'days':
5184                tB = tvalB*3600.*24.*10.e6
5185            else:
5186                print errormsg
5187                print '  ' + fname + ": combination of time untis: '" + tuA +        \
5188                  "' & '" + tuB + "' not ready !!"
5189                quit(-1)
5190        elif tuA == 'seconds':
5191            if tuB == 'microseconds':
5192                tB = tvalB/10.e6
5193            elif tuB == 'seconds':
5194                tB = tvalB*1.
5195            elif tuB == 'minutes':
5196                tB = tvalB*60.
5197            elif tuB == 'hours':
5198                tB = tvalB*3600.
5199            elif tuB == 'days':
5200                tB = tvalB*3600.*24.
5201            else:
5202                print errormsg
5203                print '  ' + fname + ": combination of time untis: '" + tuA +        \
5204                  "' & '" + tuB + "' not ready !!"
5205                quit(-1)
5206        elif tuA == 'minutes':
5207            if tuB == 'microseconds':
5208                tB = tvalB/(60.*10.e6)
5209            elif tuB == 'seconds':
5210                tB = tvalB/60.
5211            elif tuB == 'minutes':
5212                tB = tvalB*1.
5213            elif tuB == 'hours':
5214                tB = tvalB*60.
5215            elif tuB == 'days':
5216                tB = tvalB*60.*24.
5217            else:
5218                print errormsg
5219                print '  ' + fname + ": combination of time untis: '" + tuA +        \
5220                  "' & '" + tuB + "' not ready !!"
5221                quit(-1)
5222        elif tuA == 'hours':
5223            if tuB == 'microseconds':
5224                tB = tvalB/(3600.*10.e6)
5225            elif tuB == 'seconds':
5226                tB = tvalB/3600.
5227            elif tuB == 'minutes':
5228                tB = tvalB/60.
5229            elif tuB == 'hours':
5230                tB = tvalB*1.
5231            elif tuB == 'days':
5232                tB = tvalB*24.
5233            else:
5234                print errormsg
5235                print '  ' + fname + ": combination of time untis: '" + tuA +        \
5236                  "' & '" + tuB + "' not ready !!"
5237                quit(-1)
5238        elif tuA == 'days':
5239            if tuB == 'microseconds':
5240                tB = tvalB/(24.*3600.*10.e6)
5241            elif tuB == 'seconds':
5242                tB = tvalB/(24.*3600.)
5243            elif tuB == 'minutes':
5244                tB = tvalB/(24.*60.)
5245            elif tuB == 'hours':
5246                tB = tvalB/24.
5247            elif tuB == 'days':
5248                tB = tvalB*1.
5249            else:
5250                print errormsg
5251                print '  ' + fname + ": combination of time untis: '" + tuA +        \
5252                  "' & '" + tuB + "' not ready !!"
5253                quit(-1)
5254        else:
5255            print errormsg
5256            print '  ' + fname + ": time untis: '" + tuA + "' not ready !!"
5257            quit(-1)
5258    else:
5259        tB = tvalB*1.
5260
5261    if trefA != trefB:
5262        trefTA = dt.datetime.strptime(trefA, '%Y-%m-%d %H:%M:%S')
5263        trefTB = dt.datetime.strptime(trefB, '%Y-%m-%d %H:%M:%S')
5264
5265        difft = trefTB - trefTA
5266        diffv = difft.days*24.*3600.*10.e6 + difft.seconds*10.e6 + difft.microseconds
5267        print '  ' + fname + ': different reference refA:',trefTA,'refB',trefTB
5268        print '    difference:',difft,':',diffv,'microseconds'
5269
5270        if tuA == 'microseconds':
5271            tB = tB + diffv
5272        elif tuA == 'seconds':
5273            tB = tB + diffv/10.e6
5274        elif tuA == 'minutes':
5275            tB = tB + diffv/(60.*10.e6)
5276        elif tuA == 'hours':
5277            tB = tB + diffv/(3600.*10.e6)
5278        elif tuA == 'dayss':
5279            tB = tB + diffv/(24.*3600.*10.e6)
5280        else:
5281            print errormsg
5282            print '  ' + fname + ": time untis: '" + tuA + "' not ready !!"
5283            quit(-1)
5284
5285    return tB
5286
5287def wdismean(pos,val4):
5288    """ Function to compute the mean value weighted to its 4 distances
5289      pos= x,y position within the 'square'
5290      val4= values at the four vertexs (2,2)
5291    >>>position = [0.005,0.005]
5292    >>>val4 = np.zeros((2,2), dtype=np.float)
5293    >>>val4 = np.arange(4).reshape(2,2)
5294    0.035707955234
5295    """
5296    fname = 'wdismean'
5297
5298    dist = np.zeros((2,2), dtype=np.float)   
5299    dist[0,0] = np.sqrt(pos[0]*pos[0]+pos[1]*pos[1])
5300    dist[0,1] = np.sqrt(pos[0]*pos[0]+(1.-pos[1])*(1.-pos[1]))
5301    dist[1,0] = np.sqrt((1.-pos[0])*(1.-pos[0])+pos[1]*pos[1])
5302    dist[1,1] = np.sqrt((1.-pos[0])*(1.-pos[0])+(1.-pos[1])*(1.-pos[1]))
5303
5304    if np.min(dist) == 0.:
5305        pos0 = index_mat(dist, 0.)
5306        dist[:,:] = 0.
5307        posmean = val4[pos0[0], pos0[1]]
5308    else:
5309        totdist = np.sum(1./dist)
5310        posmean = np.sum(val4.flatten()/dist.flatten())/totdist
5311
5312    return posmean
5313
5314def read_ASCIIlist(filen):
5315    """ Function to build a list from an ASCII lines file
5316      filen= name of the ASCII file
5317    """
5318    import os
5319    fname = 'read_ASCIIlist'
5320
5321    if not os.path.isfile(filen):
5322        print errormsg
5323        print '  ' + fname + ":  ASCII types file '" + filen + "' does not exist !!"
5324        quit(-1)
5325
5326    of = open(filen, 'r')
5327    filevals = []
5328    for linef in of:
5329        filevals.append(linef.replace('\n',''))
5330    of.close()
5331
5332    return filevals
5333
5334def radial_points(angle,dist):
5335    """ Function to provide a number of grid point positions for a given angle
5336      angle= desired angle (rad)
5337      dist= number of grid points
5338    >>> radial_points(0.5*np.pi,5)
5339    [[  6.12323400e-17   1.00000000e+00]
5340     [  1.22464680e-16   2.00000000e+00]
5341     [  1.83697020e-16   3.00000000e+00]
5342     [  2.44929360e-16   4.00000000e+00]
5343     [  3.06161700e-16   5.00000000e+00]]
5344    """
5345    fname = 'radial_points'
5346    radpos = np.zeros((dist,2), dtype=np.float)
5347
5348    for ip in range(dist):
5349        radpos[ip,0] = (ip+1.)*np.cos(angle)
5350        radpos[ip,1] = (ip+1.)*np.sin(angle)
5351
5352    return radpos
5353
5354def read_SQradii(filename='SQradii.dat', Npt=-1, maxradii=None):
5355    """ Function to read the outcome of the function `squared_radial'
5356      filename= Name of the outcome file of the function
5357      Npt= Number of points on each grid
5358      maxradii= allowed maximum radii
5359      'SQradii.dat': file with the radii and paris of integers after ran squared_radial(1000)
5360    """
5361    fname = 'read_SQradii'
5362
5363    if not os.path.isfile(filename):
5364        print errormsg
5365        print '  ' + fname + ": file '" + filename + "' not found!!"
5366        quit(-1)
5367
5368    infile = open(filename, 'r')
5369
5370    gridradii = {}
5371    Nradii = {}
5372    radii = []
5373    for line in infile:
5374        values = values_line(line, ' ', ['[', ']'])
5375        rad = np.float(values[0])
5376# Limited by a given radii
5377        if maxradii is not None and rad > maxradii: break
5378        Nrad = int(values[2])
5379        couples = []
5380        Nradgood = 0
5381        if Nrad > 1:
5382           Ncouples = 0
5383           for ic in range(Nrad):
5384               ix = int(values[3 + ic*2])
5385               iy = int(values[3 + ic*2 + 1])
5386               if ix <= Npt and iy <= Npt:
5387                   couples.append(np.array([ix,iy]))
5388                   Nradgood = Nradgood + 1
5389               elif ix > Npt and iy > Npt: break
5390        else:
5391             ix = int(values[3])
5392             iy = int(values[4])
5393             if ix <= Npt and iy <= Npt:
5394                 couples.append(np.array([ix,iy]))
5395                 Nradgood = Nradgood + 1
5396             elif ix > Npt and iy > Npt: break
5397
5398        if Nradgood > 0:
5399            Nradii[rad] = Nradgood
5400            finalcouples = np.zeros((Nradgood,2), dtype=int)
5401            for ic in range(Nradgood):
5402                finalcouples[ic,:] = couples[ic]
5403            gridradii[rad] = finalcouples
5404
5405#    for rad in sorted(gridradii.keys()):
5406#        print rad, gridradii[rad]
5407
5408    return gridradii
5409
5410def grid_combinations(x,y):
5411    """ Function to provide all the possible grid points combination for a given pair of values
5412      x,y= pair of grid points
5413    >>>grid_combinations(1,2)
5414    [[1, 2], [-1, 2], [-1, -2], [1, -2], [2, 1], [-2, 1], [-2, -1], [2, -1]]
5415    """
5416    fname = 'grid_combinations'
5417
5418    gridcomb = []
5419    gridcomb.append([x,y])
5420    if x != 0: gridcomb.append([-x,y])
5421    if x != 0 and y != 0: gridcomb.append([-x,-y])
5422    if y != 0: gridcomb.append([x,-y])
5423
5424    if x != y:
5425        gridcomb.append([y,x])
5426        if y != 0: gridcomb.append([-y,x])
5427        if x != 0 and y != 0: gridcomb.append([-y,-x])
5428        if x != 0: gridcomb.append([y,-x])
5429
5430    return gridcomb
5431
5432def radii_points(xpos,ypos,Lrad,Nang,dx,dy):
5433    """ Function to provide the grid points for radial cross sections, by angle and radii and `squared' radii
5434      xpos= x position of the center
5435      ypos= y position of the center
5436      Lrad= length of the maximum radi in grid points
5437      Nang= number of equivalent angles
5438      dx= x size of the domain of values
5439      dy= y size of the domain of values
5440      >>> radpos, SQradpos = radii_points(12,12,1,8,25,25)
5441      radpos:
5442      [[[ 13.          12.        ]]
5443       [[ 12.70710678  12.70710678]]
5444       [[ 12.          13.        ]]
5445       [[ 11.29289322  12.70710678]]
5446       [[ 11.          12.        ]]
5447       [[ 11.29289322  11.29289322]]
5448       [[ 12.          11.        ]]
5449       [[ 12.70710678  11.29289322]]]
5450      SQradpos:
5451      {1.0: [[13, 12], [11, 12], [12, 13], [12, 11]], 1.41421356237: [[13, 13], [11, 13], [11, 11], [13, 11]]}
5452    """
5453    fname = 'radii_points'
5454
5455    radiipos = np.zeros((Nang, Lrad, 2), dtype = np.float)
5456    SQradiipos = {}
5457
5458# Getting the range of radii:
5459    pairsSQradii = read_SQradii(Npt=Lrad)
5460    SQradii = pairsSQradii.keys()
5461    Nradii = len(SQradii)
5462
5463# Angle loop
5464    for ia in range(Nang):
5465        angle = 2.*np.pi*ia/Nang
5466        posangle = np.zeros((Lrad,2), dtype=np.float)
5467
5468# Points at that given angle
5469        pangle = radial_points(angle,Lrad)
5470        posangle[:,0] = pangle[:,0] + xpos
5471        posangle[:,1] = pangle[:,1] + ypos
5472
5473        for ip in range(Lrad):
5474            iipos = int(posangle[ip,0])
5475            jjpos = int(posangle[ip,1])
5476
5477# Creation of a matrix with all the grid points at each time-step
5478            if iipos >= 0 and iipos < dx-1 and jjpos >= 0 and jjpos < dy-1:
5479                radiipos[ia,ip,0] = posangle[ip,0]
5480                radiipos[ia,ip,1] = posangle[ip,1]
5481
5482# SQ radii values
5483
5484# Radii loop (avoiding 0)
5485    pairswithin = {}
5486    for ir in range(1,Nradii):
5487        pairs = pairsSQradii[SQradii[ir]]
5488
5489# pairs loop
5490        Npairs = len(pairs.flatten())/2
5491        pairsw = []
5492        for ip in range(Npairs):
5493            if Npairs == 0: 
5494                break
5495            else:
5496                allpairs = grid_combinations(pairs[ip,0],pairs[ip,1])               
5497            for iap in range(len(allpairs)):
5498                ppos = allpairs[iap]
5499                iipos = xpos + ppos[0]
5500                jjpos = ypos + ppos[1]
5501
5502# Creation of a matrix with all the grid points at each time-step
5503                if iipos >= 0 and iipos < dx and jjpos >= 0 and jjpos < dy:
5504                    pairsw.append([iipos,jjpos])
5505
5506        SQradiipos[SQradii[ir]] = pairsw
5507
5508    return radiipos, SQradiipos
5509
5510def hor_weight_int(SWval, SEval, NWval, NEval, xpos, ypos):
5511    """ Function to weighted by distance interpolate a horizontal value from it closest 4 neighbourgs
5512      field= a 4 points representing the environment of a given point
5513      xpos, ypos: position to which one want to interpolate (relative to 0,0 at the corner SW)
5514    >>> hor_weight_int(1., 1., 1., 2., 0.75, 0.75)
5515    1.44888128193
5516    """
5517    fname = 'hor_weight_int'
5518
5519    vals = np.array([SWval, SEval, NWval, NEval])
5520    print vals
5521    if xpos > 1.: 
5522        print errormsg
5523        print '  ' + fname + ': Wrong position to interpolate! (',xpos,',',ypos,     \
5524          ') must be within (1,1) !!'
5525        quit(-1)
5526
5527    vertexs = np.zeros((4,2), dtype=np.float) 
5528    vertexs[0,0] = 0.
5529    vertexs[0,1] = 0.
5530    vertexs[1,0] = 1.
5531    vertexs[1,1] = 0.
5532    vertexs[2,0] = 0.
5533    vertexs[2,1] = 1.
5534    vertexs[3,0] = 1.
5535    vertexs[3,1] = 1.
5536    print vertexs
5537
5538    dist = np.sqrt((vertexs[:,0]-xpos)**2 + (vertexs[:,1]-ypos)**2)
5539    print dist
5540    done = False
5541    for id in range(4):
5542        if dist[id] == 0.: 
5543            intval = vals[id]
5544            done = True
5545
5546    if not done: intval = np.sum(vals/dist)/np.sum(1./dist)
5547
5548    return intval
5549
5550def rmNOnum(string):
5551    """ Removing from a string all that characters which are not numbers
5552    # From: http://stackoverflow.com/questions/4289331/python-extract-numbers-from-a-string
5553    """
5554    fname = 'rmNOnum'
5555
5556    newstr = str(re.findall("[-+]?\d+[\.]?\d*", string)[0])
5557
5558    return newstr
5559
5560def values_fortran_fmt(lin,fFMT):
5561    """ Function to give back the values of an ASCII line according to its fortran printing format
5562      lin= ASCII line
5563      fFMT= list with the fortran FORMAT formats
5564    forline = 'Natchitoches (RGNL)        1 11 0011  ( 31.733, -93.100) (  28, 157) ( 31.761, -93.113)   41.2 meters'
5565    formats = ['A26', 'I2', 'I3', 'A6', 'A2', 'F7.3', 'A1', 'F8.3', 'A3', 'I4', 'A1', 'I4',
5566      'A3', 'F7.3', 'A1', 'F8.3', 'A2', 'F6.1', 'A7']
5567    >>> values_fortran_fmt(forline, formats)
5568    ['Natchitoches (RGNL)        ', 1, 11, ' 0011  ', ' ( ', 31.733, ', ', -93.1, ') ( ', 28, ', ', 157, ')
5569      ( ', 31.761, ', ', -93.113, ')  ', 41.2, ' meters']
5570    """
5571    fname = 'values_fortran_fmt'
5572
5573    afmts = ['A', 'D', 'F', 'I']
5574
5575    if lin == 'h':
5576        print fname + '_____________________________________________________________'
5577        print values_fortran_fmt.__doc__
5578        quit()
5579
5580    fvalues = []
5581    ichar=0
5582    ival = 0
5583    for ft in fFMT:
5584        Lft = len(ft)
5585        if ft[0:1] == 'A' or ft[0:1] == 'a':
5586            Lfmt = int(ft[1:Lft+1])
5587            fvalues.append(lin[ichar:ichar+Lfmt+1])
5588            ichar = ichar + Lfmt
5589        elif ft[0:1] == 'F' or ft[0:1] == 'f':
5590            if ft.find('.') != -1:
5591                Lft = len(ft.split('.')[0])
5592            Lfmt = int(ft[1:Lft])
5593            fvalues.append(np.float(rmNOnum(lin[ichar:ichar+Lfmt+1])))
5594            ichar = ichar + Lfmt
5595        elif ft[0:1] == 'D' or ft[0:1] == 'd':
5596            if ft.find('.') != -1:
5597                Lft = len(ft.split('.')[0])
5598            Lfmt = int(ft[1:Lft])
5599            fvalues.append(np.float64(rmNOnum(lin[ichar:ichar+Lfmt+1])))
5600            ichar = ichar + Lfmt
5601        elif ft[0:1] == 'I' or ft[0:1] == 'i':
5602            Lfmt = int(ft[1:Lft+1])
5603            fvalues.append(int(rmNOnum(lin[ichar:ichar+Lfmt+1])))
5604            ichar = ichar + Lfmt
5605        elif ft.find('X') != -1 or ft.find('x') != -1:
5606            print '    ' + fname + ': skipping space'
5607            ichar = ichar + int(rmNOnum(ft))
5608        else:
5609            print errormsg
5610            print '  ' + fname + ": format '" + ft[0:1] + "' not ready!!"
5611            print '    Available formats:',afmts
5612            quit(-1)
5613
5614        ival = ival + 1
5615
5616    return fvalues
5617
5618def reduce_last_spaces(string):
5619    """ Function to reduce the last right spaces from a string
5620      string= string to remove the spaces at the righ side of the string
5621    >>> reduce_last_spaces('Hola Lluis      ')
5622    'Hola Lluis'
5623    """
5624    fname = 'reduce_last_spaces'
5625
5626    Lstring = len(string)
5627
5628    firstspace = -1
5629    for istr in range(Lstring-1,0,-1):
5630        if string[istr:istr+1] == ' ':
5631            firstspace = istr
5632        else:
5633            break
5634
5635    if firstspace == -1:
5636        print errormsg
5637        print '  ' + fname + ": string '" + string + "' is not ended by spaces!!"
5638        print '    char. number of last character:',ord(string[Lstring:Lstring+1])
5639        quit(-1)
5640
5641    newstr = string[0:firstspace]
5642
5643    return newstr
5644
5645def squared_radial(Npt):
5646    """ Function to provide the series of radii as composite of pairs (x,y) of gid cells
5647      Npt= largest amount of grid points on x and y directions
5648    >>> squared_radial(5)
5649    [[0.0, 0, 0], [1.0, 1, 0], [1.4142135623730951, 1, 1], [2.0, 2, 0], [2.2360679774997898, 2, 1], [2.8284271247461903, 2, 2], [3.0, 3, 0], [3.1622776601683795, 3, 1], [3.6055512754639891, 3, 2], [4.0, 4, 0], [4.1231056256176606, 4, 1], [4.2426406871192848, 3, 3], [4.4721359549995796, 4, 2], [5.0, array([4, 3]), array([5, 0])], [5.0990195135927845, 5, 1], [5.3851648071345037, 5, 2], [5.6568542494923806, 4, 4], [5.8309518948453007, 5, 3], [6.4031242374328485, 5, 4], [7.0710678118654755, 5, 5]]
5650    """
5651    fname = 'squared_radial'
5652
5653    radii = []
5654    gridradii = {}
5655    singradii = []
5656    Nradii = {}
5657
5658# Computing all radii
5659##
5660    for i in range(Npt+1):
5661        if np.mod(i,100) == 0: print 'done: ',i
5662        for j in range(i+1):
5663#            ir = np.float(i)
5664#            jr = np.float(j)
5665            ir = np.float64(i)
5666            jr = np.float64(j)
5667            rad = np.sqrt(ir*ir + jr*jr)
5668            if not searchInlist(singradii, rad):
5669                singradii.append(rad)
5670                gridradii[rad] = np.array([i,j], dtype=int)
5671                Nradii[rad] = 1
5672            else:
5673#                print warnmsg
5674#                print '  ' + fname + ': repeated radii',rad,'!!'
5675#                print '    Previous values:', gridradii[rad]
5676
5677                oldvalues = gridradii[rad]
5678                Nradii[rad] = Nradii[rad] + 1
5679                newvalues = np.zeros((Nradii[rad],2), dtype=int)
5680                if Nradii[rad] == 2:
5681                    newvalues[0,:] = oldvalues
5682                    Nstart = 1
5683                else:
5684                    Nstart = 0
5685                for Nr in range(Nstart,Nradii[rad]-1):
5686                    newvalues[Nr,:] = oldvalues[Nr,:]
5687                newvalues[Nradii[rad]-1,:] = np.array([i,j], dtype=int)
5688                gridradii[rad] = newvalues
5689
5690# Sorting values
5691##
5692## Only required to downwrite the output file
5693#    radiif = open('SQradii.dat', 'w')
5694#    radii = []
5695#    prevrad = 0.
5696#    for rad in sorted(gridradii.keys()):
5697#        dradii = rad - prevrad
5698## Check fo repeated values
5699#        radii.append([rad, gridradii[rad][0], gridradii[rad][1]])
5700#        radiif.write(str(rad) + ' ' + str(dradii) + ' ' + str(Nradii[rad]) + ' [ '+  \
5701#          numVector_String(gridradii[rad].flatten(), ' ') + ' ] \n')
5702#        prevrad = rad.copy()
5703
5704#    radiif.close()
5705    return gridradii
5706
5707def fillvalue_kind(vartype, fillval0):
5708    """ Function to provide the fiven fill_Value for a kind of variable
5709      [vartype]= type of the variable
5710      [fillval0]= value to take as fill value, 'std' for the standard value
5711           Float = 1.e20
5712           Character = '-'
5713           Integer = -99999
5714           Integer16 = -99999
5715           Float64 = 1.e20
5716           Integer32 = -99999
5717    """
5718    fname = 'fillvalue_kind'
5719
5720    if vartype == type('c'):
5721        if fillval0 == 'std':
5722            fillval = fillvalueC
5723        else:
5724            fillval = fillval0
5725    elif vartype == type(int(1)):
5726        if fillval0 == 'std':
5727            fillval = fillValueI
5728        else:
5729            fillval = int(fillval0)
5730    elif vartype == type(np.int16(1)):
5731        if fillval0 == 'std':
5732            fillval = np.int(9999999)
5733        else:
5734            fillval = np.int16(fillval0)
5735    elif vartype == type(np.int32(1)):
5736        if fillval0 == 'std':
5737            fillval = np.int32(fillValueI)
5738        else:
5739            fillval = np.int32(fillval0)
5740    elif vartype == type(np.float(1.)):
5741        if fillval0 == 'std':
5742            fillval = np.float(fillValueF)
5743        else:
5744            fillval = np.float(fillval0)
5745    elif vartype == type(np.float32(1.)):
5746        if fillval0 == 'std':
5747            fillval = np.float32(fillValueF)
5748        else:
5749            fillval = np.float32(fillval0)
5750    elif vartype == type(np.float64(1.)):
5751        if fillval0 == 'std':
5752            fillval = np.float64(fillValueF)
5753        else:
5754            fillval = np.float64(fillval0)
5755    else:
5756        print errormsg
5757        print '  ' + fname + ': variable type', vartype, 'not ready !!'
5758        quit(-1)
5759
5760    return fillval
5761
5762def varval_ind(var, ind):
5763    """ Function to provide a value from a variable providing a value for each index
5764      var= variable
5765      ind= list of indices for each dimension of the variable
5766    """
5767    fname = 'varval_ind'
5768    if len(var.shape) != len(ind):
5769        print errormsg
5770        print '  ' + fname + ': different shape:', var.shape,'and indices:', ind, '!!'
5771        quit(-1)
5772
5773    varslice=[]
5774    for iv in ind:
5775        varslice.append(iv)
5776
5777    val = varval_ind[slice(varslice)]
5778
5779    return val
5780
5781def CoarselonlatFind(ilon, ilat, lonv, latv, per):
5782    """ Function to search a given value from a coarser version of the data
5783      ilon, ilat= original 2D matrices with the longitudes and the latitudes
5784      lonv, latv= longitude and latitude to find
5785      per= period (as fraction over 1) of the fractions of the original grid to use to explore
5786      >>> npt=100
5787      >>> lonval0 = np.arange(0.,npt*1.,1.)
5788      >>> latval0 = np.arange(0.,npt*1.,1.)
5789      >>> lonval = np.zeros((npt,npt), dtype=np.float)
5790      >>> latval = np.zeros((npt,npt), dtype=np.float)
5791
5792      >>> for i in range(npt):
5793      >>>     lonval[:,i] = lonval0[i]
5794      >>>     latval[i,:] = latval0[i]
5795      >>> CoarselonlatFind(lonval, latval, 5.25, 5.25, .1)
5796      (array([5, 5]), 0.35355339059327379)
5797    """
5798    fname = 'CoarselonlatFind'
5799
5800    dx = ilon.shape[1]
5801    dy = ilon.shape[0]
5802
5803    nlon = np.min(ilon)
5804    xlon = np.max(ilon)
5805    nlat = np.min(ilat)
5806    xlat = np.max(ilat)
5807
5808    if lonv < nlon or lonv > xlon:
5809        print errormsg
5810        print '  ' + fname + ': longitude outside data range!!'
5811        print '    given value:', lonv,'outside [',nlon,',',xlon,']'
5812        quit(-1) 
5813    if latv < nlat or latv > xlat:
5814        print errormsg
5815        print '  ' + fname + ': latitude outside data range!!'
5816        print '    given value:', latv,'outside [',nlat,',',xlat,']'
5817        quit(-1) 
5818
5819    fracx = int(dx*per)
5820    fracy = int(dy*per)
5821
5822    fraclon = ilon[::fracy,::fracx]
5823    fraclat = ilat[::fracy,::fracx]
5824    fracdx = fraclon.shape[1]
5825    fracdy = fraclon.shape[0]
5826
5827#    print 'fraclon _______'
5828#    print fraclon
5829
5830#    print 'fraclat _______'
5831#    print fraclat
5832
5833# Fraction point
5834    difffraclonlat = np.sqrt((fraclon-lonv)**2. + (fraclat-latv)**2.)
5835    mindifffracLl = np.min(difffraclonlat)
5836    ilatlonfrac = index_mat(difffraclonlat, mindifffracLl)
5837
5838#    print 'mindifffracLl:', mindifffracLl, 'ilatlonfrac:', ilatlonfrac
5839#    print 'frac lon, lat:', fraclon[ilatlonfrac[0],ilatlonfrac[1]], ',',             \
5840#      fraclat[ilatlonfrac[0],ilatlonfrac[1]]
5841#    print 'values lon, lat:', lonv, latv
5842     
5843# Providing fraction range
5844    if fraclon[ilatlonfrac[0],ilatlonfrac[1]] >= lonv and                            \
5845      fraclat[ilatlonfrac[0],ilatlonfrac[1]] >= latv:
5846#        ifracbeg = [ilatlonfrac[0]-1, ilatlonfrac[1]-1]
5847#        ifracend = [ilatlonfrac[0], ilatlonfrac[1]]
5848        if ilatlonfrac[0] > 0: 
5849            iybeg = (ilatlonfrac[0]-1)*fracy
5850            iyend = ilatlonfrac[0]*fracy+1
5851        else:
5852            iybeg = 0
5853            iyend = fracy+1
5854        if ilatlonfrac[1] > 0: 
5855            ixbeg = (ilatlonfrac[1]-1)*fracx
5856            ixend = ilatlonfrac[1]*fracx+1
5857        else:
5858            ixbeg = 0
5859            ixend = fracx+1
5860    elif fraclon[ilatlonfrac[0],ilatlonfrac[1]] < lonv and                           \
5861      fraclat[ilatlonfrac[0],ilatlonfrac[1]] >= latv:
5862#        ifracbeg = [ilatlonfrac[0]-1, ilatlonfrac[1]]
5863#        ifracend = [ilatlonfrac[0], ilatlonfrac[1]+1]
5864        if ilatlonfrac[0] > 0: 
5865            iybeg = (ilatlonfrac[0]-1)*fracy
5866            iyend = ilatlonfrac[0]*fracy+1
5867        else:
5868            iybeg = 0
5869            iyend = fracy+1
5870        if ilatlonfrac[1] < fracdx:
5871            if ilatlonfrac[1] != 0:
5872                ixbeg = (ilatlonfrac[1]-1)*fracx
5873                ixend = ilatlonfrac[1]*fracx+1
5874            else:
5875                ixbeg = 0
5876                ixend = fracx+1
5877        else:
5878            ixbeg = fracdx*fracx
5879            ixend = dx+1
5880    elif fraclon[ilatlonfrac[0],ilatlonfrac[1]] < lonv and                           \
5881      fraclat[ilatlonfrac[0],ilatlonfrac[1]] < latv:
5882#        ifracbeg = [ilatlonfrac[0], ilatlonfrac[1]]
5883#        ifracend = [ilatlonfrac[0]+1, ilatlonfrac[1]+1]
5884        if ilatlonfrac[0] < fracdy: 
5885            if ilatlonfrac[0] != 0:
5886                iybeg = (ilatlonfrac[0]-1)*fracy
5887                iyend = ilatlonfrac[0]*fracy+1
5888            else:
5889                iybeg = 0
5890                iyend = fracy+1
5891        else:
5892            iybeg = fracdy*fracy
5893            iyend = dy+1
5894        if ilatlonfrac[1] < fracdx: 
5895            if ilatlonfrac[1] != 0:
5896                ixbeg = (ilatlonfrac[1]-1)*fracx
5897                ixend = ilatlonfrac[1]*fracx+1
5898            else:
5899                ixbeg = 0
5900                ixend = fracx+1
5901        else:
5902            ixbeg = fracdx*fracx
5903            ixend = dx+1
5904    elif fraclon[ilatlonfrac[0],ilatlonfrac[1]] >= lonv and                          \
5905      fraclat[ilatlonfrac[0],ilatlonfrac[1]] < latv:
5906#        ifracbeg = [ilatlonfrac[0], ilatlonfrac[1]-1]
5907#        ifracend = [ilatlonfrac[0]+1, ilatlonfrac[1]]
5908        if ilatlonfrac[0] < fracdy: 
5909            if ilatlonfrac[0] != 0:
5910                iybeg = (ilatlonfrac[0]-1)*fracy
5911                iyend = ilatlonfrac[0]*fracy+1
5912            else:
5913                iybeg = 0
5914                iyend = fracy+1
5915        else:
5916            iybeg = fracdy*fracy
5917            iyend = dy+1
5918        if ilatlonfrac[1] > 0: 
5919            ixbeg = (ilatlonfrac[1]-1)*fracx
5920            ixend = ilatlonfrac[1]*fracx+1
5921        else:
5922            ixbeg = 0
5923            ixend = fracx+1
5924
5925#    ibeg = [iybeg, ixbeg]
5926#    iend = [iyend, ixend]
5927#    print 'find window; beginning', ibeg, 'end:', iend
5928    lon = ilon[iybeg:iyend,ixbeg:ixend]
5929    lat = ilat[iybeg:iyend,ixbeg:ixend]
5930
5931#    print 'lon _______'
5932#    print lon
5933#    print 'lat _______'
5934#    print lat
5935
5936# Find point
5937    difflonlat = np.sqrt((lon-lonv)**2. + (lat-latv)**2.)
5938    mindiffLl = np.min(difflonlat)
5939    ilatlon = index_mat(difflonlat, mindiffLl)
5940
5941    ilatlon[0] = ilatlon[0] + iybeg
5942    ilatlon[1] = ilatlon[1] + ixbeg
5943
5944#    print 'mindiffLl:', mindiffLl, 'ilatlon:', ilatlon
5945#    print 'lon, lat:', lon[ilatlon[0],ilatlon[1]], ',', lat[ilatlon[0],ilatlon[1]]
5946#    quit()
5947
5948    return ilatlon, mindiffLl
5949
5950def CoarselonlatFindAll(onc, ilon, ilat, longvs, latvs, per, frac, out):
5951    """ Function to search all values from a coarser version of the data
5952      onc= netCDF object from an existing file
5953      ilon, ilat= original 2D matrices with the longitudes and the latitudes
5954      lonv, latv= longitude and latitude to find
5955      per= period (as fraction over 1) of the fractions of the original grid to use to explore
5956      frac= frequency of points at which syncronize file with calculations
5957      out= True/False if outcome is required
5958      >>> npt=100
5959      >>> lonval0 = np.arange(0.,npt*1.,1.)
5960      >>> latval0 = np.arange(0.,npt*1.,1.)
5961      >>> lonval = np.zeros((npt,npt), dtype=np.float)
5962      >>> latval = np.zeros((npt,npt), dtype=np.float)
5963      >>> lonvalues = np.arange(0.25,10.,0.25)
5964      >>> latvalues = np.arange(0.25,10.,0.25)
5965
5966      >>> for i in range(npt):
5967      >>>     lonval[:,i] = lonval0[i]
5968      >>>     latval[i,:] = latval0[i]
5969      >>> CoarselonlatFindAll(onewnc, lonval, latval, lovalues, latvalues, .1, 100)
5970      (array([5, 5]), 0.35355339059327379)
5971    """
5972    fname = 'CoarselonlatFindAll'
5973
5974    dx = ilon.shape[1]
5975    dy = ilon.shape[0]
5976
5977    nlon = np.min(ilon)
5978    xlon = np.max(ilon)
5979    nlat = np.min(ilat)
5980    xlat = np.max(ilat)
5981
5982    Nallpts = len(longvs)
5983
5984    fracx = int(dx*per)
5985    fracy = int(dy*per)
5986
5987    fraclon = ilon[::fracy,::fracx]
5988    fraclat = ilat[::fracy,::fracx]
5989    fracdx = fraclon.shape[1]
5990    fracdy = fraclon.shape[0]
5991
5992#    print 'fraclon _______'
5993#    print fraclon
5994
5995#    print 'fraclat _______'
5996#    print fraclat
5997
5998    if out:
5999        ilatlon = np.zeros((2,Nallpts), dtype=int)
6000        mindiffLl = np.zeros((Nallpts), dtype=np.float)
6001
6002    iptpos=0
6003    for iv in range(Nallpts):
6004        lonv = longvs[iv]
6005        latv = latvs[iv]
6006
6007        if lonv < nlon or lonv > xlon:
6008            print errormsg
6009            print '  ' + fname + ': longitude outside data range!!'
6010            print '    given value:', lonv,'outside [',nlon,',',xlon,']'
6011            quit(-1) 
6012        if latv < nlat or latv > xlat:
6013            print errormsg
6014            print '  ' + fname + ': latitude outside data range!!'
6015            print '    given value:', latv,'outside [',nlat,',',xlat,']'
6016            quit(-1) 
6017
6018# Fraction point
6019        difffraclonlat = np.sqrt((fraclon-lonv)**2. + (fraclat-latv)**2.)
6020        mindifffracLl = np.min(difffraclonlat)
6021        ilatlonfrac = index_mat(difffraclonlat, mindifffracLl)
6022
6023#        print 'values lon, lat:', lonv, latv
6024#        print 'mindifffracLl:', mindifffracLl, 'ilatlonfrac:', ilatlonfrac
6025#        print 'frac lon, lat:', fraclon[ilatlonfrac[0],ilatlonfrac[1]], ',',         \
6026#          fraclat[ilatlonfrac[0],ilatlonfrac[1]]
6027     
6028# Providing fraction range
6029        if fraclon[ilatlonfrac[0],ilatlonfrac[1]] >= lonv and                        \
6030          fraclat[ilatlonfrac[0],ilatlonfrac[1]] >= latv:
6031#            ifracbeg = [ilatlonfrac[0]-1, ilatlonfrac[1]-1]
6032#            ifracend = [ilatlonfrac[0], ilatlonfrac[1]]
6033            if ilatlonfrac[0] > 0: 
6034                iybeg = (ilatlonfrac[0]-1)*fracy
6035                iyend = ilatlonfrac[0]*fracy+1
6036            else:
6037                iybeg = 0
6038                iyend = fracy+1
6039            if ilatlonfrac[1] > 0: 
6040                ixbeg = (ilatlonfrac[1]-1)*fracx
6041                ixend = ilatlonfrac[1]*fracx+1
6042            else:
6043                ixbeg = 0
6044                ixend = fracx+1
6045        elif fraclon[ilatlonfrac[0],ilatlonfrac[1]] < lonv and                       \
6046          fraclat[ilatlonfrac[0],ilatlonfrac[1]] >= latv:
6047#            ifracbeg = [ilatlonfrac[0]-1, ilatlonfrac[1]]
6048#            ifracend = [ilatlonfrac[0], ilatlonfrac[1]+1]
6049            if ilatlonfrac[0] > 0: 
6050                iybeg = (ilatlonfrac[0]-1)*fracy
6051                iyend = ilatlonfrac[0]*fracy+1
6052            else:
6053                iybeg = 0
6054                iyend = fracy+1
6055            if ilatlonfrac[1] < fracdx:
6056                if ilatlonfrac[1] != 0:
6057                    ixbeg = (ilatlonfrac[1]-1)*fracx
6058                    ixend = ilatlonfrac[1]*fracx+1
6059                else:
6060                    ixbeg = 0
6061                    ixend = fracx+1
6062            else:
6063                ixbeg = fracdx*fracx
6064                ixend = dx+1
6065        elif fraclon[ilatlonfrac[0],ilatlonfrac[1]] < lonv and                       \
6066          fraclat[ilatlonfrac[0],ilatlonfrac[1]] < latv:
6067#            ifracbeg = [ilatlonfrac[0], ilatlonfrac[1]]
6068#            ifracend = [ilatlonfrac[0]+1, ilatlonfrac[1]+1]
6069            if ilatlonfrac[0] < fracdy: 
6070                if ilatlonfrac[0] != 0:
6071                    iybeg = (ilatlonfrac[0]-1)*fracy
6072                    iyend = ilatlonfrac[0]*fracy+1
6073                else:
6074                    iybeg = 0
6075                    iyend = fracy+1
6076            else:
6077                iybeg = fracdy*fracy
6078                iyend = dy+1
6079            if ilatlonfrac[1] < fracdx: 
6080                if ilatlonfrac[1] != 0:
6081                    ixbeg = (ilatlonfrac[1]-1)*fracx
6082                    ixend = ilatlonfrac[1]*fracx+1
6083                else:
6084                    ixbeg = 0
6085                    ixend = fracx+1
6086            else:
6087                ixbeg = fracdx*fracx
6088                ixend = dx+1
6089        elif fraclon[ilatlonfrac[0],ilatlonfrac[1]] >= lonv and                      \
6090          fraclat[ilatlonfrac[0],ilatlonfrac[1]] < latv:
6091#            ifracbeg = [ilatlonfrac[0], ilatlonfrac[1]-1]
6092#            ifracend = [ilatlonfrac[0]+1, ilatlonfrac[1]]
6093            if ilatlonfrac[0] < fracdy: 
6094                if ilatlonfrac[0] != 0:
6095                    iybeg = (ilatlonfrac[0]-1)*fracy
6096                    iyend = ilatlonfrac[0]*fracy+1
6097                else:
6098                    iybeg = 0
6099                    iyend = fracy+1
6100            else:
6101                iybeg = fracdy*fracy
6102                iyend = dy+1
6103            if ilatlonfrac[1] > 0: 
6104                ixbeg = (ilatlonfrac[1]-1)*fracx
6105                ixend = ilatlonfrac[1]*fracx+1
6106            else:
6107                ixbeg = 0
6108                ixend = fracx+1
6109   
6110#        ibeg = [iybeg, ixbeg]
6111#        iend = [iyend, ixend]
6112#        print 'find window; beginning', ibeg, 'end:', iend
6113        lon = ilon[iybeg:iyend,ixbeg:ixend]
6114        lat = ilat[iybeg:iyend,ixbeg:ixend]
6115#        print 'Looking within _______'
6116#        print 'lon:',lon[0,0],',',lon[-1,-1]
6117#        print 'lat:',lat[0,0],',',lat[-1,-1]
6118   
6119#        print 'lon _______'
6120#        print lon
6121#        print 'lat _______'
6122#        print lat
6123   
6124# Find point
6125        difflonlat = np.sqrt((lon-lonv)**2. + (lat-latv)**2.)
6126        if out:
6127            mindiffLl[iv] = np.min(difflonlat)
6128            ilatlon[:,iv] = index_mat(difflonlat, mindiffLl)
6129            ilatlon[0,iv] = ilatlon[0,iv] + iybeg
6130            ilatlon[1,iv] = ilatlon[1,iv] + ixbeg
6131        else:
6132            mindiffLl = np.min(difflonlat)
6133            ilatlon = index_mat(difflonlat, mindiffLl)
6134            ilatlon[0] = ilatlon[0] + iybeg
6135            ilatlon[1] = ilatlon[1] + ixbeg
6136
6137#        print 'mindiffLl:', mindiffLl, 'ilatlon:', ilatlon
6138#        print 'lon, lat:', lon[ilatlon[0],ilatlon[1]], ',', lat[ilatlon[0],ilatlon[1]]
6139#        quit()
6140
6141#        if mindiffLl == 0. and type(newvar[ilatlon[0],ilatlon[1]]) == type(amsk):
6142#            percendone(iv,Ninpts,0.5,'done:')
6143        if mindiffLl == 0.: 
6144            iptpos = iptpos + 1
6145# Speeding it up!
6146#            if mindiffLl > mindiff:
6147#                print errormsg
6148#                print '  ' + fname + ': for point #', iv,'lon,lat in ' +             \
6149#                  'incomplet map:', lonvs[iv], ',', latvs[iv], 'there is ' +         \
6150#                  'not a set of lon,lat in the completed map closer than: ',         \
6151#                  mindiff, '!!'
6152#                print '    minimum difference:', mindiffLl
6153#                quit(-1)
6154
6155# Speeding it up!
6156#            if ilatlon[0] >= 0 and ilatlon[1] >= 0:
6157#                newvar[ilatlon[0],ilatlon[1]] = ovar[iv]
6158#                newvarin[ilatlon[0],ilatlon[1]] = iv
6159#                newvarinpt[iv] = 1
6160#                newvarindiff[iv] = mindiffLl
6161            newvar[ilatlon[0],ilatlon[1]] = ovar[iv]
6162            newvarin[ilatlon[0],ilatlon[1]] = iv
6163            newvarinpt[iv] = 1
6164            newvarindiff[iv] = mindiffLl
6165
6166#                print 'Lluis iv:', newvarin[ilatlon[0],ilatlon[1]],                  \
6167#                  'localized:', newvarinpt[iv], 'values:',                           \
6168#                  newvar[ilatlon[0],ilatlon[1]], 'invalues:', ovar[iv],              \
6169#                  'mindist:', newvarindiff[iv], 'point:',ilatlon   
6170#            else:
6171#                print errormsg
6172#                print '  ' + fname + ': point iv:', iv, 'at', lonvs[iv], ',',        \
6173#                  latvs[iv],' not relocated !!'
6174#                print '    mindiffl:', mindiffLl, 'ilon:', ilatlon[1],               \
6175#                  'ilatlon:', ilatlon[1]
6176#                quit(-1)
6177            if np.mod(iptpos,fracs) == 0: 
6178                print 'Lluis syncronizing!'
6179                onc.sync()
6180    if out:
6181        return ilatlon, mindiffLl
6182    else:
6183        return
6184
6185def lonlatFind(ilon, ilat, lonv, latv):
6186    """ Function to search a given value from a lon, lat 2D data
6187      ilon, ilat= original 2D matrices with the longitudes and the latitudes
6188      lonv, latv= longitude and latitude to find
6189      >>> npt=100
6190      >>> lonval0 = np.arange(0.,npt*1.,1.)
6191      >>> latval0 = np.arange(0.,npt*1.,1.)
6192      >>> lonval = np.zeros((npt,npt), dtype=np.float)
6193      >>> latval = np.zeros((npt,npt), dtype=np.float)
6194
6195      >>> for i in range(npt):
6196      >>>     lonval[:,i] = lonval0[i]
6197      >>>     latval[i,:] = latval0[i]
6198      >>> lonlatFind(lonval, latval, 5.25, 5.25)
6199      (array([5, 5]), 0.35355339059327379)
6200    """
6201    fname = 'lonlatFind'
6202
6203    dx = ilon.shape[1]
6204    dy = ilon.shape[0]
6205
6206    nlon = np.min(ilon)
6207    xlon = np.max(ilon)
6208    nlat = np.min(ilat)
6209    xlat = np.max(ilat)
6210
6211    if lonv < nlon or lonv > xlon:
6212        print errormsg
6213        print '  ' + fname + ': longitude outside data range!!'
6214        print '    given value:', lonv,'outside [',nlon,',',xlon,']'
6215        quit(-1) 
6216    if latv < nlat or latv > xlat:
6217        print errormsg
6218        print '  ' + fname + ': latitude outside data range!!'
6219        print '    given value:', latv,'outside [',nlat,',',xlat,']'
6220        quit(-1) 
6221
6222# Find point
6223    difflonlat = np.sqrt((ilon-lonv)**2. + (ilat-latv)**2.)
6224    mindiffLl = np.min(difflonlat)
6225    ilatlon = index_mat(difflonlat, mindiffLl)
6226
6227#    print 'mindiffLl:', mindiffLl, 'ilatlon:', ilatlon
6228#    print 'lon, lat:', lon[ilatlon[0],ilatlon[1]], ',', lat[ilatlon[0],ilatlon[1]]
6229
6230    return ilatlon, mindiffLl
Note: See TracBrowser for help on using the repository browser.