![]() |
![]() |
#include <SimG4Core/GFlash/interface/GflashEMShowerProfile.h>
Public Member Functions | |
void | clearSpotList () |
std::vector< GflashEnergySpot > & | getEnergySpotList () |
GflashEMShowerProfile (G4Region *envelope) | |
void | parameterization (const G4FastTrack &fastTrack) |
~GflashEMShowerProfile () | |
Private Attributes | |
std::vector< GflashEnergySpot > | aEnergySpotList |
GflashTrajectory * | theHelix |
GflashHistogram * | theHisto |
CLHEP::RandGaussQ * | theRandGauss |
Definition at line 12 of file GflashEMShowerProfile.h.
GflashEMShowerProfile::GflashEMShowerProfile | ( | G4Region * | envelope | ) |
Definition at line 20 of file GflashEMShowerProfile.cc.
References Exception, GflashHistogram::instance(), edm::Service< T >::isAvailable(), theHelix, theHisto, and theRandGauss.
00021 { 00022 theHelix = new GflashTrajectory; 00023 theHisto = GflashHistogram::instance(); 00024 00025 edm::Service<edm::RandomNumberGenerator> rng; 00026 if ( ! rng.isAvailable()) { 00027 throw cms::Exception("Configuration") 00028 << "GflashHadronShowerProfile requires RandomNumberGeneratorService\n" 00029 << "which is not present in the configuration file. " 00030 << "You must add the service\n in the configuration file or " 00031 << "remove the modules that require it."; 00032 } 00033 theRandGauss = new CLHEP::RandGaussQ(rng->getEngine()); 00034 }
GflashEMShowerProfile::~GflashEMShowerProfile | ( | ) |
Definition at line 36 of file GflashEMShowerProfile.cc.
References theHelix, and theRandGauss.
00037 { 00038 delete theHelix; 00039 delete theRandGauss; 00040 }
void GflashEMShowerProfile::clearSpotList | ( | ) | [inline] |
Definition at line 21 of file GflashEMShowerProfile.h.
References aEnergySpotList.
Referenced by GflashEMShowerModel::DoIt().
00021 { aEnergySpotList.clear(); }
std::vector<GflashEnergySpot>& GflashEMShowerProfile::getEnergySpotList | ( | ) | [inline] |
Definition at line 23 of file GflashEMShowerProfile.h.
References aEnergySpotList.
Referenced by GflashEMShowerModel::DoIt().
00023 {return aEnergySpotList;};
void GflashEMShowerProfile::parameterization | ( | const G4FastTrack & | fastTrack | ) |
Definition at line 42 of file GflashEMShowerProfile.cc.
References funct::abs(), aEnergySpotList, DeDxTools::beta(), funct::cos(), GenMuonPlsPt100GeV_cfg::cout, GflashHistogram::dEdz, GflashHistogram::dEdz_p, GflashHistogram::dndz_spot, GflashHistogram::dx, lat::endl(), relval_parameters_module::energy, funct::exp(), GflashTrajectoryPoint::getCrossUnitVector(), GflashTrajectory::getGflashTrajectoryPoint(), GflashTrajectoryPoint::getOrthogonalUnitVector(), GflashTrajectory::getPathLengthAtRhoEquals(), GflashTrajectoryPoint::getPosition(), GflashHistogram::getStoreFlag(), GflashHistogram::incE_atEcal, GflashTrajectory::initializeTrajectory(), funct::log(), max, min, norm1(), p1, p2, p3, funct::pow(), radLength, GflashHistogram::rArm, rho, GflashHistogram::rho_ssp, rMoliere, GflashHistogram::rxry, GflashHistogram::rzSpots, GflashEnergySpot::setEnergy(), GflashEnergySpot::setPosition(), funct::sin(), funct::sqrt(), metsig::tau, theHelix, theHisto, theRandGauss, tmax, GflashHistogram::xdz, and y.
Referenced by GflashEMShowerModel::DoIt().
00043 { 00044 // This part of code is copied from the original GFlash Fortran code. 00045 // reference : hep-ex/0001020v1 00046 00047 const G4double energyCutoff = 0.01; 00048 const G4int maxNumberOfSpots = 100000; 00049 00050 G4double incomingEnergy = fastTrack.GetPrimaryTrack()->GetKineticEnergy()/GeV; 00051 const G4double radLength = 0.89; // cm 00052 const G4double Z = 68.360; 00053 const G4double rMoliere = 2.19; // cm 00054 const G4double criticalEnergy = 8.6155/GeV; // eScale*radLength/rMoliere (in MeV) need to convert into GeV 00055 G4double nSpots = 93.0 * std::log(Z) * std::pow(incomingEnergy,0.876); // total number of spots 00056 00057 G4double logEinc = std::log(incomingEnergy); 00058 G4double y = incomingEnergy / criticalEnergy; // y = E/Ec, criticalEnergy is in GeV 00059 G4double logY = std::log(y); 00060 00061 G4ThreeVector showerStartingPosition = fastTrack.GetPrimaryTrack()->GetPosition() / cm; 00062 G4ThreeVector showerMomentum = fastTrack.GetPrimaryTrack()->GetMomentum()/GeV; 00063 00064 00065 // implementing magnetic field effects 00066 const G4double bField = 4.0; // in Tesla 00067 double charge = fastTrack.GetPrimaryTrack()->GetStep()->GetPreStepPoint()->GetCharge(); 00068 // GflashTrajectory helix(showerMomentum,showerStartingPosition,charge,bField); 00069 theHelix->initializeTrajectory(showerMomentum,showerStartingPosition,charge,bField); 00070 00071 //path Length from the origin to the shower starting point in cm 00072 G4double pathLength0 = theHelix->getPathLengthAtRhoEquals(showerStartingPosition.getRho()); 00073 G4double pathLength = pathLength0; // this will grow along the shower development 00074 00075 00076 //--- 2.2 Fix intrinsic properties of em. showers. 00077 00078 G4double fluctuatedTmax = std::log(logY - 0.7157); 00079 G4double fluctuatedAlpha = std::log(0.7996 +(0.4581 + 1.8628/Z)*logY); 00080 00081 G4double sigmaTmax = 1.0/( -1.4 + 1.26 * logY); 00082 G4double sigmaAlpha = 1.0/( -0.58 + 0.86 * logY); 00083 G4double rho = 0.705 - 0.023 * logY; 00084 G4double sqrtPL = std::sqrt((1.0+rho)/2.0); 00085 G4double sqrtLE = std::sqrt((1.0-rho)/2.0); 00086 00087 G4double norm1 = theRandGauss->fire(); 00088 G4double norm2 = theRandGauss->fire(); 00089 G4double tempTmax = fluctuatedTmax + sigmaTmax*(sqrtPL*norm1 + sqrtLE*norm2); 00090 G4double tempAlpha = fluctuatedAlpha + sigmaAlpha*(sqrtPL*norm1 - sqrtLE*norm2); 00091 00092 // tmax, alpha, beta : parameters of gamma distribution 00093 G4double tmax = std::exp(tempTmax); 00094 G4double alpha = std::exp(tempAlpha); 00095 G4double beta = (alpha - 1.0)/tmax; 00096 00097 // spot fluctuations are added to tmax, alpha, beta 00098 G4double averageTmax = logY-0.858; 00099 G4double averageAlpha = 0.21+(0.492+2.38/Z)*logY; 00100 G4double spotTmax = averageTmax * (0.698 + .00212*Z); 00101 G4double spotAlpha = averageAlpha * (0.639 + .00334*Z); 00102 G4double spotBeta = (spotAlpha-1.0)/spotTmax; 00103 00104 00105 if(theHisto->getStoreFlag()) { 00106 theHisto->incE_atEcal->Fill(incomingEnergy); 00107 theHisto->rho_ssp->Fill(showerStartingPosition.rho()); 00108 } 00109 00110 // parameters for lateral distribution and fluctuation 00111 G4double z1=0.0251+0.00319*logEinc; 00112 G4double z2=0.1162-0.000381*Z; 00113 00114 G4double k1=0.659 - 0.00309 * Z; 00115 G4double k2=0.645; 00116 G4double k3=-2.59; 00117 G4double k4=0.3585+ 0.0421*logEinc; 00118 00119 G4double p1=2.623 -0.00094*Z; 00120 G4double p2=0.401 +0.00187*Z; 00121 G4double p3=1.313 -0.0686*logEinc; 00122 00123 //@@@ dwjang, intial tuning by comparing 20GeV TB data 00124 p1 = 2.47; 00125 00126 // preparation of longitudinal integration 00127 G4double stepLengthLeft = fastTrack.GetEnvelopeSolid()->DistanceToOut(fastTrack.GetPrimaryTrackLocalPosition(), 00128 fastTrack.GetPrimaryTrackLocalDirection()) / cm; 00129 00130 G4double zInX0 = 0.0; // shower depth in X0 unit 00131 G4double deltaZInX0 = 0.0; // segment of depth in X0 unit 00132 G4double deltaZ = 0.0; // segment of depth in cm 00133 G4double stepLengthLeftInX0 = 0.0; // step length left in X0 unit 00134 00135 const G4double divisionStepInX0 = 0.1; //step size in X0 unit 00136 G4double energy = incomingEnergy; // energy left in GeV 00137 00138 Genfun::IncompleteGamma gammaDist; 00139 00140 G4double energyInGamma = 0.0; // energy in a specific depth(z) according to Gamma distribution 00141 G4double preEnergyInGamma = 0.0; // energy calculated in a previous depth 00142 G4double sigmaInGamma = 0.; // sigma of energy in a specific depth(z) according to Gamma distribution 00143 G4double preSigmaInGamma = 0.0; // sigma of energy in a previous depth 00144 00145 //energy segment in Gamma distribution of shower in each step 00146 G4double deltaEnergy =0.0 ; // energy in deltaZ 00147 G4int spotCounter = 0; // keep track of number of spots generated 00148 00149 //step increment along the shower direction 00150 G4double deltaStep = 0.0; 00151 00152 // loop for longitudinal integration 00153 while(energy > 0.0 && stepLengthLeft > 0.0) { 00154 00155 stepLengthLeftInX0 = stepLengthLeft / radLength; 00156 00157 if ( stepLengthLeftInX0 < divisionStepInX0 ) { 00158 deltaZInX0 = stepLengthLeftInX0; 00159 deltaZ = deltaZInX0 * radLength; 00160 stepLengthLeft = 0.0; 00161 } 00162 else { 00163 deltaZInX0 = divisionStepInX0; 00164 deltaZ = deltaZInX0 * radLength; 00165 stepLengthLeft -= deltaZ; 00166 } 00167 00168 zInX0 += deltaZInX0; 00169 00170 00171 G4int nSpotsInStep = 0; 00172 00173 if ( energy > energyCutoff ) { 00174 preEnergyInGamma = energyInGamma; 00175 gammaDist.a().setValue(alpha); //alpha 00176 energyInGamma = gammaDist(beta*zInX0); //beta 00177 G4double energyInDeltaZ = energyInGamma - preEnergyInGamma; 00178 deltaEnergy = std::min(energy,incomingEnergy*energyInDeltaZ); 00179 00180 preSigmaInGamma = sigmaInGamma; 00181 gammaDist.a().setValue(spotAlpha); //alpha spot 00182 sigmaInGamma = gammaDist(spotBeta*zInX0); //beta spot 00183 nSpotsInStep = std::max(1,int(nSpots * (sigmaInGamma - preSigmaInGamma))); 00184 } 00185 else { 00186 deltaEnergy = energy; 00187 preSigmaInGamma = sigmaInGamma; 00188 nSpotsInStep = std::max(1,int(nSpots * (1.0 - preSigmaInGamma))); 00189 } 00190 00191 if ( deltaEnergy > energy || (energy-deltaEnergy) < energyCutoff ) deltaEnergy = energy; 00192 00193 energy -= deltaEnergy; 00194 00195 if ( spotCounter+nSpotsInStep > maxNumberOfSpots ) { 00196 nSpotsInStep = maxNumberOfSpots - spotCounter; 00197 if ( nSpotsInStep < 1 ) { // @@ check 00198 std::cout << "GflashEMShowerProfile::Parameterization : Too Many Spots " << std::endl; 00199 std::cout << " break to regenerate nSpotsInStep " << std::endl; 00200 break; 00201 } 00202 } 00203 00204 00205 // It begins with 0.5 of deltaZ and then icreases by 1 deltaZ 00206 deltaStep += 0.5*deltaZ; 00207 pathLength += deltaStep; 00208 deltaStep = 0.5*deltaZ; 00209 00210 00211 // lateral shape and fluctuations for homogenous calo. 00212 G4double tScale = tmax *alpha/(alpha-1.0) * (std::exp(fluctuatedAlpha)-1.0)/std::exp(fluctuatedAlpha); 00213 G4double tau = std::min(10.0,(zInX0 - 0.5*deltaZInX0)/tScale); 00214 G4double rCore = z1 + z2 * tau; 00215 G4double rTail = k1 *( std::exp(k3*(tau-k2)) + std::exp(k4*(tau-k2))); // @@ check RT3 sign 00216 G4double p23 = (p2 - tau)/p3; 00217 G4double probabilityWeight = p1 * std::exp( p23 - std::exp(p23) ); 00218 00219 00220 // Deposition of spots according to lateral distr. 00221 G4double emSpotEnergy = deltaEnergy / nSpotsInStep; 00222 GflashEnergySpot eSpot; 00223 00224 if(theHisto->getStoreFlag()) { 00225 theHisto->dEdz->Fill(zInX0-0.5,deltaEnergy); 00226 theHisto->dEdz_p->Fill(zInX0-0.5,deltaEnergy); 00227 } 00228 00229 for (G4int ispot = 0 ; ispot < nSpotsInStep ; ispot++) { 00230 spotCounter++; 00231 00232 G4double u1 = G4UniformRand(); 00233 G4double u2 = G4UniformRand(); 00234 G4double rInRM = 0.0; 00235 00236 if (u1 < probabilityWeight) { 00237 rInRM = rCore * std::sqrt( u2/(1.0-u2) ); 00238 } 00239 else { 00240 rInRM = rTail * std::sqrt( u2/(1.0-u2) ); 00241 } 00242 00243 G4double rShower = rInRM * rMoliere; 00244 00245 // Uniform & random rotation of spot along the azimuthal angle 00246 G4double azimuthalAngle = twopi*G4UniformRand(); 00247 00248 // Compute global position of generated spots with taking into account magnetic field 00249 // Divide deltaZ into nSpotsInStep and give a spot a global position 00250 G4double incrementPath = (deltaZ/nSpotsInStep)*(ispot+0.5 - 0.5*nSpotsInStep); 00251 00252 // trajectoryPoint give a spot an imaginary point along the shower development 00253 GflashTrajectoryPoint trajectoryPoint; 00254 theHelix->getGflashTrajectoryPoint(trajectoryPoint,pathLength+incrementPath); 00255 00256 // actual spot position by adding a radial vector to a trajectoryPoint 00257 G4ThreeVector SpotPosition = trajectoryPoint.getPosition() + 00258 rShower*std::cos(azimuthalAngle)*trajectoryPoint.getOrthogonalUnitVector() + 00259 rShower*std::sin(azimuthalAngle)*trajectoryPoint.getCrossUnitVector(); 00260 00261 // put energy and position to a spot 00262 eSpot.setEnergy(emSpotEnergy*GeV); 00263 eSpot.setPosition(SpotPosition*cm); 00264 00265 // for histogramming 00266 G4double zInX0_spot = std::abs(pathLength+incrementPath - pathLength0)/radLength; 00267 00268 if(theHisto->getStoreFlag()) { 00269 theHisto->rxry->Fill(rShower*std::cos(azimuthalAngle)/rMoliere,rShower*std::sin(azimuthalAngle)/rMoliere); 00270 theHisto->dx->Fill(rShower*std::cos(azimuthalAngle)/rMoliere); 00271 theHisto->xdz->Fill(zInX0-0.5,rShower*std::cos(azimuthalAngle)/rMoliere); 00272 theHisto->dndz_spot->Fill(zInX0_spot); 00273 theHisto->rzSpots->Fill(SpotPosition.z(),SpotPosition.r()); 00274 theHisto->rArm->Fill(rShower/rMoliere); 00275 } 00276 00277 // to be returned 00278 aEnergySpotList.push_back(eSpot); 00279 00280 } 00281 } 00282 00283 }
std::vector<GflashEnergySpot> GflashEMShowerProfile::aEnergySpotList [private] |
Definition at line 23 of file GflashEMShowerProfile.h.
Referenced by clearSpotList(), getEnergySpotList(), and parameterization().
GflashTrajectory* GflashEMShowerProfile::theHelix [private] |
Definition at line 30 of file GflashEMShowerProfile.h.
Referenced by GflashEMShowerProfile(), parameterization(), and ~GflashEMShowerProfile().
GflashHistogram* GflashEMShowerProfile::theHisto [private] |
Definition at line 29 of file GflashEMShowerProfile.h.
Referenced by GflashEMShowerProfile(), and parameterization().
CLHEP::RandGaussQ* GflashEMShowerProfile::theRandGauss [private] |
Definition at line 32 of file GflashEMShowerProfile.h.
Referenced by GflashEMShowerProfile(), parameterization(), and ~GflashEMShowerProfile().