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") * CLHEP::cm;
62 correctT = beamZ / CLHEP::c_light / CLHEP::nanosecond;
65 SetVerboseLevel(verbn);
67 for (
unsigned int k = 0;
k < hcn.size(); ++
k) {
69 if (
k < eminHits.size())
71 if (
k < eminHitX.size())
73 if (
k < tmaxHits.size())
75 if (
k < useResMap.size() && useResMap[
k] > 0) {
97 <<
" before saving the hit\n Correct TOF globally by " <<
correctT
99 <<
" ns and if energy is above " <<
eminHit /
CLHEP::MeV <<
" MeV (for depth 0) or "
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) {
167 G4TouchableHistory* touch = (G4TouchableHistory*)(theTrack->GetTouchable());
168 edm::LogVerbatim(
"CaloSim") <<
"CaloSD::" << GetName() <<
" PV:" << touch->GetVolume(0)->GetName()
169 <<
" PVid=" << touch->GetReplicaNumber(0) <<
" MVid=" << touch->GetReplicaNumber(1)
171 <<
edepositHAD <<
" ID=" << theTrack->GetTrackID() <<
" pID=" << theTrack->GetParentID()
172 <<
" E=" << theTrack->GetKineticEnergy() <<
" S=" << aStep->GetStepLength() <<
"\n "
173 << theTrack->GetDefinition()->GetParticleName() <<
" primaryID= " << primaryID
186 const G4Track*
track = aSpot->GetOriginatorTrack()->GetPrimaryTrack();
190 double edep = aSpot->GetEnergySpot()->GetEnergy();
196 G4StepPoint* fFakePreStepPoint = fFakeStep.GetPreStepPoint();
197 G4StepPoint* fFakePostStepPoint = fFakeStep.GetPostStepPoint();
198 fFakePreStepPoint->SetPosition(aSpot->GetPosition());
199 fFakePostStepPoint->SetPosition(aSpot->GetPosition());
201 G4TouchableHandle fTouchableHandle = aSpot->GetTouchableHandle();
202 fFakePreStepPoint->SetTouchableHandle(fTouchableHandle);
203 fFakeStep.SetTotalEnergyDeposit(edep);
220 posGlobal = aSpot->GetEnergySpot()->GetPosition();
249 edm::LogVerbatim(
"CaloSim") <<
"CaloSD : Initialize called for " << GetName();
281 theHC->PrintAllHits();
285 if (
slave.get()->name() == hname) {
288 slave.get()->Clean();
292 return touch->GetHistory()->GetTopTransform().TransformPoint(global);
296 return touch->GetHistory()->GetTopTransform().Inverse().TransformPoint(
local);
307 posGlobal = aStep->GetPreStepPoint()->GetPosition();
318 std::map<CaloHitID, CaloG4Hit*>::const_iterator it =
hitMap.find(
currentID);
326 int maxhit =
nhits - 1;
328 for (
int j = maxhit;
j > minhit; --
j) {
351 << theTrack->GetDefinition()->GetParticleName()
352 <<
" E(GeV)= " << theTrack->GetKineticEnergy() /
CLHEP::GeV
353 <<
" parentID= " << theTrack->GetParentID() <<
"\n Ein= " <<
incidentEnergy
379 etrack = theTrack->GetKineticEnergy();
395 if (trkh !=
nullptr) {
423 auto const preStepPoint = aStep->GetPreStepPoint();
428 edm::LogVerbatim(
"CaloSim") <<
"CaloSD::resetForNewPrimary for " << GetName()
437 double charge = aStep->GetPreStepPoint()->GetCharge();
438 double length = aStep->GetStepLength();
440 if (
charge != 0. && length > 0.) {
441 double density = aStep->GetPreStepPoint()->GetMaterial()->GetDensity();
442 double dedx = aStep->GetTotalEnergyDeposit() / length;
444 double c = birk2 * rkb * rkb;
447 weight = 1. / (1. + rkb * dedx +
c * dedx * dedx);
449 edm::LogVerbatim(
"CaloSim") <<
"CaloSD::getAttenuation in " << aStep->GetPreStepPoint()->GetMaterial()->GetName()
450 <<
" Charge " <<
charge <<
" dE/dx " << dedx <<
" Birk Const " << rkb <<
", " <<
c
451 <<
" Weight = " <<
weight <<
" dE " << aStep->GetTotalEnergyDeposit();
461 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: Dispatched BeginOfEvent for " << GetName() <<
" !";
468 int id = (*trk)()->GetTrackID();
470 int lastTrackID = -1;
473 if (
id == lastTrackID) {
475 if (trksForThisEvent !=
nullptr) {
476 int it = (
int)(trksForThisEvent->size()) - 1;
482 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: get track " << it <<
" from Container of size "
483 << trksForThisEvent->size() <<
" with ID " << trkH->
trackID();
485 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: get track " << it <<
" from Container of size "
486 << trksForThisEvent->size() <<
" with no ID";
507 int hc_entries =
theHC->entries();
508 for (
int i = 0;
i < hc_entries; ++
i) {
513 double x = (*theHC)[
i]->getEM();
516 x = (*theHC)[
i]->getHadr();
519 tt += (*theHC)[
i]->getTimeSlice();
520 ee += (*theHC)[
i]->getIncidentEnergy();
525 double norm = (
count > 0) ? 1.0 /
count : 0.0;
540 <<
" hits not passing cuts\n EmeanEM= " << eEM <<
" ErmsEM= " << eEM2
541 <<
"\n EmeanHAD= " << eHAD <<
" ErmsHAD= " << eHAD2 <<
" TimeMean= " <<
tt
542 <<
" E0mean= " << ee <<
" Zglob= " << zglob <<
" Zloc= " << zloc <<
" ";
545 std::vector<std::unique_ptr<CaloG4Hit>>().
swap(
reusehit);
555 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: Clears hit vector for " << GetName()
556 <<
" and initialise slave: " <<
slave.get()->name();
558 slave.get()->Initialize();
581 <<
":" << aTrack->GetTrackID() <<
":" << primaryID;
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();
601 << theTrack->GetTrackID() <<
":" << primaryID;
609 <<
" trackID= " << aStep->GetTrack()->GetTrackID() <<
" primaryID= " << primaryID;
618 if (
hit->getDepth() > 0)
621 edm::LogVerbatim(
"CaloSim") <<
"CaloSD::filterHit(..) Depth " <<
hit->getDepth() <<
" Emin = " << emin <<
" ("
668 <<
" by SimTrackManager Status " <<
ok;
673 slave.get()->processHits(
677 << aHit->
getDepth() <<
" due to " << tkID <<
" in time " <<
time <<
" of energy "
688 primary = (*trk)()->GetTrackID();
702 if (
theHC->entries() > 0)
708 std::vector<CaloG4Hit*>* theCollection =
theHC->GetVector();
718 std::vector<CaloG4Hit*> hitvec;
720 hitvec.swap(*theCollection);
723 edm::LogVerbatim(
"CaloSim") <<
"CaloSD::cleanHitCollection: sort hits in buffer starting from "
725 for (
unsigned int i = 0;
i < hitvec.size(); ++
i)
731 for (
unsigned int j =
i + 1;
j < hitvec.size() &&
equal(hitvec[
i], hitvec[
j]); ++
j) {
734 (*hitvec[
i]).addEnergyDeposit(*hitvec[
j]);
735 (*hitvec[
j]).setEM(0.);
736 (*hitvec[
j]).setHadr(0.);
743 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: cleanHitCollection merge the hits in buffer ";
744 for (
unsigned int i = 0;
i < hitvec.size(); ++
i)
749 std::stable_partition(hitvec.begin() +
cleanIndex, hitvec.end(), [](
CaloG4Hit*
p) {
return p !=
nullptr; }),
752 edm::LogVerbatim(
"CaloSim") <<
"CaloSD::cleanHitCollection: remove the merged hits in buffer,"
753 <<
" new size = " << hitvec.size();
754 for (
unsigned int i = 0;
i < hitvec.size(); ++
i)
757 hitvec.swap(*theCollection);
763 <<
" Size of reusehit= " <<
reusehit.size()
764 <<
"\n starting hit selection from index = " <<
cleanIndex;
768 for (
unsigned int i =
cleanIndex;
i < theCollection->size(); ++
i) {
784 reusehit.emplace_back((*theCollection)[
i]);
785 (*theCollection)[
i] =
nullptr;
792 <<
" Number of added hit = " << addhit;
797 for (
int ii = addhit - 1;
ii >= 0; --
ii) {
805 theCollection->erase(
806 std::stable_partition(
807 theCollection->begin() +
cleanIndex, theCollection->end(), [](
CaloG4Hit*
p) {
return p !=
nullptr; }),
808 theCollection->end());
810 edm::LogVerbatim(
"CaloSim") <<
"CaloSD: hit collection after selection, size = " <<
theHC->entries();
811 theHC->PrintAllHits();