ATLAS Offline Software
LumiCalcHtml.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 
3 # Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
4 
5 from __future__ import print_function
6 
7 import cgi, os, sys
8 import re
9 import string
10 import random
11 import subprocess
12 import cgitb
13 import shutil
14 
15 class LumiCalc:
16 
17  def __init__(self):
18 
19  self.verbose = False
20  # Python file to make updates in working directory
21  self.updateScript = 'LumiCalcWorking.py'
22  self.recoverScript = 'LumiCalcRecover.py'
23 
24  # Prod area
25  self.homeDir = '/var/www/lumicalc/'
26  self.dev = False
27 
28  # Check if we are running as dev
29  if os.environ.get('SERVER_NAME', '') == 'atlas-lumicalc-dev.cern.ch':
30  self.homeDir = '/var/www/lumicalc_dev/'
31  self.dev = True
32 
33  self.resultsDir = '/var/www/lumifiles/'
34 
35  self.htmlDir = self.homeDir + 'athena/LumiBlock/LumiCalc/html/'
36  self.scriptDir = self.homeDir + 'athena/LumiBlock/LumiCalc/share/'
37  self.workdir = os.getcwd()
38 
39  self.uselar = True
40  self.subdir = '.'
41 
42  def createWorkdir(self):
43 
44  # Create a new subdirectory for this
45  self.subdir = hex(random.randint(0,0xFFFFFF))[2:]
46  self.workdir = self.resultsDir + self.subdir
47  os.mkdir(self.workdir)
48 
49  # Open the output file
50  self.f = open(self.workdir+'/working.html', 'w')
51 
52  # Copy the working script
53  shutil.copyfile(self.updateScript, self.workdir+'/'+self.updateScript)
54 
55  # Make sure it is executable
56  os.chmod(self.workdir+'/'+self.updateScript, 0o755)
57 
58  # Also the recovery script
59  shutil.copyfile(self.recoverScript, self.workdir+'/'+self.recoverScript)
60  os.chmod(self.workdir+'/'+self.recoverScript, 0o755)
61 
62  def cleanUp(self):
63 
64  # Close the output file
65  self.f.close()
66 
67  # OK, want to move working.html to result.html
68  # Update script should do the rest
69  shutil.move(self.workdir+'/working.html', self.workdir+'/result.html')
70 
71  def printHead(self):
72 
73  self.f.write( '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">\n' )
74  self.f.write( '<head>\n' )
75  self.f.write( '<title>ATLAS Luminosity Calculator</title>\n' )
76  self.f.write( '<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"></meta>\n' )
77  self.f.write( '<meta name="ATLAS_Luminosity_Calculator" content="ATLAS Luminosity Calculator"></meta>\n' )
78  self.f.write( '<link rel="stylesheet" type="text/css" href="/css/atlas-datasummary.css" media="screen"></link>\n' )
79  self.f.write( '<link rel="stylesheet" type="text/css" href="/css/atlas-datasummary-print.css" media="print"></link>\n' )
80  self.f.write( '<link rel="shortcut icon" href="/images/favicon.ico"></link>\n' )
81  self.f.write( '</head>\n' )
82 
83  def printTopTable(self):
84  self.f.write( '<body>\n' )
85  self.f.write( '<table class="toptable">\n' )
86 
87  # Header file
88  fhead = open(self.htmlDir+"header.html", 'r')
89  for line in fhead.readlines():
90  self.f.write( line )
91  self.f.write( '</table>\n' )
92 
93  def printBottomTable(self):
94 
95  # Footer file
96  ffoot = open(self.htmlDir+"footer.html", 'r')
97  for line in ffoot.readlines():
98  self.f.write( line )
99 
100  def printFooter(self):
101  self.f.write( '<table class="bottomtable">\n')
102  self.f.write( '<tr style="height:45px; vertical-align: top;">\n')
103  self.f.write( '<td><a href="http://validator.w3.org/check?uri=referer">\n')
104  self.f.write( '<img src="/images/xhtml10.gif" alt="Valid XHTML 1.0 Transitional" /></a><br />\n')
105  self.f.write( '<a href="http://jigsaw.w3.org/css-validator/check/referer">\n')
106  self.f.write( '<img src="/images/css.gif" alt="Valid CSS!" /></a>\n')
107  self.f.write( '</td><td style="text-align:right"></td></tr></table>\n')
108 
109  def parseForm(self):
110 
111  form = cgi.FieldStorage()
112 
113  # A nested FieldStorage instance holds the file
114  self.fileitem = form['file']
115  self.lumitag = form['lumitag'].value
116  self.livetrig = form['livetrig'].value
117  self.trigger = form['trigger'].value
118  self.clopts = form['clopts'].value
119  self.lartag = form['lartag'].value
120  for otheritem in form.getlist('other'):
121  self.clopts += (' ' + otheritem)
122 
123  if self.lartag == 'None':
124  self.lartag = ''
125 
126  def printForm(self):
127  self.f.write( '<div id="content">\n' )
128 
129  # Go through and check for errors
130  error = False
131  self.f.write( '<h3>Checking inputs</h3>\n' )
132  self.f.write( '<ul>\n' )
133 
134  self.f.write( '<li>Luminosity DB tag: '+self.lumitag+'</li>\n' )
135 
136  if len(self.livetrig) == 0:
137  self.f.write( '<li><font color="red">Error: Live fraction trigger not specified!</font></li>\n' )
138  error = True
139 
140  else:
141  self.f.write( '<li>Live fraction trigger: '+self.livetrig+'</li>\n' )
142 
143  if string.find(self.livetrig, 'MBTS') > -1 and string.find(self.lumitag, 'HI') > -1:
144  self.f.write( '<li><font color="red">Error: Using MBTS to determine live fraction during Heavy Ion running is not recommended! Try using L1_LUCID_A_C instead.</font></li>\n')
145 
146  if len(self.trigger) == 0:
147  self.f.write( '<li><font color="red">Warning: No physics trigger specified, uncorrected luminosity will be reported!</font></li>\n' )
148 
149  else:
150  self.f.write( '<li>Physics trigger: '+self.trigger+'</li>\n' )
151 
152  self.uselar = False
153  if len(self.lartag) == 0:
154  self.f.write( '<li><font color="red">Warning: No LAr EventVeto tag specified, uncorrected luminosity will be reported!</font></li>\n')
155 
156  else:
157  self.f.write( '<li>LAr EventVeto Tag: ' + self.lartag+'</li>\n' )
158  self.uselar = True
159 
160  # Test if the file was uploaded
161  if self.fileitem.filename:
162 
163  # strip any leading C: from windows
164  if self.fileitem.filename[0:2] == 'C:':
165  self.fileitem.filename = self.fileitem.filename[2:]
166  # strip leading path from file name to avoid directory traversal attacks
167  self.grlfn = os.path.basename(self.fileitem.filename)
168 
169  self.grlfilepath = self.workdir + '/' + self.grlfn
170  open(self.grlfilepath, 'w').write(self.fileitem.file.read())
171  self.f.write( '<li>GRL file: '+self.grlfn+' was uploaded successfully to '+self.workdir+'</li>\n' )
172 
173  else:
174  self.f.write( '<li><font color="red">Error: No GRL file was uploaded</font></li>\n' )
175  error = True
176 
177  if len(self.clopts) > 0:
178  self.f.write( '<li>Other options: '+self.clopts+'</li>\n' )
179 
180  # Check if LAr EventVeto specified at the command line
181  if '--lar' in self.clopts:
182  self.uselar = True
183 
184  self.f.write( '</ul>\n' )
185 
186  if error:
187  self.f.write( '<p>Please fix errors before continuing!</p>\n' )
188 
189  else:
190  self.f.write( '<p>Specification complete!</p>\n' )
191 
192  return error
193 
194  def printEnvironment(self):
195 
196  self.f.write( '<h3>Environment</h3>\n' )
197  f = open(self.htmlDir+'version.html', 'r')
198  for line in f.readlines():
199  self.f.write( line )
200 
201  def printCommand(self):
202 
203  self.f.write( '<h3>Command Details</h3>\n' )
204 
205  self.command = ''
206  if self.lumitag == '--online':
207  self.command += ' --online'
208  elif self.lumitag == 'None':
209  pass
210  else:
211  self.command += (' --lumitag=' + self.lumitag)
212 
213  self.command += (' --livetrigger=' + self.livetrig)
214  if len(self.trigger) > 0:
215  self.command += (' --trigger=' + self.trigger)
216 
217  self.command += (' --xml=' + self.grlfilepath)
218 
219  if len(self.lartag) > 0:
220  self.command += (' --lar --lartag=' + self.lartag)
221 
222  if len(self.clopts) > 0:
223  self.command += (' '+self.clopts)
224 
225  self.f.write( '<p>iLumiCalc '+self.command+'</p>\n' )
226 
227  #self.cmdstr = os.getcwd()+'/runLumiCalc.sh '+self.command
228  if self.dev:
229  self.cmdstr = self.scriptDir+'runLumiCalcDev.sh '+self.command
230  else:
231  self.cmdstr = self.scriptDir+'runLumiCalc.sh '+self.command
232 
233  def runCommand(self):
234  p = subprocess.Popen(self.cmdstr+' > output.txt 2>&1', executable='/bin/bash', cwd=self.workdir, shell=True)
235  p.wait()
236 
237 #
238 # Now, parse iLumiCalc output file
239 #
240  def parseOutput(self):
241 
242  matchrun = re.compile(r'Run ([0-9]+) LB \[([0-9]+)-([0-9]+)\]')
243  matchlumidel = re.compile(r': IntL delivered \‍(ub\^-1\‍) : ([0-9\.e+]+)')
244  matchlumipre = re.compile(r': IntL after livefraction \‍(ub\^-1\‍): ([0-9\.\e\+\-]+)')
245  matchlumilar = re.compile(r': IntL after LAr fraction \‍(ub\^-1\‍): ([0-9\.\e\+\-]+)')
246  matchlumirec = re.compile(r': IntL recorded after prescale \‍(ub\^-1\‍) : ([0-9\.\e\+\-]+)')
247  matchgoodlb = re.compile(r': Good LBs : ([0-9]+)')
248  matchbadlb = re.compile(r': Bad LBs : ([0-9]+)')
249 
250  matchtotlumidel = re.compile(r': Total IntL delivered \‍(ub\^-1\‍) : ([0-9\.\e\+\-]+)')
251  matchtotlumipre = re.compile(r': Total IntL after livefraction \‍(ub\^-1\‍): ([0-9\.\e\+\-]+)')
252  matchtotlumilar = re.compile(r': Total IntL after LAr fraction \‍(ub\^-1\‍): ([0-9\.\e\+\-]+)')
253  matchtotlumirec = re.compile(r': Total IntL recorded \‍(ub\^-1\‍) : ([0-9\.\e\+\-]+)')
254  matchtotgoodlb = re.compile(r': Total Good LBs : ([0-9]+)')
255  matchtotbadlb = re.compile(r': Total Bad LBs : ([0-9]+)')
256 
257  matchrealtime = re.compile(r': Real time: ([0-9\.\e\+\-]+)')
258  matchcputime = re.compile(r': CPU time: ([0-9\.\e\+\-]+)')
259 
260  self.runset = set()
261  self.lumidel = dict()
262  self.lumirec = dict()
263  self.lumipre = dict()
264  self.lumilar = dict()
265  self.goodlb = dict()
266  self.badlb = dict()
267 
268  self.realtime = 0
269  self.cputime = 0
270 
271  currentrun = '000000'
272 
273  for line in open(self.workdir+'/output.txt').readlines():
274  m=matchrun.search(line)
275  if m:
276  if self.verbose:
277  print ('Found run/lbstart/lbend:', m.group(1), m.group(2), m.group(3))
278  currentrun = m.group(1)
279  self.runset.add(currentrun)
280 
281  m=matchlumidel.search(line)
282  if m:
283  if self.verbose:
284  print ('Found lumiDel:', m.group(1), 'in run', currentrun)
285  self.lumidel[currentrun] = float(m.group(1)) + self.lumidel.get(currentrun, 0.)
286 
287  m=matchlumirec.search(line)
288  if m:
289  if self.verbose:
290  print ('Found lumiRec:', m.group(1), 'in run', currentrun)
291  self.lumirec[currentrun] = float(m.group(1)) + self.lumirec.get(currentrun, 0.)
292 
293  m=matchlumipre.search(line)
294  if m:
295  if self.verbose:
296  print ('Found lumiPre:', m.group(1), 'in run', currentrun)
297  self.lumipre[currentrun] = float(m.group(1)) + self.lumipre.get(currentrun, 0.)
298 
299  m=matchlumilar.search(line)
300  if m:
301  if self.verbose:
302  print ('Found lumiLar:', m.group(1), 'in run', currentrun)
303  self.lumilar[currentrun] = float(m.group(1)) + self.lumilar.get(currentrun, 0.)
304 
305  m = matchgoodlb.search(line)
306  if m:
307  if self.verbose:
308  print ('Found goodLB:', m.group(1), 'in run', currentrun)
309  self.goodlb[currentrun] = int(m.group(1)) + self.goodlb.get(currentrun, 0)
310 
311  m = matchbadlb.search(line)
312  if m:
313  if self.verbose:
314  print ('Found badLB:', m.group(1), 'in run', currentrun)
315  self.badlb[currentrun] = int(m.group(1)) + self.badlb.get(currentrun, 0)
316 
317  # Match end-of-job totals
318  m=matchtotlumidel.search(line)
319  if m:
320  if self.verbose:
321  print ('Found Total lumiDel:', m.group(1))
322  self.lumidel['Total'] = float(m.group(1)) + self.lumidel.get('Total', 0.)
323 
324  m=matchtotlumirec.search(line)
325  if m:
326  if self.verbose:
327  print ('Found Total lumiRec:', m.group(1))
328  self.lumirec['Total'] = float(m.group(1)) + self.lumirec.get('Total', 0.)
329 
330  m=matchtotlumipre.search(line)
331  if m:
332  if self.verbose:
333  print ('Found Total lumiPre:', m.group(1))
334  self.lumipre['Total'] = float(m.group(1)) + self.lumipre.get('Total', 0.)
335 
336  m=matchtotlumilar.search(line)
337  if m:
338  if self.verbose:
339  print ('Found Total lumiLar:', m.group(1))
340  self.lumilar['Total'] = float(m.group(1)) + self.lumilar.get('Total', 0.)
341 
342  m = matchtotgoodlb.search(line)
343  if m:
344  if self.verbose:
345  print ('Found Total goodLB:', m.group(1), 'in run', currentrun)
346  self.goodlb['Total'] = int(m.group(1)) + self.goodlb.get('Total', 0)
347 
348  m = matchtotbadlb.search(line)
349  if m:
350  if self.verbose:
351  print ('Found Total badLB:', m.group(1), 'in run', currentrun)
352  self.badlb['Total'] = int(m.group(1)) + self.badlb.get('Total', 0)
353 
354  m = matchrealtime.search(line)
355  if m:
356  self.realtime = float(m.group(1))
357 
358  m = matchcputime.search(line)
359  if m:
360  self.cputime = float(m.group(1))
361 
362  def printTable(self):
363 
364  # Scale factor to apply to lumi values
365  # Base value is ub-1
366  totalLumi = self.lumirec.get('Total', 0.)
367  if totalLumi > 1E8:
368  scale = 1E-6
369  unit = 'pb<sup>-1</sup>'
370  elif totalLumi > 1E5:
371  scale = 1E-3
372  unit = 'nb<sup>-1</sup>'
373  elif totalLumi > 1E2:
374  scale = 1.
375  unit = 'ub<sup>-1</sup>'
376  else:
377  scale = 1000.
378  unit = 'mb<sup>-1</sup>'
379 
380 
381  # Open excel file
382  self.exf = open(self.workdir+'/lumitable.csv', 'w')
383 
384  self.f.write( '<p>Command complete - CPU time: '+str(round(float(self.cputime), 1))+' s, Clock time: '+str(round(float(self.realtime), 1))+' s</p>\n' )
385  self.f.write( '<h3>Total Luminosity: '+str(scale*self.lumirec.get('Total', 0.))+' '+unit+'</h3>\n' )
386 
387  self.f.write( '<table class="lumitable"><tbody>\n' )
388  self.f.write( '<tr><th>Run<br />Number</th><th>Number of<br />Good LBs</th><th>Number of<br />Bad LBs</th><th>Luminosity<br />Delivered ('+unit+')</th><th>Luminosity<br />Livefraction Corrected ('+unit+')</th>')
389  self.exf.write('Run, Good, Bad, LDelivered, LRecorded')
390  if self.uselar:
391  self.f.write('<th>Luminosity<br />LAr Veto Corrected ('+unit+')</th>')
392  self.exf.write(', LAr Corrected')
393 
394  self.f.write('<th>Luminosity<br />Prescale Corrected ('+unit+')</th><th>Lumi-Weighted<br />Live Fraction (percent)</th>')
395  self.exf.write(', Prescale Corrected, Live Fraction')
396 
397  if self.uselar:
398  self.f.write('<th>Lumi-Weighted<br />LAr Fraction (percent)</th>')
399  self.exf.write(', LAr Fraction')
400 
401  self.f.write('<th>Lumi-Weighted<br />Prescale</th></tr>\n' )
402  self.exf.write(', Prescale Fraction\n')
403 
404  # Sort this to get in order
405  runlist = []
406  for run in self.runset:
407  runlist.append(run)
408 
409  runlist.sort()
410 
411  # Tack this on the end so we print total also
412  runlist.append('Total')
413 
414  for run in runlist:
415 
416  if run == 'Total':
417  self.f.write( '<tr class="highlight">\n' )
418  self.f.write( '<td>Total</td>\n')
419  self.exf.write('Total, ')
420 
421  else:
422  self.f.write( '<tr>\n' )
423  self.f.write( '<td>'+run+' (<a href="http://atlas-runquery.cern.ch/query.py?q=find+run+'+run+'+%2F+show+all+and+lhc">ARQ</a>, <a href="http://atlas-trigconf.cern.ch/psevo/'+run+'/">Prescales</a>)</td>\n')
424  self.exf.write((run+', '))
425 
426  self.f.write( '<td>'+str(self.goodlb.get(run, 0))+'</td><td>'+str(self.badlb.get(run, 0))+'</td>\n' )
427 
428  self.f.write( '<td>'+str(scale*self.lumidel.get(run, 0.))+'</td>\n' )
429  self.f.write( '<td>'+str(scale*self.lumipre.get(run, 0.))+'</td>\n' )
430  self.exf.write('%d, %d, %f, %f, ' % (self.goodlb.get(run, 0), self.badlb.get(run, 0), scale*self.lumidel.get(run, 0.), scale*self.lumipre.get(run, 0.)))
431 
432  if self.uselar:
433  self.f.write( '<td>'+str(scale*self.lumilar.get(run, 0.))+'</td>\n' )
434  self.exf.write('%f, ' % (scale*self.lumilar.get(run, 0.)) )
435 
436  self.f.write( '<td>'+str(scale*self.lumirec.get(run, 0.))+'</td>\n' )
437  self.exf.write('%f, ' % (scale*self.lumirec.get(run, 0.)) )
438 
439  # Print live fraction
440  if self.lumidel.get(run, 0.) > 0.:
441  self.f.write( '<td>'+str(round(100*self.lumipre.get(run, 0.)/self.lumidel.get(run, 0.), 2))+'</td>\n' )
442  self.exf.write('%.2f, ' % (100*self.lumipre.get(run, 0.)/self.lumidel.get(run, 0.)) )
443  else:
444  self.f.write( '<td></td>\n' )
445  self.exf.write(' , ')
446 
447  # Print LAr fraction
448  if self.uselar:
449  if self.lumipre.get(run, 0.) > 0.:
450  self.f.write( '<td>'+str(round(100*self.lumilar.get(run, 0.)/self.lumipre.get(run, 0.), 2))+'</td>\n' )
451  self.exf.write('%.2f, ' % (100*self.lumilar.get(run, 0.)/self.lumipre.get(run, 0.)) )
452 
453  else:
454  self.f.write( '<td></td>\n' )
455  self.exf.write(' , ')
456 
457  # Print prescale
458  if self.lumirec.get(run, 0.) > 0.:
459  self.f.write( '<td>'+str(round(self.lumilar.get(run, 0.)/self.lumirec.get(run, 0.), 3))+'</td>\n' )
460  self.exf.write('%.2f' % (100*self.lumilar.get(run, 0.)/self.lumirec.get(run, 0.)) )
461  else:
462  self.f.write( '<td></td>\n' )
463 
464  else:
465  # Print prescale
466  if self.lumirec.get(run, 0.) > 0.:
467  self.f.write( '<td>'+str(round(self.lumipre.get(run, 0.)/self.lumirec.get(run, 0.), 3))+'</td>\n' )
468  self.exf.write('%.2f' % (100*self.lumipre.get(run, 0.)/self.lumirec.get(run, 0.)) )
469  else:
470  self.f.write( '<td></td>\n' )
471 
472  self.f.write( '</tr>\n' )
473  self.exf.write('\n')
474 
475 
476  self.exf.close()
477 
478  self.f.write( '</tbody></table>\n' )
479  self.f.write( '<p>[<a href="/results/'+self.subdir+'/lumitable.csv">Luminosity table as CSV file</a>]</p>\n' )
480 
481  #
482  # Print warnings and errors from log file
483  #
484  def printWarnings(self):
485 
486  matchwarn = re.compile('--- <.+>')
487  warnlist = []
488 
489  for line in open(self.workdir+'/output.txt').readlines():
490  if matchwarn.search(line):
491  warnlist.append(line)
492 
493  if len(warnlist) == 0:
494  return
495 
496  self.f.write('<h3>Warnings/Errors</h3>\n')
497  self.f.write('<pre style="color: red">')
498  for warnline in warnlist:
499  self.f.write(warnline.replace('<', '&lsaquo;').replace('>', '&rsaquo;'))
500 
501  self.f.write('</pre>\n')
502  self.f.write('<p>Check the <a href="/results/'+self.subdir+'/output.txt">Raw iLumiCalc output</a> for more information.</p>\n' )
503 
504  #
505  # Now setup full dump (hidden by JS button)
506  #
507  def printScript(self):
508  self.f.write( '<script>' )
509  self.f.write( 'function makevisible() {' )
510  self.f.write( 'var visible' )
511  self.f.write( 'var hidden' )
512  self.f.write( 'visible = document.getElementById("visible").innerHTML;' )
513  self.f.write( 'hidden = document.getElementById("results").innerHTML;' )
514  self.f.write( 'document.getElementById("visible").innerHTML = hidden;' )
515  self.f.write( '}' )
516  self.f.write( '</script>' )
517 
518  def printDetails(self):
519  self.f.write( '<div id="visible"><p><input type="button" value="Show detailed output" onclick="makevisible()"></p></div>\n' )
520 
521  self.f.write( '<div id="results" style="visibility: hidden">\n' )
522  self.f.write( '<h3>Detailed Output</h3>\n' )
523  self.f.write( '<pre>\n' )
524  for line in open(self.workdir+'/output.txt').readlines():
525  self.f.write( line )
526 
527  self.f.write( '</pre></div>\n' )
528 
529  def printLinks(self):
530  self.f.write( '<h3>Links</h3>\n' )
531  self.f.write( '<p>The following links provide access to the iLumiCalc output files. These will likely remain for several weeks, but please copy any critical files to a more permanent location.</p>\n' )
532 
533  self.f.write( '<p><a href="/results/'+self.subdir+'/">iLumiCalc working directory</a> - location for all output files</p>\n' )
534  self.f.write( '<p><a href="/results/'+self.subdir+'/result.html">Output HTML</a> - this page</p>\n' )
535  self.f.write( '<p><a href="/results/'+self.subdir+'/output.txt">Raw iLumiCalc output</a></p>\n' )
536  self.f.write( '<p><a href="/results/'+self.subdir+'/'+self.grlfn+'">Original GRL XML file</a></p>\n' )
537 
538  # Call iLumiCalc to print out help
539  def printHelp(self):
540  self.f.write( '<h3>LumiCalc Usage</h3>\n' )
541  self.f.write( '<pre>\n' )
542  self.f.write( '> iLumiCalc --help\n\n' )
543  for line in open (self.scriptDir+'help.txt').readlines():
544  self.f.write( line )
545 
546  self.f.write( '</pre>\n' )
547 
548  # All done
549  def printFinish(self):
550  self.f.write( '</div>\n' )
551  # self.printBottomTable()
552  self.printFooter()
553  self.f.write( '</body></html>\n' )
554 
555  def printRedirect(self, outfile='LumiCalcWorking.py'):
556  print ('Content-Type: text/html')
557  print ()# Blank line, end of headers
558  print ('<html><head>')
559  print ('<meta http-equiv="Refresh" content="0; url=/results/'+self.subdir+'/'+outfile+'">')
560  print ('</head></html>')
561 
562  # For debugging, dump all os.environ variables
563  def dumpEnviron(self):
564 
565  print ('Content-Type: text/html')
566  print () # Blank line, end of headers
567  print ('<html>')
568  for key in os.environ:
569  print('<p><b>',key,':</b>',os.environ[key],'<p>')
570  print ('</html>')
571 
572 # Run from command line
573 if __name__ == "__main__":
574 
575  # Enable debugging output for CGI
576  cgitb.enable()
577 
578  # Experimental way here
579  lc = LumiCalc()
580  lc.createWorkdir()
581 
582  # Make sure we have something in working.html
583  lc.parseForm()
584  lc.printHead()
585  lc.printTopTable()
586  if lc.printForm():
587  # Error, finish here
588  lc.printHelp()
589  lc.printFinish()
590  lc.cleanUp()
591  lc.printRedirect('result.html')
592  sys.exit(0) # Exit on error
593 
594  # OK, we are going to run iLumiCalc
595  # Print the redirect and close stdout to get the browser to respond
596  lc.printEnvironment()
597  lc.printCommand()
598  lc.f.flush()
599  lc.printRedirect()
600  sys.stdout.flush()
601  sys.stdout.close() # Trigger browser to complete
602  os.close(1) # Really close it
603 
604  # Here we run the command
605  lc.runCommand()
606 
607  lc.parseOutput()
608  lc.printTable()
609  lc.printWarnings()
610  lc.printLinks()
611  lc.printFinish()
612  lc.cleanUp()
613 
614  # Other possibility to fork
615  #sys.stdout.flush()
616  #if os.fork(): return
617  #fw = open('/dev/null','w')
618  #os.dup2(fw.fileno(),1)
619  #os.dup2(fw.fileno(),2)
620 
python.LumiCalcHtml.LumiCalc.printHelp
def printHelp(self)
Definition: LumiCalcHtml.py:539
python.LumiCalcHtml.LumiCalc.fileitem
fileitem
Definition: LumiCalcHtml.py:114
python.LumiCalcHtml.LumiCalc.lumilar
lumilar
Definition: LumiCalcHtml.py:264
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
python.LumiCalcHtml.LumiCalc.printFooter
def printFooter(self)
Definition: LumiCalcHtml.py:100
python.LumiCalcHtml.LumiCalc.lumidel
lumidel
Definition: LumiCalcHtml.py:261
python.LumiCalcHtml.LumiCalc.createWorkdir
def createWorkdir(self)
Definition: LumiCalcHtml.py:42
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
python.LumiCalcHtml.LumiCalc.command
command
Definition: LumiCalcHtml.py:205
python.LumiCalcHtml.LumiCalc.__init__
def __init__(self)
Definition: LumiCalcHtml.py:17
MuonGM::round
float round(const float toRound, const unsigned int decimals)
Definition: Mdt.cxx:27
python.LumiCalcHtml.LumiCalc.runCommand
def runCommand(self)
Definition: LumiCalcHtml.py:233
python.LumiCalcHtml.LumiCalc.lumitag
lumitag
Definition: LumiCalcHtml.py:115
python.LumiCalcHtml.LumiCalc.clopts
clopts
Definition: LumiCalcHtml.py:118
python.LumiCalcHtml.LumiCalc.parseForm
def parseForm(self)
Definition: LumiCalcHtml.py:109
python.LumiCalcHtml.LumiCalc.homeDir
homeDir
Definition: LumiCalcHtml.py:25
python.LumiCalcHtml.LumiCalc.printBottomTable
def printBottomTable(self)
Definition: LumiCalcHtml.py:93
python.LumiCalcHtml.LumiCalc.printHead
def printHead(self)
Definition: LumiCalcHtml.py:71
python.LumiCalcHtml.LumiCalc
Definition: LumiCalcHtml.py:15
python.LumiCalcHtml.LumiCalc.printCommand
def printCommand(self)
Definition: LumiCalcHtml.py:201
python.LumiCalcHtml.LumiCalc.printDetails
def printDetails(self)
Definition: LumiCalcHtml.py:518
python.LumiCalcHtml.LumiCalc.lumipre
lumipre
Definition: LumiCalcHtml.py:263
python.LumiCalcHtml.LumiCalc.printTable
def printTable(self)
Definition: LumiCalcHtml.py:362
python.LumiCalcHtml.LumiCalc.dumpEnviron
def dumpEnviron(self)
Definition: LumiCalcHtml.py:563
python.LumiCalcHtml.LumiCalc.grlfn
grlfn
Definition: LumiCalcHtml.py:167
python.LumiCalcHtml.LumiCalc.printLinks
def printLinks(self)
Definition: LumiCalcHtml.py:529
python.LumiCalcHtml.LumiCalc.f
f
Definition: LumiCalcHtml.py:50
python.LumiCalcHtml.LumiCalc.workdir
workdir
Definition: LumiCalcHtml.py:37
python.LumiCalcHtml.LumiCalc.realtime
realtime
Definition: LumiCalcHtml.py:268
python.LumiCalcHtml.LumiCalc.exf
exf
Definition: LumiCalcHtml.py:382
python.LumiCalcHtml.LumiCalc.recoverScript
recoverScript
Definition: LumiCalcHtml.py:22
python.LumiCalcHtml.LumiCalc.subdir
subdir
Definition: LumiCalcHtml.py:40
python.LumiCalcHtml.LumiCalc.printTopTable
def printTopTable(self)
Definition: LumiCalcHtml.py:83
python.LumiCalcHtml.LumiCalc.updateScript
updateScript
Definition: LumiCalcHtml.py:21
python.LumiCalcHtml.LumiCalc.lartag
lartag
Definition: LumiCalcHtml.py:119
python.LumiCalcHtml.LumiCalc.lumirec
lumirec
Definition: LumiCalcHtml.py:262
python.ByteStreamConfig.write
def write
Definition: Event/ByteStreamCnvSvc/python/ByteStreamConfig.py:248
python.LumiCalcHtml.LumiCalc.parseOutput
def parseOutput(self)
Definition: LumiCalcHtml.py:240
python.LumiCalcHtml.LumiCalc.htmlDir
htmlDir
Definition: LumiCalcHtml.py:35
add
bool add(const std::string &hname, TKey *tobj)
Definition: fastadd.cxx:55
python.LumiCalcHtml.LumiCalc.printEnvironment
def printEnvironment(self)
Definition: LumiCalcHtml.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
python.LumiCalcHtml.LumiCalc.cputime
cputime
Definition: LumiCalcHtml.py:269
python.LumiCalcHtml.LumiCalc.goodlb
goodlb
Definition: LumiCalcHtml.py:265
python.LumiCalcHtml.LumiCalc.trigger
trigger
Definition: LumiCalcHtml.py:117
python.LumiCalcHtml.LumiCalc.verbose
verbose
Definition: LumiCalcHtml.py:19
python.LumiCalcHtml.LumiCalc.uselar
uselar
Definition: LumiCalcHtml.py:39
python.LumiCalcHtml.LumiCalc.dev
dev
Definition: LumiCalcHtml.py:26
python.LumiCalcHtml.LumiCalc.cmdstr
cmdstr
Definition: LumiCalcHtml.py:229
python.LumiCalcHtml.LumiCalc.printRedirect
def printRedirect(self, outfile='LumiCalcWorking.py')
Definition: LumiCalcHtml.py:555
python.LumiCalcHtml.LumiCalc.runset
runset
Definition: LumiCalcHtml.py:260
Trk::open
@ open
Definition: BinningType.h:40
python.LumiCalcHtml.LumiCalc.printScript
def printScript(self)
Definition: LumiCalcHtml.py:507
python.LumiCalcHtml.LumiCalc.cleanUp
def cleanUp(self)
Definition: LumiCalcHtml.py:62
python.LumiCalcHtml.LumiCalc.grlfilepath
grlfilepath
Definition: LumiCalcHtml.py:169
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:127
python.LumiCalcHtml.LumiCalc.livetrig
livetrig
Definition: LumiCalcHtml.py:116
python.LumiCalcHtml.LumiCalc.badlb
badlb
Definition: LumiCalcHtml.py:266
str
Definition: BTagTrackIpAccessor.cxx:11
dbg::print
void print(std::FILE *stream, std::format_string< Args... > fmt, Args &&... args)
Definition: SGImplSvc.cxx:70
python.LumiCalcHtml.LumiCalc.printWarnings
def printWarnings(self)
Definition: LumiCalcHtml.py:484
python.LumiCalcHtml.LumiCalc.scriptDir
scriptDir
Definition: LumiCalcHtml.py:36
python.LumiCalcHtml.LumiCalc.printForm
def printForm(self)
Definition: LumiCalcHtml.py:126
readCCLHist.float
float
Definition: readCCLHist.py:83
python.LumiCalcHtml.LumiCalc.resultsDir
resultsDir
Definition: LumiCalcHtml.py:33
python.LumiCalcHtml.LumiCalc.printFinish
def printFinish(self)
Definition: LumiCalcHtml.py:549