CMS 3D CMS Logo

dirstructure.py
Go to the documentation of this file.
1 from __future__ import print_function
2 ################################################################################
3 # RelMon: a tool for automatic Release Comparison
4 # https://twiki.cern.ch/twiki/bin/view/CMSPublic/RelMon
5 #
6 #
7 #
8 # Danilo Piparo CERN - danilo.piparo@cern.ch
9 #
10 ################################################################################
11 
12 from array import array
13 from copy import deepcopy
14 from os import chdir,getcwd,listdir,makedirs,rmdir
15 from os.path import exists,join
16 
17 import sys
18 argv=sys.argv
19 from ROOT import *
20 sys.argv=argv
21 
22 from definitions import *
23 from utils import setTDRStyle
24 
25 
26 # Something nice and familiar
28 
29 # Do not display the canvases
30 gROOT.SetBatch(kTRUE)
31 
32 
33 #-------------------------------------------------------------------------------
34 _log_level=5
35 def logger(msg_level,message):
36  if msg_level>=_log_level:
37  print("[%s] %s" %(asctime(),message))
38 
39 #-------------------------------------------------------------------------------
40 
42  def __init__(self,name,weight=1):
43  self.name=name
44  self.weight=weight
45 
46 
47 #-------------------------------------------------------------------------------
49  def __init__(self,sample1="",sample2="",release1="",release2="",run1="",run2="",tier1=0,tier2=0):
50  self.sample1=sample1
51  self.sample2=sample2
52  self.release1=release1
53  self.release2=release2
54  self.run1=run1
55  self.run2=run2
56  self.tier1=tier1
57  self.tier2=tier2
58 
59 #-------------------------------------------------------------------------------
61  def __init__(self,name,mother_dir="",meta=CompInfo(),draw_success=False,do_pngs=False):
62  self.mother_dir=mother_dir
63  self.meta=meta
64  self.subdirs=[]
65  self.comparisons=[]
66  self.n_fails=0
67  self.n_successes=0
68  self.n_nulls=0
69  self.n_skiped = 0
70  self.n_comp_skiped = 0
71  self.n_comp_fails=0
73  self.n_comp_nulls=0
74  self.weight=0
75  self.stats_calculated=False
76  Weighted.__init__(self,name)
77  self.draw_success=draw_success
78  self.do_pngs=do_pngs
79  self.rank_histo=TH1I("rh%s"%name,"",50,-0.01,1.001)
80  self.rank_histo.SetDirectory(0)
82  self.different_histograms['file1']= {}
83  self.different_histograms['file2']= {}
84  self.filename1 = ""
85  self.filename2 = ""
86  self.n_missing_objs = 0
87  self.full_path = ""
88 
89  def is_empty(self):
90  if len(self.subdirs)==0 and len(self.comparisons)==0:
91  return True
92  return False
93 
94  def calcStats(self,make_pie=True):
95  '''Walk all subdirs and calculate weight,fails and successes.
96  Moreove propagate the sample and releases names.
97  '''
98  if self.stats_calculated:
99  return 0
100 
101  self.n_fails=0
102  self.n_successes=0
103  self.n_nulls=0
104  self.n_comp_fails=0
105  self.n_comp_successes=0
106  self.n_comp_nulls=0
107  self.weight=0
108 
109  self.n_skiped = 0
110  self.n_comp_skiped = 0
111  self.n_missing_objs = len(self.different_histograms['file1'])+len(self.different_histograms['file2'])
112  if self.n_missing_objs != 0:
113  print(" [*] Missing in %s: %s" %(self.filename1, self.different_histograms['file1']))
114  print(" [*] Missing in %s: %s" %(self.filename2, self.different_histograms['file2']))
115  # clean from empty dirs
116  self.subdirs = [subdir for subdir in self.subdirs if not subdir.is_empty()]
117 
118  for comp in self.comparisons:
119  if comp.status == SKIPED: #in case its in black list & skiped
120  self.n_skiped += 1
121  self.n_comp_skiped += 1
122  self.weight+=1
123  else: #else original code -> to check for Fails and Successes
124  self.rank_histo.Fill(comp.rank)
125  self.weight+=1
126  if comp.status == FAIL:
127  self.n_fails+=1
128  self.n_comp_fails+=1
129  elif comp.status == SUCCESS:
130  self.n_successes+=1
131  self.n_comp_successes+=1
132  else:
133  self.n_nulls+=1
134  self.n_comp_nulls+=1
135 
136  for subdir in self.subdirs:
137  subdir.mother_dir=join(self.mother_dir,self.name)
138  subdir.full_path = join(self.mother_dir,self.name).replace("/Run summary","")
139  subdir.calcStats(make_pie)
140  subdir.meta=self.meta
141  self.weight+=subdir.weight
142  self.n_fails+=subdir.n_fails
143  self.n_successes+=subdir.n_successes
144  self.n_nulls+=subdir.n_nulls
145 
146  self.n_skiped+=subdir.n_skiped
147  self.n_missing_objs += subdir.n_missing_objs
148 
149  self.rank_histo.Add(subdir.rank_histo)
150 
151  self.stats_calculated=True
152  self.full_path = join(self.mother_dir,self.name).replace("/Run summary","")
153  #if make_pie:
154  #self.__create_pie_image()
155 
156  def get_subdirs_dict(self):
157  subdirdict={}
158  for subdir in self.subdirs:
159  subdirdict[subdir.name]=subdir
160  return subdirdict
161 
162  def get_subdirs_names(self):
163  subdirnames=[]
164  for subdir in self.subdirs:
165  subdirnames.append(subdir.name)
166  return subdirnames
167 
168  def get_summary_chart_ajax(self,w=400,h=300):
169  """Emit the ajax to build a pie chart using google apis...
170  """
171  url = "https://chart.googleapis.com/chart?"
172  url+= "cht=p3" # Select the 3d chart
173  #url+= "&chl=Success|Null|Fail" # give labels
174  url+= "&chco=00FF00|FFFF00|FF0000|7A7A7A" # give colours to labels
175  url+= "&chs=%sx%s" %(w,h)
176  #url+= "&chtt=%s" %self.name
177  url+= "&chd=t:%.2f,%.2f,%.2f,%.2f"%(self.get_success_rate(),self.get_null_rate(),self.get_fail_rate(),self.get_skiped_rate())
178 
179  return url
180 
181  def print_report(self,indent="",verbose=False):
182  if len(indent)==0:
183  self.calcStats(make_pie=False)
184  # print small failure report
185  if verbose:
186  fail_comps=[comp for comp in self.comparisons if comp.status==FAIL]
187  fail_comps=sorted(fail_comps,key=lambda comp:comp.name )
188  if len(fail_comps)>0:
189  print(indent+"* %s/%s:" %(self.mother_dir,self.name))
190  for comp in fail_comps:
191  print(indent+" - %s: %s Test Failed (pval = %s) " %(comp.name,comp.test_name,comp.rank))
192  for subdir in self.subdirs:
193  subdir.print_report(indent+" ",verbose)
194 
195  if len(indent)==0:
196  print("\n%s - summary of %s tests:" %(self.name,self.weight))
197  print(" o Failiures: %.2f%% (%s/%s)" %(self.get_fail_rate(),self.n_fails,self.weight))
198  print(" o Nulls: %.2f%% (%s/%s) " %(self.get_null_rate(),self.n_nulls,self.weight))
199  print(" o Successes: %.2f%% (%s/%s) " %(self.get_success_rate(),self.n_successes,self.weight))
200  print(" o Skipped: %.2f%% (%s/%s) " %(self.get_skiped_rate(),self.n_skiped,self.weight))
201  print(" o Missing objects: %s" %(self.n_missing_objs))
202 
203  def get_skiped_rate(self):
204  if self.weight == 0: return 0
205  return 100.*self.n_skiped/self.weight
206  def get_fail_rate(self):
207  if self.weight == 0:return 0
208  return 100.*self.n_fails/self.weight
209 
210  def get_success_rate(self):
211  if self.weight == 0:return 1
212  return 100.*self.n_successes/self.weight
213 
214  def get_null_rate(self):
215  if self.weight == 0:return 0
216  return 100.*self.n_nulls/self.weight
217 
218  def __get_full_path(self):
219  #print "Mother is %s" %self.mother_dir
220  if len(self.mother_dir)==0:
221  return self.name
222  return join(self.mother_dir,self.name)
223 
224  def __create_on_disk(self):
225  if not exists(self.mother_dir) and len(self.mother_dir)!=0:
226  makedirs(self.mother_dir)
227  full_path=self.__get_full_path()
228  if not exists(full_path) and len(full_path)>0:
229  makedirs(full_path)
230 
232  return join(self.__get_full_path(),"summary_chart.png")
233 
235  self.__create_on_disk()
236  vals=[]
237  colors=[]
238  for n,col in zip((self.n_fails,self.n_nulls,self.n_successes,self.n_skiped),(kRed,kYellow,kGreen,kBlue)):
239  if n!=0:
240  vals.append(n)
241  colors.append(col)
242  valsa=array('f',vals)
243  colorsa=array('i',colors)
244  can = TCanvas("cpie","TPie test",100,100);
245  try:
246  pie = TPie("ThePie",self.name,len(vals),valsa,colorsa);
247  label_n=0
248  if self.n_fails!=0:
249  pie.SetEntryLabel(label_n, "Fail: %.1f(%i)" %(self.get_fail_rate(),self.n_fails) );
250  label_n+=1
251  if self.n_nulls!=0:
252  pie.SetEntryLabel(label_n, "Null: %.1f(%i)" %(self.get_null_rate(),self.n_nulls) );
253  label_n+=1
254  if self.n_successes!=0:
255  pie.SetEntryLabel(label_n, "Success: %.1f(%i)" %(self.get_success_rate(),self.n_successes) );
256  if self.n_skiped!=0:
257  pie.SetEntryLabel(label_n, "Skipped: %.1f(%i)" %(self.get_skiped_rate(),self.n_skiped));
258  pie.SetY(.52);
259  pie.SetAngularOffset(0.);
260  pie.SetLabelsOffset(-.3);
261  #pie.SetLabelFormat("#splitline{%val (%perc)}{%txt}");
262  pie.Draw("3d nol");
263  can.Print(self.get_summary_chart_name());
264  except:
265  print("self.name = %s" %self.name)
266  print("len(vals) = %s (vals=%s)" %(len(vals),vals))
267  print("valsa = %s" %valsa)
268  print("colorsa = %s" %colorsa)
269 
270  def prune(self,expandable_dir):
271  """Eliminate from the tree the directory the expandable ones.
272  """
273  #print "pruning %s" %self.name
274  exp_index=-1
275  counter=0
276  for subdir in self.subdirs:
277  # Eliminate any trace of the expandable path in the mother directories
278  # for depths higher than 1
279  subdir.mother_dir=subdir.mother_dir.replace("/"+expandable_dir,"")
280  if subdir.name==expandable_dir:
281  exp_index=counter
282  counter+=1
283 
284  # Did we find an expandable?
285  if exp_index>=0:
286  exp_dir=self.subdirs[exp_index]
287  for subsubdir in exp_dir.subdirs:
288  #print "*******",subsubdir.mother_dir,
289  subsubdir.mother_dir=subsubdir.mother_dir.replace("/"+expandable_dir,"")
290  while "//" in subsubdir.mother_dir:
291  print(subsubdir.mother_dir)
292  subsubdir.mother_dir=subsubdir.mother_dir.replace("//","/")
293  #print "*******",subsubdir.mother_dir
294  self.subdirs.append(subsubdir)
295 
296  for comp in exp_dir.comparisons:
297  comp.mother_dir=comp.mother_dir.replace("/"+expandable_dir,"")
298  while "//" in comp.mother_dir:
299  comp.mother_dir
300  comp.mother_dir=comp.mother_dir.replace("/")
301  if not comp in self.comparisons: #in case not to append same comparisons few times
302  self.comparisons.append(comp) # add a comparison
303  self.n_comp_fails = exp_dir.n_comp_fails #copy to-be removed directory
304  self.n_comp_nulls = exp_dir.n_comp_nulls # numbers to parent directory
305  self.n_comp_successes = exp_dir.n_comp_successes
306  self.n_comp_skiped = exp_dir.n_comp_skiped
307 
308  del self.subdirs[exp_index]
309  self.prune(expandable_dir)
310 
311  for subdir in self.subdirs:
312  subdir.prune(expandable_dir)
313 
314  def __repr__(self):
315  if self.is_empty():
316  return "%s seems to be empty. Please check!" %self.name
317  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)
318  for subdir in self.subdirs:
319  content+=" %s\n" % subdir
320  for comp in self.comparisons:
321  content+=" %s\n" % comp
322  return content
323 
324 #-------------------------------------------------------------------------------
325 from multiprocessing import Process
326 def print_multi_threaded(canvas,img_name):
327  canvas.Print(img_name)
328 
329 tcanvas_print_processes=[]
330 #-------------------------------------------------------------------------------
331 
333  canvas_xsize=500
334  canvas_ysize=400
335  def __init__(self,name,mother_dir,h1,h2,stat_test,draw_success=False,do_pngs=False, skip=False):
336  self.name=name
337  self.png_name="placeholder.png"
338  self.mother_dir=mother_dir
339  self.img_name=""
340  #self.draw_success=draw_success
341  Weighted.__init__(self,name)
342 
343  stat_test.set_operands(h1,h2)
344  if skip:
345  self.status = SKIPED
346  self.test_name=stat_test.name
347  self.test_name=stat_test.name
348  self.test_thr=stat_test.threshold
349  self.rank = 0
350  else:
351  self.status=stat_test.get_status()
352  self.rank=stat_test.get_rank()
353  self.test_name=stat_test.name
354  self.test_thr=stat_test.threshold
355  self.do_pngs=do_pngs
356  self.draw_success=draw_success or not do_pngs
357  if ((self.status==FAIL or self.status==NULL or self.status == SKIPED or self.draw_success) and self.do_pngs):
358  self.__make_image(h1,h2)
359  #self.__make_image(h1,h2)
360 
361  def __make_img_dir(self):
362  if not exists(self.mother_dir):
363  makedirs(self.mother_dir)
364 
365  def __get_img_name(self):
366  #self.__make_img_dir()
367  #print "MOTHER: ",self.mother_dir
368  self.img_name="%s/%s.png"%(self.mother_dir,self.name)
369  self.img_name=self.img_name.replace("Run summary","")
370  self.img_name=self.img_name.replace("/","_")
371  self.img_name=self.img_name.strip("_")
372  #print "IMAGE NAME: %s " %self.img_name
373  return self.img_name
374 
375  def tcanvas_slow(self,canvas):
376  #print "About to print %s" %self.img_name
377  #print_multi_threaded(canvas,self.img_name)
378  #print "-->Printed"
379 
380  p = Process(target=print_multi_threaded, args=(canvas,self.img_name))
381  p.start()
382  tcanvas_print_processes.append(p)
383  n_proc=len(tcanvas_print_processes)
384  if n_proc>3:
385  p_to_remove=[]
386  for iprocess in xrange(0,n_proc):
387  p=tcanvas_print_processes[iprocess]
388  p.join()
389  p_to_remove.append(iprocess)
390 
391  adjustment=0
392  for iprocess in p_to_remove:
393  tcanvas_print_processes.pop(iprocess-adjustment)
394  adjustment+=1
395 
396  def __make_image(self,obj1,obj2):
397  self.img_name=self.__get_img_name()
398  if self.rank==-1:
399  return 0
400 
401  canvas=TCanvas(self.name,self.name,Comparison.canvas_xsize,Comparison.canvas_ysize)
402  objs=(obj1,obj2)
403 
404  # Add some specifics for the graphs
405  obj1.SetTitle(self.name)
406 
407  if obj1.GetNbinsY()!=0 and not "2" in obj1.ClassName() :
408  obj1 .SetLineWidth(2)
409  obj2 .SetLineWidth(2)
410 
411  obj1.SetMarkerStyle(8)
412  obj1.SetMarkerSize(.8)
413 
414  obj2.SetMarkerStyle(8)
415  obj2.SetMarkerSize(.8)
416 
417  obj1.SetMarkerColor(kBlue)
418  obj1.SetLineColor(kBlue)
419 
420  obj2.SetMarkerColor(kRed)
421  obj2.SetLineColor(kRed)
422 
423  obj1.Draw("EP")
424  #Statsbox
425  obj2.Draw("HistSames")
426  #gPad.Update()
427  #if 'stats' in map(lambda o: o.GetName(),list(gPad.GetListOfPrimitives())):
428  #st = gPad.GetPrimitive("stats")
429  #st.SetY1NDC(0.575)
430  #st.SetY2NDC(0.735)
431  #st.SetLineColor(kRed)
432  #st.SetTextColor(kRed)
433  #print st
434  else:
435  obj1.Draw("Colz")
436  gPad.Update()
437  #if 'stats' in map(lambda o: o.GetName(),list(gPad.GetListOfPrimitives())):
438  #st = gPad.GetPrimitive("stats")
439  #st.SetY1NDC(0.575)
440  #st.SetY2NDC(0.735)
441  #st.SetLineColor(kRed)
442  #st.SetTextColor(kRed)
443  #print st
444  obj2.Draw("ColSame")
445 
446  # Put together the TLatex for the stat test if possible
447  color=kGreen+2 # which is green, as everybody knows
448  if self.status==FAIL:
449  print("This comparison failed %f" %self.rank)
450  color=kRed
451  elif self.status==NULL:
452  color=kYellow
453  elif self.status==SKIPED:
454  color=kBlue #check if kBlue exists ;)
455 
456  lat_text="#scale[.7]{#color[%s]{%s: %2.2f}}" %(color,self.test_name,self.rank)
457  lat=TLatex(.1,.91,lat_text)
458  lat.SetNDC()
459  lat.Draw()
460 
461  # Put also the stats together!
462  n1=obj1.GetEntries()
463  if n1> 100000:
464  n1="%e"%n1
465  else:
466  n1="%s"%n1
467  n2=obj2.GetEntries()
468  if n2> 100000:
469  n2="%e"%n2
470  else:
471  n2="%s"%n2
472 
473  lat_text1="#scale[.7]{#color[%s]{Entries: %s}}" %(obj1.GetLineColor(),n1)
474  lat1=TLatex(.3,.91,lat_text1)
475  lat1.SetNDC()
476  lat1.Draw()
477 
478 
479  lat_text2="#scale[.7]{#color[%s]{Entries: %s}}" %(obj2.GetLineColor(),n2)
480  lat2=TLatex(.6,.91,lat_text2)
481  lat2.SetNDC()
482  lat2.Draw()
483 
484 
485  self.tcanvas_slow(canvas)
486 
487  def __repr__(self):
488  return "%s , (%s=%s). IMG=%s. status=%s" %(self.name,self.test_name,self.rank,self.img_name,self.status)
489 
490 #-------------------------------------------------------------------------------
def __init__(self, name, mother_dir, h1, h2, stat_test, draw_success=False, do_pngs=False, skip=False)
def calcStats(self, make_pie=True)
Definition: dirstructure.py:94
def prune(self, expandable_dir)
def replace(string, replacements)
S & print(S &os, JobReport::InputFile const &f)
Definition: JobReport.cc:65
def __init__(self, sample1="", sample2="", release1="", release2="", run1="", run2="", tier1=0, tier2=0)
Definition: dirstructure.py:49
def print_report(self, indent="", verbose=False)
OutputIterator zip(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp)
def get_summary_chart_name(self)
def setTDRStyle()
Definition: plotscripts.py:88
def __init__(self, name, mother_dir="", meta=CompInfo(), draw_success=False, do_pngs=False)
Definition: dirstructure.py:61
def tcanvas_slow(self, canvas)
def get_summary_chart_ajax(self, w=400, h=300)
static std::string join(char **cmd)
Definition: RemoteFile.cc:18
def print_multi_threaded(canvas, img_name)
def logger(msg_level, message)
Definition: dirstructure.py:35
def __create_pie_image(self)
def __init__(self, name, weight=1)
Definition: dirstructure.py:42
def __make_image(self, obj1, obj2)