ATLAS Offline Software
handimod.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2 from __future__ import print_function
3 
4 import os
5 
6 import sys
7 import time
8 
9 # Needed to correct ROOT behavior; see below
10 CWD = os.getcwd()
11 # Importing gSystem may change the current directory to one of the
12 # command-line arguments; chdir to original directory to have
13 # predictable behavior
14 from ROOT import gSystem
15 
16 # Import the ROOT library for reading han results
17 gSystem.Load('libDataQualityUtils')
18 from ROOT import dqutils
19 
20 os.chdir(CWD)
21 
22 # LumiBlock length (in minutes)
23 LBlength = 1.0
24 jsonFileCull = set()
25 
26 
27 def handiWithComparisons(name, resultsFile, htmlDir, runlistLoc, compare, browserMenu, allDirsScriptDir, jsRoot=1):
28  # compare: True if you want a "compare" button on every 1histo page, False by default
29  # javaScriptLoc = url of the javascript for the "compare" button
30  # HjavaScriptLoc = url of the javascript for the "history" button
31  # runlistLoc = url where to find runlist.xml (runlist catalog)
32  # browserMenu = True if you want a browser menu instead of the
33  # allDirsScript = url of javascript to create browser menu
34  # jsRoot = enable jsRoot ;1=png;2=json;3=png&json
35 
36  if (htmlDir.rfind("/") != (len(htmlDir)-1)): # htmlDir needs "/" at the end
37  htmlDir += "/"
38 
39  dirsstring = stringListSystemPaths(resultsFile, htmlDir)
40 
41  dirs = dirsstring.rsplit()
42  for subHtmlDir in dirs:
43  if(not os.access(subHtmlDir, os.F_OK)):
44  try:
45  os.makedirs(subHtmlDir)
46  except os.error:
47  print('Cannot create directory "' + subHtmlDir + '"; exiting.')
48  sys.exit(-1)
49 
50  total = stringAllDQAssessments(resultsFile)
51 
52  LB_range = ''
53  if (name.find('minutes10_') > -1):
54  t = name.split('10_')
55  digit = ((t[len(t)-1]).split(','))[0]
56  digit = float(digit)
57  low_limit = int((digit-1.0)*10.0/LBlength+1)
58  hi_limit = int(digit*10.0/LBlength)
59  LB_range = ', LB '+str(low_limit)+' - ' + str(hi_limit)
60  elif (name.find('minutes30_') > -1):
61  t = name.split('30_')
62  digit = float(((t[len(t)-1]).split(','))[0])
63  low_limit = int((digit-1.0)*30.0/LBlength+1)
64  hi_limit = int(digit*30.0/LBlength)
65  LB_range = ', LB '+str(low_limit)+' - ' + str(hi_limit)
66 
67  nSaved = saveAllHistograms(
68  resultsFile, htmlDir, True, (name+LB_range), jsRoot)
69  if nSaved == 0:
70  print("There are no histograms in this file; writing a dummy index file")
71  if(not os.access(htmlDir, os.F_OK)):
72  try:
73  os.makedirs(htmlDir)
74  except os.error:
75  print('Cannot create directory "' + htmlDir + '"; exiting.')
76  sys.exit(-1)
77  dummyIndex = htmlDir + "/index.html"
78  d = open(dummyIndex, 'w')
79  d.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n')
80  d.write('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n')
81  d.write('<head>\n')
82  d.write('<title>Error</title>\n')
83  d.write('</head>\n')
84  d.write('<body>\n')
85  d.write('<h1>Error:</h1>\n')
86  d.write(
87  'No histograms found for display. Check the <tt>han</tt> configuration\n')
88  d.write('to make sure it is consistent with the <tt>han</tt> input file.\n')
89  d.write('</body>\n')
90  d.write('</html>\n')
91  d.close()
92  return
93 
94  s = total.rsplit('\n')
95  # number = number of lines in total
96  number = len(s)
97  if (len(s[number-1]) < 1): # last line is empty
98  number -= 1
99 
100  if (browserMenu):
101  makeAllDirsXml(htmlDir, name, s, number, resultsFile)
102  dirlist, namelist = makeAllDirsBrowserFile(
103  htmlDir, name, s, number, resultsFile, allDirsScriptDir)
104  else:
105  dirlist, namelist = makeAllDirsFile(
106  htmlDir, name, s, number, resultsFile)
107 
108  for x in range(0, len(dirlist)):
109  makeSubDirFile(htmlDir, name, s, number,
110  namelist[x], dirlist[x], runlistLoc, compare, allDirsScriptDir, jsRoot)
111  makeColorFile(htmlDir, name, s, number,
112  namelist[x], dirlist[x], 'Red', runlistLoc, compare, allDirsScriptDir, jsRoot)
113  makeColorFile(htmlDir, name, s, number,
114  namelist[x], dirlist[x], 'Yellow', runlistLoc, compare, allDirsScriptDir, jsRoot)
115  makeColorFile(htmlDir, name, s, number,
116  namelist[x], dirlist[x], 'Green', runlistLoc, compare, allDirsScriptDir, jsRoot)
117  makeCSSFile(htmlDir, "", namelist[x])
118 
119  makeCSSFile(htmlDir, "", ".")
120 
121  for path in jsonFileCull:
122  if os.path.isfile(path):
123  os.system("rm "+path)
124 
125 
126 def makeAllDirsXml(htmlDir, name, s, number, resultsFile):
127  g = open(htmlDir+'AllDirs.xml', 'w')
128  g.write('<?xml version="1.0" encoding="ISO-8859-1"?>\n')
129  # initial number of white spaces, will change to positive value once we go over the lines
130  spaces = -1
131  num_lists = 0
132  sub = ""
133  for x in range(0, number):
134  sp = s[x].rsplit()
135  if sp[3] == 'dir': # a directory
136  namedir = sp[0]
137  shortNameDir = namedir
138  namediri = namedir.rfind("/")
139  if(namediri != -1):
140  shortNameDir = namedir[namediri+1:]
141  if namedir == '<top_level>':
142  shortNameDir = 'Overall Status'
143  spaces_new = s[x].find(sp[0][0])
144  if ((x < number-1) and (s[x+1].rsplit())[3] == 'ass'):
145  histo = "yes"
146  else:
147  histo = "no"
148  if spaces_new > spaces: # current dir is subdir of previous dir -> new item in new list
149  if (spaces != -1):
150  sub += "sub"
151  g.write('<dir tag=\"'+sub+'dir\" id=\"' + shortNameDir +
152  '\" status=\"'+sp[1]+'\" histo = \"' + histo + '\">\n')
153  num_lists += 1
154  elif spaces_new == spaces: # current en previous dir in same motherdir -> new item
155  g.write('</dir>\n<dir tag=\"'+sub+'dir\" id=\"' + shortNameDir +
156  '\" status=\"'+sp[1] + '\" histo = \"' + histo + '\">\n')
157  else: # close list and open new one
158  diff = spaces - spaces_new
159  while diff > 0:
160  g.write('</dir>\n')
161  diff -= 2
162  num_lists -= 1
163  sub = sub[3:len(sub)]
164  g.write('</dir>\n')
165  g.write('<dir tag=\"'+sub+'dir\" id=\"' + shortNameDir +
166  '\" status=\"'+sp[1] + '\" histo = \"' + histo + '\">\n')
167  if (histo == 'yes'): # check that dir contains histos
168  if namedir == '<top_level>':
169  namedir = '.'
170  g.write('<a href="'+namedir + '/toplevel.html">' +
171  shortNameDir + '</a>\n')
172  else:
173  g.write('<a href="'+namedir + '/index.html" >' +
174  shortNameDir + '</a>\n')
175  # g.write('<'+sp[1]+'></'+sp[1]+'>\n')
176  spaces = spaces_new
177  for x in range(0, num_lists):
178  g.write('</dir>\n')
179  sub = sub[3:len(sub)]
180  g.close()
181 
182 
183 def makeAllDirsFile(htmlDir, name, s, number, resultsFile):
184  g = open(htmlDir+'index.html', 'w')
185  g.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n')
186  g.write('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n')
187  g.write('<head>\n')
188  g.write('<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />\n')
189  g.write('<title>' + name + '</title>\n')
190  g.write('<link rel="stylesheet" href="AutomChecks.css" type="text/css" />\n')
191  g.write('<link rel="stylesheet" href="https://atlasdqm.web.cern.ch/atlasdqm/css/mktree.css"/>\n')
192  g.write('<script type="text/javascript" src="https://atlasdqm.web.cern.ch/atlasdqm/js/mktree.js"></script>\n')
193  g.write('</head>\n')
194 # g.write('<body onload="CollapsibleLists.apply()">')
195  g.write('<body>')
196  g.write(
197  '<font class="DQGroup">[<a href="#" onclick="history.go(-1);return false;">Back</a>]</font>')
198 # g.write('<font class="DQGroup">[<a href="../index.html">Back</a>]</font>\n')
199  g.write('<h1>' + name + ': Monitoring and Automatic Checks</h1>\n')
200 
201  # initial number of white spaces, will change to positive value once we go over the lines
202  spaces = -1
203  # dirlist = list with directories (the line number) that contain histos
204  dirlist = []
205  # namelist = list with corresponding direcotory names
206  namelist = []
207 
208  num_lists = 0
209 
210  g.write('<table>\n')
211  g.write('<tr><td>Click to expand</td></tr>\n')
212  g.write('<tr valign="top">\n<td width="500"><font class="DQGroup">\n')
213  for x in range(0, number):
214  sp = s[x].rsplit()
215  if sp[3] == 'dir': # a directory
216  namedir = sp[0]
217  shortNameDir = namedir
218  namediri = namedir.rfind("/")
219  if(namediri != -1):
220  shortNameDir = namedir[namediri+1:]
221  if namedir == '<top_level>':
222  shortNameDir = 'Overall Status'
223  spaces_new = s[x].find(sp[0][0])
224  if spaces_new > spaces: # current dir is subdir of previous dir -> new item in new list
225  # g.write('<ul%s>\n<li>' % (' class="collapsibleList"' if namedir=='<top_level>' else ''))
226  g.write('<ul%s>\n<li>' %
227  (' class="mktree"' if namedir == '<top_level>' else ''))
228  num_lists += 1
229  elif spaces_new == spaces: # current en previous dir in same motherdir -> new item
230  g.write('</li>\n<li>')
231  else: # close list and open new one
232  g.write('</li>')
233  diff = spaces - spaces_new
234  while diff > 0:
235  g.write('</ul></li>\n')
236  diff -= 2
237  num_lists -= 1
238  g.write('<li>')
239 # if namedir!='<top_level>':
240 # g.write('<img src="http://atlasdqm.web.cern.ch/atlasdqm/img/pixel.png" width="0" height="13" alt="" />')
241  # check that dir contains histos
242  if ((x < number-1) and (s[x+1].rsplit())[3] == 'ass'):
243  if namedir == '<top_level>':
244  namedir = '.'
245  g.write('<a href="'+namedir +
246  '/toplevel.html">'+shortNameDir + ':</a>')
247  else:
248  g.write('<a href="'+namedir +
249  '/index.html" >'+shortNameDir + ':</a>')
250  g.write('&nbsp;&nbsp;&nbsp;<font class="' +
251  sp[1]+'">' + sp[1] + '</font>\n')
252  dirlist.append(x)
253  namelist.append(namedir)
254  else:
255  g.write(shortNameDir + ':')
256  g.write('&nbsp;&nbsp;&nbsp;<font class="' +
257  sp[1]+'">' + sp[1] + '</font>\n')
258  spaces = spaces_new
259  if num_lists > 0:
260  g.write('</li>')
261  for x in range(0, num_lists-1):
262  g.write('</ul></li>\n')
263  if num_lists > 0:
264  g.write('</ul>\n')
265  #g.write('</font></td>\n<td><font class="Info">From file:</font><br/><font class="Note">' + resultsFile + '</font></td>\n</tr>\n</table>')
266  g.write('</font></td>\n</tr>\n</table>')
267  g.write('</body>\n</html>\n')
268  g.close()
269  return dirlist, namelist
270 
271 
272 def makeAllDirsBrowserFile(htmlDir, name, s, number, resultsFile, AllDirsScriptDir):
273  g = open(htmlDir+'index.html', 'w')
274  g.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n')
275  g.write('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n')
276  g.write('<head>\n')
277  g.write('<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />\n')
278  g.write('<title>' + name + '</title>\n')
279  g.write('<link rel="stylesheet" href="AutomChecks.css" type="text/css" />\n')
280  g.write('<link rel="stylesheet" href="'+AllDirsScriptDir +
281  '/mktree/mktree.css" type="text/css" />')
282  g.write('<script type="text/javascript" src="'+AllDirsScriptDir +
283  '/AllDirs.js"><!-- dont contract--></script>\n')
284  g.write('<script type="text/javascript" src="'+AllDirsScriptDir +
285  '/mktree/mktree.js"><!-- dont contract--></script>\n')
286  g.write('</head>\n')
287  g.write('<body onLoad=\"loadXMLDoc(\'AllDirs.xml\');\">')
288  g.write(
289  '<font class="DQGroup">[<a href="#" onclick="history.go(-1);return false;">Back</a>]</font>')
290  g.write('<h1>' + name + ': Monitoring and Automatic Checks</h1>\n')
291  #g.write('<p><font class="Info">From file:</font><br/><font class="Note">' + resultsFile + '</font></p>\n')
292  g.write('<div id=\"Select_subdir\">\n</div>\n')
293  # g.write('<table>\n<tr>\n')
294  #g.write('<td valign="top"> &nbsp&nbsp &nbsp &nbsp&nbsp<input type="button" onclick="displaySubdirs();" value="... or display directories at current level" />\n')
295  # g.write('</td>\n</tr>\n</table>\n
296  #g.write('<br />\n')
297  g.write('<div id=\"Display_dir\">\n</div>\n')
298  g.write('</body>\n</html>\n')
299  g.close()
300 
301  # dirlist = list with directories (the line number) that contain histos
302  dirlist = []
303  # namelist = list with corresponding direcotory names
304  namelist = []
305 
306  for x in range(0, number):
307  sp = s[x].rsplit()
308  if sp[3] == 'dir': # a directory
309  namedir = sp[0]
310  # check that dir contains histos
311  if ((x < number-1) and (s[x+1].rsplit())[3] == 'ass'):
312  if namedir == '<top_level>':
313  namedir = '.'
314  dirlist.append(x)
315  namelist.append(namedir)
316  g.close()
317  return dirlist, namelist
318 
319 
320 def makeSubDirFile(htmlDir, name, s, number, subname, assessIndex, runlistLoc, compare, AllDirsScriptDir, jsRoot):
321 
322  if(subname == '.'):
323  h = open(htmlDir+'/'+subname+'/toplevel.html', 'w')
324  subnameTitle = 'Top Level'
325  else:
326  h = open(htmlDir+'/'+subname+'/index.html', 'w')
327  subnameTitle = subname
328  h.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n')
329  h.write('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n')
330  h.write('<head>\n')
331  h.write('<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />\n')
332  h.write('<title>' + name + ' ' + subnameTitle + '</title>\n')
333  h.write('<link rel="stylesheet" href="AutomChecks.css" type="text/css" />\n')
334  h.write('<script type="text/javascript" src="'+AllDirsScriptDir +
335  '/AllDirs.js"><!-- dont contract--></script>\n')
336  h.write('</head>\n')
337  h.write('<body>\n')
338  h.write(
339  '<font class="DQGroup">[<a href="#" onclick="history.go(-1);return false;">Back</a>]</font>')
340 # h.write('<font class="DQGroup">[<a href="')
341 # for x in range(subname.count("/")):
342 # h.write('../')
343 # h.write('../index.html">Back</a>]</font>\n')
344  h.write('<center>')
345  h.write('<table>\n<tr valign="top">\n<td width="250"></td>\n')
346  h.write('<td width="300" align="center"><h2>' +
347  name+' '+subnameTitle+'</h2>\n')
348  h.write('<a href="Red.html">[Only Red]</a>\n')
349  h.write('<a href="Yellow.html">[Only Yellow]</a>\n')
350  h.write('<a href="Green.html">[Only Green]</a></td>\n')
351  h.write('<td width="250">\n<font class="Note">Click on images for details and full size.</font>\n')
352  h.write('</td>\n</tr>\n</table>\n')
353  h.write('<table cellpadding="4" cellspacing="20">\n')
354  y = assessIndex+1
355  sp = s[y].rsplit()
356  col = 0
357  while(sp[3] == 'ass' and y < number):
358  sp = s[y].rsplit()
359  titleStream = s[y].rsplit(" title ")
360  title = titleStream[1]
361  col += 1
362  if col == 1:
363  h.write('<tr>\n<td class="' + sp[1] + '" align="center"><a href="'+sp[0]+'.html" class="hintanchor" onmouseover="showhint(\'' + title+'\', this, event, \'400px\')"><img src="' +
364  sp[0] + '.png" height="200" alt="' + name + ' ' + subname+'/'+sp[0]+'.png" /></a><br/><div style="text-overflow:ellipsis;overflow:hidden;max-width:240px">'+sp[0]+'</div></td>\n')
365  elif col == 3:
366  h.write('<td class="' + sp[1] + '" align="center"><a href="'+sp[0]+'.html" class="hintanchor" onmouseover="showhint(\'' + title+'\', this, event, \'500px\')"><img src="' + sp[0] +
367  '.png" height="200" alt="' + name + ' ' + subname+'/'+sp[0]+'.png" /></a><br/><div style="text-overflow:ellipsis;overflow:hidden;max-width:240px">'+sp[0]+'</div></td>\n</tr>\n')
368  col = 0
369  else:
370  h.write('<td class="' + sp[1] + '" align="center"><a href="'+sp[0]+'.html" class="hintanchor" onmouseover="showhint(\'' + title+'\', this, event, \'400px\')"><img src="' +
371  sp[0] + '.png" height="200" alt="' + name + ' ' + subname+'/'+sp[0]+'.png" /></a><br/><div style="text-overflow:ellipsis;overflow:hidden;max-width:240px">'+sp[0]+'</div></td>\n')
372  temp = s[y].rsplit(" title ")
373  sp = temp[0].split()
374  makeOneHistFile(htmlDir, name, subname, sp,
375  runlistLoc, compare, jsRoot)
376  y = y+1
377  if y < number:
378  sp = s[y].rsplit()
379  if not (col == 3):
380  h.write('</tr>\n')
381  h.write('</table>\n</center>\n</body>\n</html>\n')
382  h.close()
383 
384 
385 def makeColorFile(htmlDir, name, s, number, subname, assessIndex, color, runlistLoc, compare, AllDirsScriptDir, jsRoot):
386 
387  if(subname == '.'):
388  h = open(htmlDir+'/'+subname+'/'+color+'.html', 'w')
389  subnameTitle = 'Top Level'
390  else:
391  h = open(htmlDir+'/'+subname+'/'+color+'.html', 'w')
392  subnameTitle = subname
393  h.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n')
394  h.write('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n')
395  h.write('<head>\n')
396  h.write('<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />\n')
397  h.write('<title>' + name + ' ' + subnameTitle + ' ' + color + '</title>\n')
398  h.write('<link rel="stylesheet" href="AutomChecks.css" type="text/css" />\n')
399  h.write('<script type="text/javascript" src="'+AllDirsScriptDir +
400  '/AllDirs.js"><!-- dont contract--></script>\n')
401  h.write('</head>\n')
402  h.write('<body>\n')
403  h.write(
404  '<font class="DQGroup">[<a href="#" onclick="history.go(-1);return false;">Back</a>]</font>')
405  h.write('<center>')
406  h.write('<table>\n<tr valign="top">\n<td width="250"></td>\n')
407  h.write('<td width="300"><h2>'+name+' ' +
408  subnameTitle+': ' + color + ' only</h2>\n')
409  h.write('<a href="Red.html">[Only Red]</a>\n')
410  h.write('<a href="Yellow.html">[Only Yellow]</a>\n')
411  h.write('<a href="Green.html">[Only Green]</a></td>\n')
412  h.write('<td width="250">\n<font class="Note">Click on images for details and full size.</font>\n')
413  h.write('</td>\n</tr>\n</table>\n')
414  h.write('<table cellpadding="4" cellspacing="20">\n')
415  y = assessIndex+1
416  sp = s[y].rsplit()
417  col = 0
418  count = 0
419  while(sp[3] == 'ass' and y < number):
420  titleStream = s[y].rsplit(" title ")
421  title = titleStream[1]
422  sp = s[y].rsplit()
423  if sp[1] == color:
424  count = count + 1
425  col += 1
426  if col == 1:
427  h.write('<tr>\n<td class="' + sp[1] + '"><a href="'+sp[0]+'.html" class="hintanchor" onmouseover="showhint(\''+title +
428  '\', this, event, \'400px\')"><img src="' + sp[0] + '.png" height="200" alt="' + name + ' ' + subname+'/'+sp[0]+'.png" /></a></td>\n')
429  elif col == 3:
430  h.write('<td class="' + sp[1] + '"><a href="'+sp[0]+'.html" class="hintanchor" onmouseover="showhint(\''+title +
431  '\', this, event, \'500px\')"><img src="' + sp[0] + '.png" height="200" alt="' + name + ' ' + subname+'/'+sp[0]+'.png" /></a></td>\n</tr>\n')
432  col = 0
433  else:
434  h.write('<td class="' + sp[1] + '"><a href="'+sp[0]+'.html" class="hintanchor" onmouseover="showhint(\'' + title +
435  '\', this, event, \'400px\')"><img src="' + sp[0] + '.png" height="200" alt="' + name + ' ' + subname+'/'+sp[0]+'.png" /></a></td>\n')
436  temp = s[y].rsplit(" title ")
437  sp = temp[0].split()
438  makeOneHistFile(htmlDir, name, subname, sp,
439  runlistLoc, compare, jsRoot)
440  y = y+1
441  if y < number:
442  sp = s[y].rsplit()
443  if not (col == 3):
444  h.write('</tr>\n')
445  h.write('</table>\n')
446  if count == 0:
447  h.write('<h3> No '+color+' histograms </h3>\n')
448  h.write('</center>\n</body>\n</html>\n')
449  h.close()
450 
451 
452 def writeLimitDiagram(k, limitName, lowColor, hiColor, loVal, hiVal):
453  k.write('<tr><td>&nbsp;</td></tr>\n')
454  k.write('<tr><td colspan="2">\n')
455  k.write('<table>\n')
456  k.write('<caption>'+limitName+'</caption>\n')
457  k.write('<tr>\n')
458  k.write('<td width="340" align="center" colspan="4">\n')
459  k.write('<font color="'+lowColor+'">XXXXXXX</font><b>I</b>\n')
460  k.write('<font color="#ffd700">XXXXXXX</font><b>I</b>\n')
461  k.write('<font color="'+hiColor+'">XXXXXXX</font></td>\n')
462  k.write('</tr><tr>\n')
463  k.write('<td width="92"></td>\n')
464  k.write('<td width="78" align="center">' + loVal + '</td>\n')
465  k.write('<td width="78" align="center">' + hiVal + '</td>\n')
466  k.write('<td width="92"></td>\n')
467  k.write('</tr>\n</table>\n')
468 
469 
470 def makeOneHistFile(htmlDir, name, subname, sp, runlistLoc, compare, jsRoot):
471  import re
472  runmatch = re.compile('^Run ([0-9]+), ([0-9]+)/(.+)$')
473  subrunmatch = re.compile('^Run ([0-9]+), (.+)_(.*), ([0-9]+)/(.+)$')
474  rm = runmatch.match(name)
475  srm = subrunmatch.match(name)
476  if rm is not None:
477  run, proc_ver, stream = rm.groups()
478  period_type = 'run'
479  period = '1'
480  elif srm is not None:
481  run, period_type, period, proc_ver, stream = srm.groups()
482  else:
483  run, period_type, period, proc_ver, stream = [None]*5
484 
485  k = open(htmlDir+'/'+subname+'/'+sp[0]+'.html', 'w')
486  k.write('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n')
487  k.write('<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n')
488  k.write('<head>\n')
489  k.write('<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />\n')
490  k.write('<title>'+name + ' ' + subname + ' ' + sp[0]+'</title>\n')
491  k.write('<link rel="stylesheet" href="AutomChecks.css" type="text/css" />\n')
492  k.write('<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.10/require.min.js"></script>\n')
493  k.write('<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>')
494 
495  k.write('</head>\n')
496  k.write('<body>\n')
497  k.write('<center>\n')
498  k.write('<table>\n<tr valign="top">\n')
499  k.write(
500  '<td width="250"><font class="DQGroup">[<a href="#" onclick="history.go(-1);return false;">Back</a>]</font></td>\n')
501  k.write('<td width="500"><h2>'+name + ' ' +
502  subname+'/'+sp[0]+'</h2></td>\n')
503  k.write('<td width="250"></td>\n</tr>\n')
504  for x in range(4, len(sp)-1):
505  if ('inputname' in sp[x]):
506  inputname = sp[x+1]
507  k.write('<tr><td width="250"></td><td width="500">Location in ROOT file: ' +
508  inputname + '</td>\n</tr>\n')
509  k.write('</table>\n')
510  k.write('<table cellpadding="10">\n<tr>\n')
511  k.write('<td>\n<table width="400">\n')
512  k.write(
513  '<tr><td colspan="2"><font class="Heading">Assessment Details:</font></td></tr>\n')
514  k.write('<tr><td>&nbsp;</td></tr>\n')
515  k.write('<tr><td align="right"><font class="DatumName">Name:</font></td>')
516  k.write('<td>' + sp[0] + '</td></tr>\n')
517  k.write('<tr><td align="right"><font class="DatumName">Status:</font></td>')
518  k.write('<td><font class="' + sp[1] + '">' + sp[1] + '</font></td></tr>\n')
519  k.write('<tr><td align="right"><font class="DatumName">Algorithm:</font></td>')
520  k.write('<td>'+sp[2]+'</td></tr>\n')
521  algorithm = sp[2]
522  extra = len(sp)-4
523  cc = 4
524  Green = Red = 0
525  cG = -1
526  cR = -1
527  currentHeading = ''
528  namecache = []
529  while(extra > 0):
530  if 'Green' in sp[cc]:
531  currentHeading = 'limits'
532  spi = sp[cc].find("Green")
533  limitName = sp[cc][:spi]
534  Green = float(sp[cc+1])
535  cG = cc+1
536  cc += 2
537  extra -= 2
538  if (cG > 0 and cR > 0):
539  if(Green > Red):
540  writeLimitDiagram(k, limitName, "Red",
541  "Green", sp[cR], sp[cG])
542  else:
543  writeLimitDiagram(k, limitName, "Green",
544  "Red", sp[cG], sp[cR])
545  cG = -1
546  cR = -1
547  elif 'Red' in sp[cc]:
548  currentHeading = 'limits'
549  spi = sp[cc].find("Red")
550  limitName = sp[cc][:spi]
551  Red = float(sp[cc+1])
552  cR = cc+1
553  cc += 2
554  extra -= 2
555  if (cG > 0 and cR > 0):
556  if(Green > Red):
557  writeLimitDiagram(k, limitName, "Red",
558  "Green", sp[cR], sp[cG])
559  else:
560  writeLimitDiagram(k, limitName, "Green",
561  "Red", sp[cG], sp[cR])
562  cG = -1
563  cR = -1
564  elif sp[cc] == "Results":
565  currentHeading = 'results'
566  k.write('<tr><td>&nbsp;</td></tr>\n')
567  k.write(
568  '<tr><td colspan="2"><font class="Heading">Results:</font></td></tr>\n')
569  k.write('<tr><td>&nbsp;</td></tr>\n')
570  cc += 2
571  extra -= 2
572  elif sp[cc] == "Config":
573  currentHeading = 'config'
574  k.write('<tr><td>&nbsp;</td></tr>\n')
575  k.write(
576  '<tr><td colspan="2"><font class="Heading">Configuration Parameters:</font></td></tr>\n')
577  k.write('<tr><td>&nbsp;</td></tr>\n')
578  cc += 2
579  extra -= 2
580  elif sp[cc] == "entries:":
581  currentHeading = 'nentries'
582  k.write(
583  '<tr><td align="right"><font class="DatumName">Num. of Entries:</font> </td>')
584  k.write('<td>'+sp[cc+1]+'</td></tr>\n')
585  cc += 2
586  extra -= 2
587  elif sp[cc] == "Underflow:":
588  k.write(
589  '<tr><td align="right"><font class="DatumName">Underflow:</font> </td>')
590  k.write('<td>'+sp[cc+1]+'</td></tr>\n')
591  cc += 2
592  extra -= 2
593  elif sp[cc] == "Overflow:":
594  k.write(
595  '<tr><td align="right"><font class="DatumName">Overflow:</font> </td>')
596  k.write('<td>'+sp[cc+1]+'</td></tr>\n')
597  cc += 2
598  extra -= 2
599  elif cc < len(sp)-1 and 'inputname' not in sp[cc]:
600  if currentHeading == 'results':
601  namecache.append(sp[cc-2])
602  if ':' not in sp[cc]:
603  cc += 1
604  extra -= 1
605  continue
606  else:
607  name = ' '.join([namecache[-1]])
608  namecache = []
609  from six.moves import urllib
610  resultname = name.rsplit(':', 1)[0]
611  resultval = sp[cc-1]
612  if algorithm == 'RepeatAlgorithm' and resultname.endswith('|Status'):
613  resultval = {'1': 'Red', '2': 'Yellow',
614  '3': 'Green'}[resultval]
615  if compare and run is not None:
616  if period_type == 'run':
617  queryurl = 'http://atlasdqm.cern.ch:8080/dqmfquery/query?histogram=%s&result=%s&error=&stream=%s&period_type=%s&source=tier0&proc_ver=%s&low_run=%s&high_run=&low_y=&high_y=&outputtype=png' % (
618  urllib.parse.quote_plus(subname+'/'+sp[0]), urllib.parse.quote_plus(resultname), stream.strip(), period_type, proc_ver, int(run)-1000)
619  k.write(
620  '<tr><td align="right"><b><a href="%s">%s</a>:</b></td>' % (queryurl, resultname))
621  k.write('<td>'+resultval+'</td></tr>\n')
622  else:
623  queryurl1 = 'http://atlasdqm.cern.ch:8080/dqmfquery/query?histogram=%s&result=%s&error=&stream=%s&period_type=%s&source=tier0&proc_ver=%s&low_run=%s&high_run=&low_y=&high_y=&outputtype=png' % (
624  urllib.parse.quote_plus(subname+'/'+sp[0]), urllib.parse.quote_plus(resultname), stream.strip(), period_type, proc_ver, int(run)-1000)
625  queryurl2 = 'http://atlasdqm.cern.ch:8080/dqmfquery/query?histogram=%s&result=%s&error=&stream=%s&period_type=%s&source=tier0&proc_ver=%s&low_run=%s&high_run=%s&low_y=&high_y=&outputtype=png' % (
626  urllib.parse.quote_plus(subname+'/'+sp[0]), urllib.parse.quote_plus(resultname), stream.strip(), period_type, proc_ver, run, run)
627  k.write(
628  '<tr><td align="right"><b><a href="%s">%s</a>:</b></td>' % (queryurl1, resultname))
629  k.write(
630  '<td>'+resultval+' (<a href="%s">History for this run</a>)</td></tr>\n' % queryurl2)
631  else:
632  k.write('<tr><td align="right"><b> %s: </b></td>' %
633  (resultname,))
634  k.write('<td>'+resultval+'</td></tr>\n')
635  else:
636  k.write('<tr><td align="right"><b>'+sp[cc]+' </b></td>')
637  if sp[cc+1:cc+3] == ['Multiple', 'references']:
638  k.write('<td>'+' '.join(sp[cc+1:cc+3])+'</td></tr>\n')
639  cc += 1
640  extra -= 1
641  else:
642  k.write('<td>'+sp[cc+1]+'</td></tr>\n')
643  cc += 2
644  extra -= 2
645  else:
646  cc += 2
647  extra -= 2
648  k.write('</table>\n</td>\n')
649  jsonPath = htmlDir+'/'+subname+'/'+sp[0]+".json" if sp[0] else ""
650  if jsonPath:
651  jsonFileCull.add(jsonPath)
652  jsonFile = open(jsonPath, 'r') if os.path.isfile(jsonPath) else ""
653  if subname == '.':
654  if((jsRoot & 2) and os.path.isfile(jsonPath)):
655  jsonFile.seek(0)
656  jsonStr = jsonFile.read()
657  jsonStr = jsonStr.replace('\n', '')
658  k.write(
659  '<td><div id="root_plot_1" style="width: 600px; height: 400px"></div></td>\n<script>\n requirejs.config( { paths: { \'JSRootCore\' : \'https://root.cern.ch/js/dev//scripts/JSRootCore\', \'JSRootPainter\' : \'https://root.cern.ch/js/dev//scripts/JSRootPainter\', } });require([\'JSRootCore\', \'JSRootPainter\'], function(Core, Painter) {\n var obj = Core.parse(\''+jsonStr+'\');\nPainter.draw("root_plot_1", obj, ""); });</script>\n')
660  else:
661  k.write('<td><a href="toplevel.html"><img src="' +
662  sp[0] + '.png" alt="' + name + ' ' + subname+'/'+sp[0]+'.png" /></a></td>\n')
663  else:
664  if((jsRoot & 2) and os.path.isfile(jsonPath)):
665  jsonFile.seek(0)
666  jsonStr = jsonFile.read()
667  jsonStr = jsonStr.replace('\n', '')
668  k.write(
669  '<td><div id="root_plot_2" style="width: 600px; height: 400px"></div></td>\n<script>\n requirejs.config( { paths: { \'JSRootCore\' : \'https://root.cern.ch/js/dev//scripts/JSRootCore\', \'JSRootPainter\' : \'https://root.cern.ch/js/dev//scripts/JSRootPainter\', } });require([\'JSRootCore\', \'JSRootPainter\'], function(Core, Painter) {\n var obj = Core.parse(\''+jsonStr+'\');\nPainter.draw("root_plot_2", obj, ""); });</script>\n')
670  else:
671  k.write('<td><a href="index.html"><img src="' +
672  sp[0] + '.png" alt="' + name + ' ' + subname+'/'+sp[0]+'.png" /></a></td>\n')
673  k.write('</tr></table>\n')
674  k.write('</center>\n')
675  now = time.localtime()
676  #lastUpdate = "Last Update: "+str(now[0])+"-"+str(now[1])+"-"+str(now[2])+" "+str(now[3])+":"+str(now[4])+" UTC"
677  lastUpdate = "Last Update: "+time.strftime('%Y-%m-%d %H:%M %Z', now)
678  k.write('</br><font class=\"Note\">'+lastUpdate+'</font><br />\n')
679 # if(compare):
680 
700 
701 # history button (Monica D'Onofrio, 08/21/2008)
702 
710 
711 # try:
712 
715 
716 
722 
723 
727 
728  k.write('</body>\n</html>\n')
729  k.close()
730 
731 
732 def makeRootFile(htmlDir, name, subname):
733  k = open(htmlDir+'index.html', 'w')
734  k.write('<html>\n<frameset rows="200,*">\n')
735  k.write('<frame src="'+name+'AllDirs.html">\n')
736  if subname != "":
737  if subname != '.':
738  k.write('<frame src="'+subname+'/index.html" name="showframe"> \n')
739  else:
740  k.write('<frame src="'+subname +
741  '/toplevel.html" name="showframe"> \n')
742  k.write('</frameset>\n</html> \n')
743  k.close()
744 
745 
746 def makeCSSFile(htmlDir, name, subname):
747  css = open(htmlDir+'/'+subname+'/'+name+'AutomChecks.css', 'w')
748  css.write(
749  'BODY\n{\n background: #E6E6FA;\n color: #000000;\n font-family: helvetica,sans-serif;\n}\n')
750  css.write(
751  'H1\n{\n font-family: helvetica,sans-serif;\n font-size: x-large;\n text-align: left;\n}\n')
752  css.write(
753  'H2\n{\n font-family: helvetica,sans-serif;\n font-size: large;\n text-align: center;\n}\n')
754  css.write(
755  'H3\n{\n font-family: helvetica,sans-serif;\n font-size: medium;\n text-align: left;\n}\n')
756  css.write('A IMG\n{\n border: none;\n}\n')
757  css.write('FONT.Info\n{\n color: black;\n font-style: italic;\n}\n')
758  css.write(
759  'FONT.Heading\n{\n color: black;\n font-weight: bold;\n font-size: large;\n}\n')
760  css.write('FONT.DatumName\n{\n color: black;\n font-weight: bold;\n}\n')
761  css.write('FONT.Note\n{\n color: black;\n font-size: small;\n}\n')
762  css.write('FONT.DQGroup\n{\n font-size: small;\n}\n')
763  css.write('FONT.Red\n{\n color: red;\n font-weight: bold;\n}\n')
764  css.write('FONT.Yellow\n{\n color: #ffd700;\n font-weight: bold;\n}\n')
765  css.write('FONT.Green\n{\n color: green;\n font-weight: bold;\n}\n')
766  css.write('FONT.Disabled\n{\n color: black;\n font-weight: bold;\n}\n')
767  css.write('FONT.Undefined\n{\n color: gray;\n}\n')
768  css.write('FONT.NoCheck\n{\n color: black;\n font-weight: bold;\n}\n')
769  css.write('TD.Red\n{\n background-color: red;\n}\n')
770  css.write('TD.Yellow\n{\n background-color: #ffd700;\n}\n')
771  css.write('TD.Green\n{\n background-color: green;\n}\n')
772  css.write('TD.Disabled\n{\n background-color: black;\n}\n')
773  css.write('TD.Undef\n{\n background-color: gray;\n}\n')
774  css.write('TD.NoCheck\n{\n background-color: #E6E6FA;\n}\n')
775  css.write('.hintanchor\n{\n font-weight: bold; \n color: navy; \n }\n')
776  css.write('#hintbox{\n position:absolute; \n top: 0; \n background-color: lightyellow; \n width: 150px; \n padding: 3px; \n border:1px solid black; \n')
777  css.write('font:normal 15px Verdana;\n line-height:18px; \n z-index:100; \n border-right: 3px solid black; \n border-bottom: 3px solid black; \n visibility: hidden;\n }')
778  css.close()
779 
780 
781 def stringListSystemPaths(resultsFile, location):
782  of = dqutils.HanOutputFile(resultsFile)
783  dirsstring = of.stringListSystemPaths(location)
784  of.setFile('')
785  return dirsstring
786 
787 
788 def stringAllDQAssessments(resultsFile):
789  of = dqutils.HanOutputFile(resultsFile)
790  total = of.stringAllDQAssessments()
791  of.setFile('')
792  return total
793 
794 
795 def saveAllHistograms(resultsFile, location, drawRefs, run_min_LB, jsRoot):
796  of = dqutils.HanOutputFile(resultsFile)
797  # sorry, need PNG, so override jsRoot == 2
798  cnvType = 1 if jsRoot == 1 else 3
799  nSaved = of.saveAllHistograms(location, drawRefs, run_min_LB, cnvType)
800  of.setFile('')
801  return nSaved
python.handimod.makeAllDirsXml
def makeAllDirsXml(htmlDir, name, s, number, resultsFile)
Definition: handimod.py:126
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.handimod.writeLimitDiagram
def writeLimitDiagram(k, limitName, lowColor, hiColor, loVal, hiVal)
Definition: handimod.py:452
python.handimod.makeCSSFile
def makeCSSFile(htmlDir, name, subname)
Definition: handimod.py:746
while
while((inf=(TStreamerInfo *) nextinfo()) !=0)
Definition: liststreamerinfos.cxx:13
python.handimod.makeRootFile
def makeRootFile(htmlDir, name, subname)
t = htmlDir.split("/"); pref = "run"; stream = "no stream"; run = "no run"; for x in range(0,...
Definition: handimod.py:732
dqutils::HanOutputFile
Definition: HanOutputFile.h:32
python.handimod.stringAllDQAssessments
def stringAllDQAssessments(resultsFile)
Definition: handimod.py:788
python.handimod.handiWithComparisons
def handiWithComparisons(name, resultsFile, htmlDir, runlistLoc, compare, browserMenu, allDirsScriptDir, jsRoot=1)
Definition: handimod.py:27
python.handimod.makeSubDirFile
def makeSubDirFile(htmlDir, name, s, number, subname, assessIndex, runlistLoc, compare, AllDirsScriptDir, jsRoot)
Definition: handimod.py:320
python.handimod.makeAllDirsBrowserFile
def makeAllDirsBrowserFile(htmlDir, name, s, number, resultsFile, AllDirsScriptDir)
Definition: handimod.py:272
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
CxxUtils::set
constexpr std::enable_if_t< is_bitmask_v< E >, E & > set(E &lhs, E rhs)
Convenience function to set bits in a class enum bitmask.
Definition: bitmask.h:232
python.handimod.makeColorFile
def makeColorFile(htmlDir, name, s, number, subname, assessIndex, color, runlistLoc, compare, AllDirsScriptDir, jsRoot)
Definition: handimod.py:385
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
python.handimod.saveAllHistograms
def saveAllHistograms(resultsFile, location, drawRefs, run_min_LB, jsRoot)
Definition: handimod.py:795
python.handimod.makeOneHistFile
def makeOneHistFile(htmlDir, name, subname, sp, runlistLoc, compare, jsRoot)
Definition: handimod.py:470
python.handimod.makeAllDirsFile
def makeAllDirsFile(htmlDir, name, s, number, resultsFile)
Definition: handimod.py:183
python.handimod.stringListSystemPaths
def stringListSystemPaths(resultsFile, location)
Definition: handimod.py:781
Trk::open
@ open
Definition: BinningType.h:40
if
if(febId1==febId2)
Definition: LArRodBlockPhysicsV0.cxx:567
str
Definition: BTagTrackIpAccessor.cxx:11
dbg::print
void print(std::FILE *stream, std::format_string< Args... > fmt, Args &&... args)
Definition: SGImplSvc.cxx:70
readCCLHist.float
float
Definition: readCCLHist.py:83
Trk::split
@ split
Definition: LayerMaterialProperties.h:38