Skip to content

Commit

Permalink
Merged with standalone_cpp branch: Include Standalone C++ output, as …
Browse files Browse the repository at this point in the history
…well as possibility to do parallel tests with C++ output.
  • Loading branch information
Johan Alwall committed Nov 24, 2010
2 parents 93cb3a7 + 687453e commit b2b2118
Show file tree
Hide file tree
Showing 37 changed files with 2,550 additions and 573 deletions.
37 changes: 37 additions & 0 deletions madgraph/core/base_objects.py
Expand Up @@ -859,6 +859,43 @@ def check_name_free(self, name):
if antipart:
antipart.set('antiname', default[pdg])

def write_param_card(self):
"""Write out the param_card, and return as string."""

def write_param(param, lhablock):

lhacode=' '.join(['%3s' % key for key in param.lhacode])
if lhablock == 'DECAY':
return 'DECAY %s %e # %s' % (lhacode, param.value, param.name)
else:
return " %s %e # %s" % (lhacode, param.value, param.name )

if not self.get('parameters'):
raise self.PhysicsObjectError,\
"Attempt to write param_card from non-UFO model"

external_params = self.get('parameters')[('external',)]

# list all lhablock
all_lhablock = set([param.lhablock for param in external_params])

# sort lhablock alphabeticaly
all_lhablock = sorted(list(all_lhablock))
# place DECAY blocks last
all_lhablock.remove('DECAY')
all_lhablock.append('DECAY')

ret_list = ["# SLHA param_card for %s written by MadGraph 5" % \
self.get('name')]

for lhablock in all_lhablock:
if lhablock != 'DECAY':
ret_list.append("BLOCK %s" % lhablock)
ret_list.extend(sorted([write_param(param, lhablock) \
for param in external_params if \
param.lhablock == lhablock]))
return "\n".join(ret_list) + "\n"

@ staticmethod
def load_default_name():
""" load the default for name convention """
Expand Down
50 changes: 19 additions & 31 deletions madgraph/core/helas_objects.py
Expand Up @@ -1066,37 +1066,6 @@ def __eq__(self, other):
return sorted([mother['number'] for mother in self['mothers']]) == \
sorted([mother['number'] for mother in other['mothers']])

# Overloaded operators

def almost_equal(self, other):
"""Just like the equality operator above, except mass is not
taken into account for external wavefunctions.
"""

if not isinstance(other, HelasWavefunction):
return False

# Check relevant directly defined properties
if self['number_external'] != other['number_external'] or \
self['fermionflow'] != other['fermionflow'] or \
self['coupl_key'] != other['coupl_key'] or \
self['lorentz'] != other['lorentz'] or \
self['coupling'] != other['coupling'] or \
self['state'] != other['state'] or \
self['onshell'] != other['onshell'] or \
self.get('spin') != other.get('spin') or \
self.get('self_antipart') != other.get('self_antipart') or \
(self.get('mothers') and self.get('mass') != other.get('mass')) or \
self.get('width') != other.get('width') or \
self.get('color') != other.get('color') or \
self['decay'] != other['decay'] or \
self['decay'] and self['particle'] != other['particle']:
return False

# Check that mothers have the same numbers (only relevant info)
return sorted([mother['number'] for mother in self['mothers']]) == \
sorted([mother['number'] for mother in other['mothers']])

def __ne__(self, other):
"""Overloading the nonequality operator, to make comparison easy"""
return not self.__eq__(other)
Expand Down Expand Up @@ -3204,6 +3173,13 @@ def get_used_lorentz(self):
self.get_all_wavefunctions() + self.get_all_amplitudes() \
if wa.get('interaction_id') != 0]

def get_used_couplings(self):
"""Return a list with all couplings used by this
HelasMatrixElement."""

return [wa.get('coupling') for wa in \
self.get_all_wavefunctions() + self.get_all_amplitudes() \
if wa.get('interaction_id') != 0]

@staticmethod
def check_equal_decay_processes(decay1, decay2):
Expand Down Expand Up @@ -3860,3 +3836,15 @@ def get_used_lorentz(self):
helas_list.extend(me.get_used_lorentz())

return list(set(helas_list))

def get_used_couplings(self):
"""Return a list with all couplings used by this
HelasMatrixElement."""

coupling_list = []

for me in self.get('matrix_elements'):
coupling_list.extend(me.get_used_couplings())

return list(set(coupling_list))

71 changes: 54 additions & 17 deletions madgraph/interface/cmd_interface.py
Expand Up @@ -43,7 +43,7 @@
import madgraph.core.helas_objects as helas_objects

import madgraph.iolibs.drawing_eps as draw
import madgraph.iolibs.export_pythia8 as export_pythia8
import madgraph.iolibs.export_cpp as export_cpp
import madgraph.iolibs.export_v4 as export_v4
import madgraph.iolibs.helas_call_writers as helas_call_writers
import madgraph.iolibs.file_writers as writers
Expand Down Expand Up @@ -476,15 +476,18 @@ def help_output(self):
logger.info("-- Output any generated process(es) to file.")
logger.info(" mode: Default mode is madevent. Default path is \'.\'.")
logger.info(" If mode is madevent or standalone, create a copy of")
logger.info(" the V4 Template in the MG_ME directory, with the model and")
logger.info(" Helas set up appropriately.")
logger.info(" the V4 Template in the MG_ME directory, with the model and")
logger.info(" Helas set up appropriately.")
logger.info(" - If mode is standalone, the directory will be in")
logger.info(" Standalone format, otherwise in MadEvent format.")
logger.info(" - If mode is matrix, output the matrix.f files for all")
logger.info(" generated processes in directory \"name\".")
logger.info(" - If mode is pythia8, output the .h and .cc files for the")
logger.info(" processes in Pythia 8 format in directory \"name\".")
logger.info(" - If mode is pythia8_model, output the .h and .cc files for")
logger.info(" If mode is standalone_cpp, output the .h and .cc files")
logger.info(" for the processes and model files in standalone C++")
logger.info(" format in directory \"name\".")
logger.info(" If mode is pythia8, output the .h and .cc files for")
logger.info(" the processes in Pythia 8 format in directory \"name\".")
logger.info(" If mode is pythia8_model, output the .h and .cc files for")
logger.info(" for the model parameters and Aloha functions for the model.")
logger.info(" name: The name of the copy of Template.")
logger.info(" If you put '.' instead of a name, your pwd will be used.")
Expand Down Expand Up @@ -862,7 +865,7 @@ def check_output(self, args):
path = args.pop(0)
# Check for special directory treatment
if path == 'auto' and self._export_format in \
['madevent', 'standalone']:
['madevent', 'standalone', 'standalone_cpp']:
self.get_default_path()
else:
self._export_dir = path
Expand Down Expand Up @@ -896,6 +899,11 @@ def get_default_path(self):
(self._curr_model['name'], i)
auto_path = lambda i: os.path.join(self.writing_dir,
name_dir(i))
elif self._export_format == 'standalone_cpp':
name_dir = lambda i: 'PROC_SA_CPP_%s_%s' % \
(self._curr_model['name'], i)
auto_path = lambda i: os.path.join(self.writing_dir,
name_dir(i))
else:
self._export_dir = '.'
return
Expand Down Expand Up @@ -1369,8 +1377,8 @@ class MadGraphCmd(CmdExtended, HelpToCmd):
_check_opts = ['full', 'quick', 'gauge', 'lorentz_invariance']
_import_formats = ['model_v4', 'model', 'proc_v4', 'command']
_v4_export_formats = ['madevent', 'standalone','matrix']
_export_formats = _v4_export_formats + ['pythia8',
'pythia8_model']
_export_formats = _v4_export_formats + ['standalone_cpp',
'pythia8', 'pythia8_model']


# Variables to store object information
Expand All @@ -1380,6 +1388,8 @@ class MadGraphCmd(CmdExtended, HelpToCmd):
_curr_fortran_model = None
_curr_cpp_model = None
_done_export = False

# Variables to store state information
_multiparticles = {}
_generate_info = "" # store the first generated process
_model_format = None
Expand Down Expand Up @@ -2146,12 +2156,19 @@ def do_import(self, line):
self._curr_fortran_model = \
helas_call_writers.FortranUFOHelasCallWriter(\
self._curr_model)
self._curr_cpp_model = \
helas_call_writers.CPPUFOHelasCallWriter(\
self._curr_model)
if '-modelname' not in args:
self._curr_model.pass_particles_name_in_mg_default()

# Do post-processing of model
self.process_model()

# Reset amplitudes and matrix elements
self._curr_amps = diagram_generation.AmplitudeList()
self._curr_matrix_elements = helas_objects.HelasMultiProcess()

elif args[0] == 'command':
if not os.path.isfile(args[1]):
raise MadGraph5Error("Path %s is not a valid pathname" % args[1])
Expand Down Expand Up @@ -2422,6 +2439,8 @@ def do_output(self, line):
elif self._export_format == 'standalone':
export_v4.copy_v4standalone(self._mgme_dir, self._export_dir,
not noclean)
elif self._export_format == 'standalone_cpp':
export_cpp.setup_cpp_standalone_dir(self._export_dir, self._curr_model)
elif not os.path.isdir(self._export_dir):
os.makedirs(self._export_dir)

Expand Down Expand Up @@ -2464,7 +2483,7 @@ def generate_matrix_elements(self):

if self._export_format == 'pythia8_model':
cpu_time1 = time.time()
export_pythia8.convert_model_to_pythia8(\
export_cpp.convert_model_to_pythia8(\
self._curr_model, self._export_dir)
cpu_time2 = time.time()
logger.info(("Exported UFO model to Pythia 8 format in %0.3f s") \
Expand All @@ -2484,9 +2503,9 @@ def generate_matrix_elements(self):
nojpeg = '-nojpeg' in args

path = self._export_dir
if self._export_format in ['madevent', 'standalone']:
if self._export_format in ['madevent', 'standalone', 'standalone_cpp']:
path = os.path.join(path, 'SubProcesses')

if self._export_format == 'madevent':
for me in self._curr_matrix_elements.get('matrix_elements'):
calls = calls + \
Expand Down Expand Up @@ -2523,12 +2542,16 @@ def generate_matrix_elements(self):
me, self._curr_fortran_model)

if self._export_format == 'pythia8':
self._curr_cpp_model = \
helas_call_writers.Pythia8UFOHelasCallWriter(self._curr_model)
export_pythia8.generate_process_files_pythia8(\
export_cpp.generate_process_files_pythia8(\
self._curr_matrix_elements, self._curr_cpp_model,
process_string = self._generate_info, path = path)

if self._export_format == 'standalone_cpp':
for me in self._curr_matrix_elements.get('matrix_elements'):
export_cpp.generate_subprocess_directory_standalone_cpp(\
me, self._curr_cpp_model,
path = path)

logger.info(("Generated helas calls for %d subprocesses " + \
"(%d diagrams) in %0.3f s") % \
(len(self._curr_matrix_elements.get('matrix_elements')),
Expand All @@ -2547,7 +2570,7 @@ def generate_matrix_elements(self):
# Remember that we have done export
self._done_export = (self._export_dir, self._export_format)

if self._export_format in ['madevent', 'standalone']:
if self._export_format in ['madevent', 'standalone', 'standalone_cpp']:
# Automatically run finalize
options = []
if nojpeg:
Expand Down Expand Up @@ -2581,9 +2604,23 @@ def finalize(self, options):
# actually used in the wavefunctions and amplitudes in
# these processes
wanted_lorentz = self._curr_matrix_elements.get_used_lorentz()
wanted_couplings = self._curr_matrix_elements.get_used_couplings()
export_v4.convert_model_to_mg4(self._curr_model,
os.path.join(self._export_dir),
wanted_lorentz)
wanted_lorentz,
wanted_couplings)
if self._export_format == 'standalone_cpp':
logger.info('Export UFO model to C++ format')
# wanted_lorentz are the lorentz structures which are
# actually used in the wavefunctions and amplitudes in
# these processes
wanted_lorentz = self._curr_matrix_elements.get_used_lorentz()
wanted_couplings = self._curr_matrix_elements.get_used_couplings()
export_cpp.convert_model_to_cpp(self._curr_model,
os.path.join(self._export_dir),
wanted_lorentz,
wanted_couplings)
export_cpp.make_model_cpp(self._export_dir)

if self._export_format == 'madevent':
os.system('touch %s/done' % os.path.join(self._export_dir,
Expand Down

0 comments on commit b2b2118

Please sign in to comment.