GGS(GenericGEANT4Simulation)Software  2.6.3
 All Data Structures Namespaces Files Functions Variables Typedefs Macros
Public Member Functions
GGSIntHitSD Class Reference

Sensitive detector class for integrated hits. More...

#include <GGSIntHitSD.h>

Inheritance diagram for GGSIntHitSD:
Inheritance graph
[legend]
Collaboration diagram for GGSIntHitSD:
Collaboration graph
[legend]

Public Member Functions

 GGSIntHitSD (G4String name)
 Constructor. More...
 
 ~GGSIntHitSD ()
 Destructor.
 
void Initialize (G4HCofThisEvent *hitCollection)
 Initializes the sensitive detector. More...
 
G4bool ProcessHits (G4Step *aStep, G4TouchableHistory *ROHist)
 The hit processing method. More...
 
void EndOfEvent (G4HCofThisEvent *hitCollection)
 Sets the hits collection, as required by specifications of mother class. More...
 
void SetTimeBin (G4double time)
 Time bins setter. More...
 
const std::vector< G4double > & GetTimeBins ()
 Time bins getter. More...
 
void SetPartHitsStorage (bool store)
 Turn on or off the storage (i.e. persistency) of particle hits. More...
 
bool GetPartHitsStorage ()
 Return current status of particle hits storage (i.e. persistence). More...
 
void SetPosHitsStorage (bool store)
 Turn on or off the storage (i.e. persistence) of position hits. More...
 
bool GetPosHitsStorage ()
 Return current status of particle hits storage (i.e. persistence). More...
 
void SetIntHitThreshold (float minEnergy)
 Sets the minimum energy for integrated hits. More...
 
void SetPartHitThreshold (float minEnergy)
 Sets the minimum energy for particle hits. More...
 
void SetPosHitThreshold (float minEnergy)
 Sets the minimum energy for position hits. More...
 

Detailed Description

Sensitive detector class for integrated hits.

This sensitive detector takes care of summing up all energy releases inside the sensitive volume it manages, so that a single hit is produced for each single volume with non-zero energy release for each event.

Definition at line 28 of file GGSIntHitSD.h.

Constructor & Destructor Documentation

GGSIntHitSD::GGSIntHitSD ( G4String  name)

Constructor.

Parameters
nameThe sensitive detector's name.

Definition at line 24 of file GGSIntHitSD.cpp.

24  :
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);
29  _messenger = new GGSIntHitSDMessenger(this);
30 
31  auto params = name.substr(name.find_first_of('.') + 1); // Remove volume name
32  auto secondPointPos = params.find_first_of('.');
33  if (secondPointPos != std::string::npos) {
34  // Parameters have been specified so let's handle them
35  params = params.substr(secondPointPos + 1); // Remove GGSIntHitSD
36  if (params.size() > 0) {
37  // Retrieve hit classes
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);
43  }
44  else {
45  throw std::runtime_error(
46  std::string("[GGSIntHitSD::GGSIntHitSD] Missing definition of custom integrated hit class in \"") + params
47  + ("\""));
48  }
49 
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);
54  }
55  else {
56  throw std::runtime_error(
57  std::string("[GGSIntHitSD::GGSIntHitSD] Missing definition of custom particle hit class in \"") + params
58  + ("\""));
59  }
60 
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);
65  }
66  else {
67  throw std::runtime_error(
68  std::string("[GGSIntHitSD::GGSIntHitSD] Missing definition of custom position hit class in \"") + params
69  + ("\""));
70  }
71 
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.");
77  }
78  _intHitClass = intHitClassName;
79  }
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.");
85  }
86  _partHitClass = partHitClassName;
87  }
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.");
93  }
94  _posHitClass = posHitClassName;
95  }
96  }
97  }
98 }
const std::vector< std::string > & GetListOfRegisteredBuilders()
Gets a vector containing the names of available registered builders.
Definition: GGSFactory.h:118
static GGSFactory & GetInstance()
Getter method for singleton pointer.
Definition: GGSFactory.h:75
The integrated hit SD messenger class.

Member Function Documentation

void GGSIntHitSD::EndOfEvent ( G4HCofThisEvent *  hitCollection)

Sets the hits collection, as required by specifications of mother class.

Parameters
hitCollectionThe hits collection.

Definition at line 268 of file GGSIntHitSD.cpp.

268  {
269 
270  G4int IHID = G4SDManager::GetSDMpointer()->GetCollectionID(collectionName[0]);
271  hitCollection->AddHitsCollection(IHID, _intHitCollection);
272 
273 }
bool GGSIntHitSD::GetPartHitsStorage ( )
inline

Return current status of particle hits storage (i.e. persistence).

Returns
true if particle hits are going to be stored.

Definition at line 110 of file GGSIntHitSD.h.

110  {
111  return _storePartHits;
112  }
bool GGSIntHitSD::GetPosHitsStorage ( )
inline

Return current status of particle hits storage (i.e. persistence).

Returns
true if particle hits are going to be stored.

Definition at line 137 of file GGSIntHitSD.h.

137  {
138  return _storePosHits;
139  }
const std::vector<G4double>& GGSIntHitSD::GetTimeBins ( )
inline

Time bins getter.

First element is the end time of first bin (which always starts at t=0). Last element is the ending time of last bin but one, which corresponds to start time of last bin (last bin always ends at the end of event).

Returns
Vector of time bins.

Definition at line 83 of file GGSIntHitSD.h.

83  {
84  return _timeBins;
85  }
void GGSIntHitSD::Initialize ( G4HCofThisEvent *  hitCollection)

Initializes the sensitive detector.

Parameters
hitCollectionUnused (needed by the interface).

Definition at line 108 of file GGSIntHitSD.cpp.

108  {
109 
110  // The hits collection is added to G4HCofThisEvent in EndOfEvent.
111  // It is automatically deleted at the end of the event so it must be recreated every time.
112  // However, G4Allocator should provide fast memory allocation for this purpose.
113  _intHitCollection = new GGSIntHitsCollection(SensitiveDetectorName, collectionName[0]);
114 }
G4THitsCollection< GGSIntHit > GGSIntHitsCollection
Alias for G4 template hits collection for GGSIntHit.
Definition: GGSIntHit.h:272
G4bool GGSIntHitSD::ProcessHits ( G4Step *  aStep,
G4TouchableHistory *  ROHist 
)

The hit processing method.

For each physical sensitive volume, this method sums up the total energy release during this step to the total releases of previous steps.

Parameters
aStepThe current step
ROHistUnused (needed by the interface).
Returns
true if energy deposit of current step is greater than 0.

Definition at line 118 of file GGSIntHitSD.cpp.

118  {
119 
120  // The G4TouchableHistory argument of this method is non-null only if a readout geometry has been
121  // defined. Since this feature is not supported, it is currently always null.
122  // TODO: investigate the possibility to define a readout geometry
123 
124  if (aStep->GetTotalEnergyDeposit() == 0. && !_storePartHits)
125  return false;
126 
127  G4TouchableHandle touchable = aStep->GetPreStepPoint()->GetTouchableHandle();
128  G4ThreeVector volPos = touchable->GetTranslation(); // Absolute volume translation
129  G4VPhysicalVolume *physVol = touchable->GetVolume();
130 
131  // Build the absolute touchable ID
132  // Definition: the multiplicity of a physical volume is defined as the number of that volumes inside a given mother logical volume.
133  // Definition: given a history, the multiplicity at depth i is the multiplicity of the volume in history at depth i
134  // Definition: given a history, the copy number at depth i is the copy number of the volume in history at depth i
135  // Being N_i and M_i the copy number and multiplicity at depth i, the absolute ID of the touchable at history depth 0 is defined as:
136  // ID = N_0 + M_0*N_1 + M_0*M_1*N_2 + ...
137  // At each step, the product M_0*M_1*N_2*... is stored in the variable totMult.
138 
139  int historyDepth = touchable->GetHistoryDepth();
140  int totMult = 1;
141  int touchableID = 0;
142  // Map to store the multiplicity of each physical volume
143  static boost::unordered_map<G4VPhysicalVolume*, int> multMap;
144 
145  for (int iDepth = 0; iDepth < historyDepth; iDepth++) { // This loop will go up in history up to the daughter of the world volume (i.e. iDepth == historyDepth - 1)
146  touchableID += totMult * touchable->GetCopyNumber(iDepth);
147  // Compute total multiplicity for next step
148  if (iDepth != historyDepth - 1) { // No need to compute the total multiplicity on last step
149  int currVolMult = 0;
150  if (!(touchable->GetVolume(iDepth)->IsReplicated())) {
151  // See if the multiplicity for the current non-replicated volume has been computed before
152  boost::unordered_map<G4VPhysicalVolume*, int>::iterator storedMult = multMap.find(touchable->GetVolume(iDepth));
153  if (storedMult == multMap.end()) {
154  // Compute the multiplicity for non-replicated volumes placed inside the current mother logical
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)
160  currVolMult++;
161  }
162  // Store the computed multiplicity
163  multMap[touchable->GetVolume(iDepth)] = currVolMult;
164  }
165  else {
166  // Use the stored multiplicity
167  currVolMult = storedMult->second;
168  }
169  }
170  else {
171  // Use the multiplicity of the replicated volume
172  EAxis axis;
173  G4int nReplicas;
174  G4double width, offset;
175  G4bool consuming;
176  touchable->GetVolume(iDepth)->GetReplicationData(axis, nReplicas, width, offset, consuming);
177  currVolMult = nReplicas;
178  }
179  totMult *= currVolMult;
180 
181  }
182  }
183 
184  /* *** Add step to integrated hit *** */
185  GGSIntHit *intHit = nullptr;
186  bool intFound = false;
187  // Search for existing integrated hit for this volume
188  for (int iHit = 0; iHit < _intHitCollection->entries(); iHit++) {
189  intHit = (*(_intHitCollection))[iHit];
190  if (physVol == intHit->GetVolume() && touchableID == intHit->GetID() && volPos == intHit->GetAbsTranslation()) {
191  intFound = true;
192  break;
193  }
194  }
195  if (!intFound) {
196  // If we reach this point, then this is a new hit
197  intHit = GGSIntHitFactory::GetInstance().CreateObject(_intHitClass, _timeBins).release();
198  if (!intHit) {
199  throw std::runtime_error(
200  std::string("[GGSIntHitSD::ProcessHits] Can't create integrated hit of class ").append(_intHitClass));
201  }
202  // Set global hit properties
203  intHit->SetAbsTranslation(volPos);
204  intHit->SetID(touchableID);
205  intHit->SetVolume(physVol);
206  intHit->SetPartHitsStorage(_storePartHits);
207  intHit->SetPosHitsStorage(_storePosHits);
208  // Insert the new integrated hit into the hit collection
209  _intHitCollection->insert(intHit);
210  }
211  // Add the current step to the hit
212  intHit->AddStep(*aStep);
213 
214  if (_storePartHits) {
215  /* *** Add step to particle hit *** */
216  // Create the particle hit if it does not exists, i.e. on first step inside the sensitive volume.
217  // If a particle entered in the volume in previous step and immediately got stopped but not killed then IsFirstStepInVolume
218  // for the current step will be true, so check also that kinetic energy is non-zero for pre-step
219  if (aStep->IsFirstStepInVolume() && aStep->GetPreStepPoint()->GetKineticEnergy() != 0) {
220  if (_currPartHit != nullptr) {
221  // On first step there must be no current hit
222  throw std::runtime_error("GGSIntHitSD::ProcessHit: existing particle hit on first step in sensitive volume");
223  }
224  _currPartHit = GGSPartHitFactory::GetInstance().CreateObject(_partHitClass).release();
225  // Set global hit properties
226  _currPartHit->SetPosHitsStorage(_storePosHits);
227  }
228  // Add the current step to the hit
229  _currPartHit->AddStep(*aStep);
230 
231  // Check if this is the last step in the volume
232  // Do not use aStep->IsLastStepInVolume(); see https://geant4-forum.web.cern.ch/t/last-step-in-a-volume/856
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) {
237  if (_currPartHit->GetEnergyDeposit() > _partHitThreshold) {
238  // Hit above threshold: insert it into the hit collection
239  intHit->GetPartHits()->insert(_currPartHit);
240  }
241  else {
242  // Hit below threshold: delete it
243  delete _currPartHit;
244  }
245  // Do not point at the hit anymore (at this point, it's either stored in the collection or deleted)
246  _currPartHit = nullptr;
247  }
248 
249  if (_storePosHits && aStep->GetTotalEnergyDeposit() > _posHitThreshold) {
250  /* *** Create position hit for current step *** */
251  GGSPosHit *posHit = GGSPosHitFactory::GetInstance().CreateObject(_posHitClass).release();
252  if (!posHit) {
253  throw std::runtime_error(
254  std::string("[GGSIntHitSD::ProcessHits] Can't create position hit of class ").append(_posHitClass));
255  }
256  // Insert the new position hit into the hit collection
257  auto *partHit = (_currPartHit ? _currPartHit : (*(intHit->GetPartHits()))[intHit->GetPartHits()->GetSize() - 1]);
258  partHit->GetPosHits()->insert(posHit);
259  // Set members of the position hit
260  posHit->SetStep(*aStep);
261  }
262  }
263 
264  return true;
265 }
virtual void AddStep(const G4Step &step)
Adds a step to the particle hit.
Definition: GGSIntHit.cpp:104
const G4ThreeVector & GetAbsTranslation()
Getter of absolute position of sensitive element.
Definition: GGSIntHit.h:242
virtual void AddStep(const G4Step &step)
Adds a step to the particle hit.
Definition: GGSPartHit.cpp:110
G4double GetEnergyDeposit() const
Energy deposit getter.
Definition: GGSPartHit.h:144
GGSPartHitsCollection * GetPartHits()
Getter of container of particle hits.
Definition: GGSIntHit.h:234
std::unique_ptr< T > CreateObject(const std::string &name, ConstructorArgs...arguments)
Create an object.
Definition: GGSFactory.h:123
void SetAbsTranslation(const G4ThreeVector &pos)
Set the position in global coordinates of the sensitive element.
Definition: GGSIntHit.h:136
void SetPosHitsStorage(bool flag)
Turn on or off the storage of position hits.
Definition: GGSIntHit.cpp:125
const G4VPhysicalVolume * GetVolume()
Getter for volume.
Definition: GGSIntHit.h:224
Definition of GGS Position Hit.
Definition: GGSPosHit.h:31
virtual void SetStep(const G4Step &step)
Definition: GGSPosHit.cpp:65
G4int GetID()
Getter for volume ID.
Definition: GGSIntHit.h:250
void SetID(G4int id)
Setter for volume ID.
Definition: GGSIntHit.h:170
void SetPosHitsStorage(bool flag)
Turn on or off the storage of position hits.
Definition: GGSPartHit.cpp:130
void SetVolume(const G4VPhysicalVolume *volume)
Setter for volume.
Definition: GGSIntHit.h:99
Definition of GGS Integrated Hit.
Definition: GGSIntHit.h:31
static GGSFactory & GetInstance()
Getter method for singleton pointer.
Definition: GGSFactory.h:75
void SetPartHitsStorage(bool flag)
Turn on or off the storage of particle hits.
Definition: GGSIntHit.cpp:144
void GGSIntHitSD::SetIntHitThreshold ( float  minEnergy)
inline

Sets the minimum energy for integrated hits.

Hits below this threshold will be removed from the hits array.

Parameters
minEnergyThe minimum energy for integrated hits.

Definition at line 147 of file GGSIntHitSD.h.

147  {
148  _intHitThreshold = minEnergy;
149  }
void GGSIntHitSD::SetPartHitsStorage ( bool  store)
inline

Turn on or off the storage (i.e. persistency) of particle hits.

This method tells to the SD whether to activate the storage of particle hits or not. By default, storage is not activated.

Calling this method with "false" parameter will automatically disable position hits storage, i.e., it will call SetPartsHitStorage(false).

Parameters
storeif true, steps will be stored as position hits.
See Also
SetPosHitsStorage
GGSIntHit::SetPosHitsStorage

Definition at line 99 of file GGSIntHitSD.h.

99  {
100  _storePartHits = store;
101  if (store == false) {
102  SetPosHitsStorage(false);
103  }
104  }
void SetPosHitsStorage(bool store)
Turn on or off the storage (i.e. persistence) of position hits.
Definition: GGSIntHitSD.h:126
void GGSIntHitSD::SetPartHitThreshold ( float  minEnergy)
inline

Sets the minimum energy for particle hits.

Hits below this threshold will be removed from the hits array.

Parameters
minEnergyThe minimum energy for particle hits.

Definition at line 157 of file GGSIntHitSD.h.

157  {
158  _partHitThreshold = minEnergy;
159  }
void GGSIntHitSD::SetPosHitsStorage ( bool  store)
inline

Turn on or off the storage (i.e. persistence) of position hits.

This method tells to the SD whether to activate the storage of position hits or not. By default, storage is not activated.

Calling this method with "true" parameter will automatically enable particle hits storage, i.e., it will call SetPartHitsStorage(true).

Parameters
storeif true, steps will be stored as position hits.
See Also
SetPartHitsStorage
GGSIntHit::SetPosHitsStorage

Definition at line 126 of file GGSIntHitSD.h.

126  {
127  _storePosHits = store;
128  if (store == true) {
129  SetPartHitsStorage(true);
130  }
131  }
void SetPartHitsStorage(bool store)
Turn on or off the storage (i.e. persistency) of particle hits.
Definition: GGSIntHitSD.h:99
void GGSIntHitSD::SetPosHitThreshold ( float  minEnergy)
inline

Sets the minimum energy for position hits.

Hits below this threshold will be removed from the hits array.

Parameters
minEnergyThe minimum energy for position hits.

Definition at line 168 of file GGSIntHitSD.h.

168  {
169  _posHitThreshold = minEnergy;
170  }
void GGSIntHitSD::SetTimeBin ( G4double  time)
inline

Time bins setter.

This method adds a division in the timeline, effectively adding a time bin.

Parameters
timeThe time of first energy deposit.

Definition at line 70 of file GGSIntHitSD.h.

70  {
71  _timeBins.push_back(time);
72  std::sort(_timeBins.begin(), _timeBins.end());
73  }

The documentation for this class was generated from the following files: