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