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