ghit
Loading...
Searching...
No Matches
ghit.h
Go to the documentation of this file.
1#pragma once
2
3// geant4
4#include "G4VHit.hh"
5#include "G4THitsCollection.hh"
6#include "G4Allocator.hh"
7
8#include "G4ThreeVector.hh"
9#include "G4Step.hh"
10#include "G4Colour.hh"
11
12// gemc
13#include <gemc/gtouchable/gtouchable.h>
14
15// c++
16#include <optional>
17#include <atomic>
18#include <map>
19
37class GHit : public G4VHit
38{
39public:
42 {
43 int trackId{};
44 std::optional<G4ThreeVector> vertex;
45 std::optional<int> pid;
46 };
47
59 GHit(std::shared_ptr<GTouchable> gt, const G4Step* thisStep = nullptr,
60 const std::string& cScheme = "default");
61
65 ~GHit() override = default;
66
73 inline void* operator new(size_t);
74
78 inline void operator delete(void*);
79
90 void Draw() override;
91
101 [[nodiscard]] bool is_same_hit(const GHit* hit) const;
102
103private:
113 G4Colour colour_touch, colour_hit, colour_passby;
114
120 bool setColorSchema();
121
123 std::string colorSchema;
124
134 std::shared_ptr<GTouchable> gtouchable;
135
136 // -------------------------------------------------------------------------
137 // Per-step data (vectors)
138 // -------------------------------------------------------------------------
139
146 std::vector<double> edeps;
147
153 std::vector<double> times;
154
160 std::vector<G4ThreeVector> globalPositions;
161
167 std::vector<G4ThreeVector> localPositions;
168
174 std::vector<G4ThreeVector> trackVertexPositions;
175
177 std::vector<MotherInfo> motherInfos;
178
182 std::vector<int> pids;
183
187 std::vector<int> tids;
188
195 std::vector<std::string> processNames;
196
203 std::vector<G4ThreeVector> momenta;
204
210 std::vector<double> trackEs;
211
218 static thread_local std::map<int, int> pdgById;
219
220 // -------------------------------------------------------------------------
221 // Aggregated / calculated quantities (lazy)
222 // -------------------------------------------------------------------------
223
230 struct CalculatedState {
231 double totalEnergyDeposited{};
232 double averageTime{};
233 G4ThreeVector averageGlobalPosition;
234 G4ThreeVector averageLocalPosition;
235 std::optional<std::string> processName;
236 };
237
239 mutable std::optional<CalculatedState> calculatedState;
240
242 [[nodiscard]] const CalculatedState& getCalculatedState() const;
243
245 void invalidateCalculatedState();
246
247
251 static std::atomic<int> globalHitCounter;
252
260 static thread_local std::map<int, G4ThreeVector> trackVertexById;
261
262public:
263 // -------------------------------------------------------------------------
264 // Inline accessors (returning copies by design)
265 // -------------------------------------------------------------------------
266
271 [[nodiscard]] inline std::vector<double> getEdeps() const { return edeps; }
272
277 [[nodiscard]] inline std::vector<double> getTimes() const { return times; }
278
283 [[nodiscard]] inline std::vector<G4ThreeVector> getGlobalPositions() const { return globalPositions; }
284
289 [[nodiscard]] inline std::vector<G4ThreeVector> getLocalPositions() const { return localPositions; }
290
295 [[nodiscard]] inline std::vector<G4ThreeVector> getTrackVertexPositions() const {
296 return trackVertexPositions;
297 }
298
305 [[nodiscard]] inline G4ThreeVector getTrackVertexPosition() const { return trackVertexPositions.front(); }
306
308 [[nodiscard]] inline const std::vector<MotherInfo>& getMotherInfos() const { return motherInfos; }
309
311 [[nodiscard]] inline const MotherInfo& getMotherInfo() const { return motherInfos.front(); }
312
317 [[nodiscard]] inline std::vector<int> getPids() const { return pids; }
318
325 [[nodiscard]] inline int getPid() const { return pids.front(); }
326
331 [[nodiscard]] inline std::vector<int> getTids() const { return tids; }
332
339 [[nodiscard]] inline int getTid() const { return tids.front(); }
340
349 [[nodiscard]] inline double getE() const { return trackEs.front(); }
350
355 [[nodiscard]] inline size_t nsteps() const { return edeps.size(); }
356
361 [[nodiscard]] inline size_t getStepCount() const { return edeps.size(); }
362
371 [[nodiscard]] size_t getNumberOfOpticalPhotons() const;
372
377 [[nodiscard]] inline std::vector<G4ThreeVector> getMomenta() const { return momenta; }
378
385 [[nodiscard]] inline G4ThreeVector getMomentum() const { return momenta.front(); }
386
391 [[nodiscard]] inline std::vector<double> getTrackEs() const { return trackEs; }
392
399 [[nodiscard]] inline double getTrackE() const { return trackEs.front(); }
400
405 [[nodiscard]] const std::optional<std::string>& getProcessName() const;
406
411 [[nodiscard]] inline std::shared_ptr<GTouchable> getGTouchable() const { return gtouchable; }
412
419 [[nodiscard]] inline std::vector<GIdentifier> getGID() const { return gtouchable->getIdentity(); }
420
427 [[nodiscard]] inline std::vector<double> getDetectorDimensions() const {
428 return gtouchable->getDetectorDimensions();
429 }
430
435 [[nodiscard]] inline double getMass() const { return gtouchable->getMass(); }
436
437 // -------------------------------------------------------------------------
438 // Aggregation / calculation API
439 // -------------------------------------------------------------------------
440
447 [[nodiscard]] double getTotalEnergyDeposited() const;
448
456 [[nodiscard]] double getAverageTime() const;
457
462 [[nodiscard]] G4ThreeVector getAvgLocalPosition() const;
463
469 [[nodiscard]] G4ThreeVector getAvgGlobalPosition() const;
470
471 // -------------------------------------------------------------------------
472 // Hit filling / testing helpers
473 // -------------------------------------------------------------------------
474
483 void addHitInfos(const G4Step* thisStep);
484
490 static void clearTrackVertexCache();
491
502
510 [[nodiscard]] std::vector<int> getTTID() const;
511
523 static GHit* create(const std::shared_ptr<GOptions>& gopts) {
524 auto gt = GTouchable::create(gopts);
525 auto hit = new GHit(gt);
526 // Randomize between 1 and 10 steps in a deterministic, thread-safe manner.
527 hit->randomizeHitForTesting(1 + globalHitCounter.fetch_add(1, std::memory_order_relaxed) % 10);
528 return hit;
529 }
530};
531
532// MT definitions, as from:
533// https://twiki.cern.ch/twiki/bin/view/Geant4/QuickMigrationGuideForGeant4V10
534extern G4ThreadLocal G4Allocator<GHit>* GHitAllocator;
535using GHitsCollection = G4THitsCollection<GHit>;
536
537inline void* GHit::operator new(size_t) {
538 if (!GHitAllocator) GHitAllocator = new G4Allocator<GHit>;
539 return (void*)GHitAllocator->MallocSingle();
540}
541
542inline void GHit::operator delete(void* hit) {
543 if (!GHitAllocator) { GHitAllocator = new G4Allocator<GHit>; }
544
545 GHitAllocator->FreeSingle((GHit*)hit);
546}
547
548[[nodiscard]] inline std::string getIdentityString(std::vector<GIdentifier> gidentity) {
549 // Build a compact label from the stored identifier vector.
550 std::string identifierString;
551 for (size_t i = 0; i < gidentity.size() - 1; i++) {
552 identifierString += gidentity[i].getName() + "->" + std::to_string(gidentity[i].getValue()) + ", ";
553 }
554 identifierString += gidentity.back().getName() + "->" + std::to_string(gidentity.back().getValue());
555 return identifierString;
556}
557
558[[nodiscard]] inline std::map<std::string, int> getIdentityMap(std::vector<GIdentifier> gidentity) {
559 std::map<std::string, int> identityMap;
560 for (auto& id : gidentity) {
561 identityMap[id.getName()] = id.getValue();
562 }
563 return identityMap;
564}
const std::optional< std::string > & getProcessName() const
Get the representative creator process name for the hit.
size_t getStepCount() const
Number of recorded steps (same as nsteps()).
Definition ghit.h:361
std::vector< int > getPids() const
Get per-step particle PDG encodings (when enabled).
Definition ghit.h:317
int getPid() const
Convenience accessor for the first particle ID.
Definition ghit.h:325
static void clearTrackVertexCache()
Clear the per-thread track vertex cache.
Definition ghit.cc:116
G4ThreeVector getMomentum() const
Convenience accessor for the first step 3-momentum.
Definition ghit.h:385
double getTotalEnergyDeposited() const
Get the total deposited energy across all recorded steps.
size_t nsteps() const
Number of recorded steps.
Definition ghit.h:355
const std::vector< MotherInfo > & getMotherInfos() const
Definition ghit.h:308
const MotherInfo & getMotherInfo() const
Definition ghit.h:311
std::vector< double > getTimes() const
Get per-step global times.
Definition ghit.h:277
std::vector< double > getTrackEs() const
Get per-step track total energies (always present).
Definition ghit.h:391
std::vector< GIdentifier > getGID() const
Get the detector element identity.
Definition ghit.h:419
~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:523
std::vector< G4ThreeVector > getLocalPositions() const
Get per-step local positions.
Definition ghit.h:289
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:121
std::vector< G4ThreeVector > getTrackVertexPositions() const
Get per-step current-track vertex positions.
Definition ghit.h:295
GHit(std::shared_ptr< GTouchable > gt, const G4Step *thisStep=nullptr, const std::string &cScheme="default")
Construct a hit container and optionally seed it from a step.
Definition ghit.cc:36
std::vector< double > getDetectorDimensions() const
Get the sensitive-element dimensions.
Definition ghit.h:427
void Draw() override
Visualize the hit using Geant4 visualization primitives.
Definition ghit.cc:65
double getAverageTime() const
Get the average time associated with the hit.
std::vector< G4ThreeVector > getMomenta() const
Get per-step track 3-momenta (always present).
Definition ghit.h:377
std::vector< double > getEdeps() const
Get per-step energy depositions.
Definition ghit.h:271
std::shared_ptr< GTouchable > getGTouchable() const
Get the associated sensitive-element descriptor.
Definition ghit.h:411
size_t getNumberOfOpticalPhotons() const
Count distinct optical-photon tracks recorded in this hit.
Definition ghit.cc:98
double getTrackE() const
Convenience accessor for the first step track total energy.
Definition ghit.h:399
double getMass() const
Get the sensitive element mass.
Definition ghit.h:435
G4ThreeVector getTrackVertexPosition() const
Convenience accessor for the first current-track vertex position.
Definition ghit.h:305
int getTid() const
Convenience accessor for the first track ID.
Definition ghit.h:339
double getE() const
Convenience accessor for the first step track total energy.
Definition ghit.h:349
G4ThreeVector getAvgLocalPosition() const
Get the average local position of the hit.
std::vector< G4ThreeVector > getGlobalPositions() const
Get per-step global positions.
Definition ghit.h:283
void addHitInfos(const G4Step *thisStep)
Append per-step information from a G4Step.
Definition addHitInfos.cc:9
std::vector< int > getTids() const
Get per-step particle track id (when enabled).
Definition ghit.h:331
G4ThreeVector getAvgGlobalPosition() const
Get the average global position of the hit.
static std::shared_ptr< GTouchable > create(const std::shared_ptr< GOptions > &gopt)
G4ThreadLocal G4Allocator< GHit > * GHitAllocator
Definition ghit.cc:32
std::string getIdentityString(std::vector< GIdentifier > gidentity)
Definition ghit.h:548
G4ThreadLocal G4Allocator< GHit > * GHitAllocator
Definition ghit.cc:32
std::map< std::string, int > getIdentityMap(std::vector< GIdentifier > gidentity)
Definition ghit.h:558
G4THitsCollection< GHit > GHitsCollection
std::optional< int > pid
Definition ghit.h:45
std::optional< G4ThreeVector > vertex
Definition ghit.h:44