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