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