Package madgraph :: Package interface :: Module common_run_interface
[hide private]
[frames] | no frames]

Source Code for Module madgraph.interface.common_run_interface

   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  """A user friendly command line interface to access MadGraph5_aMC@NLO features. 
  16     Uses the cmd package for command interpretation and tab completion. 
  17  """ 
  18  from __future__ import division 
  19   
  20  import atexit 
  21  import cmath 
  22  import cmd 
  23  import glob 
  24  import logging 
  25  import math 
  26  import optparse 
  27  import os 
  28  import pydoc 
  29  import random 
  30  import re 
  31  import shutil 
  32  import signal 
  33  import stat 
  34  import subprocess 
  35  import sys 
  36  import time 
  37  import traceback 
  38   
  39   
  40  try: 
  41      import readline 
  42      GNU_SPLITTING = ('GNU' in readline.__doc__) 
  43  except: 
  44      GNU_SPLITTING = True 
  45   
  46  root_path = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0] 
  47  root_path = os.path.split(root_path)[0] 
  48  sys.path.insert(0, os.path.join(root_path,'bin')) 
  49   
  50  # usefull shortcut 
  51  pjoin = os.path.join 
  52  # Special logger for the Cmd Interface 
  53  logger = logging.getLogger('madgraph.stdout') # -> stdout 
  54  logger_stderr = logging.getLogger('madgraph.stderr') # ->stderr 
  55   
  56   
  57  try: 
  58      # import from madgraph directory 
  59      import madgraph.interface.extended_cmd as cmd 
  60      import madgraph.various.banner as banner_mod 
  61      import madgraph.various.misc as misc 
  62      import madgraph.iolibs.files as files 
  63      import madgraph.various.cluster as cluster 
  64      import models.check_param_card as check_param_card 
  65      from madgraph import InvalidCmd, MadGraph5Error, MG5DIR 
  66      MADEVENT=False 
  67  except Exception, error: 
  68      if __debug__: 
  69          print error 
  70      # import from madevent directory 
  71      import internal.extended_cmd as cmd 
  72      import internal.banner as banner_mod 
  73      import internal.misc as misc 
  74      import internal.cluster as cluster 
  75      import internal.check_param_card as check_param_card 
  76      import internal.files as files 
  77      from internal import InvalidCmd, MadGraph5Error 
  78      MADEVENT=True 
79 80 #=============================================================================== 81 # HelpToCmd 82 #=============================================================================== 83 -class HelpToCmd(object):
84 """ The Series of help routins in common between amcatnlo_run and 85 madevent interface""" 86
87 - def help_treatcards(self):
88 logger.info("syntax: treatcards [param|run] [--output_dir=] [--param_card=] [--run_card=]") 89 logger.info("-- create the .inc files containing the cards information." )
90
91 - def help_set(self):
92 logger.info("syntax: set %s argument" % "|".join(self._set_options)) 93 logger.info("-- set options") 94 logger.info(" stdout_level DEBUG|INFO|WARNING|ERROR|CRITICAL") 95 logger.info(" change the default level for printed information") 96 logger.info(" timeout VALUE") 97 logger.info(" (default 20) Seconds allowed to answer questions.") 98 logger.info(" Note that pressing tab always stops the timer.") 99 logger.info(" cluster_temp_path PATH") 100 logger.info(" (default None) Allow to perform the run in PATH directory") 101 logger.info(" This allow to not run on the central disk. This is not used") 102 logger.info(" by condor cluster (since condor has it's own way to prevent it).")
103
104 - def help_plot(self):
105 logger.info("syntax: help [RUN] [%s] [-f]" % '|'.join(self._plot_mode)) 106 logger.info("-- create the plot for the RUN (current run by default)") 107 logger.info(" at the different stage of the event generation") 108 logger.info(" Note than more than one mode can be specified in the same command.") 109 logger.info(" This require to have MadAnalysis and td require. By default") 110 logger.info(" if those programs are installed correctly, the creation") 111 logger.info(" will be performed automaticaly during the event generation.") 112 logger.info(" -f options: answer all question by default.")
113
114 - def help_compute_widths(self):
115 logger.info("syntax: compute_widths Particle [Particles] [--precision=] [--path=Param_card] [--output=PATH]") 116 logger.info("-- Compute the widths for the particles specified.") 117 logger.info(" By default, this takes the current param_card and overwrites it.") 118 logger.info(" Precision allows to define when to include three/four/... body decays (LO).") 119 logger.info(" If this number is an integer then all N-body decay will be included.")
120 121
122 - def help_pythia(self):
123 logger.info("syntax: pythia [RUN] [--run_options]") 124 logger.info("-- run pythia on RUN (current one by default)") 125 self.run_options_help([('-f','answer all question by default'), 126 ('--tag=', 'define the tag for the pythia run'), 127 ('--no_default', 'not run if pythia_card not present')])
128
129 - def help_pgs(self):
130 logger.info("syntax: pgs [RUN] [--run_options]") 131 logger.info("-- run pgs on RUN (current one by default)") 132 self.run_options_help([('-f','answer all question by default'), 133 ('--tag=', 'define the tag for the pgs run'), 134 ('--no_default', 'not run if pgs_card not present')])
135
136 - def help_delphes(self):
137 logger.info("syntax: delphes [RUN] [--run_options]") 138 logger.info("-- run delphes on RUN (current one by default)") 139 self.run_options_help([('-f','answer all question by default'), 140 ('--tag=', 'define the tag for the delphes run'), 141 ('--no_default', 'not run if delphes_card not present')])
142
143 - def help_decay_events(self, skip_syntax=False):
144 if not skip_syntax: 145 logger.info("syntax: decay_events [RUN]") 146 logger.info("This functionality allows for the decay of resonances") 147 logger.info("in a .lhe file, keeping track of the spin correlation effets.") 148 logger.info("BE AWARE OF THE CURRENT LIMITATIONS:") 149 logger.info(" (1) Only a succession of 2 body decay are currently allowed")
150
151 152 153 -class CheckValidForCmd(object):
154 """ The Series of check routines in common between amcatnlo_run and 155 madevent interface""" 156
157 - def check_set(self, args):
158 """ check the validity of the line""" 159 160 if len(args) < 2: 161 self.help_set() 162 raise self.InvalidCmd('set needs an option and an argument') 163 164 if args[0] not in self._set_options + self.options.keys(): 165 self.help_set() 166 raise self.InvalidCmd('Possible options for set are %s' % \ 167 self._set_options) 168 169 if args[0] in ['stdout_level']: 170 if args[1] not in ['DEBUG','INFO','WARNING','ERROR','CRITICAL'] \ 171 and not args[1].isdigit(): 172 raise self.InvalidCmd('output_level needs ' + \ 173 'a valid level') 174 175 if args[0] in ['timeout']: 176 if not args[1].isdigit(): 177 raise self.InvalidCmd('timeout values should be a integer')
178
179 - def check_compute_widths(self, args):
180 """check that the model is loadable and check that the format is of the 181 type: PART PATH --output=PATH -f --precision=N 182 return the model. 183 """ 184 185 # Check that MG5 directory is present . 186 if MADEVENT and not self.options['mg5_path']: 187 raise self.InvalidCmd, '''The automatic computations of widths requires that MG5 is installed on the system. 188 You can install it and set his path in ./Cards/me5_configuration.txt''' 189 elif MADEVENT: 190 sys.path.append(self.options['mg5_path']) 191 try: 192 import models.model_reader as model_reader 193 import models.import_ufo as import_ufo 194 except ImportError: 195 raise self.ConfigurationError, '''Can\'t load MG5. 196 The variable mg5_path should not be correctly configure.''' 197 198 ufo_path = pjoin(self.me_dir,'bin','internal', 'ufomodel') 199 # Import model 200 if not MADEVENT: 201 modelname = self.find_model_name() 202 #restrict_file = None 203 #if os.path.exists(pjoin(ufo_path, 'restrict_default.dat')): 204 # restrict_file = pjoin(ufo_path, 'restrict_default.dat') 205 model = import_ufo.import_model(modelname, decay=True, 206 restrict=True) 207 if self.mother and self.mother.options['complex_mass_scheme']: 208 model.change_mass_to_complex_scheme() 209 else: 210 model = import_ufo.import_model(pjoin(self.me_dir,'bin','internal', 'ufomodel'), 211 decay=True) 212 #pattern for checking complex mass scheme. 213 has_cms = re.compile(r'''set\s+complex_mass_scheme\s*(True|T|1|true|$|;)''') 214 if has_cms.search(open(pjoin(self.me_dir,'Cards','proc_card_mg5.dat')\ 215 ).read()): 216 model.change_mass_to_complex_scheme() 217 218 219 # if not hasattr(model.get('particles')[0], 'partial_widths'): 220 # raise self.InvalidCmd, 'The UFO model does not include partial widths information. Impossible to compute widths automatically' 221 222 # check if the name are passed to default MG5 223 if '-modelname' in open(pjoin(self.me_dir,'Cards','proc_card_mg5.dat')).read(): 224 model.pass_particles_name_in_mg_default() 225 model = model_reader.ModelReader(model) 226 particles_name = dict([(p.get('name'), p.get('pdg_code')) 227 for p in model.get('particles')]) 228 particles_name.update(dict([(p.get('antiname'), p.get('pdg_code')) 229 for p in model.get('particles')])) 230 231 output = {'model': model, 'force': False, 'output': None, 232 'path':None, 'particles': set(), 'body_decay':4.0025, 233 'min_br':None, 'precision_channel':0.01} 234 for arg in args: 235 if arg.startswith('--output='): 236 output_path = arg.split('=',1)[1] 237 if not os.path.exists(output_path): 238 raise self.InvalidCmd, 'Invalid Path for the output. Please retry.' 239 if not os.path.isfile(output_path): 240 output_path = pjoin(output_path, 'param_card.dat') 241 output['output'] = output_path 242 elif arg == '-f': 243 output['force'] = True 244 elif os.path.isfile(arg): 245 ftype = self.detect_card_type(arg) 246 if ftype != 'param_card.dat': 247 raise self.InvalidCmd , '%s is not a valid param_card.' % arg 248 output['path'] = arg 249 elif arg.startswith('--path='): 250 arg = arg.split('=',1)[1] 251 ftype = self.detect_card_type(arg) 252 if ftype != 'param_card.dat': 253 raise self.InvalidCmd , '%s is not a valid param_card.' % arg 254 output['path'] = arg 255 elif arg.startswith('--'): 256 name, value = arg.split('=',1) 257 try: 258 value = float(value) 259 except Exception: 260 raise self.InvalidCmd, '--%s requires integer or a float' % name 261 output[name[2:]] = float(value) 262 elif arg in particles_name: 263 # should be a particles 264 output['particles'].add(particles_name[arg]) 265 elif arg.isdigit() and int(arg) in particles_name.values(): 266 output['particles'].add(eval(arg)) 267 elif arg == 'all': 268 output['particles'] = set(['all']) 269 else: 270 self.help_compute_widths() 271 raise self.InvalidCmd, '%s is not a valid argument for compute_widths' % arg 272 if self.force: 273 output['force'] = True 274 275 if not output['particles']: 276 raise self.InvalidCmd, '''This routines requires at least one particle in order to compute 277 the related width''' 278 279 if output['output'] is None: 280 output['output'] = output['path'] 281 282 return output
283
284 - def check_open(self, args):
285 """ check the validity of the line """ 286 287 if len(args) != 1: 288 self.help_open() 289 raise self.InvalidCmd('OPEN command requires exactly one argument') 290 291 if args[0].startswith('./'): 292 if not os.path.isfile(args[0]): 293 raise self.InvalidCmd('%s: not such file' % args[0]) 294 return True 295 296 # if special : create the path. 297 if not self.me_dir: 298 if not os.path.isfile(args[0]): 299 self.help_open() 300 raise self.InvalidCmd('No MadEvent path defined. Unable to associate this name to a file') 301 else: 302 return True 303 304 path = self.me_dir 305 if os.path.isfile(os.path.join(path,args[0])): 306 args[0] = os.path.join(path,args[0]) 307 elif os.path.isfile(os.path.join(path,'Cards',args[0])): 308 args[0] = os.path.join(path,'Cards',args[0]) 309 elif os.path.isfile(os.path.join(path,'HTML',args[0])): 310 args[0] = os.path.join(path,'HTML',args[0]) 311 # special for card with _default define: copy the default and open it 312 elif '_card.dat' in args[0]: 313 name = args[0].replace('_card.dat','_card_default.dat') 314 if os.path.isfile(os.path.join(path,'Cards', name)): 315 files.cp(os.path.join(path,'Cards', name), os.path.join(path,'Cards', args[0])) 316 args[0] = os.path.join(path,'Cards', args[0]) 317 else: 318 raise self.InvalidCmd('No default path for this file') 319 elif not os.path.isfile(args[0]): 320 raise self.InvalidCmd('No default path for this file')
321
322 - def check_treatcards(self, args):
323 """check that treatcards arguments are valid 324 [param|run|all] [--output_dir=] [--param_card=] [--run_card=] 325 """ 326 327 opt = {'output_dir':pjoin(self.me_dir,'Source'), 328 'param_card':pjoin(self.me_dir,'Cards','param_card.dat'), 329 'run_card':pjoin(self.me_dir,'Cards','run_card.dat')} 330 mode = 'all' 331 for arg in args: 332 if arg.startswith('--') and '=' in arg: 333 key,value =arg[2:].split('=',1) 334 if not key in opt: 335 self.help_treatcards() 336 raise self.InvalidCmd('Invalid option for treatcards command:%s ' \ 337 % key) 338 if key in ['param_card', 'run_card']: 339 if os.path.isfile(value): 340 card_name = self.detect_card_type(value) 341 if card_name != key: 342 raise self.InvalidCmd('Format for input file detected as %s while expecting %s' 343 % (card_name, key)) 344 opt[key] = value 345 elif os.path.isfile(pjoin(self.me_dir,value)): 346 card_name = self.detect_card_type(pjoin(self.me_dir,value)) 347 if card_name != key: 348 raise self.InvalidCmd('Format for input file detected as %s while expecting %s' 349 % (card_name, key)) 350 opt[key] = value 351 else: 352 raise self.InvalidCmd('No such file: %s ' % value) 353 elif key in ['output_dir']: 354 if os.path.isdir(value): 355 opt[key] = value 356 elif os.path.isdir(pjoin(self.me_dir,value)): 357 opt[key] = pjoin(self.me_dir, value) 358 else: 359 raise self.InvalidCmd('No such directory: %s' % value) 360 elif arg in ['param','run','all']: 361 mode = arg 362 else: 363 self.help_treatcards() 364 raise self.InvalidCmd('Unvalid argument %s' % arg) 365 366 return mode, opt
367
368 - def check_decay_events(self,args):
369 """Check the argument for decay_events command 370 syntax: decay_events [NAME] 371 Note that other option are already remove at this point 372 """ 373 374 opts = [] 375 if '-from_cards' in args: 376 args.remove('-from_cards') 377 opts.append('-from_cards') 378 379 if len(args) == 0: 380 if self.run_name: 381 args.insert(0, self.run_name) 382 elif self.results.lastrun: 383 args.insert(0, self.results.lastrun) 384 else: 385 raise self.InvalidCmd('No run name currently defined. Please add this information.') 386 return 387 388 if args[0] != self.run_name: 389 self.set_run_name(args[0]) 390 391 args[0] = self.get_events_path(args[0]) 392 393 args += opts
394
395 - def check_check_events(self,args):
396 """Check the argument for decay_events command 397 syntax: decay_events [NAME] 398 Note that other option are already remove at this point 399 """ 400 401 if len(args) == 0: 402 if self.run_name: 403 args.insert(0, self.run_name) 404 elif self.results.lastrun: 405 args.insert(0, self.results.lastrun) 406 else: 407 raise self.InvalidCmd('No run name currently defined. Please add this information.') 408 return 409 410 if args[0] and os.path.isfile(args[0]): 411 pass 412 else: 413 if args[0] != self.run_name: 414 self.set_run_name(args[0], allow_new_tag=False) 415 416 args[0] = self.get_events_path(args[0])
417 418
419 - def get_events_path(self, run_name):
420 """Check the argument for decay_events command 421 syntax: decay_events [NAME] 422 Note that other option are already remove at this point 423 """ 424 425 426 if self.mode == 'madevent': 427 possible_path = [ 428 pjoin(self.me_dir,'Events', run_name, 'unweighted_events.lhe.gz'), 429 pjoin(self.me_dir,'Events', run_name, 'unweighted_events.lhe')] 430 else: 431 possible_path = [ 432 pjoin(self.me_dir,'Events', run_name, 'events.lhe.gz'), 433 pjoin(self.me_dir,'Events', run_name, 'events.lhe')] 434 435 for path in possible_path: 436 if os.path.exists(path): 437 correct_path = path 438 break 439 else: 440 raise self.InvalidCmd('No events file corresponding to %s run. ' % run_name) 441 return correct_path
442
443 444 445 -class MadEventAlreadyRunning(InvalidCmd):
446 pass
447 -class AlreadyRunning(MadEventAlreadyRunning):
448 pass
449
450 #=============================================================================== 451 # CommonRunCmd 452 #=============================================================================== 453 -class CommonRunCmd(HelpToCmd, CheckValidForCmd, cmd.Cmd):
454 455 debug_output = 'ME5_debug' 456 helporder = ['Main Commands', 'Documented commands', 'Require MG5 directory', 457 'Advanced commands'] 458 459 # The three options categories are treated on a different footage when a 460 # set/save configuration occur. current value are kept in self.options 461 options_configuration = {'pythia8_path': './pythia8', 462 'hwpp_path': './herwigPP', 463 'thepeg_path': './thepeg', 464 'hepmc_path': './hepmc', 465 'madanalysis_path': './MadAnalysis', 466 'pythia-pgs_path':'./pythia-pgs', 467 'td_path':'./td', 468 'delphes_path':'./Delphes', 469 'exrootanalysis_path':'./ExRootAnalysis', 470 'syscalc_path': './SysCalc', 471 'lhapdf': 'lhapdf-config', 472 'timeout': 60, 473 'web_browser':None, 474 'eps_viewer':None, 475 'text_editor':None, 476 'fortran_compiler':None, 477 'cpp_compiler': None, 478 'auto_update':7, 479 'cluster_type': 'condor', 480 'cluster_status_update': (600, 30), 481 'cluster_nb_retry':1, 482 'cluster_retry_wait':300} 483 484 options_madgraph= {'stdout_level':None} 485 486 options_madevent = {'automatic_html_opening':True, 487 'run_mode':2, 488 'cluster_queue':'madgraph', 489 'cluster_time':None, 490 'cluster_memory':None, 491 'nb_core': None, 492 'cluster_temp_path':None} 493 494
495 - def __init__(self, me_dir, options, *args, **opts):
496 """common""" 497 498 cmd.Cmd.__init__(self, *args, **opts) 499 # Define current MadEvent directory 500 if me_dir is None and MADEVENT: 501 me_dir = root_path 502 503 self.me_dir = me_dir 504 self.options = options 505 506 # usefull shortcut 507 self.status = pjoin(self.me_dir, 'status') 508 self.error = pjoin(self.me_dir, 'error') 509 self.dirbin = pjoin(self.me_dir, 'bin', 'internal') 510 511 # Check that the directory is not currently running 512 if os.path.exists(pjoin(me_dir,'RunWeb')): 513 message = '''Another instance of the program is currently running. 514 (for this exact same directory) Please wait that this is instance is 515 closed. If no instance is running, you can delete the file 516 %s and try again.''' % pjoin(me_dir,'RunWeb') 517 raise AlreadyRunning, message 518 else: 519 pid = os.getpid() 520 fsock = open(pjoin(me_dir,'RunWeb'),'w') 521 fsock.write(`pid`) 522 fsock.close() 523 524 misc.Popen([os.path.relpath(pjoin(self.dirbin, 'gen_cardhtml-pl'), me_dir)], 525 cwd=me_dir) 526 527 self.to_store = [] 528 self.run_name = None 529 self.run_tag = None 530 self.banner = None 531 # Load the configuration file 532 self.set_configuration() 533 self.configure_run_mode(self.options['run_mode']) 534 535 536 # Get number of initial states 537 nexternal = open(pjoin(self.me_dir,'Source','nexternal.inc')).read() 538 found = re.search("PARAMETER\s*\(NINCOMING=(\d)\)", nexternal) 539 self.ninitial = int(found.group(1))
540 541 542 ############################################################################
543 - def split_arg(self, line, error=False):
544 """split argument and remove run_options""" 545 546 args = cmd.Cmd.split_arg(line) 547 for arg in args[:]: 548 if not arg.startswith('-'): 549 continue 550 elif arg == '-c': 551 self.configure_run_mode(1) 552 elif arg == '-m': 553 self.configure_run_mode(2) 554 elif arg == '-f': 555 self.force = True 556 elif not arg.startswith('--'): 557 if error: 558 raise self.InvalidCmd('%s argument cannot start with - symbol' % arg) 559 else: 560 continue 561 elif arg.startswith('--cluster'): 562 self.configure_run_mode(1) 563 elif arg.startswith('--multicore'): 564 self.configure_run_mode(2) 565 elif arg.startswith('--nb_core'): 566 self.options['nb_core'] = int(arg.split('=',1)[1]) 567 self.configure_run_mode(2) 568 elif arg.startswith('--web'): 569 self.pass_in_web_mode() 570 self.configure_run_mode(1) 571 else: 572 continue 573 args.remove(arg) 574 575 return args
576 577 ############################################################################
578 - def do_treatcards(self, line, amcatnlo=False):
579 """Advanced commands: create .inc files from param_card.dat/run_card.dat""" 580 581 582 keepwidth = False 583 if '--keepwidth' in line: 584 keepwidth = True 585 line = line.replace('--keepwidth', '') 586 args = self.split_arg(line) 587 mode, opt = self.check_treatcards(args) 588 589 if mode in ['run', 'all']: 590 if not hasattr(self, 'run_card'): 591 if amcatnlo: 592 run_card = banner_mod.RunCardNLO(opt['run_card']) 593 else: 594 run_card = banner_mod.RunCard(opt['run_card']) 595 else: 596 run_card = self.run_card 597 598 run_card.write_include_file(pjoin(opt['output_dir'],'run_card.inc')) 599 600 if mode in ['param', 'all']: 601 if os.path.exists(pjoin(self.me_dir, 'Source', 'MODEL', 'mp_coupl.inc')): 602 param_card = check_param_card.ParamCardMP(opt['param_card']) 603 else: 604 param_card = check_param_card.ParamCard(opt['param_card']) 605 outfile = pjoin(opt['output_dir'], 'param_card.inc') 606 ident_card = pjoin(self.me_dir,'Cards','ident_card.dat') 607 if os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat')): 608 default = pjoin(self.me_dir,'bin','internal','ufomodel','restrict_default.dat') 609 elif os.path.isfile(pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat')): 610 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat') 611 elif not os.path.exists(pjoin(self.me_dir,'bin','internal','ufomodel')): 612 fsock = open(pjoin(self.me_dir,'Source','param_card.inc'),'w') 613 fsock.write(' ') 614 fsock.close() 615 return 616 else: 617 subprocess.call(['python', 'write_param_card.py'], 618 cwd=pjoin(self.me_dir,'bin','internal','ufomodel')) 619 default = pjoin(self.me_dir,'bin','internal','ufomodel','param_card.dat') 620 621 622 if amcatnlo and not keepwidth: 623 # force particle in final states to have zero width 624 pids = self.get_pid_final_states() 625 # check those which are charged under qcd 626 if not MADEVENT and pjoin(self.me_dir,'bin','internal') not in sys.path: 627 sys.path.insert(0,pjoin(self.me_dir,'bin','internal')) 628 629 #Ensure that the model that we are going to load is the current 630 #one. 631 to_del = [name for name in sys.modules.keys() 632 if name.startswith('internal.ufomodel') 633 or name.startswith('ufomodel')] 634 for name in to_del: 635 del(sys.modules[name]) 636 637 import ufomodel as ufomodel 638 zero = ufomodel.parameters.ZERO 639 no_width = [p for p in ufomodel.all_particles 640 if (str(p.pdg_code) in pids or str(-p.pdg_code) in pids) 641 and p.color != 1 and p.width != zero] 642 done = [] 643 for part in no_width: 644 if abs(part.pdg_code) in done: 645 continue 646 done.append(abs(part.pdg_code)) 647 param = param_card['decay'].get((part.pdg_code,)) 648 649 if param.value != 0: 650 logger.info('''For gauge cancellation, the width of \'%s\' has been set to zero.''' 651 % part.name,'$MG:color:BLACK') 652 param.value = 0 653 654 param_card.write_inc_file(outfile, ident_card, default)
655 656
657 - def ask_edit_cards(self, cards, mode='fixed', plot=True):
658 """ """ 659 if not self.options['madanalysis_path']: 660 plot = False 661 662 self.ask_edit_card_static(cards, mode, plot, self.options['timeout'], 663 self.ask)
664 665 @staticmethod
666 - def ask_edit_card_static(cards, mode='fixed', plot=True, 667 timeout=0, ask=None, **opt):
668 if not ask: 669 ask = CommonRunCmd.ask 670 671 def path2name(path): 672 if '_card' in path: 673 return path.split('_card')[0] 674 elif path == 'delphes_trigger.dat': 675 return 'trigger' 676 elif path == 'input.lhco': 677 return 'lhco' 678 else: 679 raise Exception, 'Unknow cards name %s' % path
680 681 # Ask the user if he wants to edit any of the files 682 #First create the asking text 683 question = """Do you want to edit a card (press enter to bypass editing)?\n""" 684 possible_answer = ['0', 'done'] 685 card = {0:'done'} 686 687 for i, card_name in enumerate(cards): 688 imode = path2name(card_name) 689 possible_answer.append(i+1) 690 possible_answer.append(imode) 691 question += ' %s / %-10s : %s\n' % (i+1, imode, card_name) 692 card[i+1] = imode 693 if plot: 694 question += ' 9 / %-10s : plot_card.dat\n' % 'plot' 695 possible_answer.append(9) 696 possible_answer.append('plot') 697 card[9] = 'plot' 698 699 if 'param_card.dat' in cards: 700 # Add the path options 701 question += ' you can also\n' 702 question += ' - enter the path to a valid card or banner.\n' 703 question += ' - use the \'set\' command to modify a parameter directly.\n' 704 question += ' The set option works only for param_card and run_card.\n' 705 question += ' Type \'help set\' for more information on this command.\n' 706 question += ' - call an external program (ASperGE/MadWidth/...).\n' 707 question += ' Type \'help\' for the list of available command\n' 708 else: 709 question += ' you can also\n' 710 question += ' - enter the path to a valid card.\n' 711 if 'transfer_card.dat' in cards: 712 question += ' - use the \'change_tf\' command to set a transfer functions.\n' 713 714 out = 'to_run' 715 while out not in ['0', 'done']: 716 out = ask(question, '0', possible_answer, timeout=int(1.5*timeout), 717 path_msg='enter path', ask_class = AskforEditCard, 718 cards=cards, mode=mode, **opt)
719 720 721 @staticmethod
722 - def detect_card_type(path):
723 """detect the type of the card. Return value are 724 banner 725 param_card.dat 726 run_card.dat 727 pythia_card.dat 728 plot_card.dat 729 pgs_card.dat 730 delphes_card.dat 731 delphes_trigger.dat 732 shower_card.dat [aMCatNLO] 733 madspin_card.dat [MS] 734 transfer_card.dat [MW] 735 madweight_card.dat [MW] 736 """ 737 738 text = open(path).read(50000) 739 if text == '': 740 logger.warning('File %s is empty' % path) 741 return 'unknown' 742 text = re.findall('(<MGVersion>|ParticlePropagator|<mg5proccard>|CEN_max_tracker|#TRIGGER CARD|parameter set name|muon eta coverage|QES_over_ref|MSTP|b_stable|MSTU|Begin Minpts|gridpack|ebeam1|block\s+mw_run|BLOCK|DECAY|launch|madspin|transfer_card\.dat|set)', text, re.I) 743 text = [t.lower() for t in text] 744 if '<mgversion>' in text or '<mg5proccard>' in text: 745 return 'banner' 746 elif 'particlepropagator' in text: 747 return 'delphes_card.dat' 748 elif 'cen_max_tracker' in text: 749 return 'delphes_card.dat' 750 elif '#trigger card' in text: 751 return 'delphes_trigger.dat' 752 elif 'parameter set name' in text: 753 return 'pgs_card.dat' 754 elif 'muon eta coverage' in text: 755 return 'pgs_card.dat' 756 elif 'mstp' in text and not 'b_stable' in text: 757 return 'pythia_card.dat' 758 elif 'begin minpts' in text: 759 return 'plot_card.dat' 760 elif ('gridpack' in text and 'ebeam1' in text) or \ 761 ('qes_over_ref' in text and 'ebeam1' in text): 762 return 'run_card.dat' 763 elif any(t.endswith('mw_run') for t in text): 764 return 'madweight_card.dat' 765 elif 'transfer_card.dat' in text: 766 return 'transfer_card.dat' 767 elif 'block' in text and 'decay' in text: 768 return 'param_card.dat' 769 elif 'b_stable' in text: 770 return 'shower_card.dat' 771 elif 'decay' in text and 'launch' in text and 'madspin' in text: 772 return 'madspin_card.dat' 773 elif 'launch' in text and 'set' in text: 774 return 'reweight_card.dat' 775 elif 'decay' in text and 'launch' in text: 776 return 'madspin_card.dat' 777 else: 778 return 'unknown'
779 780 781 ############################################################################
782 - def get_available_tag(self):
783 """create automatically a tag""" 784 785 used_tags = [r['tag'] for r in self.results[self.run_name]] 786 i=0 787 while 1: 788 i+=1 789 if 'tag_%s' %i not in used_tags: 790 return 'tag_%s' % i
791 792 793 ############################################################################
794 - def create_plot(self, mode='parton', event_path=None, output=None, tag=None):
795 """create the plot""" 796 797 madir = self.options['madanalysis_path'] 798 if not tag: 799 tag = self.run_card['run_tag'] 800 td = self.options['td_path'] 801 802 if not madir or not td or \ 803 not os.path.exists(pjoin(self.me_dir, 'Cards', 'plot_card.dat')): 804 return False 805 806 if 'ickkw' in self.run_card and int(self.run_card['ickkw']) and \ 807 mode == 'Pythia': 808 self.update_status('Create matching plots for Pythia', level='pythia') 809 # recover old data if none newly created 810 if not os.path.exists(pjoin(self.me_dir,'Events','events.tree')): 811 misc.gunzip(pjoin(self.me_dir,'Events', 812 self.run_name, '%s_pythia_events.tree.gz' % tag), keep=True, 813 stdout=pjoin(self.me_dir,'Events','events.tree')) 814 files.mv(pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_xsecs.tree'), 815 pjoin(self.me_dir,'Events','xsecs.tree')) 816 817 # Generate the matching plots 818 misc.call([self.dirbin+'/create_matching_plots.sh', 819 self.run_name, tag, madir], 820 stdout = os.open(os.devnull, os.O_RDWR), 821 cwd=pjoin(self.me_dir,'Events')) 822 823 #Clean output 824 misc.gzip(pjoin(self.me_dir,"Events","events.tree"), 825 stdout=pjoin(self.me_dir,'Events',self.run_name, tag + '_pythia_events.tree.gz')) 826 files.mv(pjoin(self.me_dir,'Events','xsecs.tree'), 827 pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_xsecs.tree')) 828 829 830 if not event_path: 831 if mode == 'parton': 832 possibilities=[ 833 pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'), 834 pjoin(self.me_dir, 'Events', 'unweighted_events.lhe.gz'), 835 pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe'), 836 pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe.gz')] 837 for event_path in possibilities: 838 if os.path.exists(event_path): 839 break 840 output = pjoin(self.me_dir, 'HTML',self.run_name, 'plots_parton.html') 841 842 elif mode == 'Pythia': 843 event_path = pjoin(self.me_dir, 'Events','pythia_events.lhe') 844 output = pjoin(self.me_dir, 'HTML',self.run_name, 845 'plots_pythia_%s.html' % tag) 846 elif mode == 'PGS': 847 event_path = pjoin(self.me_dir, 'Events', self.run_name, 848 '%s_pgs_events.lhco' % tag) 849 output = pjoin(self.me_dir, 'HTML',self.run_name, 850 'plots_pgs_%s.html' % tag) 851 elif mode == 'Delphes': 852 event_path = pjoin(self.me_dir, 'Events', self.run_name,'%s_delphes_events.lhco' % tag) 853 output = pjoin(self.me_dir, 'HTML',self.run_name, 854 'plots_delphes_%s.html' % tag) 855 elif mode == "shower": 856 event_path = pjoin(self.me_dir, 'Events','pythia_events.lhe') 857 output = pjoin(self.me_dir, 'HTML',self.run_name, 858 'plots_shower_%s.html' % tag) 859 if not self.options['pythia-pgs_path']: 860 return 861 else: 862 raise self.InvalidCmd, 'Invalid mode %s' % mode 863 elif mode == 'reweight' and not output: 864 output = pjoin(self.me_dir, 'HTML',self.run_name, 865 'plots_%s.html' % tag) 866 867 if not os.path.exists(event_path): 868 if os.path.exists(event_path+'.gz'): 869 misc.gunzip('%s.gz' % event_path) 870 else: 871 raise self.InvalidCmd, 'Events file %s does not exist' % event_path 872 elif event_path.endswith(".gz"): 873 misc.gunzip(event_path) 874 event_path = event_path[:-3] 875 876 877 self.update_status('Creating Plots for %s level' % mode, level = mode.lower()) 878 879 mode = mode.lower() 880 if mode not in ['parton', 'reweight']: 881 plot_dir = pjoin(self.me_dir, 'HTML', self.run_name,'plots_%s_%s' % (mode.lower(),tag)) 882 elif mode == 'parton': 883 plot_dir = pjoin(self.me_dir, 'HTML', self.run_name,'plots_parton') 884 else: 885 plot_dir =pjoin(self.me_dir, 'HTML', self.run_name,'plots_%s' % (tag)) 886 887 if not os.path.isdir(plot_dir): 888 os.makedirs(plot_dir) 889 890 files.ln(pjoin(self.me_dir, 'Cards','plot_card.dat'), plot_dir, 'ma_card.dat') 891 892 try: 893 proc = misc.Popen([os.path.join(madir, 'plot_events')], 894 stdout = open(pjoin(plot_dir, 'plot.log'),'w'), 895 stderr = subprocess.STDOUT, 896 stdin=subprocess.PIPE, 897 cwd=plot_dir) 898 proc.communicate('%s\n' % event_path) 899 del proc 900 #proc.wait() 901 misc.call(['%s/plot' % self.dirbin, madir, td], 902 stdout = open(pjoin(plot_dir, 'plot.log'),'a'), 903 stderr = subprocess.STDOUT, 904 cwd=plot_dir) 905 906 misc.call(['%s/plot_page-pl' % self.dirbin, 907 os.path.basename(plot_dir), 908 mode], 909 stdout = open(pjoin(plot_dir, 'plot.log'),'a'), 910 stderr = subprocess.STDOUT, 911 cwd=pjoin(self.me_dir, 'HTML', self.run_name)) 912 913 shutil.move(pjoin(self.me_dir, 'HTML',self.run_name ,'plots.html'), 914 output) 915 916 logger.info("Plots for %s level generated, see %s" % \ 917 (mode, output)) 918 except OSError, error: 919 logger.error('fail to create plot: %s. Please check that MadAnalysis is correctly installed.' % error) 920 921 self.update_status('End Plots for %s level' % mode, level = mode.lower(), 922 makehtml=False) 923 924 return True
925
926 - def run_hep2lhe(self, banner_path = None):
927 """Run hep2lhe on the file Events/pythia_events.hep""" 928 929 if not self.options['pythia-pgs_path']: 930 raise self.InvalidCmd, 'No pythia-pgs path defined' 931 932 pydir = pjoin(self.options['pythia-pgs_path'], 'src') 933 eradir = self.options['exrootanalysis_path'] 934 935 # Creating LHE file 936 if misc.is_executable(pjoin(pydir, 'hep2lhe')): 937 self.update_status('Creating shower LHE File (for plot)', level='pythia') 938 # Write the banner to the LHE file 939 out = open(pjoin(self.me_dir,'Events','pythia_events.lhe'), 'w') 940 #out.writelines('<LesHouchesEvents version=\"1.0\">\n') 941 out.writelines('<!--\n') 942 out.writelines('# Warning! Never use this file for detector studies!\n') 943 out.writelines('-->\n<!--\n') 944 if banner_path: 945 out.writelines(open(banner_path).read().replace('<LesHouchesEvents version="1.0">','')) 946 out.writelines('\n-->\n') 947 out.close() 948 949 self.cluster.launch_and_wait(self.dirbin+'/run_hep2lhe', 950 argument= [pydir], 951 cwd=pjoin(self.me_dir,'Events'), 952 stdout=open(os.devnull,'w')) 953 954 logger.info('Warning! Never use this lhe file for detector studies!') 955 # Creating ROOT file 956 if eradir and misc.is_executable(pjoin(eradir, 'ExRootLHEFConverter')): 957 self.update_status('Creating Pythia LHE Root File', level='pythia') 958 try: 959 misc.call([eradir+'/ExRootLHEFConverter', 960 'pythia_events.lhe', 961 pjoin(self.run_name, '%s_pythia_lhe_events.root' % self.run_tag)], 962 cwd=pjoin(self.me_dir,'Events')) 963 except Exception, error: 964 misc.sprint('ExRootLHEFConverter fails', str(error), 965 log=logger) 966 pass
967
968 - def store_result(self):
969 """Dummy routine, to be overwritten by daughter classes""" 970 971 pass
972 973 ############################################################################
974 - def do_pgs(self, line):
975 """launch pgs""" 976 977 args = self.split_arg(line) 978 # Check argument's validity 979 if '--no_default' in args: 980 no_default = True 981 args.remove('--no_default') 982 else: 983 no_default = False 984 985 # Check all arguments 986 # This might launch a gunzip in another thread. After the question 987 # This thread need to be wait for completion. (This allow to have the 988 # question right away and have the computer working in the same time) 989 # if lock is define this a locker for the completion of the thread 990 lock = self.check_pgs(args) 991 992 # Check that the pgs_card exists. If not copy the default 993 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pgs_card.dat')): 994 if no_default: 995 logger.info('No pgs_card detected, so not run pgs') 996 return 997 998 files.cp(pjoin(self.me_dir, 'Cards', 'pgs_card_default.dat'), 999 pjoin(self.me_dir, 'Cards', 'pgs_card.dat')) 1000 logger.info('No pgs card found. Take the default one.') 1001 1002 if not (no_default or self.force): 1003 self.ask_edit_cards(['pgs_card.dat']) 1004 1005 self.update_status('prepare PGS run', level=None) 1006 1007 pgsdir = pjoin(self.options['pythia-pgs_path'], 'src') 1008 eradir = self.options['exrootanalysis_path'] 1009 madir = self.options['madanalysis_path'] 1010 td = self.options['td_path'] 1011 1012 # Compile pgs if not there 1013 if not misc.is_executable(pjoin(pgsdir, 'pgs')): 1014 logger.info('No PGS executable -- running make') 1015 misc.compile(cwd=pgsdir) 1016 1017 self.update_status('Running PGS', level='pgs') 1018 1019 tag = self.run_tag 1020 # Update the banner with the pgs card 1021 banner_path = pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, self.run_tag)) 1022 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')): 1023 self.banner.add(pjoin(self.me_dir, 'Cards','pgs_card.dat')) 1024 self.banner.write(banner_path) 1025 else: 1026 open(banner_path, 'w').close() 1027 1028 ######################################################################## 1029 # now pass the event to a detector simulator and reconstruct objects 1030 ######################################################################## 1031 if lock: 1032 lock.acquire() 1033 # Prepare the output file with the banner 1034 ff = open(pjoin(self.me_dir, 'Events', 'pgs_events.lhco'), 'w') 1035 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')): 1036 text = open(banner_path).read() 1037 text = '#%s' % text.replace('\n','\n#') 1038 dico = self.results[self.run_name].get_current_info() 1039 text +='\n## Integrated weight (pb) : %.4g' % dico['cross'] 1040 text +='\n## Number of Event : %s\n' % dico['nb_event'] 1041 ff.writelines(text) 1042 ff.close() 1043 1044 try: 1045 os.remove(pjoin(self.me_dir, 'Events', 'pgs.done')) 1046 except Exception: 1047 pass 1048 1049 pgs_log = pjoin(self.me_dir, 'Events', self.run_name, "%s_pgs.log" % tag) 1050 self.cluster.launch_and_wait('../bin/internal/run_pgs', 1051 argument=[pgsdir], cwd=pjoin(self.me_dir,'Events'), 1052 stdout=pgs_log, stderr=subprocess.STDOUT) 1053 1054 if not os.path.exists(pjoin(self.me_dir, 'Events', 'pgs.done')): 1055 logger.error('Fail to create LHCO events') 1056 return 1057 else: 1058 os.remove(pjoin(self.me_dir, 'Events', 'pgs.done')) 1059 1060 if os.path.getsize(banner_path) == os.path.getsize(pjoin(self.me_dir, 'Events','pgs_events.lhco')): 1061 misc.call(['cat pgs_uncleaned_events.lhco >> pgs_events.lhco'], 1062 cwd=pjoin(self.me_dir, 'Events')) 1063 os.remove(pjoin(self.me_dir, 'Events', 'pgs_uncleaned_events.lhco ')) 1064 1065 # Creating Root file 1066 if eradir and misc.is_executable(pjoin(eradir, 'ExRootLHCOlympicsConverter')): 1067 self.update_status('Creating PGS Root File', level='pgs') 1068 try: 1069 misc.call([eradir+'/ExRootLHCOlympicsConverter', 1070 'pgs_events.lhco',pjoin('%s/%s_pgs_events.root' % (self.run_name, tag))], 1071 cwd=pjoin(self.me_dir, 'Events')) 1072 except Exception: 1073 logger.warning('fail to produce Root output [problem with ExRootAnalysis') 1074 if os.path.exists(pjoin(self.me_dir, 'Events', 'pgs_events.lhco')): 1075 # Creating plots 1076 files.mv(pjoin(self.me_dir, 'Events', 'pgs_events.lhco'), 1077 pjoin(self.me_dir, 'Events', self.run_name, '%s_pgs_events.lhco' % tag)) 1078 self.create_plot('PGS') 1079 misc.gzip(pjoin(self.me_dir, 'Events', self.run_name, '%s_pgs_events.lhco' % tag)) 1080 1081 self.update_status('finish', level='pgs', makehtml=False)
1082 1083 ############################################################################
1084 - def do_compute_widths(self, line):
1085 """Require MG5 directory: Compute automatically the widths of a set 1086 of particles""" 1087 1088 args = self.split_arg(line) 1089 opts = self.check_compute_widths(args) 1090 1091 1092 from madgraph.interface.master_interface import MasterCmd 1093 cmd = MasterCmd() 1094 self.define_child_cmd_interface(cmd, interface=False) 1095 cmd.exec_cmd('set automatic_html_opening False --no_save') 1096 if not opts['path']: 1097 opts['path'] = pjoin(self.me_dir, 'Cards', 'param_card.dat') 1098 if not opts['force'] : 1099 self.ask_edit_cards(['param_card'],[], plot=False) 1100 1101 1102 line = 'compute_widths %s %s' % \ 1103 (' '.join([str(i) for i in opts['particles']]), 1104 ' '.join('--%s=%s' % (key,value) for (key,value) in opts.items() 1105 if key not in ['model', 'force', 'particles'] and value)) 1106 1107 cmd.exec_cmd(line, model=opts['model']) 1108 self.child = None 1109 del cmd
1110 1111 ############################################################################
1112 - def do_print_results(self, line):
1113 """Not in help:Print the cross-section/ number of events for a given run""" 1114 1115 args = self.split_arg(line) 1116 options={'path':None, 'mode':'w'} 1117 for arg in list(args): 1118 if arg.startswith('--') and '=' in arg: 1119 name,value=arg.split('=',1) 1120 name = name [2:] 1121 options[name] = value 1122 args.remove(arg) 1123 1124 1125 if len(args) > 0: 1126 run_name = args[0] 1127 else: 1128 if not self.results.current: 1129 raise self.InvalidCmd('no run currently defined. Please specify one.') 1130 else: 1131 run_name = self.results.current['run_name'] 1132 if run_name not in self.results: 1133 raise self.InvalidCmd('%s is not a valid run_name or it doesn\'t have any information' \ 1134 % run_name) 1135 1136 1137 if len(args) == 2: 1138 tag = args[1] 1139 if tag.isdigit(): 1140 tag = int(tag) - 1 1141 if len(self.results[run_name]) < tag: 1142 raise self.InvalidCmd('Only %s different tag available' % \ 1143 len(self.results[run_name])) 1144 data = self.results[run_name][tag] 1145 else: 1146 data = self.results[run_name].return_tag(tag) 1147 else: 1148 data = self.results[run_name].return_tag(None) # return the last 1149 1150 if options['path']: 1151 self.print_results_in_file(data, options['path'], options['mode']) 1152 else: 1153 self.print_results_in_shell(data)
1154 1155 1156 ############################################################################
1157 - def do_delphes(self, line):
1158 """ run delphes and make associate root file/plot """ 1159 1160 args = self.split_arg(line) 1161 # Check argument's validity 1162 if '--no_default' in args: 1163 no_default = True 1164 args.remove('--no_default') 1165 else: 1166 no_default = False 1167 # Check all arguments 1168 # This might launch a gunzip in another thread. After the question 1169 # This thread need to be wait for completion. (This allow to have the 1170 # question right away and have the computer working in the same time) 1171 # if lock is define this a locker for the completion of the thread 1172 lock = self.check_delphes(args) 1173 self.update_status('prepare delphes run', level=None) 1174 1175 1176 if os.path.exists(pjoin(self.options['delphes_path'], 'data')): 1177 delphes3 = False 1178 prog = '../bin/internal/run_delphes' 1179 else: 1180 delphes3 = True 1181 prog = '../bin/internal/run_delphes3' 1182 1183 # Check that the delphes_card exists. If not copy the default and 1184 # ask for edition of the card. 1185 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')): 1186 if no_default: 1187 logger.info('No delphes_card detected, so not run Delphes') 1188 return 1189 1190 files.cp(pjoin(self.me_dir, 'Cards', 'delphes_card_default.dat'), 1191 pjoin(self.me_dir, 'Cards', 'delphes_card.dat')) 1192 logger.info('No delphes card found. Take the default one.') 1193 if not delphes3 and not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_trigger.dat')): 1194 files.cp(pjoin(self.me_dir, 'Cards', 'delphes_trigger_default.dat'), 1195 pjoin(self.me_dir, 'Cards', 'delphes_trigger.dat')) 1196 if not (no_default or self.force): 1197 if delphes3: 1198 self.ask_edit_cards(['delphes_card.dat'], args) 1199 else: 1200 self.ask_edit_cards(['delphes_card.dat', 'delphes_trigger.dat'], args) 1201 1202 self.update_status('Running Delphes', level=None) 1203 # Wait that the gunzip of the files is finished (if any) 1204 if lock: 1205 lock.acquire() 1206 1207 1208 1209 delphes_dir = self.options['delphes_path'] 1210 tag = self.run_tag 1211 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')): 1212 self.banner.add(pjoin(self.me_dir, 'Cards','delphes_card.dat')) 1213 if not delphes3: 1214 self.banner.add(pjoin(self.me_dir, 'Cards','delphes_trigger.dat')) 1215 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, tag))) 1216 1217 cross = self.results[self.run_name].get_current_info()['cross'] 1218 1219 delphes_log = pjoin(self.me_dir, 'Events', self.run_name, "%s_delphes.log" % tag) 1220 self.cluster.launch_and_wait(prog, 1221 argument= [delphes_dir, self.run_name, tag, str(cross)], 1222 stdout=delphes_log, stderr=subprocess.STDOUT, 1223 cwd=pjoin(self.me_dir,'Events')) 1224 1225 if not os.path.exists(pjoin(self.me_dir, 'Events', 1226 self.run_name, '%s_delphes_events.lhco' % tag)): 1227 logger.error('Fail to create LHCO events from DELPHES') 1228 return 1229 1230 if os.path.exists(pjoin(self.me_dir,'Events','delphes.root')): 1231 source = pjoin(self.me_dir,'Events','delphes.root') 1232 target = pjoin(self.me_dir,'Events', self.run_name, "%s_delphes_events.root" % tag) 1233 files.mv(source, target) 1234 1235 #eradir = self.options['exrootanalysis_path'] 1236 madir = self.options['madanalysis_path'] 1237 td = self.options['td_path'] 1238 1239 # Creating plots 1240 self.create_plot('Delphes') 1241 1242 if os.path.exists(pjoin(self.me_dir, 'Events', self.run_name, '%s_delphes_events.lhco' % tag)): 1243 misc.gzip(pjoin(self.me_dir, 'Events', self.run_name, '%s_delphes_events.lhco' % tag)) 1244 1245 1246 1247 self.update_status('delphes done', level='delphes', makehtml=False)
1248 1249 ############################################################################
1250 - def get_pid_final_states(self):
1251 """Find the pid of all particles in the final states""" 1252 pids = set() 1253 subproc = [l.strip() for l in open(pjoin(self.me_dir,'SubProcesses', 1254 'subproc.mg'))] 1255 nb_init = self.ninitial 1256 pat = re.compile(r'''DATA \(IDUP\(I,\d+\),I=1,\d+\)/([\+\-\d,\s]*)/''', re.I) 1257 for Pdir in subproc: 1258 text = open(pjoin(self.me_dir, 'SubProcesses', Pdir, 'born_leshouche.inc')).read() 1259 group = pat.findall(text) 1260 for particles in group: 1261 particles = particles.split(',') 1262 pids.update(set(particles[nb_init:])) 1263 1264 return pids
1265 1266 ############################################################################
1267 - def get_pdf_input_filename(self):
1268 """return the name of the file which is used by the pdfset""" 1269 1270 if hasattr(self, 'pdffile') and self.pdffile: 1271 return self.pdffile 1272 else: 1273 for line in open(pjoin(self.me_dir,'Source','PDF','pdf_list.txt')): 1274 data = line.split() 1275 if len(data) < 4: 1276 continue 1277 if data[1].lower() == self.run_card['pdlabel'].lower(): 1278 self.pdffile = pjoin(self.me_dir, 'lib', 'Pdfdata', data[2]) 1279 return self.pdffile 1280 else: 1281 # possible when using lhapdf 1282 self.pdffile = pjoin(self.me_dir, 'lib', 'PDFsets') 1283 return self.pdffile
1284
1285 - def do_quit(self, line):
1286 """Not in help: exit """ 1287 1288 1289 try: 1290 os.remove(pjoin(self.me_dir,'RunWeb')) 1291 except Exception, error: 1292 pass 1293 1294 try: 1295 self.store_result() 1296 except Exception: 1297 # If nothing runs they they are no result to update 1298 pass 1299 1300 try: 1301 self.update_status('', level=None) 1302 except Exception, error: 1303 pass 1304 try: 1305 devnull = open(os.devnull, 'w') 1306 misc.call(['./bin/internal/gen_cardhtml-pl'], cwd=self.me_dir, 1307 stdout=devnull, stderr=devnull) 1308 except Exception: 1309 pass 1310 try: 1311 devnull.close() 1312 except Exception: 1313 pass 1314 1315 return super(CommonRunCmd, self).do_quit(line)
1316 1317 1318 # Aliases 1319 do_EOF = do_quit 1320 do_exit = do_quit 1321 1322 ############################################################################
1323 - def do_open(self, line):
1324 """Open a text file/ eps file / html file""" 1325 1326 args = self.split_arg(line) 1327 # Check Argument validity and modify argument to be the real path 1328 self.check_open(args) 1329 file_path = args[0] 1330 1331 misc.open_file(file_path)
1332 1333 ############################################################################
1334 - def do_set(self, line, log=True):
1335 """Set an option, which will be default for coming generations/outputs 1336 """ 1337 # cmd calls automaticaly post_set after this command. 1338 1339 1340 args = self.split_arg(line) 1341 # Check the validity of the arguments 1342 self.check_set(args) 1343 # Check if we need to save this in the option file 1344 if args[0] in self.options_configuration and '--no_save' not in args: 1345 self.do_save('options --auto') 1346 1347 if args[0] == "stdout_level": 1348 if args[1].isdigit(): 1349 logging.root.setLevel(int(args[1])) 1350 logging.getLogger('madgraph').setLevel(int(args[1])) 1351 else: 1352 logging.root.setLevel(eval('logging.' + args[1])) 1353 logging.getLogger('madgraph').setLevel(eval('logging.' + args[1])) 1354 if log: logger.info('set output information to level: %s' % args[1]) 1355 elif args[0] == "fortran_compiler": 1356 if args[1] == 'None': 1357 args[1] = None 1358 self.options['fortran_compiler'] = args[1] 1359 current = misc.detect_current_compiler(pjoin(self.me_dir,'Source','make_opts'), 'fortran') 1360 if current != args[1] and args[1] != None: 1361 misc.mod_compilator(self.me_dir, args[1], current, 'gfortran') 1362 elif args[0] == "cpp_compiler": 1363 if args[1] == 'None': 1364 args[1] = None 1365 self.options['cpp_compiler'] = args[1] 1366 current = misc.detect_current_compiler(pjoin(self.me_dir,'Source','make_opts'), 'cpp') 1367 if current != args[1] and args[1] != None: 1368 misc.mod_compilator(self.me_dir, args[1], current, 'cpp') 1369 elif args[0] == "run_mode": 1370 if not args[1] in [0,1,2,'0','1','2']: 1371 raise self.InvalidCmd, 'run_mode should be 0, 1 or 2.' 1372 self.cluster_mode = int(args[1]) 1373 self.options['run_mode'] = self.cluster_mode 1374 elif args[0] in ['cluster_type', 'cluster_queue', 'cluster_temp_path']: 1375 if args[1] == 'None': 1376 args[1] = None 1377 self.options[args[0]] = args[1] 1378 # cluster (re)-initialization done later 1379 # self.cluster update at the end of the routine 1380 elif args[0] in ['cluster_nb_retry', 'cluster_retry_wait']: 1381 self.options[args[0]] = int(args[1]) 1382 # self.cluster update at the end of the routine 1383 elif args[0] == 'nb_core': 1384 if args[1] == 'None': 1385 import multiprocessing 1386 self.nb_core = multiprocessing.cpu_count() 1387 self.options['nb_core'] = self.nb_core 1388 return 1389 if not args[1].isdigit(): 1390 raise self.InvalidCmd('nb_core should be a positive number') 1391 self.nb_core = int(args[1]) 1392 self.options['nb_core'] = self.nb_core 1393 elif args[0] == 'timeout': 1394 self.options[args[0]] = int(args[1]) 1395 elif args[0] == 'cluster_status_update': 1396 if '(' in args[1]: 1397 data = ' '.join([a for a in args[1:] if not a.startswith('-')]) 1398 data = data.replace('(','').replace(')','').replace(',',' ').split() 1399 first, second = data[:2] 1400 else: 1401 first, second = args[1:3] 1402 1403 self.options[args[0]] = (int(first), int(second)) 1404 elif args[0] in self.options: 1405 if args[1] in ['None','True','False']: 1406 self.options[args[0]] = eval(args[1]) 1407 elif args[0].endswith('path'): 1408 if os.path.exists(args[1]): 1409 self.options[args[0]] = args[1] 1410 elif os.path.exists(pjoin(self.me_dir, args[1])): 1411 self.options[args[0]] = pjoin(self.me_dir, args[1]) 1412 else: 1413 raise self.InvalidCmd('Not a valid path: keep previous value: \'%s\'' % self.options[args[0]]) 1414 else: 1415 self.options[args[0]] = args[1]
1416
1417 - def post_set(self, stop, line):
1418 """Check if we need to save this in the option file""" 1419 try: 1420 args = self.split_arg(line) 1421 if 'cluster' in args[0] or args[0] == 'run_mode': 1422 self.configure_run_mode(self.options['run_mode']) 1423 1424 1425 # Check the validity of the arguments 1426 self.check_set(args) 1427 1428 if args[0] in self.options_configuration and '--no_save' not in args: 1429 self.exec_cmd('save options --auto') 1430 elif args[0] in self.options_madevent: 1431 logger.info('This option will be the default in any output that you are going to create in this session.') 1432 logger.info('In order to keep this changes permanent please run \'save options\'') 1433 return stop 1434 except self.InvalidCmd: 1435 return stop
1436
1437 - def configure_run_mode(self, run_mode):
1438 """change the way to submit job 0: single core, 1: cluster, 2: multicore""" 1439 1440 self.cluster_mode = run_mode 1441 1442 if run_mode == 2: 1443 if not self.options['nb_core']: 1444 import multiprocessing 1445 self.options['nb_core'] = multiprocessing.cpu_count() 1446 nb_core = self.options['nb_core'] 1447 elif run_mode == 0: 1448 nb_core = 1 1449 1450 1451 1452 if run_mode in [0, 2]: 1453 self.cluster = cluster.MultiCore( 1454 **self.options) 1455 self.cluster.nb_core = nb_core 1456 #cluster_temp_path=self.options['cluster_temp_path'], 1457 1458 if self.cluster_mode == 1: 1459 opt = self.options 1460 cluster_name = opt['cluster_type'] 1461 self.cluster = cluster.from_name[cluster_name](**opt)
1462
1463 - def check_param_card(self, path, run=True):
1464 """Check that all the width are define in the param_card. 1465 If some width are set on 'Auto', call the computation tools.""" 1466 1467 pattern = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto''',re.I) 1468 text = open(path).read() 1469 pdg = pattern.findall(text) 1470 if pdg: 1471 if run: 1472 logger.info('Computing the width set on auto in the param_card.dat') 1473 self.do_compute_widths('%s %s' % (' '.join(pdg), path)) 1474 else: 1475 logger.info('''Some width are on Auto in the card. 1476 Those will be computed as soon as you have finish the edition of the cards. 1477 If you want to force the computation right now and being able to re-edit 1478 the cards afterwards, you can type \"compute_wdiths\".''')
1479 1480
1481 - def add_error_log_in_html(self, errortype=None):
1482 """If a ME run is currently running add a link in the html output""" 1483 1484 # Be very carefull to not raise any error here (the traceback 1485 #will be modify in that case.) 1486 if hasattr(self, 'results') and hasattr(self.results, 'current') and\ 1487 self.results.current and 'run_name' in self.results.current and \ 1488 hasattr(self, 'me_dir'): 1489 name = self.results.current['run_name'] 1490 tag = self.results.current['tag'] 1491 self.debug_output = pjoin(self.me_dir, '%s_%s_debug.log' % (name,tag)) 1492 if errortype: 1493 self.results.current.debug = errortype 1494 else: 1495 self.results.current.debug = self.debug_output 1496 1497 else: 1498 #Force class default 1499 self.debug_output = CommonRunCmd.debug_output 1500 if os.path.exists('ME5_debug') and not 'ME5_debug' in self.debug_output: 1501 os.remove('ME5_debug') 1502 if not 'ME5_debug' in self.debug_output: 1503 os.system('ln -s %s ME5_debug &> /dev/null' % self.debug_output)
1504 1505
1506 - def do_quit(self, line):
1507 """Not in help: exit """ 1508 1509 try: 1510 os.remove(pjoin(self.me_dir,'RunWeb')) 1511 except Exception: 1512 pass 1513 try: 1514 self.store_result() 1515 except Exception: 1516 # If nothing runs they they are no result to update 1517 pass 1518 1519 try: 1520 self.update_status('', level=None) 1521 except Exception, error: 1522 pass 1523 devnull = open(os.devnull, 'w') 1524 try: 1525 misc.call(['./bin/internal/gen_cardhtml-pl'], cwd=self.me_dir, 1526 stdout=devnull, stderr=devnull) 1527 except Exception: 1528 pass 1529 devnull.close() 1530 1531 return super(CommonRunCmd, self).do_quit(line)
1532 1533 # Aliases 1534 do_EOF = do_quit 1535 do_exit = do_quit 1536 1537
1538 - def update_status(self, status, level, makehtml=True, force=True, 1539 error=False, starttime = None, update_results=True, 1540 print_log=True):
1541 """ update the index status """ 1542 1543 if makehtml and not force: 1544 if hasattr(self, 'next_update') and time.time() < self.next_update: 1545 return 1546 else: 1547 self.next_update = time.time() + 3 1548 1549 if print_log: 1550 if isinstance(status, str): 1551 if '<br>' not in status: 1552 logger.info(status) 1553 elif starttime: 1554 running_time = misc.format_timer(time.time()-starttime) 1555 logger.info(' Idle: %s, Running: %s, Completed: %s [ %s ]' % \ 1556 (status[0], status[1], status[2], running_time)) 1557 else: 1558 logger.info(' Idle: %s, Running: %s, Completed: %s' % status[:3]) 1559 1560 if update_results: 1561 self.results.update(status, level, makehtml=makehtml, error=error)
1562 1563 1564 ############################################################################
1565 - def keep_cards(self, need_card=[], ignore=[]):
1566 """Ask the question when launching generate_events/multi_run""" 1567 1568 check_card = ['pythia_card.dat', 'pgs_card.dat','delphes_card.dat', 1569 'delphes_trigger.dat', 'madspin_card.dat', 'shower_card.dat', 1570 'reweight_card.dat'] 1571 1572 cards_path = pjoin(self.me_dir,'Cards') 1573 for card in check_card: 1574 if card in ignore: 1575 continue 1576 if card not in need_card: 1577 if os.path.exists(pjoin(cards_path, card)): 1578 os.remove(pjoin(cards_path, card)) 1579 else: 1580 if not os.path.exists(pjoin(cards_path, card)): 1581 default = card.replace('.dat', '_default.dat') 1582 files.cp(pjoin(cards_path, default),pjoin(cards_path, card))
1583 1584 ############################################################################
1585 - def set_configuration(self, config_path=None, final=True, initdir=None, amcatnlo=False):
1586 """ assign all configuration variable from file 1587 ./Cards/mg5_configuration.txt. assign to default if not define """ 1588 1589 if not hasattr(self, 'options') or not self.options: 1590 self.options = dict(self.options_configuration) 1591 self.options.update(self.options_madgraph) 1592 self.options.update(self.options_madevent) 1593 1594 if not config_path: 1595 if os.environ.has_key('MADGRAPH_BASE'): 1596 config_path = pjoin(os.environ['MADGRAPH_BASE'],'mg5_configuration.txt') 1597 self.set_configuration(config_path=config_path, final=final) 1598 return 1599 if 'HOME' in os.environ: 1600 config_path = pjoin(os.environ['HOME'],'.mg5', 1601 'mg5_configuration.txt') 1602 if os.path.exists(config_path): 1603 self.set_configuration(config_path=config_path, final=False) 1604 if amcatnlo: 1605 me5_config = pjoin(self.me_dir, 'Cards', 'amcatnlo_configuration.txt') 1606 else: 1607 me5_config = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt') 1608 self.set_configuration(config_path=me5_config, final=False, initdir=self.me_dir) 1609 1610 if self.options.has_key('mg5_path') and self.options['mg5_path']: 1611 MG5DIR = self.options['mg5_path'] 1612 config_file = pjoin(MG5DIR, 'input', 'mg5_configuration.txt') 1613 self.set_configuration(config_path=config_file, final=False,initdir=MG5DIR) 1614 else: 1615 self.options['mg5_path'] = None 1616 return self.set_configuration(config_path=me5_config, final=final,initdir=self.me_dir) 1617 1618 config_file = open(config_path) 1619 1620 # read the file and extract information 1621 logger.info('load configuration from %s ' % config_file.name) 1622 for line in config_file: 1623 if '#' in line: 1624 line = line.split('#',1)[0] 1625 line = line.replace('\n','').replace('\r\n','') 1626 try: 1627 name, value = line.split('=') 1628 except ValueError: 1629 pass 1630 else: 1631 name = name.strip() 1632 value = value.strip() 1633 if name.endswith('_path'): 1634 path = value 1635 if os.path.isdir(path): 1636 self.options[name] = os.path.realpath(path) 1637 continue 1638 if not initdir: 1639 continue 1640 path = pjoin(initdir, value) 1641 if os.path.isdir(path): 1642 self.options[name] = os.path.realpath(path) 1643 continue 1644 else: 1645 self.options[name] = value 1646 if value.lower() == "none": 1647 self.options[name] = None 1648 1649 if not final: 1650 return self.options # the return is usefull for unittest 1651 1652 1653 # Treat each expected input 1654 # delphes/pythia/... path 1655 for key in self.options: 1656 # Final cross check for the path 1657 if key.endswith('path'): 1658 path = self.options[key] 1659 if path is None: 1660 continue 1661 if os.path.isdir(path): 1662 self.options[key] = os.path.realpath(path) 1663 continue 1664 path = pjoin(self.me_dir, self.options[key]) 1665 if os.path.isdir(path): 1666 self.options[key] = os.path.realpath(path) 1667 continue 1668 elif self.options.has_key('mg5_path') and self.options['mg5_path']: 1669 path = pjoin(self.options['mg5_path'], self.options[key]) 1670 if os.path.isdir(path): 1671 self.options[key] = os.path.realpath(path) 1672 continue 1673 self.options[key] = None 1674 elif key.startswith('cluster') and key != 'cluster_status_update': 1675 if key in ('cluster_nb_retry','cluster_wait_retry'): 1676 self.options[key] = int(self.options[key]) 1677 if hasattr(self,'cluster'): 1678 del self.cluster 1679 pass 1680 elif key == 'automatic_html_opening': 1681 if self.options[key] in ['False', 'True']: 1682 self.options[key] =eval(self.options[key]) 1683 elif key not in ['text_editor','eps_viewer','web_browser','stdout_level', 1684 'complex_mass_scheme', 'gauge', 'group_subprocesses']: 1685 # Default: try to set parameter 1686 try: 1687 self.do_set("%s %s --no_save" % (key, self.options[key]), log=False) 1688 except self.InvalidCmd: 1689 logger.warning("Option %s from config file not understood" \ 1690 % key) 1691 1692 # Configure the way to open a file: 1693 misc.open_file.configure(self.options) 1694 self.configure_run_mode(self.options['run_mode']) 1695 1696 return self.options
1697 1698 @staticmethod
1699 - def find_available_run_name(me_dir):
1700 """ find a valid run_name for the current job """ 1701 1702 name = 'run_%02d' 1703 data = [int(s[4:]) for s in os.listdir(pjoin(me_dir,'Events')) if 1704 s.startswith('run_') and len(s)>5 and s[4:].isdigit()] 1705 return name % (max(data+[0])+1)
1706 1707 1708 ############################################################################
1709 - def do_decay_events(self,line):
1710 """Require MG5 directory: decay events with spin correlations 1711 """ 1712 1713 if '-from_cards' in line and not os.path.exists(pjoin(self.me_dir, 'Cards', 'madspin_card.dat')): 1714 return 1715 1716 # First need to load MadSpin 1717 1718 # Check that MG5 directory is present . 1719 if MADEVENT and not self.options['mg5_path']: 1720 raise self.InvalidCmd, '''The module decay_events requires that MG5 is installed on the system. 1721 You can install it and set its path in ./Cards/me5_configuration.txt''' 1722 elif MADEVENT: 1723 sys.path.append(self.options['mg5_path']) 1724 try: 1725 import MadSpin.decay as decay 1726 import MadSpin.interface_madspin as interface_madspin 1727 except ImportError: 1728 raise self.ConfigurationError, '''Can\'t load MadSpin 1729 The variable mg5_path might not be correctly configured.''' 1730 1731 self.update_status('Running MadSpin', level='madspin') 1732 if not '-from_cards' in line: 1733 self.keep_cards(['madspin_card.dat']) 1734 self.ask_edit_cards(['madspin_card.dat'], 'fixed', plot=False) 1735 self.help_decay_events(skip_syntax=True) 1736 1737 # load the name of the event file 1738 args = self.split_arg(line) 1739 self.check_decay_events(args) 1740 # args now alway content the path to the valid files 1741 madspin_cmd = interface_madspin.MadSpinInterface(args[0]) 1742 madspin_cmd.update_status = lambda *x,**opt: self.update_status(*x, level='madspin',**opt) 1743 1744 path = pjoin(self.me_dir, 'Cards', 'madspin_card.dat') 1745 1746 madspin_cmd.import_command_file(path) 1747 1748 # create a new run_name directory for this output 1749 i = 1 1750 while os.path.exists(pjoin(self.me_dir,'Events', '%s_decayed_%i' % (self.run_name,i))): 1751 i+=1 1752 new_run = '%s_decayed_%i' % (self.run_name,i) 1753 evt_dir = pjoin(self.me_dir, 'Events') 1754 1755 os.mkdir(pjoin(evt_dir, new_run)) 1756 current_file = args[0].replace('.lhe', '_decayed.lhe') 1757 new_file = pjoin(evt_dir, new_run, os.path.basename(args[0])) 1758 if not os.path.exists(current_file): 1759 if os.path.exists(current_file+'.gz'): 1760 current_file += '.gz' 1761 new_file += '.gz' 1762 else: 1763 logger.error('MadSpin fails to create any decayed file.') 1764 return 1765 1766 files.mv(current_file, new_file) 1767 logger.info("The decayed event file has been moved to the following location: ") 1768 logger.info(new_file) 1769 1770 if hasattr(self, 'results'): 1771 current = self.results.current 1772 nb_event = self.results.current['nb_event'] 1773 if not nb_event: 1774 current = self.results[self.run_name][0] 1775 nb_event = current['nb_event'] 1776 1777 cross = current['cross'] 1778 error = current['error'] 1779 self.results.add_run( new_run, self.run_card) 1780 self.results.add_detail('nb_event', nb_event) 1781 self.results.add_detail('cross', cross * madspin_cmd.branching_ratio) 1782 self.results.add_detail('error', error * madspin_cmd.branching_ratio) 1783 self.results.add_detail('run_mode', current['run_mode']) 1784 1785 self.run_name = new_run 1786 self.banner = madspin_cmd.banner 1787 self.banner.add(path) 1788 self.banner.write(pjoin(self.me_dir,'Events',self.run_name, '%s_%s_banner.txt' % 1789 (self.run_name, self.run_tag))) 1790 self.update_status('MadSpin Done', level='parton', makehtml=False) 1791 if 'unweighted' in os.path.basename(args[0]): 1792 self.create_plot('parton')
1793
1794 - def complete_decay_events(self, text, line, begidx, endidx):
1795 args = self.split_arg(line[0:begidx], error=False) 1796 if len(args) == 1: 1797 return self.complete_plot(text, line, begidx, endidx) 1798 else: 1799 return
1800
1801 - def complete_print_results(self,text, line, begidx, endidx):
1802 "Complete the print results command" 1803 args = self.split_arg(line[0:begidx], error=False) 1804 if len(args) == 1: 1805 #return valid run_name 1806 data = glob.glob(pjoin(self.me_dir, 'Events', '*','unweighted_events.lhe.gz')) 1807 data = [n.rsplit('/',2)[1] for n in data] 1808 tmp1 = self.list_completion(text, data) 1809 return tmp1 1810 else: 1811 data = glob.glob(pjoin(self.me_dir, 'Events', args[0], '*_pythia_events.hep.gz')) 1812 data = [os.path.basename(p).rsplit('_',1)[0] for p in data] 1813 tmp1 = self.list_completion(text, data) 1814 return tmp1
1815
1816 - def help_print_result(self):
1817 logger.info("syntax: print_result [RUN] [TAG] [options]") 1818 logger.info("-- show in text format the status of the run (cross-section/nb-event/...)") 1819 logger.info("--path= defines the path of the output file.") 1820 logger.info("--mode=a allow to add the information at the end of the file.")
1821 1822 1823 ############################################################################
1824 - def do_check_events(self, line):
1825 """ Run some sanity check on the generated events.""" 1826 1827 # Check that MG5 directory is present . 1828 if MADEVENT and not self.options['mg5_path']: 1829 raise self.InvalidCmd, '''The module reweight requires that MG5 is installed on the system. 1830 You can install it and set its path in ./Cards/me5_configuration.txt''' 1831 elif MADEVENT: 1832 sys.path.append(self.options['mg5_path']) 1833 try: 1834 import madgraph.interface.reweight_interface as reweight_interface 1835 except ImportError: 1836 raise self.ConfigurationError, '''Can\'t load Reweight module. 1837 The variable mg5_path might not be correctly configured.''' 1838 1839 1840 # load the name of the event file 1841 args = self.split_arg(line) 1842 self.check_check_events(args) 1843 # args now alway content the path to the valid files 1844 reweight_cmd = reweight_interface.ReweightInterface(args[0]) 1845 reweight_cmd.mother = self 1846 self.update_status('Running check on events', level='check') 1847 1848 reweight_cmd.check_events()
1849 1850 ############################################################################
1851 - def complete_check_events(self, text, line, begidx, endidx):
1852 args = self.split_arg(line[0:begidx], error=False) 1853 1854 if len(args) == 1 and os.path.sep not in text: 1855 #return valid run_name 1856 data = glob.glob(pjoin(self.me_dir, 'Events', '*','*events.lhe*')) 1857 data = [n.rsplit('/',2)[1] for n in data] 1858 return self.list_completion(text, data, line) 1859 else: 1860 return self.path_completion(text, 1861 os.path.join('.',*[a for a in args \ 1862 if a.endswith(os.path.sep)]))
1863
1864 - def complete_compute_widths(self, text, line, begidx, endidx):
1865 "Complete the compute_widths command" 1866 1867 args = self.split_arg(line[0:begidx]) 1868 1869 if args[-1] in ['--path=', '--output=']: 1870 completion = {'path': self.path_completion(text)} 1871 elif line[begidx-1] == os.path.sep: 1872 current_dir = pjoin(*[a for a in args if a.endswith(os.path.sep)]) 1873 if current_dir.startswith('--path='): 1874 current_dir = current_dir[7:] 1875 if current_dir.startswith('--output='): 1876 current_dir = current_dir[9:] 1877 completion = {'path': self.path_completion(text, current_dir)} 1878 else: 1879 completion = {} 1880 completion['options'] = self.list_completion(text, 1881 ['--path=', '--output=', '--min_br=0.\$' 1882 '--precision_channel=0.\$', '--body_decay=']) 1883 1884 return self.deal_multiple_categories(completion)
1885 1886 1887 # lhapdf-related functions 1915 1916
1917 - def copy_lhapdf_set(self, lhaid_list, pdfsets_dir):
1918 """copy (if needed) the lhapdf set corresponding to the lhaid in lhaid_list 1919 into lib/PDFsets""" 1920 1921 pdfsetname = '' 1922 for lhaid in lhaid_list: 1923 try: 1924 if not pdfsetname: 1925 if lhaid in self.lhapdf_pdfsets: 1926 pdfsetname = self.lhapdf_pdfsets[lhaid]['filename'] 1927 else: 1928 raise MadGraph5Error('lhaid %s not valid input number for the current lhapdf' % lhaid ) 1929 # just check the other ids refer to the same pdfsetname 1930 elif not \ 1931 self.lhapdf_pdfsets[lhaid]['filename'] == pdfsetname: 1932 raise MadGraph5Error(\ 1933 'lhaid and PDF_set_min/max in the run_card do not correspond to the' + \ 1934 'same PDF set. Please check the run_card.') 1935 except KeyError: 1936 if self.lhapdf_version.startswith('5'): 1937 raise MadGraph5Error(\ 1938 ('invalid lhaid set in th run_card: %d .\nPlease note that some sets' % lhaid) + \ 1939 '(eg MSTW 90%CL error sets) \nare not available in aMC@NLO + LHAPDF 5.x.x') 1940 else: 1941 logger.debug('%d not found in pdfsets.index' % lhaid) 1942 1943 1944 # check if the file exists, otherwise install it: 1945 # also check that the PDFsets dir exists, otherwise create it. 1946 # if fails, install the lhapdfset into lib/PDFsets 1947 if not os.path.isdir(pdfsets_dir): 1948 try: 1949 os.mkdir(pdfsets_dir) 1950 except OSError: 1951 pdfsets_dir = pjoin(self.me_dir, 'lib', 'PDFsets') 1952 1953 #check that the pdfset is not already there 1954 if not os.path.exists(pjoin(self.me_dir, 'lib', 'PDFsets', pdfsetname)) and \ 1955 not os.path.isdir(pjoin(self.me_dir, 'lib', 'PDFsets', pdfsetname)): 1956 1957 if pdfsetname and not os.path.exists(pjoin(pdfsets_dir, pdfsetname)): 1958 self.install_lhapdf_pdfset(pdfsets_dir, pdfsetname) 1959 1960 if os.path.exists(pjoin(pdfsets_dir, pdfsetname)): 1961 files.cp(pjoin(pdfsets_dir, pdfsetname), pjoin(self.me_dir, 'lib', 'PDFsets')) 1962 elif os.path.exists(pjoin(os.path.dirname(pdfsets_dir), pdfsetname)): 1963 files.cp(pjoin(os.path.dirname(pdfsets_dir), pdfsetname), pjoin(self.me_dir, 'lib', 'PDFsets'))
1964 1965
1966 - def install_lhapdf_pdfset(self, pdfsets_dir, filename):
1967 """idownloads and install the pdfset filename in the pdfsets_dir""" 1968 lhapdf_version = self.get_lhapdf_version() 1969 logger.info('Trying to download %s' % filename) 1970 1971 if lhapdf_version.startswith('5.'): 1972 # use the lhapdf-getdata command, which is in the same path as 1973 # lhapdf-config 1974 getdata = self.options['lhapdf'].replace('lhapdf-config', ('lhapdf-getdata')) 1975 misc.call([getdata, filename], cwd = pdfsets_dir) 1976 1977 elif lhapdf_version.startswith('6.'): 1978 # use the "lhapdf install xxx" command, which is in the same path as 1979 # lhapdf-config 1980 getdata = self.options['lhapdf'].replace('lhapdf-config', ('lhapdf')) 1981 1982 misc.call([getdata, 'install', filename], cwd = pdfsets_dir) 1983 1984 else: 1985 raise MadGraph5Error('Not valid LHAPDF version: %s' % lhapdf_version) 1986 1987 # check taht the file has been installed in the global dir 1988 if os.path.exists(pjoin(pdfsets_dir, filename)) or \ 1989 os.path.isdir(pjoin(pdfsets_dir, filename)): 1990 logger.info('%s successfully downloaded and stored in %s' \ 1991 % (filename, pdfsets_dir)) 1992 #otherwise (if v5) save it locally 1993 elif lhapdf_version.startswith('5.'): 1994 logger.warning('Could not download %s into %s. Trying to save it locally' \ 1995 % (filename, pdfsets_dir)) 1996 self.install_lhapdf_pdfset(pjoin(self.me_dir, 'lib', 'PDFsets'), filename) 1997 else: 1998 raise MadGraph5Error, \ 1999 'Could not download %s into %s. Please try to install it manually.' \ 2000 % (filename, pdfsets_dir)
2001 2002
2003 - def get_lhapdf_pdfsets_list(self, pdfsets_dir):
2004 """read the PDFsets.index file, which should be located in the same 2005 place as pdfsets_dir, and return a list of dictionaries with the information 2006 about each pdf set""" 2007 lhapdf_version = self.get_lhapdf_version() 2008 2009 if lhapdf_version.startswith('5.'): 2010 if os.path.exists('%s.index' % pdfsets_dir): 2011 indexfile = '%s.index' % pdfsets_dir 2012 else: 2013 raise MadGraph5Error, 'index of lhapdf file not found' 2014 pdfsets_lines = \ 2015 [l for l in open(indexfile).read().split('\n') if l.strip() and \ 2016 not '90cl' in l] 2017 lhapdf_pdfsets = dict( (int(l.split()[0]), {'lhaid': int(l.split()[0]), 2018 'pdflib_ntype': int(l.split()[1]), 2019 'pdflib_ngroup': int(l.split()[2]), 2020 'pdflib_nset': int(l.split()[3]), 2021 'filename': l.split()[4], 2022 'lhapdf_nmem': int(l.split()[5]), 2023 'q2min': float(l.split()[6]), 2024 'q2max': float(l.split()[7]), 2025 'xmin': float(l.split()[8]), 2026 'xmax': float(l.split()[9]), 2027 'description': l.split()[10]}) \ 2028 for l in pdfsets_lines) 2029 2030 elif lhapdf_version.startswith('6.'): 2031 pdfsets_lines = \ 2032 [l for l in open(pjoin(pdfsets_dir, 'pdfsets.index')).read().split('\n') if l.strip()] 2033 lhapdf_pdfsets = dict( (int(l.split()[0]), 2034 {'lhaid': int(l.split()[0]), 2035 'filename': l.split()[1]}) \ 2036 for l in pdfsets_lines) 2037 2038 else: 2039 raise MadGraph5Error('Not valid LHAPDF version: %s' % lhapdf_version) 2040 2041 return lhapdf_pdfsets
2042 2043
2044 - def get_lhapdf_version(self):
2045 """returns the lhapdf version number""" 2046 if not hasattr(self, 'lhapdfversion'): 2047 self.lhapdf_version = \ 2048 subprocess.Popen([self.options['lhapdf'], '--version'], 2049 stdout = subprocess.PIPE).stdout.read().strip() 2050 2051 # this will be removed once some issues in lhapdf6 will be fixed 2052 if self.lhapdf_version.startswith('6.0'): 2053 raise MadGraph5Error('LHAPDF 6.0.x not supported. Please use v6.1 or later') 2054 2055 return self.lhapdf_version
2056 2057
2058 - def get_lhapdf_pdfsetsdir(self):
2059 lhapdf_version = self.get_lhapdf_version() 2060 2061 if lhapdf_version.startswith('5.'): 2062 datadir = subprocess.Popen([self.options['lhapdf'], '--pdfsets-path'], 2063 stdout = subprocess.PIPE).stdout.read().strip() 2064 2065 elif lhapdf_version.startswith('6.'): 2066 datadir = subprocess.Popen([self.options['lhapdf'], '--datadir'], 2067 stdout = subprocess.PIPE).stdout.read().strip() 2068 2069 return datadir
2070
2071 -class AskforEditCard(cmd.OneLinePathCompletion):
2072 """A class for asking a question where in addition you can have the 2073 set command define and modifying the param_card/run_card correctly""" 2074 2075 special_shortcut = {'ebeam':['run_card ebeam1 %(0)s', 'run_card ebeam2 %(0)s'], 2076 'lpp': ['run_card lpp1 %(0)s', 'run_card lpp2 %(0)s' ], 2077 'lhc': ['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2'], 2078 'lep': ['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2'], 2079 'ilc': ['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2'], 2080 'lcc':['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2'], 2081 'fixed_scale': ['run_card fixed_fac_scale T', 'run_card fixed_ren_scale T', 'run_card scale %(0)s', 'run_card dsqrt_q2fact1 %(0)s' ,'run_card dsqrt_q2fact2 %(0)s'], 2082 } 2083
2084 - def __init__(self, question, cards=[], mode='auto', *args, **opt):
2085 2086 # Initiation 2087 if 'pwd' in opt: 2088 self.me_dir = opt['pwd'] 2089 del opt['pwd'] 2090 2091 cmd.OneLinePathCompletion.__init__(self, question, *args, **opt) 2092 2093 if not hasattr(self, 'me_dir') or not self.me_dir: 2094 self.me_dir = self.mother_interface.me_dir 2095 2096 # read the card 2097 2098 try: 2099 self.run_card = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card.dat')) 2100 except IOError: 2101 self.run_card = {} 2102 try: 2103 self.param_card = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card.dat')) 2104 except (check_param_card.InvalidParamCard, ValueError) as e: 2105 logger.error('Current param_card is not valid. We are going to use the default one.') 2106 logger.error('problem detected: %s' % e) 2107 files.cp(pjoin(self.me_dir,'Cards','param_card_default.dat'), 2108 pjoin(self.me_dir,'Cards','param_card.dat')) 2109 self.param_card = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card.dat')) 2110 default_param = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card_default.dat')) 2111 try: 2112 run_card_def = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card_default.dat')) 2113 except IOError: 2114 run_card_def = {} 2115 2116 self.pname2block = {} 2117 self.conflict = [] 2118 self.restricted_value = {} 2119 self.mode = mode 2120 self.cards = cards 2121 2122 # Read the comment of the param_card_default to find name variable for 2123 # the param_card also check which value seems to be constrained in the 2124 # model. 2125 for bname, block in default_param.items(): 2126 for lha_id, param in block.param_dict.items(): 2127 all_var = [] 2128 comment = param.comment 2129 # treat merge parameter 2130 if comment.strip().startswith('set of param :'): 2131 all_var = list(re.findall(r'''[^-]1\*(\w*)\b''', comment)) 2132 # just the variable name as comment 2133 elif len(comment.split()) == 1: 2134 all_var = [comment.strip().lower()] 2135 # either contraction or not formatted 2136 else: 2137 split = comment.split() 2138 if len(split) >2 and split[1] == ':': 2139 # NO VAR associated 2140 self.restricted_value[(bname, lha_id)] = ' '.join(split[1:]) 2141 elif len(split) == 2: 2142 if re.search(r'''\[[A-Z]\]eV\^''', split[1]): 2143 all_var = [comment.strip().lower()] 2144 else: 2145 # not recognized format 2146 continue 2147 2148 for var in all_var: 2149 var = var.lower() 2150 if var in self.pname2block: 2151 self.pname2block[var].append((bname, lha_id)) 2152 else: 2153 self.pname2block[var] = [(bname, lha_id)] 2154 2155 if run_card_def: 2156 self.run_set = run_card_def.keys() + self.run_card.hidden_param 2157 elif self.run_card: 2158 self.run_set = self.run_card.keys() 2159 else: 2160 self.run_set = [] 2161 # check for conflict with run_card 2162 for var in self.pname2block: 2163 if var in self.run_set: 2164 self.conflict.append(var) 2165 2166 2167 #check if Madweight_card is present: 2168 self.has_mw = False 2169 if 'madweight_card.dat' in cards: 2170 2171 self.do_change_tf = self.mother_interface.do_define_transfer_fct 2172 self.complete_change_tf = self.mother_interface.complete_define_transfer_fct 2173 self.help_change_tf = self.mother_interface.help_define_transfer_fct 2174 if not os.path.exists(pjoin(self.me_dir,'Cards','transfer_card.dat')): 2175 logger.warning('No transfer function currently define. Please use the change_tf command to define one.') 2176 2177 2178 self.has_mw = True 2179 try: 2180 import madgraph.madweight.Cards as mwcards 2181 except: 2182 import internal.madweight.Cards as mwcards 2183 self.mw_card = mwcards.Card(pjoin(self.me_dir,'Cards','MadWeight_card.dat')) 2184 self.mw_card = self.mw_card.info 2185 self.mw_vars = [] 2186 for key in self.mw_card: 2187 if key == 'comment': 2188 continue 2189 for key2 in self.mw_card.info[key]: 2190 if isinstance(key2, str) and not key2.isdigit(): 2191 self.mw_vars.append(key2) 2192 2193 # check for conflict with run_card/param_card 2194 for var in self.pname2block: 2195 if var in self.mw_vars: 2196 self.conflict.append(var) 2197 for var in self.mw_vars: 2198 if var in self.run_card: 2199 self.conflict.append(var)
2200
2201 - def complete_set(self, text, line, begidx, endidx):
2202 """ Complete the set command""" 2203 2204 prev_timer = signal.alarm(0) # avoid timer if any 2205 if prev_timer: 2206 nb_back = len(line) 2207 self.stdout.write('\b'*nb_back + '[timer stopped]\n') 2208 self.stdout.write(line) 2209 self.stdout.flush() 2210 2211 possibilities = {} 2212 allowed = {} 2213 args = self.split_arg(line[0:begidx]) 2214 if args[-1] in ['Auto', 'default']: 2215 return 2216 if len(args) == 1: 2217 allowed = {'category':'', 'run_card':'', 'block':'all', 'param_card':'','shortcut':''} 2218 if self.has_mw: 2219 allowed['madweight_card'] = '' 2220 allowed['mw_block'] = 'all' 2221 elif len(args) == 2: 2222 if args[1] == 'run_card': 2223 allowed = {'run_card':'default'} 2224 elif args[1] == 'param_card': 2225 allowed = {'block':'all', 'param_card':'default'} 2226 elif args[1] in self.param_card.keys(): 2227 allowed = {'block':args[1]} 2228 elif args[1] == 'width': 2229 allowed = {'block': 'decay'} 2230 elif args[1] == 'MadWeight_card': 2231 allowed = {'madweight_card':'default', 'mw_block': 'all'} 2232 elif self.has_mw and args[1] in self.mw_card.keys(): 2233 allowed = {'mw_block':args[1]} 2234 else: 2235 allowed = {'value':''} 2236 else: 2237 start = 1 2238 if args[1] in ['run_card', 'param_card', 'MadWeight_card']: 2239 start = 2 2240 if args[-1] in self.pname2block.keys(): 2241 allowed['value'] = 'default' 2242 elif args[start] in self.param_card.keys() or args[start] == 'width': 2243 if args[start] == 'width': 2244 args[start] = 'decay' 2245 2246 if args[start+1:]: 2247 allowed = {'block':(args[start], args[start+1:])} 2248 else: 2249 allowed = {'block':args[start]} 2250 elif self.has_mw and args[start] in self.mw_card.keys(): 2251 if args[start+1:]: 2252 allowed = {'mw_block':(args[start], args[start+1:])} 2253 else: 2254 allowed = {'mw_block':args[start]} 2255 #elif len(args) == start +1: 2256 # allowed['value'] = '' 2257 else: 2258 allowed['value'] = '' 2259 2260 if 'category' in allowed.keys(): 2261 categories = ['run_card', 'param_card'] 2262 if self.has_mw: 2263 categories.append('MadWeight_card') 2264 2265 possibilities['category of parameter (optional)'] = \ 2266 self.list_completion(text, categories) 2267 2268 if 'shortcut' in allowed.keys(): 2269 possibilities['special values'] = self.list_completion(text, self.special_shortcut.keys()+['qcut', 'showerkt']) 2270 2271 if 'run_card' in allowed.keys(): 2272 opts = self.run_set 2273 if allowed['run_card'] == 'default': 2274 opts.append('default') 2275 2276 possibilities['Run Card'] = self.list_completion(text, opts) 2277 2278 if 'param_card' in allowed.keys(): 2279 opts = self.pname2block.keys() 2280 if allowed['param_card'] == 'default': 2281 opts.append('default') 2282 possibilities['Param Card'] = self.list_completion(text, opts) 2283 2284 if 'madweight_card' in allowed.keys(): 2285 opts = self.mw_vars + [k for k in self.mw_card.keys() if k !='comment'] 2286 if allowed['madweight_card'] == 'default': 2287 opts.append('default') 2288 possibilities['MadWeight Card'] = self.list_completion(text, opts) 2289 2290 if 'value' in allowed.keys(): 2291 opts = ['default'] 2292 if 'decay' in args: 2293 opts.append('Auto') 2294 if args[-1] in self.pname2block and self.pname2block[args[-1]][0][0] == 'decay': 2295 opts.append('Auto') 2296 possibilities['Special Value'] = self.list_completion(text, opts) 2297 2298 2299 if 'block' in allowed.keys(): 2300 if allowed['block'] == 'all': 2301 allowed_block = [i for i in self.param_card.keys() if 'qnumbers' not in i] 2302 allowed_block.append('width') 2303 possibilities['Param Card Block' ] = \ 2304 self.list_completion(text, allowed_block) 2305 elif isinstance(allowed['block'], basestring): 2306 block = self.param_card[allowed['block']].param_dict 2307 ids = [str(i[0]) for i in block 2308 if (allowed['block'], i) not in self.restricted_value] 2309 possibilities['Param Card id' ] = self.list_completion(text, ids) 2310 varname = [name for name, all_var in self.pname2block.items() 2311 if any((bname == allowed['block'] 2312 for bname,lhaid in all_var))] 2313 possibilities['Param card variable'] = self.list_completion(text, 2314 varname) 2315 else: 2316 block = self.param_card[allowed['block'][0]].param_dict 2317 nb = len(allowed['block'][1]) 2318 ids = [str(i[nb]) for i in block if len(i) > nb and \ 2319 [str(a) for a in i[:nb]] == allowed['block'][1]] 2320 2321 if not ids: 2322 if tuple([int(i) for i in allowed['block'][1]]) in block: 2323 opts = ['default'] 2324 if allowed['block'][0] == 'decay': 2325 opts.append('Auto') 2326 possibilities['Special value'] = self.list_completion(text, opts) 2327 possibilities['Param Card id' ] = self.list_completion(text, ids) 2328 2329 if 'mw_block' in allowed.keys(): 2330 if allowed['mw_block'] == 'all': 2331 allowed_block = [i for i in self.mw_card.keys() if 'comment' not in i] 2332 possibilities['MadWeight Block' ] = \ 2333 self.list_completion(text, allowed_block) 2334 elif isinstance(allowed['mw_block'], basestring): 2335 block = self.mw_card[allowed['mw_block']] 2336 ids = [str(i[0]) if isinstance(i, tuple) else str(i) for i in block] 2337 possibilities['MadWeight Card id' ] = self.list_completion(text, ids) 2338 else: 2339 block = self.mw_card[allowed['mw_block'][0]] 2340 nb = len(allowed['mw_block'][1]) 2341 ids = [str(i[nb]) for i in block if isinstance(i, tuple) and\ 2342 len(i) > nb and \ 2343 [str(a) for a in i[:nb]] == allowed['mw_block'][1]] 2344 2345 if not ids: 2346 if tuple([i for i in allowed['mw_block'][1]]) in block or \ 2347 allowed['mw_block'][1][0] in block.keys(): 2348 opts = ['default'] 2349 possibilities['Special value'] = self.list_completion(text, opts) 2350 possibilities['MadWeight Card id' ] = self.list_completion(text, ids) 2351 2352 return self.deal_multiple_categories(possibilities)
2353
2354 - def do_set(self, line):
2355 """ edit the value of one parameter in the card""" 2356 2357 args = self.split_arg(line.lower()) 2358 if '=' in args[-1]: 2359 arg1, arg2 = args.pop(-1).split('=') 2360 args += [arg1, arg2] 2361 2362 # special shortcut: 2363 if args[0] in self.special_shortcut: 2364 if len(args) == 1: 2365 values = {} 2366 elif len(args) == 2: 2367 try: 2368 values = {'0': float(args[1])} 2369 except ValueError as e: 2370 logger.warning("Wrong argument: The last entry should be a number.") 2371 return 2372 else: 2373 logger.warning("too many argument for this command") 2374 return 2375 2376 for arg in self.special_shortcut[args[0]]: 2377 try: 2378 text = arg % values 2379 except KeyError: 2380 logger.warning("This command requires one argument") 2381 return 2382 except Exception as e: 2383 logger.warning(str(e)) 2384 return 2385 else: 2386 self.do_set(arg % values) 2387 return 2388 2389 2390 start = 0 2391 if len(args) < 2: 2392 logger.warning('Invalid set command %s (need two arguments)' % line) 2393 return 2394 2395 # Special case for the qcut value 2396 if args[0].lower() == 'qcut': 2397 pythia_path = pjoin(self.me_dir, 'Cards','pythia_card.dat') 2398 if os.path.exists(pythia_path): 2399 logger.info('add line QCUT = %s in pythia_card.dat' % args[1]) 2400 p_card = open(pythia_path,'r').read() 2401 p_card, n = re.subn('''^\s*QCUT\s*=\s*[\de\+\-\.]*\s*$''', 2402 ''' QCUT = %s ''' % args[1], \ 2403 p_card, flags=(re.M+re.I)) 2404 if n==0: 2405 p_card = '%s \n QCUT= %s' % (p_card, args[1]) 2406 open(pythia_path, 'w').write(p_card) 2407 return 2408 # Special case for the showerkt value 2409 if args[0].lower() == 'showerkt': 2410 pythia_path = pjoin(self.me_dir, 'Cards','pythia_card.dat') 2411 if os.path.exists(pythia_path): 2412 logger.info('add line SHOWERKT = %s in pythia_card.dat' % args[1].upper()) 2413 p_card = open(pythia_path,'r').read() 2414 p_card, n = re.subn('''^\s*SHOWERKT\s*=\s*[default\de\+\-\.]*\s*$''', 2415 ''' SHOWERKT = %s ''' % args[1].upper(), \ 2416 p_card, flags=(re.M+re.I)) 2417 if n==0: 2418 p_card = '%s \n SHOWERKT= %s' % (p_card, args[1].upper()) 2419 open(pythia_path, 'w').write(p_card) 2420 return 2421 2422 2423 card = '' #store which card need to be modify (for name conflict) 2424 if args[0] == 'madweight_card': 2425 if not self.mw_card: 2426 logger.warning('Invalid Command: No MadWeight card defined.') 2427 return 2428 args[0] = 'MadWeight_card' 2429 2430 if args[0] in ['run_card', 'param_card', 'MadWeight_card']: 2431 if args[1] == 'default': 2432 logging.info('replace %s by the default card' % args[0]) 2433 files.cp(pjoin(self.me_dir,'Cards','%s_default.dat' % args[0]), 2434 pjoin(self.me_dir,'Cards','%s.dat'% args[0])) 2435 if args[0] == 'param_card': 2436 self.param_card = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card.dat')) 2437 elif args[0] == 'run_card': 2438 self.run_card = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card.dat')) 2439 return 2440 else: 2441 card = args[0] 2442 start=1 2443 if len(args) < 3: 2444 logger.warning('Invalid set command: %s (not enough arguments)' % line) 2445 return 2446 2447 #### RUN CARD 2448 if args[start] in [l.lower() for l in self.run_card.keys()] and card in ['', 'run_card']: 2449 if args[start] not in self.run_set: 2450 args[start] = [l for l in self.run_set if l.lower() == args[start]][0] 2451 2452 if args[start+1] in self.conflict and card == '': 2453 text = 'ambiguous name (present in more than one card). Please specify which card to edit' 2454 logger.warning(text) 2455 return 2456 2457 if args[start+1] == 'default': 2458 default = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card_default.dat')) 2459 if args[start] in default.keys(): 2460 self.setR(args[start],default[args[start]]) 2461 else: 2462 logger.info('remove information %s from the run_card' % args[start]) 2463 del self.run_card[args[start]] 2464 elif args[start+1].lower() in ['t','.true.','true']: 2465 self.setR(args[start], '.true.') 2466 elif args[start+1].lower() in ['f','.false.','false']: 2467 self.setR(args[start], '.false.') 2468 else: 2469 if args[0].startswith('sys_'): 2470 val = ' '.join(args[start+1:]) 2471 val = val.split('#')[0] 2472 else: 2473 try: 2474 val = eval(args[start+1]) 2475 except NameError: 2476 val = args[start+1] 2477 self.setR(args[start], val) 2478 self.run_card.write(pjoin(self.me_dir,'Cards','run_card.dat'), 2479 pjoin(self.me_dir,'Cards','run_card_default.dat')) 2480 2481 ### PARAM_CARD WITH BLOCK NAME ----------------------------------------- 2482 elif (args[start] in self.param_card or args[start] == 'width') \ 2483 and card in ['','param_card']: 2484 if args[start+1] in self.conflict and card == '': 2485 text = 'ambiguous name (present in more than one card). Please specify which card to edit' 2486 logger.warning(text) 2487 return 2488 2489 if args[start] == 'width': 2490 args[start] = 'decay' 2491 2492 if args[start+1] in self.pname2block: 2493 all_var = self.pname2block[args[start+1]] 2494 key = None 2495 for bname, lhaid in all_var: 2496 if bname == args[start]: 2497 key = lhaid 2498 break 2499 else: 2500 logger.warning('%s is not part of block "%s" but "%s". please correct.' % 2501 (args[start+1], args[start], bname)) 2502 return 2503 else: 2504 try: 2505 key = tuple([int(i) for i in args[start+1:-1]]) 2506 except ValueError: 2507 if args[start] == 'decay' and args[start+1:-1] == ['all']: 2508 for key in self.param_card[args[start]].param_dict: 2509 if (args[start], key) in self.restricted_value: 2510 continue 2511 else: 2512 self.setP(args[start], key, args[-1]) 2513 self.param_card.write(pjoin(self.me_dir,'Cards','param_card.dat')) 2514 return 2515 logger.warning('invalid set command %s (failed to identify LHA information)' % line) 2516 return 2517 2518 if key in self.param_card[args[start]].param_dict: 2519 if (args[start], key) in self.restricted_value: 2520 text = "Note that this parameter seems to be ignore by MG.\n" 2521 text += "MG will use instead the expression: %s\n" % \ 2522 self.restricted_value[(args[start], key)] 2523 text += "You need to match this expression for external program (such pythia)." 2524 logger.warning(text) 2525 2526 if args[-1].lower() in ['default', 'auto']: 2527 self.setP(args[start], key, args[-1]) 2528 else: 2529 try: 2530 value = float(args[-1]) 2531 except Exception: 2532 logger.warning('Invalid input: Expected number and not \'%s\'' \ 2533 % args[-1]) 2534 return 2535 self.setP(args[start], key, value) 2536 else: 2537 logger.warning('invalid set command %s' % line) 2538 return 2539 self.param_card.write(pjoin(self.me_dir,'Cards','param_card.dat')) 2540 2541 # PARAM_CARD NO BLOCK NAME --------------------------------------------- 2542 elif args[start] in self.pname2block and card != 'run_card': 2543 if args[start] in self.conflict and card == '': 2544 text = 'ambiguous name (present in both param_card and run_card. Please specify' 2545 logger.warning(text) 2546 return 2547 2548 all_var = self.pname2block[args[start]] 2549 for bname, lhaid in all_var: 2550 new_line = 'param_card %s %s %s' % (bname, 2551 ' '.join([ str(i) for i in lhaid]), ' '.join(args[start+1:])) 2552 self.do_set(new_line) 2553 if len(all_var) > 1: 2554 logger.warning('This variable correspond to more than one parameter in the param_card.') 2555 for bname, lhaid in all_var: 2556 logger.warning(' %s %s' % (bname, ' '.join([str(i) for i in lhaid]))) 2557 logger.warning('all listed variables have been modified') 2558 2559 # MadWeight_card with block name --------------------------------------- 2560 elif self.has_mw and (args[start] in self.mw_card and args[start] != 'comment') \ 2561 and card in ['','MadWeight_card']: 2562 2563 if args[start] in self.conflict and card == '': 2564 text = 'ambiguous name (present in more than one card). Please specify which card to edit' 2565 logger.warning(text) 2566 return 2567 2568 block = args[start] 2569 name = args[start+1] 2570 value = args[start+2:] 2571 self.setM(block, name, value) 2572 self.mw_card.write(pjoin(self.me_dir,'Cards','MadWeight_card.dat')) 2573 2574 # MadWeight_card NO Block name ----------------------------------------- 2575 elif self.has_mw and args[start] in self.mw_vars \ 2576 and card in ['', 'MadWeight_card']: 2577 2578 if args[start] in self.conflict and card == '': 2579 text = 'ambiguous name (present in more than one card). Please specify which card to edit' 2580 logger.warning(text) 2581 return 2582 2583 block = [b for b, data in self.mw_card.items() if args[start] in data] 2584 if len(block) > 1: 2585 logger.warning('%s is define in more than one block: %s.Please specify.' 2586 % (args[start], ','.join(block))) 2587 return 2588 2589 block = block[0] 2590 name = args[start] 2591 value = args[start+1:] 2592 self.setM(block, name, value) 2593 self.mw_card.write(pjoin(self.me_dir,'Cards','MadWeight_card.dat')) 2594 2595 # MadWeight_card New Block 2596 elif self.has_mw and args[start].startswith('mw_') and len(args[start:]) == 3\ 2597 and card == 'MadWeight_card': 2598 block = args[start] 2599 name = args[start+1] 2600 value = args[start+2] 2601 self.setM(block, name, value) 2602 self.mw_card.write(pjoin(self.me_dir,'Cards','MadWeight_card.dat')) 2603 #INVALID -------------------------------------------------------------- 2604 else: 2605 logger.warning('invalid set command %s ' % line) 2606 return
2607
2608 - def setM(self, block, name, value):
2609 2610 if isinstance(value, list) and len(value) == 1: 2611 value = value[0] 2612 2613 if block not in self.mw_card: 2614 logger.warning('block %s was not present in the current MadWeight card. We are adding it' % block) 2615 self.mw_card[block] = {} 2616 elif name not in self.mw_card[block]: 2617 logger.info('name %s was not present in the block %s for the current MadWeight card. We are adding it' % (name,block),'$MG:color:BLACK') 2618 if value == 'default': 2619 import madgraph.madweight.Cards as mwcards 2620 mw_default = mwcards.Card(pjoin(self.me_dir,'Cards','MadWeight_card_default.dat')) 2621 try: 2622 value = mw_default[block][name] 2623 except KeyError: 2624 logger.info('removing id "%s" from Block "%s" '% (name, block)) 2625 if name in self.mw_card[block]: 2626 del self.mw_card[block][name] 2627 return 2628 if value: 2629 logger.info('modify madweight_card information BLOCK "%s" with id "%s" set to %s' %\ 2630 (block, name, value)) 2631 else: 2632 logger.value("Invalid command: No value. To set default value. Use \"default\" as value") 2633 return 2634 2635 self.mw_card[block][name] = value
2636
2637 - def setR(self, name, value):
2638 logger.info('modify parameter %s of the run_card.dat to %s' % (name, value)) 2639 self.run_card[name] = value
2640
2641 - def setP(self, block, lhaid, value):
2642 if isinstance(value, str): 2643 value = value.lower() 2644 if value == 'default': 2645 default = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card_default.dat')) 2646 value = default[block].param_dict[lhaid].value 2647 2648 elif value == 'auto': 2649 value = 'Auto' 2650 if block != 'decay': 2651 logger.warning('Invalid input: \'Auto\' value only valid for DECAY') 2652 return 2653 else: 2654 try: 2655 value = float(value) 2656 except ValueError: 2657 logger.warning('Invalid input: \'%s\' not valid intput.'% value) 2658 2659 logger.info('modify param_card information BLOCK %s with id %s set to %s' %\ 2660 (block, lhaid, value)) 2661 self.param_card[block].param_dict[lhaid].value = value
2662
2663 - def reask(self, *args, **opt):
2664 2665 cmd.OneLinePathCompletion.reask(self,*args, **opt) 2666 if self.has_mw and not os.path.exists(pjoin(self.me_dir,'Cards','transfer_card.dat')): 2667 logger.warning('No transfer function currently define. Please use the change_tf command to define one.')
2668 2669
2670 - def help_set(self):
2671 '''help message for set''' 2672 2673 logger.info('********************* HELP SET ***************************') 2674 logger.info("syntax: set [run_card|param_card] NAME [VALUE|default]") 2675 logger.info("syntax: set [param_card] BLOCK ID(s) [VALUE|default]") 2676 logger.info('') 2677 logger.info('-- Edit the param_card/run_card and replace the value of the') 2678 logger.info(' parameter by the value VALUE.') 2679 logger.info(' ') 2680 logger.info('-- Example:') 2681 logger.info(' set run_card ebeam1 4000') 2682 logger.info(' set ebeam2 4000') 2683 logger.info(' set lpp1 0') 2684 logger.info(' set ptj default') 2685 logger.info('') 2686 logger.info(' set param_card mass 6 175') 2687 logger.info(' set mass 25 125.3') 2688 logger.info(' set mass mh 125') 2689 logger.info(' set mh 125') 2690 logger.info(' set decay 25 0.004') 2691 logger.info(' set decay wh 0.004') 2692 logger.info(' set vmix 2 1 2.326612e-01') 2693 logger.info('') 2694 logger.info(' set param_card default #return all parameter to default') 2695 logger.info(' set run_card default') 2696 logger.info('********************* HELP SET ***************************')
2697 2698
2699 - def default(self, line):
2700 """Default action if line is not recognized""" 2701 2702 line = line.strip() 2703 args = line.split() 2704 if line == '' and self.default_value is not None: 2705 self.value = self.default_value 2706 # check if input is a file 2707 elif hasattr(self, 'do_%s' % args[0]): 2708 self.do_set(' '.join(args[1:])) 2709 elif os.path.exists(line): 2710 self.copy_file(line) 2711 self.value = 'repeat' 2712 elif line.strip() != '0' and line.strip() != 'done' and \ 2713 str(line) != 'EOF' and line.strip() in self.allow_arg: 2714 self.open_file(line) 2715 self.value = 'repeat' 2716 else: 2717 self.value = line 2718 2719 return line
2720
2721 - def do_compute_widths(self, line):
2722 signal.alarm(0) # avoid timer if any 2723 path = pjoin(self.me_dir,'Cards','param_card.dat') 2724 pattern = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto''',re.I) 2725 text = open(path).read() 2726 pdg = pattern.findall(text) 2727 line = '%s %s' % (line, ' '.join(pdg)) 2728 if not '--path' in line: 2729 line += ' --path=%s' % path 2730 try: 2731 return self.mother_interface.do_compute_widths(line) 2732 except InvalidCmd, error: 2733 logger.error("Invalid command: %s " % error)
2734
2735 - def help_compute_widths(self):
2736 signal.alarm(0) # avoid timer if any 2737 return self.mother_interface.help_compute_widths()
2738
2739 - def complete_compute_widths(self, *args, **opts):
2740 signal.alarm(0) # avoid timer if any 2741 return self.mother_interface.complete_compute_widths(*args,**opts)
2742 2743
2744 - def help_asperge(self):
2745 """Help associated to the asperge command""" 2746 signal.alarm(0) 2747 2748 print '-- syntax: asperge [options]' 2749 print ' Call ASperGe to diagonalize all mass matrices in the model.' 2750 print ' This works only if the ASperGE module is part of the UFO model (a subdirectory).' 2751 print ' If you specify some names after the command (i.e. asperge m1 m2) then ASperGe will only' 2752 print ' diagonalize the associate mass matrices (here m1 and m2).'
2753
2754 - def complete_asperge(self, text, line, begidx, endidx):
2755 signal.alarm(0) # avoid timer if any 2756 2757 blockname = self.pname2block.keys() 2758 # remove those that we know for sure are not mixing 2759 wrong = ['decay', 'mass', 'sminput'] 2760 valid = [k for k in blockname if 'mix' in k] 2761 potential = [k for k in blockname if k not in valid+wrong] 2762 output = {'Mixing matrices': self.list_completion(text, valid, line), 2763 'Other potential valid input': self.list_completion(text, potential, line)} 2764 2765 return self.deal_multiple_categories(output)
2766 2767
2768 - def do_asperge(self, line):
2769 """Running ASperGe""" 2770 signal.alarm(0) # avoid timer if any 2771 2772 path = pjoin(self.me_dir,'bin','internal','ufomodel','ASperGE') 2773 if not os.path.exists(path): 2774 logger.error('ASperge has not been detected in the current model, therefore it will not be run.') 2775 return 2776 elif not os.path.exists(pjoin(path,'ASperGe')): 2777 logger.info('ASperGe has been detected but is not compiled. Running the compilation now.') 2778 try: 2779 misc.compile(cwd=path,shell=True) 2780 except MadGraph5Error, error: 2781 logger.error('''ASperGe failed to compile. Note that gsl is needed 2782 for this compilation to go trough. More information on how to install this package on 2783 http://www.gnu.org/software/gsl/ 2784 Full compilation log is available at %s''' % pjoin(self.me_dir, 'ASperge_compilation.log')) 2785 open(pjoin(self.me_dir, 'ASperge_compilation.log'),'w').write(str(error)) 2786 return 2787 2788 opts = line.split() 2789 card = pjoin(self.me_dir,'Cards', 'param_card.dat') 2790 logger.info('running ASperGE') 2791 returncode = misc.call([pjoin(path,'ASperGe'), card, '%s.new' % card] + opts) 2792 if returncode: 2793 logger.error('ASperGE fails with status %s' % returncode) 2794 else: 2795 logger.info('AsPerGe creates the file succesfully') 2796 files.mv(card, '%s.beforeasperge' % card) 2797 files.mv('%s.new' % card, card)
2798 2799 2800
2801 - def copy_file(self, path):
2802 """detect the type of the file and overwritte the current file""" 2803 2804 if path.endswith('.lhco'): 2805 #logger.info('copy %s as Events/input.lhco' % (path)) 2806 #files.cp(path, pjoin(self.mother_interface.me_dir, 'Events', 'input.lhco' )) 2807 self.do_set('mw_run inputfile %s' % os.path.relpath(path, self.mother_interface.me_dir)) 2808 return 2809 elif path.endswith('.lhco.gz'): 2810 #logger.info('copy %s as Events/input.lhco.gz' % (path)) 2811 #files.cp(path, pjoin(self.mother_interface.me_dir, 'Events', 'input.lhco.gz' )) 2812 self.do_set('mw_run inputfile %s' % os.path.relpath(path, self.mother_interface.me_dir)) 2813 return 2814 else: 2815 card_name = CommonRunCmd.detect_card_type(path) 2816 2817 if card_name == 'unknown': 2818 logger.warning('Fail to determine the type of the file. Not copied') 2819 if card_name != 'banner': 2820 logger.info('copy %s as %s' % (path, card_name)) 2821 files.cp(path, pjoin(self.mother_interface.me_dir, 'Cards', card_name)) 2822 elif card_name == 'banner': 2823 banner_mod.split_banner(path, self.mother_interface.me_dir, proc_card=False) 2824 logger.info('Splitting the banner in it\'s component') 2825 if not self.mode == 'auto': 2826 self.mother_interface.keep_cards(self.cards)
2827
2828 - def open_file(self, answer):
2829 """open the file""" 2830 me_dir = self.mother_interface.me_dir 2831 if answer.isdigit(): 2832 if answer == '9': 2833 answer = 'plot' 2834 else: 2835 answer = self.cards[int(answer)-1] 2836 if 'madweight' in answer: 2837 answer = answer.replace('madweight', 'MadWeight') 2838 2839 if not '.dat' in answer and not '.lhco' in answer: 2840 if answer != 'trigger': 2841 path = pjoin(me_dir,'Cards','%s_card.dat' % answer) 2842 else: 2843 path = pjoin(me_dir,'Cards','delphes_trigger.dat') 2844 elif not '.lhco' in answer: 2845 path = pjoin(me_dir, 'Cards', answer) 2846 else: 2847 path = pjoin(me_dir, self.mw_card['mw_run']['inputfile']) 2848 if not os.path.exists(path): 2849 logger.info('Path in MW_card not existing') 2850 path = pjoin(me_dir, 'Events', answer) 2851 #security 2852 path = path.replace('_card_card','_card') 2853 try: 2854 self.mother_interface.exec_cmd('open %s' % path) 2855 except InvalidCmd, error: 2856 if str(error) != 'No default path for this file': 2857 raise 2858 if answer == 'transfer_card.dat': 2859 logger.warning('You have to specify a transfer function first!') 2860 elif answer == 'input.lhco': 2861 path = pjoin(me_dir,'Events', 'input.lhco') 2862 ff = open(path,'w') 2863 ff.write('''No LHCO information imported at current time. 2864 To import a lhco file: Close this file and type the path of your file. 2865 You can also copy/paste, your event file here.''') 2866 ff.close() 2867 self.open_file(path) 2868 else: 2869 raise 2870 2871 # reload object to have it in sync 2872 if path == pjoin(self.me_dir,'Cards','param_card.dat'): 2873 try: 2874 self.param_card = check_param_card.ParamCard(path) 2875 except (check_param_card.InvalidParamCard, ValueError) as e: 2876 logger.error('Current param_card is not valid. We are going to use the default one.') 2877 logger.error('problem detected: %s' % e) 2878 logger.error('Please re-open the file and fix the problem.') 2879 logger.warning('using the \'set\' command without opening the file will discard all your manual change') 2880 elif path == pjoin(self.me_dir,'Cards','run_card.dat'): 2881 self.run_card = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card.dat')) 2882 elif path == pjoin(self.me_dir,'Cards','MadWeight_card.dat'): 2883 try: 2884 import madgraph.madweight.Cards as mwcards 2885 except: 2886 import internal.madweight.Cards as mwcards 2887 self.mw_card = mwcards.Card(pjoin(self.me_dir,'Cards','MadWeight_card.dat'))
2888