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" 36 :
CaloSD(name, es, clg, p, manager),
46 energyThresholdSL = energyThresholdSL *
GeV;
50 if (useShowerLibrary) {
56 edm::LogInfo(
"ForwardSim") <<
"********************************************************\n" 57 <<
"* Constructing a CastorSD with name " << GetName() <<
"\n" 58 <<
"* Using Castor Shower Library: " << useShowerLibrary <<
"\n" 59 <<
"********************************************************";
61 const G4LogicalVolumeStore* lvs = G4LogicalVolumeStore::GetInstance();
62 for (
auto lv : *lvs) {
63 if (strcmp((lv->GetName()).c_str(),
"C3EF") == 0) {
66 if (strcmp((lv->GetName()).c_str(),
"C3HF") == 0) {
69 if (strcmp((lv->GetName()).c_str(),
"C4EF") == 0) {
72 if (strcmp((lv->GetName()).c_str(),
"C4HF") == 0) {
75 if (strcmp((lv->GetName()).c_str(),
"CAST") == 0) {
82 edm::LogInfo(
"ForwardSim") <<
"CastorSD:: LogicalVolume pointers\n" 84 <<
" for C4HF; " <<
lvCAST <<
" for CAST. ";
94 double NCherPhot = 0.;
97 auto const theTrack = aStep->GetTrack();
100 auto const preStepPoint = aStep->GetPreStepPoint();
101 auto const currentPV = preStepPoint->GetPhysicalVolume();
102 auto const currentLV = currentPV->GetLogicalVolume();
105 edm::LogInfo(
"ForwardSim") <<
"CastorSD::getEnergyDeposit:" 106 <<
"\n CurrentStepNumber , TrackID , ParentID, Particle , VertexPosition ," 107 <<
" LogicalVolumeAtVertex , PV, Time" 108 <<
"\n TRACKINFO: " << theTrack->GetCurrentStepNumber() <<
" , " << theTrack->GetTrackID()
109 <<
" , " << theTrack->GetParentID() <<
" , " 110 << theTrack->GetDefinition()->GetParticleName() <<
" , " << theTrack->GetVertexPosition()
111 <<
" , " << theTrack->GetLogicalVolumeAtVertex()->GetName() <<
" , " 112 << currentPV->GetName() <<
" , " << 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() / cm;
165 edm::LogInfo(
"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);
258 meanNCherPhot = 370. * charge * charge * (1. - 1. / (nMedium * nMedium * beta *
beta)) * photEnSpectrDE * stepl;
262 int poissNCherPhot =
std::max(0, (
int)G4Poisson(meanNCherPhot * scale));
264 const double effPMTandTransport = 0.19;
265 const double ReflPower = 0.1;
266 double proba = d_qz + (1 - d_qz) * ReflPower;
267 NCherPhot = poissNCherPhot * effPMTandTransport * proba * 0.307;
269 edm::LogInfo(
"ForwardSim") <<
" Nph= " << NCherPhot <<
" Np= " << poissNCherPhot <<
" eff= " << effPMTandTransport
270 <<
" pb= " << proba <<
" Nmean= " << meanNCherPhot <<
" q=" << charge <<
" beta=" << beta
271 <<
" nMedium= " << nMedium <<
" sl= " << stepl <<
" Nde=" << photEnSpectrDE;
286 if (scheme !=
nullptr) {
287 edm::LogInfo(
"ForwardSim") <<
"CastorSD: updates numbering scheme for " << GetName();
304 double trackPhi = track->GetPosition().phi();
306 trackPhi += 2 *
M_PI;
310 showerPhi += 2 *
M_PI;
314 int trackOctSector = (
int)(trackPhi / (
M_PI / 4));
315 int showerOctSector = (
int)(showerPhi / (
M_PI / 4));
318 uint32_t
sec = ((unitID >> 4) & 0xF);
319 uint32_t complement = (unitID & 0xFFFFFF0F);
322 double trackZ = track->GetPosition().z();
325 int dSec = 2 * (trackOctSector - showerOctSector);
328 int sec1 = sec - dSec;
334 sec = (uint32_t)(sec1);
339 aux = (
int)(sec / 16);
343 newUnitID = complement |
sec;
346 if (newUnitID != unitID) {
347 LogDebug(
"ForwardSim") <<
"\n CastorSD::rotateUnitID: " 348 <<
"\n unitID = " << unitID <<
"\n newUnitID = " << newUnitID;
366 auto const theTrack = aStep->GetTrack();
367 auto parCode = theTrack->GetDefinition()->GetPDGEncoding();
382 auto const preStepPoint = aStep->GetPreStepPoint();
383 auto const currentPV = preStepPoint->GetPhysicalVolume();
384 auto const currentLV = currentPV->GetLogicalVolume();
387 edm::LogInfo(
"ForwardSim") <<
"CastorSD::getFromLibrary: for ID=" << theTrack->GetTrackID()
388 <<
" parentID= " << theTrack->GetParentID() <<
" " 389 << theTrack->GetDefinition()->GetParticleName() <<
" LV: " << currentLV->GetName()
390 <<
" PV: " << currentPV->GetName() <<
"\n eta= " << theTrack->GetPosition().eta()
391 <<
" phi= " << theTrack->GetPosition().phi()
392 <<
" z(cm)= " << theTrack->GetPosition().z() / cm
393 <<
" time(ns)= " << theTrack->GetGlobalTime()
394 <<
" E(GeV)= " << theTrack->GetTotalEnergy() /
GeV;
398 const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
399 const G4ThreeVector& hit_mom = preStepPoint->GetMomentumDirection();
400 double zint = hitPoint.z();
401 double pz = hit_mom.z();
404 bool backward = (pz * zint < 0.) ?
true :
false;
407 bool aboveThreshold = (theTrack->GetKineticEnergy() >
energyThresholdSL) ?
true :
false;
414 double theta_max =
M_PI - 3.1305;
415 double R_mom =
sqrt(hit_mom.x() * hit_mom.x() + hit_mom.y() * hit_mom.y());
417 bool angleok = (theta < theta_max) ?
true :
false;
420 double R =
sqrt(hitPoint.x() * hitPoint.x() + hitPoint.y() * hitPoint.y());
421 bool dot = (zint < -14450. && R < 45.) ?
true :
false;
422 bool inRange = (zint < -14700. || R > 193.) ?
false :
true;
425 bool particleWithinShowerLibrary =
426 aboveThreshold && (isEM || isHad) && (!backward) && inRange && !dot && angleok && currentLV ==
lvCAST;
429 edm::LogInfo(
"ForwardSim") <<
"CastorSD::getFromLibrary: ID= " << theTrack->GetTrackID() <<
" E>E0 " << aboveThreshold
430 <<
" isEM " << isEM <<
" isHad " << isHad <<
" backword " << backward <<
" Ok " 431 << (inRange && !
dot) <<
" angle " << angleok <<
" LV: " << currentLV->GetName() <<
" " 432 << (currentLV ==
lvCAST) <<
" " << particleWithinShowerLibrary
433 <<
" Edep= " << aStep->GetTotalEnergyDeposit();
438 if (!particleWithinShowerLibrary) {
453 edm::LogInfo(
"ForwardSim") <<
"CastorSD::getFromLibrary: " << hits.
getNhit() <<
" hits for " << GetName() <<
" from " 454 << theTrack->GetDefinition()->GetParticleName() <<
" of " 455 << preStepPoint->GetKineticEnergy() /
GeV <<
" GeV and trackID " << theTrack->GetTrackID()
456 <<
" isHad: " << isHad;
460 double E_track = preStepPoint->GetTotalEnergy();
462 double scale = E_track / E_SLhit;
469 for (
unsigned int i = 0;
i < hits.
getNhit(); ++
i) {
490 unsigned int rotatedUnitID =
rotateUnitID(unitID, theTrack, hits);
T getParameter(std::string const &) const
double getEnergyDeposit(const G4Step *) override
uint32_t setDetUnitId(const G4Step *step) override
Geom::Theta< T > theta() const
double non_compensation_factor
CastorNumberingScheme * numberingScheme
void processHit(const G4Step *step)
unsigned int getDetID(int i)
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)
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 *)
T dot(const Basic3DVector &v) const
Scalar product, or "dot" product, with a vector of same type.
virtual uint32_t getUnitID(const G4Step *aStep) const
static bool isGammaElectronPositron(int pdgCode)
static TrackerG4SimHitNumberingScheme & numberingScheme(const GeometricDet &det)
void setParameterized(bool val)
CastorSD(const std::string &, const edm::EventSetup &, const SensitiveDetectorCatalog &clg, edm::ParameterSet const &, const SimTrackManager *)