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