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;
50 <<
"***************************************************\n" 52 <<
"* Constructing a CastorSD with name " << GetName() <<
"\n" 54 <<
"***************************************************";
56 const G4LogicalVolumeStore * lvs = G4LogicalVolumeStore::GetInstance();
57 std::vector<G4LogicalVolume*>::const_iterator lvcite;
58 for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++) {
59 if (strcmp(((*lvcite)->GetName()).c_str(),
"C3EF") == 0)
lvC3EF = (*lvcite);
60 if (strcmp(((*lvcite)->GetName()).c_str(),
"C3HF") == 0)
lvC3HF = (*lvcite);
61 if (strcmp(((*lvcite)->GetName()).c_str(),
"C4EF") == 0)
lvC4EF = (*lvcite);
62 if (strcmp(((*lvcite)->GetName()).c_str(),
"C4HF") == 0)
lvC4HF = (*lvcite);
63 if (strcmp(((*lvcite)->GetName()).c_str(),
"CAST") == 0)
lvCAST = (*lvcite);
66 edm::LogInfo(
"ForwardSim") <<
"CastorSD:: LogicalVolume pointers\n" 68 <<
" for C3HF; " <<
lvC4EF <<
" for C4EF; " 70 <<
lvCAST <<
" for CAST. " << std::endl;
87 G4ParticleTable * theParticleTable = G4ParticleTable::GetParticleTable();
89 edm::LogInfo(
"ForwardSim") <<
"CastorSD::initRun: Using Castor Shower Library \n";
97 double NCherPhot = 0.;
103 G4Track*
theTrack = aStep->GetTrack();
108 G4VPhysicalVolume* currentPV = preStepPoint->GetPhysicalVolume();
109 G4LogicalVolume* currentLV = currentPV->GetLogicalVolume();
112 G4String
name = currentPV->GetName();
114 nameVolume.assign(name,0,4);
116 G4SteppingControl stepControlFlag = aStep->GetControlFlag();
117 if (aStep->IsFirstStepInVolume())
118 LogDebug(
"ForwardSim") <<
"CastorSD::getEnergyDeposit:" 119 <<
"\n IsFirstStepInVolume " ;
126 LogDebug(
"ForwardSim") <<
"CastorSD::getEnergyDeposit:" 127 <<
"\n TrackID , ParentID , ParticleName ," 128 <<
" eta , phi , z , time ," 131 << theTrack->GetTrackID()
133 << theTrack->GetParentID()
135 << theTrack->GetDefinition()->GetParticleName()
137 << theTrack->GetPosition().eta()
139 << theTrack->GetPosition().phi()
141 << theTrack->GetPosition().z()
143 << theTrack->GetGlobalTime()
145 << theTrack->GetKineticEnergy()
147 << theTrack->GetTotalEnergy()
149 << theTrack->GetMomentum().mag() ;
150 if(theTrack->GetTrackID() != 1)
151 LogDebug(
"ForwardSim") <<
"CastorSD::getEnergyDeposit:" 152 <<
"\n CurrentStepNumber , TrackID , Particle , VertexPosition ," 153 <<
" LogicalVolumeAtVertex , CreatorProcess" 155 << theTrack->GetCurrentStepNumber()
157 << theTrack->GetTrackID()
159 << theTrack->GetDefinition()->GetParticleName()
161 << theTrack->GetVertexPosition()
163 << theTrack->GetLogicalVolumeAtVertex()->GetName()
165 << theTrack->GetCreatorProcess()->GetProcessName() ;
170 bool backward =
false;
171 const G4ThreeVector& hitPoint = preStepPoint->GetPosition();
172 const G4ThreeVector& hit_mom = preStepPoint->GetMomentumDirection();
173 double zint = hitPoint.z();
174 double pz = hit_mom.z();
177 if (pz * zint < 0.) backward =
true;
180 bool aboveThreshold =
false;
184 bool notaMuon =
true;
187 G4int parCode = theTrack->GetDefinition()->GetPDGEncoding();
188 if (parCode == mupPDG || parCode == mumPDG ) notaMuon =
false;
191 double theta_max =
M_PI - 3.1305;
192 double R_mom=
sqrt(hit_mom.x()*hit_mom.x() + hit_mom.y()*hit_mom.y());
194 bool angleok =
false;
195 if ( theta < theta_max) angleok =
true;
198 double R =
sqrt(hitPoint.x()*hitPoint.x() + hitPoint.y()*hitPoint.y());
200 if ( zint < -14450. && R < 45.) dot =
true;
202 if ( zint < -14700. || R > 193.) inRange =
false;
203 bool OkToUse =
false;
204 if ( inRange && !dot) OkToUse =
true;
206 const bool particleWithinShowerLibrary = aboveThreshold &&
207 notaMuon && (!backward) && OkToUse && angleok && currentLV ==
lvCAST;
215 LogDebug(
"ForwardSim") <<
" Current logical volume is " << nameVolume ;
226 double meanNCherPhot=0;
238 const bool isHad = !(castorHitPID==
emPDG || castorHitPID==
epPDG || castorHitPID==
gammaPDG || castorHitPID == mupPDG || castorHitPID == mumPDG);
244 G4double stepl = aStep->GetStepLength()/cm;
245 G4double
beta = preStepPoint->GetBeta();
246 G4double
charge = preStepPoint->GetCharge();
259 G4StepPoint* postStepPoint= aStep->GetPostStepPoint();
260 G4VPhysicalVolume* postPV= postStepPoint->GetPhysicalVolume();
262 G4String postname = postPV->GetName();
264 postnameVolume.assign(postname,0,4);
269 G4ThreeVector vert_mom = theTrack->GetVertexMomentumDirection();
271 G4ThreeVector localPoint = theTrack->GetTouchable()->GetHistory()->
272 GetTopTransform().TransformPoint(hitPoint);
274 G4String
particleType = theTrack->GetDefinition()->GetParticleName();
278 if (vert_mom.x() != 0) phi = atan2(vert_mom.y(),vert_mom.x());
279 if (phi < 0.) phi += twopi;
282 double costheta =vert_mom.z()/
sqrt(vert_mom.x()*vert_mom.x()+
283 vert_mom.y()*vert_mom.y()+
284 vert_mom.z()*vert_mom.z());
287 G4int primaryID = theTrack->GetTrackID();
292 double edep = aStep->GetTotalEnergyDeposit();
318 double bThreshold = 0.67;
319 double nMedium = 1.4925;
323 double photEnSpectrDE = 1.24;
332 double thFullRefl = 23.;
333 double thFullReflRad = thFullRefl*
pi/180.;
336 double thFibDir = 45.;
342 double thFibDirRad = thFibDir*
pi/180.;
350 double costh =hit_mom.z()/
sqrt(hit_mom.x()*hit_mom.x()+
351 hit_mom.y()*hit_mom.y()+
352 hit_mom.z()*hit_mom.z());
353 if (zint < 0) costh = -costh;
357 if (th < 0.) th += twopi;
362 double costhcher =1./(nMedium*
beta);
366 double DelFibPart = fabs(th - thFibDirRad);
369 double d = fabs(
tan(th)-
tan(thFibDirRad));
374 double a =
tan(thFibDirRad)+
tan(fabs(thFibDirRad-thFullReflRad));
375 double r =
tan(th)+
tan(fabs(th-thcher));
383 if(DelFibPart > (thFullReflRad + thcher) ) {
391 if((th + thcher) < (thFibDirRad+thFullReflRad) &&
392 (th - thcher) > (thFibDirRad-thFullReflRad)) {
401 if((thFibDirRad + thFullReflRad) < (th + thcher) &&
402 (thFibDirRad - thFullReflRad) > (th - thcher) ) {
419 double arg_arcos = 0.;
420 double tan_arcos = 2.*a*
d;
421 if(tan_arcos != 0.) arg_arcos =(r*r-a*a-d*
d)/tan_arcos;
422 arg_arcos = fabs(arg_arcos);
423 double th_arcos = acos(
std::min(
std::max(arg_arcos,
double(-1.)),
double(1.)));
424 d_qz = fabs(th_arcos/
pi/2.);
443 if(charge != 0. && beta > bThreshold ) {
445 meanNCherPhot = 370.*charge*charge*
446 ( 1. - 1./(nMedium*nMedium*beta*
beta) )*
447 photEnSpectrDE*stepl;
450 G4int poissNCherPhot = (G4int) G4Poisson(meanNCherPhot * scale);
452 if(poissNCherPhot < 0) poissNCherPhot = 0;
454 double effPMTandTransport = 0.19;
455 double ReflPower = 0.1;
456 double proba = d_qz + (1-d_qz)*ReflPower;
457 NCherPhot = poissNCherPhot*effPMTandTransport*proba*0.307;
461 double thgrad = th*180./
pi;
462 double thchergrad = thcher*180./
pi;
463 double DelFibPartgrad = DelFibPart*180./
pi;
464 LogDebug(
"ForwardSim") <<
" ==============================> start all " 465 <<
"information:<========= \n" <<
" =====> for " 466 <<
"test:<=== \n" <<
" variant = " << variant
467 <<
"\n thgrad = " << thgrad <<
"\n thchergrad " 468 <<
"= " << thchergrad <<
"\n DelFibPartgrad = " 469 << DelFibPartgrad <<
"\n d_qz = " << d_qz
470 <<
"\n =====> Start Step Information <=== \n" 471 <<
" ===> calo preStepPoint info <=== \n" 472 <<
" hitPoint = " << hitPoint <<
"\n" 473 <<
" hitMom = " << hit_mom <<
"\n" 474 <<
" stepControlFlag = " << stepControlFlag
477 <<
"\n charge = " << charge <<
"\n" 478 <<
" beta = " << beta <<
"\n" 479 <<
" bThreshold = " << bThreshold <<
"\n" 480 <<
" thgrad =" << thgrad <<
"\n" 481 <<
" effPMTandTransport=" << effPMTandTransport
483 <<
"\n nameVolume = " << nameVolume <<
"\n" 484 <<
" nMedium = " << nMedium <<
"\n" 487 <<
" stepl = " << stepl <<
"\n" 488 <<
" photEnSpectrDE = " << photEnSpectrDE <<
"\n" 489 <<
" edep = " << edep <<
"\n" 490 <<
" ===> calo theTrack info <=== " <<
"\n" 491 <<
" particleType = " << particleType <<
"\n" 492 <<
" primaryID = " << primaryID <<
"\n" 493 <<
" entot= " << theTrack->GetTotalEnergy() <<
"\n" 494 <<
" vert_eta= " << eta <<
"\n" 495 <<
" vert_phi= " << phi <<
"\n" 496 <<
" vert_mom= " << vert_mom <<
"\n" 497 <<
" ===> calo hit preStepPointinfo <=== "<<
"\n" 498 <<
" local point = " << localPoint <<
"\n" 499 <<
" ==============================> final info" 501 <<
" meanNCherPhot = " << meanNCherPhot <<
"\n" 502 <<
" poissNCherPhot = " << poissNCherPhot <<
"\n" 503 <<
" NCherPhot = " << NCherPhot;
519 LogDebug(
"ForwardSim") <<
"CastorSD:: " << nameVolume
521 <<
" Weighted Energy Deposit " << edep/
MeV 541 if (scheme !=
nullptr) {
542 edm::LogInfo(
"ForwardSim") <<
"CastorSD: updates numbering scheme for " 557 if (primaryID == 0) {
559 edm::LogWarning(
"ForwardSim") <<
"CastorSD: Problem with primaryID **** set by force " 560 <<
"to TkID **** " <<
theTrack->GetTrackID();
584 double trackPhi = track->GetPosition().phi();
585 if(trackPhi<0) trackPhi += 2*
M_PI ;
588 if(showerPhi<0) showerPhi += 2*
M_PI ;
592 int trackOctSector = (
int) ( trackPhi / (
M_PI/4) ) ;
593 int showerOctSector = (
int) ( showerPhi / (
M_PI/4) ) ;
596 uint32_t sec = ( ( unitID>>4 ) & 0xF ) ;
597 uint32_t complement = ( unitID & 0xFFFFFF0F ) ;
605 double trackZ = track->GetPosition().z();
608 int dSec = 2*(trackOctSector - showerOctSector) ;
614 if(sec1<0) sec1 += 16;
615 if(sec1>15) sec1 -= 16;
616 sec = (uint32_t)(sec1);
618 if( dSec<0 ) sec += 16 ;
620 aux = (
int) (sec/16) ;
624 newUnitID = complement | sec ;
627 if(newUnitID != unitID) {
628 LogDebug(
"ForwardSim") <<
"\n CastorSD::rotateUnitID: " 629 <<
"\n unitID = " << unitID
630 <<
"\n newUnitID = " << newUnitID ;
669 G4int particleCode =
theTrack->GetDefinition()->GetPDGEncoding();
672 isEM =
true ; isHAD =
false;
674 isEM =
false; isHAD =
true ;
679 LogDebug(
"ForwardSim") <<
"\n CastorSD::getFromLibrary: " 680 << hits.
getNhit() <<
" hits for " << GetName() <<
" from " 681 <<
theTrack->GetDefinition()->GetParticleName() <<
" of " 689 double scale = E_track/E_SLhit ;
716 for (
unsigned int i=0;
i<hits.
getNhit();
i++) {
721 nPhotoElectrons *=
scale ;
756 theTrack->SetTrackStatus(fStopAndKill);
758 LogDebug(
"ForwardSim") <<
"CastorSD::getFromLibrary:" 759 <<
"\n \"theTrack\" with TrackID() = " 761 <<
" and with energy " 763 <<
" has been set to be killed" ;
765 G4TrackVector tv = *(aStep->GetSecondary());
766 for (
unsigned int kk=0;
kk<tv.size();
kk++) {
768 tv[
kk]->SetTrackStatus(fStopAndKill);
770 LogDebug(
"ForwardSim") <<
"CastorSD::getFromLibrary:" 771 <<
"\n tv[" <<
kk <<
"]->GetTrackID() = " 772 << tv[
kk]->GetTrackID()
774 << tv[
kk]->GetTotalEnergy()
775 <<
" has been set to be killed" ;
T getParameter(std::string const &) const
void initParticleTable(G4ParticleTable *)
void updateHit(CaloG4Hit *)
double getEnergyDeposit(G4Step *) override
Geom::Theta< T > theta() const
double non_compensation_factor
CastorNumberingScheme * numberingScheme
uint32_t rotateUnitID(uint32_t, G4Track *, const CastorShowerEvent &)
type of data representation of DDCompactView
void getFromLibrary(G4Step *)
unsigned int getDetID(int i)
static TrackerG4SimHitNumberingScheme & numberingScheme(const DDCompactView &cpv, const GeometricDet &det)
void resetForNewPrimary(const G4ThreeVector &, double)
Tan< T >::type tan(const T &t)
Abs< T >::type abs(const T &t)
uint32_t setDetUnitId(G4Step *step) override
void setID(uint32_t unitID, double timeSlice, int trackID, uint16_t depth=0)
G4StepPoint * preStepPoint
static const G4LogicalVolume * GetVolume(const std::string &name)
CastorSD(G4String, const DDCompactView &, const SensitiveDetectorCatalog &clg, edm::ParameterSet const &, const SimTrackManager *)
CastorShowerLibrary * showerLibrary
CastorShowerEvent getShowerHits(G4Step *, bool &)
void setNumberingScheme(CastorNumberingScheme *scheme)
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
CaloG4Hit * createNewHit()