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;
70 double fluctuatedTmax =
std::log(logY - 0.7157);
71 double fluctuatedAlpha =
std::log(0.7996 + (0.4581 + 1.8628 /
Gflash::Z[jCalorimeter]) * logY);
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;
76 double sqrtPL =
std::sqrt((1.0 + rho) / 2.0);
77 double sqrtLE =
std::sqrt((1.0 - rho) / 2.0);
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;
169 stepLengthLeft -= deltaZ;
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;
181 deltaEnergy =
std::min(energy, incomingEnergy * energyInDeltaZ);
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)
196 energy -= deltaEnergy;
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;
210 deltaStep = 0.5 * deltaZ;
213 double tScale = tmax * alpha / (alpha - 1.0) * (
std::exp(fluctuatedAlpha) - 1.0) /
std::exp(fluctuatedAlpha);
214 double tau =
std::min(10.0, (zInX0 - 0.5 * deltaZInX0) / tScale);
215 double rCore = z1 + z2 *
tau;
216 double rTail = k1 * (
std::exp(k3 * (tau - k2)) +
std::exp(k4 * (tau - k2)));
217 double p23 = (p2 -
tau) / p3;
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) {
299 rInRM = rCore *
std::sqrt(u2 / (1.0 - u2));
301 rInRM = rTail *
std::sqrt(u2 / (1.0 - u2));
307 double azimuthalAngle = CLHEP::twopi * CLHEP::HepUniformRand();
const double Z[kNumberCalorimeter]
T getParameter(std::string const &) const
static GflashHistogram * instance()
GflashShowino * theShowino
double getPathLengthAtZ(double z) const
const double Zmax[kNumberCalorimeter]
Gflash3Vector getCrossUnitVector()
Gflash3Vector & getPosition()
GflashTrajectory * getHelix()
Sin< T >::type sin(const T &t)
double getDistanceToOut(Gflash::CalorimeterNumber kCalor)
GflashHistogram * theHisto
std::vector< GflashHit > theGflashHitList
GflashEMShowerProfile(const edm::ParameterSet &parSet)
Gflash::CalorimeterNumber jCalorimeter
const double rMoliere[kNumberCalorimeter]
CalorimeterNumber getCalorimeterNumber(const Gflash3Vector &position)
double getPathLengthAtShower()
Cos< T >::type cos(const T &t)
Abs< T >::type abs(const T &t)
void initialize(int showerType, double energy, double globalTime, double charge, Gflash3Vector &position, Gflash3Vector &momentum)
const double criticalEnergy
Gflash3Vector & getPositionAtShower()
Gflash3Vector getOrthogonalUnitVector()
void getGflashTrajectoryPoint(GflashTrajectoryPoint &point, double s) const
Gflash3Vector locateHitPosition(GflashTrajectoryPoint &point, double rCore, double rTail, double probability, double &rShower)
static const double tmax[3]
const double radLength[kNumberCalorimeter]
CLHEP::Hep3Vector Gflash3Vector
Gflash3Vector & getPosition()
static int position[264][3]
const double Rmax[kNumberCalorimeter]
Power< A, B >::type pow(const A &a, const B &b)
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
double getPathLengthAtRhoEquals(double rho) const
void initialize(int showerType, double energy, double globalTime, double charge, Gflash3Vector &position, Gflash3Vector &momentum, double magneticField)