1
2
3
4
5
6
7
8
9
10
11
12
13 from aloha.aloha_object import *
14 import aloha.aloha_lib as aloha_lib
15 import cmath
16
19
20
21
22
24 """Get the fermion flow follows the UFO convention
25 {I1:O1, I2:O2,...}"""
26
27 assert nb_fermion != 0 and (nb_fermion % 2) == 0
28
29 try:
30 expr = eval(expression)
31 except Exception as error:
32 print error
33 return
34 expr = expr.simplify()
35
36 if expr.vartype != 1:
37 expr = [expr]
38
39 out = {}
40 for term in expr:
41 if term.vartype == 0:
42 if not term.spin_ind in [[1,2], [2,1]]:
43 raise WrongFermionFlow, 'Fermion should be the first particles of any interactions'
44 if isinstance(term, (Gamma, Gamma5, Sigma)):
45 if term.spin_ind == [2,1]:
46 out[1] = 2
47 else:
48 out[2] = 1
49 elif isinstance(term, Identity):
50 out[1] = 2
51
52 elif term.vartype == 2:
53 link, rlink = {}, {}
54 for obj in term:
55 obj = aloha_lib.KERNEL.objs[obj]
56 if not obj.spin_ind:
57 continue
58 ind1, ind2 = obj.spin_ind
59 if ind1 not in link.keys():
60 link[ind1] = ind2
61 else:
62 raise WrongFermionFlow, 'a spin indices should appear only once on the left indices of an object: %s' % expr
63 if ind2 not in rlink.keys():
64 rlink[ind2] = ind1
65 else:
66 raise WrongFermionFlow, 'a spin indices should appear only once on the left indices of an object: %s' % expr
67
68 for i in range(1, nb_fermion):
69 if i in out.keys() or i in out.values():
70 continue
71 old = []
72 pos = i
73 while 1:
74 old.append(pos)
75 if pos in link.keys() and link[pos] not in old:
76 pos = link[pos]
77 elif pos in rlink.keys() and rlink[pos] not in old:
78 pos = rlink[pos]
79 else:
80 if pos in link.keys() and i in rlink.keys():
81 out[i] = pos
82 break
83 elif pos in rlink.keys() and i in link.keys():
84 out[pos] = i
85 break
86 else:
87 raise WrongFermionFlow, 'incoherent IO state: %s' % expr
88 if not len(out) == nb_fermion //2:
89 raise WrongFermionFlow, 'Not coherent Incoming/outcoming fermion flow'
90 return out
91
92
93
95 """Check that the fermion flow follows the UFO convention
96 1) Only one flow is defined and is 1 -> 2, 3 -> 4, ...
97 2) that 1/3/... are on the left side of any Gamma matrices
98 """
99
100 assert nb_fermion != 0 and (nb_fermion % 2) == 0
101
102
103 try:
104 expr = eval(expression)
105 except Exception:
106 return
107 expr = expr.simplify()
108
109 if expr.vartype != 1:
110 expr = [expr]
111
112 for term in expr:
113 if term.vartype == 0:
114 if not term.spin_ind in [[1,2], [2,1]]:
115 raise WrongFermionFlow, 'Fermion should be the first particles of any interactions'
116 if isinstance(term, (Gamma, Gamma5, Sigma)):
117 if not term.spin_ind == [2,1]:
118 raise WrongFermionFlow, 'Not coherent Incoming/outcoming fermion flow'
119
120 elif term.vartype == 2:
121 link, rlink = {}, {}
122 for obj in term:
123 obj = aloha_lib.KERNEL.objs[obj]
124 if not obj.spin_ind:
125 continue
126 ind1, ind2 = obj.spin_ind
127 if isinstance(obj, (Gamma, Sigma)):
128 if (ind1 in range(1, nb_fermion+1) and ind1 % 2 == 1) or \
129 (ind2 in range(2, nb_fermion+1) and ind2 % 2 == 0 ):
130 raise WrongFermionFlow, 'Not coherent Incoming/outcoming fermion flow'
131 if ind1 not in link.keys():
132 link[ind1] = ind2
133 else:
134 rlink[ind1] = ind2
135 if ind2 not in link.keys():
136 link[ind2] = ind1
137 else:
138 rlink[ind2] = ind1
139 for i in range(1, nb_fermion,2):
140 old = []
141 pos = i
142 while 1:
143 old.append(pos)
144 if pos in link.keys() and link[pos] not in old:
145 pos = link[pos]
146 elif pos in rlink.keys() and rlink[pos] not in old:
147 pos = rlink[pos]
148 elif pos != i+1:
149 raise WrongFermionFlow, 'Not coherent Incoming/outcoming fermion flow'
150 elif pos == i+1:
151 break
152
154 """ return (UFO name, tag , offshell) from a given name """
155
156 output =[]
157 for name in names:
158 if name.startswith('MP_'):
159 name = name[3:]
160 tags = ['MP_']
161 else:
162 tags = []
163
164 data = name.split('_')
165 if len(data) == 2:
166 main, offshell = data
167 multiple = []
168 else:
169 main, multiple, offshell = data[0], data[1:-1],data[-1]
170
171
172 allow_tag = ['C1','C2','C3','C4','C5','C6','C7']
173 allow_tag += ['L%s' % i for i in range(1,20)]
174 allow_tag += ['P%s' % i for i in range(0,20)]
175 allow_tag += ['L']
176 tags = []
177
178 len_tag = -1
179 while len(tags) != len_tag:
180 len_tag = len(tags)
181 for tag in allow_tag:
182 if multiple and multiple[-1].endswith(tag):
183 multiple[-1] = multiple[-1][:-len(tag)]
184 tags.append(tag)
185 break
186 elif main.endswith(tag):
187 main = main[:-len(tag)]
188 tags.append(tag)
189 break
190
191
192
193 lorentz = [main]
194 if multiple:
195 base = main
196 while base[-1].isdigit():
197 base = base[:-1]
198 for nb in multiple:
199 lorentz.append('%s%s' % (base, nb))
200
201
202 output.append((tuple(lorentz), tuple(tags), int(offshell)))
203 return output
204