Package madgraph :: Package madevent :: Module gen_crossxhtml
[hide private]
[frames] | no frames]

Source Code for Module madgraph.madevent.gen_crossxhtml

   1  ################################################################################ 
   2  # 
   3  # Copyright (c) 2011 The MadGraph5_aMC@NLO Development team and Contributors 
   4  # 
   5  # This file is a part of the MadGraph5_aMC@NLO project, an application which  
   6  # automatically generates Feynman diagrams and matrix elements for arbitrary 
   7  # high-energy processes in the Standard Model and beyond. 
   8  # 
   9  # It is subject to the MadGraph5_aMC@NLO license which should accompany this  
  10  # distribution. 
  11  # 
  12  # For more information, visit madgraph.phys.ucl.ac.be and amcatnlo.web.cern.ch 
  13  # 
  14  ################################################################################ 
  15  """ Create gen_crossxhtml """ 
  16   
  17   
  18  import os 
  19  import math 
  20  import re 
  21  import pickle 
  22  import re 
  23  import glob 
  24  import logging 
  25   
  26  try: 
  27      import madgraph 
  28  except ImportError: 
  29      import internal.files as files 
  30      import internal.save_load_object as save_load_object 
  31      import internal.lhe_parser as lhe_parser 
  32      import internal.misc as misc 
  33      import internal.banner as bannerlib 
  34  else: 
  35      import madgraph.iolibs.files as files 
  36      import madgraph.iolibs.save_load_object as save_load_object 
  37      import madgraph.various.lhe_parser as lhe_parser 
  38      import madgraph.various.misc as misc 
  39      import madgraph.various.banner as bannerlib 
  40   
  41  pjoin = os.path.join 
  42  exists = os.path.exists 
  43  logger = logging.getLogger('madgraph.stdout') # -> stdout 
  44   
  45   
  46   
  47  crossxhtml_template = """ 
  48  <HTML>  
  49  <HEAD>  
  50      %(refresh)s  
  51      <META HTTP-EQUIV="EXPIRES" CONTENT="20" >  
  52      <TITLE>Online Event Generation</TITLE> 
  53      <link rel=stylesheet href="./HTML/mgstyle.css" type="text/css"> 
  54  </HEAD> 
  55  <BODY> 
  56  <script type="text/javascript"> 
  57  function UrlExists(url) { 
  58    var http = new XMLHttpRequest(); 
  59    http.open('HEAD', url, false); 
  60    try{ 
  61       http.send() 
  62       } 
  63    catch(err){ 
  64     return 1==2; 
  65    } 
  66    return http.status!=404; 
  67  } 
  68  function check_link(url,alt, id){ 
  69      var obj = document.getElementById(id); 
  70      if ( ! UrlExists(url)){ 
  71         if ( ! UrlExists(alt)){ 
  72           obj.href = url; 
  73           return 1==1; 
  74          } 
  75         obj.href = alt; 
  76         return 1 == 2; 
  77      } 
  78      obj.href = url; 
  79      return 1==1; 
  80  } 
  81  </script>     
  82      <H2 align=center> Results in the %(model)s for %(process)s </H2>  
  83      <HR> 
  84      %(status)s 
  85      <br> 
  86      <br> 
  87      <H2 align="center"> Available Results </H2> 
  88          <TABLE BORDER=2 align="center">   
  89              <TR align="center"> 
  90                  <TH>Run</TH>  
  91                  <TH>Collider</TH>  
  92                  <TH> Banner </TH> 
  93                  <TH> %(numerical_title)s </TH>  
  94                  <TH> Events  </TH> 
  95                  <TH> Data </TH>   
  96                  <TH>Output</TH> 
  97                  <TH>Action</TH>  
  98              </TR>       
  99              %(old_run)s 
 100          </TABLE> 
 101      <H3 align=center><A HREF="./index.html"> Main Page </A></H3> 
 102  </BODY>  
 103  </HTML>  
 104  """ 
 105   
 106  status_template = """ 
 107  <H2 ALIGN=CENTER> Currently Running %(run_mode_string)s</H2> 
 108  <TABLE BORDER=2 ALIGN=CENTER> 
 109      <TR ALIGN=CENTER> 
 110          <TH nowrap ROWSPAN=2 font color="#0000FF"> Run Name </TH> 
 111          <TH nowrap ROWSPAN=2 font color="#0000FF"> Tag Name </TH> 
 112          <TH nowrap ROWSPAN=2 font color="#0000FF"> Cards </TH>    
 113          <TH nowrap ROWSPAN=2 font color="#0000FF"> Results </TH>  
 114          <TH nowrap ROWSPAN=1 COLSPAN=3 font color="#0000FF"> Status/Jobs </TH> 
 115      </TR> 
 116          <TR>  
 117              <TH>   Queued </TH> 
 118              <TH>  Running </TH> 
 119              <TH> Done  </TH> 
 120          </TR> 
 121      <TR ALIGN=CENTER>  
 122          <TD nowrap ROWSPAN=2> %(run_name)s </TD> 
 123          <TD nowrap ROWSPAN=2> %(tag_name)s </TD> 
 124          <TD nowrap ROWSPAN=2> <a href="./Cards/param_card.dat">param_card</a><BR> 
 125                      <a href="./Cards/run_card.dat">run_card</a><BR> 
 126                      %(plot_card)s 
 127                      %(pythia_card)s 
 128                      %(pgs_card)s 
 129                      %(delphes_card)s 
 130                      %(shower_card)s 
 131                      %(fo_analyse_card)s 
 132          </TD> 
 133          <TD nowrap ROWSPAN=2> %(results)s </TD>  
 134          %(status)s 
 135   </TR> 
 136   <TR></TR> 
 137     %(stop_form)s 
 138   </TABLE> 
 139  """ 
 140   
141 -class AllResults(dict):
142 """Store the results for all the run of a given directory""" 143 144 web = False 145
146 - def __init__(self, model, process, path, recreateold=True):
147 148 dict.__init__(self) 149 self.order = [] 150 self.lastrun = None 151 self.process = ', '.join(process) 152 if len(self.process) > 60: 153 pos = self.process[50:].find(',') 154 if pos != -1: 155 self.process = self.process[:50+pos] + ', ...' 156 self.path = path 157 self.model = model 158 self.status = '' 159 self.unit = 'pb' 160 self.current = None 161 162 # Check if some directory already exists and if so add them 163 runs = [d for d in os.listdir(pjoin(path, 'Events')) if 164 os.path.isdir(pjoin(path, 'Events', d))] 165 166 if runs: 167 if recreateold: 168 for run in runs: 169 self.readd_old_run(run) 170 if self.order: 171 self.current = self[self.order[-1]] 172 else: 173 logger.warning("Previous runs exists but they will not be present in the html output.")
174
175 - def readd_old_run(self, run_name):
176 """ re-create the data-base from scratch if the db was remove """ 177 178 event_path = pjoin(self.path, "Events", run_name, "unweighted_events.lhe") 179 180 try: 181 import internal 182 except ImportError: 183 import madgraph.various.banner as bannerlib 184 else: 185 import internal.banner as bannerlib 186 187 if os.path.exists("%s.gz" % event_path): 188 misc.gunzip(event_path, keep=True) 189 if not os.path.exists(event_path): 190 return 191 banner = bannerlib.Banner(event_path) 192 193 # load the information to add a new Run: 194 run_card = banner.charge_card("run_card") 195 process = banner.get_detail("proc_card", "generate") 196 #create the new object 197 run = RunResults(run_name, run_card, process, self.path) 198 run.recreate(banner) 199 self[run_name] = run 200 self.order.append(run_name)
201 202
203 - def def_current(self, run, tag=None):
204 """define the name of the current run 205 The first argument can be a OneTagResults 206 """ 207 208 if isinstance(run, OneTagResults): 209 self.current = run 210 self.lastrun = run['run_name'] 211 return 212 213 assert run in self or run == None 214 self.lastrun = run 215 if run: 216 if not tag: 217 self.current = self[run][-1] 218 else: 219 assert tag in self[run].tags 220 index = self[run].tags.index(tag) 221 self.current = self[run][index] 222 223 else: 224 self.current = None
225
226 - def delete_run(self, run_name, tag=None):
227 """delete a run from the database""" 228 229 assert run_name in self 230 231 if not tag : 232 if self.current and self.current['run_name'] == run_name: 233 self.def_current(None) 234 del self[run_name] 235 self.order.remove(run_name) 236 if self.lastrun == run_name: 237 self.lastrun = None 238 else: 239 assert tag in [a['tag'] for a in self[run_name]] 240 RUN = self[run_name] 241 if len(RUN) == 1: 242 self.delete_run(run_name) 243 return 244 RUN.remove(tag) 245 246 #update the html 247 self.output()
248
249 - def def_web_mode(self, web):
250 """define if we are in web mode or not """ 251 if web is True: 252 try: 253 web = os.environ['SERVER_NAME'] 254 except Exception: 255 web = 'my_computer' 256 self['web'] = web 257 self.web = web
258
259 - def add_run(self, name, run_card, current=True):
260 """ Adding a run to this directory""" 261 262 tag = run_card['run_tag'] 263 if name in self.order: 264 #self.order.remove(name) # Reorder the run to put this one at the end 265 if tag in self[name].tags: 266 if self[name].return_tag(tag).parton and len(self[name]) > 1: 267 #move the parton information before the removr 268 self[name].return_tag(self[name][1]['tag']).parton = \ 269 self[name].return_tag(tag).parton 270 if len(self[name]) > 1: 271 self[name].remove(tag) # Remove previous tag if define 272 self[name].add(OneTagResults(name, run_card, self.path)) 273 else: 274 #add the new tag run 275 self[name].add(OneTagResults(name, run_card, self.path)) 276 new = self[name] 277 else: 278 new = RunResults(name, run_card, self.process, self.path) 279 self[name] = new 280 self.order.append(name) 281 282 if current: 283 self.def_current(name) 284 if new.info['unit'] == 'GeV': 285 self.unit = 'GeV'
286
287 - def update(self, status, level, makehtml=True, error=False):
288 """update the current run status""" 289 if self.current: 290 self.current.update_status(level) 291 self.status = status 292 if self.current and self.current.debug and self.status and not error: 293 self.current.debug = None 294 295 if makehtml: 296 self.output()
297
298 - def resetall(self, main_path=None):
299 """check the output status of all run 300 main_path redefines the path associated to the run (allowing to move 301 the directory) 302 """ 303 304 self.path = main_path 305 306 for key,run in self.items(): 307 if key == 'web': 308 continue 309 for i,subrun in enumerate(run): 310 self.def_current(subrun) 311 self.clean() 312 self.current.event_path = pjoin(main_path,'Events') 313 self.current.me_dir = main_path 314 if i==0: 315 self.current.update_status() 316 else: 317 self.current.update_status(nolevel='parton') 318 self.output()
319
320 - def clean(self, levels = ['all'], run=None, tag=None):
321 """clean the run for the levels""" 322 323 if not run and not self.current: 324 return 325 to_clean = self.current 326 if run and not tag: 327 for tagrun in self[run]: 328 self.clean(levels, run, tagrun['tag']) 329 return 330 331 if run: 332 to_clean = self[run].return_tag(tag) 333 else: 334 run = to_clean['run_name'] 335 336 if 'all' in levels: 337 levels = ['parton', 'pythia', 'pgs', 'delphes', 'channel'] 338 339 if 'parton' in levels: 340 to_clean.parton = [] 341 if 'pythia' in levels: 342 to_clean.pythia = [] 343 if 'pgs' in levels: 344 to_clean.pgs = [] 345 if 'delphes' in levels: 346 to_clean.delphes = []
347 348
349 - def save(self):
350 """Save the results of this directory in a pickle file""" 351 filename = pjoin(self.path, 'HTML', 'results.pkl') 352 save_load_object.save_to_file(filename, self)
353
354 - def add_detail(self, name, value, run=None, tag=None):
355 """ add information to current run (cross/error/event)""" 356 assert name in ['cross', 'error', 'nb_event', 'cross_pythia', 357 'nb_event_pythia','error_pythia', 'run_mode', 358 'run_statistics'] 359 360 if not run and not self.current: 361 return 362 363 if not run: 364 run = self.current 365 else: 366 run = self[run].return_tag(tag) 367 368 if name == 'cross_pythia': 369 run['cross_pythia'] = float(value) 370 elif name == 'nb_event': 371 run[name] = int(value) 372 elif name == 'nb_event_pythia': 373 run[name] = int(value) 374 elif name in ['run_mode','run_statistics']: 375 run[name] = value 376 else: 377 run[name] = float(value)
378
379 - def get_detail(self, name, run=None, tag=None):
380 """ add information to current run (cross/error/event)""" 381 assert name in ['cross', 'error', 'nb_event', 'cross_pythia', 382 'nb_event_pythia','error_pythia', 'run_mode', 383 'run_statistics'] 384 385 if not run and not self.current: 386 return None 387 388 if not run: 389 run = self.current 390 else: 391 run = self[run].return_tag(tag) 392 393 return run[name]
394
395 - def output(self):
396 """ write the output file """ 397 398 # 1) Create the text for the status directory 399 if self.status and self.current: 400 if isinstance(self.status, str): 401 status = '<td ROWSPAN=2 colspan=4>%s</td>' % self.status 402 else: 403 s = list(self.status) 404 if s[0] == '$events': 405 if self.current['nb_event']: 406 nevent = self.current['nb_event'] 407 else: 408 nevent = self[self.current['run_name']][0]['nb_event'] 409 if nevent: 410 s[0] = nevent - int(s[1]) -int(s[2]) 411 else: 412 s[0] = '' 413 status ='''<td> %s </td> <td> %s </td> <td> %s </td> 414 </tr><tr><td colspan=3><center> %s </center></td>''' % (s[0],s[1], s[2], s[3]) 415 416 417 status_dict = {'status': status, 418 'cross': self.current['cross'], 419 'error': self.current['error'], 420 'run_name': self.current['run_name'], 421 'tag_name': self.current['tag'], 422 'unit': self[self.current['run_name']].info['unit']} 423 # add the run_mode_string for amcatnlo_run 424 if 'run_mode' in self.current.keys(): 425 run_mode_string = {'aMC@NLO': '(aMC@NLO)', 426 'aMC@LO': '(aMC@LO)', 427 'noshower': '(aMC@NLO)', 428 'noshowerLO': '(aMC@LO)', 429 'NLO': '(NLO f.o.)', 430 'LO': '(LO f.o.)', 431 'madevent':''} 432 status_dict['run_mode_string'] = run_mode_string[self.current['run_mode']] 433 else: 434 status_dict['run_mode_string'] = '' 435 436 437 if exists(pjoin(self.path, 'HTML',self.current['run_name'], 438 'results.html')): 439 status_dict['results'] = """<A HREF="./HTML/%(run_name)s/results.html">%(cross).4g <font face=symbol>&#177;</font> %(error).4g (%(unit)s)</A>""" % status_dict 440 else: 441 status_dict['results'] = "No results yet" 442 if exists(pjoin(self.path, 'Cards', 'plot_card.dat')): 443 status_dict['plot_card'] = """ <a href="./Cards/plot_card.dat">plot_card</a><BR>""" 444 else: 445 status_dict['plot_card'] = "" 446 if exists(pjoin(self.path, 'Cards', 'pythia_card.dat')): 447 status_dict['pythia_card'] = """ <a href="./Cards/pythia_card.dat">pythia_card</a><BR>""" 448 else: 449 status_dict['pythia_card'] = "" 450 if exists(pjoin(self.path, 'Cards', 'pgs_card.dat')): 451 status_dict['pgs_card'] = """ <a href="./Cards/pgs_card.dat">pgs_card</a><BR>""" 452 else: 453 status_dict['pgs_card'] = "" 454 if exists(pjoin(self.path, 'Cards', 'delphes_card.dat')): 455 status_dict['delphes_card'] = """ <a href="./Cards/delphes_card.dat">delphes_card</a><BR>""" 456 else: 457 status_dict['delphes_card'] = "" 458 if exists(pjoin(self.path, 'Cards', 'shower_card.dat')): 459 status_dict['shower_card'] = """ <a href="./Cards/shower_card.dat">shower_card</a><BR>""" 460 else: 461 status_dict['shower_card'] = "" 462 if exists(pjoin(self.path, 'Cards', 'FO_analyse_card.dat')): 463 status_dict['fo_analyse_card'] = """ <a href="./Cards/FO_analyse_card.dat">FO_analyse_card</a><BR>""" 464 else: 465 status_dict['fo_analyse_card'] = "" 466 467 if self.web: 468 status_dict['stop_form'] = """ 469 <TR ALIGN=CENTER><TD COLSPAN=7 text-align=center> 470 <FORM ACTION="http://%(web)s/cgi-bin/RunProcess/handle_runs-pl" ENCTYPE="multipart/form-data" METHOD="POST"> 471 <INPUT TYPE=HIDDEN NAME=directory VALUE="%(me_dir)s"> 472 <INPUT TYPE=HIDDEN NAME=whattodo VALUE="stop_job"> 473 <INPUT TYPE=SUBMIT VALUE="Stop Current Job"> 474 </FORM></TD></TR>""" % {'me_dir': self.path, 'web': self.web} 475 else: 476 status_dict['stop_form'] = "" 477 478 479 status = status_template % status_dict 480 refresh = "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"10\">" 481 else: 482 status ='' 483 refresh = '' 484 485 486 # See if we need to incorporate the button for submission 487 if os.path.exists(pjoin(self.path, 'RunWeb')): 488 running = True 489 else: 490 running = False 491 492 # 2) Create the text for the old run: 493 old_run = '' 494 for key in self.order: 495 old_run += self[key].get_html(self.path, web=self.web, running=running) 496 497 text_dict = {'process': self.process, 498 'model': self.model, 499 'status': status, 500 'old_run': old_run, 501 'refresh': refresh, 502 'numerical_title': self.unit == 'pb' and 'Cross section (pb)'\ 503 or 'Width (GeV)'} 504 505 text = crossxhtml_template % text_dict 506 open(pjoin(self.path,'crossx.html'),'w').write(text)
507 508
509 -class AllResultsNLO(AllResults):
510 """Store the results for a NLO run of a given directory""" 511
512 - def __init__(self,model, process, path, recreateold=False):
513 return AllResults.__init__(self, model, process, path, recreateold=recreateold)
514 515
516 -class RunResults(list):
517 """The list of all OneTagResults""" 518
519 - def __init__(self, run_name, run_card, process, path):
520 """initialize the object""" 521 522 self.info = {'run_name': run_name,'me_dir':path} 523 self.tags = [run_card['run_tag']] 524 525 # Set the collider information 526 data = process.split('>',1)[0].split() 527 if len(data) == 2: 528 name1,name2 = data 529 if run_card['lpp1'] == -1: 530 name1 = ' p~' 531 elif run_card['lpp1'] == 1: 532 name1 = ' p' 533 elif run_card['lpp1'] in [2,3]: 534 name1 = ' a' 535 if run_card['lpp2'] == -1: 536 name2 = 'p~' 537 elif run_card['lpp2'] == 1: 538 name2 = ' p' 539 elif run_card['lpp2'] == [2,3]: 540 name2 = ' a' 541 self.info['collider'] = '''%s %s <br> %s x %s GeV''' % \ 542 (name1, name2, run_card['ebeam1'], run_card['ebeam2']) 543 self.info['unit'] = 'pb' 544 else: 545 self.info['collider'] = 'decay' 546 self.info['unit'] = 'GeV' 547 548 self.append(OneTagResults(run_name, run_card, path))
549 550
551 - def get_html(self, output_path, **opt):
552 """WRITE HTML OUTPUT""" 553 try: 554 self.web = opt['web'] 555 self.info['web'] = self.web 556 except Exception: 557 self.web = False 558 559 # check if more than one parton output 560 parton = [r for r in self if r.parton] 561 # clean wrong previous run link 562 if len(parton)>1: 563 for p in parton[:-1]: 564 p.parton = [] 565 566 dico = self.info 567 dico['run_span'] = sum([tag.get_nb_line() for tag in self], 1) -1 568 dico['tag_data'] = '\n'.join([tag.get_html(self) for tag in self]) 569 text = """ 570 <tr> 571 <td rowspan=%(run_span)s>%(run_name)s</td> 572 <td rowspan=%(run_span)s><center> %(collider)s </center></td> 573 %(tag_data)s 574 </tr> 575 """ % dico 576 577 if self.web: 578 579 text = text % self.info 580 581 return text
582 583
584 - def return_tag(self, name):
585 586 for data in self: 587 if data['tag'] == name: 588 return data 589 590 if name is None: 591 # return last entry 592 return self[-1] 593 594 raise Exception, '%s is not a valid tag' % name
595
596 - def recreate(self, banner):
597 """Fully recreate the information due to a hard removal of the db 598 Work for LO ONLY!""" 599 600 run_name = self.info["run_name"] 601 run_card = banner.get("run_card") 602 path = self.info["me_dir"] 603 # Recover the main information (cross-section/number of event) 604 informations = banner['mggenerationinfo'] 605 #number of events 606 nb_event = re.search(r"Number\s*of\s*Events\s*:\s*(\d*)", informations) 607 if nb_event: 608 nb_event = int(nb_event.group(1)) 609 else: 610 nb_event = 0 611 612 # cross-section 613 cross = re.search(r"Integrated\s*weight\s*\(\s*pb\s*\)\s*:\s*([\+\-\d.e]+)", informations, 614 re.I) 615 if cross: 616 cross = float(cross.group(1)) 617 else: 618 cross = 0 619 620 # search pythia file for tag: tag_1_pythia.log 621 path = pjoin(self.info['me_dir'],'Events', self.info['run_name']) 622 files = [pjoin(path, f) for f in os.listdir(path) if 623 os.path.isfile(pjoin(path,f)) and f.endswith('pythia.log')] 624 #order them by creation date. 625 files.sort(key=lambda x: os.path.getmtime(x)) 626 tags = [os.path.basename(name[:-11]) for name in files] 627 628 629 # No pythia only a single run: 630 if not tags: 631 self[-1]['nb_event'] = nb_event 632 self[-1]['cross'] = cross 633 634 #Loop over pythia run 635 for tag in tags: 636 if tag not in self.tags: 637 tagresult = OneTagResults(run_name, run_card, path) 638 tagresult['tag'] = tag 639 self.add(tagresult) 640 else: 641 tagresult = self.return_tag(tag) 642 tagresult['nb_event'] = nb_event 643 tagresult['cross'] = cross 644 if run_card['ickkw'] != 0: 645 #parse the file to have back the information 646 pythia_log = misc.BackRead(pjoin(path, '%s_pythia.log' % tag)) 647 pythiare = re.compile("\s*I\s+0 All included subprocesses\s+I\s+(?P<generated>\d+)\s+(?P<tried>\d+)\s+I\s+(?P<xsec>[\d\.D\-+]+)\s+I") 648 for line in pythia_log: 649 info = pythiare.search(line) 650 if not info: 651 continue 652 try: 653 # Pythia cross section in mb, we want pb 654 sigma_m = float(info.group('xsec').replace('D','E')) *1e9 655 Nacc = int(info.group('generated')) 656 except ValueError: 657 # xsec is not float - this should not happen 658 tagresult['cross_pythia'] = 0 659 tagresult['nb_event_pythia'] = 0 660 tagresult['error_pythia'] = 0 661 else: 662 tagresult['cross_pythia'] = sigma_m 663 tagresult['nb_event_pythia'] = Nacc 664 tagresult['error_pythia'] = 0 665 break 666 pythia_log.close()
667 668
669 - def is_empty(self):
670 """Check if this run contains smtg else than html information""" 671 672 if not self: 673 return True 674 if len(self) > 1: 675 return False 676 677 data = self[0] 678 if data.parton or data.pythia or data.pgs or data.delphes: 679 return False 680 else: 681 return True
682
683 - def add(self, obj):
684 """ """ 685 686 assert isinstance(obj, OneTagResults) 687 tag = obj['tag'] 688 assert tag not in self.tags 689 self.tags.append(tag) 690 self.append(obj)
691
692 - def get_last_pythia(self):
693 for i in range(1, len(self)+1): 694 if self[-i].pythia: 695 return self[-i]['tag']
696
697 - def get_current_info(self):
698 699 output = {} 700 current = self[-1] 701 # Check that cross/nb_event/error are define 702 if current.pythia and not current['nb_event'] and len(self) > 1: 703 output['nb_event'] = self[-2]['nb_event'] 704 output['cross'] = self[-2]['cross'] 705 output['error'] = self[-2]['error'] 706 elif (current.pgs or current.delphes) and not current['nb_event'] and len(self) > 1: 707 if self[-2]['cross_pythia'] and self[-2]['nb_event_pythia']: 708 output['cross'] = self[-2]['cross_pythia'] 709 output['nb_event'] = self[-2]['nb_event_pythia'] 710 output['error'] = self[-2]['error_pythia'] 711 else: 712 output['nb_event'] = self[-2]['nb_event'] 713 output['cross'] = self[-2]['cross'] 714 output['error'] = self[-2]['error'] 715 elif current['cross']: 716 return current 717 elif len(self) > 1: 718 output['nb_event'] = self[-2]['nb_event'] 719 output['cross'] = self[-2]['cross'] 720 output['error'] = self[-2]['error'] 721 else: 722 output['nb_event'] = 0 723 output['cross'] = 0 724 output['error'] = 1e-99 725 return output
726 727
728 - def remove(self, tag):
729 730 assert tag in self.tags 731 732 obj = [o for o in self if o['tag']==tag][0] 733 self.tags.remove(tag) 734 list.remove(self, obj)
735 736 737
738 -class OneTagResults(dict):
739 """ Store the results of a specific run """ 740
741 - def __init__(self, run_name, run_card, path):
742 """initialize the object""" 743 744 # define at run_result 745 self['run_name'] = run_name 746 self['tag'] = run_card['run_tag'] 747 self.event_path = pjoin(path,'Events') 748 self.me_dir = path 749 self.debug = None 750 751 # Default value 752 self['nb_event'] = 0 753 self['cross'] = 0 754 self['cross_pythia'] = '' 755 self['nb_event_pythia'] = 0 756 self['error'] = 0 757 self['run_mode'] = 'madevent' 758 self.parton = [] 759 self.reweight = [] 760 self.pythia = [] 761 self.pgs = [] 762 self.delphes = [] 763 self.shower = [] 764 # data 765 self.status = '' 766 767 # Dictionary with (Pdir,G) as keys and sum_html.RunStatistics instances 768 # as values 769 self['run_statistics'] = {}
770 771
772 - def update_status(self, level='all', nolevel=[]):
773 """update the status of the current run """ 774 775 exists = os.path.exists 776 run = self['run_name'] 777 tag =self['tag'] 778 779 path = pjoin(self.event_path, run) 780 html_path = pjoin(self.event_path, os.pardir, 'HTML', run) 781 782 # Check if the output of the last status exists 783 if level in ['gridpack','all']: 784 if 'gridpack' not in self.parton and \ 785 exists(pjoin(path,os.pardir ,os.pardir,"%s_gridpack.tar.gz" % run)): 786 self.parton.append('gridpack') 787 # Check if the output of the last status exists 788 if level in ['reweight','all']: 789 if 'plot' not in self.reweight and \ 790 exists(pjoin(html_path,"plots_%s.html" % tag)): 791 self.reweight.append('plot') 792 793 if level in ['parton','all'] and 'parton' not in nolevel: 794 795 if 'lhe' not in self.parton and \ 796 (exists(pjoin(path,"unweighted_events.lhe.gz")) or 797 exists(pjoin(path,"unweighted_events.lhe")) or 798 exists(pjoin(path,"events.lhe.gz")) or 799 exists(pjoin(path,"events.lhe"))): 800 self.parton.append('lhe') 801 802 if 'root' not in self.parton and \ 803 exists(pjoin(path,"unweighted_events.root")): 804 self.parton.append('root') 805 806 if 'plot' not in self.parton and \ 807 exists(pjoin(html_path,"plots_parton.html")): 808 self.parton.append('plot') 809 810 if 'param_card' not in self.parton and \ 811 exists(pjoin(path, "param_card.dat")): 812 self.parton.append('param_card') 813 814 if 'syst' not in self.parton and \ 815 exists(pjoin(path, "%s_parton_syscalc.log" %self['tag'])): 816 self.parton.append('syst') 817 818 for kind in ['top','HwU','pdf','ps']: 819 if misc.glob("*.%s" % kind, path): 820 if self['run_mode'] in ['LO', 'NLO']: 821 self.parton.append('%s' % kind) 822 if exists(pjoin(path,'summary.txt')): 823 self.parton.append('summary.txt') 824 825 826 if level in ['shower','all'] and 'shower' not in nolevel \ 827 and self['run_mode'] != 'madevent': 828 # this is for hep/top/HwU files from amcatnlo 829 if misc.glob("*.hep", path) + \ 830 misc.glob("*.hep.gz", path): 831 self.shower.append('hep') 832 833 if 'plot' not in self.shower and \ 834 exists(pjoin(html_path,"plots_shower_%s.html" % tag)): 835 self.shower.append('plot') 836 837 if misc.glob("*.hepmc", path) + \ 838 misc.glob("*.hepmc.gz", path): 839 self.shower.append('hepmc') 840 841 for kind in ['top','HwU','pdf','ps']: 842 if misc.glob('*.' + kind, path): 843 if self['run_mode'] in ['LO', 'NLO']: 844 self.parton.append('%s' % kind) 845 else: 846 self.shower.append('%s' % kind) 847 848 if level in ['pythia', 'all']: 849 850 if 'plot' not in self.pythia and \ 851 exists(pjoin(html_path,"plots_pythia_%s.html" % tag)): 852 self.pythia.append('plot') 853 854 if 'lhe' not in self.pythia and \ 855 (exists(pjoin(path,"%s_pythia_events.lhe.gz" % tag)) or 856 exists(pjoin(path,"%s_pythia_events.lhe" % tag))): 857 self.pythia.append('lhe') 858 859 860 if 'hep' not in self.pythia and \ 861 (exists(pjoin(path,"%s_pythia_events.hep.gz" % tag)) or 862 exists(pjoin(path,"%s_pythia_events.hep" % tag))): 863 self.pythia.append('hep') 864 865 if 'rwt' not in self.pythia and \ 866 (exists(pjoin(path,"%s_syscalc.dat.gz" % tag)) or 867 exists(pjoin(path,"%s_syscalc.dat" % tag))): 868 self.pythia.append('rwt') 869 870 if 'root' not in self.pythia and \ 871 exists(pjoin(path,"%s_pythia_events.root" % tag)): 872 self.pythia.append('root') 873 874 if 'lheroot' not in self.pythia and \ 875 exists(pjoin(path,"%s_pythia_lhe_events.root" % tag)): 876 self.pythia.append('lheroot') 877 878 if 'log' not in self.pythia and \ 879 exists(pjoin(path,"%s_pythia.log" % tag)): 880 self.pythia.append('log') 881 882 if level in ['pgs', 'all']: 883 884 if 'plot' not in self.pgs and \ 885 exists(pjoin(html_path,"plots_pgs_%s.html" % tag)): 886 self.pgs.append('plot') 887 888 if 'lhco' not in self.pgs and \ 889 (exists(pjoin(path,"%s_pgs_events.lhco.gz" % tag)) or 890 exists(pjoin(path,"%s_pgs_events.lhco." % tag))): 891 self.pgs.append('lhco') 892 893 if 'root' not in self.pgs and \ 894 exists(pjoin(path,"%s_pgs_events.root" % tag)): 895 self.pgs.append('root') 896 897 if 'log' not in self.pgs and \ 898 exists(pjoin(path,"%s_pgs.log" % tag)): 899 self.pgs.append('log') 900 901 if level in ['delphes', 'all']: 902 903 if 'plot' not in self.delphes and \ 904 exists(pjoin(html_path,"plots_delphes_%s.html" % tag)): 905 self.delphes.append('plot') 906 907 if 'lhco' not in self.delphes and \ 908 (exists(pjoin(path,"%s_delphes_events.lhco.gz" % tag)) or 909 exists(pjoin(path,"%s_delphes_events.lhco" % tag))): 910 self.delphes.append('lhco') 911 912 if 'root' not in self.delphes and \ 913 exists(pjoin(path,"%s_delphes_events.root" % tag)): 914 self.delphes.append('root') 915 916 if 'log' not in self.delphes and \ 917 exists(pjoin(path,"%s_delphes.log" % tag)): 918 self.delphes.append('log')
919 926 931 1056 1057
1058 - def get_nb_line(self):
1059 1060 nb_line = 0 1061 for i in [self.parton, self.reweight, self.pythia, self.pgs, self.delphes, self.shower]: 1062 if len(i): 1063 nb_line += 1 1064 return max([nb_line,1])
1065 1066
1067 - def get_html(self, runresults):
1068 """create the html output linked to the this tag 1069 RunResults is given in case of cross-section need to be taken 1070 from a previous run 1071 """ 1072 1073 1074 tag_template = """ 1075 <td rowspan=%(tag_span)s> <a href="./Events/%(run)s/%(run)s_%(tag)s_banner.txt">%(tag)s</a>%(debug)s</td> 1076 %(subruns)s""" 1077 1078 # Compute the text for eachsubpart 1079 1080 sub_part_template_parton = """ 1081 <td rowspan=%(cross_span)s><center><a href="./HTML/%(run)s/results.html"> %(cross).4g <font face=symbol>&#177;</font> %(err).2g</a> %(syst)s </center></td> 1082 <td rowspan=%(cross_span)s><center> %(nb_event)s<center></td><td> %(type)s </td> 1083 <td> %(links)s</td> 1084 <td> %(action)s</td> 1085 </tr>""" 1086 1087 sub_part_template_reweight = """ 1088 <td rowspan=%(cross_span)s><center> %(cross).4g </center></td> 1089 <td rowspan=%(cross_span)s><center> %(nb_event)s<center></td><td> %(type)s </td> 1090 <td> %(links)s</td> 1091 <td> %(action)s</td> 1092 </tr>""" 1093 1094 sub_part_template_pgs = """ 1095 <td> %(type)s </td> 1096 <td> %(links)s</td> 1097 <td> %(action)s</td> 1098 </tr>""" 1099 1100 sub_part_template_shower = """ 1101 <td> %(type)s %(run_mode)s </td> 1102 <td> %(links)s</td> 1103 <td> %(action)s</td> 1104 </tr>""" 1105 1106 # Compute the HTMl output for subpart 1107 nb_line = self.get_nb_line() 1108 # Check that cross/nb_event/error are define 1109 if self.pythia and not self['nb_event']: 1110 try: 1111 self['nb_event'] = runresults[-2]['nb_event'] 1112 self['cross'] = runresults[-2]['cross'] 1113 self['error'] = runresults[-2]['error'] 1114 except Exception: 1115 pass 1116 1117 elif (self.pgs or self.delphes) and not self['nb_event'] and \ 1118 len(runresults) > 1: 1119 if runresults[-2]['cross_pythia'] and runresults[-2]['cross']: 1120 self['cross'] = runresults[-2]['cross_pythia'] 1121 self['error'] = runresults[-2]['error_pythia'] 1122 self['nb_event'] = runresults[-2]['nb_event_pythia'] 1123 else: 1124 self['nb_event'] = runresults[-2]['nb_event'] 1125 self['cross'] = runresults[-2]['cross'] 1126 self['error'] = runresults[-2]['error'] 1127 1128 1129 first = None 1130 subresults_html = '' 1131 for ttype in ['parton', 'pythia', 'pgs', 'delphes','reweight','shower']: 1132 data = getattr(self, ttype) 1133 if not data: 1134 continue 1135 1136 local_dico = {'type': ttype, 'run': self['run_name'], 'syst': ''} 1137 if 'run_mode' in self.keys(): 1138 local_dico['run_mode'] = self['run_mode'] 1139 else: 1140 local_dico['run_mode'] = "" 1141 if not first: 1142 if ttype == 'reweight': 1143 template = sub_part_template_reweight 1144 else: 1145 template = sub_part_template_parton 1146 first = ttype 1147 if ttype=='parton' and self['cross_pythia']: 1148 local_dico['cross_span'] = 1 1149 local_dico['cross'] = self['cross'] 1150 local_dico['err'] = self['error'] 1151 local_dico['nb_event'] = self['nb_event'] 1152 if 'syst' in self.parton: 1153 local_dico['syst'] = '<font face=symbol>&#177;</font> <a href="./Events/%(run_name)s/%(tag)s_parton_syscalc.log">systematics</a>' \ 1154 % {'run_name':self['run_name'], 'tag': self['tag']} 1155 elif self['cross_pythia']: 1156 if self.parton: 1157 local_dico['cross_span'] = nb_line -1 1158 else: 1159 local_dico['cross_span'] = nb_line 1160 if self['nb_event_pythia']: 1161 local_dico['nb_event'] = self['nb_event_pythia'] 1162 else: 1163 local_dico['nb_event'] = 0 1164 local_dico['cross'] = self['cross_pythia'] 1165 local_dico['err'] = self['error_pythia'] 1166 if 'rwt' in self.pythia: 1167 local_dico['syst'] = '<font face=symbol>&#177;</font> <a href="./Events/%(run_name)s/%(tag)s_Pythia_syscalc.log">systematics</a>' \ 1168 % {'run_name':self['run_name'], 'tag': self['tag']} 1169 else: 1170 local_dico['type'] += ' %s' % self['run_mode'] 1171 local_dico['cross_span'] = nb_line 1172 local_dico['cross'] = self['cross'] 1173 local_dico['err'] = self['error'] 1174 local_dico['nb_event'] = self['nb_event'] 1175 if 'syst' in self.parton: 1176 local_dico['syst'] = '<font face=symbol>&#177;</font> <a href="./Events/%(run_name)s/%(tag)s_parton_syscalc.log">systematics</a>' \ 1177 % {'run_name':self['run_name'], 'tag': self['tag']} 1178 1179 elif ttype == 'pythia' and self['cross_pythia']: 1180 template = sub_part_template_parton 1181 if self.parton: 1182 local_dico['cross_span'] = nb_line - 1 1183 if self['nb_event_pythia']: 1184 local_dico['nb_event'] = self['nb_event_pythia'] 1185 else: 1186 local_dico['nb_event'] = 0 1187 else: 1188 local_dico['cross_span'] = nb_line 1189 local_dico['nb_event'] = self['nb_event'] 1190 if 'rwt' in self.pythia: 1191 local_dico['syst'] = '<font face=symbol>&#177;</font> <a href="./Events/%(run_name)s/%(tag)s_Pythia_syscalc.log">systematics</a>' \ 1192 % {'run_name':self['run_name'], 'tag': self['tag']} 1193 local_dico['cross'] = self['cross_pythia'] 1194 local_dico['err'] = self['error_pythia'] 1195 1196 elif ttype == 'shower': 1197 template = sub_part_template_shower 1198 if self.parton: 1199 local_dico['cross_span'] = nb_line - 1 1200 else: 1201 local_dico['cross_span'] = nb_line 1202 else: 1203 template = sub_part_template_pgs 1204 1205 # Fill the links 1206 local_dico['links'] = self.get_links(ttype) 1207 1208 # Fill the actions 1209 if ttype == 'parton': 1210 if runresults.web: 1211 local_dico['action'] = """ 1212 <FORM ACTION="http://%(web)s/cgi-bin/RunProcess/handle_runs-pl" ENCTYPE="multipart/form-data" METHOD="POST"> 1213 <INPUT TYPE=HIDDEN NAME=directory VALUE="%(me_dir)s"> 1214 <INPUT TYPE=HIDDEN NAME=whattodo VALUE="remove_level"> 1215 <INPUT TYPE=HIDDEN NAME=level VALUE="all"> 1216 <INPUT TYPE=HIDDEN NAME=tag VALUE=\"""" + self['tag'] + """\"> 1217 <INPUT TYPE=HIDDEN NAME=run VALUE="%(run_name)s"> 1218 <INPUT TYPE=SUBMIT VALUE="Remove run"> 1219 </FORM> 1220 1221 <FORM ACTION="http://%(web)s/cgi-bin/RunProcess/handle_runs-pl" ENCTYPE="multipart/form-data" METHOD="POST"> 1222 <INPUT TYPE=HIDDEN NAME=directory VALUE="%(me_dir)s"> 1223 <INPUT TYPE=HIDDEN NAME=whattodo VALUE="pythia"> 1224 <INPUT TYPE=HIDDEN NAME=run VALUE="%(run_name)s"> 1225 <INPUT TYPE=SUBMIT VALUE="Run Pythia"> 1226 </FORM>""" 1227 else: 1228 local_dico['action'] = self.command_suggestion_html('remove %s parton --tag=%s' \ 1229 % (self['run_name'], self['tag'])) 1230 # this the detector simulation and pythia should be available only for madevent 1231 if self['run_mode'] == 'madevent': 1232 local_dico['action'] += self.command_suggestion_html('pythia %s ' % self['run_name']) 1233 else: 1234 pass 1235 1236 elif ttype == 'shower': 1237 if runresults.web: 1238 local_dico['action'] = """ 1239 <FORM ACTION="http://%(web)s/cgi-bin/RunProcess/handle_runs-pl" ENCTYPE="multipart/form-data" METHOD="POST"> 1240 <INPUT TYPE=HIDDEN NAME=directory VALUE="%(me_dir)s"> 1241 <INPUT TYPE=HIDDEN NAME=whattodo VALUE="remove_level"> 1242 <INPUT TYPE=HIDDEN NAME=level VALUE="all"> 1243 <INPUT TYPE=HIDDEN NAME=tag VALUE=\"""" + self['tag'] + """\"> 1244 <INPUT TYPE=HIDDEN NAME=run VALUE="%(run_name)s"> 1245 <INPUT TYPE=SUBMIT VALUE="Remove run"> 1246 </FORM> 1247 1248 <FORM ACTION="http://%(web)s/cgi-bin/RunProcess/handle_runs-pl" ENCTYPE="multipart/form-data" METHOD="POST"> 1249 <INPUT TYPE=HIDDEN NAME=directory VALUE="%(me_dir)s"> 1250 <INPUT TYPE=HIDDEN NAME=whattodo VALUE="pythia"> 1251 <INPUT TYPE=HIDDEN NAME=run VALUE="%(run_name)s"> 1252 <INPUT TYPE=SUBMIT VALUE="Run Pythia"> 1253 </FORM>""" 1254 else: 1255 local_dico['action'] = self.command_suggestion_html('remove %s parton --tag=%s' \ 1256 % (self['run_name'], self['tag'])) 1257 # this the detector simulation and pythia should be available only for madevent 1258 if self['run_mode'] == 'madevent': 1259 local_dico['action'] += self.command_suggestion_html('pythia %s ' % self['run_name']) 1260 else: 1261 pass 1262 1263 elif ttype == 'pythia': 1264 if self['tag'] == runresults.get_last_pythia(): 1265 if runresults.web: 1266 local_dico['action'] = """ 1267 <FORM ACTION="http://%(web)s/cgi-bin/RunProcess/handle_runs-pl" ENCTYPE="multipart/form-data" METHOD="POST"> 1268 <INPUT TYPE=HIDDEN NAME=directory VALUE="%(me_dir)s"> 1269 <INPUT TYPE=HIDDEN NAME=whattodo VALUE="remove_level"> 1270 <INPUT TYPE=HIDDEN NAME=level VALUE="pythia"> 1271 <INPUT TYPE=HIDDEN NAME=run VALUE="%(run_name)s"> 1272 <INPUT TYPE=HIDDEN NAME=tag VALUE=\"""" + self['tag'] + """\"> 1273 <INPUT TYPE=SUBMIT VALUE="Remove pythia"> 1274 </FORM> 1275 1276 <FORM ACTION="http://%(web)s/cgi-bin/RunProcess/handle_runs-pl" ENCTYPE="multipart/form-data" METHOD="POST"> 1277 <INPUT TYPE=HIDDEN NAME=directory VALUE="%(me_dir)s"> 1278 <INPUT TYPE=HIDDEN NAME=whattodo VALUE="pgs"> 1279 <INPUT TYPE=HIDDEN NAME=run VALUE="%(run_name)s"> 1280 <INPUT TYPE=SUBMIT VALUE="Run Detector"> 1281 </FORM>""" 1282 else: 1283 local_dico['action'] = self.command_suggestion_html( 1284 'remove %s pythia --tag=%s' % \ 1285 (self['run_name'], self['tag'])) 1286 local_dico['action'] += self.command_suggestion_html( 1287 'pgs %(1)s or delphes %(1)s' % {'1': self['run_name']}) 1288 else: 1289 if runresults.web: 1290 local_dico['action'] = '' 1291 else: 1292 local_dico['action'] = self.command_suggestion_html('remove %s pythia --tag=%s'\ 1293 % (self['run_name'], self['tag'])) 1294 else: 1295 if runresults.web: 1296 local_dico['action'] = """ 1297 <FORM ACTION="http://%(web)s/cgi-bin/RunProcess/handle_runs-pl" ENCTYPE="multipart/form-data" METHOD="POST"> 1298 <INPUT TYPE=HIDDEN NAME=directory VALUE="%(me_dir)s"> 1299 <INPUT TYPE=HIDDEN NAME=whattodo VALUE="remove_level"> 1300 <INPUT TYPE=HIDDEN NAME=level VALUE=\"""" + str(type) + """\"> 1301 <INPUT TYPE=HIDDEN NAME=tag VALUE=\"""" + self['tag'] + """\"> 1302 <INPUT TYPE=HIDDEN NAME=run VALUE="%(run_name)s"> 1303 <INPUT TYPE=SUBMIT VALUE="Remove """ + str(ttype) + """\"> 1304 </FORM>""" 1305 else: 1306 local_dico['action'] = self.command_suggestion_html('remove %s %s --tag=%s' %\ 1307 (self['run_name'], ttype, self['tag'])) 1308 1309 # create the text 1310 subresults_html += template % local_dico 1311 1312 1313 if subresults_html == '': 1314 if runresults.web: 1315 action = """ 1316 <FORM ACTION="http://%(web)s/cgi-bin/RunProcess/handle_runs-pl" ENCTYPE="multipart/form-data" METHOD="POST"> 1317 <INPUT TYPE=HIDDEN NAME=directory VALUE="%(me_dir)s"> 1318 <INPUT TYPE=HIDDEN NAME=whattodo VALUE="remove_level"> 1319 <INPUT TYPE=HIDDEN NAME=level VALUE="banner"> 1320 <INPUT TYPE=HIDDEN NAME=tag VALUE=\"""" + self['tag'] + """\"> 1321 <INPUT TYPE=HIDDEN NAME=run VALUE="%(run_name)s"> 1322 <INPUT TYPE=SUBMIT VALUE="Remove Banner"> 1323 </FORM> 1324 1325 <FORM ACTION="http://%(web)s/cgi-bin/RunProcess/handle_runs-pl" ENCTYPE="multipart/form-data" METHOD="POST"> 1326 <INPUT TYPE=HIDDEN NAME=directory VALUE="%(me_dir)s"> 1327 <INPUT TYPE=HIDDEN NAME=whattodo VALUE="banner"> 1328 <INPUT TYPE=HIDDEN NAME=run VALUE="%(run_name)s"> 1329 <INPUT TYPE=SUBMIT VALUE="Run the banner"> 1330 </FORM>""" 1331 else: 1332 action = self.command_suggestion_html('remove %s banner --tag=%s' \ 1333 % (self['run_name'], self['tag'])) 1334 action += self.command_suggestion_html('banner_run %s ' % self['run_name']) 1335 1336 1337 1338 subresults_html = sub_part_template_parton % \ 1339 {'type': '', 1340 'run': self['run_name'], 1341 'cross_span': 1, 1342 'cross': self['cross'], 1343 'err': self['error'], 1344 'nb_event': self['nb_event'] and self['nb_event'] or 'No events yet', 1345 'links': 'banner only', 1346 'action': action, 1347 'run_mode': '', 1348 'syst':'' 1349 } 1350 1351 if self.debug is KeyboardInterrupt: 1352 debug = '<br><font color=red>Interrupted</font>' 1353 elif isinstance(self.debug, basestring): 1354 if not os.path.isabs(self.debug) and not self.debug.startswith('./'): 1355 self.debug = './' + self.debug 1356 elif os.path.isabs(self.debug): 1357 self.debug = os.path.relpath(self.debug, self.me_dir) 1358 debug = '<br> <a href=\'%s\'> <font color=red>ERROR</font></a>' \ 1359 % (self.debug) 1360 elif self.debug: 1361 text = str(self.debug).replace('. ','.<br>') 1362 if 'http' in text: 1363 pat = re.compile('(http[\S]*)') 1364 text = pat.sub(r'<a href=\1> here </a>', text) 1365 debug = '<br><font color=red>%s<BR>%s</font>' % \ 1366 (self.debug.__class__.__name__, text) 1367 else: 1368 debug = '' 1369 text = tag_template % {'tag_span': nb_line, 1370 'run': self['run_name'], 'tag': self['tag'], 1371 'subruns' : subresults_html, 1372 'debug':debug} 1373 1374 return text
1375 1376
1377 - def command_suggestion_html(self, command):
1378 """return html button with code suggestion""" 1379 1380 if command.startswith('pythia'): 1381 button = 'launch pythia' 1382 if command.startswith('shower'): 1383 button = 'shower events' 1384 elif command.startswith('remove banner'): 1385 button = 'remove banner' 1386 elif command.startswith('remove'): 1387 button = 'remove run' 1388 elif command.startswith('banner_run'): 1389 button = 're-run from the banner' 1390 else: 1391 button = 'launch detector simulation' 1392 if self['run_mode'] == 'madevent': 1393 header = 'Launch ./bin/madevent in a shell, and run the following command: ' 1394 else: 1395 header = 'Launch ./bin/aMCatNLO in a shell, and run the following command: ' 1396 1397 return "<INPUT TYPE=SUBMIT VALUE='%s' onClick=\"alert('%s')\">" % (button, header + command) 1398 1399 1400 return + '<br>'
1401