2 #include "montecarlo/scoring/GGSIntHitSDMessenger.h"
8 #include "G4TouchableHandle.hh"
9 #include "G4PVReplica.hh"
10 #include "G4SDManager.hh"
12 #include "G4TransportationManager.hh"
14 #include <boost/unordered_map.hpp>
25 G4VSensitiveDetector(name), _intHitCollection(NULL), _timeBins(0), _intHitClass(
"GGSIntHit"), _partHitClass(
26 "GGSPartHit"), _posHitClass(
"GGSPosHit"), _storePartHits(false), _storePosHits(false), _intHitThreshold { 0. }, _partHitThreshold {
27 0. }, _posHitThreshold { 0. }, _currPartHit {
nullptr } {
28 collectionName.insert(name);
31 auto params = name.substr(name.find_first_of(
'.') + 1);
32 auto secondPointPos = params.find_first_of(
'.');
33 if (secondPointPos != std::string::npos) {
35 params = params.substr(secondPointPos + 1);
36 if (params.size() > 0) {
38 std::string intHitClassName, partHitClassName, posHitClassName;
39 auto start = params.find_first_of(
'[');
40 auto end = params.find_first_of(
']');
41 if (start < std::string::npos && end != std::string::npos) {
42 intHitClassName = params.substr(start + 1, end - start - 1);
45 throw std::runtime_error(
46 std::string(
"[GGSIntHitSD::GGSIntHitSD] Missing definition of custom integrated hit class in \"") + params
50 start = params.find_first_of(
'[', end + 1);
51 end = params.find_first_of(
']', start + 1);
52 if (start != std::string::npos && end != std::string::npos) {
53 partHitClassName = params.substr(start + 1, end - start - 1);
56 throw std::runtime_error(
57 std::string(
"[GGSIntHitSD::GGSIntHitSD] Missing definition of custom particle hit class in \"") + params
61 start = params.find_first_of(
'[', end + 1);
62 end = params.find_first_of(
']', start + 1);
63 if (start != std::string::npos && end != std::string::npos) {
64 posHitClassName = params.substr(start + 1, end - start - 1);
67 throw std::runtime_error(
68 std::string(
"[GGSIntHitSD::GGSIntHitSD] Missing definition of custom position hit class in \"") + params
72 if (intHitClassName.size() > 0) {
74 if (std::find(buildersList.begin(), buildersList.end(), intHitClassName) == buildersList.end()) {
75 throw std::runtime_error(
76 std::string(
"[GGSIntHitSD::GGSIntHitSD] Integrated hit class \"") + intHitClassName +
"\" not found.");
78 _intHitClass = intHitClassName;
80 if (partHitClassName.size() > 0) {
82 if (std::find(buildersList.begin(), buildersList.end(), partHitClassName) == buildersList.end()) {
83 throw std::runtime_error(
84 std::string(
"[GGSIntHitSD::GGSIntHitSD] Particle hit class \"") + partHitClassName +
"\" not found.");
86 _partHitClass = partHitClassName;
88 if (posHitClassName.size() > 0) {
90 if (std::find(buildersList.begin(), buildersList.end(), posHitClassName) == buildersList.end()) {
91 throw std::runtime_error(
92 std::string(
"[GGSIntHitSD::GGSIntHitSD] Position hit class \"") + posHitClassName +
"\" not found.");
94 _posHitClass = posHitClassName;
124 if (aStep->GetTotalEnergyDeposit() == 0. && !_storePartHits)
127 G4TouchableHandle touchable = aStep->GetPreStepPoint()->GetTouchableHandle();
128 G4ThreeVector volPos = touchable->GetTranslation();
129 G4VPhysicalVolume *physVol = touchable->GetVolume();
139 int historyDepth = touchable->GetHistoryDepth();
143 static boost::unordered_map<G4VPhysicalVolume*, int> multMap;
145 for (
int iDepth = 0; iDepth < historyDepth; iDepth++) {
146 touchableID += totMult * touchable->GetCopyNumber(iDepth);
148 if (iDepth != historyDepth - 1) {
150 if (!(touchable->GetVolume(iDepth)->IsReplicated())) {
152 boost::unordered_map<G4VPhysicalVolume*, int>::iterator storedMult = multMap.find(touchable->GetVolume(iDepth));
153 if (storedMult == multMap.end()) {
155 G4LogicalVolume *currLogVol = touchable->GetVolume(iDepth)->GetLogicalVolume();
156 G4LogicalVolume *motherLogVol = touchable->GetVolume(iDepth)->GetMotherLogical();
157 int nDaughters = motherLogVol->GetNoDaughters();
158 for (
int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
159 if (motherLogVol->GetDaughter(iDaughter)->GetLogicalVolume() == currLogVol)
163 multMap[touchable->GetVolume(iDepth)] = currVolMult;
167 currVolMult = storedMult->second;
174 G4double width, offset;
176 touchable->GetVolume(iDepth)->GetReplicationData(axis, nReplicas, width, offset, consuming);
177 currVolMult = nReplicas;
179 totMult *= currVolMult;
186 bool intFound =
false;
188 for (
int iHit = 0; iHit < _intHitCollection->entries(); iHit++) {
189 intHit = (*(_intHitCollection))[iHit];
199 throw std::runtime_error(
200 std::string(
"[GGSIntHitSD::ProcessHits] Can't create integrated hit of class ").append(_intHitClass));
204 intHit->
SetID(touchableID);
209 _intHitCollection->insert(intHit);
214 if (_storePartHits) {
219 if (aStep->IsFirstStepInVolume() && aStep->GetPreStepPoint()->GetKineticEnergy() != 0) {
220 if (_currPartHit !=
nullptr) {
222 throw std::runtime_error(
"GGSIntHitSD::ProcessHit: existing particle hit on first step in sensitive volume");
233 if ((aStep->GetPostStepPoint()->GetStepStatus() == G4StepStatus::fGeomBoundary
234 && aStep->GetTrack()->GetTrackStatus() != G4TrackStatus::fStopButAlive)
235 || aStep->GetTrack()->GetTrackStatus() == G4TrackStatus::fStopAndKill
236 || aStep->GetTrack()->GetTrackStatus() == G4TrackStatus::fKillTrackAndSecondaries) {
246 _currPartHit =
nullptr;
249 if (_storePosHits && aStep->GetTotalEnergyDeposit() > _posHitThreshold) {
253 throw std::runtime_error(
254 std::string(
"[GGSIntHitSD::ProcessHits] Can't create position hit of class ").append(_posHitClass));
257 auto *partHit = (_currPartHit ? _currPartHit : (*(intHit->
GetPartHits()))[intHit->
GetPartHits()->GetSize() - 1]);
258 partHit->GetPosHits()->insert(posHit);
270 G4int IHID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]);
271 hitCollection->AddHitsCollection(IHID, _intHitCollection);
virtual void AddStep(const G4Step &step)
Adds a step to the particle hit.
const G4ThreeVector & GetAbsTranslation()
Getter of absolute position of sensitive element.
Sensitive detector class for integrated hits.
virtual void AddStep(const G4Step &step)
Adds a step to the particle hit.
G4double GetEnergyDeposit() const
Energy deposit getter.
GGSPartHitsCollection * GetPartHits()
Getter of container of particle hits.
void EndOfEvent(G4HCofThisEvent *hitCollection)
Sets the hits collection, as required by specifications of mother class.
std::unique_ptr< T > CreateObject(const std::string &name, ConstructorArgs...arguments)
Create an object.
const std::vector< std::string > & GetListOfRegisteredBuilders()
Gets a vector containing the names of available registered builders.
void SetAbsTranslation(const G4ThreeVector &pos)
Set the position in global coordinates of the sensitive element.
#define RegisterSD(sdClassName)
Macro for registration of sensitive detector classes.
void SetPosHitsStorage(bool flag)
Turn on or off the storage of position hits.
const G4VPhysicalVolume * GetVolume()
Getter for volume.
Definition of GGS Position Hit.
virtual void SetStep(const G4Step &step)
G4int GetID()
Getter for volume ID.
void SetID(G4int id)
Setter for volume ID.
void SetPosHitsStorage(bool flag)
Turn on or off the storage of position hits.
GGSIntHitSD(G4String name)
Constructor.
void Initialize(G4HCofThisEvent *hitCollection)
Initializes the sensitive detector.
void SetVolume(const G4VPhysicalVolume *volume)
Setter for volume.
~GGSIntHitSD()
Destructor.
G4THitsCollection< GGSIntHit > GGSIntHitsCollection
Alias for G4 template hits collection for GGSIntHit.
Definition of GGS Integrated Hit.
static GGSFactory & GetInstance()
Getter method for singleton pointer.
G4bool ProcessHits(G4Step *aStep, G4TouchableHistory *ROHist)
The hit processing method.
The integrated hit SD messenger class.
void SetPartHitsStorage(bool flag)
Turn on or off the storage of particle hits.