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):
243
263
277
279 """ treat output aloha in order to use always the one in MG5 """
280 if line.strip().startswith('aloha'):
281 MGcmd.MadGraphCmd.do_output(self, line, *args, **opts)
282 else:
283 self.cmd.do_output(self, line, *args, **opts)
284
290
291
292
293
294
295
296 - def export(self, *args, **opts):
298
301
304
307
310
313
316
319
322
325
328
331
334
337
340
343
346
349
350 - def check_history(self, *args, **opts):
351 return self.cmd.check_history(self, *args, **opts)
352
355
358
361
364
367
370
373
376
379
382
385
388
391
394
397
400
403
404 - def complete_history(self, *args, **opts):
405 return self.cmd.complete_history(self, *args, **opts)
406
409
412
415
418
421
424
427
430
433
435 """Not in help """
436 return self.cmd.do_switch(self, *args, **opts)
437
438 - def do_EOF(self, *args, **opts):
440
443
446
449
452
453 - def do_history(self, *args, **opts):
454 return self.cmd.do_history(self, *args, **opts)
455
458
460 args = cmd.Cmd.split_arg(line)
461
462 if len(args) >=1:
463 if os.path.isdir(args[0]):
464 path = os.path.realpath(args[0])
465 elif os.path.isdir(pjoin(MG5DIR,args[0])):
466 path = pjoin(MG5DIR,args[0])
467 elif MG4DIR and os.path.isdir(pjoin(MG4DIR,args[0])):
468 path = pjoin(MG4DIR,args[0])
469 else:
470 path=None
471
472 if path:
473 type = self.cmd.find_output_type(self, path)
474 if type in ['standalone', 'standalone_cpp', 'pythia8', 'madevent']:
475 self.change_principal_cmd('MadGraph')
476 elif type == 'aMC@NLO':
477 self.change_principal_cmd('aMC@NLO')
478 elif type == 'MadLoop':
479 self.change_principal_cmd('MadLoop')
480
481 return self.cmd.do_launch(self, line, *argss, **opts)
482
485
488
491
494
495 - def do_set(self, *args, **opts):
497
500
503
506
509
512
515
518
521
522 - def help_history(self, *args, **opts):
523 return self.cmd.help_history(self, *args, **opts)
524
527
530
533
536
539
542
545
548
551
554
557
560
563
566
569
572
573 -class MasterCmd(Switcher, LoopCmd.LoopInterface, amcatnloCmd.aMCatNLOInterface, cmd.CmdShell):
574
575 - def __init__(self, main='MadGraph', *args, **opt):
586
590
601
620
621
622 -class MasterCmdWeb(MGcmd.MadGraphCmdWeb, Switcher, LoopCmd.LoopInterfaceWeb):
623
625
626 if os.environ.has_key('_CONDOR_SCRATCH_DIR'):
627 self.writing_dir = pjoin(os.environ['_CONDOR_SCRATCH_DIR'], \
628 os.path.pardir)
629 else:
630 self.writing_dir = pjoin(os.environ['MADGRAPH_DATA'],
631 os.environ['REMOTE_USER'])
632
633
634
635 Switcher.__init__(self, mgme_dir = '', *arg, **opt)
636
637 self.options['timeout'] = 1
638
649
652
653 - def finalize(self, nojpeg, flaglist=[]):
654 """Finalize web generation"""
655
656 if flaglist != []:
657 raise Exception
658 self.cmd.finalize(self, nojpeg, online = True)
659
661 """Finalize web generation"""
662
663 opts['online'] = True
664 self.cmd.finalize(self, nojpeg, opts)
665
666
668 """Generate an amplitude for a given process"""
669
670 try:
671 Switcher.do_generate(self, line)
672 except:
673
674 files.cp(self._export_dir+'/HTML/stop.jpg',self._export_dir+'/HTML/card.jpg')
675 raise
676
677
679 """Generate an amplitude for a given process and add to
680 existing amplitudes
681 syntax:
682 """
683 try:
684 Switcher.do_add(self, line)
685 except:
686
687 files.cp(self._export_dir+'/HTML/stop.jpg',self._export_dir+'/HTML/card.jpg')
688 raise
689
690
692
693 """Force to use the web configuration file only"""
694 config_path = pjoin(os.environ['MADGRAPH_BASE'], 'mg5_configuration.txt')
695 return Switcher.set_configuration(self, config_path=config_path, final=final)
696
697 - def do_save(self, line, check=True, **opt):
712
714 """block all install"""
715 return
716