00001 from Gaudi.Configuration import *
00002 from GaudiPython import AppMgr, gbl
00003 from ROOT import TFile, TBufferFile, TBuffer
00004 from processing import Process, Queue
00005
00006 import sys, sets
00007
00008
00009
00010
00011
00012
00013
00014 def checkKeys( name ) :
00015
00016 fname = name[4:]
00017 tf = TFile(fname, 'REC')
00018
00019
00020
00021
00022
00023 importOptions('$STDOPTS/LHCbApplication.opts')
00024 importOptions('$GAUDIPOOLDBROOT/options/GaudiPoolDbRoot.opts')
00025
00026
00027 OutputStream("DstWriter").Output = ''
00028 HistogramPersistencySvc().OutputFile = ''
00029 MessageSvc(OutputLevel = ERROR)
00030 EventSelector().PrintFreq = 100
00031
00032 ApplicationMgr( OutputLevel = ERROR,
00033 AppName = 'File Check - Serial vs Parallel' )
00034
00035
00036 PAR = 'PARALLEL'
00037 SER = 'SERIAL'
00038
00039 def CompareTrees( pname, sname ) :
00040 pf = TFile(pname, 'REC')
00041 sf = TFile(sname, 'REC')
00042 event = '_Event'
00043 pfks = pf.GetListOfKeys()
00044 sfks = sf.GetListOfKeys()
00045 pfkeys = list( [pfk.GetName() for pfk in pfks] ) ; pfkeys.sort()
00046 sfkeys = list( [sfk.GetName() for sfk in sfks] ) ; sfkeys.sort()
00047 pMeta = [] ; pEvent = [] ; pOther = []
00048 for k in pfkeys :
00049 if k.startswith(event) : pEvent.append(k)
00050 elif k.startswith('##') : pMeta.append(k)
00051 else : pOther.append(k)
00052 sMeta = [] ; sEvent = [] ; sOther = []
00053 for k in sfkeys :
00054 if k.startswith(event) : sEvent.append(k)
00055 elif k.startswith('##') : sMeta.append(k)
00056 else : sOther.append(k)
00057
00058 if pMeta == sMeta : pass
00059 else : print 'Meta Data differs'
00060
00061 if pEvent == sEvent : pass
00062 else : print 'Event data differs'
00063
00064 if pOther != sOther :
00065 pset = sets.Set(pOther)
00066 sset = sets.Set(sOther)
00067 pExtra = pset-sset
00068 sExtra = sset-pset
00069 if pExtra : print 'Extra Data in parallel file : ', pExtra
00070 if sExtra : print 'Extra Data in serial file : ', sExtra
00071 if sExtra or pExtra : print 'Files will have different sizes'
00072 pf.Close()
00073 sf.Close()
00074
00075 def switchDict( d ) :
00076
00077
00078 nkeys = len(d.keys())
00079 vals = d.values()
00080 nvals = len(vals)
00081 for v in vals :
00082 if vals.count(v) > 1 :
00083 print 'Dictionary cannot be switched, values not unique'
00084 return None
00085 print 'Dict has keys/values : %i/%i'%( nkeys, nvals )
00086 pairs = d.items()
00087 newd = {}
00088 for k, entry in pairs : newd[entry] = k
00089 return newd
00090
00091
00092 def printDict( d, name='unspecified' ) :
00093
00094
00095
00096
00097
00098
00099
00100 print '-'*80
00101 print 'Dictionary %s : '%(name)
00102 for k in iter(d.keys()) :
00103 print '\t', k, '\t', d[k]
00104 print '-'*80
00105
00106
00107 def Reader( readerType, filename, qacross, qToEngine ) :
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120 a = AppMgr()
00121 sel = a.evtsel()
00122 evt = a.evtsvc()
00123
00124 header = '/Event/Rec/Header'
00125 sel.open( filename )
00126 ct = 0
00127 order = {}
00128 fname = filename[4:]
00129
00130
00131 while True :
00132 a.run(1)
00133 if evt[header] :
00134 eNumber = int(evt[header].evtNumber())
00135 order[eNumber] = ct
00136 ct += 1
00137 else : break
00138
00139 if readerType==SER :
00140
00141 order = switchDict( order )
00142 qacross.put( order )
00143 qacross.put( None )
00144
00145 serOrder = order
00146 elif readerType==PAR :
00147
00148 for serOrder in iter(qacross.get, None) : pass
00149 lsks = len(serOrder.keys())
00150 lpks = len(order.keys())
00151 print 'Events in Files (serial/parallel) : %i / %i'%( lsks, lpks )
00152
00153
00154
00155 for i in iter( serOrder.keys() ) :
00156 if readerType==PAR : i = order[serOrder[i]]
00157 a.runSelectedEvents( fname, i )
00158 lst = evt.getList() ; lst.sort()
00159 ascii = dict( [ (l, (evt[l].__class__.__name__, evt[l].__repr__())) for l in lst ] )
00160 qToEngine.put(ascii)
00161 qToEngine.put(None)
00162 print '%s Reader Finished'%(readerType)
00163
00164 def ComparisonEngine( pQueue, sQueue ) :
00165
00166
00167
00168
00169
00170
00171
00172
00173 results = []
00174 while True :
00175 pitem = pQueue.get()
00176 sitem = sQueue.get()
00177 if pitem==sitem==None : print 'Termination Signals received ok' ; break
00178 elif pitem==None : print 'pitem != sitem : ', pitem, sitem ; break
00179 elif sitem==None : print 'pitem != sitem : ', pitem, sitem ; break
00180 results.append( compareEvents(pitem,sitem) )
00181 print '='*80
00182 print 'Comparison Engine Finished'
00183 print '-'*80
00184 print 'Total Events Checked : %i'%( len(results) )
00185 print 'Perfect Matches : %i'%( sum(results) )
00186 print 'Errors : %i'%( len(results)-sum(results) )
00187 print '='*80
00188
00189 def checkForAddressDifference( a, b ) :
00190
00191
00192
00193
00194
00195
00196
00197
00198 ref = 'DataObject at 0x'
00199 if a[:16]==b[:16]==ref : return True
00200 else : return False
00201
00202
00203 def compareEvents( s, p ) :
00204
00205
00206
00207
00208 sks = s.keys() ; pks = p.keys()
00209 sks.sort() ; pks.sort()
00210 if len(sks) == len(pks) : pass
00211 else :
00212
00213
00214
00215
00216
00217
00218
00219
00220 extras = list(sets.Set(pks) - sets.Set(sks))
00221 for e in extras :
00222 if p[e][0] == 'DataObject' : pks.remove(e)
00223 else : print 'Extra Other thing found!', e, p[e][0] ; return False
00224
00225
00226 if sks == pks : pass
00227 else : return False
00228
00229
00230 l = len(sks)
00231 diffs = []
00232 for i in xrange(l) :
00233 key = sks[i]
00234
00235 if s[key][0] == p[key][0] : pass
00236 else : diffs.append(key)
00237
00238 if s[key][1] == p[key][1] : pass
00239 elif checkForAddressDifference( p[key][1], s[key][1] ) : pass
00240 else : diffs.append(key)
00241
00242
00243 if diffs : return False
00244 else : return True
00245
00246
00247 if __name__ == '__main__' :
00248
00249 args = sys.argv
00250 args.pop(0)
00251 if len(args) != 2 :
00252 print 'Please supply two arguments : > python loadFile <parallelFile> <serialFile>'
00253 sys.exit(0)
00254 else :
00255 par = 'PFN:'+args[0]
00256 ser = 'PFN:'+args[1]
00257 print 'Parallel File to be analysed : %s'%( par )
00258 print 'Serial File to be analysed : %s'%( ser )
00259
00260
00261 pname = par[4:]
00262 sname = ser[4:]
00263
00264
00265
00266 qacross = Queue()
00267 pout = Queue()
00268 sout = Queue()
00269
00270 par = Process( target=Reader, args=( PAR, par, qacross, pout) )
00271 ser = Process( target=Reader, args=( SER, ser, qacross, sout) )
00272 com = Process( target=ComparisonEngine, args=(pout, sout) )
00273
00274 com.start() ; par.start() ; ser.start()
00275 ser.join() ; par.join() ; com.join()
00276
00277 CompareTrees( pname, sname )
00278