ATLAS Offline Software
Loading...
Searching...
No Matches
compareTCTs.py
Go to the documentation of this file.
1#!/bin/env python
2
3# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
4
5import os,sys
6from PROCTools.getFileLists import tctPath, findTCTFiles
7sys.argv += [ '-b' ] # tell ROOT to not use graphics
8from ROOT import TFile,TTree
9from PROCTools.diffTAGTree import diffTTree
10
11os.environ['STAGE_SVCCLASS']="atlascerngroupdisk"
12os.environ['STAGE_HOST']="castoratlast3"
13
14ignoreTrees=set(("CollectionMetadata",))
15
16def compareTreeFiles(rName,vName,details):
17 if rName.startswith("/castor"):
18 rFile=TFile.Open("root://castoratlas/"+rName)
19 elif rName.startswith("/eos"):
20 rFile=TFile.Open("root://eosatlas.cern.ch/"+rName)
21 else:
22 rFile=TFile.Open(rName)
23
24 if vName.startswith("/castor"):
25 vFile=TFile.Open("root://castoratlas/"+vName)
26 elif vName.startswith("/eos"):
27 vFile=TFile.Open("root://eosatlas.cern.ch/"+vName)
28 else:
29 vFile=TFile.Open(vName)
30
31 if rFile is None:
32 print ("Failed to open reference file",rName)
33 return (0,1)
34
35 if vFile is None:
36 print ("Failed to open validation file",vName)
37 return (0,1)
38
39 rKeys=set()
40 for k in rFile.GetListOfKeys():
41 rKeys.add(k.GetName())
42 vKeys=set()
43 for k in vFile.GetListOfKeys():
44 vKeys.add(k.GetName())
45 #print (rKeys)
46 #print (vKeys)
47 keys=rKeys & vKeys
48 keys -= ignoreTrees
49
50 if len(keys)==0:
51 print ("ERROR no common trees names found in files",rName,vName)
52 return 0
53
54 nGood=0
55 nBad=0
56 for k in keys:
57 rTree=rFile.Get(k)
58 vTree=vFile.Get(k)
59 if not isinstance(rTree,TTree):
60 continue
61 if not isinstance(vTree,TTree):
62 continue
63 print ("Comparing TTree",k)
64 (good,bad)=diffTTree(rTree,vTree,details)
65 nGood+=good
66 nBad+=bad
67 return (nGood,nBad)
68
69def diffPoolFiles(ref,chk,details,toIgnore = ['RecoTimingObj_p1_RAWtoESD_timings', 'RecoTimingObj_p1_ESDtoAOD_timings']):
70 import PyUtils.PoolFile as PF
71 try:
72 df = PF.DiffFiles( refFileName = ref, chkFileName = chk, ignoreList = toIgnore)
73 if details is None:
74 df.printSummary()
75 else:
76 df.printSummary(details)
77 stat=df.status()
78 del df
79 except Exception:
80 print ("Exception caught while diff'ing POOL files")
81 stat=True
82 return stat
83
84def diffPickleFiles(ref,chk,details):
85 try:
86 ref_nlines = open(ref).readlines()
87 chk_nlines = open(chk).readlines()
88 if len(ref_nlines) == len(chk_nlines):
89 stat=False
90 print ("same number of lines!")
91 else :
92 print (ref," has ",len(ref_nlines)," lines." )
93 print (chk," has ",len(chk_nlines)," lines.")
94 stat=True
95 #print (ref," has ",len(ref_nlines)," lines." )
96 #print (chk," has ",len(chk_nlines)," lines.")
97 #for refer, check in zip(ref_nlines,chk_nlines):
98 # if refer != check:
99 # print ("Expected %r; got %r " % (refer,check))
100 #stat=False
101 except Exception:
102 stat=True
103 print ("Exception caught while comparinging jobReport(_RecoTrf)?.gpickle files")
104 return stat
105
106
107if __name__ == "__main__":
108 if len(sys.argv)<3 or sys.argv[1]=="-h" or sys.argv[1]=="--help":
109 print ("Usage: compareTCTs.py --nRef=<refernce nightly number> --nVal=<validation nightly number> --rRef=<reference nightly> --rVal=<validation nightly> --details=<text file> --file=<pattern> --sum=<summary file> --refPath=<path to ref-nightly> --valPath=<path to val-nightly>")
110 print (" Example: compareTCTs.py --nRef=15.6.X.Y --nVal=15.6.X.Y-VAL --rel=rel_4")
111 sys.exit(-1)
112
113 import getopt
114 nRef=None
115 nVal=None
116 rRef=None
117 rVal=None
118 detailsFN=None
119 filePattern=[]
120 sumFileName=None
121 refPath=None
122 valPath=None
123 diffroot=False
124 opts,args=getopt.getopt(sys.argv[1:],"b",["nRef=","nVal=","rRef=","rVal=","rel=","nightly=","details=","file=","sum=","refPath=","valPath=","diff-root="])
125 for o,a in opts:
126 if o=="--nRef": nRef=a
127 if o=="--nVal": nVal=a
128 if o=="--rRef": rRef=a
129 if o=="--rVal": rVal=a
130 if o=="--nightly": nRef=nVal=a
131 if o=="--rel": rVal=rRef=a
132 if o=="--details": detailsFN=a
133 if o=="--file": filePattern+=(a,)
134 if o=="--sum": sumFileName=a
135 if o=="--refPath": refPath=a
136 if o=="--valPath": valPath=a
137 if o=="--diff-root":
138 if a=="True": diffroot=True
139
140 if refPath is None:
141 if nRef is None:
142 print ("Reference nightly not defined! Please use --nRef parameter!")
143 sys.exit(-1)
144
145 if rRef is None:
146 print ("Reference nightly number not defined! Please use --rRef parameter!")
147 sys.exit(-1)
148
149 if valPath is None:
150 if nVal is None:
151 print ("Validation nightly not defined! Please use --nVal parameter!")
152 sys.exit(-1)
153 if rVal is None:
154 print ("Validation nightly number not defined! Please use --rVal parameter!")
155 sys.exit(-1)
156
157 if len(filePattern)==0:
158 filePattern+=(".*myESD.*pool.root$",".*myRDO.*pool.root$",".*myAOD.*pool.root$","myTAG.*.root$","jobReport(_RecoTrf)?.gpickle$")
159 else:
160 for i in range(len(filePattern)):
161 #for fP in filePattern:
162 if filePattern[i].upper()=="ROOT":
163 filePattern[i]="*root$"
164 elif filePattern[i].upper()=="POOL":
165 filePattern[i]="*.pool.root$"
166 elif filePattern[i].upper()=="ESD":
167 filePattern[i]=".*myESD.*pool.root$"
168 elif filePattern[i].upper()=="RDO":
169 filePattern[i]=".*myRDO.*pool.root$"
170 elif filePattern[i].upper()=="AOD":
171 filePattern[i]=".*myAOD.*pool.root$"
172 elif filePattern[i].upper()=="TAGCOMM":
173 filePattern[i]="myTAGCOMM.*root$"
174 elif filePattern[i]=="TAG":
175 filePattern[i]="myTAG.*.root$"
176 elif filePattern[i].upper()=="NONE":
177 filePattern=[]
178 else:
179 pass
180
181 print ("Comparing files matching:" )
182 print (filePattern)
183
184 #Hack to process POOL files first (otherwise inifite loop)
185 allPatterns = []
186 for fP in filePattern:
187 if fP.find("pool") == -1:
188 allPatterns.append(fP)
189 else:
190 allPatterns.insert(0, fP)
191
192 if refPath is None:
193 refPath = tctPath(nRef, rRef)
194
195 if valPath is None:
196 valPath = tctPath(nVal, rVal)
197
198 if not os.access(refPath, os.R_OK):
199 print ("Can't access output of reference TCT at",refPath)
200 sys.exit(-1)
201
202 if not os.access(valPath, os.R_OK):
203 print ("Can't access output of validation TCT at",valPath)
204 sys.exit(-1)
205
206 msg = "Reference TCT:\n"
207 msg += refPath + "\n"
208 msg += "Validation TCT:\n"
209 msg += valPath + "\n"
210
211 print (msg)
212 if detailsFN is not None:
213 details = open(detailsFN, "w")
214 details.write(msg)
215 else:
216 details=None
217
218 ff = findTCTFiles(refPath,valPath)
219 tctlist=ff.getCommonChains()
220 print ("Output from findTCTFile.getCommonChains():")
221 print (tctlist)
222
223 statPerChain=dict()
224
225 Summary=""
226 for pattern in allPatterns:
227 nIdenticalFiles = 0
228 nDifferentFiles = 0
229 filesToCompare = ff.findFiles(pattern)
230 print ("Will now look for files matching pattern:", pattern)
231 print ("The found files to compare:", filesToCompare)
232 print ("Comparing files matching [%s]" % pattern)
233 Summary += "Comparing files matching [%s]\n" % pattern
234 #for (tctName,r,v) in filesToCompare:
235 for name,rv in filesToCompare.items():
236 #print ("TCT:",name,":",len(rv))
237 print ("Chain %s: Found %i files matching [%s]" % (name,len(rv),pattern))
238 for (r,v) in rv:
239 fileName=r.split('/')[-1]
240 print ("Comparing files",fileName,"of TCT",name)
241 identical=False
242 if (fileName.endswith(".pool.root") and not fileName.startswith("myTAG")):
243 if(r.startswith("/eos")): r = "root://eosatlas.cern.ch/"+r
244 if(v.startswith("/eos")): v = "root://eosatlas.cern.ch/"+v
245 if not diffroot: stat=diffPoolFiles(r,v,details)
246 else:
247 stat=os.system("acmd.py diff-root "+r+" "+v+" --error-mode resilient --ignore-leaves HITStoRDO_timings RecoTimingObj_p1_HITStoRDO_timings RecoTimingObj_p1_RAWtoESD_mems RecoTimingObj_p1_RAWtoESD_timings RAWtoESD_mems RAWtoESD_timings ESDtoAOD_mems ESDtoAOD_timings RAWtoALL_mems RAWtoALL_timings RecoTimingObj_p1_RAWtoALL_mems RecoTimingObj_p1_RAWtoALL_timings --entries 10 > tmp.txt")
248 os.system("cat tmp.txt|grep -v sync")
249 os.system("rm -f tmp.txt")
250 identical=not stat
251 elif fileName.endswith(".root"):
252 #(eq,dif)=compareTreeFiles(r,v,details)
253 #if eq==0 and dif==0: continue
254 #identical=(dif==0)
255 stat=os.system("diffTAGTree.py "+r+" "+v+" > tmp.txt")
256 os.system("cat tmp.txt|grep -v sync")
257 os.system("rm -f tmp.txt")
258 identical=not stat
259 elif fileName.endswith(".pickle"):
260 stat=diffPickleFiles(r,v,details)
261 identical=not stat
262 else:
263 print ("ERROR: Don't know how to compare",fileName)
264
265 if (identical):
266 nIdenticalFiles+=1
267 if name not in statPerChain:
268 statPerChain[name]=False
269 else:
270 statPerChain[name]|=False
271 print ("Files are identical")
272 else:
273 statPerChain[name]=True
274 nDifferentFiles+=1
275 print ("Files are not identical")
276
277 Summary+="Found %i identical files and %i different files\n" % (nIdenticalFiles, nDifferentFiles)
278 print ("Found %i identical files and %i different files\n" % (nIdenticalFiles, nDifferentFiles))
279
280 if details is not None:
281 details.write(Summary)
282 details.close()
283
284 #print (Summary)
285
286 #print (tctlist)
287 #Check log,mem & cpu,
288 complain=""
289 for (name,info) in tctlist.items():
290 #print (name,info,len(info))
291 if len(info)<2: continue
292 print ("\n"+name+":")
293 if (info[0].loglines>0 and info[1].loglines>0):
294 ratio=100.0*(info[1].loglines-info[0].loglines)/info[0].loglines
295 ln="\tLoglines: %i -> %i (%.2f)" % (info[0].loglines,info[1].loglines,ratio)
296 if abs(ratio)>5:
297 print (ln+"***")
298 complain+=name+" "+ln+"***\n"
299 else:
300 print (ln)
301 if len(info[0].cpulist)>4 and len(info[1].cpulist)>4:
302 #ESD
303 cpu_r=info[0].cpulist[1]
304 cpu_v=info[1].cpulist[1]
305 if (cpu_r>0 and cpu_v>0):
306 ratio=100.0*(cpu_v-cpu_r)/cpu_r
307 ln="\tESD CPU: %i -> %i (%.2f%%)" % (cpu_r,cpu_v,ratio)
308 if abs(ratio)>15:
309 print (ln+"***")
310 complain+=name+" "+ln+"***\n"
311 else:
312 print (ln)
313
314 #AOD
315 cpu_r=info[0].cpulist[4]
316 cpu_v=info[1].cpulist[4]
317 if (cpu_r>0 and cpu_v>0):
318 ratio=100.0*(cpu_v-cpu_r)/cpu_r
319 ln="\tAOD CPU: %i -> %i (%.2f%%)" % (cpu_r,cpu_v,ratio)
320 if abs(ratio)>15:
321 print (ln+"***")
322 complain+=name+" "+ln+"***\n"
323 else:
324 print (ln)
325
326 if len(info[0].memlist)>4 and len(info[1].memlist)>4:
327 mem_r=info[0].memlist[1]
328 mem_v=info[1].memlist[1]
329 if (mem_r>0 and mem_v>0):
330 ratio=100.0*(mem_v-mem_r)/mem_r
331 ln="\tESD MEM: %i -> %i (%.2f%%)" % (mem_r,mem_v,ratio)
332 if abs(ratio)>15:
333 print (ln+"***")
334 complain+=name+" "+ln+"***\n"
335 else:
336 print (ln)
337
338 mem_r=info[0].memlist[4]
339 mem_v=info[1].memlist[4]
340 if (mem_r>0 and mem_v>0):
341 ratio=100.0*(mem_v-mem_r)/mem_r
342 ln="\tAOD MEM: %i -> %i (%.2f%%)" % (mem_r,mem_v,ratio)
343 if abs(ratio)>15:
344 print (ln+"***")
345 complain+=name+" "+ln+"***\n"
346 else:
347 print (ln)
348
349 isok=True
350 for f,s in statPerChain.items():
351 if s:
352 print ("%-70s CHANGED" % f)
353 isok=False
354 else:
355 print ("%-70s IDENTICAL" % f)
356
357 if sumFileName is not None:
358 sumFile=open(sumFileName,"w")
359 for f,s in statPerChain.items():
360 line = "%-70s" % f
361 if s:
362 line += "CHANGED\n"
363 else:
364 line += "IDENTICAL\n"
365 sumFile.write(line)
366
367 sumFile.write("\n\n")
368 sumFile.write(complain)
369 sumFile.close()
370
371 #print (statPerChain)
372 del diffTTree
373 if not isok:
374 sys.exit(-1)
int upper(int c)
if(febId1==febId2)
STL class.
compareTreeFiles(rName, vName, details)
diffPickleFiles(ref, chk, details)