15 #include <CLHEP/GenericFunctions/IncompleteGamma.hh>
16 #include <CLHEP/Units/PhysicalConstants.h>
17 #include <CLHEP/Random/Randomize.h>
18 #include <CLHEP/Random/RandGaussQ.h>
54 const double energyCutoff = 0.01;
55 const int maxNumberOfSpots = 100000;
63 double logEinc =
std::log(incomingEnergy);
72 double pathLength = pathLength0;
76 double fluctuatedTmax =
std::log(logY - 0.7157);
77 double fluctuatedAlpha =
std::log(0.7996 +(0.4581 + 1.8628/
Gflash::Z[jCalorimeter])*logY);
79 double sigmaTmax = 1.0/( -1.4 + 1.26 * logY);
80 double sigmaAlpha = 1.0/( -0.58 + 0.86 * logY);
81 double rho = 0.705 - 0.023 * logY;
85 double norm1 = CLHEP::RandGaussQ::shoot();
86 double norm2 = CLHEP::RandGaussQ::shoot();
87 double tempTmax = fluctuatedTmax + sigmaTmax*(sqrtPL*norm1 + sqrtLE*norm2);
88 double tempAlpha = fluctuatedAlpha + sigmaAlpha*(sqrtPL*norm1 - sqrtLE*norm2);
96 double averageTmax = logY-0.858;
100 double spotBeta =
std::max(0.0,(spotAlpha-1.0)/spotTmax);
109 double z1=0.0251+0.00319*logEinc;
115 double k4=0.3585+ 0.0421*logEinc;
119 double p3=1.313 -0.0686*logEinc;
124 double e25Scale = 1.0;
136 double deltaZInX0 = 0.0;
138 double stepLengthLeftInX0 = 0.0;
140 const double divisionStepInX0 = 0.1;
141 double energy = incomingEnergy;
143 Genfun::IncompleteGamma gammaDist;
145 double energyInGamma = 0.0;
146 double preEnergyInGamma = 0.0;
147 double sigmaInGamma = 0.;
148 double preSigmaInGamma = 0.0;
151 double deltaEnergy =0.0 ;
155 double deltaStep = 0.0;
160 while(energy > 0.0 && stepLengthLeft > 0.0) {
164 if ( stepLengthLeftInX0 < divisionStepInX0 ) {
165 deltaZInX0 = stepLengthLeftInX0;
167 stepLengthLeft = 0.0;
170 deltaZInX0 = divisionStepInX0;
172 stepLengthLeft -= deltaZ;
177 int nSpotsInStep = 0;
179 if ( energy > energyCutoff ) {
180 preEnergyInGamma = energyInGamma;
181 gammaDist.a().setValue(alpha);
182 energyInGamma = gammaDist(beta*zInX0);
183 double energyInDeltaZ = energyInGamma - preEnergyInGamma;
184 deltaEnergy =
std::min(energy,incomingEnergy*energyInDeltaZ);
186 preSigmaInGamma = sigmaInGamma;
187 gammaDist.a().setValue(spotAlpha);
188 sigmaInGamma = gammaDist(spotBeta*zInX0);
189 nSpotsInStep =
std::max(1,
int(nSpots * (sigmaInGamma - preSigmaInGamma)));
193 preSigmaInGamma = sigmaInGamma;
194 nSpotsInStep =
std::max(1,
int(nSpots * (1.0 - preSigmaInGamma)));
197 if ( deltaEnergy > energy || (energy-deltaEnergy) < energyCutoff ) deltaEnergy =
energy;
199 energy -= deltaEnergy;
201 if ( spotCounter+nSpotsInStep > maxNumberOfSpots ) {
202 nSpotsInStep = maxNumberOfSpots - spotCounter;
203 if ( nSpotsInStep < 1 ) {
204 edm::LogInfo(
"SimGeneralGFlash") <<
"GflashEMShowerProfile: Too Many Spots ";
205 edm::LogInfo(
"SimGeneralGFlash") <<
" - break to regenerate nSpotsInStep ";
211 deltaStep += 0.5*deltaZ;
212 pathLength += deltaStep;
213 deltaStep = 0.5*deltaZ;
216 double tScale = tmax *alpha/(alpha-1.0) * (
std::exp(fluctuatedAlpha)-1.0)/
std::exp(fluctuatedAlpha);
217 double tau =
std::min(10.0,(zInX0 - 0.5*deltaZInX0)/tScale);
218 double rCore = z1 + z2 *
tau;
220 double p23 = (p2 -
tau)/p3;
226 double hitEnergy = deltaEnergy / nSpotsInStep * e25Scale * CLHEP::GeV;
231 for (
int ispot = 0 ; ispot < nSpotsInStep ; ispot++) {
236 double incrementPath = (deltaZ/nSpotsInStep)*(ispot+0.5 - 0.5*nSpotsInStep);
242 double rShower = 0.0;
246 hitPosition *= CLHEP::cm;
251 aHit.setTime(hitTime);
252 aHit.setEnergy(hitEnergy);
253 aHit.setPosition(hitPosition);
282 double stepLengthLeft = 0.0;
292 return stepLengthLeft;
297 double rCore,
double rTail,
double probability,
double &rShower)
299 double u1 = CLHEP::HepUniformRand();
300 double u2 = CLHEP::HepUniformRand();
303 if (u1 < probability ) {
307 rInRM = rTail *
std::sqrt( u2/(1.0-u2) );
313 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
static int position[TOTALCHAMBERS][3]
GflashEMShowerProfile(const edm::ParameterSet &parSet)
Gflash::CalorimeterNumber jCalorimeter
const double rMoliere[kNumberCalorimeter]
CalorimeterNumber getCalorimeterNumber(const Gflash3Vector &position)
const T & max(const T &a, const T &b)
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()
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)