12 #include "G4EventManager.hh" 13 #include "G4SDManager.hh" 16 #include "G4VProcess.hh" 17 #include "G4GFlashSpot.hh" 18 #include "G4ParticleTable.hh" 20 #include "G4SystemOfUnits.hh" 21 #include "G4PhysicalConstants.hh" 31 float timeSliceUnit,
bool ignoreTkID) :
33 G4VGFlashSensitiveDetector(), eminHit(0.),currentHit(
nullptr),
34 m_trackManager(manager), theHC(
nullptr), ignoreTrackID(ignoreTkID), hcID(-1),
41 std::vector<double> eminHits = m_CaloSD.
getParameter<std::vector<double> >(
"EminHits");
42 std::vector<double> tmaxHits = m_CaloSD.
getParameter<std::vector<double> >(
"TmaxHits");
43 std::vector<std::string> hcn = m_CaloSD.
getParameter<std::vector<std::string> >(
"HCNames");
44 std::vector<int> useResMap = m_CaloSD.
getParameter<std::vector<int> >(
"UseResponseTables");
45 std::vector<double> eminHitX = m_CaloSD.
getParameter<std::vector<double> >(
"EminHitsDepth");
54 double beamZ = m_CaloSD.
getParameter<
double>(
"BeamPosition")*cm;
57 SetVerboseLevel(verbn);
59 for (
unsigned int k=0;
k<hcn.size(); ++
k) {
61 if (k < eminHits.size())
eminHit = eminHits[k]*
MeV;
63 if (k < tmaxHits.size()) tmaxHit = tmaxHits[k]*ns;
64 if (k < useResMap.size() && useResMap[
k] > 0) {
84 edm::LogInfo(
"CaloSim") <<
"CaloSD: Minimum energy of track for saving it " 85 << energyCut/
GeV <<
" GeV" <<
"\n" 86 <<
" Use of HitID Map " << useMap <<
"\n" 87 <<
" Check last " << nCheckedHits
88 <<
" before saving the hit\n" 89 <<
" Correct TOF globally by " << correctT
90 <<
" ns (Flag =" << corrTOFBeam <<
")\n" 91 <<
" Save hits recorded before " << tmaxHit
92 <<
" ns and if energy is above " <<
eminHit/
MeV 94 <<
" MeV (for nonzero depths);\n" 95 <<
" Time Slice Unit " 110 <<
" ID= " << aStep->GetTrack()->GetTrackID()
111 <<
" prID= " << aStep->GetTrack()->GetParentID()
112 <<
" Eprestep= " << aStep->GetPreStepPoint()->GetKineticEnergy()
113 <<
" step= " << aStep->GetStepLength()
114 <<
" Edep= " << aStep->GetTotalEnergyDeposit();
121 aStep->GetTrack()->SetTrackStatus(fStopAndKill);
122 auto tv = aStep->GetSecondary();
123 auto vol = aStep->GetPreStepPoint()->GetPhysicalVolume();
124 for(
auto & tk : *tv) {
125 if (tk->GetVolume() == vol) {
126 tk->SetTrackStatus(fStopAndKill);
136 auto const theTrack = aStep->GetTrack();
139 double time = theTrack->GetGlobalTime()/nanosecond;
144 if(aStep->GetTotalEnergyDeposit() > 0.0) {
145 G4TouchableHistory* touch =(G4TouchableHistory*)(theTrack->GetTouchable());
146 edm::LogInfo(
"CaloSim") <<
"CaloSD::ProcessHits: unitID= " << unitID
148 <<
" Detector: " << GetName()
149 <<
" trackID= " << theTrack->GetTrackID()
150 <<
" " << theTrack->GetDefinition()->GetParticleName()
151 <<
"\n Edep= " << aStep->GetTotalEnergyDeposit()
152 <<
" PV: " << touch->GetVolume(0)->GetName()
153 <<
" PVid= " << touch->GetReplicaNumber(0)
154 <<
" MVid= " << touch->GetReplicaNumber(1);
159 if(aStep->GetTotalEnergyDeposit() == 0.0) {
174 G4TouchableHistory* touch =(G4TouchableHistory*)(theTrack->GetTouchable());
176 <<
"CaloSD::" << GetName()
177 <<
" PV:" << touch->GetVolume(0)->GetName()
178 <<
" PVid=" << touch->GetReplicaNumber(0)
179 <<
" MVid=" << touch->GetReplicaNumber(1)
180 <<
" Unit:" << std::hex << unitID <<
std::dec 182 <<
" ID=" << theTrack->GetTrackID()
183 <<
" pID=" << theTrack->GetParentID()
184 <<
" E=" << theTrack->GetKineticEnergy()
185 <<
" S=" << aStep->GetStepLength()
186 <<
"\n " << theTrack->GetDefinition()->GetParticleName()
187 <<
" primaryID= " << primaryID
202 const G4Track*
track = aSpot->GetOriginatorTrack()->GetPrimaryTrack();
204 double edep = aSpot->GetEnergySpot()->GetEnergy();
205 if (edep <= 0.0) {
return false; }
208 G4StepPoint * fFakePreStepPoint = fFakeStep.GetPreStepPoint();
209 G4StepPoint * fFakePostStepPoint = fFakeStep.GetPostStepPoint();
210 fFakePreStepPoint->SetPosition(aSpot->GetPosition());
211 fFakePostStepPoint->SetPosition(aSpot->GetPosition());
213 G4TouchableHandle fTouchableHandle = aSpot->GetTouchableHandle();
214 fFakePreStepPoint->SetTouchableHandle(fTouchableHandle);
215 fFakeStep.SetTotalEnergyDeposit(edep);
234 posGlobal = aSpot->GetEnergySpot()->GetPosition();
242 LogDebug(
"CaloSim") <<
"CaloSD: Incident energy " 256 return aStep->GetTotalEnergyDeposit();
267 edm::LogVerbatim(
"CaloSim") <<
"CaloSD : Initialize called for " << GetName();
299 theHC->PrintAllHits();
303 if (
slave.get()->name() == hname) { cc=
slave.get()->hits(); }
304 slave.get()->Clean();
308 return touch->GetHistory()->GetTopTransform().TransformPoint(global);
312 return touch->GetHistory()->GetTopTransform().Inverse().TransformPoint(local);
323 posGlobal = aStep->GetPreStepPoint()->GetPosition();
334 std::map<CaloHitID,CaloG4Hit*>::const_iterator it =
hitMap.find(
currentID);
341 int maxhit=
theHC->entries()-1;
343 for (
int j=maxhit; j>minhit; --j) {
360 auto const theTrack = aStep->GetTrack();
363 <<
" for " << GetName()
369 <<
" ID= " << theTrack->GetTrackID()
370 <<
" " <<theTrack->GetDefinition()->GetParticleName()
371 <<
" E(GeV)= " << theTrack->GetKineticEnergy()/
GeV 372 <<
" parentID= " << theTrack->GetParentID()
392 aHit->
setPosition(posGlobal.x(),posGlobal.y(),posGlobal.z());
400 etrack= theTrack->GetKineticEnergy();
403 <<
" etrack " << etrack <<
" eCut " <<
energyCut 418 if (trkh !=
nullptr) {
438 edm::LogVerbatim(
"CaloSim") <<
"CaloSD:" << GetName() <<
" Add energy deposit in " 448 auto const preStepPoint = aStep->GetPreStepPoint();
454 <<
"CaloSD::resetForNewPrimary for " << GetName()
455 <<
" ID= " << aStep->GetTrack()->GetTrackID()
456 <<
" Ein= " << incidentEnergy/
GeV 464 double charge = aStep->GetPreStepPoint()->GetCharge();
465 double length = aStep->GetStepLength();
467 if (charge != 0. && length > 0.) {
468 double density = aStep->GetPreStepPoint()->GetMaterial()->GetDensity();
469 double dedx = aStep->GetTotalEnergyDeposit()/length;
470 double rkb = birk1/density;
471 double c = birk2*rkb*rkb;
472 if (
std::abs(charge) >= 2.) rkb /= birk3;
473 weight = 1./(1.+rkb*dedx+c*dedx*dedx);
475 edm::LogVerbatim(
"CaloSim") <<
"CaloSD::getAttenuation in " << mat->GetName()
476 <<
" Charge " << charge <<
" dE/dx " << dedx
477 <<
" Birk Const " << rkb <<
", " << c <<
" Weight = " 478 << weight <<
" dE " << aStep->GetTotalEnergyDeposit();
491 << GetName() <<
" !" ;
497 int id = (*trk)()->GetTrackID();
499 int lastTrackID = -1;
501 if (
id == lastTrackID) {
503 if (trksForThisEvent !=
nullptr) {
504 int it = (
int)(trksForThisEvent->size()) - 1;
510 <<
"Container of size " << trksForThisEvent->size()
511 <<
" with ID " << trkH->
trackID();
514 <<
"Container of size " << trksForThisEvent->size()
537 for (
int i=0;
i<
theHC->entries(); ++
i) {
540 double x = (*theHC)[
i]->getEM();
543 x = (*theHC)[
i]->getHadr();
546 tt += (*theHC)[
i]->getTimeSlice();
547 ee += (*theHC)[
i]->getIncidentEnergy();
552 double norm = (count>0) ? 1.0/count : 0.0;
564 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: " << GetName() <<
" store " << count
565 <<
" hits; " << wrong
566 <<
" track IDs not given properly and " 567 <<
totalHits-count <<
" hits not passing cuts" 568 <<
"\n EmeanEM= " << eEM <<
" ErmsEM= " << eEM2
569 <<
"\n EmeanHAD= " << eHAD <<
" ErmsHAD= " << eHAD2
570 <<
" TimeMean= " << tt <<
" E0mean= " << ee
571 <<
" Zglob= " << zglob <<
" Zloc= " << zloc
585 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: Clears hit vector for " << GetName()
586 <<
" and initialise slave: " <<
slave;
588 slave.get()->Initialize();
601 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: hit update from track Id on Calo Surface " 605 primaryID = aTrack->GetTrackID();
607 edm::LogWarning(
"CaloSim") <<
"CaloSD: Problem with primaryID **** set by " 608 <<
"force to TkID **** " << primaryID <<
" in " 609 << preStepPoint->GetTouchable()->GetVolume(0)->GetName();
617 auto const theTrack = aStep->GetTrack();
620 if (primaryID == 0) { primaryID = theTrack->GetTrackID(); }
627 <<
" trackID= " << aStep->GetTrack()->GetTrackID()
628 <<
" primaryID= " << primaryID;
640 <<
" Emin = " << emin
683 <<
" changed to " << tkID <<
" by SimTrackManager" 693 << aHit->
getDepth() <<
" due to " << tkID
694 <<
" in time " << time <<
" of energy " 695 << aHit->
getEM()/
GeV <<
" GeV (EM) and " 704 if ( trkInfo->
isPrimary() ) primary = (*trk)()->GetTrackID();
708 <<
" primary ID = " << primary
714 if (primary > 0 && primary != primAncestor) {
715 primAncestor = primary;
725 std::vector<CaloG4Hit*>* theCollection =
theHC->GetVector();
737 hitvec.swap(*theCollection);
740 edm::LogVerbatim(
"CaloSim") <<
"CaloSD::cleanHitCollection: sort hits in buffer " 742 for (
unsigned int i = 0;
i<
hitvec.size(); ++
i)
747 for (i=cleanIndex; i<hitvec.size(); ++
i) {
750 for (j = i+1; j <hitvec.size() &&
equal(hitvec[i], hitvec[j]); ++j) {
753 (*hitvec[
i]).addEnergyDeposit(*hitvec[j]);
754 (*hitvec[j]).setEM(0.);
755 (*hitvec[j]).setHadr(0.);
761 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: cleanHitCollection merge the hits in buffer ";
762 for (
unsigned int i = 0; i<hitvec.size(); ++
i)
765 for (
unsigned int i = cleanIndex; i < cleanIndex+
selIndex.size(); ++
i ) {
768 hitvec.resize(cleanIndex+
selIndex.size());
771 <<
"CaloSD::cleanHitCollection: remove the merged hits in buffer," 772 <<
" new size = " << hitvec.size();
773 for (
unsigned int i = 0; i<hitvec.size(); ++
i)
776 hitvec.swap(*theCollection);
777 std::vector<CaloG4Hit*>().
swap(hitvec);
785 <<
" Size of reusehit= " <<
reusehit.size()
786 <<
"\n starting hit selection from index = " 792 for (
unsigned int i =
cleanIndex;
i<theCollection->size(); ++
i) {
801 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: dropped CaloG4Hit " <<
" " << *aHit;
806 reusehit.push_back((*theCollection)[i]);
814 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: Size of reusehit after selection = " 815 <<
reusehit.size() <<
" Number of added hit = " 821 for (
int ii = addhit-1;
ii>=0; --
ii) {
827 for (
unsigned int j = 0; j<
selIndex.size(); ++j) {
836 <<
"CaloSD: hit collection after selection, size = " 838 theHC->PrintAllHits();
Int_t getEntry(TBranch *branch, EntryNumber entryNumber)
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
virtual bool getFromLibrary(const G4Step *step)
std::vector< PCaloHit > PCaloHitContainer
void updateHit(CaloG4Hit *)
virtual uint16_t getDepth(const G4Step *)
virtual double getEnergyDeposit(const G4Step *step)
void setIncidentEnergy(double e)
void setEntryLocal(double x, double y, double z)
uint32_t setDetUnitId(const G4Step *step) override=0
uint16_t getDepth() const
virtual int getTrackID(const G4Track *)
void Initialize(G4HCofThisEvent *HCE) override
Compact representation of the geometrical detector hierarchy.
void fillHits(edm::PCaloHitContainer &, const std::string &) override
void swap(Association< C > &lhs, Association< C > &rhs)
std::vector< CaloG4Hit * > reusehit
bool equal(const T &first, const T &second)
void cleanHitCollection()
void addEnergyDeposit(double em, double hd)
const TrackContainer * trackContainer() const
std::string const collectionName[nCollections]
std::unique_ptr< CaloSlaveSD > slave
std::vector< TrackWithHistory * > TrackContainer
unsigned int trackID() const
void resetForNewPrimary(const G4Step *)
bool trackExists(unsigned int i) const
void setID(uint32_t i, double d, int j, uint16_t k=0)
Abs< T >::type abs(const T &t)
CaloG4Hit * createNewHit(const G4Step *)
G4bool ProcessHits(G4Step *step, G4TouchableHistory *) override
std::vector< CaloG4Hit * > hitvec
G4ThreeVector setToGlobal(const G4ThreeVector &, const G4VTouchable *) const
CaloSD(const std::string &aSDname, const DDCompactView &cpv, const SensitiveDetectorCatalog &clg, edm::ParameterSet const &p, const SimTrackManager *, float timeSlice=1., bool ignoreTkID=false)
int giveMotherNeeded(int i) const
std::vector< unsigned int > selIndex
void storeHit(CaloG4Hit *)
TrackInformation * cmsTrackInformation(const G4Track *aTrack)
virtual bool filterHit(CaloG4Hit *, double)
void setID(uint32_t unitID, double timeSlice, int trackID, uint16_t depth=0)
G4ThreeVector setToLocal(const G4ThreeVector &, const G4VTouchable *) const
bool hitExists(const G4Step *)
std::unique_ptr< CaloMeanResponse > meanResponse
const math::XYZVectorD & momentum() const
void EndOfEvent(G4HCofThisEvent *eventHC) override
CSCCFEBTimeSlice const *const timeSlice(T const &data, int nCFEB, int nSample)
std::map< CaloHitID, CaloG4Hit * > hitMap
double getAttenuation(const G4Step *aStep, double birk1, double birk2, double birk3) const
CaloG4HitCollection * theHC
virtual int setTrackID(const G4Step *)
void setPosition(double x, double y, double z)
void setEntry(double x, double y, double z)
G4THitsCollection< CaloG4Hit > CaloG4HitCollection
static bool isGammaElectronPositron(int pdgCode)
double getTimeSlice() const
std::map< int, TrackWithHistory * > tkMap
const SimTrackManager * m_trackManager
uint32_t getUnitID() const
void clearHits() override
double getResponseWt(const G4Track *)
bool saveHit(CaloG4Hit *)
G4ThreeVector entrancePoint
G4ThreeVector entranceLocal
void update(const BeginOfRun *) override
This routine will be called when the appropriate signal arrives.
double getEnergyDeposit() const
void NaNTrap(const G4Step *step) const