• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

APN-Pucky / feynamp / 9267239762

28 May 2024 09:53AM UTC coverage: 80.215% (-2.1%) from 82.348%
9267239762

Pull #67

github

APN-Pucky
fix: PREFACTOR
Pull Request #67: add: spin correlation

13 of 43 new or added lines in 5 files covered. (30.23%)

31 existing lines in 3 files now uncovered.

896 of 1117 relevant lines covered (80.21%)

0.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

65.94
/feynamp/form/lorentz.py
1
from typing import List
1✔
2

3
from feynml.feynmandiagram import FeynmanDiagram
1✔
4
from feynml.leg import Leg
1✔
5
from feynmodel.feyn_model import FeynModel
1✔
6

7
from feynamp.form.form import get_dummy_index, init, run, string_to_form
1✔
8
from feynamp.leg import find_leg_in_model, get_leg_momentum, is_vector
1✔
9
from feynamp.log import debug
1✔
10
from feynamp.momentum import insert_mass, insert_momentum
1✔
11
from feynamp.util import is_mass_zero
1✔
12

13
gammas = """
1✔
14
repeat;
15
* identity
16
    id Gamma(Mua?,Spinb?,Spinc?) * GammaId(Spinc?,Spind?) = Gamma(Mua,Spinb,Spind);
17
    id Gamma(Mua?,Spinb?,Spinc?) * GammaId(Spind?,Spinb?) = Gamma(Mua,Spind,Spinc);
18
    id GammaId(Spina?,Spinb?) * GammaId(Spinb?,Spind?) = GammaId(Spina,Spind);
19
    id GammaId(Spina?,Spina?) = 4;
20
* Metric
21
    id Metric(Mua?,Mub?) * Gamma(Mua?,Spind?,Spinf?) = Gamma(Mub,Spind,Spinf);
22
    id Metric(Mua?,Mub?) * P(Mua?,Momd?) = P(Mub,Momd);
23
    id Metric(Mua?,Mub?) * Metric(Mub?,Mua?) = 4;
24
    id Metric(Mua?,Mub?) * Metric(Mub?,Muc?) = Metric(Mua,Muc);
25
    id Metric(Mua?,Mua?) = 4;
26
* standard Gamma algebra
27
    id Gamma(Mua?,Spinb?,Spinc?)*Gamma(Mua?,Spinc?,Spind?) = -GammaId(Spinb,Spind);
28
    id Gamma(Mua?,Spinb?,Spinc?)*Gamma(Mud?,Spinc?,Spine?)*Gamma(Mua?,Spine?,Spinf?) = -2*Gamma(Mud,Spinb,Spinf);
29
    id Gamma(Mua?,Spinb?,Spinc?)*Gamma(Mud?,Spinc?,Spine?)*Gamma(Muf?,Spine?,Spinm?)*Gamma(Mua?,Spinm?,Spink?) = 4*Metric(Mud,Muf)*GammaId(Spinb,Spink);
30
    id Gamma(Mua?,Spinb?,Spinc?)*Gamma(Mud?,Spinc?,Spine?)*Gamma(Muf?,Spine?,Spinm?)*Gamma(Muk?,Spinm?,Spinl?)*Gamma(Mua?,Spinl?,Spinj?) = -2*Gamma(Muk,Spinb,Spinc)*Gamma(Muf,Spinc,Spinl)*Gamma(Mud,Spinl,Spinj);
31
* traces of Gamma
32
    id Gamma(Mua?,Spinb?,Spinb?) = 0;
33
    id Gamma(Mua?,Spinb?,Spinc?)*Gamma(Mub?,Spinc?,Spinb?) = 4*Metric(Mua,Mub);
34
    id Gamma(Mua?,Spinb?,Spinc?)*Gamma(Mub?,Spinc?,Spind?)*Gamma(Muc?,Spind?,Spinb?) = 0;
35
    id Gamma(Mua?,Spinb?,Spinc?)*Gamma(Mub?,Spinc?,Spind?)*Gamma(Muc?,Spind?,Spine?)*Gamma(Mud?,Spine?,Spinb?) 
36
        = 4*(Metric(Mua,Mub)*Metric(Muc,Mud) - Metric(Mua,Muc)*Metric(Mub,Mud)+ Metric(Mua,Mud)*Metric(Mub,Muc)) ;
37
    id Gamma(Mua?,Spinb?,Spinc?)*Gamma(Mub?,Spinc?,Spind?)*Gamma(Muc?,Spind?,Spine?)*Gamma(Mud?,Spine?,Spinf?)*Gamma(Mue?,Spinf?,Sping?)*Gamma(Muf?,Sping?,Spinb?)
38
        = 4*(Metric(Mua,Mub)*Metric(Muc,Mud)*Metric(Mue,Muf) 
39
           - Metric(Mua,Mub)*Metric(Muc,Mue)*Metric(Mud,Muf) 
40
           + Metric(Mua,Mub)*Metric(Muc,Muf)*Metric(Mud,Mue) 
41
           - Metric(Mua,Muc)*Metric(Mub,Mud)*Metric(Mue,Muf) 
42
           + Metric(Mua,Muc)*Metric(Mub,Mue)*Metric(Mud,Muf) 
43
           - Metric(Mua,Muc)*Metric(Mub,Muf)*Metric(Mud,Mue) 
44
           + Metric(Mua,Mud)*Metric(Mub,Muc)*Metric(Mue,Muf) 
45
           - Metric(Mua,Mud)*Metric(Mub,Mue)*Metric(Muc,Muf) 
46
           + Metric(Mua,Mud)*Metric(Mub,Muf)*Metric(Muc,Mue)
47
           - Metric(Mua,Mue)*Metric(Mub,Muc)*Metric(Mud,Muf)
48
           + Metric(Mua,Mue)*Metric(Mub,Mud)*Metric(Muc,Muf)
49
           - Metric(Mua,Mue)*Metric(Mub,Muf)*Metric(Muc,Mud)
50
           + Metric(Mua,Muf)*Metric(Mub,Muc)*Metric(Mud,Mue)
51
           - Metric(Mua,Muf)*Metric(Mub,Mud)*Metric(Muc,Mue)
52
           + Metric(Mua,Muf)*Metric(Mub,Mue)*Metric(Muc,Mud));
53
endrepeat;
54
"""
55

56

57
# TODO implement collecting of gammas and form calc solving of it
58
# idea: GammaCollect(1,spin1,spin2, mu,nu,...) run through and then apply to expression
59
gamma_collect = """
1✔
60
#do i = 1, 10
61
once Gamma(Mux?,Spin1?,Spin2?) = GammaCollect(`i',Spin1,Spin2,Mux);
62
repeat;
63
id GammaCollect(`i',Spin1?,Spin2?,?mus)*Gamma(Mux?, Spin2?,Spin3?) = GammaCollect(`i',Spin1,Spin3, ?mus, Mux);
64
id GammaCollect(`i',Spin1?,Spin2?,?mus)*GammaId(Spin2?,Spin3?) = GammaCollect(`i',Spin1,Spin3, ?mus)*gi_(`i');
65
endrepeat;
66
id GammaCollect(`i',Spin1?,Spin1?,?mus) = g_(`i',?mus);
67
trace4, `i';
68
#enddo
69
#do i = 11, 21
70
once GammaId(Spin1?,Spin2?) = GammaIdCollect(`i',Spin1,Spin2);
71
repeat;
72
id GammaIdCollect(`i',Spin1?,Spin2?)*GammaId(Spin2?,Spin3?) = GammaIdCollect(`i',Spin1,Spin3)*gi_(`i');
73
endrepeat;
74
id GammaIdCollect(`i',Spin1?,Spin1?) = 1;
75
trace4, `i';
76
#enddo
77
"""
78

79
metrics = """
1✔
80
* Simplify metrics, here let form handle it 
81
repeat;
82
id Metric(Mua?,Mub?) = d_(Mua,Mub);
83
endrepeat;
84
"""
85

86

87
def get_metrics():
1✔
88
    return metrics
1✔
89

90

91
def apply_metrics(string_expr):
1✔
92
    s = string_to_form(string_expr)
×
93
    from .color import color_init
×
94

95
    return run(init + color_init + f"Local TMP = {s};" + get_metrics())
×
96

97

98
def get_gammas(fds, model):
1✔
99
    return get_gammas_v3(fds, model)
1✔
100

101

102
def get_gammas_v3(fds, model):
1✔
103
    return get_dirac_tricks(fds, model) + get_metrics() + gamma_collect
1✔
104

105

106
def get_gammas_v2():
1✔
107
    return get_dirac_trick_v1() + get_metrics() + gamma_collect
×
108

109

110
def get_gammas_v1():
1✔
111
    return get_polarisation_sum_v1() + get_dirac_trick_v1() + gammas
1✔
112

113

114
def apply_gammas(string_expr):
1✔
115
    s = string_to_form(string_expr)
×
116
    return run(init + f"Local TMP = {s};" + get_gammas())
×
117

118

119
def apply_gammas_v1(string_expr):
1✔
120
    s = string_to_form(string_expr)
1✔
121
    return run(init + f"Local TMP = {s};" + get_gammas_v1())
1✔
122

123

124
def get_orthogonal_polarisation_momentum(
1✔
125
    leg: Leg, fds: List[FeynmanDiagram], model: FeynModel
126
):
127
    for fd in [fds[0]]:
1✔
128
        for fleg in fd.legs:
1✔
129
            p = find_leg_in_model(fd, fleg, model)
1✔
130
            if (
1✔
131
                is_mass_zero(p)
132
                and fleg != leg
133
                and leg.is_incoming() == fleg.is_incoming()
134
            ):
135
                mom = insert_momentum(fleg.momentum.name)
1✔
136
                return mom
1✔
137
    raise ValueError("No orthogonal momentum found")
×
138

139

140
def get_polarisation_sums(
1✔
141
    fds: List[FeynmanDiagram], model: FeynModel, spincorrelated=False
142
):
143
    pol_sums = ""
1✔
144
    if spincorrelated:
1✔
NEW
145
        legs = fds[0].legs
×
NEW
146
        left = ""
×
NEW
147
        right = ""
×
NEW
148
        mom = []
×
NEW
149
        ind1 = []
×
NEW
150
        ind2 = []
×
NEW
151
        isvec = []
×
NEW
152
        for i, leg in enumerate(legs):
×
NEW
153
            mom += [get_leg_momentum(leg)]
×
NEW
154
            ind1 += [f"Pol{leg.id}"]
×
NEW
155
            ind2 += [f"Pol{get_dummy_index(underscore=False, questionmark=False)}"]
×
NEW
156
            isvec += [is_vector(fds[0], leg, model)]
×
NEW
157
        for i, legi in enumerate(legs):
×
NEW
158
            if isvec[i]:
×
NEW
159
                mom = mom[i]
×
NEW
160
                i1 = ind1[i]
×
NEW
161
                i2 = ind2[i]
×
NEW
162
                left += f"VPol({i1},{mom})*VPol({i2},{mom})*"
×
NEW
163
                deltas = "*"
×
NEW
164
                for k in range(len(legs)):
×
NEW
165
                    if isvec[k] and k != i and k != j:
×
NEW
166
                        deltas += f"d_({ind1[k]},{ind2[k]})*"
×
NEW
167
                right += f"\nspincorrelation({mom[i]},MuMu,MuNu)*epsstar(MuMu,{i1},{mom})*eps(MuNu,{i2},{mom}){deltas[:-1]}+"
×
NEW
168
        if right == "" or left == "":
×
169
            # There is nothing to correlate => force the result to be 0
NEW
170
            pol_sums += "id PREFACTOR = 0;"
×
171
        else:
NEW
172
            pol_sums += f"""
×
173
        id {left} = ({right});
174
        """
NEW
175
            print(f"{pol_sums=}")
×
176
    else:
177
        pol_sums += """
1✔
178
    repeat;
179
    id VPol(Polb?,Moma?) * VPol(Pold?,Moma?) = d_(Polb,Pold);
180
    endrepeat;
181
    """
182

183
    # TODO might want to loop over all fds?
184
    for fd in [fds[0]]:
1✔
185
        for l in fd.legs:
1✔
186
            p = find_leg_in_model(fd, l, model)
1✔
187
            mom = insert_momentum(l.momentum.name)
1✔
188
            # mass = insert_mass(string_to_form(p.mass.name))
189
            if p.spin == 3:
1✔
190
                if is_mass_zero(p):
1✔
191
                    if p.color == 8:
1✔
192
                        mom_n = get_orthogonal_polarisation_momentum(l, fds, model)
1✔
193
                        pol_sums += get_polarisation_sum_physical(mom, mom_n)
1✔
194
                        # pol_sums += get_polarisation_sum_feynman(mom)
195
                        debug(f"mom: {mom}, mom_n: {mom_n}")
1✔
196
                    elif p.color == 1:
1✔
197
                        pol_sums += get_polarisation_sum_feynman(mom)
1✔
198
                else:
UNCOV
199
                    pol_sums += get_polarisation_sum_massive(mom)
×
200
    debug(f"pol_sums: {pol_sums}")
1✔
201
    return pol_sums
1✔
202

203

204
def get_polarisation_sum_massive(mom_a):
1✔
UNCOV
205
    pol_sum = f"""
×
206
    id epsstar(Muc?,Polb?,{mom_a}) * eps(Mul?,Polb?,{mom_a}) = -Metric(Mul,Muc) + (P(Mul,{mom_a})*P(Muc,{mom_a}))*Den({mom_a}.{mom_a});
207
    """
208
    return pol_sum
×
209

210

211
def get_polarisation_sum_feynman(mom_a):
1✔
212
    pol_sum = f"""
1✔
213
    id epsstar(Muc?,Polb?,{mom_a}) * eps(Mul?,Polb?,{mom_a}) = -Metric(Mul,Muc);
214
    """
215
    return pol_sum
1✔
216

217

218
def get_polarisation_sum_physical(mom_a, mom_b):
1✔
219
    pol_sum = f"""
1✔
220
    id epsstar(Muc?,Polb?,{mom_a}) * eps(Mul?,Polb?,{mom_a}) = -Metric(Muc,Mul) 
221
    + (P(Muc,{mom_a})*P(Mul,{mom_b}) +  P(Mul,{mom_a})*P(Muc,{mom_b}))*Den({mom_b}.{mom_a}) 
222
    - P(Muc,{mom_a})*P(Mul,{mom_a})*({mom_b}.{mom_b})*Den({mom_b}.{mom_a})*Den({mom_b}.{mom_a});
223
    """
224
    return pol_sum
1✔
225

226

227
def get_polarisation_sum(mom_a, mom_b=None):
1✔
UNCOV
228
    if mom_b is None:
×
229
        # massive case
UNCOV
230
        return get_polarisation_sum_massive(mom_a)
×
231
    elif mom_b == 0:
×
232
        # photon massless case
233
        return get_polarisation_sum_feynman(mom_a)
×
234
    else:
235
        # gluon massless case
236
        return get_polarisation_sum_physical(mom_a, mom_b)
×
237

238

239
def get_polarisation_sum_v1():
1✔
240
    polsum_feyn = """
1✔
241
    id epsstar(Muc?,Polb?,Moma?) * eps(Mul?,Pold?,Moma?) = -Metric(Muc,Mul);
242
    """
243
    polsum_feyn = """
1✔
244
    id epsstar(Muc?,Polb?,Moma?) * eps(Mul?,Pold?,Moma?) = -Metric(Mul,Muc);
245
    """
246
    return polsum_feyn
1✔
247

248

249
# TODO figure out why this does not work but manual dummies work
250
dirac_trick = """
1✔
251
repeat;
252
    id u(Spinc?,Momb?)*ubar(Spina?,Momb?) = Gamma(N5_?,Spinc,Spina) * P(N5_?,Momb) + GammaId(Spinc,Spina) * P(N5_?,Momb) * P(N5_?,Momb);
253
    id vbar(Spinc?,Momb?)*v(Spina?,Momb?) = Gamma(N7_?,Spinc,Spina) * P(N7_?,Momb) - GammaId(Spinc,Spina) * P(N7_?,Momb) * P(N7_?,Momb);
254
endrepeat;
255
"""
256

257

258
def get_dirac_tricks(fds: List[FeynmanDiagram], model: FeynModel):
1✔
259
    ret = ""
1✔
260
    # TODO might want to loop over all fds?
261
    for fd in [fds[0]]:
1✔
262
        for l in fd.legs:
1✔
263
            p = find_leg_in_model(fd, l, model)
1✔
264
            mom = insert_momentum(l.momentum.name)
1✔
265
            mass = insert_mass(string_to_form(p.mass.name))
1✔
266
            if p.spin == 2:
1✔
267
                dummy = get_dummy_index()
1✔
268
                ret += f"""
1✔
269
    once u(Spinc?,{mom})*ubar(Spina?,{mom}) = Gamma({dummy},Spinc,Spina) * P({dummy},{mom}) + GammaId(Spinc,Spina) * {mass};
270
    """
271
                dummy = get_dummy_index()
1✔
272
                ret += f"""
1✔
273
    once vbar(Spinc?,{mom})*v(Spina?,{mom}) = Gamma({dummy},Spinc,Spina) * P({dummy},{mom}) - GammaId(Spinc,Spina) * {mass};
274
    """
275
    return ret
1✔
276

277

278
def get_dirac_trick_v1(N=10):
1✔
279
    ret = ""
1✔
280
    for i in range(N):
1✔
281
        dummy = get_dummy_index()
1✔
282
        dirac_trick = f"""
1✔
283
    once u(Spinc?,Momb?)*ubar(Spina?,Momb?) = Gamma({dummy},Spinc,Spina) * P({dummy},Momb) + GammaId(Spinc,Spina) *  P({dummy},Momb) * P({dummy},Momb);
284
    """
285
        ret += dirac_trick
1✔
286
    for i in range(N):
1✔
287
        dummy = get_dummy_index()
1✔
288
        dirac_trick = f"""
1✔
289
    once vbar(Spinc?,Momb?)*v(Spina?,Momb?) = Gamma({dummy},Spinc,Spina) * P({dummy},Momb) - GammaId(Spinc,Spina) *P({dummy},Momb) * P({dummy},Momb) ;
290
    """
291
        ret += dirac_trick
1✔
292
    return ret
1✔
293

294

295
# TODO: look above
296
# def get_dirac_trick():
297
#    return dirac_trick
298

299

300
def apply_dirac_trick(string_expr):
1✔
UNCOV
301
    s = string_to_form(string_expr)
×
UNCOV
302
    return run(init + f"Local TMP = {s};" + get_dirac_trick())
×
303

304

305
def apply_polarisation_sum(string_expr):
1✔
UNCOV
306
    s = string_to_form(string_expr)
×
UNCOV
307
    return run(init + f"Local TMP = {s};" + get_polarisation_sum())
×
308

309

310
# TODO: implement this use forms gamma algebra
311
def replace_indices_by_line():
1✔
312
    # return list of lines
UNCOV
313
    pass
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc