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" 35 G4VGFlashSensitiveDetector(),
38 m_trackManager(manager),
40 ignoreTrackID(ignoreTkID),
48 std::vector<double> eminHits = m_CaloSD.
getParameter<std::vector<double> >(
"EminHits");
49 std::vector<double> tmaxHits = m_CaloSD.
getParameter<std::vector<double> >(
"TmaxHits");
50 std::vector<std::string> hcn = m_CaloSD.
getParameter<std::vector<std::string> >(
"HCNames");
51 std::vector<int> useResMap = m_CaloSD.
getParameter<std::vector<int> >(
"UseResponseTables");
52 std::vector<double> eminHitX = m_CaloSD.
getParameter<std::vector<double> >(
"EminHitsDepth");
61 double beamZ = m_CaloSD.
getParameter<
double>(
"BeamPosition") * cm;
62 correctT = beamZ / c_light / nanosecond;
64 SetVerboseLevel(verbn);
66 for (
unsigned int k = 0;
k < hcn.size(); ++
k) {
68 if (k < eminHits.size())
70 if (k < eminHitX.size())
72 if (k < tmaxHits.size())
73 tmaxHit = tmaxHits[k] * ns;
74 if (k < useResMap.size() && useResMap[
k] > 0) {
94 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: Minimum energy of track for saving it " << energyCut /
GeV <<
" GeV" 96 <<
" Use of HitID Map " << useMap <<
"\n" 97 <<
" Check last " << nCheckedHits <<
" before saving the hit\n" 98 <<
" Correct TOF globally by " << correctT <<
" ns (Flag =" << corrTOFBeam <<
")\n" 99 <<
" Save hits recorded before " << tmaxHit <<
" ns and if energy is above " 101 <<
" MeV (for nonzero depths);\n" 111 edm::LogVerbatim(
"CaloSim") <<
"CaloSD::" << GetName() <<
" ID= " << aStep->GetTrack()->GetTrackID()
112 <<
" prID= " << aStep->GetTrack()->GetParentID()
113 <<
" Eprestep= " << aStep->GetPreStepPoint()->GetKineticEnergy()
114 <<
" step= " << aStep->GetStepLength() <<
" Edep= " << aStep->GetTotalEnergyDeposit();
120 aStep->GetTrack()->SetTrackStatus(fStopAndKill);
121 auto tv = aStep->GetSecondary();
122 auto vol = aStep->GetPreStepPoint()->GetPhysicalVolume();
123 for (
auto& tk : *tv) {
124 if (tk->GetVolume() == vol) {
125 tk->SetTrackStatus(fStopAndKill);
135 auto const theTrack = aStep->GetTrack();
138 double time = theTrack->GetGlobalTime() / nanosecond;
143 if (aStep->GetTotalEnergyDeposit() > 0.0) {
144 const G4TouchableHistory* touch =
static_cast<const G4TouchableHistory*
>(theTrack->GetTouchable());
146 <<
" Detector: " << GetName() <<
" trackID= " << theTrack->GetTrackID() <<
" " 147 << theTrack->GetDefinition()->GetParticleName()
148 <<
"\n Edep= " << aStep->GetTotalEnergyDeposit()
149 <<
" PV: " << touch->GetVolume(0)->GetName()
150 <<
" PVid= " << touch->GetReplicaNumber(0) <<
" MVid= " << touch->GetReplicaNumber(1);
155 if (aStep->GetTotalEnergyDeposit() == 0.0) {
170 G4TouchableHistory* touch = (G4TouchableHistory*)(theTrack->GetTouchable());
171 edm::LogVerbatim(
"CaloSim") <<
"CaloSD::" << GetName() <<
" PV:" << touch->GetVolume(0)->GetName()
172 <<
" PVid=" << touch->GetReplicaNumber(0) <<
" MVid=" << touch->GetReplicaNumber(1)
174 <<
edepositHAD <<
" ID=" << theTrack->GetTrackID() <<
" pID=" << theTrack->GetParentID()
175 <<
" E=" << theTrack->GetKineticEnergy() <<
" S=" << aStep->GetStepLength() <<
"\n " 176 << theTrack->GetDefinition()->GetParticleName() <<
" primaryID= " << primaryID
189 const G4Track*
track = aSpot->GetOriginatorTrack()->GetPrimaryTrack();
193 double edep = aSpot->GetEnergySpot()->GetEnergy();
199 G4StepPoint* fFakePreStepPoint = fFakeStep.GetPreStepPoint();
200 G4StepPoint* fFakePostStepPoint = fFakeStep.GetPostStepPoint();
201 fFakePreStepPoint->SetPosition(aSpot->GetPosition());
202 fFakePostStepPoint->SetPosition(aSpot->GetPosition());
204 G4TouchableHandle fTouchableHandle = aSpot->GetTouchableHandle();
205 fFakePreStepPoint->SetTouchableHandle(fTouchableHandle);
206 fFakeStep.SetTotalEnergyDeposit(edep);
223 posGlobal = aSpot->GetEnergySpot()->GetPosition();
252 edm::LogVerbatim(
"CaloSim") <<
"CaloSD : Initialize called for " << GetName();
284 theHC->PrintAllHits();
288 if (
slave.get()->name() == hname) {
289 cc =
slave.get()->hits();
291 slave.get()->Clean();
295 return touch->GetHistory()->GetTopTransform().TransformPoint(global);
299 return touch->GetHistory()->GetTopTransform().Inverse().TransformPoint(local);
310 posGlobal = aStep->GetPreStepPoint()->GetPosition();
321 std::map<CaloHitID, CaloG4Hit*>::const_iterator it =
hitMap.find(
currentID);
328 int maxhit =
theHC->entries() - 1;
330 for (
int j = maxhit; j > minhit; --j) {
348 auto const theTrack = aStep->GetTrack();
354 << theTrack->GetDefinition()->GetParticleName()
355 <<
" E(GeV)= " << theTrack->GetKineticEnergy() /
GeV 356 <<
" parentID= " << theTrack->GetParentID() <<
"\n Ein= " <<
incidentEnergy 374 aHit->
setPosition(posGlobal.x(), posGlobal.y(), posGlobal.z());
382 etrack = theTrack->GetKineticEnergy();
398 if (trkh !=
nullptr) {
426 auto const preStepPoint = aStep->GetPreStepPoint();
431 edm::LogVerbatim(
"CaloSim") <<
"CaloSD::resetForNewPrimary for " << GetName()
432 <<
" ID= " << aStep->GetTrack()->GetTrackID() <<
" Ein= " << incidentEnergy /
GeV 440 double charge = aStep->GetPreStepPoint()->GetCharge();
441 double length = aStep->GetStepLength();
443 if (charge != 0. && length > 0.) {
444 double density = aStep->GetPreStepPoint()->GetMaterial()->GetDensity();
445 double dedx = aStep->GetTotalEnergyDeposit() / length;
446 double rkb = birk1 / density;
447 double c = birk2 * rkb * rkb;
450 weight = 1. / (1. + rkb * dedx + c * dedx * dedx);
452 edm::LogVerbatim(
"CaloSim") <<
"CaloSD::getAttenuation in " << aStep->GetPreStepPoint()->GetMaterial()->GetName()
453 <<
" Charge " << charge <<
" dE/dx " << dedx <<
" Birk Const " << rkb <<
", " << c
454 <<
" Weight = " << weight <<
" dE " << aStep->GetTotalEnergyDeposit();
464 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: Dispatched BeginOfEvent for " << GetName() <<
" !";
471 int id = (*trk)()->GetTrackID();
473 int lastTrackID = -1;
476 if (
id == lastTrackID) {
478 if (trksForThisEvent !=
nullptr) {
479 int it = (
int)(trksForThisEvent->size()) - 1;
485 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: get track " << it <<
" from Container of size " 486 << trksForThisEvent->size() <<
" with ID " << trkH->
trackID();
488 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: get track " << it <<
" from Container of size " 489 << trksForThisEvent->size() <<
" with no ID";
511 for (
int i = 0;
i <
theHC->entries(); ++
i) {
516 double x = (*theHC)[
i]->getEM();
519 x = (*theHC)[
i]->getHadr();
522 tt += (*theHC)[
i]->getTimeSlice();
523 ee += (*theHC)[
i]->getIncidentEnergy();
528 double norm = (count > 0) ? 1.0 / count : 0.0;
540 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: " << GetName() <<
" store " << count <<
" hits; " << wrong
541 <<
" track IDs not given properly and " <<
totalHits - count
542 <<
" hits not passing cuts\n EmeanEM= " << eEM <<
" ErmsEM= " << eEM2
543 <<
"\n EmeanHAD= " << eHAD <<
" ErmsHAD= " << eHAD2 <<
" TimeMean= " << tt
544 <<
" E0mean= " << ee <<
" Zglob= " << zglob <<
" Zloc= " << zloc <<
" ";
547 std::vector<std::unique_ptr<CaloG4Hit>>().
swap(
reusehit);
556 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: Clears hit vector for " << GetName()
557 <<
" and initialise slave: " <<
slave.get()->name();
559 slave.get()->Initialize();
584 primaryID = aTrack->GetTrackID();
586 edm::LogWarning(
"CaloSim") <<
"CaloSD: Problem with primaryID **** set by force to TkID **** " << primaryID;
593 auto const theTrack = aStep->GetTrack();
596 if (primaryID == 0) {
597 primaryID = theTrack->GetTrackID();
605 <<
" trackID= " << aStep->GetTrack()->GetTrackID() <<
" primaryID= " << primaryID;
662 <<
" by SimTrackManager Status " <<
ok;
670 << aHit->
getDepth() <<
" due to " << tkID <<
" in time " << time <<
" of energy " 680 primary = (*trk)()->GetTrackID();
689 if (primary > 0 && primary != primAncestor) {
690 primAncestor = primary;
694 if (
theHC->entries() > 0)
700 std::vector<CaloG4Hit*>* theCollection =
theHC->GetVector();
710 std::vector<CaloG4Hit*> hitvec;
712 hitvec.swap(*theCollection);
715 edm::LogVerbatim(
"CaloSim") <<
"CaloSD::cleanHitCollection: sort hits in buffer starting from " 717 for (
unsigned int i = 0;
i < hitvec.size(); ++
i)
721 for (
unsigned int i= cleanIndex;
i < hitvec.size(); ++
i) {
723 for (
unsigned int j =
i + 1; j < hitvec.size() &&
equal(hitvec[
i], hitvec[j]); ++j) {
726 (*hitvec[
i]).addEnergyDeposit(*hitvec[j]);
727 (*hitvec[j]).setEM(0.);
728 (*hitvec[j]).setHadr(0.);
735 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: cleanHitCollection merge the hits in buffer ";
736 for (
unsigned int i = 0;
i < hitvec.size(); ++
i)
740 hitvec.erase(std::stable_partition(hitvec.begin()+
cleanIndex,
741 hitvec.end(), [](
CaloG4Hit*
p) {
return p!=
nullptr;}),
744 edm::LogVerbatim(
"CaloSim") <<
"CaloSD::cleanHitCollection: remove the merged hits in buffer," 745 <<
" new size = " << hitvec.size();
746 for (
unsigned int i = 0;
i < hitvec.size(); ++
i)
749 hitvec.swap(*theCollection);
755 <<
" Size of reusehit= " <<
reusehit.size()
756 <<
"\n starting hit selection from index = " <<
cleanIndex;
760 for (
unsigned int i =
cleanIndex;
i < theCollection->size(); ++
i) {
776 reusehit.emplace_back((*theCollection)[i]);
777 (*theCollection)[
i] =
nullptr;
784 <<
" Number of added hit = " << addhit;
789 for (
int ii = addhit - 1;
ii >= 0; --
ii) {
797 theCollection->erase(std::stable_partition(theCollection->begin()+
cleanIndex,
798 theCollection->end(), [](
CaloG4Hit*
p) {
return p!=
nullptr;}),
799 theCollection->end());
801 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: hit collection after selection, size = " <<
theHC->entries();
802 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
G4ThreadLocal G4Allocator< CaloG4Hit > * fpCaloG4HitAllocator
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)
bool equal(const T &first, const T &second)
virtual void initEvent(const BeginOfEvent *)
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
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
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
std::map< CaloHitID, CaloG4Hit * > hitMap
const math::XYZVectorD & momentum() const
void EndOfEvent(G4HCofThisEvent *eventHC) override
CSCCFEBTimeSlice const *const timeSlice(T const &data, int nCFEB, int nSample)
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
std::vector< std::unique_ptr< CaloG4Hit > > reusehit
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