Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4MuonDecayChannelWithSpin.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4MuonDecayChannelWithSpin class implementation
27//
28// References:
29// - Florian Scheck "Muon Physics", in Physics Reports
30// (Review Section of Physics Letters) 44, No. 4 (1978)
31// 187-248. North-Holland Publishing Company, Amsterdam at page 210 cc.
32// - W.E. Fisher and F. Scheck, Nucl. Phys. B83 (1974) 25.
33
34// Authors: P.Gumplinger and T.MacPhail, 17 August 2004
35// --------------------------------------------------------------------
36
38
40#include "G4SystemOfUnits.hh"
41#include "Randomize.hh"
42
43#include "G4DecayProducts.hh"
44#include "G4LorentzVector.hh"
45
48{
49}
50
51G4MuonDecayChannelWithSpin::
52G4MuonDecayChannelWithSpin(const G4String& theParentName,
53 G4double theBR)
54 : G4MuonDecayChannel(theParentName,theBR)
55{
56}
57
59{
60}
61
62G4MuonDecayChannelWithSpin::
63G4MuonDecayChannelWithSpin(const G4MuonDecayChannelWithSpin& right)
64 : G4MuonDecayChannel(right)
65{
66}
67
70{
71 if (this != &right)
72 {
75 rbranch = right.rbranch;
76
77 // copy parent name
78 delete parent_name;
79 parent_name = new G4String(*right.parent_name);
80
81 // clear daughters_name array
83
84 // recreate array
86 if ( numberOfDaughters > 0 )
87 {
89 // copy daughters name
90 for (G4int index=0; index<numberOfDaughters; ++index)
91 {
92 daughters_name[index] = new G4String(*right.daughters_name[index]);
93 }
94 }
95 }
96 return *this;
97}
98
100{
101 // This version assumes V-A coupling with 1st order radiative correctons,
102 // the standard model Michel parameter values, but
103 // gives incorrect energy spectrum for neutrinos
104
105#ifdef G4VERBOSE
106 if (GetVerboseLevel()>1) G4cout << "G4MuonDecayChannelWithSpin::DecayIt ";
107#endif
108
111
112 // parent mass
113 G4double parentmass = G4MT_parent->GetPDGMass();
114
115 G4double EMMU = parentmass;
116
117 //daughters'mass
118 G4double daughtermass[3];
119 //G4double sumofdaughtermass = 0.0;
120 for (G4int index=0; index<3; ++index)
121 {
122 daughtermass[index] = G4MT_daughters[index]->GetPDGMass();
123 //sumofdaughtermass += daughtermass[index];
124 }
125
126 G4double EMASS = daughtermass[0];
127
128 // create parent G4DynamicParticle at rest
129 G4ThreeVector dummy;
130 G4DynamicParticle* parentparticle
131 = new G4DynamicParticle( G4MT_parent, dummy, 0.0);
132 // create G4Decayproducts
133 G4DecayProducts *products = new G4DecayProducts(*parentparticle);
134 delete parentparticle;
135
136 // calculate electron energy
137
138 G4double michel_rho = 0.75; //Standard Model Michel rho
139 G4double michel_delta = 0.75; //Standard Model Michel delta
140 G4double michel_xsi = 1.00; //Standard Model Michel xsi
141 G4double michel_eta = 0.00; //Standard Model eta
142
143 G4double rndm, x, ctheta;
144
145 G4double FG;
146 G4double FG_max = 2.00;
147
148 G4double W_mue = (EMMU*EMMU+EMASS*EMASS)/(2.*EMMU);
149 G4double x0 = EMASS/W_mue;
150
151 G4double x0_squared = x0*x0;
152
153 // ***************************************************
154 // x0 <= x <= 1. and -1 <= y <= 1
155 //
156 // F(x,y) = f(x)*g(x,y); g(x,y) = 1.+g(x)*y
157 // ***************************************************
158
159 // ***** sampling F(x,y) directly (brute force) *****
160
161 const std::size_t MAX_LOOP=10000;
162 for (std::size_t loop_count=0; loop_count<MAX_LOOP; ++loop_count)
163 {
164 // Sample the positron energy by sampling from F
165
166 rndm = G4UniformRand();
167
168 x = x0 + rndm*(1.-x0);
169
170 G4double x_squared = x*x;
171
172 G4double F_IS, F_AS, G_IS, G_AS;
173
174 F_IS = 1./6.*(-2.*x_squared+3.*x-x0_squared);
175 F_AS = 1./6.*std::sqrt(x_squared-x0_squared)
176 *(2.*x-2.+std::sqrt(1.-x0_squared));
177
178 G_IS = 2./9.*(michel_rho-0.75)*(4.*x_squared-3.*x-x0_squared);
179 G_IS = G_IS + michel_eta*(1.-x)*x0;
180
181 G_AS = 3.*(michel_xsi-1.)*(1.-x);
182 G_AS = G_AS+2.*(michel_xsi*michel_delta-0.75)
183 *(4.*x-4.+std::sqrt(1.-x0_squared));
184 G_AS = 1./9.*std::sqrt(x_squared-x0_squared)*G_AS;
185
186 F_IS = F_IS + G_IS;
187 F_AS = F_AS + G_AS;
188
189 // *** Radiative Corrections ***
190
191 const G4double omega = std::log(EMMU/EMASS);
192 G4double R_IS = F_c(x,x0,omega);
193
194 G4double F = 6.*F_IS + R_IS/std::sqrt(x_squared-x0_squared);
195
196 // *** Radiative Corrections ***
197
198 G4double R_AS = F_theta(x,x0,omega);
199
200 rndm = G4UniformRand();
201
202 ctheta = 2.*rndm-1.;
203
204 G4double G = 6.*F_AS - R_AS/std::sqrt(x_squared-x0_squared);
205
206 FG = std::sqrt(x_squared-x0_squared)*F*(1.+(G/F)*ctheta);
207
208 if(FG>FG_max)
209 {
210 G4Exception("G4MuonDecayChannelWithSpin::DecayIt()",
211 "PART113", JustWarning,
212 "Problem in Muon Decay: FG > FG_max");
213 FG_max = FG;
214 }
215
216 rndm = G4UniformRand();
217
218 if (FG >= rndm*FG_max) break;
219 }
220
221 G4double energy = x * W_mue;
222
223 rndm = G4UniformRand();
224
225 G4double phi = twopi * rndm;
226
227 if(energy < EMASS) energy = EMASS;
228
229 // Calculate daughter momentum
230 G4double daughtermomentum[3];
231
232 daughtermomentum[0] = std::sqrt(energy*energy - EMASS*EMASS);
233
234 G4double stheta = std::sqrt(1.-ctheta*ctheta);
235 G4double cphi = std::cos(phi);
236 G4double sphi = std::sin(phi);
237
238 // Coordinates of the decay positron with respect to the muon spin
239 G4double px = stheta*cphi;
240 G4double py = stheta*sphi;
241 G4double pz = ctheta;
242
243 G4ThreeVector direction0(px,py,pz);
244
245 direction0.rotateUz(parent_polarization);
246
247 G4DynamicParticle * daughterparticle0
248 = new G4DynamicParticle( G4MT_daughters[0], daughtermomentum[0]*direction0);
249
250 products->PushProducts(daughterparticle0);
251
252
253 // daughter 1 ,2 (neutrinos)
254 // create neutrinos in the C.M frame of two neutrinos
255 G4double energy2 = parentmass-energy;
256 G4double vmass = std::sqrt((energy2-daughtermomentum[0])
257 * (energy2+daughtermomentum[0]));
258 G4double beta = -1.0*daughtermomentum[0]/energy2;
259 G4double costhetan = 2.*G4UniformRand()-1.0;
260 G4double sinthetan = std::sqrt((1.0-costhetan)*(1.0+costhetan));
261 G4double phin = twopi*G4UniformRand()*rad;
262 G4double sinphin = std::sin(phin);
263 G4double cosphin = std::cos(phin);
264
265 G4ThreeVector direction1(sinthetan*cosphin,sinthetan*sinphin,costhetan);
266 G4DynamicParticle * daughterparticle1
267 = new G4DynamicParticle( G4MT_daughters[1], direction1*(vmass/2.));
268 G4DynamicParticle * daughterparticle2
269 = new G4DynamicParticle( G4MT_daughters[2], direction1*(-1.0*vmass/2.));
270
271 // boost to the muon rest frame
273 p4 = daughterparticle1->Get4Momentum();
274 p4.boost( direction0.x()*beta, direction0.y()*beta, direction0.z()*beta);
275 daughterparticle1->Set4Momentum(p4);
276 p4 = daughterparticle2->Get4Momentum();
277 p4.boost( direction0.x()*beta, direction0.y()*beta, direction0.z()*beta);
278 daughterparticle2->Set4Momentum(p4);
279 products->PushProducts(daughterparticle1);
280 products->PushProducts(daughterparticle2);
281 daughtermomentum[1] = daughterparticle1->GetTotalMomentum();
282 daughtermomentum[2] = daughterparticle2->GetTotalMomentum();
283
284 // output message
285#ifdef G4VERBOSE
286 if (GetVerboseLevel()>1)
287 {
288 G4cout << "G4MuonDecayChannelWithSpin::DecayIt ";
289 G4cout << " create decay products in rest frame " <<G4endl;
290 G4double TT = daughterparticle0->GetTotalEnergy()
291 + daughterparticle1->GetTotalEnergy()
292 + daughterparticle2->GetTotalEnergy();
293 G4cout << "e " << daughterparticle0->GetTotalEnergy()/MeV << G4endl;
294 G4cout << "nu1" << daughterparticle1->GetTotalEnergy()/MeV << G4endl;
295 G4cout << "nu2" << daughterparticle2->GetTotalEnergy()/MeV << G4endl;
296 G4cout << "total" << (TT-parentmass)/keV << G4endl;
297 if (GetVerboseLevel()>2) { products->DumpInfo(); }
298 }
299#endif
300
301 return products;
302}
303
304G4double G4MuonDecayChannelWithSpin::R_c(G4double x,G4double omega)
305{
306 G4int n_max = (G4int)(100.*x);
307
308 if(n_max<10)n_max=10;
309
310 G4double L2 = 0.0;
311
312 for(G4int n=1; n<=n_max; ++n)
313 {
314 L2 += std::pow(x,n)/(n*n);
315 }
316
317 G4double r_c;
318
319 r_c = 2.*L2-(pi*pi/3.)-2.;
320 r_c = r_c + omega * (1.5+2.*std::log((1.-x)/x));
321 r_c = r_c - std::log(x)*(2.*std::log(x)-1.);
322 r_c = r_c + (3.*std::log(x)-1.-1./x)*std::log(1.-x);
323
324 return r_c;
325}
@ JustWarning
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
double G4double
Definition: G4Types.hh:83
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
double z() const
double x() const
double y() const
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:33
HepLorentzVector & boost(double, double, double)
void DumpInfo() const
G4int PushProducts(G4DynamicParticle *aParticle)
G4LorentzVector Get4Momentum() const
G4double GetTotalEnergy() const
void Set4Momentum(const G4LorentzVector &momentum)
G4double GetTotalMomentum() const
G4MuonDecayChannelWithSpin(const G4String &theParentName, G4double theBR)
virtual G4DecayProducts * DecayIt(G4double)
G4MuonDecayChannelWithSpin & operator=(const G4MuonDecayChannelWithSpin &)
G4ParticleDefinition ** G4MT_daughters
G4String * parent_name
G4String ** daughters_name
G4int GetVerboseLevel() const
G4ParticleDefinition * G4MT_parent
void CheckAndFillDaughters()
G4ThreeVector parent_polarization
G4String kinematics_name
const G4double pi