14
class UFOError(Exception):
15
"""Exception raised if when inconsistencies are detected in the UFO model."""
18
class UFOBaseClass(object):
19
"""The class from which all FeynRules classes are derived."""
23
def __init__(self, *args, **options):
24
assert(len(self.require_args) == len (args))
26
for i, name in enumerate(self.require_args):
27
setattr(self, name, args[i])
29
for (option, value) in options.items():
30
setattr(self, option, value)
33
return getattr(self, name)
35
def set(self, name, value):
36
setattr(self, name, value)
39
"""Return a dictionary containing all the information of the object"""
45
def nice_string(self):
46
""" return string with the full information """
47
return '\n'.join(['%s \t: %s' %(name, value) for name, value in self.__dict__.items()])
60
for orig,sub in replacements:
61
text = text.replace(orig,sub)
70
class Particle(UFOBaseClass):
71
"""A standard Particle"""
73
require_args=['pdg_code', 'name', 'antiname', 'spin', 'color', 'mass', 'width', 'texname', 'antitexname', 'charge']
75
require_args_all = ['pdg_code', 'name', 'antiname', 'spin', 'color', 'mass', 'width', 'texname', 'antitexname', 'charge', 'loop_particles', 'counterterm','line', 'propagating', 'goldstoneboson']
77
def __init__(self, pdg_code, name, antiname, spin, color, mass, width, texname,
78
antitexname, charge , loop_particles=None, counterterm=None, line=None, propagating=True, goldstoneboson=False, **options):
80
args= (pdg_code, name, antiname, spin, color, mass, width, texname,
81
antitexname, float(charge))
83
UFOBaseClass.__init__(self, *args, **options)
86
all_particles.append(self)
88
self.propagating = propagating
89
self.goldstoneboson= goldstoneboson
91
self.selfconjugate = (name == antiname)
93
self.line = self.find_line_type()
97
def find_line_type(self):
98
""" find how we draw a line if not defined
99
valid output: dashed/straight/wavy/curly/double/swavy/scurly
109
if not self.selfconjugate:
126
return 'dashed' # not supported yet
129
# We do not copy the UV wavefunction renormalization as it is defined for the particle only.
130
if self.selfconjugate:
131
raise Exception('%s has no anti particle.' % self.name)
133
for k,v in self.__dict__.iteritems():
134
if k not in self.require_args_all:
136
if self.color in [1,8]:
137
newcolor = self.color
139
newcolor = -self.color
141
return Particle(-self.pdg_code, self.antiname, self.name, self.spin, newcolor, self.mass, self.width,
142
self.antitexname, self.texname, -self.charge, self.line, self.propagating, self.goldstoneboson, **outdic)
148
class Parameter(UFOBaseClass):
150
require_args=['name', 'nature', 'type', 'value', 'texname']
152
def __init__(self, name, nature, type, value, texname, lhablock=None, lhacode=None):
154
args = (name,nature,type,value,texname)
156
UFOBaseClass.__init__(self, *args)
158
args=(name,nature,type,value,texname)
160
global all_parameters
161
all_parameters.append(self)
163
if (lhablock is None or lhacode is None) and nature == 'external':
164
raise Exception('Need LHA information for external parameter "%s".' % name)
165
self.lhablock = lhablock
166
self.lhacode = lhacode
168
all_CTparameters = []
170
class CTParameter(UFOBaseClass):
172
require_args=['name', 'nature,', 'type', 'value', 'texname']
174
def __init__(self, name, type, value, texname):
176
args = (name,'internal',type,value,texname)
178
UFOBaseClass.__init__(self, *args)
180
args=(name,'internal',type,value,texname)
182
self.nature='interal'
184
global all_CTparameters
185
all_CTparameters.append(self)
195
return self.value[-x]
201
class Vertex(UFOBaseClass):
203
require_args=['name', 'particles', 'color', 'lorentz', 'couplings']
205
def __init__(self, name, particles, color, lorentz, couplings, **opt):
207
args = (name, particles, color, lorentz, couplings)
209
UFOBaseClass.__init__(self, *args, **opt)
211
args=(particles,color,lorentz,couplings)
214
all_vertices.append(self)
218
class CTVertex(UFOBaseClass):
220
require_args=['name', 'particles', 'color', 'lorentz', 'couplings', 'type', 'loop_particles']
222
def __init__(self, name, particles, color, lorentz, couplings, type, loop_particles, **opt):
224
args = (name, particles, color, lorentz, couplings, type, loop_particles)
226
UFOBaseClass.__init__(self, *args, **opt)
228
args=(particles,color,lorentz,couplings, type, loop_particles)
230
global all_CTvertices
231
all_CTvertices.append(self)
235
class Coupling(UFOBaseClass):
237
require_args=['name', 'value', 'order']
239
require_args_all=['name', 'value', 'order', 'loop_particles', 'counterterm']
241
def __init__(self, name, value, order, loop_particles=None, counterterm=None, **opt):
243
args =(name, value, order)
244
UFOBaseClass.__init__(self, *args, **opt)
246
all_couplings.append(self)
252
""" the self.value attribute can be a dictionary directly specifying the Laurent serie using normal
253
parameter or just a string which can possibly contain CTparameter defining the Laurent serie."""
255
if isinstance(self.value,dict):
256
if -x in self.value.keys():
257
return self.value[-x]
262
for param in all_CTparameters:
263
pattern=re.compile(r"(?P<first>\A|\*|\+|\-|\()(?P<name>"+param.name+r")(?P<second>\Z|\*|\+|\-|\))")
264
numberOfMatches=len(pattern.findall(self.value))
265
if numberOfMatches==1:
269
raise UFOError, "UFO does not support yet more than one occurence of CTParameters in the couplings values."
270
elif numberOfMatches>1:
271
raise UFOError, "UFO does not support yet more than one occurence of CTParameters in the couplings values."
279
if CTparam.pole(x)=='ZERO':
282
def substitution(matchedObj):
283
return matchedObj.group('first')+"("+CTparam.pole(x)+")"+matchedObj.group('second')
284
pattern=re.compile(r"(?P<first>\A|\*|\+|\-|\()(?P<name>"+CTparam.name+r")(?P<second>\Z|\*|\+|\-|\))")
285
return pattern.sub(substitution,self.value)
289
class Lorentz(UFOBaseClass):
291
require_args=['name','spins','structure']
293
def __init__(self, name, spins, structure='external', **opt):
294
args = (name, spins, structure)
295
UFOBaseClass.__init__(self, *args, **opt)
298
all_lorentz.append(self)
303
class Function(object):
305
def __init__(self, name, arguments, expression):
308
all_functions.append(self)
311
self.arguments = arguments
312
self.expr = expression
314
def __call__(self, *opt):
316
for i, arg in enumerate(self.arguments):
317
exec('%s = %s' % (arg, opt[i] ))
319
return eval(self.expr)
323
class CouplingOrder(object):
325
def __init__(self, name, expansion_order, hierarchy, perturbative_expansion = 0):
328
all_orders.append(self)
331
self.expansion_order = expansion_order
332
self.hierarchy = hierarchy
333
self.perturbative_expansion = perturbative_expansion