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