1
2
3
4
5
6
7
8
9
10
11
12
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
20 import atexit
21 import logging
22 import optparse
23 import os
24 import pydoc
25 import re
26 import subprocess
27 import sys
28 import traceback
29 import time
30
31 root_path = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0]
32 root_path = os.path.split(root_path)[0]
33 sys.path.insert(0, root_path)
34
35
36 pjoin = os.path.join
37
38 import madgraph
39 import madgraph.core.diagram_generation as diagram_generation
40 import madgraph.core.helas_objects as helas_objects
41 import madgraph.loop.loop_base_objects as loop_base_objects
42 import madgraph.interface.extended_cmd as cmd
43 import madgraph.interface.madgraph_interface as MGcmd
44 import madgraph.interface.loop_interface as LoopCmd
45 import madgraph.interface.amcatnlo_interface as amcatnloCmd
46 import madgraph.fks.fks_base as fks_base
47 import madgraph.iolibs.files as files
48 import madgraph.various.misc as misc
49
50 from madgraph import MG4DIR, MG5DIR, MadGraph5Error
51
52 logger = logging.getLogger('cmdprint')
56 """ Helping class containing all the switching routine """
57
58 - def __init__(self, main='MadGraph', *args, **opt):
63
64 interface_names= {'MadGraph':('MG5_aMC',MGcmd.MadGraphCmd),
65 'MadLoop':('MG5_aMC',LoopCmd.LoopInterface),
66 'aMC@NLO':('MG5_aMC',amcatnloCmd.aMCatNLOInterface)}
67
68 _switch_opts = interface_names.keys()
69 current_interface = None
70
71
72
73 - def setup(self, *args, **opts):
74 """ Function to initialize the interface when switched to it. It is not
75 the same as __init__ as this latter functions would call its mother
76 from madgraph_interface and this is only desirable for the first
77 initialization when launching MG5 """
78 return self.cmd.setup(self, *args, **opts)
79
81 """redefine all the command to call directly the appropriate child"""
82
83 correct = True
84
85
86 overwritable = []
87
88 self.to_preserve = [key for key,method in Switcher.__dict__.items() if
89 hasattr(method, '__call__') ]
90 self.to_preserve += ['do_shell', 'help_shell', 'complete_shell']
91
92 ff = open(pjoin(os.getcwd(), 'additional_command'), 'w')
93
94 for key in dir(self):
95
96 if key in self.to_preserve:
97 continue
98 if not (key.startswith('do_') or key.startswith('complete_') or \
99 key.startswith('help_') or key.startswith('check_') or \
100 key in overwritable):
101 continue
102 text = """\
103 def %(key)s(self, *args, **opts):
104 return self.cmd.%(key)s(self, *args, **opts)
105
106 """ % {'key': key}
107 logger.warning("""Command %s not define in the Master.
108 The line to add to the master_interface.py are written in 'additional_command' file""" % key)
109 ff.write(text)
110 correct = False
111
112
113
114
115 define = {}
116 for mother in MasterCmd.__mro__:
117 if mother.__name__ in ['Cmd', 'BasicCmd', 'ExtendedCmd']:
118 continue
119
120
121 for data in mother.__dict__:
122
123 if data in Switcher.__dict__ or data.startswith('__'):
124 continue
125 if data in MasterCmd.__dict__:
126
127 continue
128 if data not in define:
129 define[data] = mother.__name__
130 else:
131 logger.warning('%s define in %s and in %s but not in Switcher.' % (data, define[data], mother.__name__))
132 correct = False
133
134
135 define = {}
136 for mother in MasterCmdWeb.__mro__:
137 if mother.__name__ in ['Cmd', 'BasicCmd', 'ExtendedCmd']:
138 continue
139
140 for data in mother.__dict__:
141
142 if data in Switcher.__dict__ or data.startswith('__'):
143 continue
144 if data in MasterCmdWeb.__dict__:
145
146 continue
147 if data not in define:
148 define[data] = mother.__name__
149 else:
150 logger.warning('%s define in %s and in %s but not in Switcher.' % (data, define[data], mother.__name__))
151 correct = False
152
153 if not correct:
154 raise Exception, 'The Cmd interface has dangerous features. Please see previous warnings and correct those.'
155
156
157
158 @staticmethod
160 """Extract from a string what is the type of the computation. This
161 returns a tuple (mode, option, pert_orders) where mode can be either 'NLO' or 'tree'
162 and option 'all', 'real' or 'virt'."""
163
164
165
166 space_before = re.compile(r"(?P<carac>\S)(?P<tag>[\\[\\]/\,\\$\\>|])(?P<carac2>\S)")
167 line2 = space_before.sub(r'\g<carac> \g<tag> \g<carac2>', line)
168
169
170
171
172 loopRE = re.compile(r"^(.*)(?P<loop>\[(\s*(?P<option>\w+)\s*=)?(?P<orders>.+)?\])(.*)$")
173 res=loopRE.search(line)
174 if res:
175 orders=res.group('orders').split() if res.group('orders') else []
176 if res.group('option') and len(res.group('option').split())==1:
177 if res.group('option').split()[0]=='tree':
178 return ('tree',res.group('option').split()[0],orders)
179 else:
180 return ('NLO',res.group('option').split()[0],orders)
181 else:
182
183
184 if len(orders)>0:
185 return ('NLO','all',orders)
186 else:
187 return ('tree',None,[])
188 else:
189 return ('tree',None,[])
190
191
192
193 - def do_add(self, line, *args, **opts):
194
195 argss = cmd.Cmd.split_arg(line)
196 if len(argss)>=1 and argss[0] in ['process','timing','profile']:
197 proc_line = ' '.join(argss[1:])
198 (type,nlo_mode,orders)=self.extract_process_type(proc_line)
199 if type=='NLO':
200 if not nlo_mode in self._valid_nlo_modes: raise self.InvalidCMD( \
201 'The NLO mode %s is not valid. Please choose one among: %s' \
202 % (nlo_mode, ' '.join(self._valid_nlo_modes)))
203 elif nlo_mode in ['all', 'real', 'LOonly']:
204 self.change_principal_cmd('aMC@NLO')
205 elif nlo_mode in ['virt', 'sqrvirt']:
206 self.change_principal_cmd('MadLoop')
207 elif nlo_mode == 'noborn':
208 self.change_principal_cmd('MadLoop')
209 self.cmd.validate_model(self, loop_type=nlo_mode,
210 coupling_type=orders)
211 self.change_principal_cmd('MadGraph')
212 return self.cmd.create_loop_induced(self, line, *args, **opts)
213 try:
214 return self.cmd.do_add(self, line, *args, **opts)
215 except fks_base.NoBornException:
216 logger.info("------------------------------------------------------------------------", '$MG:color:BLACK')
217 logger.info(" No Born diagrams found. Now switching to the loop-induced mode. ", '$MG:color:BLACK')
218 logger.info(" Please cite ref. 'arXiv:1507.00020' when using results from this mode. ", '$MG:color:BLACK')
219 logger.info("------------------------------------------------------------------------", '$MG:color:BLACK')
220 self.change_principal_cmd('MadGraph')
221 return self.cmd.create_loop_induced(self, line, *args, **opts)
222
223
224 - def do_check(self, line, *args, **opts):
244
264
278
280 """ treat output aloha in order to use always the one in MG5 """
281 if line.strip().startswith('aloha'):
282 MGcmd.MadGraphCmd.do_output(self, line, *args, **opts)
283 else:
284 self.cmd.do_output(self, line, *args, **opts)
285
291
292
293
294
295
296
297 - def export(self, *args, **opts):
299
302
305
308
311
314
317
320
323
326
329
332
335
338
341
344
347
350
351 - def check_history(self, *args, **opts):
352 return self.cmd.check_history(self, *args, **opts)
353
356
359
362
365
368
371
374
377
380
383
386
389
392
395
398
401
404
405 - def complete_history(self, *args, **opts):
406 return self.cmd.complete_history(self, *args, **opts)
407
410
413
416
419
422
425
428
431
434
436 """Not in help """
437 return self.cmd.do_switch(self, *args, **opts)
438
439 - def do_EOF(self, *args, **opts):
441
444
447
450
453
454 - def do_history(self, *args, **opts):
455 return self.cmd.do_history(self, *args, **opts)
456
459
461 args = cmd.Cmd.split_arg(line)
462
463 if len(args) >=1:
464 if os.path.isdir(args[0]):
465 path = os.path.realpath(args[0])
466 elif os.path.isdir(pjoin(MG5DIR,args[0])):
467 path = pjoin(MG5DIR,args[0])
468 elif MG4DIR and os.path.isdir(pjoin(MG4DIR,args[0])):
469 path = pjoin(MG4DIR,args[0])
470 else:
471 path=None
472
473 if path:
474 type = self.cmd.find_output_type(self, path)
475 if type in ['standalone', 'standalone_cpp', 'pythia8', 'madevent']:
476 self.change_principal_cmd('MadGraph')
477 elif type == 'aMC@NLO':
478 self.change_principal_cmd('aMC@NLO')
479 elif type == 'MadLoop':
480 self.change_principal_cmd('MadLoop')
481
482 return self.cmd.do_launch(self, line, *argss, **opts)
483
486
489
492
495
496 - def do_set(self, *args, **opts):
498
501
504
507
510
513
516
519
522
523 - def help_history(self, *args, **opts):
524 return self.cmd.help_history(self, *args, **opts)
525
528
531
534
537
540
543
546
549
552
555
558
561
564
567
570
573
574 -class MasterCmd(Switcher, LoopCmd.LoopInterface, amcatnloCmd.aMCatNLOInterface, cmd.CmdShell):
575
576 - def __init__(self, main='MadGraph', *args, **opt):
587
591
602
621
622
623 -class MasterCmdWeb(MGcmd.MadGraphCmdWeb, Switcher, LoopCmd.LoopInterfaceWeb):
624
626
627 if os.environ.has_key('_CONDOR_SCRATCH_DIR'):
628 self.writing_dir = pjoin(os.environ['_CONDOR_SCRATCH_DIR'], \
629 os.path.pardir)
630 else:
631 self.writing_dir = pjoin(os.environ['MADGRAPH_DATA'],
632 os.environ['REMOTE_USER'])
633
634
635
636 Switcher.__init__(self, mgme_dir = '', *arg, **opt)
637
638 self.options['timeout'] = 1
639
650
653
654 - def finalize(self, nojpeg, flaglist=[]):
655 """Finalize web generation"""
656
657 if flaglist != []:
658 raise Exception
659 self.cmd.finalize(self, nojpeg, online = True)
660
662 """Finalize web generation"""
663
664 opts['online'] = True
665 self.cmd.finalize(self, nojpeg, opts)
666
667
669 """Generate an amplitude for a given process"""
670
671 try:
672 Switcher.do_generate(self, line)
673 except:
674
675 files.cp(self._export_dir+'/HTML/stop.jpg',self._export_dir+'/HTML/card.jpg')
676 raise
677
678
680 """Generate an amplitude for a given process and add to
681 existing amplitudes
682 syntax:
683 """
684 try:
685 Switcher.do_add(self, line)
686 except:
687
688 files.cp(self._export_dir+'/HTML/stop.jpg',self._export_dir+'/HTML/card.jpg')
689 raise
690
691
693
694 """Force to use the web configuration file only"""
695 config_path = pjoin(os.environ['MADGRAPH_BASE'], 'mg5_configuration.txt')
696 return Switcher.set_configuration(self, config_path=config_path, final=final)
697
698 - def do_save(self, line, check=True, **opt):
713
715 """block all install"""
716 return
717