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"
22 : G4VSensitiveDetector(name), _intHitCollection(NULL), _timeBins(0), _intHitClass(
"GGSIntHit"),
23 _partHitClass(
"GGSPartHit"), _posHitClass(
"GGSPosHit"), _storePartHits(false), _storePosHits(false),
24 _idComputer(nullptr), _intHitThreshold{0.}, _partHitThreshold{0.}, _posHitThreshold{0.}, _currPartHit{
nullptr} {
26 collectionName.insert(name);
29 auto params = name.substr(name.find_first_of(
'.') + 1);
30 auto secondPointPos = params.find_first_of(
'.');
31 if (secondPointPos != std::string::npos) {
33 params = params.substr(secondPointPos + 1);
34 if (params.size() > 0) {
36 std::string intHitClassName, partHitClassName, posHitClassName;
37 auto start = params.find_first_of(
'[');
38 auto end = params.find_first_of(
']');
39 if (start < std::string::npos && end != std::string::npos) {
40 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);
52 throw std::runtime_error(
53 std::string(
"[GGSIntHitSD::GGSIntHitSD] Missing definition of custom particle hit class in \"") + params +
57 start = params.find_first_of(
'[', end + 1);
58 end = params.find_first_of(
']', start + 1);
59 if (start != std::string::npos && end != std::string::npos) {
60 posHitClassName = params.substr(start + 1, end - start - 1);
62 throw std::runtime_error(
63 std::string(
"[GGSIntHitSD::GGSIntHitSD] Missing definition of custom position hit class in \"") + params +
67 if (intHitClassName.size() > 0) {
69 if (std::find(buildersList.begin(), buildersList.end(), intHitClassName) == buildersList.end()) {
70 throw std::runtime_error(std::string(
"[GGSIntHitSD::GGSIntHitSD] Integrated hit class \"") + intHitClassName +
73 _intHitClass = intHitClassName;
75 if (partHitClassName.size() > 0) {
77 if (std::find(buildersList.begin(), buildersList.end(), partHitClassName) == buildersList.end()) {
78 throw std::runtime_error(std::string(
"[GGSIntHitSD::GGSIntHitSD] Particle hit class \"") + partHitClassName +
81 _partHitClass = partHitClassName;
83 if (posHitClassName.size() > 0) {
85 if (std::find(buildersList.begin(), buildersList.end(), posHitClassName) == buildersList.end()) {
86 throw std::runtime_error(std::string(
"[GGSIntHitSD::GGSIntHitSD] Position hit class \"") + posHitClassName +
89 _posHitClass = posHitClassName;
95 SetTouchableIDComputer(
"GGSUniqueTouchableIDComputer");
103 throw std::runtime_error(
"[GGSIntHitSD::GGSIntHitSD] Touchable ID computer class " + tidcClassName +
" not found");
116 static const std::string routineName(
"GGSIntHitSD::ProcessHits");
122 if (aStep->GetTotalEnergyDeposit() == 0. && !_storePartHits)
125 int touchableID = _idComputer->ComputeTouchableID(aStep);
126 G4TouchableHandle touchable = aStep->GetPreStepPoint()->GetTouchableHandle();
127 G4ThreeVector volPos = touchable->GetTranslation();
128 G4VPhysicalVolume *physVol = touchable->GetVolume();
132 bool intFound =
false;
134 auto nIntHits = _intHitCollection->entries();
135 for (
int iHit = nIntHits - 1; iHit >= 0; iHit--) {
136 intHit = (*(_intHitCollection))[iHit];
146 throw std::runtime_error(
147 std::string(
"[GGSIntHitSD::ProcessHits] Can't create integrated hit of class ").append(_intHitClass));
151 intHit->
SetID(touchableID);
158 _intHitCollection->insert(intHit);
163 if (_storePartHits) {
168 if (aStep->IsFirstStepInVolume() && aStep->GetPreStepPoint()->GetKineticEnergy() != 0) {
169 if (_currPartHit !=
nullptr) {
171 throw std::runtime_error(
"GGSIntHitSD::ProcessHit: existing particle hit on first step in sensitive volume");
175 throw std::runtime_error(
176 std::string(
"[GGSIntHitSD::ProcessHits] Can't create particle hit of class ").append(_partHitClass));
182 if (_currPartHit !=
nullptr) {
188 if ((aStep->GetPostStepPoint()->GetStepStatus() == G4StepStatus::fGeomBoundary &&
189 aStep->GetTrack()->GetTrackStatus() != G4TrackStatus::fStopButAlive) ||
190 aStep->GetTrack()->GetTrackStatus() == G4TrackStatus::fStopAndKill ||
191 aStep->GetTrack()->GetTrackStatus() == G4TrackStatus::fKillTrackAndSecondaries) {
200 _currPartHit =
nullptr;
203 if (_storePosHits && aStep->GetTotalEnergyDeposit() > _posHitThreshold) {
207 throw std::runtime_error(
208 std::string(
"[GGSIntHitSD::ProcessHits] Can't create position hit of class ").append(_posHitClass));
213 partHit->GetPosHits()->insert(posHit);
218 std::vector<std::string> statusNames{
219 "fAlive",
"fStopButAlive",
"fStopAndKill",
"fKillTrackAndSecondaries",
"fSuspend",
"fPostponeToNextEvent"};
220 GGSCOUT(WARNING) <<
"No particle hit has been created for particle:\n";
222 << aStep->GetTrack()->GetDynamicParticle()->GetParticleDefinition()->GetParticleName() <<
"\n";
223 GGSCCOUT(WARNING) <<
" - creator process: " << aStep->GetTrack()->GetCreatorProcess()->GetProcessName() <<
"\n";
224 GGSCCOUT(WARNING) <<
" - trackID: " << aStep->GetTrack()->GetTrackID() <<
"\n";
225 GGSCCOUT(WARNING) <<
" - status: " << statusNames[
static_cast<int>(aStep->GetTrack()->GetTrackStatus())] <<
"\n";
226 GGSCCOUT(WARNING) <<
" - eDep: " << aStep->GetTotalEnergyDeposit() / CLHEP::MeV <<
" MeV \n";
227 GGSCCOUT(WARNING) <<
" - kin. energy (pre) : " << aStep->GetPreStepPoint()->GetKineticEnergy() / CLHEP::MeV
229 GGSCCOUT(WARNING) <<
" - kin. energy (post): " << aStep->GetPostStepPoint()->GetKineticEnergy() / CLHEP::MeV
231 GGSCCOUT(WARNING) <<
" - process (pre) : "
232 << (aStep->GetPreStepPoint()->GetProcessDefinedStep()
233 ? aStep->GetPreStepPoint()->GetProcessDefinedStep()->GetProcessName()
236 GGSCCOUT(WARNING) <<
" - process (post): "
237 << (aStep->GetPostStepPoint()->GetProcessDefinedStep()
238 ? aStep->GetPostStepPoint()->GetProcessDefinedStep()->GetProcessName()
249 G4int IHID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]);
250 hitCollection->AddHitsCollection(IHID, _intHitCollection);
#define GGSCCOUT(level)
Smart log utility which prints no header at the beginning of the line.
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 UserInit(G4Step *aStep)
User initialization of hit global properties.
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.
void SetTouchableIDComputer(const std::string &tidcClassName)
Sets the touchable ID computer class.