16 #include <CLHEP/GenericFunctions/IncompleteGamma.hh>
17 #include <CLHEP/Units/PhysicalConstants.h>
18 #include <CLHEP/Random/Randomize.h>
19 #include <CLHEP/Random/RandGaussQ.h>
55 const double energyCutoff = 0.01;
56 const int maxNumberOfSpots = 100000;
64 double logEinc =
std::log(incomingEnergy);
73 double pathLength = pathLength0;
77 double fluctuatedTmax =
std::log(logY - 0.7157);
78 double fluctuatedAlpha =
std::log(0.7996 +(0.4581 + 1.8628/
Gflash::Z[jCalorimeter])*logY);
80 double sigmaTmax = 1.0/( -1.4 + 1.26 * logY);
81 double sigmaAlpha = 1.0/( -0.58 + 0.86 * logY);
82 double rho = 0.705 - 0.023 * logY;
86 double norm1 = CLHEP::RandGaussQ::shoot();
87 double norm2 = CLHEP::RandGaussQ::shoot();
88 double tempTmax = fluctuatedTmax + sigmaTmax*(sqrtPL*norm1 + sqrtLE*norm2);
89 double tempAlpha = fluctuatedAlpha + sigmaAlpha*(sqrtPL*norm1 - sqrtLE*norm2);
97 double averageTmax = logY-0.858;
101 double spotBeta =
std::max(0.0,(spotAlpha-1.0)/spotTmax);
110 double z1=0.0251+0.00319*logEinc;
116 double k4=0.3585+ 0.0421*logEinc;
120 double p3=1.313 -0.0686*logEinc;
125 double e25Scale = 1.0;
137 double deltaZInX0 = 0.0;
139 double stepLengthLeftInX0 = 0.0;
141 const double divisionStepInX0 = 0.1;
142 double energy = incomingEnergy;
144 Genfun::IncompleteGamma gammaDist;
146 double energyInGamma = 0.0;
147 double preEnergyInGamma = 0.0;
148 double sigmaInGamma = 0.;
149 double preSigmaInGamma = 0.0;
152 double deltaEnergy =0.0 ;
156 double deltaStep = 0.0;
161 while(energy > 0.0 && stepLengthLeft > 0.0) {
165 if ( stepLengthLeftInX0 < divisionStepInX0 ) {
166 deltaZInX0 = stepLengthLeftInX0;
168 stepLengthLeft = 0.0;
171 deltaZInX0 = divisionStepInX0;
173 stepLengthLeft -= deltaZ;
178 int nSpotsInStep = 0;
180 if ( energy > energyCutoff ) {
181 preEnergyInGamma = energyInGamma;
182 gammaDist.a().setValue(alpha);
183 energyInGamma = gammaDist(beta*zInX0);
184 double energyInDeltaZ = energyInGamma - preEnergyInGamma;
185 deltaEnergy =
std::min(energy,incomingEnergy*energyInDeltaZ);
187 preSigmaInGamma = sigmaInGamma;
188 gammaDist.a().setValue(spotAlpha);
189 sigmaInGamma = gammaDist(spotBeta*zInX0);
190 nSpotsInStep =
std::max(1,
int(nSpots * (sigmaInGamma - preSigmaInGamma)));
194 preSigmaInGamma = sigmaInGamma;
195 nSpotsInStep =
std::max(1,
int(nSpots * (1.0 - preSigmaInGamma)));
198 if ( deltaEnergy > energy || (energy-deltaEnergy) < energyCutoff ) deltaEnergy =
energy;
200 energy -= deltaEnergy;
202 if ( spotCounter+nSpotsInStep > maxNumberOfSpots ) {
203 nSpotsInStep = maxNumberOfSpots - spotCounter;
204 if ( nSpotsInStep < 1 ) {
205 edm::LogInfo(
"SimGeneralGFlash") <<
"GflashEMShowerProfile: Too Many Spots ";
206 edm::LogInfo(
"SimGeneralGFlash") <<
" - break to regenerate nSpotsInStep ";
212 deltaStep += 0.5*deltaZ;
213 pathLength += deltaStep;
214 deltaStep = 0.5*deltaZ;
217 double tScale = tmax *alpha/(alpha-1.0) * (
std::exp(fluctuatedAlpha)-1.0)/
std::exp(fluctuatedAlpha);
218 double tau =
std::min(10.0,(zInX0 - 0.5*deltaZInX0)/tScale);
219 double rCore = z1 + z2 *
tau;
221 double p23 = (p2 -
tau)/p3;
227 double hitEnergy = deltaEnergy / nSpotsInStep * e25Scale * CLHEP::GeV;
232 for (
int ispot = 0 ; ispot < nSpotsInStep ; ispot++) {
237 double incrementPath = (deltaZ/nSpotsInStep)*(ispot+0.5 - 0.5*nSpotsInStep);
243 double rShower = 0.0;
247 hitPosition *= CLHEP::cm;
252 aHit.setTime(hitTime);
253 aHit.setEnergy(hitEnergy);
254 aHit.setPosition(hitPosition);
283 double stepLengthLeft = 0.0;
293 return stepLengthLeft;
298 double rCore,
double rTail,
double probability,
double &rShower)
300 double u1 = CLHEP::HepUniformRand();
301 double u2 = CLHEP::HepUniformRand();
304 if (u1 < probability ) {
308 rInRM = rTail *
std::sqrt( u2/(1.0-u2) );
314 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
Gflash::CalorimeterNumber jCalorimeter
const double rMoliere[kNumberCalorimeter]
const T & max(const T &a, const T &b)
double getPathLengthAtShower()
Cos< T >::type cos(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
CalorimeterNumber getCalorimeterNumber(const Gflash3Vector position)
Gflash3Vector & getPosition()
static int position[264][3]
const double Rmax[kNumberCalorimeter]
GflashEMShowerProfile(edm::ParameterSet parSet)
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)