CMS 3D CMS Logo

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