15 #include "G4SDManager.hh"
18 #include "G4VProcess.hh"
21 #include "G4Cerenkov.hh"
22 #include "G4LogicalVolumeStore.hh"
24 #include "CLHEP/Units/GlobalSystemOfUnits.h"
25 #include "Randomize.hh"
26 #include "G4Poisson.hh"
35 lvC3HF(0), lvC4EF(0), lvC4HF(0), lvCAST(0) {
40 energyThresholdSL = energyThresholdSL*GeV;
49 <<
"***************************************************\n"
51 <<
"* Constructing a CastorSD with name " << GetName() <<
"\n"
53 <<
"***************************************************";
55 const G4LogicalVolumeStore * lvs = G4LogicalVolumeStore::GetInstance();
56 std::vector<G4LogicalVolume*>::const_iterator lvcite;
57 for (lvcite = lvs->begin(); lvcite != lvs->end(); lvcite++) {
58 if (strcmp(((*lvcite)->GetName()).c_str(),
"C3EF") == 0)
lvC3EF = (*lvcite);
59 if (strcmp(((*lvcite)->GetName()).c_str(),
"C3HF") == 0)
lvC3HF = (*lvcite);
60 if (strcmp(((*lvcite)->GetName()).c_str(),
"C4EF") == 0)
lvC4EF = (*lvcite);
61 if (strcmp(((*lvcite)->GetName()).c_str(),
"C4HF") == 0)
lvC4HF = (*lvcite);
62 if (strcmp(((*lvcite)->GetName()).c_str(),
"CAST") == 0)
lvCAST = (*lvcite);
65 edm::LogInfo(
"ForwardSim") <<
"CastorSD:: LogicalVolume pointers\n"
67 <<
" for C3HF; " <<
lvC4EF <<
" for C4EF; "
69 <<
lvCAST <<
" for CAST. " << std::endl;
86 G4ParticleTable * theParticleTable = G4ParticleTable::GetParticleTable();
88 edm::LogInfo(
"ForwardSim") <<
"CastorSD::initRun: Using Castor Shower Library \n";
104 G4VPhysicalVolume* currentPV = preStepPoint->GetPhysicalVolume();
105 G4LogicalVolume* currentLV = currentPV->GetLogicalVolume();
106 G4String
name = currentPV->GetName();
107 std::string nameVolume;
108 nameVolume.assign(name,0,4);
111 G4SteppingControl stepControlFlag = aStep->GetControlFlag();
112 if (aStep->IsFirstStepInVolume())
113 LogDebug(
"ForwardSim") <<
"CastorSD::getEnergyDeposit:"
114 <<
"\n IsFirstStepInVolume " ;
118 G4Track*
theTrack = aStep->GetTrack();
122 LogDebug(
"ForwardSim") <<
"CastorSD::getEnergyDeposit:"
123 <<
"\n TrackID , ParentID , ParticleName ,"
124 <<
" eta , phi , z , time ,"
127 << theTrack->GetTrackID()
129 << theTrack->GetParentID()
131 << theTrack->GetDefinition()->GetParticleName()
133 << theTrack->GetPosition().eta()
135 << theTrack->GetPosition().phi()
137 << theTrack->GetPosition().z()
139 << theTrack->GetGlobalTime()
141 << theTrack->GetKineticEnergy()
143 << theTrack->GetTotalEnergy()
145 << theTrack->GetMomentum().mag() ;
146 if(theTrack->GetTrackID() != 1)
147 LogDebug(
"ForwardSim") <<
"CastorSD::getEnergyDeposit:"
148 <<
"\n CurrentStepNumber , TrackID , Particle , VertexPosition ,"
149 <<
" LogicalVolumeAtVertex , CreatorProcess"
151 << theTrack->GetCurrentStepNumber()
153 << theTrack->GetTrackID()
155 << theTrack->GetDefinition()->GetParticleName()
157 << theTrack->GetVertexPosition()
159 << theTrack->GetLogicalVolumeAtVertex()->GetName()
161 << theTrack->GetCreatorProcess()->GetProcessName() ;
166 bool backward =
false;
167 G4ThreeVector hitPoint = preStepPoint->GetPosition();
168 G4ThreeVector hit_mom = preStepPoint->GetMomentumDirection();
169 double zint = hitPoint.z();
170 double pz = hit_mom.z();
173 if (pz * zint < 0.) backward =
true;
176 bool aboveThreshold =
false;
180 bool notaMuon =
true;
183 G4int parCode = theTrack->GetDefinition()->GetPDGEncoding();
184 if (parCode == mupPDG || parCode == mumPDG ) notaMuon =
false;
187 double theta_max =
M_PI - 3.1305;
188 double R_mom=
sqrt(hit_mom.x()*hit_mom.x() + hit_mom.y()*hit_mom.y());
190 bool angleok =
false;
191 if ( theta < theta_max) angleok =
true;
194 double R =
sqrt(hitPoint.x()*hitPoint.x() + hitPoint.y()*hitPoint.y());
196 if ( zint < -14450. && R < 45.) dot =
true;
198 if ( zint < -14700. || R > 193.) inRange =
false;
199 bool OkToUse =
false;
200 if ( inRange && !dot) OkToUse =
true;
202 if (
useShowerLibrary && aboveThreshold && notaMuon && (!backward) && OkToUse && angleok && currentLV ==
lvCAST ) {
208 LogDebug(
"ForwardSim") <<
" Current logical volume is " << nameVolume ;
215 G4double stepl = aStep->GetStepLength()/cm;
216 G4double
beta = preStepPoint->GetBeta();
217 G4double
charge = preStepPoint->GetCharge();
229 G4StepPoint* postStepPoint= aStep->GetPostStepPoint();
230 G4VPhysicalVolume* postPV = postStepPoint->GetPhysicalVolume();
231 G4String postname = postPV->GetName();
232 std::string postnameVolume;
233 postnameVolume.assign(postname,0,4);
238 G4ThreeVector vert_mom = theTrack->GetVertexMomentumDirection();
240 G4ThreeVector localPoint = theTrack->GetTouchable()->GetHistory()->
241 GetTopTransform().TransformPoint(hitPoint);
245 if (vert_mom.x() != 0) phi = atan2(vert_mom.y(),vert_mom.x());
246 if (phi < 0.) phi += twopi;
247 G4String particleType = theTrack->GetDefinition()->GetParticleName();
249 float costheta =vert_mom.z()/
sqrt(vert_mom.x()*vert_mom.x()+
250 vert_mom.y()*vert_mom.y()+
251 vert_mom.z()*vert_mom.z());
254 G4int primaryID = theTrack->GetTrackID();
259 double edep = aStep->GetTotalEnergyDeposit();
281 double meanNCherPhot=0;
287 float bThreshold = 0.67;
288 float nMedium = 1.4925;
292 float photEnSpectrDE = 1.24;
300 float effPMTandTransport = 0.19;
307 float thFullRefl = 23.;
308 float thFullReflRad = thFullRefl*
pi/180.;
311 float thFibDir = 45.;
317 float thFibDirRad = thFibDir*
pi/180.;
325 float costh =hit_mom.z()/
sqrt(hit_mom.x()*hit_mom.x()+
326 hit_mom.y()*hit_mom.y()+
327 hit_mom.z()*hit_mom.z());
328 if (zint < 0) costh = -costh;
332 if (th < 0.) th += twopi;
337 float costhcher =1./(nMedium*
beta);
341 float DelFibPart = fabs(th - thFibDirRad);
344 float d = fabs(
tan(th)-
tan(thFibDirRad));
349 float a =
tan(thFibDirRad)+
tan(fabs(thFibDirRad-thFullReflRad));
350 float r =
tan(th)+
tan(fabs(th-thcher));
357 if(DelFibPart > (thFullReflRad + thcher) ) {d_qz = 0.; variant=0.;}
360 if((th + thcher) < (thFibDirRad+thFullReflRad) &&
361 (th - thcher) > (thFibDirRad-thFullReflRad)
362 ) {d_qz = 1.; variant=1.;}
366 if((thFibDirRad + thFullReflRad) < (th + thcher) &&
367 (thFibDirRad - thFullReflRad) > (th - thcher) ) {
370 d_qz = 0.; variant=2.;
376 d_qz = 0.; variant=3.;
381 float arg_arcos = 0.;
382 float tan_arcos = 2.*a*d;
383 if(tan_arcos != 0.) arg_arcos =(r*r-a*a-d*d)/tan_arcos;
384 arg_arcos = fabs(arg_arcos);
386 d_qz = th_arcos/
pi/2.;
408 if(charge != 0. && beta > bThreshold && d_qz != 0. ) {
410 meanNCherPhot = 370.*charge*charge*
411 ( 1. - 1./(nMedium*nMedium*beta*
beta) )*
412 photEnSpectrDE*stepl;
422 G4int poissNCherPhot = (G4int) G4Poisson(meanNCherPhot);
424 if(poissNCherPhot < 0) poissNCherPhot = 0;
426 NCherPhot = poissNCherPhot * effPMTandTransport * d_qz;
431 float thgrad = th*180./
pi;
432 float thchergrad = thcher*180./
pi;
433 float DelFibPartgrad = DelFibPart*180./
pi;
434 LogDebug(
"ForwardSim") <<
" ==============================> start all "
435 <<
"information:<========= \n" <<
" =====> for "
436 <<
"test:<=== \n" <<
" variant = " << variant
437 <<
"\n thgrad = " << thgrad <<
"\n thchergrad "
438 <<
"= " << thchergrad <<
"\n DelFibPartgrad = "
439 << DelFibPartgrad <<
"\n d_qz = " << d_qz
440 <<
"\n =====> Start Step Information <=== \n"
441 <<
" ===> calo preStepPoint info <=== \n"
442 <<
" hitPoint = " << hitPoint <<
"\n"
443 <<
" hitMom = " << hit_mom <<
"\n"
444 <<
" stepControlFlag = " << stepControlFlag
447 <<
"\n charge = " << charge <<
"\n"
448 <<
" beta = " << beta <<
"\n"
449 <<
" bThreshold = " << bThreshold <<
"\n"
450 <<
" thgrad =" << thgrad <<
"\n"
451 <<
" effPMTandTransport=" << effPMTandTransport
453 <<
"\n nameVolume = " << nameVolume <<
"\n"
454 <<
" nMedium = " << nMedium <<
"\n"
457 <<
" stepl = " << stepl <<
"\n"
458 <<
" photEnSpectrDE = " << photEnSpectrDE <<
"\n"
459 <<
" edep = " << edep <<
"\n"
460 <<
" ===> calo theTrack info <=== " <<
"\n"
461 <<
" particleType = " << particleType <<
"\n"
462 <<
" primaryID = " << primaryID <<
"\n"
463 <<
" entot= " << theTrack->GetTotalEnergy() <<
"\n"
464 <<
" vert_eta= " << eta <<
"\n"
465 <<
" vert_phi= " << phi <<
"\n"
466 <<
" vert_mom= " << vert_mom <<
"\n"
467 <<
" ===> calo hit preStepPointinfo <=== "<<
"\n"
468 <<
" local point = " << localPoint <<
"\n"
469 <<
" ==============================> final info"
471 <<
" meanNCherPhot = " << meanNCherPhot <<
"\n"
472 <<
" poissNCherPhot = " << poissNCherPhot <<
"\n"
473 <<
" NCherPhot = " << NCherPhot;
489 LogDebug(
"ForwardSim") <<
"CastorSD:: " << nameVolume
491 <<
" Weighted Energy Deposit " << edep/MeV
515 edm::LogInfo(
"ForwardSim") <<
"CastorSD: updates numbering scheme for "
531 if (primaryID == 0) {
533 edm::LogWarning(
"ForwardSim") <<
"CastorSD: Problem with primaryID **** set by force "
534 <<
"to TkID **** " <<
theTrack->GetTrackID();
556 float trackPhi = track->GetPosition().phi();
557 if(trackPhi<0) trackPhi += 2*
M_PI ;
560 if(showerPhi<0) showerPhi += 2*
M_PI ;
564 int trackOctSector = (int) ( trackPhi / (
M_PI/4) ) ;
565 int showerOctSector = (int) ( showerPhi / (
M_PI/4) ) ;
568 uint32_t sec = ( ( unitID>>4 ) & 0xF ) ;
569 uint32_t complement = ( unitID & 0xFFFFFF0F ) ;
577 float trackZ = track->GetPosition().z();
580 int dSec = 2*(trackOctSector - showerOctSector) ;
586 if(sec1<0) sec1 += 16;
587 if(sec1>15) sec1 -= 16;
588 sec = (uint32_t)(sec1);
590 if( dSec<0 ) sec += 16 ;
592 aux = (int) (sec/16) ;
596 newUnitID = complement | sec ;
599 if(newUnitID != unitID) {
600 LogDebug(
"ForwardSim") <<
"\n CastorSD::rotateUnitID: "
601 <<
"\n unitID = " << unitID
602 <<
"\n newUnitID = " << newUnitID ;
641 G4int particleCode =
theTrack->GetDefinition()->GetPDGEncoding();
644 isEM =
true ; isHAD =
false;
646 isEM =
false; isHAD =
true ;
651 LogDebug(
"ForwardSim") <<
"\n CastorSD::getFromLibrary: "
652 << hits.
getNhit() <<
" hits for " << GetName() <<
" from "
653 <<
theTrack->GetDefinition()->GetParticleName() <<
" of "
654 <<
preStepPoint->GetKineticEnergy()/GeV <<
" GeV and trackID "
660 double E_SLhit = hits.
getPrimE() * GeV ;
661 double scale = E_track/E_SLhit ;
688 for (
unsigned int i=0;
i<hits.
getNhit();
i++) {
693 nPhotoElectrons *= scale ;
728 theTrack->SetTrackStatus(fStopAndKill);
730 LogDebug(
"ForwardSim") <<
"CastorSD::getFromLibrary:"
731 <<
"\n \"theTrack\" with TrackID() = "
733 <<
" and with energy "
735 <<
" has been set to be killed" ;
737 G4TrackVector tv = *(aStep->GetSecondary());
738 for (
unsigned int kk=0; kk<tv.size(); kk++) {
740 tv[kk]->SetTrackStatus(fStopAndKill);
742 LogDebug(
"ForwardSim") <<
"CastorSD::getFromLibrary:"
743 <<
"\n tv[" << kk <<
"]->GetTrackID() = "
744 << tv[kk]->GetTrackID()
746 << tv[kk]->GetTotalEnergy()
747 <<
" has been set to be killed" ;
T getParameter(std::string const &) const
void initParticleTable(G4ParticleTable *)
void updateHit(CaloG4Hit *)
Point getHitPosition(int i)
virtual double getEnergyDeposit(G4Step *)
uint32_t rotateUnitID(uint32_t, G4Track *, CastorShowerEvent)
Geom::Theta< T > theta() const
double non_compensation_factor
CastorNumberingScheme * numberingScheme
type of data representation of DDCompactView
CastorSD(G4String, const DDCompactView &, SensitiveDetectorCatalog &clg, edm::ParameterSet const &, const SimTrackManager *)
void getFromLibrary(G4Step *)
unsigned int getDetID(int i)
static int position[TOTALCHAMBERS][3]
static TrackerG4SimHitNumberingScheme & numberingScheme(const DDCompactView &cpv, const GeometricDet &det)
const T & max(const T &a, const T &b)
Tan< T >::type tan(const T &t)
void setID(uint32_t unitID, double timeSlice, int trackID, uint16_t depth=0)
G4StepPoint * preStepPoint
static const G4LogicalVolume * GetVolume(const std::string &name)
Log< T >::type log(const T &t)
XYZPointD XYZPoint
point in space with cartesian internal representation
CastorShowerLibrary * showerLibrary
CastorShowerEvent getShowerHits(G4Step *, bool &)
virtual uint32_t setDetUnitId(G4Step *step)
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
void resetForNewPrimary(G4ThreeVector, double)
CaloG4Hit * createNewHit()