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>
23 G4VSensitiveDetector(name), _intHitCollection(NULL), _timeBins(0), _intHitClass(
"GGSIntHit"), _partHitClass(
24 "GGSPartHit"), _posHitClass(
"GGSPosHit"), _storePartHits(false), _storePosHits(false) {
25 collectionName.insert(name);
28 auto params = name.substr(name.find_first_of(
'.') + 1);
29 auto secondPointPos = params.find_first_of(
'.');
30 if (secondPointPos != std::string::npos) {
32 params = params.substr(secondPointPos + 1);
33 if (params.size() > 0) {
35 std::string intHitClassName, partHitClassName, posHitClassName;
36 auto start = params.find_first_of(
'[');
37 auto end = params.find_first_of(
']');
38 if (start < std::string::npos && end != std::string::npos) {
39 intHitClassName = params.substr(start + 1, end - start - 1);
42 throw std::runtime_error(
43 std::string(
"[GGSIntHitSD::GGSIntHitSD] Missing definition of custom integrated hit class in \"") + params
47 start = params.find_first_of(
'[', end + 1);
48 end = params.find_first_of(
']', start + 1);
49 if (start != std::string::npos && end != std::string::npos) {
50 partHitClassName = params.substr(start + 1, end - start - 1);
53 throw std::runtime_error(
54 std::string(
"[GGSIntHitSD::GGSIntHitSD] Missing definition of custom particle hit class in \"") + params
58 start = params.find_first_of(
'[', end + 1);
59 end = params.find_first_of(
']', start + 1);
60 if (start != std::string::npos && end != std::string::npos) {
61 posHitClassName = params.substr(start + 1, end - start - 1);
64 throw std::runtime_error(
65 std::string(
"[GGSIntHitSD::GGSIntHitSD] Missing definition of custom position hit class in \"") + params
69 if (intHitClassName.size() > 0) {
71 if (std::find(buildersList.begin(), buildersList.end(), intHitClassName) == buildersList.end()) {
72 throw std::runtime_error(
73 std::string(
"[GGSIntHitSD::GGSIntHitSD] Integrated hit class \"") + intHitClassName +
"\" not found.");
75 _intHitClass = intHitClassName;
77 if (partHitClassName.size() > 0) {
79 if (std::find(buildersList.begin(), buildersList.end(), partHitClassName) == buildersList.end()) {
80 throw std::runtime_error(
81 std::string(
"[GGSIntHitSD::GGSIntHitSD] Particle hit class \"") + partHitClassName +
"\" not found.");
83 _partHitClass = partHitClassName;
85 if (posHitClassName.size() > 0) {
87 if (std::find(buildersList.begin(), buildersList.end(), posHitClassName) == buildersList.end()) {
88 throw std::runtime_error(
89 std::string(
"[GGSIntHitSD::GGSIntHitSD] Position hit class \"") + posHitClassName +
"\" not found.");
91 _posHitClass = posHitClassName;
121 if (aStep->GetTotalEnergyDeposit() == 0. && !_storePartHits)
124 G4TouchableHandle touchable = aStep->GetPreStepPoint()->GetTouchableHandle();
125 G4ThreeVector volPos = touchable->GetTranslation();
126 G4VPhysicalVolume *physVol = touchable->GetVolume();
136 int historyDepth = touchable->GetHistoryDepth();
140 static boost::unordered_map<G4VPhysicalVolume*, int> multMap;
142 for (
int iDepth = 0; iDepth < historyDepth; iDepth++) {
143 touchableID += totMult * touchable->GetCopyNumber(iDepth);
145 if (iDepth != historyDepth - 1) {
147 if (!(touchable->GetVolume(iDepth)->IsReplicated())) {
149 boost::unordered_map<G4VPhysicalVolume*, int>::iterator storedMult = multMap.find(touchable->GetVolume(iDepth));
150 if (storedMult == multMap.end()) {
152 G4LogicalVolume *currLogVol = touchable->GetVolume(iDepth)->GetLogicalVolume();
153 G4LogicalVolume *motherLogVol = touchable->GetVolume(iDepth)->GetMotherLogical();
154 int nDaughters = motherLogVol->GetNoDaughters();
155 for (
int iDaughter = 0; iDaughter < nDaughters; iDaughter++) {
156 if (motherLogVol->GetDaughter(iDaughter)->GetLogicalVolume() == currLogVol)
160 multMap[touchable->GetVolume(iDepth)] = currVolMult;
164 currVolMult = storedMult->second;
169 currVolMult = touchable->GetVolume(iDepth)->GetMultiplicity();
171 totMult *= currVolMult;
178 bool intFound =
false;
180 for (
int iHit = 0; iHit < _intHitCollection->entries(); iHit++) {
181 intHit = (*(_intHitCollection))[iHit];
191 throw std::runtime_error(
192 std::string(
"[GGSIntHitSD::ProcessHits] Can't create integrated hit of class ").append(_intHitClass));
196 intHit->
SetID(touchableID);
201 _intHitCollection->insert(intHit);
206 if (_storePartHits) {
210 bool partFound =
false;
212 for (
int iHit = 0; iHit < partHitCollection->entries(); iHit++) {
213 partHit = (*(partHitCollection))[iHit];
214 if ((*partHitCollection)[iHit]->GetTrackID() == aStep->GetTrack()->GetTrackID()) {
223 throw std::runtime_error(
224 std::string(
"[GGSIntHitSD::ProcessHits] Can't create particle hit of class ").append(_partHitClass));
230 partHitCollection->insert(partHit);
239 throw std::runtime_error(
240 std::string(
"[GGSIntHitSD::ProcessHits] Can't create position hit of class ").append(_posHitClass));
255 G4int IHID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]);
256 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.
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 Particle Hit.
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.
GGSPosHitsCollection * GetPosHits()
Getter of container of position hits.
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.