CMS 3D CMS Logo

directories2html.py
Go to the documentation of this file.
1 from __future__ import print_function
2 from __future__ import absolute_import
3 
7 
8 #
9 #
10 # Danilo Piparo CERN - danilo.piparo@cern.ch
11 #
12 
13 
14 from builtins import range
15 from os import chdir,getcwd,listdir,makedirs
16 from os.path import basename,join,exists
17 import html
18 
19 import sys
20 theargv=sys.argv
21 sys.argv=[]
22 from ROOT import TCanvas,gStyle,TH1F,TGaxis,gPad,kRed
23 sys.argv=theargv
24 
25 import os
26 import hashlib
27 import random
28 from matplotlib.colors import to_hex
29 
30 if "RELMON_SA" in os.environ:
31  from .dirstructure import Comparison,Directory
32  from .definitions import *
33  from .utils import unpickler
34 else:
35  from Utilities.RelMon.dirstructure import Comparison,Directory
36  from Utilities.RelMon.definitions import *
37  from Utilities.RelMon.utils import unpickler
38 
39 #-------------------------------------------------------------------------------
40 
41 def encode_obj_url(url):
42  for old,new in url_encode_dict.items():
43  url=url.replace(old,new)
44  return url
45 
46 def plot_size(h=250,w=200):
47  return "w=%s;h=%s" %(h,w)
48 
49 def build_obj_addr(run,sample,version,plot_path,tier):
50  slash="/"
51  obj_url="archive/%s/%s/%s/%s/" %(run,sample,version,tier)
52  obj_url+=plot_path
53  while obj_url.endswith(slash):
54  obj_url=obj_url[:-1]
55  while slash*2 in obj_url:
56  obj_url=obj_url.replace(slash*2,slash)
57  return obj_url
58 
59 def build_obj(run,sample,version,plot_path,tier):
60  obj_url="obj=%s;" %build_obj_addr(run,sample,version,plot_path,tier)
61  return encode_obj_url(obj_url)
62 
63 def fairy_url(run1,run2,sample1,sample2,version1,version2,plot_path,tier1,tier2,draw_opts="",h=250,w=200):
64  fairy_url = "%s/%s/plotfairy/overlay?" %(server,base_url)
65  fairy_url+= build_obj(run1,sample1,version1,plot_path,tier1)
66  fairy_url+= build_obj(run2,sample2,version2,plot_path,tier2)
67  if len(draw_opts)>0:
68  fairy_url+="drawopts=%s;" %draw_opts
69  fairy_url+= plot_size(h,w)
70  fairy_url += ";ref=ratiooverlay"
71  return fairy_url
72 
73 def fairy_url_single(run,sample,version,plot_path,tier,draw_opts="",h=250,w=200):
74  fairy_url = "%s/%s/plotfairy/" %(server,base_url)
75  fairy_url+=build_obj_addr(run,sample,version,plot_path,tier)
76  fairy_url+= "?%s"%plot_size(h,w)
77  if len(draw_opts)>0:
78  fairy_url+="drawopts=%s;" %draw_opts
79  return fairy_url
80 
81 #-------------------------------------------------------------------------------
82 style_location="/cms-service-reldqm"
83 def get_page_header(directory=None, standalone=False, additional_header=""):
84  style_location="/cms-service-reldqm"
85  if standalone:
86  style_location = "https://raw.githubusercontent.com/cms-PdmV/RelMonService2/77c534ec93401ca5de222ac62a6422f02389dafc/report_website/" #RelMonService2
87  javascripts=''
88  style=''
89  tablestyle=''
90  thead_h = 400
91  wrapper_h = 1500
92  if directory!=None and len(directory.comparisons)>0:
93  meta=directory.meta
94  style='img.fail {border:1px solid #ff0000;}\n'+\
95  'img.succes {border:1px solid #00ff00;}\n'+\
96  'img.null {border:1px solid #ffff00;}\n'+\
97  'img.skiped {border:1px solid #7a7a7a;}\n'+\
98  'a.black_link:link {color: #333333}\n'+\
99  'a.black_link:hover {color: #737373}\n'+\
100  'a.black_link:visited {color: #333333}\n'+\
101  'a.black_link:active {color: #333333}\n'
102 
103 
104  wrapper_h = min(thead_h + (70 * len(directory.comparisons)),1800)
105 
106  tablestyle = '\n.wrapper { overflow: auto; height: %dpx;} \n'%(wrapper_h)
107  tablestyle += 'table { position: relative; border-collapse: separate; border-spacing: 0;} \n'
108  tablestyle += 'table { position: relative; border-collapse: separate; border-spacing: 0;} \n'
109  tablestyle += 'table th, table td { width: 50px; padding: 5px; background-color: white;} \n'
110  tablestyle += 'table th { position: sticky; top: 0; z-index: 2; height: %dpx;} \n'%(thead_h)
111  tablestyle += 'table th:nth-child(1) { left:0; z-index:3;} \n'
112  tablestyle += '.sticky-col { position: sticky; background-color: #C9FFD1 ; width: 200px; left:0}\n'
113  tablestyle += '.center_head { position: absolute; top: 50%; left: 50%;} \n'
114  tablestyle += '.vertical_head {top: 60%; -webkit-transform: translateX(-50%) translateY(-50%) rotate(-90deg); -moz-transform: translateX(-50%) translateY(-50%) rotate(-90deg);} \n'
115  javascripts=""
116 
117 
118 
119  html='<html>'+\
120  '<head>'+\
121  '<title>RelMon Summary</title>'+\
122  '<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>' + \
123  '<link rel="stylesheet" href="%s/screen.css" type="text/css" media="screen, projection">'%style_location+\
124  '<link rel="stylesheet" href="%s/print.css" type="text/css" media="print">'%style_location+\
125  '<link rel="stylesheet" href="%s/fancy-type-screen.css" type="text/css" media="screen, projection">'%style_location+\
126  '<style type="text/css">'+\
127  '.rotation {display: block;-webkit-transform: rotate(-90deg);-moz-transform: rotate(-90deg); }'+\
128  '%s'%style+\
129  '%s'%tablestyle +\
130  '</style>'+\
131  '%s'%javascripts+\
132  '%s'%additional_header+\
133  '</head>'+\
134  '<body>'+\
135  '<div class="container">'
136 
137  return html
138 
139 #-------------------------------------------------------------------------------
140 
142  return '</div></body></html>'
143 
144 #-------------------------------------------------------------------------------
145 
146 def get_title_section(directory, hashing_flag, standalone, depth=2):
147 
148  mother_name=basename(directory.mother_dir)
149  mother_file_name=""
150  if depth==1:
151  mother_file_name="../RelMonSummary.html"
152  if mother_name!="":
153  mother_file_name="%s.html" %(hash_name(mother_name, hashing_flag))
154  elif depth==2:
155  mother_file_name="RelMonSummary.html"
156  #mother_file_name="%s.html" %(hash_name("RelMonSummary", hashing_flag))
157  if mother_name!="":
158  mother_file_name="%s.html" %(hash_name(mother_name, hashing_flag))
159  else:
160  if hashing_flag:
161  files = directory.mother_dir.split("/")
162  if len(files) != 1:
163  dir_name = files[-2]+files[-1]
164  else:
165  dir_name = files[-1]
166  dir_name = directory.mother_dir
167  mother_file_name="%s.html" %(hash_name(dir_name, hashing_flag))
168  else:
169  mother_file_name="%s.html" %directory.mother_dir.replace("/","_")
170  mother_file_name=mother_file_name.strip("_")
171 
172  link_to_mother='<a href="%s">..</a>' %mother_file_name
173  html= '<div class="span-20">'+\
174  '<h1>%s</h1>'%directory.name+\
175  '</div>'+\
176  '<div class="span-1">'+\
177  '<h1>%s</h1>'%link_to_mother+\
178  '</div>'+\
179  '<div class="span-3 last">'+\
180  '<img src="%s" class="top right" width="54" hight="54">'%cms_logo_url+\
181  '</div>'+\
182  '<hr>'
183  if len(mother_name)>0:
184  html+='<h2 class="alt">%s</h2>'% directory.mother_dir+\
185  '<hr>'
186  return html
187 
188 #-------------------------------------------------------------------------------
189 def get_dir_stats(directory):
190  html='<p><span class="caps alt">%s comparisons:</span></p>'%directory.weight
191  html+='<ul>'
192  if directory.n_successes>0:
193  html+='<li><span class="caps">Success: %.1f%% (%s)</span></li>'%(directory.get_success_rate(),directory.n_successes)
194  if directory.n_nulls>0:
195  html+='<li><span class="caps">Null: %.1f%% (%s)</span></li>'%(directory.get_null_rate(),directory.n_nulls)
196  if directory.n_fails>0:
197  html+='<li><span class="caps">Fail: %.1f%% (%s)</span></li>'%(directory.get_fail_rate(),directory.n_fails)
198  if directory.n_skiped>0:
199  html+='<li><span class="caps">Skipped: %.1f%% (%s)</span></li>'%(directory.get_skiped_rate(),directory.n_skiped)
200  if directory.n_missing_objs>0:
201  html+='<li><span class="caps">Unpaired: %s</span></li>'%(directory.n_missing_objs)
202  html+='</ul>'
203  return html
204 
205 #-------------------------------------------------------------------------------
206 
207 def get_subdirs_section(directory, hashing_flag):
208  if len(directory.subdirs)==0:
209  return ""
210  html= '<div class="span-20 colborder">'
211  html+='<h2 class="alt">Sub-Directories</h2>'
212  # sort subdirs according to the number of fails and number of nulls and then alphabveticaly
213  # so reverse :)
214  sorted_subdirs= sorted(directory.subdirs, key= lambda subdir: subdir.name)
215  sorted_subdirs= sorted(sorted_subdirs, key= lambda subdir: subdir.n_nulls, reverse=True)
216  sorted_subdirs= sorted(sorted_subdirs, key= lambda subdir: subdir.n_fails, reverse=True)
217  for subdir in sorted_subdirs:
218  name=subdir.name
219  if hashing_flag:
220  link = "%s.html" %(hash_name(join(directory.full_path,name), hashing_flag)) #do hash with directory name + subdirname as single name hashing might get problems with same subdirs name in different parent dirs.
221  else:
222  link="%s_%s_%s.html" %(directory.mother_dir.replace("/","_"),directory.name.replace("/","_"),name)
223  link=link.strip("_")
224  html+='<div class="span-4 prepend-2 colborder">'
225  html+='<h3>%s</h3>'%name
226  html+='</div>'
227 
228  html+='<div class="span-7">'
229  html+=get_dir_stats(subdir)
230  html+='</div>'
231 
232  html+='<div class="span-6 last">'
233  html+= subdir.get_piechart_js(120,link)
234  html+='</div>'
235 
236  html+='<hr>'
237  return html+'</div>'
238 
239 
240 #-------------------------------------------------------------------------------
241 
242 def get_summary_section(directory,matrix_page=True):
243 
244  # Hack find the first comparison and fill test and threshold
245  # shall this be put in meta?
246  test_name=""
247  test_threshold=0
248  for comparison in directory.comparisons:
249  test_name=comparison.test_name
250  test_threshold=comparison.test_thr
251  break
252  if len(test_name)==0:
253  for subdir in directory.subdirs:
254  for comparison in subdir.comparisons:
255  test_name=comparison.test_name
256  test_threshold=comparison.test_thr
257  break
258  if len(test_name)!=0:break
259  if len(test_name)==0:
260  for subsubdir in subdir.subdirs:
261  for comparison in subsubdir.comparisons:
262  test_name=comparison.test_name
263  test_threshold=comparison.test_thr
264  break
265  if len(test_name)!=0:break
266  if len(test_name)==0:
267  for subsubsubdir in subsubdir.subdirs:
268  for comparison in subsubsubdir.comparisons:
269  test_name=comparison.test_name
270  test_threshold=comparison.test_thr
271  break
272  if len(test_name)!=0:break
273 
274 
275  meta=directory.meta
276 
277  html= '<div class="span-6">'+\
278  '<h3>Summary</h3>'
279  html+=get_dir_stats(directory)
280  html+='<a href="%s/%s/start?runnr=%s;dataset=/%s/%s/DQMIO;sampletype=offline_data;filter=all;referencepos=on-side;referenceshow=all;referencenorm=True;referenceobj1=other:%s:/%s/%s/DQMIO:;referenceobj2=none;referenceobj3=none;referenceobj4=none;search=;striptype=object;stripruns=;stripaxis=run;stripomit=none;workspace=Everything;size=M;focus=;zoom=no;">To the DQM GUI...</a>' %(server,base_url,meta.run1,meta.sample1,meta.release1,meta.run2,meta.sample2,meta.release2)
281  html+='</div>'
282 
283  html+='<div class="span-7 colborder">'+\
284  '%s'%(directory.get_piechart_js(150)) +\
285  '</div>'+\
286  '<div class="span-9 last">'
287  if matrix_page:
288  html+='<h3>Sample:</h3>'+\
289  '<p class="caps">%s</p>'%meta.sample1+\
290  '<h3>Run1 and Run2:</h3>'+\
291  '<p class="caps">%s - %s</p>'%(meta.run1,meta.run2)
292  html+='<h3>Releases:</h3>'+\
293  '<ul><li><p>%s</p></li><li><p>%s</p></li></ul>'%(meta.release1,meta.release2)+\
294  '<h3>Statistical Test (Pvalue threshold):</h3>'+\
295  '<ul><li><p class="caps">%s (%s)</p></li></ul>'%(test_name,test_threshold)+\
296  '</div>'+\
297  '<hr>'
298  return html
299 
300 #-------------------------------------------------------------------------------
301 
302 def get_comparisons(category,directory):
303  """Prepare the comparisons between histograms and organise them in the page.
304  Moreover create separate pages with the overlay and the single plots.
305  """
306  counter=1
307  tot_counter=1
308 
309  # get the right ones
310  comparisons= [comp for comp in directory.comparisons if comp.status == cat_states[category]]
311  n_comparisons=len(comparisons)
312 
313  is_reverse=True
314  if category == FAIL:
315  is_reverse=False
316  comparisons=sorted(comparisons, key=lambda comp:comp.rank, reverse=is_reverse)
317 
318 
319  dir_abs_path="%s/%s/" %(directory.mother_dir,directory.name)
320  html_comparisons=""
321  for comparison in comparisons:
322  plot_name=comparison.img_name
323  if "http://" not in plot_name:
324  plot_name= basename(comparison.img_name)
325  class_type="colborder"
326  if counter==3 or tot_counter==n_comparisons:
327  class_type=" colborder last"
328  comp_abs_path="%s/%s" %(dir_abs_path,comparison.name)
329 
330 
331  if directory.do_pngs:
332  png_link=comparison.img_name
333  html_comparisons+='<div class="span-6 %s"><p>%s</p>' %(class_type,comparison.name)+\
334  '<p class="alt">%s: %.2E</p>' %(comparison.test_name,comparison.rank)+\
335  '<a href="%s"><img src="%s" width="250" height="200" class="top center %s"></a></div>'%(png_link,png_link,cat_classes[category])
336  else:
337  big_fairy=fairy_url(directory.meta.run1,
338  directory.meta.run2,
339  directory.meta.sample1,
340  directory.meta.sample2,
341  directory.meta.release1,
342  directory.meta.release2,
343  comp_abs_path,
344  directory.meta.tier1,
345  directory.meta.tier2,
346  "",600,600)
347  small_fairy=fairy_url(directory.meta.run1,
348  directory.meta.run2,
349  directory.meta.sample1,
350  directory.meta.sample2,
351  directory.meta.release1,
352  directory.meta.release2,
353  comp_abs_path,
354  directory.meta.tier1,
355  directory.meta.tier2)
356 
357  single_fairy1=fairy_url_single(directory.meta.run1,
358  directory.meta.sample1,
359  directory.meta.release1,
360  comp_abs_path,
361  directory.meta.tier1,
362  "",500,500)
363  single_fairy2=fairy_url_single(directory.meta.run2,
364  directory.meta.sample2,
365  directory.meta.release2,
366  comp_abs_path,
367  directory.meta.tier2,
368  "",500,500)
369 
370  html_comparisons+='<div class="span-6 %s"><p>%s</p>' %(class_type,comparison.name)+\
371  '<p class="alt">%s: %.2E</p>' %(comparison.test_name,comparison.rank)+\
372  '<div><a class="black_link" href="%s">%s</a></div>'%(single_fairy1,directory.meta.release1)+\
373  '<div><a href="%s">%s</a></div>'%(single_fairy2,directory.meta.release2)+\
374  '<a href="%s"><img src="%s" class="top center %s"></a></div>'%(big_fairy,small_fairy,cat_classes[category])
375 
376  if counter==3:
377  html_comparisons+="<hr>"
378  counter=0
379  counter+=1
380  tot_counter+=1
381 
382  if len(html_comparisons)!=0:
383  html='<div class="span-20"><h2 class="alt">%s Comparisons</h2></div>' %cat_names[category]
384  html+=html_comparisons
385  html+='<hr>'
386  return html
387  return ""
388 
389 #-------------------------------------------------------------------------------
390 
391 def get_rank_section(directory):
392 # do Rank histo png
393  imgname="RankSummary.png"
394  gStyle.SetPadTickY(0)
395  c=TCanvas("ranks","ranks",500,400)
396  #gStyle.SetOptStat(0)
397  c.cd()
398 
399  h=directory.rank_histo
400  rank_histof=TH1F(h.GetName(),"",h.GetNbinsX(),h.GetXaxis().GetXmin(),h.GetXaxis().GetXmax())
401  rank_histof.SetLineWidth(2)
402  for i in range(0,h.GetNbinsX()+1):
403  rank_histof.SetBinContent(i,h.GetBinContent(i))
404  h.SetTitle("Ranks Summary;Rank;Frequency")
405  h.Draw("Hist")
406  c.Update()
407  rank_histof.ComputeIntegral()
408  integral = rank_histof.GetIntegral()
409  rank_histof.SetContent(integral)
410 
411  rightmax = 1.1*rank_histof.GetMaximum()
412  scale = gPad.GetUymax()/rightmax
413  rank_histof.SetLineColor(kRed)
414  rank_histof.Scale(scale)
415  rank_histof.Draw("same")
416 
417  #draw an axis on the right side
418  axis = TGaxis(gPad.GetUxmax(),gPad.GetUymin(),gPad.GetUxmax(), gPad.GetUymax(),0,rightmax,510,"+L")
419  axis.SetTitle("Cumulative")
420  axis.SetTitleColor(kRed)
421  axis.SetLineColor(kRed)
422  axis.SetLabelColor(kRed)
423  axis.Draw()
424 
425  rank_histof.Draw("Same");
426 
427 
428  c.Print(imgname)
429 
430  page_html='<div class="span-20"><h2 class="alt"><a name="rank_summary">Ranks Summary</a></h2>'
431  page_html+='<div class="span-19"><img src="%s"></div>' %imgname
432  page_html+='</div> <a href="#top">Top...</a><hr>'
433 
434  return page_html
435 
436 #-------------------------------------------------------------------------------
437 
438 #-------------------------------------------------------------------------------
440  """Method to get missing objects from directory: in case histogram/directory was in one ROOT file but not in other
441  """
442  page_html = "Unpaired in %s</br>"%(directory.filename1)
443  for elem in directory.different_histograms['file1']:
444  page_html += "name: %s type:%s </br>"%(elem,directory.different_histograms['file1'][elem])
445  page_html +="</br>"
446  page_html += "Unpaired in %s</br>"%(directory.filename2)
447  for elem in directory.different_histograms['file2']:
448  page_html += "name: %s type:%s </br>"%(elem,directory.different_histograms['file2'][elem])
449  return page_html
450 #-------------------------------------------------------------------------------
451 
452 def directory2html(directory, hashing, standalone, depth=0):
453  """Converts a directory tree into html pages, very nice ones.
454  """
455  #print "d2html: depth", str(depth)," dir ",directory.name
456  depth+=1
457  #old_cwd=getcwd()
458  #if not exists(directory.name) and len(directory.name)>0:
459  #makedirs(directory.name)
460 
461  #if len(directory.name)>0:
462  #chdir(directory.name)
463 
464  for subdir in directory.subdirs:
465  directory2html(subdir,hashing,standalone, depth)
466 
467  page_html=get_page_header(directory, standalone)+\
468  get_title_section(directory,hashing, standalone, depth)+\
469  get_summary_section(directory)+\
470  get_subdirs_section(directory, hashing)
471 
472  for do_cat,cat in ((directory.n_comp_fails >0,FAIL ),
473  (directory.n_comp_nulls >0,NULL ),
474 
475  (directory.n_comp_successes >0 and directory.draw_success,SUCCESS ),
476  (directory.n_comp_skiped >0,SKIPED)):
477  if do_cat:
478  page_html+=get_comparisons(cat,directory)
479 
480  if (len(directory.different_histograms['file1']) >0) or (len(directory.different_histograms['file2']) >0):
481  page_html += get_missing_objs_section(directory)
482 
483  # Distribution of ranks
484 
485  if depth==1:
486  page_html+=get_rank_section(directory)
487 
488 
489  page_html+=get_page_footer()
490 
491  page_name=directory.name
492 
493  if len(page_name)==0:
494  page_name="RelMonSummary"
495  if hashing:
496  if page_name != "RelMonSummary":
497  #print " ## oFile path: %s"%(join(directory.full_path))
498  #print " ## oFile hash: %s"%(hash_name(join(directory.full_path), hashing))
499  ofilename = "%s.html" %(hash_name(join(directory.full_path), hashing)) #as links is generated: parentdi+subdir; we split and get the last parent dir
500  else:
501  ofilename = "RelMonSummary.html"
502  else:
503  ofilename="%s_%s.html" %(directory.mother_dir.replace("/","_"),page_name)
504  ofilename=ofilename.strip("_")
505  #print "Writing on %s" %ofilename
506  ofile=open(ofilename,"w")
507  ofile.write(page_html)
508  ofile.close()
509 
510  #chdir(old_cwd)
511 
512 def build_gauge_js(rate,w=100,minrate=.80,add_rate=False):
513 
514  color = to_hex(gauge_cmap((rate-minrate)/(1.0-minrate)))
515  font_size = int(w/9)
516  gauge_max = 1. - rate
517 
518  name = random.getrandbits(64) # just a random has for the canvas
519  html = ""
520  html += '<canvas id="%s" style="width:100%%;max-width:%d"></canvas>'%(name,w)
521 
522  # "gauge" chart
523  html += '<script> new Chart("%s",'%(name)
524  html += '{ type: "doughnut",'
525 
526  # data
527  html += 'data: {'
528  html += 'labels: ["Success", "Failure"],'
529  html += 'datasets: [{ backgroundColor: ["%s", "#C7C7C7"],'%(color)
530  html += 'data: [%f,%f]}] },'%(rate,gauge_max)
531 
532  #options
533  html += 'options: { responsive: true, rotation: -3.1415926536, circumference: 3.1415926536 ,'
534  html += ' legend: { display: false }, tooltips: {enabled: false}, hover: {mode: null}},'
535  html += '}); </script>'
536  if add_rate:
537  html += '<div style="width: 100%%; position: relative; left: %d; margin-top: -%dpx; font-align: center">'%(int(2*w/7),font_size)
538  html += '<span style="color: %s; font-family: courier; font-size: %dpx;">%.2f%%</span></div>'%(color,font_size,rate*100.)
539 
540  return html
541 #-------------------------------------------------------------------------------
542 
543 def get_aggr_pairs_info(dir_dict,the_aggr_pairs=[]):
544  # Let's make a summary for an overview in categories act on the global dir
545  aggr_pairs_info=[]#(name,{directories names:{nsucc: nsucc,weight:weight}},weight,success_rate)
546 
547  list_of_names=[]
548  if the_aggr_pairs==[]:
549  for samplename,sampledir in dir_dict.items():
550  for subsysdirname in sorted(sampledir.get_subdirs_dict().keys()):
551  if not subsysdirname in list_of_names:
552  list_of_names.append(subsysdirname)
553  the_aggr_pairs.append((subsysdirname,[subsysdirname]))
554 
555  #print the_aggr_pairs
556  for cat_name, subdir_list in the_aggr_pairs:
557  total_successes=0.
558  total_directory_successes=0
559  total_weight=0.
560  present_subdirs={}
561  total_ndirs=0
562  # Loop on samples
563  for dirname, sampledir in dir_dict.items():
564  # Loop on directories
565  for subdirname,subdir in sampledir.get_subdirs_dict().items():
566  if subdirname in subdir_list:
567  nsucc=subdir.n_successes
568  total_successes+=nsucc
569  weight=subdir.weight
570  total_weight+=weight
571  total_ndirs+=1
572 
573  total_directory_successes+= float(nsucc)/weight
574  if subdirname in present_subdirs:
575  this_dir_dict=present_subdirs[subdirname]
576  this_dir_dict["nsucc"]+=nsucc
577  this_dir_dict["weight"]+=weight
578  else:
579  present_subdirs[subdirname]={"nsucc":nsucc,"weight":weight}
580  # Make it usable also for subdirectories
581  for subsubdirname,subsubdir in subdir.get_subdirs_dict().items():
582  for pathname in [name for name in subdir_list if "/" in name]:
583  selected_subdirname,selected_subsubdirname = pathname.split("/")
584  if selected_subdirname == subdirname and selected_subsubdirname==subsubdirname:
585  #print "Studying directory ",subsubdirname," in directory ",subdirname
586  nsucc=subsubdir.n_successes
587  total_successes+=nsucc
588  weight=subsubdir.weight
589  total_weight+=weight
590  total_ndirs+=1
591  total_directory_successes+= float(nsucc)/weight
592 
593  if subsubdirname in present_subdirs:
594  this_dir_dict=present_subdirs[subsubdirname]
595  this_dir_dict["nsucc"]+=nsucc
596  this_dir_dict["weight"]+=weight
597  else:
598  present_subdirs[subsubdirname]={"nsucc":nsucc,"weight":weight}
599 
600  if total_ndirs == 0:
601  print("No directory of the category %s is present in the samples: skipping." %cat_name)
602  continue
603 
604  average_success_rate=total_directory_successes/(total_ndirs)
605  aggr_pairs_info.append((cat_name,present_subdirs,total_weight,average_success_rate))
606 
607  return aggr_pairs_info
608 
609 #-------------------------------------------------------------------------------
610 
611 def make_categories_summary(dir_dict,aggregation_rules):
612 
613  aggr_pairs_info= get_aggr_pairs_info(dir_dict,aggregation_rules)
614 
615  #print aggr_pairs_info
616 
617  # Now Let's build the HTML
618 
619  html= '<div class="span-20 colborder">'
620  html+='<h2 class="alt"><a name="categories">Categories:</a></h2>'
621 
622  for cat_name,present_subdirs,total_weight,average_success_rate in aggr_pairs_info:
623  #print cat_name,present_subdirs,total_weight,average_success_rate
624  html+='<div class="span-3 prepend-0 colborder">'
625  html+='<h3>%s</h3>'%cat_name
626  html+='<div><span class="alt">Avg. Success rate:</span></div>'
627  html+='<div><span class="alt">%2.1f%%</span></div>'%(average_success_rate*100)
628  html+='</div>'
629  html+='<div class="span-9">'
630 
631  html+='<div><p><span class="caps alt">DQM Directories (%i comparisons):</span></p></div>' %total_weight
632  html+='<div><p><span class="alt">name: succ. rate - rel. weight</span></p></div>'
633  html+='<ul>'
634  for subdirname in sorted(present_subdirs.keys()):
635  this_dir_dict=present_subdirs[subdirname]
636  nsucc=this_dir_dict["nsucc"]
637  weight=this_dir_dict["weight"]
638  html+='<li><span class="caps">%s: %2.1f%% - %2.1f%%</span></li>'%(subdirname,100*float(nsucc)/weight,100*float(weight)/total_weight)
639  html+='</ul>'
640  html+='</div>'
641 
642  html+='<div class="span-6 last">'
643  html+=build_gauge_js(average_success_rate,add_rate=True)
644  html+='</div>'
645 
646  html+='<hr>'
647  return html+'<br><a href="#top">Top...</a> </div><hr>'
648 
649  #-------------------------------------------------------------------------------
650 
651 def make_twiki_table(dir_dict,aggregation_rules):
652 
653  # decide the release
654  meta= list(dir_dict.items())[0][1].meta
655  releases=sorted([meta.release1,meta.release2])
656  latest_release=releases[1].split("-")[0]
657 
658 
659  aggr_pairs_info= get_aggr_pairs_info(dir_dict,aggregation_rules)
660 
661  # Now Let's build the HTML
662 
663  html= '<div class="span-20 colborder">'
664  html+='<h2 class="alt"><a name="twiki_table">Twiki snipppet for release managers</a></h2>'
665  html+='<div>| Release | Comparison |'
666  for cat_name,present_subdirs,total_weight,average_success_rate in aggr_pairs_info:
667  html+=cat_name
668  html+=" | "
669  html+='</div>'
670 
671  html+='<div>| %s | %%ICON{arrowdot}%% | '%latest_release
672 
673  # Now add all the line with small gauges
674 
675  for cat_name,present_subdirs,total_weight,average_success_rate in aggr_pairs_info:
676  #print cat_name,present_subdirs,total_weight,average_success_rate
677  html+=build_gauge_js(average_success_rate,w=40)
678  html+=" | "
679 
680  html+='</div> <a href="#top">Top...</a>'
681  html+='<hr>'
682  return html+'</div>'
683 
684 #-------------------------------------------------------------------------------
685 
686 def get_pie_tooltip(directory):
687  tooltip="%s\nS:%2.1f%% N:%2.1f%% F:%2.1f%% Sk:%2.1f%%" %(directory.name,directory.get_success_rate(),directory.get_null_rate(),directory.get_fail_rate(),directory.get_skiped_rate())
688  return tooltip
689 
690 #-------------------------------------------------------------------------------
691 
692 def make_barchart_summary(dir_dict,name="the_chart",title="DQM directory",the_aggr_pairs=[]):
693 
694  aggr_pairs_info= get_aggr_pairs_info(dir_dict,the_aggr_pairs)
695 
696  script="""
697  <script type="text/javascript" src="https://www.google.com/jsapi"></script>
698  <script type="text/javascript">
699  google.load("visualization", "1", {packages:["corechart"]});
700  google.setOnLoadCallback(drawChart);
701  function drawChart() {
702  var data = new google.visualization.DataTable();
703  data.addColumn('string', 'DQM Directory');
704  data.addColumn('number', 'Success Rate');
705  """
706  script+="data.addRows(%i);\n"%len(aggr_pairs_info)
707  counter=0
708  for subsystname,present_directories,weight,success_rate in aggr_pairs_info:
709  #print subsystname,present_directories
710  script+="data.setValue(%i, 0, '%s');\n"%(counter,subsystname)
711  script+="data.setValue(%i, 1, %2.2f);\n"%(counter,success_rate)
712  counter+=1
713  script+="""
714  var chart = new google.visualization.BarChart(document.getElementById('%s'));
715  chart.draw(data, {width: 1024, height: %i, title: 'Success Rate',
716  vAxis: {title: '%s', titleTextStyle: {color: 'red'},textStyle: {fontSize: 14}}
717  });
718  }
719  </script>
720  """%(name,35*counter,title)
721  return script
722 
723 
724 #-------------------------------------------------------------------------------
725 
726 def make_summary_table(indir,aggregation_rules,aggregation_rules_twiki, hashing_flag, standalone_flag):
727  """Create a table, with as rows the directories and as columns the samples.
728  Each box in the table will contain a pie chart linking to the directory.
729  """
730  #aggregation_rules={}
731  #aggregation_rules_twiki={}
732 
733  chdir(indir)
734  if os.path.isabs(indir):
735  title = basename(indir)
736  else:
737  title=indir
738  title=title.strip(".")
739  title=title.strip("/")
740 
741 
742  # Get the list of pickles
743  sample_pkls=[name for name in listdir("./") if name.endswith(".pkl")]
744 
745  # Load directories, build a list of all first level subdirs
746  dir_unpicklers=[]
747  n_unpicklers=0
748  for sample_pkl in sample_pkls:
749  dir_unpickler=unpickler(sample_pkl)
750  dir_unpickler.start()
751  n_unpicklers+=1
752  dir_unpicklers.append(dir_unpickler)
753  if n_unpicklers>=1: #pickleing is very expensive. Do not overload cpu
754  n_unpicklers=0
755  for dir_unpickler in dir_unpicklers:
756  dir_unpickler.join()
757 
758  dir_dict={}
759 
760  # create a fake global directory
761  global_dir=Directory("global","")
762  for dir_unpickler in dir_unpicklers:
763  dir_unpickler.join()
764  directory=dir_unpickler.directory
765  #directory.prune("Run summary")
766  #directory.calcStats()
767  global_dir.meta=directory.meta
768  dir_dict[dir_unpickler.filename.replace(".pkl","")]=directory
769  global_dir.subdirs.append(directory)
770 
771  global_dir.calcStats()
772 
773  directories_barchart=make_barchart_summary(dir_dict,'dir_chart',"DQM Directory")
774  categories_barchart=make_barchart_summary(dir_dict,'cat_chart','Category',aggregation_rules)
775 
776  page_html = get_page_header(standalone=standalone_flag, additional_header=directories_barchart+categories_barchart)
777  rel1=""
778  rel2=""
779  try:
780  rel1,rel2=title.split("VS")
781  except:
782  rel1=global_dir.meta.release1.split("-")[0]
783  rel2=global_dir.meta.release2.split("-")[0]
784  global_dir.meta.release1=rel1
785  global_dir.meta.release2=rel2
786 
787  # union of all subdirs names
788  all_subdirs=[]
789  for directory in dir_dict.values():
790  for subdir_name in directory.get_subdirs_names():
791  all_subdirs.append(subdir_name)
792  all_subdirs=sorted(list(set(all_subdirs)))
793 
794  #print " $$ all_subdirs: %s" %(all_subdirs)
795 
796  # Get The title
797  page_html+= '<div class="span-20">'+\
798  '<h2><a name="top" href="https://twiki.cern.ch/twiki/bin/view/CMSPublic/RelMon">RelMon</a> Global Report: %s</h2>'%title+\
799  '</div>'+\
800  '<div class="span-1">'+\
801  '<h2><a href="%s">main...</a></h2>' %relmon_mainpage+\
802  '</div>'+\
803  '<hr>'
804  page_html+='<div class="span-24"><p></p></div>\n'*3
805 
806  # Get The summary section
807  page_html+= get_summary_section(global_dir,False)
808 
809  # Make the anchor sections
810  page_html+= '<div class="span-24">'
811  page_html+= '<div class="span-20 colborder"><h2 class="alt">Sections:</h2>'+\
812  '<ul>'+\
813  '<li><a href="#summary_barchart">Summary Barchart</a></li>'+\
814  '<li><a href="#categories">Categories</a></li>'+\
815  '<li><a href="#detailed_barchart">Detailed Barchart</a></li>'+\
816  '<li><a href="#summary_table">Summary Table</a></li>'+\
817  '<li><a href="#rank_summary">Ranks Summary</a></li>'+\
818  '<li><a href="#twiki_table">Twiki Table</a></li>'+\
819  '</ul>'+\
820  '</div><hr>'
821 
822 
823  # Make the CategoriesBar chart
824  page_html+='<div class="span-24"><h2 class="alt"><a name="summary_barchart">Summary Barchart</a></h2></div>'
825  page_html+='<div id="cat_chart"></div> <a href="#top">Top...</a><hr>'
826 
827  # Make the gauges per categories
828  page_html+=make_categories_summary(dir_dict,aggregation_rules)
829 
830  # Make the Directories chart
831  page_html+='<div id="dir_chart"></div> <a href="#top">Top...</a><hr>'
832 
833  # Barbarian vertical space. Suggestions are welcome
834  for i in range(2):
835  page_html+='<div class="span-24"><p></p></div>\n'
836 
837 
838  # Prepare the table
839  page_html+='<div class="span-24"><h2 class="alt"><a name="summary_table">Summary Table</a></h2> <h4> <span class="alt"> (scrollable) </span> </h4> </div>'
840 
841  div_width= min(len(dir_dict.keys()) * 70 + 500,1500) #80 px per column + 200 for the first column
842  page_html+='<div class="wrapper" style = "width: %dpx;">'%(div_width)
843  page_html+="""
844  <table>
845  <thead>
846  <tr>
847  <th> <p class = "vertical_head center_head"></p> </th>
848  """
849 
850  # First row with samples
851  page_html+="""
852  <th> <p class = "vertical_head center_head">Summary</p></th>"""
853 
854  sorted_samples=sorted(dir_dict.keys())
855  for sample in sorted_samples:
856  if "_" in sample and "Data" not in sample:
857  sample_nick="_".join(sample.split("X_")[0].split("_")[:-1])
858  # Cleaning for MC: just the fragment
859  elif "Data" in sample and "RelVal" in sample:
860  sample_nick = "".join([sample.split("_")[0],sample.split("RelVal")[-1]])
861  # Cleaning for Data: PD + Era + Run
862  else:
863  sample_nick = sample
864 
865  page_html+="""
866  <th> <p class = "vertical_head center_head">%s</th></p>"""%sample_nick
867  page_html+="</tr> \n </thead> \n </tbody> \n"
868 
869 
870  # FIRST ROW
871  # Now the summaries at the beginning of the table
872  page_html+="<tr>"
873  page_html+='<td class="sticky-col">'
874 
875  page_html+='<b>Summary</b></td>'
876  page_html+='<td><div class="span-1"> %s </div></td>'%(global_dir.get_piechart_js(50))
877  for sample in sorted_samples:
878  col=dir_dict[sample]
879  # check if the directory was a top one or not
880  summary_page_name="RelMonSummary.html"
881  if col.name!="":
882  summary_page_name=hash_name(col.name, hashing_flag)+".html"
883  title = get_pie_tooltip(col)
884  chart = col.get_piechart_js(50,sample+"/"+summary_page_name)
885  page_html+='<td>'
886  page_html+='%s </a></td>' %(chart)
887  page_html+="</tr>"
888 
889  # Now the content
890  for subdir_name in all_subdirs:
891 
892  page_html+=' <tr>\n'
893  page_html+=' <td class="sticky-col" style="font-weight:bold;">%s</td>\n' %subdir_name
894 
895  row_summary=Directory("row_summary","")
896  sample_counter=0
897  n_samples=len(sorted_samples)
898 
899  for sample in sorted_samples:
900  subdirs_dict=directory.get_subdirs_dict()
901  directory=dir_dict[sample]
902  dir_is_there=subdir_name in subdirs_dict
903  if dir_is_there:
904  row_summary.subdirs.append(subdirs_dict[subdir_name])
905 
906  # one first row for the summary!
907  row_summary.calcStats()
908  title = get_pie_tooltip(col)
909  chart = row_summary.get_piechart_js(50)
910  page_html+='<td><div>'#<div class="span-1">'
911  page_html+= chart + '</div></td>'
912 
913  for sample in sorted_samples:
914  sample_counter+=1
915 
916  directory=dir_dict[sample]
917  subdirs_dict=directory.get_subdirs_dict()
918 
919  # Check if the directory is the top one
920  if directory.name!="":
921  # We did not run on the topdir
922  #print " ## summary_page: %s"%(directory.name+"_"+subdir_name)
923  #print " ## summary_page hash: %s" %(hash_name(directory.name+"/"+subdir_name,hashing_flag))
924  if hashing_flag:
925  summary_page=join(sample,"%s.html"%(hash_name(directory.name+"/"+subdir_name,hashing_flag)))
926  else:
927  summary_page=join(sample,"%s.html"%(hash_name(directory.name+"_"+subdir_name,hashing_flag)))
928  else:
929  #print " ## summary_page: %s"%(directory.name+subdir_name)
930  #print " ## summary_page hash: %s" %(hash_name(directory.name+subdir_name,hashing_flag))
931  summary_page=join(sample,"%s.html"%(hash_name(directory.name+subdir_name,hashing_flag)))
932  dir_is_there=subdir_name in subdirs_dict
933 
934  img_link="https://upload.wikimedia.org/wikipedia/commons/a/a8/Circle_Davys-Grey_Solid.svg"
935  page_html+='<td><div class="span-1">'
936 
937  if dir_is_there:
938  #row_summary.subdirs.append(subdirs_dict[subdir_name])
939  chart=subdirs_dict[subdir_name].get_piechart_js(50,summary_page)
940  page_html+='%s'%chart
941  else:
942  page_html+='<img src="%s" title="%s" height=50 width=50>' %(img_link,"Unavailable")
943  page_html+='</div></td>'
944 
945  page_html+=" </tr>\n"
946 
947 
948 
949  page_html+='</tbody> </table> </div> <a href="#top">Top...</a><hr>'
950 
951  page_html+=get_rank_section(global_dir)
952 
953  #page_html+=make_twiki_table(dir_dict,aggregation_rules_twiki)
954  # ^ commenting out for the moment, not really useful nor used
955 
956  page_html+=get_page_footer()
957  return page_html
958 
959 
960 #-----------UPDATES------
961 def hash_name(file_name, flag):
962  if flag: #if hashing flag is ON then return
963  if (3,0,0) <= sys.version_info:
964  return hashlib.md5(file_name.encode('utf-8')).hexdigest()[:10]
965  return hashlib.md5(file_name).hexdigest()[:10] #md5 hashed file name with length 10
966  else:
967  return file_name #return standart name
static char to_hex(unsigned int i)
Definition: types.cc:27
def hash_name(file_name, flag)
def get_comparisons(category, directory)
def get_subdirs_section(directory, hashing_flag)
def get_pie_tooltip(directory)
def build_obj(run, sample, version, plot_path, tier)
def build_gauge_js(rate, w=100, minrate=.80, add_rate=False)
def get_aggr_pairs_info(dir_dict, the_aggr_pairs=[])
def make_summary_table(indir, aggregation_rules, aggregation_rules_twiki, hashing_flag, standalone_flag)
def plot_size(h=250, w=200)
def get_page_header(directory=None, standalone=False, additional_header="")
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
def get_title_section(directory, hashing_flag, standalone, depth=2)
def get_dir_stats(directory)
def make_barchart_summary(dir_dict, name="the_chart", title="DQM directory", the_aggr_pairs=[])
def get_summary_section(directory, matrix_page=True)
def directory2html(directory, hashing, standalone, depth=0)
def make_twiki_table(dir_dict, aggregation_rules)
static std::string join(char **cmd)
Definition: RemoteFile.cc:19
def make_categories_summary(dir_dict, aggregation_rules)
def fairy_url_single(run, sample, version, plot_path, tier, draw_opts="", h=250, w=200)
def fairy_url(run1, run2, sample1, sample2, version1, version2, plot_path, tier1, tier2, draw_opts="", h=250, w=200)
def build_obj_addr(run, sample, version, plot_path, tier)
def get_missing_objs_section(directory)
def get_rank_section(directory)