thepeg
is hosted by
Hepforge
,
IPPP Durham
ThePEG
2.3.0
Helicity
HelicityFunctions.h
1
// -*- C++ -*-
2
//
3
// HelicityFunctions.h is a part of ThePEG - Toolkit for HEP Event Generation
4
// Copyright (C) 2003-2019 Peter Richardson, Leif Lonnblad
5
//
6
// ThePEG is licenced under version 3 of the GPL, see COPYING for details.
7
// Please respect the MCnet academic guidelines, see GUIDELINES for details.
8
//
9
#ifndef ThePEG_HelicityFunctions_H
10
#define ThePEG_HelicityFunctions_H
11
//
12
// This is the declaration of the HelicityFunctions header for common functions
13
// used in helicity calculations to avoid duplication of code
14
15
#include "
ThePEG/Vectors/LorentzVector.h
"
16
#include "LorentzSpinor.h"
17
#include "LorentzSpinorBar.h"
18
19
namespace
ThePEG
{
20
namespace
Helicity {
21
namespace
HelicityFunctions {
22
23
inline
LorentzPolarizationVector
polarizationVector(
const
Lorentz5Momentum
& p,
24
unsigned
int
ihel,
25
Direction dir,
26
VectorPhase
vphase=
default_vector_phase
) {
27
// check the direction
28
assert(dir!=
intermediate
);
29
// special helicity combination for gauge invariance tests
30
if
(ihel==10)
return
p*UnitRemoval::InvE;
31
// check a valid helicity combination
32
assert(ihel==0 || ihel == 2 || ((ihel==1 || ihel==3) && p.mass()>
ZERO
));
33
// convert the helicitty from 0,1,2 to -1,0,1
34
int
jhel=ihel-1;
35
// extract the momentum components
36
double
fact = dir==
outgoing
? -1 : 1;
37
Energy
ppx=fact*p.x(),ppy=fact*p.y(),ppz=fact*p.z(),pee=fact*p.e(),pmm=p.mass();
38
// calculate some kinematic quantites
39
Energy2 pt2 = ppx*ppx+ppy*ppy;
40
Energy
pabs = sqrt(pt2+ppz*ppz);
41
Energy
pt = sqrt(pt2);
42
// zero subtracted
43
if
(ihel==3) {
44
InvEnergy pre = pmm/pabs/(pee+pabs);
45
return
LorentzPolarizationVector
(
double
(pre*ppx),
double
(pre*ppy),
double
(pre*ppz),-
double
(pre*pabs));
46
}
47
// overall phase of the vector
48
Complex
phase(1.);
49
if
(vphase==
vector_phase
) {
50
if
(pt==
ZERO
|| ihel==1) phase = 1.;
51
else
if
(ihel==0) phase =
Complex
(ppx/pt,-fact*ppy/pt);
52
else
phase =
Complex
(ppx/pt, fact*ppy/pt);
53
}
54
if
(ihel!=1) phase = phase/sqrt(2.);
55
// first the +/-1 helicity states
56
if
(ihel!=1) {
57
// first the zero pt case
58
if
(pt==
ZERO
) {
59
double
sgnz = ppz<
ZERO
? -1. : 1.;
60
return
LorentzPolarizationVector
(-complex<double>(jhel)*phase,
61
sgnz*phase*complex<double>(0,-fact),
62
0.,0.);
63
}
64
else
{
65
InvEnergy opabs=1./pabs;
66
InvEnergy opt =1./pt;
67
return
LorentzPolarizationVector
(phase*complex<double>(-jhel*ppz*ppx*opabs*opt, fact*ppy*opt),
68
phase*complex<double>(-jhel*ppz*ppy*opabs*opt,-fact*ppx*opt),
69
double
(jhel*pt*opabs)*phase,0.);
70
}
71
}
72
// 0 component for massive vectors
73
else
{
74
if
(pabs==
ZERO
) {
75
return
LorentzPolarizationVector
(0.,0.,1.,0.);
76
}
77
else
{
78
InvEnergy empabs=pee/pmm/pabs;
79
return
LorentzPolarizationVector
(
double
(empabs*ppx),
double
(empabs*ppy),
80
double
(empabs*ppz),
double
(pabs/pmm));
81
}
82
}
83
}
84
85
86
inline
LorentzSpinor<SqrtEnergy> dimensionedSpinor(
const
Lorentz5Momentum
& p,
87
unsigned
int
ihel,
88
Direction dir) {
89
// check direction and helicity
90
assert(dir!=
intermediate
);
91
assert(ihel<=1);
92
// extract the momentum components
93
double
fact = dir==
incoming
? 1 : -1.;
94
Energy
ppx=fact*p.x(),ppy=fact*p.y(),ppz=fact*p.z(),pee=fact*p.e(),pmm=p.mass();
95
// define and calculate some kinematic quantities
96
Energy2 ptran2 = ppx*ppx+ppy*ppy;
97
Energy
pabs = sqrt(ptran2+ppz*ppz);
98
Energy
ptran = sqrt(ptran2);
99
// first need to evalulate the 2-component helicity spinors
100
// this is the same regardless of which definition of the spinors
101
// we are using
102
complex <double> hel_wf[2];
103
// compute the + spinor for + helicty particles and - helicity antiparticles
104
if
((dir==
incoming
&& ihel== 1) || (dir==
outgoing
&& ihel==0)) {
105
// no transverse momentum
106
if
(ptran==
ZERO
) {
107
if
(ppz>=
ZERO
) {
108
hel_wf[0] = 1;
109
hel_wf[1] = 0;
110
}
111
else
{
112
hel_wf[0] = 0;
113
hel_wf[1] = 1;
114
}
115
}
116
else
{
117
InvSqrtEnergy denominator = 1./sqrt(2.*pabs);
118
SqrtEnergy rtppluspz = (ppz>=
ZERO
) ? sqrt(pabs+ppz) : ptran/sqrt(pabs-ppz);
119
hel_wf[0] = denominator*rtppluspz;
120
hel_wf[1] =
Complex
(denominator/rtppluspz*complex<Energy>(ppx,ppy));
121
}
122
}
123
// compute the - spinor for - helicty particles and + helicity antiparticles
124
else
{
125
// no transverse momentum
126
if
(ptran==
ZERO
) {
127
if
(ppz>=
ZERO
) {
128
hel_wf[0] = 0;
129
hel_wf[1] = 1;
130
}
131
// transverse momentum
132
else
{
133
hel_wf[0] = -1;
134
hel_wf[1] = 0;
135
}
136
}
137
else
{
138
InvSqrtEnergy denominator = 1./sqrt(2.*pabs);
139
SqrtEnergy rtppluspz = (ppz>=
ZERO
) ? sqrt(pabs+ppz) : ptran/sqrt(pabs-ppz);
140
hel_wf[0] =
Complex
(denominator/rtppluspz*complex<Energy>(-ppx,ppy));
141
hel_wf[1] = denominator*rtppluspz;
142
}
143
}
144
145
SqrtEnergy upper,lower;
146
SqrtEnergy eplusp = sqrt(max(pee+pabs,
ZERO
));
147
SqrtEnergy eminusp = ( pmm !=
ZERO
) ? pmm/eplusp :
ZERO
;
148
// set up the coefficients for the different cases
149
if
(dir==
incoming
) {
150
if
(ihel==1) {
151
upper = eminusp;
152
lower = eplusp;
153
}
154
else
{
155
upper = eplusp;
156
lower = eminusp;
157
}
158
}
159
else
{
160
if
(ihel==1) {
161
upper = -eplusp;
162
lower = eminusp;
163
}
164
else
{
165
upper = eminusp;
166
lower =-eplusp;
167
}
168
}
169
return
LorentzSpinor<SqrtEnergy>(upper*hel_wf[0],upper*hel_wf[1],
170
lower*hel_wf[0],lower*hel_wf[1],
171
(dir==
incoming
) ?
SpinorType::u
:
SpinorType::v
);
172
}
173
174
inline
LorentzSpinor<double> spinor(
const
Lorentz5Momentum
& p,
175
unsigned
int
ihel,
176
Direction dir) {
177
LorentzSpinor<SqrtEnergy> temp = dimensionedSpinor(p,ihel,dir);
178
return
LorentzSpinor<double>(temp.s1()*UnitRemoval::InvSqrtE,
179
temp.s2()*UnitRemoval::InvSqrtE,
180
temp.s3()*UnitRemoval::InvSqrtE,
181
temp.s4()*UnitRemoval::InvSqrtE,temp.Type());
182
}
183
184
inline
LorentzSpinorBar<SqrtEnergy> dimensionedSpinorBar(
const
Lorentz5Momentum
& p,
185
unsigned
int
ihel,
186
Direction dir) {
187
// check direction and helicity
188
assert(dir!=
intermediate
);
189
assert(ihel<=1);
190
// extract the momentum components
191
double
fact = dir==
incoming
? 1. : -1.;
192
Energy
ppx=fact*p.x(),ppy=fact*p.y(),ppz=fact*p.z(),pee=fact*p.e(),pmm=p.mass();
193
// define and calculate some kinematic quantities
194
Energy2 ptran2 = ppx*ppx+ppy*ppy;
195
Energy
pabs = sqrt(ptran2+ppz*ppz);
196
Energy
ptran = sqrt(ptran2);
197
// first need to evalulate the 2-component helicity spinors
198
Complex
hel_wf[2];
199
// compute the + spinor for + helicty particles and - helicity antiparticles
200
if
((dir==
outgoing
&& ihel== 1) || (dir==
incoming
&& ihel==0)) {
201
// no transverse momentum
202
if
(ptran==
ZERO
) {
203
if
(ppz>=
ZERO
) {
204
hel_wf[0] = 1;
205
hel_wf[1] = 0;
206
}
207
else
{
208
hel_wf[0] = 0;
209
hel_wf[1] = 1;
210
}
211
}
212
else
{
213
InvSqrtEnergy denominator = 1./sqrt(2.*pabs);
214
SqrtEnergy rtppluspz = (ppz>=
ZERO
) ? sqrt(pabs+ppz) : ptran/sqrt(pabs-ppz);
215
hel_wf[0] = denominator*rtppluspz;
216
hel_wf[1] =
Complex
(denominator/rtppluspz*complex<Energy>(ppx,-ppy));
217
}
218
}
219
// compute the - spinor for - helicty particles and + helicity antiparticles
220
else
{
221
// no transverse momentum
222
if
(ptran==
ZERO
) {
223
if
(ppz>=
ZERO
) {
224
hel_wf[0] = 0;
225
hel_wf[1] = 1;
226
}
227
// transverse momentum
228
else
{
229
hel_wf[0] = -1;
230
hel_wf[1] = 0;
231
}
232
}
233
else
{
234
InvSqrtEnergy denominator = 1./sqrt(2.*pabs);
235
SqrtEnergy rtppluspz = (ppz>=
ZERO
) ? sqrt(pabs+ppz) : ptran/sqrt(pabs-ppz);
236
hel_wf[0] =
Complex
(denominator/rtppluspz*complex<Energy>(-ppx,-ppy));
237
hel_wf[1] = denominator*rtppluspz;
238
}
239
}
240
SqrtEnergy upper, lower;
241
SqrtEnergy eplusp = sqrt(max(pee+pabs,
ZERO
));
242
SqrtEnergy eminusp = ( pmm!=
ZERO
) ? pmm/eplusp :
ZERO
;
243
// set up the coefficients for the different cases
244
if
(dir==
outgoing
) {
245
if
(ihel==1) {
246
upper = eplusp;
247
lower = eminusp;
248
}
249
else
{
250
upper = eminusp;
251
lower = eplusp;
252
}
253
}
254
else
{
255
if
(ihel==1) {
256
upper = eminusp;
257
lower = -eplusp;
258
}
259
else
{
260
upper =-eplusp;
261
lower = eminusp;
262
}
263
}
264
// now finally we can construct the spinors
265
return
LorentzSpinorBar<SqrtEnergy>(upper*hel_wf[0],
266
upper*hel_wf[1],
267
lower*hel_wf[0],
268
lower*hel_wf[1],
269
(dir==
incoming
) ?
SpinorType::v
:
SpinorType::u
);
270
}
271
272
inline
LorentzSpinorBar<double> spinorBar(
const
Lorentz5Momentum
& p,
273
unsigned
int
ihel,
274
Direction dir) {
275
LorentzSpinorBar<SqrtEnergy> temp = dimensionedSpinorBar(p,ihel,dir);
276
return
LorentzSpinorBar<double>(temp.s1()*UnitRemoval::InvSqrtE,
277
temp.s2()*UnitRemoval::InvSqrtE,
278
temp.s3()*UnitRemoval::InvSqrtE,
279
temp.s4()*UnitRemoval::InvSqrtE,temp.Type());
280
}
281
}
282
}
283
}
284
285
#endif
/* ThePEG_HelicityFunctions_H */
LorentzVector.h
contains the LorentzVector class.
ThePEG::Helicity::SpinorType::u
@ u
u spinor.
ThePEG::Helicity::SpinorType::v
@ v
v spinor.
ThePEG::Helicity::outgoing
@ outgoing
An outgoing particle.
Definition:
WaveFunctionBase.h:32
ThePEG::Helicity::incoming
@ incoming
An incoming particle.
Definition:
WaveFunctionBase.h:31
ThePEG::Helicity::intermediate
@ intermediate
An intermediate particle.
Definition:
WaveFunctionBase.h:33
ThePEG::Helicity::VectorPhase
VectorPhase
Definition of the enumerated values of the phase to include in the calculation of the polarization ve...
Definition:
HelicityDefinitions.h:47
ThePEG::Helicity::vector_phase
@ vector_phase
Include the phase factor.
Definition:
HelicityDefinitions.h:48
ThePEG::Helicity::default_vector_phase
@ default_vector_phase
Default option.
Definition:
HelicityDefinitions.h:50
ThePEG::Helicity::LorentzPolarizationVector
LorentzVector< complex< double > > LorentzPolarizationVector
Convenience typedef.
Definition:
LorentzPolarizationVector.h:20
ThePEG::Units::Energy
Qty< 0, 1, 0 > Energy
Energy.
Definition:
Unitsystem.h:42
ThePEG::Units::Lorentz5Momentum
Lorentz5Vector< Energy > Lorentz5Momentum
A momentum in four-dimensional space-time with an explicit invariant mass component.
Definition:
Unitsystem.h:156
ThePEG
This is the main namespace within which all identifiers in ThePEG are declared.
Definition:
FactoryBase.h:28
ThePEG::Complex
std::complex< double > Complex
ThePEG code should use Complex for all complex scalars.
Definition:
Complex.h:23
ThePEG::ZERO
constexpr ZeroUnit ZERO
ZERO can be used as zero for any unitful quantity.
Definition:
PhysicalQty.h:35
Generated on Thu Jun 20 2024 14:47:00 for ThePEG by
1.9.6