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(re.split('%s\-\-', line,1)[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_amps:
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 if self.current_interface == "MadGraph":
219 allow_switch = True
220 self.change_principal_cmd('MadLoop', allow_switch)
221 self.cmd.validate_model(self, loop_type=nlo_mode,
222 coupling_type=orders)
223 self.change_principal_cmd('MadGraph', allow_switch)
224 return self.cmd.create_loop_induced(self, line, *args, **opts)
225 else:
226 self.change_principal_cmd('MadGraph', allow_switch)
227 try:
228 return self.cmd.do_add(self, line, *args, **opts)
229 except fks_base.NoBornException:
230 logger.info("------------------------------------------------------------------------", '$MG:BOLD')
231 logger.info(" No Born diagrams found. Now switching to the loop-induced mode. ", '$MG:BOLD')
232 logger.info(" Please cite ref. 'arXiv:1507.00020' when using results from this mode. ", '$MG:BOLD')
233 logger.info("------------------------------------------------------------------------", '$MG:BOLD')
234 self.change_principal_cmd('MadGraph',allow_switch)
235 return self.cmd.create_loop_induced(self, line, *args, **opts)
236
237
238 - def do_check(self, line, *args, **opts):
258
278
292
294 """ treat output aloha in order to use always the one in MG5 """
295 if line.strip().startswith('aloha'):
296 MGcmd.MadGraphCmd.do_output(self, line, *args, **opts)
297 else:
298 self.cmd.do_output(self, line, *args, **opts)
299
305
306
307
308
309
310
311 - def export(self, *args, **opts):
313
316
319
322
325
328
331
334
337
340
343
346
349
352
355
358
361
364
365 - def check_history(self, *args, **opts):
366 return self.cmd.check_history(self, *args, **opts)
367
370
373
376
379
382
385
388
391
394
397
400
403
406
409
412
415
418
419 - def complete_history(self, *args, **opts):
420 return self.cmd.complete_history(self, *args, **opts)
421
424
427
430
433
436
439
442
445
448
450 """Not in help """
451 return self.cmd.do_switch(self, *args, **opts)
452
453 - def do_EOF(self, *args, **opts):
455
458
461
464
467
468 - def do_history(self, *args, **opts):
469 return self.cmd.do_history(self, *args, **opts)
470
473
475 args = cmd.Cmd.split_arg(line)
476
477 if len(args) >=1:
478 if os.path.isdir(args[0]):
479 path = os.path.realpath(args[0])
480 elif os.path.isdir(pjoin(MG5DIR,args[0])):
481 path = pjoin(MG5DIR,args[0])
482 elif MG4DIR and os.path.isdir(pjoin(MG4DIR,args[0])):
483 path = pjoin(MG4DIR,args[0])
484 else:
485 path=None
486
487 if path:
488 type = self.cmd.find_output_type(self, path)
489 if type in ['standalone', 'standalone_cpp', 'pythia8', 'madevent']:
490 self.change_principal_cmd('MadGraph')
491 elif type == 'aMC@NLO':
492 self.change_principal_cmd('aMC@NLO')
493 elif type == 'MadLoop':
494 self.change_principal_cmd('MadLoop')
495
496 return self.cmd.do_launch(self, line, *argss, **opts)
497
500
503
506
509
510 - def do_set(self, *args, **opts):
512
515
518
521
524
527
530
533
536
537 - def help_history(self, *args, **opts):
538 return self.cmd.help_history(self, *args, **opts)
539
542
545
548
551
554
557
560
563
566
569
572
575
578
581
584
587
588 -class MasterCmd(Switcher, LoopCmd.LoopInterface, amcatnloCmd.aMCatNLOInterface, cmd.CmdShell):
589
590 - def __init__(self, main='MadGraph', *args, **opt):
601
605
616
642
643
644 -class MasterCmdWeb(MGcmd.MadGraphCmdWeb, Switcher, LoopCmd.LoopInterfaceWeb):
645
647
648 if os.environ.has_key('_CONDOR_SCRATCH_DIR'):
649 self.writing_dir = pjoin(os.environ['_CONDOR_SCRATCH_DIR'], \
650 os.path.pardir)
651 else:
652 self.writing_dir = pjoin(os.environ['MADGRAPH_DATA'],
653 os.environ['REMOTE_USER'])
654
655
656
657 Switcher.__init__(self, mgme_dir = '', *arg, **opt)
658
659 self.options['timeout'] = 1
660
671
674
675 - def finalize(self, nojpeg, flaglist=[]):
676 """Finalize web generation"""
677
678 if flaglist != []:
679 raise Exception
680 self.cmd.finalize(self, nojpeg, online = True)
681
683 """Finalize web generation"""
684
685 opts['online'] = True
686 self.cmd.finalize(self, nojpeg, opts)
687
688
690 """Generate an amplitude for a given process"""
691
692 try:
693 Switcher.do_generate(self, line)
694 except:
695
696 files.cp(self._export_dir+'/HTML/stop.jpg',self._export_dir+'/HTML/card.jpg')
697 raise
698
699
701 """Generate an amplitude for a given process and add to
702 existing amplitudes
703 syntax:
704 """
705 try:
706 Switcher.do_add(self, line)
707 except:
708
709 files.cp(self._export_dir+'/HTML/stop.jpg',self._export_dir+'/HTML/card.jpg')
710 raise
711
712
714
715 """Force to use the web configuration file only"""
716 config_path = pjoin(os.environ['MADGRAPH_BASE'], 'mg5_configuration.txt')
717 return Switcher.set_configuration(self, config_path=config_path, final=final)
718
719 - def do_save(self, line, check=True, **opt):
734
736 """block all install"""
737 return
738