~maddevelopers/mg5amcnlo/3.0.2-alpha0-merged3.2.0

« back to all changes in this revision

Viewing changes to tests/loop_smgrav/object_library.py

  • Committer: olivier-mattelaer
  • Date: 2021-05-06 14:57:23 UTC
  • mfrom: (956.2.9 3.0)
  • Revision ID: olivier-mattelaer-20210506145723-oasykft3zdy37td2
merge with 3.1.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