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