# -*- 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' infmsg = 'INFORMATION -- information -- INFORMATION -- information' fillValue = 1.e20 fillValueF = 1.e20 fillValueR = 1.e20 fillValueD = 1.e20 fillValueC = '-' fillValueS = '-' fillValueB = 'None' fillValueI = -99999 fillValueI16 = -99999 fillValueF64 = 1.e20 fillValueI32 = -99999 # 12 Months MONTHnames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', \ 'August', 'September', 'October', 'November', 'December'] shortmon = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', \ 'Nov', 'Dec'] # For variables_values # Variable name might come with a statistical surname... statsurname=['MIN', 'MAX', 'MEAN', 'STD', 'SUM', 'TURB', 'VAR', \ 'min', 'max', 'mean', 'std', 'sum', 'turb', 'var'] Lstatsurname = {'MIN': 'minimum', 'MAX': 'maximum', 'MEAN': 'mean', \ 'STD': 'standard deviation', 'SUM': 'summ', 'TURB': 'turbulence', \ 'VAR': 'variability', 'min': 'minimum', 'max': 'maximum', 'mean': 'mean', \ 'std': 'standard deviation', 'sum': 'summ', 'turb': 'turbulence', \ 'var': 'variability'} # masked array (for type tests) mamat = ma.masked_equal([0,1],1) ####### Content # advance_date: Function to advance a date object a certain given units of time # advance_matDate: Function to advance matrix-date with a matrix-increment # all_consecutive_combs: Function to provide all the consecutive possible # combinations from a series of indices # angle_DegMinSec: Function to transform an angle to Degrees Minutes Seconds # ASCIIfile_stats: Function to provide the statistics of a series of values from an ASCII file # ASCII_HTML: Function to transform from an ASCII line to HTML codification # ASCII_LaTeX: Function to transform from an ASCII character to LaTeX codification # ASCII_to: Function to provide the equivalence text to a given lenguage omitting certain characters # ASCII_WIKItab: Function to pass a line to WIKI table format # auto_val: Function to provide a value following an 'auto' configuration # auto_val_list: Function to provide a list of values following an 'auto' configuration or a single value # Capturing: Class to capture the standard output from a function # CF_gribequiv: Function to provide the GRIB variable code number from a CF name # CFcorValues: Function to provide CF information about a given coordinate # CFmonthU_daysU: Function to transform from a CF date series with units as 'months since [DATE]' to 'days since [DATE]' # CFtime_freq: Function to provide the frequency of CF times (in seconds) # CFtimes_datetime: Provide date/time array from a file with a series of netCDF CF-compilant time variable # CFtimesvar_datetime: Provide date/time array from a CF-compilant time variable # 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 # check_timestep: Function to check if a time-units are 'timestep' based. If it's the case, transform them # 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 # consecutive_list: Function to provide a list of consecutive values # contflow: Function to bring back the increment in j,i grid points according to a trip: (inflow directions) # create_LateX_figs: Function to create a LaTeX from a folder with multiple plots from different values # crossingpoint_2Dlines: Function to determinant the crossing point between two lines in a plane # curvelocalize_2D: Function to provide the localization a curve in a 2D field of positions via the equivalent # i,j-quads within which the curve lays (-1, no value for the given quad [2x2 points around]) and provide # the weights of the quad to perform a distance-weighted mean at the given curve point # cyclevar: Function to provide the given index of a cycle variable. A cycle variable # is a given structure with a series of values, once the maximum is overpassed # it restarts from the beginning (e.g.: 12 months of a year) # cyclevar_within: Function to tell if a given value is within a period of a cycle variable. # A cycle variable is a given structure with a series of values, once the # maximum is overpassed it restarts from the beginning (e.g.: 12 months of a year) # DateTimeStr_date: Function to transform a string date-time ([YYYY][MM][DD][HH][MI][SS] format) to a date object # datetimeStr_datetime: Function to transform a string date-time ([YYYY]-[MM]-[DD]_[HH]:[MI]:[SS] format) to a date object # DegMinSec_angle: Function to transform Degrees Minutes Seconds to an angle # 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] # fill_Narray: Function to fill a n-dimensional array with an arrary of lesser rank # get_configuration: Function to get the configuration from an ASCII external file # get_right_CFtimeunits: Function to get the right CFtime units from any given format # get_specdictionary_HMT: Function to get specific values from a dictionary by selcting that keys with H*M*T # getting_fixedline: Function to get the values from a line of text with fixed lenght of different values # generate_CFtimes: Function to generate CFtimes for a given period, frequency and units # grib_CFequiv: Function to provide the CF name of a GRIB variable code number # inf_operSlist: Function to provide information from a string as a list separated by # a given character followig a given operation and a set of values # 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 # InsertVal_list_sign: Insert values into a sorrted list according to its sign of growth # int_to_roman: Convert an integer to Roman numerals # IsNumber: Function to determine if a given String is a given type of number # julday_360d: Function to provide the julian day of a date in a 360 days/yr (or 12 30-days months) calendar # latex_fig_array: Function to add an array of figures to an existing tex file # latex_text: Function to transform a text to LaTeX following style rules # Latin_Greek: Function to pass an ASCII latin character to its equivalent greek # linearint_weights: Function to provide the weights for a linear interpolation of a value between a couple of values as a weighted distance mean # linearint_3x3weights: Function to provide the weights for a linear interpolation of a value inside a 3x3 matrix of values as a weighted distance mean # 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 # lstring_values: Function to provide a new list-string from a string which is a list of word separated by a character if some values are repeated they are not included # make_colors: Function to create a palette of colors from a series of high and low values # mat_dimreshape: Function to reshape a matrix on a new one according to values along their dimensions # maxNcounts: Function to provide a value according to the maximum number of repeated values along a given axis # minNcounts: Function to provide a value according to the minimum number of repeated values along a given axis # mindist: Function to provide the minimum distance toa pair of lon,lat # minmax_range: Function to provide a range for a given pair of minimum and maximum # multi_index_mat: Function to provide the multiple coordinates of a given value inside a matrix # multi_index_string: Function to provide the indeces of every repetition of a group of characters within a string # multi_index_vec: Function to provide the coordinates of multiples repetitions of a value inside a vector # Nomasked: Function to bring back a given array wthout the masked values reducing a given dimension # Nstr: Function to transform a number to string, but making sure it preserves # characteristics of the number # Ntchar: Function to repeat a number of times a given tring # num_chainSnum: Function to pass a value to a `ChainStrNum' number # num_ordinal: Function to provide the ordinal of a given number, language, format and gender # 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 # operations: Function to perform different operations to a pair of matrices of values # 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 # points_2Dline: Function to define a line from a pair of points on a plane # PolyArea: Function to compute the area of the polygon following 'Shoelace formula' # 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 # provide_slices: Function to provide a list of slices for a matrix giving a sub-section of running dimensions # 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 # rectangular_spiral: Function to provide a rectangular spiral (along x,y-axis values) of values # replace_list: Function to replace a value in a given list # roman_to_int: Convert a roman numeral to an integer # 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 # shrinkarray_dim: Function to shrink a given array with a vector of True/False along a given dimension # 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 # stats_Slist: Function to provide extremes from a string as a list separated by a given character # 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 # str_list_rep: Function to obtain a list from a string givin a split character and a total number of values # 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 # time_slices: Function to return temporal slices of a series of times for a given amount of periods # 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 # timefmt_timelab: Function to transform from C-like time format to general one # 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 # xtrm_nx: Function to provide the extreme (a percentage above min,max) of a series of values # WRF_percenlevels: Function to compute eta-levels for WRF following a percentage distribution # WRFsetup: Function to check the set-up of a WRF model namelist or from any other model 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 Ntchar(char,N): """ Function to repeat a number of times a given tring char= string to repeat N= quantity of repetitions >>> Ntchar('c', 4) cccc """ fname = 'Ntchar' newstr = '' for it in range(N): newstr = newstr + char return newstr 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' truelist = ['True', 'true', '1', 'Yes', 'yes', 'T', 't'] falselist = ['False', 'false', '0', 'No', 'no', 'F', 'f'] if searchInlist(truelist,val): boolv = True elif searchInlist(falselist, val): 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_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 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',[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 'Y-m-dTH:M:SZ': [YYYY]-[MM]-[DD]T[HH]:[MI]:[SS]Z UNIDATA 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),'cfTime,minutes since 1979-12-01_00:00:00','Y/m/d H-M-S') 1980/03/05 18-00-00 >>> datetimeStr_conversion('1980/03/05 18-00-00','Y/m/d H-M-S','cfTime,minutes since 1979-12-01_00:00:00') 137880.0 """ import datetime as dt fname = 'datetimeStr_conversion' availableSio = {'cfTime,[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', \ 'Y-m-dTH:M:SZ': '[YYYY]-[MM]-[DD]T[HH]:[MI]:[SS]Z UNIDATA format', \ 'WRFdatetime': "[Y], [Y], [Y], [Y], '-', [M], [M], '-', [D], [D], '_', " + \ "[H], [H], ':', [M], [M], ':', [S], [S]"} if StringDT[0:1] == 'h': print fname + '_____________________________________________________________' print datetimeStr_conversion.__doc__ quit() if typeSi[0:6] == 'cfTime': timeval = np.float(StringDT) tunits = typeSi.split(',')[1].split(' ')[0] Srefdate = typeSi.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 = typeSi.split(',')[1].find(':') if not trefT == -1: if len(typeSi.split(',')[1].split(' ')) == 3: horref=Srefdate[11:13] minref=Srefdate[14:16] secref=Srefdate[17:19] else: Sreftime = typeSi.split(',')[1].split(' ')[3] horref=Sreftime[0:2] minref=Sreftime[3:5] secref=Sreftime[6:8] 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 == 'Y-m-dTH:M:SZ': dateDT = StringDT.split('T') dateD = dateDT[0].split('-') timeT = dateDT[1].replace('Z','').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 !!!!' printing_dictionary(availableSio) quit(-1) if typeSo[0:6] == 'cfTime': tunits = typeSo.split(',')[1].split(' ')[0] Srefdate = typeSo.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 = typeSo.split(',')[1].find(':') if not trefT == -1: # print ' ' + fname + ': refdate with time!' if len(typeSo.split(',')[1].split(' ')) == 3: horref=Srefdate[11:13] minref=Srefdate[14:16] secref=Srefdate[17:19] else: Sreftime = typeSo.split(',')[1].split(' ')[3] horref=Sreftime[0:2] minref=Sreftime[3:5] secref=Sreftime[6:8] refdate = datetimeStr_datetime( yrref + '-' + monref + '-' + dayref + \ '_' + horref + ':' + minref + ':' + secref) else: refdate = datetimeStr_datetime( yrref + '-' + monref + '-' + dayref + \ '_00:00:00') datei = dt.datetime(yr, mo, da, ho, mi, se) difft = datei - refdate if searchInlist(dir(difft),'total_seconds'): totsecs = difft.total_seconds() else: totsecs = difft.days()*24*3600. + difft.seconds() if tunits == 'weeks': cfdt = totsecs / (7*24*3600) elif tunits == 'days': cfdt = totsecs / (24*3600) elif tunits == 'hours': cfdt = totsecs / (3600) elif tunits == 'minutes': cfdt = totsecs / (60) elif tunits == 'seconds': cfdt = totsecs elif tunits == 'milliseconds': cfdt = totsecs*100. else: print errormsg print ' timeref_datetime: time units "' + tunits + '" not ready!!!!' quit(-1) dateYmdHMS = cfdt elif 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 == 'Y-m-dTH:M:SZ': dateYmdHMS = str(yr).zfill(4) + '-' + str(mo).zfill(2) + '-' + \ str(da).zfill(2) + 'T' + str(ho).zfill(2) + ':' + str(mi).zfill(2) + ':' + \ str(se).zfill(2) + 'Z' 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 !!!!' printing_dictionary(availableSio) 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), [LaTeX name], [ASCII name] [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', '$z$', 'z'] """ 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 break varn = varName ncf = open(infile, 'r') for line in ncf: if line[0:1] != '#': values = line.replace('\n','').split(',') if len(values) != 10: print errormsg print "problem in varibale: '", values[0], \ ' it should have 10 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', '$'+varn[6:Lvarn+1]+'$', varn[6:Lvarn+1]] else: if ifst: Lstat = Lstatsurname[st] stn = st.lower() latexv = values[8].replace(' ','') latexn = latexv[0:len(latexv)-1] + stn + '$' varvals = [values[1].replace(' ','') + stn, \ values[2].replace(' ',''), np.float(values[3]), \ np.float(values[4]), Lstat + '|' + values[5].replace(' ',''), \ values[6].replace(' ',''), values[7].replace(' ',''), \ latexn, values[9].replace(' ','') + stn] 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(' ',''), values[8].replace(' ',''), \ values[9].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' if type(vec) == type(np.arange(2)): valpos = -1 for i in range(vec.shape[0]): if vec[i] == val: valpos = i break elif type(vec) == type(tuple([1,2])): valpos = -1 for i in range(len(vec)): if vec[i] == val: valpos = i break elif type(vec) == type(range(2)): valpos = vec.index(val) else: print errormsg print ' ' + fname + ': type', type(vec), 'not ready !!' print ' available ones:', type(np.arange(2)), type(range(2)), \ type(tuple([1,2])) quit(-1) return valpos def multi_index_vec(vec,val): """ Function to provide the coordinates of multiples repetitions of a value inside a vector index_vec(vec,val) vec= vector with values val= value to search >>> vecv = np.arange(27) >>> vecv[2] = 22 >>> vecv[12] = 22 >>> multi_index_vec(vecv,22) 2, 12, 22 """ fname = 'multi_index_vec' valpos = [] if type(vec) == type(np.arange(2)): for i in range(vec.shape[0]): if vec[i] == val: valpos.append(i) elif type(vec) == type(tuple([1,2])): for i in range(len(vec)): if vec[i] == val: valpos.append(i) elif type(vec) == type(range(2)): for i in vec: if vec[i] == val: valpos.append(i) else: print errormsg print ' ' + fname + ': type', type(vec), 'not ready !!' print ' available ones:', type(np.arange(2)), type(range(2)), \ type(tuple([1,2])) quit(-1) if len(valpos) == 0: valpos.append(-1) return valpos def index_mat(mat,val,quitval=True): """ Function to provide the coordinates of a given value inside a matrix index_mat(mat,val) mat= matrix with values val= value to search quitval= Whether one should arise quit signal in case no grid-point is found >>> index_mat(np.arange(27).reshape(3,3,3),22) [2 1 1] """ fname = 'index_mat' matshape = mat.shape matlist = list(mat.flatten()) # From: https://www.google.com.ar/url?sa=t&rct=j&q=&esrc=s&source=web&cd=3&cad=rja&uact=8&ved=0ahUKEwj30JLKjMfQAhUEthoKHVAkAwoQFggtMAI&url=http%3A%2F%2Fstackoverflow.com%2Fquestions%2F7571635%2Ffastest-way-to-check-if-a-value-exist-in-a-list&usg=AFQjCNFboI4YVafR26qSpyj5zx5GrQ3LGQ&bvm=bv.139782543,d.d2s if not val in matlist: print errormsg print ' ' + fname + ': matrix does not content ', val,' !!' if quitval: quit(-1) else: return -1 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 multi_index_string(String, char): """ Function to provide the indeces of every repetition of a group of characters within a string String= string to look in char= chain of character to look for >>> multi_index_string('12345654321','2') [1, 9] >>> multi_index_string('12345654321','7') [] >>> multi_index_string('1234565432123456','23') [1, 11] """ fname = 'multi_index_string' Lstring = len(String) Lchar = len(char) newstring = String + '' indices = [] iss = 0 while iss < Lstring: if newstring.find(char) != -1: ichar = newstring.find(char) indices.append(ichar+iss) print newstring, ':', ichar newstring = newstring[ichar+iss+Lchar:-1] iss = iss + ichar + Lchar else: iss = Lstring return indices 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 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 >>> timeStr_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 DateTimeStr_date(StringDate): """ Function to transform a string date-time ([YYYY][MM][DD][HH][MI][SS] format) to a date object >>> DateTimeStr_date('19760217083205') 1976-02-17 08:32:05 """ import datetime as dt yr = int(StringDate[0:4]) mo = int(StringDate[4:6]) da = int(StringDate[6:8]) ho = int(StringDate[8:10]) mi = int(StringDate[10:12]) se = int(StringDate[12:14]) if yr == 0: print warnmsg print ' ' + fname + ': 0 reference year!! changing to 1' yr = 1 newdate = dt.datetime(yr, mo, da, ho, mi, se) return newdate 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' availtunits = ['weeks', 'days', 'hours', 'minutes', 'seconds', 'miliseconds'] 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 fname + ' : time units "' + tunits + '" not ready!!!!' print ' avaialable ones:', availtunits 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 ' ' + fname + ': time units "' + tunits + '" not ready!!!!' quit(-1) return realdates def CFtimesvar_datetime(times, units, calendar): """ Provide date/time array from a CF-compilant time variable timevals = CF values of the variable time units = CF-compilant units ([Tunit] since [date]) of timevals calendar= calendar of the time values 'earth_360d', '360d', '360days', '360_day' any of them for years of 360 days 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 = 'CFtimesvar_datetime' availtunits = ['weeks', 'days', 'hours', 'minutes', 'seconds', 'miliseconds'] 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(times) realdates = np.zeros((dimt, 6), dtype=int) secsDay=3600*24. # Checking calendar! ## y360 = False daycal360 = ['earth_360d', '360d', '360days', '360_day'] 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 ' ' + fname + ': time units "' + tunits + '" not ready!!!!' print ' available ones:', availtunits 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 ' ' + fname + ': time units "' + tunits + '" not ready!!!!' print ' available ones:', availtunits 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, Notenough=True): """ Function to provide the quantiles of a masked array 20 for %5 bins (21 in total) """ import numpy.ma as ma fname = 'mask_quantiles' if type(maskmat) != type(mamat): maskvals = np.zeros((maskmat.shape), dtype=bool) else: maskvals = maskmat.mask sortmat = maskmat.flatten().copy() sortmat.sort() quants = np.zeros(Nquants+1, dtype=type(maskmat[0])) Nv = ma.size(maskmat) NoMask=np.sum(~maskvals) if NoMask < Nquants: if Notenough: print errormsg print ' ' + fname + ': Not enough data=', NoMask, 'to compute', Nquants,\ 'quantiles !!' quit(-1) else: quants = fillValueF 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 array of 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' or typeval == 'I': return int(value) elif typeval == 'long': return long(value) elif typeval == 'float' or typeval == 'F' or typeval == 'R': 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 == 'B': return Str_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' or typeval == 'D': 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) if month+1 > 12: date2=dt.date(year+1,1,1) else: 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' or vtype == type('s'): 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 self.precen[t]: temporal percentiles at each grid point """ def __init__(self, vals): from scipy import stats as sts fname = 'stats_time2D' if type(vals) == type('S') and vals == 'h': print fname + '_____________________________________________________________' print stats_time2Dvars.__doc__ quit() if vals is None: self.minv = None self.maxv = None self.meanv = None self.mean2v = None self.stdv = None self.percen = None else: dimx = vals.shape[2] dimy = vals.shape[1] stats=np.zeros((dimy,dimx,6), dtype=np.float) absmean = np.mean(vals,axis=0) percents = np.zeros((21,dimy,dimx), dtype=np.float) 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]=np.std(vals, axis=0) stats[:,:,5]=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) for j in range(dimy): for i in range(dimx): percents[:,j,i] = Quantiles(vals[:,j,i],20).quantilesv self.minv=stats[:,:,0] self.maxv=stats[:,:,1] self.meanv=stats[:,:,2] self.mean2v=stats[:,:,3] self.stdv=stats[:,:,4] self.anomv=stats[:,:,5] self.percen=percents[:] 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, error=True): """ Function to return lon, lat 2D matrices from any lon,lat matrix lon= matrix with longitude values lat= matrix with latitude values error= whether should quit if there is an error """ fname = 'lonlat2D' if len(lon.shape) == len(lat.shape): 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] else: print errormsg print ' ' + fname + ': longitude values with shape:', lon.shape, \ 'is different than latitude values with shape:', lat.shape, '(dif. size) !!' if error: quit(-1) # Not so weird case !! print ' Trying to fix it!' if len(lon.shape) == 3: lonv0 = lon[0,:,:] else: lonv0 = lon.copy() if len(lat.shape) == 3: latv0 = lat[0,:,:] else: latv0 = lat.copy() if len(lonv0.shape) == 1 and len(latv0.shape) == 2: lonvv = np.zeros(latv0.shape, dtype=np.float) if lonv0.shape[0] == latv0.shape[0]: for k in range(latv0.shape[1]): lonvv[:,k] = lonv0[:] else: for k in range(latv0.shape[0]): lonvv[k,:] = lonv0[:] latvv = latv0.copy() if len(lonv0.shape) == 2 and len(latv0.shape) == 1: lonvv = lonv0.copy() latvv = np.zeros(lonv0.shape, dtype=np.float) if lonv0.shape[0] == latv0.shape[0]: for k in range(lonv0.shape[1]): latvv[:,k] = latv0[:] else: for k in range(lonv0.shape[0]): latvv[k,:] = latv0[:] return lonvv, latvv def interpolate_locs_old(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 type(locs) == type('S') and 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): found = False a = None b = None c = None for icor in range(Ncoords-1): if locs[iloc] < minc and dcoords > 0.: a = 0. b = coords[1] - coords[0] c = coords[0] elif locs[iloc] > maxc and dcoords > 0.: a = (Ncoords-1)*1. b = coords[Ncoords-1] - coords[Ncoords-2] c = coords[Ncoords-2] elif locs[iloc] < minc and dcoords < 0.: a = (Ncoords-1)*1. b = coords[Ncoords-1] - coords[Ncoords-2] c = coords[Ncoords-2] elif locs[iloc] > maxc and dcoords < 0.: a = 0. b = (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 = coords[icor+1] - coords[icor] c = coords[icor] elif locs[iloc] <= coords[icor] and locs[iloc] > coords[icor+1] and dcoords < 0.: a = icor*1. b = coords[icor+1] - coords[icor] c = coords[icor] if a is not None: found = True if not found: print errormsg print ' ' + fname + ": case not prepared !!" print ' locs[iloc]:', locs[iloc], 'minc:', minc, 'maxc:', maxc, 'dcoords:', dcoords quit(-1) 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 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 12. ] >>> coordinates[0] = 0.5 >>> coordinates[2] = 2.5 >>> interpolate_locs(values,coordinates,'lin') [ -3.4 1.93333333 5.6 7.8 12. ] >>> coordinates = -10+np.arange((10), dtype=np.float) >>> values = -np.array([-1.2, 2.4, 5.6, 7.8, 12.0]) >>> interpolate_locs(values,coordinates,'lin') [ 11.2 7.6 4.4 2.2 -2. ] """ fname = 'interpolate_locs' if type(locs) == type('S') and locs == 'h': print fname + '_____________________________________________________________' print interpolate_locs.__doc__ quit() Nlocs = locs.shape[0] Ncoords = coords.shape[0] origsing = np.abs(coords[Ncoords-1]-coords[0])/(coords[Ncoords-1]-coords[0]) intlocs = np.zeros((Nlocs), dtype=np.float) minc = np.min(coords) maxc = np.max(coords) sortc = list(coords) sortc.sort() for iloc in range(Nlocs): a = None refi = None if locs[iloc] < minc: a = 0 refi = 0 sing = -1. elif locs[iloc] > maxc: a = Ncoords-1 refi = Ncoords-2 sing = 1. elif locs[iloc] == minc: a = 0 refi = 0 sing = 1. elif locs[iloc] == maxc: a = Ncoords-1 refi = Ncoords-2 sing = 1. else: for icor in range(Ncoords-1): if locs[iloc] >= sortc[icor] and locs[iloc] < sortc[icor+1]: a = icor refi = icor sing = 1. if a is None: print errormsg print ' ' + fname + ': locs[iloc]:', locs[iloc], 'minc:', minc, 'maxc:',\ maxc, 'not ready!!' quit(-1) b = sortc[refi+1]-sortc[refi] #print 'locs[iloc]:', locs[iloc], 'a:', a, 'refi:', refi, 'b:', b, 'np.abs(sortc[refi]-locs[iloc]):', np.abs(sortc[refi]-locs[iloc]) if kinterp == 'lin': intlocs[iloc] = a + sing*np.abs(sortc[a]-locs[iloc])/b else: print errormsg print ' ' + fname + ": interpolation kind '" + kinterp + "' not ready !!!!!" quit(-1) if origsing < 0.: intlocs = Ncoords - intlocs 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, fill=None): """ 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 [fill]: fill value to use [value]: value to use to fill outside runmean values 'vals': using actual values instead NOTE: resultant size would be the same but with [fill] 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]) if fill != 'vals': runmean = np.where(runmean == fillValue, fill, runmean) else: runmean = np.where(runmean == fillValue, values, 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() # FROM: http://stackoverflow.com/questions/9997048/python-subprocess-wildcard-usage ins = folder + "/" + head + "*" + middle + '*' + tail #ins = folder + "/" #files = sub.Popen(["/bin/ls","-1R",ins], shell=True, stdout=sub.PIPE) files = sub.Popen("/bin/ls -1R " + ins, shell=True, stdout=sub.PIPE) fileslist = files.communicate() listfiles0 = str(fileslist).replace("'",'').replace('(','').replace(')','').split('\\n') # Filtering output listfiles = [] for ifile in listfiles0: # Removing folder section filen = ifile[len(folder)+1:len(ifile)+1] if ifile.find(head) != -1 and ifile.find(middle) != -1 and \ ifile.find(tail) != -1: indhead = filen.index(head) indmiddle = filen.index(middle) if indmiddle == 0: indmiddle = indhead indtail = filen.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 check_timestep(otval): """ Function to check if a time-units are 'timestep' based. If it's the case, transform them otval = time variable object """ fname = 'check_timestep' varatrs = otval.ncattrs() if not searchInlist(varatrs, 'units'): print errormsg print ' ' + main+'.'+fname + ": object variable without 'units' attribute!!" print ' attributes found:', varatrs quit(-1) tunits = otval.getncattr('units') if tunits.split(' ')[0] == 'timesteps': print warnmsg print ' ' + fname + ": time variable with 'timesteps' as units !!" print ' modifying time values' dimvn = otval.dimensions[0] # looking for units of time-step as 'clever' combination with dimension name? Tunitssecs = ['second', 'minute', 'hour', 'day'] foundCFunits = False Tunitsguess = [] for Tunit in Tunitssecs: attrn = Tunit[0:1] if searchInlist(varatrs,dimvn+'_'+attrn): CFtu = Tunit + 's' foundCFunits = True break Tunitsguess.append(dimvn+'_'+attrn) attrn = Tunit[0:3] if searchInlist(varatrs,dimvn+'_'+attrn): CFtu = Tunit + 's' foundCFunits = True break Tunitsguess.append(dimvn+'_'+attrn) attrn = Tunit if searchInlist(varatrs,dimvn+'_'+attrn): CFtu = Tunit + 's' foundCFunits = True break Tunitsguess.append(dimvn+'_'+attrn) attrn = Tunit + 's' if searchInlist(varatrs,dimvn+'_'+attrn): CFtu = Tunit + 's' foundCFunits = True break Tunitsguess.append(dimvn+'_'+attrn) if not foundCFunits: print errormsg print ' ' + fname + ": time-variable with units as 'timesteps' does " + \ 'not have a prepared way:', Tunitsguess, 'to find its units !!' print " variables' attributes:", varatrs quit(-1) CFtv = otval.getncattr(dimvn+'_'+attrn) newTS = [CFtu] + tunits.split(' ')[1:] newTunits = ' '.join(newTS) newTvals = otval[:]*CFtv else: newTunits = tunits newTvals = otval[:] return newTunits, newTvals 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) if Lstring < 1: print errormsg print ' ' + fname + ": String '" + string + "' too short !!" quit(-1) firstspace = -1 for istr in range(Lstring-1,0,-1): if string[istr:istr+1] == ' ': firstspace = istr else: break if firstspace == -1: firstspace = Lstring + 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]] """ import numpy.ma as ma fname = 'vals_around' # Issues with 'None' #vals3x3 = np.array([None]*9).reshape(3,3) vals3x3 = ma.masked_equal(np.ones((3,3), dtype=np.float), 1.) 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)).zfill(2) hexgreen = '{0:X}'.format(int(col[1]*255)).zfill(2) hexblue = '{0:X}'.format(int(col[2]*255)).zfill(2) 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: finalist = None return finalist def str_list_rep(string, cdiv, Nvals): """ Function to obtain a list from a string givin a split character and a total number of values string= String from which to obtain a list ('None' for None) cdiv= character to use to split the string Nvals= number of values (if [string] only provides 1 value, list will be completed with the first value) >>> str_list('1:@#:$', ':', 3) ['1', '@#', '$'] >>> str_list('1@#$56', ':', 3) ['1@#$56', '1@#$56', '1@#$56'] >>> str_list('--:-.'', ':', 3) ['--', '-.', '--'] """ fname = 'str_list_rep' if string.find(cdiv) != -1: listv = string.split(cdiv) else: if string == 'None': listv = None else: listv = [string] if len(listv) < Nvals: for iv in range(Nvals-len(listv)): listv.append(listv[0]) elif len(listv) > Nvals: print errormsg print ' ' +fname+ ': number of obtained values:', len(listv), 'is larger' + \ ' than the desired ones:', Nvals, '!!' print " check string: '" + string + "' " quit(-1) return listv 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: 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]) idim = idim + 1 if len(vdstaggered) > 1: destagger_varv = np.zeros(tuple(newdims), dtype=np.float) ndim = 0 upstagslc = [] downstagslc = [] for vd in dndims: 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 # Avoiding zero month... if int(newmm) == 0: newmm = 1 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_differences(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('_',' ') if len(tunitA) == 4: trefA = tunitA.split(' ')[2] + ' ' + tunitA.split(' ')[3] else: print warnmsg print ' ' + fname + ": time-units without time '" + tunitA + "' !!" print " adding: '00:00:00" trefA = tunitA.split(' ')[2] + ' 00:00:00' if len(tunitB) == 4: trefB = tunitB.split(' ')[2] + ' ' + tunitB.split(' ')[3] else: print warnmsg print ' ' + fname + ": time-units without time '" + tunitB + "' !!" print " adding: '00:00:00" trefB = tunitB.split(' ')[2] + ' 00:00:00' 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,quitval=True): """ Function to check if two matrices have the same shape mat1,2= matrices to check """ fname = 'same_shape' same = True 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 same = False if quitval: quit(-1) for idn in range(Ndims1): if shape1[idn] != shape2[idn]: print errormsg print ' ' +fname+ ': length of',idn,'dimension in mat1 and mat2 differ !!' print ' Length mat 1:', shape1[idn],' Length mat2:', shape2[idn] print ' shape mat 1:', shape1, 'mat 2:', shape2 same = False if quitval: quit(-1) return same 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_to(text,to,nochg=None): """ Function to provide the equivalence text to a given lenguage omitting certain characters text= text to transform to= language to use 'tex': LaTeX nochg: a list with characters to be omitted >>> ASCII_to('à$353\pol', 'tex') \`a\$353\textbackslashpol >>> ASCII_to('à$353\pol', 'tex', ['$']) \`a$353\textbackslashpol >>> NOchange = ['_', '^', '\\', '&', '$'] >>> ASCII_to('$[spatial\ cloud\ cover]^{sub-section}_{cld\ >\ 80000.}\ (%)$', 'tex', NOchange) $[spatial\ cloud\ cover]^{sub-section}_{cld\ >\ 80000.}\ (\%)$ """ fname = 'ASCII_to' langs = ['tex'] #From: http://tex.stackexchange.com/questions/14872/croatian-serbian-letters-in-cv-problem # From: https://www.dpg-tagung.de/dd14/infochars.html?language=en # From: http://mirror.neu.edu.cn/CTAN/info/symbols/comprehensive/symbols-a4.pdf texchars = {'\\': '\\textbackslash', \ 'á': "\\'a", 'é': "\\'e", 'í': "\\'i", 'ó': "\\'o", 'ú': "\\'u", \ 'ć': "\\'c", 'ǵ': "\\'g", 'ḱ': "\\'k", 'ĺ': "\\'l", 'ḿ': "\\'m", 'ń': "\\'n", \ 'ṕ': "\\'p", 'ŕ': "\\'r", 'ś': "\\'s", 'ẃ': "\\'w", 'ý': "\\'y", 'ź': "\\'z", \ 'à': "\\`a", 'è': "\\`e", 'ì': "\\`i", 'ò': "\\`o", 'ù': "\\`u", \ 'ǹ': "\\`n", 'ẁ': "\\`w", 'ỳ': "\\`y", \ 'â': "\\^a", 'ê': "\\^e", 'î': "\\^i", 'ô': "\\^o", 'û': "\\^u", \ 'ĉ': "\\^c", 'ĝ': "\\^g", 'ĥ': "\\^h", 'ĵ': "\\^j", 'ŝ': "\\^s", 'ŵ': "\\^w", \ 'ŷ': "\\^y", 'ẑ': "\\^z", \ 'ä': '\\"a', 'ë': '\\"e', 'ï': '\\"i', 'ö': '\\"o', 'ü': '\\"u', \ 'ḧ': '\\"h', 'ẗ': '\\"t', 'ẅ': '\\"w', 'ẍ': '\\"x', 'ÿ': '\\"y', \ 'ă': '\\u{a}', 'ĕ': '\\u{e}', 'ĭ': '\\u{i}', 'ŏ': '\\u{o}', 'ŭ': '\\u{u}', \ 'ğ': '\\u{g}', \ 'ǎ': '\\v{a}', 'ě': '\\v{e}', 'ǐ': '\\v{i}', 'ǒ': '\\v{o}', 'ǔ': '\\v{u}', \ 'č': '\\v{c}', 'ď': '\\v{d}', 'ǧ': '\\v{g}', 'ȟ': '\\v{h}', 'ǰ': '\\v{j}', \ 'ǩ': '\\v{k}', 'ľ': '\\v{l}', 'ň': '\\v{n}', 'ř': '\\v{r}', 'š': '\\v{s}', \ 'ť': '\\v{t}', 'ž': '\\v{z}', \ 'å': '\\a{}', 'ů': '\\r{u}', 'ẘ': '\\r{w}', 'ẙ': '\\r{y}', \ 'ã': '\\~{a}', 'ẽ': '\\~{e}', 'ĩ': '\\~{i}', 'õ': '\\~{o}', 'ũ': '\\~{u}', \ 'ñ': '\\~{n}', 'ṽ': '\\~{v}', 'ỹ': '\\~{y}', \ 'ç': '\\c{c}', 'ḑ': '\\c{d}', 'ȩ': '\\c{e}', 'ģ': '\\c{g}', 'ḩ': '\\c{h}', \ 'ķ': '\\c{k}', 'ļ': '\\c{l}', 'ņ': '\\c{n}', 'ŗ': '\\c{r}', 'ş': '\\c{s}', \ 'ţ': '\\c{t}', \ 'ł': '\\l{}', 'ø': '\\o{}', 'đ': '\\dj{}', 'ß': '\\ss{}', \ 'æ': '\\ae{}', 'œ': '\\oe{}', \ 'Á': "\\'A", 'É': "\\'E", 'Í': "\\'I", 'Ó': "\\'O", 'Ú': "\\'U", \ 'Ć': "\\'C", 'Ǵ': "\\'G", 'Ḱ': "\\'K", 'Ĺ': "\\'L", 'Ḿ': "\\'M", 'Ń': "\\'N", \ 'Ṕ': "\\'P", 'Ŕ': "\\'R", 'Ś': "\\'S", 'Ẃ': "\\'W", 'Ý': "\\'Y", 'Ź': "\\'Z", \ 'À': "\\`A", 'È': "\\`E", 'Ì': "\\`I", 'Ò': "\\`O", 'Ù': "\\`U", \ 'Ǹ': "\\`N", 'Ẁ': "\\`W", 'Ỳ': "\\`Y", \ 'Â': "\\^A", 'Ê': "\\^E", 'Î': "\\^I", 'Ô': "\\^O", 'Û': "\\^U", \ 'Ĉ': "\\^C", 'Ĝ': "\\^G", 'Ĥ': "\\^H", 'Ĵ': "\\^J", 'Ŝ': "\\^S", 'Ŵ': "\\^W", \ 'Ŷ': "\\^Y", 'Ẑ': "\\^Z", \ 'Ä': '\\"A', 'Ë': '\\"E', 'Ï': '\\"I', 'Ö': '\\"O', 'Ü': '\\"U', \ 'Ḧ': '\\"H', 'Ẅ': '\\"W', 'Ẍ': '\\"X', 'Ÿ': '\\"Y', \ 'Ă': '\\u{A}', 'Ĕ': '\\u{E}', 'Ĭ': '\\u{I}', 'Ŏ': '\\u{O}', 'Ŭ': '\\u{U}', \ 'Ğ': '\\u{G}', 'Ž': '\\u{Z}', \ 'Ǎ': '\\v{A}', 'Ě': '\\v{E}', 'Ǐ': '\\v{I}', 'Ǒ': '\\v{O}', 'Ǔ': '\\v{U}', \ 'Č': '\\v{C}', 'Ď': '\\v{D}', 'Ǧ': '\\v{G}', 'Ȟ': '\\v{H}', 'Ǩ': '\\v{K}', \ 'Ľ': '\\v{L}', 'Ň': '\\v{N}', 'Ř': '\\v{R}', 'Š': '\\v{S}', 'Ť': '\\v{T}', \ 'Ž': '\\v{Z}', \ 'Å': '\\AA{}', 'Ů': '\\r{U}', \ 'Ã': '\\~{A}', 'Ẽ': '\\~{E}', 'Ĩ': '\\~{I}', 'Õ': '\\~{O}', 'Ũ': '\\~{U}', \ 'Ñ': '\\~{N}', 'Ṽ': '\\~{V}', 'Ỹ': '\\~{Y}', \ 'Ç': '\\c{C}', 'Ḑ': '\\c{D}', 'Ȩ': '\\c{E}', 'Ģ': '\\c{G}', 'Ḩ': '\\c{H}', \ 'Ķ': '\\c{K}', 'Ļ': '\\c{L}', 'Ņ': '\\c{N}', 'Ŗ': '\\c{R}', 'Ş': '\\c{S}', \ 'Ţ': '\\c{T}', \ 'Ł': '\\L{}', 'Ø': '\\O{}', 'Đ': '\\DJ{}', \ 'Æ': '\\AE{}', 'Œ': '\\OE{}', \ # '¡': '!`, '¿': '¿`' '¡': '\\textexclamdown', '¿': '\\textquestiondown', \ '%': '\\%', '#': '\\#', '&': '\\&', '$': '\\$', \ '_': '\\_', '–': '--', '·': '\\textperiodcentered', '|': '\\textbar', \ '<': '\\textless', '>': '\\textgreater', \ '': '*', 'ª': '\\textordfeminine', 'º': '\\textordmasculine', \ '°': '$^{\\circ}$', '²': '$^{2}$', \ '\n': '\\\\\n', '\t': '\\medskip', \ '“': '\\textquotedblleft', '”': '\\textquotedblright', '^': '\^{}', '’': "'", \ '≥': '$\geq$', '~': '$\sim$'} if to == 'tex': chars = texchars # Specific first characters to change firstchars = ['\\'] else: print errormsg print ' ' + fname + ": language '" + to + "' not ready !!" print ' available languages:', langs quit(-1) if nochg is not None: for noc in nochg: if not chars.has_key(noc): print errormsg print ' ' + fname + ": language '" + to + "' does not have '" + \ noc + "' to change !!" quit(-1) chars.pop(noc) if searchInlist(firstchars,noc): firstchars.remove(noc) newtext = text for char in firstchars: # newtext = newtext.replace(char.decode('iso-8859-15'),chars[char].decode('iso-8859-15')) newtext = newtext.replace(char,chars[char]) chars.pop(char) for char in chars.keys(): newtext = newtext.replace(char,chars[char]) # There are some issues one inside a math environment # $ (...) $<$ (...)$: will not work! need to be $ (...) < (...)$ CHANGEinsideMATH = ['$<$', '$>$', '$^{a}$', '$^{o}$', '$^{\circ}$'] Nchgmath = len(CHANGEinsideMATH) Lnewtext = len(newtext) mathpos = [] for ic in range(Lnewtext): if newtext[ic] == '$': mathpos.append(ic) # Dictionary with locations within line of the dangerous strings... mathchg = {} for icS in CHANGEinsideMATH: indices = multi_index_string(newtext,icS) if len(indices) > 0: mathchg[icS] = indices Lmathpos = len(mathpos) # All this only has sens if at least there are 4 $! if Lmathpos >= 4: for imath in range(Lmathpos,0,-2): for chars in mathchg.keys(): positions = mathchg[chars] Lchars = len(chars) for ipos in positions: if mathpos[imath-4] < ipos and mathpos[imath-2] == ipos + Lchars - 1: print ' ' + fname + ": removing '" + chars + "'" Lnewstring = len(newtext) newstring = newtext[0:ipos] + chars.replace('$','') + \ newtext[ipos+Lchars:Lnewstring+1] newtext = newstring return newtext #NOchange = ['_', '^', '\\', '&', '$'] def ASCII_HTML(ln): """ Function to transform from an ASCII line to HTML codification >>> ASCII_HTML('Laboratoire de Météorologie Dynamique però Hovmöller ¿') Laboratoire de MéMtéorologie Dynamique però Hovöller ¿ """ newln = ln.replace('&', '&') newln = newln.replace('á', "á") newln = newln.replace('é', "é") newln = newln.replace('í', "í") newln = newln.replace('ó', "ó") newln = newln.replace('ú', "ú") newln = newln.replace('à', "à") newln = newln.replace('è', "è") newln = newln.replace('ì', "ì") newln = newln.replace('ò', "ò") newln = newln.replace('ù', "ù") newln = newln.replace('â', "â") newln = newln.replace('ê', "ê") newln = newln.replace('î', "î") newln = newln.replace('ô', "ô") newln = newln.replace('û', "û") newln = newln.replace('ä', 'ä') newln = newln.replace('ë', 'ë') newln = newln.replace('ï', 'ï') newln = newln.replace('ö', 'ö') newln = newln.replace('ü', 'ü') newln = newln.replace('ç', 'ç') newln = newln.replace('ñ', 'ñ') newln = newln.replace('æ', 'æ') newln = newln.replace('œ', 'œ') newln = newln.replace('Á', "Á") newln = newln.replace('É', "É") newln = newln.replace('Í', "Í") newln = newln.replace('Ó', "Ó") newln = newln.replace('Ú', "Ú") newln = newln.replace('À', "À") newln = newln.replace('È', "È") newln = newln.replace('Ì', "Ì") newln = newln.replace('Ò', "Ò") newln = newln.replace('Ù', "Ù") newln = newln.replace('Â', "Â") newln = newln.replace('Ê', "Ê") newln = newln.replace('Î', "Î") newln = newln.replace('Ô', "Ô") newln = newln.replace('Û', "Û") newln = newln.replace('Ä', 'Ä') newln = newln.replace('Ë', 'Ë') newln = newln.replace('Ï', 'Ï') newln = newln.replace('Ö', 'Ö') newln = newln.replace('Ü', 'Ü') newln = newln.replace('Ç', 'Ç') newln = newln.replace('Ñ', 'Ñ') newln = newln.replace('Æ', 'Æ') newln = newln.replace('Œ', 'Œ') newln = newln.replace('¡', '¡') newln = newln.replace('¿', '¿') newln = newln.replace('·', '·') newln = newln.replace('<', '<') newln = newln.replace('>', '>') newln = newln.replace('', '*') # newln = newln.replace('º', '°') newln = newln.replace('ª', 'a') newln = newln.replace('º', 'o') newln = newln.replace('°', '°') newln = newln.replace('\n', '
\n') newln = newln.replace('\t', '    ') return newln 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('\xf6', '\\"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('<', '\\tetxless') newln = newln.replace('>', '\\textgreater') 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 ASCII_WIKItab(ln,sep): """ Function to pass a line to WIKI table format ln= line to transform sep= character to split columns """ fname = 'ASCII_WIKItab' values = ln.split(sep) newln = '' for val in values: newln = newln + '| ' + val + '\n' newln = newln + '|-\n' 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}$ >>> latex_text('Lluís Fita$_{1976/02/17}$') Llu\'is Fita$_{1976/02/17}$ """ 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 NOchange = ['_', '^', '\\', '&', '$'] latextext = ASCII_to(latextext, 'tex', NOchange) 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 or zero' 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 def matoperations(opN,matA,matB=None): """ Function to perform different operations to a pair of matrices of values opN: name of the operation 'add': adding matB to matA (matA + matB) 'addc',[modval1]: add [modval1] 'arctan', arctangent of matA (result [-pi, pi]) 'centerderiv',[N],[ord],[dim]: un-scaled center [N]-derivative of order [ord] along dimension [dim] of matA 'div': dividing by matB (matA / matB) 'divc',[modval1]: divide by [modval1] 'forwrdderiv',[N],[ord],[dim]: un-scaled forward [N]-derivative of order [ord] along dimension [dim] of matA 'ifreq_anom',[dimns],[istep],[stepdimn]: computing anomalues by substracting sub-means at each step by averaging from there all values taken every [istep] along dimension [stepdim]. mean(j) = sum(matA[j+k*istep]_k=0,Nstep)/Nstep; Nstep = len(stepdimn)/istep; j=[0,istep] [dimns]= ':' list of dimensions of the matrice [istep]= frequency to sample [stepdimn]= name of the dimension along which to sample 'ifreq_mean',[dimns],[istep],[stepdimn]: computing sub-means at each step by averaging from there all values taken every [istep] along dimension [stepdim]. mean(j) = sum(matA[j+k*istep]_k=0,Nstep)/Nstep; Nstep = len(stepdimn)/istep; j=[0,istep] [dimns]= ':' list of dimensions of the matrice [istep]= frequency to sample [stepdimn]= name of the dimension along which to sample 'inv': inverting matA (1/matA) 'lowthres',[modval1],[modval2]: if [val] < [modval1]; val = [modval2] 'lowthres@oper',[modval1],[oper],[modval2]: if [val] < [modval1]; val = [oper] (operation as [modval2]) 'mul': multiplying ny matB (matA * matB) 'mulc',[modval1]: multiply by [modval1] 'norm_meanminmax',[dimns],[normdimns],[idims]: normalization of data of dimensions [dimns] (':' list) as: (val - )/(max(val)-min(val)) along dimension-names [normdimns] (':' list of names) and dimension-indices [idims] (':' list of indices) of matA 'norm_minmax',[NOTnormdims]: normalization of data as: [2val-(max(val)+min(val)]/[max(val)-min(val)] except along dimensions [NOTnormdims] (':' list of dimension names, or 'any' for using all dimensions) 'norm_meanstd',[dimns],[normdimns],[idims]: normalization of data of dimensions [dimns] (':' list) as: (val - )/stdev(val) along dimension-names [normdimns] (':' list of names) and dimension-indices [idims] (':' list of indices) of matA 'pot': powering with matB (matA ** matB) 'potc',[modval1]: [val] ** [modval1] 'repl',[modval1]: replace values of matA with values from matB except matB = [modval1] 'replbig',[modval1]: replace values of matA with values from matB except matB > [modval1] 'repless',[modval1]: replace values of matA with values from matB except matB < [modval1] 'sub': substracting matB to matA (matA - matB) 'subc',[modval1]: remove [modval1] 'upthres',[modval1],[modval2]: if [val] > [modval1]; val = [modval2] 'upthres@oper',[modval1],[oper],[modval2]: if [val] > [modval1]; val = [oper] (operation with [modval2]) matA: initial values matB: values to operate with >>> matoperations('centerderiv,1,8,0',np.arange(81.).reshape(9,9)) [[ 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 9. 9. 9. 9. 9. 9. 9. 9. 9.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0.]], '1-center_deriv_ord(8)[0]' >>> matoperations('forwrdderiv,2,2,0',np.arange(81.).reshape(9,9)) [[ 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0.] [ 0. 0. 0. 0. 0. 0. 0. 0. 0.]], '2-forward_deriv_ord(2)[0]' >>> matoperations('upthres,4,3',np.arange(81).reshape(9,9)) [[0 1 2 3 4 3 3 3 3] [3 3 3 3 3 3 3 3 3] [3 3 3 3 3 3 3 3 3] [3 3 3 3 3 3 3 3 3] [3 3 3 3 3 3 3 3 3] [3 3 3 3 3 3 3 3 3] [3 3 3 3 3 3 3 3 3] [3 3 3 3 3 3 3 3 3] [3 3 3 3 3 3 3 3 3]], '>4 [=3]' >>> matoperations('lowthres@oper,37,divc,7',np.arange(81).reshape(9,9)) [[ 0 0 0 0 0 0 0 1 1] [ 1 1 1 1 1 2 2 2 2] [ 2 2 2 3 3 3 3 3 3] [ 3 4 4 4 4 4 4 4 5] [ 5 37 38 39 40 41 42 43 44] [45 46 47 48 49 50 51 52 53] [54 55 56 57 58 59 60 61 62] [63 64 65 66 67 68 69 70 71] [72 73 74 75 76 77 78 79 80]], '<37 [=/7]' """ fname = 'matoperations' newmat = None matAshape = list(matA.shape) # From: https://en.wikipedia.org/wiki/Finite_difference_coefficient # Coefficients for center derivatives at different orders (as key) centerderiv = np.zeros((6,8,9), dtype=np.float) # Different available orders for each derivative centerorder = {} centerorder[0] = [1,3,5,7] centerorder[1] = [1,3,5,7] centerorder[2] = [1,3,5] centerorder[3] = [1,3,5] centerorder[4] = [1] centerorder[5] = [1] # First derivative centerderiv[0,1,:]= [ 0., 0., 0., -1./2., 0., 1./2., 0., 0., 0.] centerderiv[0,3,:]= [ 0., 0., 1./12., -2./3., 0., 2./3., -1./12., 0., 0.] centerderiv[0,5,:]= [ 0., -1./60., 3./20., -3./4., 0., 3./4., -3./20., 1./60, 0.] centerderiv[0,7,:]= [ 1./280., -4./105., 1./5., -4./5., 0., 4./5., -1./5., 4./105., -1./280.] # Second derivative centerderiv[1,1,:]= [ 0., 0., 0., 1., -2., 1., 0., 0., 0.] centerderiv[1,3,:]= [ 0., 0., -1./12., 4./3., -5./2., 4./3., -1./12., 0., 0.] centerderiv[1,5,:]= [ 0., 1./90., -3./20., 3./2., -49./18., 3./2., -.3/20., 1./90., 0.] centerderiv[1,7,:]= [ -1./560., 8./315., -1./5., 8./5., -205./72., 8./5., -1./5., 8./315., -1./560.] # 3rd derivative centerderiv[2,1,:]= [ 0., 0., -1./2., 1., 0., -1., 1./2., 0., 0.] centerderiv[2,3,:]= [ 0., 1./8., -1., 13./8., 0., -13./8., 1., -1./8., 0.] centerderiv[2,5,:]= [ -7./240., 3./10.,-169./120., 61./30., 0., -61./30., 169./120., -3./10., 7./240.] # 4th derivative centerderiv[3,1,:]= [ 0., 0., 1., -4., 6., -4., 1., 0., 0.] centerderiv[3,3,:]= [ 0., -1./6., 2., -13./2., 28./3., -13./2., 2., -1./6., 0.] centerderiv[3,5,:]= [ 7./240., -2./5., 169./60., -122./15., 91./8., -122./15., 169./60., -2./5., 7./240.] # 5th derivative centerderiv[4,1,:]= [ 0., -1./2., 2., -5./2., 0., 5./2., -2., 1./2., 0.] # 6th derivative centerderiv[5,1,:]= [ 0., 1., -6., 15., -20., 15., -6., 1., 0.] # Coefficients for forward derivatives at different orders (as key) forwrdderiv = np.zeros((6,6,9), dtype=np.float) # Different available orders for each derivative forwrdorder = {} forwrdorder[0] = range(6) forwrdorder[1] = range(6) forwrdorder[2] = range(6) forwrdorder[3] = range(4) # First derivative forwrdderiv[0,0,:]= [ -1., 1., 0., 0., 0., 0., 0., 0., 0.] forwrdderiv[0,1,:]= [ -3./2., 2., -1./2., 0., 0., 0., 0., 0., 0.] forwrdderiv[0,2,:]= [ -11./6., 3., -3./2., 1./3., 0., 0., 0., 0., 0.] forwrdderiv[0,3,:]= [ -25./12., 4., -3., 4./3., -1./4., 0., 0., 0., 0.] forwrdderiv[0,4,:]= [ -137./60., 5., -5., 10./3., -5./4., 1./5., 0., 0., 0.] forwrdderiv[0,5,:]= [ -49./20., 6., -15./2., 20./3., -15./4., 6./5., -1./6., 0., 0.] # Second derivative forwrdderiv[1,0,:]= [ 1., -2., 1., 0., 0., 0., 0., 0., 0.] forwrdderiv[1,1,:]= [ 2., -5., 4., -1., 0., 0., 0., 0., 0.] forwrdderiv[1,2,:]= [ 35./12., -26./3., 19./2., -14./3., 11./12., 0., 0., 0., 0.] forwrdderiv[1,3,:]= [ 15./4., -77./6., 107./6., -13., 61./12., -5./6., 0., 0., 0.] forwrdderiv[1,4,:]= [ 203./45., -87./5., 117./4., -254./9., 33./2., -27./5., 137./180., 0., 0.] forwrdderiv[1,5,:]= [ 469./90., -223./10., 879./20., -949./18., 41., -201./10.,1019./180., -7./10., 0.] # 3rd derivative forwrdderiv[2,0,:]= [ -1., 3., -3., 1., 0., 0., 0., 0., 0.] forwrdderiv[2,1,:]= [ -5./2., 9., -12., 7., -3./2., 0., 0., 0., 0.] forwrdderiv[2,2,:]= [ -17./4., 71./4., -59./2., 49./2., -41./4., 7./4., 0., 0., 0.] forwrdderiv[2,3,:]= [ -49./8., 29., -461./8., 62., -307./8., 13., -15./8., 0., 0.] forwrdderiv[2,4,:]= [-967./120., 638./15.,-3929./40., 389./3.,-2545./24., 268./5.,-1849./120, 29./15., 0.] forwrdderiv[2,5,:]= [ -801./80., 349./6.,-18353./120,2391./10., -1457./6., 4891./30., -561./8., 527./30.,-469./240.] # 4th derivative forwrdderiv[3,0,:]= [ 1., -4., 6., -4., 1., 0., 0., 0., 0.] forwrdderiv[3,1,:]= [ 3., -14., 26., -24., 11., -2., 0., 0., 0.] forwrdderiv[3,2,:]= [ 35./6., -31., 137./2., -242./3., 107./2., -19., 17./6., 0., 0.] forwrdderiv[3,3,:]= [ 28./3., -111./2., 142., -1219./6., 176., -185./2., 82./3., -7./2., 0.] forwrdderiv[3,4,:]= [ 1069./80.,-1316./15.,15289./60., -2144./5.,10993./24.,-4772./15., 2803./20., -536./15., 967./240.] # Dictionary with the description of the operations Lopn = {'add': '+', 'addc': '+', 'arctan': 'arctangent', 'div': '/', 'divc': '/',\ 'ifreq_mean': 'ifreq_mean', 'ifreq_mean': 'ifreq_mean', 'inv': '^(-1)', \ 'lowthres': '<', 'mul': '*', \ 'mulc': '*', 'norm_meanminmax': 'Norm_mean_minmax', \ 'norm_minmax': 'Norm_minmax', 'norm_meanstd': 'Norm_mean_devstd', 'pot': '^', \ 'potc': '^', 'repl': 'repl_excpt', 'replbig': 'repl_excpt_bigger', \ 'repless': 'repl_excpt_less', 'sub': '-', 'subc': '-', 'upthres': '<'} # Operations by constant value Lopnc = {'addc': '+', 'divc': '/', 'inv': '^{-1)', 'mulc': '*', 'potc': '^', \ 'repl': 'repl_excpt', 'replbig': 'repl_excpt_bigger', \ 'repless': 'repl_excpt_less', 'subc': '-'} # Available operations opavail = ['add', 'addc', 'arctan', 'centerderiv', 'div', 'divc', 'forwrdderiv', \ 'ifreq_anom', 'ifreq_mean', 'inv', \ 'lowthres', 'lowthres@oper', 'mul', 'mulc', 'norm_meanminmax', 'norm_minmax', \ 'norm_meanstd', 'pot', 'potc', 'repl', 'replbig', 'repless', 'sub', 'subc', \ 'upthres', 'upthres@oper'] opavailc = ['addc', 'divc', 'inv', 'mulc', 'potc', 'subc'] valtype = matA.dtype if opN[0:4] == 'addc': opn = 'addc' value1 = retype(opN.split(',')[1], valtype) Lopn['addc'] = '+' + str(value1) elif opN[0:6] == 'arctan': opn = 'arctan' Lopn['arctan'] = 'arctan' elif opN[0:11] == 'centerderiv': opn = 'centerderiv' Nderiv = int(opN.split(',')[1]) order = int(opN.split(',')[2]) dim = int(opN.split(',')[3]) Lopn[opn]= str(Nderiv)+'-center_deriv_ord('+str(order)+ ')[' + str(dim) + ']' if not centerorder.has_key(Nderiv-1): print errormsg print ' ' + fname + ': ', Nderiv,'-center derivative does not exist!!' print ' existing ones:', list(centeroder.keys())+1 quit() derivorders = centerorder[Nderiv-1] if not searchInlist(derivorders,order-1): print errormsg print ' ' + fname + ': ', Nderiv,'-center derivative does not have ' + \ 'order:', order,'!!' print ' existing ones:', np.array(derivorders) + 1 quit() if dim > len(matAshape)-1: print errormsg print ' '+fname+ ': wrong dimension:', dim, 'to compute the center-' + \ 'derivative!!' print ' matrix has a smaller rank:', len(matAshape) quit(-1) derivcoeff = centerderiv[Nderiv-1,order-1,:] elif opN[0:4] == 'divc': opn = 'divc' value1 = retype(opN.split(',')[1], valtype) Lopn['divc'] = '/' + str(value1) elif opN[0:11] == 'forwrdderiv': opn = 'forwrdderiv' Nderiv = int(opN.split(',')[1]) order = int(opN.split(',')[2]) dim = int(opN.split(',')[3]) Lopn[opn]= str(Nderiv)+'-forward_deriv_ord('+str(order)+ ')[' + str(dim) + ']' if not forwrdorder.has_key(Nderiv-1): print errormsg print ' ' + fname + ': ', Nderiv,'-forward derivative does not exist!!' print ' existing ones:', list(forwrdoder.keys())+1 quit() derivorders = forwrdorder[Nderiv-1] if not searchInlist(derivorders,order-1): print errormsg print ' ' + fname + ': ', Nderiv,'-forward derivative does not have ' + \ 'order:', order,'!!' print ' existing ones:', np.array(derivorders) + 1 quit() if dim > len(matAshape)-1: print errormsg print ' '+fname+ ': wrong dimension:', dim, 'to compute the forward-' + \ 'derivative!!' print ' matrix has a smaller rank:', len(matAshape) quit(-1) derivcoeff = forwrdderiv[Nderiv-1,order-1,:] elif opN[0:10] == 'ifreq_anom': opn = 'ifreq_anom' dimns = opN.split(',')[1].split(':') istep = int(opN.split(',')[2]) stepdimn = opN.split(',')[3] Lopn['ifreq_anom'] = 'anomaly by substracting ifreq_mean = sum(mat[j+k*' + \ str(istep)+']_k=0,Nstep)/Nstep; ' + 'Nstep=len(' + stepdimn + ')/' + \ str(istep) + '; j=[0,' + str(istep) + ']' elif opN[0:10] == 'ifreq_mean': opn = 'ifreq_mean' dimns = opN.split(',')[1].split(':') istep = int(opN.split(',')[2]) stepdimn = opN.split(',')[3] Lopn['ifreq_mean'] = 'sum(mat[j+k*' +str(istep)+']_k=0,Nstep)/Nstep; ' + \ 'Nstep=len(' + stepdimn + ')/' + str(istep) + '; j=[0,' + str(istep) + ']' elif opN[0:17] == 'ifreq_normmeanstd': opn = 'ifreq_normmeanstd' dimns = opN.split(',')[1].split(':') istep = int(opN.split(',')[2]) stepdimn = opN.split(',')[3] Lopn['ifreq_normmeanstd'] = 'normalization by substracting ' + \ 'ifreq_mean/ifreq_stdv ifreq_mean= sum(mat[j+k*' + str(istep) + \ ']_k=0,Nstep)/Nstep; ifreq_stdv=stdv(mat[j+k*' + str(istep)+']_k=0,Nstep)'+\ 'Nstep=len(' + stepdimn + ')/' + str(istep) + '; j=[0,' + str(istep) + ']' elif opN[0:4] == 'inv': opn = 'inv' Lopn['inv'] = 'inverse' elif opN[0:8] == 'lowthres' and opN.find('@') == -1: opn = 'lowthres' value1 = retype(opN.split(',')[1], valtype) value2 = retype(opN.split(',')[2], valtype) Lopn['lowthres'] = '<' + str(value1) + ' [=' + str(value2) +']' elif opN[0:13] == 'lowthres@oper': opn = 'lowthres@oper' value1 = retype(opN.split(',')[1], valtype) value2 = opN.split(',')[2] value3 = retype(opN.split(',')[3], valtype) if not Lopnc.has_key(value2): print errormsg print ' ' + fname + ": second operation '" + value2 + "' not ready !!" print ' available ones:', opavailc quit(-1) Lopn['lowthres@oper'] = '<' + str(value1) + ' [=' + Lopnc[value2] + \ str(value3) + ']' elif opN[0:4] == 'mulc': opn = 'mulc' value1 = retype(opN.split(',')[1], valtype) Lopn['mulc'] = '*' + str(value1) elif opN[0:15] == 'norm_meanminmax': opn = 'norm_meanminmax' dimns = opN.split(',')[1].split(':') normdimns = opN.split(',')[2].split(':') idimsS = opN.split(',')[3].split(':') idims = tuple(np.array(idimsS, dtype=int)) Lopn['norm_meanminmax'] = 'Norm_mean_minmax(' + ','.join(normdimns) + ')' elif opN[0:11] == 'norm_minmax': opn = 'norm_minmax' dimns = opN.split(',')[1].split(':') normdimns = opN.split(',')[2].split(':') idimsS = opN.split(',')[3].split(':') idims = tuple(np.array(idimsS, dtype=int)) Lopn['norm_minmax'] = 'Norm_minmax(' + ','.join(normdimns) + ')' elif opN[0:12] == 'norm_meanstd': opn = 'norm_meanstd' dimns = opN.split(',')[1].split(':') normdimns = opN.split(',')[2].split(':') idimsS = opN.split(',')[3].split(':') idims = tuple(np.array(idimsS, dtype=int)) Lopn['norm_meanstd'] = 'Norm_mean_std(' + ','.join(normdimns) + ')' elif opN[0:4] == 'potc': opn = 'potc' value1 = retype(opN.split(',')[1], valtype) Lopn['potc'] = '^' + str(value1) elif opN[0:4] == 'repl' and opN.split(',')[0] == 'repl': opn = 'repl' value1 = retype(opN.split(',')[1], valtype) Lopn['repl'] = 'repl_excpt(' + str(value1) + ')' elif opN[0:7] == 'replbig': opn = 'replbig' value1 = retype(opN.split(',')[1], valtype) Lopn['replbig'] = 'repl_excpt(<' + str(value1) + ')' elif opN[0:7] == 'repless': opn = 'repless' value1 = retype(opN.split(',')[1], valtype) Lopn['repless'] = 'repl_excpt(>' + str(value1) + ')' elif opN[0:4] == 'subc': opn = 'subc' value1 = retype(opN.split(',')[1], valtype) Lopn['subc'] = '-' + str(value1) elif opN[0:7] == 'upthres' and opN.find('@') == -1: opn = 'upthres' value1 = retype(opN.split(',')[1], valtype) value2 = retype(opN.split(',')[2], valtype) Lopn['upthres'] = '>' + str(value1) + ' [=' + str(value2) +']' elif opN[0:12] == 'upthres@oper': opn = 'upthres@oper' value1 = retype(opN.split(',')[1], valtype) value2 = opN.split(',')[2] value3 = retype(opN.split(',')[3], valtype) if not Lopnc.has_key(value2): print errormsg print ' ' + fname + ": second operation '" + value2 + "' not ready !!" print ' available ones:', opavailc quit(-1) Lopn['upthres@oper'] = '>' + str(value1) + ' [=' + Lopnc[value2] + \ str(value3) +']' else: opn = opN # Carrying on the operation additional = None if opn == 'add': newmat = matA + matB elif opn == 'addc': newmat = matA + value1 elif opn == 'arctan': newmat = np.arctan2(matA,matB) elif opn == 'centerderiv': sdim = matAshape[dim] # Getting the different slices for each coefficient # newmat = matA_4*coef_4 + matA_3*coef_3 + matA_2*coef_2 + matA_1*coef_1 + # matA*coef0 + matA1*coef1 + mat2*coef2 + matA3*coef3 + mat4*coef4 newmat = np.zeros(tuple(matAshape), dtype=valtype) mat0 = [] mat1_ = [] mat1 = [] mat2_ = [] mat2 = [] mat3_ = [] mat3 = [] mat4_ = [] mat4 = [] Nterms = 2*int((Nderiv-1)/2)+order+1 for idim in range(len(matAshape)): if idim == dim: sd = (Nterms-1)/2 ed = sdim - (Nterms-1)/2 mat0.append(slice(sd,ed)) mat1_.append(slice(sd-1,ed-1)) mat1.append(slice(sd+1,ed+1)) mat2_.append(slice(sd-2,ed-2)) mat2.append(slice(sd+2,ed+2)) mat3_.append(slice(sd-3,ed-3)) mat3.append(slice(sd+3,ed+3)) mat4_.append(slice(sd-4,ed-4)) mat4.append(slice(sd+4,ed+4)) else: mat0.append(slice(0,matAshape[idim]+1)) mat1_.append(slice(0,matAshape[idim]+1)) mat1.append(slice(0,matAshape[idim]+1)) mat2_.append(slice(0,matAshape[idim]+1)) mat2.append(slice(0,matAshape[idim]+1)) mat3_.append(slice(0,matAshape[idim]+1)) mat3.append(slice(0,matAshape[idim]+1)) mat4_.append(slice(0,matAshape[idim]+1)) mat4.append(slice(0,matAshape[idim]+1)) if Nterms == 3: newmat[tuple(mat0)] = matA[tuple(mat1_)]*derivcoeff[3] + \ matA[tuple(mat0)]*derivcoeff[4] + matA[tuple(mat1)]*derivcoeff[5] elif Nterms == 5: newmat[tuple(mat0)] = matA[tuple(mat2_)]*derivcoeff[2] + \ matA[tuple(mat1_)]*derivcoeff[3] + \ matA[tuple(mat0)]*derivcoeff[4] + \ matA[tuple(mat1)]*derivcoeff[5] + matA[tuple(mat2)]*derivcoeff[6] elif Nterms == 7: newmat[tuple(mat0)] = matA[tuple(mat3_)]*derivcoeff[1] + \ matA[tuple(mat2_)]*derivcoeff[2] + matA[tuple(mat1_)]*derivcoeff[3] + \ matA[tuple(mat0)]*derivcoeff[4] + \ matA[tuple(mat1)]*derivcoeff[5] + matA[tuple(mat2)]*derivcoeff[6] + \ matA[tuple(mat3)]*derivcoeff[7] elif Nterms == 9: newmat[tuple(mat0)] = matA[tuple(mat4_)]*derivcoeff[0] + \ matA[tuple(mat3_)]*derivcoeff[1] + matA[tuple(mat2_)]*derivcoeff[2] + \ matA[tuple(mat1_)]*derivcoeff[3] + \ matA[tuple(mat0)]*derivcoeff[4] + \ matA[tuple(mat1)]*derivcoeff[5] + matA[tuple(mat2)]*derivcoeff[6] + \ matA[tuple(mat3)]*derivcoeff[7] + matA[tuple(mat4)]*derivcoeff[8] elif opn == 'div': newmat = matA / matB elif opn == 'divc': newmat = matA / value1 elif opn == 'forwrdderiv': sdim = matAshape[dim] # Getting the different slices for each coefficient # newmat = matA0*coef0 + matA1*coef1 + matA2*coef2 + matA3*coef3 + # matA4*coef4 + matA5*coef5 + matA6*coef6 + matA7*coef7 + matA8*coef8 newmat = np.zeros(tuple(matAshape), dtype=valtype) mat0 = [] mat1 = [] mat2 = [] mat3 = [] mat4 = [] mat5 = [] mat6 = [] mat7 = [] mat8 = [] Nterms = Nderiv + order for idim in range(len(matAshape)): if idim == dim: sd = 0 ed = sdim-Nterms+1 mat0.append(slice(sd,ed)) mat1.append(slice(sd+1,ed+1)) mat2.append(slice(sd+2,ed+2)) mat3.append(slice(sd+3,ed+3)) mat4.append(slice(sd+4,ed+4)) mat5.append(slice(sd+5,ed+5)) mat6.append(slice(sd+6,ed+6)) mat7.append(slice(sd+7,ed+7)) mat8.append(slice(sd+8,ed+8)) else: mat0.append(slice(0,matAshape[idim]+1)) mat1.append(slice(0,matAshape[idim]+1)) mat2.append(slice(0,matAshape[idim]+1)) mat3.append(slice(0,matAshape[idim]+1)) mat4.append(slice(0,matAshape[idim]+1)) mat5.append(slice(0,matAshape[idim]+1)) mat6.append(slice(0,matAshape[idim]+1)) mat7.append(slice(0,matAshape[idim]+1)) mat8.append(slice(0,matAshape[idim]+1)) if Nterms == 2: newmat[tuple(mat0)] = matA[tuple(mat0)]*derivcoeff[0] + \ matA[tuple(mat1)]*derivcoeff[1] elif Nterms == 3: newmat[tuple(mat0)] = matA[tuple(mat0)]*derivcoeff[0] + \ matA[tuple(mat1)]*derivcoeff[1] + matA[tuple(mat2)]*derivcoeff[2] elif Nterms == 4: newmat[tuple(mat0)] = matA[tuple(mat0)]*derivcoeff[0] + \ matA[tuple(mat1)]*derivcoeff[1] + matA[tuple(mat2)]*derivcoeff[2] + \ matA[tuple(mat3)]*derivcoeff[3] elif Nterms == 5: newmat[tuple(mat0)] = matA[tuple(mat0)]*derivcoeff[0] + \ matA[tuple(mat1)]*derivcoeff[1] + matA[tuple(mat2)]*derivcoeff[2] + \ matA[tuple(mat3)]*derivcoeff[3] + matA[tuple(mat4)]*derivcoeff[4] elif Nterms == 6: newmat[tuple(mat0)] = matA[tuple(mat0)]*derivcoeff[0] + \ matA[tuple(mat1)]*derivcoeff[1] + matA[tuple(mat2)]*derivcoeff[2] + \ matA[tuple(mat3)]*derivcoeff[3] + matA[tuple(mat4)]*derivcoeff[4] + \ matA[tuple(mat5)]*derivcoeff[5] elif Nterms == 7: newmat[tuple(mat0)] = matA[tuple(mat0)]*derivcoeff[0] + \ matA[tuple(mat1)]*derivcoeff[1] + matA[tuple(mat2)]*derivcoeff[2] + \ matA[tuple(mat3)]*derivcoeff[3] + matA[tuple(mat4)]*derivcoeff[4] + \ matA[tuple(mat5)]*derivcoeff[5] + matA[tuple(mat6)]*derivcoeff[6] elif Nterms == 8: newmat[tuple(mat0)] = matA[tuple(mat0)]*derivcoeff[0] + \ matA[tuple(mat1)]*derivcoeff[1] + matA[tuple(mat2)]*derivcoeff[2] + \ matA[tuple(mat3)]*derivcoeff[3] + matA[tuple(mat4)]*derivcoeff[4] + \ matA[tuple(mat5)]*derivcoeff[5] + matA[tuple(mat6)]*derivcoeff[6] + \ matA[tuple(mat7)]*derivcoeff[7] elif Nterms == 9: newmat[tuple(mat0)] = matA[tuple(mat0)]*derivcoeff[0] + \ matA[tuple(mat1)]*derivcoeff[1] + matA[tuple(mat2)]*derivcoeff[2] + \ matA[tuple(mat3)]*derivcoeff[3] + matA[tuple(mat4)]*derivcoeff[4] + \ matA[tuple(mat5)]*derivcoeff[5] + matA[tuple(mat6)]*derivcoeff[6] + \ matA[tuple(mat7)]*derivcoeff[7] + matA[tuple(mat8)]*derivcoeff[8] elif opn == 'ifreq_anom': istepdim = dimns.index(stepdimn) lenstepdim = matA.shape[istepdim] Nsteps = lenstepdim/istep meannewmatsize = list(matA.shape) meannewmatsize[istepdim] = istep meannewmat = np.zeros(tuple(meannewmatsize), dtype=valtype) matAshape = matA.shape NmatAdims = len(matAshape) newmat = np.zeros(tuple(matAshape), dtype=valtype) for j in range(istep): slicemat = [] slicenewmat = [] meandims = [] for idim in range(NmatAdims): if idim == istepdim: slicemat.append(slice(j,j+Nsteps*istep,istep)) slicenewmat.append(j) meandims.append(idim) else: slicemat.append(slice(0,matAshape[idim])) slicenewmat.append(slice(0,matAshape[idim])) mdims=tuple(meandims) meannewmat[tuple(slicenewmat)]= np.mean(matA[tuple(slicemat)], axis=mdims) # Computing anomaly for it in range(Nsteps): slicemat = [] for idim in range(NmatAdims): if idim == istepdim: slicemat.append(j+it*istep) else: slicemat.append(slice(0,matAshape[idim])) newmat[tuple(slicemat)] = matA[tuple(slicemat)] - \ meannewmat[tuple(slicenewmat)] additional = [meannewmat] elif opn == 'ifreq_mean': istepdim = dimns.index(stepdimn) lenstepdim = matA.shape[istepdim] Nsteps = lenstepdim/istep newmatsize = list(matA.shape) newmatsize[istepdim] = istep newmat = np.zeros(tuple(newmatsize), dtype=valtype) matAshape = matA.shape NmatAdims = len(matAshape) for j in range(istep): slicemat = [] slicenewmat = [] meandims = [] for idim in range(NmatAdims): if idim == istepdim: slicemat.append(slice(j,j+Nsteps*istep,istep)) slicenewmat.append(j) meandims.append(idim) else: slicemat.append(slice(0,matAshape[idim])) slicenewmat.append(slice(0,matAshape[idim])) mdims=tuple(meandims) newmat[tuple(slicenewmat)] = np.mean(matA[tuple(slicemat)], axis=mdims) elif opn == 'ifreq_normmeanstd': istepdim = dimns.index(stepdimn) lenstepdim = matA.shape[istepdim] Nsteps = lenstepdim/istep meannewmatsize = list(matA.shape) meannewmatsize[istepdim] = istep meannewmat = np.zeros(tuple(meannewmatsize), dtype=valtype) stdnewmat = np.zeros(tuple(meannewmatsize), dtype=valtype) matAshape = matA.shape NmatAdims = len(matAshape) newmat = np.zeros(tuple(matAshape), dtype=valtype) for j in range(istep): slicemat = [] slicenewmat = [] meandims = [] for idim in range(NmatAdims): if idim == istepdim: slicemat.append(slice(j,j+Nsteps*istep,istep)) slicenewmat.append(j) meandims.append(idim) else: slicemat.append(slice(0,matAshape[idim])) slicenewmat.append(slice(0,matAshape[idim])) mdims=tuple(meandims) meannewmat[tuple(slicenewmat)]= np.mean(matA[tuple(slicemat)], axis=mdims) stdnewmat[tuple(slicenewmat)]= np.std(matA[tuple(slicemat)], axis=mdims) # Computing anomaly for it in range(Nsteps): slicemat = [] for idim in range(NmatAdims): if idim == istepdim: slicemat.append(j+it*istep) else: slicemat.append(slice(0,matAshape[idim])) newmat[tuple(slicemat)] = (matA[tuple(slicemat)] - \ meannewmat[tuple(slicenewmat)])/stdnewmat[tuple(slicenewmat)] additional = [meannewmat, stdnewmat] elif opn == 'inv': newmat = retype(1., valtype) / matA elif opn == 'lowthres': newmat = np.where(matA < value1, value2, matA) elif opn == 'lowthres@oper': if value2 == 'addc': newmat = np.where(matA < value1, matA + value3, matA) elif value2 == 'divc': newmat = np.where(matA < value1, matA / value3, matA) elif value2 == 'inv': newmat = np.where(matA < value1, retype(1.,valtype) / matA, matA) elif value2 == 'mulc': newmat = np.where(matA < value1, matA * value3, matA) elif value2 == 'potc': newmat = np.where(matA < value1, matA ** value3, matA) elif value2 == 'subc': newmat = np.where(matA < value1, matA - value3, matA) else: print errormsg print ' ' + fname + ": second operation '" + value2 + "' not ready !!" print ' available ones:', opavailc quit(-1) elif opn == 'mul': newmat = matA * matB elif opn == 'mulc': newmat = matA * value1 elif opn == 'norm_meanminmax': newmat = np.zeros((matA.shape), dtype=matA.dtype) meanval = np.mean(matA, axis=idims) minval = np.min(matA, axis=idims) maxval = np.max(matA, axis=idims) slices = provide_slices(dimns, matA.shape, normdimns) Nslices = len(slices) for islc in range(Nslices): listv = list(slices[islc]) for iind in range(len(idims)): indv = idims[iind] - iind listv.pop(indv) newmat[tuple(slices[islc])] = (matA[tuple(slices[islc])] - \ meanval[tuple(listv)]) / (maxval[tuple(listv)]-minval[tuple(listv)]) additional = [meanval, minval, maxval] elif opn == 'norm_minmax': newmat = np.zeros((matA.shape), dtype=matA.dtype) minval = np.min(matA, axis=idims) maxval = np.max(matA, axis=idims) slices = provide_slices(dimns, matA.shape, normdimns) Nslices = len(slices) for islc in range(Nslices): listv = list(slices[islc]) for iind in range(len(idims)): indv = idims[iind] - iind listv.pop(indv) xnadd = maxval[tuple(listv)]+minval[tuple(listv)] xnsub = maxval[tuple(listv)]-minval[tuple(listv)] newmat[tuple(slices[islc])] = (2.*matA[tuple(slices[islc])]-xnadd)/xnsub additional = [minval, maxval] elif opn == 'norm_meanstd': newmat = np.zeros((matA.shape), dtype=matA.dtype) meanval = np.mean(matA, axis=idims) stdval = np.std(matA, axis=idims) slices = provide_slices(dimns, matA.shape, normdimns) Nslices = len(slices) for islc in range(Nslices): listv = list(slices[islc]) for iind in range(len(idims)): indv = idims[iind] - iind listv.pop(indv) newmat[tuple(slices[islc])] = (matA[tuple(slices[islc])] - \ meanval[tuple(listv)]) / stdval[tuple(listv)] additional = [meanval, stdval] elif opn == 'pot': newmat = matA ** matB elif opn == 'potc': newmat = matA ** value1 elif opn == 'repl': newmat = np.where(matB == value1, matA, matB) elif opn == 'replbig': newmat = np.where(matB > value1, matA, matB) elif opn == 'repless': newmat = np.where(matB < value1, matA, matB) elif opn == 'sub': newmat = matA - matB elif opn == 'subc': newmat = matA - value1 elif opn == 'upthres': newmat = np.where(matA > value1, value2, matA) elif opn == 'upthres@oper': if value2 == 'addc': newmat = np.where(matA > value1, matA + value3, matA) elif value2 == 'divc': newmat = np.where(matA > value1, matA / value3, matA) elif value2 == 'inv': newmat = np.where(matA > value1, retype(1.,valtype) / matA, matA) elif value2 == 'mulc': newmat = np.where(matA > value1, matA * value3, matA) elif value2 == 'potc': newmat = np.where(matA > value1, matA ** value3, matA) elif value2 == 'subc': newmat = np.where(matA > value1, matA - value3, matA) else: print errormsg print ' ' + fname + ": second operation '" + value2 + "' not ready !!" print ' available ones:', opavailc quit(-1) else: print ' ' + fname + ": operation '" + opn + "' does not exist !!" print ' available ones:', opavail quit(-1) return newmat, Lopn[opn], additional def latex_fig_array(figs, obf, figcaption, figlabel, dist='sqr', refsize=0.9, \ width='auto', height='None', dorest='nothing'): """ Function to add an array of figures to an existing tex file figs= list of figures names (with path) obf= already exisiting object open tex file figcaption= caption for the figure figlabel= label for the figure dist= kind of distribution 'sqr': squared, figures are equivenly distributed in rows and columns (sqrt(Nfigs), default) [Ncol]'x'Nrow: a given number of columns and rows refsize= refernce images size (0.9, default) width= with of the figures 'None': no value passed 'auto': getting according to fractions of [refsize]\textwidth (default) [value]: exactly as it is desired (e.g.: '0.3\\textwidht', '5cm' ...) height= height of the figures 'None': no value passed (default) 'auto': getting according to fractions of [refsize]\textheight [value]: exactly as it is desired (e.g.: '0.3\\textheight', '5cm' ...) dorest= what to do with the last row if it does not fill the number of columns 'nothing': left empty columns (default) 'center': center the figures >>> latex_fig_array(['figs/figA.png','figs/figB.png','figs/figC.png','figs/figD.png','figs/figE.png'], \ objf, 'figure test', 'fig:test', dist='2x3', width='None', height='auto', dorest='center') \begin{figure} \begin{center} \begin{tabular}{cc} \includegraphics[height=0.3\textheight]{figs/figA.png} & \includegraphics[height=0.3\textheight]{figs/figB.png} \\ \includegraphics[height=0.3\textheight]{figs/figC.png} & \includegraphics[height=0.3\textheight]{figs/figD.png} \\ \multicolumn{2}{c}{\begin{tabular}{c} \includegraphics[height=0.3\textheight]{figs/figE.png} \end{tabular}} \end{tabular} \end{center} \caption{figure test} \label{fig:test} \end{figure} """ fname = 'latex_fig_array' if type(figs) == type('s'): figs = list(figs) Nfig = len(figs) if dist == 'sqr': Ncol = int(np.sqrt(Nfig)) Nrow = Nfig/Ncol Nrest = np.mod(Nfig,Ncol) if Nrest != 0: Nrow = Nrow + 1 elif dist.find('x') != -1: Ncol = int(dist.split('x')[0]) Nrow = int(dist.split('x')[1]) Nrest = np.mod(Nfig,Ncol) if Ncol*Nrow < Nfig: print errormsg print ' ' + fname +': wrong number of rows and columns!!' print " passed value of '" + dist + "' does not fit", Nfig, 'figures' quit(-1) else: print errormsg print ' ' + fname + ": figure distribution '" + dist + "' does not exist!!" print " existing ones: 'sqr', [Ncol]x[Nrow]" quit(-1) # Special case on Nfigs == 2 if Nfig == 2: Ncol = 2 Nrow = 1 Nrest = np.mod(Nfig,Ncol) # We prefer lines of figures rather than columns print 'Lluis Ncol:', Ncol, 'Nrow:', Nrow if dist == 'sqr' and (Ncol < Nrow): vc = Ncol vr = Nrow Ncol = vr Nrow = vc Nrest = np.mod(Nfig,Ncol) print ' ' + fname + ': table of figures of: ', Ncol, 'columns', Nrow, 'rows' # Checking for row/column size consistency definition if width == 'auto' and height == 'None' and Nrow > Ncol: print warnmsg print ' ' + fname + ': changing autmoatic configuration !!' print ' row-based definition of image sizes since number of rows:', Nrow, \ 'is larger than the number of columns:', Ncol print " from width='auto', height='None'" print " to width='None', height='auto'" width = 'None' height = 'auto' # Width and height section widthheight = '' if width != 'None': if width == 'auto': sec = np.float(refsize)/Ncol widthheight = 'width=' + str(sec) + '\\textwidth' else: widthheight = 'width=' + width if height != 'None': if len(widthheight) > 0: widthheight = widthheight + ', ' if height == 'auto': sec = np.float(refsize)/Nrow widthheight = widthheight + 'height=' + str(sec) + '\\textheight' else: widthheight = widthheight + 'height=' + height # num cols cS = '' for ic in range(Ncol): cS = cS + 'c' obf.write('\n') obf.write('\\begin{figure}\n') obf.write('\\begin{center}\n') # loop of figures distributed by Ncol, Nrow if Nfig > 1: obf.write('\\begin{tabular}{' + cS + '}\n') iifig = 0 for irow in range(Nrow): if irow < Nrow -1 or (irow == Nrow - 1 and dorest == 'nothing'): for icol in range(Ncol): # Getting figure name if it does exist if iifig <= Nfig - 1: fign = figs[iifig] obf.write('\\includegraphics[' + widthheight + ']{' +fign+ '}\n') if icol < Ncol - 1: obf.write('&\n') elif irow != Nrow - 1: obf.write('\\\\\n') else: if icol < Ncol -2: obf.write('&\n') iifig = iifig + 1 elif irow == Nrow -1 and dorest == 'center': crestS = '' if Nrest != 0: for irc in range(Nrest): crestS = crestS + 'c' obf.write('\\multicolumn{'+str(Ncol)+'}{c}{\\begin{tabular}{' + \ crestS + '}\n') for icol in range(Nrest): fign = figs[iifig] obf.write('\\includegraphics[' + widthheight + ']{' + fign + \ '}\n') if icol < Nrest - 1: obf.write('&\n') else: obf.write('\\end{tabular}}\n') iifig = iifig + 1 else: # Case with images which fulfill the last row for icol in range(Ncol): fign = figs[iifig] obf.write('\\includegraphics[' + widthheight + ']{' + fign + \ '}\n') if icol < Ncol - 1: obf.write('&\n') iifig = iifig + 1 obf.write('\\end{tabular}\n') else: print warnmsg print ' ' + fname + ': passed a single figure!!' fign = figs[0] obf.write('\\includegraphics[' + widthheight + ']{' +fign+ '}\n') obf.write('\\end{center}\n') obf.write('\\caption{' + figcaption + '}\n') obf.write('\\label{' + figlabel + '}\n') obf.write('\\end{figure}\n') obf.write('\n') return def lstring_values(liststring,sepchar,finalchar): """ Function to provide a new list-string from a string which is a list of word separated by a character if some values are repeated they are not included liststring= string of [sepchar] separated list of words sepchar= original character used to separate different words finalchar= final character used to separated values at the resultant string >>> lstring_values('tas-tas','-',':') tas >>> lstring_values('tturb-xmean-last@tturb-xmean-last','@','-') tturb-xmean-last """ fname = 'lstring_values' words = liststring.split(sepchar) newwords = [] for word in words: if not searchInlist(newwords,word): newwords.append(word) newstring = finalchar.join(newwords) return newstring #quit() def int_to_roman(input, romanchar='U'): """ FROM: http://code.activestate.com/recipes/81611-roman-numerals/ Convert an integer to Roman numerals. input= number to transform romanchar= type of characters 'l': lower romans: i, v, c, ... 'U': upper romans: I, V, C, ... (default) Examples: >>> int_to_roman(0) Traceback (most recent call last): ValueError: Argument must be between 1 and 3999 >>> int_to_roman(-1) Traceback (most recent call last): ValueError: Argument must be between 1 and 3999 >>> int_to_roman(1.5) Traceback (most recent call last): TypeError: expected integer, got >>> for i in range(1, 21): print int_to_roman(i) ... I II III IV V VI VII VIII IX X XI XII XIII XIV XV XVI XVII XVIII XIX XX >>> print int_to_roman(2000) MM >>> print int_to_roman(1999) MCMXCIX """ if type(input) != type(1): raise TypeError, "expected integer, got %s" % type(input) if not 0 < input < 4000: raise ValueError, "Argument must be between 1 and 3999" ints = (1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1) if romanchar == 'U': nums = ('M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I') elif romanchar == 'l': nums = ('m', 'cm', 'd', 'cd', 'c', 'xc', 'l', 'xl', 'x', 'ix', 'v', 'iv', 'i') else: print errormsg print ' ' + fname + ": roman char '" + romanchar + "' not ready!!" print " authorized ones: 'U', 'l'" quit(-1) result = "" for i in range(len(ints)): count = int(input / ints[i]) result += nums[i] * count input -= ints[i] * count return result def roman_to_int(input, romanchar='U'): """ FROM: http://code.activestate.com/recipes/81611-roman-numerals/ Convert a roman numeral to an integer. input= roman number to transform romanchar= type of characters 'l': lower romans: i, v, c, ... 'U': upper romans: I, V, C, ... (default) >>> r = range(1, 4000) >>> nums = [int_to_roman(i) for i in r] >>> ints = [roman_to_int(n) for n in nums] >>> print r == ints 1 >>> roman_to_int('VVVIV') Traceback (most recent call last): ... ValueError: input is not a valid roman numeral: VVVIV >>> roman_to_int(1) Traceback (most recent call last): ... TypeError: expected string, got >>> roman_to_int('a') Traceback (most recent call last): ... ValueError: input is not a valid roman numeral: A >>> roman_to_int('IL') Traceback (most recent call last): ... ValueError: input is not a valid roman numeral: IL """ if type(input) != type(""): raise TypeError, "expected string, got %s" % type(input) input = input.upper() if romanchar == 'U': nums = ['M', 'D', 'C', 'L', 'X', 'V', 'I'] elif romanchar == 'l': nums = ['m', 'd', 'c', 'l', 'x', 'v', 'i'] else: print errormsg print ' ' + fname + ": roman char '" + romanchar + "' not ready!!" print " authorized ones: 'U', 'l'" quit(-1) ints = [1000, 500, 100, 50, 10, 5, 1] places = [] for c in input: if not c in nums: raise ValueError, "input is not a valid roman numeral: %s" % input for i in range(len(input)): c = input[i] value = ints[nums.index(c)] # If the next place holds a larger number, this value is negative. try: nextvalue = ints[nums.index(input[i +1])] if nextvalue > value: value *= -1 except IndexError: # there is no next place. pass places.append(value) sum = 0 for n in places: sum += n # Easiest test for validity... if int_to_roman(sum) == input: return sum else: raise ValueError, 'input is not a valid roman numeral: %s' % input def linearint_weights(vals, intval): """ Function to provide the weights for a linear interpolation of a value between a couple of values as a weighted distance mean vals: couple of values intval: value to interpolate between [vals] >>> linearint_weights([1., 2.], 1.5) [0.5 0.5] >>> linearint_weights([-2., -1.], -1.0005) [ 5.00000000e-04 9.99500000e-01] """ fname = 'linear_weights' if vals[0] > vals[1]: sign = 'neg' else: sign = 'pos' if sign == 'neg' and not (intval <= vals[0] and intval >= vals[1]): print errormsg print ' ' + fname + ': wrong value:', intval , ' to interpolate for:', \ vals, ' range' quit(-1) if sign == 'pos' and not (intval >= vals[0] and intval <= vals[1]): print intval >= vals[0] print intval <= vals[1] print errormsg print ' ' + fname + ': wrong value:', intval , ' to interpolate for:', \ vals, ' range' quit(-1) inc = np.abs(vals[0] - vals[1]) linearwgt = [np.abs(intval - vals[0]), np.abs(intval - vals[1])] linearwgt = 1. - linearwgt / inc return linearwgt def linearint_3x3weights(xvals, yvals, intval0): """ Function to provide the weights for a linear interpolation of a value inside a 3x3 matrix of values as a weighted distance mean xvals: 3x3 matrix of x-values yvals: 3x3 matrix of y-values intval: value to interpolate between [yintval, xintval] It returns: * 3x3 matrix with weights (zero if are above the 4th shortest distacce, masked values for outside dx,dy positions) * Number of closest grid points (<=4) * 2x9 matrix with distance-sorted positions within the 3x3 matrix xvals = ma.masked_equal(np.zeros(9).reshape(3,3),0.) xvals[:,0] = 1. xvals[:,1] = 2. xvals[:,2] = 3. xvals.mask[2,2] = True yvals = xvals.transpose() >>> linearint_3x3weights(xvals, yvals, [1.5, 2.5]) (masked_array(data = [[0.0 0.25 0.25] [0.0 0.25 0.25] [0.0 0.0 --]], mask = [[False False False] [False False False] [False False True]], fill_value = 1e+20) , 4, array([[ 0, 0, 1, 1, 0, 1, 2, 2, -1], [ 1, 2, 1, 2, 0, 0, 1, 0, -1]])) """ fname = 'linear_3x3wegiths' intval = np.array(intval0, dtype=np.float) # Check data nx = xvals.min() xx = xvals.max() ny = yvals.min() xy = yvals.max() #print 'Lluis intval:', intval #print ' ' + fname + ' Lluis xvals ____' #print xvals #print ' ' + fname + ' Lluis yvals ____' #print yvals if not intval[1] >= nx and intval[1] <= xx: print errormsg print ' ' + fname + ': wrong value:', intval[1] , ' to interpolate for ' + \ 'x-range:' for i in range(3): print ' ', xvals[:,i] quit(-1) if not intval[0] >= ny and intval[0] <= xy: print errormsg print ' ' + fname + ': wrong value:', intval[0] , ' to interpolate for ' + \ 'y-range:' for i in range(3): print ' ', yvals[:,i] quit(-1) dist = np.sqrt( (xvals-intval[1])**2 + (yvals-intval[0])**2) inc = np.sum(dist) #print 'inc:', inc, 'intval', intval, 'dist ___' #for i in range(3): # print dist[:,i] ijvals = dist.copy() distpos = np.ones((2,9), dtype=int)*(-1) # shortest minium distance sortdist = list(dist.compressed()) sortdist.sort() iijj = 0 if sortdist[0] == 0.: ij = index_mat(ijvals,0.) distpos[:,iijj] = ij[:] wgt = np.zeros((3,3), dtype=np.float) wgt[ij[0], ij[1]] = 1. return wgt, 1, distpos # Getting ij values of distances, removing he already localized values iijj = 0 for ijdist in sortdist: if ijdist is not ma.masked: ij = index_mat(ijvals,ijdist) distpos[:,iijj] = ij[:] ijvals[ij[0],ij[1]] = fillValueF iijj = iijj + 1 # Normalizing values (only the first 4) if iijj >= 3: inc = np.sum(1./np.array(sortdist[0:4])) maxdist = sortdist[3] Nvals = 4 else: inc = np.sum(1./np.array(sortdist[0:iijj])) maxdist = sortdist[iijj] Nvals = iijj wgt = np.where(dist <= maxdist, 1./dist/inc, 0.) # Case with more than 4 points with less distance than `maxdist' (point at the diagonal) if np.sum(wgt) > 1.000001: print 'maxdist:', maxdist wgt = np.where(dist <= maxdist, dist, 0.) inc = 0. wgtflat = wgt.flatten() for i in range(9): if wgtflat[i] > 0.: inc = inc + 1./wgtflat[i] wgt = np.where(wgt > 0., 1./wgt/inc, 0.) Nvals = np.sum(wgt > 0.) if np.all(wgt == 0.): print errormsg print ' ' + fname + ': no point found !!' print ' point to interpolate:', intval0, ' around x & y & dist _____' for i in range(3): print xvals[:,i], '&', yvals[:,i], '&', dist[:,i] print ' sortdist:', sortdist, 'weights _____' for i in range(3): print wgt[:,i] quit(-1) # print 'Lluis weights _______', sortdist[0:4],'max:',maxdist,'sum:',np.sum(wgt) # for i in range(3): # print wgt[:,i] return wgt, Nvals, distpos def curvelocalize_2D(curve,xvals,yvals): """ Function to provide the localization a curve in a 2D field of positions via the equivalent i,j-quads within which the curve lays (-1, no value for the given quad [2x2 points around]) and provide the weights of the quad to perform a distance-weighted mean at the given curve point x,y_j,i x,y_j,i+1 curve(k) curve(k+1) x,y_j-1,i x,y_j-1,i+1 curve= [2, Npts] matrix of values of the curve yval0, xval0 yval1, xval1 (...) yvalNpts, xvalNpts xvals= 2D matrix of x-coordinate values yvals= 2D matrix of y-coordinate values RETURNS: curvloc= [Npts,2] matrix with the closest i,j grid point in the 2D space of the field positions curvweights= [Npts,3,3] 3x3 matrix weights around the curve position Nwgt= Number of weights ijaorund3x3= [Npts,2,9] distance (in xval, yval units) to the curve position exctcurvloc= [Npts,2] matrix with the exact i,j grid point in the 2D space of the field positions """ fname = 'curvelocalize_2D' Npts = curve.shape[0] curvloc = np.ones((curve.shape), dtype=int)*(-1) Nwgts = np.zeros((Npts), dtype=int) curveweights = np.zeros((Npts,3,3), dtype=np.float) ijaround3x3 = np.zeros((Npts,2,9), dtype=int) exctcurvloc = np.ones((curve.shape), dtype=np.float)*(-1) for icv in range(Npts): # Closest grid-point dist = np.sqrt((xvals - curve[icv,1])**2 + (yvals - curve[icv,0])**2) mindist = np.min(dist) ijloc = index_mat(dist,mindist) if np.any(ijloc == -1): print errormsg print ' ', fname, ': curve position:', curve[icv,:], 'not found !!' quit(-1) curvloc[icv,0] = ijloc[0] curvloc[icv,1] = ijloc[1] # Values around the nearest 2D-point to the curve point xaroundvls = vals_around(xvals,ijloc) yaroundvls = vals_around(yvals,ijloc) curveweights[icv,:,:], Nwgts[icv], ijaround3x3[icv,:,:] = \ linearint_3x3weights(xaroundvls, yaroundvls, curve[icv,:]) exctcurvloc[icv,:] = curvloc[icv,:] for ip in range(Nwgts[icv]): ipy = ijaround3x3[icv,0,ip] ipx = ijaround3x3[icv,1,ip] exctcurvloc[icv,0] = np.float(exctcurvloc[icv,0]) + curveweights[icv,ipy,ipx]*(ipy-1.) exctcurvloc[icv,1] = np.float(exctcurvloc[icv,1]) + curveweights[icv,ipy,ipx]*(ipx-1.) #print ' ' + fname + 'ip:', ip, 'ipy:', ipy-1., 'wgt:', curveweights[icv,ipy,ipx], \ # 'exctcurv:', exctcurvloc[icv,0] #print ' ' + fname + ' icv:', icv, 'curve:', curve[icv,:], 'ijloc:', ijloc, \ # 'cwgt:', curveweights[icv,:,:], 'exctloc:', exctcurvloc[icv,:] # quit() return curvloc, curveweights, Nwgts, ijaround3x3, exctcurvloc # #lon1d = np.arange(10) #lat1d = np.arange(-5,5) #dx = lon1d.shape[0] #dy = lat1d.shape[0] # #lons = np.zeros((dy,dx), dtype=np.float) #lats = np.zeros((dy,dx), dtype=np.float) # #for iy in range(dy): # lons[iy,:] = lon1d #for ix in range(dx): # lats[:,ix] = lat1d # #Ncurve = 12 #iicurve = 0 #eicurve = dx-1 #ijcurve = 1 #ejcurve = dy-3 #iloncurve = lon1d[iicurve] #eloncurve = lon1d[eicurve] #ilatcurve = lat1d[ijcurve] #elatcurve = lat1d[ejcurve] #Dxcurve = (eloncurve-iloncurve)/(Ncurve-1.) #Dycurve = (elatcurve-ilatcurve)/(Ncurve-1.) # #curve = np.zeros((Ncurve,2), dtype=np.float) #for icv in range(Ncurve): # curve[icv,0] = ilatcurve + Dycurve*icv # curve[icv,1] = iloncurve + Dxcurve*icv # #print 'Curve origin:', ilatcurve, ',', iloncurve #print 'Curve ending:', elatcurve, ',', eloncurve # #print curve # #loccurve, wgts, Nwgts, loc3x3, exctloccurve = curvelocalize_2D(curve,lons,lats) #for ipt in range(Ncurve): # print 'pos:', ipt, 'curve:', curve[ipt,:],'loccurve:', loccurve[ipt,:], 'wgts:', wgts[ipt,:,:], 'Nwgts:', Nwgts[ipt], 'loc3x3:', loc3x3[ipt,:], 'exctloccurve:', exctloccurve[ipt,:] # for iw in range(Nwgts[ipt]): # iwy = loc3x3[ipt,0,iw] # iwx = loc3x3[ipt,1,iw] # print ' sort wgts:', iw,' iwy,iwx:', iwy,',',iwx, 'wgt:', wgts[ipt,iwy,iwx] def num_ordinal(num, lang='eng', kind='numOr', fmt='ascii', gender='masc'): """ Function to provide the ordinal of a given number, language, format and gender num= number to provide the ordinal lang= language of the ordinal 'eng': English kind= kind of the ordinal 'numOr': as num[Ord] 'Ordinal': long ordinal (not fully ready) fmt= format of the ordinal 'ascii': standard ASCII 'utf': utf-8 (with accents) gender= gender of the ordinal 'fem': femenin 'masc': masculin >>> num_ordinal(2, 'eng', 'numOr', 'ascii') '2nd' >>> num_ordinal(2, 'eng', 'Ordinal', 'ascii') 'second' >>> num_ordinal(7, 'cat', 'Ordinal', 'utf') 'setè' >>> num_ordinal(1, 'cat', 'Ordinal', 'utf', fem) 'primera' """ fname = 'num_ordinal' languages = ['cat', 'eng'] kinds = ['numOr', 'Ordinal'] formats = ['ascii', 'utf'] genders = ['fem', 'masc'] if not searchInlist(languages, lang): print errormsg print ' ' + fname + ": language '" + lang + "' not ready !!" print ' available ones:', languages quit(-1) if not searchInlist(kinds, kind): print errormsg print ' ' + fname + ": kind '" + kind + "' not ready !!" print ' available ones:', kinds quit(-1) if not searchInlist(formats, fmt): print errormsg print ' ' + fname + ": format '" + fmt + "' not ready !!" print ' available ones:', fomrats quit(-1) if not searchInlist(genders, gender): print errormsg print ' ' + fname + ": gender '" + gender + "' not ready !!" print ' available ones:', genders quit(-1) # Catalan # short ordinals ([fem, masc]) catord = {1: ['era', 'er'], 2: ['ona', 'on'], 3: ['era', 'er'], 4: ['rta', 'rt']} # Last special ordinal catlastord = 4 # generic ordinal ([fem, masc]) catgenord = ['ena', 'è'] # long ordinals catLord = {1: ['primera', 'primer'], 2: ['segona', 'segon'], 3: ['tercera', \ 'tercer'], 4: ['quarta', 'quart'], 5: ['cinquena', 'cinquè'], 6: ['sisena', \ 'sisè'], 7: ['setena', 'setè'], 8: ['vuitena', 'vuitè'], 9: ['novena', 'novè']} # English # short ordinals ([fem, masc]) engord = {1: ['st', 'st'], 2: ['nd', 'nd'], 3: ['rd', 'rd']} # Last special ordinal englastord = 3 # generic ordinal ([fem, masc]) enggenord = ['th','th'] # long ordinals engLord = {1: ['first', 'first'], 2: ['second', 'second'], 3: ['third', 'third'],\ 4: ['fourth', 'fourth'], 5: ['fifth', 'fifth'], 6: ['sixth','sixth'], \ 7: ['seventh', 'seventh'], 8: ['eight', 'eight'], 9: ['nineth', 'nineth']} if lang == 'cat': ords = catord lastord = catlastord genord = catgenord Lords = catLord elif lang == 'eng': ords = engord lastord = englastord genord = enggenord Lords = engLord Snum = str(num) if num > 10: LSnum = len(Snum) Senu = Snum[LSnum:LSnum+1] else: Senu = Snum # Ordinal if num < lastord: Ord = ords[num] else: Ord = genord if gender == 'fem': Sord = Ord[0] else: Sord = Ord[1] # Long ordinal if num < 10: LOrd = Lords[num] else: print warnmsg print ' ' + fname + ' long ordinal not ready for:', num, '!!' LOrd = 'None' if gender == 'fem': SLord = LOrd[0] else: SLord = LOrd[1] if kind == 'numOr': stringv = Sord elif kind == 'Ordinal': stringv = SLord else: print errormsg print ' ' + fname + ": kind '" + kind + "' not ready !!" print ' available ones:', kinds quit(-1) return stringv def auto_val(valchk, aval): """ Function to provide a value following an 'auto' configuration valchk= value to take (if != 'auto'), value is transformed to the type(aval) aval= value to take when it is configured as 'auto' >>> auto_val('auto', 3.) 3. >>> auto_val('2.3456', 3.) 2.3456 """ fname = 'auto_val' if valchk == 'auto': autoval = aval else: autoval = retype(valchk, type(aval)) return autoval def auto_val_list(listchk, Nvals, alist): """ Function to provide a list of values following an 'auto' configuration or a single value listchk= list to take (if != 'auto'), value is transformed to the type(aval[0]) *NOTE: if it is a single value, output will be Nvals copies of the single value Nvals= number of values to provide. alist= list to take when it is configured as 'auto' >>> auto_val('auto', 3, drawing_tools.colorsauto) ['#FF0000', '#00FF00', '#0000FF'] >>> auto_val('#00FFAA', 3, drawing_tools.colorsauto) ['#00FFAA', '#00FFAA', '#00FFAA'] >>> auto_val_list(['2.3','2','3.4'], 3, np.arange(3.)) [2.2999999999999998, 2.0, 3.3999999999999999] """ fname = 'auto_val_list' if type(listchk) == type('S'): if listchk == 'auto': autoval = alist[0:Nvals] else: autoval = [] for i in range(Nvals): autoval.append(retype(listchk, type(alist[0]))) else: autoval = [] if len(listchk) == 1: if listchk[0] != 'auto': for i in range(Nvals): autoval.append(retype(listchk[0], type(alist[0]))) else: autoval = alist[0:Nvals] else: for i in range(Nvals): autoval.append(retype(listchk[i], type(alist[0]))) return autoval #colorsauto = ['#FF0000', '#00FF00', '#0000FF', '#FF00FF', '#00FFFF', '#FFAA00', \ # '#AA0000', '#00AA00', '#0000AA', '#AA00AA', '#00AAAA', '#AA3200', '#AA0032', \ # '#32AA00', '#3200AA', '#00AA32', '#0032AA', '#32FF00', '#3200FF', '#0032FF', \ # '#FF3200', '#FF0032', '#00FF32', '#323200', '#320032', '#003232'] #print auto_val_list('auto', 3, colorsauto) #print auto_val_list('#00FFAA', 3, colorsauto) #print auto_val_list(['2.3','2','3.4'], 3, np.arange(3.)) def rectangular_spiral(Ntimes, dunits): """ Function to provide a rectangular spiral (along x,y-axis values) of values Ntimes: number of loops of the spiral (increasing by 1 along each axis dunits: units interval from which assign a value for each spiral value >>> rectangular_spiral(3, 3600.) array([ 0., 1., 1., 0., -1., -1., -1., 0., 1., 2., 2., 0., -2., -2., -2., 0 array([ 0., 0., 1., 1., 1., 0., -1., -1., -1., 0., 2., 2., 2., 0., -2., -2., -2., 0., 3., 3., 3., 0., -3., -3., -3.]), [0.0, 3600.0, 7200.0, 10800.0, 14400.0, 18000.0, 21600.0, 25200.0, 28800.0, 32400.0, 36000.0, 39600.0, 43200.0, 46800.0, 50400.0, 54000.0, 57600.0, 61200.0, 64800.0, 68400.0, 72000.0, 75600.0, 79200.0, 82800.0, 86400.0]) """ fname = 'rectangular_spiral' # Wind test values uwindtestv0 = [1., 1., 0., -1., -1., -1., 0., 1. ] vwindtestv0 = [0., 1., 1., 1., 0., -1., -1., -1. ] Nvals = len(uwindtestv0) uwindtestv = np.zeros((Nvals*Ntimes+1), dtype=np.float) vwindtestv = np.zeros((Nvals*Ntimes+1), dtype=np.float) for i in range(Ntimes): uwindtestv[i*Nvals+1:(i+1)*Nvals+1] = np.array(uwindtestv0)*(i+1) vwindtestv[i*Nvals+1:(i+1)*Nvals+1] = np.array(vwindtestv0)*(i+1) dimt = len(uwindtestv) twindtestv = [] for it in range(dimt): twindtestv.append(dtsecs*it) return uwindtestv, vwindtestv, twindtestv def timefmt_timelab(timefmt): """ Function to transform from C-like time format to general one timefmt= C-like instruction for time %y as [YY], %Y as [YYYY], %m as [MM], %d as [DD], %h as [HH], %M as [MI], %S as [SS] >>> timefmt_timelab('$%d^{%H}$') $[DD]^{[HH]}$ """ fname = 'timefmt_timelab' # Dictionary wtth the equivalencies dictchanges = {'%y': '[YY]', '%Y': '[YYYY]', '%m': '[MM]', '%d': '[DD]', \ '%H': '[HH]', '%M': '[MI]', '%S': '[SS]'} timelab = timefmt for chg in dictchanges.keys(): newv = dictchanges[chg] timelab = timelab.replace(chg, newv) if timelab.find('%') != -1: print warnsmg print ' '+fname+": unsuccesfull substitution of all C-like values from '" + \ timefmt + "' !!" return timelab def grib_CFequiv(gribcode, table): """ Function to provide the CF name of a GRIB variable code number gridcode= grib number to search for the reference table= gribd table reference returns list with [CFname], [GRistdbname], [Griblong_name], [Gribunits]] >>> grib_CFequiv(129, '128ECMWF') ['z', 'Z', 'Geopotential', 'm2s-2'] """ fname = 'grib_CFequiv' availtables = ['128ECMWF'] if table == '128ECMWF': # Source: https://rda.ucar.edu/cgi-bin/transform?xml=/metadata/ParameterTables/WMO_GRIB1.98-0.128.xml&view=gribdoc gribCF = {129: ['z', 'z', 'Geopotential', 'm2 s-2'], \ 130: ['ta', 't', 'Temperature', 'K'], \ 131: ['ua', 'u', 'U velocity', 'm s-1'], \ 132: ['va', 'v', 'U velocity', 'm s-1'], \ 134: ['ps', 'sp', 'Surface pressure', 'Pa'], \ 151: ['psl', 'msl', 'Mean sea-level pressure', 'Pa'], \ 157: ['hur', 'r', 'Relative humidity', '%']} else: print errormsg print ' ' + fname + ": grib table '" + table + "' not ready !!" print ' available ones:', availtables quit(-1) if not gribCF.has_key(gribcode): print errormsg print ' ' + fname + ": table '" + table + "' does not have grib code :", \ gribcode, '!!' print ' available ones:', gribCF.keys() quit(-1) CFname = gribCF[gribcode] return CFname def CF_gribequiv(CFname, table): """ Function to provide the GRIB variable code number from a CF name CFname= CF-variable name table= gribd table reference >>> CF_gribequiv('ua', '128ECMWF') [131, 'U', 'U velocity', 'm s-1'] """ fname = 'CF_gribequiv' availtables = ['128ECMWF'] if table == '128ECMWF': # Source: https://rda.ucar.edu/cgi-bin/transform?xml=/metadata/ParameterTables/WMO_GRIB1.98-0.128.xml&view=gribdoc gribCF = {129: ['z', 'z', 'Geopotential', 'm2 s-2'], \ 130: ['ta', 't', 'Temperature', 'K'], \ 131: ['ua', 'u', 'U velocity', 'm s-1'], \ 132: ['va', 'v', 'U velocity', 'm s-1'], \ 134: ['ps', 'sp', 'Surface pressure', 'Pa'], \ 151: ['psl', 'msl', 'Mean sea-level pressure', 'Pa'], \ 157: ['hur', 'r', 'Relative humidity', '%']} else: print errormsg print ' ' + fname + ": grib table '" + table + "' not ready !!" print ' available ones:', availtables quit(-1) # Inverting dictionaries (no need to hand write two dictionaries!) # For single values # FROM: http://stackoverflow.com/questions/483666/python-reverse-invert-a-mapping # CFgrib = dict((gribCF[k], k) for k in gribCF) CFgrib = {} for kv in gribCF.keys(): vals = gribCF[kv] newkv = vals[0] vals[0] = kv CFgrib[newkv] = vals if not CFgrib.has_key(CFname): print errormsg print ' ' + fname + ": table '" + table + "' does not have CF name :" + \ CFname + "' !!" print ' available ones:', CFgrib.keys() quit(-1) gribcode = CFgrib[CFname] return gribcode def crossingpoint_2Dlines(line1, line2): """ Function to determinant the crossing point between two lines in a plane line1= [a,b,c] terms of the polynomial representation of line1 ax+by+d line2= [a,b,c] terms of the polynomial representation of line2 ax+by+d >>> crossingpoint_2Dlines(np.array([1,-1,0]), np.array([1,1,-3])) [[ 1.5 1.5]] """ fname = 'crossingpoint_2lines' if len(line1.shape) != len(line2.shape): print errormsg print ' ' + fname + ': rank difference between lines !!' print ' shape line1:', line1.shape, 'line2:', line2.shape quit(-1) #determinant matA = np.array([line1[0:2], line2[0:2]]) detA = np.linalg.det(matA) # x-det matX = np.array([[-line1[2],-line1[1]], [line2[2],line2[1]]]) detX = np.linalg.det(matX) # y-det matY = np.array([[line1[0],line1[2]], [-line2[0],-line2[2]]]) detY = np.linalg.det(matY) #print 'mat A:' #print matA #print 'mat X:' #print matX #print 'mat Y:' #print matY #print 'det A:', detA, 'X:', detX, 'Y:', detY x = detX / detA y = detY / detA return np.array([[x, y]]) #print crossingpoint_2Dlines(np.array([1,-1,0]), np.array([1,1,-3])) def points_2Dline(pt1, pt2): """ Function to define a line from a pair of points on a plane it returns the terms of the polynomial description of the line ax+by+c=0 [a,b,c] pt1= first point [x,y] pt2= second point [x,y] >>> points_2Dline(np.array([1,1]), np.array([2,2])) [1 -1 0] points_2Dline(np.array([1,2]), np.array([2,1])) [1 1 -3] """ fname = 'points_2Dline' # minus minuseq = pt1 - pt2 b = -minuseq[0]/minuseq[1] # plus pluseq = pt1 + pt2 subsb = pluseq[1]*b subsa = pluseq[0] + subsb c = -subsa/2 return np.array([1, b, c]) def provide_slices(dimns, dimzs, rundims): """ Function to provide a list of slices for a matrix giving a sub-section of running dimensions dimns: list of names of dimensions dimzs: list of sizes of dimensions in the same order as in [dimns] rundims: name of dimensions to allow to run >>> provide_slices(['z', 't', 'y', 'x'], [2, 3, 10, 20], ['t', 'z', 'l']) [[1, 2, slice(0, 10, None), slice(0, 20, None)], [0, 1, slice(0, 10, None), slice(0, 20, None)], [1, 1, slice(0, 10, None), slice(0, 20, None)], [0, 0, slice(0, 10, None), slice(0, 20, None)], [1, 0, slice(0, 10, None), slice(0, 20, None)], [0, 2, slice(0, 10, None), slice(0, 20, None)]] """ fname = 'provide_slices' Ndims = len(dimns) # Checking presence of dimension in list of dimensions Tslicesize = 1 origslicesize = {} runslicesize = {} for dimn in rundims: if not searchInlist(dimns, dimn): #print warnmsg #print ' ' + fname + ": dimension '" + dimn + "' not in list !!" #print ' removing it' rundims.remove(dimn) for dimn in dimns: idim = index_vec(dimns, dimn) origslicesize[dimn] = dimzs[idim] if searchInlist(rundims, dimn): runslicesize[dimn] = dimzs[idim] - 1 Tslicesize = Tslicesize*dimzs[idim] #print ' ' + fname + ': Total number of slices to provide:', Tslicesize, \ # 'along:', runslicesize slices = [] for il in range(Tslicesize): islice = [] alreadychanged = False for idim in range(Ndims): dimn = dimns[idim] if searchInlist(rundims,dimn): islice.append(runslicesize[dimn]) # Only running value for a given dimension for the next if not alreadychanged: runslicesize[dimn] = runslicesize[dimn] - 1 alreadychanged = True if runslicesize[dimn] < 0: runslicesize[dimn] = origslicesize[dimn] - 1 for rdimn in rundims: if rdimn != dimn: runslicesize[rdimn] = runslicesize[rdimn] - 1 if runslicesize[rdimn] >= 0: break else: runslicesize[rdimn] = origslicesize[rdimn] - 1 else: islice.append(slice(0,origslicesize[dimn])) slices.append(islice) return slices def minmax_range(minv,maxv,rangekind): """ Function to provide a range for a given pair of minimum and maximum minv: minimum value from data maxv: maximum value from data rangekind: kind of range [val1],[val2]: tacking the provided ',' separated list of desired [val1] and [val2] 'auto': automatically set up range using minv and maxv 'extremescentered': extremes automatically centered on zero by computing from data -absmax, absmax; absmax=max(abs(minval),maxval) 'meancentered': extremes automatically centered on mean by computing from data minv+meanv, maxv-meanv; meanv=(minval + maxval)/2. >>> minmax_range(-3.25, 4.75, '-2.0,2.0') [-2.0, 2.0] >>> minmax_range(-3.25, 4.75, 'extremescentered') [-4.75, 4.75] >>> minmax_range(-3.25, 4.75, 'meancentered') [-2.5, 4.0] """ possibleranges = ['auto', 'extremescentered', 'meancentered'] if rangekind == 'None': valmin = minv valmax = maxv else: if not searchInlist(possibleranges, rangekind): valmin = np.float(rangekind.split(',')[0]) valmax = np.float(rangekind.split(',')[1]) else: if rangekind == 'auto': valmin = minv valmax = maxv elif rangekind == 'extremescentered': absmax = np.max([np.abs(minv), maxv]) valmin = -absmax*1. valmax = absmax elif rangekind == 'meancentered': meanv = (minv + maxv)/2. valmin = minv+meanv valmax = maxv-meanv else: print errormsg print ' ' +fname+ ": type of range '" + rangekind + "' not ready !!" print ' available ones:', possibleranges quit(-1) return [valmin, valmax] def transform(vals, trans, dxv='0', dyv='0', dxt='0', dyt='0', dxl='0', \ dyl='0', dxtit='0', dytit='0'): """ Function to transform the values and the axes vals= values to transform trans= '|' separated list of operations of transformation 'transpose': Transpose matrix of values (x-->y, y-->x) 'flip@[x/y]': Flip the given axis d[x/y]v= original values for the [x/y]-axis d[x/y]t= original ticks for the [x/y]-axis d[x/y]l= original tick-labels for the [x/y]-axis d[x/y]tit= original titles for the [x/y]-axis >>> mat = np.arange(15).reshape(3,5) >>> xvals = np.zeros((3,5), dtype=np.float) >>> yvals = np.zeros((3,5), dtype=np.float) >>> for i in range(5): >>> xvals[:,i] = -1.25 + i*0.5 >>> for j in range(3): >>> yvals[j,:] = 40.25 + j*0.5 >>> xticks = np.array([-1.25, -0.25, 0.25]) >>> yticks = np.array([40.25, 41.25]) >>> xticklab = ['1.25 W', '0.25 W', '0,25 E'] >>> yticklab = ['40.25 N', '41.25 N'] >>> xtit = 'Longitude' >>> ytit = 'Latitude' >>> nv, ndxv, ndyv, ndxt, ndyt, dxl, ndyl, ndxT, ndyT = transform(mat, 'transpose', \ xvals, yvals, xticks, yticks, xticklab, yticklab, xtit, ytit) [[ 0 5 10] [ 1 6 11] [ 2 7 12] [ 3 8 13] [ 4 9 14]] [[ 40.25 40.75 41.25] [ 40.25 40.75 41.25] [ 40.25 40.75 41.25] [ 40.25 40.75 41.25] [ 40.25 40.75 41.25]] [[-1.25 -1.25 -1.25] [-0.75 -0.75 -0.75] [-0.25 -0.25 -0.25] [ 0.25 0.25 0.25] [ 0.75 0.75 0.75]] [ 40.25 41.25] [-1.25 -0.25 0.25] ['41.25 N', '40.25 N'] ['0,25 E', '0.25 W', '1.25 W'] Latitude Longitude """ fname = 'transform' transforms = trans.split('|') Ntransforms = len(transforms) newvals = vals.copy() # values wdvx = False if type(dxv) == type('S') and dxv == '0': newdxv = None else: newdxv = dxv.copy() wdvx = True wdvy = False if type(dyv) == type('S') and dyv == '0': newdyv = None else: newdyv = dyv.copy() wdvy = True # ticks wdtx = False if type(dxt) == type('S') and dxt == '0': newdxt = None else: newdxt = dxt.copy() wdtx = True wdty = False if type(dyt) == type('S') and dyt == '0': newdyt = None else: newdyt = dyt.copy() wdty = True # label in ticks wdlx = False if type(dxl) == type('S') and dxl == '0': newdxl = None else: newdxl = list(dxl) wdlx = True wdly = False if type(dyl) == type('S') and dyl == '0': newdyl = None else: newdyl = list(dyl) wdly = True # axes' title wdTx = False if dxtit != 0: newdxtit = str(dxtit) wdTx = True else: newdxtit = None wdTy = False if dytit != '0': newdytit = str(dytit) wdTy = True else: newdytit = None # axis limits. They will be used to flip the axis in plot if necessary newxaxislim = [np.min(dxv), np.max(dxv)] newyaxislim = [np.min(dyv), np.max(dyv)] for transform in transforms: if transform == 'transpose': newvals = np.transpose(newvals) if wdvx and wdvy: copy = newdxv.copy() newdxv = np.transpose(newdyv) newdyv = np.transpose(copy) # else: # print errormsg # print ' ' + fname + ": it can not be '" + transform + "' without " +\ # ' both dimxvals:', dxv, ' and dimyvals:', dyv, ' !!' # quit(-1) if wdtx and wdtx: copy = newdxt.copy() newdxt = np.transpose(newdyt) newdyt = np.transpose(copy) # else: # print errormsg # print ' ' + fname + ": it can not be '" + transform + "' without " +\ # ' both dimxtickvals:', dxt, ' and dimytickvals:', dyt, ' !!' # quit(-1) if wdlx and wdly: copy = list(newdxl) newdxl = list(newdyl) newdyl = list(copy) # else: # print errormsg # print ' ' + fname + ": it can not be '" + transform + "' without " +\ # ' both dimxlabels:', dxl, ' and dimylabels:', dyl, ' !!' # quit(-1) if wdTx and wdTy: copy = str(newdxtit) newdxtit = str(newdytit) newdytit = str(copy) # else: # print errormsg # print ' ' + fname + ": it can not be '" + transform + "' without " +\ # ' both dimx title:', dxtit, ' and dimytitle:', dytit, ' !!' # quit(-1) copy = newxaxislim.copy() newxaxislim = newyaxislim newyaxislim = copy elif transform[0:4] == 'flip': if transform.find('@') == -1: print errormsg print ' ' + fname + ": no ax given for '" + transform + "' !!" quit(-1) flip = transform.split('@')[1] if flip == 'x': oldv = list(newxaxislim) newxaxislim[0] = oldv[1] newxaxislim[1] = oldv[0] elif flip == 'y': oldv = list(newyaxislim) newyaxislim[0] = oldv[1] newyaxislim[1] = oldv[0] elif flip == 'z': newvals = newvals[...,::-1,:,:] else: print errormsg print ' '+ fname + ": transformation '" + transform + "' not ready!!" print ' available ones:', ['transpose', 'flip@x', 'flip@y'] quit(-1) return newvals, newdxv, newdyv, newdxt, newdyt, newdxl, newdyl, newdxtit, newdytit, newxaxislim, newyaxislim #mat = np.arange(15).reshape(3,5) #xvals = np.zeros((3,5), dtype=np.float) #yvals = np.zeros((3,5), dtype=np.float) #for i in range(5): # xvals[:,i] = -1.25 + i*0.5 #for j in range(3): # yvals[j,:] = 40.25 + j*0.5 #xticks = np.array([-1.25, -0.25, 0.25]) #yticks = np.array([40.25, 41.25]) #xticklab = ['1.25 W', '0.25 W', '0,25 E'] #yticklab = ['40.25 N', '41.25 N'] #xtit = 'Longitude' #ytit = 'Latitude' #nv, ndxv, ndyv, ndxt, ndyt, dxl, ndyl, ndxT, ndyT = transform(mat, 'flip@y', \ # xvals, yvals, xticks, yticks, xticklab, yticklab, xtit, ytit) # #print nv, ndxv, ndyv, ndxt, ndyt, dxl, ndyl, ndxT, ndyT #quit() def InsertVal_list_sign(listv, newvalues): """ Insert values into a sorrted list according to its sign of growth listv= inital values of the list newvalues= values to add >>> InsertVal_list_sign(range(0,100,10), [0,1,2,3,5,8,13,21,34,55,89,144]) [0, 1, 2, 3, 5, 8, 10, 13, 20, 21, 30, 34, 40, 50, 55, 60, 70, 80, 89, 90, 144] """ fname = 'InsertVal_list_sign' newlist = [] # Number of values Nold = len(listv) Nnew = len(newvalues) lsign = np.float(listv[1]) - np.float(listv[0]) # Number of values Lcoinvals = len(set(listv).intersection(set(newvalues))) Ldiffvals = len(set(listv).symmetric_difference(set(newvalues))) Ltot = Lcoinvals + Ldiffvals inew = 0 iold = 0 if lsign > 0.: for il in range(Ltot): if listv[iold] < newvalues[inew]: newval = listv[iold] iold = iold + 1 else: newval = newvalues[inew] inew = inew + 1 # Not repeating values if not searchInlist(newlist,newval): newlist.append(newval) # breaking just in case ... if iold > Nold -1: if not searchInlist(newlist,newvalues[inew]): newlist = newlist + newvalues[inew:Nnew] else: newlist = newlist + newvalues[inew+1:Nnew] break if inew > Nnew -1: if not searchInlist(newlist,listv[iold]): newlist = newlist + listv[iold:Nold] else: newlist = newlist + listv[iold+1:Nold] break else: for il in range(Ltot+1): if listv[iold] > newvalues[inew]: newval = listv[iold] iold = iold + 1 else: newval = newvalues[inew] inew = inew + 1 # Not repeating values if not searchInlist(newlist,newval): newlist.append(newval) # breaking just in case ... if iold > Nold -1: if not searchInlist(newlist,newvalues[inew]): newlist = newlist + newvalues[inew:Nnew] else: newlist = newlist + newvalues[inew+1:Nnew] break if inew > Nnew -1: if not searchInlist(newlist,listv[iold]): newlist = newlist + listv[iold:Nold] else: newlist = newlist + listv[iold+1:Nold] break return newlist def Nomasked(vals, dim): """ Function to bring back a given array wthout the masked values reducing a given dimension vals= array of values dim= which dimension along which if all values are maskd reduce >>> arrayv = np.arange(32).reshape(4,8) >>> maskv = np.zeros((4,8), dtype=bool) >>> maskv[1:3,:] = True >>> maarray = ma.maskedarray(arrayv, mask=maskv) >>> Nomasked(maarray, 0) masked_array(data = [[ 0 1 2 3 4 5 6 7] [24 25 26 27 28 29 30 31]], mask = False, fill_value = 999999) , array([False, True, True, False], dtype=bool)) """ fname = 'Nomasked' if type(vals) != type(mamat): print errormsg print ' ' + fname + ': only works with masked arrays !!' print ' provided type:', type(vals) quit(-1) if dim >= len(vals.shape): print errormsg print ' ' + fname + ': dimension provided too big !!' print ' shape of the values:', vals.shape quit(-1) varshape = vals.shape fillvalue = vals.fill_value dimns = [] for id in range(len(varshape)): dimns.append('d' + str(id)) # Looking for the slices along the given dimension slices = provide_slices(dimns, varshape, ['d'+str(dim)]) Nslices = len(slices) allmasked = np.zeros((Nslices), dtype=bool) for islc in range(Nslices): if all(vals.mask[tuple(slices[islc])]): allmasked[islc] = True # First looking for the slices Novals = np.sum(allmasked) # Definition of the new array newvarshape = list(varshape) newvarshape[dim] = varshape[dim]-Novals newarray = np.zeros(tuple(newvarshape), dtype=vals.dtype) newmaksv = np.zeros(tuple(newvarshape), dtype=bool) imask = 0 for islc in range(Nslices-1,-1,-1): if not allmasked[islc]: slicev = list(slices[islc]) slicev[dim] = imask newarray[tuple(slicev)] = vals[tuple(slices[islc])] imask = imask + 1 newarray = ma.masked_equal(newarray, fillvalue) return newarray, allmasked def shrinkarray_dim(vals, vector, dim): """ Function to shrink a given array with a vector of True/False along a given dimension vals= array of values vector= vector of booleans of the same length as dim (True: remove) dim= which dimension along which if all values are maskd reduce >>> arrayv = np.arange(32).reshape(4,8) >>> maskv = np.zeros((4), dtype=bool) >>> maskv[1:3] = True >>> shrinkarray_dim(arrayv, maskv, 0) [[ 0 1 2 3 4 5 6 7] [24 25 26 27 28 29 30 31]] """ fname = 'shrinkarray_dim' if dim >= len(vals.shape): print errormsg print ' ' + fname + ': dimension provided too big !!' print ' shape of the values:', vals.shape quit(-1) if len(vector) != vals.shape[dim]: print errormsg print ' ' + fname + ': provided vector and length of the dimension differ !!' print ' shape of the array:', vals.shape[dim], 'on dimension:', dim print ' length of the vector:', len(vector) quit(-1) varshape = vals.shape dimns = [] for id in range(len(varshape)): dimns.append('d' + str(id)) # Looking for the slices along the given dimension slices = provide_slices(dimns, varshape, ['d'+str(dim)]) Nslices = len(slices) # First looking for the slices Novals = np.sum(vector) # Definition of the new array newvarshape = list(varshape) newvarshape[dim] = varshape[dim]-Novals newarray = np.zeros(tuple(newvarshape), dtype=vals.dtype) imask = 0 for islc in range(Nslices-1,-1,-1): if not vector[islc]: slicev = list(slices[islc]) slicev[dim] = imask newarray[tuple(slicev)] = vals[tuple(slices[islc])] imask = imask + 1 return newarray def IsNumber(stringS, kind): """ Function to determine if a given String is a given type of number stringS: string to check kind: kind of number to check 'I': integer 'R': float 'D': float64 >>> IsNumber('3.14', 'R') True >>> IsNumber('3.14', 'I') False """ fname = 'IsNumber' availkind = ['I', 'R', 'D'] # Checking for conversion if kind == 'I': try: newnum = int(stringS) except: return False elif kind == 'R': try: newnum = np.float(stringS) except: return False elif kind == 'D': try: newnum = np.float64(stringS) except: return False else: print errormsg print ' ' + fname + ": provided type '" + kind + "' to check is not ready!!" print ' available ones:', availkind quit(-1) return True def fill_Narray(idata, narray, filldim=None): """ Function to fill a n-dimensional array with an arrary of lesser rank idata: initial array narray: enpty narray yo fill filldim: which number of dimensions have to be filled (None, for automatic) provide a list of number of dimensions in case some lengths of dimensions are repeated >>> ivec = np.arange(3, dtype=int) >>> nmat = np.zeros((3,2), dtype=int) >>> fill_Narray(ivec, nmat) [[0 0] [1 1] [2 2]] >>> nmat = np.zeros((3,2,3), dtype=int) >>> fill_Narray(ivec, nmat, filldim=[2]) [[[0 0 0] [0 0 0]] [[1 1 1] [1 1 1]] [[2 2 2] [2 2 2]]] """ fname = 'fill_Narray' ishape = idata.shape nshape = narray.shape Ndimsi = len(ishape) Ndimsn = len(nshape) # Dictionary with the equivalencies among dimensions # (-1, fill; 0, same dim as input) dimequiv = {} dimns = [] rundims = [] for idim in range(Ndimsn): dimns.append(str(idim)) if searchInlist(ishape, nshape[idim]): if filldim is not None: if searchInlist(filldim, idim): dimequiv[idim] = -1 rundims.append(str(idim)) else: dimequiv[idim] = 0 else: dimequiv[idim] = 0 else: dimequiv[idim] = -1 rundims.append(str(idim)) # Getting all the slices to fill narrayslices = provide_slices(dimns, list(nshape), rundims) # Filling narray Nslices = len(narrayslices) for islc in range(Nslices): narray[tuple(narrayslices[islc])] = idata return narray def getting_fixedline(line, cuts, types, dbg=False): """ Function to get the values from a line of text with fixed lenght of different values line: line with values cuts: character number where a value ends types: consecutive type of values 'I': integer 'R': real 'D': float64 'S': string 'B': boolean dbg: debug mode (default False) >>> Sline=' 87007 03012015 25.6 6.4 9.4 5 15' >>> getting_fixedline(Sline, [8, 17, 23, 29, 36, 40, 45, 50], ['I', 'R', 'R', 'R', 'I', 'R', 'R', 'R']) [87007, 3012015.0, 25.6, 6.4, -99999, -99999, 9.4, 5.0, 15.0] """ fname = 'getting_fixedline' if len(cuts) + 1 != len(types): print errormsg print ' ' + fname + ': The number of types :', len(types), 'must be +1', \ 'number of cuts:', len(cuts) quit(-1) values = [] val = line[0:cuts[0]] if len(val.replace(' ','')) >= 1: values.append(typemod(val, types[0])) else: if types[0] == 'I': values.append(fillValueI) elif types[0] == 'R': values.append(fillValueF) elif types[0] == 'D': values.append(fillValueF) elif types[0] == 'S': values.append(fillValueS) elif types[0] == 'B': values.append(fillValueB) Ncuts = len(cuts) for ic in range(1,Ncuts): val = line[cuts[ic-1]:cuts[ic]] if dbg: print ic, ':', val, '-->', types[ic] if len(val.replace(' ','')) >= 1: values.append(typemod(val, types[ic])) else: if types[ic] == 'I': values.append(fillValueI) elif types[ic] == 'R': values.append(fillValueF) elif types[ic] == 'D': values.append(fillValueF) elif types[ic] == 'S': values.append(fillValueS) elif types[ic] == 'B': values.append(fillValueB) # Last value Lline = len(line) val = line[cuts[Ncuts-1]:Lline] if len(val.replace(' ','')) >= 1: values.append(typemod(val, types[Ncuts])) else: if types[Ncuts] == 'I': values.append(fillValueI) elif types[Ncuts] == 'R': values.append(fillValueF) elif types[Ncuts] == 'D': values.append(fillValueF) elif types[Ncuts] == 'S': values.append(fillValueS) elif types[Ncuts] == 'B': values.append(fillValueB) return values def angle_DegMinSec(angle): """ Function to transform an angle to Degrees Minutes Seconds angle= decimal angle to transform >>> angle_DegMinSec(3.98765) 3 59 15.54 >>> angle_DegMinSec(-23.0025) -23 0 9.0 """ fname = 'angle_DegMinSec' degv = int(abs(angle)) minv = int((abs(angle) - degv*1.)*60.) secv = (abs(angle) - degv*1. - minv/60.)*3600. if angle < 0.: return -degv, minv, secv else: return degv, minv, secv def DegMinSec_angle(degv, minv, secv): """ Function to transform Degrees Minutes Seconds to an angle degv: value in degrees minv: minutes of arc secv: seconds of arc >>> DegMinSec_angle(-23, 0, 9.0) -23.0025 """ fname = 'DegMinSec_angle' angle = np.abs(degv) + np.abs(minv)/60. + np.abs(secv)/3600. if degv < 0.: return -angle else: return angle def xtrm_nx(vals, percen): """ Function to provide the extreme (a percentage above min,max) of a series of values as: max(abs(min(vals)), max(vals))*percen vals: values to use percen: percentage [%] above the min/max >>> xtrm_nx(np.arange(10, dtype=np.float), 110.) """ fname = 'xtrm_nx' nv = np.abs(np.min(vals)) xv = np.max(vals) xtrm = np.max([nv,xv])*percen/100. return xtrm def CFcorValues(name): """ Function to provide CF information about a given coordinate name: name of dimension, axis, .... # Output dictionary values: dimn: name of the dimension vdimn: name of the variable-dimension stdn: standard name of the variable dimension longname: longname of the variable dimension units: units of the variable dimension axis: generic related axis _CoordinateAxisType: generic type of axis maxrank: maximunm allowed rank of the variable dimension length: length of the coordinate (0: unknown, -1: unlimited) >>> CFcorValues('lon') {'units': 'degrees_east', '_CoordinateAxisType': 'Lon', 'stdn': 'longitude', 'axis': 'X', 'dimn': 'lon', 'longname': 'Longitude', 'maxrank:' 2, 'length': 0, 'vdimn': 'lon'} >>> CFcorValues('T') {'stdn': 'time', 'longname': 'Time', 'units': '[t] since [date]', 'dimn': 'time', '_CoordinateAxisType': 'Time', 'maxrank:' 1, 'calendar': '[calendar]', 'vdimn': 'time', 'axis': 'T', 'length': -1} """ fname = 'CFcorValues' # Dictionary for each dimension CFlon= {'dimn': 'lon', 'vdimn': 'lon', 'stdn': 'longitude', 'longname': 'Longitude', 'units': 'degrees_east', \ 'axis': 'X', '_CoordinateAxisType': 'Lon', \ 'maxrank': 2, 'length': 0} CFlat= {'dimn': 'lat', 'vdimn': 'lat', \ 'stdn': 'latitude', 'longname': 'Latitude', 'units': 'degrees_north', \ 'axis': 'Y', '_CoordinateAxisType': 'Lat', \ 'maxrank': 2, 'length': 0} CFpress= {'dimn': 'pres', 'vdimn': 'pres', \ 'stdn': 'pressure', 'longname': 'Pressure', 'units': 'Pa', \ 'axis': 'Z', '_CoordinateAxisType': 'Pres', 'positive': 'down', \ 'maxrank': 1, 'length': 0} CFheight= {'dimn': 'height', 'vdimn': 'height', \ 'stdn': 'height', 'longname': 'Height', 'units': 'm', \ 'axis': 'Z', '_CoordinateAxisType': 'Height', 'positive': 'up', \ 'maxrank': 1, 'length': 0} CFtime= {'dimn': 'time', 'vdimn': 'time', \ 'stdn': 'time', 'longname': 'Time', 'units': '[t] since [date]', \ 'axis': 'T', '_CoordinateAxisType': 'Time', 'calendar': '[calendar]', \ 'maxrank': 1, 'length': -1} # names to search for lonn = ['lon', 'X', 'Longitude', 'longitude', 'x', 'west_east', 'rlon'] latn = ['lat', 'Y', 'Latitude', 'latitude', 'y', 'south_north', 'rlat'] pressn = ['pres', 'press', 'P', 'Press', 'Pressure', 'pressure', 'p'] heightn = ['height', 'Z', 'Height', 'z', 'heightv'] timen = ['time', 'T', 'Time', 'TIME', 't'] if searchInlist(lonn, name): cdfim = CFlon elif searchInlist(latn, name): cdfim = CFlat elif searchInlist(pressn, name): cdfim = CFpress elif searchInlist(heightn, name): cdfim = CFheight elif searchInlist(timen, name): cdfim = CFtime else: print errormsg print ' ' + fname + ": coordinate name '" + name + "' not ready !!" print " available ones for 'X':", lonn print " available ones for 'Y':", latn print " available ones for 'Z' [pressure]:", pressn print " available ones for 'Z' [height]:", heightn print " available ones for 'T':", timen quit(-1) return cdfim def CFtime_freq(time1, time2, tunits): """ Function to provide the frequency of CF times (in seconds) time1: time-step value time2: following time-step value tunits: time untis following CF conventions >>> CFtime_freq(521438., 521439., 'hours since 1950-01-01_00:00:00') 3600.0 """ fname = 'CFtime_freq' timediff = time2 - time1 tunitsval = tunits.split(' ')[0] # Units for the variable 'time' to seconds availtunitvals = ['centuries', 'years', 'days', 'hours', 'minutes', 'seconds'] if tunitsval == 'centuries': tsecsuv = 100 * 365 * 24 * 3600. elif tunitsval == 'years': tsecsuv = 365 * 24 * 3600. elif tunitsval == 'weeks': tsecsuv = 7 * 24 * 3600. elif tunitsval == 'days': tsecsuv = 24 * 3600. elif tunitsval == 'hours': tsecsuv = 3600. elif tunitsval == 'minutes': tsecsuv = 60. elif tunitsval == 'seconds': tsecsuv = 1. else: print errormsg print ' ' + fname + ":' tunitsvals= '" + tunitsval + "' not ready!!" print ' available ones: ', availtunitvals quit(-1) freq = timediff*tsecsuv return freq #print CFtime_freq(521438., 521439., 'hours since 1950-01-01_00:00:00') def WRFsetup(namelistns, params='WRFbasic', output='twopoints@'): """ Function to check the set-up of a series of model namelist namelistns= ',' separated list of namelist files params= parameters to check 'WRFbasic': a pre-determined WRF list of basic parameters (default) 'specific',[listparams]: a given ':' separated list of parameters to check output= kind of format of the output 'textabcol': a LaTeX-table column formated for each model 'textabrow': a LaTeX-table row formated for each model 'twopoints@': as ':' separated list of values [attrn]@[attrv]:... (default) for each model with ';' for the following model WRFsetup('namelist.input') """ fname = 'WRFsetup' availparams = ['basic', 'specific,[listparams]'] availoutput = ['textabcol', 'textabrow', 'twopoints@'] if params == 'basic': lookparams = { \ 'time_control': ['start_year', 'start_month', 'start_day', 'start_hour', \ 'start_minute', 'start_second', 'end_year', 'end_month', 'end_day', \ 'end_hour', 'end_minute', 'end_second', 'history_interval', \ 'frames_per_outfile', 'restart', 'restart_interval_h'], \ 'domains': ['time_step', 'max_dom', 'e_we', 'e_sn', 'e_vert', \ 'p_top_requested', 'dx', 'dy', 'parent_grid_ratio', \ 'parent_time_step_ratio', 'feedback'], \ 'physics': ['mp_physics', 'ra_lw_physics', 'ra_sw_physics', 'radt', \ 'sf_sfclay_physics', 'sf_surface_physics', 'bl_pbl_physics', 'bldt', \ 'cu_physics', 'cudt', 'shcu_physics', 'sst_update'], \ 'fdda': [], \ 'dynamics': ['w_damping', 'diff_opt', 'km_opt', 'diff_6th_opt', \ 'diff_6th_factor', 'damp_opt', 'zdamp', 'dampcoef', 'khdif', 'kvdif', \ 'moist_adv_opt', 'scalar_adv_opt'], \ 'bdy_control': ['spec_bdy_width', 'relax_zone'], \ 'IFexist': ['eta_levels']} secnames = ['time_control', 'domains', 'physics', 'fdda', 'dynamics', \ 'bdy_control'] elif params[0:8] == 'specific': secnames = ['specific'] lparns = params.split(',')[1].split(':') lpns = [] for lp in lparns: lpns.append(lp) lookparams = {'specific': lpns} else: print errormsg print ' ' + fname + ": parameters to check '" + params + "' not ready !!" print ' available ones:', availparams quit(-1) # namelist files nmlfs = str_list(namelistns, ',') Nfiles = len(nmlfs) # Number of total parameters to look for Npars = 0 for kn in lookparams.keys(): Npars = Npars + len(lookparams[kn]) allfparams = {} for namelistn in nmlfs: onf = open(namelistn, 'r') fparams = {} pvals = '' for line in onf: if line[0:1] != '#' and len(line) > 1 and line.find('&') == -1 and \ line.find('/') == -1: if line.find('=') != -1: if len(pvals) != 0: fparams[paramn] = pvals ilvals = line.replace('\n', '').replace('\r', '').replace('\t','').split('=') paramn = ilvals[0].replace(' ','') pvals = ilvals[1].replace(' ','') else: ilvals = line.replace('\n', '').replace('\r', '').replace('\t','').replace(' ', '') pvals = pvals + ilvals allfparams[namelistn] = fparams # Output ## outl = '' # LaTeX table with a column per file if output == 'textabcol': ipar = 0 outl = '\\begin{tabular}{' + Ntchar('c',Nfiles+1) + '}\n' + \ '{\\bfseries{filename}}' for fn in nmlfs: outl = outl + ' & {\\bfseries{' + fn.replace('_', '\\_') + '}}' outl = outl + ' \\\\ \hline\n' for secn in secnames: psec = lookparams[secn] ipar = 0 for ps in psec: ifile = 0 outl = outl + '{\\bfseries{' + ps.replace('_', '\\_') + '}}' for fn in nmlfs: fparams = allfparams[fn] if not fparams.has_key(ps): #print infmsg #print ' ' + fname + ": provided namelist file '" + fn + \ # "' has not parameter '" + ps + "' !!" val = '-' else: val = fparams[ps].replace('_', '\\_') outl = outl + ' & ' + val ifile = ifile + 1 outl = outl + ' \\\\ \n' ipar = ipar + 1 outl = outl + '\\end{tabular}\n' # LaTeX table with a row per file elif output == 'textabrow': ifile = 0 outl = '\\begin{tabular}{' + Ntchar('c',Npars+1) + '}\n' + \ '{\\bfseries{filename}}' for secn in secnames: psec = lookparams[secn] for ps in psec: outl = outl + ' & {\\bfseries{' + ps.replace('_', '\\_') + '}}' outl = outl + ' \\\\ \\hline\n' for fn in nmlfs: fparams = allfparams[fn] ipar = 0 outl = outl + fn.replace('_', '\\_') for secn in secnames: print secn + "&" psec = lookparams[secn] for ps in psec: if not fparams.has_key(ps): #print infmsg #print ' ' + fname + ": provided namelist file '" + fn + \ # "' has not parameter '" + ps + "' !!" val = '-' else: val = fparams[ps].replace('_', '\\_') outl = outl + ' & ' + val outl = outl + '\\\\ \n' outl = outl + '\\end{tabular}\n' # ASCII line elif output == 'twopoints@': ifile = 0 for fn in nmlfs: fparams = allfparams[fn] ipar = 0 if ifile == 0: outl = fn else: outl = outl + ';' + fn for secn in secnames: print secn + "&" psec = lookparams[secn] for ps in psec: if not fparams.has_key(ps): print infmsg print ' ' + fname + ": provided namelist file '" + fn + \ "' has not parameter '" + ps + "' !!" val = '-' else: val = fparams[ps] if ipar == 0: outl = ps + '@' + val else: outl = outl + ':' + ps + '@' + val ipar = ipar + 1 ifile = ifile + 1 else: print errormsg print ' ' + fname + ": kind of output '" + output + "' not ready !!" print ' available ones:', availoutput quit(-1) return outl #print WRFsetup('/home/lluis/estudios/RELAMPAGO/SimCoor/UBA/namelist.input,/home/lluis/estudios/RELAMPAGO/SimCoor/SMN/namelist.input,/home/lluis/estudios/RELAMPAGO/SimCoor/NOA-IERSD/namelist.input,/home/lluis/estudios/RELAMPAGO/SimCoor/UBAmili/namelist.input', 'basic', 'textabcol') def advance_matDate(matdate, matinc): """ Function to advance matrix-date with a matrix-increment matdate= matrix date (yr, mn, dd, hh, mi, ss) matinc= matrix increment for the date (incyre, incmm, incdd, inchh, incmm, incss) >>> advance_matDate([1976, 02, 27, 23, 59, 0], [0, 11, 0, 0, 2, 0]) [1977, 1, 28, 0, 1, 0] """ import datetime as dt fname = 'advance_matDate' idate = dt.datetime(matdate[0], matdate[1], matdate[2], matdate[3], matdate[4], \ matdate[5]) inct = dt.timedelta(days=matinc[2], hours=matinc[3], minutes=matinc[4], \ seconds=matdate[5]) newdate = idate + inct newmatdate = [newdate.year, newdate.month, newdate.day, newdate.hour, \ newdate.minute, newdate.second] # Specific Incrementing if matinc[0] != 0 or matinc[1] != 0: if newmatdate[1] + matinc[1] > 12: newmatdate[0] = newmatdate[0] + 1 newmatdate[1] = 1 else: newmatdate[1] = newmatdate[1] + matinc[1] newmatdate[0] = newmatdate[0] + matinc[0] return newmatdate #print advance_matDate([1976, 02, 27, 23, 59, 0], [0, 11, 0, 0, 2, 0]) def Nstr(number): """ Function to transform a number to string, but making sure it preserves characteristics of the number >>> Nstr(np.float(1./3.)) 0.33333333 >>> Nstr(np.float32(1./3.)) 0.33333334 >>> Nstr(np.float64(1./3.)) 0.3333333333333333 """ fname = 'Nstr' if type(number) == type(1) or type(number) == type(long(1)): newStr = '{:d}'.format(number) elif type(number) == type(np.int16(1)) or type(number) == type(np.int32(1)) or \ type(number) == type(np.int64(1)): newStr = '{:d}'.format(number) elif type(number) == type(float(1.)) or type(number) == type(np.float(1.)): newStr = '{:.8f}'.format(number) elif type(number) == type(np.float32(1.)): newStr = '{:.8f}'.format(number) elif type(number) == type(np.float64(1.)): newStr = '{:.16f}'.format(number) else: print errormsg print ' ' + fname + ": number type '", type(number), "' not ready !!" quit(-1) return newStr def maxNcounts(values, axis): """ Function to provide a value according to the maximum number of repeated values along a given axis values= values to count maximum values axis= which axis to use to count values >>> values3D = np.arange(27).reshape(3,3,3) >>> values3D[2,:,:] = 3 >>> values3D[1,0:2,0:2] = 3 >>> maxNcounts(values3D, 0) [[3 3 2] [3 3 5] [6 7 8]] """ import module_ForSci as fsci fname = 'maxNcounts' shapev = list(values.shape) Ndims = len(shapev) if axis > len(shapev): print errormsg print ' ' + fname + ': axis to use:', axis, 'not in shape:', values.shapev quit(-1) newshape = shapev.pop(axis) maxNCvalues = np.zeros(tuple(shapev), dtype=values.dtype) origdimns = [] newdimns = [] for iid in range(Ndims): origdimns.append('d'+str(iid)) if iid != axis: newdimns.append(origdimns[iid]) listslcs = provide_slices(origdimns, values.shape, newdimns) Nslcs = len(listslcs) for islc in range(Nslcs): slicev = listslcs[islc] + [] slicev.pop(axis) vals = values[tuple(listslcs[islc])].flatten() Ndiffv, vcounts = fsci.module_scientific.ncountr(values=vals, d1=len(vals)) countmax = np.max(vcounts[0:Ndiffv,1]) idmax = index_vec(vcounts[0:Ndiffv,1],countmax) maxNCvalues[tuple(slicev)] = vcounts[idmax,0] return maxNCvalues def minNcounts(values, axis): """ Function to provide a value according to the minimum number of repeated values along a given axis values= values to count maximum values axis= which axis to use to count values >>> values3D = np.arange(27).reshape(3,3,3) >>> values3D[2,:,:] = 3 >>> values3D[1,0:2,0:2] = 3 >>> minNcounts(values3D, 0) [[0 1 2] [3 4 5] [6 7 8]] """ import module_ForSci as fsci fname = 'minNcounts' shapev = list(values.shape) Ndims = len(shapev) if axis > len(shapev): print errormsg print ' ' + fname + ': axis to use:', axis, 'not in shape:', values.shapev quit(-1) newshape = shapev.pop(axis) minNCvalues = np.zeros(tuple(shapev), dtype=values.dtype) origdimns = [] newdimns = [] for iid in range(Ndims): origdimns.append('d'+str(iid)) if iid != axis: newdimns.append(origdimns[iid]) listslcs = provide_slices(origdimns, values.shape, newdimns) Nslcs = len(listslcs) for islc in range(Nslcs): slicev = listslcs[islc] + [] slicev.pop(axis) vals = values[tuple(listslcs[islc])].flatten() Ndiffv, vcounts = fsci.module_scientific.ncountr(values=vals, d1=len(vals)) countmax = np.min(vcounts[0:Ndiffv,1]) idmax = index_vec(vcounts[0:Ndiffv,1],countmax) minNCvalues[tuple(slicev)] = vcounts[idmax,0] return minNCvalues def ASCIIfile_stats(filen, comment='#', kind='R'): """ Function to provide the statistics of a series of values from an ASCII file filen= name of the file comment= ':' separated list of comment characters kind= kind of values 'I': integer 'R': float 'D': double """ fname = 'ACIIfile_stats' if not os.path.isfile(filen): print errormsg print ' ' + fname + ": ASCII file '" + filen + "' does not exist !!" quit(-1) comments = str_list(comment, ':') objf = open(filen, 'r') values = [] for line in objf: linev = line.replace('\n','').replace('\t','').replace('\r','') if len(linev) >= 1: ch1 = linev[0:1] if not searchInlist(comments, ch1): values.append(typemod(linev,kind)) objf.close() matv = np.array(values) # Statistics minv = np.min(matv) maxv = np.max(matv) meanv = np.mean(matv) stdv = np.std(matv) quantv = Quantiles(matv, 20) print "# Statistics of '" + filen + "' _______" print ' #@# min:', minv print ' #@# max:', maxv print ' #@# mean:', meanv print ' #@# stddev:', stdv print ' #@# quantiles:', quantv.quantilesv quantS = [] for iq in quantv.quantilesv: quantS.append(str(iq)) print ' #@# allvalues; min:' + str(minv) + ';max:' + str(maxv) + ';mean:' + \ str(meanv) + ';stddev:' + str(stdv) + ';quant:' + ','.join(quantS) return #ASCIIfile_stats('times_NOCDXWRF2.dat') def create_LateX_figs(folder, plots, values, kfig): """ Function to create a LaTeX from a folder with multiple plots from different values folder: folder with figures plots: list of names of plots values: list of values for each plot to guess sort of plots kfig: kind of figure """ import subprocess as sub fname = 'create_LaTeX_figs' texfn = 'LaTeX_figs.tex' otex = open(texfn, 'w') otex.write('\\documentclass{article}\n') otex.write('\\usepackage{graphicx}\n') otex.write('\\usepackage[colorlinks=true,urlcolor=blue]{hyperref}\n') otex.write('\n') otex.write('\\textheight=23cm\n') otex.write('\\textwidth=18cm\n') otex.write('\\oddsidemargin=-1cm\n') otex.write('\\evensidemargin=-1cm\n') otex.write('\\topmargin=-1cm\n') otex.write('\n') otex.write('\\begin{document}\n') otex.write('\n') otex.write('\\listoffigures\n') otex.write('\\clearpage\n') for plotn in plots: print plotn + ' ...' figs = files_folder_HMT(folder, head='', middle=plotn, tail=kfig) unsortfigs = figs + [] Nfigs = len(figs) # grouping figures for valn in values: print ' ' + valn + ' ...' valfigs = [] for fign in figs: if fign.find(valn) != -1: valfigs.append(fign) unsortfigs.remove(fign) Nvalfig = len(valfigs) if Nvalfig > 0: Ncol = int(np.sqrt(Nvalfig)) Nrow = Nvalfig/Ncol if Nrow > Ncol: Ncol = Nrow cs = Ntchar('c', Ncol) frcwth = 0.9/Ncol otex.write('\\begin{figure}\n') otex.write('\\begin{center}\n') otex.write('\\begin{tabular}{' + cs + '}\n') ifig = 1 for valfn in valfigs: if ifig != 0 and np.mod(ifig,Ncol) == 0: endchar = ' \\\\\n' else: endchar = ' &\n' otex.write('\\includegraphics[width=' + str(frcwth) + \ '\\textwidth]{' + valfigs[ifig-1] + '}' + endchar + '\n') ifig = ifig + 1 if Nvalfig - ifig + 1 != 0: endrow = Ntchar(' & ', Nvalfig - ifig + 1) otex.write(endrow + '\n') otex.write('\\end{tabular}\n') otex.write('\\end{center}\n') otex.write('\\caption{' + latex_text(plotn) +' '+ latex_text(valn) + \ '}\n') otex.write('\\label{fig:' + plotn + '_' + valn + '}\n') otex.write('\\end{figure}\n') if len(unsortfigs) != 0: Nunsortfig = len(unsortfigs) print infmsg print ' ' + fname + ': sorting unsorted:', Nunsortfig, 'figures !!' print ' figures:', unsortfigs Ncol = int(np.sqrt(Nunsortfig)) Nrow = Nvalfig/Ncol if Nrow > Ncol: Ncol = Nrow cs = Ntchar('c', Ncol) frcwth = 0.9/Ncol otex.write('\\begin{figure}\n') otex.write('\\begin{center}\n') otex.write('\\begin{tabular}{' + cs + '}\n') ifig = 1 for valfn in unsortfigs: if ifig != 0 and np.mod(ifig,Ncol) == 0: endchar = ' \\\\\n' else: endchar = ' &\n' otex.write('\\includegraphics[width=' + str(frcwth) + \ '\\textwidth]{' + valfn + '}' + endchar + '\n') ifig = ifig + 1 #if np.mod(ifig-1,Ncol) != 0: # endrow = Ntchar(' & ', np.mod(ifig-1,Ncol)) # otex.write(endrow + '\n') if Nunsortfig - ifig + 1 != 0: endrow = Ntchar(' & ', Nunsortfig - ifig + 1) otex.write(endrow + '\n') otex.write('\\end{tabular}\n') otex.write('\\end{center}\n') otex.write('\\caption{' + latex_text(plotn) + '}\n') otex.write('\\label{fig:' + plotn + '_unsorted}\n') otex.write('\\end{figure}\n') otex.write('\n') otex.write('\\clearpage\n') otex.write('\\end{document}\n') otex.close() print fname + ": LaTeX file '" + texfn + "' succesfully written !!" sub.call('pdflatex ' + texfn.split('.')[0], shell=True) sub.call('pdflatex ' + texfn.split('.')[0], shell=True) sub.call('pdflatex ' + texfn.split('.')[0], shell=True) sub.call('evince ' + texfn.split('.')[0]+'.pdf &', shell=True) return #pltns = ['WindRose_obs', 'SkewT-logP_obs_ta-tda', 'SkewT-logP_obs_evol', 'WindRose_obs-sim_step', 'SkewT-logP_obs-sim_step', 'SkewT-logP_obs-sim_evol'] #sts = ['10868', '16080', '16144', '16546'] #create_LateX_figs('/home/lluis/estudios/FPS_ALPS/additional/IOP/analysis/figs', pltns, sts, 'png') def stats_Slist(listS, char=':'): """ Function to provide extremes from a string as a list separated by a given character listS= String as list char= character to provide different values >>> stats_Slist('1.2:3.45:-98.21:34321.1:100.1', ':') stats_Slist min max mean standard_dev _______ stats_Slist_values: -98.21 34321.1 6865.528 13727.9292697 """ fname = 'stats_Slist' haschar = listS.find(char) if haschar == -1: print errormsg print ' ' + fname + ": provided String-list '" + + "' does not have " + \ "character '" + char + "' !!" quit(-1) listv = str_list_k(listS, char, 'F') nl = np.min(listv) xl = np.max(listv) ml = np.mean(listv) sl = np.std(listv) print fname + ' min max mean standard_dev _______' print fname + '_values:', nl, xl, ml, sl return #print stats_Slist('1.2:3.45:-98.21:34321.1:100.1', ':') def inf_operSlist(listS, oper, char=':', values=None): """ Function to provide information from a string as a list separated by a given character followig a given operation and a set of values listS= String as list char= character to provide different values oper= available operations 'getvalue': get the value at a given index 'maxloc': index of the maximum value 'minloc': index of the minimum value 'sort': sort list of values (returned as a new String list) 'threshold': index of the values between which a given threshold is met (only useful for sort values) values= char separated list of required values for the given operation (if applicable) >>> inf_operSlist('1.2:3.45:-98.21:34321.1:100.1', 'sort', ':') -98.21:1.2:3.45:100.1:34321.1 >>> inf_operSlist('1.2:3.45:-98.21:34321.1:100.1', 'minloc', ':') 2 >>> inf_operSlist('-98.21:1.2:3.45:100.1:34321.1', 'threshold', ':', 3.) 1 """ fname = 'inf_operSlist' availoper = ['getvalue', 'getvalue''maxloc', 'minloc', 'sort', 'threshold'] haschar = listS.find(char) if haschar == -1: print errormsg print ' ' + fname + ": provided String-list '" + + "' does not have " + \ "character '" + char + "' !!" quit(-1) listv = str_list_k(listS, char, 'F') if oper == 'getvalue': Nvals = len(listv) if int(values) > Nvals-1: print errormsg print ' ' + fname + ': index:', int(values), 'larger than values in ' + \ 'list:', Nvals, '!!' quit(-1) return listv[int(values)] elif oper == 'maxloc': xl = np.max(listv) return index_vec(listv, xl) elif oper == 'minloc': nl = np.min(listv) return index_vec(listv, nl) elif oper == 'sort': sortl = listv + [] sortl.sort() sortlistS = '' Nval = len(sortl) sortlistS = '' for iv in range(Nval-1): sortlistS = sortlistS + str(sortl[iv]) + ':' sortlistS = sortlistS + str(sortl[Nval-1]) if char != ':': return sortlistS.replace(':', char) else: return sortlistS elif oper == 'threshold': if values is None: print errormsg print ' ' + fname + ": operation '" + oper + "' requires a value !!" print " None provided" quit(-1) val = np.float(values) Nval = len(listv) dlist = np.array(listv[1:Nval]) - np.array(listv[0:Nval-1]) if dlist[0] > 0. and not np.all(dlist > 0.): print errormsg print ' ' + fname + ": operation '" + oper + "' requires sort list !!" print " provided one '" + listS + "' is not!!" if dlist[0] > 0.: for iv in range(1,Nval-2): if dlist[iv] < 0.: print ' change of sign of interval at value:', iv, \ listv[iv], listv[iv+1] if dlist[0] < 0. and not np.all(dlist < 0.): print errormsg print ' ' + fname + ": operation '" + oper + "' requires sort list !!" print " provided one '" + listS + "' is not!!" if dlist[0] < 0.: for iv in range(1,Nval-2): if dlist[iv] > 0.: print ' change of sign of interval at value:', iv, \ listv[iv], listv[iv+1] quit(-1) sign = listv[1] - listv[0] if sign > 0.: for iloc in range(Nval-1): if listv[iloc+1] >= val and listv[iloc] < val: return iloc return Nval elif sign < 0.: for iloc in range(Nval-1): if listv[iloc+1] <= val and listv[iloc] > val: return iloc return Nval else: print errormsg print ' ' + fname + ": operation '" + oper + "' nor ready !!" print " available ones:", availoper quit(-1) return def WRF_percenlevels(Nlevs=38, ps=1000., pt=20.): """ Function to compute eta-levels for WRF following a percentage distribution Nlevs: number of levels pt: p_top pressure [hPa] ps: p_sfc pressure [hPa] p_sfc - 975 hPa: 4 % 975 - 900 hPa: 28 % 900 - 850 hPa: 10 % 850 - 600 hPa: 25 % 600 - 450 hPa: 12 % 450 - 250 hPa: 12 % 250 - p_top: 9 % """ fname = 'WRF_percenlevels' # 72 numbers #dps = {900.:5., 850.: 10., 700.: 15., 600.: 20., 450.: 10., 250.: 20., 50.: 30.} #Nlevp: {450.0: 15, 900.0: 20, 50.0: 6, 850.0: 5, 600.0: 5, 250.0: 10, 700.0: 10} % #900.0 : 27.7777777778 #850.0 : 6.94444444444 #700.0 : 13.8888888889 #600.0 : 6.94444444444 #450.0 : 20.8333333333 #250.0 : 13.8888888889 #50.0 : 8.33333333333 # Assigning percentage of levels per interval # Computing dps #dppsperce = {900.: 29., 850.: 6., 700.: 15., 600.: 7., 450.:21., 250.:14., 50.: 8.} dppsperce = {990: 4., 900.: 28., 850.: 10., 600.: 25., 450.:12., 250.:12., pt: 9.} dpps0 = dppsperce.keys() dpps0.sort(reverse=True) dps = {} # Assigning number of levels nplevs = {} percen = 0 Ntotlev = 0 # Removing 1st and last levels Nlevs1 = Nlevs - 2 for dpp in dpps0: nlev = int(Nlevs1*dppsperce[dpp]/100.) nplevs[dpp] = nlev Ntotlev = Ntotlev + nlev print ' ' + fname + ' final total number of levels:', Ntotlev, \ 'of initial Nlevs:', Nlevs, 'TOT %:', np.sum(dppsperce.values()) # Re-distributing rest of levels on first intervals if Ntotlev < Nlevs1: Nextralevs = Nlevs1 - Ntotlev print ' ' + fname + ': Ntotlev:', Ntotlev, 're-distributing:', Nextralevs, \ 'extra levels !!' for i in range(Nextralevs): nplevs[dpps0[i]] = nplevs[dpps0[i]] + 1 else: Nextralevs = 0 print ' ' + fname + ' final number of levels:', nplevs, 'sum:', \ np.sum(nplevs.values()) + 2 # Assigning pressure-differenctials pp0 = ps print ' uppper_limit_section [hPa] dp [hPa] _______' for dpp in dpps0: nlev = nplevs[dpp] # Adding an extra level to meet final pt if dpp == dpps0[len(dpps0)-1]: nlev = nlev + 1 dp = pp0 - dpp ddp = dp / nlev dps[dpp] = ddp percen = percen + dppsperce[dpp] print ' ', '{:.2f}'.format(dpp), ' ', ddp pp0 = dpp p = [ps] dpps = list(dps.keys()) dpps.sort(reverse=True) iiz = 1 Ntotlevs = 0 for dpp in dpps: dp = dps[dpp] Ntotlevs = Ntotlevs + nplevs[dpp] for iz in range(nplevs[dpp]): p.append(p[iiz-1] - dp) iiz = iiz + 1 #print 'iz:', iz, p[iz], dp, pt p.append(pt) p = np.array(p) eta = (p-pt)/(ps-pt) dz=p.shape[0] ofilen = 'WRFpercen_p' + str(Nlevs) + 'lev.dat' of = open(ofilen, 'w') of.write('# ' + str(Nlevs) + ' i-lev[1] pressure[2] eta[3] dp[4]__________\n') for i in range(dz-1): of.write(str(i) + ' ' + str(p[i]) + ' ' + str(eta[i]) + ' ' + str(p[i]-p[i+1]) + '\n') i = dz-1 of.write(str(i) + ' ' + str(pt) + ' ' + str(eta[i]) + ' 0.\n') of.close() print fname + ": succesfull written of file '" + ofilen + "' !!" return #print WRF_percenlevels(38) def cyclevar(cycvar,ind): """ Function to provide the given index of a cycle variable. A cycle variable is a given structure with a series of values, once the maximum is overpassed it restarts from the beginning (e.g.: 12 months of a year) cycvar: array of values ind: index to provide the value from >>> cyclevar(np.arange(12)+1, 3) 4 >>> cyclevar(np.arange(12)+1, 14) 3 """ fname = 'cyclevar' dcyc = cycvar.shape[0] Ncyc = int(ind / dcyc) rescyc = ind - Ncyc*dcyc return cycvar[rescyc] def cyclevar_within(cycvar, bper, eper, val): """ Function to tell if a given value is within a period of a cycle variable. A cycle variable is a given structure with a series of values, once the maximum is overpassed it restarts from the beginning (e.g.: 12 months of a year) cycvar: array of values bper: beginning period eper: end period (if eper < bper, assuming period overpassing cycle) val: value to look for (if val < bper, assuming value next cycle) >>> cyclevar_within(np.arange(12)+1, 3, 6, 4) True >>> cyclevar_within(np.arange(12)+1, 12, 3, 2) True >>> cyclevar_within(np.arange(12)+1, 12, 3, 5) False """ fname = 'cyclevar_within' dcyc = cycvar.shape[0] # Indices of the beginning and end of the period bind = index_vec(cycvar,bper) eind = index_vec(cycvar,eper) # Index of the value vind = index_vec(cycvar,val) if eind < bind: eind = eind + dcyc if vind < bind: vind = vind + dcyc if vind >= bind and vind < eind: within = True else: within = False return within def time_slices(tv, tu, cal, per, amount): """ Function to return temporal slices of a series of times for a given amount of periods tv: time vallues (CF format) tu: CF time-units cal: calendar per: period 'year': full year [01/01 00:00:00 - 12/31 23:59:59] 'month': full months [01 00:00:00 - [31,30,28/29] 23:59:59] 'day': full days [00:00:00 - 23:59:59] 'hour': full hours [00:00 - 59:59] 'minute': full minutes [00 - 59] amount: amount of periods """ import datetime as dt fname = 'time_slices' availper = ['year', 'month', 'day', 'hour', 'minute'] mattimes = CFtimesvar_datetime(tv, tu, cal) if type(tv) == type(np.arange(2)): dimt = tv.shape[0] elif type(tv) == type(range(2)): dimt = len(tv) else: print errormsg print ' ' + fname + ': time values type ', type(tv), 'not ready !!' print ' available ones:', type(np.arange(1)), type(range(2)) quit(-1) #print 'mat times _______' #for it in range(dimt): # print ' ',it, mattimes[it,:] # Beginning and Ending of time data it = 0 idate = dt.datetime(mattimes[it,0], mattimes[it,1], mattimes[it,2], \ mattimes[it,3], mattimes[it,4], mattimes[it,5]) it = dimt-1 edate = dt.datetime(mattimes[it,0], mattimes[it,1], mattimes[it,2], \ mattimes[it,3], mattimes[it,4], mattimes[it,5]) istats = mattimes[0,:] estats = mattimes[dimt-1,:] #print 'idate:', idate, 'edate:', edate # Getting the dates if per == 'year': # Arranging accordingly beginning/ending statistics periods istats[1] = 1 istats[2] = 1 istats[3:5] = 0 estats[0] = estats[0] + 1 estats[1] = 1 estats[2] = 1 estats[3:5] = 0 istdate = dt.datetime(istats[0], istats[1], istats[2], istats[3], istats[4], \ istats[5]) estdate = dt.datetime(estats[0], estats[1], estats[2], estats[3], estats[4], \ estats[5]) # Getting statistics periods stmatdates = [istats] idate = istdate imdate = istats.copy() while idate < estdate: imdate = imdate.copy() imdate[0] = imdate[0] + amount idate= dt.datetime(imdate[0], imdate[1], imdate[2], imdate[3], imdate[4],\ imdate[5]) if idate < estdate: stmatdates.append(imdate) else: break stmatdates.append(imdate) elif per == 'month': # Arranging accordingly beginning/ending statistics periods istats[2] = 1 istats[3:5] = 0 estats[1] = estats[1]+1 if estats[1] > 12: estats[0] = estats[0] + 1 estats[1] = 1 estats[2] = 1 estats[3:5] = 0 istdate = dt.datetime(istats[0], istats[1], istats[2], istats[3], istats[4], \ istats[5]) estdate = dt.datetime(estats[0], estats[1], estats[2], estats[3], estats[4], \ estats[5]) # Getting statistics periods stmatdates = [istats] idate = istdate imdate = istats.copy() while idate < estdate: imdate = imdate.copy() imdate[1] = imdate[1] + amount if imdate[1] > 12: imdate[0] = imdate[0] + 1 imdate[1] = 1 idate= dt.datetime(imdate[0], imdate[1], imdate[2], imdate[3], imdate[4],\ imdate[5]) if idate < estdate: stmatdates.append(imdate) else: break stmatdates.append(imdate) elif per == 'day': # Arranging accordingly beginning/ending statistics periods istats[3:5] = 0 dmon = days_month(estats[0], estats[1]) estats[2] = estats[2]+1 if estats[2] > dmon: estats[1] = estats[1] + 1 if estats[1] > 12: estats[0] = estats[0] + 1 estats[1] = 1 estats[3:5] = 0 istdate = dt.datetime(istats[0], istats[1], istats[2], istats[3], istats[4], \ istats[5]) estdate = dt.datetime(estats[0], estats[1], estats[2], estats[3], estats[4], \ estats[5]) # Getting statistics periods stmatdates = [istats] idate = istdate imdate = istats.copy() while idate < estdate: imdate = imdate.copy() dmon = days_month(imdate[0], imdate[1]) imdate[2] = imdate[2] + amount if imdate[2] > dmon: imdate[2] = imdate[2] - dmon imdate[1] = imdate[1] + 1 if imdate[1] > 12: imdate[0] = imdate[0] + 1 imdate[1] = 1 idate= dt.datetime(imdate[0], imdate[1], imdate[2], imdate[3], imdate[4],\ imdate[5]) if idate < estdate: stmatdates.append(imdate) else: break stmatdates.append(imdate) else: print errormsg print ' ' + fname + ": period '" + per + "' not ready !!" print ' available ones:', availper quit(-1) # Getting the slices ## slices = [] # Passing to CF-times Srefdate0 = tu.split(' ')[2] Sreftime0 = tu.split(' ')[3] tunits = tu.split(' ')[0] if Srefdate0.find('/') != -1: Srdate = Srefdate0.replace('/', '') elif Srefdate0.find('-') != -1: Srdate = Srefdate0.replace('-','') else: print errormsg print ' ' + fname + ": I do not know how to create a [YYYY][MM][DD] " + \ "date with '" + Srefdate0 + "' !!" print " expecting '/' or '-' splitting characters" quit(-1) if Sreftime0.find(':') != -1: Srtime = Sreftime0.replace(':', '') else: print errormsg print ' ' + fname + ": I do not know how to create a [HH][MI][SS] " + \ "date with '" + Sreftime0 + "' !!" print " expecting ':' splitting character" quit(-1) Srefdate = Srdate + Srtime Nslices = len(stmatdates) stmdates = np.zeros((Nslices,6), dtype=np.int) #print ' dates slices ________' for islc in range(Nslices): # print islc, ' ', stmatdates[islc] stmdates[islc,:] = stmatdates[islc] cfstdates = realdatetime_CFcompilant(stmdates, Srefdate, tunits) Nslices = len(cfstdates) itt = 0 icfst = 0 for it in range(dimt): timeslice = [itt,itt,1] timeslice[1] = it icfstup = np.min([icfst+1, Nslices-1]) if not(tv[it] >= cfstdates[icfst] and tv[it] < cfstdates[icfstup]): slices.append(timeslice) itt = it icfst = icfst + 1 slices.append(timeslice) Nslices = len(slices) print infmsg print ' ' + fname + ' slices _______' for isl in range(Nslices-1): print ' ', isl, stmatdates[isl], stmatdates[isl+1], ':', slices[isl] return slices, Nslices #tv = [] #values = [] #totT = 24.*60. #dT = 7. #for it in range(0,10): # for itt in range(3): # tv.append(29*24*60.+it*totT+dT*itt) # values.append(it*1.) #vals = np.array(values) #itdim = 0 #tu = 'minutes since 1949-12-01 00:00:00' #per = 'day' #calend = 'standard' #amount = 1 #tslc, Ntslc = time_slices(tv, tu, calend, per, amount) #statn = 'mean' #tstat = np.ones((Ntslc), dtype=np.float) #for islc in range(Ntslc): # timeslcv = tslc[islc] # timeslc = [slice(timeslcv[0],timeslcv[1],timeslcv[2])] # tvals = vals[tuple(timeslc)] # if statn == 'min': # tstat[islc] = np.min(tvals, axis=itdim) # elif statn == 'max': # tstat[islc] = np.max(tvals, axis=itdim) # elif statn == 'mean': # tstat[islc] = np.mean(tvals, axis=itdim) # elif statn == 'mean2': # tstat[islc] = np.mean(tvals**2, axis=itdim) # elif statn == 'std': # tstat[islc] = np.std(tvals, axis=itdim) # timeslc = tslc[islc] # itime = tv[timeslc[0]] # etime = tv[timeslc[1]] # print islc, ':', itime, '-', etime, '<>', tvals, '=', tstat[islc] def Latin_Greek(char): """ Function to pass an ASCII latin character to its equivalent greek char: latin character to pass >>> Latin_Greek('a') $\alpha$ >>> Latin_Greek('z') $\omega$ """ fname = 'Latin_Greek' greekequiv = {'a': '$\\alpha$', 'b': '$\\beta$', 'c': '$\\gamma$', \ 'd': '$\\delta$', 'e': '$\\epsilon$', 'f': '$\\zeta$', 'g': '$\\eta$', \ 'h': '$\\theta$', 'i': '$\\iota$', 'j': '$\\kappa$', 'k': '$\\lambda$', \ 'l': '$\\mu$', 'm': '$\\nu $', 'n': '$\\xi$', 'o': '$\\omicron$', 'p': '$\\pi$',\ 'q': '$\\(san)$', 'r': '$\\(koppa)$', 's': '$\\rho$', 't': '$\\sigma$', \ 'u': '$\\tau$', 'v': '$\\upsilon$', 'w': '$\\phi$', 'x': '$\\chi$', \ 'y': '$\\psi$', 'z': '$\\omega$'} greek = greekequiv[char] return greek def consecutive_list(Nvals, kind): """ Function to provide a list of consecutive values Nvals: number of values kind: kind of values 'ALPHA': list of consecutive characters upper case 'alpha': list of consecutive characters lower case 'greek': list of consecutive greek characters lower case (LaTeX) 'numberF': list of consecutive float numbers 'numberI': list of consecutive integer numbers 'ROMAN': list of consecutive uppercase roman numbers 'roman': list of consecutive lowercase roman numbers >>> consecutive_list(10, 'ALPHA') ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'] >>> consecutive_list(10, 'alpha') ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] >>> consecutive_list(10, 'greek') ['$\\alpha$', '$\\beta$', '$\\gamma$', '$\\delta$', '$\\epsilon$', '$\\zeta$', '$\\eta$', '$\\theta$', '$\\iota$', '$\\kappa$'] >>> consecutive_list(10, 'numberI') [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> consecutive_list(10, 'roman') ['i', 'ii', 'iii', 'iv', 'v', 'vi', 'vii', 'viii', 'ix', 'x'] """ fname = 'consecutive_list' availkind = ['ALPHA', 'alpha', 'greek', 'numberF', 'numberI', 'ROMAN', 'roman'] if kind == 'ALPHA': vals = [] for ic in range(Nvals): vals.append(chr(65+ic)) elif kind == 'alpha': vals = [] for ic in range(Nvals): vals.append(chr(97+ic)) elif kind == 'greek': vals = [] for ic in range(Nvals): vals.append(Latin_Greek(chr(97+ic))) elif kind == 'numberF': vals = list(np.arange(Nvals, drype=np.float)) elif kind == 'numberI': vals = range(Nvals) elif kind == 'ROMAN': vals = [] for ic in range(Nvals): vals.append(int_to_roman(ic+1, 'U')) elif kind == 'roman': vals = [] for ic in range(Nvals): vals.append(int_to_roman(ic+1, 'l')) else: print errormsg print ' ' + fname + ": kind '" + kind + "' not ready !!" print ' avaiable ones:', availkind quit(-1) return vals def advance_date(date, Tunit, NTunits): """ Function to advance a date a certain given units of time date: datetime object to advance Tunit: units of time (one from 'years', 'months', 'days', 'minutes', 'hours', 'seconds') NTunits: number of [Tunit] to advance >>> advance_date(dt.datetime(1976,02,17,8,30,0), 'seconds', 25) 1976-02-17 08:30:25 >>> advance_date(dt.datetime(1976,02,17,8,30,0), 'seconds', 75) 1976-02-17 08:31:15 >>> advance_date(dt.datetime(1976,02,17,8,30,0), 'seconds', 2500) 1976-02-17 09:11:40 >>> advance_date(dt.datetime(1976,02,17,8,30,0), 'seconds', 3600*20) 1976-02-18 04:30:00 >>> advance_date(dt.datetime(1976,02,17,8,30,0), 'seconds', 24*3600*100) 1976-05-27 08:30:00 >>> advance_date(dt.datetime(1976,02,17,8,30,0), 'seconds', 24*3600*1000) 1978-11-13 08:30:00 """ import datetime as dt fname = 'advance_date' availtunits = ['years', 'months', 'days', 'minutes', 'hours', 'seconds'] mdate = [date.year, date.month, date.day, date.hour, date.minute, date.second] if Tunit == 'years': idate = 0 elif Tunit == 'months': idate = 1 elif Tunit == 'days': idate = 2 elif Tunit == 'hours': idate = 3 elif Tunit == 'minutes': idate = 4 elif Tunit == 'seconds': idate = 5 else: print errormsg print ' ' + fname + ": time units '" + uints + "' not ready !!" print ' available ones:', availtunits quit(-1) thresholds = [100000, 13, days_month(mdate[0],mdate[1])+1, 24, 60, 60] mins = [-100000., 1., 1., 0., 0., 0.] ndate = mdate + [] ndate[idate] = ndate[idate] + NTunits for idd in range(5,0,-1): if ndate[idd] >= thresholds[idd]: Nthres = int(ndate[idd]/thresholds[idd]) if idd == 2 and Nthres > 1: TOTthres = thresholds[idd] - 1 year = ndate[0] mon = ndate[1] while TOTthres < ndate[idd]: if mon + 1 > 12: mon = 1 year = year + 1 else: mon = mon + 1 dmon = days_month(year,mon) if TOTthres + dmon > ndate[idd]: break else: TOTthres = TOTthres + dmon ndate[idd] = ndate[idd] - TOTthres ndate[1] = mon ndate[0] = year else: ndate[idd] = int(np.max([ndate[idd] - thresholds[idd]*Nthres*1., \ mins[idd]])) ndate[idd-1] = ndate[idd-1] + Nthres newdate = dt.datetime(year=ndate[0], month=ndate[1], day=ndate[2], \ hour=ndate[3], minute=ndate[4], second=ndate[5]) return newdate def generate_CFtimes(datei, datef, units, freq, dateref='19491201000000'): """ Function to generate CFtimes for a given period, frequency and units datei: initial date of the period ([YYYY][MM][DD][HH][MI][SS] format) datef: final date of the period ([YYYY][MM][DD][HH][MI][SS] format) units: units of time (one from 'days', 'hours', 'minutes', 'seconds') Tfreq: frequency of time-steps in number of [units] time dateref: reference date ([YYYY][MM][DD][HH][MI][SS] format) >>> generate_CFtimes('20021230000000', '20030103000000', 'days', 1) [19387.0, 19388.0, 19389.0, 19390.0, 19391.0, 19392.0], 'days since 1949-12-01 00:00:00' """ import datetime as dt fname = 'generate_CFtimes' availtunits = ['days', 'minutes', 'hours', 'seconds'] if units == 'days': ddt = 3600.*24. elif units == 'hours': ddt = 3600. elif units == 'minutes': ddt = 60. elif units == 'seconds': ddt = 1. else: print errormsg print ' ' + fname + ": time units '" + uints + "' not ready !!" print ' available ones:', availtunits quit(-1) idate = dt.datetime.strptime(datei, '%Y%m%d%H%M%S') edate = dt.datetime.strptime(datef, '%Y%m%d%H%M%S') refdate = dt.datetime.strptime(dateref, '%Y%m%d%H%M%S') refdateS = refdate.strftime("%Y-%m-%d %H:%M:%S") delta = idate - refdate # Python version depending if searchInlist(dir(delta), 'total_seconds'): diffT = delta.total_seconds() else: diffT = delta.days*24*3600. + delta.seconds cftimes = [np.float64(diffT/ddt)] date = idate while date <= edate: date = advance_date(date, units, freq) if date > edate: break delta = date - refdate # Python version depending if searchInlist(dir(delta), 'total_seconds'): diffT = delta.total_seconds() else: diffT = delta.days*24*3600. + delta.seconds cftimes.append(np.float64(diffT/ddt)) timeu = units + ' since ' + refdateS return cftimes, timeu def mindist(lonv,latv,lonvalue,latvalue): """ Function to proivde the minimum distance toa pair of lon,lat lonv: matrix with longitudes latv: matrix with longitudes lonvalue: longitude to look for latvalue: latitude to look for """ fname = 'mindist' if len(lonv.shape) == 1: distlon = np.abs(lonv - lonvalue) distlat = np.abs(latv - latvalue) mindifflon = np.min(distlon) mindifflat = np.min(distlat) ix = index_vec(distlon, mindistlon) iy = index_vec(distlat, mindistlat) else: dist = np.sqrt((lonv - lonvalue)**2 + (latv - latvalue)**2) mindist = np.min(dist) [iy, ix] = index_mat(dist, mindist) return [ix, iy], mindist def get_right_CFtimeunits(CFtimeu): """ Function to get the right CFtime units from any given format CF-time units must be like: [time_unit] since [YYYY]-[MM]-[DD] [HH]:[MI]:[SS] CFtimeu: CF-time units to look >>> get_right_CFtimeunits('minutes since 1949-12-01 00:00:00') minutes simnce 1949-12-01 00:00:00 >>> get_right_CFtimeunits('minutes since 1949-12-01') minutes simnce 1949-12-01 00:00:00 >>> get_right_CFtimeunits('minutes since 19491201 000000') minutes simnce 1949-12-01 00:00:00 >>> get_right_CFtimeunits('days since 1850-1-1') days simnce 1850-01-01 00:00:00 """ fname = 'get_right_CFtimeunits' if CFtimeu.find('since') == -1: print errormsg print ' ' + fname + ": provided time-units '" + CFtimeu + "' does not " + \ "have even 'since', impossible to proceed !!" quit(-1) uvalsecs = CFtimeu.split(' ') # Getting four sections if len(uvalsecs) == 4: date=uvalsecs[2] time=uvalsecs[3] else: if uvalsecs[2].find('_') == -1: print infmsg print ' ' + fname + ": CF-time units without time !!" print " adding '00:00:00'" date=uvalsecs[2] time='00:00:00' else: date=uvalsecs[2].split('_')[0] time=uvalsecs[2].split('_')[1] # Getting four digits if date.find('-') == -1: if len(date) == 8: date = date[0:4] + '-' + date[4:6] + '-' + date[6:8] else: date = date.replace('/','-') datesecs=date.split('-') date = datesecs[0].zfill(4)+'-'+datesecs[1].zfill(2)+'-'+datesecs[2].zfill(2) #print ' ' + fname + ': final date:', date if time.find(':') == -1: if len(time) == 6: time = time[0:2] + ':' + time[2:4] + ':' + time[4:6] else: date = date.replace('_',':') timesecs=time.split(':') time = timesecs[0].zfill(2)+':'+timesecs[1].zfill(2)+':'+timesecs[2].zfill(2) #print ' ' + fname + ': final time:', time refdateS = date + ' ' + time if int(date.split('-')[0]) > 1900: refdate = datetimeStr_datetime(refdateS) refdateS = refdate.strftime("%Y-%m-%d %H:%M:%S") else: print warnmsg print ' ' + fname + ": reference date: '" + date + "' below 1900 !!" time_unit = uvalsecs[0] rightCFtimeu = time_unit + ' simnce ' + refdateS return rightCFtimeu def mat_dimreshape(dimns, values, dimnsuse, shapeuse, nonusevaluesdims): """ Function to reshape a matrix on a new one according to values along their dimensions dimns= list of dimensions names of the input matrix values= values of the matrix dimnsuse= list of dimensions to use shapeuse: list with shape of being produced nonusevaluesdims: dictionary to provide index values to that non-concident dimennsios of [values] from [dimnuse] >>> mask1 = np.zeros((3,3,3), dtype=bool) mask1[1,:,:] = True print mat_dimreshape(['dt', 'dy', 'dx'], mask1, ['dz', 'dy', 'dx'], [2, 3, 3], {'dt': 0}) [[[False False False] [False False False] [False False False]] [[False False False] [False False False] [False False False]]] >>> mask2 = np.zeros((2,3), dtype=bool) mask2[1,1] = True mat_dimreshape(['dt', 'dy'], mask2, ['dz', 'dy', 'dx'], [3, 3, 3], {'dt': 1}) [[[False False False] [ True True True] [False False False]] [[False False False] [ True True True] [False False False]] [[False False False] [ True True True] [False False False]]] """ fname = 'mat_dimreshape' coincdims = list(set(dimns) & set(dimnsuse)) NOTcoincdims = list(set(dimnsuse) - set(dimns)) newvalues = np.zeros(tuple(shapeuse), dtype=values.dtype) # Slices to fill new matrix newslices = provide_slices(dimnsuse, shapeuse, NOTcoincdims) # Getting values to use to fill new matrix from values shapevals = values.shape slcvalues = [] idim = 0 for dn in dimns: if searchInlist(coincdims,dn): slcvalues.append(slice(0,shapevals[idim])) else: if not nonusevaluesdims.has_key(dn): print errormsg print ' ' + fname + ": non-concident dimension '" + dn + \ "' requires a value to proceed in dictionary 'nonusevaluesdims'!!" print ' values provided _______' printing_dictionary(nonusevaluesdims) quit(-1) else: slcvalues.append(nonusevaluesdims[dn]) idim = idim + 1 slicevals = values[tuple(slcvalues)] # Checking for consistency newvalslc = newvalues[tuple(newslices[0])] matsame = same_shape(slicevals, newvalslc, quitval=False) if not matsame: print errormsg print ' ' + fname + ": not coincident shapes of matrices !!" print ' shape of example of slice for new values:', newvalslc.shape print ' example of slice from the newvalues:', newslices[0] print ' shape of values:', values.shape print ' shape of slice from values to fill:', slicevals.shape print ' slice of values:', slcvalues print ' check dimensions and values provided ________' print ' * dimension names of values:', dimns print ' * dimensions of new values:', dimnsuse print ' * shape of new values:', shapeuse print ' * selected indices from values for non-coincident dimensions' printing_dictionary(nonusevaluesdims) quit(-1) Nnewslices = len(newslices) for islc in range(Nnewslices): slc = newslices[islc] newvalues[tuple(slc)] = slicevals return newvalues def make_colors(highs, lows): """ Function to create a palette of colors from a series of high and low values highs= ',' separated list of high RGB lows= ',' separated list of low RGB returns string as [col1]:[col2]:... >>> make_colors('AA','32') #AAAA32:#AA32AA:#32AAAA:#AA3232:#32AA32:#3232AA """ fname = 'make_colors' hvs = highs.split(',') lvs = lows.split(',') Nhighs=len(hvs) Nlows=len(lvs) colors='' icol = 0 for ih in range(Nhighs): for il in range(Nlows): if ih == 0 and il == 0: colors = '#'+hvs[ih]+hvs[ih]+lvs[ih] colors = colors + ':#'+hvs[ih]+lvs[ih]+hvs[ih] colors = colors + ':#'+lvs[ih]+hvs[ih]+hvs[ih] colors = colors + ':#'+hvs[ih]+lvs[ih]+lvs[ih] colors = colors + ':#'+lvs[ih]+hvs[ih]+lvs[ih] colors = colors + ':#'+lvs[ih]+lvs[ih]+hvs[ih] else: colors = colors + ':#'+hvs[ih]+hvs[ih]+lvs[ih] colors = colors + ':#'+hvs[ih]+lvs[ih]+hvs[ih] colors = colors + ':#'+lvs[ih]+hvs[ih]+hvs[ih] colors = colors + ':#'+hvs[ih]+lvs[ih]+lvs[ih] colors = colors + ':#'+lvs[ih]+hvs[ih]+lvs[ih] colors = colors + ':#'+lvs[ih]+lvs[ih]+hvs[ih] return colors def all_consecutive_combs(sizes): """ Function to provide all the consecutive possible combinations from a series of indices sizes: list of indices to expand and combine >>> all_consecutive_combs([3, 2, 2]) [[0 0 0] [0 0 1] [0 1 0] [0 1 1] [1 0 0] [1 0 1] [1 1 0] [1 1 1] [2 0 0] [2 0 1] [2 1 0] [2 1 1]] """ fname = 'all_consecutive_combs' Nsizes = len(sizes) Ncombs = np.prod(sizes) combs = np.zeros((Ncombs, Nsizes), dtype=int) itervals = np.zeros((Nsizes), dtype=int) for icomb in range(Ncombs): combs[icomb,:] = itervals overlimit = True for i in range(Nsizes): ind = Nsizes-i-1 itervals[ind] = itervals[ind] + 1 if itervals[ind] < sizes[ind]: overlimit = False if not overlimit: break else: itervals[ind] = 0 return combs #print all_consecutive_combs([3, 2, 2]) #quit()