################################################################################ # # Copyright (c) 2009 The MadGraph5_aMC@NLO Development team and Contributors # # This file is a part of the MadGraph5_aMC@NLO project, an application which # automatically generates Feynman diagrams and matrix elements for arbitrary # high-energy processes in the Standard Model and beyond. # # It is subject to the MadGraph5_aMC@NLO license which should accompany this # distribution. # # For more information, visit madgraph.phys.ucl.ac.be and amcatnlo.web.cern.ch # ################################################################################ """A user friendly command line interface to access all MadGraph5_aMC@NLO features. Uses the cmd package for command interpretation and tab completion. """ import atexit import logging import optparse import os import pydoc import re import subprocess import sys import traceback import time root_path = os.path.split(os.path.dirname(os.path.realpath( __file__ )))[0] root_path = os.path.split(root_path)[0] sys.path.insert(0, root_path) #usefull shortcut pjoin = os.path.join import madgraph import madgraph.core.diagram_generation as diagram_generation import madgraph.core.helas_objects as helas_objects import madgraph.loop.loop_base_objects as loop_base_objects import madgraph.interface.extended_cmd as cmd import madgraph.interface.madgraph_interface as MGcmd import madgraph.interface.loop_interface as LoopCmd import madgraph.interface.amcatnlo_interface as amcatnloCmd import madgraph.fks.fks_base as fks_base import madgraph.iolibs.files as files import madgraph.various.misc as misc from madgraph import MG4DIR, MG5DIR, MadGraph5Error logger = logging.getLogger('cmdprint') # -> stdout class Switcher(object): """ Helping class containing all the switching routine """ def __init__(self, main='MadGraph', *args, **opt): # define the interface self.change_principal_cmd(main) self.cmd.__init__(self, *args, **opt) interface_names= {'MadGraph':('MG5_aMC',MGcmd.MadGraphCmd), 'MadLoop':('MG5_aMC',LoopCmd.LoopInterface), 'aMC@NLO':('MG5_aMC',amcatnloCmd.aMCatNLOInterface)} _switch_opts = interface_names.keys() current_interface = None # Helper functions def setup(self, *args, **opts): """ Function to initialize the interface when switched to it. It is not the same as __init__ as this latter functions would call its mother from madgraph_interface and this is only desirable for the first initialization when launching MG5 """ return self.cmd.setup(self, *args, **opts) def debug_link_to_command(self): """redefine all the command to call directly the appropriate child""" if hasattr(self, 'plugin') and self.plugin: return True correct = True # function which should be self.cmd dependent but which doesn't start # by do_xxxx, help_xxx, check_xxxx or complete_xxx overwritable = [] # list of item overwritten by the MasterClass self.to_preserve = [key for key,method in Switcher.__dict__.items() if hasattr(method, '__call__') ] self.to_preserve += ['do_shell', 'help_shell', 'complete_shell'] ff = open(pjoin(os.getcwd(), 'additional_command'), 'w') for key in dir(self): # by pass all not over-writable command if key in self.to_preserve: continue if not (key.startswith('do_') or key.startswith('complete_') or \ key.startswith('help_') or key.startswith('check_') or \ key in overwritable): continue text = """\ def %(key)s(self, *args, **opts): return self.cmd.%(key)s(self, *args, **opts) """ % {'key': key} logger.warning("""Command %s not define in the Master. The line to add to the master_interface.py are written in 'additional_command' file""" % key) ff.write(text) correct = False # Check that all function define in more than one subclass is define # in the Switcher or in one of the MasterClass define = {} for mother in MasterCmd.__mro__: if mother.__name__ in ['OriginalCmd', 'BasicCmd', 'CmdExtended', 'Cmd']: continue for data in mother.__dict__: #check if define in Switcher if data in Switcher.__dict__ or data.startswith('__'): continue if data in MasterCmd.__dict__: #always overwritten in the main class continue if data not in define: define[data] = mother.__name__ else: logger.warning('%s define in %s and in %s but not in Switcher.' % (data, define[data], mother.__name__)) correct = False # Do the same for the WEb MasterClass define = {} for mother in MasterCmdWeb.__mro__: if mother.__name__ in ['OriginalCmd', 'BasicCmd', 'CmdExtended', 'Cmd']: continue for data in mother.__dict__: #check if define in Switcher if data in Switcher.__dict__ or data.startswith('__'): continue if data in MasterCmdWeb.__dict__: #always overwritten in the main class continue if data not in define: define[data] = mother.__name__ else: logger.warning('%s define in %s and in %s but not in Switcher.' % (data, define[data], mother.__name__)) correct = False if not correct: raise Exception, 'The Cmd interface has dangerous features. Please see previous warnings and correct those.' @staticmethod def extract_process_type(line): """Extract from a string what is the type of the computation. This returns a tuple (mode, option, pert_orders) where mode can be either 'NLO' or 'tree' and option 'all', 'real' or 'virt'.""" # Perform sanity modifications on the lines: # Add a space before and after any > , $ / | [ ] space_before = re.compile(r"(?P\S)(?P[\\[\\]/\,\\$\\>|])(?P\S)") line2 = space_before.sub(r'\g \g \g', line) # Use regular expressions to extract the loop mode (if present) and its # option, specified in the line with format [ option = loop_orders ] or # [ loop_orders ] which implicitly select the 'all' option. loopRE = re.compile(r"^(.*)(?P\[(\s*(?P