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