thepeg is hosted by Hepforge, IPPP Durham
ThePEG 2.3.0
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
16#include "LorentzSpinor.h"
17#include "LorentzSpinorBar.h"
18
19namespace ThePEG {
20namespace Helicity {
21namespace HelicityFunctions {
22
23inline LorentzPolarizationVector polarizationVector(const Lorentz5Momentum & p,
24 unsigned int ihel,
25 Direction dir,
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
86inline 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],
172}
173
174inline 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
184inline 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],
270}
271
272inline 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 */
contains the LorentzVector class.
@ outgoing
An outgoing particle.
@ incoming
An incoming particle.
@ intermediate
An intermediate particle.
VectorPhase
Definition of the enumerated values of the phase to include in the calculation of the polarization ve...
@ vector_phase
Include the phase factor.
@ default_vector_phase
Default option.
LorentzVector< complex< double > > LorentzPolarizationVector
Convenience typedef.
Qty< 0, 1, 0 > Energy
Energy.
Definition: Unitsystem.h:42
Lorentz5Vector< Energy > Lorentz5Momentum
A momentum in four-dimensional space-time with an explicit invariant mass component.
Definition: Unitsystem.h:156
This is the main namespace within which all identifiers in ThePEG are declared.
Definition: FactoryBase.h:28
std::complex< double > Complex
ThePEG code should use Complex for all complex scalars.
Definition: Complex.h:23
constexpr ZeroUnit ZERO
ZERO can be used as zero for any unitful quantity.
Definition: PhysicalQty.h:35