# -*- coding: iso-8859-15 -*- # Python tools # From L. Fita work in different places: CCRC (Australia), LMD (France) # More information at: http://www.xn--llusfb-5va.cat/python/PyNCplot # # pyNCplot and its component generic_tools.py comes with ABSOLUTELY NO WARRANTY. # This work is licendes under a Creative Commons # Attribution-ShareAlike 4.0 International License (http://creativecommons.org/licenses/by-sa/4.0) # import numpy as np from netCDF4 import Dataset as NetCDFFile import os import re import numpy.ma as ma from cStringIO import StringIO import sys main = 'nc_var_tools.py' errormsg='ERROR -- error -- ERROR -- error' warnmsg='WARNING -- warning -- WARNING -- warning' fillValue = 1.e20 fillValueF = 1.e20 fillValueC = '-' fillValueI = -99999 fillValueI16 = -99999 fillValueF64 = 1.e20 fillValueI32 = -99999 # For variables_values # Variable name might come with a statistical surname... statsurname=['min','max','mean','std', 'sum', 'turb', 'var'] ####### Content # ASCII_LaTeX: Function to transform from an ASCII character to LaTeX codification # Capturing: Class to capture the standard output from a function # CFmonthU_daysU: Function to transform from a CF date series with units as 'months since [DATE]' to 'days since [DATE]' # CFvar_DIAGvar: Function to provide which model diagnostic values can provide a CF-variable from ASCII file # CFvar_MODvar: Function to provide which model values can provide a CF-variable from ASCII file # chainSnumHierarchy: Class to provide the structure of a `ChainStrNum' hierarchy # chainSnum_levnext: Function to provide the next value for a given level from a chainStrnum hirerarchy of numbers # chainSnum_num: Function to pass a `ChainStrNum' string to a number # changedate360: Class to change a date on a 360 days/yr (or 12 30-days months) calendar # coincident_CFtimes: Function to make coincident times for two different sets of CFtimes # coldec_hex: Function to pas a decimal ([r,g,b]; [0.,1.]) color to hexadecimal (#[RR][GG][BB], 00-64, 0A-FF) # colhex_dec: Function to pas a hexadecimal (#[RR][GG][BB]; 00-64, 0A-FF) color to decimal ([0.,1.]) # color_deg: Function to generate a degradation of colors in rgb base # contflow: Function to bring back the increment in j,i grid points according to a trip: (inflow directions) # dictionary_key: Function to provide the first key in a dictionay with a given value # dictionary_key_list: Function to provide the first key in a dictionary of lists with a given value # dictKeysVals_stringList: Function to provide strings from a dictionary with keys which contain values of lists # dictvar_listS: Function to provide a Dc string separated list of DVs separated [key] [value] couples following a list of keys # diff_dates360: Function to provide the number of seconds of difference between two dates (dateA - dateB) on a # 360 days/yr (or 12 30-days months) calendar # dtsec360dyr: Class to operate a number of seconds to a date in a 360 days/yr (or 12 30-days months) calendar # files_folder_HMT: Function to retrieve a list of files from a folder [fold] and files with [head]*[middle]*[tail] # get_configuration: Function to get the configuration from an ASCII external file # get_specdictionary_HMT: Function to get specific values from a dictionary by selcting that keys with H*M*T # ijlonlat: Function to provide the imin,jmin imax,jmax of a lon,lat box # incomming_flow: Function to determine if a fgrid-flow inflows to the central grid point # index_flatten_mat: Function to provide the matrix coordinates of an index from its flatten version # index_mat_way: Function to look for a value within a matrix following a direction # index_mat: Function to provide the coordinates of a given value inside a matrix # index_vec: Function to provide the coordinates of a given value inside a vector # julday_360d: Function to provide the julian day of a date in a 360 days/yr (or 12 30-days months) calendar # latex_text: Function to transform a text to LaTeX following style rules # list_combos: Function to construct a new list with all possible N-combinations of the list-values # list_coincidences: Function to provide the coincidences between two lists # list_differences: Function to provide the differences between two lists # list_norepeatcombos: Function to all possible (Num-1)-combinations of a Num values without repetitions # multi_index_mat: Function to provide the multiple coordinates of a given value inside a matrix # num_chainSnum: Function to pass a value to a `ChainStrNum' number # num_split: Function to split a string at each numeric value keeping the number as the last character of each cut # oper_submatrix: Function to perform an operation of a given matrix along a sub-set of values along its dimensions # period_information_360d: Function to provide the information of a given period idate, edate (dates in # [YYYY][MM][DD][HH][MI][SS] format) in a 360 years calendar # pretty_int: Function to plot nice intervals # prime_decomposition: Function to decompose a given number with its multiple prime numbers # prime_numbers: Function to find all the prime numbers up to a given value above 17 # printing_dictionary: Function to print the content of a dictionary # PolyArea: Function to compute the area of the polygon following 'Shoelace formula' # radius_angle: Function to generate a matrix with the angle at a given point # radius_dist: Function to generate a matrix with the distance at a given point # replace_list: Function to replace a value in a given list # same_shape: Function to check if two matrices have the same shape # search_sec_list: Function to provide the values and indices on a list which matches a section of a string # significant_decomposition: Function to decompose a given number by its signifcant potencies # singleline_printing_class: Function to print all the values of a given class in a single line to be parseavel # stagger_unstagger: Function to de-stagger a variable # std_stats2Val: two variables standard Statistics class # Str_Bool: Function to transform from a String value to a boolean one # str_list: Function to obtain a list from a string givin a split character # str_list_k: Function to obtain a list of types of values from a string giving a split character # stringS_dictvar: Function to provide a dictionary from a Srting which list of DVs separated [key] [value] couples # stringList_dictKeysVals: Function to provide a dictionary with keys which contain values of lists from a string # subbasin_point: Function to provide sub-basins given a grid point following a matrix of trips # timestep_conform: Function to provide the time-step in seconds which conforms 1 temporal unit and the resultant number # of time-steps for a whole period is multiple of a given number # unitsdsDate: Function to know how many units of time are from a given pair of dates # vals_around: Function to provide the 3x3 values around a given j,i point def searchInlist(listname, nameFind): """ Function to search a value within a list listname = list nameFind = value to find >>> searInlist(['1', '2', '3', '5'], '5') True """ for x in listname: if x == nameFind: return True return False def values_line(line, splitv, chars): """ Function to retrieve values from a line of ASCII text removing a series of characters line= line of ASCII text to work with splitv= character to use to split with the line chars= list of characters/strings to remove >>> values_line('0.0 0.0 1 [ 0 0 ]', ' ', ['[', ']']) ['0.0', '0.0', '1', '0', '0'] """ fname = 'values_line' vals = line.replace('\n', '') for ic in chars: vals = vals.replace(ic, '') vals0 = vals.split(splitv) vals = [] for val in vals0: if not len(val) == 0: vals.append(val) return vals def filexist(filen, emsg, fmsg): """ Check existence of a file filen= file name emsg= general error message fmsg= message before generic text of inexistence of file """ if not os.path.isfile(filen): print emsg print ' ' + fmsg + ' file "' + filen + '" does not exist !!' print emsg quit(-1) return def reduce_spaces(string): """ Function to give words of a line of text removing any extra space """ values = string.replace('\n','').split(' ') vals = [] for val in values: if len(val) > 0: vals.append(val) return vals def reduce_tabulars(string): """ Function to give words of a line of text removing any extra space and tabular separation """ values = string.replace('\n','').split('\t') vals = [] for val in values: if len(val) > 0: vals.append(val) return vals def check_arguments(funcname,args,expectargs,char): """ Function to check the number of arguments if they are coincident check_arguments(funcname,Nargs,args,char) funcname= name of the function/program to check args= passed arguments expectargs= expected arguments char= character used to split the arguments """ fname = 'check_arguments' Nvals = len(args.split(char)) Nargs = len(expectargs.split(char)) if Nvals != Nargs: print errormsg print ' ' + fname + ': wrong number of arguments:',Nvals," passed to '", \ funcname, "' which requires:",Nargs,'!!' print ' # given expected _______' Nmax = np.max([Nvals, Nargs]) for ia in range(Nmax): if ia > Nvals-1: aval = ' ' else: aval = args.split(char)[ia] if ia > Nargs-1: aexp = ' ' else: aexp = expectargs.split(char)[ia] print ' ', ia, aval, aexp quit(-1) return def Str_Bool(val): """ Function to transform from a String value to a boolean one >>> Str_Bool('True') True >>> Str_Bool('0') False >>> Str_Bool('no') False """ fname = 'Str_Bool' if val == 'True' or val == 'true' or val == '1' or val == 'yes' or val == 'T' or val == 't': boolv = True boolv = True elif val == 'False' or val == 'false' or val == '0' or val== 'no' or val == 'F' or val == 'f': boolv = False else: print errormsg print ' ' + fname + ": value '" + val + "' not ready!!" quit(-1) return boolv def Nchar(N,string): """ Function to provide 'N' times concatenated 'string' N= number of copies strin= string to reproduce >>> Nchar(4,'#') #### """ fname = 'Nchar' newstring='' for it in range(N): newstring=newstring + string return newstring def string_dicvals_char(dictionary, string, char): """ Function to provide a string taking values from a given [string] where each single character coincide with the key of the dictionary [dictionary], separated by a given set of characters [char] dictionary= dictionary of the values dim([c]) = {[value]} string = [c1][...[cN]] String with the combination of [c]s >>> dictvals = {'i': 'dimx', 'j': 'dimy', 'k': 'dimz', 't': 'dimt'} >>> string_dicvals_char(dictvals, 'ijkt', ', ') dimx, dimy, dimz, dimt """ fname = 'string_dicvals_char' Lstring = len(string) newstring = '' for ic in range(Lstring): cc = string[ic:ic+1] if not dictionary.has_key(cc): print errormsg print ' ' + fname + ": dictionary of values does not have character '" +\ cc + "' !!" print ' it has:',dictionary if ic == 0: newstring = dictionary[cc] else: newstring = newstring + char + dictionary[cc] return newstring def substring(stringv,pos,char): """ Function to substitute a character of a given string stringv= string to change pos= position to change char= characters to use as substitution >>> substring('0123456',2,'ii') 01ii3456 """ fname = 'substring' # From: http://stackoverflow.com/questions/1228299/change-one-character-in-a-string-in-python newstring = stringv[:pos] + char + stringv[pos+1:] return newstring def list_combos(listv,Ncombos): """ Function to construct a new list with all possible N-combinations of the list-values listv= list of values Ncombos= number of combinations >>> list_combos(['a', 'b', 'c', 'd'],1) ['a', 'b', 'c', 'd', 'aa', 'ab', 'ac', 'ad', 'ba', 'bb', 'bc', 'bd', 'ca', 'cb', 'cc', 'cd', 'da', 'db', 'dc', 'dd'] """ fname = 'list_combos' newlist = list(listv) Nlvs = len(listv) for ic in range(Ncombos): prevlist = list(newlist) for lv in prevlist: for ilv in listv: newlist.append(lv + ilv) return newlist def list_norepeatcombos(Num): """ Function to all possible (Num-1)-combinations of a Num values without repetitions Num= number of elements >>> list_norepeatcombos(4) [[0], [1], [2], [3], [0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3], [0, 1, 2], [0, 1, 3], [0, 2, 3], [1, 2, 3], [0, 1, 2, 3]] """ from math import factorial fname = 'list_norepeatcombos' listv = range(Num) # Single values are also combinations! combos = [] for i in range(Num): combos.append([i]) samevals = [] diffvals = [] for iv in listv: if not searchInlist(diffvals,iv): diffvals.append(iv) if searchInlist(samevals,iv): samevals.append(iv) Nlvs = len(listv) # Number of possible combinations for ic in range(2,Nlvs+1): Ncombs = factorial(Nlvs)/(factorial(ic)*factorial(Nlvs-ic)) combo = range(ic) # Getting the limits for each element of the combination of ic-elements limitcombo = range(ic) for icc in range(ic): limitcombo[icc] = Nlvs-ic+icc combos.append(combo) ncombo = list(combo) for ico in range(Ncombs): # Incrementing the last coordinate ncombo[ic-1] = ncombo[ic-1] + 1 if ncombo[ic-1] > limitcombo[ic-1]: # looping all over the others if there is an overpass of the value # previous coordinate will be incremented and the following ones # will be incremented by 1 starting from the new assigned previous # value for icc in range(1,ic): # Incrementing the previous one ncombo[ic-icc-1] = ncombo[ic-icc-1]+1 # Incrementing the following ones since the value at the previous # position for iccc in range(ic-icc,ic): ncombo[iccc] = ncombo[iccc-1]+1 if ncombo[ic-icc-1] <= limitcombo[ic-icc-1]: combos.append(list(ncombo)) break else: combos.append(list(ncombo)) return combos def datetimeStr_conversion(StringDT,typeSi,typeSo): """ Function to transform a string date to an another date object StringDT= string with the date and time typeSi= type of datetime string input typeSo= type of datetime string output [typeSi/o] 'cfTime': [time],[units]; ]time in CF-convention format [units] = [tunits] since [refdate] 'matYmdHMS': numerical vector with [[YYYY], [MM], [DD], [HH], [MI], [SS]] 'YmdHMS': [YYYY][MM][DD][HH][MI][SS] format 'Y-m-d_H:M:S': [YYYY]-[MM]-[DD]_[HH]:[MI]:[SS] format 'Y-m-d H:M:S': [YYYY]-[MM]-[DD] [HH]:[MI]:[SS] format 'Y/m/d H-M-S': [YYYY]/[MM]/[DD] [HH]-[MI]-[SS] format 'WRFdatetime': [Y], [Y], [Y], [Y], '-', [M], [M], '-', [D], [D], '_', [H], [H], ':', [M], [M], ':', [S], [S] >>> datetimeStr_conversion('1976-02-17_08:32:05','Y-m-d_H:M:S','matYmdHMS') [1976 2 17 8 32 5] >>> datetimeStr_conversion(str(137880)+',minutes since 1979-12-01_00:00:00','cfTime','Y/m/d H-M-S') 1980/03/05 18-00-00 """ import datetime as dt fname = 'datetimeStr_conversion' if StringDT[0:1] == 'h': print fname + '_____________________________________________________________' print datetimeStr_conversion.__doc__ quit() if typeSi == 'cfTime': timeval = np.float(StringDT.split(',')[0]) tunits = StringDT.split(',')[1].split(' ')[0] Srefdate = StringDT.split(',')[1].split(' ')[2] # Does reference date contain a time value [YYYY]-[MM]-[DD] [HH]:[MI]:[SS] ## yrref=Srefdate[0:4] monref=Srefdate[5:7] dayref=Srefdate[8:10] trefT = Srefdate.find(':') if not trefT == -1: # print ' ' + fname + ': refdate with time!' horref=Srefdate[11:13] minref=Srefdate[14:16] secref=Srefdate[17:19] refdate = datetimeStr_datetime( yrref + '-' + monref + '-' + dayref + \ '_' + horref + ':' + minref + ':' + secref) else: refdate = datetimeStr_datetime( yrref + '-' + monref + '-' + dayref + \ + '_00:00:00') if tunits == 'weeks': newdate = refdate + dt.timedelta(weeks=float(timeval)) elif tunits == 'days': newdate = refdate + dt.timedelta(days=float(timeval)) elif tunits == 'hours': newdate = refdate + dt.timedelta(hours=float(timeval)) elif tunits == 'minutes': newdate = refdate + dt.timedelta(minutes=float(timeval)) elif tunits == 'seconds': newdate = refdate + dt.timedelta(seconds=float(timeval)) elif tunits == 'milliseconds': newdate = refdate + dt.timedelta(milliseconds=float(timeval)) else: print errormsg print ' timeref_datetime: time units "' + tunits + '" not ready!!!!' quit(-1) yr = newdate.year mo = newdate.month da = newdate.day ho = newdate.hour mi = newdate.minute se = newdate.second elif typeSi == 'matYmdHMS': yr = StringDT[0] mo = StringDT[1] da = StringDT[2] ho = StringDT[3] mi = StringDT[4] se = StringDT[5] elif typeSi == 'YmdHMS': yr = int(StringDT[0:4]) mo = int(StringDT[4:6]) da = int(StringDT[6:8]) ho = int(StringDT[8:10]) mi = int(StringDT[10:12]) se = int(StringDT[12:14]) elif typeSi == 'Y-m-d_H:M:S': dateDT = StringDT.split('_') dateD = dateDT[0].split('-') timeT = dateDT[1].split(':') yr = int(dateD[0]) mo = int(dateD[1]) da = int(dateD[2]) ho = int(timeT[0]) mi = int(timeT[1]) se = int(timeT[2]) elif typeSi == 'Y-m-d H:M:S': dateDT = StringDT.split(' ') dateD = dateDT[0].split('-') timeT = dateDT[1].split(':') yr = int(dateD[0]) mo = int(dateD[1]) da = int(dateD[2]) ho = int(timeT[0]) mi = int(timeT[1]) se = int(timeT[2]) elif typeSi == 'Y/m/d H-M-S': dateDT = StringDT.split(' ') dateD = dateDT[0].split('/') timeT = dateDT[1].split('-') yr = int(dateD[0]) mo = int(dateD[1]) da = int(dateD[2]) ho = int(timeT[0]) mi = int(timeT[1]) se = int(timeT[2]) elif typeSi == 'WRFdatetime': yr = int(StringDT[0])*1000 + int(StringDT[1])*100 + int(StringDT[2])*10 + \ int(StringDT[3]) mo = int(StringDT[5])*10 + int(StringDT[6]) da = int(StringDT[8])*10 + int(StringDT[9]) ho = int(StringDT[11])*10 + int(StringDT[12]) mi = int(StringDT[14])*10 + int(StringDT[15]) se = int(StringDT[17])*10 + int(StringDT[18]) else: print errormsg print ' ' + fname + ': type of String input date "' + typeSi + \ '" not ready !!!!' quit(-1) if typeSo == 'matYmdHMS': dateYmdHMS = np.zeros((6), dtype=int) dateYmdHMS[0] = yr dateYmdHMS[1] = mo dateYmdHMS[2] = da dateYmdHMS[3] = ho dateYmdHMS[4] = mi dateYmdHMS[5] = se elif typeSo == 'YmdHMS': dateYmdHMS = str(yr).zfill(4) + str(mo).zfill(2) + str(da).zfill(2) + \ str(ho).zfill(2) + str(mi).zfill(2) + str(se).zfill(2) elif typeSo == 'Y-m-d_H:M:S': dateYmdHMS = str(yr).zfill(4) + '-' + str(mo).zfill(2) + '-' + \ str(da).zfill(2) + '_' + str(ho).zfill(2) + ':' + str(mi).zfill(2) + ':' + \ str(se).zfill(2) elif typeSo == 'Y-m-d H:M:S': dateYmdHMS = str(yr).zfill(4) + '-' + str(mo).zfill(2) + '-' + \ str(da).zfill(2) + ' ' + str(ho).zfill(2) + ':' + str(mi).zfill(2) + ':' + \ str(se).zfill(2) elif typeSo == 'Y/m/d H-M-S': dateYmdHMS = str(yr).zfill(4) + '/' + str(mo).zfill(2) + '/' + \ str(da).zfill(2) + ' ' + str(ho).zfill(2) + '-' + str(mi).zfill(2) + '-' + \ str(se).zfill(2) elif typeSo == 'WRFdatetime': dateYmdHMS = [] yM = yr/1000 yC = (yr-yM*1000)/100 yD = (yr-yM*1000-yC*100)/10 yU = yr-yM*1000-yC*100-yD*10 mD = mo/10 mU = mo-mD*10 dD = da/10 dU = da-dD*10 hD = ho/10 hU = ho-hD*10 miD = mi/10 miU = mi-miD*10 sD = se/10 sU = se-sD*10 dateYmdHMS.append(str(yM)) dateYmdHMS.append(str(yC)) dateYmdHMS.append(str(yD)) dateYmdHMS.append(str(yU)) dateYmdHMS.append('-') dateYmdHMS.append(str(mD)) dateYmdHMS.append(str(mU)) dateYmdHMS.append('-') dateYmdHMS.append(str(dD)) dateYmdHMS.append(str(dU)) dateYmdHMS.append('_') dateYmdHMS.append(str(hD)) dateYmdHMS.append(str(hU)) dateYmdHMS.append(':') dateYmdHMS.append(str(miD)) dateYmdHMS.append(str(miU)) dateYmdHMS.append(':') dateYmdHMS.append(str(sD)) dateYmdHMS.append(str(sU)) else: print errormsg print ' ' + fname + ': type of output date "' + typeSo + '" not ready !!!!' quit(-1) return dateYmdHMS def period_information(idate, edate, totunits): """ Function to provide the information of a given period idate, edate (dates in [YYYY][MM][DD][HH][MI][SS] format) [idate]= initial date of the period (in [YYYY][MM][DD][HH][MI][SS] format) [edate]= end date of the period (in [YYYY][MM][DD][HH][MI][SS] format) [totunits]= latest number of entire temporal units to compute: 'year', 'month', 'day', 'hour', 'minute', 'second' resultant information given as ',' list of: [dT]: sign of the temporal increment ('pos', 'neg') [idate]: initial date as [YYYY]:[MM]:[DD]:[HH]:[MI]:[SS] [edate]: end date as [YYYY]:[MM]:[DD]:[HH]:[MI]:[SS] [Nsecs]: total seconds between dates [Nyears]: Number of years taken as entire units ([iYYYY]0101000000 to [eYYYY+1]0101000000) [ExactYears]: Exact year-dates of the period as a '@' separated list of [YYYY]0101000000 [Nmonths]: Number of months taken as entire units ([iYYYY][iMM]01000000 to [eYYYY][eMM+1]01000000) [ExactMonths]: Exact mon-dates of the period as a '@' separated list of [YYYY][MM]01000000 [Ndays]: Number of days taken as entire units ([iYYYY][iMM][iDD]000000 to [eYYYY][eMM][eDD+1]000000) [ExactDays]: Exact day-dates of the period as a '@' separated list of [YYYY][MM][DD]000000 [Nhours]: Number of hours taken as entire units ([iYYYY][iMM][iDD][iHH]0000 to [eYYYY][eMM][eDD][eHH+1]0000) [ExactHours]: Exact hour-dates of the period as a '@' separated list of [YYYY][MM][DD][HH]0000 [Nminutes]: Number of minutes taken as entire units ([iYYYY][iMM][iDD][iHH][iMI]00 to [eYYYY][eMM][eDD][eHH][eMI+1]00) [ExactMinutes]: Exact minutes-dates of the period as a '@' separated list of [YYYY][MM][DD][HH][MI]00 [Nsecs]: Number of minutes taken as entire units ([iYYYY][iMM][iDD][iHH][iMI][iS] to [eYYYY][eMM][eDD][eHH][eMI][eSE+1]) [ExactSeconds]: Exact seconds-dates of the period as a '@' separated list of [YYYY][MM][DD][HH][MI][SS] >>> period_information( '19760217083110', '19770828000000', 'month') pos,1976:02:17:08:31:10,1977:08:28:00:00:00,48180530.0,19,19760201000000@19760301000000@19760401000000@ 19760501000000@19760601000000@19760701000000@19760801000000@19760901000000@19761001000000@19761101000000@ 19761201000000@19770101000000@19770201000000@19770301000000@19770401000000@19770501000000@19770601000000@ 19770701000000@19770801000000@19770901000000 """ import datetime as dt fname = 'period_information' if idate == 'h': print fname + '_____________________________________________________________' print period_information.__doc__ quit() expectargs = '[idate],[edate],[totunits]' check_arguments(fname,str(idate)+','+str(edate)+','+str(totunits),expectargs,',') readyT = ['year','month','week','day','hour','minute','second'] # Checking length Lidate = len(idate) Ledate = len(edate) if Lidate != Ledate: print errormsg print ' ' + fname + ': string dates of the period have different length !!' print " idate: '" + idate + "' (L=", Lidate, ") edate: '" + edate + \ "' (L=", Ledate, ')' quit(-1) else: if Lidate != 14: print errormsg print ' ' + fname + ": wrong initial date: '" + idate + "' must " + \ 'have 14 characters!!' print ' and it has:', Lidate quit(-1) if Ledate != 14: print errormsg print ' ' + fname + ": wrong end date: '" + edate + "' must " + \ 'have 14 characters!!' print ' and it has:', Ledate quit(-1) # Checking for right order of dates if int(idate) > int(edate): print warnmsg print ' ' + fname + ": initial date '" + idate + "' after end date '" + \ edate + "' !!" print " re-sorting them!" i1 = edate e1 = idate idate = i1 edate = e1 oinf = 'neg' else: oinf = 'pos' # Year, month, day, hour, minute, second initial date iyrS = idate[0:4] imoS = idate[4:6] idaS = idate[6:8] ihoS = idate[8:10] imiS = idate[10:12] iseS = idate[12:14] oinf = oinf + ',' + iyrS+':'+imoS+':'+idaS+':'+ihoS+':'+imiS+':'+iseS # Year, month, day, hour, minute, second end date eyrS = edate[0:4] emoS = edate[4:6] edaS = edate[6:8] ehoS = edate[8:10] emiS = edate[10:12] eseS = edate[12:14] oinf = oinf + ',' + eyrS+':'+emoS+':'+edaS+':'+ehoS+':'+emiS+':'+eseS idateT = dt.datetime(int(iyrS),int(imoS),int(idaS),int(ihoS),int(imiS),int(iseS)) edateT = dt.datetime(int(eyrS),int(emoS),int(edaS),int(ehoS),int(emiS),int(eseS)) # Seconds between dates DT = edateT - idateT # Python version depending if searchInlist(dir(DT), 'total_seconds'): Nsecs = DT.total_seconds() else: Nsecs = DT.days*24*3600. + DT.seconds oinf = oinf + ',' + str(Nsecs) # Looking for number of years tacking exact beginning of the units [iYYYY]0101000000, [eYYYY+1]0101000000 ## if totunits == 'year': itime = int(iyrS) if edate[4:15] != '0101000000': etime = int(eyrS)+1 else: etime = int(eyrS) itimeT = dt.datetime(itime,1,1,0,0,0) Nyears = 1 ExactYears = itimeT.strftime("%Y%m%d%H%M%S") it = int(iyrS) while it + 1 <= etime: it = it + 1 Nyears = Nyears + 1 itT = dt.datetime(it,1,1,0,0,0) ExactYears = ExactYears + '@' + itT.strftime("%Y%m%d%H%M%S") oinf = oinf + ',' + str(Nyears) + ',' + ExactYears # Looking for number of months tacking exact beginning of the units [iYYYY][iMM]01000000, [eYYYY][eMM+1]01000000 ## elif totunits == 'month': itime = int(iyrS)*100 + int(imoS) if edate[6:15] != '01000000': emo1 = int(emoS)+1 if emo1 > 13: eyr1 = str(int(eyrS) + 1) emo1 = 01 else: eyr1 = eyrS else: eyr1 = eyrS emo1 = emoS etime = int(eyr1)*100 + int(emo1) itimeT = dt.datetime(int(iyrS),int(imoS),1,0,0,0) Nmonths = 1 ExactMonths = itimeT.strftime("%Y%m%d%H%M%S") it = itime while it + 1 <= etime: it = it + 1 Nmonths = Nmonths + 1 ityr = it/100 itmo = it - ityr*100 if itmo > 12: ityr = ityr + 1 itmo = 1 it = ityr * 100 + itmo itT = dt.datetime(ityr,itmo,1,0,0,0) ExactMonths = ExactMonths + '@' + itT.strftime("%Y%m%d%H%M%S") oinf = oinf + ',' + str(Nmonths) + ',' + ExactMonths # Looking for number of days tacking exact beginning of the units [iYYYY][iMM][iDD]000000, [eYYYY][eMM][eDD+7]000000 ## elif totunits == 'week': itime = dt.datetime(int(iyrS),int(imoS),int(idaS),0,0,0) if edate[8:15] != '000000': etime = dt.datetime(int(eyrS), int(emoS), int(edaS)+7,0,0,0) else: etime = edateT Nweeks = 1 ExactDays = itime.strftime("%Y%m%d%H%M%S") it = itime while it + dt.timedelta(days=7) <= etime: it = it + dt.timedelta(days=7) Nweeks = Nweeks + 1 ExactDays = ExactDays + '@' + it.strftime("%Y%m%d%H%M%S") oinf = oinf + ',' + str(Nweeks) + ',' + ExactDays # Looking for number of days tacking exact beginning of the units [iYYYY][iMM][iDD]000000, [eYYYY][eMM][eDD+1]000000 ## elif totunits == 'day': itime = dt.datetime(int(iyrS),int(imoS),int(idaS),0,0,0) if edate[8:15] != '000000': etime = dt.datetime(int(eyrS), int(emoS), int(edaS)+1,0,0,0) else: etime = edateT Ndays = 1 ExactDays = itime.strftime("%Y%m%d%H%M%S") it = itime while it + dt.timedelta(days=1) <= etime: it = it + dt.timedelta(days=1) Ndays = Ndays + 1 ExactDays = ExactDays + '@' + it.strftime("%Y%m%d%H%M%S") oinf = oinf + ',' + str(Ndays) + ',' + ExactDays # Looking for number of hours tacking exact beginning of the units [iYYYY][iMM][iDD][iHH]0000, [eYYYY][eMM][eDD][iHH+1]0000 ## elif totunits == 'hour': itime = dt.datetime(int(iyrS),int(imoS),int(idaS),int(ihoS),0,0) if edate[10:15] != '0000': etime = dt.datetime(int(eyrS), int(emoS), int(edaS), int(ehoS)+1,0,0) else: etime = edateT Nhours = 1 ExactHours = itime.strftime("%Y%m%d%H%M%S") it = itime while it + dt.timedelta(hours=1) <= etime: it = it + dt.timedelta(hours=1) Nhours = Nhours + 1 ExactHours = ExactHours + '@' + it.strftime("%Y%m%d%H%M%S") oinf = oinf + ',' + str(Nhours) + ',' + ExactHours # Looking for number of minutes tacking exact beginning of the units [iYYYY][iMM][iDD][iHH][iMI]00, [eYYYY][eMM][eDD][iHH][iMI+1]00 ## elif totunits == 'minute': itime = dt.datetime(int(iyrS),int(imoS),int(idaS),int(ihoS),int(imiS),0) if edate[12:15] != '00': etime = dt.datetime(int(eyrS), int(emoS), int(edaS), int(ehoS), int(emiS)+1,0) else: etime = edateT Nminutes = 1 ExactMinutes = itime.strftime("%Y%m%d%H%M%S") it = itime while it + dt.timedelta(minutes=1) <= etime: it = it + dt.timedelta(minutes=1) Nminutes = Nminutes + 1 ExactMinutes = ExactMinutes + '@' + it.strftime("%Y%m%d%H%M%S") oinf = oinf + ',' + str(Nminutes) + ',' + ExactMinutes # Looking for number of seconds tacking exact beginning of the units [iYYYY][iMM][iDD][iHH][iMI][iSE], # [eYYYY][eMM][eDD][iHH][iMI][iSE+1] ## elif totunits == 'second': itime = dt.datetime(int(iyrS),int(imoS),int(idaS),int(ihoS),int(imiS),int(iseS)) if edate[12:15] != '00': etime = dt.datetime(int(eyrS), int(emoS), int(edaS), int(ehoS), int(emiS), int(eseS)+1) else: etime = edateT Nseconds = 1 ExactSeconds = itime.strftime("%Y%m%d%H%M%S") it = itime while it + dt.timedelta(seconds=1) < etime: it = it + dt.timedelta(seconds=1) Nseconds = Nseconds + 1 ExactSeconds = ExactSeconds + '@' + it.strftime("%Y%m%d%H%M%S") oinf = oinf + ',' + str(Nseconds) + ',' + ExactSeconds else: print errormsg print ' '+ fname + ": totalunits '" + totunits + "' not ready !!" print ' total time units ready:', readyT quit(-1) return oinf def diff_dates360(dateA,dateB): """ Function to provide the number of seconds of difference between two dates (dateA - dateB) on a 360 days/yr (or 12 30-days months) calendar dateA= date in [Y, m, d, h, mi, s] dateB= date in [Y, m, d, h, mi, s] >>> diff_dates360([1976,2,17,8,29,30], [1976,2,27,8,29,30]) -864000 """ fname = 'diff_dates360' # Reference date January first 1 refdate = np.array([1,1,1,0,0,0]) diffdatesA = np.array(dateA) - np.array(refdate) diffdatesB = np.array(dateB) - np.array(refdate) # seconds by time-units minsec = 60 hoursec = 60 * minsec daysec = 24 * hoursec monsec = 30 * daysec yrsec = 12 * monsec secs = [yrsec,monsec,daysec,hoursec,minsec,1] dsecsA = np.sum(diffdatesA*secs) dsecsB = np.sum(diffdatesB*secs) diffsecs = dsecsA - dsecsB return diffsecs def changedate360(idate,val,unit): """ Class to change a date on a 360 days/yr (or 12 30-days months) calendar idate = date to change [Y, m, d, h, mi, s] val = value to change unit= units to change [0: year; 1: month; 2: day; 3: hour; 4: minute; 5: second] >>> changedate360([1976,2,17,8,29,15],55,4) [1976, 2, 17, 9, 24, 15] >>> changedate360([1976,2,17,8,29,15],-55,5) [1976, 2, 17, 8, 28, 20] changedate360([1976,12,29,23,59,15],55,5) [1977, 1, 1, 0, 0, 10] """ fname = 'changedate360' sgn = np.abs(val)/val newdate = list(idate) Sunits = ['year', 'month', 'day', 'hour', 'minute', 'second'] # Maximum values for the time-unit tumaxs = [1e9, 13, 31, 24, 60, 60] # Minimum values for the time-unit tumins = [1, 1, 1, 0, 0, 0] if val > tumaxs[unit]: print errormsg print ' ' + fname + ': value to change:', val," for unit: '"+Sunits[unit]+ \ "' bigger than its limit:", tumaxs[unit] quit(-1) newval = idate[unit] + val for itu in range(unit,-1,-1): if newval >= tumaxs[itu]: if itu > 2: newdate[itu] = newval - tumaxs[itu] else: newdate[itu] = newval - tumaxs[itu] + 1 if newdate[itu] < tumins[itu]: newdate[itu] = tumins[itu] newdate[itu-1] = newdate[itu-1] + 1 elif newval < tumins[itu]: newdate[itu] = newdate[itu] + val + tumaxs[itu] + tumins[itu] newdate[itu-1] = newdate[itu-1] - 1 else: newdate[itu] = newval break newval = newdate[itu-1] return newdate def julday_360d(date): """ Function to provide the julian day of a date in a 360 days/yr (or 12 30-days months) calendar date= date [Y, m, d, h, mi, s] >>> julday_360d([1976,2,17,8,30,2]) 47 """ fname = 'julday_360d' julday = (date[1]-1)*30 + date[2] return julday class dtsec360dyr(object): """ Class to operate a number of seconds to a date in a 360 days/yr (or 12 30-days months) calendar date = initial date [Y, m, d, h, mi, s] delatsec = diferential of seconds to use self.year= year new date self.month= month new date self.day= day new date self.hour= hour new date self.minute= minute new date self.second= second new date self.dyear= increment in years self.dmonth= increment in months self.dday= increment in days self.dhour= increment in hours self.dminute= increment in minutes self.dsecond= increment in seconds self.newdate= resultant date as [Y, m, d, h, mi, s] >>> dtsec360dyr([1976,2,17,8,27,0], 3680) 1976 2 17 9 28 20 0 0 0 1 1 20 >>> dtsec360dyr([1976,2,17,8,27,0], -3680) 1976 2 17 7 25 40 0 0 0 -1 -1 -20 """ def __init__(self, date, deltasec): fname = 'dtsec360dyr' minsec = 60 hoursec = 60 * minsec daysec = 24 * hoursec monsec = 30 * daysec yrsec = 12 * monsec secs = [yrsec,monsec,daysec,hoursec,minsec,1] self.year = None self.month = None self.day = None self.hour = None self.minute = None self.second = None self.dyear = None self.dmonth = None self.dday = None self.dhour = None self.dminute = None self.dsecond = None self.newdate = None if date is not None and deltasec is not None: absdelta = np.abs(deltasec) sign = deltasec/absdelta newdate = list(date) Ndeltas = np.zeros((6), dtype=int) for idt in range(6): Ndeltas[idt] = (absdelta-np.sum(Ndeltas[0:idt]*secs[0:idt]))/secs[idt] if Ndeltas[idt] != 0: newdate = changedate360(newdate,sign*Ndeltas[idt],idt) self.year = newdate[0] self.month = newdate[1] self.day = newdate[2] self.hour = newdate[3] self.minute = newdate[4] self.second = newdate[5] self.dyear = sign*Ndeltas[0] self.dmonth = sign*Ndeltas[1] self.dday = sign*Ndeltas[2] self.dhour = sign*Ndeltas[3] self.dminute = sign*Ndeltas[4] self.dsecond = sign*Ndeltas[5] self.newdate = newdate def period_information_360d(idate, edate, totunits): """ Function to provide the information of a given period idate, edate (dates in [YYYY][MM][DD][HH][MI][SS] format) in a 360 years calendar [idate]= initial date of the period (in [YYYY][MM][DD][HH][MI][SS] format) [edate]= end date of the period (in [YYYY][MM][DD][HH][MI][SS] format) [totunits]= latest number of entire temporal units to compute: 'year', 'month', 'day', 'hour', 'minute', 'second' resultant information given as ',' list of: [dT]: sign of the temporal increment ('pos', 'neg') [idate]: initial date as [YYYY]:[MM]:[DD]:[HH]:[MI]:[SS] [edate]: end date as [YYYY]:[MM]:[DD]:[HH]:[MI]:[SS] [Nsecs]: total seconds between dates [Nyears]: Number of years taken as entire units ([iYYYY]0101000000 to [eYYYY+1]0101000000) [ExactYears]: Exact year-dates of the period as a '@' separated list of [YYYY]0101000000 [Nmonths]: Number of months taken as entire units ([iYYYY][iMM]01000000 to [eYYYY][eMM+1]01000000) [ExactMonths]: Exact mon-dates of the period as a '@' separated list of [YYYY][MM]01000000 [Ndays]: Number of days taken as entire units ([iYYYY][iMM][iDD]000000 to [eYYYY][eMM][eDD+1]000000) [ExactDays]: Exact day-dates of the period as a '@' separated list of [YYYY][MM][DD]000000 [Nhours]: Number of hours taken as entire units ([iYYYY][iMM][iDD][iHH]0000 to [eYYYY][eMM][eDD][eHH+1]0000) [ExactHours]: Exact hour-dates of the period as a '@' separated list of [YYYY][MM][DD][HH]0000 [Nminutes]: Number of minutes taken as entire units ([iYYYY][iMM][iDD][iHH][iMI]00 to [eYYYY][eMM][eDD][eHH][eMI+1]00) [ExactMinutes]: Exact minutes-dates of the period as a '@' separated list of [YYYY][MM][DD][HH][MI]00 [Nsecs]: Number of minutes taken as entire units ([iYYYY][iMM][iDD][iHH][iMI][iS] to [eYYYY][eMM][eDD][eHH][eMI][eSE+1]) [ExactSeconds]: Exact seconds-dates of the period as a '@' separated list of [YYYY][MM][DD][HH][MI][SS] >>> period_information_360d( '19760217083110', '19770128000000', 'week') pos,1976:02:17:08:31:10,1977:01:28:00:00:00,29863730.0,49,19760217000000@19760224000000@19760301000000@19760308000000@ 19760315000000@19760322000000@19760329000000@19760406000000@19760413000000@19760420000000@19760427000000@ 19760504000000@19760511000000@19760518000000@19760525000000@19760602000000@19760609000000@19760616000000@ 19760623000000@19760630000000@19760707000000@19760714000000@19760721000000@19760728000000@19760805000000@ 19760812000000@19760819000000@19760826000000@19760903000000@19760910000000@19760917000000@19760924000000@ 19761001000000@19761008000000@19761015000000@19761022000000@19761029000000@19761106000000@19761113000000@ 19761120000000@19761127000000@19761204000000@19761211000000@19761218000000@19761225000000@19770102000000@ 19770109000000@19770116000000@19770123000000 """ import datetime as dt fname = 'period_information_360d' if idate == 'h': print fname + '_____________________________________________________________' print period_information_360d.__doc__ quit() expectargs = '[idate],[edate],[totunits]' check_arguments(fname,str(idate)+','+str(edate)+','+str(totunits),expectargs,',') readyT = ['year','month','week','day','hour','minute','second'] # Seconds time-units minsec = 60 hoursec = 60 * minsec daysec = 24 * hoursec monsec = 30 * daysec yrsec = 12 * monsec secs = [yrsec,monsec,daysec,hoursec,minsec,1] # Checking length Lidate = len(idate) Ledate = len(edate) if Lidate != Ledate: print errormsg print ' ' + fname + ': string dates of the period have different length !!' print " idate: '" + idate + "' (L=", Lidate, ") edate: '" + edate + \ "' (L=", Ledate, ')' quit(-1) else: if Lidate != 14: print errormsg print ' ' + fname + ": wrong initial date: '" + idate + "' must " + \ 'have 14 characters!!' print ' and it has:', Lidate quit(-1) if Ledate != 14: print errormsg print ' ' + fname + ": wrong end date: '" + edate + "' must " + \ 'have 14 characters!!' print ' and it has:', Ledate quit(-1) # Checking for right order of dates if int(idate) > int(edate): print warnmsg print ' ' + fname + ": initial date '" + idate + "' after end date '" + \ edate + "' !!" print " re-sorting them!" i1 = edate e1 = idate idate = i1 edate = e1 oinf = 'neg' else: oinf = 'pos' # Year, month, day, hour, minute, second initial date iyrS = idate[0:4] imoS = idate[4:6] idaS = idate[6:8] ihoS = idate[8:10] imiS = idate[10:12] iseS = idate[12:14] oinf = oinf + ',' + iyrS+':'+imoS+':'+idaS+':'+ihoS+':'+imiS+':'+iseS # Year, month, day, hour, minute, second end date eyrS = edate[0:4] emoS = edate[4:6] edaS = edate[6:8] ehoS = edate[8:10] emiS = edate[10:12] eseS = edate[12:14] oinf = oinf + ',' + eyrS+':'+emoS+':'+edaS+':'+ehoS+':'+emiS+':'+eseS idateT = dt.datetime(int(iyrS),int(imoS),int(idaS),int(ihoS),int(imiS),int(iseS)) edateT = dt.datetime(int(eyrS),int(emoS),int(edaS),int(ehoS),int(emiS),int(eseS)) # Seconds between dates DT = edateT - idateT # Python version depending if searchInlist(dir(DT), 'total_seconds'): Nsecs = DT.total_seconds() else: Nsecs = DT.days*24*3600. + DT.seconds oinf = oinf + ',' + str(Nsecs) daysYr = 360 months = np.ones((12), dtype=int)*1 # Looking for number of years tacking exact beginning of the units [iYYYY]0101000000, [eYYYY+1]0101000000 ## if totunits == 'year': itime = int(iyrS) if edate[4:15] != '0101000000': etime = int(eyrS)+1 else: etime = int(eyrS) itimeT = dt.datetime(itime,1,1,0,0,0) Nyears = 1 ExactYears = itimeT.strftime("%Y%m%d%H%M%S") it = int(iyrS) while it + 1 <= etime: it = it + 1 Nyears = Nyears + 1 itT = dt.datetime(it,1,1,0,0,0) ExactYears = ExactYears + '@' + itT.strftime("%Y%m%d%H%M%S") oinf = oinf + ',' + str(Nyears) + ',' + ExactYears # Looking for number of months tacking exact beginning of the units [iYYYY][iMM]01000000, [eYYYY][eMM+1]01000000 ## elif totunits == 'month': itime = int(iyrS)*100 + int(imoS) if edate[6:15] != '01000000': emo1 = int(emoS)+1 if emo1 > 13: eyr1 = str(int(eyrS) + 1) emo1 = 01 else: eyr1 = eyrS else: eyr1 = eyrS emo1 = emoS etime = int(eyr1)*100 + int(emo1) itimeT = dt.datetime(int(iyrS),int(imoS),1,0,0,0) Nmonths = 1 ExactMonths = itimeT.strftime("%Y%m%d%H%M%S") it = itime while it + 1 <= etime: it = it + 1 Nmonths = Nmonths + 1 ityr = it/100 itmo = it - ityr*100 if itmo > 12: ityr = ityr + 1 itmo = 1 it = ityr * 100 + itmo itT = dt.datetime(ityr,itmo,1,0,0,0) ExactMonths = ExactMonths + '@' + itT.strftime("%Y%m%d%H%M%S") oinf = oinf + ',' + str(Nmonths) + ',' + ExactMonths # Looking for number of weeks tacking exact beginning of the units [iYYYY][iMM][iDD]000000, [eYYYY][eMM][eDD+7]000000 ## elif totunits == 'week': itime = [int(iyrS),int(imoS),int(idaS),0,0,0] if edate[8:15] != '000000': etime = [int(eyrS), int(emoS), int(edaS)+7,0,0,0] else: etime = [int(eyrS),int(emoS),int(edaS),int(ehoS),int(emiS),int(eseS)] ExactDays = datetimeStr_conversion(itime,'matYmdHMS','YmdHMS') erefsecs = diff_dates360(etime,[1,1,1,0,0,0]) Nweeks = 1 it = itime refsecs = diff_dates360(it,[1,1,1,0,0,0]) while refsecs + 7*daysec <= erefsecs: refsecs = refsecs + 7*daysec dateincr = dtsec360dyr(it,7*daysec) it = dateincr.newdate Nweeks = Nweeks + 1 ExactDays = ExactDays + '@' + datetimeStr_conversion(it,'matYmdHMS','YmdHMS') oinf = oinf + ',' + str(Nweeks) + ',' + ExactDays # Looking for number of days tacking exact beginning of the units [iYYYY][iMM][iDD]000000, [eYYYY][eMM][eDD+1]000000 ## elif totunits == 'day': itime = [int(iyrS),int(imoS),int(idaS),0,0,0] if edate[8:15] != '000000': etime = [int(eyrS), int(emoS), int(edaS)+1,0,0,0] else: etime = [int(eyrS),int(emoS),int(edaS),int(ehoS),int(emiS),int(eseS)] ExactDays = datetimeStr_conversion(itime,'matYmdHMS','YmdHMS') erefsecs = diff_dates360(etime,[1,1,1,0,0,0]) Ndays = 1 it = itime refsecs = diff_dates360(it,[1,1,1,0,0,0]) while refsecs + 1*daysec <= erefsecs: refsecs = refsecs + 1*daysec dateincr = dtsec360dyr(it,1*daysec) it = dateincr.newdate Ndays = Ndayss + 1 ExactDays = ExactDays + '@' + datetimeStr_conversion(it,'matYmdHMS','YmdHMS') oinf = oinf + ',' + str(Ndays) + ',' + ExactDays # Looking for number of hours tacking exact beginning of the units [iYYYY][iMM][iDD][iHH]0000, [eYYYY][eMM][eDD][iHH+1]0000 ## elif totunits == 'hour': itime = [int(iyrS),int(imoS),int(idaS),int(ihoS),0,0] if edate[10:15] != '0000': etime = [int(eyrS), int(emoS), int(edaS), int(ehoS)+1,0,0] else: etime = [int(eyrS),int(emoS),int(edaS),int(ehoS),int(emiS),int(eseS)] Nhours = 1 ExactHours = datetimeStr_conversion(itime,'matYmdHMS','YmdHMS') erefsecs = diff_dates360(etime,[1,1,1,0,0,0]) it = itime refsecs = diff_dates360(it,[1,1,1,0,0,0]) while refsecs + 1*daysec <= erefsecs: refsecs = refsecs + 1*hoursec dateincr = dtsec360dyr(it,1*hoursec) it = dateincr.newdate Nhours = Nhours + 1 ExactHours = ExactHours + '@' + datetimeStr_conversion(it,'matYmdHMS','YmdHMS') oinf = oinf + ',' + str(Nhours) + ',' + ExactHours # Looking for number of minutes tacking exact beginning of the units [iYYYY][iMM][iDD][iHH][iMI]00, [eYYYY][eMM][eDD][iHH][iMI+1]00 ## elif totunits == 'minute': itime = [int(iyrS),int(imoS),int(idaS),int(ihoS),int(imiS),0] if edate[12:15] != '00': etime = [int(eyrS), int(emoS), int(edaS), int(ehoS), int(emiS)+1,0] else: etime = [int(eyrS),int(emoS),int(edaS),int(ehoS),int(emiS),int(eseS)] Nminutes = 1 ExactMinutes = datetimeStr_conversion(itime,'matYmdHMS','YmdHMS') erefsecs = diff_dates360(etime,[1,1,1,0,0,0]) it = itime refsecs = diff_dates360(it,[1,1,1,0,0,0]) while refsecs + 1*minsec <= erefsecs: refsecs = refsecs + 1*minsec dateincr = dtsec360dyr(it,1*hoursec) Nminutes = Nminutes + 1 ExactMinutes = ExactMinutes +'@' + datetimeStr_conversion(it,'matYmdHMS',\ 'YmdHMS') oinf = oinf + ',' + str(Nminutes) + ',' + ExactMinutes # Looking for number of seconds tacking exact beginning of the units [iYYYY][iMM][iDD][iHH][iMI][iSE], # [eYYYY][eMM][eDD][iHH][iMI][iSE+1] ## elif totunits == 'second': itime = [int(iyrS),int(imoS),int(idaS),int(ihoS),int(imiS),int(iseS)] if edate[12:15] != '00': etime = [int(eyrS), int(emoS), int(edaS), int(ehoS), int(emiS), int(eseS)+1] else: etime = [int(iyrS),int(imoS),int(idaS),int(ihoS),int(imiS),int(iseS)] Nseconds = 1 ExactSeconds = datetimeStr_conversion(itime,'matYmdHMS','YmdHMS') erefsecs = diff_dates360(etime,[1,1,1,0,0,0]) it = itime refsecs = diff_dates360(it,[1,1,1,0,0,0]) while refsecs + 1 <= erefsecs: refsecs = refsecs + 1 dateincr = dtsec360dyr(it,1*hoursec) Nseconds = Nseconds + 1 ExactSeconds = ExactSeconds + '@'+ datetimeStr_conversion(it,'matYmdHMS',\ 'YmdHMS') oinf = oinf + ',' + str(Nseconds) + ',' + ExactSeconds else: print errormsg print ' '+ fname + ": totalunits '" + totunits + "' not ready !!" print ' total time units ready:', readyT quit(-1) return oinf def variables_values(varName): """ Function to provide values to plot the different variables values from ASCII file 'variables_values.dat' variables_values(varName) [varName]= name of the variable return: [var name], [std name], [minimum], [maximum], [long name]('|' for spaces), [units], [color palette] (following: http://matplotlib.org/1.3.1/examples/color/colormaps_reference.html) [varn]: original name of the variable NOTE: It might be better doing it with an external ASII file. But then we got an extra dependency... >>> variables_values('WRFght') ['z', 'geopotential_height', 0.0, 80000.0, 'geopotential|height', 'm2s-2', 'rainbow'] """ import subprocess as sub fname='variables_values' if varName == 'h': print fname + '_____________________________________________________________' print variables_values.__doc__ quit() # This does not work.... # folderins = sub.Popen(["pwd"], stdout=sub.PIPE) # folder = list(folderins.communicate())[0].replace('\n','') # From http://stackoverflow.com/questions/4934806/how-can-i-find-scripts-directory-with-python folder = os.path.dirname(os.path.realpath(__file__)) infile = folder + '/variables_values.dat' if not os.path.isfile(infile): print errormsg print ' ' + fname + ": File '" + infile + "' does not exist !!" quit(-1) # Variables with a statistical section on their name... NOstatsvars = ['zmaxth', 'zmax_th', 'lmax_th', 'lmaxth'] ifst = False if not searchInlist(NOstatsvars, varName.lower()): for st in statsurname: if varName.find(st) > -1: print ' '+ fname + ": varibale '" + varName + "' with a " + \ "statistical surname: '",st,"' !!" varName = varName.replace(st,'') ifst = True varn = varName ncf = open(infile, 'r') for line in ncf: if line[0:1] != '#': values = line.replace('\n','').split(',') if len(values) != 8: print errormsg print "problem in varibale:'", values[0], \ 'it should have 8 values and it has',len(values) quit(-1) if varn[0:6] == 'varDIM': # Variable from a dimension (all with 'varDIM' prefix) Lvarn = len(varn) varvals = [varn[6:Lvarn+1], varn[6:Lvarn+1], 0., 1., \ "variable|from|size|of|dimension|'" + varn[6:Lvarn+1] + "'", '1', \ 'rainbow'] else: varvals = [values[1].replace(' ',''), values[2].replace(' ',''), \ np.float(values[3]), np.float(values[4]),values[5].replace(' ',''),\ values[6].replace(' ',''), values[7].replace(' ','')] if values[0] == varn: ncf.close() return varvals break print errormsg print ' ' + fname + ": variable '" + varn + "' not defined !!!" ncf.close() quit(-1) return def CFvar_MODvar(varn): """ Function to provide which model values can provide a CF-variable from ASCII file 'variables_values.dat' CFvar_MODvar(varn) [varn]= CF name of the variable >>> CFvar_MODvar('hfss') ['hfss', 'LSENS', 'sens', 'HFX', 'hfx'] >>> CFvar_MODvar('clm') ['clm', 'cldm', 'LCLDM', 'Mid-level cloudiness'] >>> CFvar_MODvar('pr') ['pr', 'RAINTOT', 'precip', 'LPRECIP', 'Precip Totale liq+sol'] """ import subprocess as sub fname='CFvar_MODvar' if varn == 'h': print fname + '_____________________________________________________________' print CFvar_MODvar.__doc__ quit() folder = os.path.dirname(os.path.realpath(__file__)) infile = folder + '/variables_values.dat' if not os.path.isfile(infile): print errormsg print ' ' + fname + ": File '" + infile + "' does not exist !!" quit(-1) ncf = open(infile, 'r') MODvars = [] for line in ncf: if line[0:1] != '#': values = line.replace('\n','').split(',') varvals = [values[1].replace(' ',''), values[2].replace(' ',''), \ np.float(values[3]), np.float(values[4]),values[5].replace(' ',''), \ values[6].replace(' ',''), values[7].replace(' ','')] if varvals[0] == varn: MODvars.append(values[0]) if len(MODvars) == 0: # print errormsg # print ' ' + fname + ": variable '" + varn + "' not defined !!!" ncf.close() return None else: return MODvars def CFvar_DIAGvar(varn): """ Function to provide which model diagnostic values can provide a CF-variable from ASCII file 'diagnostics.inf' (reference for diagnostics.py') [CFname], [moddiag], [varcombo] [CFname]: CF name of the variable [moddiag]: name of the diagnosted variable (for `diagnostic.py') [varcombo]: combnination of variables to be used to compute diagnostic CFvar_DIAGvar(varn) [varn]= CF name of the variable >>> CFvar_DIAGvar('pr') {'RAINTOT': ['RAINC', 'RAINNC']} >>> CFvar_DIAGvar('hurs') {'TSrhs': ['psfc', 't', 'q'], 'LMDZrhs': ['psol', 't2m', 'q2m'], 'WRFrhs': ['PSFC', 'T2', 'Q2']} >>> CFvar_DIAGvar('wss') {'wss': [['U10', 'V10'], ['u10m', 'v10m']]} """ import subprocess as sub fname='CFvar_DIAGvar' if varn == 'h': print fname + '_____________________________________________________________' print CFvar_DIAGvar.__doc__ quit() folder = os.path.dirname(os.path.realpath(__file__)) infile = folder + '/diagnostics.inf' if not os.path.isfile(infile): print errormsg print ' ' + fname + ": File '" + infile + "' does not exist !!" quit(-1) ncf = open(infile, 'r') MODvars = {} for line in ncf: if line[0:1] != '#': values = line.replace('\n','').replace(' ','').split(',') if values[0] == varn: MODdiags = values[2].split('@') if MODvars.has_key(values[1]): oldvals = MODvars[values[1]] oldvals = [oldvals, MODdiags] MODvars[values[1]] = oldvals else: MODvars[values[1]] = MODdiags if len(MODvars) == 0: # print errormsg # print ' ' + fname + ": variable '" + varn + "' not defined !!!" ncf.close() return None else: ncf.close() return MODvars def variables_values_old(varName): """ Function to provide values to plot the different variables variables_values(varName) [varName]= name of the variable return: [var name], [std name], [minimum], [maximum], [long name]('|' for spaces), [units], [color palette] (following: http://matplotlib.org/1.3.1/examples/color/colormaps_reference.html) [varn]: original name of the variable NOTE: It might be better doing it with an external ASII file. But then we got an extra dependency... >>> variables_values('WRFght') ['z', 'geopotential_height', 0.0, 80000.0, 'geopotential|height', 'm2s-2', 'rainbow'] """ fname='variables_values' if varName == 'h': print fname + '_____________________________________________________________' print variables_values.__doc__ quit() # Variable name might come with a statistical surname... stats=['min','max','mean','stdv', 'sum'] ifst = False for st in stats: if varName.find(st) > -1: print ' '+ fname + ": varibale '" + varName + "' with a statistical "+\ " surname: '",st,"' !!" Lst = len(st) LvarName = len(varName) varn = varName[0:LvarName - Lst] ifst = True break if not ifst: varn = varName if varn[0:6] == 'varDIM': # Variable from a dimension (all with 'varDIM' prefix) Lvarn = len(varn) varvals = [varn[6:Lvarn+1], varn[6:Lvarn+1], 0., 1., \ "variable|from|size|of|dimension|'" + varn[6:Lvarn+1] + "'", '1', 'rainbox'] elif varn == 'a_tht' or varn == 'LA_THT': varvals = ['ath', 'total_thermal_plume_cover', 0., 1., \ 'total|column|thermal|plume|cover', '1', 'YlGnBu'] elif varn == 'acprc' or varn == 'RAINC': varvals = ['acprc', 'accumulated_cmulus_precipitation', 0., 3.e4, \ 'accumulated|cmulus|precipitation', 'mm', 'Blues'] elif varn == 'acprnc' or varn == 'RAINNC': varvals = ['acprnc', 'accumulated_non-cmulus_precipitation', 0., 3.e4, \ 'accumulated|non-cmulus|precipitation', 'mm', 'Blues'] elif varn == 'bils' or varn == 'LBILS': varvals = ['bils', 'surface_total_heat_flux', -100., 100., \ 'surface|total|heat|flux', 'Wm-2', 'seismic'] elif varn == 'landcat' or varn == 'category': varvals = ['landcat', 'land_categories', 0., 22., 'land|categories', '1', \ 'rainbow'] elif varn == 'c' or varn == 'QCLOUD' or varn == 'oliq' or varn == 'OLIQ': varvals = ['c', 'condensed_water_mixing_ratio', 0., 3.e-4, \ 'condensed|water|mixing|ratio', 'kgkg-1', 'BuPu'] elif varn == 'ci' or varn == 'iwcon' or varn == 'LIWCON': varvals = ['ci', 'cloud_iced_water_mixing_ratio', 0., 0.0003, \ 'cloud|iced|water|mixing|ratio', 'kgkg-1', 'Purples'] elif varn == 'cl' or varn == 'lwcon' or varn == 'LLWCON': varvals = ['cl', 'cloud_liquidwater_mixing_ratio', 0., 0.0003, \ 'cloud|liquid|water|mixing|ratio', 'kgkg-1', 'Blues'] elif varn == 'cld' or varn == 'CLDFRA' or varn == 'rneb' or varn == 'lrneb' or \ varn == 'LRNEB': varvals = ['cld', 'cloud_area_fraction', 0., 1., 'cloud|fraction', '1', \ 'gist_gray'] elif varn == 'cldc' or varn == 'rnebcon' or varn == 'lrnebcon' or \ varn == 'LRNEBCON': varvals = ['cldc', 'convective_cloud_area_fraction', 0., 1., \ 'convective|cloud|fraction', '1', 'gist_gray'] elif varn == 'cldl' or varn == 'rnebls' or varn == 'lrnebls' or varn == 'LRNEBLS': varvals = ['cldl', 'large_scale_cloud_area_fraction', 0., 1., \ 'large|scale|cloud|fraction', '1', 'gist_gray'] elif varn == 'clt' or varn == 'CLT' or varn == 'cldt' or \ varn == 'Total cloudiness': varvals = ['clt', 'cloud_area_fraction', 0., 1., 'total|cloud|cover', '1', \ 'gist_gray'] elif varn == 'cll' or varn == 'cldl' or varn == 'LCLDL' or \ varn == 'Low-level cloudiness': varvals = ['cll', 'low_level_cloud_area_fraction', 0., 1., \ 'low|level|(p|>|680|hPa)|cloud|fraction', '1', 'gist_gray'] elif varn == 'clm' or varn == 'cldm' or varn == 'LCLDM' or \ varn == 'Mid-level cloudiness': varvals = ['clm', 'mid_level_cloud_area_fraction', 0., 1., \ 'medium|level|(440|<|p|<|680|hPa)|cloud|fraction', '1', 'gist_gray'] elif varn == 'clh' or varn == 'cldh' or varn == 'LCLDH' or \ varn == 'High-level cloudiness': varvals = ['clh', 'high_level_cloud_area_fraction', 0., 1., \ 'high|level|(p|<|440|hPa)|cloud|fraction', '1', 'gist_gray'] elif varn == 'clmf' or varn == 'fbase' or varn == 'LFBASE': varvals = ['clmf', 'cloud_base_max_flux', -0.3, 0.3, 'cloud|base|max|flux', \ 'kgm-2s-1', 'seismic'] elif varn == 'clp' or varn == 'pbase' or varn == 'LPBASE': varvals = ['clp', 'cloud_base_pressure', -0.3, 0.3, 'cloud|base|pressure', \ 'Pa', 'Reds'] elif varn == 'cpt' or varn == 'ptconv' or varn == 'LPTCONV': varvals = ['cpt', 'convective_point', 0., 1., 'convective|point', '1', \ 'seismic'] elif varn == 'dqajs' or varn == 'LDQAJS': varvals = ['dqajs', 'dry_adjustment_water_vapor_tendency', -0.0003, 0.0003, \ 'dry|adjustment|water|vapor|tendency', 'kg/kg/s', 'seismic'] elif varn == 'dqcon' or varn == 'LDQCON': varvals = ['dqcon', 'convective_water_vapor_tendency', -3e-8, 3.e-8, \ 'convective|water|vapor|tendency', 'kg/kg/s', 'seismic'] elif varn == 'dqdyn' or varn == 'LDQDYN': varvals = ['dqdyn', 'dynamics_water_vapor_tendency', -3.e-7, 3.e-7, \ 'dynamics|water|vapor|tendency', 'kg/kg/s', 'seismic'] elif varn == 'dqeva' or varn == 'LDQEVA': varvals = ['dqeva', 'evaporation_water_vapor_tendency', -3.e-6, 3.e-6, \ 'evaporation|water|vapor|tendency', 'kg/kg/s', 'seismic'] elif varn == 'dqlscst' or varn == 'LDQLSCST': varvals = ['dqlscst', 'stratocumulus_water_vapor_tendency', -3.e-7, 3.e-7, \ 'stratocumulus|water|vapor|tendency', 'kg/kg/s', 'seismic'] elif varn == 'dqlscth' or varn == 'LDQLSCTH': varvals = ['dqlscth', 'thermals_water_vapor_tendency', -3.e-7, 3.e-7, \ 'thermal|plumes|water|vapor|tendency', 'kg/kg/s', 'seismic'] elif varn == 'dqlsc' or varn == 'LDQLSC': varvals = ['dqlsc', 'condensation_water_vapor_tendency', -3.e-6, 3.e-6, \ 'condensation|water|vapor|tendency', 'kg/kg/s', 'seismic'] elif varn == 'dqphy' or varn == 'LDQPHY': varvals = ['dqphy', 'physics_water_vapor_tendency', -3.e-7, 3.e-7, \ 'physics|water|vapor|tendency', 'kg/kg/s', 'seismic'] elif varn == 'dqthe' or varn == 'LDQTHE': varvals = ['dqthe', 'thermals_water_vapor_tendency', -3.e-7, 3.e-7, \ 'thermal|plumes|water|vapor|tendency', 'kg/kg/s', 'seismic'] elif varn == 'dqvdf' or varn == 'LDQVDF': varvals = ['dqvdf', 'vertical_difussion_water_vapor_tendency', -3.e-8, 3.e-8,\ 'vertical|difussion|water|vapor|tendency', 'kg/kg/s', 'seismic'] elif varn == 'dqwak' or varn == 'LDQWAK': varvals = ['dqwak', 'wake_water_vapor_tendency', -3.e-7, 3.e-7, \ 'wake|water|vapor|tendency', 'kg/kg/s', 'seismic'] elif varn == 'dta' or varn == 'tnt' or varn == 'LTNT': varvals = ['dta', 'tendency_air_temperature', -3.e-3, 3.e-3, \ 'tendency|of|air|temperature', 'K/s', 'seismic'] elif varn == 'dtac' or varn == 'tntc' or varn == 'LTNTC': varvals = ['dtac', 'moist_convection_tendency_air_temperature', -3.e-3, \ 3.e-3, 'moist|convection|tendency|of|air|temperature', 'K/s', 'seismic'] elif varn == 'dtar' or varn == 'tntr' or varn == 'LTNTR': varvals = ['dtar', 'radiative_heating_tendency_air_temperature', -3.e-3, \ 3.e-3, 'radiative|heating|tendency|of|air|temperature', 'K/s', 'seismic'] elif varn == 'dtascpbl' or varn == 'tntscpbl' or varn == 'LTNTSCPBL': varvals = ['dtascpbl', \ 'stratiform_cloud_precipitation_BL_mixing_tendency_air_temperature', \ -3.e-6, 3.e-6, \ 'stratiform|cloud|precipitation|Boundary|Layer|mixing|tendency|air|' + 'temperature', 'K/s', 'seismic'] elif varn == 'dtajs' or varn == 'LDTAJS': varvals = ['dtajs', 'dry_adjustment_thermal_tendency', -3.e-5, 3.e-5, \ 'dry|adjustment|thermal|tendency', 'K/s', 'seismic'] elif varn == 'dtcon' or varn == 'LDTCON': varvals = ['dtcon', 'convective_thermal_tendency', -3.e-5, 3.e-5, \ 'convective|thermal|tendency', 'K/s', 'seismic'] elif varn == 'dtdyn' or varn == 'LDTDYN': varvals = ['dtdyn', 'dynamics_thermal_tendency', -3.e-4, 3.e-4, \ 'dynamics|thermal|tendency', 'K/s', 'seismic'] elif varn == 'dteva' or varn == 'LDTEVA': varvals = ['dteva', 'evaporation_thermal_tendency', -3.e-3, 3.e-3, \ 'evaporation|thermal|tendency', 'K/s', 'seismic'] elif varn == 'dtlscst' or varn == 'LDTLSCST': varvals = ['dtlscst', 'stratocumulus_thermal_tendency', -3.e-4, 3.e-4, \ 'stratocumulus|thermal|tendency', 'K/s', 'seismic'] elif varn == 'dtlscth' or varn == 'LDTLSCTH': varvals = ['dtlscth', 'thermals_thermal_tendency', -3.e-4, 3.e-4, \ 'thermal|plumes|thermal|tendency', 'K/s', 'seismic'] elif varn == 'dtlsc' or varn == 'LDTLSC': varvals = ['dtlsc', 'condensation_thermal_tendency', -3.e-3, 3.e-3, \ 'condensation|thermal|tendency', 'K/s', 'seismic'] elif varn == 'dtlwr' or varn == 'LDTLWR': varvals = ['dtlwr', 'long_wave_thermal_tendency', -3.e-3, 3.e-3, \ 'long|wave|radiation|thermal|tendency', 'K/s', 'seismic'] elif varn == 'dtphy' or varn == 'LDTPHY': varvals = ['dtphy', 'physics_thermal_tendency', -3.e-4, 3.e-4, \ 'physics|thermal|tendency', 'K/s', 'seismic'] elif varn == 'dtsw0' or varn == 'LDTSW0': varvals = ['dtsw0', 'cloudy_sky_short_wave_thermal_tendency', -3.e-4, 3.e-4, \ 'cloudy|sky|short|wave|radiation|thermal|tendency', 'K/s', 'seismic'] elif varn == 'dtthe' or varn == 'LDTTHE': varvals = ['dtthe', 'thermals_thermal_tendency', -3.e-4, 3.e-4, \ 'thermal|plumes|thermal|tendency', 'K/s', 'seismic'] elif varn == 'dtvdf' or varn == 'LDTVDF': varvals = ['dtvdf', 'vertical_difussion_thermal_tendency', -3.e-5, 3.e-5, \ 'vertical|difussion|thermal|tendency', 'K/s', 'seismic'] elif varn == 'dtwak' or varn == 'LDTWAK': varvals = ['dtwak', 'wake_thermal_tendency', -3.e-4, 3.e-4, \ 'wake|thermal|tendency', 'K/s', 'seismic'] elif varn == 'ducon' or varn == 'LDUCON': varvals = ['ducon', 'convective_eastward_wind_tendency', -3.e-3, 3.e-3, \ 'convective|eastward|wind|tendency', 'ms-2', 'seismic'] elif varn == 'dudyn' or varn == 'LDUDYN': varvals = ['dudyn', 'dynamics_eastward_wind_tendency', -3.e-3, 3.e-3, \ 'dynamics|eastward|wind|tendency', 'ms-2', 'seismic'] elif varn == 'duvdf' or varn == 'LDUVDF': varvals = ['duvdf', 'vertical_difussion_eastward_wind_tendency', -3.e-3, \ 3.e-3, 'vertical|difussion|eastward|wind|tendency', 'ms-2', 'seismic'] elif varn == 'dvcon' or varn == 'LDVCON': varvals = ['dvcon', 'convective_difussion_northward_wind_tendency', -3.e-3, \ 3.e-3, 'convective|northward|wind|tendency', 'ms-2', 'seismic'] elif varn == 'dvdyn' or varn == 'LDVDYN': varvals = ['dvdyn', 'dynamics_northward_wind_tendency', -3.e-3, \ 3.e-3, 'dynamics|difussion|northward|wind|tendency', 'ms-2', 'seismic'] elif varn == 'dvvdf' or varn == 'LDVVDF': varvals = ['dvvdf', 'vertical_difussion_northward_wind_tendency', -3.e-3, \ 3.e-3, 'vertical|difussion|northward|wind|tendency', 'ms-2', 'seismic'] elif varn == 'etau' or varn == 'ZNU': varvals = ['etau', 'etau', 0., 1, 'eta values on half (mass) levels', '-', \ 'reds'] elif varn == 'evspsbl' or varn == 'LEVAP' or varn == 'evap' or varn == 'SFCEVPde': varvals = ['evspsbl', 'water_evaporation_flux', 0., 1.5e-4, \ 'water|evaporation|flux', 'kgm-2s-1', 'Blues'] elif varn == 'evspsbl' or varn == 'SFCEVPde': varvals = ['evspsblac', 'water_evaporation_flux_ac', 0., 1.5e-4, \ 'accumulated|water|evaporation|flux', 'kgm-2', 'Blues'] elif varn == 'g' or varn == 'QGRAUPEL': varvals = ['g', 'grauepl_mixing_ratio', 0., 0.0003, 'graupel|mixing|ratio', \ 'kgkg-1', 'Purples'] elif varn == 'h2o' or varn == 'LH2O': varvals = ['h2o', 'water_mass_fraction', 0., 3.e-2, \ 'mass|fraction|of|water', '1', 'Blues'] elif varn == 'h' or varn == 'QHAIL': varvals = ['h', 'hail_mixing_ratio', 0., 0.0003, 'hail|mixing|ratio', \ 'kgkg-1', 'Purples'] elif varn == 'hfls' or varn == 'LH' or varn == 'LFLAT' or varn == 'flat': varvals = ['hfls', 'surface_upward_latent_heat_flux', -400., 400., \ 'upward|latnt|heat|flux|at|the|surface', 'Wm-2', 'seismic'] elif varn == 'hfss' or varn == 'LSENS' or varn == 'sens': varvals = ['hfss', 'surface_upward_sensible_heat_flux', -150., 150., \ 'upward|sensible|heat|flux|at|the|surface', 'Wm-2', 'seismic'] elif varn == 'hus' or varn == 'WRFrh' or varn == 'LMDZrh' or varn == 'rhum' or \ varn == 'LRHUM': varvals = ['hus', 'specific_humidity', 0., 1., 'specific|humidty', '1', \ 'BuPu'] elif varn == 'huss' or varn == 'WRFrhs' or varn == 'LMDZrhs' or varn == 'rh2m' or\ varn == 'LRH2M': varvals = ['huss', 'specific_humidity', 0., 1., 'specific|humidty|at|2m', \ '1', 'BuPu'] elif varn == 'i' or varn == 'QICE': varvals = ['i', 'iced_water_mixing_ratio', 0., 0.0003, \ 'iced|water|mixing|ratio', 'kgkg-1', 'Purples'] elif varn == 'lat' or varn == 'XLAT' or varn == 'XLAT_M' or varn == 'latitude': varvals = ['lat', 'latitude', -90., 90., 'latitude', 'degrees North', \ 'seismic'] elif varn == 'lcl' or varn == 's_lcl' or varn == 'ls_lcl' or varn == 'LS_LCL': varvals = ['lcl', 'condensation_level', 0., 2500., 'level|of|condensation', \ 'm', 'Greens'] elif varn == 'lambdath' or varn == 'lambda_th' or varn == 'LLAMBDA_TH': varvals = ['lambdath', 'thermal_plume_vertical_velocity', -30., 30., \ 'thermal|plume|vertical|velocity', 'm/s', 'seismic'] elif varn == 'lmaxth' or varn == 'LLMAXTH': varvals = ['lmaxth', 'upper_level_thermals', 0., 100., 'upper|level|thermals'\ , '1', 'Greens'] elif varn == 'lon' or varn == 'XLONG' or varn == 'XLONG_M': varvals = ['lon', 'longitude', -180., 180., 'longitude', 'degrees East', \ 'seismic'] elif varn == 'longitude': varvals = ['lon', 'longitude', 0., 360., 'longitude', 'degrees East', \ 'seismic'] elif varn == 'orog' or varn == 'HGT' or varn == 'HGT_M': varvals = ['orog', 'orography', 0., 3000., 'surface|altitude', 'm','terrain'] elif varn == 'pfc' or varn == 'plfc' or varn == 'LPLFC': varvals = ['pfc', 'pressure_free_convection', 100., 1100., \ 'pressure|free|convection', 'hPa', 'BuPu'] elif varn == 'plcl' or varn == 'LPLCL': varvals = ['plcl', 'pressure_lifting_condensation_level', 700., 1100., \ 'pressure|lifting|condensation|level', 'hPa', 'BuPu'] elif varn == 'pr' or varn == 'RAINTOT' or varn == 'precip' or \ varn == 'LPRECIP' or varn == 'Precip Totale liq+sol': varvals = ['pr', 'precipitation_flux', 0., 1.e-4, 'precipitation|flux', \ 'kgm-2s-1', 'BuPu'] elif varn == 'prprof' or varn == 'vprecip' or varn == 'LVPRECIP': varvals = ['prprof', 'precipitation_profile', 0., 1.e-3, \ 'precipitation|profile', 'kg/m2/s', 'BuPu'] elif varn == 'prprofci' or varn == 'pr_con_i' or varn == 'LPR_CON_I': varvals = ['prprofci', 'precipitation_profile_convective_i', 0., 1.e-3, \ 'precipitation|profile|convective|i', 'kg/m2/s', 'BuPu'] elif varn == 'prprofcl' or varn == 'pr_con_l' or varn == 'LPR_CON_L': varvals = ['prprofcl', 'precipitation_profile_convective_l', 0., 1.e-3, \ 'precipitation|profile|convective|l', 'kg/m2/s', 'BuPu'] elif varn == 'prprofli' or varn == 'pr_lsc_i' or varn == 'LPR_LSC_I': varvals = ['prprofli', 'precipitation_profile_large_scale_i', 0., 1.e-3, \ 'precipitation|profile|large|scale|i', 'kg/m2/s', 'BuPu'] elif varn == 'prprofll' or varn == 'pr_lsc_l' or varn == 'LPR_LSC_L': varvals = ['prprofll', 'precipitation_profile_large_scale_l', 0., 1.e-3, \ 'precipitation|profile|large|scale|l', 'kg/m2/s', 'BuPu'] elif varn == 'pracc' or varn == 'ACRAINTOT': varvals = ['pracc', 'precipitation_amount', 0., 100., \ 'accumulated|precipitation', 'kgm-2', 'BuPu'] elif varn == 'prc' or varn == 'LPLUC' or varn == 'pluc' or varn == 'WRFprc' or \ varn == 'RAINCde': varvals = ['prc', 'convective_precipitation_flux', 0., 2.e-4, \ 'convective|precipitation|flux', 'kgm-2s-1', 'Blues'] elif varn == 'prci' or varn == 'pr_con_i' or varn == 'LPR_CON_I': varvals = ['prci', 'convective_ice_precipitation_flux', 0., 0.003, \ 'convective|ice|precipitation|flux', 'kgm-2s-1', 'Purples'] elif varn == 'prcl' or varn == 'pr_con_l' or varn == 'LPR_CON_L': varvals = ['prcl', 'convective_liquid_precipitation_flux', 0., 0.003, \ 'convective|liquid|precipitation|flux', 'kgm-2s-1', 'Blues'] elif varn == 'pres' or varn == 'presnivs' or varn == 'pressure' or \ varn == 'lpres' or varn == 'LPRES': varvals = ['pres', 'air_pressure', 0., 103000., 'air|pressure', 'Pa', \ 'Blues'] elif varn == 'prls' or varn == 'WRFprls' or varn == 'LPLUL' or varn == 'plul' or \ varn == 'RAINNCde': varvals = ['prls', 'large_scale_precipitation_flux', 0., 2.e-4, \ 'large|scale|precipitation|flux', 'kgm-2s-1', 'Blues'] elif varn == 'prsn' or varn == 'SNOW' or varn == 'snow' or varn == 'LSNOW': varvals = ['prsn', 'snowfall', 0., 1.e-4, 'snowfall|flux', 'kgm-2s-1', 'BuPu'] elif varn == 'prw' or varn == 'WRFprh': varvals = ['prw', 'atmosphere_water_vapor_content', 0., 10., \ 'water|vapor"path', 'kgm-2', 'Blues'] elif varn == 'ps' or varn == 'psfc' or varn =='PSFC' or varn == 'psol' or \ varn == 'Surface Pressure': varvals=['ps', 'surface_air_pressure', 85000., 105400., 'surface|pressure', \ 'hPa', 'cool'] elif varn == 'psl' or varn == 'mslp' or varn =='WRFmslp': varvals=['psl', 'air_pressure_at_sea_level', 85000., 104000., \ 'mean|sea|level|pressure', 'Pa', 'Greens'] elif varn == 'qth' or varn == 'q_th' or varn == 'LQ_TH': varvals = ['qth', 'thermal_plume_total_water_content', 0., 25., \ 'total|water|cotent|in|thermal|plume', 'mm', 'YlOrRd'] elif varn == 'r' or varn == 'QVAPOR' or varn == 'ovap' or varn == 'LOVAP': varvals = ['r', 'water_mixing_ratio', 0., 0.03, 'water|mixing|ratio', \ 'kgkg-1', 'BuPu'] elif varn == 'r2' or varn == 'Q2': varvals = ['r2', 'water_mixing_ratio_at_2m', 0., 0.03, 'water|mixing|' + \ 'ratio|at|2|m','kgkg-1', 'BuPu'] elif varn == 'rsds' or varn == 'SWdnSFC' or varn == 'SWdn at surface' or \ varn == 'SWDOWN': varvals=['rsds', 'surface_downwelling_shortwave_flux_in_air', 0., 1200., \ 'downward|SW|surface|radiation', 'Wm-2' ,'Reds'] elif varn == 'rsdsacc': varvals=['rsdsacc', 'accumulated_surface_downwelling_shortwave_flux_in_air', \ 0., 1200., 'accumulated|downward|SW|surface|radiation', 'Wm-2' ,'Reds'] elif varn == 'rvor' or varn == 'WRFrvor': varvals = ['rvor', 'air_relative_vorticity', -2.5E-3, 2.5E-3, \ 'air|relative|vorticity', 's-1', 'seismic'] elif varn == 'rvors' or varn == 'WRFrvors': varvals = ['rvors', 'surface_air_relative_vorticity', -2.5E-3, 2.5E-3, \ 'surface|air|relative|vorticity', 's-1', 'seismic'] elif varn == 's' or varn == 'QSNOW': varvals = ['s', 'snow_mixing_ratio', 0., 0.0003, 'snow|mixing|ratio', \ 'kgkg-1', 'Purples'] elif varn == 'stherm' or varn == 'LS_THERM': varvals = ['stherm', 'thermals_excess', 0., 0.8, 'thermals|excess', 'K', \ 'Reds'] elif varn == 'ta' or varn == 'WRFt' or varn == 'temp' or varn == 'LTEMP' or \ varn == 'Air temperature': varvals = ['ta', 'air_temperature', 195., 320., 'air|temperature', 'K', \ 'YlOrRd'] elif varn == 'tah' or varn == 'theta' or varn == 'LTHETA': varvals = ['tah', 'potential_air_temperature', 195., 320., \ 'potential|air|temperature', 'K', 'YlOrRd'] elif varn == 'tas' or varn == 'T2' or varn == 't2m' or varn == 'T2M' or \ varn == 'Temperature 2m': varvals = ['tas', 'air_temperature', 240., 310., 'air|temperature|at|2m', ' \ K', 'YlOrRd'] elif varn == 'tds' or varn == 'TH2': varvals = ['tds', 'air_dew_point_temperature', 240., 310., \ 'air|dew|point|temperature|at|2m', 'K', 'YlGnBu'] elif varn == 'tke' or varn == 'TKE' or varn == 'tke' or varn == 'LTKE': varvals = ['tke', 'turbulent_kinetic_energy', 0., 0.003, \ 'turbulent|kinetic|energy', 'm2/s2', 'Reds'] elif varn == 'time'or varn == 'time_counter': varvals = ['time', 'time', 0., 1000., 'time', \ 'hours|since|1949/12/01|00:00:00', 'Reds'] elif varn == 'tmla' or varn == 's_pblt' or varn == 'LS_PBLT': varvals = ['tmla', 'atmosphere_top_boundary_layer_temperature', 250., 330., \ 'atmosphere|top|boundary|layer|temperature', 'K', 'Reds'] elif varn == 'ua' or varn == 'vitu' or varn == 'U' or varn == 'Zonal wind' or \ varn == 'LVITU': varvals = ['ua', 'eastward_wind', -30., 30., 'eastward|wind', 'ms-1', \ 'seismic'] elif varn == 'uas' or varn == 'u10m' or varn == 'U10' or varn =='Vent zonal 10m': varvals = ['uas', 'eastward_wind', -30., 30., 'eastward|2m|wind', \ 'ms-1', 'seismic'] elif varn == 'va' or varn == 'vitv' or varn == 'V' or varn == 'Meridional wind' \ or varn == 'LVITV': varvals = ['va', 'northward_wind', -30., 30., 'northward|wind', 'ms-1', \ 'seismic'] elif varn == 'vas' or varn == 'v10m' or varn == 'V10' or \ varn =='Vent meridien 10m': varvals = ['vas', 'northward_wind', -30., 30., 'northward|2m|wind', 'ms-1', \ 'seismic'] elif varn == 'wakedeltaq' or varn == 'wake_deltaq' or varn == 'lwake_deltaq' or \ varn == 'LWAKE_DELTAQ': varvals = ['wakedeltaq', 'wake_delta_vapor', -0.003, 0.003, \ 'wake|delta|mixing|ratio', '-', 'seismic'] elif varn == 'wakedeltat' or varn == 'wake_deltat' or varn == 'lwake_deltat' or \ varn == 'LWAKE_DELTAT': varvals = ['wakedeltat', 'wake_delta_temp', -0.003, 0.003, \ 'wake|delta|temperature', '-', 'seismic'] elif varn == 'wakeh' or varn == 'wake_h' or varn == 'LWAKE_H': varvals = ['wakeh', 'wake_height', 0., 1000., 'height|of|the|wakes', 'm', \ 'YlOrRd'] elif varn == 'wakeomg' or varn == 'wake_omg' or varn == 'lwake_omg' or \ varn == 'LWAKE_OMG': varvals = ['wakeomg', 'wake_omega', 0., 3., 'wake|omega', \ '-', 'BuGn'] elif varn == 'wakes' or varn == 'wake_s' or varn == 'LWAKE_S': varvals = ['wakes', 'wake_area_fraction', 0., 0.5, 'wake|spatial|fraction', \ '1', 'BuGn'] elif varn == 'wa' or varn == 'W' or varn == 'Vertical wind': varvals = ['wa', 'upward_wind', -10., 10., 'upward|wind', 'ms-1', \ 'seismic'] elif varn == 'wap' or varn == 'vitw' or varn == 'LVITW': varvals = ['wap', 'upward_wind', -3.e-10, 3.e-10, 'upward|wind', 'mPa-1', \ 'seismic'] elif varn == 'wss' or varn == 'SPDUV': varvals = ['wss', 'air_velocity', 0., 30., 'surface|horizontal|wind|speed', \ 'ms-1', 'Reds'] # Water budget # Water budget de-accumulated elif varn == 'ccond' or varn == 'CCOND' or varn == 'ACCCONDde': varvals = ['ccond', 'cw_cond', 0., 30., \ 'cloud|water|condensation', 'mm', 'Reds'] elif varn == 'wbr' or varn == 'ACQVAPORde': varvals = ['wbr', 'wbr', 0., 30., 'Water|Budget|water|wapor', 'mm', 'Blues'] elif varn == 'diabh' or varn == 'DIABH' or varn == 'ACDIABHde': varvals = ['diabh', 'diabh', 0., 30., 'diabatic|heating', 'K', 'Reds'] elif varn == 'wbpw' or varn == 'WBPW' or varn == 'WBACPWde': varvals = ['wbpw', 'water_budget_pw', 0., 30., 'Water|Budget|water|content',\ 'mms-1', 'Reds'] elif varn == 'wbf' or varn == 'WBACF' or varn == 'WBACFde': varvals = ['wbf', 'water_budget_hfcqv', 0., 30., \ 'Water|Budget|horizontal|convergence|of|water|vapour|(+,|' + \ 'conv.;|-,|div.)', 'mms-1', 'Reds'] elif varn == 'wbfc' or varn == 'WBFC' or varn == 'WBACFCde': varvals = ['wbfc', 'water_budget_fc', 0., 30., \ 'Water|Budget|horizontal|convergence|of|cloud|(+,|conv.;|-,|' +\ 'div.)', 'mms-1', 'Reds'] elif varn == 'wbfp' or varn == 'WBFP' or varn == 'WBACFPde': varvals = ['wbfp', 'water_budget_cfp', 0., 30., \ 'Water|Budget|horizontal|convergence|of|precipitation|(+,|' + \ 'conv.;|-,|div.)', 'mms-1', 'Reds'] elif varn == 'wbz' or varn == 'WBZ' or varn == 'WBACZde': varvals = ['wbz', 'water_budget_z', 0., 30., \ 'Water|Budget|vertical|convergence|of|water|vapour|(+,|conv.' +\ ';|-,|div.)', 'mms-1', 'Reds'] elif varn == 'wbc' or varn == 'WBC' or varn == 'WBACCde': varvals = ['wbc', 'water_budget_c', 0., 30., \ 'Water|Budget|Cloud|water|species','mms-1', 'Reds'] elif varn == 'wbqvd' or varn == 'WBQVD' or varn == 'WBACQVDde': varvals = ['wbqvd', 'water_budget_qvd', 0., 30., \ 'Water|Budget|water|vapour|divergence', 'mms-1', 'Reds'] elif varn == 'wbqvblten' or varn == 'WBQVBLTEN' or varn == 'WBACQVBLTENde': varvals = ['wbqvblten', 'water_budget_qv_blten', 0., 30., \ 'Water|Budget|QV|tendency|due|to|pbl|parameterization', \ 'kg kg-1 s-1', 'Reds'] elif varn == 'wbqvcuten' or varn == 'WBQVCUTEN' or varn == 'WBACQVCUTENde': varvals = ['wbqvcuten', 'water_budget_qv_cuten', 0., 30., \ 'Water|Budget|QV|tendency|due|to|cu|parameterization', \ 'kg kg-1 s-1', 'Reds'] elif varn == 'wbqvshten' or varn == 'WBQVSHTEN' or varn == 'WBACQVSHTENde': varvals = ['wbqvshten', 'water_budget_qv_shten', 0., 30., \ 'Water|Budget|QV|tendency|due|to|shallow|cu|parameterization', \ 'kg kg-1 s-1', 'Reds'] elif varn == 'wbpr' or varn == 'WBP' or varn == 'WBACPde': varvals = ['wbpr', 'water_budget_pr', 0., 30., \ 'Water|Budget|recipitation', 'mms-1', 'Reds'] elif varn == 'wbpw' or varn == 'WBPW' or varn == 'WBACPWde': varvals = ['wbpw', 'water_budget_pw', 0., 30., \ 'Water|Budget|water|content', 'mms-1', 'Reds'] elif varn == 'wbcondt' or varn == 'WBCONDT' or varn == 'WBACCONDTde': varvals = ['wbcondt', 'water_budget_condt', 0., 30., \ 'Water|Budget|condensation|and|deposition', 'mms-1', 'Reds'] elif varn == 'wbqcm' or varn == 'WBQCM' or varn == 'WBACQCMde': varvals = ['wbqcm', 'water_budget_qcm', 0., 30., \ 'Water|Budget|hydrometeor|change|and|convergence', 'mms-1', 'Reds'] elif varn == 'wbsi' or varn == 'WBSI' or varn == 'WBACSIde': varvals = ['wbsi', 'water_budget_si', 0., 30., \ 'Water|Budget|hydrometeor|sink', 'mms-1', 'Reds'] elif varn == 'wbso' or varn == 'WBSO' or varn == 'WBACSOde': varvals = ['wbso', 'water_budget_so', 0., 30., \ 'Water|Budget|hydrometeor|source', 'mms-1', 'Reds'] # Water Budget accumulated elif varn == 'ccondac' or varn == 'ACCCOND': varvals = ['ccondac', 'cw_cond_ac', 0., 30., \ 'accumulated|cloud|water|condensation', 'mm', 'Reds'] elif varn == 'rac' or varn == 'ACQVAPOR': varvals = ['rac', 'ac_r', 0., 30., 'accumualted|water|wapor', 'mm', 'Blues'] elif varn == 'diabhac' or varn == 'ACDIABH': varvals = ['diabhac', 'diabh_ac', 0., 30., 'accumualted|diabatic|heating', \ 'K', 'Reds'] elif varn == 'wbpwac' or varn == 'WBACPW': varvals = ['wbpwac', 'water_budget_pw_ac', 0., 30., \ 'Water|Budget|accumulated|water|content', 'mm', 'Reds'] elif varn == 'wbfac' or varn == 'WBACF': varvals = ['wbfac', 'water_budget_hfcqv_ac', 0., 30., \ 'Water|Budget|accumulated|horizontal|convergence|of|water|vapour|(+,|' + \ 'conv.;|-,|div.)', 'mm', 'Reds'] elif varn == 'wbfcac' or varn == 'WBACFC': varvals = ['wbfcac', 'water_budget_fc_ac', 0., 30., \ 'Water|Budget|accumulated|horizontal|convergence|of|cloud|(+,|conv.;|-,|' +\ 'div.)', 'mm', 'Reds'] elif varn == 'wbfpac' or varn == 'WBACFP': varvals = ['wbfpac', 'water_budget_cfp_ac', 0., 30., \ 'Water|Budget|accumulated|horizontal|convergence|of|precipitation|(+,|' + \ 'conv.;|-,|div.)', 'mm', 'Reds'] elif varn == 'wbzac' or varn == 'WBACZ': varvals = ['wbzac', 'water_budget_z_ac', 0., 30., \ 'Water|Budget|accumulated|vertical|convergence|of|water|vapour|(+,|conv.' +\ ';|-,|div.)', 'mm', 'Reds'] elif varn == 'wbcac' or varn == 'WBACC': varvals = ['wbcac', 'water_budget_c_ac', 0., 30., \ 'Water|Budget|accumulated|Cloud|water|species','mm', 'Reds'] elif varn == 'wbqvdac' or varn == 'WBACQVD': varvals = ['wbqvdac', 'water_budget_qvd_ac', 0., 30., \ 'Water|Budget|accumulated|water|vapour|divergence', 'mm', 'Reds'] elif varn == 'wbqvbltenac' or varn == 'WBACQVBLTEN': varvals = ['wbqvbltenac', 'water_budget_qv_blten_ac', 0., 30., \ 'Water|Budget|accumulated|QV|tendency|due|to|pbl|parameterization', \ 'kg kg-1 s-1', 'Reds'] elif varn == 'wbqvcutenac' or varn == 'WBACQVCUTEN': varvals = ['wbqvcutenac', 'water_budget_qv_cuten_ac', 0., 30., \ 'Water|Budget|accumulated|QV|tendency|due|to|cu|parameterization', \ 'kg kg-1 s-1', 'Reds'] elif varn == 'wbqvshtenac' or varn == 'WBACQVSHTEN': varvals = ['wbqvshtenac', 'water_budget_qv_shten_ac', 0., 30., \ 'Water|Budget|accumulated|QV|tendency|due|to|shallow|cu|parameterization', \ 'kg kg-1 s-1', 'Reds'] elif varn == 'wbprac' or varn == 'WBACP': varvals = ['wbprac', 'water_budget_pr_ac', 0., 30., \ 'Water|Budget|accumulated|precipitation', 'mm', 'Reds'] elif varn == 'wbpwac' or varn == 'WBACPW': varvals = ['wbpwac', 'water_budget_pw_ac', 0., 30., \ 'Water|Budget|accumulated|water|content', 'mm', 'Reds'] elif varn == 'wbcondtac' or varn == 'WBACCONDT': varvals = ['wbcondtac', 'water_budget_condt_ac', 0., 30., \ 'Water|Budget|accumulated|condensation|and|deposition', 'mm', 'Reds'] elif varn == 'wbqcmac' or varn == 'WBACQCM': varvals = ['wbqcmac', 'water_budget_qcm_ac', 0., 30., \ 'Water|Budget|accumulated|hydrometeor|change|and|convergence', 'mm', 'Reds'] elif varn == 'wbsiac' or varn == 'WBACSI': varvals = ['wbsiac', 'water_budget_si_ac', 0., 30., \ 'Water|Budget|accumulated|hydrometeor|sink', 'mm', 'Reds'] elif varn == 'wbsoac' or varn == 'WBACSO': varvals = ['wbsoac', 'water_budget_so_ac', 0., 30., \ 'Water|Budget|accumulated|hydrometeor|source', 'mm', 'Reds'] elif varn == 'xtime' or varn == 'XTIME': varvals = ['xtime', 'time', 0., 1.e5, 'time', \ 'minutes|since|simulation|start', 'Reds'] elif varn == 'x' or varn == 'X': varvals = ['x', 'x', 0., 100., 'x', '-', 'Reds'] elif varn == 'y' or varn == 'Y': varvals = ['y', 'y', 0., 100., 'y', '-', 'Blues'] elif varn == 'z' or varn == 'Z': varvals = ['z', 'z', 0., 100., 'z', '-', 'Greens'] elif varn == 'zg' or varn == 'WRFght' or varn == 'Geopotential height' or \ varn == 'geop' or varn == 'LGEOP': varvals = ['zg', 'geopotential_height', 0., 80000., 'geopotential|height', \ 'm2s-2', 'rainbow'] elif varn == 'zmaxth' or varn == 'zmax_th' or varn == 'LZMAX_TH': varvals = ['zmaxth', 'thermal_plume_height', 0., 4000., \ 'maximum|thermals|plume|height', 'm', 'YlOrRd'] elif varn == 'zmla' or varn == 's_pblh' or varn == 'LS_PBLH': varvals = ['zmla', 'atmosphere_boundary_layer_thickness', 0., 2500., \ 'atmosphere|boundary|layer|thickness', 'm', 'Blues'] else: print errormsg print ' ' + fname + ": variable '" + varn + "' not defined !!!" quit(-1) return varvals def numVector_String(vec,char): """ Function to transform a vector of numbers to a single string [char] separated numVector_String(vec,char) vec= vector with the numerical values char= single character to split the values >>> print numVector_String(np.arange(10),' ') 0 1 2 3 4 5 6 7 8 9 """ fname = 'numVector_String' # if vec == 'h': # print fname + '_____________________________________________________________' # print numVector_String.__doc__ # quit() Nvals = len(vec) string='' for i in range(Nvals): if i == 0: string = str(vec[i]) else: string = string + char + str(vec[i]) return string def index_vec(vec,val): """ Function to provide the coordinates of a given value inside a vector index_vec(vec,val) vec= vector with values val= value to search >>> index_vec(np.arange(27),22) 22 """ fname = 'index_vec' vecv = np.array(vec) valpos = -1 for i in range(vecv.shape[0]): if vecv[i] == val: valpos = i break return valpos def index_mat(mat,val): """ Function to provide the coordinates of a given value inside a matrix index_mat(mat,val) mat= matrix with values val= value to search >>> index_mat(np.arange(27).reshape(3,3,3),22) [2 1 1] """ fname = 'index_mat' matshape = mat.shape matlist = list(mat.flatten()) ifound = matlist.index(val) Ndims = len(matshape) valpos = np.zeros((Ndims), dtype=int) baseprevdims = np.zeros((Ndims), dtype=int) for dimid in range(Ndims): baseprevdims[dimid] = np.product(matshape[dimid+1:Ndims]) if dimid == 0: alreadyplaced = 0 else: alreadyplaced = np.sum(baseprevdims[0:dimid]*valpos[0:dimid]) valpos[dimid] = int((ifound - alreadyplaced )/ baseprevdims[dimid]) return valpos def multi_index_mat(mat,val): """ Function to provide the multiple coordinates of a given value inside a matrix index_mat(mat,val) mat= matrix with values val= value to search >>> vals = np.ones((24), dtype=np.float).reshape(2,3,4) vals[:,:,2] = 0. vals[1,:,:] = np.pi vals[:,2,:] = -1. multi_index_mat(vals,1.) [array([0, 0, 0]), array([0, 0, 1]), array([0, 0, 3]), array([0, 1, 0]), array([0, 1, 1]), array([0, 1, 3])] """ fname = 'multi_index_mat' matshape = mat.shape ivalpos = [] matlist = list(mat.flatten()) Lmatlist = len(matlist) val0 = val - val if val != val0: valdiff = val0 else: valdiff = np.ones((1), dtype = type(val)) ifound = 0 while ifound < Lmatlist: if matlist.count(val) == 0: ifound = Lmatlist + 1 else: ifound = matlist.index(val) Ndims = len(matshape) valpos = np.zeros((Ndims), dtype=int) baseprevdims = np.zeros((Ndims), dtype=int) for dimid in range(Ndims): baseprevdims[dimid] = np.product(matshape[dimid+1:Ndims]) if dimid == 0: alreadyplaced = 0 else: alreadyplaced = np.sum(baseprevdims[0:dimid]*valpos[0:dimid]) valpos[dimid] = int((ifound - alreadyplaced )/ baseprevdims[dimid]) matlist[ifound] = valdiff ivalpos.append(valpos) return ivalpos def addfileInfile(origfile,destfile,addfile,addsign): """ Function to add the content of a file [addfile] to another one [origfile] at a given position [addsign] creating a new file called [destfile] origfile= original file destfile= destination file addfile= content of the file to add addsign= sign where to add the file """ fname = 'addfileInfile' if not os.path.isfile(origfile): print errormsg print ' ' + fname + ": original file '" + origfile + "' does not exist !!" quit(-1) if not os.path.isfile(addfile): print errormsg print ' ' + fname + ": adding file '" + addfile + "' does not exist !!" quit(-1) ofile = open(origfile, 'r') # Inspecting flag ## Nfound = 0 for line in ofile: if line == addsign + '\n': Nfound = Nfound + 1 if Nfound == 0: print errormsg print ' ' + fname + ": adding sign '" + addsign + "' not found !!" quit(-1) print ' '+ fname + ': found', Nfound," times sign '" + addsign + "' " ofile.seek(0) dfile = open(destfile, 'w') for line in ofile: if line != addsign + '\n': dfile.write(line) else: afile = open(addfile,'r') for aline in afile: print aline dfile.write(aline) afile.close() ofile.close() dfile.close() print main + " successful writting of file '" + destfile + "' !!" return ####### ###### ##### #### ### ## # def valmodoper(varVal, valuesS): """ Function to run the modification of a variable varVAl= matrix with the values valuesS= [modins],[[modval1],...,[modvalN]] modification instruction, value with which modify [modins]: Modifiers: sumc: add [modval1] subc: remove [modval1] mulc: multiply by [modval1] divc: divide by [modval1] lowthres: if [val] < [modval1]; val = [modval2] upthres: if [val] > [modval1]; val = [modval2] lowthres@oper: if [val] < [modval1]; val = [oper] (operation as [modval2],[modval3]) upthres@oper: if [val] > [modval1]; val = [oper] (operation as [modval2],[modval3]) potc: [val] ** [modval1] """ fname='valmodoper' if valuesS == 'h': print fname + '_____________________________________________________________' print valmodoper.__doc__ quit() valsS = valuesS.split(',') modins = valsS[0] modval = float(valsS[1]) opers = ['sumc', 'subc', 'mulc', 'divc', 'lowthres', 'upthres', 'lowthres@oper', \ 'upthres@oper', 'potc'] if modins == 'sumc': varVal[:] = varVal[:] + modval elif modins == 'subc': varVal[:] = varVal[:] - modval elif modins == 'mulc': varVal[:] = varVal[:] * modval elif modins == 'divc': varVal[:] = varVal[:] / modval elif modins == 'lowthres': varVal2 = np.where(varVal[:] < float(valsS[1]), float(valsS[2]), varVal[:]) varVal[:] = varVal2 elif modins == 'upthres': varVal2 = np.where(varVal[:] > float(valsS[1]), float(valsS[2]), varVal[:]) varVal[:] = varVal2 elif modins == 'lowthres@oper': if valsS[2] == 'sumc': varVal2 = np.where(varVal[:] < float(valsS[1]), \ varVal[:] + float(valsS[3]), varVal[:]) varVal[:] = varVal2 elif valsS[2] == 'subc': varVal2 = np.where(varVal[:] < float(valsS[1]), \ varVal[:] - float(valsS[3]), varVal[:]) varVal[:] = varVal2 elif valsS[2] == 'mulc': varVal2 = np.where(varVal[:] < float(valsS[1]), \ varVal[:] * float(valsS[3]), varVal[:]) varVal[:] = varVal2 elif valsS[2] == 'divc': varVal2 = np.where(varVal[:] < float(valsS[1]), \ varVal[:] / float(valsS[3]), varVal[:]) varVal[:] = varVal2 elif valsS[2] == 'potc': varVal2 = np.where(varVal[:] < float(valsS[1]), \ varVal[:] ** float(valsS[3]), varVal[:]) varVal[:] = varVal2 else: print errormsg print ' ' + fname + ": Operation to modify values '" + modins + \ "' is not defined !!" quit(-1) elif modins == 'upthres@oper': if valsS[2] == 'sumc': varVal2 = np.where(varVal[:] > float(valsS[1]), \ varVal[:] + float(valsS[3]), varVal[:]) varVal[:] = varVal2 elif valsS[2] == 'subc': varVal2 = np.where(varVal[:] > float(valsS[1]), \ varVal[:] - float(valsS[3]), varVal[:]) varVal[:] = varVal2 elif valsS[2] == 'mulc': varVal2 = np.where(varVal[:] > float(valsS[1]), \ varVal[:] * float(valsS[3]), varVal[:]) varVal[:] = varVal2 elif valsS[2] == 'divc': varVal2 = np.where(varVal[:] > float(valsS[1]), \ varVal[:] / float(valsS[3]), varVal[:]) varVal[:] = varVal2 elif valsS[2] == 'potc': varVal2 = np.where(varVal[:] > float(valsS[1]), \ varVal[:] ** float(valsS[3]), varVal[:]) varVal[:] = varVal2 else: print errormsg print ' ' + fname + ": Operation to modify values '" + modins + \ "' is not defined !!" quit(-1) elif modins == 'potc': varVal[:] = varVal[:] ** modval else: print errormsg print ' ' + fname + ": Operation to modify values '" + modins + \ "' is not defined !!" print ' available:', opers quit(-1) return varVal def rangedim(end, shape): """Gives the instruction to retrieve values from a dimension of a variable >>> print rangedim(-1, 15) 15 """ if end == -1: return shape else: return end def datetimeStr_datetime(StringDT): """ Function to transform a string date ([YYYY]-[MM]-[DD]_[HH]:[MI]:[SS] format) to a date object >>> datetimeStr_datetime('1976-02-17_00:00:00') 1976-02-17 00:00:00 """ import datetime as dt fname = 'datetimeStr_datetime' dateD = np.zeros((3), dtype=int) timeT = np.zeros((3), dtype=int) dateD[0] = int(StringDT[0:4]) dateD[1] = int(StringDT[5:7]) dateD[2] = int(StringDT[8:10]) trefT = StringDT.find(':') if not trefT == -1: # print ' ' + fname + ': refdate with time!' timeT[0] = int(StringDT[11:13]) timeT[1] = int(StringDT[14:16]) timeT[2] = int(StringDT[17:19]) if int(dateD[0]) == 0: print warnmsg print ' ' + fname + ': 0 reference year!! changing to 1' dateD[0] = 1 newdatetime = dt.datetime(dateD[0], dateD[1], dateD[2], timeT[0], timeT[1], timeT[2]) return newdatetime def dateStr_date(StringDate): """ Function to transform a string date ([YYYY]-[MM]-[DD] format) to a date object >>> dateStr_date('1976-02-17') 1976-02-17 """ import datetime as dt dateD = StringDate.split('-') if int(dateD[0]) == 0: print warnmsg print ' dateStr_date: 0 reference year!! changing to 1' dateD[0] = 1 newdate = dt.date(int(dateD[0]), int(dateD[1]), int(dateD[2])) return newdate def timeStr_time(StringDate): """ Function to transform a string date ([HH]:[MI]:[SS] format) to a time object >>> datetimeStr_datetime('04:32:54') 04:32:54 """ import datetime as dt timeT = StringDate.split(':') if len(timeT) == 3: newtime = dt.time(int(timeT[0]), int(timeT[1]), int(timeT[2])) else: newtime = dt.time(int(timeT[0]), int(timeT[1]), 0) return newtime def timeref_datetime(refd, timeval, tu): """ Function to transform from a [timeval] in [tu] units from the time referece [tref] to datetime object refd: time of reference (as datetime object) timeval: time value (as [tu] from [tref]) tu: time units >>> timeref = date(1949,12,1,0,0,0) >>> timeref_datetime(timeref, 229784.36, hours) 1976-02-17 08:21:36 """ import datetime as dt import numpy as np ## Not in timedelta # if tu == 'years': # realdate = refdate + dt.timedelta(years=float(timeval)) # elif tu == 'months': # realdate = refdate + dt.timedelta(months=float(timeval)) if tu == 'weeks': realdate = refd + dt.timedelta(weeks=float(timeval)) elif tu == 'days': realdate = refd + dt.timedelta(days=float(timeval)) elif tu == 'hours': realdate = refd + dt.timedelta(hours=float(timeval)) elif tu == 'minutes': realdate = refd + dt.timedelta(minutes=float(timeval)) elif tu == 'seconds': realdate = refd + dt.timedelta(seconds=float(timeval)) elif tu == 'milliseconds': realdate = refd + dt.timedelta(milliseconds=float(timeval)) else: print errormsg print ' timeref_datetime: time units "' + tu + '" not ready!!!!' quit(-1) return realdate def timeref_datetime_mat(refd, timeval, tu): """ Function to transform from a [timeval] in [tu] units from the time referece [tref] to matrix with: year, day, month, hour, minute, second refd: time of reference (as datetime object) timeval: time value (as [tu] from [tref]) tu: time units >>> timeref = date(1949,12,1,0,0,0) >>> timeref_datetime(timeref, 229784.36, hours) [1976 2 17 8 36 21] """ import datetime as dt import numpy as np realdates = np.zeros(6, dtype=int) ## Not in timedelta # if tu == 'years': # realdate = refdate + dt.timedelta(years=float(timeval)) # elif tu == 'months': # realdate = refdate + dt.timedelta(months=float(timeval)) if tu == 'weeks': realdate = refd + dt.timedelta(weeks=float(timeval)) elif tu == 'days': realdate = refd + dt.timedelta(days=float(timeval)) elif tu == 'hours': realdate = refd + dt.timedelta(hours=float(timeval)) elif tu == 'minutes': realdate = refd + dt.timedelta(minutes=float(timeval)) elif tunits == 'seconds': realdate = refd + dt.timedelta(seconds=float(timeval)) elif tunits == 'milliseconds': realdate = refd + dt.timedelta(milliseconds=float(timeval)) else: print errormsg print ' timeref_datetime: time units "' + tu + '" not ready!!!!' quit(-1) realdates[0] = int(realdate.year) realdates[1] = int(realdate.month) realdates[2] = int(realdate.day) realdates[3] = int(realdate.hour) realdates[4] = int(realdate.second) realdates[5] = int(realdate.minute) return realdates def realdatetime_CFcompilant(times, Srefdate, tunits): """ Function to transform a matrix with real time values ([year, month, day, hour, minute, second]) to a netCDF one times= matrix with times Srefdate= reference date ([YYYY][MM][DD][HH][MI][SS] format) tunits= units of time respect to Srefdate >>> realdatetime_CFcompilant(np.array([ [1976, 2, 17, 8, 20, 0], [1976, 2, 18, 8, 20, 0]], dtype=int), '19491201000000', 'hours') [ 229784.33333333 229808.33333333] """ import datetime as dt yrref=int(Srefdate[0:4]) monref=int(Srefdate[4:6]) dayref=int(Srefdate[6:8]) horref=int(Srefdate[8:10]) minref=int(Srefdate[10:12]) secref=int(Srefdate[12:14]) refdate=dt.datetime(yrref, monref, dayref, horref, minref, secref) dimt=times.shape[0] cfdates = np.zeros((dimt), dtype=np.float64) if tunits == 'weeks': for it in range(dimt): cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate cfdates[it] = (cfdate.days + cfdate.seconds/(3600.*24.))/7. elif tunits == 'days': for it in range(dimt): cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate cfdates[it] = cfdate.days + cfdate.seconds/(3600.*24.) elif tunits == 'hours': for it in range(dimt): cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate cfdates[it] = cfdate.days*24. + cfdate.seconds/3600. elif tunits == 'minutes': for it in range(dimt): cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate cfdates[it] = cfdate.days*24.*60. + cfdate.seconds/60. elif tunits == 'seconds': for it in range(dimt): cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate cfdates[it] = cfdate.days*24.*3600. + cfdate.seconds elif tunits == 'milliseconds': for it in range(dimt): cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate cfdates[it] = cfdate.days*1000.*24.*3600. + cfdate.seconds*1000. elif tunits == 'microseconds': for it in range(dimt): cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate cfdates[it] = cfdate.days*1000000.*24.*3600. + cfdate.seconds*1000000. else: print errormsg print ' ' + fname + ': time units "' + tunits + '" is not ready!!!' quit(-1) return cfdates def netCDFdatetime_realdatetime(units, tcalendar, times): """ Function to transfrom from netCDF CF-compilant times to real time """ import datetime as dt txtunits = units.split(' ') tunits = txtunits[0] Srefdate = txtunits[len(txtunits) - 1] # Calendar type ## is360 = False if tcalendar is not None: print ' netCDFdatetime_realdatetime: There is a calendar attribute' if tcalendar == '365_day' or tcalendar == 'noleap': print ' netCDFdatetime_realdatetime: No leap years!' isleapcal = False elif tcalendar == 'proleptic_gregorian' or tcalendar == 'standard' or tcalendar == 'gregorian': isleapcal = True elif tcalendar == '360_day': is360 = True isleapcal = False else: print errormsg print ' netCDFdatetime_realdatetime: Calendar "' + tcalendar + '" not prepared!' quit(-1) # Does reference date contain a time value [YYYY]-[MM]-[DD] [HH]:[MI]:[SS] ## timeval = Srefdate.find(':') if not timeval == -1: print ' netCDFdatetime_realdatetime: refdate with time!' refdate = datetimeStr_datetime(txtunits[len(txtunits) - 2] + '_' + Srefdate) else: refdate = dateStr_date(Srefdate) dimt = len(times) # datetype = type(dt.datetime(1972,02,01)) # realdates = np.array(dimt, datetype) # print realdates ## Not in timedelta # if tunits == 'years': # for it in range(dimt): # realdate = refdate + dt.timedelta(years=float(times[it])) # realdates[it] = int(realdate.year) # elif tunits == 'months': # for it in range(dimt): # realdate = refdate + dt.timedelta(months=float(times[it])) # realdates[it] = int(realdate.year) # realdates = [] realdates = np.zeros((dimt, 6), dtype=int) if tunits == 'weeks': for it in range(dimt): realdate = refdate + dt.timedelta(weeks=float(times[it])) realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second] elif tunits == 'days': for it in range(dimt): realdate = refdate + dt.timedelta(days=float(times[it])) realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second] elif tunits == 'hours': for it in range(dimt): realdate = refdate + dt.timedelta(hours=float(times[it])) # if not isleapcal: # Nleapdays = cal.leapdays(int(refdate.year), int(realdate.year)) # realdate = realdate - dt.timedelta(days=Nleapdays) # if is360: # Nyears360 = int(realdate.year) - int(refdate.year) + 1 # realdate = realdate -dt.timedelta(days=Nyears360*5) # realdates[it] = realdate # realdates = refdate + dt.timedelta(hours=float(times)) realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second] elif tunits == 'minutes': for it in range(dimt): realdate = refdate + dt.timedelta(minutes=float(times[it])) realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second] elif tunits == 'seconds': for it in range(dimt): realdate = refdate + dt.timedelta(seconds=float(times[it])) realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second] elif tunits == 'milliseconds': for it in range(dimt): realdate = refdate + dt.timedelta(milliseconds=float(times[it])) realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second] elif tunits == 'microseconds': for it in range(dimt): realdate = refdate + dt.timedelta(microseconds=float(times[it])) realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second] else: print errormsg print ' netCDFdatetime_realdatetime: time units "' + tunits + '" is not ready!!!' quit(-1) return realdates def date_juliandate(refyr, TOTsecs): """ Function to transform from a total quantity of seconds since the beginning of a year to 360 days / year calendar TOTsecs= total number of seconds """ fname = 'date_juliandate' secsYear = 3600*24*30*12. secsMonth = 3600*24*30. secsDay = 3600*24. secsHour = 3600. secsMinute = 60. rldate = np.zeros((6), dtype=int) rldate[0] = refyr if TOTsecs > secsYear: rldate[0] = refyr + int(TOTsecs/secsYear) + 1 TOTsecs = TOTsecs - int(TOTsecs/secsYear)*secsYear if np.mod(TOTsecs,secsMonth) == 0: rldate[1] = int(TOTsecs/secsMonth) else: rldate[1] = int(TOTsecs/secsMonth) + 1 TOTsecs = TOTsecs - int(TOTsecs/secsMonth)*secsMonth if np.mod(TOTsecs,secsDay) == 0: rldate[2] = int(TOTsecs/secsDay) else: rldate[2] = int(TOTsecs/secsDay) + 1 TOTsecs = TOTsecs - int(TOTsecs/secsDay)*secsDay if np.mod(TOTsecs,secsHour) == 0: rldate[3] = int(TOTsecs/secsHour) else: rldate[3] = int(TOTsecs/secsHour) + 1 TOTsecs = TOTsecs - int(TOTsecs/secsHour)*secsHour if np.mod(TOTsecs,secsMinute) == 0: rldate[4] = int(TOTsecs/secsMinute) else: rldate[4] = int(TOTsecs/secsMinute) + 1 TOTsecs = TOTsecs - int(TOTsecs/secsMinute)*secsMinute rldate[5] = TOTsecs # print refyr,TOTsecs,':',rldate # quit() return rldate def CFtimes_datetime(ncfile, tname): """ Provide date/time array from a file with a series of netCDF CF-compilant time variable ncfile = netCDF file name tname = name of the variable time in [ncfile] output: array(dimt, 0) = year array(dimt, 1) = month array(dimt, 2) = day array(dimt, 3) = hour array(dimt, 4) = minute array(dimt, 5) = second """ import datetime as dt fname = 'CFtimes_datetime' times = ncfile.variables[tname] timevals = times[:] attvar = times.ncattrs() if not searchInlist(attvar, 'units'): print errormsg print ' ' + fname + ": '" + tname + "' does not have attribute: 'units'" quit(-1) else: units = times.getncattr('units') txtunits = units.split(' ') tunits = txtunits[0] Srefdate = txtunits[len(txtunits) - 1] # Does reference date contain a time value [YYYY]-[MM]-[DD] [HH]:[MI]:[SS] ## timeval = Srefdate.find(':') if not timeval == -1: # print ' refdate with time!' refdate = datetimeStr_datetime(txtunits[len(txtunits) - 2] + '_' + Srefdate) else: refdate = dateStr_date(Srefdate) dimt = len(timevals) realdates = np.zeros((dimt, 6), dtype=int) secsDay=3600*24. # Checking calendar! ## y360 = False daycal360 = ['earth_360d', '360d', '360days', '360_day'] if searchInlist(attvar, 'calendar'): calendar = times.getncattr('calendar') if searchInlist(daycal360,calendar): print warnmsg print ' ' + fname + ': calendar of 12 months of 30 days !!' y360 = True ## Not in timedelta # if tunits == 'years': # for it in range(dimt): # realdate = refdate + dt.timedelta(years=float(times[it])) # realdates[it] = int(realdate.year) # elif tunits == 'months': # for it in range(dimt): # realdate = refdate + dt.timedelta(months=float(times[it])) # realdates[it] = int(realdate.year) if y360: if tunits == 'weeks': for it in range(dimt): deltat = dt.timedelta(weeks=float(times[it])) Tsecs = deltat.days*secsDay + deltat.seconds + deltat.microseconds/1000. realdates[it,:] = date_juliandate(refdate.year,Tsecs) elif tunits == 'days': for it in range(dimt): deltat = dt.timedelta(days=float(times[it])) Tsecs = deltat.days*secsDay + deltat.seconds + deltat.microseconds/1000. realdates[it,:] = date_juliandate(refdate.year,Tsecs) elif tunits == 'hours': for it in range(dimt): realdate = dt.timedelta(hours=float(times[it])) Tsecs = deltat.days*secsDay + deltat.seconds + deltat.microseconds/1000. realdates[it,:] = date_juliandate(refdate.year,Tsecs) elif tunits == 'minutes': for it in range(dimt): realdate = dt.timedelta(minutes=float(times[it])) Tsecs = deltat.days*secsDay + deltat.seconds + deltat.microseconds/1000. realdates[it,:] = date_juliandate(refdate.year,Tsecs) elif tunits == 'seconds': for it in range(dimt): realdate = dt.timedelta(seconds=float(times[it])) Tsecs = deltat.days*secsDay + deltat.seconds + deltat.microseconds/1000. realdates[it,:] = date_juliandate(refdate.year,Tsecs) elif tunits == 'miliseconds': for it in range(dimt): realdate = dt.timedelta(miliseconds=float(times[it])) Tsecs = deltat.days*secsDay + deltat.seconds + deltat.microseconds/1000. realdates[it,:] = date_juliandate(refdate.year,Tsecs) else: print errormsg print ' CFtimes_datetime: time units "' + tunits + '" not ready!!!!' quit(-1) else: if tunits == 'weeks': for it in range(dimt): realdate = refdate + dt.timedelta(weeks=float(times[it])) realdates[it,0] = int(realdate.year) realdates[it,1] = int(realdate.month) realdates[it,2] = int(realdate.day) realdates[it,3] = int(realdate.hour) realdates[it,4] = int(realdate.second) realdates[it,5] = int(realdate.minute) elif tunits == 'days': for it in range(dimt): realdate = refdate + dt.timedelta(days=float(times[it])) realdates[it,0] = int(realdate.year) realdates[it,1] = int(realdate.month) realdates[it,2] = int(realdate.day) realdates[it,3] = int(realdate.hour) realdates[it,4] = int(realdate.second) realdates[it,5] = int(realdate.minute) elif tunits == 'hours': for it in range(dimt): realdate = refdate + dt.timedelta(hours=float(times[it])) realdates[it,0] = int(realdate.year) realdates[it,1] = int(realdate.month) realdates[it,2] = int(realdate.day) realdates[it,3] = int(realdate.hour) realdates[it,4] = int(realdate.second) realdates[it,5] = int(realdate.minute) elif tunits == 'minutes': for it in range(dimt): realdate = refdate + dt.timedelta(minutes=float(times[it])) realdates[it,0] = int(realdate.year) realdates[it,1] = int(realdate.month) realdates[it,2] = int(realdate.day) realdates[it,3] = int(realdate.hour) realdates[it,4] = int(realdate.second) realdates[it,5] = int(realdate.minute) elif tunits == 'seconds': for it in range(dimt): realdate = refdate + dt.timedelta(seconds=float(times[it])) realdates[it,0] = int(realdate.year) realdates[it,1] = int(realdate.month) realdates[it,2] = int(realdate.day) realdates[it,3] = int(realdate.hour) realdates[it,4] = int(realdate.second) realdates[it,5] = int(realdate.minute) elif tunits == 'milliseconds': for it in range(dimt): realdate = refdate + dt.timedelta(milliseconds=float(times[it])) realdates[it,0] = int(realdate.year) realdates[it,1] = int(realdate.month) realdates[it,2] = int(realdate.day) realdates[it,3] = int(realdate.hour) realdates[it,4] = int(realdate.second) realdates[it,5] = int(realdate.minute) else: print errormsg print ' CFtimes_datetime: time units "' + tunits + '" not ready!!!!' quit(-1) return realdates class statsValWeigthed(object): """Weigthed Statistics class providing: vals = values (can be a matrix) wgs = weights (can be a matrix) self.meanv: mean weigthed value self.mean2v: mean quadratic weigthed value self.stdv: weigthed standard deviation self.Nokvalue non None values of a list of values self.meanwgt: mean of the weigths self.mean2wgt: cuadratic mean of the weigths self.stdwgt: standard deviation of the weigths """ def __init__(self, vals, wgs): if vals is None: self.Nv = None self.meanv = None self.mean2v = None self.stdv = None self.Nokvalues = None self.meanwgt = None self.mean2wgt = None self.stdwgt = None else: values = vals.flatten() weights = wgs.flatten() self.Nv=len(values) self.meanv=0. self.mean2v=0. self.stdv=0. self.meanwgt = 0. self.mean2wgt = 0. self.stdwgt = 0. self.Nokvalues = 0 for inum in range(self.Nv): if not values[inum] is None: self.Nokvalues = self.Nokvalues + 1 self.meanv = self.meanv+values[inum]*weights[inum] self.mean2v = self.mean2v+values[inum]*weights[inum]*values[inum] self.meanwgt = self.meanwgt+weights[inum] self.mean2wgt = self.mean2wgt+weights[inum]*weights[inum] self.meanv = self.meanv/float(self.meanwgt) self.mean2v = self.mean2v/float(self.meanwgt) self.stdv = np.sqrt(self.mean2v-self.meanv*self.meanv) self.meanwgt = self.meanwgt/float(self.Nokvalues) self.mean2wgt = self.mean2wgt/float(self.Nokvalues) self.stdwgt = np.sqrt(self.mean2wgt-self.meanwgt*self.meanwgt) return class statsValWeighted_missVal(object): """Weighted Statistics taking into account a missing value class providing: vals = values (can be a matrix) wgs = weights (can be a matrix) missVal= missing value self.meanv: mean weigthed value self.mean2v: mean quadratic weigthed value self.stdv: weigthed standard deviation self.Nokvalue non None values of a list of values self.meanwgt: mean of the weigths self.mean2wgt: cuadratic mean of the weigths self.stdwgt: standard deviation of the weigths self.quantilesv: quantiles of the weighted values """ def __init__(self, vals, wgs, missVal): fname='statsValWeigthed_missVal' if vals is None: self.Nv = None self.meanv = None self.mean2v = None self.stdv = None self.Nokvalues = None self.meanwgt = None self.mean2wgt = None self.stdwgt = None self.quantilesv = None else: Npt = 1 for idim in range(len(vals.shape)): Npt = Npt * vals.shape[idim] if np.sum(vals >= missVal) == Npt: print errormsg print ' ' + fname + ' all values get missing!!' print errormsg quit(-1) vals0 = np.where(vals >= missVal, None, vals) values = vals0.flatten() weights = wgs.flatten() self.Nv=Npt self.meanv=0. self.mean2v=0. self.stdv=0. self.meanwgt = 0. self.mean2wgt = 0. self.stdwgt = 0. self.Nokvalues = 0 valswgt = values for inum in range(self.Nv): if not values[inum] is None: self.Nokvalues = self.Nokvalues + 1 valswgt[inum] = valswgt[inum]*weights[inum] self.meanv = self.meanv+values[inum]*weights[inum] self.mean2v = self.mean2v+values[inum]*weights[inum]*values[inum] self.meanwgt = self.meanwgt+weights[inum] self.mean2wgt = self.mean2wgt+weights[inum]*weights[inum] self.meanv = self.meanv/float(self.meanwgt) self.mean2v = self.mean2v/float(self.meanwgt) self.stdv = np.sqrt(self.mean2v-self.meanv*self.meanv) valswgt = valswgt/np.float(self.meanwgt) self.meanwgt = self.meanwgt/float(self.Nokvalues) self.mean2wgt = self.mean2wgt/float(self.Nokvalues) self.stdwgt = np.sqrt(self.mean2wgt-self.meanwgt*self.meanwgt) valsq=Quantiles(valswgt, 20) self.quantilesv=valsq.quantilesv return class std_stats2Val(object): """two variables standard Statistics class providing: vals1 = variable 1 vals2 = variable 2 self.bias=mean(var1-var2) self.mae=mean(abs(var1-var2)) self.rmse=sqrt((var1-var2)**2) self.explvar = stddev1/stddev2 self.correlation (and p-value) """ def __init__(self, vals1, vals2): import numpy as np from scipy import stats as sts fname = 'std_stats2Val' if vals1 is None: self.bias = None self.mae = None self.rmse = None self.explvar = None self.corr = None else: values1 = vals1.flatten() values2 = vals2.flatten() Nvals1 = len(values1) Nvals2 = len(values2) if not len(values1) == len(values2): print errormsg print ' ' + fname + ': lengths of variables differ!! Lvar1: ', Nvals1, \ ' Lvar2: ', Nvals2,' statistics between them can not be computed!' quit(-1) self.bias = 0. self.mae = 0. self.rmse = 0. self.explvar = 0. self.corr = np.zeros(2, dtype=np.float) for inum in range(Nvals1): Sval = values1[inum] - values2[inum] self.mae = self.mae + abs(Sval) self.rmse = self.rmse + Sval**2 self.bias = np.mean(vals1) - np.mean(vals2) self.mae = self.mae/Nvals1 self.rmse = np.sqrt(self.rmse/Nvals1) self.explvar = np.var(vals1)/np.var(vals2) self.corr[0], self.corr[1] = sts.pearsonr(values1, values2) return class stats2Val(object): """two variables Statistics class providing: vals1 = variable 1 vals2 = variable 2 power = power of the polynomial fitting to apply between both variables self.min[var], self.max[var], self.mean[var], self.mean2[var], self.std[var] of [var] = var1+var2[v1Av2], var1-var2[v1Sv2], var1/var2[v1Dv2], var1*var2[v1Pv2] self.Nokvalues1: number of correct values of variable 1 self.Nokvalues2: number of correct values of variable 2 self.Nokvalues12: number of correct coincident values of variable 1 and variable 2 self.mae=mean(abs(var1-var2)) self.rmse=sqrt((var1-var2)**2) self.correlation (and p-value) self.linRegress: linear regression [trend, intercept, regression coefficient, p_value, standard error] self.polRegress: polinomial Regresion of degree [power] [coef**[power], coef**[power-1], ...., coef**0] """ def __init__(self, vals1, vals2, power): import numpy as np from scipy import stats as sts if vals1 is None: self.Nv = None self.Nokvalues1 = None self.Nokvalues2 = None self.Nokvalues12 = None self.NDvalNone = None self.minv1Av2 = None self.maxv1Av2 = None self.meanv1Av2 = None self.mean2v1Av2 = None self.stdv1Av2 = None self.minv1Sv2 = None self.maxv1Sv2 = None self.meanv1Sv2 = None self.mean2v1Sv2 = None self.stdv1Sv2 = None self.minv1Dv2 = None self.maxv1Dv2 = None self.meanv1Dv2 = None self.mean2v1Dv2 = None self.stdv1Dv2 = None self.minv1Pv2 = None self.maxv1Pv2 = None self.meanv1Pv2 = None self.mean2v1Pv2 = None self.stdv1Pv2 = None self.bias = None self.mae = None self.rmse = None self.corr = None self.linRegress = None self.polRegress = None self.polRegressResidual = None self.polRegressRes = None self.polRegressSingVal = None else: values1 = vals1.flatten() values2 = vals2.flatten() if not len(values1) == len(values2): print errormsg print ' stats2Val: lengths of variables differ!! Lvar1: ', len(values1), ' Lvar2: ',len(values2),' statistics between them can not be computed!' quit(-1) self.Nv=len(values1) self.minv1Av2=10000000000. self.maxv1Av2=-self.minv1Av2 self.meanv1Av2=0. self.mean2v1Av2=0. self.stdv1Av2=0. self.minv1Sv2=self.minv1Av2 self.maxv1Sv2=-self.minv1Av2 self.meanv1Sv2=0. self.mean2v1Sv2=0. self.stdv1Sv2=0. self.minv1Dv2=self.minv1Av2 self.maxv1Dv2=-self.minv1Av2 self.meanv1Dv2=0. self.mean2v1Dv2=0. self.stdv1Dv2=0. self.minv1Pv2=self.minv1Av2 self.maxv1Pv2=-self.minv1Av2 self.meanv1Pv2=0. self.mean2v1Pv2=0. self.stdv1Pv2=0. self.bias = 0. self.mae = 0. self.rmse = 0. self.corr = np.zeros(2, dtype=np.float) self.linRegress = np.zeros(5, float) self.polRegress = np.zeros(power+1, float) self.polRegressResidual = 0. self.polRegressSingVal = np.zeros(power+1, float) # v1 [+ / - / / / *] v2 ## self.Nokvalues1 = 0 self.Nokvalues2 = 0 self.Nokvalues12 = 0 self.NDvalNone = 0 for inum in range(self.Nv): if not values1[inum] is None: self.Nokvalues1 = self.Nokvalues1 + 1 if not values2[inum] is None: self.Nokvalues2 = self.Nokvalues2 + 1 if not values1[inum] is None and not values2[inum] is None: self.Nokvalues12 = self.Nokvalues12 + 1 Aval = values1[inum] + values2[inum] Sval = values1[inum] - values2[inum] Pval = values1[inum] * values2[inum] if np.isinf(values1[inum] / values2[inum]) or np.isnan(values1[inum] / values2[inum]): if self.NDvalNone < 1: print warnmsg print ' stats2Val: val1/val2 inf or Nan!!!!' Dval = None self.NDvalNone = self.NDvalNone + 1 else: Dval = values1[inum] / values2[inum] self.bias = self.bias + Sval self.mae = self.mae + abs(Sval) self.rmse = self.rmse + Sval**2 if Aval < self.minv1Av2: self.minv1Av2 = Aval if Aval > self.maxv1Av2: self.maxv1Av2 = Aval if Sval < self.minv1Sv2: self.minv1Sv2 = Sval if Sval > self.maxv1Sv2: self.maxv1Sv2 = Sval if not Dval is None and Dval < self.minv1Dv2: self.minv1Dv2 = Dval if not Dval is None and Dval > self.maxv1Dv2: self.maxv1Dv2 = Dval if Pval < self.minv1Pv2: self.minv1Pv2 = Pval if Pval > self.maxv1Pv2: self.maxv1Pv2 = Pval self.meanv1Av2 = self.meanv1Av2+Aval self.mean2v1Av2 = self.mean2v1Av2+Aval*Aval self.meanv1Sv2 = self.meanv1Sv2+Sval self.mean2v1Sv2 = self.mean2v1Sv2+Sval*Sval if not Dval is None: self.meanv1Dv2 = self.meanv1Dv2+Dval self.mean2v1Dv2 = self.mean2v1Dv2+Dval*Dval self.meanv1Pv2 = self.meanv1Pv2+Pval self.mean2v1Pv2 = self.mean2v1Pv2+Pval*Pval ## print 'Nokvalues1: ', self.Nokvalues1, 'Nokvalues2: ', self.Nokvalues2, 'Nokvalues12: ', float(self.Nokvalues12), 'NDvalNone: ',self.NDvalNone self.meanv1Av2 = self.meanv1Av2/float(self.Nokvalues12) self.mean2v1Av2 = self.mean2v1Av2/float(self.Nokvalues12) self.stdv1Av2 = np.sqrt(self.mean2v1Av2-self.meanv1Av2*self.meanv1Av2) self.meanv1Sv2 = self.meanv1Sv2/float(self.Nokvalues12) self.mean2v1Sv2 = self.mean2v1Sv2/float(self.Nokvalues12) self.stdv1Sv2 = np.sqrt(self.mean2v1Sv2-self.meanv1Sv2*self.meanv1Sv2) if self.Nokvalues12 - self.NDvalNone == 0: self.meanv1Dv2 = None self.mean2v1Dv2 = None self.stdv1Dv2 = None print warnmsg print ' stats2Val: all values of val1/val2 are None!' else: self.meanv1Dv2 = self.meanv1Dv2/(float(self.Nokvalues12 - self.NDvalNone)) self.mean2v1Dv2 = self.mean2v1Dv2/(float(self.Nokvalues12 - self.NDvalNone)) self.stdv1Dv2 = np.sqrt(self.mean2v1Dv2-self.meanv1Dv2*self.meanv1Dv2) self.meanv1Pv2 = self.meanv1Pv2/float(self.Nokvalues12) self.mean2v1Pv2 = self.mean2v1Pv2/float(self.Nokvalues12) self.stdv1Pv2 = np.sqrt(self.mean2v1Pv2-self.meanv1Pv2*self.meanv1Pv2) self.bias = self.bias/self.Nokvalues12 self.mae = self.mae/self.Nokvalues12 self.rmse = np.sqrt(self.rmse/self.Nokvalues12) self.corr[0], self.corr[1] = sts.pearsonr(values1, values2) self.linRegress[0], self.linRegress[1], self.linRegress[2], self.linRegress[3], self.linRegress[4] = sts.linregress(values1, values2) polyfitvals=np.polyfit(values1, values2, power, full = True) self.polRegress = polyfitvals[0] self.polRegressRes = polyfitvals[1] self.polRegressSingVal = polyfitvals[3] return class stats2Val_missVal(object): """two variables Statistics taking into account a missing value class providing: vals1 = variable 1 vals2 = variable 2 missVal = missing value power = power of the polynomial fitting to apply between both variables self.min[var], self.max[var], self.mean[var], self.mean2[var], self.std[var] of [var] = var1+var2[v1Av2], var1-var2[v1Sv2], var1/var2[v1Dv2], var1*var2[v1Pv2] self.Nokvalues1: number of correct values of variable 1 self.Nokvalues2: number of correct values of variable 2 self.Nokvalues12: number of correct coincident values of variable 1 and variable 2 self.mae=mean(abs(var1-var2)) self.rmse=sqrt((var1-var2)**2) self.correlation (and p-value) self.linRegress: linear regression [trend, intercept, regression coefficient, p_value, standard error] self.polRegress: polinomial Regresion of degree [power] [coef**[power], coef**[power-1], ...., coef**0] """ def __init__(self, vals1, vals2, power, missVal): import numpy as np from scipy import stats as sts fname='stats2Val_missVal' if vals1 is None: self.Nv = None self.Nokvalues1 = None self.Nokvalues2 = None self.Nokvalues12 = None self.NDvalNone = None self.minv1Av2 = None self.maxv1Av2 = None self.meanv1Av2 = None self.mean2v1Av2 = None self.stdv1Av2 = None self.minv1Sv2 = None self.maxv1Sv2 = None self.meanv1Sv2 = None self.mean2v1Sv2 = None self.stdv1Sv2 = None self.minv1Dv2 = None self.maxv1Dv2 = None self.meanv1Dv2 = None self.mean2v1Dv2 = None self.stdv1Dv2 = None self.minv1Pv2 = None self.maxv1Pv2 = None self.meanv1Pv2 = None self.mean2v1Pv2 = None self.stdv1Pv2 = None self.mae = None self.rmse = None self.corr = None self.linRegress = None self.polRegress = None self.polRegressResidual = None self.polRegressRes = None self.polRegressSingVal = None else: Npt1 = 1 for idim in range(len(vals1.shape)): Npt1 = Npt1 * vals1.shape[idim] if np.sum(vals1 >= missVal) == Npt1: print errormsg print ' ' + fname + ' all values 1 get missing!!' print errormsg quit(-1) Npt2 = 1 for idim in range(len(vals2.shape)): Npt2 = Npt2 * vals2.shape[idim] if np.sum(vals2 >= missVal) == Npt2: print errormsg print ' ' + fname + ' all values 2 get missing!!' print errormsg quit(-1) vals10 = np.where(abs(vals1) >= missVal, None, vals1) vals20 = np.where(abs(vals2) >= missVal, None, vals2) values1 = vals10.flatten() values2 = vals20.flatten() if not len(values1) == len(values2): print errormsg print ' stats2Val: lengths of variables differ!! Lvar1: ', len(values1), ' Lvar2: ',len(values2),' statistics between them can not be computed!' quit(-1) self.Nv=Npt1 self.minv1Av2=10000000000. self.maxv1Av2=-self.minv1Av2 self.meanv1Av2=0. self.mean2v1Av2=0. self.stdv1Av2=0. self.minv1Sv2=self.minv1Av2 self.maxv1Sv2=-self.minv1Av2 self.meanv1Sv2=0. self.mean2v1Sv2=0. self.stdv1Sv2=0. self.minv1Dv2=self.minv1Av2 self.maxv1Dv2=-self.minv1Av2 self.meanv1Dv2=0. self.mean2v1Dv2=0. self.stdv1Dv2=0. self.minv1Pv2=self.minv1Av2 self.maxv1Pv2=-self.minv1Av2 self.meanv1Pv2=0. self.mean2v1Pv2=0. self.stdv1Pv2=0. self.mae = 0. self.rmse = 0. self.corr = np.array([0., 0.]) self.linRegress = np.zeros(5, float) self.polRegress = np.zeros(power+1, float) self.polRegressResidual = 0. self.polRegressSingVal = np.zeros(power+1, float) # v1 [+ / - / / / *] v2 ## self.Nokvalues1 = 0 self.Nokvalues2 = 0 self.Nokvalues12 = 0 self.NDvalNone = 0 for inum in range(self.Nv): if not values1[inum] is None: self.Nokvalues1 = self.Nokvalues1 + 1 if not values2[inum] is None: self.Nokvalues2 = self.Nokvalues2 + 1 if not values1[inum] is None and not values2[inum] is None: self.Nokvalues12 = self.Nokvalues12 + 1 Aval = values1[inum] + values2[inum] Sval = values1[inum] - values2[inum] Pval = values1[inum] * values2[inum] if np.isinf(values1[inum] / values2[inum]) or np.isnan(values1[inum] / values2[inum]): if self.NDvalNone < 1: print warnmsg print ' stats2Val: val1/val2 inf or Nan!!!!' Dval = None self.NDvalNone = self.NDvalNone + 1 else: Dval = values1[inum] / values2[inum] self.mae = self.mae + abs(Sval) self.rmse = self.rmse + Sval**2 if Aval < self.minv1Av2: self.minv1Av2 = Aval if Aval > self.maxv1Av2: self.maxv1Av2 = Aval if Sval < self.minv1Sv2: self.minv1Sv2 = Sval if Sval > self.maxv1Sv2: self.maxv1Sv2 = Sval if not Dval is None and Dval < self.minv1Dv2: self.minv1Dv2 = Dval if not Dval is None and Dval > self.maxv1Dv2: self.maxv1Dv2 = Dval if Pval < self.minv1Pv2: self.minv1Pv2 = Pval if Pval > self.maxv1Pv2: self.maxv1Pv2 = Pval self.meanv1Av2 = self.meanv1Av2+Aval self.mean2v1Av2 = self.mean2v1Av2+Aval*Aval self.meanv1Sv2 = self.meanv1Sv2+Sval self.mean2v1Sv2 = self.mean2v1Sv2+Sval*Sval if not Dval is None: self.meanv1Dv2 = self.meanv1Dv2+Dval self.mean2v1Dv2 = self.mean2v1Dv2+Dval*Dval self.meanv1Pv2 = self.meanv1Pv2+Pval self.mean2v1Pv2 = self.mean2v1Pv2+Pval*Pval ## print 'Nokvalues1: ', self.Nokvalues1, 'Nokvalues2: ', self.Nokvalues2, 'Nokvalues12: ', float(self.Nokvalues12), 'NDvalNone: ',self.NDvalNone self.meanv1Av2 = self.meanv1Av2/float(self.Nokvalues12) self.mean2v1Av2 = self.mean2v1Av2/float(self.Nokvalues12) self.stdv1Av2 = np.sqrt(self.mean2v1Av2-self.meanv1Av2*self.meanv1Av2) self.meanv1Sv2 = self.meanv1Sv2/float(self.Nokvalues12) self.mean2v1Sv2 = self.mean2v1Sv2/float(self.Nokvalues12) self.stdv1Sv2 = np.sqrt(self.mean2v1Sv2-self.meanv1Sv2*self.meanv1Sv2) if self.Nokvalues12 - self.NDvalNone == 0: self.meanv1Dv2 = None self.mean2v1Dv2 = None self.stdv1Dv2 = None print warnmsg print ' stats2Val: all values of val1/val2 are None!' else: self.meanv1Dv2 = self.meanv1Dv2/(float(self.Nokvalues12 - self.NDvalNone)) self.mean2v1Dv2 = self.mean2v1Dv2/(float(self.Nokvalues12 - self.NDvalNone)) self.stdv1Dv2 = np.sqrt(self.mean2v1Dv2-self.meanv1Dv2*self.meanv1Dv2) self.meanv1Pv2 = self.meanv1Pv2/float(self.Nokvalues12) self.mean2v1Pv2 = self.mean2v1Pv2/float(self.Nokvalues12) self.stdv1Pv2 = np.sqrt(self.mean2v1Pv2-self.meanv1Pv2*self.meanv1Pv2) self.mae = self.mae/self.Nokvalues12 self.rmse = np.sqrt(self.rmse/self.Nokvalues12) vals1Nomiss = np.ones(len(values1), dtype=bool) vals2Nomiss = np.ones(len(values1), dtype=bool) for i in range(len(values1)): if values1[i] is None: vals1Nomiss[i] = False for i in range(len(values2)): if values2[i] is None: vals2Nomiss[i] = False v1 = np.array(values1[vals1Nomiss], dtype=float) v2 = np.array(values2[vals2Nomiss], dtype=float) if not v1.shape == v2.shape: print errormsg print ' ' + fname + ': variables without missing values v1: ',v1.shape , ' and v2: ',v2.shape ,' do not have the same shape! ' print errormsg quit(-1) self.corr = sts.pearsonr(v1, v2) self.linRegress[0], self.linRegress[1], self.linRegress[2], self.linRegress[3], self.linRegress[4] = sts.linregress(v1, v2) polyfitvals=np.polyfit(v1, v2, power, full = True) self.polRegress = polyfitvals[0] self.polRegressRes = polyfitvals[1] self.polRegressSingVal = polyfitvals[3] return def mask_2masked(vals1, vals2): """ Function to provide the boolean matrix (in opposite way as it is in the mask) as combination of mask from to masked matrices """ import numpy.ma as ma fname = 'mask_2masked' # if len(vals1.shape) != len(vals2.shape): # print errormsg # print ' ' + fname + ' matrix 1 :', len(vals1.shape), ' and matrix 2 ', len(vals2.shape), ' have different size!' # print errormsg # quit(-1) # for idim in range(len(vals1.shape)): # if vals1.shape[idim] != vals2.shape[idim]: # print errormsg # print ' ' + fname + ' dimension ', idim,' from matrix 1 :', vals1.shape[idim], ' and matrix 2 ', \ # vals2.shape[idim], ' have different size!' # print errormsg # quit(-1) if type(vals1) == type(ma.array(1)): mask1array=np.where(ma.getmaskarray(vals1) == False, True, False) else: mask1array=np.ones(vals1.shape, dtype=bool) if type(vals2) == type(ma.array(1)): mask2array=np.where(ma.getmaskarray(vals2) == False, True, False) else: mask2array=np.ones(vals2.shape, dtype=bool) mask12 = mask1array*mask2array return mask12 def mask_pearsonr(xvals, yvals): """ Function to compute a pearson correlation from mask matrices """ from scipy import stats as sts fillVal = 1.e20 maskxy = mask_2masked(xvals, yvals) if np.sum(maskxy) > 1: pearsonr = sts.pearsonr(xvals[maskxy], yvals[maskxy]) if np.isnan(pearsonr[0]) or np.isnan(pearsonr[1]): pearsonr = ( fillVal, fillVal) else: pearsonr = (fillVal, fillVal) return pearsonr def mask_quantiles(maskmat, Nquants): """ Function to provide the quantiles of a masked array 20 for %5 bins (21 in total) """ import numpy.ma as ma fillValue = 1.e20 sortmat = maskmat.flatten().copy() sortmat.sort() quants = np.zeros(Nquants+1, dtype=type(maskmat[0])) Nv = ma.size(maskmat) NoMask=maskmat.count() if NoMask < Nquants: quants[:] = fillValue else: for iq in range(Nquants): quants[iq] = sortmat[int((NoMask-1)*iq/(Nquants))] quants[Nquants] = sortmat[NoMask-1] return quants def percendone(nvals,tot,percen,msg): """ Function to provide the percentage of an action across the matrix nvals=number of values tot=total number of values percen=percentage frequency for which the message is wanted msg= message """ from sys import stdout num = int(tot * percen/100) if (nvals%num == 0): print '\r ' + msg + '{0:8.3g}'.format(nvals*100./tot) + ' %', stdout.flush() return '' def mask_linregres(vals1, vals2): """ Function to compute a linear regression from masked data vals1: x-values for the regresion vals2: y-values for the regresion """ import numpy.ma as ma fname = 'mask_linregres' missval1 = vals1.get_fill_value() missval2 = vals2.get_fill_value() vals10 = np.where(abs(vals1) >= abs(missval1*0.9), None, vals1) vals20 = np.where(abs(vals2) >= abs(missval2*0.9), None, vals2) values1 = vals10.flatten() values2 = vals20.flatten() vals1Nomiss = np.ones(len(values1), dtype=bool) vals2Nomiss = np.ones(len(values2), dtype=bool) for i in range(len(values1)): if values1[i] is None: vals1Nomiss[i] = False for i in range(len(values2)): if values2[i] is None: vals2Nomiss[i] = False v1 = np.array(values1[vals1Nomiss], dtype=float) v2 = np.array(values2[vals2Nomiss], dtype=float) if len(v1) != len(v2): print errormsg print fname + ': length of masked matrices mat1:',len(v1),'and mat2:',len(v2),'does not match!' print errormsg quit(-1) linregres = np.array(sts.linregress(v1, v2), dtype= np.float64) return linregres def mask_space_stats(maskmat,statsvals,dim): """ Function to give back the multi-dimensional statisitcs of a given masked array maskmat=multidimensional masked array statsvals=[statn]:[values] [statn]: statistics to do: 'quant', quantiles [values]: value for the statistics: Nquantiles dim= dimension to run the statistics """ from sys import stdout fname = 'mask_space_stats' statn=statsvals.split(':')[0] if len(statsvals.split(':')) > 1: values=statsvals.split(':')[1] maskshape = maskmat.shape Ndims = len(maskshape) if statn == 'quant': if len(statsvals.split(':')) == 1: print errormsg print fname + ': statistics "' + statn + '" requires a value!!!' print errormsg quit(-1) Nquants=int(values) if Ndims == 2: if dim == 0: statval = np.ones((21, maskshape[1]), dtype=np.float64)*fillValue for i in range(maskshape[1]): percendone(i, maskshape[1], 5, 'quantiles') statval[:,i] = mask_quantiles(maskmat[:,i],Nquants) if dim == 1: statval = np.ones((21, maskshape[0]), dtype=np.float64)*fillValue for i in range(maskshape[0]): percendone(i, maskshape[0], 5, 'quantiles') statval[:,i] = mask_quantiles(statval[i,:],Nquants) elif Ndims == 3: if dim == 0: statval = np.ones((21, maskshape[1], maskshape[2]), dtype=np.float64)*fillValue for i in range(maskshape[1]): for j in range(maskshape[2]): percendone(i*maskshape[2] + j, maskshape[1]*maskshape[2], 5, 'quantiles') statval[:,i,j] = mask_quantiles(maskmat[:,i,j],Nquants) if dim == 1: statval = np.ones((21, maskshape[0], maskshape[2]), dtype=np.float64)*fillValue for i in range(maskshape[0]): for j in range(maskshape[2]): percendone(i*maskshape[2] + j, maskshape[0]*maskshape[2], 5, 'quantiles') statval[:,i,j] = mask_quantiles(maskmat[i,:,j],Nquants) if dim == 2: statval = np.ones((21, maskshape[0], maskshape[1]), dtype=np.float64)*fillValue for i in range(maskshape[0]): for j in range(maskshape[1]): percendone(i*maskshape[1] + j, maskshape[0]*maskshape[1], 5, 'quantiles') statval[:,i,j] = mask_quantiles(maskmat[i,j,:],Nquants) elif Ndims == 4: if dim == 0: statval = np.ones((21, maskshape[1], maskshape[2], maskshape[3]), dtype=np.float64)*fillValue for i in range(maskshape[1]): for j in range(maskshape[2]): for k in range(maskshape[3]): percendone(i*maskshape[1]*maskshape[2] + j*maskshape[2] + k, maskshape[1]*maskshape[2]*maskshape[3], 5, 'quantiles') statval[:,i,j,k] = mask_quantiles(maskmat[:,i,j,k],Nquants) if dim == 1: statval = np.ones((21, maskshape[0], maskshape[2], maskshape[3]), dtype=np.float64)*fillValue for i in range(maskshape[0]): for j in range(maskshape[2]): for k in range(maskshape[3]): percendone(i*maskshape[0]*maskshape[2] + j*maskshape[2] + k, maskshape[0]*maskshape[2]*maskshape[3], 5, 'quantiles') statval[:,i,j,k] = mask_quantiles(maskmat[i,:,j,k],Nquants) if dim == 2: statval = np.ones((21, maskshape[0], maskshape[1], maskshape[3]), dtype=np.float64)*fillValue for i in range(maskshape[0]): for j in range(maskshape[1]): for k in range(maskshape[3]): percendone(i*maskshape[0]*maskshape[1] + j*maskshape[1] + k, maskshape[0]*maskshape[1]*maskshape[3], 5, 'quantiles') statval[:,i,j,k] = mask_quantiles(maskmat[i,j,:,k],Nquants) if dim == 3: statval = np.ones((21, maskshape[0], maskshape[1], maskshape[2]), dtype=np.float64)*fillValue for i in range(maskshape[0]): for j in range(maskshape[1]): for k in range(maskshape[2]): percendone(i*maskshape[0]*maskshape[1] + j*maskshape[1] + k, maskshape[0]*maskshape[1]*maskshape[2], 5, 'quantiles') statval[:,i,j,k] = mask_quantiles(maskmat[i,j,k,:],Nquants) else: print errormsg print fname + ': size of matrix ', Ndims,'not ready!!!' print errormsg quit(-1) else: print errormsg print fname + ': statistics "' + statn + '" not ready!!!!' print errormsg quit(-1) print stdout.write("\n") return statval class statsVal(object): """Statistics class providing vals = variable self.Nv = number of values self.minv = minimum value self.maxv = maximum value self.meanv = mean value self.mean2v = cuadratic mean value self.stdv = standard deviation value self.Nokvalues = number of correct values of variable self.quantilesv = quantiles (%5 bins) of the variable """ def __init__(self, vals): if vals is None: self.Nv = None self.minv = None self.maxv = None self.meanv = None self.mean2v = None self.stdv = None self.Nokvalues = None self.quantilesv = None else: values = vals.flatten() self.Nv=len(values) self.minv=10000000000. self.maxv=-100000000. self.meanv=0. self.mean2v=0. self.stdv=0. sortedvalues = sorted(values) self.Nokvalues = 0 for inum in range(self.Nv): if not values[inum] is None: self.Nokvalues = self.Nokvalues + 1 if values[inum] < self.minv: self.minv = values[inum] if values[inum] > self.maxv: self.maxv = values[inum] self.meanv = self.meanv+values[inum] self.mean2v = self.mean2v+values[inum]*values[inum] self.meanv = self.meanv/float(self.Nokvalues) self.mean2v = self.mean2v/float(self.Nokvalues) self.stdv = np.sqrt(self.mean2v-self.meanv*self.meanv) self.quantilesv = [] for iq in range(20): self.quantilesv.append(sortedvalues[int((self.Nv-1)*iq/20)]) self.quantilesv.append(sortedvalues[self.Nv-1]) self.medianv = self.quantilesv[10] return class Quantiles(object): """ Class to provide quantiles from a given arrayof values """ def __init__(self, values, Nquants): import numpy.ma as ma if values is None: self.quantilesv = None else: self.quantilesv = [] vals0 = values.flatten() Nvalues = len(vals0) vals = ma.masked_equal(vals0, None) Nvals=len(vals.compressed()) sortedvals = sorted(vals.compressed()) for iq in range(Nquants): self.quantilesv.append(sortedvals[int((Nvals-1)*iq/Nquants)]) self.quantilesv.append(sortedvals[Nvals-1]) return class statsVal_missVal(object): """Statistics class tacking into account a missing value providing vals = variable missval = missing value self.Nv = number of values self.minv = minimum value self.maxv = maximum value self.meanv = mean value self.mean2v = cuadratic mean value self.stdv = standard deviation value self.Nokvalues = number of correct values of variable self.quantilesv = quantiles (%5 bins) of the variable """ def __init__(self, vals, missVal): fname='statsVal_missVal' if vals is None: self.Nv = None self.minv = None self.maxv = None self.meanv = None self.mean2v = None self.stdv = None self.Nokvalues = None self.quantilesv = None else: Npt = 1 for idim in range(len(vals.shape)): Npt = Npt * vals.shape[idim] if np.sum(vals >= missVal) == Npt: print errormsg print ' ' + fname + ' all values get missing!!' print errormsg quit(-1) vals1 = np.where(abs(vals) >= missVal, None, vals) vals0 = np.where(np.isnan(vals1), None, vals1) values = vals0.flatten() self.Nv=Npt self.minv=10000000000. self.maxv=-100000000. self.meanv=0. self.mean2v=0. self.stdv=0. sortedvalues = sorted(values) self.Nokvalues = 0 for inum in range(self.Nv): if not values[inum] is None: self.Nokvalues = self.Nokvalues + 1 if values[inum] < self.minv: self.minv = values[inum] if values[inum] > self.maxv: self.maxv = values[inum] self.meanv = self.meanv+values[inum] self.mean2v = self.mean2v+values[inum]*values[inum] self.meanv = self.meanv/float(self.Nokvalues) self.mean2v = self.mean2v/float(self.Nokvalues) self.stdv = np.sqrt(self.mean2v-self.meanv*self.meanv) self.quantilesv = [] for iq in range(20): self.quantilesv.append(sortedvalues[int((self.Nv-1)*iq/20)]) self.quantilesv.append(sortedvalues[self.Nv-1]) self.medianv = self.quantilesv[10] return def printing_class(classobj): """ Function to print all the values of a given class """ valscls = vars(classobj) for attrcls in valscls: print attrcls, ':', valscls[attrcls] return def fmtprinting_class(classobj): """ Function to print all the values of a given class """ valscls = vars(classobj) for attrcls in valscls: print '@' + attrcls + '@', ':', valscls[attrcls] return def singleline_printing_class(classobj): """ Function to print all the values of a given class in a single line to be parseavel output as: 'singleline_printing_class[attrval]';'[attrval]';'... [attrval] = @'[attribute]'@='[value]('!' for spaces) """ fname='singleline_printing_class' valscls = vars(classobj) sline=fname + ' ' for attrcls in valscls: sline = sline + '@' + attrcls + '@=' + str(valscls[attrcls]).replace(' ','!') + ";" print sline return def cycl_incr(cyclval,cycle,ninc): """ Function to increment a cyclic value [cyclval] with a cycle [cycle] a given number [ninc] of times >>> cycl_incr(1,4,1) 2 >>> cycl_incr(3,4,1) 0 >>> cycl_incr(1,4,10) 3 """ if ninc >= cycle: print 'cycl_incr: WARNING -- warning -- WARNING -- warning' print ' given increment: ', ninc,' is larger than the cycle !!' ninc = ninc - cycle*int(ninc/cycle) print ' reducing it to: ', ninc val=cyclval + ninc if val >= cycle: val=cyclval + ninc - cycle return val def times_4seasons(tvals, integrity): """ Function to split a time series in matricial date format ([:,year,mon,day,hour,minute,second]) in the four stations DJF,MAM,JJA,SON tvals= matrix withe times as [:,year,mon,day,hour,minute,second] integrity= only give values for entire seasons [True, 3 months for the season], or just split the values by seasons [False] """ fillVal=1.e20 # print tvals dt=tvals.shape[0] seasons=np.ones((dt,4),dtype=bool) seasons=seasons*False monseas=[12,3,6,9] firstseas=False for it in range(dt): if not firstseas: if integrity: for iseas in range(4): if tvals[it,1] == monseas[iseas]: nseas=iseas seasons[it,nseas]=True firstseas=True begseas=it else: for iseas in range(4): for imon in range(3): if tvals[it,1] == cycl_incr(monseas[iseas],12,imon): nseas=iseas seasons[it,nseas]=True firstseas=True else: newseas=cycl_incr(nseas,4,1) if tvals[it,1] == monseas[newseas]: seasons[it,newseas] = True nseas=newseas begseas=it else: seasons[it,nseas] = True endseas = it ## print 'Last season: ',nseas,' beginnig: ',begseas,' ending: ',endseas # Checking integrity of last season (has to have 3 months) ## if integrity: fullseas=True Nmon=np.unique(tvals[begseas:endseas+1,1]) for it in range(begseas,endseas): fullseas=fullseas*seasons[it,nseas] if len(Nmon) < 3 or not fullseas: seasons[begseas:endseas+1,nseas] = False return seasons def realdatetime_CFcompilant(times, Srefdate, tunits): """ Function to transform a matrix with real time values ([year, month, day, hour, minute, second]) to a netCDF one times= matrix with times Srefdate= reference date ([YYYY][MM][DD][HH][MI][SS] format) tunits= units of time respect to Srefdate >>> realdatetime_CFcompilant(np.array([ [1976, 2, 17, 8, 20, 0], [1976, 2, 18, 8, 20, 0]], dtype=int), '19491201000000', 'hours') [ 229784.33333333 229808.33333333] """ import datetime as dt yrref=int(Srefdate[0:4]) monref=int(Srefdate[4:6]) dayref=int(Srefdate[6:8]) horref=int(Srefdate[8:10]) minref=int(Srefdate[10:12]) secref=int(Srefdate[12:14]) refdate=dt.datetime(yrref, monref, dayref, horref, minref, secref) dimt=times.shape[0] cfdates = np.zeros((dimt), dtype=np.float64) if tunits == 'weeks': for it in range(dimt): cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate cfdates[it] = (cfdate.days + cfdate.seconds/(3600.*24.))/7. elif tunits == 'days': for it in range(dimt): cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate cfdates[it] = cfdate.days + cfdate.seconds/(3600.*24.) elif tunits == 'hours': for it in range(dimt): cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate cfdates[it] = cfdate.days*24. + cfdate.seconds/3600. elif tunits == 'minutes': for it in range(dimt): cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate cfdates[it] = cfdate.days*24.*60. + cfdate.seconds/60. elif tunits == 'seconds': for it in range(dimt): cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate cfdates[it] = cfdate.days*24.*3600. + cfdate.seconds elif tunits == 'milliseconds': for it in range(dimt): cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate cfdates[it] = cfdate.days*1000.*24.*3600. + cfdate.seconds*1000. elif tunits == 'microseconds': for it in range(dimt): cfdate = dt.datetime(times[it,0], times[it,1], times[it,2], times[it,3], times[it,4], times[it,5]) - refdate cfdates[it] = cfdate.days*1000000.*24.*3600. + cfdate.seconds*1000000. else: print errormsg print ' ' + fname + ': time units "' + tunits + '" is not ready!!!' quit(-1) return cfdates def realdatetime1_CFcompilant(time, Srefdate, tunits): """ Function to transform a matrix with a real time value ([year, month, day, hour, minute, second]) to a netCDF one time= matrix with time Srefdate= reference date ([YYYY][MM][DD][HH][MI][SS] format) tunits= units of time respect to Srefdate >>> realdatetime1_CFcompilant([1976, 2, 17, 8, 20, 0], '19491201000000', 'hours') 229784.33333333 """ import datetime as dt yrref=int(Srefdate[0:4]) monref=int(Srefdate[4:6]) dayref=int(Srefdate[6:8]) horref=int(Srefdate[8:10]) minref=int(Srefdate[10:12]) secref=int(Srefdate[12:14]) refdate=dt.datetime(yrref, monref, dayref, horref, minref, secref) if tunits == 'weeks': cfdate = dt.datetime(time[0],time[1],time[2],time[3],time[4],time[5])-refdate cfdates = (cfdate.days + cfdate.seconds/(3600.*24.))/7. elif tunits == 'days': cfdate = dt.datetime(time[0],time[1],time[2],time[3],time[4],time[5]) - refdate cfdates = cfdate.days + cfdate.seconds/(3600.*24.) elif tunits == 'hours': cfdate = dt.datetime(time[0],time[1],time[2],time[3],time[4],time[5]) - refdate cfdates = cfdate.days*24. + cfdate.seconds/3600. elif tunits == 'minutes': cfdate = dt.datetime(time[0],time[1],time[2],time[3],time[4],time[5]) - refdate cfdates = cfdate.days*24.*60. + cfdate.seconds/60. elif tunits == 'seconds': cfdate = dt.datetime(time[0],time[1],time[2],time[3],time[4],time[5]) - refdate cfdates = cfdate.days*24.*3600. + cfdate.seconds elif tunits == 'milliseconds': cfdate = dt.datetime(time[0],time[1],time[2],time[3],time[4],time[5]) - refdate cfdates = cfdate.days*1000.*24.*3600. + cfdate.seconds*1000. elif tunits == 'microseconds': cfdate = dt.datetime(time[0],time[1],time[2],time[3],time[4],times[5]) - refdate cfdates = cfdate.days*1000000.*24.*3600. + cfdate.seconds*1000000. else: print errormsg print ' ' + fname + ': time units "' + tunits + '" is not ready!!!' quit(-1) return cfdates def netCDFdatetime_realdatetime(units, tcalendar, times): """ Function to transfrom from netCDF CF-compilant times to real time [units]= CF time units [tunits] since [YYYY]-[MM]-[HH] [[HH]:[MI]:[SS]] [tcalendar]= time calendar [times]= CF time values """ import datetime as dt txtunits = units.split(' ') tunits = txtunits[0] Srefdate = txtunits[len(txtunits) - 1] # Calendar type ## is360 = False if tcalendar is not None: print ' netCDFdatetime_realdatetime: There is a calendar attribute' if tcalendar == '365_day' or tcalendar == 'noleap': print ' netCDFdatetime_realdatetime: No leap years!' isleapcal = False elif tcalendar == 'proleptic_gregorian' or tcalendar == 'standard' or tcalendar == 'gregorian': isleapcal = True elif tcalendar == '360_day': is360 = True isleapcal = False else: print errormsg print ' netCDFdatetime_realdatetime: Calendar "' + tcalendar + '" not prepared!' quit(-1) # Does reference date contain a time value [YYYY]-[MM]-[DD] [HH]:[MI]:[SS] ## timeval = Srefdate.find(':') if not timeval == -1: print ' netCDFdatetime_realdatetime: refdate with time!' refdate = datetimeStr_datetime(txtunits[len(txtunits) - 2] + '_' + Srefdate) else: refdate = dateStr_date(Srefdate) dimt = len(times) # datetype = type(dt.datetime(1972,02,01)) # realdates = np.array(dimt, datetype) # print realdates ## Not in timedelta # if tunits == 'years': # for it in range(dimt): # realdate = refdate + dt.timedelta(years=float(times[it])) # realdates[it] = int(realdate.year) # elif tunits == 'months': # for it in range(dimt): # realdate = refdate + dt.timedelta(months=float(times[it])) # realdates[it] = int(realdate.year) # realdates = [] realdates = np.zeros((dimt, 6), dtype=int) if tunits == 'weeks': for it in range(dimt): realdate = refdate + dt.timedelta(weeks=float(times[it])) realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second] elif tunits == 'days': for it in range(dimt): realdate = refdate + dt.timedelta(days=float(times[it])) realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second] elif tunits == 'hours': for it in range(dimt): realdate = refdate + dt.timedelta(hours=float(times[it])) # if not isleapcal: # Nleapdays = cal.leapdays(int(refdate.year), int(realdate.year)) # realdate = realdate - dt.timedelta(days=Nleapdays) # if is360: # Nyears360 = int(realdate.year) - int(refdate.year) + 1 # realdate = realdate -dt.timedelta(days=Nyears360*5) # realdates[it] = realdate # realdates = refdate + dt.timedelta(hours=float(times)) realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second] elif tunits == 'minutes': for it in range(dimt): realdate = refdate + dt.timedelta(minutes=float(times[it])) realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second] elif tunits == 'seconds': for it in range(dimt): realdate = refdate + dt.timedelta(seconds=float(times[it])) realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second] elif tunits == 'milliseconds': for it in range(dimt): realdate = refdate + dt.timedelta(milliseconds=float(times[it])) realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second] elif tunits == 'microseconds': for it in range(dimt): realdate = refdate + dt.timedelta(microseconds=float(times[it])) realdates[it,:]=[realdate.year, realdate.month, realdate.day, realdate.hour, realdate.minute, realdate.second] else: print errormsg print ' netCDFdatetime_realdatetime: time units "' + tunits + '" is not ready!!!' quit(-1) return realdates class cls_yearly_means(object): """ Class to compute the yearly mean of a time series of values tvals=time values (year, month, day, hour, minute, second) format values=time-series of values dateref= reference date [YYYY][MM][DD][HH][MI][SS] format tunits= time units self.dimt = Number of values self.yrv = yearly mean values self.yrt = years of the mean values >>> timesv = netCDFdatetime_realdatetime('days since 1949-12-01 00:00:00', 'standard', np.arange(1129)) >>> valuesv = np.zeros((1129), dtype=np.float) >>> valuesv[0:31] = 0. >>> valuesv[31:394] = 1. >>> valuesv[395:761] = 2. >>> valuesv[761:1127] = 3. >>> valuesv[1127:1129] = 4. >>> yrlmeans = cls_yearly_means(timesv, valuesv, '19491201000000', 'days') >>> print yrlmeans.dimt,yrlmeans.yrv, yrlmeans.yrt 5 [ 0. 1. 2. 3. 4.] [ 1949. 1950. 1951. 1952. 1953.] """ def __init__(self, tvals, values, dateref, tunits): import numpy.ma as ma fillVal=1.e20 fname = 'cls_yearly_means' if tvals is None: self.dimt = None self.yrv = None self.yrt = None elif tvals == 'h': print fname + '_____________________________________________________________' print cls_yearly_means.__doc__ quit() else: dt=len(values) if dt > 0: years = np.unique(tvals[:,0]) Nyrs = len(years) yrmean = np.zeros((Nyrs), dtype=np.float) yrt = np.zeros((Nyrs), dtype=np.float) iiyr = tvals[0,0] yrmean[0] = values[0] yrt[0] = iiyr iit = 0 for iyr in range(Nyrs): nvals = 1 for it in range(iit+1,dt): # print iyr, iiyr, it, tvals[it,0],':',values[it],'->',yrmean[iyr] if tvals[it,0] == iiyr: yrmean[iyr] = yrmean[iyr] + values[it] nvals = nvals + 1 else: yrmean[iyr] = yrmean[iyr] / (nvals*1.) iiyr = tvals[it,0] yrmean[iyr + 1] = values[it] yrt[iyr+1] = iiyr iit = it break yrmean[Nyrs-1] = yrmean[Nyrs-1]/nvals self.dimt = Nyrs self.yrv = yrmean self.yrt = yrt else: print errormsg print ' ' + fname + ': No values passed!' print ' values:', values quit(-1) return class cls_seasonal_means(object): """ Class to compute the seasonal mean of a time series of values tvals=time values (year, month, day, hour, minute, second) format values=time-series of values dateref= reference date [YYYY][MM][DD][HH][MI][SS] format tunits= time units self.dimt = Number of values self.seasv = seasonal mean values self.seast = seasonal time mean values """ def __init__(self, tvals, values, dateref, tunits): import numpy.ma as ma fillVal=1.e20 fname = 'cls_seasonal_means' if tvals is None: self.dimt = None self.seasv = None self.seast = None else: tseasons=times_4seasons(tvals, True) dt=len(values) seasvals=np.ones((dt/12,4), dtype=np.float64)*fillVal seastimes=np.zeros((dt/12,4), dtype=np.float64) dates = realdatetime_CFcompilant(tvals, dateref, tunits) for iseas in range(4): for it in range(dt): if tseasons[it,iseas]: tfirstseas=int(it/11) firstseas=True ## print ' first time-step of season ', iseas, ' is: ',it,' position: ',tfirstseas break for itt in range(it, dt-1,12): seasvals[int(itt/12),iseas]=(values[itt] + values[itt+1] + values[itt+2])/3. seastimes[int(itt/12),iseas]=dates[itt] + (dates[itt+2] - dates[itt])/2. ## print itt, values[itt], values[itt+1], values[itt+2], '--->', seasvals[int(itt/12),iseas] self.dimt = dt/12 self.seasv = ma.masked_equal(seasvals, fillVal) self.seast = ma.masked_equal(seastimes, fillVal) return class cls_seasonal_accums(object): """ Class to compute the seasonal accumulations of a time series of values tvals=time values (year, month, day, hour, minute, second) format values=time-series of values dateref= reference date [YYYY][MM][DD][HH][MI][SS] format tunits= time units self.dimt = Number of values self.seasv = seasonal mean values self.seast = seasonal time mean values """ def __init__(self, tvals, values, dateref, tunits): import numpy.ma as ma fillVal=1.e20 if tvals is None: self.dimt = None self.seasv = None self.seast = None else: tseasons=times_4seasons(tvals, True) dt=len(values) seasvals=np.ones((dt/12,4), dtype=np.float64)*fillVal seastimes=np.zeros((dt/12,4), dtype=np.float64) dates = realdatetime_CFcompilant(tvals, dateref, tunits) for iseas in range(4): for it in range(dt): if tseasons[it,iseas]: tfirstseas=int(it/11) firstseas=True # print ' first time-step of season ', iseas, ' is: ',it,' position: ',tfirstseas break for itt in range(it, dt-1,12): seasvals[int(itt/12),iseas]=values[itt] + values[itt+1] + values[itt+2] seastimes[int(itt/12),iseas]=dates[itt] + (dates[itt+2] - dates[itt])/2. self.dimt = dt/12 self.seasv = ma.masked_equal(seasvals, fillVal) self.seast = ma.masked_equal(seastimes, fillVal) return def seasonal_means(tvals, values): """ Function to compute the seasonal mean of a time series of values tvals=time values (year, month, day, hour, minute, second) format values=time-series of values """ fillVal=1.e20 tseasons=times_4seasons(tvals, True) dt=len(values) seasvals=np.ones((dt/4,4), dtype=np.float64) seasvals=seasvals*fillVal for iseas in range(4): for it in range(dt): if tseasons[it,iseas]: tfirstseas=int(it/11) firstseas=True # print ' first time-step of season ', iseas, ' is: ',it,' position: ',tfirstseas break for itt in range(it, dt-1,12): seasvals[int(itt/12),iseas]=(values[itt] + values[itt+1] + values[itt+2])/3. return seasvals def seasonal_accum(tvals, values): """ Function to compute the seasonal accumulation of a time series of values tvals=time values (year, month, day, hour, minute, second) format values=time-series of values """ fillVal=1.e20 tseasons=times_4seasons(tvals, True) dt=len(values) seasvals=np.ones((dt/4,4), dtype=np.float64) seasvals=seasvals*fillVal for iseas in range(4): for it in range(dt): if tseasons[it,iseas]: tfirstseas=int(it/11) firstseas=True # print ' first time-step of season ', iseas, ' is: ',it,' position: ',tfirstseas break for itt in range(it, dt-1,12): seasvals[int(itt/11),iseas]=values[itt] + values[itt+1] + values[itt+2] return seasvals def load_variable_lastdims(var, prevdims, Nlastdims): """ Function to load the last [Nlastdims] dimensions of a variable [var] at the other dimensions at [prevdims] >>> load_variable_lastdims(np.array(range(5*5*5)).reshape(5,5,5), [1,2], 1) [35 36 37 38 39] """ fname='load_variable_lastdims' dims=var.shape Ndims=len(dims) Nprevdims = len(prevdims) if not Nprevdims + Nlastdims == Ndims: print erromsg print ' ' + fname + ': number of dimensions previous (',Nprevdim,') and last (',Nlastdims, ') does not match with variable size: ',Ndims,' !!!!' print errormsg quit(-1) if Nlastdims > Ndims-1: print errormsg print ' ' + fname + ': number of last dimensions ', Nlastdims,' >= than the number of dimensions of the variable ', Ndims,' !!!!' print errormsg quit(-1) if Ndims == 1: loadvar = var[:] elif Ndims == 2: loadvar = var[prevdims[0], :] elif Ndims == 3: if Nlastdims == 1: loadvar = var[prevdims[0], prevdims[1], :] else: loadvar = var[prevdims[0], :, :] elif Ndims == 4: if Nlastdims == 1: loadvar = var[prevdims[0], prevdims[1], prevdims[2], :] elif Nlastdims == 2: loadvar = var[prevdims[0], prevdims[1], :, :] else: loadvar = var[prevdims[0], :, :, :] elif Ndims == 5: if Nlastdims == 1: loadvar = var[prevdims[0], prevdims[1], prevdims[2], prevdims[3], :] elif Nlastdims == 2: loadvar = var[prevdims[0], prevdims[1], prevdims[2], :, :] elif Nlastdims == 3: loadvar = var[prevdims[0], prevdims[1], :, :, :] else: loadvar = var[prevdims[0], :, :, :, :] elif Ndims == 6: if Nlastdims == 1: loadvar = var[prevdims[0], prevdims[1], prevdims[2], prevdims[3], prevdims[4], :] elif Nlastdims == 2: loadvar = var[prevdims[0], prevdims[1], prevdims[2], prevdims[3], :, :] elif Nlastdims == 3: loadvar = var[prevdims[0], prevdims[1], prevdims[2], :, :, :] elif Nlastdims == 4: loadvar = var[prevdims[0], prevdims[1], :, :, :, :] else: loadvar = var[prevdims[0], :, :, :, :] else: print errormsg print ' ' + fname + ' variable size ', Ndims, ' not ready!!!' print errormsg quit(-1) return loadvar def indices_mask(mask): """ Function to retrieve the indices from a 2D mask mask= 2D mask matrix mat=np.array(range(100), dtype=float).reshape((10,10)) >>> mask1= mat >= 45. >>> mask2= mat <= 55. >>> mask = mask1 * mask2 indices_mask(mask) [[4 5] [4 6] [4 7] [4 8] [4 9] [5 0] [5 1] [5 2] [5 3] [5 4] [5 5]] """ dy=mask.shape[0] dx=mask.shape[1] Nptmask = np.sum(mask) maskindices = np.zeros((Nptmask,2), dtype=int) ij=0 for j in range(dy): for i in range(dx): if mask[j,i] == True: maskindices[ij,0] = j maskindices[ij,1] = i ij = ij + 1 return maskindices def typemod(value, typeval): """ Function to give back a value in a given dtype >>> print(typemod(8.2223, 'np.float64')) >>> print(typemod(8.2223, 'tuple')) """ fname='typemod' if typeval == 'int': return int(value) elif typeval == 'long': return long(value) elif typeval == 'float': return float(value) elif typeval == 'complex': return complex(value) elif typeval == 'str' or typeval == 'S': return str(value) elif typeval == 'bool': return bool(value) elif typeval == 'list': newval = [] newval.append(value) return newval elif typeval == 'dic': newval = {} newval[value] = value return newval elif typeval == 'tuple': newv = [] newv.append(value) newval = tuple(newv) return newval elif typeval == 'np.int8': return np.int8(value) elif typeval == 'np.int16': return np.int16(value) elif typeval == 'np.int32': return np.int32(value) elif typeval == 'np.int64': return np.int64(value) elif typeval == 'np.uint8': return np.uint8(value) elif typeval == 'np.uint16': return np.uint16(value) elif typeval == 'np.np.uint32': return np.uint32(value) elif typeval == 'np.uint64': return np.uint64(value) elif typeval == 'np.float' or typeval == 'R': return np.float(value) elif typeval == 'np.float16': return np.float16(value) elif typeval == 'np.float32': return np.float32(value) elif typeval == 'float32': return np.float32(value) elif typeval == 'np.float64': return np.float64(value) elif typeval == 'float64': return np.float64(value) elif typeval == 'np.complex': return np.complex(value) elif typeval == 'np.complex64': return np.complex64(value) elif typeval == 'np.complex128': return np.complex128(value) else: print errormsg print fname + ': data type "' + typeval + '" is not ready !' print errormsg quit(-1) return def diffdate_units(diffdate, units): """ Function to transform a difference of dates to a certain units diffdate = difference of dates (as timedelta) units = units to transform: 'weeks', 'days', 'hours', 'minutes', 'seconds', 'miliseconds', 'nanoseconds' >>> diffdate_units(dt.datetime(1976, 2, 17, 8, 32, 5) - dt.datetime(1949, 12, 1, 0, 0, 0), 'seconds') 827224325.0 """ fname = 'diffdate_units' if units == 'weeks': diffunits = diffdate.days/7. + diffdate.seconds/(3600.*24.*7.) elif units == 'days': diffunits = diffdate.days + diffdate.seconds/(3600.*24.) elif units == 'hours': diffunits = diffdate.days*24. + diffdate.seconds/(3600.) elif units == 'minutes': diffunits = diffdate.days*24.*60. + diffdate.seconds/(60.) elif units == 'seconds': diffunits = diffdate.days*24.*3600. + diffdate.seconds elif units == 'miliseconds': diffunits = diffdate.days*24.*3600.*1000. + diffdate.seconds*1000. elif units == 'nanoseconds': diffunits = diffdate.days*24.*3600.*1000000. + diffdate.seconds*1000000. else: print errormsg print fname + ': time units "' + units + '" not ready!!!' print errormsg quit(-1) return diffunits def days_month(year,month): """ Function to give the number of days of a month of a given year >>> days_month(1976,2) 29 """ import datetime as dt date1=dt.date(year,month,1) date2=dt.date(year,month+1,1) diffdate = date2-date1 return diffdate.days def mid_period(yr1,mon1,day1,hour1,min1,sec1,yr2,mon2,day2,hour2,min2,sec2): """ Function to give the mid poiint of a period >>> mid_period(1976,2,1,0,0,0,1976,3,1,0,0,0) [1976 2 15 12 0 0] """ import datetime as dt date1=dt.datetime(yr1,mon1,day1,hour1,min1,sec1) date2=dt.datetime(yr2,mon2,day2,hour2,min2,sec2) diffdate = date2-date1 diffseconds = diffdate.days*24*3600 + diffdate.seconds diff2 = dt.timedelta(seconds=diffseconds/2) datenew = date1 + diff2 datenewvals = np.array([datenew.year, datenew.month, datenew.day, datenew.hour, \ datenew.minute, datenew.second]) return datenewvals def days_year(year): """ Function to give the number of days of a year >>> days_year(1976) 366 """ import datetime as dt date1=dt.date(year,1,1) date2=dt.date(year+1,1,1) diffdate = date2-date1 return diffdate.days def days_period(yeari,yearf): """ Function to give the number of days for a period >>> days_period(1976,1980) 1827 """ ndays=0 for iyr in range(yearf-yeari+1): ndays=ndays+days_year(yeari+iyr) return ndays class ysubsetstats(object): """ Class to compute multi-year statistics of a given subset of values values= values to use dates=dates of the values in matrix format ([year], [month], [day], [hour], [minute], [second]) sec=section to use for the period='year', 'month', 'day', 'hour', 'minute', 'second' vali=initial value of the period valf=final value of the period Nq= number of quantiles (20 for 5% bins, it is going to produce 21 values) missval= missing value self.Nvalues = Number of non masked values self.min = minimum non masked value self.max = maximum non masked value self.mean = mean non masked value self.mean2 = quandratic mean non masked value self.stdev = standard deviation non masked value self.quantiles = quantiles non masked value """ def __init__(self, values, dates, sec, vali, valf, Nq, missVal): import numpy.ma as ma fname = 'ysubsetstats' if values is None: self.Nvalues = None self.min = None self.max = None self.mean = None self.mean2 = None self.stdev = None self.quantiles = None else: Nvalues = len(values) Ndates = len(dates) if Nvalues != Ndates: print errormsg print fname + ': number of values ', Nvalues,' does not coincide with the number of dates ',Ndates, '!!!!!!' print errormsg quit(-1) initialsub = np.zeros(Nvalues, dtype=bool) endsub = initialsub.copy() if missVal > 0.: valuesmask = ma.masked_greater_equal(values, missVal*0.9) else: valuesmask = ma.masked_less_equal(values, missVal*0.9) if sec == 'year': isec = 0 elif sec == 'month': isec = 1 elif sec == 'day': isec = 2 elif sec == 'hour': isec = 3 elif sec == 'minute': isec = 4 elif sec == 'second': isec = 5 else: print errormsg print fname + ': sction "' + sec + '" not ready!!!!' print errormsg quit(-1) if vali < valf: timesmaskperi = ma.masked_less(dates[:,isec], vali) timesmaskperf = ma.masked_greater(dates[:,isec], valf) else: timesmaskperi = ma.masked_less(dates[:,isec], valf) timesmaskperf = ma.masked_greater(dates[:,isec], vali) finalmask = valuesmask.mask+timesmaskperi.mask+timesmaskperf.mask finalvalues = ma.array(values, mask=finalmask) finalvalues2 = finalvalues*finalvalues self.Nvalues = finalvalues.count() self.min = finalvalues.min() self.max = finalvalues.max() self.mean = finalvalues.mean() self.mean2 = finalvalues2.mean() self.stdev = finalvalues.std() self.quantiles = mask_quantiles(finalvalues, Nq) return def give_fix1dim_values(mat,iddim,dimval): """ Function to return matrix values when one dimension has been removed at a given value mat = matrix iddim = dimesion to remove (starting from 0 tacking the right most) dimval = value of the dimension >>> matrix = np.array( (range(27)), dtype=np.float).reshape(3,3,3) give_fix1dim_values(matrix,2,2) [[[ 0. 1. 2.] [ 3. 4. 5.] [ 6. 7. 8.]] [[ 9. 10. 11.] [ 12. 13. 14.] [ 15. 16. 17.]]] """ fname='give_fix1dim_values' # Not working ma.squeeze ## import numpy.ma as ma ## print ma.squeeze(mat, axis = (idim,)) matshape = mat.shape mattype = mat.dtype matmask = np.ones( tuple(matshape), dtype=bool) zerodims=np.ones( (6), dtype=int) Ndims = len(matshape) if Ndims > 6: print errmsg print ' ' + fname + ' number of dimensions: ',Ndims,' not ready!!!!!' quit(-1) zerodims[5-Ndims+1:6] = matshape newdims = list(matshape) newdims[Ndims-1-iddim] = matshape[iddim]-1 mask = np.ones(tuple(zerodims), dtype=bool) vals = np.zeros(tuple(zerodims), dtype=mattype) vals[0:zerodims[0],0:zerodims[1],0:zerodims[2],0:zerodims[3],0:zerodims[4], 0:zerodims[5]] = mat for i5 in range(zerodims[5]): for i4 in range(zerodims[4]): for i3 in range(zerodims[3]): for i2 in range(zerodims[2]): for i1 in range(zerodims[1]): for i0 in range(zerodims[0]): # print 'iddim:',iddim,'dimval:',dimval,'-->',i0,i1,i2,i3,i4,i5 if iddim == 5 and dimval == i0: mask[i0,i1,i2,i3,i4,i5] = False elif iddim == 4 and dimval == i1: mask[i0,i1,i2,i3,i4,i5] = False elif iddim == 3 and dimval == i2: mask[i0,i1,i2,i3,i4,i5] = False elif iddim == 2 and dimval == i3: mask[i0,i1,i2,i3,i4,i5] = False elif iddim == 1 and dimval == i4: mask[i0,i1,i2,i3,i4,i5] = False elif iddim == 0 and dimval == i5: mask[i0,i1,i2,i3,i4,i5] = False newmat = vals[mask].reshape(tuple(newdims)) # print 'newmat dim:',iddim,'val:',dimval,':',newdims,'______' # print newmat return newmat def portion_fix1dim_values(mat,iddim,dimval): """ Function to return that portion of the matrix values when one dimension has been removed at a given value mat = matrix iddim = dimesion to remove (starting from 0 tacking the right most) dimval = value of the dimension >>> matrix = np.array( (range(27)), dtype=np.float).reshape(3,3,3) portion_fix1dim_values(matrix,2,2) [[ 18. 19. 20.] [ 21. 22. 23.] [ 24. 25. 26.]] """ fname='portion_fix1dim_values' # Not working ma.squeeze ## import numpy.ma as ma ## print ma.squeeze(mat, axis = (idim,)) matshape = mat.shape mattype = mat.dtype matmask = np.zeros( tuple(matshape), dtype=bool) zerodims=np.ones( (6), dtype=int) Ndims = len(matshape) if Ndims > 6: print errmsg print ' ' + fname + ' number of dimensions: ',Ndims,' not ready!!!!!' quit(-1) zerodims[5-Ndims+1:6] = matshape newdims = [] for idim in range(Ndims): if idim != iddim: newdims.append(matshape[idim]) newdims.reverse() mask = np.zeros(tuple(zerodims), dtype=bool) vals = np.zeros(tuple(zerodims), dtype=mattype) vals[0:zerodims[0],0:zerodims[1],0:zerodims[2],0:zerodims[3],0:zerodims[4], 0:zerodims[5]] = mat for i5 in range(zerodims[5]): for i4 in range(zerodims[4]): for i3 in range(zerodims[3]): for i2 in range(zerodims[2]): for i1 in range(zerodims[1]): for i0 in range(zerodims[0]): # print 'iddim:',iddim,'dimval:',dimval,'-->',i0,i1,i2,i3,i4,i5 if iddim == 5 and dimval == i0: mask[i0,i1,i2,i3,i4,i5] = True elif iddim == 4 and dimval == i1: mask[i0,i1,i2,i3,i4,i5] = True elif iddim == 3 and dimval == i2: mask[i0,i1,i2,i3,i4,i5] = True elif iddim == 2 and dimval == i3: mask[i0,i1,i2,i3,i4,i5] = True elif iddim == 1 and dimval == i4: mask[i0,i1,i2,i3,i4,i5] = True elif iddim == 0 and dimval == i5: mask[i0,i1,i2,i3,i4,i5] = True # print 'newmat dim:',iddim,'val:',dimval,':',newdims,'______' newmat = vals[mask].reshape(tuple(newdims)) # print newmat return newmat def retype(val, vtype): """ Function to transform a value to a given type retype(val, vtype) [val]= value [vtype]= type to transform >>> retype(0, type(True)) False """ fname = 'retype' if val == 'h': print fname + '_____________________________________________________________' print retype.__doc__ quit() if vtype == type(int(1)): newval = int(val) elif vtype == type(float(1)): newval = float(val) # elif vtype == type(float32(1)): # newval = float32(val) elif vtype == type(np.int(1)): typeinf = np.iinfo(np.int) if (abs(np.float64(val)) > typeinf.max): print warnmsg print ' ' + fname + ': value to transform ', val,' overpasses type:', \ vtype,' limits!!' print ' Changing value to kind largest allowed value:', typeinf.max newval = abs(np.float64(val))/np.float64(val) * np.int(typeinf.max) else: newval = np.int(val) elif vtype == type(np.int16(1)): typeinf = np.iinfo(np.int16) if (abs(np.float64(val)) > typeinf.max): print warnmsg print ' ' + fname + ': value to transform ', val,' overpasses type:', \ vtype,' limits!!' print ' Changing value to kind largest allowed value:', typeinf.max newval = abs(np.float64(val))/np.float64(val) * np.int16(typeinf.max) else: newval = np.int16(val) elif vtype == type(np.int32(1)): typeinf = np.iinfo(np.int32) if (np.abs(np.float64(val)) > typeinf.max): print warnmsg print ' ' + fname + ': value to transform ', val,' overpasses type:', \ vtype,' limits!!' print ' Changing value to kind largest allowed value:', typeinf.max newval = abs(np.float64(val))/np.float64(val) * np.int32(typeinf.max) else: newval = np.int32(np.float64(val)) elif vtype == type(np.int64(1)): newval = np.int64(val) elif vtype == type(np.float(1)): newval = np.float(val) # elif vtype == type(np.float16(1)): # newval = np.float16(val) elif vtype == type(np.float32(1)): newval = np.float32(val) elif vtype == type(np.float64(1)): newval = np.float64(val) elif vtype == type(True): if val == 0: newval = False else: newval = True elif vtype == '|S1': newval = str(val) else: print errormsg print ' ' + fname + ': variable type "', vtype, '" not ready!!!' quit(-1) return newval class stats_space2D(object): """spatial statistics for a 2D file: vals= variable ro check (assuming var[t,dy,dx]) self.minv[t]: spatial minimum at each time-step self.maxv[t]: spatial maximum at each time-step self.meanv[t]: spatial mean at each time-step self.mean2v[t]: spatial quadratic mean at each time-step self.stdv[t]: spatial standard deviation at each time-step self.anomv[t]: spatial anomaly from the whole mean at each time-step """ def __init__(self, vals): from scipy import stats as sts fname = 'stats_space2D' if vals1 == 'h': print fname + '_____________________________________________________________' print stats_space2Dvars.__doc__ quit() if vals1 is None: self.minv = None self.maxv = None self.meanv = None self.mean2v = None self.stdv = None else: dimt = vals.shape[0] stats=np.zeros((dimt,5), dtype=np.float) absmean = np.mean(vals) for it in range(dimt): stats[it,0]=np.min(vals[it,:,:]) stats[it,1]=np.max(vals[it,:,:]) stats[it,2]=np.mean(vals[it,:,:]) stats[it,3]=np.mean(vals[it,:,:]*vals[it,:,:]) stats[it,4]=absmean - stats[it,2] stats = np.where(stats > 0.1*fillValue, fillValue, stats) stats = np.where(stats is nan, fillValue, stats) stats = np.where(stats is np.inf, fillValue, stats) stats = np.where(stats is None, fillValue, stats) self.minv=stats[:,0] self.maxv=stats[:,1] self.meanv=stats[:,2] self.mean2v=stats[:,3] self.stdv=np.sqrt(stats[:,3]-stats[:,2]*stats[:,2]) self.anomv=stats[:,4] return class stats_space2Dvars(object): """spatial statistics beween 2 2D files: valsA = variable 1 (assuming var[t,dy,dx]) valsB = variable 2 (assuming var[t,dy,dx]) self.min[t,var], self.max[t,var], self.mean[t,var], self.mean2[t,var], self.std[t,var] [var] = var1+var2[v1Av2], var1-var2[v1Sv2], var1/var2[v1Dv2], var1*var2[v1Pv2] self.mae=mean[t,abs(var1-var2)] self.correlation=correlation[var1,var2] (and p-value) self.bias=[t,mean(var1)-mean(var2)] self.meancorrelation=correlation[mean(var1),mean(var2)] (and p-value) """ def __init__(self, vals1, vals2): from scipy import stats as sts fname = 'stats_space2Dvars' if vals1 == 'h': print fname + '_____________________________________________________________' print stats_space2Dvars.__doc__ quit() if vals1 is None: self.minv1Av2 = None self.maxv1Av2 = None self.meanv1Av2 = None self.mean2v1Av2 = None self.stdv1Av2 = None self.minv1Sv2 = None self.maxv1Sv2 = None self.meanv1Sv2 = None self.mean2v1Sv2 = None self.stdv1Sv2 = None self.minv1Dv2 = None self.maxv1Dv2 = None self.meanv1Dv2 = None self.mean2v1Dv2 = None self.stdv1Dv2 = None self.minv1Pv2 = None self.maxv1Pv2 = None self.meanv1Pv2 = None self.mean2v1Pv2 = None self.stdv1Pv2 = None self.mae = None self.corr = None else: dimt = vals1.shape[0] stats=np.zeros((dimt,26), dtype=np.float) meanvals1 = np.zeros((dimt), dtype=np.float) meanvals2 = np.zeros((dimt), dtype=np.float) for it in range(dimt): v1 = vals1[it,:,:].flatten() v2 = vals2[it,:,:].flatten() # add vs = v1 + v2 stats[it,0] = np.min(vs) stats[it,1] = np.max(vs) stats[it,2] = np.mean(vs) stats[it,3] = np.mean(vs*vs) stats[it,4] = np.sqrt(stats[it,3] - stats[it,2]*stats[it,2]) # sub stats[it,20] = np.mean(np.abs(v1-v2)) vs = v1 - v2 stats[it,5] = np.min(vs) stats[it,6] = np.max(vs) stats[it,7] = np.mean(vs) stats[it,8] = np.mean(vs*vs) stats[it,9] = np.sqrt(stats[it,8] - stats[it,7]*stats[it,7]) # mul vs = v1 * v2 stats[it,10] = np.min(vs) stats[it,11] = np.max(vs) stats[it,12] = np.mean(vs) stats[it,13] = np.mean(vs*vs) stats[it,14] = np.sqrt(stats[it,13] - stats[it,12]*stats[it,12]) # div vs = v1 / v2 stats[it,15] = np.min(vs) stats[it,16] = np.max(vs) stats[it,17] = np.mean(vs) stats[it,18] = np.mean(vs*vs) stats[it,19] = np.sqrt(stats[it,18] - stats[it,17]*stats[it,17]) # corr stats[it,21], stats[it,22] = mask_pearsonr(v1, v2) # Mean values meanvals1[it] = np.mean(v1) meanvals2[it] = np.mean(v2) stats[it,23] = meanvals1[it] - meanvals2[it] stats = np.where(stats > 0.1*fillValue, fillValue, stats) stats = np.where(stats is np.nan, fillValue, stats) stats = np.where(stats is np.inf, fillValue, stats) stats = np.where(stats is None, fillValue, stats) self.minv1Av2 = stats[:,0] self.maxv1Av2 = stats[:,1] self.meanv1Av2 = stats[:,2] self.meanv21Av2 = stats[:,3] self.stdv1Av2 = stats[:,4] self.minv1Sv2 = stats[:,5] self.maxv1Sv2 = stats[:,6] self.meanv1Sv2 = stats[:,7] self.meanv21Sv2 = stats[:,8] self.stdv1Sv2 = stats[:,9] self.minv1Pv2 = stats[:,10] self.maxv1Pv2 = stats[:,11] self.meanv1Pv2 = stats[:,12] self.meanv21Pv2 = stats[:,13] self.stdv1Pv2 = stats[:,14] self.minv1Dv2 = stats[:,15] self.maxv1Dv2 = stats[:,16] self.meanv1Dv2 = stats[:,17] self.meanv21Dv2 = stats[:,18] self.stdv1Dv2 = stats[:,19] self.mae = stats[:,20] self.corr = stats[:,21] self.p_value = stats[:,22] self.bias = stats[:,23] self.meancorr, self.meanp_value = sts.pearsonr(meanvals1, meanvals2) return class stats_time2D(object): """temporal statistics for a 2D file: vals= variable ro check (assuming var[t,dy,dx]) self.minv[t]: temporal minimum at each grid point self.maxv[t]: temporal maximum at each grid point self.meanv[t]: temporal mean at each grid point self.mean2v[t]: temporal quadratic mean at each grid point self.stdv[t]: temporal standard deviation at each grid point self.anomv[t]: temporal anomaly from the whole mean at each grid point """ def __init__(self, vals): from scipy import stats as sts fname = 'stats_time2D' if vals1 == 'h': print fname + '_____________________________________________________________' print stats_time2Dvars.__doc__ quit() if vals1 is None: self.minv = None self.maxv = None self.meanv = None self.mean2v = None self.stdv = None else: dimx = vals.shape[2] dimy = vals.shape[1] stats=np.zeros((dimy,dimx,5), dtype=np.float) absmean = np.mean(vals,axis=0) stats[:,:,0]=np.min(vals, axis=0) stats[:,:,1]=np.max(vals, axis=0) stats[:,:,2]=np.mean(vals, axis=0) stats[:,:,3]=np.mean(vals*vals, axis=0) stats[:,:,4]=absmean - stats[:,:,2] stats = np.where(stats > 0.1*fillValue, fillValue, stats) stats = np.where(stats is np.nan, fillValue, stats) stats = np.where(stats is np.inf, fillValue, stats) stats = np.where(stats is None, fillValue, stats) self.minv=stats[:,:,0] self.maxv=stats[:,:,1] self.meanv=stats[:,:,2] self.mean2v=stats[:,:,3] self.stdv=np.sqrt(stats[:,:,3]-stats[:,:,2]*stats[:,:,2]) self.anomv=stats[:,:,4] return class stats_time2Dvars(object): """temporal statistics beween 2 2D files: valsA = variable 1 (assuming var[t,dy,dx]) valsB = variable 2 (assuming var[t,dy,dx]) self.min[dy,dx,var], self.max[dy,dx,var], self.mean[dy,dx,var], self.mean2[dy,dx,var], self.std[dy,dx,var] [var] = var1+var2[v1Av2], var1-var2[v1Sv2], var1/var2[v1Dv2], var1*var2[v1Pv2] self.mae=mean[dy,dx,abs(var1-var2)] self.correlation=correlation[var1,var2] (and p-value) self.bias=[dy,dx,mean(var1)-mean(var2)] self.meancorrelation=correlation[mean(var1),mean(var2)] (and p-value) """ def __init__(self, vals1, vals2): from scipy import stats as sts fname = 'stats_time2Dvars' if vals1 == 'h': print fname + '_____________________________________________________________' print stats_time2Dvars.__doc__ quit() if vals1 is None: self.minv1Av2 = None self.maxv1Av2 = None self.meanv1Av2 = None self.mean2v1Av2 = None self.stdv1Av2 = None self.minv1Sv2 = None self.maxv1Sv2 = None self.meanv1Sv2 = None self.mean2v1Sv2 = None self.stdv1Sv2 = None self.minv1Dv2 = None self.maxv1Dv2 = None self.meanv1Dv2 = None self.mean2v1Dv2 = None self.stdv1Dv2 = None self.minv1Pv2 = None self.maxv1Pv2 = None self.meanv1Pv2 = None self.mean2v1Pv2 = None self.stdv1Pv2 = None self.mae = None self.corr = None else: dimx = vals1.shape[1] dimy = vals1.shape[1] stats=np.zeros((dimy,dimx,24), dtype=np.float) meanvals1 = np.zeros((dimy,dimx), dtype=np.float) meanvals2 = np.zeros((dimy,dimx), dtype=np.float) # add vs = vals1 + vals2 stats[:,:,0] = np.min(vs,axis=0) stats[:,:,1] = np.max(vs,axis=0) stats[:,:,2] = np.mean(vs,axis=0) stats[:,:,3] = np.mean(vs*vs,axis=0) stats[:,:,4] = np.sqrt(stats[:,:,3] - stats[:,:,2]*stats[:,:,2]) # sub stats[:,:,20] = np.mean(np.abs(vals1-vals2), axis=0) vs = vals1 - vals2 stats[:,:,5] = np.min(vs,axis=0) stats[:,:,6] = np.max(vs,axis=0) stats[:,:,7] = np.mean(vs,axis=0) stats[:,:,8] = np.mean(vs*vs,axis=0) stats[:,:,9] = np.sqrt(stats[:,:,8] - stats[:,:,7]*stats[:,:,7]) # mul vs = vals1 * vals2 stats[:,:,10] = np.min(vs,axis=0) stats[:,:,11] = np.max(vs,axis=0) stats[:,:,12] = np.mean(vs,axis=0) stats[:,:,13] = np.mean(vs*vs,axis=0) stats[:,:,14] = np.sqrt(stats[:,:,13] - stats[:,:,12]*stats[:,:,12]) # div vs = vals1 / vals2 stats[:,:,15] = np.min(vs,axis=0) stats[:,:,16] = np.max(vs,axis=0) stats[:,:,17] = np.mean(vs,axis=0) stats[:,:,18] = np.mean(vs*vs,axis=0) stats[:,:,19] = np.sqrt(stats[:,:,18] - stats[:,:,17]*stats[:,:,17]) # Mean values meanvals1[:,:] = np.mean(vals1,axis=0) meanvals2[:,:] = np.mean(vals2,axis=0) stats[:,:,23] = meanvals1[:,:] - meanvals2[:,:] # corr self.meancorr, self.meanp_value = sts.pearsonr(meanvals1.flatten(), meanvals2.flatten()) for j in range(dimy): for i in range(dimx): stats[j,i,21], stats[j,i,22] = sts.pearsonr(vals1[:,j,i], vals2[:,j,i]) stats = np.where(stats > 0.1*fillValue, fillValue, stats) stats = np.where(stats is np.nan, fillValue, stats) stats = np.where(stats is np.inf, fillValue, stats) stats = np.where(stats is None, fillValue, stats) self.minv1Av2 = stats[:,:,0] self.maxv1Av2 = stats[:,:,1] self.meanv1Av2 = stats[:,:,2] self.meanv21Av2 = stats[:,:,3] self.stdv1Av2 = stats[:,:,4] self.minv1Sv2 = stats[:,:,5] self.maxv1Sv2 = stats[:,:,6] self.meanv1Sv2 = stats[:,:,7] self.meanv21Sv2 = stats[:,:,8] self.stdv1Sv2 = stats[:,:,9] self.minv1Pv2 = stats[:,:,10] self.maxv1Pv2 = stats[:,:,11] self.meanv1Pv2 = stats[:,:,12] self.meanv21Pv2 = stats[:,:,13] self.stdv1Pv2 = stats[:,:,14] self.minv1Dv2 = stats[:,:,15] self.maxv1Dv2 = stats[:,:,16] self.meanv1Dv2 = stats[:,:,17] self.meanv21Dv2 = stats[:,:,18] self.stdv1Dv2 = stats[:,:,19] self.mae = stats[:,:,20] self.corr = stats[:,:,21] self.p_value = stats[:,:,22] self.bias = stats[:,:,23] return #vals1 = np.arange(27).reshape(3,3,3)*1. #vals2 = np.arange(1,28).reshape(3,3,3)*1. #printing_class(stats_time2Dvars(vals1,vals2)) def file_nlines(filen,char): """ Function to provide the number of lines of a file filen= name of the file char= character as no line >>> file_nlines('trajectory.dat','#') 49 """ fname = 'file_nlines' if not os.path.isfile(filen): print errormsg print ' ' + fname + ' file: "' + filen + '" does not exist !!' quit(-1) fo = open(filen,'r') nlines=0 for line in fo: if line[0:1] != char: nlines = nlines + 1 fo.close() return nlines def table_tex(tablevals, colnames, rownames, of): """ Function to write into a LaTeX tabular from a table of values tablevals = (ncol nrow) of values colnames = list with ncol labels for the columns (1 more than data for the row names) rownames = list with nrow labels for the rows of= object ASCII file to write the table """ errormsg = 'ERROR -- error -- ERROR -- error' fname = 'table_tex' Ncol = tablevals.shape[0] Nrow = tablevals.shape[1] if Ncol + 1 != len(colnames): print errormsg print ' ' + fname + ': wrong number of column names!!' print ' data has:', Ncol, 'and you provided:', len(colnames) print ' remember to provide one more for the label of the rows!' print ' you provide:',colnames quit(-1) if Nrow != len(rownames): print errormsg print ' ' + fname + ': wrong number of row names!!' print ' data has:', Nrow, 'and you provided:', len(rownames) print ' you provide:',rownames quit(-1) colcs = '' colns = '' for icol in colnames: colcs = colcs + 'c' if icol == colnames[0]: colns = ' {\\bfseries{' + icol + '}}' else: colns = colns + ' & {\\bfseries{' + icol + '}}' of.write('\n') of.write("%Automatically written file from function '" + fname + "'\n") of.write('\\begin{tabular}{l'+colcs+'}\n') of.write(colns + ' \\\\ \\hline\n') ir = 0 for irow in rownames: rowns = '{\\bfseries{' + irow + '}}' for ic in range(Ncol): rowns = rowns + ' & ' + str(tablevals[ic,ir]) rowns = rowns + ' \\\\' of.write(rowns + '\n') ir = ir + 1 of.write('\\end{tabular}\n') return def table_tex_file(Ncol, Nrow, tablevals, colnames, rownames, ofile): """ Function to write into a file a LaTeX tabular from a table of values tablevals = (ncol nrow) of values colnames = list with ncol labels for the columns (1 more than data for the row names) rownames = list with nrow labels for the rows ofile= ASCII file to write the table >>> values = np.arange(15).reshape(5,3) >>> colns = ['a','b','c','d','e'] >>> rowns = ['i','ii','iii'] >>> table_text_file(5, 3, values, colns, rowns, 'table.tex') """ fname = 'table_tex_file' objf = open(ofile, 'w') objf.write('\\documentclass{article}\n') objf.write('\n') objf.write('\\begin{document}\n') table_tex(tablevals, colnames, rownames, objf) objf.write('\\end{document}\n') objf.close() print fname + "': successfull written of '" + ofile + "' !!" return def radius_dist(dx,dy,ptx,pty): """ Function to generate a matrix with the distance at a given point radius_dist(dx,dy,ptx,pty) [dx/y]: dimension of the matrix [ptx/y]: grid point coordinates of the point >>> radius_dist(5,4,2,2) [[ 2.82842712 2.23606798 2. 2.23606798 2.82842712] [ 2.23606798 1.41421356 1. 1.41421356 2.23606798] [ 2. 1. 0. 1. 2. ] [ 2.23606798 1.41421356 1. 1.41421356 2.23606798]] """ fname = 'radius_dist' if ptx < 0 or ptx > dx-1 or pty < 0 or pty > dy-1: print errormsg print ' ' + fname + ': wrong point coordinates:',dx,',',dy,'for matrix;',dx \ ,'x',dy quit(-1) xdist = np.zeros((dy,dx), dtype=np.float) ydist = np.zeros((dy,dx), dtype=np.float) dist = np.zeros((dy,dx), dtype=np.float) for ix in range(dx): xdist[:,ix] = np.float(ix-ptx) for iy in range(dy): ydist[iy,:] = np.float(pty-iy) dist = np.sqrt(xdist*xdist + ydist*ydist) return dist def radius_angle(dx,dy,ptx,pty): """ Function to generate a matrix with the angle at a given point radius_angle(dx,dy,ptx,pty) [dx/y]: dimension of the matrix [ptx/y]: grid point coordinates of the point >>> radius_angle(5,4,2,2)*180./np.pi [[ 315. 333.43494882 0. 26.56505118 45. ] [ 296.56505118 315. 0. 45. 63.43494882] [ 270. 270. 0. 90. 90. ] [ 243.43494882 225. 180. 135. 116.56505118]] """ fname = 'radius_angle' if ptx < 0 or ptx > dx-1 or pty < 0 or pty > dy-1: print errormsg print ' ' + fname + ': wrong point coordinates:',dx,',',dy,'for matrix;',dx \ ,'x',dy quit(-1) xdist = np.zeros((dy,dx), dtype=np.float) ydist = np.zeros((dy,dx), dtype=np.float) angle = np.zeros((dy,dx), dtype=np.float) for ix in range(dx): xdist[:,ix] = np.float(ix-ptx) for iy in range(dy): ydist[iy,:] = np.float(pty-iy) angle = np.arctan2(xdist,ydist) angle = np.where(angle < 0., angle + 2*np.pi, angle) return angle def lonlat2D(lon,lat): """ Function to return lon, lat 2D matrices from any lon,lat matrix lon= matrix with longitude values lat= matrix with latitude values """ fname = 'lonlat2D' if len(lon.shape) != len(lat.shape): print errormsg print ' ' + fname + ': longitude values with shape:', lon.shape, \ 'is different than latitude values with shape:', lat.shape, '(dif. size) !!' quit(-1) if len(lon.shape) == 3: lonvv = lon[0,:,:] latvv = lat[0,:,:] elif len(lon.shape) == 2: lonvv = lon[:] latvv = lat[:] elif len(lon.shape) == 1: lonlatv = np.meshgrid(lon[:],lat[:]) lonvv = lonlatv[0] latvv = lonlatv[1] return lonvv, latvv def interpolate_locs(locs,coords,kinterp): """ Function to provide interpolate locations on a given axis interpolate_locs(locs,axis,kinterp) locs= locations to interpolate coords= axis values with the reference of coordinates kinterp: kind of interpolation 'lin': linear >>> coordinates = np.arange((10), dtype=np.float) >>> values = np.array([-1.2, 2.4, 5.6, 7.8, 12.0]) >>> interpolate_locs(values,coordinates,'lin') [ -1.2 2.4 5.6 7.8 13. ] >>> coordinates[0] = 0.5 >>> coordinates[2] = 2.5 >>> interpolate_locs(values,coordinates,'lin') [ -3.4 1.93333333 5.6 7.8 13. ] """ fname = 'interpolate_locs' if locs == 'h': print fname + '_____________________________________________________________' print interpolate_locs.__doc__ quit() Nlocs = locs.shape[0] Ncoords = coords.shape[0] dcoords = coords[Ncoords-1] - coords[0] intlocs = np.zeros((Nlocs), dtype=np.float) minc = np.min(coords) maxc = np.max(coords) for iloc in range(Nlocs): for icor in range(Ncoords-1): if locs[iloc] < minc and dcoords > 0.: a = 0. b = 1. / (coords[1] - coords[0]) c = coords[0] elif locs[iloc] > maxc and dcoords > 0.: a = (Ncoords-1)*1. b = 1. / (coords[Ncoords-1] - coords[Ncoords-2]) c = coords[Ncoords-2] elif locs[iloc] < minc and dcoords < 0.: a = (Ncoords-1)*1. b = 1. / (coords[Ncoords-1] - coords[Ncoords-2]) c = coords[Ncoords-2] elif locs[iloc] > maxc and dcoords < 0.: a = 0. b = 1. / (coords[1] - coords[0]) c = coords[0] elif locs[iloc] >= coords[icor] and locs[iloc] < coords[icor+1] and dcoords > 0.: a = icor*1. b = 1. / (coords[icor+1] - coords[icor]) c = coords[icor] print coords[icor], locs[iloc], coords[icor+1], ':', icor, '->', a, b elif locs[iloc] <= coords[icor] and locs[iloc] > coords[icor+1] and dcoords < 0.: a = icor*1. b = 1. / (coords[icor+1] - coords[icor]) c = coords[icor] if kinterp == 'lin': intlocs[iloc] = a + (locs[iloc] - c)*b else: print errormsg print ' ' + fname + ": interpolation kind '" + kinterp + "' not ready !!!!!" quit(-1) return intlocs def vertical_interpolation2D(varb,vart,zorigvals,znewval,kinterp): """ Function to vertically integrate a 3D variable vertical_interpolation2D(varb,vart,zorigvals,znewval) varb= values at the base of the interval of interpolation (2D field) vart= values at the top of the interval of interpolation (2D field) zorigvals= pair of original values (2, 2D field) znewval= new value to interpolate Possible cases: zorigvals[0,:,:] <= znewval < zorigvals[1,:,:] znewval <= zorigvals[0,:,:] < zorigvals[1,:,:] zorigvals[0,:,:] < zorigvals[1,:,:] <= znewval kinterp: kind of interpolation 'lin': linear >>> dx=5 >>> dy=7 >>> vals1 = np.ones((dy,dx), dtype=np.float) >>> vals2 = np.ones((dy,dx), dtype=np.float)*2. >>> zbase = np.zeros((2,dy,dx), dtype=np.float) >>> zbase[0,:,:] = 0.5 >>> zbase[1,:,:] = 1. >>> vertical_interpolation2D(vals1,vals2, zbase, newz,'lin') [[ 1.5 1.5 1.5 1.5 1.5] [ 1.5 1.5 1.5 1.5 1.5] [ 1.5 1.5 1.5 1.5 1.5] [ 1.5 1.5 1.5 1.5 1.5] [ 1.5 1.5 1.5 1.5 1.5] [ 1.5 1.5 1.5 1.5 1.5] [ 1.5 1.5 1.5 1.5 1.5]] """ fname = 'vertical_interpolation2D' if varb == 'h': print fname + '_____________________________________________________________' print vertical_interpolation2D.__doc__ quit() newvar = np.zeros((varb.shape), dtype=np.float) if kinterp == 'lin': ## print ' ' + fname + ' Vertical linear interpolation at',znewval # Standard linear interpolation (y = a + b*incz) # a = zorig[0], b = (vart-varb)/(zorig[1]-zorig[0])), incz = znewval - zorig[0] a = varb b = np.where(zorigvals[1,:,:] == zorigvals[0,:,:], 0., \ (vart - varb)/(zorigvals[1,:,:] - zorigvals[0,:,:])) incz = np.ones((varb.shape), dtype=np.float)*znewval - zorigvals[0,:,:] newvar = a + b*incz # Too code for not be used... but maybe? # dx=varb.shape[1] # dy=varb.shape[0] # for j in range(dy): # for i in range(dx): # if zorigvals[1,j,i] == zorigvals[0,j,i]: print 'equals!', \ # zorigvals[1,j,i], zorigvals[0,j,i],':',newvar[j,i],'@',vart[j,i] # if zorigvals[0,j,i] != zorigvals[0,j,i]: print '0 Nan', \ # zorigvals[0,j,i],':',newvar[j,i],'@',vart[j,i] # if zorigvals[1,j,i] != zorigvals[1,j,i]: print '1 Nan', \ # zorigvals[1,j,i],':',newvar[j,i],'@',vart[j,i] # if zorigvals[0,j,i] is None: print '0 None', zorigvals[0,j,i],':', \ # newvar[j,i],'@',vart[j,i] # if zorigvals[1,j,i] is None: print '1 None', zorigvals[1,j,i],':', \ # newvar[j,i],'@',vart[j,i] else: print errormsg print ' ' + fname + ": interpolation kind '" + kinterp + "' not ready !!!!!" quit(-1) return newvar #dx=5 #dy=7 #vals1 = np.ones((dy,dx), dtype=np.float) #vals2 = np.ones((dy,dx), dtype=np.float)*2. #zbase = np.zeros((2,dy,dx), dtype=np.float) #zbase[0,:,:] = 0.5 #for i in range(dx): # for j in range(dy): # zbase[1,j,i] = np.sqrt((j-dy/2.)**2. + (i-dx/2.)**2.) / \ # np.sqrt((dy/2.)**2.+(dy/2.)**2.) + 1. #zbase[1,:,:] = 1. #newz = 0.75 #print vertical_interpolation2D(vals1,vals2, zbase, newz,'lin') def vertical_interpolation(varb,vart,zorigvals,znewval,kinterp): """ Function to vertically integrate a 1D variable vertical_interpolation(varb,vart,zorigvals,znewval) varb= values at the base of the interval of interpolation vart= values at the top of the interval of interpolation zorigvals= pair of original values (2) znewval= new value to interpolate Possible cases: zorigvals[0,:] <= znewval < zorigvals[1,:] znewval <= zorigvals[0,:] < zorigvals[1,:] zorigvals[0,:] < zorigvals[1,:] <= znewval kinterp: kind of interpolation 'lin': linear >>> dx=5 >>> vals1 = np.ones((dx), dtype=np.float) >>> vals2 = np.ones((dx), dtype=np.float)*2. >>> zbase = np.zeros((2,dx), dtype=np.float) >>> zbase[0,:] = 0.5 >>> for i in range(dx): >>> zbase[1,i] = i + 1. >>> newz = 0.75 >>> vertical_interpolation2D(vals1,vals2, zbase, newz,'lin') [ 1.5 1.16666667 1.1 1.07142857 1.05555556] """ fname = 'vertical_interpolation' if varb == 'h': print fname + '_____________________________________________________________' print vertical_interpolation.__doc__ quit() newvar = np.zeros((varb.shape), dtype=np.float) if kinterp == 'lin': ## print ' ' + fname + ' Vertical linear interpolation at',znewval # Standard linear interpolation (y = a + b*incz) # a = zorig[0], b = (vart-varb)/(zorig[1]-zorig[0])), incz = znewval - zorig[0] a = varb b = np.where(zorigvals[1,:] == zorigvals[0,:], 0., \ (vart - varb)/(zorigvals[1,:] - zorigvals[0,:])) incz = np.ones((varb.shape), dtype=np.float)*znewval - zorigvals[0,:] newvar = a + b*incz else: print errormsg print ' ' + fname + ": interpolation kind '" + kinterp + "' not ready !!!!!" quit(-1) return newvar def interpolate_3D(zorigvs, varv, zintvs, kint): """ Function to interpolate a 3D variable interpolate_3D(zintvs, varv, zorigvals) zorigvs= original 3D z values varv= 3D variable to interpolate zintvs= new series of z values to interpolate kint= kind of interpolation 'lin': linear """ fname = 'interpolate_3D' if zorigvs == 'h': print fname + '_____________________________________________________________' print interpolate_3D.__doc__ quit() Ninv = len(zintvs) dimv = varv.shape # Sense of the original z-variable Lzorig = zorigvs.shape[0] incz = zorigvs[Lzorig-1,0,0] - zorigvs[0,0,0] varin = np.zeros((Ninv,dimv[1],dimv[2]), dtype=np.float) for ilev in range(Ninv): # print ' vertical interpolate level: ',zintvs[ilev] valinf = np.zeros((dimv[1], dimv[2]), dtype=np.float) valsup = np.zeros((dimv[1], dimv[2]), dtype=np.float) zorigv = np.zeros((2,dimv[1], dimv[2]), dtype=np.float) for j in range(valinf.shape[0]): for i in range(valinf.shape[1]): if np.min(zorigvs[:,j,i]) > zintvs[ilev] and incz > 0.: valinf[j,i] = varv[0,j,i] valsup[j,i] = varv[1,j,i] zorigv[0,j,i] = zorigvs[0,j,i] zorigv[1,j,i] = zorigvs[1,j,i] elif np.max(zorigvs[:,j,i]) < zintvs[ilev] and incz < 0.: valinf[j,i] = varv[0,j,i] valsup[j,i] = varv[1,j,i] zorigv[0,j,i] = zorigvs[0,j,i] zorigv[1,j,i] = zorigvs[1,j,i] elif np.max(zorigvs[:,j,i]) < zintvs[ilev] and incz > 0.: valinf[j,i] = varv[Lzorig-2,j,i] valsup[j,i] = varv[Lzorig-1,j,i] zorigv[0,j,i] = zorigvs[Lzorig-2,j,i] zorigv[1,j,i] = zorigvs[Lzorig-1,j,i] elif np.min(zorigvs[:,j,i]) > zintvs[ilev] and incz < 0.: valinf[j,i] = varv[Lzorig-2,j,i] valsup[j,i] = varv[Lzorig-1,j,i] zorigv[0,j,i] = zorigvs[Lzorig-2,j,i] zorigv[1,j,i] = zorigvs[Lzorig-1,j,i] # print 'top: ',i,j,':',zorigv[0,j,i], zintvs[ilev], zorigv[1,j,i] else: for z in range(Lzorig-1): if (zorigvs[z,j,i]-zintvs[ilev])*(zorigvs[z+1,j,i]- \ zintvs[ilev]) <= 0.: valinf[j,i] = varv[z,j,i] valsup[j,i] = varv[z+1,j,i] zorigv[0,j,i] = zorigvs[z,j,i] zorigv[1,j,i] = zorigvs[z+1,j,i] break # print 'zorigvs: ',zorigvs[:,0,0] # print ' valinf:', valinf[0,0] # print ' valsup:', valsup[0,0] # print ' zorigv 0:',zorigv[0,0,0] # print ' zorigv 1:',zorigv[1,0,0] varin[ilev,:,:] = vertical_interpolation2D(valinf,valsup,zorigv, \ zintvs[ilev], kint) # print ' varin:',varin[ilev,0,0] # quit() # quit() return varin def interpolate_2D(zorigvs0, varv0, zdim, zintvs, kint): """ Function to interpolate a 2D variable interpolate_2D(zintvs, varv, zorigvals) zorigvs= original 2D z values varv= 2D variable to interpolate zdim= number of the dimension with the z-values zintvs= new series of z values to interpolate kint= kind of interpolation 'lin': linear """ fname = 'interpolate_2D' if zorigvs0 == 'h': print fname + '_____________________________________________________________' print interpolate_2D.__doc__ quit() Ninv = len(zintvs) if zdim == 0: varv = varv0 zorigvs = zorigvs0 else: varv = np.transpose(varv0) zorigvs = np.transpose(zorigvs0) dimv = varv.shape # Sense of the original z-variable Lzorig = zorigvs.shape[0] incz = zorigvs[Lzorig-1,0] - zorigvs[0,0] varin = np.zeros((Ninv,dimv[1]), dtype=np.float) for ilev in range(Ninv): valinf = np.zeros((dimv[1]), dtype=np.float) valsup = np.zeros((dimv[1]), dtype=np.float) zorigv = np.zeros((2,dimv[1]), dtype=np.float) for i in range(valinf.shape[0]): if np.min(zorigvs[:,i]) > zintvs[ilev] and incz > 0.: valinf[i] = varv[0,i] valsup[i] = varv[1,i] zorigv[0,i] = zorigvs[0,i] zorigv[1,i] = zorigvs[1,i] elif np.max(zorigvs[:,i]) < zintvs[ilev] and incz < 0.: valinf[i] = varv[0,i] valsup[i] = varv[1,i] zorigv[0,i] = zorigvs[0,i] zorigv[1,i] = zorigvs[1,i] elif np.max(zorigvs[:,i]) < zintvs[ilev] and incz > 0.: valinf[i] = varv[Lzorig-2,i] valsup[i] = varv[Lzorig-1,i] zorigv[0,i] = zorigvs[Lzorig-2,i] zorigv[1,i] = zorigvs[Lzorig-1,i] elif np.min(zorigvs[:,i]) > zintvs[ilev] and incz < 0.: valinf[i] = varv[Lzorig-2,i] valsup[i] = varv[Lzorig-1,i] zorigv[0,i] = zorigvs[Lzorig-2,i] zorigv[1,i] = zorigvs[Lzorig-1,i] else: for z in range(Lzorig-1): if (zorigvs[z,i]-zintvs[ilev])*(zorigvs[z+1,i]- \ zintvs[ilev]) <= 0.: valinf[i] = varv[z,i] valsup[i] = varv[z+1,i] zorigv[0,i] = zorigvs[z,i] zorigv[1,i] = zorigvs[z+1,i] break varin[ilev,:] = vertical_interpolation(valinf,valsup,zorigv, \ zintvs[ilev], kint) if zdim == 0: varin0 = varin else: varin0 = np.transpose(varin) return varin0 def list_toVec(listv, kind): """ Function to transform from a list of values to a vector list_toVec(listv, kind) listv= list with the values kind= kind of values >>> list_toVec(['1', 2, '3', 4, 5, '6.9', 7, 9], 'npfloat') [ 1. 2. 3. 4. 5. 6.9 7. 9. ] """ fname = 'list_toVec' if listv == 'h': print fname + '_____________________________________________________________' print list_toVec.__doc__ quit() Nvals = len(listv) if kind == 'npfloat': vecv = np.zeros((Nvals), dtype=np.float) for iv in range(Nvals): vecv[iv] = np.float(listv[iv]) else: print errormsg print ' ' + fname + ': type of value "' + kind + '" not ready!!' quit(-1) return vecv def running_mean(values, run): """ Function to compute a running mean of a series of values running_mean(vals, int) [vals]: series of values [run]: interval to use to compute the running mean NOTE: resultant size would be the same but with None except at [run/2,size(vals)-run/2] >>> running_mean(np.arange(100),10) [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 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 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 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 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 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 90.5 91.5 92.5 93.5 None None None None None] """ fname = 'running_mean' if values == 'h': print fname + '_____________________________________________________________' print running_mean.__doc__ quit() runmean = np.ones((len(values)), dtype=np.float)*fillValue for ip in range(run/2,len(values)-run/2): runmean[ip] = np.mean(values[ip-run/2:ip+run/2]) runmean = np.where(runmean == fillValue, None, runmean) return runmean def files_folder_HMT(folder='.',head='',middle='',tail=''): """ Function to retrieve a list of files from a folder [fold] and files with [head]*[middle]*[tail] >>> files_folder_HMT('.','t','wrf','mean.nc') ['clt_wrfout_tmean.nc', 'tas_wrfout_tmean.nc', 'ta_wrfout_xmean.nc'] >>> files_folder_HMT(folder='/home/lluis/etudes/WRF_LMDZ/WaquaL_highres/tests/model_graphics/WRF/current', \ head='hfls', tail='.nc') ['hfls_wrfout.nc', 'hfls_wrfout_tmean.nc'] """ import subprocess as sub fname = 'files_folder' if folder == 'h': print fname + '_____________________________________________________________' print files_folder.__doc__ quit() # ins = folder + "/" + head + "*" + middle + '*' + tail ins = folder + "/" # print 'ins:',ins files = sub.Popen(["/bin/ls","-1",ins], stdout=sub.PIPE) fileslist = files.communicate() listfiles0 = str(fileslist).replace("'",'').replace('(','').replace(')','').split('\\n') # Filtering output listfiles = [] for ifile in listfiles0: if ifile.find(head) != -1 and ifile.find(middle) != -1 and \ ifile.find(tail) != -1: indhead = ifile.index(head) indmiddle = ifile.index(middle) if indmiddle == 0: indmiddle = indhead indtail = ifile.index(tail) if indtail == 0: indtail = inhead + inmiddle if indhead <= indmiddle <= indtail: listfiles.append(ifile) return listfiles def files_folder(folder,headfile): """ Function to retrieve a list of files from a folder [fold] and head [headfile] >>> files_folder('/media/data2/etudes/WRF_LMDZ/WL_HyMeX_HighRes/medic950116/', 'wrfout_d03') ['wrfout_d03_1995-01-13_02:00:00', 'wrfout_d03_1995-01-13_04:00:00', 'wrfout_d03_1995-01-13_06:00:00', 'wrfout_d03_1995-01-13_06:15:00', 'wrfout_d03_1995-01-13_08:15:00', 'wrfout_d03_1995-01-13_10:15:00', 'wrfout_d03_1995-01-13_12:15:00', 'wrfout_d03_1995-01-13_14:15:00', 'wrfout_d03_1995-01-13_16:15:00', (...) 'wrfout_d03_1995-01-17_18:15:00', 'wrfout_d03_1995-01-17_20:15:00', 'wrfout_d03_1995-01-17_22:15:00'] """ import subprocess as sub fname = 'files_folder' if folder == 'h': print fname + '_____________________________________________________________' print files_folder.__doc__ quit() # ins = folder + "/" + headfile + "*" ins = folder + "/" # print 'ins:',ins files = sub.Popen(["/bin/ls","-1",ins], stdout=sub.PIPE) fileslist = files.communicate() listfiles0 = str(fileslist).replace("'",'').replace('(','').replace(')','').split('\\n') # Filtering output Lheader=len(headfile) listfiles = [] for ifile in listfiles0: if ifile[0:Lheader] == headfile: listfiles.append(ifile) return listfiles def count_cond(var, val, con): """ Function to count values of a variable which attain a condition [var]= variable [val]= value [con]= statistics/condition 'eq': equal than [val] 'neq': not equal than [val] 'lt': less than [val] 'le': less and equal than [val] 'gt': greater than [val] 'ge': greater and equal than [val] 'in': inside the range [val[0]] <= [var] <= [val[1]] (where [val]=[val1, val2] 'out': inside the range [val[0]] > [var]; [val[1]] < [var] (where [val]=[val1, val2] >>> vals = np.arange(100) >>> count_cond(vals,50,'eq') 1 >>> count_cond(vals,50,'neq') 99 >>> count_cond(vals,50,'lt') 50 >>> count_cond(vals,50,'le') 51 >>> count_cond(vals,50,'gt') 49 >>> count_cond(vals,50,'ge') 50 >>> count_cond(vals,[25,75],'in') 51 >>> count_cond(vals,[25,75],'out') 49 """ fname = 'count_cond' cons = ['eq', 'neq', 'lt', 'le', 'gt', 'ge', 'in', 'out'] if con == 'eq': Nvals = np.sum(var == val) elif con == 'neq': Nvals = np.sum(var != val) elif con == 'lt': Nvals = np.sum(var < val) elif con == 'le': Nvals = np.sum(var <= val) elif con == 'gt': Nvals = np.sum(var > val) elif con == 'ge': Nvals = np.sum(var >= val) elif con == 'in': if len(val) != 2: print errormsg print ' ' + fname + ": for condition '" + con + "' we must have two " + \ " values!!" print ' we have:', val quit(-1) Nvals = np.sum((var >= val[0])*(var <= val[1])) elif con == 'out': if len(val) != 2: print errormsg print ' ' + fname + ": for condition '" + con + "' we must have two " + \ " values!!" print ' we have:', val quit(-1) Nvals = np.sum((var < val[0])+(var > val[1])) else: print errormsg print ' ' + fname + ": condition '" + con + "' not ready!!" print ' only ready:', cons quit(-1) return Nvals def coincident_CFtimes(tvalB, tunitA, tunitB): """ Function to make coincident times for two different sets of CFtimes tvalB= time values B tunitA= time units times A to which we want to make coincidence tunitB= time units times B >>> coincident_CFtimes(np.arange(10),'seconds since 1949-12-01 00:00:00', 'hours since 1949-12-01 00:00:00') [ 0. 3600. 7200. 10800. 14400. 18000. 21600. 25200. 28800. 32400.] >>> coincident_CFtimes(np.arange(10),'seconds since 1949-12-01 00:00:00', 'hours since 1979-12-01 00:00:00') [ 9.46684800e+08 9.46688400e+08 9.46692000e+08 9.46695600e+08 9.46699200e+08 9.46702800e+08 9.46706400e+08 9.46710000e+08 9.46713600e+08 9.46717200e+08] """ import datetime as dt fname = 'coincident_CFtimes' trefA = tunitA.split(' ')[2] + ' ' + tunitA.split(' ')[3] trefB = tunitB.split(' ')[2] + ' ' + tunitB.split(' ')[3] tuA = tunitA.split(' ')[0] tuB = tunitB.split(' ')[0] if tuA != tuB: if tuA == 'microseconds': if tuB == 'microseconds': tB = tvalB*1. elif tuB == 'seconds': tB = tvalB*10.e6 elif tuB == 'minutes': tB = tvalB*60.*10.e6 elif tuB == 'hours': tB = tvalB*3600.*10.e6 elif tuB == 'days': tB = tvalB*3600.*24.*10.e6 else: print errormsg print ' ' + fname + ": combination of time untis: '" + tuA + \ "' & '" + tuB + "' not ready !!" quit(-1) elif tuA == 'seconds': if tuB == 'microseconds': tB = tvalB/10.e6 elif tuB == 'seconds': tB = tvalB*1. elif tuB == 'minutes': tB = tvalB*60. elif tuB == 'hours': tB = tvalB*3600. elif tuB == 'days': tB = tvalB*3600.*24. else: print errormsg print ' ' + fname + ": combination of time untis: '" + tuA + \ "' & '" + tuB + "' not ready !!" quit(-1) elif tuA == 'minutes': if tuB == 'microseconds': tB = tvalB/(60.*10.e6) elif tuB == 'seconds': tB = tvalB/60. elif tuB == 'minutes': tB = tvalB*1. elif tuB == 'hours': tB = tvalB*60. elif tuB == 'days': tB = tvalB*60.*24. else: print errormsg print ' ' + fname + ": combination of time untis: '" + tuA + \ "' & '" + tuB + "' not ready !!" quit(-1) elif tuA == 'hours': if tuB == 'microseconds': tB = tvalB/(3600.*10.e6) elif tuB == 'seconds': tB = tvalB/3600. elif tuB == 'minutes': tB = tvalB/60. elif tuB == 'hours': tB = tvalB*1. elif tuB == 'days': tB = tvalB*24. else: print errormsg print ' ' + fname + ": combination of time untis: '" + tuA + \ "' & '" + tuB + "' not ready !!" quit(-1) elif tuA == 'days': if tuB == 'microseconds': tB = tvalB/(24.*3600.*10.e6) elif tuB == 'seconds': tB = tvalB/(24.*3600.) elif tuB == 'minutes': tB = tvalB/(24.*60.) elif tuB == 'hours': tB = tvalB/24. elif tuB == 'days': tB = tvalB*1. else: print errormsg print ' ' + fname + ": combination of time untis: '" + tuA + \ "' & '" + tuB + "' not ready !!" quit(-1) else: print errormsg print ' ' + fname + ": time untis: '" + tuA + "' not ready !!" quit(-1) else: tB = tvalB*1. if trefA != trefB: trefTA = dt.datetime.strptime(trefA, '%Y-%m-%d %H:%M:%S') trefTB = dt.datetime.strptime(trefB, '%Y-%m-%d %H:%M:%S') difft = trefTB - trefTA diffv = difft.days*24.*3600.*10.e6 + difft.seconds*10.e6 + difft.microseconds print ' ' + fname + ': different reference refA:',trefTA,'refB',trefTB print ' difference:',difft,':',diffv,'microseconds' if tuA == 'microseconds': tB = tB + diffv elif tuA == 'seconds': tB = tB + diffv/10.e6 elif tuA == 'minutes': tB = tB + diffv/(60.*10.e6) elif tuA == 'hours': tB = tB + diffv/(3600.*10.e6) elif tuA == 'dayss': tB = tB + diffv/(24.*3600.*10.e6) else: print errormsg print ' ' + fname + ": time untis: '" + tuA + "' not ready !!" quit(-1) return tB def wdismean(pos,val4): """ Function to compute the mean value weighted to its 4 distances pos= x,y position within the 'square' val4= values at the four vertexs (2,2) >>>position = [0.005,0.005] >>>val4 = np.zeros((2,2), dtype=np.float) >>>val4 = np.arange(4).reshape(2,2) 0.035707955234 """ fname = 'wdismean' dist = np.zeros((2,2), dtype=np.float) dist[0,0] = np.sqrt(pos[0]*pos[0]+pos[1]*pos[1]) dist[0,1] = np.sqrt(pos[0]*pos[0]+(1.-pos[1])*(1.-pos[1])) dist[1,0] = np.sqrt((1.-pos[0])*(1.-pos[0])+pos[1]*pos[1]) dist[1,1] = np.sqrt((1.-pos[0])*(1.-pos[0])+(1.-pos[1])*(1.-pos[1])) if np.min(dist) == 0.: pos0 = index_mat(dist, 0.) dist[:,:] = 0. posmean = val4[pos0[0], pos0[1]] else: totdist = np.sum(1./dist) posmean = np.sum(val4.flatten()/dist.flatten())/totdist return posmean def read_ASCIIlist(filen): """ Function to build a list from an ASCII lines file filen= name of the ASCII file """ import os fname = 'read_ASCIIlist' if not os.path.isfile(filen): print errormsg print ' ' + fname + ": ASCII types file '" + filen + "' does not exist !!" quit(-1) of = open(filen, 'r') filevals = [] for linef in of: filevals.append(linef.replace('\n','')) of.close() return filevals def radial_points(angle,dist): """ Function to provide a number of grid point positions for a given angle angle= desired angle (rad) dist= number of grid points >>> radial_points(0.5*np.pi,5) [[ 6.12323400e-17 1.00000000e+00] [ 1.22464680e-16 2.00000000e+00] [ 1.83697020e-16 3.00000000e+00] [ 2.44929360e-16 4.00000000e+00] [ 3.06161700e-16 5.00000000e+00]] """ fname = 'radial_points' radpos = np.zeros((dist,2), dtype=np.float) for ip in range(dist): radpos[ip,0] = (ip+1.)*np.cos(angle) radpos[ip,1] = (ip+1.)*np.sin(angle) return radpos def read_SQradii(filename='SQradii.dat', Npt=-1, maxradii=None): """ Function to read the outcome of the function `squared_radial' filename= Name of the outcome file of the function Npt= Number of points on each grid maxradii= allowed maximum radii 'SQradii.dat': file with the radii and paris of integers after ran squared_radial(1000) """ fname = 'read_SQradii' if not os.path.isfile(filename): print errormsg print ' ' + fname + ": file '" + filename + "' not found!!" quit(-1) infile = open(filename, 'r') gridradii = {} Nradii = {} radii = [] for line in infile: values = values_line(line, ' ', ['[', ']']) rad = np.float(values[0]) # Limited by a given radii if maxradii is not None and rad > maxradii: break Nrad = int(values[2]) couples = [] Nradgood = 0 if Nrad > 1: Ncouples = 0 for ic in range(Nrad): ix = int(values[3 + ic*2]) iy = int(values[3 + ic*2 + 1]) if ix <= Npt and iy <= Npt: couples.append(np.array([ix,iy])) Nradgood = Nradgood + 1 elif ix > Npt and iy > Npt: break else: ix = int(values[3]) iy = int(values[4]) if ix <= Npt and iy <= Npt: couples.append(np.array([ix,iy])) Nradgood = Nradgood + 1 elif ix > Npt and iy > Npt: break if Nradgood > 0: Nradii[rad] = Nradgood finalcouples = np.zeros((Nradgood,2), dtype=int) for ic in range(Nradgood): finalcouples[ic,:] = couples[ic] gridradii[rad] = finalcouples # for rad in sorted(gridradii.keys()): # print rad, gridradii[rad] return gridradii def grid_combinations(x,y): """ Function to provide all the possible grid points combination for a given pair of values x,y= pair of grid points >>>grid_combinations(1,2) [[1, 2], [-1, 2], [-1, -2], [1, -2], [2, 1], [-2, 1], [-2, -1], [2, -1]] """ fname = 'grid_combinations' gridcomb = [] gridcomb.append([x,y]) if x != 0: gridcomb.append([-x,y]) if x != 0 and y != 0: gridcomb.append([-x,-y]) if y != 0: gridcomb.append([x,-y]) if x != y: gridcomb.append([y,x]) if y != 0: gridcomb.append([-y,x]) if x != 0 and y != 0: gridcomb.append([-y,-x]) if x != 0: gridcomb.append([y,-x]) return gridcomb def radii_points(xpos,ypos,Lrad,Nang,dx,dy): """ Function to provide the grid points for radial cross sections, by angle and radii and `squared' radii xpos= x position of the center ypos= y position of the center Lrad= length of the maximum radi in grid points Nang= number of equivalent angles dx= x size of the domain of values dy= y size of the domain of values >>> radpos, SQradpos = radii_points(12,12,1,8,25,25) radpos: [[[ 13. 12. ]] [[ 12.70710678 12.70710678]] [[ 12. 13. ]] [[ 11.29289322 12.70710678]] [[ 11. 12. ]] [[ 11.29289322 11.29289322]] [[ 12. 11. ]] [[ 12.70710678 11.29289322]]] SQradpos: {1.0: [[13, 12], [11, 12], [12, 13], [12, 11]], 1.41421356237: [[13, 13], [11, 13], [11, 11], [13, 11]]} """ fname = 'radii_points' radiipos = np.zeros((Nang, Lrad, 2), dtype = np.float) SQradiipos = {} # Getting the range of radii: pairsSQradii = read_SQradii(Npt=Lrad) SQradii = pairsSQradii.keys() Nradii = len(SQradii) # Angle loop for ia in range(Nang): angle = 2.*np.pi*ia/Nang posangle = np.zeros((Lrad,2), dtype=np.float) # Points at that given angle pangle = radial_points(angle,Lrad) posangle[:,0] = pangle[:,0] + xpos posangle[:,1] = pangle[:,1] + ypos for ip in range(Lrad): iipos = int(posangle[ip,0]) jjpos = int(posangle[ip,1]) # Creation of a matrix with all the grid points at each time-step if iipos >= 0 and iipos < dx-1 and jjpos >= 0 and jjpos < dy-1: radiipos[ia,ip,0] = posangle[ip,0] radiipos[ia,ip,1] = posangle[ip,1] # SQ radii values # Radii loop (avoiding 0) pairswithin = {} for ir in range(1,Nradii): pairs = pairsSQradii[SQradii[ir]] # pairs loop Npairs = len(pairs.flatten())/2 pairsw = [] for ip in range(Npairs): if Npairs == 0: break else: allpairs = grid_combinations(pairs[ip,0],pairs[ip,1]) for iap in range(len(allpairs)): ppos = allpairs[iap] iipos = xpos + ppos[0] jjpos = ypos + ppos[1] # Creation of a matrix with all the grid points at each time-step if iipos >= 0 and iipos < dx and jjpos >= 0 and jjpos < dy: pairsw.append([iipos,jjpos]) SQradiipos[SQradii[ir]] = pairsw return radiipos, SQradiipos def hor_weight_int(SWval, SEval, NWval, NEval, xpos, ypos): """ Function to weighted by distance interpolate a horizontal value from it closest 4 neighbourgs field= a 4 points representing the environment of a given point xpos, ypos: position to which one want to interpolate (relative to 0,0 at the corner SW) >>> hor_weight_int(1., 1., 1., 2., 0.75, 0.75) 1.44888128193 """ fname = 'hor_weight_int' vals = np.array([SWval, SEval, NWval, NEval]) print vals if xpos > 1.: print errormsg print ' ' + fname + ': Wrong position to interpolate! (',xpos,',',ypos, \ ') must be within (1,1) !!' quit(-1) vertexs = np.zeros((4,2), dtype=np.float) vertexs[0,0] = 0. vertexs[0,1] = 0. vertexs[1,0] = 1. vertexs[1,1] = 0. vertexs[2,0] = 0. vertexs[2,1] = 1. vertexs[3,0] = 1. vertexs[3,1] = 1. print vertexs dist = np.sqrt((vertexs[:,0]-xpos)**2 + (vertexs[:,1]-ypos)**2) print dist done = False for id in range(4): if dist[id] == 0.: intval = vals[id] done = True if not done: intval = np.sum(vals/dist)/np.sum(1./dist) return intval def rmNOnum(string): """ Removing from a string all that characters which are not numbers # From: http://stackoverflow.com/questions/4289331/python-extract-numbers-from-a-string """ fname = 'rmNOnum' newstr = str(re.findall("[-+]?\d+[\.]?\d*", string)[0]) return newstr def values_fortran_fmt(lin,fFMT): """ Function to give back the values of an ASCII line according to its fortran printing format lin= ASCII line fFMT= list with the fortran FORMAT formats forline = 'Natchitoches (RGNL) 1 11 0011 ( 31.733, -93.100) ( 28, 157) ( 31.761, -93.113) 41.2 meters' formats = ['A26', 'I2', 'I3', 'A6', 'A2', 'F7.3', 'A1', 'F8.3', 'A3', 'I4', 'A1', 'I4', 'A3', 'F7.3', 'A1', 'F8.3', 'A2', 'F6.1', 'A7'] >>> values_fortran_fmt(forline, formats) ['Natchitoches (RGNL) ', 1, 11, ' 0011 ', ' ( ', 31.733, ', ', -93.1, ') ( ', 28, ', ', 157, ') ( ', 31.761, ', ', -93.113, ') ', 41.2, ' meters'] """ fname = 'values_fortran_fmt' afmts = ['A', 'D', 'F', 'I'] if lin == 'h': print fname + '_____________________________________________________________' print values_fortran_fmt.__doc__ quit() fvalues = [] ichar=0 ival = 0 for ft in fFMT: Lft = len(ft) if ft[0:1] == 'A' or ft[0:1] == 'a': Lfmt = int(ft[1:Lft+1]) fvalues.append(lin[ichar:ichar+Lfmt+1]) ichar = ichar + Lfmt elif ft[0:1] == 'F' or ft[0:1] == 'f': if ft.find('.') != -1: Lft = len(ft.split('.')[0]) Lfmt = int(ft[1:Lft]) fvalues.append(np.float(rmNOnum(lin[ichar:ichar+Lfmt+1]))) ichar = ichar + Lfmt elif ft[0:1] == 'D' or ft[0:1] == 'd': if ft.find('.') != -1: Lft = len(ft.split('.')[0]) Lfmt = int(ft[1:Lft]) fvalues.append(np.float64(rmNOnum(lin[ichar:ichar+Lfmt+1]))) ichar = ichar + Lfmt elif ft[0:1] == 'I' or ft[0:1] == 'i': Lfmt = int(ft[1:Lft+1]) fvalues.append(int(rmNOnum(lin[ichar:ichar+Lfmt+1]))) ichar = ichar + Lfmt elif ft.find('X') != -1 or ft.find('x') != -1: print ' ' + fname + ': skipping space' ichar = ichar + int(rmNOnum(ft)) else: print errormsg print ' ' + fname + ": format '" + ft[0:1] + "' not ready!!" print ' Available formats:',afmts quit(-1) ival = ival + 1 return fvalues def reduce_last_spaces(string): """ Function to reduce the last right spaces from a string string= string to remove the spaces at the righ side of the string >>> reduce_last_spaces('Hola Lluis ') 'Hola Lluis' """ fname = 'reduce_last_spaces' Lstring = len(string) firstspace = -1 for istr in range(Lstring-1,0,-1): if string[istr:istr+1] == ' ': firstspace = istr else: break if firstspace == -1: print errormsg print ' ' + fname + ": string '" + string + "' is not ended by spaces!!" print ' char. number of last character:',ord(string[Lstring:Lstring+1]) quit(-1) newstr = string[0:firstspace] return newstr def squared_radial(Npt): """ Function to provide the series of radii as composite of pairs (x,y) of gid cells Npt= largest amount of grid points on x and y directions >>> squared_radial(5) [[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]] """ fname = 'squared_radial' if Npt == 'h': print fname + '_____________________________________________________________' print squared_radial.__doc__ quit() radii = [] gridradii = {} singradii = [] Nradii = {} # Computing all radii ## for i in range(Npt+1): if np.mod(i,100) == 0: print 'done: ',i for j in range(i+1): # ir = np.float(i) # jr = np.float(j) ir = np.float64(i) jr = np.float64(j) rad = np.sqrt(ir*ir + jr*jr) if not searchInlist(singradii, rad): singradii.append(rad) gridradii[rad] = np.array([i,j], dtype=int) Nradii[rad] = 1 else: # print warnmsg # print ' ' + fname + ': repeated radii',rad,'!!' # print ' Previous values:', gridradii[rad] oldvalues = gridradii[rad] Nradii[rad] = Nradii[rad] + 1 newvalues = np.zeros((Nradii[rad],2), dtype=int) if Nradii[rad] == 2: newvalues[0,:] = oldvalues Nstart = 1 else: Nstart = 0 for Nr in range(Nstart,Nradii[rad]-1): newvalues[Nr,:] = oldvalues[Nr,:] newvalues[Nradii[rad]-1,:] = np.array([i,j], dtype=int) gridradii[rad] = newvalues # Sorting values ## ## Only required to downwrite the output file # radiif = open('SQradii.dat', 'w') # radii = [] # prevrad = 0. # for rad in sorted(gridradii.keys()): # dradii = rad - prevrad ## Check fo repeated values # radii.append([rad, gridradii[rad][0], gridradii[rad][1]]) # radiif.write(str(rad) + ' ' + str(dradii) + ' ' + str(Nradii[rad]) + ' [ '+ \ # numVector_String(gridradii[rad].flatten(), ' ') + ' ] \n') # prevrad = rad.copy() # radiif.close() return gridradii def fillvalue_kind(vartype, fillval0): """ Function to provide the fiven fill_Value for a kind of variable [vartype]= type of the variable [fillval0]= value to take as fill value, 'std' for the standard value Float = 1.e20 Character = '-' Integer = -99999 Integer16 = -99999 Float64 = 1.e20 Integer32 = -99999 """ fname = 'fillvalue_kind' if vartype == 'h': print fname + '_____________________________________________________________' print fillvalue_kind.__doc__ quit() if vartype == type('c'): if fillval0 == 'std': fillval = fillvalueC else: fillval = fillval0 elif vartype == type(int(1)): if fillval0 == 'std': fillval = fillValueI else: fillval = int(fillval0) elif vartype == type(np.int16(1)): if fillval0 == 'std': fillval = np.int(9999999) else: fillval = np.int16(fillval0) elif vartype == type(np.int32(1)): if fillval0 == 'std': fillval = np.int32(fillValueI) else: fillval = np.int32(fillval0) elif vartype == type(np.float(1.)): if fillval0 == 'std': fillval = np.float(fillValueF) else: fillval = np.float(fillval0) elif vartype == type(np.float32(1.)): if fillval0 == 'std': fillval = np.float32(fillValueF) else: fillval = np.float32(fillval0) elif vartype == type(np.float64(1.)): if fillval0 == 'std': fillval = np.float64(fillValueF) else: fillval = np.float64(fillval0) else: print errormsg print ' ' + fname + ': variable type', vartype, 'not ready !!' quit(-1) return fillval def varval_ind(var, ind): """ Function to provide a value from a variable providing a value for each index var= variable ind= list of indices for each dimension of the variable """ fname = 'varval_ind' if len(var.shape) != len(ind): print errormsg print ' ' + fname + ': different shape:', var.shape,'and indices:', ind, '!!' quit(-1) varslice=[] for iv in ind: varslice.append(iv) val = varval_ind[slice(varslice)] return val def CoarselonlatFind(ilon, ilat, lonv, latv, per): """ Function to search a given value from a coarser version of the data ilon, ilat= original 2D matrices with the longitudes and the latitudes lonv, latv= longitude and latitude to find per= period (as fraction over 1) of the fractions of the original grid to use to explore >>> npt=100 >>> lonval0 = np.arange(0.,npt*1.,1.) >>> latval0 = np.arange(0.,npt*1.,1.) >>> lonval = np.zeros((npt,npt), dtype=np.float) >>> latval = np.zeros((npt,npt), dtype=np.float) >>> for i in range(npt): >>> lonval[:,i] = lonval0[i] >>> latval[i,:] = latval0[i] >>> CoarselonlatFind(lonval, latval, 5.25, 5.25, .1) (array([5, 5]), 0.35355339059327379) """ fname = 'CoarselonlatFind' dx = ilon.shape[1] dy = ilon.shape[0] nlon = np.min(ilon) xlon = np.max(ilon) nlat = np.min(ilat) xlat = np.max(ilat) if lonv < nlon or lonv > xlon: print errormsg print ' ' + fname + ': longitude outside data range!!' print ' given value:', lonv,'outside [',nlon,',',xlon,']' quit(-1) if latv < nlat or latv > xlat: print errormsg print ' ' + fname + ': latitude outside data range!!' print ' given value:', latv,'outside [',nlat,',',xlat,']' quit(-1) fracx = int(dx*per) fracy = int(dy*per) fraclon = ilon[::fracy,::fracx] fraclat = ilat[::fracy,::fracx] fracdx = fraclon.shape[1] fracdy = fraclon.shape[0] # print 'fraclon _______' # print fraclon # print 'fraclat _______' # print fraclat # Fraction point difffraclonlat = np.sqrt((fraclon-lonv)**2. + (fraclat-latv)**2.) mindifffracLl = np.min(difffraclonlat) ilatlonfrac = index_mat(difffraclonlat, mindifffracLl) # print 'mindifffracLl:', mindifffracLl, 'ilatlonfrac:', ilatlonfrac # print 'frac lon, lat:', fraclon[ilatlonfrac[0],ilatlonfrac[1]], ',', \ # fraclat[ilatlonfrac[0],ilatlonfrac[1]] # print 'values lon, lat:', lonv, latv # Providing fraction range if fraclon[ilatlonfrac[0],ilatlonfrac[1]] >= lonv and \ fraclat[ilatlonfrac[0],ilatlonfrac[1]] >= latv: # ifracbeg = [ilatlonfrac[0]-1, ilatlonfrac[1]-1] # ifracend = [ilatlonfrac[0], ilatlonfrac[1]] if ilatlonfrac[0] > 0: iybeg = (ilatlonfrac[0]-1)*fracy iyend = ilatlonfrac[0]*fracy+1 else: iybeg = 0 iyend = fracy+1 if ilatlonfrac[1] > 0: ixbeg = (ilatlonfrac[1]-1)*fracx ixend = ilatlonfrac[1]*fracx+1 else: ixbeg = 0 ixend = fracx+1 elif fraclon[ilatlonfrac[0],ilatlonfrac[1]] < lonv and \ fraclat[ilatlonfrac[0],ilatlonfrac[1]] >= latv: # ifracbeg = [ilatlonfrac[0]-1, ilatlonfrac[1]] # ifracend = [ilatlonfrac[0], ilatlonfrac[1]+1] if ilatlonfrac[0] > 0: iybeg = (ilatlonfrac[0]-1)*fracy iyend = ilatlonfrac[0]*fracy+1 else: iybeg = 0 iyend = fracy+1 if ilatlonfrac[1] < fracdx: if ilatlonfrac[1] != 0: ixbeg = (ilatlonfrac[1]-1)*fracx ixend = ilatlonfrac[1]*fracx+1 else: ixbeg = 0 ixend = fracx+1 else: ixbeg = fracdx*fracx ixend = dx+1 elif fraclon[ilatlonfrac[0],ilatlonfrac[1]] < lonv and \ fraclat[ilatlonfrac[0],ilatlonfrac[1]] < latv: # ifracbeg = [ilatlonfrac[0], ilatlonfrac[1]] # ifracend = [ilatlonfrac[0]+1, ilatlonfrac[1]+1] if ilatlonfrac[0] < fracdy: if ilatlonfrac[0] != 0: iybeg = (ilatlonfrac[0]-1)*fracy iyend = ilatlonfrac[0]*fracy+1 else: iybeg = 0 iyend = fracy+1 else: iybeg = fracdy*fracy iyend = dy+1 if ilatlonfrac[1] < fracdx: if ilatlonfrac[1] != 0: ixbeg = (ilatlonfrac[1]-1)*fracx ixend = ilatlonfrac[1]*fracx+1 else: ixbeg = 0 ixend = fracx+1 else: ixbeg = fracdx*fracx ixend = dx+1 elif fraclon[ilatlonfrac[0],ilatlonfrac[1]] >= lonv and \ fraclat[ilatlonfrac[0],ilatlonfrac[1]] < latv: # ifracbeg = [ilatlonfrac[0], ilatlonfrac[1]-1] # ifracend = [ilatlonfrac[0]+1, ilatlonfrac[1]] if ilatlonfrac[0] < fracdy: if ilatlonfrac[0] != 0: iybeg = (ilatlonfrac[0]-1)*fracy iyend = ilatlonfrac[0]*fracy+1 else: iybeg = 0 iyend = fracy+1 else: iybeg = fracdy*fracy iyend = dy+1 if ilatlonfrac[1] > 0: ixbeg = (ilatlonfrac[1]-1)*fracx ixend = ilatlonfrac[1]*fracx+1 else: ixbeg = 0 ixend = fracx+1 # ibeg = [iybeg, ixbeg] # iend = [iyend, ixend] # print 'find window; beginning', ibeg, 'end:', iend lon = ilon[iybeg:iyend,ixbeg:ixend] lat = ilat[iybeg:iyend,ixbeg:ixend] # print 'lon _______' # print lon # print 'lat _______' # print lat # Find point difflonlat = np.sqrt((lon-lonv)**2. + (lat-latv)**2.) mindiffLl = np.min(difflonlat) ilatlon = index_mat(difflonlat, mindiffLl) ilatlon[0] = ilatlon[0] + iybeg ilatlon[1] = ilatlon[1] + ixbeg # print 'mindiffLl:', mindiffLl, 'ilatlon:', ilatlon # print 'lon, lat:', lon[ilatlon[0],ilatlon[1]], ',', lat[ilatlon[0],ilatlon[1]] # quit() return ilatlon, mindiffLl def CoarselonlatFindAll(onc, ilon, ilat, longvs, latvs, per, frac, out): """ Function to search all values from a coarser version of the data onc= netCDF object from an existing file ilon, ilat= original 2D matrices with the longitudes and the latitudes lonv, latv= longitude and latitude to find per= period (as fraction over 1) of the fractions of the original grid to use to explore frac= frequency of points at which syncronize file with calculations out= True/False if outcome is required >>> npt=100 >>> lonval0 = np.arange(0.,npt*1.,1.) >>> latval0 = np.arange(0.,npt*1.,1.) >>> lonval = np.zeros((npt,npt), dtype=np.float) >>> latval = np.zeros((npt,npt), dtype=np.float) >>> lonvalues = np.arange(0.25,10.,0.25) >>> latvalues = np.arange(0.25,10.,0.25) >>> for i in range(npt): >>> lonval[:,i] = lonval0[i] >>> latval[i,:] = latval0[i] >>> CoarselonlatFindAll(onewnc, lonval, latval, lovalues, latvalues, .1, 100) (array([5, 5]), 0.35355339059327379) """ fname = 'CoarselonlatFindAll' dx = ilon.shape[1] dy = ilon.shape[0] nlon = np.min(ilon) xlon = np.max(ilon) nlat = np.min(ilat) xlat = np.max(ilat) Nallpts = len(longvs) fracx = int(dx*per) fracy = int(dy*per) fraclon = ilon[::fracy,::fracx] fraclat = ilat[::fracy,::fracx] fracdx = fraclon.shape[1] fracdy = fraclon.shape[0] # print 'fraclon _______' # print fraclon # print 'fraclat _______' # print fraclat if out: ilatlon = np.zeros((2,Nallpts), dtype=int) mindiffLl = np.zeros((Nallpts), dtype=np.float) iptpos=0 for iv in range(Nallpts): lonv = longvs[iv] latv = latvs[iv] if lonv < nlon or lonv > xlon: print errormsg print ' ' + fname + ': longitude outside data range!!' print ' given value:', lonv,'outside [',nlon,',',xlon,']' quit(-1) if latv < nlat or latv > xlat: print errormsg print ' ' + fname + ': latitude outside data range!!' print ' given value:', latv,'outside [',nlat,',',xlat,']' quit(-1) # Fraction point difffraclonlat = np.sqrt((fraclon-lonv)**2. + (fraclat-latv)**2.) mindifffracLl = np.min(difffraclonlat) ilatlonfrac = index_mat(difffraclonlat, mindifffracLl) # print 'values lon, lat:', lonv, latv # print 'mindifffracLl:', mindifffracLl, 'ilatlonfrac:', ilatlonfrac # print 'frac lon, lat:', fraclon[ilatlonfrac[0],ilatlonfrac[1]], ',', \ # fraclat[ilatlonfrac[0],ilatlonfrac[1]] # Providing fraction range if fraclon[ilatlonfrac[0],ilatlonfrac[1]] >= lonv and \ fraclat[ilatlonfrac[0],ilatlonfrac[1]] >= latv: # ifracbeg = [ilatlonfrac[0]-1, ilatlonfrac[1]-1] # ifracend = [ilatlonfrac[0], ilatlonfrac[1]] if ilatlonfrac[0] > 0: iybeg = (ilatlonfrac[0]-1)*fracy iyend = ilatlonfrac[0]*fracy+1 else: iybeg = 0 iyend = fracy+1 if ilatlonfrac[1] > 0: ixbeg = (ilatlonfrac[1]-1)*fracx ixend = ilatlonfrac[1]*fracx+1 else: ixbeg = 0 ixend = fracx+1 elif fraclon[ilatlonfrac[0],ilatlonfrac[1]] < lonv and \ fraclat[ilatlonfrac[0],ilatlonfrac[1]] >= latv: # ifracbeg = [ilatlonfrac[0]-1, ilatlonfrac[1]] # ifracend = [ilatlonfrac[0], ilatlonfrac[1]+1] if ilatlonfrac[0] > 0: iybeg = (ilatlonfrac[0]-1)*fracy iyend = ilatlonfrac[0]*fracy+1 else: iybeg = 0 iyend = fracy+1 if ilatlonfrac[1] < fracdx: if ilatlonfrac[1] != 0: ixbeg = (ilatlonfrac[1]-1)*fracx ixend = ilatlonfrac[1]*fracx+1 else: ixbeg = 0 ixend = fracx+1 else: ixbeg = fracdx*fracx ixend = dx+1 elif fraclon[ilatlonfrac[0],ilatlonfrac[1]] < lonv and \ fraclat[ilatlonfrac[0],ilatlonfrac[1]] < latv: # ifracbeg = [ilatlonfrac[0], ilatlonfrac[1]] # ifracend = [ilatlonfrac[0]+1, ilatlonfrac[1]+1] if ilatlonfrac[0] < fracdy: if ilatlonfrac[0] != 0: iybeg = (ilatlonfrac[0]-1)*fracy iyend = ilatlonfrac[0]*fracy+1 else: iybeg = 0 iyend = fracy+1 else: iybeg = fracdy*fracy iyend = dy+1 if ilatlonfrac[1] < fracdx: if ilatlonfrac[1] != 0: ixbeg = (ilatlonfrac[1]-1)*fracx ixend = ilatlonfrac[1]*fracx+1 else: ixbeg = 0 ixend = fracx+1 else: ixbeg = fracdx*fracx ixend = dx+1 elif fraclon[ilatlonfrac[0],ilatlonfrac[1]] >= lonv and \ fraclat[ilatlonfrac[0],ilatlonfrac[1]] < latv: # ifracbeg = [ilatlonfrac[0], ilatlonfrac[1]-1] # ifracend = [ilatlonfrac[0]+1, ilatlonfrac[1]] if ilatlonfrac[0] < fracdy: if ilatlonfrac[0] != 0: iybeg = (ilatlonfrac[0]-1)*fracy iyend = ilatlonfrac[0]*fracy+1 else: iybeg = 0 iyend = fracy+1 else: iybeg = fracdy*fracy iyend = dy+1 if ilatlonfrac[1] > 0: ixbeg = (ilatlonfrac[1]-1)*fracx ixend = ilatlonfrac[1]*fracx+1 else: ixbeg = 0 ixend = fracx+1 # ibeg = [iybeg, ixbeg] # iend = [iyend, ixend] # print 'find window; beginning', ibeg, 'end:', iend lon = ilon[iybeg:iyend,ixbeg:ixend] lat = ilat[iybeg:iyend,ixbeg:ixend] # print 'Looking within _______' # print 'lon:',lon[0,0],',',lon[-1,-1] # print 'lat:',lat[0,0],',',lat[-1,-1] # print 'lon _______' # print lon # print 'lat _______' # print lat # Find point difflonlat = np.sqrt((lon-lonv)**2. + (lat-latv)**2.) if out: mindiffLl[iv] = np.min(difflonlat) ilatlon[:,iv] = index_mat(difflonlat, mindiffLl) ilatlon[0,iv] = ilatlon[0,iv] + iybeg ilatlon[1,iv] = ilatlon[1,iv] + ixbeg else: mindiffLl = np.min(difflonlat) ilatlon = index_mat(difflonlat, mindiffLl) ilatlon[0] = ilatlon[0] + iybeg ilatlon[1] = ilatlon[1] + ixbeg # print 'mindiffLl:', mindiffLl, 'ilatlon:', ilatlon # print 'lon, lat:', lon[ilatlon[0],ilatlon[1]], ',', lat[ilatlon[0],ilatlon[1]] # quit() # if mindiffLl == 0. and type(newvar[ilatlon[0],ilatlon[1]]) == type(amsk): # percendone(iv,Ninpts,0.5,'done:') if mindiffLl == 0.: iptpos = iptpos + 1 # Speeding it up! # if mindiffLl > mindiff: # print errormsg # print ' ' + fname + ': for point #', iv,'lon,lat in ' + \ # 'incomplet map:', lonvs[iv], ',', latvs[iv], 'there is ' + \ # 'not a set of lon,lat in the completed map closer than: ', \ # mindiff, '!!' # print ' minimum difference:', mindiffLl # quit(-1) # Speeding it up! # if ilatlon[0] >= 0 and ilatlon[1] >= 0: # newvar[ilatlon[0],ilatlon[1]] = ovar[iv] # newvarin[ilatlon[0],ilatlon[1]] = iv # newvarinpt[iv] = 1 # newvarindiff[iv] = mindiffLl newvar[ilatlon[0],ilatlon[1]] = ovar[iv] newvarin[ilatlon[0],ilatlon[1]] = iv newvarinpt[iv] = 1 newvarindiff[iv] = mindiffLl # print 'Lluis iv:', newvarin[ilatlon[0],ilatlon[1]], \ # 'localized:', newvarinpt[iv], 'values:', \ # newvar[ilatlon[0],ilatlon[1]], 'invalues:', ovar[iv], \ # 'mindist:', newvarindiff[iv], 'point:',ilatlon # else: # print errormsg # print ' ' + fname + ': point iv:', iv, 'at', lonvs[iv], ',', \ # latvs[iv],' not relocated !!' # print ' mindiffl:', mindiffLl, 'ilon:', ilatlon[1], \ # 'ilatlon:', ilatlon[1] # quit(-1) if np.mod(iptpos,fracs) == 0: onc.sync() if out: return ilatlon, mindiffLl else: return def lonlatFind(ilon, ilat, lonv, latv): """ Function to search a given value from a lon, lat 2D data ilon, ilat= original 2D matrices with the longitudes and the latitudes lonv, latv= longitude and latitude to find >>> npt=100 >>> lonval0 = np.arange(0.,npt*1.,1.) >>> latval0 = np.arange(0.,npt*1.,1.) >>> lonval = np.zeros((npt,npt), dtype=np.float) >>> latval = np.zeros((npt,npt), dtype=np.float) >>> for i in range(npt): >>> lonval[:,i] = lonval0[i] >>> latval[i,:] = latval0[i] >>> lonlatFind(lonval, latval, 5.25, 5.25) (array([5, 5]), 0.35355339059327379) """ fname = 'lonlatFind' dx = ilon.shape[1] dy = ilon.shape[0] nlon = np.min(ilon) xlon = np.max(ilon) nlat = np.min(ilat) xlat = np.max(ilat) if lonv < nlon or lonv > xlon: print errormsg print ' ' + fname + ': longitude outside data range!!' print ' given value:', lonv,'outside [',nlon,',',xlon,']' quit(-1) if latv < nlat or latv > xlat: print errormsg print ' ' + fname + ': latitude outside data range!!' print ' given value:', latv,'outside [',nlat,',',xlat,']' quit(-1) # Find point difflonlat = np.sqrt((ilon-lonv)**2. + (ilat-latv)**2.) mindiffLl = np.min(difflonlat) ilatlon = index_mat(difflonlat, mindiffLl) # print 'mindiffLl:', mindiffLl, 'ilatlon:', ilatlon # print 'lon, lat:', lon[ilatlon[0],ilatlon[1]], ',', lat[ilatlon[0],ilatlon[1]] return ilatlon, mindiffLl def PolyArea(x,y): """ Function to compute the area of the polygon following 'Shoelace formula' from: http://stackoverflow.com/questions/24467972/calculate-area-of-polygon-given-x-y-coordinates x: x-values of the vertexs of the polygon y: y-values of the vertexs of the polygon >>> x = np.array([-0.5,0.5,0.5,-0.5]) >>> y = np.array([0.5,0.5,-0.5,-0.5]) >>> PolyArea(x,y) 1.0 """ fname = 'PolyArea' return 0.5*np.abs(np.dot(x,np.roll(y,1))-np.dot(y,np.roll(x,1))) def ijlonlat(lon, lat, nlon, xlon, nlat, xlat): """ Function to provide the imin,jmin imax,jmax of a lon,lat box lon= 2D matrix with the longitudes lat= 2D matrix with the latitudes nlon, xlon= minimun, maximum of the longitudes for the lon,lat box nlat, xlat= minimun, maximum of the latitudes for the lon,lat box """ fname = 'ijlonlat' if nlon < np.min(lon): print errormsg print ' ' + fname + ': minimum longitude:',nlon,'too small!!' print ' smallest possible:',np.min(lon) quit(-1) if xlon > np.max(lon): print errormsg print ' ' + fname + ': maximum longitude:',xlon,'too large!!' print ' largest possible:',np.max(lon) quit(-1) if nlat < np.min(lat): print errormsg print ' ' + fname + ': minimum laitude:',nlat,'too small!!' print ' smallest possible:',np.min(lat) quit(-1) if xlat > np.max(lat): print errormsg print ' ' + fname + ': maximum latitude:',xlat,'too large!!' print ' largest possible:',np.max(lat) quit(-1) nlonv = np.abs(lon - nlon) xlonv = np.abs(lon - xlon) nlatv = np.abs(lat - nlat) xlatv = np.abs(lat - xlat) ni0 = index_mat(nlonv,np.min(nlonv))[1] xi0 = index_mat(xlonv,np.min(xlonv))[1] + 1 nj0 = index_mat(nlatv,np.min(nlatv))[0] xj0 = index_mat(xlatv,np.min(xlatv))[0] + 1 if ni0 > xi0: ni = xi0 xi = ni0 else: ni = ni0 xi = xi0 if nj0 > xj0: nj = xj0 xj = nj0 else: nj = nj0 xj = xj0 return ni,xi,nj,xj def significant_decomposition(num,minpot): """ Function to decompose a given number by its signifcant potencies returns: [numPot], [Potlist], [Diglist] [numPot]: number of potencies [Potlist]: list of potencies [Diglist]: list of digits Thus: num <> np.sum([Diglist]*10.**[Potlist]) num= number to decompose minpot= minumum potence to decompose >>> significant_decomposition(np.pi,-6) 7, [0.0, -1.0, -2.0, -3.0, -4.0, -5.0, -6.0], [3, 1, 4, 1, 5, 9, 2] """ fname = 'significant_decomposition' potencies = [] potval = [] anum = np.abs(num) diff = anum*1. iipot = 1 pot = np.floor(np.log10(anum)) if pot < minpot: print errormsg print ' ' + fname + ': required minimum potency:', minpot, 'is smaller ' + \ 'than the potency of the value:', pot, '!!' print ' minimum value 10**minpot:', 10**(minpot), '>', anum print " reduce 'minpot'" quit(-1) while pot > minpot: if diff >= 10.**(pot-1): pot = np.floor(np.log10(diff)) potv = np.int(diff/(10.**pot)) # print 'Lluis:',np.log10(diff), pot,':',10.**pot,':',diff/(10.**pot),'.',potv,'.',potv*10.**pot,diff else: potv = 0 pot = pot - 1 # print 'Lluis:','*****', pot,':',10.**pot,':',diff/(10.**pot),'.',potv,'.',potv*10.**pot,diff diff = diff - potv*10.**pot # print ' real diff', diff potencies.append(pot) potval.append(potv) iipot = iipot + 1 return iipot, potencies, potval def unitsDate(refdate, date, units): """ Function to know how many units of time are from a given pair of dates refdate= date of reference (as [YYYY][MM][DD][HH][MI][SS]) date= date to look for (as [YYYY][MM][DD][HH][MI][SS]) units= units of time ('century', 'year', 'month', 'day', 'week', 'hour', 'minute', 'second') >>> unitsDate('19490101000000', '19760217082932', 'second') 856081772.0 >>> unitsDate('19490101000000', '19760217082932', 'minute') 237800.492222 """ import datetime as dt fname = 'unitsDate' yrref=int(refdate[0:4]) monref=int(refdate[4:6]) dayref=int(refdate[6:8]) horref=int(refdate[8:10]) minref=int(refdate[10:12]) secref=int(refdate[12:14]) yrd=int(date[0:4]) mond=int(date[4:6]) dayd=int(date[6:8]) hord=int(date[8:10]) mind=int(date[10:12]) secd=int(date[12:14]) refdateT = dt.datetime(yrref, monref, dayref, horref, minref, secref) ddateT = dt.datetime(yrd, mond, dayd, hord, mind, secd) diffT = ddateT - refdateT if searchInlist(dir(diffT), 'total_seconds'): totsecs = diffT.total_seconds() else: totsecs = diffT.days*24*3600. + diffT.seconds if units == 'century': times = totsecs / (100.*365.*24.*3600.) elif units == 'year': times = totsecs / (365.*24.*3600.) elif units == 'month': print errormsg print ' ' + fname + "' units '" + units + "' not ready!!" quit(-1) elif units == 'week': times = totsecs / (7.*24.*3600.) elif units == 'day': times = totsecs / (24.*3600.) elif units == 'hour': times = totsecs / (3600.) elif units == 'minute': times = totsecs / (3600.) elif units == 'second': times = totsecs / (1.) return times #print unitsDate('19490101000000', '19760217082932', 'second') #print unitsDate('19490101000000', '19760217082932', 'minute') def incomming_flow(dirs): """ Function to determine if a fgrid-flow inflows to the central grid point dirs = [3,3] matrix with the trip: (inflow directions) 1: N, 2: NE, 3: E, 4: SE, 5: S, 6: SW: 7: W, 8: NW being: 0,0: NW point, 0,1: N point, 0,2: NE point, 1,0: W point, 1,1: grid-point, 1,2: E point, 2,0: SW point, 2,1: S point, 2,2: SE point >>> dirflow = np.array([5, 5, 5, 98, 7, 7, 1, 1, 1], dtype=int).reshape(3,3) >>> print dirflow [[5 5 5] [98 7 7] [1 1 1]] >>> print incomming_flow(dirflow) [[False True False] [False False True] [False True False]] """ fname = 'incomming_flow' inflow = np.zeros((3,3), dtype=bool) rightinflow = np.zeros((3,3), dtype=int) rightinflow[0,0] = 4 rightinflow[0,1] = 5 rightinflow[0,2] = 6 rightinflow[1,0] = 3 rightinflow[1,1] = 0 rightinflow[1,2] = 7 rightinflow[2,0] = 2 rightinflow[2,1] = 1 rightinflow[2,2] = 8 inflow = np.where(dirs == rightinflow, True, False) return inflow def contflow(dirflow): """ Function to bring back the increment in j,i grid points according to a trip: (inflow directions) 1: N, 2: NE, 3: E, 4: SE, 5: S, 6: SW: 7: W, 8: NW >>> contflow(2) [1 1] >>> contflow(7) [0 -1] >>> contflow(98) [-1 -1] """ fname = 'contflow' inc = np.ones((2), dtype=int)*(-1) if dirflow == 1: #N inc[0] = 1 inc[1] = 0 elif dirflow == 2: #NE inc[0] = 1 inc[1] = 1 elif dirflow == 3: #E inc[0] = 0 inc[1] = 1 elif dirflow == 4: #SE inc[0] = -1 inc[1] = 1 elif dirflow == 5: #S inc[0] = -1 inc[1] = 0 elif dirflow == 6: #SW inc[0] = -1 inc[1] = -1 elif dirflow == 7: #W inc[0] = 0 inc[1] = -1 elif dirflow == 8: #NW inc[0] = 1 inc[1] = -1 else: # inc[0] = -1 inc[1] = -1 return inc def vals_around(vals,pt): """ Function to provide the 3x3 values around a given j,i point vals = matrix of values pt = j,i point to serch around >>> vals_around(np.arange(16).reshape(4,4), [3, 3]) [[10.0 11.0 None] [14.0 15.0 None] [None None None]] """ fname = 'vals_around' vals3x3 = np.array([None]*9).reshape(3,3) dx = vals.shape[1] dy = vals.shape[0] nx = np.max([0,pt[1]-1]) xx = np.min([dx-1,pt[1]+1]) + 1 ny = np.max([0,pt[0]-1]) xy = np.min([dy-1,pt[0]+1]) + 1 vals3x3[1-(pt[0]-ny):1+(xy-pt[0]),1-(pt[1]-nx):1+(xx-pt[1])] = vals[ny:xy,nx:xx] return vals3x3 def dictionary_key(dictv, val): """ Function to provide the first key in a dictionay with a given value ditcv= dictionary val= value to search >>> dictionary_key({'i': 1, 'ii': 2, 'iii': 3, 'iv': 4}, 3) 'iii' """ fname = 'dictionary_key' keyval = None for keyv in dictv.keys(): if dictv[keyv] == val: keyval = keyv break return keyval def dictionary_key_list(dictv, val): """ Function to provide the first key in a dictionay of lists with a given value ditcv= dictionary val= value to search >>> dictionary_key_list({'i': [1, 0, -1], 'ii': [2, 8, 16], 'iii': [-3, 3, 9], 'iv': [4]}, 3) 'iii' """ fname = 'dictionary_key' keyval = None for keyv in dictv.keys(): if searchInlist(dictv[keyv],val): keyval = keyv break return keyval def num_chainSnum(val): """ Function to pass a value to a `ChainStrNum' number `ChainStrNum:' hirerarchy classification where each levels is a significant number within a string: 1 lev.: [n] 2 lev.: [n][m] 3 lev.: [n][m][l] ... NOTE: when a given level has more than 9 values in a given potency of 10, then 'a' is attached in the front: 'a'[i] NOTE: when a given level has more than 19 values in a given potency of 10, then 'b' is attached in the front: 'b'[i] NOTE: when a given level has more than 29 values in a given potency of 10, then 'c' is attached in the front: 'c'[i] (...) NOTE: when a given level has more than 89 values in a given potency of 10, then 'i' is attached in the front: 'i'[i] NOTE: 'o' is for that potencies of 10 without value val = value to transform >>> num_chainSnum(3) 3 >>> num_chainSnum(1976) aig6 >>> num_chainSnum(12010) aboa0 """ fname = 'num_chainSnum' npot = np.int(np.log10(val)) chainSnum='' if npot > 0: Nvals, pots, vals = significant_decomposition(val,0) rest = 0 for ipot in range(npot): rest = rest + int(vals[ipot]*10**pots[ipot]) if vals[ipot] > 0: chainSnum = chainSnum + chr(96+vals[ipot]) else: chainSnum = chainSnum + 'o' num = val - rest else: num = val chainSnum = chainSnum + str(num) return chainSnum def chainSnum_num(cSnum): """ Function to pass a `ChainStrNum' string to number `ChainStrNum:' hierarchy classification where each levels is a significant number within a string: 1 lev.: [n] 2 lev.: [n][m] 3 lev.: [n][m][l] ... NOTE: when a given level has more than 9 values in a given potency of 10, then 'a' is attached in the front: 'a'[i] NOTE: when a given level has more than 19 values in a given potency of 10, then 'b' is attached in the front: 'b'[i] NOTE: when a given level has more than 29 values in a given potency of 10, then 'c' is attached in the front: 'c'[i] (...) NOTE: when a given level has more than 89 values in a given potency of 10, then 'i' is attached in the front: 'i'[i] NOTE: 'o' is for that potencies of 10 without value cSnum = value to transform >>> num_chainSnum('3') 3 >>> num_chainSnum('aig6') 1976 >>> num_chainSnum('aboa0') 12010 """ fname = 'chainSnum_num' num = 0 LcSnum = len(cSnum) if LcSnum > 1: for ic in range(LcSnum-1): ipot = ord(cSnum[ic:ic+1]) - 96 if ipot < 0 or ipot > 9 and ipot != ord('o') - 96: print errormsg print ' ' + fname + ": wrong character '" + cSnum[ic:ic+1] + "' !!", ipot print " 'ChainStrNum' codification only allows 'a' to 'i' and 'o'" quit(-1) else: if ipot == ord('o') - 96: ipot = 0 num = num + int(ipot*10**(LcSnum-ic-1)) num = num + int(cSnum[LcSnum-1:LcSnum]) return num def num_split(string): """ Function to split a string at each numeric value keeping the number as the last character of each cut string= string to cut >>> num_split('asd123asdsa1') ['asd1', '2', '3', 'asdsa1'] """ fname = 'num_split' Lstring = len(string) cuts = [] newcut = '' for ic in range(Lstring): sc = string[ic:ic+1] newcut = newcut + sc if ord(sc) >= 48 and ord(sc) <= 57: cuts.append(newcut) newcut = '' return cuts def chainSnum_levnext(parentlev, ChainStrNums): """ Function to provide the next value for a given level from a chainStrnum hirerarchy of numbers prevlev: parent level of the desired level ChainStrNums: list of strings as `ChainStrNum' `ChainStrNum:' hierarchyc classification where each levels is a significant number within a string: 1 lev.: [n] 2 lev.: [n][m] 3 lev.: [n][m][l] ... NOTE: when a given level has more than 9 values in a given potency of 10, then 'a' is attached in the front: 'a'[i] NOTE: when a given level has more than 19 values in a given potency of 10, then 'b' is attached in the front: 'b'[i] NOTE: when a given level has more than 29 values in a given potency of 10, then 'c' is attached in the front: 'c'[i] (...) NOTE: when a given level has more than 89 values in a given potency of 10, then 'i' is attached in the front: 'i'[i] NOTE: 'o' is for that potencies of 10 without value >>> ChainStrNums = ['1', '2', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1a0', '111', '112', '113', '121', '122' ] >>> chainSnum_levnext('',ChainStrNums) 3 >>> chainSnum_levnext('1',ChainStrNums) 1a1 >>> chainSnum_levnext('12',ChainStrNums) 123 >>> chainSnum_levnextt('111',ChainStrNums) 1111 """ fname = 'chainSnum_levnext' # Number of levels of the parent level if len(parentlev) > 0: parentlevs = num_split(parentlev) Nparentlevs = len(parentlevs) else: parentlevs = [''] Nparentlevs = 0 # print ' ' + fname + ' parentlev:', parentlev,'Nlevs:', Nparentlevs,'parentlevs:',parentlevs # Level to increment lev = Nparentlevs + 1 rightvals = [] for istr in ChainStrNums: levs = num_split(istr) if len(levs) == lev: parent = '' for ilev in range(len(levs)-1): parent = parent + levs[ilev] if parent == parentlev: rightvals.append(chainSnum_num(levs[lev-1])) if len(rightvals) > 0: newnum = np.max(rightvals) newchainSnum = num_chainSnum(newnum + 1) else: newchainSnum = '1' return parentlev + newchainSnum class chainSnumHierarchy(object): """ Function to provide the structure of a `ChainStrNum' hierarchy ChainStrNums: list of strings as `ChainStrNum' Nlevs: number of levels levs: all the strings xlevs: list with the maximum number of each level Llev[N]: numbers of values in level N (up to 10 levels) xlev[N]: maximun numbers of a level N (up to 10 levels) Slev[N]: strings of level N (up to 10 levels) Nlev[N]: numbers of level N (up to 10 levels) # methods levincr([ChainStrNum]): method to increase `ChainStrNum' level `ChainStrNum:' hierarchyc classification where each levels is a significant number within a string: 1 lev.: [n] 2 lev.: [n][m] 3 lev.: [n][m][l] ... NOTE: when a given level has more than 9 values in a given potency of 10, then 'a' is attached in the front: 'a'[i] NOTE: when a given level has more than 19 values in a given potency of 10, then 'b' is attached in the front: 'b'[i] NOTE: when a given level has more than 29 values in a given potency of 10, then 'c' is attached in the front: 'c'[i] (...) NOTE: when a given level has more than 89 values in a given potency of 10, then 'i' is attached in the front: 'i'[i] NOTE: 'o' is for that potencies of 10 without value """ fname = 'chainSnumHierarchy' def __init__(self,ChainStrNums): self.Nchars = len(ChainStrNums) self.Nlevs = 0 self.levs = [] self.xlevs = [] self.Llev1 = None self.Llev2 = None self.Llev3 = None self.Llev4 = None self.Llev5 = None self.Llev6 = None self.Llev7 = None self.Llev8 = None self.Llev9 = None self.Llev10 = None self.xlev1 = None self.xlev2 = None self.xlev3 = None self.xlev4 = None self.xlev5 = None self.xlev6 = None self.xlev7 = None self.xlev8 = None self.xlev9 = None self.xlev10 = None self.Slev1 = [] self.Slev2 = [] self.Slev3 = [] self.Slev4 = [] self.Slev5 = [] self.Slev6 = [] self.Slev7 = [] self.Slev8 = [] self.Slev9 = [] self.Slev10 = [] self.Nlev1 = [] self.Nlev2 = [] self.Nlev3 = [] self.Nlev4 = [] self.Nlev5 = [] self.Nlev6 = [] self.Nlev7 = [] self.Nlev8 = [] self.Nlev9 = [] self.Nlev10 = [] levsNvals = np.zeros((11,self.Nchars), dtype=int) ilevvals = np.zeros((11), dtype=int) xtrmlevs = [] Svals1 = [] Svals2 = [] Svals3 = [] Svals4 = [] Svals5 = [] Svals6 = [] Svals7 = [] Svals8 = [] Svals9 = [] Svals10 = [] for istr in ChainStrNums: levs = num_split(istr) Nlevs = len(levs) if Nlevs > self.Nlevs: self.Nlevs = Nlevs if Nlevs > 10: print errormsg print ' ' + fname + ': too levels:', Nlevs, " in StringNum '" + \ istr + "' !!" print ' increase in the code the number of levels in the class' quit(-1) ilevvals[Nlevs] = ilevvals[Nlevs] + 1 if Nlevs == 1: Svals1.append(istr) if Nlevs == 2: Svals2.append(istr) if Nlevs == 3: Svals3.append(istr) if Nlevs == 4: Svals4.append(istr) if Nlevs == 5: Svals5.append(istr) if Nlevs == 6: Svals6.append(istr) if Nlevs == 7: Svals7.append(istr) if Nlevs == 8: Svals8.append(istr) if Nlevs == 9: Svals9.append(istr) if Nlevs == 10: Svals10.append(istr) levsNvals[Nlevs,ilevvals[Nlevs]] = chainSnum_num(levs[Nlevs-1]) valslist = ChainStrNums.sort() self.levs = valslist # 1st lev self.Llev1 = ilevvals[1] Svlist = Svals1 Nvlist = list(levsNvals[1,1:self.Llev1+1]) self.xlev1 = np.max(Nvlist) xtrmlevs.append(self.xlev1) Svlist.sort() Nvlist.sort() self.Slev1 = Svlist self.Nlev1 = Nvlist # 2nd lev if self.Nlevs > 1: self.Llev2 = ilevvals[2] Svlist = Svals2 Nvlist = list(levsNvals[2,1:self.Llev2+1]) self.xlev2 = np.max(Nvlist) xtrmlevs.append(self.xlev2) Svlist.sort() Nvlist.sort() self.Slev2 = Svlist self.Nlev2 = Nvlist # 3rd lev if self.Nlevs > 2: self.Llev3 = ilevvals[3] Svlist = Svals3 Nvlist = list(levsNvals[3,1:self.Llev3+1]) self.xlev3 = np.max(Nvlist) xtrmlevs.append(self.xlev3) Svlist.sort() Nvlist.sort() self.Slev3 = Svlist self.Nlev3 = Nvlist # 4th lev if self.Nlevs > 3: self.Llev4 = ilevvals[4] Svlist = Svals4 Nvlist = list(levsNvals[4,1:self.Llev4+1]) self.xlev4 = np.max(Nvlist) xtrmlevs.append(self.xlev4) Svlist.sort() Nvlist.sort() self.Slev4 = Svlist self.Nlev4 = Nvlist # 5th lev if self.Nlevs > 4: self.Llev5 = ilevvals[5] Svlist = Svals5 Nvlist = list(levsNvals[5,1:self.Llev5+1]) self.xlev5 = np.max(Nvlist) xtrmlevs.append(self.xlev5) Svlist.sort() Nvlist.sort() self.Slev5 = Svlist self.Nlev5 = Nvlist # 6th lev if self.Nlevs > 5: self.Llev6 = ilevvals[6] Svlist = Svals6 Nvlist = list(levsNvals[6,1:self.Llev6+1]) self.xlev6 = np.max(Nvlist) xtrmlevs.append(self.xlev6) Svlist.sort() Nvlist.sort() self.Slev6 = Svlist self.Nlev6 = Nvlist # 7th lev if self.Nlevs > 6: self.Llev7 = ilevvals[7] Svlist = Svals7 Nvlist = list(levsNvals[7,1:self.Llev7+1]) self.xlev7 = np.max(Nvlist) xtrmlevs.append(self.xlev7) Svlist.sort() Nvlist.sort() self.Slev7 = Svlist self.Nlev7 = Nvlist # 8th lev if self.Nlevs > 7: self.Llev8 = ilevvals[8] Svlist = Svals8 Nvlist = list(levsNvals[8,1:self.Llev8+1]) self.xlev8 = np.max(Nvlist) xtrmlevs.append(self.xlev8) Svlist.sort() Nvlist.sort() self.Slev8 = Svlist self.Nlev8 = Nvlist # 9th lev if self.Nlevs > 9: self.Llev9 = ilevvals[9] Svlist = Svals9 Nvlist = list(levsNvals[9,1:self.Llev9+1]) self.xlev9 = np.max(Nvlist) xtrmlevs.append(self.xlev9) Svlist.sort() Nvlist.sort() self.Slev9 = Svlist self.Nlev9 = Nvlist # 10th lev if self.Nlevs > 9: self.Llev10 = ilevvals[10] Svlist = Svals10 Nvlist = list(levsNvals[10,1:self.Llev10+1]) self.xlev10 = np.max(Nvlist) xtrmlevs.append(self.xlev10) Svlist.sort() Nvlist.sort() self.Slev10 = Svlist self.Nlev10 = Nvlist self.xlevs = xtrmlevs def levincr(self,plev): """ Method to increase a given plevel level levincr(self,plev): >>> ChainStrNums = ['1', '2', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1a0', '111', '112', '113', '121', '122' ] >>> CSN_hyr = chainSnumHierarchy(ChainStrNums) >>> CSN_hyr.levincr('11') 114 """ return chainSnum_levnext(plev, ChainStrNums) #ChainStrNums = ['1', '2', '11', '12', '13', '14', '15', '16', '17', '18', '19', '1a0', '111', '112', '113', '121', '122' ] #CSN_hyr = chainSnumHierarchy(ChainStrNums) #print CSN_hyr.levincr.__doc__ #quit() def index_mat_way(mat,val,way): """ Function to look for a value within a matrix following a way and direction mat: matrix val: value to search way: way of search 'anticlockwise12': looking in an anti-clockwise direction starting at 12 'anticlockwise6': looking in an anti-clockwise direction starting at 6 'clockwise12': looking in an clockwise direction starting at 12 'clockwise6': looking in an clockwise direction starting at 6 >>> mat = np.arange(20).reshape(4,5) >>> mat[2,1] = 3 >>> index_mat_way(mat,3,'clockwise12') [array([0, 3]), array([2, 1])] >>> index_mat_way(mat,3,'anticlockwise12') [array([2, 1]), array([0, 3])] """ fname = 'index_mat_way' ways = ['anticlockwise12', 'anticlockwise6', 'clockwise12', 'clockwise6'] Ndims = len(mat.shape) dx = mat.shape[Ndims-1] dy = mat.shape[Ndims-2] diffmat = np.abs(mat - val) mindiff = np.min(diffmat) if np.sum(diffmat == mindiff) == 1: ijindex = index_mat(diffmat,mindiff) return ijindex if Ndims > 2: dz = mat.shape[Ndims-3] if Ndims > 3: dt = mat.shape[Ndims-4] if way == 'anticlockwise12': # Sorting following a double criteria, first angle and then distance taken from the # center in the anti-clockwise direction starting at 12 if Ndims > 2: print errormsg print ' ' + fame + ': wiht more than 2-dims:', Ndims, "'" + way + \ "' is not possible !!" quit(-1) distrad = radius_dist(dx,dy,dx/2,dy/2) distangle = radius_angle(dx,dy,dx/2,dy/2) distangle = np.where(distangle >= np.pi, distangle - 2.*np.pi, distangle) distangle = np.where(distangle > 0., 2.* np.pi - distangle, -distangle) sortedij = {} minangle = 10000. notfound = np.zeros((dy,dx), dtype=bool) maskdistrad = ma.array(distrad, mask=notfound) maskdistangle = ma.array(distangle, mask=notfound) for ip in range(dx*dy): minangle = np.min(maskdistangle) jiangle = multi_index_mat(maskdistangle, minangle) mindist = 10000. for ia in range(len(jiangle)): iaji = jiangle[ia] if maskdistrad[iaji[0], iaji[1]] < mindist: mindist = maskdistrad[iaji[0], iaji[1]] idistangle = iaji notfound[idistangle[0],idistangle[1]] = True sortedij[ip] = idistangle elif way == 'anticlockwise6': # Sorting following a double criteria, first angle and then distance taken from the # center in the anti-clockwise direction starting at 6 if Ndims > 2: print errormsg print ' ' + fame + ': wiht more than 2-dims:', Ndims, "'" + way + \ "' is not possible !!" quit(-1) distrad = radius_dist(dx,dy,dx/2,dy/2) distangle = radius_angle(dx,dy,dx/2,dy/2) distangle = np.where(distangle > np.pi, distangle - 2.*np.pi, distangle) distangle = np.where(distangle >= 0., np.pi - distangle, np.pi-distangle) sortedij = {} minangle = 10000. notfound = np.zeros((dy,dx), dtype=bool) maskdistrad = ma.array(distrad, mask=notfound) maskdistangle = ma.array(distangle, mask=notfound) for ip in range(dx*dy): minangle = np.min(maskdistangle) jiangle = multi_index_mat(maskdistangle, minangle) mindist = 10000. for ia in range(len(jiangle)): iaji = jiangle[ia] if maskdistrad[iaji[0], iaji[1]] < mindist: mindist = maskdistrad[iaji[0], iaji[1]] idistangle = iaji notfound[idistangle[0],idistangle[1]] = True sortedij[ip] = idistangle elif way == 'clockwise12': # Sorting following a double criteria, first angle and then distance taken from the # center in the cloc-kwise direction starting at 12 if Ndims > 2: print errormsg print ' ' + fame + ': wiht more than 2-dims:', Ndims, "'" + way + \ "' is not possible !!" quit(-1) distrad = radius_dist(dx,dy,dx/2,dy/2) distangle = radius_angle(dx,dy,dx/2,dy/2) sortedij = {} minangle = 10000. notfound = np.zeros((dy,dx), dtype=bool) maskdistrad = ma.array(distrad, mask=notfound) maskdistangle = ma.array(distangle, mask=notfound) for ip in range(dx*dy): minangle = np.min(maskdistangle) jiangle = multi_index_mat(maskdistangle, minangle) mindist = 10000. for ia in range(len(jiangle)): iaji = jiangle[ia] if maskdistrad[iaji[0], iaji[1]] < mindist: mindist = maskdistrad[iaji[0], iaji[1]] idistangle = iaji notfound[idistangle[0],idistangle[1]] = True sortedij[ip] = idistangle elif way == 'clockwise6': # Sorting following a double criteria, first angle and then distance taken from the # center in the clockwise direction starting at 6 if Ndims > 2: print errormsg print ' ' + fame + ': wiht more than 2-dims:', Ndims, "'" + way + \ "' is not possible !!" quit(-1) distrad = radius_dist(dx,dy,dx/2,dy/2) distangle = radius_angle(dx,dy,dx/2,dy/2) distangle = np.where(distangle >= np.pi, distangle - 2.*np.pi, distangle) distangle = np.where(distangle > 0., np.pi + distangle, np.pi+distangle) sortedij = {} minangle = 10000. notfound = np.zeros((dy,dx), dtype=bool) maskdistrad = ma.array(distrad, mask=notfound) maskdistangle = ma.array(distangle, mask=notfound) for ip in range(dx*dy): minangle = np.min(maskdistangle) jiangle = multi_index_mat(maskdistangle, minangle) mindist = 10000. for ia in range(len(jiangle)): iaji = jiangle[ia] if maskdistrad[iaji[0], iaji[1]] < mindist: mindist = maskdistrad[iaji[0], iaji[1]] idistangle = iaji notfound[idistangle[0],idistangle[1]] = True sortedij[ip] = idistangle else: print errormsg print ' ' + fname + ": way of search '" + way + "' not ready !!" print ' available ways:', ways indices = [] for ij in range(dx*dy): sij = sortedij[ij] sval = mat[sij[0], sij[1]] if sval == val: indices.append(sij) return indices def subbasin_point_orig(trips, pt): """ Function to provide sub-basins given a grid point following a matrix of trips trips= matrix of trips values 1: N, 2: NE, 3: E, 4: SE, 5: S, 6: SW: 7: W, 8: NW pt= point within the trip matrix """ fname = 'subbasin_point' subbasin = np.zeros((trips.shape), dtype=bool) TOTtrips = len(trips.flatten()) # Dictionary with the j,i points of all the subbasin ijsubbasin = {} # Dictionary to tell if a given j,i sub-basin point has been localized (as number from ijsubbasin) ijfound = {} # Dictionary to tell if a given sub-flow has been finished (when Narrive == 0) subfinished = {} # Dictionary with the list of points which are contained in a sub-flow ijsubflow = {} # Number of ji sub-basin points Nij = 1 subbasin[pt[0], pt[1]] = True ijsubbasin[Nij] = np.array(pt) ijfound[Nij] = False ijsubflow[str(Nij)] = [Nij] subfinished[str(Nij)] = False # Loop around all sub-flows ## while np.sum(subfinished.values) != 0 and np.sum(ijfound.values) != 0: Njipt = dictionary_key(subfinished, False) if Njipt is not None: # print Njipt, 'points subflow:', ijsubflow[Njipt] for ipt in ijsubflow[Njipt]: if ijfound[ipt] == False: jipt = ijsubbasin[ipt] break # print ' working from point:', ipt, 'ji pair:', jipt ijfound[ipt] = True Nij = ipt else: # Keep searching since there are grid-points not found! # print ' ' + fname + ': Keep searching since there are grid-points not found!!' # print ijfound Nij = dictionary_key(ijfound, False) if Nij is None: return subbasin, ijsubflow, ijsubbasin ijfound[Nij] = True jipt = ijsubbasin[Nij] parentNjipt = dictionary_key_list(ijsubflow, Nij) Njipt = chainSnum_levnext(parentNjipt, ijsubflow.keys()) # print ' ' + fname + "new sub-flow '" + Njipt + "' !!" subfinished[Njipt] = False Nij = np.max(ijfound.keys()) # print 'Lluis Nij:', Nij # Looking for which point of the sub-flow retake the search if Nij == 1: ipt = 1 jipt = pt ardtrips = vals_around(trips,jipt) # print ' ' + fname + 'ardtrips _______' # print ardtrips arrive = incomming_flow(ardtrips) Narrive = np.sum(arrive) # print Nij, ' ' + fname + ' Narrive:', Narrive if Narrive == 0: ijfound[Nij] = True subfinished[Njipt] = True else: # print ' ' + fname + 'arrive _______' # print arrive followvals = np.zeros((3,3), dtype=bool) followvals = arrive parentNjipt = Njipt for ifollow in range(Narrive): # print 'ifollow:',ifollow,'/',Narrive # We only want to work with that ij, which have not yet been found while np.sum(followvals) != 0: # print Nij,' Looking for a non-located point in subbasin ________' # print subbasin[jipt[0]-1:jipt[0]+2,jipt[1]-1:jipt[1]+2] jifollow = index_mat(followvals, True) jiequiv = jifollow - [1,1] if subbasin[jipt[0]+jiequiv[0], jipt[1]+jiequiv[1]] == False: Nij = np.max(ijfound.keys()) + 1 jiptnew = jipt + jiequiv if ifollow != 0: # Avoiding repetition of sub-flow name if len(ijsubflow.keys()) > 1: Njipt = chainSnum_levnext(parentNjipt, ijsubflow.keys()) else: Njipt = '11' else: Njipt = parentNjipt # print ' ' + fname + "new sub-flow '" + Njipt + "' !!" subfinished[Njipt] = False subbasin[jipt[0]+jiequiv[0], jipt[1]+jiequiv[1]] = True ijfound[Nij] = False ijsubbasin[Nij] = jiptnew if ijsubflow.has_key(Njipt): subflowpts = ijsubflow[Njipt] subflowpts.append(Nij) ijsubflow[Njipt] = subflowpts else: ijsubflow[Njipt] = [Nij] break else: followvals[jifollow[0],jifollow[1]] = False if np.sum(followvals) == 0: ijfound[Nij] = True subfinished[Njipt] = True # print Nij," subflow '" + Njipt + "' finished!!" break if Nij > TOTtrips: print errormsg print ' ' + fname + ': sub-flow point', Nij, 'larger than ' + \ 'the number of trips', TOTtrips,'!!' quit() # if ijsubflow.has_key(Njipt): # print "Lluis points of subflow: '" + Njipt + "' _______=", ijsubflow[Njipt] # for isub in ijsubflow[Njipt]: # print ' ' , isub , ':', ijsubbasin[isub], ijfound[isub] # if Nij == 10: print 'Nij = 9:', ijfound[9] # print subbasin # if Nij > 4: quit() return subbasin def subbasin_point(trips, pt, direction): """ Function to provide sub-basins given a grid point following a matrix of trips trips= matrix of trips values 1: N, 2: NE, 3: E, 4: SE, 5: S, 6: SW: 7: W, 8: NW pt= point within the trip matrix direction= searching direction river-up ('left': clockwise, 'right': anti-clockwise) """ fname = 'subbasin_point' subbasin = np.zeros((trips.shape), dtype=bool) TOTtrips = len(trips.flatten()) # Dictionary with the j,i points of all the subbasin ijsubbasin = {} # Dictionary to tell if a given j,i sub-basin point has been localized (as number from ijsubbasin) ijfound = {} # Dictionary to tell if a given sub-flow has been finished (when Narrive == 0) subfinished = {} # Dictionary with the list of points which are contained in a sub-flow ijsubflow = {} # Number of ji sub-basin points Nij = 1 subbasin[pt[0], pt[1]] = True ijsubbasin[Nij] = np.array(pt) ijfound[Nij] = False ijsubflow[str(Nij)] = [Nij] subfinished[str(Nij)] = False # Loop around all sub-flows ## while np.sum(subfinished.values) != 0 and np.sum(ijfound.values) != 0: Njipt = dictionary_key(subfinished, False) if Njipt is not None: # print Njipt, 'points subflow:', ijsubflow[Njipt] for ipt in ijsubflow[Njipt]: if ijfound[ipt] == False: jipt = ijsubbasin[ipt] break # print ' working from point:', ipt, 'ji pair:', jipt ijfound[ipt] = True Nij = ipt else: # Keep searching since there are grid-points not found! # print ' ' + fname + ': Keep searching since there are grid-points not found!!' # print ijfound Nij = dictionary_key(ijfound, False) if Nij is None: return subbasin, ijsubflow, ijsubbasin ijfound[Nij] = True jipt = ijsubbasin[Nij] parentNjipt = dictionary_key_list(ijsubflow, Nij) Njipt = chainSnum_levnext(parentNjipt, ijsubflow.keys()) # print ' ' + fname + "new sub-flow '" + Njipt + "' !!" subfinished[Njipt] = False Nij = np.max(ijfound.keys()) # print 'Lluis Nij:', Nij # Looking for which point of the sub-flow retake the search if Nij == 1: ipt = 1 jipt = pt ardtrips = vals_around(trips,jipt) # print ' ' + fname + 'ardtrips _______' # print ardtrips arrive = incomming_flow(ardtrips) Narrive = np.sum(arrive) # print Nij, ' ' + fname + ' Narrive:', Narrive if Narrive == 0: ijfound[Nij] = True subfinished[Njipt] = True else: # print ' ' + fname + 'arrive _______' # print arrive followvals = np.zeros((3,3), dtype=bool) followvals = arrive parentNjipt = Njipt for ifollow in range(Narrive): # print 'ifollow:',ifollow,'/',Narrive # We only want to work with that ij, which have not yet been found while np.sum(followvals) != 0: # print Nij,' Looking for a non-located point in subbasin ________' # print subbasin[jipt[0]-1:jipt[0]+2,jipt[1]-1:jipt[1]+2] # Searching direction river-up. 'left': starting from the left, 'right' starting from the right if direction == 'left': jifollow0 = index_mat_way(followvals, True, 'clockwise6') elif direction == 'right': jifollow0 = index_mat_way(followvals, True, 'anticlockwise6') if len(jifollow0) > 1 and type(jifollow0) == type([2]): jifollow = jifollow0[0] else: jifollow = jifollow0 ## orig ## jifollow = index_mat(followvals, True) jiequiv = jifollow - [1,1] if subbasin[jipt[0]+jiequiv[0], jipt[1]+jiequiv[1]] == False: Nij = np.max(ijfound.keys()) + 1 jiptnew = jipt + jiequiv if ifollow != 0: # Avoiding repetition of sub-flow name if len(ijsubflow.keys()) > 1: Njipt = chainSnum_levnext(parentNjipt, ijsubflow.keys()) else: Njipt = '11' else: Njipt = parentNjipt # print ' ' + fname + "new sub-flow '" + Njipt + "' !!" subfinished[Njipt] = False subbasin[jipt[0]+jiequiv[0], jipt[1]+jiequiv[1]] = True ijfound[Nij] = False ijsubbasin[Nij] = jiptnew if ijsubflow.has_key(Njipt): subflowpts = ijsubflow[Njipt] subflowpts.append(Nij) ijsubflow[Njipt] = subflowpts else: ijsubflow[Njipt] = [Nij] break else: followvals[jifollow[0],jifollow[1]] = False if np.sum(followvals) == 0: ijfound[Nij] = True subfinished[Njipt] = True # print Nij," subflow '" + Njipt + "' finished!!" break if Nij > TOTtrips: print errormsg print ' ' + fname + ': sub-flow point', Nij, 'larger than ' + \ 'the number of trips', TOTtrips,'!!' quit() # if ijsubflow.has_key(Njipt): # print "Lluis points of subflow: '" + Njipt + "' _______=", ijsubflow[Njipt] # for isub in ijsubflow[Njipt]: # print ' ' , isub , ':', ijsubbasin[isub], ijfound[isub] # if Nij == 10: print 'Nij = 9:', ijfound[9] # print subbasin # if Nij > 4: quit() return subbasin ## Caceres #rivers = np.array([7, 1, 1, 1, 1, 5, 5, 1, \ # 7, 1, 6, 3, 5, 5, 6, 5, \ # 8, 7, 5, 3, 5, 6, 3, 5, \ # 1, 1, 3, 5, 5, 7, 5, 5, \ # 3, 3, 5, 6, 5, 5, 5, 7 ], dtype=int).reshape(5,8) #point = [4,4] # Porto Do Alegre #rivers = np.array([5, 5, 1, 7, 1, 8, 8, 2, \ # 5, 6, 5, 7, 7, 1, 3, 1, \ # 6, 3, 5, 1, 3, 3, 3, 3, \ # 7, 5, 5, 5, 5, 5, 5, 1, \ # 5, 5, 7, 7, 7, 6, 7, 7, \ # 5, 5, 7, 7, 7, 7, 8, 7, \ # 6, 6, 7, 7, 7, 7, 7, 7, \ # 5, 7, 7, 7, 8, 7, 7, 6, \ # 6, 7, 7, 7, 7, 7, 7, 6], dtype=int).reshape(9,8) #point = [7,0] #print rivers #print rivers[point[0], point[1]] #direc = 'left' #masksubbasin, subflows, subflowspt = subbasin_point_dir(rivers, point, 'right') #print rivers #print masksubbasin #for subflow in subflows: # print subflow, ':', subflows[subflow] # for isub in subflows[subflow]: # print ' ' , isub , ':', subflowspt[isub] #print 'Total sub-basin:', np.sum(masksubbasin) #quit() def color_deg(colors, Nsteps, typedeg, values=None): """ Function to generate a degradation of colors in rgb base colors= list of colors to use [r,g,b] r,g,b <= 1. Nsteps= number of steps (NOTE: final number of colors might differ from this value) typedeg= type of degradate 'std': simple linear degradation between equi-spaced colors 'vals': change of colors at a given value (it requires [values]) values= list of values to use as reference (when applicable) provides: [colordeg], [Ncolors] [colordeg] = (4, [Ncolors]) matrix with [0,:]= assigned value to the color (for 'std': counter) [1:4,:]= r,g,b color >>> color_deg([ [1.,0.,0.], [0.,1.,0.], [0.,0.,1.] ], 10, 'std') [[ 0. 0.125 0.25 0.375 0.5 0.625 0.75 0.875 1. ] [ 1. 0.75 0.5 0.25 0. 0. 0. 0. 0. ] [ 0. 0.25 0.5 0.75 1. 0.75 0.5 0.25 0. ] [ 0. 0. 0. 0. 0. 0.25 0.5 0.75 1. ]] defcolors = color_deg([ [1.,0.,0.], [0.,1.,0.], [0.,0.,1.]], 12, 'vals', [-3., 0., 3.]) [[-3. -2.4 -1.8 -1.2 -0.6 0. 0.6 1.2 1.8 2.4 3. ] [ 1. 0.8 0.6 0.4 0.2 0. 0. 0. 0. 0. 0. ] [ 0. 0.2 0.4 0.6 0.8 1. 0.8 0.6 0.4 0.2 0. ] [ 0. 0. 0. 0. 0. 0. 0.2 0.4 0.6 0.8 1. ]] """ fname = 'color_deg' colordeg = np.zeros((4,Nsteps), dtype=np.float) Ncols = len(colors) cols = np.zeros((3,Ncols), dtype=np.float) for icol in range(Ncols): cols[:,icol] = np.array(colors[icol]) if Ncols > Nsteps: print warnmsg print ' ' + fname + ': too few steps:', Nsteps, 'for the number of colors:',\ Ncols,'!!' print ' directly assigning the given color' Nfincol = Nsteps if Nsteps > 1: for istp in range(Nsteps): colordeg[0,istp] = istp / (Nsteps-1.) colordeg[1:4,istp] = cols[:,istp] else: colordeg[0,0] = 1. colordeg[1:4,0] = cols[:,0] else: if typedeg == 'std': Nstepcols = np.int(Nsteps*1. / (Ncols-1.)) iicol = 0 for icol in range(Ncols-1): dcolors = (cols[:,icol+1]- cols[:,icol])/(Nstepcols-1.) # Toavoid repetition of the color if icol == 0: ibeg = 0 else: ibeg = 1 for i in range(ibeg,Nstepcols): colordeg[0,iicol] = iicol*1. colordeg[1:4,iicol] = cols[:,icol] + dcolors*i iicol = iicol + 1 Nfincol = iicol-1 colordeg[0,:] = colordeg[0,:]/(Nfincol*1.) elif typedeg == 'vals': if values is None: print errormsg print ' ' + fname + ": type '" + typedeg + "' require values !!" quit(-1) Nvals = len(values) if Nvals != Ncols: print errormsg print ' ' + fname + ': different number of values:', Nvals, \ 'and colors:', Ncols, '!!' print ' provided values:', values print ' provided colors:', cols quit(-1) TOTrange = values[Nvals-1] - values[0] iicol = 0 for icol in range(Ncols-1): pairange = values[icol+1] - values[icol] drange = pairange / TOTrange Nstepcols = np.int(Nsteps*drange) dcolors = (cols[:,icol+1]-cols[:,icol])/(Nstepcols-1.) # To avoid repetition of the color if icol == 0: ibeg = 0 else: ibeg = 1 for i in range(ibeg,Nstepcols): colordeg[0,iicol] = values[icol]+i*pairange/(Nstepcols-1) colordeg[1:4,iicol] = cols[:,icol] + dcolors*i iicol = iicol + 1 Nfincol = iicol - 1 else: print errormsg print ' ' + fname + ": degradation type '" + typedeg + "' not ready !!" quit(-1) degcolor = np.zeros((4,Nfincol), dtype=np.float) degcolor = colordeg[:,0:Nfincol+1] return degcolor def colhex_dec(col): """ Function to pas a hexadecimal (#[RR][GG][BB]; 00-64, 0A-FF) color to decimal ([0.,1.]) col= '#'[RR][GG][BB] hexadecimal color string >>>colhex_dec('#000000') [0.0, 0.0, 0.0] >>>colhex_dec('#00FF00') [0.0, 1.0, 0.0] >>>colhex_dec('#3264EE') [0.19607843137254902, 0.39215686274509803, 0.9333333333333333] """ fname = 'colhex_dec' hexred = col[1:3] hexgreen = col[3:5] hexblue = col[5:7] deccol = [int(hexred, 16)/255., int(hexgreen, 16)/255., int(hexblue, 16)/255.,] return deccol def coldec_hex(col): """ Function to pas a decimal ([r,g,b]; [0.,1.]) color to hexadecimal (#[RR][GG][BB], 00-64, 0A-FF) col= '#'[RR][GG][BB] hexadecimal color string >>>coldec_hex([0.0, 0.0, 0.0]) #000000 >>>coldec_hex([0.0, 1.0, 0.0]) #00FF00 >>>coldec_hex([0.19607843137254902, 0.39215686274509803, 0.9333333333333333]) #3264EE """ fname = 'coldec_hex' hexred = '{0:X}'.format(int(col[0]*255)) hexgreen = '{0:X}'.format(int(col[1]*255)) hexblue = '{0:X}'.format(int(col[2]*255)) if hexred == '0': hexred = '00' if hexgreen == '0': hexgreen = '00' if hexblue == '0': hexblue = '00' hexcol = '#' + hexred + hexgreen + hexblue return hexcol def str_list(string, cdiv): """ Function to obtain a list from a string givin a split character string= String from which to obtain a list ('None' for None) cdiv= character to use to split the string >>> str_list('1:@#:$:56', ':') ['1', '@#', '$', '56'] >>> str_list('1@#$56', ':') ['1@#$56'] """ fname = 'str_list' if string.find(cdiv) != -1: listv = string.split(cdiv) else: if string == 'None': listv = None else: listv = [string] return listv def str_list_k(string, cdiv, kind): """ Function to obtain a list of types of values from a string giving a split character string= String from which to obtain a list ('None' for None) cdiv= character to use to split the string kind= kind of desired value (as string like: 'np.float', 'int', 'np.float64', ....) >>> str_list_k('1:@#:$:56', ':', 'S') ['1', '@#', '$', '56'] >>> str_list_k('1:3.4:12.3', ':', 'np.float64') [1.0, 3.3999999999999999, 12.300000000000001] """ fname = 'str_list' if string.find(cdiv) != -1: listv = string.split(cdiv) else: if string == 'None': listv = None else: listv = [string] if listv is not None: finalist = [] for lv in listv: finalist.append(typemod(lv, kind)) else: finallist = None return finalist def stagger_unstagger(varv, dndims, udims): """ Function to de-stagger a variable varv= values of the variable to de-stagger dndims = dn[x/y/z/t] list of the names of the dimenions of the variable udims = ud[x/y/z/t] unstaggered dictionary with the dimenions of the variable >>> mat = np.arange((20), dtype=np.float).reshape(5,4) >>> dmat = ['dystaggered','dx'] >>> unstagdims = {'dy': 4, 'dx': 4} >>> stagger_unstagger(mat, dmat, unstagdims) [[ 2. 3. 4. 5.] [ 6. 7. 8. 9.] [ 10. 11. 12. 13.] [ 14. 15. 16. 17.]] """ fname = 'stagger_unstagger' udndims = list(udims.keys()) idim = 0 vdstaggered = {} newdims = [] idim = 0 for vd in dndims: idim = dndims.index(vd) if searchInlist(udndims, vd): if varv.shape[idim] - 1 == udims[vd]: vdstaggered[vd] = varv.shape[idim] - 1 else: vdstaggered[vd] = varv.shape[idim] else: vdstaggered[vd] = varv.shape[idim] - 1 print ' ' + fname + ": new dimension '" + vd + "' with length :", \ varv.shape[idim], 'as staggered dim' newdims.append(vdstaggered[vd]) if len(vdstaggered) > 1: destagger_varv = np.zeros(tuple(newdims), dtype=np.float) ndim = 0 upstagslc = [] downstagslc = [] for vd in vdstaggered.keys(): idim = dndims.index(vd) if vdstaggered[vd] != varv.shape[idim]: upstagslc.append(slice(1,varv.shape[idim])) downstagslc.append(slice(0,varv.shape[idim]-1)) else: upstagslc.append(slice(0,varv.shape[idim])) downstagslc.append(slice(0,varv.shape[idim])) destagger_varv = 0.5*(varv[tuple(upstagslc)] + varv[tuple(downstagslc)]) return destagger_varv else: return varv def CFmonthU_daysU(datev,tunits): """ Function to transform from a CF date series with units as 'months since [DATE]' to 'days since [DATE]' datev= series of dates to transform tunits= time units of the dates >>> CFmonthU_daysU([1,2,3,4,5,6,17,18,], 'months since 1979-12-01 00:00:00') array([ 31., 62., 91., 122., 152., 183., 517., 548.]) """ import datetime as dt fname = 'CFmonthU_secondsU' if tunits.find('month') == -1: print errormsg print ' ' + fname + ": times do not have 'months' as units !!" print " they have: '" + tunits + "'" quit(-1) secstunits = tunits.replace('_',' ').split(' ') newtunits = 'days' for itsec in range(1,len(secstunits)): newtunits = newtunits + ' ' + secstunits[itsec] yr = np.int(secstunits[2].split('-')[0]) mm = np.int(secstunits[2].split('-')[1]) dd = np.int(secstunits[2].split('-')[2]) if tunits.find(':') != -1: hh = np.int(secstunits[3].split(':')[0]) mi = np.int(secstunits[3].split(':')[1]) ss = np.int(secstunits[3].split(':')[2]) else: hh = 0 mi = 0 ss = 0 refT = dt.datetime(yr, mm, dd, hh, mi, ss) refm = 0 newdatev = np.zeros((len(datev)), dtype=np.float) for itv in range(len(datev)): while mm + datev[itv] - refm > 12.: yr = int(yr + 1) refm = refm + 12 newmm = mm + datev[itv] - refm if newmm/int(newmm) - 1. != 0.: print warnmsg print ' ' + fname + ': fractional months values', newmm, '!!' mmdec = newmm - int(newmm)*1. newmm = np.int(newmm) if newmm + 1 > 12: daysnextmon = 31 else: daysnextmon = days_month(yr,newmm+1) newdd = daysnextmon*mmdec dddec = newdd - int(newdd)*1. newdd = int(newdd) newhh = dddec*24. hhdec = newhh - int(newhh)*1. newhh = int(newhh) newmi = hhdec*60. midec = newmi - int(newmi)*1. newmi = int(newmi) newss = midec*60. ssdec = newss - int(newss)*1. newss = int(newss) if ssdec != 0.: print ' residual seconds after adjustmen:', ssdec else: newmm = np.int(newmm) newdd = np.int(dd) newhh = np.int(hh) newmi = np.int(mi) newss = np.int(ss) idate = dt.datetime(yr, newmm, newdd, newhh, newmi, newss) diffT = idate - refT if searchInlist(dir(dt.timedelta), 'total_seconds'): newdatev[itv] = diffT.total_seconds()/(3600.*24.) else: newdatev[itv] = diffT.days() + diffT.seconds()/(3600.*24) return newdatev, newtunits def get_configuration(configfile,glob): """ Function to get the configuration from an ASCII external file with [arg] = [value] returned as a dictionay as configuration[arg] = [value] '#' for comentaries in the ASCII file configfile= ASCII file to read glob= do we want vairables as global ones? (True/False) """ fname = 'get_configuration' if not os.path.isfile(configfile): print errormsg print ' ' + fmsg + ': configuratio file "' + filen + '" does not exist !!' quit(-1) of = open(configfile, 'r') config = {} for line in of: if line[0:1] != '#' and len(line) > 1: arg = line.replace('\n','').split('=')[0].replace(' ','') val = line.replace('\n','').split('=')[1].replace(' ','') config[arg] = val # From: http://stackoverflow.com/questions/11553721/using-a-string-variable-as-a-variable-name #exec( "pyHOME = '" + conf['pyHOME'] + "'") # From: http://stackoverflow.com/questions/1373164/how-do-i-create-a-variable-number-of-variables-in-python if glob: globals()[arg] = val of.close() return config #conf = get_configuration('model_graphics.dat',False) #print pyHOME def printing_dictionary(dictv): """ Function to print the content of a dictionary dictv= dictionary to print """ fname = 'printing_dictionary' for key in dictv.keys(): print ' # ' + key + ':', dictv[key] return def get_specdictionary_HMT(dictv,H='',M='',T=''): """ Function to get specific values from a dictionary by selcting that keys with H*M*T dictv= dictionary with the values H= head of the key (empty for nothing) M= middle of the key (empty for nothing) T= tail of the key (empty for nothing) >>> dictrom = {'i':1, 'ii':2, 'iii':3, 'iv':4, 'v':5, 'vi':6, 'vii':2, 'viii':8, 'ix':9, 'x':10, 'xi':11 } >>> get_specdictionary_HTM(dictrom,H='i') {'ii': 2, 'ix': 9, 'iii': 3, 'i': 1, 'iv': 4} >>> get_specdictionary_HTM(dictrom,M='i') {'vii': 2, 'iii': 3, 'viii': 8} >>> get_specdictionary_HTM(dictrom,T='i') {'xi': 11, 'i': 1, 'vi': 6, 'vii': 2, 'ii': 2, 'viii': 8, 'iii': 3} >>> get_specdictionary_HMT(dictrom,H='v',M='i') {'vii': 2, 'viii': 8} >>> get_specdictionary_HMT(dictrom,H='x',T='i') {'xi': 11} >>> get_specdictionary_HMT(dictrom,M='i',T='x') None >>> get_specdictionary_HMT(dictrom,H='v',M='i',T='i') {'vii': 2, 'viii': 8} """ fname = 'get_specdictionary_HMT' LH = len(H) LM = len(M) LT = len(T) dictkeys = dictv.keys() #print ' ' + fname + ': H=',H,'M=',M,'T=',T,'_______' # Looking for heads if LH > 0: Hkeys = [] for key in dictkeys: if key[0:LH] == H: Hkeys.append(key) #print ' Hkeys:', Hkeys # Looking for middles if LM > 0: Mkeys = [] for key in dictkeys: Lkey = len(key) if len(key[1:Lkey-1]) < LM: print warnmsg print ' ' + fname + ": key '" + key + "' too short for M='" + M + \ "' !!" if key[1:Lkey-1].find(M) != -1: Mkeys.append(key) #print ' Mkeys:', Mkeys # Looking for tails if LT > 0: Tkeys = [] for key in dictkeys: Lkey = len(key) if key[Lkey-LT:Lkey+1] == T: Tkeys.append(key) #print ' Tkeys:', Tkeys # Coincidences if LH > 0: if LM > 0: coinlistA = list(set(Hkeys).intersection(set(Mkeys))) if LT > 0: coinlist = list(set(coinlistA).intersection(set(Tkeys))) else: coinlist = list(coinlistA) elif LT > 0: coinlist = list(set(Hkeys).intersection(set(Tkeys))) else: coinlist = list(Hkeys) elif LM > 0: if LT > 0: coinlist = list(set(Mkeys).intersection(set(Tkeys))) else: coinlist = list(Mkeys) elif LT > 0: coinlist = list(Tkeys) if len(coinlist) > 0: newdictv = {} for key in coinlist: newdictv[key] = dictv[key] else: newdictv= None return newdictv def dictKeysVals_stringList(dictv,cD=',',cK='@',cV='|'): """ Function to provide strings from a dictionary with keys which contain values of lists dictv= dictionary with the values cD= character to use to separate keys cK= character to use to separate keys from their values cV= character to use to separate the values for each key >>> dictvals = {'Spain': ['Madrid', 'Santander', 'Sevilla', 'Toledo'], 'France': ['Paris', 'Marseille', 'Tolouse']} >>> dictKeysVals_stringList(dictvals) Spain@Madrid|Santander|Sevilla|Toledo,France@Paris|Marseille|Tolouse """ fname = 'dictKeysVals_stringList' ik = 0 if len(dictv.keys()) < 1: print errormsg print ' ' + fname + ': empty dictionary !!' quit(-1) string = '' for key in dictv.keys(): if ik == 0: string = key + cK else: string = string + cD + key + cK dictval = dictv[key] if type(dictval) == type(list([1,2])): iv = 0 for val in dictval: if iv == 0: string = string + val else: string = string + cV + val iv = iv + 1 elif type(dictval) == type('A'): string = string + dictval ik = ik + 1 return string def stringList_dictKeysVals(string,cD=',',cK='@',cV='|'): """ Function to provide a dictionary with keys which contain values of lists from a string string= dictionary with the values cD= character to use to separate keys cK= character to use to separate keys from their values cV= character to use to separate the values for each key >>> stringv = 'Spain@Madrid|Santander|Sevilla|Toledo,France@Paris|Marseille|Tolouse' >>> dictKeysVals_stringList(stringv) {'Spain': ['Madrid', 'Santander', 'Sevilla', 'Toledo'], 'France': ['Paris', 'Marseille', 'Tolouse']} """ fname = 'stringList_dictKeysVals' dictv = {} dvs = string.split(cD) for dv in dvs: key = dv.replace('\n','').split(cK)[0] vals = dv.replace('\n','').split(cK)[1].split(cV) dictv[key] = vals return dictv class Capturing(list): """ Class to capture the standard output from a function from: http://stackoverflow.com/questions/16571150/how-to-capture-stdout-output-from-a-python-function-call Usage: 'output' is now a list containing the lines printed by the function call. >>> romdict = {'i': 1, 'ii': 2, 'iii': 3, 'iv': 4, 'v':5, 'vi':6, 'vii':7, 'viii':8, 'ix': 9, 'x':10} >>> with Capturing() as output: >>> printing_dictionary(romdict) >>> print output [' # i: 1', ' # ii: 2', ' # iii: 3', ' # iv: 4'] """ def __enter__(self): self._stdout = sys.stdout sys.stdout = self._stringio = StringIO() return self def __exit__(self, *args): self.extend(self._stringio.getvalue().splitlines()) sys.stdout = self._stdout def search_sec_list(listv,sec): """ Function to provide the values and indices on a list which matches a section of a string listv= list to find matches sec= section to search for >>> romlist = ['i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'viii', 'ix', 'x', 'xi'] >>> search_sec_list(romlist,'ii') (['ii', 'iii', 'vii', 'viii'], [1, 2, 6, 7]) """ fname = 'search_sec_list' matches = [] locs = [] il = 0 for string in listv: if string.find(sec) != -1: matches.append(string) locs.append(il) il = il + 1 if len(locs) < 1: matches = None locs = None return matches, locs def dictvar_listS(listv, dictv, Dc=',', DVs=':'): """ Function to provide a Dc string separated list of DVs separated [key] [value] couples following a list of keys listv: list of keys from dictionary to use dictv= dictionary with values to build the string Sc: character to separate key values DVs: character to separate key-value couples >>> romdict = {'i': 1, 'ii': 2, 'iii': 3, 'iv': 4, 'v':5, 'vi':6, 'vii':7, 'viii':8, 'ix': 9, 'x':10} >>> dictvar_listS(['i', 'iv', 'vii'],romdict,',',':') i:1,iv:4,vii:7 """ fname = 'dictvar_listS' ik = 0 for key in listv: if not dictv.has_key(key): print errormsg print ' ' + fname + ": dictionary does not have key '" + key + "' !!" print ' available keys:', dictv.keys() quit(-1) else: if ik == 0: stringv = str(key) + DVs + str(dictv[key]) else: stringv = stringv + Dc + str(key) + DVs + str(dictv[key]) ik = ik + 1 return stringv def stringS_dictvar(stringv, Dc=',', DVs=':'): """ Function to provide a dictionary from a Srting which list of DVs separated [key] [value] couples stringv: String with a dictionary content as [key1][DVs][val1][Dc][key2][DVs][Val2][Dc]... Sc: character to separate key values DVs: character to separate key-value couples >>> stringS_dictvar('i:1,iv:4,vii:7',',',':') {'i': '1', 'vii': '7', 'iv': '4'} """ fname = 'stringS_dictvar' dictv = {} for Svals in stringv.split(Dc): keyn = Svals.split(DVs)[0] valn = Svals.split(DVs)[1] dictv[keyn] = valn return dictv def list_coincidences(listA, listB): """ Function to provide the coincdences between two lists listA= list with values listB= list with values to match with >>> list_coincidences(range(10),range(8,15)) [8, 9], [8, 9], [0, 1] """ fname = 'list_coincidences' coinc = list(set(listA).intersection(set(listB))) Acoin = [] Bcoin = [] # Positions in each list for coinv in coinc: Acoin.append(listA.index(coinv)) Bcoin.append(listB.index(coinv)) return coinc, Acoin, Bcoin def list_differences(listA, listB): """ Function to provide the differences between two lists listA= list with values to match with listB= list with values >>> list_coincidences(range(10),range(8,15)) [10, 11, 12, 13, 14], [2, 3, 4, 5, 6] """ fname = 'list_differences' # Not coincident of B in A diffs = list(set(listB).difference(set(listA))) Bdiff = [] for diff in diffs: Bdiff.append(listB.index(diff)) return diffs, Bdiff def coincident_CFtimes(tvalB, tunitA, tunitB): """ Function to make coincident times for two different sets of CFtimes tvalB= time values B tunitA= time units times A to which we want to make coincidence tunitB= time units times B >>> coincident_CFtimes(np.arange(10),'seconds since 1949-12-01 00:00:00', 'hours since 1949-12-01 00:00:00') [ 0. 3600. 7200. 10800. 14400. 18000. 21600. 25200. 28800. 32400.] >>> coincident_CFtimes(np.arange(10),'seconds since 1949-12-01 00:00:00', 'hours since 1979-12-01 00:00:00') [ 9.46684800e+08 9.46688400e+08 9.46692000e+08 9.46695600e+08 9.46699200e+08 9.46702800e+08 9.46706400e+08 9.46710000e+08 9.46713600e+08 9.46717200e+08] """ import datetime as dt fname = 'coincident_CFtimes' tunitA = tunitA.replace('_',' ') tunitB = tunitB.replace('_',' ') trefA = tunitA.split(' ')[2] + ' ' + tunitA.split(' ')[3] trefB = tunitB.split(' ')[2] + ' ' + tunitB.split(' ')[3] tuA = tunitA.split(' ')[0] tuB = tunitB.split(' ')[0] # if tuB == 'months': # tvalB, tunitB = gen.CFmonthU_daysU(tvalB, tunitB) # tuB = tunitB.split(' ')[0] if tuA != tuB: if tuA == 'microseconds': if tuB == 'microseconds': tB = tvalB*1. elif tuB == 'seconds': tB = tvalB*10.e6 elif tuB == 'minutes': tB = tvalB*60.*10.e6 elif tuB == 'hours': tB = tvalB*3600.*10.e6 elif tuB == 'days': tB = tvalB*3600.*24.*10.e6 else: print errormsg print ' ' + fname + ": combination of time untis: '" + tuA + \ "' & '" + tuB + "' not ready !!" quit(-1) elif tuA == 'seconds': if tuB == 'microseconds': tB = tvalB/10.e6 elif tuB == 'seconds': tB = tvalB*1. elif tuB == 'minutes': tB = tvalB*60. elif tuB == 'hours': tB = tvalB*3600. elif tuB == 'days': tB = tvalB*3600.*24. else: print errormsg print ' ' + fname + ": combination of time untis: '" + tuA + \ "' & '" + tuB + "' not ready !!" quit(-1) elif tuA == 'minutes': if tuB == 'microseconds': tB = tvalB/(60.*10.e6) elif tuB == 'seconds': tB = tvalB/60. elif tuB == 'minutes': tB = tvalB*1. elif tuB == 'hours': tB = tvalB*60. elif tuB == 'days': tB = tvalB*60.*24. else: print errormsg print ' ' + fname + ": combination of time untis: '" + tuA + \ "' & '" + tuB + "' not ready !!" quit(-1) elif tuA == 'hours': if tuB == 'microseconds': tB = tvalB/(3600.*10.e6) elif tuB == 'seconds': tB = tvalB/3600. elif tuB == 'minutes': tB = tvalB/60. elif tuB == 'hours': tB = tvalB*1. elif tuB == 'days': tB = tvalB*24. else: print errormsg print ' ' + fname + ": combination of time untis: '" + tuA + \ "' & '" + tuB + "' not ready !!" quit(-1) elif tuA == 'days': if tuB == 'microseconds': tB = tvalB/(24.*3600.*10.e6) elif tuB == 'seconds': tB = tvalB/(24.*3600.) elif tuB == 'minutes': tB = tvalB/(24.*60.) elif tuB == 'hours': tB = tvalB/24. elif tuB == 'days': tB = tvalB*1. else: print errormsg print ' ' + fname + ": combination of time untis: '" + tuA + \ "' & '" + tuB + "' not ready !!" quit(-1) else: print errormsg print ' ' + fname + ": time untis: '" + tuA + "' not ready !!" quit(-1) else: tB = tvalB*1. if trefA != trefB: trefTA = dt.datetime.strptime(trefA, '%Y-%m-%d %H:%M:%S') trefTB = dt.datetime.strptime(trefB, '%Y-%m-%d %H:%M:%S') difft = trefTB - trefTA diffv = difft.days*24.*3600.*10.e6 + difft.seconds*10.e6 + difft.microseconds print ' ' + fname + ': different reference refA:',trefTA,'refB',trefTB print ' difference:',difft,':',diffv,'microseconds' if tuA == 'microseconds': tB = tB + diffv elif tuA == 'seconds': tB = tB + diffv/10.e6 elif tuA == 'minutes': tB = tB + diffv/(60.*10.e6) elif tuA == 'hours': tB = tB + diffv/(3600.*10.e6) elif tuA == 'days': tB = tB + diffv/(24.*3600.*10.e6) else: print errormsg print ' ' + fname + ": time untis: '" + tuA + "' not ready !!" quit(-1) return tB def same_shape(mat1,mat2): """ Function to check if two matrices have the same shape mat1,2= matrices to check """ fname = 'same_shape' shape1 = mat1.shape shape2 = mat2.shape Ndims1 = len(shape1) Ndims2 = len(shape2) if Ndims1 != Ndims2: print errormsg print ' ' + fname + ': mat1 and mat2 have different number of dimensions !!' print ' Ndims mat 1:', Ndims1,' Ndims mat2:', Ndims2 print ' shape mat 1:', shape1, 'mat 2:', shape2 quit(-1) for idn in range(Ndims1): if shape1[idn] != shape2[idn]: print errormsg print ' ' +fname+ ': length of',idn,'diemsion in mat1 and mat2 differ !!' print ' Length mat 1:', shape1[idn],' Length mat2:', shape2[idn] print ' shape mat 1:', shape1, 'mat 2:', shape2 quit(-1) return def index_flatten_mat(index,Ldims): """ Function to provide the matrix coordinates of an index from its flatten version index= index of the matrix's flatten version Ldims= lengths of the dimensions of the matrix >>> index_flatten_mat(17,[3,3,3]) [1 2 2] """ fname = 'index_flatten_mat' Ndims = len(Ldims) if index < Ldims[Ndims-1]: indices = np.zeros((len(Ldims)), dtype=int) indices[Ndims-1] = index else: for idn in range(1,Ndims): indices = np.zeros((len(Ldims)), dtype=int) subsize = int(np.prod(Ldims[Ndims-idn-1:Ndims])) # Reaching depth level in the matrix if subsize > idn: # Getting index for each dimension from the depth prevsubsizeind = index for idnd in range(Ndims-idn, Ndims): prevsubsize = int(np.prod(Ldims[idnd:Ndims])) Nprevsubsize = int(prevsubsizeind/prevsubsize) indices[idnd-1] = Nprevsubsize prevsubsizeind = prevsubsizeind - Nprevsubsize*prevsubsize # Final index indices[Ndims-1] = prevsubsizeind return indices def oper_submatrix(mat,dimns,submatval,oper,opdims): """ Function to perform an operation of a given matrix along a sub-set of values along its dimensions mat= matrix with values dimns= names of the matrix dimensions submatval= matrix value to use with some dimensions reduced oper= operation to perform 'sumc', add [val] 'subc', substraction [val] 'mulc', multiply by [val] 'divc', divide by [val] 'lowthres',[val]: modify all values below [val] to submatval 'upthres',[val]: modify all values above [val] to submatval opdims= dimensions of the operation >>> mat = np.arange(12).reshape(3,2,2) >>> dimsn = ['time', 'lon', 'lat'] >>> oper_submatrix(mat, dimsn, np.matrix([[1., 1.],[2., 2.]]), 'sumc', ['time']) [[[ 1 2] [ 4 5]] [[ 5 6] [ 8 9]] [[ 9 10] [12 13]] """ fname = 'oper_submatrix' operations = ['sumc', 'subc', 'mulc', 'divc', 'lowthres', 'upthres'] matype = mat.dtype if oper.find(',') != -1: opern = oper.split(',')[0] val = retype(oper.split(',')[1], matype) else: opern = oper Ndims = len(dimns) # Getting the slice, on '-1', dimension to operate along # Keeping in 'ldimuse': length of the dimensions of the values to use # Keeping in 'ldimop': length of the dimension to operate along idim = 0 ldimuse = [] ldimop = [] slicevals = [] for dimn in dimns: if searchInlist(opdims,dimn): for dn in opdims: if dimn == dn: slicevals.append(-1) ldimop.append(mat.shape[idim]) break else: slicevals.append(mat.shape[idim]) ldimuse.append(mat.shape[idim]) idim = idim + 1 if len(ldimop) == 0: print errormsg print ' ' + fname + ': no dimensions found for the operation !!' print ' dimensions in file:', dimns print ' dimensions for the operation:', opdims quit(-1) Ndop = len(opdims) Ntotdims = np.prod(ldimop) # Checking for coincidence in shapes try: with Capturing() as output: same_shape(submatval,np.zeros(ldimuse)) except: print errormsg print ' ' + fname + ': shape of matrix to use and shape of values to ' + \ 'operate differ!!' for sout in output: print sout quit(-1) # Operation newmat = np.zeros(tuple(mat.shape), dtype=mat.dtype) for ijk in range(Ntotdims): ijkop = -1 opslice = [] idcalc = index_flatten_mat(ijk,ldimop) for idn in range(Ndims): if slicevals[idn] == -1: ijkop = ijkop + 1 opslice.append(idcalc[ijkop]) else: opslice.append(slice(0,slicevals[idn])) if opern == 'sumc': newmat[tuple(opslice)] = mat[tuple(opslice)] + submatval elif opern == 'subc': newmat[tuple(opslice)] = mat[tuple(opslice)] - submatval elif opern == 'mulc': newmat[tuple(opslice)] = mat[tuple(opslice)] * submatval elif opern == 'divc': newmat[tuple(opslice)] = mat[tuple(opslice)] / submatval elif opern == 'lowthres': newmat[tuple(opslice)] = np.where(mat[tuple(opslice)] < val, submatval, \ mat[tuple(opslice)]) elif opern == 'upthres': newmat[tuple(opslice)] = np.where(mat[tuple(opslice)] > val, submatval, \ mat[tuple(opslice)]) else: print errormsg print ' ' + fname + ": operation '" + opern + "' not ready !!" print ' ready operations:', operations quit(-1) return newmat def ASCII_LaTeX(ln): """ Function to transform from an ASCII character to LaTeX codification >>> ASCII_LaTeX('Laboratoire de Météorologie Dynamique però Hovmöller \¿') Laboratoire de M\'et\'eorologie Dynamique per\`o Hovm\"oller \textbackslash¿` """ newln = ln.replace('\\', '\\textbackslash') newln = newln.replace('á', "\\'a") newln = newln.replace('é', "\\'e") newln = newln.replace('í', "\\'i") newln = newln.replace('ó', "\\'o") newln = newln.replace('ú', "\\'u") newln = newln.replace('à', "\\`a") newln = newln.replace('è', "\\`e") newln = newln.replace('ì', "\\`i") newln = newln.replace('ò', "\\`o") newln = newln.replace('ù', "\\`u") newln = newln.replace('â', "\\^a") newln = newln.replace('ê', "\\^e") newln = newln.replace('î', "\\^i") newln = newln.replace('ô', "\\^o") newln = newln.replace('û', "\\^u") newln = newln.replace('ä', '\\"a') newln = newln.replace('ë', '\\"e') newln = newln.replace('ï', '\\"i') newln = newln.replace('ö', '\\"o') newln = newln.replace('ü', '\\"u') newln = newln.replace('ç', '\c{c}') newln = newln.replace('ñ', '\~{n}') newln = newln.replace('Á', "\\'A") newln = newln.replace('É', "\\'E") newln = newln.replace('Í', "\\'I") newln = newln.replace('Ó', "\\'O") newln = newln.replace('Ú', "\\'U") newln = newln.replace('À', "\\`A") newln = newln.replace('È', "\\`E") newln = newln.replace('Ì', "\\`I") newln = newln.replace('Ò', "\\`O") newln = newln.replace('Ù', "\\`U") newln = newln.replace('Â', "\\^A") newln = newln.replace('Ê', "\\^E") newln = newln.replace('Î', "\\^I") newln = newln.replace('Ô', "\\^O") newln = newln.replace('Û', "\\^U") newln = newln.replace('Ä', '\\"A') newln = newln.replace('Ë', '\\"E') newln = newln.replace('Ï', '\\"I') newln = newln.replace('Ö', '\\"O') newln = newln.replace('Ü', '\\"U') newln = newln.replace('Ç', '\\c{C}') newln = newln.replace('Ñ', '\\~{N}') newln = newln.replace('¡', '!`') newln = newln.replace('¿', '¿`') newln = newln.replace('%', '\\%') newln = newln.replace('#', '\\#') newln = newln.replace('&', '\\&') newln = newln.replace('$', '\\$') newln = newln.replace('_', '\\_') newln = newln.replace('·', '\\textperiodcentered') newln = newln.replace('<', '$<$') newln = newln.replace('>', '$>$') newln = newln.replace('', '*') # newln = newln.replace('º', '$^{\\circ}$') newln = newln.replace('ª', '$^{a}$') newln = newln.replace('º', '$^{o}$') newln = newln.replace('°', '$^{\\circ}$') newln = newln.replace('\n', '\\\\\n') newln = newln.replace('\t', '\\medskip') newln = newln.replace('“', '``') newln = newln.replace('”', '\'\'') return newln def latex_text(itext): """ Function to transform a text to LaTeX following style rules itext: original text >>> latex_text('US use the dolar $ as in AUS') US use the dolar \$ as in AUS >>> latex_text('definition of sinus: $\sin=\\frac{a}{\\sqrt{a^2+b^2}}$') definition of sinus: $\sin=\frac{a}{\sqrt{a^2+b^2}}$ >>> latex_text('WRF_LMDZ$_{current}^{AR40}$') WRF\_LMDZ$_{current}^{AR40}$ """ fname = 'latex_text' # Sesitive characters which might interfer with the mathematical environment symbs = {'sub': '_', 'sup':'^', 'slash':'\\', 'and': '&'} # Do not change that sensitive_math which are between $ (from mathematical notation) latexsymb = {} Litext = len(itext) for ic in range(Litext): if itext[ic] == '$': if latexsymb.has_key('math'): vals = latexsymb['math'] vals.append(ic) else: vals = [ic] latexsymb['math'] = vals elif itext[ic] == '_': if latexsymb.has_key('sub'): vals = latexsymb['sub'] vals.append(ic) else: vals = [ic] latexsymb['sub'] = vals elif itext[ic] == '^': if latexsymb.has_key('sup'): vals = latexsymb['sup'] vals.append(ic) else: vals = [ic] latexsymb['sup'] = vals elif itext[ic] == '\\': if latexsymb.has_key('slash'): vals = latexsymb['slash'] vals.append(ic) else: vals = [ic] latexsymb['slash'] = vals elif itext[ic] == '&': if latexsymb.has_key('and'): vals = latexsymb['and'] vals.append(ic) else: vals = [ic] latexsymb['and'] = vals #print fname + "; Lluis itext '" + itext + "'" #printing_dictionary(latexsymb) latextext = itext + '' for car in symbs.keys(): changecar = ASCII_LaTeX(symbs[car]) if latexsymb.has_key(car): if not latexsymb.has_key('math') or len(latexsymb['math']) == 1: latextext = latextext.replace(symbs[car],changecar) else: # Changing that characters which are outside an even 'math' pair mathpos = latexsymb['math'] Nmath = len(mathpos) if np.mod(Nmath,2) != 0 and Nmath > 1: print errormsg print ' '+fname + ': even number', Nmath,' of math symbols $ !!' print ' impossible to determine where starts math environment ' print " change text: '" + itext + "'" quit(-1) for isymb in latexsymb[car]: Ltxt = len(latextext) if Nmath == 2: # Case with only 2 $ mathbeg = mathpos[0] mathend = mathpos[1] if isymb < mathbeg or isymb > mathend: headtxt = latextext[0:isymb] tailtxt = latextext[isymb+1:Ltxt+1] latextext = headtxt + changecar + tailtxt else: # Case with more than 2 $ for imath in range(0,Nmath,2): mathbeg = mathpos[imath] mathend = mathpos[imath+1] if imath+1 == Nmath-1: mathnext = Ltxt else: mathnext = mathpos[imath+2] if isymb < mathbeg and (isymb > mathend and isymb < mathnext): headtxt = latextext[0:isymb] tailtxt = latextext[isymb+1:Ltxt+1] latextext = headtxt + changecar + tailtxt break # Only 1 mathematical sign Ltxt = len(latextext) if latexsymb.has_key('math') and len(latexsymb['math']) == 1: isymb = latexsymb['math'][0] headtxt = latextext[0:isymb] tailtxt = latextext[isymb+1:Ltxt+1] latextext = headtxt + '\\$' + tailtxt return latextext def replace_list(listv,oldv,newv): """ Function to replace a value in a given list listv= list of values oldv= value to replace newv= value to use >>> replace_list(range(10),3,'iii') [0, 1, 2, 'iii', 4, 5, 6, 7, 8, 9] """ fname = 'replace_list' newlist = list(listv) iv = 0 for vv in listv: if vv == oldv: newlist[iv] = newv iv = iv + 1 return newlist def pretty_int(minv,maxv,Nint): """ Function to plot nice intervals minv= minimum value maxv= maximum value Nint= number of intervals >>> pretty_int(23.50,67.21,5) [ 25. 30. 35. 40. 45. 50. 55. 60. 65.] >>> pretty_int(-23.50,67.21,15) [ 0. 20. 40. 60.] >>> pretty_int(14.75,25.25,5) [ 16. 18. 20. 22. 24.] >>> pretty_int(-20.,20.,10) [-20. -15. -10. -5. 0. 5. 10. 15.] """ fname = 'pretty_int' nice_int = [1,2,5] interval = np.abs(maxv - minv) if interval < 0.: print errormsg print ' ' + fname + ': wrong interval',interval,'!!' print ' it can not be negative' quit(-1) potinterval = np.log10(interval) Ipotint = int(potinterval) intvalue = np.float(interval / np.float(Nint)) # new potinterval = np.log10(intvalue) Ipotint = np.floor(potinterval) # print fname + '; Lluis: interval:', interval, 'intavlue:', intvalue, 'potinterval:', potinterval, \ # 'Ipotint:', Ipotint, 'intvalue:', intvalue mindist = 10.e15 for inice in nice_int: # print inice,':',inice*10.**Ipotint,np.abs(inice*10.**Ipotint - intvalue),mindist if np.abs(inice*10.**Ipotint - intvalue) < mindist: mindist = np.abs(inice*10.**Ipotint - intvalue) closestint = inice Ibeg = int(minv / (closestint*10.**Ipotint)) values = [] val = closestint*(Ibeg)*10.**(Ipotint) dval = closestint*10.**(Ipotint) # print 'closestint:',closestint,'Ibeg:',Ibeg,'val:',val,'dval:',dval while val < maxv: values.append(val) val = val + dval return np.array(values, dtype=np.float) def prime_numbers(value): """ Function to find all the prime numbers up to a given value above 17 value: limiting value to use >>> primes(100) [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] """ fname = 'prime_numbers' primes = [2,3,5,7,11,13,17] lastprime = 17 for i in range(lastprime+1,value): #print ' ',i,value isprime = False for ip in primes: # No need to find allover the previous primes, just as big as the half if ip < i/2: if np.mod(i,ip) == 0: isprime = False break else: isprime = True if isprime: primes.append(i) lastprime = i #print fname + ': prime number',i,'!!' return primes def prime_decomposition(num): """ Function to decompose a given number with its multiple prime numbers fname= num >>> prime_decomposition(100) {2: 2, 5: 2} """ fname = 'prime_decomposition' decomposition = {} # Prime numbers primnums = prime_numbers(num) inum = num while inum > primnums[0]: for primn in primnums: if np.mod(inum,primn) == 0: inum = inum / primn if decomposition.has_key(primn): decomposition[primn] = decomposition[primn] + 1 else: decomposition[primn] = 1 break return decomposition def timestep_conform(TOTtime,tunit,multnum): """ Function to provide the time-step in seconds which conforms 1 temporal unit and the resultant number of time-steps for a whole period is multiple of a given number TOTtime: period [seconds] tunit: temporal unit at which the time-step has to conform [seconds] multnum: number to which the resultant number of time-step for `TOTtime' have to be multiple >>> timestep_conform(86400,3600,5) [4, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 30, 36, 40, 45, 48, 60, 72, 80, 90, 120, 144, 180, 240, 360, 720] """ fname = 'timestep_conform' # Possible fractions tunitdecompos = prime_decomposition(tunit) allvals = [] for prime in tunitdecompos.keys(): for it in range(tunitdecompos[prime]): allvals.append(prime) Nallvals = len(allvals) allcombinations = list_norepeatcombos(Nallvals) Ncombos = len(allcombinations) # It might be a far more efficient way? I'm lazy... timestep = [] for ic in range(Ncombos): combo = allcombinations[ic] val = 1 for icc in combo: val = val*allvals[icc] if not searchInlist(timestep,val) and np.mod(TOTtime/val,multnum) == 0: timestep.append(val) timestep.sort() return timestep #quit()