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" 41 energyThresholdSL = energyThresholdSL*
GeV;
45 if (useShowerLibrary) {
52 <<
"********************************************************\n" 53 <<
"* Constructing a CastorSD with name " << GetName() <<
"\n" 54 <<
"* Using Castor Shower Library: " << useShowerLibrary <<
"\n" 55 <<
"********************************************************";
57 const G4LogicalVolumeStore * lvs = G4LogicalVolumeStore::GetInstance();
58 for (
auto lv : *lvs) {
59 if (strcmp((lv->GetName()).c_str(),
"C3EF") == 0) {
lvC3EF = lv; }
60 if (strcmp((lv->GetName()).c_str(),
"C3HF") == 0) {
lvC3HF = lv; }
61 if (strcmp((lv->GetName()).c_str(),
"C4EF") == 0) {
lvC4EF = lv; }
62 if (strcmp((lv->GetName()).c_str(),
"C4HF") == 0) {
lvC4HF = lv; }
63 if (strcmp((lv->GetName()).c_str(),
"CAST") == 0) {
lvCAST = lv; }
67 edm::LogInfo(
"ForwardSim") <<
"CastorSD:: LogicalVolume pointers\n" 69 <<
" for C3HF; " <<
lvC4EF <<
" for C4EF; " 71 <<
lvCAST <<
" for CAST. ";
84 double NCherPhot = 0.;
87 auto const theTrack = aStep->GetTrack();
90 auto const preStepPoint = aStep->GetPreStepPoint();
91 auto const currentPV = preStepPoint->GetPhysicalVolume();
92 auto const currentLV = currentPV->GetLogicalVolume();
95 edm::LogInfo(
"ForwardSim") <<
"CastorSD::getEnergyDeposit:" 96 <<
"\n CurrentStepNumber , TrackID , ParentID, Particle , VertexPosition ," 97 <<
" LogicalVolumeAtVertex , PV, Time" 99 << theTrack->GetCurrentStepNumber()
101 << theTrack->GetTrackID()
103 << theTrack->GetParentID()
105 << theTrack->GetDefinition()->GetParticleName()
107 << theTrack->GetVertexPosition()
109 << theTrack->GetLogicalVolumeAtVertex()->GetName()
111 << currentPV->GetName()
113 << theTrack->GetGlobalTime();
117 const G4ThreeVector& hit_mom = preStepPoint->GetMomentumDirection();
118 const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
119 double zint = hitPoint.z();
122 G4int parCode = theTrack->GetDefinition()->GetPDGEncoding();
125 double meanNCherPhot=0;
126 G4double
charge = preStepPoint->GetCharge();
128 if(0.0 == charge) {
return meanNCherPhot; }
130 G4double
beta = preStepPoint->GetBeta();
131 const double bThreshold = 0.67;
133 if(beta < bThreshold) {
return meanNCherPhot; }
141 G4double stepl = aStep->GetStepLength()/cm;
163 edm::LogInfo(
"ForwardSim") <<
"CastorSD::getEnergyDeposit: for ID=" 164 << theTrack->GetTrackID() <<
" LV: " << currentLV->GetName()
165 <<
" isHad:" << isHad <<
" pdg=" << parCode
167 <<
" sl= " << stepl <<
" Edep= " << aStep->GetTotalEnergyDeposit();
172 const double nMedium = 1.4925;
176 const double photEnSpectrDE = 1.24;
185 const double thFullRefl = 23.;
186 const double thFullReflRad = thFullRefl*
pi/180.;
189 const double thFibDir = 45.;
195 const double thFibDirRad = thFibDir*
pi/180.;
198 double costh =hit_mom.z()/
sqrt(hit_mom.x()*hit_mom.x()+
199 hit_mom.y()*hit_mom.y()+
200 hit_mom.z()*hit_mom.z());
201 if (zint < 0) costh = -costh;
205 if (th < 0.) th += twopi;
208 double costhcher =1./(nMedium*
beta);
212 double DelFibPart =
std::abs(th - thFibDirRad);
225 if(DelFibPart > (thFullReflRad + thcher) ) {
229 if((th + thcher) < (thFibDirRad+thFullReflRad) &&
230 (th - thcher) > (thFibDirRad-thFullReflRad)) {
237 if((thFibDirRad + thFullReflRad) < (th + thcher) &&
238 (thFibDirRad - thFullReflRad) > (th - thcher) ) {
249 double arg_arcos = 0.;
250 double tan_arcos = 2.*a*
d;
251 if(tan_arcos != 0.) arg_arcos =(r*r-a*a-d*
d)/tan_arcos;
254 d_qz =
std::abs(th_arcos/CLHEP::twopi);
261 meanNCherPhot = 370.*charge*charge*
262 ( 1. - 1./(nMedium*nMedium*beta*
beta) )*photEnSpectrDE*stepl;
266 int poissNCherPhot =
std::max(0, (
int)G4Poisson(meanNCherPhot * scale));
268 const double effPMTandTransport = 0.19;
269 const double ReflPower = 0.1;
270 double proba = d_qz + (1-d_qz)*ReflPower;
271 NCherPhot = poissNCherPhot*effPMTandTransport*proba*0.307;
273 edm::LogInfo(
"ForwardSim") <<
" Nph= " << NCherPhot <<
" Np= " << poissNCherPhot
274 <<
" eff= " << effPMTandTransport <<
" pb= " << proba
275 <<
" Nmean= " << meanNCherPhot
276 <<
" q=" << charge <<
" beta=" << beta
277 <<
" nMedium= " << nMedium <<
" sl= " << stepl
278 <<
" Nde=" << photEnSpectrDE;
294 if (scheme !=
nullptr) {
295 edm::LogInfo(
"ForwardSim") <<
"CastorSD: updates numbering scheme for " 313 double trackPhi = track->GetPosition().phi();
314 if(trackPhi<0) trackPhi += 2*
M_PI ;
317 if(showerPhi<0) showerPhi += 2*
M_PI ;
321 int trackOctSector = (
int) ( trackPhi / (
M_PI/4) ) ;
322 int showerOctSector = (
int) ( showerPhi / (
M_PI/4) ) ;
325 uint32_t sec = ( ( unitID>>4 ) & 0xF ) ;
326 uint32_t complement = ( unitID & 0xFFFFFF0F ) ;
329 double trackZ = track->GetPosition().z();
332 int dSec = 2*(trackOctSector - showerOctSector) ;
337 if(sec1<0) sec1 += 16;
338 if(sec1>15) sec1 -= 16;
339 sec = (uint32_t)(sec1);
341 if( dSec<0 ) sec += 16 ;
343 aux = (
int) (sec/16) ;
347 newUnitID = complement | sec ;
350 if(newUnitID != unitID) {
351 LogDebug(
"ForwardSim") <<
"\n CastorSD::rotateUnitID: " 352 <<
"\n unitID = " << unitID
353 <<
"\n newUnitID = " << newUnitID ;
373 auto const theTrack = aStep->GetTrack();
374 auto parCode = theTrack->GetDefinition()->GetPDGEncoding();
387 auto const preStepPoint = aStep->GetPreStepPoint();
388 auto const currentPV = preStepPoint->GetPhysicalVolume();
389 auto const currentLV = currentPV->GetLogicalVolume();
392 edm::LogInfo(
"ForwardSim") <<
"CastorSD::getFromLibrary: for ID=" << theTrack->GetTrackID()
393 <<
" parentID= " << theTrack->GetParentID() <<
" " 394 << theTrack->GetDefinition()->GetParticleName()
395 <<
" LV: " << currentLV->GetName() <<
" PV: " << currentPV->GetName()
396 <<
"\n eta= " << theTrack->GetPosition().eta()
397 <<
" phi= " << theTrack->GetPosition().phi()
398 <<
" z(cm)= " << theTrack->GetPosition().z()/cm
399 <<
" time(ns)= " << theTrack->GetGlobalTime()
400 <<
" E(GeV)= " << theTrack->GetTotalEnergy()/
GeV;
404 const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
405 const G4ThreeVector& hit_mom = preStepPoint->GetMomentumDirection();
406 double zint = hitPoint.z();
407 double pz = hit_mom.z();
410 bool backward = (pz * zint < 0.) ?
true :
false;
421 double theta_max =
M_PI - 3.1305;
422 double R_mom=
sqrt(hit_mom.x()*hit_mom.x() + hit_mom.y()*hit_mom.y());
424 bool angleok = (theta < theta_max) ?
true :
false;
427 double R =
sqrt(hitPoint.x()*hitPoint.x() + hitPoint.y()*hitPoint.y());
428 bool dot = (zint < -14450. && R < 45.) ?
true :
false;
429 bool inRange = (zint < -14700. || R > 193.) ?
false :
true;
432 bool particleWithinShowerLibrary = aboveThreshold && (isEM || isHad)
433 && (!backward) && inRange && !dot && angleok && currentLV ==
lvCAST;
436 edm::LogInfo(
"ForwardSim") <<
"CastorSD::getFromLibrary: ID= " << theTrack->GetTrackID()
437 <<
" E>E0 " << aboveThreshold
438 <<
" isEM " << isEM <<
" isHad " << isHad
439 <<
" backword " << backward
440 <<
" Ok " << (inRange && !
dot) <<
" angle " << angleok <<
" LV: " 441 << currentLV->GetName() <<
" " << (currentLV ==
lvCAST)
442 <<
" " << particleWithinShowerLibrary
443 <<
" Edep= " << aStep->GetTotalEnergyDeposit();
448 if (!particleWithinShowerLibrary) {
453 G4double edep = aStep->GetTotalEnergyDeposit();
454 G4double
beta = preStepPoint->GetBeta();
455 G4double
charge = preStepPoint->GetCharge();
456 double bThreshold = 0.67;
457 if(edep == 0.0 && charge != 0.0 && beta > bThreshold) {
480 <<
"CastorSD::getFromLibrary: " 481 << hits.
getNhit() <<
" hits for " << GetName() <<
" from " 482 << theTrack->GetDefinition()->GetParticleName() <<
" of " 483 << preStepPoint->GetKineticEnergy()/
GeV <<
" GeV and trackID " 484 << theTrack->GetTrackID() <<
" isHad: " << isHad;
488 double E_track = preStepPoint->GetTotalEnergy() ;
490 double scale = E_track/E_SLhit ;
497 for (
unsigned int i=0;
i<hits.
getNhit(); ++
i) {
519 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)
Compact representation of the geometrical detector hierarchy.
unsigned int getDetID(int i)
static TrackerG4SimHitNumberingScheme & numberingScheme(const DDCompactView &cpv, const GeometricDet &det)
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 &)
CastorSD(const std::string &, const DDCompactView &, const SensitiveDetectorCatalog &clg, edm::ParameterSet const &, const SimTrackManager *)
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)
void setParameterized(bool val)