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