19 #include "CLHEP/Random/RandomEngine.h"
20 #include "CLHEP/Random/RandExpZiggurat.h"
21 #include "CLHEP/Random/RandFlat.h"
22 #include "TLorentzVector.h"
23 #include "CLHEP/Units/PhysicalConstants.h"
34 double iBetaGammaFn(
const double k){
36 constexpr
double me =0.51099906;
37 if (
auto subCalc = 2. * me +
k; subCalc>0){
38 result = std::sqrt(
k*subCalc)/me;
42 double iBetaGammaFn(
const TLorentzVector &
vec){
55 if (std::fabs(pdgId) == 2212)
return 1;
57 if (std::fabs(pdgId) == 211)
return 2;
60 if (std::fabs(pdgId) == 11)
return 4;
62 if (std::fabs(pdgId) == 321)
return 5;
64 if (std::fabs(pdgId) == 13)
return 6;
73 setFailureFlag(std::vector<std::pair<double, double> >& rawHitRecord) {
75 std::pair<double, double> specialFlag;
76 specialFlag.first = -1.;
77 specialFlag.second = -1.;
78 rawHitRecord.push_back(specialFlag);
92 ATH_MSG_INFO(
"You are using EnergyDepositionTool for solid-state silicon detectors.");
107 int n_ParticleType = 6;
108 for (
int iParticleType = 1; iParticleType <= n_ParticleType; iParticleType++) {
121 return StatusCode::SUCCESS;
129 return StatusCode::SUCCESS;
136 std::vector<std::pair<double, double> >& trfHitRecord,
137 std::vector<double>& initialConditions,
138 CLHEP::HepRandomEngine* rndmEngine,
139 const EventContext &ctx) {
145 bool delta_hit =
true;
146 if (genPart) delta_hit =
false;
152 const CLHEP::Hep3Vector startPosition = phit->localStartPosition();
153 const CLHEP::Hep3Vector endPosition = phit->localEndPosition();
167 double dEta = eta_f - eta_0;
168 double dPhi = phi_f - phi_0;
169 const double dDepth = depth_f - depth_0;
173 const int nsteps =
int(pathLength / stepsize) + 1;
177 initialConditions.clear();
178 initialConditions = {eta_0, phi_0, depth_0,
dEta,
dPhi, dDepth,
static_cast<double>(ncharges)};
183 double iTotalLength = pathLength * 1000.;
184 initialConditions.push_back(iTotalLength);
191 TLorentzVector genPart_4V;
194 genPart_4V.SetPtEtaPhiM(genPart->momentum().perp(), genPart->momentum().eta(),
195 genPart->momentum().phi(), genPart->momentum().m());
218 TLorentzVector genPart_4V;
219 double iBetaGamma=0.;
221 genPart_4V.SetPtEtaPhiM(genPart->momentum().perp(), genPart->momentum().eta(),
222 genPart->momentum().phi(), genPart->momentum().m());
223 iBetaGamma = iBetaGammaFn(genPart_4V);
226 iBetaGamma = iBetaGammaFn(
k);
231 std::vector<std::pair<double, double> > rawHitRecord =
bichselSim(iBetaGamma, iParticleType, iTotalLength,
232 genPart ? (genPart->momentum().e() /
238 if (rawHitRecord.empty()) {
239 std::pair<double, double> specialHit;
240 specialHit.first = 0.;
241 specialHit.second = 0.;
242 trfHitRecord.push_back(specialHit);
243 }
else if ((rawHitRecord.size() == 1) && (rawHitRecord[0].first == -1.) && (rawHitRecord[0].second == -1.)) {
244 for (
int j = 0; j < nsteps; j++) {
245 std::pair<double, double> specialHit;
246 specialHit.first = 1.0 * iTotalLength / nsteps * (j + 0.5);
247 specialHit.second = phit->energyLoss() * 1.E+6 / nsteps;
248 trfHitRecord.push_back(specialHit);
258 for (
int j = 0; j < nsteps; j++) {
259 std::pair<double, double> specialHit;
260 specialHit.first = 1.0 * iTotalLength / nsteps * (j + 0.5);
261 specialHit.second = phit->energyLoss() * 1.E+6 / nsteps;
262 trfHitRecord.push_back(specialHit);
267 return StatusCode::SUCCESS;
274 const double zi,
double& xf,
double& yf,
const double zf)
const {
307 std::vector<std::pair<double, double> >
309 double InciEnergy,CLHEP::HepRandomEngine* rndmEngine)
const {
313 std::vector<std::pair<double, double> > rawHitRecord;
314 double TotalEnergyLoss = 0.;
315 double accumLength = 0.;
318 setFailureFlag(rawHitRecord);
324 double BetaGammaLog10 = std::log10(BetaGamma);
329 if (IntXUpperBound <= 0.) {
330 ATH_MSG_WARNING(
"Negative IntXUpperBound in EnergyDepositionTool::bichselSim! (-1,-1) will be returned for log(betaGamma) = "<<BetaGammaLog10);
331 setFailureFlag(rawHitRecord);
336 setFailureFlag(rawHitRecord);
341 double lambda = (1. / IntXUpperBound) * 1.E4;
346 if (std::abs(1.0 * TotalLength / lambda) > LoopLimit) {
347 setFailureFlag(rawHitRecord);
357 "Potential infinite loop in bichselSim. Exit Loop. A special flag "
358 "will be returned (-1,-1). The total length is "
359 << TotalLength <<
". The lambda is " << lambda <<
".");
360 setFailureFlag(rawHitRecord);
365 double HitPosition = 0.;
366 for (
int iHit = 0; iHit <
m_nCols; iHit++) {
367 HitPosition += CLHEP::RandExpZiggurat::shoot(rndmEngine, lambda);
371 if (accumLength + HitPosition >= TotalLength)
break;
374 double TossEnergyLoss = -1.;
375 while (TossEnergyLoss <= 0.) {
377 double TossIntX = CLHEP::RandFlat::shoot(rndmEngine, 0., IntXUpperBound);
389 bool fLastStep =
false;
391 if (((TotalEnergyLoss + TossEnergyLoss) / 1.
E+6) > InciEnergy) {
393 "Energy loss is larger than incident energy in EnergyDepositionTool::bichselSim! This is usually delta-ray.");
394 TossEnergyLoss = InciEnergy * 1.E+6 - TotalEnergyLoss;
399 accumLength += HitPosition;
400 TotalEnergyLoss += TossEnergyLoss;
403 std::pair<double, double> oneHit;
404 if (
m_nCols == 1) oneHit.first = accumLength;
405 else oneHit.first = (accumLength - 1.0 * HitPosition / 2);
406 oneHit.second = TossEnergyLoss;
407 rawHitRecord.push_back(oneHit);
411 if (fLastStep)
break;
423 double> >& rawHitRecord,
424 int n_pieces)
const {
426 std::vector<std::pair<double, double> > trfHitRecord;
428 if ((
int) (rawHitRecord.size()) < n_pieces) {
429 n_pieces = rawHitRecord.size();
432 int unitlength =
int(1.0 * rawHitRecord.size() / n_pieces);
434 int index_end = unitlength - 1;
437 double position = 0.;
438 double energyloss = 0.;
441 position += (rawHitRecord[
index].first * rawHitRecord[
index].second);
442 energyloss += rawHitRecord[
index].second;
444 position = (energyloss == 0. ? 0. : position / energyloss);
447 std::pair<double, double> oneHit;
448 oneHit.first = position;
449 oneHit.second = energyloss;
450 trfHitRecord.push_back(oneHit);
453 index_start = index_end + 1;
454 index_end = index_start + unitlength - 1;
456 if (index_start > (
int) (rawHitRecord.size() - 1)) {
460 if (index_end > (
int) (rawHitRecord.size() - 1)) {
461 index_end = rawHitRecord.size() - 1;