18 #include "G4SDManager.hh" 21 #include "G4VProcess.hh" 23 #include "G4Cerenkov.hh" 24 #include "G4ParticleTable.hh" 25 #include "G4PhysicalConstants.hh" 26 #include <CLHEP/Units/SystemOfUnits.h> 27 #include <CLHEP/Units/GlobalPhysicalConstants.h> 28 #include "Randomize.hh" 29 #include "G4Poisson.hh" 30 #include "G4TwoVector.hh" 49 edm::LogVerbatim(
"ForwardSim") <<
"***************************************************\n" 51 <<
"* Constructing a ZdcSD with name " <<
name <<
" *\n" 53 <<
"***************************************************";
70 G4ParticleTable* theParticleTable = G4ParticleTable::GetParticleTable();
81 edm::LogVerbatim(
"ZdcSD") <<
"ZdcSD::" << GetName() <<
" ID= " << aStep->GetTrack()->GetTrackID()
82 <<
" prID= " << aStep->GetTrack()->GetParentID()
83 <<
" Eprestep= " << aStep->GetPreStepPoint()->GetKineticEnergy()
84 <<
" step= " << aStep->GetStepLength() <<
" Edep= " << aStep->GetTotalEnergyDeposit();
92 auto const theTrack = aStep->GetTrack();
95 double time = theTrack->GetGlobalTime() / CLHEP::nanosecond;
101 double wt2 = theTrack->GetWeight();
115 G4ThreeVector
pre = aStep->GetPreStepPoint()->GetPosition();
127 auto const preStepPoint = aStep->GetPreStepPoint();
129 double etrack = preStepPoint->GetKineticEnergy();
141 auto const theTrack = aStep->GetTrack();
142 edm::LogVerbatim(
"ForwardSim") <<
"----------------New track------------------------------\n" 143 <<
"Incident EnergyTrack: " << etrack <<
" MeV \n" 145 <<
"ZdcSD::getFromLibrary " <<
hits.size() <<
" hits for " << GetName() <<
" of " 146 << primaryID <<
" with " << theTrack->GetDefinition()->GetParticleName() <<
" of " 147 << etrack <<
" MeV\n";
154 for (
unsigned int i = 0;
i <
hits.size();
i++) {
158 unsigned int unitID =
hits[
i].detID;
179 double NCherPhot = 0.;
182 G4StepPoint* preStepPoint = aStep->GetPreStepPoint();
184 const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
185 const G4ThreeVector& hit_mom = preStepPoint->GetMomentumDirection();
186 G4double stepL = aStep->GetStepLength() / CLHEP::cm;
187 G4double
beta = preStepPoint->GetBeta();
188 G4double
charge = preStepPoint->GetCharge();
193 G4Track* theTrack = aStep->GetTrack();
194 G4String
particleType = theTrack->GetDefinition()->GetParticleName();
195 G4ThreeVector localPoint = theTrack->GetTouchable()->GetHistory()->GetTopTransform().TransformPoint(hitPoint);
198 const G4ThreeVector& vert_mom = theTrack->GetVertexMomentumDirection();
202 vert_mom.z() /
sqrt(vert_mom.x() * vert_mom.x() + vert_mom.y() * vert_mom.y() + vert_mom.z() * vert_mom.z());
206 if (vert_mom.x() != 0)
207 phi = std::atan2(vert_mom.y(), vert_mom.x());
212 double stepE = aStep->GetTotalEnergyDeposit();
215 G4StepPoint* postStepPoint = aStep->GetPostStepPoint();
216 G4VPhysicalVolume* postPV = postStepPoint->GetPhysicalVolume();
218 std::string nameVolume = preStepPoint->GetPhysicalVolume()->GetName();
220 <<
" preStepPoint: " << nameVolume <<
"," << stepL <<
"," << stepE <<
"," <<
beta 222 <<
" postStepPoint: " << postnameVolume <<
"," << costheta <<
"," <<
theta <<
"," 224 <<
" Etot(GeV)= " << theTrack->GetTotalEnergy() / CLHEP::GeV;
226 const double bThreshold = 0.67;
227 if (
beta > bThreshold) {
231 const float nMedium = 1.4925;
235 const float photEnSpectrDE = 1.24;
241 const float effPMTandTransport = 0.15;
244 const float thFullRefl = 23.;
245 float thFullReflRad = thFullRefl *
pi / 180.;
253 float costh = hit_mom.z() /
sqrt(hit_mom.x() * hit_mom.x() + hit_mom.y() * hit_mom.y() + hit_mom.z() * hit_mom.z());
260 float costhcher = 1. / (nMedium *
beta);
264 float DelFibPart =
std::abs(th - thFibDirRad);
278 if (DelFibPart > (thFullReflRad + thcher)) {
285 if ((th + thcher) < (thFibDirRad + thFullReflRad) && (th - thcher) > (thFibDirRad - thFullReflRad)) {
292 if ((thFibDirRad + thFullReflRad) < (th + thcher) && (thFibDirRad - thFullReflRad) > (th - thcher)) {
302 float arg_arcos = 0.;
303 float tan_arcos = 2. *
a *
d;
305 arg_arcos = (
r *
r -
a *
a -
d *
d) / tan_arcos;
308 d_qz = th_arcos / CLHEP::twopi;
311 edm::LogVerbatim(
"ForwardSim") <<
" d_qz: " <<
r <<
"," <<
a <<
"," <<
d <<
" " << tan_arcos <<
" " 321 double meanNCherPhot = 0.;
322 int poissNCherPhot = 0;
324 meanNCherPhot = 370. *
charge *
charge * (1. - 1. / (nMedium * nMedium *
beta *
beta)) * photEnSpectrDE * stepL;
326 poissNCherPhot =
std::max((
int)G4Poisson(meanNCherPhot), 0);
327 NCherPhot = poissNCherPhot * effPMTandTransport * d_qz;
331 edm::LogVerbatim(
"ForwardSim") <<
"ZdcSD:: getEnergyDeposit: gED: " << stepE <<
"," << costh <<
"," << th <<
"," 332 << costhcher <<
"," << thcher <<
"," << DelFibPart <<
"," <<
d <<
"," <<
a <<
"," 333 <<
r <<
"," << hitPoint <<
"," << hit_mom <<
"," << vert_mom <<
"," << localPoint
334 <<
"," <<
charge <<
"," <<
beta <<
"," << stepL <<
"," << d_qz <<
"," << variant
335 <<
"," << meanNCherPhot <<
"," << poissNCherPhot <<
"," << NCherPhot;
340 if (
beta <= bThreshold)
353 const double NA = 0.22;
357 const double ALPHA = 0.0072973525693;
358 const double HBARC = 6.582119514E-16 * 2.99792458E8 ;
362 const G4StepPoint* pPreStepPoint = aStep->GetPreStepPoint();
363 G4double
charge = pPreStepPoint->GetCharge() / CLHEP::eplus;
364 if (
charge == 0.0 || aStep->GetStepLength() < 1
e-9 * CLHEP::mm)
367 const G4StepPoint* pPostStepPoint = aStep->GetPostStepPoint();
369 G4ThreeVector
pre = pPreStepPoint->GetPosition();
370 G4ThreeVector
post = pPostStepPoint->GetPosition();
373 const G4ThreeVector localPre =
setToLocal(
pre, pPreStepPoint->GetTouchable());
374 const G4ThreeVector localPost =
setToLocal(
post, pPreStepPoint->GetTouchable());
377 const G4ThreeVector particleDirection = (localPost - localPre) / (localPost - localPre).mag();
379 double beta = 0.5 * (pPreStepPoint->GetBeta() + pPostStepPoint->GetBeta());
380 double stepLength = aStep->GetStepLength() / 1000;
390 double photonE =
EMIN + G4UniformRand() * (
EMAX -
EMIN);
396 double omega = G4UniformRand() * twopi;
398 double sinTheta =
std::sqrt((1. - cosTheta) * (1.0 + cosTheta));
401 edm::LogVerbatim(
"ZdcSD") <<
"E_gamma: " << photonE <<
"\t omega: " << omega <<
"\t thetaC: " << cosTheta;
404 double px = photonE * sinTheta *
std::cos(omega);
405 double py = photonE * sinTheta *
std::sin(omega);
406 double pz = photonE * cosTheta;
407 G4ThreeVector photonMomentum(
px,
py, pz);
410 edm::LogVerbatim(
"ZdcSD") <<
"pPR = (" << particleDirection.x() <<
"," << particleDirection.y() <<
"," 411 << particleDirection.z() <<
")";
415 photonMomentum.rotateUz(particleDirection);
418 edm::LogVerbatim(
"ZdcSD") <<
"pLAB = (" << photonMomentum.x() <<
"," << photonMomentum.y() <<
"," 419 << photonMomentum.z() <<
")";
422 G4ThreeVector photonPosition = localPre + G4UniformRand() * (localPost - localPre);
425 G4TwoVector r0(photonPosition);
426 G4TwoVector
v0(photonMomentum);
429 double R2 = 0.3 * 0.3;
431 if (r0.mag() <
R && photonMomentum.z() < 0.0) {
433 double a =
v0.mag2();
434 double b = 2.0 * r0 *
v0;
435 double c = r0.mag2() - R2;
441 double t = (-
b +
sqrt(
b *
b - 4.0 *
a *
c)) / (2.0 *
a);
442 G4ThreeVector
n(r0.x() +
v0.x() *
t, r0.y() +
v0.y() *
t, 0.0);
443 double cosTheta = (
n * photonMomentum) / (
n.mag() * photonE);
451 edm::LogVerbatim(
"ZdcSD") <<
"r = (" << photonPosition.x() <<
"," << photonPosition.y() <<
"," << photonPosition.z()
476 const std::vector<double> ENERGY_TAB{1.75715, 1.81902, 1.88311, 1.94944, 2.0183, 2.08939, 2.16302, 2.23919,
477 2.31789, 2.39954, 2.48416, 2.57175, 2.66232, 2.75643, 2.85349, 2.95411,
478 3.05756, 3.16528, 3.2774, 3.39218, 3.5123, 3.6359, 3.76394, 3.89642,
479 4.03332, 4.17596, 4.32302, 4.47596, 4.63319, 4.79629};
481 const std::vector<double> RINDEX_TAB{1.45517, 1.45572, 1.45631, 1.45693, 1.45758, 1.45826, 1.45899, 1.45976,
482 1.46057, 1.46144, 1.46238, 1.46337, 1.46444, 1.46558, 1.4668, 1.46812,
483 1.46953, 1.47105, 1.4727, 1.47447, 1.4764, 1.47847, 1.48071, 1.48315,
484 1.48579, 1.48868, 1.49182, 1.49526, 1.499, 1.5031};
495 photonE = G4UniformRand() * (
EMAX - Emin) + Emin;
505 const std::vector<double> EMIN_TAB{1.75715, 1.81902, 1.88311, 1.94944, 2.0183, 2.08939, 2.16302, 2.23919,
506 2.31789, 2.39954, 2.48416, 2.57175, 2.66232, 2.75643, 2.85349, 2.95411,
507 3.05756, 3.16528, 3.2774, 3.39218, 3.5123, 3.6359, 3.76394, 3.89642,
508 4.03332, 4.17596, 4.32302, 4.47596, 4.63319};
511 const std::vector<double> INTEGRAL_TAB{1.39756, 1.36835, 1.33812, 1.30686, 1.27443, 1.24099, 1.20638, 1.17061,
512 1.1337, 1.09545, 1.05586, 1.01493, 0.972664, 0.928815, 0.883664, 0.836938,
513 0.788988, 0.739157, 0.687404, 0.634547, 0.579368, 0.522743, 0.464256, 0.40393,
514 0.341808, 0.27732, 0.211101, 0.142536, 0.0723891};
520 const std::vector<double> LAMBDA_TAB{263.27, 265.98, 268.69, 271.39, 273.20, 275.90, 282.22, 282.22, 293.04,
521 308.38, 325.52, 346.26, 367.91, 392.27, 417.53, 440.98, 463.53, 484.28,
522 502.32, 516.75, 528.48, 539.30, 551.93, 564.56, 574.48, 584.41, 595.23,
523 606.96, 616.88, 625.00, 632.22, 637.63, 642.14, 647.55, 652.96, 656.57,
524 661.08, 666.49, 669.20, 673.71, 677.32, 680.93, 686.34, 692.65};
527 const std::vector<double> EFF_TAB{2.215, 2.860, 3.659, 4.724, 5.989, 7.734, 9.806, 9.806, 12.322,
528 15.068, 17.929, 20.570, 22.963, 24.050, 23.847, 22.798, 20.445, 18.003,
529 15.007, 12.282, 9.869, 7.858, 6.373, 5.121, 4.077, 3.276, 2.562,
530 2.077, 1.669, 1.305, 1.030, 0.805, 0.629, 0.492, 0.388, 0.303,
531 0.239, 0.187, 0.144, 0.113, 0.088, 0.069, 0.054, 0.043};
535 for (
int i = 0;
i < 44 - 1;
i++) {
536 if (lambda > LAMBDA_TAB[
i] && lambda < LAMBDA_TAB[
i + 1]) {
537 double a = (EFF_TAB[
i] - EFF_TAB[
i + 1]) / (LAMBDA_TAB[
i] - LAMBDA_TAB[
i + 1]);
538 double b = EFF_TAB[
i] -
a * LAMBDA_TAB[
i];
539 return (
a * lambda +
b) / 100.0;
549 for (
unsigned int i = 0;
i <
X.size() - 1;
i++) {
550 if (
x >
X[
i] &&
x <
X[
i + 1]) {
559 if (fabs(
X[0] -
x) < 1E-8)
561 else if (fabs(
X[
X.size() - 1] -
x) < 1E-8)
562 return Y[
X.size() - 1];
585 auto const theTrack = aStep->GetTrack();
588 if (primaryID == 0) {
590 auto const preStepPoint = aStep->GetPreStepPoint();
591 double etrack = preStepPoint->GetKineticEnergy();
592 edm::LogVerbatim(
"ZdcSD") <<
"ZdcSD: Problem with primaryID **** set by force to TkID **** " 593 << theTrack->GetTrackID() <<
" E " << etrack;
595 primaryID = theTrack->GetTrackID();
CaloG4Hit * currentHit[2]
double convertEnergyToWavelength(double)
Log< level::Info, true > LogVerbatim
std::unique_ptr< ZdcNumberingScheme > numberingScheme
T getParameter(std::string const &) const
math::XYZPoint getEntryLocal() const
double calculateN2InvIntegral(double)
virtual uint16_t getDepth(const G4Step *)
std::vector< ZdcShowerLibrary::Hit > hits
Sin< T >::type sin(const T &t)
G4ThreeVector setToLocal(const G4ThreeVector &, const G4VTouchable *) const
virtual int getTrackID(const G4Track *)
double calculateCherenkovDeposit(const G4Step *)
double evaluateFunction(const std::vector< double > &, const std::vector< double > &, double)
void processHit(const G4Step *step)
double calculateMeanNumberOfPhotons(double, double, double)
CaloG4Hit * createNewHit(const G4Step *, const G4Track *, int k)
double generatePhotonEnergy(double, double, double)
void resetForNewPrimary(const G4Step *)
Cos< T >::type cos(const T &t)
int setTrackID(const G4Step *step) override
Tan< T >::type tan(const T &t)
Abs< T >::type abs(const T &t)
bool ProcessHits(G4Step *step, G4TouchableHistory *tHistory) override
ZdcSD(const std::string &, const SensitiveDetectorCatalog &, edm::ParameterSet const &, const SimTrackManager *)
void setID(uint32_t unitID, double timeSlice, int trackID, uint16_t depth=0)
uint32_t getUnitID() const
bool hitExists(const G4Step *, int k)
double pmtEfficiency(double)
std::unique_ptr< ZdcShowerLibrary > showerLibrary
static bool isGammaElectronPositron(int pdgCode)
std::string getName(const G4String &)
double photonEnergyDist(double, double, double)
double linearInterpolation(double, double, double, double, double)
double getIncidentEnergy() const
bool getFromLibrary(const G4Step *) override
Geom::Theta< T > theta() const
uint32_t setDetUnitId(const G4Step *step) override
G4ThreeVector entrancePoint
G4ThreeVector entranceLocal
double getEnergyDeposit(const G4Step *) override
void setParameterized(bool val)