00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 from array import array
00015 from copy import deepcopy
00016 from os import chdir,getcwd,listdir,makedirs,rmdir
00017 from os.path import exists,join
00018
00019 import sys
00020 argv=sys.argv
00021 from ROOT import *
00022 sys.argv=argv
00023
00024 from definitions import *
00025 from utils import setTDRStyle
00026
00027
00028
00029 setTDRStyle()
00030
00031
00032 gROOT.SetBatch(kTRUE)
00033
00034
00035
00036 _log_level=5
00037 def logger(msg_level,message):
00038 if msg_level>=_log_level:
00039 print "[%s] %s" %(asctime(),message)
00040
00041
00042
00043 class Weighted(object):
00044 def __init__(self,name,weight=1):
00045 self.name=name
00046 self.weight=weight
00047
00048
00049
00050 class CompInfo(object):
00051 def __init__(self,sample="",release1="",release2="",run1="",run2="",tier1=0,tier2=0):
00052 self.sample=sample
00053 self.release1=release1
00054 self.release2=release2
00055 self.run1=run1
00056 self.run2=run2
00057 self.tier1=tier1
00058 self.tier2=tier2
00059
00060
00061 class Directory(Weighted):
00062 def __init__(self,name,mother_dir="",meta=CompInfo(),draw_success=False,do_pngs=False):
00063 self.mother_dir=mother_dir
00064 self.meta=meta
00065 self.subdirs=[]
00066 self.comparisons=[]
00067 self.n_fails=0
00068 self.n_successes=0
00069 self.n_nulls=0
00070 self.n_skiped = 0
00071 self.n_comp_skiped = 0
00072 self.n_comp_fails=0
00073 self.n_comp_successes=0
00074 self.n_comp_nulls=0
00075 self.weight=0
00076 self.stats_calculated=False
00077 Weighted.__init__(self,name)
00078 self.draw_success=draw_success
00079 self.do_pngs=do_pngs
00080 self.rank_histo=TH1I("rh%s"%name,"",50,-0.01,1.001)
00081 self.rank_histo.SetDirectory(0)
00082
00083 def is_empty(self):
00084 if len(self.subdirs)==0 and len(self.comparisons)==0:
00085 return True
00086 return False
00087
00088 def calcStats(self,make_pie=True):
00089 '''Walk all subdirs and calculate weight,fails and successes.
00090 Moreove propagate the sample and releases names.
00091 '''
00092 if self.stats_calculated:
00093 return 0
00094
00095 self.n_fails=0
00096 self.n_successes=0
00097 self.n_nulls=0
00098 self.n_comp_fails=0
00099 self.n_comp_successes=0
00100 self.n_comp_nulls=0
00101 self.weight=0
00102
00103 self.n_skiped = 0
00104 self.n_comp_skiped = 0
00105
00106
00107 self.subdirs = filter(lambda subdir: not subdir.is_empty(),self.subdirs)
00108
00109 for comp in self.comparisons:
00110 if comp.status == SKIPED:
00111 self.n_skiped += 1
00112 self.n_comp_skiped += 1
00113 self.weight+=1
00114 else:
00115 self.rank_histo.Fill(comp.rank)
00116 self.weight+=1
00117 if comp.status == FAIL:
00118 self.n_fails+=1
00119 self.n_comp_fails+=1
00120 elif comp.status == SUCCESS:
00121 self.n_successes+=1
00122 self.n_comp_successes+=1
00123 else:
00124 self.n_nulls+=1
00125 self.n_comp_nulls+=1
00126
00127 for subdir in self.subdirs:
00128 subdir.mother_dir=join(self.mother_dir,self.name)
00129 subdir.calcStats(make_pie)
00130 subdir.meta=self.meta
00131 self.weight+=subdir.weight
00132 self.n_fails+=subdir.n_fails
00133 self.n_successes+=subdir.n_successes
00134 self.n_nulls+=subdir.n_nulls
00135
00136 self.n_skiped+=subdir.n_skiped
00137
00138 self.rank_histo.Add(subdir.rank_histo)
00139
00140 self.stats_calculated=True
00141
00142
00143
00144 def get_subdirs_dict(self):
00145 subdirdict={}
00146 for subdir in self.subdirs:
00147 subdirdict[subdir.name]=subdir
00148 return subdirdict
00149
00150 def get_subdirs_names(self):
00151 subdirnames=[]
00152 for subdir in self.subdirs:
00153 subdirnames.append(subdir.name)
00154 return subdirnames
00155
00156 def get_summary_chart_ajax(self,w=400,h=300):
00157 """Emit the ajax to build a pie chart using google apis...
00158 """
00159 url = "https://chart.googleapis.com/chart?"
00160 url+= "cht=p3"
00161
00162 url+= "&chco=00FF00|FFFF00|FF0000|7A7A7A"
00163 url+= "&chs=%sx%s" %(w,h)
00164
00165 url+= "&chd=t:%.2f,%.2f,%.2f,%.2f"%(self.get_success_rate(),self.get_null_rate(),self.get_fail_rate(),self.get_skiped_rate())
00166
00167 return url
00168
00169 def print_report(self,indent="",verbose=False):
00170 if len(indent)==0:
00171 self.calcStats(make_pie=False)
00172
00173 if verbose:
00174 fail_comps=filter(lambda comp:comp.status==FAIL,self.comparisons)
00175 fail_comps=sorted(fail_comps,key=lambda comp:comp.name )
00176 if len(fail_comps)>0:
00177 print indent+"* %s/%s:" %(self.mother_dir,self.name)
00178 for comp in fail_comps:
00179 print indent+" - %s: %s Test Failed (pval = %s) " %(comp.name,comp.test_name,comp.rank)
00180 for subdir in self.subdirs:
00181 subdir.print_report(indent+" ",verbose)
00182
00183 if len(indent)==0:
00184 print "\n%s - summary of %s tests:" %(self.name,self.weight)
00185 print " o Failiures: %.2f%% (%s/%s)" %(self.get_fail_rate(),self.n_fails,self.weight)
00186 print " o Nulls: %.2f%% (%s/%s) " %(self.get_null_rate(),self.n_nulls,self.weight)
00187 print " o Successes: %.2f%% (%s/%s) " %(self.get_success_rate(),self.n_successes,self.weight)
00188 print " o Skipped: %.2f%% (%s/%s) " %(self.get_skiped_rate(),self.n_skiped,self.weight)
00189
00190 def get_skiped_rate(self):
00191 if self.weight == 0: return 0
00192 return 100.*self.n_skiped/self.weight
00193 def get_fail_rate(self):
00194 if self.weight == 0:return 0
00195 return 100.*self.n_fails/self.weight
00196
00197 def get_success_rate(self):
00198 if self.weight == 0:return 1
00199 return 100.*self.n_successes/self.weight
00200
00201 def get_null_rate(self):
00202 if self.weight == 0:return 0
00203 return 100.*self.n_nulls/self.weight
00204
00205 def __get_full_path(self):
00206
00207 if len(self.mother_dir)==0:
00208 return self.name
00209 return join(self.mother_dir,self.name)
00210
00211 def __create_on_disk(self):
00212 if not exists(self.mother_dir) and len(self.mother_dir)!=0:
00213 makedirs(self.mother_dir)
00214 full_path=self.__get_full_path()
00215 if not exists(full_path) and len(full_path)>0:
00216 makedirs(full_path)
00217
00218 def get_summary_chart_name(self):
00219 return join(self.__get_full_path(),"summary_chart.png")
00220
00221 def __create_pie_image(self):
00222 self.__create_on_disk()
00223 vals=[]
00224 colors=[]
00225 for n,col in zip((self.n_fails,self.n_nulls,self.n_successes,self.n_skiped),(kRed,kYellow,kGreen,kBlue)):
00226 if n!=0:
00227 vals.append(n)
00228 colors.append(col)
00229 valsa=array('f',vals)
00230 colorsa=array('i',colors)
00231 can = TCanvas("cpie","TPie test",100,100);
00232 try:
00233 pie = TPie("ThePie",self.name,len(vals),valsa,colorsa);
00234 label_n=0
00235 if self.n_fails!=0:
00236 pie.SetEntryLabel(label_n, "Fail: %.1f(%i)" %(self.get_fail_rate(),self.n_fails) );
00237 label_n+=1
00238 if self.n_nulls!=0:
00239 pie.SetEntryLabel(label_n, "Null: %.1f(%i)" %(self.get_null_rate(),self.n_nulls) );
00240 label_n+=1
00241 if self.n_successes!=0:
00242 pie.SetEntryLabel(label_n, "Success: %.1f(%i)" %(self.get_success_rate(),self.n_successes) );
00243 if self.n_skiped!=0:
00244 pie.SetEntryLabel(label_n, "Skipped: %.1f(%i)" %(self.get_skiped_rate(),self.n_skiped));
00245 pie.SetY(.52);
00246 pie.SetAngularOffset(0.);
00247 pie.SetLabelsOffset(-.3);
00248
00249 pie.Draw("3d nol");
00250 can.Print(self.get_summary_chart_name());
00251 except:
00252 print "self.name = %s" %self.name
00253 print "len(vals) = %s (vals=%s)" %(len(vals),vals)
00254 print "valsa = %s" %valsa
00255 print "colorsa = %s" %colorsa
00256
00257 def prune(self,expandable_dir):
00258 """Eliminate from the tree the directory the expandable ones.
00259 """
00260
00261 exp_index=-1
00262 counter=0
00263 for subdir in self.subdirs:
00264
00265
00266 subdir.mother_dir=subdir.mother_dir.replace("/"+expandable_dir,"")
00267 if subdir.name==expandable_dir:
00268 exp_index=counter
00269 counter+=1
00270
00271
00272 if exp_index>=0:
00273 exp_dir=self.subdirs[exp_index]
00274 for subsubdir in exp_dir.subdirs:
00275
00276 subsubdir.mother_dir=subsubdir.mother_dir.replace("/"+expandable_dir,"")
00277 while "//" in subsubdir.mother_dir:
00278 print subsubdir.mother_dir
00279 subsubdir.mother_dir=subsubdir.mother_dir.replace("//","/")
00280
00281 self.subdirs.append(subsubdir)
00282
00283 for comp in exp_dir.comparisons:
00284 comp.mother_dir=comp.mother_dir.replace("/"+expandable_dir,"")
00285 while "//" in comp.mother_dir:
00286 comp.mother_dir
00287 comp.mother_dir=comp.mother_dir.replace("/")
00288 if not comp in self.comparisons:
00289 self.comparisons.append(comp)
00290 self.n_comp_fails = exp_dir.n_comp_fails
00291 self.n_comp_nulls = exp_dir.n_comp_nulls
00292 self.n_comp_successes = exp_dir.n_comp_successes
00293 self.n_comp_skiped = exp_dir.n_comp_skiped
00294
00295 del self.subdirs[exp_index]
00296 self.prune(expandable_dir)
00297
00298 for subdir in self.subdirs:
00299 subdir.prune(expandable_dir)
00300
00301 def __repr__(self):
00302 if self.is_empty():
00303 return "%s seems to be empty. Please check!" %self.name
00304 content="%s , Rates: Success %.2f%%(%s) - Fail %.2f%%(%s) - Null %.2f%%(%s)\n" %(self.name,self.get_success_rate(),self.n_successes,self.get_fail_rate(),self.n_fails,self.get_null_rate(),self.n_nulls)
00305 for subdir in self.subdirs:
00306 content+=" %s\n" % subdir
00307 for comp in self.comparisons:
00308 content+=" %s\n" % comp
00309 return content
00310
00311
00312 from multiprocessing import Process
00313 def print_multi_threaded(canvas,img_name):
00314 canvas.Print(img_name)
00315
00316 tcanvas_print_processes=[]
00317
00318
00319 class Comparison(Weighted):
00320 canvas_xsize=500
00321 canvas_ysize=400
00322 def __init__(self,name,mother_dir,h1,h2,stat_test,draw_success=False,do_pngs=False, skip=False):
00323 self.name=name
00324 self.png_name="placeholder.png"
00325 self.mother_dir=mother_dir
00326 self.img_name=""
00327
00328 Weighted.__init__(self,name)
00329
00330 stat_test.set_operands(h1,h2)
00331 if skip:
00332 self.status = SKIPED
00333 self.test_name=stat_test.name
00334 self.test_name=stat_test.name
00335 self.test_thr=stat_test.threshold
00336 self.rank = 0
00337 else:
00338 self.status=stat_test.get_status()
00339 self.rank=stat_test.get_rank()
00340 self.test_name=stat_test.name
00341 self.test_thr=stat_test.threshold
00342 self.do_pngs=do_pngs
00343 self.draw_success=draw_success or not do_pngs
00344 if ((self.status==FAIL or self.status==NULL or self.status == SKIPED or self.draw_success) and self.do_pngs):
00345 self.__make_image(h1,h2)
00346
00347
00348 def __make_img_dir(self):
00349 if not exists(self.mother_dir):
00350 makedirs(self.mother_dir)
00351
00352 def __get_img_name(self):
00353
00354
00355 self.img_name="%s/%s.png"%(self.mother_dir,self.name)
00356 self.img_name=self.img_name.replace("Run summary","")
00357 self.img_name=self.img_name.replace("/","_")
00358 self.img_name=self.img_name.strip("_")
00359
00360 return self.img_name
00361
00362 def tcanvas_slow(self,canvas):
00363
00364
00365
00366
00367 p = Process(target=print_multi_threaded, args=(canvas,self.img_name))
00368 p.start()
00369 tcanvas_print_processes.append(p)
00370 n_proc=len(tcanvas_print_processes)
00371 if n_proc>3:
00372 p_to_remove=[]
00373 for iprocess in xrange(0,n_proc):
00374 p=tcanvas_print_processes[iprocess]
00375 p.join()
00376 p_to_remove.append(iprocess)
00377
00378 adjustment=0
00379 for iprocess in p_to_remove:
00380 tcanvas_print_processes.pop(iprocess-adjustment)
00381 adjustment+=1
00382
00383 def __make_image(self,obj1,obj2):
00384 self.img_name=self.__get_img_name()
00385 if self.rank==-1:
00386 return 0
00387
00388 canvas=TCanvas(self.name,self.name,Comparison.canvas_xsize,Comparison.canvas_ysize)
00389 objs=(obj1,obj2)
00390
00391
00392 obj1.SetTitle(self.name)
00393
00394 if obj1.GetNbinsY()!=0 and not "2" in obj1.ClassName() :
00395 obj1 .SetLineWidth(2)
00396 obj2 .SetLineWidth(2)
00397
00398 obj1.SetMarkerStyle(8)
00399 obj1.SetMarkerSize(.8)
00400
00401 obj2.SetMarkerStyle(8)
00402 obj2.SetMarkerSize(.8)
00403
00404 obj1.SetMarkerColor(kBlue)
00405 obj1.SetLineColor(kBlue)
00406
00407 obj2.SetMarkerColor(kRed)
00408 obj2.SetLineColor(kRed)
00409
00410 obj1.Draw("EP")
00411
00412 obj2.Draw("HistSames")
00413
00414
00415
00416
00417
00418
00419
00420
00421 else:
00422 obj1.Draw("Colz")
00423 gPad.Update()
00424
00425
00426
00427
00428
00429
00430
00431 obj2.Draw("ColSame")
00432
00433
00434 color=kGreen+2
00435 if self.status==FAIL:
00436 print "This comparison failed %f" %self.rank
00437 color=kRed
00438 elif self.status==NULL:
00439 color=kYellow
00440 elif self.status==SKIPED:
00441 color=kBlue
00442
00443 lat_text="#scale[.7]{#color[%s]{%s: %2.2f}}" %(color,self.test_name,self.rank)
00444 lat=TLatex(.1,.91,lat_text)
00445 lat.SetNDC()
00446 lat.Draw()
00447
00448
00449 n1=obj1.GetEntries()
00450 if n1> 100000:
00451 n1="%e"%n1
00452 else:
00453 n1="%s"%n1
00454 n2=obj2.GetEntries()
00455 if n2> 100000:
00456 n2="%e"%n2
00457 else:
00458 n2="%s"%n2
00459
00460 lat_text1="#scale[.7]{#color[%s]{Entries: %s}}" %(obj1.GetLineColor(),n1)
00461 lat1=TLatex(.3,.91,lat_text1)
00462 lat1.SetNDC()
00463 lat1.Draw()
00464
00465
00466 lat_text2="#scale[.7]{#color[%s]{Entries: %s}}" %(obj2.GetLineColor(),n2)
00467 lat2=TLatex(.6,.91,lat_text2)
00468 lat2.SetNDC()
00469 lat2.Draw()
00470
00471
00472 self.tcanvas_slow(canvas)
00473
00474 def __repr__(self):
00475 return "%s , (%s=%s). IMG=%s. status=%s" %(self.name,self.test_name,self.rank,self.img_name,self.status)
00476
00477