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
G4MuonRadiativeDecayChannelWithSpin.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// G4MuonRadiativeDecayChannelWithSpin class implementation
27//
28// References:
29// - TRIUMF/TWIST Technote TN-55:
30// "Radiative muon decay" by P. Depommier and A. Vacheret
31// - Yoshitaka Kuno and Yasuhiro Okada
32// "Muon Decays and Physics Beyond the Standard Model"
33// Rev. Mod. Phys. 73, 151 (2001)
34//
35// Author: P.Gumplinger - Triumf, 25 July 2007
36// Revision: D.Mingming - Center for HEP, Tsinghua Univ., 10 August 2011
37// --------------------------------------------------------------------
38
40
42#include "G4SystemOfUnits.hh"
43#include "Randomize.hh"
44#include "G4DecayProducts.hh"
45#include "G4LorentzVector.hh"
46
49{
50}
51
52G4MuonRadiativeDecayChannelWithSpin::
53G4MuonRadiativeDecayChannelWithSpin(const G4String& theParentName,
54 G4double theBR)
55 : G4VDecayChannel("Radiative Muon Decay",1)
56{
57 // set names for daughter particles
58 if (theParentName == "mu+")
59 {
60 SetBR(theBR);
61 SetParent("mu+");
63 SetDaughter(0, "e+");
64 SetDaughter(1, "gamma");
65 SetDaughter(2, "nu_e");
66 SetDaughter(3, "anti_nu_mu");
67 }
68 else if (theParentName == "mu-")
69 {
70 SetBR(theBR);
71 SetParent("mu-");
73 SetDaughter(0, "e-");
74 SetDaughter(1, "gamma");
75 SetDaughter(2, "anti_nu_e");
76 SetDaughter(3, "nu_mu");
77 }
78 else
79 {
80#ifdef G4VERBOSE
81 if (GetVerboseLevel()>0)
82 {
83 G4cout << "G4RadiativeMuonDecayChannel::G4RadiativeMuonDecayChannel():";
84 G4cout << " parent particle is not muon but ";
85 G4cout << theParentName << G4endl;
86 }
87#endif
88 }
89}
90
92{
93}
94
95G4MuonRadiativeDecayChannelWithSpin::
96G4MuonRadiativeDecayChannelWithSpin(const G4MuonRadiativeDecayChannelWithSpin& r)
98{
99}
100
103{
104 if (this != &right)
105 {
108 rbranch = right.rbranch;
109
110 // copy parent name
111 parent_name = new G4String(*right.parent_name);
112
113 // clear daughters_name array
115
116 // recreate array
118 if ( numberOfDaughters > 0 )
119 {
120 if (daughters_name != nullptr) ClearDaughtersName();
122 // copy daughters name
123 for (G4int index=0; index<numberOfDaughters; ++index)
124 {
125 daughters_name[index] = new G4String(*right.daughters_name[index]);
126 }
127 }
129 }
130 return *this;
131}
132
133
135{
136#ifdef G4VERBOSE
137 if (GetVerboseLevel()>1)
138 G4cout << "G4MuonRadiativeDecayChannelWithSpin::DecayIt()";
139#endif
140
143
144 // parent mass
145 G4double parentmass = G4MT_parent->GetPDGMass();
146
147 G4double EMMU = parentmass;
148
149 // daughters'mass
150 G4double daughtermass[4];
151 //G4double sumofdaughtermass = 0.0;
152 for (G4int index=0; index<4; ++index)
153 {
154 daughtermass[index] = G4MT_daughters[index]->GetPDGMass();
155 //sumofdaughtermass += daughtermass[index];
156 }
157
158 G4double EMASS = daughtermass[0];
159
160 //create parent G4DynamicParticle at rest
161 G4ThreeVector dummy;
162 G4DynamicParticle* parentparticle
163 = new G4DynamicParticle( G4MT_parent, dummy, 0.0 );
164
165 // create G4Decayproducts
166 G4DecayProducts *products = new G4DecayProducts(*parentparticle);
167 delete parentparticle;
168
169 G4double eps = EMASS/EMMU;
170
171 G4double som0, x, y, xx, yy, zz;
172 G4double cthetaE, cthetaG, cthetaGE, phiE, phiG;
173 const std::size_t MAX_LOOP=10000;
174
175 for (std::size_t loop_counter1=0; loop_counter1<MAX_LOOP; ++loop_counter1)
176 {
177 for (std::size_t loop_counter2=0; loop_counter2<MAX_LOOP; ++loop_counter2)
178 {
179 // -------------------------------------------------------------------
180 // Build two vectors of random length and random direction, for the
181 // positron and the photon.
182 // x/y is the length of the vector, xx, yy and zz the components,
183 // phi is the azimutal angle, theta the polar angle.
184 // -------------------------------------------------------------------
185
186 // For the positron
187 //
188 x = G4UniformRand();
189
190 rn3dim(xx,yy,zz,x);
191
192 if(std::fabs((xx*xx)+(yy*yy)+(zz*zz)-(x*x))>0.001)
193 {
194 G4cout << "Norm of x not correct" << G4endl;
195 }
196
197 phiE = atan4(xx,yy);
198 cthetaE = zz/x;
199 G4double sthetaE = std::sqrt((xx*xx)+(yy*yy))/x;
200
201 // What you get:
202 //
203 // x = positron energy
204 // phiE = azimutal angle of positron momentum
205 // cthetaE = cosine of polar angle of positron momentum
206 // sthetaE = sine of polar angle of positron momentum
207 //
208 //// G4cout << " x, xx, yy, zz " << x << " " << xx << " "
209 //// << yy << " " << zz << G4endl;
210 //// G4cout << " phiE, cthetaE, sthetaE " << phiE << " "
211 //// << cthetaE << " "
212 //// << sthetaE << " " << G4endl;
213
214 // For the photon
215 //
216 y = G4UniformRand();
217
218 rn3dim(xx,yy,zz,y);
219
220 if(std::fabs((xx*xx)+(yy*yy)+(zz*zz)-(y*y))>0.001)
221 {
222 G4cout << " Norm of y not correct " << G4endl;
223 }
224
225 phiG = atan4(xx,yy);
226 cthetaG = zz/y;
227 G4double sthetaG = std::sqrt((xx*xx)+(yy*yy))/y;
228
229 // What you get:
230 //
231 // y = photon energy
232 // phiG = azimutal angle of photon momentum
233 // cthetaG = cosine of polar angle of photon momentum
234 // sthetaG = sine of polar angle of photon momentum
235 //
236 //// G4cout << " y, xx, yy, zz " << y << " " << xx << " "
237 //// << yy << " " << zz << G4endl;
238 //// G4cout << " phiG, cthetaG, sthetaG " << phiG << " "
239 //// << cthetaG << " "
240 //// << sthetaG << " " << G4endl;
241
242 // Calculate the angle between positron and photon (cosine)
243 //
244 cthetaGE = cthetaE*cthetaG+sthetaE*sthetaG*std::cos(phiE-phiG);
245
246 //// G4cout << x << " " << cthetaE << " " << sthetaE << " "
247 //// << y << " " << cthetaG << " " << sthetaG << " "
248 //// << cthetaGE
249
250 G4double term0 = eps*eps;
251 G4double term1 = x*((1.0-eps)*(1.0-eps))+2.0*eps;
252 G4double beta = std::sqrt( x*((1.0-eps)*(1.0-eps))*
253 (x*((1.0-eps)*(1.0-eps))+4.0*eps))/term1;
254 G4double delta = 1.0-beta*cthetaGE;
255
256 G4double term3 = y*(1.0-(eps*eps));
257 G4double term6 = term1*delta*term3;
258
259 G4double Qsqr = (1.0-term1-term3+term0+0.5*term6)/((1.0-eps)*(1.0-eps));
260
261 // Check the kinematics.
262 //
263 if ( Qsqr>=0.0 && Qsqr<=1.0 ) break;
264
265 } // end loop count
266
267 // Do the calculation for -1 muon polarization (i.e. mu+)
268 //
269 G4double Pmu = -1.0;
270 if (GetParentName() == "mu-") { Pmu = +1.0; }
271
272 som0 = fron(Pmu,x,y,cthetaE,cthetaG,cthetaGE);
273
274 // Sample the decay rate
275 //
276 if (G4UniformRand()*177.0 <= som0) break;
277 }
278
279 G4double E = EMMU/2.*(x*((1.-eps)*(1.-eps))+2.*eps);
280 G4double G = EMMU/2.*y*(1.-eps*eps);
281
282 if(E < EMASS) E = EMASS;
283
284 // calculate daughter momentum
285 G4double daughtermomentum[4];
286
287 daughtermomentum[0] = std::sqrt(E*E - EMASS*EMASS);
288
289 G4double sthetaE = std::sqrt(1.-cthetaE*cthetaE);
290 G4double cphiE = std::cos(phiE);
291 G4double sphiE = std::sin(phiE);
292
293 // Coordinates of the decay positron with respect to the muon spin
294
295 G4double px = sthetaE*cphiE;
296 G4double py = sthetaE*sphiE;
297 G4double pz = cthetaE;
298
299 G4ThreeVector direction0(px,py,pz);
300
301 direction0.rotateUz(parent_polarization);
302
303 G4DynamicParticle * daughterparticle0
304 = new G4DynamicParticle( G4MT_daughters[0], daughtermomentum[0]*direction0);
305
306 products->PushProducts(daughterparticle0);
307
308 daughtermomentum[1] = G;
309
310 G4double sthetaG = std::sqrt(1.-cthetaG*cthetaG);
311 G4double cphiG = std::cos(phiG);
312 G4double sphiG = std::sin(phiG);
313
314 // Coordinates of the decay gamma with respect to the muon spin
315
316 px = sthetaG*cphiG;
317 py = sthetaG*sphiG;
318 pz = cthetaG;
319
320 G4ThreeVector direction1(px,py,pz);
321
322 direction1.rotateUz(parent_polarization);
323
324 G4DynamicParticle * daughterparticle1
325 = new G4DynamicParticle( G4MT_daughters[1], daughtermomentum[1]*direction1);
326
327 products->PushProducts(daughterparticle1);
328
329 // daughter 3 ,4 (neutrinos)
330 // create neutrinos in the C.M frame of two neutrinos
331
332 G4double energy2 = parentmass-E-G;
333
334 G4ThreeVector P34 = -1.*(daughtermomentum[0]*direction0
335 +daughtermomentum[1]*direction1);
336 G4double vmass2 = energy2*energy2 - P34.mag2();
337 G4double vmass = std::sqrt(vmass2);
338
339 G4double costhetan = 2.*G4UniformRand()-1.0;
340 G4double sinthetan = std::sqrt((1.0-costhetan)*(1.0+costhetan));
341 G4double phin = twopi*G4UniformRand()*rad;
342 G4double sinphin = std::sin(phin);
343 G4double cosphin = std::cos(phin);
344
345 G4ThreeVector direction2(sinthetan*cosphin,sinthetan*sinphin,costhetan);
346
347 G4DynamicParticle * daughterparticle2
348 = new G4DynamicParticle( G4MT_daughters[2], direction2*(vmass/2.));
349 G4DynamicParticle * daughterparticle3
350 = new G4DynamicParticle( G4MT_daughters[3], direction2*(-1.0*vmass/2.));
351
352 // boost to the muon rest frame
353 G4double beta = P34.mag()/energy2;
354 G4ThreeVector direction34 = P34.unit();
355
356 G4LorentzVector p4 = daughterparticle2->Get4Momentum();
357 p4.boost(direction34.x()*beta,direction34.y()*beta,direction34.z()*beta);
358 daughterparticle2->Set4Momentum(p4);
359
360 p4 = daughterparticle3->Get4Momentum();
361 p4.boost(direction34.x()*beta,direction34.y()*beta,direction34.z()*beta);
362 daughterparticle3->Set4Momentum(p4);
363
364 products->PushProducts(daughterparticle2);
365 products->PushProducts(daughterparticle3);
366
367 daughtermomentum[2] = daughterparticle2->GetTotalMomentum();
368 daughtermomentum[3] = daughterparticle3->GetTotalMomentum();
369
370 // output message
371#ifdef G4VERBOSE
372 if (GetVerboseLevel()>1)
373 {
374 G4cout << "G4MuonRadiativeDecayChannelWithSpin::DecayIt() -";
375 G4cout << " create decay products in rest frame " <<G4endl;
376 G4double TT = daughterparticle0->GetTotalEnergy()
377 + daughterparticle1->GetTotalEnergy()
378 + daughterparticle2->GetTotalEnergy()
379 + daughterparticle3->GetTotalEnergy();
380 G4cout << "e :" << daughterparticle0->GetTotalEnergy()/MeV << G4endl;
381 G4cout << "gamma:" << daughterparticle1->GetTotalEnergy()/MeV << G4endl;
382 G4cout << "nu2 :" << daughterparticle2->GetTotalEnergy()/MeV << G4endl;
383 G4cout << "nu2 :" << daughterparticle3->GetTotalEnergy()/MeV << G4endl;
384 G4cout << "total:" << (TT-parentmass)/keV << G4endl;
385 if (GetVerboseLevel()>1) { products->DumpInfo(); }
386 }
387#endif
388
389 return products;
390}
391
392G4double G4MuonRadiativeDecayChannelWithSpin::fron(G4double Pmu,
393 G4double x,
394 G4double y,
395 G4double cthetaE,
396 G4double cthetaG,
397 G4double cthetaGE)
398{
399 G4double mu = 105.65;
400 G4double me = 0.511;
401 G4double rho = 0.75;
402 G4double del = 0.75;
403 G4double eps = 0.0;
404 G4double kap = 0.0;
405 G4double ksi = 1.0;
406
407 G4double delta = 1-cthetaGE;
408
409 // Calculation of the functions f(x,y)
410
411 G4double f_1s = 12.0*((y*y)*(1.0-y)+x*y*(2.0-3.0*y)
412 +2.0*(x*x)*(1.0-2.0*y)-2.0*(x*x*x));
413 G4double f0s = 6.0*(-x*y*(2.0-3.0*(y*y))
414 -2.0*(x*x)*(1.0-y-3.0*(y*y))+2.0*(x*x*x)*(1.0+2.0*y));
415 G4double f1s = 3.0*((x*x)*y*(2.0-3.0*y-3.0*(y*y))
416 -(x*x*x)*y*(4.0+3.0*y));
417 G4double f2s = 1.5*((x*x*x)*(y*y)*(2.0+y));
418
419 G4double f_1se = 12.0*(x*y*(1.0-y)+(x*x)*(2.0-3.0*y)
420 -2.0*(x*x*x));
421 G4double f0se = 6.0*(-(x*x)*(2.0-y-2.0*(y*y))
422 +(x*x*x)*(2.0+3.0*y));
423 G4double f1se = -3.0*(x*x*x)*y*(2.0+y);
424 G4double f2se = 0.0;
425
426 G4double f_1sg = 12.0*((y*y)*(1.0-y)+x*y*(1.0-2.0*y)
427 -(x*x)*y);
428 G4double f0sg = 6.0*(-x*(y*y)*(2.0-3.0*y)-(x*x)*y*(1.0-4.0*y)
429 +(x*x*x)*y);
430 G4double f1sg = 3.0*((x*x)*(y*y)*(1.0-3.0*y)
431 -2.0*(x*x*x)*(y*y));
432 G4double f2sg = 1.5*(x*x*x)*(y*y*y);
433
434 G4double f_1v = 8.0*((y*y)*(3.0-2.0*y)+6.0*x*y*(1.0-y)
435 +2.0*(x*x)*(3.0-4.0*y)-4.0*(x*x*x));
436 G4double f0v = 8.0*(-x*y*(3.0-y-(y*y))-(x*x)*(3.0-y-4.0*(y*y))
437 +2.0*(x*x*x)*(1.0+2.0*y));
438 G4double f1v = 2.0*((x*x)*y*(6.0-5.0*y-2.0*(y*y))
439 -2.0*(x*x*x)*y*(4.0+3.0*y));
440 G4double f2v = 2.0*(x*x*x)*(y*y)*(2.0+y);
441
442 G4double f_1ve = 8.0*(x*y*(1.0-2.0*y)
443 +2.0*(x*x)*(1.0-3.0*y)-4.0*(x*x*x));
444 G4double f0ve = 4.0*(-(x*x)*(2.0-3.0*y-4.0*(y*y))
445 +2.0*(x*x*x)*(2.0+3.0*y));
446 G4double f1ve = -4.0*(x*x*x)*y*(2.0+y);
447 G4double f2ve = 0.0;
448
449 G4double f_1vg = 8.0*((y*y)*(1.0-2.0*y)+x*y*(1.0-4.0*y)
450 -2.0*(x*x)*y);
451 G4double f0vg = 4.0*(2.0*x*(y*y)*(1.0+y)-(x*x)*y*(1.0-4.0*y)
452 +2.0*(x*x*x)*y);
453 G4double f1vg = 2.0*((x*x)*(y*y)*(1.0-2.0*y)
454 -4.0*(x*x*x)*(y*y));
455 G4double f2vg = 2.0*(x*x*x)*(y*y*y);
456
457 G4double f_1t = 8.0*((y*y)*(3.0-y)+3.0*x*y*(2.0-y)
458 +2.0*(x*x)*(3.0-2.0*y)-2.0*(x*x*x));
459 G4double f0t = 4.0*(-x*y*(6.0+(y*y))
460 -2.0*(x*x)*(3.0+y-3.0*(y*y))+2.0*(x*x*x)*(1.0+2.0*y));
461 G4double f1t = 2.0*((x*x)*y*(6.0-5.0*y+(y*y))
462 -(x*x*x)*y*(4.0+3.0*y));
463 G4double f2t = (x*x*x)*(y*y)*(2.0+y);
464
465 G4double f_1te = -8.0*(x*y*(1.0+3.0*y)+(x*x)*(2.0+3.0*y)
466 +2.0*(x*x*x));
467 G4double f0te = 4.0*((x*x)*(2.0+3.0*y+4.0*(y*y))
468 +(x*x*x)*(2.0+3.0*y));
469 G4double f1te = -2.0*(x*x*x)*y*(2.0+y);
470 G4double f2te = 0.0;
471
472 G4double f_1tg = -8.0*((y*y)*(1.0+y)+x*y+(x*x)*y);
473 G4double f0tg = 4.0*(x*(y*y)*(2.0-y)+(x*x)*y*(1.0+2.0*y)
474 +(x*x*x)*y);
475 G4double f1tg = -2.0*((x*x)*(y*y)*(1.0-y)+2.0*(x*x*x)*y);
476 G4double f2tg = (x*x*x)*(y*y*y);
477
478 G4double term = delta+2.0*(me*me)/((mu*mu)*(x*x));
479 term = 1.0/term;
480
481 G4double nss = term*f_1s+f0s+delta*f1s+(delta*delta)*f2s;
482 G4double nv = term*f_1v+f0v+delta*f1v+(delta*delta)*f2v;
483 G4double nt = term*f_1t+f0t+delta*f1t+(delta*delta)*f2t;
484
485 G4double nse = term*f_1se+f0se+delta*f1se+(delta*delta)*f2se;
486 G4double nve = term*f_1ve+f0ve+delta*f1ve+(delta*delta)*f2ve;
487 G4double nte = term*f_1te+f0te+delta*f1te+(delta*delta)*f2te;
488
489 G4double nsg = term*f_1sg+f0sg+delta*f1sg+(delta*delta)*f2sg;
490 G4double nvg = term*f_1vg+f0vg+delta*f1vg+(delta*delta)*f2vg;
491 G4double ntg = term*f_1tg+f0tg+delta*f1tg+(delta*delta)*f2tg;
492
493 G4double term1 = nv;
494 G4double term2 = 2.0*nss+nv-nt;
495 G4double term3 = 2.0*nss-2.0*nv+nt;
496
497 G4double term1e = 1.0/3.0*(1.0-4.0/3.0*del);
498 G4double term2e = 2.0*nse+5.0*nve-nte;
499 G4double term3e = 2.0*nse-2.0*nve+nte;
500
501 G4double term1g = 1.0/3.0*(1.0-4.0/3.0*del);
502 G4double term2g = 2.0*nsg+5.0*nvg-ntg;
503 G4double term3g = 2.0*nsg-2.0*nvg+ntg;
504
505 G4double som00 = term1+(1.0-4.0/3.0*rho)*term2+eps*term3;
506 G4double som01 = Pmu*ksi*(cthetaE*(nve-term1e*term2e+kap*term3e)
507 +cthetaG*(nvg-term1g*term2g+kap*term3g));
508
509 G4double som0 = (som00+som01)/y;
510 som0 = fine_structure_const/8./(twopi*twopi*twopi)*som0;
511
512 return som0;
513}
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
Hep3Vector unit() const
double x() const
double mag2() const
double y() const
double mag() 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
G4MuonRadiativeDecayChannelWithSpin & operator=(const G4MuonRadiativeDecayChannelWithSpin &)
G4MuonRadiativeDecayChannelWithSpin(const G4String &theParentName, G4double theBR)
G4ParticleDefinition ** G4MT_daughters
G4String * parent_name
const G4String & GetParentName() const
void SetBR(G4double value)
G4String ** daughters_name
G4int GetVerboseLevel() const
void SetNumberOfDaughters(G4int value)
G4ParticleDefinition * G4MT_parent
void CheckAndFillDaughters()
void SetDaughter(G4int anIndex, const G4ParticleDefinition *particle_type)
G4ThreeVector parent_polarization
G4String kinematics_name
void SetParent(const G4ParticleDefinition *particle_type)