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