5#include "G4THitsCollection.hh"
6#include "G4Allocator.hh"
8#include "G4ThreeVector.hh"
13#include <gemc/gtouchable/gtouchable.h>
45 std::optional<int>
pid;
59 GHit(std::shared_ptr<GTouchable> gt,
const G4Step* thisStep =
nullptr,
60 const std::string& cScheme =
"default");
73 inline void*
operator new(size_t);
78 inline void operator delete(
void*);
113 G4Colour colour_touch, colour_hit, colour_passby;
120 bool setColorSchema();
123 std::string colorSchema;
146 std::vector<double> edeps;
153 std::vector<double> times;
160 std::vector<G4ThreeVector> globalPositions;
167 std::vector<G4ThreeVector> localPositions;
174 std::vector<G4ThreeVector> trackVertexPositions;
177 std::vector<MotherInfo> motherInfos;
182 std::vector<int> pids;
187 std::vector<int> tids;
195 std::vector<std::string> processNames;
203 std::vector<G4ThreeVector> momenta;
210 std::vector<double> trackEs;
218 static thread_local std::map<int, int> pdgById;
230 struct CalculatedState {
231 double totalEnergyDeposited{};
232 double averageTime{};
233 G4ThreeVector averageGlobalPosition;
234 G4ThreeVector averageLocalPosition;
235 std::optional<std::string> processName;
239 mutable std::optional<CalculatedState> calculatedState;
242 [[nodiscard]]
const CalculatedState& getCalculatedState()
const;
245 void invalidateCalculatedState();
251 static std::atomic<int> globalHitCounter;
260 static thread_local std::map<int, G4ThreeVector> trackVertexById;
271 [[nodiscard]]
inline std::vector<double>
getEdeps()
const {
return edeps; }
277 [[nodiscard]]
inline std::vector<double>
getTimes()
const {
return times; }
283 [[nodiscard]]
inline std::vector<G4ThreeVector>
getGlobalPositions()
const {
return globalPositions; }
289 [[nodiscard]]
inline std::vector<G4ThreeVector>
getLocalPositions()
const {
return localPositions; }
296 return trackVertexPositions;
308 [[nodiscard]]
inline const std::vector<MotherInfo>&
getMotherInfos()
const {
return motherInfos; }
317 [[nodiscard]]
inline std::vector<int>
getPids()
const {
return pids; }
325 [[nodiscard]]
inline int getPid()
const {
return pids.front(); }
331 [[nodiscard]]
inline std::vector<int>
getTids()
const {
return tids; }
339 [[nodiscard]]
inline int getTid()
const {
return tids.front(); }
349 [[nodiscard]]
inline double getE()
const {
return trackEs.front(); }
355 [[nodiscard]]
inline size_t nsteps()
const {
return edeps.size(); }
361 [[nodiscard]]
inline size_t getStepCount()
const {
return edeps.size(); }
377 [[nodiscard]]
inline std::vector<G4ThreeVector>
getMomenta()
const {
return momenta; }
385 [[nodiscard]]
inline G4ThreeVector
getMomentum()
const {
return momenta.front(); }
391 [[nodiscard]]
inline std::vector<double>
getTrackEs()
const {
return trackEs; }
399 [[nodiscard]]
inline double getTrackE()
const {
return trackEs.front(); }
405 [[nodiscard]]
const std::optional<std::string>&
getProcessName()
const;
419 [[nodiscard]]
inline std::vector<GIdentifier>
getGID()
const {
return gtouchable->getIdentity(); }
510 [[nodiscard]] std::vector<int>
getTTID()
const;
523 static GHit*
create(
const std::shared_ptr<GOptions>& gopts) {
525 auto hit =
new GHit(gt);
527 hit->randomizeHitForTesting(1 + globalHitCounter.fetch_add(1, std::memory_order_relaxed) % 10);
537inline void* GHit::operator
new(size_t) {
542inline void GHit::operator
delete(
void* hit) {
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()) +
", ";
554 identifierString += gidentity.back().getName() +
"->" + std::to_string(gidentity.back().getValue());
555 return identifierString;
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();
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()).
std::vector< int > getPids() const
Get per-step particle PDG encodings (when enabled).
int getPid() const
Convenience accessor for the first particle ID.
static void clearTrackVertexCache()
Clear the per-thread track vertex cache.
G4ThreeVector getMomentum() const
Convenience accessor for the first step 3-momentum.
double getTotalEnergyDeposited() const
Get the total deposited energy across all recorded steps.
size_t nsteps() const
Number of recorded steps.
const std::vector< MotherInfo > & getMotherInfos() const
const MotherInfo & getMotherInfo() const
std::vector< double > getTimes() const
Get per-step global times.
std::vector< double > getTrackEs() const
Get per-step track total energies (always present).
std::vector< GIdentifier > getGID() const
Get the detector element identity.
~GHit() override=default
Destructor.
static GHit * create(const std::shared_ptr< GOptions > &gopts)
Create a fake hit for testing, using the current options.
std::vector< G4ThreeVector > getLocalPositions() const
Get per-step local positions.
std::vector< int > getTTID() const
Get the touchable identity values as integers.
bool is_same_hit(const GHit *hit) const
Compare this hit against another hit by sensitive-element identity.
void randomizeHitForTesting(int nsteps)
Randomize internal vectors for test-only usage.
std::vector< G4ThreeVector > getTrackVertexPositions() const
Get per-step current-track vertex positions.
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.
std::vector< double > getDetectorDimensions() const
Get the sensitive-element dimensions.
void Draw() override
Visualize the hit using Geant4 visualization primitives.
double getAverageTime() const
Get the average time associated with the hit.
std::vector< G4ThreeVector > getMomenta() const
Get per-step track 3-momenta (always present).
std::vector< double > getEdeps() const
Get per-step energy depositions.
std::shared_ptr< GTouchable > getGTouchable() const
Get the associated sensitive-element descriptor.
size_t getNumberOfOpticalPhotons() const
Count distinct optical-photon tracks recorded in this hit.
double getTrackE() const
Convenience accessor for the first step track total energy.
double getMass() const
Get the sensitive element mass.
G4ThreeVector getTrackVertexPosition() const
Convenience accessor for the first current-track vertex position.
int getTid() const
Convenience accessor for the first track ID.
double getE() const
Convenience accessor for the first step track total energy.
G4ThreeVector getAvgLocalPosition() const
Get the average local position of the hit.
std::vector< G4ThreeVector > getGlobalPositions() const
Get per-step global positions.
void addHitInfos(const G4Step *thisStep)
Append per-step information from a G4Step.
std::vector< int > getTids() const
Get per-step particle track id (when enabled).
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
std::string getIdentityString(std::vector< GIdentifier > gidentity)
G4ThreadLocal G4Allocator< GHit > * GHitAllocator
std::map< std::string, int > getIdentityMap(std::vector< GIdentifier > gidentity)
G4THitsCollection< GHit > GHitsCollection
std::optional< G4ThreeVector > vertex