CMS 3D CMS Logo

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