00001 '''This module collects some frequently used helper functions
00002 '''
00003 import time,ast,re,json,coral,array
00004 def flatten(obj):
00005 '''Given nested lists or tuples, returns a single flattened list'''
00006 result = []
00007 for piece in obj:
00008 if hasattr (piece, '__iter__') and not isinstance (piece, basestring):
00009 result.extend( flatten (piece) )
00010 else:
00011 result.append (piece)
00012 return result
00013
00014 def parseTime(iTime):
00015 '''
00016 input string of the ("^\d\d/\d\d/\d\d \d\d:\d\d:\d\d$|^\d{6}$|^\d{4}$" format
00017 output (runnum,fillnum,timeStr)
00018 '''
00019 if not iTime: return (None,None,None)
00020 p=re.compile('^\d\d/\d\d/\d\d \d\d:\d\d:\d\d$')
00021 if re.match(p,iTime):
00022 return (None,None,iTime)
00023 p=re.compile('^\d{6}$')
00024 if re.match(p,iTime):
00025 return (int(iTime),None,None)
00026 p=re.compile('^\d{4}$')
00027 if re.match(p,iTime):
00028 return (None,int(iTime),None)
00029
00030 def lumiUnitForPrint(t):
00031 '''
00032 input : largest lumivalue
00033 output: (unitstring,denomitor)
00034 '''
00035 unitstring='/ub'
00036 denomitor=1.0
00037 if t>=1.0e3 and t<1.0e06:
00038 denomitor=1.0e3
00039 unitstring='/nb'
00040 elif t>=1.0e6 and t<1.0e9:
00041 denomitor=1.0e6
00042 unitstring='/pb'
00043 elif t>=1.0e9 and t<1.0e12:
00044 denomitor=1.0e9
00045 unitstring='/fb'
00046 elif t>=1.0e12 and t<1.0e15:
00047 denomitor=1.0e12
00048 unitstring='/ab'
00049 elif t<1.0 and t>=1.0e-3:
00050 denomitor=1.0e-03
00051 unitstring='/mb'
00052 elif t<1.0e-03 and t>=1.0e-06:
00053 denomitor=1.0e-06
00054 unitstring='/b'
00055 elif t<1.0e-06 and t>=1.0e-09:
00056 denomitor=1.0e-9
00057 unitstring='/kb'
00058 return (unitstring,denomitor)
00059 def guessUnit(inverseubval):
00060 '''
00061 input:
00062 float value in 1/ub
00063 output:
00064 printable value (value(float),unit(str)) unit in [1/kb,1/b,1/mb,1/ub,1/nb,1/pb,1/fb]
00065 '''
00066 if inverseubval>=1.0e-09 and inverseubval<1.0e-06:
00067 denomitor=1.0e-09
00068 unitstring='/kb'
00069 return (float(inverseubval)/float(denomitor),unitstring)
00070 if inverseubval>=1.0e-06 and inverseubval<1.0e-03:
00071 denomitor=1.0e-06
00072 unitstring='/b'
00073 return (float(inverseubval)/float(denomitor),unitstring)
00074 if inverseubval>=1.0e-03 and inverseubval<1.0:
00075 denomitor=1.0e-03
00076 unitstring='/mb'
00077 return (float(inverseubval)/float(denomitor),unitstring)
00078 if inverseubval>=1.0 and inverseubval<1.0e3:
00079 unitstring='/ub'
00080 return (inverseubval,unitstring)
00081 if inverseubval>=1.0e3 and inverseubval<1.0e06:
00082 denomitor=1.0e3
00083 unitstring='/nb'
00084 return (float(inverseubval)/float(denomitor),unitstring)
00085 if inverseubval>=1.0e6 and inverseubval<1.0e9:
00086 denomitor=1.0e6
00087 unitstring='/pb'
00088 return (float(inverseubval)/float(denomitor),unitstring)
00089 if inverseubval>=1.0e9 and inverseubval<1.0e12:
00090 denomitor=1.0e9
00091 unitstring='/fb'
00092 return (float(inverseubval)/float(denomitor),unitstring)
00093 if inverseubval>=1.0e12 and inverseubval<1.0e15:
00094 denomitor=1.0e12
00095 unitstring='/ab'
00096 return (float(inverseubval)/float(denomitor),unitstring)
00097 return (float(inverseubval),'/ub')
00098 def pairwise(lst):
00099 """
00100 yield item i and item i+1 in lst. e.g.
00101 (lst[0], lst[1]), (lst[1], lst[2]), ..., (lst[-1], None)
00102
00103 from https://code.activestate.com/recipes/409825-look-ahead-one-item-during-iteration
00104 """
00105 if not len(lst): return
00106
00107 for i in range(len(lst)-1):
00108 yield lst[i], lst[i+1]
00109 yield lst[-1], None
00110 def findInList(mylist,element):
00111 """
00112 check if an element is in the list
00113 """
00114 pos=-1
00115 try:
00116 pos=mylist.index(element)
00117 except ValueError:
00118 pos=-1
00119 return pos!=-1
00120 def is_intstr(s):
00121 """test if a string can be converted to a int
00122 """
00123 try:
00124 int(s)
00125 return True
00126 except ValueError:
00127 return False
00128 def is_floatstr(s):
00129 """
00130 test if a string can be converted to a float
00131 """
00132 try:
00133 float(s)
00134 return True
00135 except ValueError:
00136 return False
00137 def count_dups(l):
00138 """
00139 report the number of duplicates in a python list
00140 """
00141 from collections import defaultdict
00142 tally=defaultdict(int)
00143 for x in l:
00144 tally[x]+=1
00145 return tally.items()
00146 def transposed(lists, defaultval=None):
00147 """
00148 transposing list of lists
00149 from https://code.activestate.com/recipes/410687-transposing-a-list-of-lists-with-different-lengths/
00150 """
00151 if not lists: return []
00152
00153 return map(lambda *row: [elem for elem in row or defaultval], *lists)
00154 def pack(high,low):
00155 """pack high,low 32bit unsigned int to one unsigned 64bit long long
00156 Note:the print value of result number may appear signed, if the sign bit is used.
00157 """
00158 h=high<<32
00159 return (h|low)
00160 def packToString(high,low):
00161 """pack high,low 32bit unsigned int to one unsigned 64bit long long in string format
00162 Note:the print value of result number may appear signed, if the sign bit is used.
00163 """
00164 fmt="%u"
00165 return fmt%pack(high,low)
00166 def unpack(i):
00167 """unpack 64bit unsigned long long into 2 32bit unsigned int, return tuple (high,low)
00168 """
00169 high=i>>32
00170 low=i&0xFFFFFFFF
00171 return(high,low)
00172 def unpackFromString(i):
00173 """unpack 64bit unsigned long long in string format into 2 32bit unsigned int, return tuple(high,low)
00174 """
00175 return unpack(int(i))
00176 def timeStamptoDate(i):
00177 """convert 64bit timestamp to local date in string format
00178 """
00179 return time.ctime(unpack(i)[0])
00180 def timeStamptoUTC(i):
00181 """convert 64bit timestamp to Universal Time in string format
00182 """
00183 t=unpack(i)[0]
00184 return time.strftime("%a, %d %b %Y %H:%M:%S +0000",time.gmtime(t))
00185 def unpackLumiid(i):
00186 """unpack 64bit lumiid to dictionary {'run','lumisection'}
00187 """
00188 j=unpack(i)
00189 return {'run':j[0],'lumisection':j[1]}
00190 def inclusiveRange(start,stop,step):
00191 """return range including the stop value
00192 """
00193 v=start
00194 while v<stop:
00195 yield v
00196 v+=step
00197 if v>=stop:
00198 yield stop
00199
00200 def tolegalJSON(inputstring):
00201 '''
00202 convert json like string to legal json string
00203 add double quote around json keys if they are not there, change single quote to double quote around keys
00204 '''
00205 strresult=inputstring.strip()
00206 strresult=re.sub("\s+","",strresult)
00207 try:
00208 mydict=ast.literal_eval(strresult)
00209 except SyntaxError:
00210 print 'error in converting string to dict'
00211 raise
00212 result={}
00213 for k,v in mydict.items():
00214 if not isinstance(k,str):
00215 result[str(k)]=v
00216 else:
00217 result[k]=v
00218 return re.sub("'",'"',str(result))
00219
00220 def packArraytoBlob(iarray):
00221 '''
00222 Inputs:
00223 inputarray: a python array
00224 '''
00225 result=coral.Blob()
00226 result.write(iarray.tostring())
00227 return result
00228
00229 def unpackBlobtoArray(iblob,itemtypecode):
00230 '''
00231 Inputs:
00232 iblob: coral.Blob
00233 itemtypecode: python array type code
00234 '''
00235 if itemtypecode not in ['c','b','B','u','h','H','i','I','l','L','f','d']:
00236 raise RuntimeError('unsupported typecode '+itemtypecode)
00237 result=array.array(itemtypecode)
00238 blobstr=iblob.readline()
00239 if not blobstr :
00240 return None
00241 result.fromstring(blobstr)
00242 return result
00243
00244 def packListstrtoCLOB(iListstr,separator=','):
00245 '''
00246 pack list of string of comma separated large string CLOB
00247 '''
00248 return separator.join(iListstr)
00249
00250 def unpackCLOBtoListstr(iStr,separator=','):
00251 '''
00252 unpack a large string to list of string
00253 '''
00254 return [i.strip() for i in iStr.strip().split(separator)]
00255
00256 def splitlistToRangeString (inPut):
00257 result = []
00258 first = inPut[0]
00259 last = inPut[0]
00260 result.append ([inPut[0]])
00261 counter = 0
00262 for i in inPut[1:]:
00263 if i == last+1:
00264 result[counter].append (i)
00265 else:
00266 counter += 1
00267 result.append ([i])
00268 last = i
00269 return ', '.join (['['+str (min (x))+'-'+str (max (x))+']' for x in result])
00270
00271 def parselumicorrector(correctorStr):
00272 '''
00273 output: (functionname,parametersinuppercase[])
00274 '''
00275 cleancorrectorStr=correctorStr.replace(' ','')
00276 [correctorFunc,paramsStr]=cleancorrectorStr.split(':')
00277 params=paramsStr.split(',')
00278 return (correctorFunc,params)
00279
00280 if __name__=='__main__':
00281 nested=[[[1,2],[6,6,8]],[[3,4,5],[4,5]]]
00282 print 'flattened ',flatten(nested)
00283 a=[1,2,3,4,5]
00284 for i,j in pairwise(a):
00285 if j :
00286 print i,j
00287 lst = ['I1','I2','I1','I3','I4','I4','I7','I7','I7','I7','I7']
00288 print count_dups(lst)
00289 seqbag=[[1,2,3],[1,3,3],[1,4,6],[4,5,6,7],[8,9]]
00290 print 'before ',seqbag
00291 print 'after ',transposed(seqbag,None)
00292 print [i for i in inclusiveRange(1,3,1)]
00293
00294 result=tolegalJSON('{1:[],2:[[1,3],[4,5]]}')
00295 print result
00296 pp=json.loads(result)
00297 print pp["2"]
00298 result=tolegalJSON("{'1':[],'2':[[1,3],[4,5]]}")
00299 print result
00300 pp=json.loads(result)
00301 print pp["2"]
00302 result=tolegalJSON('{"1":[],"2":[[1,3],[4,5]]}')
00303 print result
00304 pp=json.loads(result)
00305 print pp["2"]
00306
00307 a=array.array('f')
00308 a.append(1.3)
00309 a.append(1.4)
00310 a.append(2.3)
00311 a.append(6.3)
00312 myblob=packArraytoBlob(a)
00313 print myblob.size()
00314 print unpackBlobtoArray(myblob,'f')
00315 b=array.array('f')
00316 myblob=packArraytoBlob(b)
00317 print myblob.size()
00318 a=['aa_f', 'bb', 'dfc']
00319 print packListstrtoCLOB(a)