15 #include "G4SDManager.hh" 18 #include "G4VProcess.hh" 21 #include "G4Cerenkov.hh" 22 #include "G4LogicalVolumeStore.hh" 24 #include "CLHEP/Units/GlobalSystemOfUnits.h" 25 #include "CLHEP/Units/GlobalPhysicalConstants.h" 26 #include "Randomize.hh" 27 #include "G4Poisson.hh" 55 edm::LogVerbatim(
"ForwardSim") <<
"********************************************************\n" 56 <<
"* Constructing a CastorSD with name " << GetName() <<
"\n" 58 <<
"********************************************************";
60 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
61 for (
auto lv : *lvs) {
62 if (strcmp((lv->GetName()).c_str(),
"C3EF") == 0) {
65 if (strcmp((lv->GetName()).c_str(),
"C3HF") == 0) {
68 if (strcmp((lv->GetName()).c_str(),
"C4EF") == 0) {
71 if (strcmp((lv->GetName()).c_str(),
"C4HF") == 0) {
74 if (strcmp((lv->GetName()).c_str(),
"CAST") == 0) {
93 double NCherPhot = 0.;
96 auto const theTrack = aStep->GetTrack();
99 auto const preStepPoint = aStep->GetPreStepPoint();
100 auto const currentPV = preStepPoint->GetPhysicalVolume();
101 auto const currentLV = currentPV->GetLogicalVolume();
105 <<
"\n CurrentStepNumber , TrackID , ParentID, Particle , VertexPosition ," 106 <<
" LogicalVolumeAtVertex , PV, Time" 107 <<
"\n TRACKINFO: " << theTrack->GetCurrentStepNumber() <<
" , " 108 << theTrack->GetTrackID() <<
" , " << theTrack->GetParentID() <<
" , " 109 << theTrack->GetDefinition()->GetParticleName() <<
" , " 110 << theTrack->GetVertexPosition() <<
" , " 111 << theTrack->GetLogicalVolumeAtVertex()->GetName() <<
" , " << currentPV->GetName()
112 <<
" , " << theTrack->GetGlobalTime();
116 const G4ThreeVector& hit_mom = preStepPoint->GetMomentumDirection();
117 const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
118 double zint = hitPoint.z();
121 G4int parCode = theTrack->GetDefinition()->GetPDGEncoding();
124 double meanNCherPhot = 0;
125 G4double
charge = preStepPoint->GetCharge();
128 return meanNCherPhot;
131 G4double
beta = preStepPoint->GetBeta();
132 const double bThreshold = 0.67;
134 if (
beta < bThreshold) {
135 return meanNCherPhot;
144 G4double stepl = aStep->GetStepLength() / CLHEP::cm;
165 edm::LogVerbatim(
"ForwardSim") <<
"CastorSD::getEnergyDeposit: for ID=" << theTrack->GetTrackID()
166 <<
" LV: " << currentLV->GetName() <<
" isHad:" << isHad <<
" pdg=" << parCode
168 <<
" Edep= " << aStep->GetTotalEnergyDeposit();
171 const double nMedium = 1.4925;
175 const double photEnSpectrDE = 1.24;
184 const double thFullRefl = 23.;
185 const double thFullReflRad = thFullRefl *
pi / 180.;
188 const double thFibDir = 45.;
194 const double thFibDirRad = thFibDir *
pi / 180.;
198 hit_mom.z() /
sqrt(hit_mom.x() * hit_mom.x() + hit_mom.y() * hit_mom.y() + hit_mom.z() * hit_mom.z());
208 double costhcher = 1. / (nMedium *
beta);
209 double thcher = acos(
std::min(
std::max(costhcher,
double(-1.)),
double(1.)));
212 double DelFibPart =
std::abs(th - thFibDirRad);
217 double a =
tan(thFibDirRad) +
tan(
std::abs(thFibDirRad - thFullReflRad));
225 if (DelFibPart > (thFullReflRad + thcher)) {
228 if ((th + thcher) < (thFibDirRad + thFullReflRad) && (th - thcher) > (thFibDirRad - thFullReflRad)) {
234 if ((thFibDirRad + thFullReflRad) < (th + thcher) && (thFibDirRad - thFullReflRad) > (th - thcher)) {
245 double arg_arcos = 0.;
246 double tan_arcos = 2. *
a *
d;
248 arg_arcos = (
r *
r -
a *
a -
d *
d) / tan_arcos;
251 d_qz =
std::abs(th_arcos / CLHEP::twopi);
261 meanNCherPhot = 370. *
charge *
charge * (1. - 1. / (nMedium * nMedium *
beta *
beta)) * photEnSpectrDE * stepl;
265 int poissNCherPhot =
std::max(0, (
int)G4Poisson(meanNCherPhot *
scale));
267 const double effPMTandTransport = 0.19;
268 const double ReflPower = 0.1;
269 double proba = d_qz + (1 - d_qz) * ReflPower;
270 NCherPhot = poissNCherPhot * effPMTandTransport * proba * 0.307;
272 edm::LogVerbatim(
"ForwardSim") <<
" Nph= " << NCherPhot <<
" Np= " << poissNCherPhot
273 <<
" eff= " << effPMTandTransport <<
" pb= " << proba <<
" Nmean= " << meanNCherPhot
274 <<
" q=" <<
charge <<
" beta=" <<
beta <<
" nMedium= " << nMedium <<
" sl= " << stepl
275 <<
" Nde=" << photEnSpectrDE;
291 edm::LogVerbatim(
"ForwardSim") <<
"CastorSD: updates numbering scheme for " << GetName();
314 showerPhi += 2 *
M_PI;
319 int showerOctSector = (
int)(showerPhi / (
M_PI / 4));
322 uint32_t
sec = ((unitID >> 4) & 0xF);
323 uint32_t complement = (unitID & 0xFFFFFF0F);
326 double trackZ =
track->GetPosition().z();
329 int dSec = 2 * (trackOctSector - showerOctSector);
332 int sec1 =
sec - dSec;
338 sec = (uint32_t)(sec1);
347 newUnitID = complement |
sec;
350 if (newUnitID != unitID) {
352 <<
"\n unitID = " << unitID <<
"\n newUnitID = " << newUnitID;
370 auto const theTrack = aStep->GetTrack();
371 auto parCode = theTrack->GetDefinition()->GetPDGEncoding();
386 auto const preStepPoint = aStep->GetPreStepPoint();
387 auto const currentPV = preStepPoint->GetPhysicalVolume();
388 auto const currentLV = currentPV->GetLogicalVolume();
391 edm::LogVerbatim(
"ForwardSim") <<
"CastorSD::getFromLibrary: for ID=" << theTrack->GetTrackID()
392 <<
" parentID= " << theTrack->GetParentID() <<
" " 393 << theTrack->GetDefinition()->GetParticleName() <<
" LV: " << currentLV->GetName()
394 <<
" PV: " << currentPV->GetName() <<
"\n eta= " << theTrack->GetPosition().eta()
395 <<
" phi= " << theTrack->GetPosition().phi()
396 <<
" z(cm)= " << theTrack->GetPosition().z() / CLHEP::cm
397 <<
" time(ns)= " << theTrack->GetGlobalTime()
398 <<
" E(GeV)= " << theTrack->GetTotalEnergy() / CLHEP::GeV;
402 const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
403 const G4ThreeVector& hit_mom = preStepPoint->GetMomentumDirection();
404 double zint = hitPoint.z();
405 double pz = hit_mom.z();
408 bool backward = (pz * zint < 0.) ?
true :
false;
411 bool aboveThreshold = (theTrack->GetKineticEnergy() >
energyThresholdSL) ?
true :
false;
418 double theta_max =
M_PI - 3.1305;
419 double R_mom =
sqrt(hit_mom.x() * hit_mom.x() + hit_mom.y() * hit_mom.y());
421 bool angleok = (
theta < theta_max) ?
true :
false;
424 double R =
sqrt(hitPoint.x() * hitPoint.x() + hitPoint.y() * hitPoint.y());
425 bool dot = (zint < -14450. &&
R < 45.) ?
true :
false;
426 bool inRange = (zint < -14700. ||
R > 193.) ?
false :
true;
429 bool particleWithinShowerLibrary =
430 aboveThreshold && (isEM || isHad) && (!backward) && inRange && !
dot && angleok && currentLV ==
lvCAST;
433 edm::LogVerbatim(
"ForwardSim") <<
"CastorSD::getFromLibrary: ID= " << theTrack->GetTrackID() <<
" E>E0 " 434 << aboveThreshold <<
" isEM " << isEM <<
" isHad " << isHad <<
" backword " << backward
435 <<
" Ok " << (inRange && !
dot) <<
" angle " << angleok
436 <<
" LV: " << currentLV->GetName() <<
" " << (currentLV ==
lvCAST) <<
" " 437 << particleWithinShowerLibrary <<
" Edep= " << aStep->GetTotalEnergyDeposit();
442 if (!particleWithinShowerLibrary) {
457 edm::LogVerbatim(
"ForwardSim") <<
"CastorSD::getFromLibrary: " <<
hits.getNhit() <<
" hits for " << GetName()
458 <<
" from " << theTrack->GetDefinition()->GetParticleName() <<
" of " 459 << preStepPoint->GetKineticEnergy() / CLHEP::GeV <<
" GeV and trackID " 460 << theTrack->GetTrackID() <<
" isHad: " << isHad;
464 double E_track = preStepPoint->GetTotalEnergy();
465 double E_SLhit =
hits.getPrimE() * CLHEP::GeV;
466 double scale = E_track / E_SLhit;
473 for (
unsigned int i = 0;
i <
hits.getNhit(); ++
i) {
475 double nPhotoElectrons =
hits.getNphotons(
i) *
scale;
489 unsigned int unitID =
hits.getDetID(
i);
Log< level::Info, true > LogVerbatim
double getEnergyDeposit(const G4Step *) override
virtual uint32_t getUnitID(const G4Step *aStep) const
T getParameter(std::string const &) const
uint32_t setDetUnitId(const G4Step *step) override
double non_compensation_factor
CastorNumberingScheme * numberingScheme
void processHit(const G4Step *step)
T dot(const Basic3DVector &v) const
Scalar product, or "dot" product, with a vector of same type.
bool getFromLibrary(const G4Step *) override
CastorShowerEvent getShowerHits(const G4Step *, bool &)
void resetForNewPrimary(const G4Step *)
Tan< T >::type tan(const T &t)
Abs< T >::type abs(const T &t)
CastorSD(const std::string &, const SensitiveDetectorCatalog &clg, edm::ParameterSet const &, const SimTrackManager *)
static bool isStableHadronIon(const G4Track *)
void setID(uint32_t unitID, double timeSlice, int trackID, uint16_t depth=0)
uint32_t rotateUnitID(uint32_t, const G4Track *, const CastorShowerEvent &)
CastorShowerLibrary * showerLibrary
void setNumberingScheme(CastorNumberingScheme *scheme)
virtual int setTrackID(const G4Step *)
static bool isGammaElectronPositron(int pdgCode)
static TrackerG4SimHitNumberingScheme & numberingScheme(const GeometricDet &det)
Geom::Theta< T > theta() const
void setParameterized(bool val)