Package madgraph :: Package interface :: Module amcatnlo_interface
[hide private]
[frames] | no frames]

Source Code for Module madgraph.interface.amcatnlo_interface

  1  ################################################################################ 
  2  # 
  3  # Copyright (c) 2009 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 all MadGraph5_aMC@NLO features. 
 16     Uses the cmd package for command interpretation and tab completion. 
 17  """ 
 18   
 19  import os 
 20  import logging 
 21  import pydoc 
 22  import sys 
 23  import time 
 24  import optparse 
 25  import subprocess 
 26  import shutil 
 27  import multiprocessing 
 28  import signal 
 29  import tempfile 
 30  import itertools 
 31  import os 
 32  import cPickle 
 33   
 34   
 35  import madgraph 
 36  from madgraph import MG4DIR, MG5DIR, MadGraph5Error 
 37  import madgraph.interface.extended_cmd as cmd 
 38  import madgraph.interface.madgraph_interface as mg_interface 
 39  import madgraph.interface.madevent_interface as me_interface 
 40  import madgraph.interface.extended_cmd as extended_cmd 
 41  import madgraph.interface.amcatnlo_run_interface as run_interface 
 42  import madgraph.interface.launch_ext_program as launch_ext 
 43  import madgraph.interface.loop_interface as Loop_interface 
 44  import madgraph.fks.fks_base as fks_base 
 45  import madgraph.fks.fks_helas_objects as fks_helas 
 46  import madgraph.iolibs.export_fks as export_fks 
 47  import madgraph.iolibs.export_v4 as export_v4 
 48  import madgraph.loop.loop_base_objects as loop_base_objects 
 49  import madgraph.core.diagram_generation as diagram_generation 
 50  import madgraph.core.helas_objects as helas_objects 
 51  import madgraph.various.cluster as cluster 
 52  import madgraph.various.misc as misc 
 53  import madgraph.various.banner as banner_mod 
 54   
 55  #usefull shortcut 
 56  pjoin = os.path.join 
 57   
 58   
 59  logger = logging.getLogger('cmdprint') # -> stdout 
 60  logger_stderr = logging.getLogger('fatalerror') # ->stderr 
 61   
 62  # a new function for the improved NLO generation 
 63  glob_directories_map = [] 
64 -def generate_directories_fks_async(i):
65 66 arglist = glob_directories_map[i] 67 68 curr_exporter = arglist[0] 69 mefile = arglist[1] 70 curr_fortran_model = arglist[2] 71 ime = arglist[3] 72 nme = arglist[4] 73 path = arglist[5] 74 olpopts = arglist[6] 75 76 infile = open(mefile,'rb') 77 me = cPickle.load(infile) 78 infile.close() 79 80 calls = curr_exporter.generate_directories_fks(me, curr_fortran_model, ime, nme, path, olpopts) 81 nexternal = curr_exporter.proc_characteristic['nexternal'] 82 ninitial = curr_exporter.proc_characteristic['ninitial'] 83 processes = me.born_matrix_element.get('processes') 84 85 #only available after export has been done, so has to be returned from here 86 max_loop_vertex_rank = -99 87 if me.virt_matrix_element: 88 max_loop_vertex_rank = me.virt_matrix_element.get_max_loop_vertex_rank() 89 90 return [calls, curr_exporter.fksdirs, max_loop_vertex_rank, ninitial, nexternal, processes]
91 92
93 -class CheckFKS(mg_interface.CheckValidForCmd):
94 95
96 - def check_display(self, args):
97 """ Check the arguments of the display diagrams command in the context 98 of the Loop interface.""" 99 100 mg_interface.MadGraphCmd.check_display(self,args) 101 102 if args[0] in ['diagrams', 'processes'] and len(args)>=3 \ 103 and args[1] not in ['born','loop','virt','real']: 104 raise self.InvalidCmd("Can only display born, loop (virt) or real diagrams, not %s."%args[1]) 105 # rename args[1] if it is 'virt' 106 if len(args) > 1: 107 if args[1] == 'virt': 108 args[1] = 'loop'
109
110 - def check_add(self, args):
111 112 super(CheckFKS, self).check_add(args) 113 if '$' in args: 114 raise self.InvalidCmd('$ syntax not valid for aMC@NLO. $$ syntax is on the other hand a valid syntax.')
115
116 - def check_tutorial(self, args):
117 """check the validity of the line""" 118 if len(args) == 0: 119 #this means mg5 tutorial 120 args.append('aMCatNLO') 121 else: 122 return mg_interface.CheckValidForCmd.check_tutorial(self,args)
123
124 - def check_output(self, args):
125 """ check the validity of the line""" 126 127 self._export_format = 'NLO' 128 forbidden_formats = ['madevent', 'standalone'] 129 130 131 if not hasattr(self, '_fks_multi_proc') or not self._fks_multi_proc: 132 text = 'No processes generated. Please generate a process first.' 133 raise self.InvalidCmd(text) 134 135 if not self._curr_model: 136 text = 'No model found. Please import a model first and then retry.' 137 raise self.InvalidCmd(text) 138 139 if args and args[0][0] != '-': 140 if args[0] in forbidden_formats: 141 text = 'You generated a NLO process, which cannot be exported in %s mode.\n' % args[0] 142 text+= 'Please use the command "output DIR_NAME".\n' 143 raise self.InvalidCmd(text) 144 145 # This is a path 146 path = args.pop(0) 147 # Check for special directory treatment 148 if path == 'auto': 149 self.get_default_path() 150 elif path != 'auto': 151 self._export_dir = path 152 else: 153 # No valid path 154 self.get_default_path() 155 156 self._export_dir = os.path.realpath(self._export_dir)
157 158
159 - def check_launch(self, args, options):
160 """check the validity of the line. args are DIR and MODE 161 MODE being LO, NLO, aMC@NLO or aMC@LO. If no mode is passed, aMC@NLO is used""" 162 # modify args in order to be DIR 163 # mode being either standalone or madevent 164 165 if not args: 166 if self._done_export: 167 args.append(self._done_export[0]) 168 args.append('auto') 169 170 return 171 else: 172 self.help_launch() 173 raise self.InvalidCmd, \ 174 'No default location available, please specify location.' 175 176 if len(args) > 2: 177 self.help_launch() 178 return self.InvalidCmd, 'Invalid Syntax: Too many argument' 179 180 elif len(args) == 2: 181 if not args[1] in ['LO', 'NLO', 'aMC@NLO', 'aMC@LO', 'auto']: 182 raise self.InvalidCmd, '%s is not a valid mode, please use "LO", "NLO", "aMC@NLO" or "aMC@LO"' % args[1] 183 else: 184 #check if args[0] is path or mode 185 if args[0] in ['LO', 'NLO', 'aMC@NLO', 'aMC@LO', 'auto'] and self._done_export: 186 args.insert(0, self._done_export[0]) 187 elif os.path.isdir(args[0]) or os.path.isdir(pjoin(MG5DIR, args[0]))\ 188 or os.path.isdir(pjoin(MG4DIR, args[0])): 189 args.append('auto') 190 else: 191 self.help_launch() 192 raise self.InvalidCmd, '%s is not a valid process directory nor run mode' % args[0] 193 194 mode = args[1] 195 196 # search for a valid path 197 if os.path.isdir(args[0]): 198 path = os.path.realpath(args[0]) 199 elif os.path.isdir(pjoin(MG5DIR,args[0])): 200 path = pjoin(MG5DIR,args[0]) 201 elif MG4DIR and os.path.isdir(pjoin(MG4DIR,args[0])): 202 path = pjoin(MG4DIR,args[0]) 203 else: 204 raise self.InvalidCmd, '%s is not a valid directory' % args[0] 205 args[0] = path 206 207 # inform where we are for future command 208 self._done_export = [path, mode] 209 210 # check for incompatible options/modes 211 if options['multicore'] and options['cluster']: 212 raise self.InvalidCmd, 'options -m (--multicore) and -c (--cluster)' + \ 213 ' are not compatible. Please choose one.' 214 if mode == 'NLO' and options['reweightonly']: 215 raise self.InvalidCmd, 'option -r (--reweightonly) needs mode "aMC@NLO" or "aMC@LO"'
216 217
218 -class CheckFKSWeb(mg_interface.CheckValidForCmdWeb, CheckFKS):
219 pass
220
221 -class CompleteFKS(mg_interface.CompleteForCmd):
222
223 - def complete_display(self, text, line, begidx, endidx):
224 """Complete the display command in the context of the FKS interface""" 225 226 args = self.split_arg(line[0:begidx]) 227 228 if len(args) == 2 and args[1] in ['diagrams', 'processes']: 229 return self.list_completion(text, ['born', 'loop', 'virt', 'real']) 230 else: 231 return mg_interface.MadGraphCmd.complete_display(self, text, line, 232 begidx, endidx)
233 234
235 - def complete_output(self, text, line, begidx, endidx):
236 """Complete the output command in the context of the FKS interface""" 237 #don't propose directory use by MG_ME 238 forbidden_names = ['MadGraphII', 'Template', 'pythia-pgs', 'CVS', 239 'Calculators', 'MadAnalysis', 'SimpleAnalysis', 240 'mg5', 'DECAY', 'EventConverter', 'Models', 241 'ExRootAnalysis', 'HELAS', 'Transfer_Fct', 'aloha', 242 'madgraph', 'bin', 'tests', 'input', 'vendor', 'models'] 243 244 #name of the run =>proposes old run name 245 args = self.split_arg(line[0:begidx]) 246 if len(args) >= 1: 247 if len(args) > 1 and args[1] == 'aloha': 248 try: 249 return self.aloha_complete_output(text, line, begidx, endidx) 250 except Exception, error: 251 print error 252 # Directory continuation 253 if args[-1].endswith(os.path.sep): 254 return [name for name in self.path_completion(text, 255 pjoin(*[a for a in args if a.endswith(os.path.sep)]), 256 only_dirs = True) if name not in forbidden_names] 257 258 # directory names 259 content = [name for name in self.path_completion(text, '.', only_dirs = True) \ 260 if name not in forbidden_names] 261 return self.list_completion(text, content)
262 263
264 - def complete_launch(self, text, line, begidx, endidx):
265 """ complete the launch command""" 266 args = self.split_arg(line[0:begidx]) 267 268 # Directory continuation 269 if args[-1].endswith(os.path.sep): 270 return self.path_completion(text, 271 pjoin(*[a for a in args if a.endswith(os.path.sep)]), 272 only_dirs = True) 273 # Format 274 if len(args) == 1: 275 out = {'Path from ./': self.path_completion(text, '.', only_dirs = True)} 276 if MG5DIR != os.path.realpath('.'): 277 out['Path from %s' % MG5DIR] = self.path_completion(text, 278 MG5DIR, only_dirs = True, relative=False) 279 if MG4DIR and MG4DIR != os.path.realpath('.') and MG4DIR != MG5DIR: 280 out['Path from %s' % MG4DIR] = self.path_completion(text, 281 MG4DIR, only_dirs = True, relative=False) 282 283 if len(args) == 2: 284 modes = ['aMC@NLO', 'NLO', 'aMC@LO', 'LO'] 285 return self.list_completion(text, modes, line) 286 287 #option 288 if len(args) >= 3: 289 out={} 290 291 if line[0:begidx].endswith('--laststep='): 292 opt = ['parton', 'pythia', 'pgs','delphes','auto'] 293 out['Options'] = self.list_completion(text, opt, line) 294 else: 295 296 opt = ['-f', '-c', '-m', '-i', '-x', '-r', '-p', '-o', '-n', 'a', 297 '--force', '--cluster', '--multicore', '--interactive', 298 '--nocompile', '--reweightonly', '--parton', '--only_generation', '--name', '--appl_start_grid'] 299 out['Options'] = self.list_completion(text, opt, line) 300 301 302 return self.deal_multiple_categories(out)
303
304 -class HelpFKS(mg_interface.HelpToCmd):
305
306 - def help_display(self):
307 mg_interface.MadGraphCmd.help_display(self) 308 logger.info(" In aMC@NLO5, after display diagrams, the user can add the option") 309 logger.info(" \"born\", \"virt\" or \"real\" to display only the corresponding diagrams.")
310
311 - def help_launch(self):
312 """help for launch command""" 313 _launch_parser.print_help()
314
315 -class aMCatNLOInterface(CheckFKS, CompleteFKS, HelpFKS, Loop_interface.CommonLoopInterface):
316 317 _fks_display_opts = ['real_diagrams', 'born_diagrams', 'virt_diagrams', 318 'real_processes', 'born_processes', 'virt_processes'] 319 320 _nlo_modes_for_completion = ['all','real'] 321
322 - def __init__(self, mgme_dir = '', *completekey, **stdin):
323 """ Special init tasks for the Loop Interface """ 324 325 mg_interface.MadGraphCmd.__init__(self, mgme_dir = '', *completekey, **stdin) 326 misc.sprint(type(self.history)) 327 self.setup()
328
329 - def setup(self):
330 """ Special tasks when switching to this interface """ 331 332 # Refresh all the interface stored value as things like generated 333 # processes and amplitudes are not to be reused in between different 334 # interfaces 335 # Clear history, amplitudes and matrix elements when a model is imported 336 # Remove previous imports, generations and outputs from history 337 self.history.clean(remove_bef_last='import', 338 to_keep=['set','load','import', 'define']) 339 # Reset amplitudes and matrix elements 340 self._done_export=False 341 self._curr_amps = diagram_generation.AmplitudeList() 342 self._curr_matrix_elements = helas_objects.HelasMultiProcess() 343 self._v4_export_formats = [] 344 self._nlo_modes_for_completion = ['all','real'] 345 self._export_formats = [ 'madevent', 'aloha' ] 346 # Do not force NLO model as the user might have asked for reals only. 347 # It will anyway be forced later if he attempts virt= or all=. 348 self.validate_model(loop_type='real_init', stop=False) 349 # Set where to look for CutTools installation. 350 # In further versions, it will be set in the same manner as _mgme_dir so that 351 # the user can chose its own CutTools distribution. 352 self._cuttools_dir=str(pjoin(self._mgme_dir,'vendor','CutTools')) 353 if not os.path.isdir(pjoin(self._cuttools_dir, 'src','cts')): 354 logger.warning(('Warning: Directory %s is not a valid CutTools directory.'+\ 355 'Using default CutTools instead.') % \ 356 self._cuttools_dir) 357 self._cuttools_dir=str(pjoin(self._mgme_dir,'vendor','CutTools')) 358 # Set where to look for IREGI installation 359 self._iregi_dir=str(os.path.join(self._mgme_dir,'vendor','IREGI','src')) 360 if not os.path.isdir(self._iregi_dir): 361 logger.warning(('Warning: Directory %s is not a valid IREGI directory.'+\ 362 'Using default IREGI instead.')%\ 363 self._iregi_dir) 364 self._iregi_dir=str(os.path.join(self._mgme_dir,'vendor','IREGI','src'))
365
366 - def do_display(self, line, output=sys.stdout):
367 # if we arrive here it means that a _fks_display_opts has been chosen 368 args = self.split_arg(line) 369 #check the validity of the arguments 370 self.check_display(args) 371 372 if args[0] in ['diagrams', 'processes', 'diagrams_text']: 373 get_amps_dict = {'real': self._fks_multi_proc.get_real_amplitudes, 374 'born': self._fks_multi_proc.get_born_amplitudes, 375 'loop': self._fks_multi_proc.get_virt_amplitudes} 376 if args[0] == 'diagrams': 377 if len(args)>=2 and args[1] in get_amps_dict.keys(): 378 get_amps = get_amps_dict[args[1]] 379 self._curr_amps = get_amps() 380 #check that if one requests the virt diagrams, there are virt_amplitudes 381 if args[1] == 'loop' and len(self._curr_amps) == 0: 382 raise self.InvalidCmd('No virtuals have been generated') 383 self.draw(' '.join(args[2:]),type = args[1]) 384 else: 385 for diag_type, get_amps in get_amps_dict.items(): 386 self._curr_amps = get_amps() 387 self.draw(' '.join(args[1:]), type=diag_type) 388 # set _curr_amps back to empty 389 self._curr_amps = diagram_generation.AmplitudeList() 390 391 if args[0] == 'diagrams_text': 392 if len(args)>=2 and args[1] in get_amps_dict.keys(): 393 get_amps = get_amps_dict[args[1]] 394 self._curr_amps = get_amps() 395 #check that if one requests the virt diagrams, there are virt_amplitudes 396 if args[1] in ['virt', 'loop'] and len(self._curr_amps) == 0: 397 raise self.InvalidCmd('No virtuals have been generated') 398 text = "\n".join([amp.nice_string() for amp in self._curr_amps]) 399 else: 400 text = 'Born diagrams:\n' 401 text += '\n'.join(amp.nice_string() for amp in get_amps_dict['born']()) 402 text += '\n\nReal diagrams:' 403 text += '\n'.join(amp.nice_string() for amp in get_amps_dict['real']()) 404 text += '\n\nLoop diagrams:\n' 405 text += '\n'.join(amp.nice_string() for amp in get_amps_dict['virt']()) 406 pydoc.pager(text) 407 408 # set _curr_amps back to empty 409 self._curr_amps = diagram_generation.AmplitudeList() 410 411 elif args[0] == 'processes': 412 if len(args)>=2 and args[1] in get_amps_dict.keys(): 413 get_amps = get_amps_dict[args[1]] 414 self._curr_amps = get_amps() 415 #check that if one requests the virt diagrams, there are virt_amplitudes 416 if args[1] in ['virt', 'loop'] and len(self._curr_amps) == 0: 417 raise self.InvalidCmd('No virtuals have been generated') 418 print '\n'.join(amp.nice_string_processes() for amp in self._curr_amps) 419 else: 420 print 'Born processes:' 421 print '\n'.join(amp.nice_string_processes() for amp in get_amps_dict['born']()) 422 print 'Real processes:' 423 print '\n'.join(amp.nice_string_processes() for amp in get_amps_dict['real']()) 424 print 'Loop processes:' 425 print '\n'.join(amp.nice_string_processes() for amp in get_amps_dict['loop']()) 426 # set _curr_amps back to empty 427 self._curr_amps = diagram_generation.AmplitudeList() 428 429 else: 430 mg_interface.MadGraphCmd.do_display(self,line,output)
431
432 - def do_add(self, line, *args,**opt):
433 434 args = self.split_arg(line) 435 # Check the validity of the arguments 436 self.check_add(args) 437 438 if args[0] == 'model': 439 return self.add_model(args[1:]) 440 elif args[0] != 'process': 441 raise self.InvalidCmd("The add command can only be used with process or model") 442 else: 443 line = ' '.join(args[1:]) 444 445 proc_type=self.extract_process_type(line) 446 if proc_type[1] not in ['real', 'LOonly']: 447 run_interface.check_compiler(self.options, block=False) 448 self.validate_model(proc_type[1], coupling_type=proc_type[2]) 449 450 #now generate the amplitudes as usual 451 #self.options['group_subprocesses'] = 'False' 452 collect_mirror_procs = False 453 ignore_six_quark_processes = self.options['ignore_six_quark_processes'] 454 if ',' in line: 455 myprocdef, line = mg_interface.MadGraphCmd.extract_decay_chain_process(self,line) 456 if myprocdef.are_decays_perturbed(): 457 raise MadGraph5Error("Decay processes cannot be perturbed") 458 else: 459 myprocdef = mg_interface.MadGraphCmd.extract_process(self,line) 460 461 self.proc_validity(myprocdef,'aMCatNLO_%s'%proc_type[1]) 462 463 # if myprocdef['perturbation_couplings']!=['QCD']: 464 # message = ""FKS for reals only available in QCD for now, you asked %s" \ 465 # % ', '.join(myprocdef['perturbation_couplings'])" 466 # logger.info("%s. Checking for loop induced") 467 # new_line = ln 468 # 469 # 470 # raise self.InvalidCmd("FKS for reals only available in QCD for now, you asked %s" \ 471 # % ', '.join(myprocdef['perturbation_couplings'])) 472 ## 473 474 # if the new nlo process generation mode is enabled, the number of cores to be 475 # used has to be passed 476 # ncores_for_proc_gen has the following meaning 477 # 0 : do things the old way 478 # > 0 use ncores_for_proc_gen 479 # -1 : use all cores 480 if self.options['low_mem_multicore_nlo_generation']: 481 if self.options['nb_core']: 482 self.ncores_for_proc_gen = int(self.options['nb_core']) 483 else: 484 self.ncores_for_proc_gen = -1 485 else: 486 self.ncores_for_proc_gen = 0 487 488 # this is the options dictionary to pass to the FKSMultiProcess 489 fks_options = {'OLP': self.options['OLP'], 490 'ignore_six_quark_processes': self.options['ignore_six_quark_processes'], 491 'ncores_for_proc_gen': self.ncores_for_proc_gen} 492 try: 493 self._fks_multi_proc.add(fks_base.FKSMultiProcess(myprocdef,fks_options)) 494 except AttributeError: 495 self._fks_multi_proc = fks_base.FKSMultiProcess(myprocdef,fks_options)
496 497
498 - def do_output(self, line):
499 """Main commands: Initialize a new Template or reinitialize one""" 500 501 args = self.split_arg(line) 502 # Check Argument validity 503 self.check_output(args) 504 505 noclean = '-noclean' in args 506 force = '-f' in args 507 nojpeg = '-nojpeg' in args 508 main_file_name = "" 509 try: 510 main_file_name = args[args.index('-name') + 1] 511 except Exception: 512 pass 513 514 # For NLO, the group_subprocesses is automatically set to false 515 group_processes = False 516 # initialize the writer 517 if self._export_format in ['NLO']: 518 self._curr_exporter = export_v4.ExportV4Factory(self, noclean, 519 output_type='amcatnlo',group_subprocesses=group_processes) 520 521 # check if a dir with the same name already exists 522 if not force and not noclean and os.path.isdir(self._export_dir)\ 523 and self._export_format in ['NLO']: 524 # Don't ask if user already specified force or noclean 525 logger.info('INFO: directory %s already exists.' % self._export_dir) 526 logger.info('If you continue this directory will be deleted and replaced.') 527 answer = self.ask('Do you want to continue?', 'y', ['y','n'], 528 timeout=self.options['timeout']) 529 if answer != 'y': 530 raise self.InvalidCmd('Stopped by user request') 531 532 # if one gets here either used -f or answered yes to the question about 533 # removing the dir 534 if os.path.exists(self._export_dir): 535 shutil.rmtree(self._export_dir) 536 537 # Make a Template Copy 538 if self._export_format in ['NLO']: 539 self._curr_exporter.copy_fkstemplate() 540 541 # Reset _done_export, since we have new directory 542 self._done_export = False 543 544 # Perform export and finalize right away 545 self.export(nojpeg, main_file_name, group_processes=group_processes) 546 547 # Automatically run finalize 548 self.finalize(nojpeg) 549 550 # Generate the virtuals if from OLP 551 if self.options['OLP']!='MadLoop': 552 self._curr_exporter.generate_virtuals_from_OLP( 553 self.born_processes_for_olp,self._export_dir,self.options['OLP']) 554 555 # Remember that we have done export 556 self._done_export = (self._export_dir, self._export_format) 557 558 # Reset _export_dir, so we don't overwrite by mistake later 559 self._export_dir = None
560 561 # Export a matrix element
562 - def export(self, nojpeg = False, main_file_name = "", group_processes=False):
563 """Export a generated amplitude to file""" 564 565 def generate_matrix_elements(self, group=False): 566 """Helper function to generate the matrix elements before 567 exporting""" 568 569 # Sort amplitudes according to number of diagrams, 570 # to get most efficient multichannel output 571 self._curr_amps.sort(lambda a1, a2: a2.get_number_of_diagrams() - \ 572 a1.get_number_of_diagrams()) 573 574 cpu_time1 = time.time() 575 ndiags = 0 576 if not self._curr_matrix_elements.get_matrix_elements(): 577 if group: 578 raise MadGraph5Error, "Cannot group subprocesses when "+\ 579 "exporting to NLO" 580 else: 581 self._curr_matrix_elements = \ 582 fks_helas.FKSHelasMultiProcess(\ 583 self._fks_multi_proc, 584 loop_optimized= self.options['loop_optimized_output']) 585 586 if not self.options['low_mem_multicore_nlo_generation']: 587 # generate the code the old way 588 ndiags = sum([len(me.get('diagrams')) for \ 589 me in self._curr_matrix_elements.\ 590 get_matrix_elements()]) 591 # assign a unique id number to all process and 592 # generate a list of possible PDF combinations 593 uid = 0 594 initial_states=[] 595 for me in self._curr_matrix_elements.get_matrix_elements(): 596 uid += 1 # update the identification number 597 me.get('processes')[0].set('uid', uid) 598 try: 599 initial_states.append(sorted(list(set((p.get_initial_pdg(1),p.get_initial_pdg(2)) for \ 600 p in me.born_matrix_element.get('processes'))))) 601 except IndexError: 602 initial_states.append(sorted(list(set((p.get_initial_pdg(1)) for \ 603 p in me.born_matrix_element.get('processes'))))) 604 605 for fksreal in me.real_processes: 606 # Pick out all initial state particles for the two beams 607 try: 608 initial_states.append(sorted(list(set((p.get_initial_pdg(1),p.get_initial_pdg(2)) for \ 609 p in fksreal.matrix_element.get('processes'))))) 610 except IndexError: 611 initial_states.append(sorted(list(set((p.get_initial_pdg(1)) for \ 612 p in fksreal.matrix_element.get('processes'))))) 613 614 615 # remove doubles from the list 616 checked = [] 617 for e in initial_states: 618 if e not in checked: 619 checked.append(e) 620 initial_states=checked 621 622 self._curr_matrix_elements.set('initial_states',initial_states) 623 624 else: 625 #new NLO generation 626 if self._curr_matrix_elements['has_loops']: 627 self._curr_exporter.opt['mp'] = True 628 self._curr_exporter.model = self._curr_model 629 ndiags = 0 630 631 cpu_time2 = time.time() 632 return ndiags, cpu_time2 - cpu_time1
633 634 # Start of the actual routine 635 636 ndiags, cpu_time = generate_matrix_elements(self, group=group_processes) 637 calls = 0 638 639 path = self._export_dir 640 641 if self._export_format in ['NLO']: 642 path = os.path.join(path, 'SubProcesses') 643 644 #_curr_matrix_element is a FKSHelasMultiProcess Object 645 self._fks_directories = [] 646 proc_charac = self._curr_exporter.proc_characteristic 647 for charac in ['has_isr', 'has_fsr', 'has_loops']: 648 proc_charac[charac] = self._curr_matrix_elements[charac] 649 650 # prepare for the generation 651 # glob_directories_map is for the new NLO generation 652 global glob_directories_map 653 glob_directories_map = [] 654 655 self.born_processes_for_olp = [] 656 for ime, me in \ 657 enumerate(self._curr_matrix_elements.get('matrix_elements')): 658 if not self.options['low_mem_multicore_nlo_generation']: 659 #me is a FKSHelasProcessFromReals 660 calls = calls + \ 661 self._curr_exporter.generate_directories_fks(me, 662 self._curr_fortran_model, 663 ime, len(self._curr_matrix_elements.get('matrix_elements')), 664 path,self.options['OLP']) 665 self._fks_directories.extend(self._curr_exporter.fksdirs) 666 self.born_processes_for_olp.append(me.born_matrix_element.get('processes')[0]) 667 else: 668 glob_directories_map.append(\ 669 [self._curr_exporter, me, self._curr_fortran_model, 670 ime, len(self._curr_matrix_elements.get('matrix_elements')), 671 path, self.options['OLP']]) 672 673 if self.options['low_mem_multicore_nlo_generation']: 674 # start the pool instance with a signal instance to catch ctr+c 675 logger.info('Writing directories...') 676 original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN) 677 if self.ncores_for_proc_gen < 0: # use all cores 678 pool = multiprocessing.Pool(maxtasksperchild=1) 679 else: 680 pool = multiprocessing.Pool(processes=self.ncores_for_proc_gen,maxtasksperchild=1) 681 signal.signal(signal.SIGINT, original_sigint_handler) 682 try: 683 # the very large timeout passed to get is to be able to catch 684 # KeyboardInterrupts 685 diroutputmap = pool.map_async(generate_directories_fks_async, 686 range(len(glob_directories_map))).get(9999999) 687 except KeyboardInterrupt: 688 pool.terminate() 689 raise KeyboardInterrupt 690 691 pool.close() 692 pool.join() 693 694 #clean up tmp files containing final matrix elements 695 for mefile in self._curr_matrix_elements.get('matrix_elements'): 696 os.remove(mefile) 697 698 for charac in ['nexternal', 'ninitial']: 699 proc_charac[charac] = self._curr_exporter.proc_characteristic[charac] 700 # ninitial and nexternal 701 proc_charac['nexternal'] = max([diroutput[4] for diroutput in diroutputmap]) 702 ninitial_set = set([diroutput[3] for diroutput in diroutputmap]) 703 if len(ninitial_set) != 1: 704 raise MadGraph5Error, ("Invalid ninitial values: %s" % ' ,'.join(list(ninitial_set))) 705 proc_charac['ninitial'] = list(ninitial_set)[0] 706 707 self.born_processes = [] 708 self.born_processes_for_olp = [] 709 max_loop_vertex_ranks = [] 710 711 for diroutput in diroutputmap: 712 calls = calls + diroutput[0] 713 self._fks_directories.extend(diroutput[1]) 714 max_loop_vertex_ranks.append(diroutput[2]) 715 self.born_processes.extend(diroutput[5]) 716 self.born_processes_for_olp.append(diroutput[5][0]) 717 718 else: 719 max_loop_vertex_ranks = [me.get_max_loop_vertex_rank() for \ 720 me in self._curr_matrix_elements.get_virt_matrix_elements()] 721 722 card_path = os.path.join(path, os.path.pardir, 'SubProcesses', \ 723 'procdef_mg5.dat') 724 725 if self.options['loop_optimized_output'] and \ 726 len(max_loop_vertex_ranks) > 0: 727 self._curr_exporter.write_coef_specs_file(max_loop_vertex_ranks) 728 if self._generate_info: 729 self._curr_exporter.write_procdef_mg5(card_path, # 730 self._curr_model['name'], 731 self._generate_info) 732 try: 733 cmd.Cmd.onecmd(self, 'history .') 734 except Exception: 735 logger.debug('fail to run command \"history cmd\"') 736 pass 737 subproc_path = os.path.join(path, os.path.pardir, 'SubProcesses', \ 738 'initial_states_map.dat') 739 self._curr_exporter.write_init_map(subproc_path, 740 self._curr_matrix_elements.get('initial_states')) 741 742 cpu_time1 = time.time()
743 744
745 - def do_launch(self, line):
746 """Main commands: Ask for editing the parameters and then execute the code (NLO or aMC@(N)LO) 747 """ 748 old_cwd = os.getcwd() 749 argss = self.split_arg(line) 750 # check argument validity and normalise argument 751 (options, argss) = _launch_parser.parse_args(argss) 752 options = options.__dict__ 753 self.check_launch(argss, options) 754 if not os.path.isdir(os.path.join(os.getcwd(), argss[0], 'Events')): 755 self.do_switch('ML5') 756 return mg_interface.MadGraphCmd.do_launch(self,line) 757 # if self.options['automatic_html_opening']: 758 # misc.open_file(os.path.join(os.getcwd(), argss[0], 'crossx.html')) 759 # self.options['automatic_html_opening'] = False 760 761 if options['interactive']: 762 if isinstance(self, extended_cmd.CmdShell): 763 ME = run_interface.aMCatNLOCmdShell(me_dir=argss[0], options=self.options) 764 else: 765 ME = run_interface.aMCatNLOCmd(me_dir=argss[0],options=self.options) 766 ME.pass_in_web_mode() 767 # transfer interactive configuration 768 config_line = [l for l in self.history if l.strip().startswith('set')] 769 for line in config_line: 770 ME.exec_cmd(line) 771 stop = self.define_child_cmd_interface(ME) 772 return stop 773 774 ext_program = launch_ext.aMCatNLOLauncher(argss[0], self, run_mode=argss[1], 775 shell = isinstance(self, extended_cmd.CmdShell), 776 **options) 777 ext_program.run()
778 779 780
781 -class aMCatNLOInterfaceWeb(mg_interface.CheckValidForCmdWeb, aMCatNLOInterface):
782 pass
783 784 _launch_usage = "launch [DIRPATH] [MODE] [options]\n" + \ 785 "-- execute the aMC@NLO output present in DIRPATH\n" + \ 786 " By default DIRPATH is the latest created directory\n" + \ 787 " MODE can be either LO, NLO, aMC@NLO or aMC@LO (if omitted, it is asked in a separate question)\n" + \ 788 " If mode is set to LO/NLO, no event generation will be performed, but only the \n" + \ 789 " computation of the total cross-section and the filling of parton-level histograms \n" + \ 790 " specified in the DIRPATH/SubProcesses/madfks_plot.f file.\n" + \ 791 " If mode is set to aMC@LO/aMC@NLO, after the cross-section computation, a .lhe \n" + \ 792 " event file is generated which will be showered with the MonteCarlo specified \n" + \ 793 " in the run_card.dat\n" 794 795 _launch_parser = misc.OptionParser(usage=_launch_usage) 796 _launch_parser.add_option("-f", "--force", default=False, action='store_true', 797 help="Use the card present in the directory for the launch, without editing them") 798 _launch_parser.add_option("-c", "--cluster", default=False, action='store_true', 799 help="Submit the jobs on the cluster") 800 _launch_parser.add_option("-i", "--interactive", default=False, action='store_true', 801 help="Use interactive consol") 802 _launch_parser.add_option("-m", "--multicore", default=False, action='store_true', 803 help="Submit the jobs on multicore mode") 804 _launch_parser.add_option("-x", "--nocompile", default=False, action='store_true', 805 help="Skip compilation. Ignored if no executable is found") 806 _launch_parser.add_option("-r", "--reweightonly", default=False, action='store_true', 807 help="Skip integration and event generation, just run reweight on the" + \ 808 " latest generated event files (see list in SubProcesses/nevents_unweighted)") 809 _launch_parser.add_option("-p", "--parton", default=False, action='store_true', 810 help="Stop the run after the parton level file generation (you need " + \ 811 "to shower the file in order to get physical results)") 812 _launch_parser.add_option("-o", "--only_generation", default=False, action='store_true', 813 help="Skip grid set up, just generate events starting from " + \ 814 "the last available results") 815 # the last option is different from the corresponding in amcatnlo_run_interface as it stores the 816 # 'name' entry of the options, not the run_name one 817 _launch_parser.add_option("-n", "--name", default=False, dest='name', 818 help="Provide a name to the run") 819 _launch_parser.add_option("-a", "--appl_start_grid", default=False, dest='appl_start_grid', 820 help="For use with APPLgrid only: start from existing grids") 821 _launch_parser.add_option("-R", "--reweight", default=False, action='store_true', 822 help="Run the reweight module (reweighting by different model parameter") 823 _launch_parser.add_option("-M", "--madspin", default=False, action='store_true', 824 help="Run the madspin package") 825