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 @staticmethod
760 - def detect_card_type(path):
761 """detect the type of the card. Return value are 762 banner 763 param_card.dat 764 run_card.dat 765 pythia_card.dat 766 plot_card.dat 767 pgs_card.dat 768 delphes_card.dat 769 delphes_trigger.dat 770 shower_card.dat [aMCatNLO] 771 FO_analyse_card.dat [aMCatNLO] 772 madspin_card.dat [MS] 773 transfer_card.dat [MW] 774 madweight_card.dat [MW] 775 """ 776 777 text = open(path).read(50000) 778 if text == '': 779 logger.warning('File %s is empty' % path) 780 return 'unknown' 781 text = re.findall('(<MGVersion>|ParticlePropagator|<mg5proccard>|CEN_max_tracker|#TRIGGER CARD|parameter set name|muon eta coverage|QES_over_ref|MSTP|b_stable|FO_ANALYSIS_FORMAT|MSTU|Begin Minpts|gridpack|ebeam1|block\s+mw_run|BLOCK|DECAY|launch|madspin|transfer_card\.dat|set)', text, re.I) 782 text = [t.lower() for t in text] 783 if '<mgversion>' in text or '<mg5proccard>' in text: 784 return 'banner' 785 elif 'particlepropagator' in text: 786 return 'delphes_card.dat' 787 elif 'cen_max_tracker' in text: 788 return 'delphes_card.dat' 789 elif '#trigger card' in text: 790 return 'delphes_trigger.dat' 791 elif 'parameter set name' in text: 792 return 'pgs_card.dat' 793 elif 'muon eta coverage' in text: 794 return 'pgs_card.dat' 795 elif 'mstp' in text and not 'b_stable' in text: 796 return 'pythia_card.dat' 797 elif 'begin minpts' in text: 798 return 'plot_card.dat' 799 elif ('gridpack' in text and 'ebeam1' in text) or \ 800 ('qes_over_ref' in text and 'ebeam1' in text): 801 return 'run_card.dat' 802 elif any(t.endswith('mw_run') for t in text): 803 return 'madweight_card.dat' 804 elif 'transfer_card.dat' in text: 805 return 'transfer_card.dat' 806 elif 'block' in text and 'decay' in text: 807 return 'param_card.dat' 808 elif 'b_stable' in text: 809 return 'shower_card.dat' 810 elif 'fo_analysis_format' in text: 811 return 'FO_analyse_card.dat' 812 elif 'decay' in text and 'launch' in text and 'madspin' in text: 813 return 'madspin_card.dat' 814 elif 'launch' in text and 'set' in text: 815 return 'reweight_card.dat' 816 elif 'decay' in text and 'launch' in text: 817 return 'madspin_card.dat' 818 else: 819 return 'unknown'
820 821 822 ############################################################################
823 - def get_available_tag(self):
824 """create automatically a tag""" 825 826 used_tags = [r['tag'] for r in self.results[self.run_name]] 827 i=0 828 while 1: 829 i+=1 830 if 'tag_%s' %i not in used_tags: 831 return 'tag_%s' % i
832 833 834 ############################################################################
835 - def create_plot(self, mode='parton', event_path=None, output=None, tag=None):
836 """create the plot""" 837 838 madir = self.options['madanalysis_path'] 839 if not tag: 840 tag = self.run_card['run_tag'] 841 td = self.options['td_path'] 842 843 if not madir or not td or \ 844 not os.path.exists(pjoin(self.me_dir, 'Cards', 'plot_card.dat')): 845 return False 846 847 if 'ickkw' in self.run_card and int(self.run_card['ickkw']) and \ 848 mode == 'Pythia': 849 self.update_status('Create matching plots for Pythia', level='pythia') 850 # recover old data if none newly created 851 if not os.path.exists(pjoin(self.me_dir,'Events','events.tree')): 852 misc.gunzip(pjoin(self.me_dir,'Events', 853 self.run_name, '%s_pythia_events.tree.gz' % tag), keep=True, 854 stdout=pjoin(self.me_dir,'Events','events.tree')) 855 files.mv(pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_xsecs.tree'), 856 pjoin(self.me_dir,'Events','xsecs.tree')) 857 858 # Generate the matching plots 859 misc.call([self.dirbin+'/create_matching_plots.sh', 860 self.run_name, tag, madir], 861 stdout = os.open(os.devnull, os.O_RDWR), 862 cwd=pjoin(self.me_dir,'Events')) 863 864 #Clean output 865 misc.gzip(pjoin(self.me_dir,"Events","events.tree"), 866 stdout=pjoin(self.me_dir,'Events',self.run_name, tag + '_pythia_events.tree.gz')) 867 files.mv(pjoin(self.me_dir,'Events','xsecs.tree'), 868 pjoin(self.me_dir,'Events',self.run_name, tag+'_pythia_xsecs.tree')) 869 870 871 if not event_path: 872 if mode == 'parton': 873 possibilities=[ 874 pjoin(self.me_dir, 'Events', 'unweighted_events.lhe'), 875 pjoin(self.me_dir, 'Events', 'unweighted_events.lhe.gz'), 876 pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe'), 877 pjoin(self.me_dir, 'Events', self.run_name, 'unweighted_events.lhe.gz')] 878 for event_path in possibilities: 879 if os.path.exists(event_path): 880 break 881 output = pjoin(self.me_dir, 'HTML',self.run_name, 'plots_parton.html') 882 883 elif mode == 'Pythia': 884 event_path = pjoin(self.me_dir, 'Events','pythia_events.lhe') 885 output = pjoin(self.me_dir, 'HTML',self.run_name, 886 'plots_pythia_%s.html' % tag) 887 elif mode == 'PGS': 888 event_path = pjoin(self.me_dir, 'Events', self.run_name, 889 '%s_pgs_events.lhco' % tag) 890 output = pjoin(self.me_dir, 'HTML',self.run_name, 891 'plots_pgs_%s.html' % tag) 892 elif mode == 'Delphes': 893 event_path = pjoin(self.me_dir, 'Events', self.run_name,'%s_delphes_events.lhco' % tag) 894 output = pjoin(self.me_dir, 'HTML',self.run_name, 895 'plots_delphes_%s.html' % tag) 896 elif mode == "shower": 897 event_path = pjoin(self.me_dir, 'Events','pythia_events.lhe') 898 output = pjoin(self.me_dir, 'HTML',self.run_name, 899 'plots_shower_%s.html' % tag) 900 if not self.options['pythia-pgs_path']: 901 return 902 else: 903 raise self.InvalidCmd, 'Invalid mode %s' % mode 904 elif mode == 'reweight' and not output: 905 output = pjoin(self.me_dir, 'HTML',self.run_name, 906 'plots_%s.html' % tag) 907 908 if not os.path.exists(event_path): 909 if os.path.exists(event_path+'.gz'): 910 misc.gunzip('%s.gz' % event_path) 911 else: 912 raise self.InvalidCmd, 'Events file %s does not exist' % event_path 913 elif event_path.endswith(".gz"): 914 misc.gunzip(event_path) 915 event_path = event_path[:-3] 916 917 918 self.update_status('Creating Plots for %s level' % mode, level = mode.lower()) 919 920 mode = mode.lower() 921 if mode not in ['parton', 'reweight']: 922 plot_dir = pjoin(self.me_dir, 'HTML', self.run_name,'plots_%s_%s' % (mode.lower(),tag)) 923 elif mode == 'parton': 924 plot_dir = pjoin(self.me_dir, 'HTML', self.run_name,'plots_parton') 925 else: 926 plot_dir =pjoin(self.me_dir, 'HTML', self.run_name,'plots_%s' % (tag)) 927 928 if not os.path.isdir(plot_dir): 929 os.makedirs(plot_dir) 930 931 files.ln(pjoin(self.me_dir, 'Cards','plot_card.dat'), plot_dir, 'ma_card.dat') 932 933 try: 934 proc = misc.Popen([os.path.join(madir, 'plot_events')], 935 stdout = open(pjoin(plot_dir, 'plot.log'),'w'), 936 stderr = subprocess.STDOUT, 937 stdin=subprocess.PIPE, 938 cwd=plot_dir) 939 proc.communicate('%s\n' % event_path) 940 del proc 941 #proc.wait() 942 misc.call(['%s/plot' % self.dirbin, madir, td], 943 stdout = open(pjoin(plot_dir, 'plot.log'),'a'), 944 stderr = subprocess.STDOUT, 945 cwd=plot_dir) 946 947 misc.call(['%s/plot_page-pl' % self.dirbin, 948 os.path.basename(plot_dir), 949 mode], 950 stdout = open(pjoin(plot_dir, 'plot.log'),'a'), 951 stderr = subprocess.STDOUT, 952 cwd=pjoin(self.me_dir, 'HTML', self.run_name)) 953 954 shutil.move(pjoin(self.me_dir, 'HTML',self.run_name ,'plots.html'), 955 output) 956 957 logger.info("Plots for %s level generated, see %s" % \ 958 (mode, output)) 959 except OSError, error: 960 logger.error('fail to create plot: %s. Please check that MadAnalysis is correctly installed.' % error) 961 962 self.update_status('End Plots for %s level' % mode, level = mode.lower(), 963 makehtml=False) 964 965 return True
966
967 - def run_hep2lhe(self, banner_path = None):
968 """Run hep2lhe on the file Events/pythia_events.hep""" 969 970 if not self.options['pythia-pgs_path']: 971 raise self.InvalidCmd, 'No pythia-pgs path defined' 972 973 pydir = pjoin(self.options['pythia-pgs_path'], 'src') 974 eradir = self.options['exrootanalysis_path'] 975 976 # Creating LHE file 977 if misc.is_executable(pjoin(pydir, 'hep2lhe')): 978 self.update_status('Creating shower LHE File (for plot)', level='pythia') 979 # Write the banner to the LHE file 980 out = open(pjoin(self.me_dir,'Events','pythia_events.lhe'), 'w') 981 #out.writelines('<LesHouchesEvents version=\"1.0\">\n') 982 out.writelines('<!--\n') 983 out.writelines('# Warning! Never use this file for detector studies!\n') 984 out.writelines('-->\n<!--\n') 985 if banner_path: 986 out.writelines(open(banner_path).read().replace('<LesHouchesEvents version="1.0">','')) 987 out.writelines('\n-->\n') 988 out.close() 989 990 self.cluster.launch_and_wait(self.dirbin+'/run_hep2lhe', 991 argument= [pydir], 992 cwd=pjoin(self.me_dir,'Events'), 993 stdout=os.devnull) 994 995 logger.info('Warning! Never use this lhe file for detector studies!') 996 # Creating ROOT file 997 if eradir and misc.is_executable(pjoin(eradir, 'ExRootLHEFConverter')): 998 self.update_status('Creating Pythia LHE Root File', level='pythia') 999 try: 1000 misc.call([eradir+'/ExRootLHEFConverter', 1001 'pythia_events.lhe', 1002 pjoin(self.run_name, '%s_pythia_lhe_events.root' % self.run_tag)], 1003 cwd=pjoin(self.me_dir,'Events')) 1004 except Exception, error: 1005 misc.sprint('ExRootLHEFConverter fails', str(error), 1006 log=logger) 1007 pass
1008
1009 - def store_result(self):
1010 """Dummy routine, to be overwritten by daughter classes""" 1011 1012 pass
1013 1014 ############################################################################
1015 - def do_pgs(self, line):
1016 """launch pgs""" 1017 1018 args = self.split_arg(line) 1019 # Check argument's validity 1020 if '--no_default' in args: 1021 no_default = True 1022 args.remove('--no_default') 1023 else: 1024 no_default = False 1025 1026 # Check all arguments 1027 # This might launch a gunzip in another thread. After the question 1028 # This thread need to be wait for completion. (This allow to have the 1029 # question right away and have the computer working in the same time) 1030 # if lock is define this a locker for the completion of the thread 1031 lock = self.check_pgs(args) 1032 1033 # Check that the pgs_card exists. If not copy the default 1034 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'pgs_card.dat')): 1035 if no_default: 1036 logger.info('No pgs_card detected, so not run pgs') 1037 return 1038 1039 files.cp(pjoin(self.me_dir, 'Cards', 'pgs_card_default.dat'), 1040 pjoin(self.me_dir, 'Cards', 'pgs_card.dat')) 1041 logger.info('No pgs card found. Take the default one.') 1042 1043 if not (no_default or self.force): 1044 self.ask_edit_cards(['pgs_card.dat']) 1045 1046 self.update_status('prepare PGS run', level=None) 1047 1048 pgsdir = pjoin(self.options['pythia-pgs_path'], 'src') 1049 eradir = self.options['exrootanalysis_path'] 1050 madir = self.options['madanalysis_path'] 1051 td = self.options['td_path'] 1052 1053 # Compile pgs if not there 1054 if not misc.is_executable(pjoin(pgsdir, 'pgs')): 1055 logger.info('No PGS executable -- running make') 1056 misc.compile(cwd=pgsdir) 1057 1058 self.update_status('Running PGS', level='pgs') 1059 1060 tag = self.run_tag 1061 # Update the banner with the pgs card 1062 banner_path = pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, self.run_tag)) 1063 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')): 1064 self.banner.add(pjoin(self.me_dir, 'Cards','pgs_card.dat')) 1065 self.banner.write(banner_path) 1066 else: 1067 open(banner_path, 'w').close() 1068 1069 ######################################################################## 1070 # now pass the event to a detector simulator and reconstruct objects 1071 ######################################################################## 1072 if lock: 1073 lock.wait() 1074 # Prepare the output file with the banner 1075 ff = open(pjoin(self.me_dir, 'Events', 'pgs_events.lhco'), 'w') 1076 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')): 1077 text = open(banner_path).read() 1078 text = '#%s' % text.replace('\n','\n#') 1079 dico = self.results[self.run_name].get_current_info() 1080 text +='\n## Integrated weight (pb) : %.4g' % dico['cross'] 1081 text +='\n## Number of Event : %s\n' % dico['nb_event'] 1082 ff.writelines(text) 1083 ff.close() 1084 1085 try: 1086 os.remove(pjoin(self.me_dir, 'Events', 'pgs.done')) 1087 except Exception: 1088 pass 1089 1090 pgs_log = pjoin(self.me_dir, 'Events', self.run_name, "%s_pgs.log" % tag) 1091 self.cluster.launch_and_wait('../bin/internal/run_pgs', 1092 argument=[pgsdir], cwd=pjoin(self.me_dir,'Events'), 1093 stdout=pgs_log, stderr=subprocess.STDOUT) 1094 1095 if not os.path.exists(pjoin(self.me_dir, 'Events', 'pgs.done')): 1096 logger.error('Fail to create LHCO events') 1097 return 1098 else: 1099 os.remove(pjoin(self.me_dir, 'Events', 'pgs.done')) 1100 1101 if os.path.getsize(banner_path) == os.path.getsize(pjoin(self.me_dir, 'Events','pgs_events.lhco')): 1102 misc.call(['cat pgs_uncleaned_events.lhco >> pgs_events.lhco'], 1103 cwd=pjoin(self.me_dir, 'Events')) 1104 os.remove(pjoin(self.me_dir, 'Events', 'pgs_uncleaned_events.lhco ')) 1105 1106 # Creating Root file 1107 if eradir and misc.is_executable(pjoin(eradir, 'ExRootLHCOlympicsConverter')): 1108 self.update_status('Creating PGS Root File', level='pgs') 1109 try: 1110 misc.call([eradir+'/ExRootLHCOlympicsConverter', 1111 'pgs_events.lhco',pjoin('%s/%s_pgs_events.root' % (self.run_name, tag))], 1112 cwd=pjoin(self.me_dir, 'Events')) 1113 except Exception: 1114 logger.warning('fail to produce Root output [problem with ExRootAnalysis') 1115 if os.path.exists(pjoin(self.me_dir, 'Events', 'pgs_events.lhco')): 1116 # Creating plots 1117 files.mv(pjoin(self.me_dir, 'Events', 'pgs_events.lhco'), 1118 pjoin(self.me_dir, 'Events', self.run_name, '%s_pgs_events.lhco' % tag)) 1119 self.create_plot('PGS') 1120 misc.gzip(pjoin(self.me_dir, 'Events', self.run_name, '%s_pgs_events.lhco' % tag)) 1121 1122 self.update_status('finish', level='pgs', makehtml=False)
1123 1124 ############################################################################
1125 - def do_compute_widths(self, line):
1126 """Require MG5 directory: Compute automatically the widths of a set 1127 of particles""" 1128 1129 1130 1131 args = self.split_arg(line) 1132 opts = self.check_compute_widths(args) 1133 1134 from madgraph.interface.master_interface import MasterCmd 1135 cmd = MasterCmd() 1136 self.define_child_cmd_interface(cmd, interface=False) 1137 cmd.exec_cmd('set automatic_html_opening False --no_save') 1138 if not opts['path']: 1139 opts['path'] = pjoin(self.me_dir, 'Cards', 'param_card.dat') 1140 if not opts['force'] : 1141 self.ask_edit_cards(['param_card'],[], plot=False) 1142 1143 1144 line = 'compute_widths %s %s' % \ 1145 (' '.join([str(i) for i in opts['particles']]), 1146 ' '.join('--%s=%s' % (key,value) for (key,value) in opts.items() 1147 if key not in ['model', 'force', 'particles'] and value)) 1148 cmd.exec_cmd(line, model=opts['model']) 1149 self.child = None 1150 del cmd
1151 1152 ############################################################################
1153 - def do_print_results(self, line):
1154 """Not in help:Print the cross-section/ number of events for a given run""" 1155 1156 args = self.split_arg(line) 1157 options={'path':None, 'mode':'w', 'format':'full'} 1158 for arg in list(args): 1159 if arg.startswith('--') and '=' in arg: 1160 name,value=arg.split('=',1) 1161 name = name [2:] 1162 options[name] = value 1163 args.remove(arg) 1164 1165 1166 if len(args) > 0: 1167 run_name = args[0] 1168 else: 1169 for i, run_name in enumerate(self.results.order): 1170 for j, one_result in enumerate(self.results[run_name]): 1171 if i or j: 1172 options['mode'] = "a" 1173 if options['path']: 1174 self.print_results_in_file(one_result, options['path'], options['mode'], options['format']) 1175 else: 1176 self.print_results_in_shell(one_result) 1177 return 1178 1179 if run_name not in self.results: 1180 raise self.InvalidCmd('%s is not a valid run_name or it doesn\'t have any information' \ 1181 % run_name) 1182 1183 1184 if len(args) == 2: 1185 tag = args[1] 1186 if tag.isdigit(): 1187 tag = int(tag) - 1 1188 if len(self.results[run_name]) < tag: 1189 raise self.InvalidCmd('Only %s different tag available' % \ 1190 len(self.results[run_name])) 1191 data = self.results[run_name][tag] 1192 else: 1193 data = self.results[run_name].return_tag(tag) 1194 else: 1195 data = self.results[run_name].return_tag(None) # return the last 1196 1197 if options['path']: 1198 self.print_results_in_file(data, options['path'], options['mode'], options['format']) 1199 else: 1200 self.print_results_in_shell(data)
1201 1202 1203 ############################################################################
1204 - def do_delphes(self, line):
1205 """ run delphes and make associate root file/plot """ 1206 1207 args = self.split_arg(line) 1208 # Check argument's validity 1209 if '--no_default' in args: 1210 no_default = True 1211 args.remove('--no_default') 1212 else: 1213 no_default = False 1214 # Check all arguments 1215 # This might launch a gunzip in another thread. After the question 1216 # This thread need to be wait for completion. (This allow to have the 1217 # question right away and have the computer working in the same time) 1218 # if lock is define this a locker for the completion of the thread 1219 lock = self.check_delphes(args) 1220 self.update_status('prepare delphes run', level=None) 1221 1222 1223 if os.path.exists(pjoin(self.options['delphes_path'], 'data')): 1224 delphes3 = False 1225 prog = '../bin/internal/run_delphes' 1226 else: 1227 delphes3 = True 1228 prog = '../bin/internal/run_delphes3' 1229 1230 # Check that the delphes_card exists. If not copy the default and 1231 # ask for edition of the card. 1232 if not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_card.dat')): 1233 if no_default: 1234 logger.info('No delphes_card detected, so not run Delphes') 1235 return 1236 1237 files.cp(pjoin(self.me_dir, 'Cards', 'delphes_card_default.dat'), 1238 pjoin(self.me_dir, 'Cards', 'delphes_card.dat')) 1239 logger.info('No delphes card found. Take the default one.') 1240 if not delphes3 and not os.path.exists(pjoin(self.me_dir, 'Cards', 'delphes_trigger.dat')): 1241 files.cp(pjoin(self.me_dir, 'Cards', 'delphes_trigger_default.dat'), 1242 pjoin(self.me_dir, 'Cards', 'delphes_trigger.dat')) 1243 if not (no_default or self.force): 1244 if delphes3: 1245 self.ask_edit_cards(['delphes_card.dat'], args) 1246 else: 1247 self.ask_edit_cards(['delphes_card.dat', 'delphes_trigger.dat'], args) 1248 1249 self.update_status('Running Delphes', level=None) 1250 # Wait that the gunzip of the files is finished (if any) 1251 if lock: 1252 lock.wait() 1253 1254 1255 1256 delphes_dir = self.options['delphes_path'] 1257 tag = self.run_tag 1258 if os.path.exists(pjoin(self.me_dir, 'Source', 'banner_header.txt')): 1259 self.banner.add(pjoin(self.me_dir, 'Cards','delphes_card.dat')) 1260 if not delphes3: 1261 self.banner.add(pjoin(self.me_dir, 'Cards','delphes_trigger.dat')) 1262 self.banner.write(pjoin(self.me_dir, 'Events', self.run_name, '%s_%s_banner.txt' % (self.run_name, tag))) 1263 1264 cross = self.results[self.run_name].get_current_info()['cross'] 1265 1266 delphes_log = pjoin(self.me_dir, 'Events', self.run_name, "%s_delphes.log" % tag) 1267 self.cluster.launch_and_wait(prog, 1268 argument= [delphes_dir, self.run_name, tag, str(cross)], 1269 stdout=delphes_log, stderr=subprocess.STDOUT, 1270 cwd=pjoin(self.me_dir,'Events')) 1271 1272 if not os.path.exists(pjoin(self.me_dir, 'Events', 1273 self.run_name, '%s_delphes_events.lhco' % tag)): 1274 logger.error('Fail to create LHCO events from DELPHES') 1275 return 1276 1277 if os.path.exists(pjoin(self.me_dir,'Events','delphes.root')): 1278 source = pjoin(self.me_dir,'Events','delphes.root') 1279 target = pjoin(self.me_dir,'Events', self.run_name, "%s_delphes_events.root" % tag) 1280 files.mv(source, target) 1281 1282 #eradir = self.options['exrootanalysis_path'] 1283 madir = self.options['madanalysis_path'] 1284 td = self.options['td_path'] 1285 1286 # Creating plots 1287 self.create_plot('Delphes') 1288 1289 if os.path.exists(pjoin(self.me_dir, 'Events', self.run_name, '%s_delphes_events.lhco' % tag)): 1290 misc.gzip(pjoin(self.me_dir, 'Events', self.run_name, '%s_delphes_events.lhco' % tag)) 1291 1292 1293 1294 self.update_status('delphes done', level='delphes', makehtml=False)
1295 1296 ############################################################################
1297 - def get_pid_final_states(self):
1298 """Find the pid of all particles in the final states""" 1299 pids = set() 1300 subproc = [l.strip() for l in open(pjoin(self.me_dir,'SubProcesses', 1301 'subproc.mg'))] 1302 nb_init = self.ninitial 1303 pat = re.compile(r'''DATA \(IDUP\(I,\d+\),I=1,\d+\)/([\+\-\d,\s]*)/''', re.I) 1304 for Pdir in subproc: 1305 text = open(pjoin(self.me_dir, 'SubProcesses', Pdir, 'born_leshouche.inc')).read() 1306 group = pat.findall(text) 1307 for particles in group: 1308 particles = particles.split(',') 1309 pids.update(set(particles[nb_init:])) 1310 1311 return pids
1312 1313 ############################################################################
1314 - def get_pdf_input_filename(self):
1315 """return the name of the file which is used by the pdfset""" 1316 1317 if self.options["cluster_local_path"] and self.options['run_mode'] ==1: 1318 # no need to transfer the pdf. 1319 return '' 1320 1321 def check_cluster(path): 1322 if not self.options["cluster_local_path"] or \ 1323 os.path.exists(self.options["cluster_local_path"]) or\ 1324 self.options['run_mode'] !=1: 1325 return path 1326 main = self.options["cluster_local_path"] 1327 if os.path.isfile(path): 1328 filename = os.path.basename(path) 1329 possible_path = [pjoin(main, filename), 1330 pjoin(main, "lhadpf", filename), 1331 pjoin(main, "Pdfdata", filename)] 1332 if any(os.path.exists(p) for p in possible_path): 1333 return " " 1334 else: 1335 return path
1336 1337 1338 if hasattr(self, 'pdffile') and self.pdffile: 1339 return self.pdffile 1340 else: 1341 for line in open(pjoin(self.me_dir,'Source','PDF','pdf_list.txt')): 1342 data = line.split() 1343 if len(data) < 4: 1344 continue 1345 if data[1].lower() == self.run_card['pdlabel'].lower(): 1346 self.pdffile = check_cluster(pjoin(self.me_dir, 'lib', 'Pdfdata', data[2])) 1347 return self.pdffile 1348 else: 1349 # possible when using lhapdf 1350 path = pjoin(self.me_dir, 'lib', 'PDFsets') 1351 if os.path.exists(path): 1352 self.pdffile = path 1353 else: 1354 self.pdffile = " " 1355 return self.pdffile 1356
1357 - def do_quit(self, line):
1358 """Not in help: exit """ 1359 1360 1361 try: 1362 os.remove(pjoin(self.me_dir,'RunWeb')) 1363 except Exception, error: 1364 pass 1365 1366 try: 1367 self.store_result() 1368 except Exception: 1369 # If nothing runs they they are no result to update 1370 pass 1371 1372 try: 1373 self.update_status('', level=None) 1374 except Exception, error: 1375 pass 1376 try: 1377 devnull = open(os.devnull, 'w') 1378 misc.call(['./bin/internal/gen_cardhtml-pl'], cwd=self.me_dir, 1379 stdout=devnull, stderr=devnull) 1380 except Exception: 1381 pass 1382 try: 1383 devnull.close() 1384 except Exception: 1385 pass 1386 1387 return super(CommonRunCmd, self).do_quit(line)
1388 1389 1390 # Aliases 1391 do_EOF = do_quit 1392 do_exit = do_quit 1393 1394 ############################################################################
1395 - def do_open(self, line):
1396 """Open a text file/ eps file / html file""" 1397 1398 args = self.split_arg(line) 1399 # Check Argument validity and modify argument to be the real path 1400 self.check_open(args) 1401 file_path = args[0] 1402 1403 misc.open_file(file_path)
1404 1405 ############################################################################
1406 - def do_set(self, line, log=True):
1407 """Set an option, which will be default for coming generations/outputs 1408 """ 1409 # cmd calls automaticaly post_set after this command. 1410 1411 1412 args = self.split_arg(line) 1413 # Check the validity of the arguments 1414 self.check_set(args) 1415 # Check if we need to save this in the option file 1416 if args[0] in self.options_configuration and '--no_save' not in args: 1417 self.do_save('options --auto') 1418 1419 if args[0] == "stdout_level": 1420 if args[1].isdigit(): 1421 logging.root.setLevel(int(args[1])) 1422 logging.getLogger('madgraph').setLevel(int(args[1])) 1423 else: 1424 logging.root.setLevel(eval('logging.' + args[1])) 1425 logging.getLogger('madgraph').setLevel(eval('logging.' + args[1])) 1426 if log: logger.info('set output information to level: %s' % args[1]) 1427 elif args[0] == "fortran_compiler": 1428 if args[1] == 'None': 1429 args[1] = None 1430 self.options['fortran_compiler'] = args[1] 1431 current = misc.detect_current_compiler(pjoin(self.me_dir,'Source','make_opts'), 'fortran') 1432 if current != args[1] and args[1] != None: 1433 misc.mod_compilator(self.me_dir, args[1], current, 'gfortran') 1434 elif args[0] == "cpp_compiler": 1435 if args[1] == 'None': 1436 args[1] = None 1437 self.options['cpp_compiler'] = args[1] 1438 current = misc.detect_current_compiler(pjoin(self.me_dir,'Source','make_opts'), 'cpp') 1439 if current != args[1] and args[1] != None: 1440 misc.mod_compilator(self.me_dir, args[1], current, 'cpp') 1441 elif args[0] == "run_mode": 1442 if not args[1] in [0,1,2,'0','1','2']: 1443 raise self.InvalidCmd, 'run_mode should be 0, 1 or 2.' 1444 self.cluster_mode = int(args[1]) 1445 self.options['run_mode'] = self.cluster_mode 1446 elif args[0] in ['cluster_type', 'cluster_queue', 'cluster_temp_path']: 1447 if args[1] == 'None': 1448 args[1] = None 1449 self.options[args[0]] = args[1] 1450 # cluster (re)-initialization done later 1451 # self.cluster update at the end of the routine 1452 elif args[0] in ['cluster_nb_retry', 'cluster_retry_wait', 'cluster_size']: 1453 self.options[args[0]] = int(args[1]) 1454 # self.cluster update at the end of the routine 1455 elif args[0] == 'nb_core': 1456 if args[1] == 'None': 1457 import multiprocessing 1458 self.nb_core = multiprocessing.cpu_count() 1459 self.options['nb_core'] = self.nb_core 1460 return 1461 if not args[1].isdigit(): 1462 raise self.InvalidCmd('nb_core should be a positive number') 1463 self.nb_core = int(args[1]) 1464 self.options['nb_core'] = self.nb_core 1465 elif args[0] == 'timeout': 1466 self.options[args[0]] = int(args[1]) 1467 elif args[0] == 'cluster_status_update': 1468 if '(' in args[1]: 1469 data = ' '.join([a for a in args[1:] if not a.startswith('-')]) 1470 data = data.replace('(','').replace(')','').replace(',',' ').split() 1471 first, second = data[:2] 1472 else: 1473 first, second = args[1:3] 1474 1475 self.options[args[0]] = (int(first), int(second)) 1476 elif args[0] in self.options: 1477 if args[1] in ['None','True','False']: 1478 self.options[args[0]] = eval(args[1]) 1479 elif args[0].endswith('path'): 1480 if os.path.exists(args[1]): 1481 self.options[args[0]] = args[1] 1482 elif os.path.exists(pjoin(self.me_dir, args[1])): 1483 self.options[args[0]] = pjoin(self.me_dir, args[1]) 1484 else: 1485 raise self.InvalidCmd('Not a valid path: keep previous value: \'%s\'' % self.options[args[0]]) 1486 else: 1487 self.options[args[0]] = args[1]
1488
1489 - def post_set(self, stop, line):
1490 """Check if we need to save this in the option file""" 1491 try: 1492 args = self.split_arg(line) 1493 if 'cluster' in args[0] or args[0] == 'run_mode': 1494 self.configure_run_mode(self.options['run_mode']) 1495 1496 1497 # Check the validity of the arguments 1498 self.check_set(args) 1499 1500 if args[0] in self.options_configuration and '--no_save' not in args: 1501 self.exec_cmd('save options --auto') 1502 elif args[0] in self.options_madevent: 1503 logger.info('This option will be the default in any output that you are going to create in this session.') 1504 logger.info('In order to keep this changes permanent please run \'save options\'') 1505 return stop 1506 except self.InvalidCmd: 1507 return stop
1508
1509 - def configure_run_mode(self, run_mode):
1510 """change the way to submit job 0: single core, 1: cluster, 2: multicore""" 1511 1512 self.cluster_mode = run_mode 1513 self.options['run_mode'] = run_mode 1514 1515 if run_mode == 2: 1516 if not self.options['nb_core']: 1517 import multiprocessing 1518 self.options['nb_core'] = multiprocessing.cpu_count() 1519 nb_core = self.options['nb_core'] 1520 elif run_mode == 0: 1521 nb_core = 1 1522 1523 1524 1525 if run_mode in [0, 2]: 1526 self.cluster = cluster.MultiCore( 1527 **self.options) 1528 self.cluster.nb_core = nb_core 1529 #cluster_temp_path=self.options['cluster_temp_path'], 1530 1531 if self.cluster_mode == 1: 1532 opt = self.options 1533 cluster_name = opt['cluster_type'] 1534 self.cluster = cluster.from_name[cluster_name](**opt)
1535 1536
1537 - def check_param_card(self, path, run=True):
1538 """Check that all the width are define in the param_card. 1539 If some width are set on 'Auto', call the computation tools.""" 1540 1541 pattern = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto(@NLO|)''',re.I) 1542 text = open(path).read() 1543 pdg_info = pattern.findall(text) 1544 if pdg_info: 1545 if run: 1546 logger.info('Computing the width set on auto in the param_card.dat') 1547 has_nlo = any(nlo.lower()=="@nlo" for _,nlo in pdg_info) 1548 pdg = [pdg for pdg,nlo in pdg_info] 1549 if not has_nlo: 1550 self.do_compute_widths('%s %s' % (' '.join(pdg), path)) 1551 else: 1552 self.do_compute_widths('%s %s --nlo' % (' '.join(pdg), path)) 1553 else: 1554 logger.info('''Some width are on Auto in the card. 1555 Those will be computed as soon as you have finish the edition of the cards. 1556 If you want to force the computation right now and being able to re-edit 1557 the cards afterwards, you can type \"compute_wdiths\".''')
1558 1559
1560 - def add_error_log_in_html(self, errortype=None):
1561 """If a ME run is currently running add a link in the html output""" 1562 1563 # Be very carefull to not raise any error here (the traceback 1564 #will be modify in that case.) 1565 if hasattr(self, 'results') and hasattr(self.results, 'current') and\ 1566 self.results.current and 'run_name' in self.results.current and \ 1567 hasattr(self, 'me_dir'): 1568 name = self.results.current['run_name'] 1569 tag = self.results.current['tag'] 1570 self.debug_output = pjoin(self.me_dir, '%s_%s_debug.log' % (name,tag)) 1571 if errortype: 1572 self.results.current.debug = errortype 1573 else: 1574 self.results.current.debug = self.debug_output 1575 1576 else: 1577 #Force class default 1578 self.debug_output = CommonRunCmd.debug_output 1579 if os.path.exists('ME5_debug') and not 'ME5_debug' in self.debug_output: 1580 os.remove('ME5_debug') 1581 if not 'ME5_debug' in self.debug_output: 1582 os.system('ln -s %s ME5_debug &> /dev/null' % self.debug_output)
1583 1584
1585 - def do_quit(self, line):
1586 """Not in help: exit """ 1587 1588 try: 1589 os.remove(pjoin(self.me_dir,'RunWeb')) 1590 except Exception: 1591 pass 1592 try: 1593 self.store_result() 1594 except Exception: 1595 # If nothing runs they they are no result to update 1596 pass 1597 1598 try: 1599 self.update_status('', level=None) 1600 except Exception, error: 1601 pass 1602 devnull = open(os.devnull, 'w') 1603 try: 1604 misc.call(['./bin/internal/gen_cardhtml-pl'], cwd=self.me_dir, 1605 stdout=devnull, stderr=devnull) 1606 except Exception: 1607 pass 1608 devnull.close() 1609 1610 return super(CommonRunCmd, self).do_quit(line)
1611 1612 # Aliases 1613 do_EOF = do_quit 1614 do_exit = do_quit 1615 1616
1617 - def update_status(self, status, level, makehtml=True, force=True, 1618 error=False, starttime = None, update_results=True, 1619 print_log=True):
1620 """ update the index status """ 1621 1622 if makehtml and not force: 1623 if hasattr(self, 'next_update') and time.time() < self.next_update: 1624 return 1625 else: 1626 self.next_update = time.time() + 3 1627 1628 if print_log: 1629 if isinstance(status, str): 1630 if '<br>' not in status: 1631 logger.info(status) 1632 elif starttime: 1633 running_time = misc.format_timer(time.time()-starttime) 1634 logger.info(' Idle: %s, Running: %s, Completed: %s [ %s ]' % \ 1635 (status[0], status[1], status[2], running_time)) 1636 else: 1637 logger.info(' Idle: %s, Running: %s, Completed: %s' % status[:3]) 1638 1639 if update_results: 1640 self.results.update(status, level, makehtml=makehtml, error=error)
1641 1642 1643 ############################################################################
1644 - def keep_cards(self, need_card=[], ignore=[]):
1645 """Ask the question when launching generate_events/multi_run""" 1646 1647 check_card = ['pythia_card.dat', 'pgs_card.dat','delphes_card.dat', 1648 'delphes_trigger.dat', 'madspin_card.dat', 'shower_card.dat', 1649 'reweight_card.dat'] 1650 1651 cards_path = pjoin(self.me_dir,'Cards') 1652 for card in check_card: 1653 if card in ignore: 1654 continue 1655 if card not in need_card: 1656 if os.path.exists(pjoin(cards_path, card)): 1657 os.remove(pjoin(cards_path, card)) 1658 else: 1659 if not os.path.exists(pjoin(cards_path, card)): 1660 default = card.replace('.dat', '_default.dat') 1661 files.cp(pjoin(cards_path, default),pjoin(cards_path, card))
1662 1663 ############################################################################
1664 - def set_configuration(self, config_path=None, final=True, initdir=None, amcatnlo=False):
1665 """ assign all configuration variable from file 1666 ./Cards/mg5_configuration.txt. assign to default if not define """ 1667 1668 if not hasattr(self, 'options') or not self.options: 1669 self.options = dict(self.options_configuration) 1670 self.options.update(self.options_madgraph) 1671 self.options.update(self.options_madevent) 1672 1673 if not config_path: 1674 if os.environ.has_key('MADGRAPH_BASE'): 1675 config_path = pjoin(os.environ['MADGRAPH_BASE'],'mg5_configuration.txt') 1676 self.set_configuration(config_path=config_path, final=final) 1677 return 1678 if 'HOME' in os.environ: 1679 config_path = pjoin(os.environ['HOME'],'.mg5', 1680 'mg5_configuration.txt') 1681 if os.path.exists(config_path): 1682 self.set_configuration(config_path=config_path, final=False) 1683 if amcatnlo: 1684 me5_config = pjoin(self.me_dir, 'Cards', 'amcatnlo_configuration.txt') 1685 else: 1686 me5_config = pjoin(self.me_dir, 'Cards', 'me5_configuration.txt') 1687 self.set_configuration(config_path=me5_config, final=False, initdir=self.me_dir) 1688 1689 if self.options.has_key('mg5_path') and self.options['mg5_path']: 1690 MG5DIR = self.options['mg5_path'] 1691 config_file = pjoin(MG5DIR, 'input', 'mg5_configuration.txt') 1692 self.set_configuration(config_path=config_file, final=False,initdir=MG5DIR) 1693 else: 1694 self.options['mg5_path'] = None 1695 return self.set_configuration(config_path=me5_config, final=final,initdir=self.me_dir) 1696 1697 config_file = open(config_path) 1698 1699 # read the file and extract information 1700 logger.info('load configuration from %s ' % config_file.name) 1701 for line in config_file: 1702 1703 if '#' in line: 1704 line = line.split('#',1)[0] 1705 line = line.replace('\n','').replace('\r\n','') 1706 try: 1707 name, value = line.split('=') 1708 except ValueError: 1709 pass 1710 else: 1711 name = name.strip() 1712 value = value.strip() 1713 if name.endswith('_path') and not name.startswith('cluster'): 1714 path = value 1715 if os.path.isdir(path): 1716 self.options[name] = os.path.realpath(path) 1717 continue 1718 if not initdir: 1719 continue 1720 path = pjoin(initdir, value) 1721 if os.path.isdir(path): 1722 self.options[name] = os.path.realpath(path) 1723 continue 1724 else: 1725 self.options[name] = value 1726 if value.lower() == "none": 1727 self.options[name] = None 1728 1729 if not final: 1730 return self.options # the return is usefull for unittest 1731 1732 # Treat each expected input 1733 # delphes/pythia/... path 1734 for key in self.options: 1735 # Final cross check for the path 1736 if key.endswith('path') and not key.startswith("cluster"): 1737 path = self.options[key] 1738 if path is None: 1739 continue 1740 if os.path.isdir(path): 1741 self.options[key] = os.path.realpath(path) 1742 continue 1743 path = pjoin(self.me_dir, self.options[key]) 1744 if os.path.isdir(path): 1745 self.options[key] = os.path.realpath(path) 1746 continue 1747 elif self.options.has_key('mg5_path') and self.options['mg5_path']: 1748 path = pjoin(self.options['mg5_path'], self.options[key]) 1749 if os.path.isdir(path): 1750 self.options[key] = os.path.realpath(path) 1751 continue 1752 self.options[key] = None 1753 elif key.startswith('cluster') and key != 'cluster_status_update': 1754 if key in ('cluster_nb_retry','cluster_wait_retry'): 1755 self.options[key] = int(self.options[key]) 1756 if hasattr(self,'cluster'): 1757 del self.cluster 1758 pass 1759 elif key == 'automatic_html_opening': 1760 if self.options[key] in ['False', 'True']: 1761 self.options[key] =eval(self.options[key]) 1762 elif key not in ['text_editor','eps_viewer','web_browser','stdout_level', 1763 'complex_mass_scheme', 'gauge', 'group_subprocesses']: 1764 # Default: try to set parameter 1765 try: 1766 self.do_set("%s %s --no_save" % (key, self.options[key]), log=False) 1767 except self.InvalidCmd: 1768 logger.warning("Option %s from config file not understood" \ 1769 % key) 1770 1771 # Configure the way to open a file: 1772 misc.open_file.configure(self.options) 1773 self.configure_run_mode(self.options['run_mode']) 1774 return self.options
1775 1776 @staticmethod
1777 - def find_available_run_name(me_dir):
1778 """ find a valid run_name for the current job """ 1779 1780 name = 'run_%02d' 1781 data = [int(s[4:j]) for s in os.listdir(pjoin(me_dir,'Events')) for 1782 j in range(4,len(s)+1) if \ 1783 s.startswith('run_') and s[4:j].isdigit()] 1784 return name % (max(data+[0])+1)
1785 1786 1787 ############################################################################
1788 - def do_decay_events(self,line):
1789 """Require MG5 directory: decay events with spin correlations 1790 """ 1791 1792 if '-from_cards' in line and not os.path.exists(pjoin(self.me_dir, 'Cards', 'madspin_card.dat')): 1793 return 1794 1795 # First need to load MadSpin 1796 1797 # Check that MG5 directory is present . 1798 if MADEVENT and not self.options['mg5_path']: 1799 raise self.InvalidCmd, '''The module decay_events requires that MG5 is installed on the system. 1800 You can install it and set its path in ./Cards/me5_configuration.txt''' 1801 elif MADEVENT: 1802 sys.path.append(self.options['mg5_path']) 1803 try: 1804 import MadSpin.decay as decay 1805 import MadSpin.interface_madspin as interface_madspin 1806 except ImportError: 1807 if __debug__: 1808 raise 1809 else: 1810 raise self.ConfigurationError, '''Can\'t load MadSpin 1811 The variable mg5_path might not be correctly configured.''' 1812 1813 self.update_status('Running MadSpin', level='madspin') 1814 if not '-from_cards' in line: 1815 self.keep_cards(['madspin_card.dat']) 1816 self.ask_edit_cards(['madspin_card.dat'], 'fixed', plot=False) 1817 self.help_decay_events(skip_syntax=True) 1818 1819 # load the name of the event file 1820 args = self.split_arg(line) 1821 self.check_decay_events(args) 1822 # args now alway content the path to the valid files 1823 madspin_cmd = interface_madspin.MadSpinInterface(args[0]) 1824 madspin_cmd.update_status = lambda *x,**opt: self.update_status(*x, level='madspin',**opt) 1825 1826 path = pjoin(self.me_dir, 'Cards', 'madspin_card.dat') 1827 1828 madspin_cmd.import_command_file(path) 1829 1830 # create a new run_name directory for this output 1831 i = 1 1832 while os.path.exists(pjoin(self.me_dir,'Events', '%s_decayed_%i' % (self.run_name,i))): 1833 i+=1 1834 new_run = '%s_decayed_%i' % (self.run_name,i) 1835 evt_dir = pjoin(self.me_dir, 'Events') 1836 1837 os.mkdir(pjoin(evt_dir, new_run)) 1838 current_file = args[0].replace('.lhe', '_decayed.lhe') 1839 new_file = pjoin(evt_dir, new_run, os.path.basename(args[0])) 1840 if not os.path.exists(current_file): 1841 if os.path.exists(current_file+'.gz'): 1842 current_file += '.gz' 1843 new_file += '.gz' 1844 else: 1845 logger.error('MadSpin fails to create any decayed file.') 1846 return 1847 1848 files.mv(current_file, new_file) 1849 logger.info("The decayed event file has been moved to the following location: ") 1850 logger.info(new_file) 1851 1852 if hasattr(self, 'results'): 1853 current = self.results.current 1854 nb_event = self.results.current['nb_event'] 1855 if not nb_event: 1856 current = self.results[self.run_name][0] 1857 nb_event = current['nb_event'] 1858 1859 cross = current['cross'] 1860 error = current['error'] 1861 self.results.add_run( new_run, self.run_card) 1862 self.results.add_detail('nb_event', nb_event) 1863 self.results.add_detail('cross', cross * madspin_cmd.branching_ratio) 1864 self.results.add_detail('error', error * madspin_cmd.branching_ratio + cross * madspin_cmd.err_branching_ratio) 1865 self.results.add_detail('run_mode', current['run_mode']) 1866 1867 self.run_name = new_run 1868 self.banner = madspin_cmd.banner 1869 self.banner.add(path) 1870 self.banner.write(pjoin(self.me_dir,'Events',self.run_name, '%s_%s_banner.txt' % 1871 (self.run_name, self.run_tag))) 1872 self.update_status('MadSpin Done', level='parton', makehtml=False) 1873 if 'unweighted' in os.path.basename(args[0]): 1874 self.create_plot('parton')
1875
1876 - def complete_decay_events(self, text, line, begidx, endidx):
1877 args = self.split_arg(line[0:begidx], error=False) 1878 if len(args) == 1: 1879 return self.complete_plot(text, line, begidx, endidx) 1880 else: 1881 return
1882
1883 - def complete_print_results(self,text, line, begidx, endidx):
1884 "Complete the print results command" 1885 args = self.split_arg(line[0:begidx], error=False) 1886 if len(args) == 1: 1887 #return valid run_name 1888 data = glob.glob(pjoin(self.me_dir, 'Events', '*','unweighted_events.lhe.gz')) 1889 data = [n.rsplit('/',2)[1] for n in data] 1890 tmp1 = self.list_completion(text, data) 1891 return tmp1 1892 else: 1893 data = glob.glob(pjoin(self.me_dir, 'Events', args[0], '*_pythia_events.hep.gz')) 1894 data = [os.path.basename(p).rsplit('_',1)[0] for p in data] 1895 data += ["--mode=a", "--mode=w", "--path=", "--format=short"] 1896 tmp1 = self.list_completion(text, data) 1897 return tmp1
1898
1899 - def help_print_result(self):
1900 logger.info("syntax: print_result [RUN] [TAG] [options]") 1901 logger.info("-- show in text format the status of the run (cross-section/nb-event/...)") 1902 logger.info("--path= defines the path of the output file.") 1903 logger.info("--mode=a allow to add the information at the end of the file.") 1904 logger.info("--format=short (only if --path is define)") 1905 logger.info(" allows to have a multi-column output easy to parse")
1906 1907 ############################################################################
1908 - def do_check_events(self, line):
1909 """ Run some sanity check on the generated events.""" 1910 1911 # Check that MG5 directory is present . 1912 if MADEVENT and not self.options['mg5_path']: 1913 raise self.InvalidCmd, '''The module reweight requires that MG5 is installed on the system. 1914 You can install it and set its path in ./Cards/me5_configuration.txt''' 1915 elif MADEVENT: 1916 sys.path.append(self.options['mg5_path']) 1917 try: 1918 import madgraph.interface.reweight_interface as reweight_interface 1919 except ImportError: 1920 raise self.ConfigurationError, '''Can\'t load Reweight module. 1921 The variable mg5_path might not be correctly configured.''' 1922 1923 1924 # load the name of the event file 1925 args = self.split_arg(line) 1926 self.check_check_events(args) 1927 # args now alway content the path to the valid files 1928 reweight_cmd = reweight_interface.ReweightInterface(args[0], allow_madspin=True) 1929 reweight_cmd.mother = self 1930 self.update_status('Running check on events', level='check') 1931 1932 reweight_cmd.check_events()
1933 1934 ############################################################################
1935 - def complete_check_events(self, text, line, begidx, endidx):
1936 args = self.split_arg(line[0:begidx], error=False) 1937 1938 if len(args) == 1 and os.path.sep not in text: 1939 #return valid run_name 1940 data = glob.glob(pjoin(self.me_dir, 'Events', '*','*events.lhe*')) 1941 data = [n.rsplit('/',2)[1] for n in data] 1942 return self.list_completion(text, data, line) 1943 else: 1944 return self.path_completion(text, 1945 os.path.join('.',*[a for a in args \ 1946 if a.endswith(os.path.sep)]))
1947
1948 - def complete_compute_widths(self, text, line, begidx, endidx):
1949 "Complete the compute_widths command" 1950 1951 args = self.split_arg(line[0:begidx]) 1952 1953 if args[-1] in ['--path=', '--output=']: 1954 completion = {'path': self.path_completion(text)} 1955 elif line[begidx-1] == os.path.sep: 1956 current_dir = pjoin(*[a for a in args if a.endswith(os.path.sep)]) 1957 if current_dir.startswith('--path='): 1958 current_dir = current_dir[7:] 1959 if current_dir.startswith('--output='): 1960 current_dir = current_dir[9:] 1961 completion = {'path': self.path_completion(text, current_dir)} 1962 else: 1963 completion = {} 1964 completion['options'] = self.list_completion(text, 1965 ['--path=', '--output=', '--min_br=0.\$', '--nlo', 1966 '--precision_channel=0.\$', '--body_decay=']) 1967 1968 return self.deal_multiple_categories(completion)
1969 1970 1971 # lhapdf-related functions 1999 2000
2001 - def get_characteristics(self, path=None):
2002 """reads the proc_characteristics file and initialises the correspondant 2003 dictionary""" 2004 2005 if not path: 2006 path = os.path.join(self.me_dir, 'SubProcesses', 'proc_characteristics') 2007 2008 self.proc_characteristics = banner_mod.ProcCharacteristic(path) 2009 return self.proc_characteristics
2010 2011
2012 - def copy_lhapdf_set(self, lhaid_list, pdfsets_dir):
2013 """copy (if needed) the lhapdf set corresponding to the lhaid in lhaid_list 2014 into lib/PDFsets""" 2015 2016 pdfsetname = '' 2017 for lhaid in lhaid_list: 2018 try: 2019 if not pdfsetname: 2020 if lhaid in self.lhapdf_pdfsets: 2021 pdfsetname = self.lhapdf_pdfsets[lhaid]['filename'] 2022 else: 2023 raise MadGraph5Error('lhaid %s not valid input number for the current lhapdf' % lhaid ) 2024 # just check the other ids refer to the same pdfsetname 2025 elif not \ 2026 self.lhapdf_pdfsets[lhaid]['filename'] == pdfsetname: 2027 raise MadGraph5Error(\ 2028 'lhaid and PDF_set_min/max in the run_card do not correspond to the' + \ 2029 'same PDF set. Please check the run_card.') 2030 except KeyError: 2031 if self.lhapdf_version.startswith('5'): 2032 raise MadGraph5Error(\ 2033 ('invalid lhaid set in th run_card: %d .\nPlease note that some sets' % lhaid) + \ 2034 '(eg MSTW 90%CL error sets) \nare not available in aMC@NLO + LHAPDF 5.x.x') 2035 else: 2036 logger.debug('%d not found in pdfsets.index' % lhaid) 2037 2038 2039 # check if the file exists, otherwise install it: 2040 # also check that the PDFsets dir exists, otherwise create it. 2041 # if fails, install the lhapdfset into lib/PDFsets 2042 if not os.path.isdir(pdfsets_dir): 2043 try: 2044 os.mkdir(pdfsets_dir) 2045 except OSError: 2046 pdfsets_dir = pjoin(self.me_dir, 'lib', 'PDFsets') 2047 else: 2048 #clean previous set of pdf used 2049 for name in os.listdir(pjoin(self.me_dir, 'lib', 'PDFsets')): 2050 if name != pdfsetname: 2051 try: 2052 if os.path.isdir(pjoin(self.me_dir, 'lib', 'PDFsets', name)): 2053 shutil.rmtree(pjoin(self.me_dir, 'lib', 'PDFsets', name)) 2054 else: 2055 os.remove(pjoin(self.me_dir, 'lib', 'PDFsets', name)) 2056 except Exception, error: 2057 logger.debug('%s', error) 2058 2059 if self.options["cluster_local_path"]: 2060 lhapdf_cluster_possibilities = [self.options["cluster_local_path"], 2061 pjoin(self.options["cluster_local_path"], "lhapdf"), 2062 pjoin(self.options["cluster_local_path"], "lhapdf", "pdfsets"), 2063 pjoin(self.options["cluster_local_path"], "..", "lhapdf"), 2064 pjoin(self.options["cluster_local_path"], "..", "lhapdf", "pdfsets"), 2065 pjoin(self.options["cluster_local_path"], "..", "lhapdf","pdfsets", "6.1") 2066 ] 2067 else: 2068 lhapdf_cluster_possibilities = [] 2069 2070 # Check if we need to copy the pdf 2071 if self.options["cluster_local_path"] and self.options["run_mode"] == 1 and \ 2072 any((os.path.exists(pjoin(d, pdfsetname)) for d in lhapdf_cluster_possibilities)): 2073 2074 os.environ["LHAPATH"] = [d for d in lhapdf_cluster_possibilities if os.path.exists(pjoin(d, pdfsetname))][0] 2075 os.environ["CLUSTER_LHAPATH"] = os.environ["LHAPATH"] 2076 # no need to copy it 2077 if os.path.exists(pjoin(pdfsets_dir, pdfsetname)): 2078 try: 2079 if os.path.isdir(pjoin(pdfsets_dir, name)): 2080 shutil.rmtree(pjoin(pdfsets_dir, name)) 2081 else: 2082 os.remove(pjoin(pdfsets_dir, name)) 2083 except Exception, error: 2084 logger.debug('%s', error) 2085 2086 #check that the pdfset is not already there 2087 elif not os.path.exists(pjoin(self.me_dir, 'lib', 'PDFsets', pdfsetname)) and \ 2088 not os.path.isdir(pjoin(self.me_dir, 'lib', 'PDFsets', pdfsetname)): 2089 2090 if pdfsetname and not os.path.exists(pjoin(pdfsets_dir, pdfsetname)): 2091 self.install_lhapdf_pdfset(pdfsets_dir, pdfsetname) 2092 2093 if os.path.exists(pjoin(pdfsets_dir, pdfsetname)): 2094 files.cp(pjoin(pdfsets_dir, pdfsetname), pjoin(self.me_dir, 'lib', 'PDFsets')) 2095 elif os.path.exists(pjoin(os.path.dirname(pdfsets_dir), pdfsetname)): 2096 files.cp(pjoin(os.path.dirname(pdfsets_dir), pdfsetname), pjoin(self.me_dir, 'lib', 'PDFsets'))
2097
2098 - def install_lhapdf_pdfset(self, pdfsets_dir, filename):
2099 """idownloads and install the pdfset filename in the pdfsets_dir""" 2100 lhapdf_version = self.get_lhapdf_version() 2101 logger.info('Trying to download %s' % filename) 2102 2103 if lhapdf_version.startswith('5.'): 2104 # use the lhapdf-getdata command, which is in the same path as 2105 # lhapdf-config 2106 getdata = self.options['lhapdf'].replace('lhapdf-config', ('lhapdf-getdata')) 2107 misc.call([getdata, filename], cwd = pdfsets_dir) 2108 2109 elif lhapdf_version.startswith('6.'): 2110 # use the "lhapdf install xxx" command, which is in the same path as 2111 # lhapdf-config 2112 getdata = self.options['lhapdf'].replace('lhapdf-config', ('lhapdf')) 2113 2114 misc.call([getdata, 'install', filename], cwd = pdfsets_dir) 2115 2116 else: 2117 raise MadGraph5Error('Not valid LHAPDF version: %s' % lhapdf_version) 2118 2119 # check taht the file has been installed in the global dir 2120 if os.path.exists(pjoin(pdfsets_dir, filename)) or \ 2121 os.path.isdir(pjoin(pdfsets_dir, filename)): 2122 logger.info('%s successfully downloaded and stored in %s' \ 2123 % (filename, pdfsets_dir)) 2124 #otherwise (if v5) save it locally 2125 elif lhapdf_version.startswith('5.'): 2126 logger.warning('Could not download %s into %s. Trying to save it locally' \ 2127 % (filename, pdfsets_dir)) 2128 self.install_lhapdf_pdfset(pjoin(self.me_dir, 'lib', 'PDFsets'), filename) 2129 else: 2130 raise MadGraph5Error, \ 2131 'Could not download %s into %s. Please try to install it manually.' \ 2132 % (filename, pdfsets_dir)
2133 2134
2135 - def get_lhapdf_pdfsets_list(self, pdfsets_dir):
2136 """read the PDFsets.index file, which should be located in the same 2137 place as pdfsets_dir, and return a list of dictionaries with the information 2138 about each pdf set""" 2139 lhapdf_version = self.get_lhapdf_version() 2140 2141 if lhapdf_version.startswith('5.'): 2142 if os.path.exists('%s.index' % pdfsets_dir): 2143 indexfile = '%s.index' % pdfsets_dir 2144 else: 2145 raise MadGraph5Error, 'index of lhapdf file not found' 2146 pdfsets_lines = \ 2147 [l for l in open(indexfile).read().split('\n') if l.strip() and \ 2148 not '90cl' in l] 2149 lhapdf_pdfsets = dict( (int(l.split()[0]), {'lhaid': int(l.split()[0]), 2150 'pdflib_ntype': int(l.split()[1]), 2151 'pdflib_ngroup': int(l.split()[2]), 2152 'pdflib_nset': int(l.split()[3]), 2153 'filename': l.split()[4], 2154 'lhapdf_nmem': int(l.split()[5]), 2155 'q2min': float(l.split()[6]), 2156 'q2max': float(l.split()[7]), 2157 'xmin': float(l.split()[8]), 2158 'xmax': float(l.split()[9]), 2159 'description': l.split()[10]}) \ 2160 for l in pdfsets_lines) 2161 2162 elif lhapdf_version.startswith('6.'): 2163 pdfsets_lines = \ 2164 [l for l in open(pjoin(pdfsets_dir, 'pdfsets.index')).read().split('\n') if l.strip()] 2165 lhapdf_pdfsets = dict( (int(l.split()[0]), 2166 {'lhaid': int(l.split()[0]), 2167 'filename': l.split()[1]}) \ 2168 for l in pdfsets_lines) 2169 2170 else: 2171 raise MadGraph5Error('Not valid LHAPDF version: %s' % lhapdf_version) 2172 2173 return lhapdf_pdfsets
2174 2175
2176 - def get_lhapdf_version(self):
2177 """returns the lhapdf version number""" 2178 if not hasattr(self, 'lhapdfversion'): 2179 self.lhapdf_version = \ 2180 subprocess.Popen([self.options['lhapdf'], '--version'], 2181 stdout = subprocess.PIPE).stdout.read().strip() 2182 2183 # this will be removed once some issues in lhapdf6 will be fixed 2184 if self.lhapdf_version.startswith('6.0'): 2185 raise MadGraph5Error('LHAPDF 6.0.x not supported. Please use v6.1 or later') 2186 2187 return self.lhapdf_version
2188 2189
2190 - def get_lhapdf_pdfsetsdir(self):
2191 lhapdf_version = self.get_lhapdf_version() 2192 2193 # check if the LHAPDF_DATA_PATH variable is defined 2194 if 'LHAPDF_DATA_PATH' in os.environ.keys() and os.environ['LHAPDF_DATA_PATH']: 2195 datadir = os.environ['LHAPDF_DATA_PATH'] 2196 2197 elif lhapdf_version.startswith('5.'): 2198 datadir = subprocess.Popen([self.options['lhapdf'], '--pdfsets-path'], 2199 stdout = subprocess.PIPE).stdout.read().strip() 2200 2201 elif lhapdf_version.startswith('6.'): 2202 datadir = subprocess.Popen([self.options['lhapdf'], '--datadir'], 2203 stdout = subprocess.PIPE).stdout.read().strip() 2204 2205 return datadir
2206
2207 -class AskforEditCard(cmd.OneLinePathCompletion):
2208 """A class for asking a question where in addition you can have the 2209 set command define and modifying the param_card/run_card correctly""" 2210 2211 special_shortcut = {'ebeam':['run_card ebeam1 %(0)s', 'run_card ebeam2 %(0)s'], 2212 'lpp': ['run_card lpp1 %(0)s', 'run_card lpp2 %(0)s' ], 2213 'lhc': ['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2'], 2214 'lep': ['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2'], 2215 'ilc': ['run_card lpp1 0', 'run_card lpp2 0', 'run_card ebeam1 %(0)s/2', 'run_card ebeam2 %(0)s/2'], 2216 'lcc':['run_card lpp1 1', 'run_card lpp2 1', 'run_card ebeam1 %(0)s*1000/2', 'run_card ebeam2 %(0)s*1000/2'], 2217 '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'], 2218 } 2219
2220 - def __init__(self, question, cards=[], mode='auto', *args, **opt):
2221 2222 # Initiation 2223 if 'pwd' in opt: 2224 self.me_dir = opt['pwd'] 2225 del opt['pwd'] 2226 2227 cmd.OneLinePathCompletion.__init__(self, question, *args, **opt) 2228 2229 if not hasattr(self, 'me_dir') or not self.me_dir: 2230 self.me_dir = self.mother_interface.me_dir 2231 2232 # read the card 2233 2234 2235 try: 2236 self.param_card = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card.dat')) 2237 except (check_param_card.InvalidParamCard, ValueError) as e: 2238 logger.error('Current param_card is not valid. We are going to use the default one.') 2239 logger.error('problem detected: %s' % e) 2240 files.cp(pjoin(self.me_dir,'Cards','param_card_default.dat'), 2241 pjoin(self.me_dir,'Cards','param_card.dat')) 2242 self.param_card = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card.dat')) 2243 default_param = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card_default.dat')) 2244 2245 2246 try: 2247 self.run_card = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card.dat')) 2248 except IOError: 2249 self.run_card = {} 2250 try: 2251 run_card_def = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card_default.dat')) 2252 except IOError: 2253 run_card_def = {} 2254 2255 self.pname2block = {} 2256 self.conflict = [] 2257 self.restricted_value = {} 2258 self.mode = mode 2259 self.cards = cards 2260 2261 # Read the comment of the param_card_default to find name variable for 2262 # the param_card also check which value seems to be constrained in the 2263 # model. 2264 for bname, block in default_param.items(): 2265 for lha_id, param in block.param_dict.items(): 2266 all_var = [] 2267 comment = param.comment 2268 # treat merge parameter 2269 if comment.strip().startswith('set of param :'): 2270 all_var = list(re.findall(r'''[^-]1\*(\w*)\b''', comment)) 2271 # just the variable name as comment 2272 elif len(comment.split()) == 1: 2273 all_var = [comment.strip().lower()] 2274 # either contraction or not formatted 2275 else: 2276 split = comment.split() 2277 if len(split) >2 and split[1] == ':': 2278 # NO VAR associated 2279 self.restricted_value[(bname, lha_id)] = ' '.join(split[1:]) 2280 elif len(split) == 2: 2281 if re.search(r'''\[[A-Z]\]eV\^''', split[1]): 2282 all_var = [comment.strip().lower()] 2283 elif len(split) >=2 and split[1].startswith('('): 2284 all_var = [split[0].strip().lower()] 2285 else: 2286 if not bname.startswith('qnumbers'): 2287 logger.debug("not recognize information for %s %s : %s", 2288 bname, lha_id, comment) 2289 # not recognized format 2290 continue 2291 2292 for var in all_var: 2293 var = var.lower() 2294 if var in self.pname2block: 2295 self.pname2block[var].append((bname, lha_id)) 2296 else: 2297 self.pname2block[var] = [(bname, lha_id)] 2298 2299 if run_card_def: 2300 self.run_set = run_card_def.keys() + self.run_card.hidden_param 2301 elif self.run_card: 2302 self.run_set = self.run_card.keys() 2303 else: 2304 self.run_set = [] 2305 # check for conflict with run_card 2306 for var in self.pname2block: 2307 if var in self.run_set: 2308 self.conflict.append(var) 2309 2310 2311 #check if Madweight_card is present: 2312 self.has_mw = False 2313 if 'madweight_card.dat' in cards: 2314 2315 self.do_change_tf = self.mother_interface.do_define_transfer_fct 2316 self.complete_change_tf = self.mother_interface.complete_define_transfer_fct 2317 self.help_change_tf = self.mother_interface.help_define_transfer_fct 2318 if not os.path.exists(pjoin(self.me_dir,'Cards','transfer_card.dat')): 2319 logger.warning('No transfer function currently define. Please use the change_tf command to define one.') 2320 2321 2322 self.has_mw = True 2323 try: 2324 import madgraph.madweight.Cards as mwcards 2325 except: 2326 import internal.madweight.Cards as mwcards 2327 self.mw_card = mwcards.Card(pjoin(self.me_dir,'Cards','MadWeight_card.dat')) 2328 self.mw_card = self.mw_card.info 2329 self.mw_vars = [] 2330 for key in self.mw_card: 2331 if key == 'comment': 2332 continue 2333 for key2 in self.mw_card.info[key]: 2334 if isinstance(key2, str) and not key2.isdigit(): 2335 self.mw_vars.append(key2) 2336 2337 # check for conflict with run_card/param_card 2338 for var in self.pname2block: 2339 if var in self.mw_vars: 2340 self.conflict.append(var) 2341 for var in self.mw_vars: 2342 if var in self.run_card: 2343 self.conflict.append(var) 2344 2345 #check if MadLoopParams.dat is present: 2346 self.has_ml = False 2347 if os.path.isfile(pjoin(self.me_dir,'Cards','MadLoopParams.dat')): 2348 self.has_ml = True 2349 self.MLcard = banner_mod.MadLoopParam(pjoin(self.me_dir,'Cards','MadLoopParams.dat')) 2350 self.MLcardDefault = banner_mod.MadLoopParam() 2351 2352 self.ml_vars = [k.lower() for k in self.MLcard.keys()] 2353 # check for conflict 2354 for var in self.MLcard: 2355 if var in self.run_card: 2356 self.conflict.append(var) 2357 if var in self.pname2block: 2358 self.conflict.append(var) 2359 if self.has_mw and var in self.mw_vars: 2360 self.conflict.append(var) 2361 2362 #check if shower_card is present: 2363 self.has_shower = False 2364 if 'shower_card.dat' in cards: 2365 self.has_shower = True 2366 try: 2367 import madgraph.various.shower_card as showercards 2368 except: 2369 import internal.shower_card as showercards 2370 self.shower_card = showercards.ShowerCard(pjoin(self.me_dir,'Cards','shower_card.dat')) 2371 self.shower_vars = self.shower_card.keys() 2372 2373 # check for conflict with run_card/param_card 2374 for var in self.pname2block: 2375 if var in self.shower_vars: 2376 self.conflict.append(var) 2377 for var in self.shower_vars: 2378 if var in self.run_card: 2379 self.conflict.append(var)
2380 2381
2382 - def complete_set(self, text, line, begidx, endidx):
2383 """ Complete the set command""" 2384 2385 prev_timer = signal.alarm(0) # avoid timer if any 2386 if prev_timer: 2387 nb_back = len(line) 2388 self.stdout.write('\b'*nb_back + '[timer stopped]\n') 2389 self.stdout.write(line) 2390 self.stdout.flush() 2391 2392 possibilities = {} 2393 allowed = {} 2394 args = self.split_arg(line[0:begidx]) 2395 if args[-1] in ['Auto', 'default']: 2396 return 2397 if len(args) == 1: 2398 allowed = {'category':'', 'run_card':'', 'block':'all', 'param_card':'','shortcut':''} 2399 if self.has_mw: 2400 allowed['madweight_card'] = '' 2401 allowed['mw_block'] = 'all' 2402 if self.has_shower: 2403 allowed['shower_card'] = '' 2404 if self.has_ml: 2405 allowed['madloop_card'] = '' 2406 elif len(args) == 2: 2407 if args[1] == 'run_card': 2408 allowed = {'run_card':'default'} 2409 elif args[1] == 'param_card': 2410 allowed = {'block':'all', 'param_card':'default'} 2411 elif args[1] in self.param_card.keys(): 2412 allowed = {'block':args[1]} 2413 elif args[1] == 'width': 2414 allowed = {'block': 'decay'} 2415 elif args[1] == 'MadWeight_card': 2416 allowed = {'madweight_card':'default', 'mw_block': 'all'} 2417 elif args[1] == 'MadLoop_card': 2418 allowed = {'madloop_card':'default'} 2419 elif self.has_mw and args[1] in self.mw_card.keys(): 2420 allowed = {'mw_block':args[1]} 2421 elif args[1] == 'shower_card': 2422 allowed = {'shower_card':'default'} 2423 else: 2424 allowed = {'value':''} 2425 else: 2426 start = 1 2427 if args[1] in ['run_card', 'param_card', 'MadWeight_card', 'shower_card', 'MadLoop_card']: 2428 start = 2 2429 if args[-1] in self.pname2block.keys(): 2430 allowed['value'] = 'default' 2431 elif args[start] in self.param_card.keys() or args[start] == 'width': 2432 if args[start] == 'width': 2433 args[start] = 'decay' 2434 2435 if args[start+1:]: 2436 allowed = {'block':(args[start], args[start+1:])} 2437 else: 2438 allowed = {'block':args[start]} 2439 elif self.has_mw and args[start] in self.mw_card.keys(): 2440 if args[start+1:]: 2441 allowed = {'mw_block':(args[start], args[start+1:])} 2442 else: 2443 allowed = {'mw_block':args[start]} 2444 #elif len(args) == start +1: 2445 # allowed['value'] = '' 2446 else: 2447 allowed['value'] = '' 2448 2449 if 'category' in allowed.keys(): 2450 categories = ['run_card', 'param_card'] 2451 if self.has_mw: 2452 categories.append('MadWeight_card') 2453 if self.has_shower: 2454 categories.append('shower_card') 2455 if self.has_ml: 2456 categories.append('MadLoop_card') 2457 2458 possibilities['category of parameter (optional)'] = \ 2459 self.list_completion(text, categories) 2460 2461 if 'shortcut' in allowed.keys(): 2462 possibilities['special values'] = self.list_completion(text, self.special_shortcut.keys()+['qcut', 'showerkt']) 2463 2464 if 'run_card' in allowed.keys(): 2465 opts = self.run_set 2466 if allowed['run_card'] == 'default': 2467 opts.append('default') 2468 2469 possibilities['Run Card'] = self.list_completion(text, opts) 2470 2471 if 'param_card' in allowed.keys(): 2472 opts = self.pname2block.keys() 2473 if allowed['param_card'] == 'default': 2474 opts.append('default') 2475 possibilities['Param Card'] = self.list_completion(text, opts) 2476 2477 if 'madweight_card' in allowed.keys(): 2478 opts = self.mw_vars + [k for k in self.mw_card.keys() if k !='comment'] 2479 if allowed['madweight_card'] == 'default': 2480 opts.append('default') 2481 possibilities['MadWeight Card'] = self.list_completion(text, opts) 2482 2483 if 'madloop_card' in allowed.keys(): 2484 opts = self.ml_vars 2485 if allowed['madloop_card'] == 'default': 2486 opts.append('default') 2487 2488 possibilities['MadLoop Parameter'] = self.list_completion(text, opts) 2489 2490 if 'shower_card' in allowed.keys(): 2491 opts = self.shower_vars + [k for k in self.shower_card.keys() if k !='comment'] 2492 if allowed['shower_card'] == 'default': 2493 opts.append('default') 2494 possibilities['Shower Card'] = self.list_completion(text, opts) 2495 2496 if 'value' in allowed.keys(): 2497 opts = ['default'] 2498 if 'decay' in args: 2499 opts.append('Auto') 2500 opts.append('Auto@NLO') 2501 elif args[-1] in self.pname2block and self.pname2block[args[-1]][0][0] == 'decay': 2502 opts.append('Auto') 2503 opts.append('Auto@NLO') 2504 possibilities['Special Value'] = self.list_completion(text, opts) 2505 2506 if 'block' in allowed.keys(): 2507 if allowed['block'] == 'all': 2508 allowed_block = [i for i in self.param_card.keys() if 'qnumbers' not in i] 2509 allowed_block.append('width') 2510 possibilities['Param Card Block' ] = \ 2511 self.list_completion(text, allowed_block) 2512 elif isinstance(allowed['block'], basestring): 2513 block = self.param_card[allowed['block']].param_dict 2514 ids = [str(i[0]) for i in block 2515 if (allowed['block'], i) not in self.restricted_value] 2516 possibilities['Param Card id' ] = self.list_completion(text, ids) 2517 varname = [name for name, all_var in self.pname2block.items() 2518 if any((bname == allowed['block'] 2519 for bname,lhaid in all_var))] 2520 possibilities['Param card variable'] = self.list_completion(text, 2521 varname) 2522 else: 2523 block = self.param_card[allowed['block'][0]].param_dict 2524 nb = len(allowed['block'][1]) 2525 ids = [str(i[nb]) for i in block if len(i) > nb and \ 2526 [str(a) for a in i[:nb]] == allowed['block'][1]] 2527 2528 if not ids: 2529 if tuple([int(i) for i in allowed['block'][1]]) in block: 2530 opts = ['default'] 2531 if allowed['block'][0] == 'decay': 2532 opts.append('Auto') 2533 opts.append('Auto@NLO') 2534 possibilities['Special value'] = self.list_completion(text, opts) 2535 possibilities['Param Card id' ] = self.list_completion(text, ids) 2536 2537 if 'mw_block' in allowed.keys(): 2538 if allowed['mw_block'] == 'all': 2539 allowed_block = [i for i in self.mw_card.keys() if 'comment' not in i] 2540 possibilities['MadWeight Block' ] = \ 2541 self.list_completion(text, allowed_block) 2542 elif isinstance(allowed['mw_block'], basestring): 2543 block = self.mw_card[allowed['mw_block']] 2544 ids = [str(i[0]) if isinstance(i, tuple) else str(i) for i in block] 2545 possibilities['MadWeight Card id' ] = self.list_completion(text, ids) 2546 else: 2547 block = self.mw_card[allowed['mw_block'][0]] 2548 nb = len(allowed['mw_block'][1]) 2549 ids = [str(i[nb]) for i in block if isinstance(i, tuple) and\ 2550 len(i) > nb and \ 2551 [str(a) for a in i[:nb]] == allowed['mw_block'][1]] 2552 2553 if not ids: 2554 if tuple([i for i in allowed['mw_block'][1]]) in block or \ 2555 allowed['mw_block'][1][0] in block.keys(): 2556 opts = ['default'] 2557 possibilities['Special value'] = self.list_completion(text, opts) 2558 possibilities['MadWeight Card id' ] = self.list_completion(text, ids) 2559 2560 return self.deal_multiple_categories(possibilities)
2561
2562 - def do_set(self, line):
2563 """ edit the value of one parameter in the card""" 2564 2565 args = self.split_arg(line) 2566 if '=' in args[-1]: 2567 arg1, arg2 = args.pop(-1).split('=') 2568 args += [arg1, arg2] 2569 args[:-1] = [ a.lower() for a in args[:-1]] 2570 # special shortcut: 2571 if args[0] in self.special_shortcut: 2572 if len(args) == 1: 2573 values = {} 2574 elif len(args) == 2: 2575 targettype = float 2576 if args[1].strip().isdigit(): 2577 targettype = int 2578 2579 try: 2580 values = {'0': targettype(args[1])} 2581 except ValueError as e: 2582 logger.warning("Wrong argument: The last entry should be a number.") 2583 return 2584 else: 2585 logger.warning("too many argument for this command") 2586 return 2587 2588 for arg in self.special_shortcut[args[0]]: 2589 try: 2590 text = arg % values 2591 except KeyError: 2592 logger.warning("This command requires one argument") 2593 return 2594 except Exception as e: 2595 logger.warning(str(e)) 2596 return 2597 else: 2598 self.do_set(arg % values) 2599 return 2600 2601 2602 start = 0 2603 if len(args) < 2: 2604 logger.warning('Invalid set command %s (need two arguments)' % line) 2605 return 2606 2607 # Special case for the qcut value 2608 if args[0].lower() == 'qcut': 2609 pythia_path = pjoin(self.me_dir, 'Cards','pythia_card.dat') 2610 if os.path.exists(pythia_path): 2611 logger.info('add line QCUT = %s in pythia_card.dat' % args[1]) 2612 p_card = open(pythia_path,'r').read() 2613 p_card, n = re.subn('''^\s*QCUT\s*=\s*[\de\+\-\.]*\s*$''', 2614 ''' QCUT = %s ''' % args[1], \ 2615 p_card, flags=(re.M+re.I)) 2616 if n==0: 2617 p_card = '%s \n QCUT= %s' % (p_card, args[1]) 2618 open(pythia_path, 'w').write(p_card) 2619 return 2620 # Special case for the showerkt value 2621 if args[0].lower() == 'showerkt': 2622 pythia_path = pjoin(self.me_dir, 'Cards','pythia_card.dat') 2623 if os.path.exists(pythia_path): 2624 logger.info('add line SHOWERKT = %s in pythia_card.dat' % args[1].upper()) 2625 p_card = open(pythia_path,'r').read() 2626 p_card, n = re.subn('''^\s*SHOWERKT\s*=\s*[default\de\+\-\.]*\s*$''', 2627 ''' SHOWERKT = %s ''' % args[1].upper(), \ 2628 p_card, flags=(re.M+re.I)) 2629 if n==0: 2630 p_card = '%s \n SHOWERKT= %s' % (p_card, args[1].upper()) 2631 open(pythia_path, 'w').write(p_card) 2632 return 2633 2634 2635 card = '' #store which card need to be modify (for name conflict) 2636 if args[0] == 'madweight_card': 2637 if not self.mw_card: 2638 logger.warning('Invalid Command: No MadWeight card defined.') 2639 return 2640 args[0] = 'MadWeight_card' 2641 2642 if args[0] == 'shower_card': 2643 if not self.shower_card: 2644 logger.warning('Invalid Command: No Shower card defined.') 2645 return 2646 args[0] = 'shower_card' 2647 2648 if args[0] == "madloop_card": 2649 if not self.has_ml: 2650 logger.warning('Invalid Command: No MadLoopParam card defined.') 2651 return 2652 args[0] = 'MadLoop_card' 2653 2654 if args[0] in ['run_card', 'param_card', 'MadWeight_card', 'shower_card']: 2655 if args[1] == 'default': 2656 logging.info('replace %s by the default card' % args[0]) 2657 files.cp(pjoin(self.me_dir,'Cards','%s_default.dat' % args[0]), 2658 pjoin(self.me_dir,'Cards','%s.dat'% args[0])) 2659 if args[0] == 'param_card': 2660 self.param_card = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card.dat')) 2661 elif args[0] == 'run_card': 2662 self.run_card = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card.dat')) 2663 elif args[0] == 'shower_card': 2664 self.shower_card = shower_card_mod.ShowerCard(pjoin(self.me_dir,'Cards','shower_card.dat')) 2665 return 2666 else: 2667 card = args[0] 2668 start=1 2669 if len(args) < 3: 2670 logger.warning('Invalid set command: %s (not enough arguments)' % line) 2671 return 2672 2673 elif args[0] in ['MadLoop_card']: 2674 if args[1] == 'default': 2675 logging.info('replace MadLoopParams.dat by the default card') 2676 self.MLcard = banner_mod.MadLoopParam(self.MLcardDefault) 2677 self.MLcard.write(pjoin(self.me_dir,'Cards','MadLoopParams.dat'), 2678 commentdefault=True) 2679 return 2680 else: 2681 card = args[0] 2682 start=1 2683 if len(args) < 3: 2684 logger.warning('Invalid set command: %s (not enough arguments)' % line) 2685 return 2686 elif args[0] in ['madspin_card']: 2687 if args[1] == 'default': 2688 logging.info('replace madspin_card.dat by the default card') 2689 files.cp(pjoin(self.me_dir,'Cards/madspin_card_default.dat'), 2690 pjoin(self.me_dir,'Cards/madspin_card.dat')) 2691 return 2692 else: 2693 logger.warning("""Command set not allowed for modifying the madspin_card. 2694 Check the command \"decay\" instead.""") 2695 return 2696 2697 #### RUN CARD 2698 if args[start] in [l.lower() for l in self.run_card.keys()] and card in ['', 'run_card']: 2699 if args[start] not in self.run_set: 2700 args[start] = [l for l in self.run_set if l.lower() == args[start]][0] 2701 2702 if args[start] in self.conflict and card == '': 2703 text = 'Ambiguous name (present in more than one card). Will assume it to be referred to run_card.\n' 2704 text += 'If this is not intended, please reset it in the run_card and specify the relevant card to \n' 2705 text += 'edit, in the format < set card parameter value >' 2706 logger.warning(text) 2707 2708 if args[start+1] == 'default': 2709 default = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card_default.dat')) 2710 if args[start] in default.keys(): 2711 self.setR(args[start],default[args[start]]) 2712 else: 2713 logger.info('remove information %s from the run_card' % args[start]) 2714 del self.run_card[args[start]] 2715 elif args[start+1].lower() in ['t','.true.','true']: 2716 self.setR(args[start], '.true.') 2717 elif args[start+1].lower() in ['f','.false.','false']: 2718 self.setR(args[start], '.false.') 2719 else: 2720 if args[0].startswith('sys_'): 2721 val = ' '.join(args[start+1:]) 2722 val = val.split('#')[0] 2723 else: 2724 try: 2725 val = eval(args[start+1]) 2726 except NameError: 2727 val = args[start+1] 2728 self.setR(args[start], val) 2729 self.run_card.write(pjoin(self.me_dir,'Cards','run_card.dat'), 2730 pjoin(self.me_dir,'Cards','run_card_default.dat')) 2731 2732 ### PARAM_CARD WITH BLOCK NAME ----------------------------------------- 2733 elif (args[start] in self.param_card or args[start] == 'width') \ 2734 and card in ['','param_card']: 2735 if args[start] in self.conflict and card == '': 2736 text = 'ambiguous name (present in more than one card). Please specify which card to edit' 2737 text += ' in the format < set card parameter value>' 2738 logger.warning(text) 2739 return 2740 2741 if args[start] == 'width': 2742 args[start] = 'decay' 2743 2744 if args[start+1] in self.pname2block: 2745 all_var = self.pname2block[args[start+1]] 2746 key = None 2747 for bname, lhaid in all_var: 2748 if bname == args[start]: 2749 key = lhaid 2750 break 2751 else: 2752 logger.warning('%s is not part of block "%s" but "%s". please correct.' % 2753 (args[start+1], args[start], bname)) 2754 return 2755 else: 2756 try: 2757 key = tuple([int(i) for i in args[start+1:-1]]) 2758 except ValueError: 2759 if args[start] == 'decay' and args[start+1:-1] == ['all']: 2760 for key in self.param_card[args[start]].param_dict: 2761 if (args[start], key) in self.restricted_value: 2762 continue 2763 else: 2764 self.setP(args[start], key, args[-1]) 2765 self.param_card.write(pjoin(self.me_dir,'Cards','param_card.dat')) 2766 return 2767 logger.warning('invalid set command %s (failed to identify LHA information)' % line) 2768 return 2769 2770 if key in self.param_card[args[start]].param_dict: 2771 if (args[start], key) in self.restricted_value: 2772 text = "Note that this parameter seems to be ignore by MG.\n" 2773 text += "MG will use instead the expression: %s\n" % \ 2774 self.restricted_value[(args[start], key)] 2775 text += "You need to match this expression for external program (such pythia)." 2776 logger.warning(text) 2777 2778 if args[-1].lower() in ['default', 'auto', 'auto@nlo']: 2779 self.setP(args[start], key, args[-1]) 2780 else: 2781 try: 2782 value = float(args[-1]) 2783 except Exception: 2784 logger.warning('Invalid input: Expected number and not \'%s\'' \ 2785 % args[-1]) 2786 return 2787 self.setP(args[start], key, value) 2788 else: 2789 logger.warning('invalid set command %s' % line) 2790 return 2791 self.param_card.write(pjoin(self.me_dir,'Cards','param_card.dat')) 2792 2793 # PARAM_CARD NO BLOCK NAME --------------------------------------------- 2794 elif args[start] in self.pname2block and card != 'run_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 all_var = self.pname2block[args[start]] 2802 for bname, lhaid in all_var: 2803 new_line = 'param_card %s %s %s' % (bname, 2804 ' '.join([ str(i) for i in lhaid]), ' '.join(args[start+1:])) 2805 self.do_set(new_line) 2806 if len(all_var) > 1: 2807 logger.warning('This variable correspond to more than one parameter in the param_card.') 2808 for bname, lhaid in all_var: 2809 logger.warning(' %s %s' % (bname, ' '.join([str(i) for i in lhaid]))) 2810 logger.warning('all listed variables have been modified') 2811 2812 # MadWeight_card with block name --------------------------------------- 2813 elif self.has_mw and (args[start] in self.mw_card and args[start] != 'comment') \ 2814 and card in ['','MadWeight_card']: 2815 2816 if args[start] in self.conflict and card == '': 2817 text = 'ambiguous name (present in more than one card). Please specify which card to edit' 2818 text += ' in the format < set card parameter value>' 2819 logger.warning(text) 2820 return 2821 2822 block = args[start] 2823 name = args[start+1] 2824 value = args[start+2:] 2825 self.setM(block, name, value) 2826 self.mw_card.write(pjoin(self.me_dir,'Cards','MadWeight_card.dat')) 2827 2828 # MadWeight_card NO Block name ----------------------------------------- 2829 elif self.has_mw and args[start] in self.mw_vars \ 2830 and card in ['', 'MadWeight_card']: 2831 2832 if args[start] in self.conflict and card == '': 2833 text = 'ambiguous name (present in more than one card). Please specify which card to edit' 2834 text += ' in the format < set card parameter value>' 2835 logger.warning(text) 2836 return 2837 2838 block = [b for b, data in self.mw_card.items() if args[start] in data] 2839 if len(block) > 1: 2840 logger.warning('%s is define in more than one block: %s.Please specify.' 2841 % (args[start], ','.join(block))) 2842 return 2843 2844 block = block[0] 2845 name = args[start] 2846 value = args[start+1:] 2847 self.setM(block, name, value) 2848 self.mw_card.write(pjoin(self.me_dir,'Cards','MadWeight_card.dat')) 2849 2850 # MadWeight_card New Block --------------------------------------------- 2851 elif self.has_mw and args[start].startswith('mw_') and len(args[start:]) == 3\ 2852 and card == 'MadWeight_card': 2853 block = args[start] 2854 name = args[start+1] 2855 value = args[start+2] 2856 self.setM(block, name, value) 2857 self.mw_card.write(pjoin(self.me_dir,'Cards','MadWeight_card.dat')) 2858 2859 #### SHOWER CARD 2860 elif self.has_shower and args[start] in [l.lower() for l in \ 2861 self.shower_card.keys()] and card in ['', 'shower_card']: 2862 if args[start] not in self.shower_card: 2863 args[start] = [l for l in self.shower_card if l.lower() == args[start]][0] 2864 2865 if args[start] in self.conflict and card == '': 2866 text = 'ambiguous name (present in more than one card). Please specify which card to edit' 2867 text += ' in the format < set card parameter value>' 2868 logger.warning(text) 2869 return 2870 2871 if args[start+1].lower() == 'default': 2872 default = shower_card_mod.ShowerCard(pjoin(self.me_dir,'Cards','shower_card_default.dat')) 2873 if args[start] in default.keys(): 2874 self.shower_card.set_param(args[start],default[args[start]],pjoin(self.me_dir,'Cards','shower_card.dat')) 2875 else: 2876 logger.info('remove information %s from the shower_card' % args[start]) 2877 del self.shower_card[args[start]] 2878 elif args[start+1].lower() in ['t','.true.','true']: 2879 self.shower_card.set_param(args[start],'.true.',pjoin(self.me_dir,'Cards','shower_card.dat')) 2880 elif args[start+1].lower() in ['f','.false.','false']: 2881 self.shower_card.set_param(args[start],'.false.',pjoin(self.me_dir,'Cards','shower_card.dat')) 2882 else: 2883 args_str = ' '.join(str(a) for a in args[start+1:len(args)]) 2884 self.shower_card.set_param(args[start],args_str,pjoin(self.me_dir,'Cards','shower_card.dat')) 2885 2886 # MadLoop Parameter --------------------------------------------------- 2887 elif self.has_ml and args[start] in self.ml_vars \ 2888 and card in ['', 'MadLoop_card']: 2889 2890 if args[start] in self.conflict and card == '': 2891 text = 'ambiguous name (present in more than one card). Please specify which card to edit' 2892 logger.warning(text) 2893 return 2894 2895 if args[start+1] == 'default': 2896 value = self.MLcardDefault[args[start]] 2897 default = True 2898 else: 2899 value = args[start+1] 2900 default = False 2901 self.setML(args[start], value, default=default) 2902 self.MLcard.write(pjoin(self.me_dir,'Cards','MadLoopParams.dat'), 2903 commentdefault=True) 2904 2905 #INVALID -------------------------------------------------------------- 2906 else: 2907 logger.warning('invalid set command %s ' % line) 2908 return
2909
2910 - def setM(self, block, name, value):
2911 2912 if isinstance(value, list) and len(value) == 1: 2913 value = value[0] 2914 2915 if block not in self.mw_card: 2916 logger.warning('block %s was not present in the current MadWeight card. We are adding it' % block) 2917 self.mw_card[block] = {} 2918 elif name not in self.mw_card[block]: 2919 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') 2920 if value == 'default': 2921 import madgraph.madweight.Cards as mwcards 2922 mw_default = mwcards.Card(pjoin(self.me_dir,'Cards','MadWeight_card_default.dat')) 2923 try: 2924 value = mw_default[block][name] 2925 except KeyError: 2926 logger.info('removing id "%s" from Block "%s" '% (name, block)) 2927 if name in self.mw_card[block]: 2928 del self.mw_card[block][name] 2929 return 2930 if value: 2931 logger.info('modify madweight_card information BLOCK "%s" with id "%s" set to %s' %\ 2932 (block, name, value), '$MG:color:BLACK') 2933 else: 2934 logger.value("Invalid command: No value. To set default value. Use \"default\" as value") 2935 return 2936 2937 self.mw_card[block][name] = value
2938
2939 - def setR(self, name, value):
2940 logger.info('modify parameter %s of the run_card.dat to %s' % (name, value)) 2941 self.run_card.set(name, value, user=True)
2942
2943 - def setML(self, name, value, default=False):
2944 2945 try: 2946 self.MLcard.set(name, value, user=True) 2947 except Exception, error: 2948 logger.warning("Fail to change parameter. Please Retry. Reason: %s." % error) 2949 return 2950 logger.info('modify parameter %s of the MadLoopParam.dat to %s' % (name, value)) 2951 if default and name.lower() in self.MLcard.user_set: 2952 self.MLcard.user_set.remove(name.lower())
2953
2954 - def setP(self, block, lhaid, value):
2955 if isinstance(value, str): 2956 value = value.lower() 2957 if value == 'default': 2958 default = check_param_card.ParamCard(pjoin(self.me_dir,'Cards','param_card_default.dat')) 2959 value = default[block].param_dict[lhaid].value 2960 2961 elif value in ['auto', 'auto@nlo']: 2962 if 'nlo' in value: 2963 value = 'Auto@NLO' 2964 else: 2965 value = 'Auto' 2966 if block != 'decay': 2967 logger.warning('Invalid input: \'Auto\' value only valid for DECAY') 2968 return 2969 else: 2970 try: 2971 value = float(value) 2972 except ValueError: 2973 logger.warning('Invalid input: \'%s\' not valid intput.'% value) 2974 2975 logger.info('modify param_card information BLOCK %s with id %s set to %s' %\ 2976 (block, lhaid, value), '$MG:color:BLACK') 2977 self.param_card[block].param_dict[lhaid].value = value
2978
2979 - def reask(self, *args, **opt):
2980 2981 cmd.OneLinePathCompletion.reask(self,*args, **opt) 2982 if self.has_mw and not os.path.exists(pjoin(self.me_dir,'Cards','transfer_card.dat')): 2983 logger.warning('No transfer function currently define. Please use the change_tf command to define one.')
2984 2985
2986 - def help_set(self):
2987 '''help message for set''' 2988 2989 logger.info('********************* HELP SET ***************************') 2990 logger.info("syntax: set [run_card|param_card] NAME [VALUE|default]") 2991 logger.info("syntax: set [param_card] BLOCK ID(s) [VALUE|default]") 2992 logger.info('') 2993 logger.info('-- Edit the param_card/run_card and replace the value of the') 2994 logger.info(' parameter by the value VALUE.') 2995 logger.info(' ') 2996 logger.info('-- Example:') 2997 logger.info(' set run_card ebeam1 4000') 2998 logger.info(' set ebeam2 4000') 2999 logger.info(' set lpp1 0') 3000 logger.info(' set ptj default') 3001 logger.info('') 3002 logger.info(' set param_card mass 6 175') 3003 logger.info(' set mass 25 125.3') 3004 logger.info(' set mass mh 125') 3005 logger.info(' set mh 125') 3006 logger.info(' set decay 25 0.004') 3007 logger.info(' set decay wh 0.004') 3008 logger.info(' set vmix 2 1 2.326612e-01') 3009 logger.info('') 3010 logger.info(' set param_card default #return all parameter to default') 3011 logger.info(' set run_card default') 3012 logger.info('********************* HELP SET ***************************')
3013 3014
3015 - def default(self, line):
3016 """Default action if line is not recognized""" 3017 3018 line = line.strip() 3019 args = line.split() 3020 if line == '' and self.default_value is not None: 3021 self.value = self.default_value 3022 # check if input is a file 3023 elif hasattr(self, 'do_%s' % args[0]): 3024 self.do_set(' '.join(args[1:])) 3025 elif os.path.exists(line): 3026 self.copy_file(line) 3027 self.value = 'repeat' 3028 elif os.path.exists(pjoin(self.me_dir, line)): 3029 self.copy_file(pjoin(self.me_dir,line)) 3030 self.value = 'repeat' 3031 elif line.strip() != '0' and line.strip() != 'done' and \ 3032 str(line) != 'EOF' and line.strip() in self.allow_arg: 3033 self.open_file(line) 3034 self.value = 'repeat' 3035 else: 3036 self.value = line 3037 3038 return line
3039
3040 - def do_decay(self, line):
3041 """edit the madspin_card to define the decay of the associate particle""" 3042 signal.alarm(0) # avoid timer if any 3043 path = pjoin(self.me_dir,'Cards','madspin_card.dat') 3044 3045 if 'madspin_card.dat' not in self.cards or not os.path.exists(path): 3046 logger.warning("Command decay not valid. Since MadSpin is not available.") 3047 return 3048 3049 if ">" not in line: 3050 logger.warning("invalid command for decay. Line ignored") 3051 return 3052 3053 misc.sprint( line, "-add" in line) 3054 if "-add" in line: 3055 # just to have to add the line to the end of the file 3056 particle = line.split('>')[0].strip() 3057 text = open(path).read() 3058 line = line.replace('--add', '').replace('-add','') 3059 logger.info("change madspin_card to add one decay to %s: %s" %(particle, line.strip()), '$MG:color:BLACK') 3060 3061 text = text.replace('launch', "\ndecay %s\nlaunch\n" % line,1) 3062 open(path,'w').write(text) 3063 else: 3064 # Here we have to remove all the previous definition of the decay 3065 #first find the particle 3066 particle = line.split('>')[0].strip() 3067 logger.info("change madspin_card to define the decay of %s: %s" %(particle, line.strip()), '$MG:color:BLACK') 3068 particle = particle.replace('+','\+').replace('-','\-') 3069 decay_pattern = re.compile(r"^\s*decay\s+%s\s*>[\s\w+-~]*?$" % particle, re.I+re.M) 3070 text= open(path).read() 3071 text = decay_pattern.sub('', text) 3072 text = text.replace('launch', "\ndecay %s\nlaunch\n" % line,1) 3073 open(path,'w').write(text)
3074 3075 3076
3077 - def do_compute_widths(self, line):
3078 signal.alarm(0) # avoid timer if any 3079 path = pjoin(self.me_dir,'Cards','param_card.dat') 3080 pattern = re.compile(r'''decay\s+(\+?\-?\d+)\s+auto(@NLO|)''',re.I) 3081 text = open(path).read() 3082 pdg_info = pattern.findall(text) 3083 has_nlo = any("@nlo"==nlo.lower() for _, nlo in pdg_info) 3084 pdg = [p for p,_ in pdg_info] 3085 3086 3087 line = '%s %s' % (line, ' '.join(pdg)) 3088 if not '--path' in line: 3089 line += ' --path=%s' % path 3090 if has_nlo: 3091 line += ' --nlo' 3092 3093 try: 3094 return self.mother_interface.do_compute_widths(line) 3095 except InvalidCmd, error: 3096 logger.error("Invalid command: %s " % error)
3097
3098 - def help_compute_widths(self):
3099 signal.alarm(0) # avoid timer if any 3100 return self.mother_interface.help_compute_widths()
3101
3102 - def help_decay(self):
3103 """help for command decay which modifies MadSpin_card""" 3104 3105 signal.alarm(0) # avoid timer if any 3106 print '--syntax: decay PROC [--add]' 3107 print ' ' 3108 print ' modify the madspin_card to modify the decay of the associate particle.' 3109 print ' and define it to PROC.' 3110 print ' if --add is present, just add a new decay for the associate particle.'
3111
3112 - def complete_compute_widths(self, *args, **opts):
3113 signal.alarm(0) # avoid timer if any 3114 return self.mother_interface.complete_compute_widths(*args,**opts)
3115 3116
3117 - def help_asperge(self):
3118 """Help associated to the asperge command""" 3119 signal.alarm(0) 3120 3121 print '-- syntax: asperge [options]' 3122 print ' Call ASperGe to diagonalize all mass matrices in the model.' 3123 print ' This works only if the ASperGE module is part of the UFO model (a subdirectory).' 3124 print ' If you specify some names after the command (i.e. asperge m1 m2) then ASperGe will only' 3125 print ' diagonalize the associate mass matrices (here m1 and m2).'
3126
3127 - def complete_asperge(self, text, line, begidx, endidx):
3128 signal.alarm(0) # avoid timer if any 3129 3130 blockname = self.pname2block.keys() 3131 # remove those that we know for sure are not mixing 3132 wrong = ['decay', 'mass', 'sminput'] 3133 valid = [k for k in blockname if 'mix' in k] 3134 potential = [k for k in blockname if k not in valid+wrong] 3135 output = {'Mixing matrices': self.list_completion(text, valid, line), 3136 'Other potential valid input': self.list_completion(text, potential, line)} 3137 3138 return self.deal_multiple_categories(output)
3139 3140
3141 - def do_asperge(self, line):
3142 """Running ASperGe""" 3143 signal.alarm(0) # avoid timer if any 3144 3145 path = pjoin(self.me_dir,'bin','internal','ufomodel','ASperGE') 3146 if not os.path.exists(path): 3147 logger.error('ASperge has not been detected in the current model, therefore it will not be run.') 3148 return 3149 elif not os.path.exists(pjoin(path,'ASperGe')): 3150 logger.info('ASperGe has been detected but is not compiled. Running the compilation now.') 3151 try: 3152 misc.compile(cwd=path,shell=True) 3153 except MadGraph5Error, error: 3154 logger.error('''ASperGe failed to compile. Note that gsl is needed 3155 for this compilation to go trough. More information on how to install this package on 3156 http://www.gnu.org/software/gsl/ 3157 Full compilation log is available at %s''' % pjoin(self.me_dir, 'ASperge_compilation.log')) 3158 open(pjoin(self.me_dir, 'ASperge_compilation.log'),'w').write(str(error)) 3159 return 3160 3161 opts = line.split() 3162 card = pjoin(self.me_dir,'Cards', 'param_card.dat') 3163 logger.info('running ASperGE') 3164 returncode = misc.call([pjoin(path,'ASperGe'), card, '%s.new' % card] + opts) 3165 if returncode: 3166 logger.error('ASperGE fails with status %s' % returncode) 3167 else: 3168 logger.info('AsPerGe creates the file succesfully') 3169 files.mv(card, '%s.beforeasperge' % card) 3170 files.mv('%s.new' % card, card)
3171 3172 3173
3174 - def copy_file(self, path):
3175 """detect the type of the file and overwritte the current file""" 3176 3177 if path.endswith('.lhco'): 3178 #logger.info('copy %s as Events/input.lhco' % (path)) 3179 #files.cp(path, pjoin(self.mother_interface.me_dir, 'Events', 'input.lhco' )) 3180 self.do_set('mw_run inputfile %s' % os.path.relpath(path, self.mother_interface.me_dir)) 3181 return 3182 elif path.endswith('.lhco.gz'): 3183 #logger.info('copy %s as Events/input.lhco.gz' % (path)) 3184 #files.cp(path, pjoin(self.mother_interface.me_dir, 'Events', 'input.lhco.gz' )) 3185 self.do_set('mw_run inputfile %s' % os.path.relpath(path, self.mother_interface.me_dir)) 3186 return 3187 else: 3188 card_name = CommonRunCmd.detect_card_type(path) 3189 3190 if card_name == 'unknown': 3191 logger.warning('Fail to determine the type of the file. Not copied') 3192 if card_name != 'banner': 3193 logger.info('copy %s as %s' % (path, card_name)) 3194 files.cp(path, pjoin(self.mother_interface.me_dir, 'Cards', card_name)) 3195 elif card_name == 'banner': 3196 banner_mod.split_banner(path, self.mother_interface.me_dir, proc_card=False) 3197 logger.info('Splitting the banner in it\'s component') 3198 if not self.mode == 'auto': 3199 self.mother_interface.keep_cards(self.cards)
3200
3201 - def open_file(self, answer):
3202 """open the file""" 3203 me_dir = self.mother_interface.me_dir 3204 if answer.isdigit(): 3205 if answer == '9': 3206 answer = 'plot' 3207 else: 3208 answer = self.cards[int(answer)-1] 3209 if 'madweight' in answer: 3210 answer = answer.replace('madweight', 'MadWeight') 3211 3212 if 'MadLoopParams' in answer: 3213 answer = pjoin(me_dir,'Cards','MadLoopParams.dat') 3214 if not '.dat' in answer and not '.lhco' in answer: 3215 if answer != 'trigger': 3216 path = pjoin(me_dir,'Cards','%s_card.dat' % answer) 3217 else: 3218 path = pjoin(me_dir,'Cards','delphes_trigger.dat') 3219 elif not '.lhco' in answer: 3220 path = pjoin(me_dir, 'Cards', answer) 3221 else: 3222 path = pjoin(me_dir, self.mw_card['mw_run']['inputfile']) 3223 if not os.path.exists(path): 3224 logger.info('Path in MW_card not existing') 3225 path = pjoin(me_dir, 'Events', answer) 3226 #security 3227 path = path.replace('_card_card','_card') 3228 try: 3229 self.mother_interface.exec_cmd('open %s' % path) 3230 except InvalidCmd, error: 3231 if str(error) != 'No default path for this file': 3232 raise 3233 if answer == 'transfer_card.dat': 3234 logger.warning('You have to specify a transfer function first!') 3235 elif answer == 'input.lhco': 3236 path = pjoin(me_dir,'Events', 'input.lhco') 3237 ff = open(path,'w') 3238 ff.write('''No LHCO information imported at current time. 3239 To import a lhco file: Close this file and type the path of your file. 3240 You can also copy/paste, your event file here.''') 3241 ff.close() 3242 self.open_file(path) 3243 else: 3244 raise 3245 3246 # reload object to have it in sync 3247 if path == pjoin(self.me_dir,'Cards','param_card.dat'): 3248 try: 3249 self.param_card = check_param_card.ParamCard(path) 3250 except (check_param_card.InvalidParamCard, ValueError) as e: 3251 logger.error('Current param_card is not valid. We are going to use the default one.') 3252 logger.error('problem detected: %s' % e) 3253 logger.error('Please re-open the file and fix the problem.') 3254 logger.warning('using the \'set\' command without opening the file will discard all your manual change') 3255 elif path == pjoin(self.me_dir,'Cards','run_card.dat'): 3256 self.run_card = banner_mod.RunCard(pjoin(self.me_dir,'Cards','run_card.dat')) 3257 elif path == pjoin(self.me_dir,'Cards','MadLoopParams.dat'): 3258 self.MLcard = banner_mod.MadLoopParam(pjoin(self.me_dir,'Cards','MadLoopParams.dat')) 3259 elif path == pjoin(self.me_dir,'Cards','MadWeight_card.dat'): 3260 try: 3261 import madgraph.madweight.Cards as mwcards 3262 except: 3263 import internal.madweight.Cards as mwcards 3264 self.mw_card = mwcards.Card(pjoin(self.me_dir,'Cards','MadWeight_card.dat'))
3265