4 #include "montecarlo/scoring/GGSIntHitSDMessenger.h"
5 #include "montecarlo/scoring/GGSTouchableIDComputer.h"
9 #include "G4PVReplica.hh"
10 #include "G4SDManager.hh"
12 #include "G4TouchableHandle.hh"
13 #include "G4TransportationManager.hh"
14 #include "G4VProcess.hh"
17 #include <boost/unordered_map.hpp>
24 : G4VSensitiveDetector(name), _intHitCollection(NULL), _timeBins(0), _intHitClass(
"GGSIntHit"),
25 _partHitClass(
"GGSPartHit"), _posHitClass(
"GGSPosHit"), _storePartHits(false), _storePosHits(false),
26 _idComputer(nullptr), _intHitThreshold{0.}, _partHitThreshold{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);
44 throw std::runtime_error(
45 std::string(
"[GGSIntHitSD::GGSIntHitSD] Missing definition of custom integrated hit class in \"") + params +
49 start = params.find_first_of(
'[', end + 1);
50 end = params.find_first_of(
']', start + 1);
51 if (start != std::string::npos && end != std::string::npos) {
52 partHitClassName = params.substr(start + 1, end - start - 1);
54 throw std::runtime_error(
55 std::string(
"[GGSIntHitSD::GGSIntHitSD] Missing definition of custom particle hit class in \"") + params +
59 start = params.find_first_of(
'[', end + 1);
60 end = params.find_first_of(
']', start + 1);
61 if (start != std::string::npos && end != std::string::npos) {
62 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(std::string(
"[GGSIntHitSD::GGSIntHitSD] Integrated hit class \"") + intHitClassName +
75 _intHitClass = intHitClassName;
77 if (partHitClassName.size() > 0) {
79 if (std::find(buildersList.begin(), buildersList.end(), partHitClassName) == buildersList.end()) {
80 throw std::runtime_error(std::string(
"[GGSIntHitSD::GGSIntHitSD] Particle hit class \"") + partHitClassName +
83 _partHitClass = partHitClassName;
85 if (posHitClassName.size() > 0) {
87 if (std::find(buildersList.begin(), buildersList.end(), posHitClassName) == buildersList.end()) {
88 throw std::runtime_error(std::string(
"[GGSIntHitSD::GGSIntHitSD] Position hit class \"") + posHitClassName +
91 _posHitClass = posHitClassName;
97 SetTouchableIDComputer(
"GGSUniqueTouchableIDComputer");
105 throw std::runtime_error(
"[GGSIntHitSD::GGSIntHitSD] Touchable ID computer class " + tidcClassName +
" not found");
118 static const std::string routineName(
"GGSIntHitSD::ProcessHits");
124 if (aStep->GetTotalEnergyDeposit() == 0. && !_storePartHits)
127 int touchableID = _idComputer->ComputeTouchableID(aStep);
128 G4TouchableHandle touchable = aStep->GetPreStepPoint()->GetTouchableHandle();
129 G4ThreeVector volPos = touchable->GetTranslation();
130 G4VPhysicalVolume *physVol = touchable->GetVolume();
134 bool intFound =
false;
136 auto nIntHits = _intHitCollection->entries();
137 for (
int iHit = nIntHits - 1; iHit >= 0; iHit--) {
138 intHit = (*(_intHitCollection))[iHit];
148 throw std::runtime_error(
149 std::string(
"[GGSIntHitSD::ProcessHits] Can't create integrated hit of class ").append(_intHitClass));
153 intHit->
SetID(touchableID);
160 _intHitCollection->insert(intHit);
165 if (_storePartHits) {
170 if (aStep->IsFirstStepInVolume() && aStep->GetPreStepPoint()->GetKineticEnergy() != 0) {
171 if (_currPartHit !=
nullptr) {
173 throw std::runtime_error(
"GGSIntHitSD::ProcessHit: existing particle hit on first step in sensitive volume");
177 throw std::runtime_error(
178 std::string(
"[GGSIntHitSD::ProcessHits] Can't create particle hit of class ").append(_partHitClass));
184 if (_currPartHit !=
nullptr) {
190 if ((aStep->GetPostStepPoint()->GetStepStatus() == G4StepStatus::fGeomBoundary &&
191 aStep->GetTrack()->GetTrackStatus() != G4TrackStatus::fStopButAlive) ||
192 aStep->GetTrack()->GetTrackStatus() == G4TrackStatus::fStopAndKill ||
193 aStep->GetTrack()->GetTrackStatus() == G4TrackStatus::fKillTrackAndSecondaries) {
202 _currPartHit =
nullptr;
205 if (_storePosHits && aStep->GetTotalEnergyDeposit() > _posHitThreshold) {
209 throw std::runtime_error(
210 std::string(
"[GGSIntHitSD::ProcessHits] Can't create position hit of class ").append(_posHitClass));
215 partHit->GetPosHits()->insert(posHit);
220 std::vector<std::string> statusNames{
221 "fAlive",
"fStopButAlive",
"fStopAndKill",
"fKillTrackAndSecondaries",
"fSuspend",
"fPostponeToNextEvent"};
222 COUT(WARNING) <<
"No particle hit has been created for particle:\n";
223 CCOUT(WARNING) <<
" - type: "
224 << aStep->GetTrack()->GetDynamicParticle()->GetParticleDefinition()->GetParticleName() <<
"\n";
225 CCOUT(WARNING) <<
" - creator process: " << aStep->GetTrack()->GetCreatorProcess()->GetProcessName() <<
"\n";
226 CCOUT(WARNING) <<
" - trackID: " << aStep->GetTrack()->GetTrackID() <<
"\n";
227 CCOUT(WARNING) <<
" - status: " << statusNames[
static_cast<int>(aStep->GetTrack()->GetTrackStatus())] <<
"\n";
228 CCOUT(WARNING) <<
" - eDep: " << aStep->GetTotalEnergyDeposit() / CLHEP::MeV <<
" MeV \n";
229 CCOUT(WARNING) <<
" - kin. energy (pre) : " << aStep->GetPreStepPoint()->GetKineticEnergy() / CLHEP::MeV
231 CCOUT(WARNING) <<
" - kin. energy (post): " << aStep->GetPostStepPoint()->GetKineticEnergy() / CLHEP::MeV
233 CCOUT(WARNING) <<
" - process (pre) : "
234 << (aStep->GetPreStepPoint()->GetProcessDefinedStep()
235 ? aStep->GetPreStepPoint()->GetProcessDefinedStep()->GetProcessName()
238 CCOUT(WARNING) <<
" - process (post): "
239 << (aStep->GetPostStepPoint()->GetProcessDefinedStep()
240 ? aStep->GetPostStepPoint()->GetProcessDefinedStep()->GetProcessName()
251 G4int IHID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]);
252 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.
#define COUT(level)
Smart log macro. It writes on stdout only if the specified verbosity level is lesser than the maximum...
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 UserInit(G4Step *aStep)
User initialization of hit global properties.
virtual void SetStep(const G4Step &step)
G4int GetID()
Getter for volume ID.
#define CCOUT(level)
Smart log utility which prints no header at the beginning of the line.
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.
void SetTouchableIDComputer(const std::string &tidcClassName)
Sets the touchable ID computer class.