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

Last change on this file since 817 was 816, checked in by lfita, 9 years ago

Removing spurious commentaries

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