15 #include <CLHEP/GenericFunctions/IncompleteGamma.hh>
16 #include <CLHEP/Random/RandGaussQ.h>
17 #include <CLHEP/Random/Randomize.h>
18 #include <CLHEP/Units/PhysicalConstants.h>
48 const double energyCutoff = 0.01;
49 const int maxNumberOfSpots = 100000;
57 double logEinc =
std::log(incomingEnergy);
66 double pathLength = pathLength0;
73 double sigmaTmax = 1.0 / (-1.4 + 1.26 *
logY);
74 double sigmaAlpha = 1.0 / (-0.58 + 0.86 *
logY);
75 double rho = 0.705 - 0.023 *
logY;
79 double norm1 = CLHEP::RandGaussQ::shoot();
80 double norm2 = CLHEP::RandGaussQ::shoot();
81 double tempTmax = fluctuatedTmax + sigmaTmax * (sqrtPL * norm1 + sqrtLE * norm2);
82 double tempAlpha = fluctuatedAlpha + sigmaAlpha * (sqrtPL * norm1 - sqrtLE * norm2);
90 double averageTmax =
logY - 0.858;
94 double spotBeta =
std::max(0.0, (spotAlpha - 1.0) / spotTmax);
103 double z1 = 0.0251 + 0.00319 * logEinc;
109 double k4 = 0.3585 + 0.0421 * logEinc;
113 double p3 = 1.313 - 0.0686 * logEinc;
120 double e25Scale = 1.0;
134 double deltaZInX0 = 0.0;
136 double stepLengthLeftInX0 = 0.0;
138 const double divisionStepInX0 = 0.1;
139 double energy = incomingEnergy;
141 Genfun::IncompleteGamma gammaDist;
143 double energyInGamma = 0.0;
144 double preEnergyInGamma = 0.0;
145 double sigmaInGamma = 0.;
147 double preSigmaInGamma = 0.0;
150 double deltaEnergy = 0.0;
154 double deltaStep = 0.0;
159 while (
energy > 0.0 && stepLengthLeft > 0.0) {
162 if (stepLengthLeftInX0 < divisionStepInX0) {
163 deltaZInX0 = stepLengthLeftInX0;
165 stepLengthLeft = 0.0;
167 deltaZInX0 = divisionStepInX0;
174 int nSpotsInStep = 0;
176 if (
energy > energyCutoff) {
177 preEnergyInGamma = energyInGamma;
178 gammaDist.a().setValue(
alpha);
179 energyInGamma = gammaDist(
beta * zInX0);
180 double energyInDeltaZ = energyInGamma - preEnergyInGamma;
183 preSigmaInGamma = sigmaInGamma;
184 gammaDist.a().setValue(spotAlpha);
185 sigmaInGamma = gammaDist(spotBeta * zInX0);
186 nSpotsInStep =
std::max(1,
int(nSpots * (sigmaInGamma - preSigmaInGamma)));
189 preSigmaInGamma = sigmaInGamma;
190 nSpotsInStep =
std::max(1,
int(nSpots * (1.0 - preSigmaInGamma)));
193 if (deltaEnergy >
energy || (
energy - deltaEnergy) < energyCutoff)
198 if (spotCounter + nSpotsInStep > maxNumberOfSpots) {
199 nSpotsInStep = maxNumberOfSpots - spotCounter;
200 if (nSpotsInStep < 1) {
201 edm::LogInfo(
"SimGeneralGFlash") <<
"GflashEMShowerProfile: Too Many Spots ";
202 edm::LogInfo(
"SimGeneralGFlash") <<
" - break to regenerate nSpotsInStep ";
208 deltaStep += 0.5 *
deltaZ;
209 pathLength += deltaStep;
214 double tau =
std::min(10.0, (zInX0 - 0.5 * deltaZInX0) / tScale);
215 double rCore = z1 +
z2 *
tau;
223 double hitEnergy = deltaEnergy / nSpotsInStep * e25Scale *
CLHEP::GeV;
228 for (
int ispot = 0; ispot < nSpotsInStep; ispot++) {
234 double incrementPath = (
deltaZ / nSpotsInStep) * (ispot + 0.5 - 0.5 * nSpotsInStep);
241 double rShower = 0.0;
245 hitPosition *= CLHEP::cm;
251 aHit.setTime(hitTime);
252 aHit.setEnergy(hitEnergy);
253 aHit.setPosition(hitPosition);
280 double stepLengthLeft = 0.0;
289 return stepLengthLeft;
294 double u1 = CLHEP::HepUniformRand();
295 double u2 = CLHEP::HepUniformRand();
298 if (
u1 < probability) {
307 double azimuthalAngle = CLHEP::twopi * CLHEP::HepUniformRand();
311 rShower *
std::sin(azimuthalAngle) *
point.getCrossUnitVector();