Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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 G4int i = 0;
170
171 G4double eps = EMASS/EMMU;
172
173 G4double som0, x, y, xx, yy, zz;
174 G4double cthetaE, cthetaG, cthetaGE, phiE, phiG;
175 const std::size_t MAX_LOOP=10000;
176
177 for (std::size_t loop_counter1=0; loop_counter1<MAX_LOOP; ++loop_counter1)
178 {
179 // leap1:
180
181 ++i;
182
183 // leap2:
184
185 for (std::size_t loop_counter2=0; loop_counter2<MAX_LOOP; ++loop_counter2)
186 {
187 // -------------------------------------------------------------------
188 // Build two vectors of random length and random direction, for the
189 // positron and the photon.
190 // x/y is the length of the vector, xx, yy and zz the components,
191 // phi is the azimutal angle, theta the polar angle.
192 // -------------------------------------------------------------------
193
194 // For the positron
195 //
196 x = G4UniformRand();
197
198 rn3dim(xx,yy,zz,x);
199
200 if(std::fabs((xx*xx)+(yy*yy)+(zz*zz)-(x*x))>0.001)
201 {
202 G4cout << "Norm of x not correct" << G4endl;
203 }
204
205 phiE = atan4(xx,yy);
206 cthetaE = zz/x;
207 G4double sthetaE = std::sqrt((xx*xx)+(yy*yy))/x;
208
209 // What you get:
210 //
211 // x = positron energy
212 // phiE = azimutal angle of positron momentum
213 // cthetaE = cosine of polar angle of positron momentum
214 // sthetaE = sine of polar angle of positron momentum
215 //
216 //// G4cout << " x, xx, yy, zz " << x << " " << xx << " "
217 //// << yy << " " << zz << G4endl;
218 //// G4cout << " phiE, cthetaE, sthetaE " << phiE << " "
219 //// << cthetaE << " "
220 //// << sthetaE << " " << G4endl;
221
222 // For the photon
223 //
224 y = G4UniformRand();
225
226 rn3dim(xx,yy,zz,y);
227
228 if(std::fabs((xx*xx)+(yy*yy)+(zz*zz)-(y*y))>0.001)
229 {
230 G4cout << " Norm of y not correct " << G4endl;
231 }
232
233 phiG = atan4(xx,yy);
234 cthetaG = zz/y;
235 G4double sthetaG = std::sqrt((xx*xx)+(yy*yy))/y;
236
237 // What you get:
238 //
239 // y = photon energy
240 // phiG = azimutal angle of photon momentum
241 // cthetaG = cosine of polar angle of photon momentum
242 // sthetaG = sine of polar angle of photon momentum
243 //
244 //// G4cout << " y, xx, yy, zz " << y << " " << xx << " "
245 //// << yy << " " << zz << G4endl;
246 //// G4cout << " phiG, cthetaG, sthetaG " << phiG << " "
247 //// << cthetaG << " "
248 //// << sthetaG << " " << G4endl;
249
250 // Calculate the angle between positron and photon (cosine)
251 //
252 cthetaGE = cthetaE*cthetaG+sthetaE*sthetaG*std::cos(phiE-phiG);
253
254 //// G4cout << x << " " << cthetaE << " " << sthetaE << " "
255 //// << y << " " << cthetaG << " " << sthetaG << " "
256 //// << cthetaGE
257
258 G4double term0 = eps*eps;
259 G4double term1 = x*((1.0-eps)*(1.0-eps))+2.0*eps;
260 G4double beta = std::sqrt( x*((1.0-eps)*(1.0-eps))*
261 (x*((1.0-eps)*(1.0-eps))+4.0*eps))/term1;
262 G4double delta = 1.0-beta*cthetaGE;
263
264 G4double term3 = y*(1.0-(eps*eps));
265 G4double term6 = term1*delta*term3;
266
267 G4double Qsqr = (1.0-term1-term3+term0+0.5*term6)/((1.0-eps)*(1.0-eps));
268
269 // Check the kinematics.
270 //
271 if ( Qsqr>=0.0 && Qsqr<=1.0 ) break;
272
273 } // end loop count
274
275 // Do the calculation for -1 muon polarization (i.e. mu+)
276 //
277 G4double Pmu = -1.0;
278 if (GetParentName() == "mu-") { Pmu = +1.0; }
279
280 som0 = fron(Pmu,x,y,cthetaE,cthetaG,cthetaGE);
281
282 // Sample the decay rate
283 //
284 if (G4UniformRand()*177.0 <= som0) break;
285 }
286
287 G4double E = EMMU/2.*(x*((1.-eps)*(1.-eps))+2.*eps);
288 G4double G = EMMU/2.*y*(1.-eps*eps);
289
290 if(E < EMASS) E = EMASS;
291
292 // calculate daughter momentum
293 G4double daughtermomentum[4];
294
295 daughtermomentum[0] = std::sqrt(E*E - EMASS*EMASS);
296
297 G4double sthetaE = std::sqrt(1.-cthetaE*cthetaE);
298 G4double cphiE = std::cos(phiE);
299 G4double sphiE = std::sin(phiE);
300
301 // Coordinates of the decay positron with respect to the muon spin
302
303 G4double px = sthetaE*cphiE;
304 G4double py = sthetaE*sphiE;
305 G4double pz = cthetaE;
306
307 G4ThreeVector direction0(px,py,pz);
308
309 direction0.rotateUz(parent_polarization);
310
311 G4DynamicParticle * daughterparticle0
312 = new G4DynamicParticle( G4MT_daughters[0], daughtermomentum[0]*direction0);
313
314 products->PushProducts(daughterparticle0);
315
316 daughtermomentum[1] = G;
317
318 G4double sthetaG = std::sqrt(1.-cthetaG*cthetaG);
319 G4double cphiG = std::cos(phiG);
320 G4double sphiG = std::sin(phiG);
321
322 // Coordinates of the decay gamma with respect to the muon spin
323
324 px = sthetaG*cphiG;
325 py = sthetaG*sphiG;
326 pz = cthetaG;
327
328 G4ThreeVector direction1(px,py,pz);
329
330 direction1.rotateUz(parent_polarization);
331
332 G4DynamicParticle * daughterparticle1
333 = new G4DynamicParticle( G4MT_daughters[1], daughtermomentum[1]*direction1);
334
335 products->PushProducts(daughterparticle1);
336
337 // daughter 3 ,4 (neutrinos)
338 // create neutrinos in the C.M frame of two neutrinos
339
340 G4double energy2 = parentmass-E-G;
341
342 G4ThreeVector P34 = -1.*(daughtermomentum[0]*direction0
343 +daughtermomentum[1]*direction1);
344 G4double vmass2 = energy2*energy2 - P34.mag2();
345 G4double vmass = std::sqrt(vmass2);
346
347 G4double costhetan = 2.*G4UniformRand()-1.0;
348 G4double sinthetan = std::sqrt((1.0-costhetan)*(1.0+costhetan));
349 G4double phin = twopi*G4UniformRand()*rad;
350 G4double sinphin = std::sin(phin);
351 G4double cosphin = std::cos(phin);
352
353 G4ThreeVector direction2(sinthetan*cosphin,sinthetan*sinphin,costhetan);
354
355 G4DynamicParticle * daughterparticle2
356 = new G4DynamicParticle( G4MT_daughters[2], direction2*(vmass/2.));
357 G4DynamicParticle * daughterparticle3
358 = new G4DynamicParticle( G4MT_daughters[3], direction2*(-1.0*vmass/2.));
359
360 // boost to the muon rest frame
361 G4double beta = P34.mag()/energy2;
362 G4ThreeVector direction34 = P34.unit();
363
364 G4LorentzVector p4 = daughterparticle2->Get4Momentum();
365 p4.boost(direction34.x()*beta,direction34.y()*beta,direction34.z()*beta);
366 daughterparticle2->Set4Momentum(p4);
367
368 p4 = daughterparticle3->Get4Momentum();
369 p4.boost(direction34.x()*beta,direction34.y()*beta,direction34.z()*beta);
370 daughterparticle3->Set4Momentum(p4);
371
372 products->PushProducts(daughterparticle2);
373 products->PushProducts(daughterparticle3);
374
375 daughtermomentum[2] = daughterparticle2->GetTotalMomentum();
376 daughtermomentum[3] = daughterparticle3->GetTotalMomentum();
377
378 // output message
379#ifdef G4VERBOSE
380 if (GetVerboseLevel()>1)
381 {
382 G4cout << "G4MuonRadiativeDecayChannelWithSpin::DecayIt() -";
383 G4cout << " create decay products in rest frame " <<G4endl;
384 G4double TT = daughterparticle0->GetTotalEnergy()
385 + daughterparticle1->GetTotalEnergy()
386 + daughterparticle2->GetTotalEnergy()
387 + daughterparticle3->GetTotalEnergy();
388 G4cout << "e :" << daughterparticle0->GetTotalEnergy()/MeV << G4endl;
389 G4cout << "gamma:" << daughterparticle1->GetTotalEnergy()/MeV << G4endl;
390 G4cout << "nu2 :" << daughterparticle2->GetTotalEnergy()/MeV << G4endl;
391 G4cout << "nu2 :" << daughterparticle3->GetTotalEnergy()/MeV << G4endl;
392 G4cout << "total:" << (TT-parentmass)/keV << G4endl;
393 if (GetVerboseLevel()>1) { products->DumpInfo(); }
394 }
395#endif
396
397 return products;
398}
399
400G4double G4MuonRadiativeDecayChannelWithSpin::fron(G4double Pmu,
401 G4double x,
402 G4double y,
403 G4double cthetaE,
404 G4double cthetaG,
405 G4double cthetaGE)
406{
407 G4double mu = 105.65;
408 G4double me = 0.511;
409 G4double rho = 0.75;
410 G4double del = 0.75;
411 G4double eps = 0.0;
412 G4double kap = 0.0;
413 G4double ksi = 1.0;
414
415 G4double delta = 1-cthetaGE;
416
417 // Calculation of the functions f(x,y)
418
419 G4double f_1s = 12.0*((y*y)*(1.0-y)+x*y*(2.0-3.0*y)
420 +2.0*(x*x)*(1.0-2.0*y)-2.0*(x*x*x));
421 G4double f0s = 6.0*(-x*y*(2.0-3.0*(y*y))
422 -2.0*(x*x)*(1.0-y-3.0*(y*y))+2.0*(x*x*x)*(1.0+2.0*y));
423 G4double f1s = 3.0*((x*x)*y*(2.0-3.0*y-3.0*(y*y))
424 -(x*x*x)*y*(4.0+3.0*y));
425 G4double f2s = 1.5*((x*x*x)*(y*y)*(2.0+y));
426
427 G4double f_1se = 12.0*(x*y*(1.0-y)+(x*x)*(2.0-3.0*y)
428 -2.0*(x*x*x));
429 G4double f0se = 6.0*(-(x*x)*(2.0-y-2.0*(y*y))
430 +(x*x*x)*(2.0+3.0*y));
431 G4double f1se = -3.0*(x*x*x)*y*(2.0+y);
432 G4double f2se = 0.0;
433
434 G4double f_1sg = 12.0*((y*y)*(1.0-y)+x*y*(1.0-2.0*y)
435 -(x*x)*y);
436 G4double f0sg = 6.0*(-x*(y*y)*(2.0-3.0*y)-(x*x)*y*(1.0-4.0*y)
437 +(x*x*x)*y);
438 G4double f1sg = 3.0*((x*x)*(y*y)*(1.0-3.0*y)
439 -2.0*(x*x*x)*(y*y));
440 G4double f2sg = 1.5*(x*x*x)*(y*y*y);
441
442 G4double f_1v = 8.0*((y*y)*(3.0-2.0*y)+6.0*x*y*(1.0-y)
443 +2.0*(x*x)*(3.0-4.0*y)-4.0*(x*x*x));
444 G4double f0v = 8.0*(-x*y*(3.0-y-(y*y))-(x*x)*(3.0-y-4.0*(y*y))
445 +2.0*(x*x*x)*(1.0+2.0*y));
446 G4double f1v = 2.0*((x*x)*y*(6.0-5.0*y-2.0*(y*y))
447 -2.0*(x*x*x)*y*(4.0+3.0*y));
448 G4double f2v = 2.0*(x*x*x)*(y*y)*(2.0+y);
449
450 G4double f_1ve = 8.0*(x*y*(1.0-2.0*y)
451 +2.0*(x*x)*(1.0-3.0*y)-4.0*(x*x*x));
452 G4double f0ve = 4.0*(-(x*x)*(2.0-3.0*y-4.0*(y*y))
453 +2.0*(x*x*x)*(2.0+3.0*y));
454 G4double f1ve = -4.0*(x*x*x)*y*(2.0+y);
455 G4double f2ve = 0.0;
456
457 G4double f_1vg = 8.0*((y*y)*(1.0-2.0*y)+x*y*(1.0-4.0*y)
458 -2.0*(x*x)*y);
459 G4double f0vg = 4.0*(2.0*x*(y*y)*(1.0+y)-(x*x)*y*(1.0-4.0*y)
460 +2.0*(x*x*x)*y);
461 G4double f1vg = 2.0*((x*x)*(y*y)*(1.0-2.0*y)
462 -4.0*(x*x*x)*(y*y));
463 G4double f2vg = 2.0*(x*x*x)*(y*y*y);
464
465 G4double f_1t = 8.0*((y*y)*(3.0-y)+3.0*x*y*(2.0-y)
466 +2.0*(x*x)*(3.0-2.0*y)-2.0*(x*x*x));
467 G4double f0t = 4.0*(-x*y*(6.0+(y*y))
468 -2.0*(x*x)*(3.0+y-3.0*(y*y))+2.0*(x*x*x)*(1.0+2.0*y));
469 G4double f1t = 2.0*((x*x)*y*(6.0-5.0*y+(y*y))
470 -(x*x*x)*y*(4.0+3.0*y));
471 G4double f2t = (x*x*x)*(y*y)*(2.0+y);
472
473 G4double f_1te = -8.0*(x*y*(1.0+3.0*y)+(x*x)*(2.0+3.0*y)
474 +2.0*(x*x*x));
475 G4double f0te = 4.0*((x*x)*(2.0+3.0*y+4.0*(y*y))
476 +(x*x*x)*(2.0+3.0*y));
477 G4double f1te = -2.0*(x*x*x)*y*(2.0+y);
478 G4double f2te = 0.0;
479
480 G4double f_1tg = -8.0*((y*y)*(1.0+y)+x*y+(x*x)*y);
481 G4double f0tg = 4.0*(x*(y*y)*(2.0-y)+(x*x)*y*(1.0+2.0*y)
482 +(x*x*x)*y);
483 G4double f1tg = -2.0*((x*x)*(y*y)*(1.0-y)+2.0*(x*x*x)*y);
484 G4double f2tg = (x*x*x)*(y*y*y);
485
486 G4double term = delta+2.0*(me*me)/((mu*mu)*(x*x));
487 term = 1.0/term;
488
489 G4double nss = term*f_1s+f0s+delta*f1s+(delta*delta)*f2s;
490 G4double nv = term*f_1v+f0v+delta*f1v+(delta*delta)*f2v;
491 G4double nt = term*f_1t+f0t+delta*f1t+(delta*delta)*f2t;
492
493 G4double nse = term*f_1se+f0se+delta*f1se+(delta*delta)*f2se;
494 G4double nve = term*f_1ve+f0ve+delta*f1ve+(delta*delta)*f2ve;
495 G4double nte = term*f_1te+f0te+delta*f1te+(delta*delta)*f2te;
496
497 G4double nsg = term*f_1sg+f0sg+delta*f1sg+(delta*delta)*f2sg;
498 G4double nvg = term*f_1vg+f0vg+delta*f1vg+(delta*delta)*f2vg;
499 G4double ntg = term*f_1tg+f0tg+delta*f1tg+(delta*delta)*f2tg;
500
501 G4double term1 = nv;
502 G4double term2 = 2.0*nss+nv-nt;
503 G4double term3 = 2.0*nss-2.0*nv+nt;
504
505 G4double term1e = 1.0/3.0*(1.0-4.0/3.0*del);
506 G4double term2e = 2.0*nse+5.0*nve-nte;
507 G4double term3e = 2.0*nse-2.0*nve+nte;
508
509 G4double term1g = 1.0/3.0*(1.0-4.0/3.0*del);
510 G4double term2g = 2.0*nsg+5.0*nvg-ntg;
511 G4double term3g = 2.0*nsg-2.0*nvg+ntg;
512
513 G4double som00 = term1+(1.0-4.0/3.0*rho)*term2+eps*term3;
514 G4double som01 = Pmu*ksi*(cthetaE*(nve-term1e*term2e+kap*term3e)
515 +cthetaG*(nvg-term1g*term2g+kap*term3g));
516
517 G4double som0 = (som00+som01)/y;
518 som0 = fine_structure_const/8./(twopi*twopi*twopi)*som0;
519
520 return som0;
521}
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)