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