Geant4-11
G4KL3DecayChannel.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// G4KL3DecayChannel class implementation
27//
28// Author: H.Kurashige, 30 May 1997
29// --------------------------------------------------------------------
30
33#include "G4SystemOfUnits.hh"
34#include "G4DecayProducts.hh"
35#include "G4VDecayChannel.hh"
36#include "G4KL3DecayChannel.hh"
37#include "Randomize.hh"
38#include "G4LorentzVector.hh"
39#include "G4LorentzRotation.hh"
40
43{
44}
45
46
48G4KL3DecayChannel(const G4String& theParentName,
49 G4double theBR,
50 const G4String& thePionName,
51 const G4String& theLeptonName,
52 const G4String& theNutrinoName)
53 : G4VDecayChannel("KL3 Decay", theParentName, theBR, 3,
54 thePionName, theLeptonName, theNutrinoName)
55{
56 static const G4String K_plus("kaon+");
57 static const G4String K_minus("kaon-");
58 static const G4String K_L("kaon0L");
59 static const G4String Mu_plus("mu+");
60 static const G4String Mu_minus("mu-");
61 static const G4String E_plus("e+");
62 static const G4String E_minus("e-");
63
64 // check modes
65 if ( ((theParentName == K_plus)&&(theLeptonName == E_plus)) ||
66 ((theParentName == K_minus)&&(theLeptonName == E_minus)) )
67 {
68 // K+- (Ke3)
69 pLambda = 0.0286;
70 pXi0 = -0.35;
71 }
72 else if ( ((theParentName == K_plus)&&(theLeptonName == Mu_plus)) ||
73 ((theParentName == K_minus)&&(theLeptonName == Mu_minus)) )
74 {
75 // K+- (Kmu3)
76 pLambda = 0.033;
77 pXi0 = -0.35;
78 }
79 else if ( (theParentName == K_L) &&
80 ((theLeptonName == E_plus) || (theLeptonName == E_minus)) )
81 {
82 // K0L (Ke3)
83 pLambda = 0.0300;
84 pXi0 = -0.11;
85 }
86 else if ( (theParentName == K_L) &&
87 ((theLeptonName == Mu_plus) || (theLeptonName == Mu_minus)) )
88 {
89 // K0L (Kmu3)
90 pLambda = 0.034;
91 pXi0 = -0.11;
92 }
93 else
94 {
95#ifdef G4VERBOSE
96 if (GetVerboseLevel()>2)
97 {
98 G4cout << "G4KL3DecayChannel:: constructor :";
99 G4cout << "illegal arguments " << G4endl;;
100 DumpInfo();
101 }
102#endif
103 // set values for K0L (Ke3) temporarily
104 pLambda = 0.0300;
105 pXi0 = -0.11;
106 }
107}
108
110{
111}
112
114 : G4VDecayChannel(right),
115 pLambda(right.pLambda),
116 pXi0(right.pXi0)
117{
118}
119
121{
122 if (this != &right)
123 {
126 rbranch = right.rbranch;
127
128 // copy parent name
129 parent_name = new G4String(*right.parent_name);
130
131 // clear daughters_name array
133
134 // recreate array
136 if ( numberOfDaughters >0 )
137 {
140 //copy daughters name
141 for (G4int index=0; index<numberOfDaughters; ++index)
142 {
143 daughters_name[index] = new G4String(*right.daughters_name[index]);
144 }
145 }
146 pLambda = right.pLambda;
147 pXi0 = right.pXi0;
148 }
149 return *this;
150}
151
153{
154 // this version neglects muon polarization
155 // assumes the pure V-A coupling
156 // gives incorrect energy spectrum for Neutrinos
157#ifdef G4VERBOSE
158 if (GetVerboseLevel()>1) G4cout << "G4KL3DecayChannel::DecayIt " << G4endl;
159#endif
160
161 // fill parent particle and its mass
164
165 // fill daughter particles and their mass
167 G4double daughterM[3];
168 daughterM[idPi] = G4MT_daughters[idPi]->GetPDGMass();
171
172 // determine momentum/energy of daughters according to DalitzDensity
173 G4double daughterP[3], daughterE[3];
174 G4double w;
175 G4double r;
176 const size_t MAX_LOOP = 10000;
177 for (std::size_t loop_counter=0; loop_counter<MAX_LOOP; ++loop_counter)
178 {
179 r = G4UniformRand();
180 PhaseSpace(massK, &daughterM[0], &daughterE[0], &daughterP[0]);
181 w = DalitzDensity(massK, daughterE[idPi], daughterE[idLepton],
182 daughterE[idNutrino], daughterM[idPi],
183 daughterM[idLepton], daughterM[idNutrino]);
184 if ( r <= w) break;
185 }
186
187 // output message
188#ifdef G4VERBOSE
189 if (GetVerboseLevel()>1)
190 {
191 G4cout << *daughters_name[0] << ":" << daughterP[0]/GeV << "[GeV/c]"
192 << G4endl;
193 G4cout << *daughters_name[1] << ":" << daughterP[1]/GeV << "[GeV/c]"
194 << G4endl;
195 G4cout << *daughters_name[2] << ":" << daughterP[2]/GeV << "[GeV/c]"
196 << G4endl;
197 }
198#endif
199
200 // create parent G4DynamicParticle at rest
201 G4ThreeVector* direction = new G4ThreeVector(1.0,0.0,0.0);
202 G4DynamicParticle* parentparticle
203 = new G4DynamicParticle( G4MT_parent, *direction, 0.0);
204 delete direction;
205
206 // create G4Decayproducts
207 G4DecayProducts *products
208 = new G4DecayProducts(*parentparticle);
209 delete parentparticle;
210
211 // create daughter G4DynamicParticle
212 G4double costheta, sintheta, phi, sinphi, cosphi;
213 G4double costhetan, sinthetan, phin, sinphin, cosphin;
214
215 // pion
216 costheta = 2.*G4UniformRand()-1.0;
217 sintheta = std::sqrt((1.0-costheta)*(1.0+costheta));
218 phi = twopi*G4UniformRand()*rad;
219 sinphi = std::sin(phi);
220 cosphi = std::cos(phi);
221 direction = new G4ThreeVector(sintheta*cosphi,sintheta*sinphi,costheta);
222 G4ThreeVector momentum0 = (*direction)*daughterP[0];
223 G4DynamicParticle * daughterparticle
224 = new G4DynamicParticle(G4MT_daughters[0], momentum0);
225 products->PushProducts(daughterparticle);
226
227 // neutrino
228 costhetan = (daughterP[1]*daughterP[1]
229 - daughterP[2]*daughterP[2]
230 - daughterP[0]*daughterP[0])/(2.0*daughterP[2]*daughterP[0]);
231 sinthetan = std::sqrt((1.0-costhetan)*(1.0+costhetan));
232 phin = twopi*G4UniformRand()*rad;
233 sinphin = std::sin(phin);
234 cosphin = std::cos(phin);
235 direction->setX( sinthetan*cosphin*costheta*cosphi
236 - sinthetan*sinphin*sinphi + costhetan*sintheta*cosphi);
237 direction->setY( sinthetan*cosphin*costheta*sinphi
238 + sinthetan*sinphin*cosphi + costhetan*sintheta*sinphi);
239 direction->setZ( -sinthetan*cosphin*sintheta + costhetan*costheta);
240
241 G4ThreeVector momentum2 = (*direction)*daughterP[2];
242 daughterparticle = new G4DynamicParticle( G4MT_daughters[2], momentum2);
243 products->PushProducts(daughterparticle);
244
245 // lepton
246 G4ThreeVector momentum1 = (momentum0 + momentum2) * (-1.0);
247 daughterparticle = new G4DynamicParticle( G4MT_daughters[1], momentum1);
248 products->PushProducts(daughterparticle);
249
250#ifdef G4VERBOSE
251 if (GetVerboseLevel()>1)
252 {
253 G4cout << "G4KL3DecayChannel::DecayIt ";
254 G4cout << " create decay products in rest frame " <<G4endl;
255 G4cout << " decay products address=" << products << G4endl;
256 products->DumpInfo();
257 }
258#endif
259 delete direction;
260 return products;
261}
262
264 const G4double* M,
265 G4double* E,
266 G4double* P )
267{
268 // Algorithm in this code was originally written in GDECA3 in GEANT3
269
270 // sum of daughters'mass
271 G4double sumofdaughtermass = 0.0;
272 G4int index;
273 const G4int N_DAUGHTER=3;
274
275 for (index=0; index<N_DAUGHTER; ++index)
276 {
277 sumofdaughtermass += M[index];
278 }
279
280 // calculate daughter momentum. Generate two
281 G4double rd1, rd2, rd;
282 G4double momentummax=0.0, momentumsum = 0.0;
284 const size_t MAX_LOOP=10000;
285 for (std::size_t loop_counter=0; loop_counter<MAX_LOOP; ++loop_counter)
286 {
287 rd1 = G4UniformRand();
288 rd2 = G4UniformRand();
289 if (rd2 > rd1)
290 {
291 rd = rd1;
292 rd1 = rd2;
293 rd2 = rd;
294 }
295 momentummax = 0.0;
296 momentumsum = 0.0;
297 // daughter 0
298 energy = rd2*(parentM - sumofdaughtermass);
299 P[0] = std::sqrt(energy*energy + 2.0*energy*M[0]);
300 E[0] = energy;
301 if ( P[0] >momentummax )momentummax = P[0];
302 momentumsum += P[0];
303 // daughter 1
304 energy = (1.-rd1)*(parentM - sumofdaughtermass);
305 P[1] = std::sqrt(energy*energy + 2.0*energy*M[1]);
306 E[1] = energy;
307 if ( P[1] >momentummax )momentummax = P[1];
308 momentumsum += P[1];
309 // daughter 2
310 energy = (rd1-rd2)*(parentM - sumofdaughtermass);
311 P[2] = std::sqrt(energy*energy + 2.0*energy*M[2]);
312 E[2] = energy;
313 if ( P[2] >momentummax )momentummax = P[2];
314 momentumsum += P[2];
315 if (momentummax <= momentumsum - momentummax ) break;
316 }
317#ifdef G4VERBOSE
318 if (GetVerboseLevel()>2)
319 {
320 G4cout << "G4KL3DecayChannel::PhaseSpace ";
321 G4cout << "Kon mass:" << parentM/GeV << "GeV/c/c" << G4endl;
322 for (index=0; index<3; ++index)
323 {
324 G4cout << index << " : " << M[index]/GeV << "GeV/c/c ";
325 G4cout << " : " << E[index]/GeV << "GeV ";
326 G4cout << " : " << P[index]/GeV << "GeV/c " << G4endl;
327 }
328 }
329#endif
330}
331
334 G4double Enu, G4double massPi, G4double massL,
335 G4double massNu)
336{
337 // KL3 decay - Dalitz Plot Density, see Chounet et al Phys. Rep. 4, 201
338 // Arguments
339 // Epi: kinetic enregy of pion
340 // El: kinetic enregy of lepton (e or mu)
341 // Enu: kinetic energy of nutrino
342 // Constants
343 // pLambda : linear energy dependence of f+
344 // pXi0 : = f+(0)/f-
345 // pNorm : normalization factor
346 // Variables
347 // Epi: total energy of pion
348 // El: total energy of lepton (e or mu)
349 // Enu: total energy of nutrino
350
351 // calculate total energy
352 Epi = Epi + massPi;
353 El = El + massL;
354 Enu = Enu + massNu;
355
356 G4double Epi_max = (massK*massK+massPi*massPi-massL*massL)/2.0/massK;
357 G4double E = Epi_max - Epi;
358 G4double q2 = massK*massK + massPi*massPi - 2.0*massK*Epi;
359
360 G4double F = 1.0 + pLambda*q2/massPi/massPi;
361 G4double Fmax = 1.0;
362 if (pLambda >0.0) Fmax = (1.0 + pLambda*(massK*massK/massPi/massPi+1.0));
363
364 G4double Xi = pXi0*(1.0 + pLambda*q2/massPi/massPi);
365
366 G4double coeffA = massK*(2.0*El*Enu-massK*E)+massL*massL*(E/4.0-Enu);
367 G4double coeffB = massL*massL*(Enu-E/2.0);
368 G4double coeffC = massL*massL*E/4.0;
369
370 G4double RhoMax = (Fmax*Fmax)*(massK*massK*massK/8.0);
371
372 G4double Rho = (F*F)*(coeffA + coeffB*Xi + coeffC*Xi*Xi);
373
374#ifdef G4VERBOSE
375 if (GetVerboseLevel()>2)
376 {
377 G4cout << "G4KL3DecayChannel::DalitzDensity " <<G4endl;
378 G4cout << " Pi[" << massPi/GeV <<"GeV/c/c] :" << Epi/GeV << "GeV" <<G4endl;
379 G4cout << " L[" << massL/GeV <<"GeV/c/c] :" << El/GeV << "GeV" <<G4endl;
380 G4cout << " Nu[" << massNu/GeV <<"GeV/c/c] :" << Enu/GeV << "GeV" <<G4endl;
381 G4cout << " F :" << F << " Fmax :" << Fmax << " Xi :" << Xi << G4endl;
382 G4cout << " A :" << coeffA << " B :" << coeffB << " C :"<< coeffC
383 << G4endl;
384 G4cout << " Rho :" << Rho << " RhoMax :" << RhoMax << G4endl;
385 }
386#endif
387 return (Rho/RhoMax);
388}
#define M(row, col)
static constexpr double twopi
Definition: G4SIunits.hh:56
static constexpr double rad
Definition: G4SIunits.hh:129
static constexpr double GeV
Definition: G4SIunits.hh:203
CLHEP::Hep3Vector G4ThreeVector
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
void setY(double)
void setZ(double)
void setX(double)
void DumpInfo() const
G4int PushProducts(G4DynamicParticle *aParticle)
void PhaseSpace(G4double Mparent, const G4double *Mdaughter, G4double *Edaughter, G4double *Pdaughter)
virtual G4DecayProducts * DecayIt(G4double)
G4double DalitzDensity(G4double parentmass, G4double Epi, G4double El, G4double Enu, G4double massPi, G4double massL, G4double massNu)
G4KL3DecayChannel & operator=(const G4KL3DecayChannel &)
G4ParticleDefinition ** G4MT_daughters
G4String * parent_name
G4String ** daughters_name
G4int GetVerboseLevel() const
G4ParticleDefinition * G4MT_parent
void CheckAndFillDaughters()
G4String kinematics_name
G4double energy(const ThreeVector &p, const G4double m)
static double P[]