~maddevelopers/mg5amcnlo/2.9.4

« back to all changes in this revision

Viewing changes to tests/input_files/LoopSMTest/object_library.py

pass to v2.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
##
 
2
##
 
3
## Feynrules Header
 
4
##
 
5
##
 
6
##
 
7
##
 
8
##
 
9
 
 
10
import cmath
 
11
import re
 
12
 
 
13
 
 
14
class UFOError(Exception):
 
15
        """Exception raised if when inconsistencies are detected in the UFO model."""
 
16
        pass
 
17
 
 
18
class UFOBaseClass(object):
 
19
    """The class from which all FeynRules classes are derived."""
 
20
 
 
21
    require_args = []
 
22
 
 
23
    def __init__(self, *args, **options):
 
24
        assert(len(self.require_args) == len (args))
 
25
    
 
26
        for i, name in enumerate(self.require_args):
 
27
            setattr(self, name, args[i])
 
28
    
 
29
        for (option, value) in options.items():
 
30
            setattr(self, option, value)
 
31
 
 
32
    def get(self, name):
 
33
        return getattr(self, name)
 
34
    
 
35
    def set(self, name, value):
 
36
        setattr(self, name, value)
 
37
        
 
38
    def get_all(self):
 
39
        """Return a dictionary containing all the information of the object"""
 
40
        return self.__dict__
 
41
 
 
42
    def __str__(self):
 
43
        return self.name
 
44
 
 
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()])
 
48
 
 
49
    def __repr__(self):
 
50
        replacements = [
 
51
            ('+','__plus__'),
 
52
            ('-','__minus__'),
 
53
            ('@','__at__'),
 
54
            ('!','__exclam__'),
 
55
            ('?','__quest__'),
 
56
            ('*','__star__'),
 
57
            ('~','__tilde__')
 
58
            ]
 
59
        text = self.name
 
60
        for orig,sub in replacements:
 
61
            text = text.replace(orig,sub)
 
62
        return text
 
63
 
 
64
 
 
65
 
 
66
all_particles = []
 
67
 
 
68
    
 
69
 
 
70
class Particle(UFOBaseClass):
 
71
    """A standard Particle""" 
 
72
 
 
73
    require_args=['pdg_code', 'name', 'antiname', 'spin', 'color', 'mass', 'width', 'texname', 'antitexname', 'charge']
 
74
 
 
75
    require_args_all = ['pdg_code', 'name', 'antiname', 'spin', 'color', 'mass', 'width', 'texname', 'antitexname', 'charge', 'loop_particles', 'counterterm','line', 'propagating', 'goldstoneboson']
 
76
 
 
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):
 
79
 
 
80
        args= (pdg_code, name, antiname, spin, color, mass, width, texname,
 
81
                 antitexname, float(charge))
 
82
 
 
83
        UFOBaseClass.__init__(self, *args,  **options)
 
84
 
 
85
        global all_particles
 
86
        all_particles.append(self)
 
87
 
 
88
        self.propagating = propagating
 
89
        self.goldstoneboson= goldstoneboson
 
90
 
 
91
        self.selfconjugate = (name == antiname)
 
92
        if 1: #not line:
 
93
            self.line = self.find_line_type()
 
94
        else:
 
95
            self.line = line
 
96
 
 
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
 
100
        """
 
101
        
 
102
        spin = self.spin
 
103
        color = self.color
 
104
        
 
105
        #use default
 
106
        if spin == 1:
 
107
            return 'dashed'
 
108
        elif spin == 2:
 
109
            if not self.selfconjugate:
 
110
                return 'straight'
 
111
            elif color == 1:
 
112
                return 'swavy'
 
113
            else:
 
114
                return 'scurly'
 
115
        elif spin == 3:
 
116
            if color == 1:
 
117
                return 'wavy'
 
118
            
 
119
            else:
 
120
                return 'curly'
 
121
        elif spin == 5:
 
122
            return 'double'
 
123
        elif spin == -1:
 
124
            return 'dotted'
 
125
        else:
 
126
            return 'dashed' # not supported yet
 
127
 
 
128
    def anti(self):
 
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) 
 
132
        outdic = {}
 
133
        for k,v in self.__dict__.iteritems():
 
134
            if k not in self.require_args_all:                
 
135
                outdic[k] = -v
 
136
        if self.color in [1,8]:
 
137
            newcolor = self.color
 
138
        else:
 
139
            newcolor = -self.color
 
140
                
 
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)
 
143
 
 
144
 
 
145
 
 
146
all_parameters = []
 
147
 
 
148
class Parameter(UFOBaseClass):
 
149
 
 
150
    require_args=['name', 'nature', 'type', 'value', 'texname']
 
151
 
 
152
    def __init__(self, name, nature, type, value, texname, lhablock=None, lhacode=None):
 
153
 
 
154
        args = (name,nature,type,value,texname)
 
155
 
 
156
        UFOBaseClass.__init__(self, *args)
 
157
 
 
158
        args=(name,nature,type,value,texname)
 
159
 
 
160
        global all_parameters
 
161
        all_parameters.append(self)
 
162
 
 
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
 
167
 
 
168
all_CTparameters = []
 
169
 
 
170
class CTParameter(UFOBaseClass):
 
171
 
 
172
    require_args=['name', 'nature,', 'type', 'value', 'texname']
 
173
 
 
174
    def __init__(self, name, type, value, texname):
 
175
 
 
176
        args = (name,'internal',type,value,texname)
 
177
 
 
178
        UFOBaseClass.__init__(self, *args)
 
179
 
 
180
        args=(name,'internal',type,value,texname)
 
181
 
 
182
        self.nature='interal'
 
183
 
 
184
        global all_CTparameters
 
185
        all_CTparameters.append(self)
 
186
 
 
187
    def finite(self):
 
188
        try:
 
189
            return self.value[0]
 
190
        except KeyError:
 
191
            return 'ZERO'
 
192
    
 
193
    def pole(self, x):
 
194
        try:
 
195
            return self.value[-x]
 
196
        except KeyError:
 
197
            return 'ZERO'
 
198
 
 
199
all_vertices = []
 
200
 
 
201
class Vertex(UFOBaseClass):
 
202
 
 
203
    require_args=['name', 'particles', 'color', 'lorentz', 'couplings']
 
204
 
 
205
    def __init__(self, name, particles, color, lorentz, couplings, **opt):
 
206
 
 
207
        args = (name, particles, color, lorentz, couplings)
 
208
 
 
209
        UFOBaseClass.__init__(self, *args, **opt)
 
210
 
 
211
        args=(particles,color,lorentz,couplings)
 
212
        
 
213
        global all_vertices
 
214
        all_vertices.append(self)
 
215
 
 
216
all_CTvertices = []
 
217
 
 
218
class CTVertex(UFOBaseClass):
 
219
 
 
220
    require_args=['name', 'particles', 'color', 'lorentz', 'couplings', 'type', 'loop_particles']
 
221
 
 
222
    def __init__(self, name, particles, color, lorentz, couplings, type, loop_particles, **opt):
 
223
 
 
224
        args = (name, particles, color, lorentz, couplings, type, loop_particles)
 
225
 
 
226
        UFOBaseClass.__init__(self, *args, **opt)
 
227
 
 
228
        args=(particles,color,lorentz,couplings, type, loop_particles)
 
229
        
 
230
        global all_CTvertices
 
231
        all_CTvertices.append(self)
 
232
 
 
233
all_couplings = []
 
234
 
 
235
class Coupling(UFOBaseClass):
 
236
 
 
237
    require_args=['name', 'value', 'order']
 
238
 
 
239
    require_args_all=['name', 'value', 'order', 'loop_particles', 'counterterm']
 
240
 
 
241
    def __init__(self, name, value, order, loop_particles=None, counterterm=None, **opt):
 
242
 
 
243
        args =(name, value, order)      
 
244
        UFOBaseClass.__init__(self, *args, **opt)
 
245
        global all_couplings
 
246
        all_couplings.append(self)
 
247
   
 
248
    def value(self):
 
249
        return self.pole(0)
 
250
 
 
251
    def pole(self, x):
 
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."""
 
254
        
 
255
        if isinstance(self.value,dict):
 
256
            if -x in self.value.keys():
 
257
                return self.value[-x]
 
258
            else:
 
259
                return 'ZERO'
 
260
 
 
261
        CTparam=None
 
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:
 
266
               if not CTparam:
 
267
                   CTparam=param
 
268
               else:
 
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."
 
272
 
 
273
        if not CTparam:
 
274
            if x==0:
 
275
                return self.value
 
276
            else:
 
277
                return 'ZERO'
 
278
        else:
 
279
            if CTparam.pole(x)=='ZERO':
 
280
                return 'ZERO'
 
281
            else:
 
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)
 
286
 
 
287
all_lorentz = []
 
288
 
 
289
class Lorentz(UFOBaseClass):
 
290
 
 
291
    require_args=['name','spins','structure']
 
292
    
 
293
    def __init__(self, name, spins, structure='external', **opt):
 
294
        args = (name, spins, structure)
 
295
        UFOBaseClass.__init__(self, *args, **opt)
 
296
 
 
297
        global all_lorentz
 
298
        all_lorentz.append(self)
 
299
 
 
300
 
 
301
all_functions = []
 
302
 
 
303
class Function(object):
 
304
 
 
305
    def __init__(self, name, arguments, expression):
 
306
 
 
307
        global all_functions
 
308
        all_functions.append(self)
 
309
 
 
310
        self.name = name
 
311
        self.arguments = arguments
 
312
        self.expr = expression
 
313
    
 
314
    def __call__(self, *opt):
 
315
 
 
316
        for i, arg in enumerate(self.arguments):
 
317
            exec('%s = %s' % (arg, opt[i] ))
 
318
 
 
319
        return eval(self.expr)
 
320
 
 
321
all_orders = []
 
322
 
 
323
class CouplingOrder(object):
 
324
 
 
325
    def __init__(self, name, expansion_order, hierarchy, perturbative_expansion = 0):
 
326
        
 
327
        global all_orders
 
328
        all_orders.append(self)
 
329
 
 
330
        self.name = name
 
331
        self.expansion_order = expansion_order
 
332
        self.hierarchy = hierarchy
 
333
        self.perturbative_expansion = perturbative_expansion