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 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 if len(orders)>0:
188 return ('NLO','all',orders)
189 else:
190 return ('tree',None,[])
191 else:
192 return ('tree',None,[])
193
194
195
196 - def do_add(self, line, *args, **opts):
197
198 argss = cmd.Cmd.split_arg(line)
199 if len(argss)>=1 and argss[0] in ['process','timing','profile']:
200 proc_line = ' '.join(argss[1:])
201 (type,nlo_mode,orders)=self.extract_process_type(proc_line)
202 if type=='NLO':
203 if not nlo_mode in self._valid_nlo_modes: raise self.InvalidCMD( \
204 'The NLO mode %s is not valid. Please choose one among: %s' \
205 % (nlo_mode, ' '.join(self._valid_nlo_modes)))
206 elif nlo_mode in ['all', 'real', 'LOonly']:
207 self.change_principal_cmd('aMC@NLO')
208 elif nlo_mode in ['virt', 'sqrvirt']:
209 self.change_principal_cmd('MadLoop')
210 elif nlo_mode == 'noborn':
211 self.change_principal_cmd('MadLoop')
212 self.cmd.validate_model(self, loop_type=nlo_mode,
213 coupling_type=orders)
214 self.change_principal_cmd('MadGraph')
215 return self.cmd.create_loop_induced(self, line, *args, **opts)
216 try:
217 return self.cmd.do_add(self, line, *args, **opts)
218 except fks_base.NoBornException:
219 logger.info("------------------------------------------------------------------------", '$MG:color:BLACK')
220 logger.info(" No Born diagrams found. Now switching to the loop-induced mode. ", '$MG:color:BLACK')
221 logger.info(" Please cite ref. 'arXiv:1507.00020' when using results from this mode. ", '$MG:color:BLACK')
222 logger.info("------------------------------------------------------------------------", '$MG:color:BLACK')
223 self.change_principal_cmd('MadGraph')
224 return self.cmd.create_loop_induced(self, line, *args, **opts)
225
226
227 - def do_check(self, line, *args, **opts):
247
267
281
283 """ treat output aloha in order to use always the one in MG5 """
284 if line.strip().startswith('aloha'):
285 MGcmd.MadGraphCmd.do_output(self, line, *args, **opts)
286 else:
287 self.cmd.do_output(self, line, *args, **opts)
288
294
295
296
297
298
299
300 - def export(self, *args, **opts):
302
305
308
311
314
317
320
323
326
329
332
335
338
341
344
347
350
353
354 - def check_history(self, *args, **opts):
355 return self.cmd.check_history(self, *args, **opts)
356
359
362
365
368
371
374
377
380
383
386
389
392
395
398
401
404
407
408 - def complete_history(self, *args, **opts):
409 return self.cmd.complete_history(self, *args, **opts)
410
413
416
419
422
425
428
431
434
437
439 """Not in help """
440 return self.cmd.do_switch(self, *args, **opts)
441
442 - def do_EOF(self, *args, **opts):
444
447
450
453
456
457 - def do_history(self, *args, **opts):
458 return self.cmd.do_history(self, *args, **opts)
459
462
464 args = cmd.Cmd.split_arg(line)
465
466 if len(args) >=1:
467 if os.path.isdir(args[0]):
468 path = os.path.realpath(args[0])
469 elif os.path.isdir(pjoin(MG5DIR,args[0])):
470 path = pjoin(MG5DIR,args[0])
471 elif MG4DIR and os.path.isdir(pjoin(MG4DIR,args[0])):
472 path = pjoin(MG4DIR,args[0])
473 else:
474 path=None
475
476 if path:
477 type = self.cmd.find_output_type(self, path)
478 if type in ['standalone', 'standalone_cpp', 'pythia8', 'madevent']:
479 self.change_principal_cmd('MadGraph')
480 elif type == 'aMC@NLO':
481 self.change_principal_cmd('aMC@NLO')
482 elif type == 'MadLoop':
483 self.change_principal_cmd('MadLoop')
484
485 return self.cmd.do_launch(self, line, *argss, **opts)
486
489
492
495
498
499 - def do_set(self, *args, **opts):
501
504
507
510
513
516
519
522
525
526 - def help_history(self, *args, **opts):
527 return self.cmd.help_history(self, *args, **opts)
528
531
534
537
540
543
546
549
552
555
558
561
564
567
570
573
576
577 -class MasterCmd(Switcher, LoopCmd.LoopInterface, amcatnloCmd.aMCatNLOInterface, cmd.CmdShell):
578
579 - def __init__(self, main='MadGraph', *args, **opt):
590
594
605
624
625
626 -class MasterCmdWeb(MGcmd.MadGraphCmdWeb, Switcher, LoopCmd.LoopInterfaceWeb):
627
629
630 if os.environ.has_key('_CONDOR_SCRATCH_DIR'):
631 self.writing_dir = pjoin(os.environ['_CONDOR_SCRATCH_DIR'], \
632 os.path.pardir)
633 else:
634 self.writing_dir = pjoin(os.environ['MADGRAPH_DATA'],
635 os.environ['REMOTE_USER'])
636
637
638
639 Switcher.__init__(self, mgme_dir = '', *arg, **opt)
640
641 self.options['timeout'] = 1
642
653
656
657 - def finalize(self, nojpeg, flaglist=[]):
658 """Finalize web generation"""
659
660 if flaglist != []:
661 raise Exception
662 self.cmd.finalize(self, nojpeg, online = True)
663
665 """Finalize web generation"""
666
667 opts['online'] = True
668 self.cmd.finalize(self, nojpeg, opts)
669
670
672 """Generate an amplitude for a given process"""
673
674 try:
675 Switcher.do_generate(self, line)
676 except:
677
678 files.cp(self._export_dir+'/HTML/stop.jpg',self._export_dir+'/HTML/card.jpg')
679 raise
680
681
683 """Generate an amplitude for a given process and add to
684 existing amplitudes
685 syntax:
686 """
687 try:
688 Switcher.do_add(self, line)
689 except:
690
691 files.cp(self._export_dir+'/HTML/stop.jpg',self._export_dir+'/HTML/card.jpg')
692 raise
693
694
696
697 """Force to use the web configuration file only"""
698 config_path = pjoin(os.environ['MADGRAPH_BASE'], 'mg5_configuration.txt')
699 return Switcher.set_configuration(self, config_path=config_path, final=final)
700
701 - def do_save(self, line, check=True, **opt):
716
718 """block all install"""
719 return
720