43 #include "CLHEP/Random/RandGaussQ.h"
44 #include "CLHEP/Random/RandPoisson.h"
45 #include "CLHEP/Random/RandFlat.h"
48 #include <EVENT/MCParticle.h>
51 using namespace CLHEP ;
58 SiEnergyFluct::SiEnergyFluct(
double cutOnDeltaRays) : _cutOnDeltaRays(cutOnDeltaRays)
124 double mass = part->getMass() *
GeV;
125 double momentum2 = ( part->getMomentum()[0]*part->getMomentum()[0] +
126 part->getMomentum()[1]*part->getMomentum()[1] +
127 part->getMomentum()[2]*part->getMomentum()[2] ) *
GeV*
GeV;
128 double kineticEnergy = sqrt(momentum2 + mass*mass) - mass;
129 double ratio =
e_mass/mass;
130 double tau = kineticEnergy/mass;
131 double gam = tau + 1.0;
132 double gam2 = gam*gam;
133 double bg2 = tau * (tau+2.0);
134 double beta2 = bg2/(gam2);
135 int pdg = part->getPDG();
136 double chargeSquare = part->getCharge()*part->getCharge();
138 double maxT = 2.0*
e_mass*tau*(tau + 2.) / (1. + 2.0*(tau + 1.)*ratio + ratio*ratio);
142 double meanLoss = 0.;
183 double massrate =
e_mass/mass ;
184 double tmaxkine = 2.*
e_mass*beta2*gam2/(1.+massrate*(2.*gam+massrate));
186 if (tmaxkine <= 2.*maxT) {
189 sigma = (1.0/beta2 - 0.5) *
_KBethe * maxT * length * chargeSquare;
192 double twomeanLoss = meanLoss + meanLoss;
194 if (twomeanLoss < sigma) {
199 loss = twomeanLoss*RandFlat::shoot();
200 x = (loss - meanLoss)/sigma;
202 }
while (1.0 - 0.5*x*x < RandFlat::shoot());
208 loss = RandGaussQ::shoot(meanLoss,sigma);
210 }
while (loss < 0. || loss > twomeanLoss);
221 if (maxT <=
_e0)
return meanLoss;
235 if (width > 4.50) width = 4.50;
243 double w2 = log(2.*
e_mass*beta2*gam2)-beta2;
256 double w1 = maxT/
_e0;
257 if(maxT >
_e0) a3 = rate*meanLoss*(maxT-
_e0)/(
_e0*maxT*log(w1));
275 p1 = double(RandPoisson::shoot(a1));
278 if(p1 > 0.) loss += (1.-2.*RandFlat::shoot())*e1;
289 p2 = double(RandPoisson::shoot(a2));
292 if(p2 > 0.) loss += (1.-2.*RandFlat::shoot())*e2;
306 double alfa1 = alfa*log(alfa)/(alfa-1.);
307 double namean = a3*w1*(alfa-1.)/((w1-1.)*alfa);
308 emean += namean*
_e0*alfa1;
309 sig2e +=
_e0*
_e0*namean*(alfa-alfa1*alfa1);
313 double w2 = alfa*
_e0;
314 double w = (maxT-w2)/maxT;
316 int nb = RandPoisson::shoot(p3);
318 if (nb > 0)
for (
int k=0;
k<nb;
k++) lossc += w2/(1.-w*RandFlat::shoot());
324 loss += std::max(0.,RandGaussQ::shoot(emean,sige));
338 double mass = part->getMass() *
GeV;
339 double momentum2 = ( part->getMomentum()[0]*part->getMomentum()[0] +
340 part->getMomentum()[1]*part->getMomentum()[1] +
341 part->getMomentum()[2]*part->getMomentum()[2] ) *
GeV*
GeV;
342 double kineticEnergy = sqrt(momentum2 + mass*mass) - mass;
344 double charge2 = part->getCharge()*part->getCharge();
345 double ratio =
e_mass/mass;
346 double tau = kineticEnergy/mass;
347 double gam = tau + 1.0;
348 double bg2 = tau * (tau+2.0);
349 double beta2 = bg2/(gam*gam);
351 double maxT = 2.0*
e_mass*tau*(tau + 2.) / (1. + 2.0*(tau + 1.)*ratio + ratio*ratio);
355 double dedx = log(2.0*
e_mass*bg2*cutEnergy/
_eexc2) - (1.0 + cutEnergy/maxT)*beta2;
360 double del = 0.5*cutEnergy/(kineticEnergy + mass);
377 if (dedx < 0.0) dedx = 0.0 ;
393 double mass = part->getMass() *
GeV;
394 double momentum2 = ( part->getMomentum()[0]*part->getMomentum()[0] +
395 part->getMomentum()[1]*part->getMomentum()[1] +
396 part->getMomentum()[2]*part->getMomentum()[2] ) *
GeV*
GeV;
397 double kineticEnergy = sqrt(momentum2 + mass*mass) - mass;
398 double totEnergy = kineticEnergy + mass;
399 double ratio =
e_mass/mass;
400 double tau = kineticEnergy/mass;
401 double gam = tau + 1.0;
402 double bg2 = tau * (tau+2.0);
403 double beta2 = bg2/(gam*gam);
405 double maxT = 2.0*
e_mass*tau*(tau + 2.) / (1. + 2.0*(tau + 1.)*ratio + ratio*ratio);
409 double dedx = log(2.0*
e_mass*bg2*cutEnergy/
_eexc2) - (1.0 + cutEnergy/maxT)*beta2;
411 double del = 0.5*cutEnergy/totEnergy;
428 if (dedx < 0.0) dedx = 0.0 ;
433 double logtmax = log(cutEnergy);
436 double ftot2 = 0.5/(totEnergy*totEnergy);
438 for (
int ll=0; ll<8; ll++)
440 double ep = exp(_logLimitKinEnergy +
_xgi[ll]*logstep);
441 double a1 = log(1.0 + 2.0*ep/
e_mass);
442 double a3 = log(4.0*totEnergy*(totEnergy - ep)/mass/mass);
443 dloss +=
_wgi[ll]*(1.0 - beta2*ep/maxT + ep*ep*ftot2)*a1*(a3 - a1);
462 double mass = part->getMass() *
GeV;
463 double momentum = ( part->getMomentum()[0]*part->getMomentum()[0] +
464 part->getMomentum()[1]*part->getMomentum()[1] +
465 part->getMomentum()[2]*part->getMomentum()[2] ) *
GeV*
GeV;
466 double kineticEnergy = sqrt(momentum*momentum + mass*mass) - mass;
467 double charge = part->getCharge();
468 double tau = kineticEnergy/mass;
469 double gam = tau + 1.0;
470 double gamma2 = gam*gam;
471 double bg2 = tau * (tau+2.0);
472 double beta2 = bg2/(gamma2);
475 bool lowEnergy =
false;
476 double tkin = kineticEnergy;
478 if (kineticEnergy <
_th) {
482 double lowLimit = 0.2*
keV;
484 double maxT = kineticEnergy;
486 if(charge < 0.) maxT *= 0.5;
489 double eexc2 = eexc*eexc;
497 dedx = log(2.0*(tau + 2.0)/eexc2) - 1.0 - beta2 + log((tau-d)*d) + tau/(tau-d)
498 + (0.5*d*d + (2.0*tau + 1.)*log(1. - d/tau))/gamma2;
504 double d3 = d2*d/1.5;
505 double d4 = d3*d*3.75;
506 double y = 1.0/(1.0 + gam);
507 dedx = log(2.0*(tau + 2.0)/eexc2) + log(tau*d) - beta2*(tau + 2.0*d - y*(3.0*d2
508 + y*(d - d3 + y*(d2 - tau*d3 + d4))))/tau;
522 if (dedx < 0.0) dedx = 0.0;
528 if (kineticEnergy >= lowLimit) dedx *= sqrt(tkin/kineticEnergy);
529 else dedx *= sqrt(tkin*kineticEnergy)/lowLimit;
double getElectronDEDX(const MCParticle *part)
Method calculating actual dEdx for electrons & positrons - based on ComputeDEDXPerVolume method G4Mol...
double _minNumberInteractionsBohr
static const double e_mass
double _cutOnDeltaRays
Cut on secondary electrons - must be the same as in Geant4.
double SampleFluctuations(const MCParticle *part, const double length)
Method providing energy loss fluctuations, the model used to get the fluctuations is essentially the ...
const MCParticle * _prevMCPart
double getMuonDEDX(const MCParticle *part)
Method calculating actual dEdx for muons - based on ComputeDEDXPerVolume method from G4MuBetheBlochMo...
double _logLimitKinEnergy
~SiEnergyFluct()
Destructor.
double getHadronDEDX(const MCParticle *part)
Method calculating actual dEdx for hadrons - based on ComputeDEDXPerVolume method from G4BetheBlochMo...
static const double fine_str_const