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 #validate_model will reset self._generate_info; to avoid 449 #this store it 450 geninfo = self._generate_info 451 self.validate_model(proc_type[1], coupling_type=proc_type[2]) 452 self._generate_info = geninfo 453 454 #now generate the amplitudes as usual 455 #self.options['group_subprocesses'] = 'False' 456 collect_mirror_procs = False 457 ignore_six_quark_processes = self.options['ignore_six_quark_processes'] 458 if ',' in line: 459 myprocdef, line = mg_interface.MadGraphCmd.extract_decay_chain_process(self,line) 460 if myprocdef.are_decays_perturbed(): 461 raise MadGraph5Error("Decay processes cannot be perturbed") 462 else: 463 myprocdef = mg_interface.MadGraphCmd.extract_process(self,line) 464 465 self.proc_validity(myprocdef,'aMCatNLO_%s'%proc_type[1]) 466 467 self._curr_proc_defs.append(myprocdef) 468 469 # if myprocdef['perturbation_couplings']!=['QCD']: 470 # message = ""FKS for reals only available in QCD for now, you asked %s" \ 471 # % ', '.join(myprocdef['perturbation_couplings'])" 472 # logger.info("%s. Checking for loop induced") 473 # new_line = ln 474 # 475 # 476 # raise self.InvalidCmd("FKS for reals only available in QCD for now, you asked %s" \ 477 # % ', '.join(myprocdef['perturbation_couplings'])) 478 ## 479 480 # if the new nlo process generation mode is enabled, the number of cores to be 481 # used has to be passed 482 # ncores_for_proc_gen has the following meaning 483 # 0 : do things the old way 484 # > 0 use ncores_for_proc_gen 485 # -1 : use all cores 486 if self.options['low_mem_multicore_nlo_generation']: 487 if self.options['nb_core']: 488 self.ncores_for_proc_gen = int(self.options['nb_core']) 489 else: 490 self.ncores_for_proc_gen = -1 491 else: 492 self.ncores_for_proc_gen = 0 493 494 # this is the options dictionary to pass to the FKSMultiProcess 495 fks_options = {'OLP': self.options['OLP'], 496 'ignore_six_quark_processes': self.options['ignore_six_quark_processes'], 497 'ncores_for_proc_gen': self.ncores_for_proc_gen} 498 try: 499 self._fks_multi_proc.add(fks_base.FKSMultiProcess(myprocdef,fks_options)) 500 except AttributeError: 501 self._fks_multi_proc = fks_base.FKSMultiProcess(myprocdef,fks_options)
502 503
504 - def do_output(self, line):
505 """Main commands: Initialize a new Template or reinitialize one""" 506 507 args = self.split_arg(line) 508 # Check Argument validity 509 self.check_output(args) 510 511 noclean = '-noclean' in args 512 force = '-f' in args 513 nojpeg = '-nojpeg' in args 514 main_file_name = "" 515 try: 516 main_file_name = args[args.index('-name') + 1] 517 except Exception: 518 pass 519 520 # For NLO, the group_subprocesses is automatically set to false 521 group_processes = False 522 # initialize the writer 523 if self._export_format in ['NLO']: 524 self._curr_exporter = export_v4.ExportV4Factory(self, noclean, 525 output_type='amcatnlo',group_subprocesses=group_processes) 526 527 self._curr_exporter.pass_information_from_cmd(self) 528 529 # check if a dir with the same name already exists 530 if not force and not noclean and os.path.isdir(self._export_dir)\ 531 and self._export_format in ['NLO']: 532 # Don't ask if user already specified force or noclean 533 logger.info('INFO: directory %s already exists.' % self._export_dir) 534 logger.info('If you continue this directory will be deleted and replaced.') 535 answer = self.ask('Do you want to continue?', 'y', ['y','n'], 536 timeout=self.options['timeout']) 537 if answer != 'y': 538 raise self.InvalidCmd('Stopped by user request') 539 540 # if one gets here either used -f or answered yes to the question about 541 # removing the dir 542 if os.path.exists(self._export_dir): 543 shutil.rmtree(self._export_dir) 544 545 # Make a Template Copy 546 if self._export_format in ['NLO']: 547 self._curr_exporter.copy_fkstemplate() 548 549 # Reset _done_export, since we have new directory 550 self._done_export = False 551 552 # Perform export and finalize right away 553 self.export(nojpeg, main_file_name, group_processes=group_processes) 554 555 # Pass potential new information generated during the export. 556 self._curr_exporter.pass_information_from_cmd(self) 557 558 # Automatically run finalize 559 self.finalize(nojpeg) 560 561 # Generate the virtuals if from OLP 562 if self.options['OLP']!='MadLoop': 563 self._curr_exporter.generate_virtuals_from_OLP( 564 self.born_processes_for_olp,self._export_dir,self.options['OLP']) 565 566 # Remember that we have done export 567 self._done_export = (self._export_dir, self._export_format) 568 569 # Reset _export_dir, so we don't overwrite by mistake later 570 self._export_dir = None
571 572 # Export a matrix element
573 - def export(self, nojpeg = False, main_file_name = "", group_processes=False):
574 """Export a generated amplitude to file""" 575 576 self._curr_helas_model = helas_call_writers.FortranUFOHelasCallWriter(self._curr_model) 577 def generate_matrix_elements(self, group=False): 578 """Helper function to generate the matrix elements before 579 exporting""" 580 581 # Sort amplitudes according to number of diagrams, 582 # to get most efficient multichannel output 583 self._curr_amps.sort(lambda a1, a2: a2.get_number_of_diagrams() - \ 584 a1.get_number_of_diagrams()) 585 586 cpu_time1 = time.time() 587 ndiags = 0 588 if not self._curr_matrix_elements.get_matrix_elements(): 589 if group: 590 raise MadGraph5Error, "Cannot group subprocesses when "+\ 591 "exporting to NLO" 592 else: 593 self._curr_matrix_elements = \ 594 fks_helas.FKSHelasMultiProcess(\ 595 self._fks_multi_proc, 596 loop_optimized= self.options['loop_optimized_output']) 597 598 if not self.options['low_mem_multicore_nlo_generation']: 599 # generate the code the old way 600 ndiags = sum([len(me.get('diagrams')) for \ 601 me in self._curr_matrix_elements.\ 602 get_matrix_elements()]) 603 # assign a unique id number to all process and 604 # generate a list of possible PDF combinations 605 uid = 0 606 initial_states=[] 607 for me in self._curr_matrix_elements.get_matrix_elements(): 608 uid += 1 # update the identification number 609 me.get('processes')[0].set('uid', uid) 610 try: 611 initial_states.append(sorted(list(set((p.get_initial_pdg(1),p.get_initial_pdg(2)) for \ 612 p in me.born_matrix_element.get('processes'))))) 613 except IndexError: 614 initial_states.append(sorted(list(set((p.get_initial_pdg(1)) for \ 615 p in me.born_matrix_element.get('processes'))))) 616 617 for fksreal in me.real_processes: 618 # Pick out all initial state particles for the two beams 619 try: 620 initial_states.append(sorted(list(set((p.get_initial_pdg(1),p.get_initial_pdg(2)) for \ 621 p in fksreal.matrix_element.get('processes'))))) 622 except IndexError: 623 initial_states.append(sorted(list(set((p.get_initial_pdg(1)) for \ 624 p in fksreal.matrix_element.get('processes'))))) 625 626 627 # remove doubles from the list 628 checked = [] 629 for e in initial_states: 630 if e not in checked: 631 checked.append(e) 632 initial_states=checked 633 634 self._curr_matrix_elements.set('initial_states',initial_states) 635 636 else: 637 #new NLO generation 638 if self._curr_matrix_elements['has_loops']: 639 self._curr_exporter.opt['mp'] = True 640 self._curr_exporter.model = self._curr_model 641 ndiags = 0 642 643 cpu_time2 = time.time() 644 return ndiags, cpu_time2 - cpu_time1
645 646 # Start of the actual routine 647 648 ndiags, cpu_time = generate_matrix_elements(self, group=group_processes) 649 calls = 0 650 651 path = self._export_dir 652 653 if self._export_format in ['NLO']: 654 path = os.path.join(path, 'SubProcesses') 655 656 #_curr_matrix_element is a FKSHelasMultiProcess Object 657 self._fks_directories = [] 658 proc_charac = self._curr_exporter.proc_characteristic 659 for charac in ['has_isr', 'has_fsr', 'has_loops']: 660 proc_charac[charac] = self._curr_matrix_elements[charac] 661 662 # prepare for the generation 663 # glob_directories_map is for the new NLO generation 664 global glob_directories_map 665 glob_directories_map = [] 666 667 # Save processes instances generated 668 self.born_processes_for_olp = [] 669 self.born_processes = [] 670 for ime, me in \ 671 enumerate(self._curr_matrix_elements.get('matrix_elements')): 672 if not self.options['low_mem_multicore_nlo_generation']: 673 #me is a FKSHelasProcessFromReals 674 calls = calls + \ 675 self._curr_exporter.generate_directories_fks(me, 676 self._curr_helas_model, 677 ime, len(self._curr_matrix_elements.get('matrix_elements')), 678 path,self.options['OLP']) 679 self._fks_directories.extend(self._curr_exporter.fksdirs) 680 self.born_processes_for_olp.append(me.born_matrix_element.get('processes')[0]) 681 self.born_processes.append(me.born_matrix_element.get('processes')) 682 else: 683 glob_directories_map.append(\ 684 [self._curr_exporter, me, self._curr_helas_model, 685 ime, len(self._curr_matrix_elements.get('matrix_elements')), 686 path, self.options['OLP']]) 687 688 if self.options['low_mem_multicore_nlo_generation']: 689 # start the pool instance with a signal instance to catch ctr+c 690 logger.info('Writing directories...') 691 original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN) 692 if self.ncores_for_proc_gen < 0: # use all cores 693 pool = multiprocessing.Pool(maxtasksperchild=1) 694 else: 695 pool = multiprocessing.Pool(processes=self.ncores_for_proc_gen,maxtasksperchild=1) 696 signal.signal(signal.SIGINT, original_sigint_handler) 697 try: 698 # the very large timeout passed to get is to be able to catch 699 # KeyboardInterrupts 700 diroutputmap = pool.map_async(generate_directories_fks_async, 701 range(len(glob_directories_map))).get(9999999) 702 except KeyboardInterrupt: 703 pool.terminate() 704 raise KeyboardInterrupt 705 706 pool.close() 707 pool.join() 708 709 #clean up tmp files containing final matrix elements 710 for mefile in self._curr_matrix_elements.get('matrix_elements'): 711 os.remove(mefile) 712 713 for charac in ['nexternal', 'ninitial']: 714 proc_charac[charac] = self._curr_exporter.proc_characteristic[charac] 715 # ninitial and nexternal 716 proc_charac['nexternal'] = max([diroutput[4] for diroutput in diroutputmap]) 717 ninitial_set = set([diroutput[3] for diroutput in diroutputmap]) 718 if len(ninitial_set) != 1: 719 raise MadGraph5Error, ("Invalid ninitial values: %s" % ' ,'.join(list(ninitial_set))) 720 proc_charac['ninitial'] = list(ninitial_set)[0] 721 722 self.born_processes = [] 723 self.born_processes_for_olp = [] 724 max_loop_vertex_ranks = [] 725 726 for diroutput in diroutputmap: 727 calls = calls + diroutput[0] 728 self._fks_directories.extend(diroutput[1]) 729 max_loop_vertex_ranks.append(diroutput[2]) 730 self.born_processes.extend(diroutput[5]) 731 self.born_processes_for_olp.append(diroutput[5][0]) 732 733 else: 734 max_loop_vertex_ranks = [me.get_max_loop_vertex_rank() for \ 735 me in self._curr_matrix_elements.get_virt_matrix_elements()] 736 737 card_path = os.path.join(path, os.path.pardir, 'SubProcesses', \ 738 'procdef_mg5.dat') 739 740 if self.options['loop_optimized_output'] and \ 741 len(max_loop_vertex_ranks) > 0: 742 self._curr_exporter.write_coef_specs_file(max_loop_vertex_ranks) 743 if self._generate_info: 744 self._curr_exporter.write_procdef_mg5(card_path, # 745 self._curr_model['name'], 746 self._generate_info) 747 try: 748 cmd.Cmd.onecmd(self, 'history .') 749 except Exception: 750 logger.debug('fail to run command \"history cmd\"') 751 pass 752 subproc_path = os.path.join(path, os.path.pardir, 'SubProcesses', \ 753 'initial_states_map.dat') 754 self._curr_exporter.write_init_map(subproc_path, 755 self._curr_matrix_elements.get('initial_states')) 756 757 cpu_time1 = time.time()
758 759
760 - def do_launch(self, line):
761 """Main commands: Ask for editing the parameters and then execute the code (NLO or aMC@(N)LO) 762 """ 763 old_cwd = os.getcwd() 764 argss = self.split_arg(line) 765 # check argument validity and normalise argument 766 (options, argss) = _launch_parser.parse_args(argss) 767 options = options.__dict__ 768 self.check_launch(argss, options) 769 if not os.path.isdir(os.path.join(os.getcwd(), argss[0], 'Events')): 770 self.do_switch('ML5') 771 return mg_interface.MadGraphCmd.do_launch(self,line) 772 # if self.options['automatic_html_opening']: 773 # misc.open_file(os.path.join(os.getcwd(), argss[0], 'crossx.html')) 774 # self.options['automatic_html_opening'] = False 775 776 if options['interactive']: 777 if isinstance(self, extended_cmd.CmdShell): 778 ME = run_interface.aMCatNLOCmdShell(me_dir=argss[0], options=self.options) 779 else: 780 ME = run_interface.aMCatNLOCmd(me_dir=argss[0],options=self.options) 781 ME.pass_in_web_mode() 782 # transfer interactive configuration 783 config_line = [l for l in self.history if l.strip().startswith('set')] 784 for line in config_line: 785 ME.exec_cmd(line) 786 stop = self.define_child_cmd_interface(ME) 787 return stop 788 789 ext_program = launch_ext.aMCatNLOLauncher(argss[0], self, run_mode=argss[1], 790 shell = isinstance(self, extended_cmd.CmdShell), 791 **options) 792 ext_program.run()
793 794 795
796 -class aMCatNLOInterfaceWeb(mg_interface.CheckValidForCmdWeb, aMCatNLOInterface):
797 pass
798 799 _launch_usage = "launch [DIRPATH] [MODE] [options]\n" + \ 800 "-- execute the aMC@NLO output present in DIRPATH\n" + \ 801 " By default DIRPATH is the latest created directory\n" + \ 802 " MODE can be either LO, NLO, aMC@NLO or aMC@LO (if omitted, it is asked in a separate question)\n" + \ 803 " If mode is set to LO/NLO, no event generation will be performed, but only the \n" + \ 804 " computation of the total cross-section and the filling of parton-level histograms \n" + \ 805 " specified in the DIRPATH/SubProcesses/madfks_plot.f file.\n" + \ 806 " If mode is set to aMC@LO/aMC@NLO, after the cross-section computation, a .lhe \n" + \ 807 " event file is generated which will be showered with the MonteCarlo specified \n" + \ 808 " in the run_card.dat\n" 809 810 _launch_parser = misc.OptionParser(usage=_launch_usage) 811 _launch_parser.add_option("-f", "--force", default=False, action='store_true', 812 help="Use the card present in the directory for the launch, without editing them") 813 _launch_parser.add_option("-c", "--cluster", default=False, action='store_true', 814 help="Submit the jobs on the cluster") 815 _launch_parser.add_option("-i", "--interactive", default=False, action='store_true', 816 help="Use interactive consol") 817 _launch_parser.add_option("-m", "--multicore", default=False, action='store_true', 818 help="Submit the jobs on multicore mode") 819 _launch_parser.add_option("-x", "--nocompile", default=False, action='store_true', 820 help="Skip compilation. Ignored if no executable is found") 821 _launch_parser.add_option("-r", "--reweightonly", default=False, action='store_true', 822 help="Skip integration and event generation, just run reweight on the" + \ 823 " latest generated event files (see list in SubProcesses/nevents_unweighted)") 824 _launch_parser.add_option("-p", "--parton", default=False, action='store_true', 825 help="Stop the run after the parton level file generation (you need " + \ 826 "to shower the file in order to get physical results)") 827 _launch_parser.add_option("-o", "--only_generation", default=False, action='store_true', 828 help="Skip grid set up, just generate events starting from " + \ 829 "the last available results") 830 # the last option is different from the corresponding in amcatnlo_run_interface as it stores the 831 # 'name' entry of the options, not the run_name one 832 _launch_parser.add_option("-n", "--name", default=False, dest='name', 833 help="Provide a name to the run") 834 _launch_parser.add_option("-a", "--appl_start_grid", default=False, dest='appl_start_grid', 835 help="For use with APPLgrid only: start from existing grids") 836 _launch_parser.add_option("-R", "--reweight", default=False, action='store_true', 837 help="Run the reweight module (reweighting by different model parameter") 838 _launch_parser.add_option("-M", "--madspin", default=False, action='store_true', 839 help="Run the madspin package") 840