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
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 argss = cmd.Cmd.split_arg(line)
202 if len(argss)>=1 and argss[0] in ['process','timing','profile']:
203 proc_line = ' '.join(argss[1:])
204 (type,nlo_mode,orders)=self.extract_process_type(proc_line)
205 if type=='NLO':
206 if not nlo_mode in self._valid_nlo_modes: raise self.InvalidCMD( \
207 'The NLO mode %s is not valid. Please choose one among: %s' \
208 % (nlo_mode, ' '.join(self._valid_nlo_modes)))
209 elif nlo_mode in ['all', 'real', 'LOonly']:
210 self.change_principal_cmd('aMC@NLO')
211 elif nlo_mode in ['virt', 'sqrvirt']:
212 self.change_principal_cmd('MadLoop')
213 elif nlo_mode == 'noborn':
214 self.change_principal_cmd('MadLoop')
215 self.cmd.validate_model(self, loop_type=nlo_mode,
216 coupling_type=orders)
217 self.change_principal_cmd('MadGraph')
218 return self.cmd.create_loop_induced(self, line, *args, **opts)
219 try:
220 return self.cmd.do_add(self, line, *args, **opts)
221 except fks_base.NoBornException:
222 logger.info("------------------------------------------------------------------------", '$MG:color:BLACK')
223 logger.info(" No Born diagrams found. Now switching to the loop-induced mode. ", '$MG:color:BLACK')
224 logger.info(" Please cite ref. 'arXiv:1507.00020' when using results from this mode. ", '$MG:color:BLACK')
225 logger.info("------------------------------------------------------------------------", '$MG:color:BLACK')
226 self.change_principal_cmd('MadGraph')
227 return self.cmd.create_loop_induced(self, line, *args, **opts)
228
229
230 - def do_check(self, line, *args, **opts):
250
270
284
286 """ treat output aloha in order to use always the one in MG5 """
287 if line.strip().startswith('aloha'):
288 MGcmd.MadGraphCmd.do_output(self, line, *args, **opts)
289 else:
290 self.cmd.do_output(self, line, *args, **opts)
291
297
298
299
300
301
302
303 - def export(self, *args, **opts):
305
308
311
314
317
320
323
326
329
332
335
338
341
344
347
350
353
356
357 - def check_history(self, *args, **opts):
358 return self.cmd.check_history(self, *args, **opts)
359
362
365
368
371
374
377
380
383
386
389
392
395
398
401
404
407
410
411 - def complete_history(self, *args, **opts):
412 return self.cmd.complete_history(self, *args, **opts)
413
416
419
422
425
428
431
434
437
440
442 """Not in help """
443 return self.cmd.do_switch(self, *args, **opts)
444
445 - def do_EOF(self, *args, **opts):
447
450
453
456
459
460 - def do_history(self, *args, **opts):
461 return self.cmd.do_history(self, *args, **opts)
462
465
467 args = cmd.Cmd.split_arg(line)
468
469 if len(args) >=1:
470 if os.path.isdir(args[0]):
471 path = os.path.realpath(args[0])
472 elif os.path.isdir(pjoin(MG5DIR,args[0])):
473 path = pjoin(MG5DIR,args[0])
474 elif MG4DIR and os.path.isdir(pjoin(MG4DIR,args[0])):
475 path = pjoin(MG4DIR,args[0])
476 else:
477 path=None
478
479 if path:
480 type = self.cmd.find_output_type(self, path)
481 if type in ['standalone', 'standalone_cpp', 'pythia8', 'madevent']:
482 self.change_principal_cmd('MadGraph')
483 elif type == 'aMC@NLO':
484 self.change_principal_cmd('aMC@NLO')
485 elif type == 'MadLoop':
486 self.change_principal_cmd('MadLoop')
487
488 return self.cmd.do_launch(self, line, *argss, **opts)
489
492
495
498
501
502 - def do_set(self, *args, **opts):
504
507
510
513
516
519
522
525
528
529 - def help_history(self, *args, **opts):
530 return self.cmd.help_history(self, *args, **opts)
531
534
537
540
543
546
549
552
555
558
561
564
567
570
573
576
579
580 -class MasterCmd(Switcher, LoopCmd.LoopInterface, amcatnloCmd.aMCatNLOInterface, cmd.CmdShell):
581
582 - def __init__(self, main='MadGraph', *args, **opt):
593
597
608
627
628
629 -class MasterCmdWeb(MGcmd.MadGraphCmdWeb, Switcher, LoopCmd.LoopInterfaceWeb):
630
632
633 if os.environ.has_key('_CONDOR_SCRATCH_DIR'):
634 self.writing_dir = pjoin(os.environ['_CONDOR_SCRATCH_DIR'], \
635 os.path.pardir)
636 else:
637 self.writing_dir = pjoin(os.environ['MADGRAPH_DATA'],
638 os.environ['REMOTE_USER'])
639
640
641
642 Switcher.__init__(self, mgme_dir = '', *arg, **opt)
643
644 self.options['timeout'] = 1
645
656
659
660 - def finalize(self, nojpeg, flaglist=[]):
661 """Finalize web generation"""
662
663 if flaglist != []:
664 raise Exception
665 self.cmd.finalize(self, nojpeg, online = True)
666
668 """Finalize web generation"""
669
670 opts['online'] = True
671 self.cmd.finalize(self, nojpeg, opts)
672
673
675 """Generate an amplitude for a given process"""
676
677 try:
678 Switcher.do_generate(self, line)
679 except:
680
681 files.cp(self._export_dir+'/HTML/stop.jpg',self._export_dir+'/HTML/card.jpg')
682 raise
683
684
686 """Generate an amplitude for a given process and add to
687 existing amplitudes
688 syntax:
689 """
690 try:
691 Switcher.do_add(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
700 """Force to use the web configuration file only"""
701 config_path = pjoin(os.environ['MADGRAPH_BASE'], 'mg5_configuration.txt')
702 return Switcher.set_configuration(self, config_path=config_path, final=final)
703
704 - def do_save(self, line, check=True, **opt):
719
721 """block all install"""
722 return
723