ghit
Loading...
Searching...
No Matches
ghit.h
Go to the documentation of this file.
1#pragma once
2
3// HitBitSet definition
4#include "ghitConventions.h"
5
6// geant4
7#include "G4VHit.hh"
8#include "G4THitsCollection.hh"
9#include "G4Allocator.hh"
10
11#include "G4ThreeVector.hh"
12#include "G4Step.hh"
13#include "G4Colour.hh"
14
15// gemc
16#include "gtouchable.h"
17
18// c++
19#include <optional>
20#include <atomic>
21
42class GHit : public G4VHit
43{
44public:
58 GHit(std::shared_ptr<GTouchable> gt, HitBitSet hbs, const G4Step* thisStep = nullptr,
59 const std::string& cScheme = "default");
60
64 ~GHit() override = default;
65
72 inline void* operator new(size_t);
73
77 inline void operator delete(void*);
78
88 void Draw() override;
89
99 [[nodiscard]] bool is_same_hit(const GHit* hit) const;
100
101private:
111 G4Colour colour_touch, colour_hit, colour_passby;
112
118 bool setColorSchema();
119
121 std::string colorSchema;
122
132 std::shared_ptr<GTouchable> gtouchable;
133
134 // -------------------------------------------------------------------------
135 // Per-step data (vectors)
136 // -------------------------------------------------------------------------
137
144 std::vector<double> edeps;
145
151 std::vector<double> times;
152
158 std::vector<G4ThreeVector> globalPositions;
159
165 std::vector<G4ThreeVector> localPositions;
166
167 // Optional per-step data, controlled by HitBitSet (see ghitConventions.h : meaning of each bit)
168
174 std::vector<int> pids;
175
181 std::vector<int> tids;
182
188 std::vector<double> Es;
189
196 std::vector<std::string> processNames;
197
203 std::vector<double> stepSize;
204
205 // -------------------------------------------------------------------------
206 // Aggregated / calculated quantities (lazy)
207 // -------------------------------------------------------------------------
208
214 std::optional<double> totalEnergyDeposited;
215
216
225 double averageTime;
226
232 G4ThreeVector avgGlobalPosition;
233
239 G4ThreeVector avgLocalPosition;
240
246 std::string processName;
247
259 bool addHitInfosForBitIndex(size_t bitIndex, bool test, const G4Step* thisStep);
260
264 static std::atomic<int> globalHitCounter;
265
266public:
267 // -------------------------------------------------------------------------
268 // Inline accessors (returning copies by design)
269 // -------------------------------------------------------------------------
270
275 [[nodiscard]] inline std::vector<double> getEdeps() const { return edeps; }
276
281 [[nodiscard]] inline std::vector<double> getTimes() const { return times; }
282
287 [[nodiscard]] inline std::vector<G4ThreeVector> getGlobalPositions() const { return globalPositions; }
288
293 [[nodiscard]] inline std::vector<G4ThreeVector> getLocalPositions() const { return localPositions; }
294
299 [[nodiscard]] inline std::vector<int> getPids() const { return pids; }
300
307 [[nodiscard]] inline int getPid() const { return pids.front(); }
308
313 [[nodiscard]] inline std::vector<int> getTids() const { return tids; }
314
321 [[nodiscard]] inline int getTid() const { return tids.front(); }
322
327 [[nodiscard]] inline std::vector<double> getEs() const { return Es; }
328
335 [[nodiscard]] inline double getE() const { return Es.front(); }
336
344 [[nodiscard]] inline size_t nsteps() const { return Es.size(); }
345
353 [[nodiscard]] inline std::string getProcessName() const { return processName; }
354
359 [[nodiscard]] inline std::shared_ptr<GTouchable> getGTouchable() const { return gtouchable; }
360
367 [[nodiscard]] inline std::vector<GIdentifier> getGID() const { return gtouchable->getIdentity(); }
368
375 [[nodiscard]] inline std::vector<double> getDetectorDimensions() const {
376 return gtouchable->getDetectorDimensions();
377 }
378
383 [[nodiscard]] inline double getMass() const { return gtouchable->getMass(); }
384
385 // -------------------------------------------------------------------------
386 // Aggregation / calculation API
387 // -------------------------------------------------------------------------
388
399 void calculateInfosForBit(int bit);
400
408
416 double getAverageTime();
417
422 G4ThreeVector getAvgLocalPosition();
423
430 G4ThreeVector getAvgGlobaPosition();
431
432 // -------------------------------------------------------------------------
433 // Hit filling / testing helpers
434 // -------------------------------------------------------------------------
435
450 void addHitInfosForBitset(HitBitSet hbs, const G4Step* thisStep);
451
462
470 [[nodiscard]] std::vector<int> getTTID() const;
471
483 static GHit* create(const std::shared_ptr<GOptions>& gopts) {
484 HitBitSet hitBitSet;
485 auto gt = GTouchable::create(gopts);
486 auto hit = new GHit(gt, hitBitSet);
487 // Randomize between 1 and 10 steps in a deterministic, thread-safe manner.
488 hit->randomizeHitForTesting(1 + globalHitCounter.fetch_add(1, std::memory_order_relaxed) % 10);
489 return hit;
490 }
491};
492
493// MT definitions, as from:
494// https://twiki.cern.ch/twiki/bin/view/Geant4/QuickMigrationGuideForGeant4V10
495extern G4ThreadLocal G4Allocator<GHit>* GHitAllocator;
496using GHitsCollection = G4THitsCollection<GHit>;
497
498inline void* GHit::operator new(size_t) {
499 if (!GHitAllocator) GHitAllocator = new G4Allocator<GHit>;
500 return (void*)GHitAllocator->MallocSingle();
501}
502
503inline void GHit::operator delete(void* hit) {
504 if (!GHitAllocator) { GHitAllocator = new G4Allocator<GHit>; }
505
506 GHitAllocator->FreeSingle((GHit*)hit);
507}
508
509[[nodiscard]] inline std::string getIdentityString(std::vector<GIdentifier> gidentity) {
510 // Build a compact label from the stored identifier vector.
511 std::string identifierString;
512 for (size_t i = 0; i < gidentity.size() - 1; i++) {
513 identifierString += gidentity[i].getName() + "->" + std::to_string(gidentity[i].getValue()) + ", ";
514 }
515 identifierString += gidentity.back().getName() + "->" + std::to_string(gidentity.back().getValue());
516 return identifierString;
517}
518
519[[nodiscard]] inline std::map<std::string, int> getIdentityMap(std::vector<GIdentifier> gidentity) {
520 std::map<std::string, int> identityMap;
521 for (auto& id : gidentity) {
522 identityMap[id.getName()] = id.getValue();
523 }
524 return identityMap;
525}
Stores step-by-step and aggregated information for a detector hit.
Definition ghit.h:43
GHit(std::shared_ptr< GTouchable > gt, HitBitSet hbs, const G4Step *thisStep=nullptr, const std::string &cScheme="default")
Construct a hit container and optionally seed it from a step.
Definition ghit.cc:26
std::vector< int > getPids() const
Get per-step particle PDG encodings (when enabled).
Definition ghit.h:299
void addHitInfosForBitset(HitBitSet hbs, const G4Step *thisStep)
Append per-step information from a G4Step according to a bitset.
int getPid() const
Convenience accessor for the first particle ID.
Definition ghit.h:307
size_t nsteps() const
Number of recorded steps for the optional-energy vector.
Definition ghit.h:344
std::vector< double > getEs() const
Get per-step total energies (when enabled).
Definition ghit.h:327
std::vector< double > getTimes() const
Get per-step global times.
Definition ghit.h:281
std::vector< GIdentifier > getGID() const
Get the detector element identity.
Definition ghit.h:367
~GHit() override=default
Destructor.
static GHit * create(const std::shared_ptr< GOptions > &gopts)
Create a fake hit for testing, using the current options.
Definition ghit.h:483
std::vector< G4ThreeVector > getLocalPositions() const
Get per-step local positions.
Definition ghit.h:293
std::vector< int > getTTID() const
Get the touchable identity values as integers.
Definition ghit.cc:53
bool is_same_hit(const GHit *hit) const
Compare this hit against another hit by sensitive-element identity.
Definition ghit.cc:46
void randomizeHitForTesting(int nsteps)
Randomize internal vectors for test-only usage.
Definition ghit.cc:100
std::vector< double > getDetectorDimensions() const
Get the sensitive-element dimensions.
Definition ghit.h:375
void Draw() override
Visualize the hit using Geant4 visualization primitives.
Definition ghit.cc:65
void calculateInfosForBit(int bit)
Compute and cache derived information for the requested bit.
G4ThreeVector getAvgGlobaPosition()
Get the average global position of the hit.
std::vector< double > getEdeps() const
Get per-step energy depositions.
Definition ghit.h:275
double getTotalEnergyDeposited()
Get the total deposited energy across all recorded steps.
std::shared_ptr< GTouchable > getGTouchable() const
Get the associated sensitive-element descriptor.
Definition ghit.h:359
double getAverageTime()
Get the average time associated with the hit.
double getMass() const
Get the sensitive element mass.
Definition ghit.h:383
G4ThreeVector getAvgLocalPosition()
Get the average local position of the hit.
int getTid() const
Convenience accessor for the first track ID.
Definition ghit.h:321
double getE() const
Convenience accessor for the first energy value.
Definition ghit.h:335
std::vector< G4ThreeVector > getGlobalPositions() const
Get per-step global positions.
Definition ghit.h:287
std::string getProcessName() const
Get the representative process name for the hit.
Definition ghit.h:353
std::vector< int > getTids() const
Get per-step particle track id (when enabled).
Definition ghit.h:313
static std::shared_ptr< GTouchable > create(const std::shared_ptr< GOptions > &gopt)
Defines the hit information selection bitset for GHit.
std::bitset< NHITBITS > HitBitSet
Bitset selecting which optional hit information is recorded.
std::string getIdentityString(std::vector< GIdentifier > gidentity)
Definition ghit.h:509
G4ThreadLocal G4Allocator< GHit > * GHitAllocator
Definition ghit.cc:22
std::map< std::string, int > getIdentityMap(std::vector< GIdentifier > gidentity)
Definition ghit.h:519
G4THitsCollection< GHit > GHitsCollection