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