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, InvalidCmd
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 if hasattr(self, 'plugin') and self.plugin:
84 return True
85
86 correct = True
87
88
89 overwritable = []
90
91 self.to_preserve = [key for key,method in Switcher.__dict__.items() if
92 hasattr(method, '__call__') ]
93 self.to_preserve += ['do_shell', 'help_shell', 'complete_shell']
94
95 ff = open(pjoin(os.getcwd(), 'additional_command'), 'w')
96
97 for key in dir(self):
98
99 if key in self.to_preserve:
100 continue
101 if not (key.startswith('do_') or key.startswith('complete_') or \
102 key.startswith('help_') or key.startswith('check_') or \
103 key in overwritable):
104 continue
105 text = """\
106 def %(key)s(self, *args, **opts):
107 return self.cmd.%(key)s(self, *args, **opts)
108
109 """ % {'key': key}
110 logger.warning("""Command %s not define in the Master.
111 The line to add to the master_interface.py are written in 'additional_command' file""" % key)
112 ff.write(text)
113 correct = False
114
115
116
117
118 define = {}
119 for mother in MasterCmd.__mro__:
120 if mother.__name__ in ['OriginalCmd', 'BasicCmd', 'CmdExtended', 'Cmd']:
121 continue
122
123
124 for data in mother.__dict__:
125
126 if data in Switcher.__dict__ or data.startswith('__'):
127 continue
128 if data in MasterCmd.__dict__:
129
130 continue
131 if data not in define:
132 define[data] = mother.__name__
133 else:
134 logger.warning('%s define in %s and in %s but not in Switcher.' % (data, define[data], mother.__name__))
135 correct = False
136
137
138 define = {}
139 for mother in MasterCmdWeb.__mro__:
140 if mother.__name__ in ['OriginalCmd', 'BasicCmd', 'CmdExtended', 'Cmd']:
141 continue
142 for data in mother.__dict__:
143
144 if data in Switcher.__dict__ or data.startswith('__'):
145 continue
146 if data in MasterCmdWeb.__dict__:
147
148 continue
149 if data not in define:
150 define[data] = mother.__name__
151 else:
152 logger.warning('%s define in %s and in %s but not in Switcher.' % (data, define[data], mother.__name__))
153 correct = False
154
155 if not correct:
156 raise Exception, 'The Cmd interface has dangerous features. Please see previous warnings and correct those.'
157
158
159
160 @staticmethod
162 """Extract from a string what is the type of the computation. This
163 returns a tuple (mode, option, pert_orders) where mode can be either 'NLO' or 'tree'
164 and option 'all', 'real' or 'virt'."""
165
166
167
168 space_before = re.compile(r"(?P<carac>\S)(?P<tag>[\\[\\]/\,\\$\\>|])(?P<carac2>\S)")
169 line2 = space_before.sub(r'\g<carac> \g<tag> \g<carac2>', line)
170
171
172
173
174 loopRE = re.compile(r"^(.*)(?P<loop>\[(\s*(?P<option>\w+)\s*=)?(?P<orders>.+)?\])(.*)$")
175
176 res=loopRE.search(line.split('--')[0])
177 if res:
178 orders=res.group('orders').split() if res.group('orders') else []
179 if res.group('option') and len(res.group('option').split())==1:
180 if res.group('option').split()[0]=='tree':
181 return ('tree',res.group('option').split()[0],orders)
182 else:
183 return ('NLO',res.group('option').split()[0],orders)
184 else:
185
186
187
188 if orders == ['LOonly']:
189 return ('NLO', 'LOonly', ['QCD'])
190 elif len(orders)>0:
191 return ('NLO','all',orders)
192 else:
193 return ('tree',None,[])
194 else:
195 return ('tree',None,[])
196
197
198
199 - def do_add(self, line, *args, **opts):
200
201 allow_switch = True
202 if self._curr_proc_defs:
203 allow_switch = False
204
205 argss = cmd.Cmd.split_arg(line)
206 if len(argss)>=1 and argss[0] in ['process','timing','profile']:
207 proc_line = ' '.join(argss[1:])
208 (type,nlo_mode,orders)=self.extract_process_type(proc_line)
209 if type=='NLO':
210 if not nlo_mode in self._valid_nlo_modes: raise self.InvalidCMD( \
211 'The NLO mode %s is not valid. Please choose one among: %s' \
212 % (nlo_mode, ' '.join(self._valid_nlo_modes)))
213 elif nlo_mode in ['all', 'real', 'LOonly']:
214 self.change_principal_cmd('aMC@NLO', allow_switch)
215 elif nlo_mode in ['virt', 'sqrvirt']:
216 self.change_principal_cmd('MadLoop', allow_switch)
217 elif nlo_mode == 'noborn':
218 self.change_principal_cmd('MadLoop', allow_switch)
219 self.cmd.validate_model(self, loop_type=nlo_mode,
220 coupling_type=orders)
221 self.change_principal_cmd('MadGraph', allow_switch)
222 return self.cmd.create_loop_induced(self, line, *args, **opts)
223 else:
224 self.change_principal_cmd('MadGraph', allow_switch)
225 try:
226 return self.cmd.do_add(self, line, *args, **opts)
227 except fks_base.NoBornException:
228 logger.info("------------------------------------------------------------------------", '$MG:BOLD')
229 logger.info(" No Born diagrams found. Now switching to the loop-induced mode. ", '$MG:BOLD')
230 logger.info(" Please cite ref. 'arXiv:1507.00020' when using results from this mode. ", '$MG:BOLD')
231 logger.info("------------------------------------------------------------------------", '$MG:BOLD')
232 self.change_principal_cmd('MadGraph',allow_switch)
233 return self.cmd.create_loop_induced(self, line, *args, **opts)
234
235
236 - def do_check(self, line, *args, **opts):
256
276
290
292 """ treat output aloha in order to use always the one in MG5 """
293 if line.strip().startswith('aloha'):
294 MGcmd.MadGraphCmd.do_output(self, line, *args, **opts)
295 else:
296 self.cmd.do_output(self, line, *args, **opts)
297
303
304
305
306
307
308
309 - def export(self, *args, **opts):
311
314
317
320
323
326
329
332
335
338
341
344
347
350
353
356
359
362
363 - def check_history(self, *args, **opts):
364 return self.cmd.check_history(self, *args, **opts)
365
368
371
374
377
380
383
386
389
392
395
398
401
404
407
410
413
416
417 - def complete_history(self, *args, **opts):
418 return self.cmd.complete_history(self, *args, **opts)
419
422
425
428
431
434
437
440
443
446
448 """Not in help """
449 return self.cmd.do_switch(self, *args, **opts)
450
451 - def do_EOF(self, *args, **opts):
453
456
459
462
465
466 - def do_history(self, *args, **opts):
467 return self.cmd.do_history(self, *args, **opts)
468
471
473 args = cmd.Cmd.split_arg(line)
474
475 if len(args) >=1:
476 if os.path.isdir(args[0]):
477 path = os.path.realpath(args[0])
478 elif os.path.isdir(pjoin(MG5DIR,args[0])):
479 path = pjoin(MG5DIR,args[0])
480 elif MG4DIR and os.path.isdir(pjoin(MG4DIR,args[0])):
481 path = pjoin(MG4DIR,args[0])
482 else:
483 path=None
484
485 if path:
486 type = self.cmd.find_output_type(self, path)
487 if type in ['standalone', 'standalone_cpp', 'pythia8', 'madevent']:
488 self.change_principal_cmd('MadGraph')
489 elif type == 'aMC@NLO':
490 self.change_principal_cmd('aMC@NLO')
491 elif type == 'MadLoop':
492 self.change_principal_cmd('MadLoop')
493
494 return self.cmd.do_launch(self, line, *argss, **opts)
495
498
501
504
507
508 - def do_set(self, *args, **opts):
510
513
516
519
522
525
528
531
534
535 - def help_history(self, *args, **opts):
536 return self.cmd.help_history(self, *args, **opts)
537
540
543
546
549
552
555
558
561
564
567
570
573
576
579
582
585
586 -class MasterCmd(Switcher, LoopCmd.LoopInterface, amcatnloCmd.aMCatNLOInterface, cmd.CmdShell):
587
588 - def __init__(self, main='MadGraph', *args, **opt):
599
603
614
640
641
642 -class MasterCmdWeb(MGcmd.MadGraphCmdWeb, Switcher, LoopCmd.LoopInterfaceWeb):
643
645
646 if os.environ.has_key('_CONDOR_SCRATCH_DIR'):
647 self.writing_dir = pjoin(os.environ['_CONDOR_SCRATCH_DIR'], \
648 os.path.pardir)
649 else:
650 self.writing_dir = pjoin(os.environ['MADGRAPH_DATA'],
651 os.environ['REMOTE_USER'])
652
653
654
655 Switcher.__init__(self, mgme_dir = '', *arg, **opt)
656
657 self.options['timeout'] = 1
658
669
672
673 - def finalize(self, nojpeg, flaglist=[]):
674 """Finalize web generation"""
675
676 if flaglist != []:
677 raise Exception
678 self.cmd.finalize(self, nojpeg, online = True)
679
681 """Finalize web generation"""
682
683 opts['online'] = True
684 self.cmd.finalize(self, nojpeg, opts)
685
686
688 """Generate an amplitude for a given process"""
689
690 try:
691 Switcher.do_generate(self, line)
692 except:
693
694 files.cp(self._export_dir+'/HTML/stop.jpg',self._export_dir+'/HTML/card.jpg')
695 raise
696
697
699 """Generate an amplitude for a given process and add to
700 existing amplitudes
701 syntax:
702 """
703 try:
704 Switcher.do_add(self, line)
705 except:
706
707 files.cp(self._export_dir+'/HTML/stop.jpg',self._export_dir+'/HTML/card.jpg')
708 raise
709
710
712
713 """Force to use the web configuration file only"""
714 config_path = pjoin(os.environ['MADGRAPH_BASE'], 'mg5_configuration.txt')
715 return Switcher.set_configuration(self, config_path=config_path, final=final)
716
717 - def do_save(self, line, check=True, **opt):
732
734 """block all install"""
735 return
736