gtouchable
Loading...
Searching...
No Matches
gtouchable.cc
Go to the documentation of this file.
1// gtouchable
2#include "gtouchable.h"
4
5// gemc
6#include "gutilities.h"
7#include "gutsConventions.h"
8
9// Define the static counter here
10std::atomic<int> GTouchable::globalGTouchableCounter{0};
11
12// See header for API docs.
13
14// constructor from gopt, digitization and gidentity strings
15// called in GDetectorConstruction::ConstructSDandField
16GTouchable::GTouchable(const std::shared_ptr<GOptions>& gopt,
17 const std::string& digitization,
18 const std::string& gidentityString,
19 const std::vector<double>& dimensions) : GBase(gopt, TOUCHABLE_LOGGER),
20 trackId(0),
21 eMultiplier(1),
22 stepTimeAtElectronicsIndex(
24 detectorDimensions(dimensions) {
25 // Determine the type based on the digitization string.
26 // The string constants are defined in gtouchableConventions.h : FLUXNAME, COUNTERNAME, DOSIMETERNAME.
27 if (digitization == FLUXNAME) { gType = flux; }
28 else if (digitization == COUNTERNAME) { gType = particleCounter; }
29 else if (digitization == DOSIMETERNAME) { gType = dosimeter; }
30 else { gType = readout; }
31
32 // Parse the gidentity string into (name,value) pairs.
33 // Expected format: "sector: 2, layer: 4, wire: 33"
34 // The identity vector order is preserved because comparisons assume the same schema/order.
35 std::vector<std::string> identity = gutilities::getStringVectorFromStringWithDelimiter(gidentityString, ",");
36 // Process each identifier token (e.g., "sector: 2").
37 for (auto& gid : identity) {
38 std::vector<std::string> identifier = gutilities::getStringVectorFromStringWithDelimiter(gid, ":");
39
40 // The parser assumes the token splits into [name, value].
41 // Note: In production, consider adding try-catch here to handle conversion errors.
42 const std::string& idName = identifier[0];
43 int idValue = std::stoi(identifier[1]);
44
45 gidentity.emplace_back(idName, idValue);
46 }
47 log->debug(CONSTRUCTOR, "GTouchable", gtouchable::to_string(gType), " ", getIdentityString());
48}
49
50// constructor from logger, digitization and gidentity strings
51// called in GDetectorConstruction::ConstructSDandField
52GTouchable::GTouchable(const std::shared_ptr<GLogger>& logger,
53 const std::string& digitization,
54 const std::string& gidentityString,
55 const std::vector<double>& dimensions) : GBase(logger),
56 trackId(0),
57 eMultiplier(1),
58 stepTimeAtElectronicsIndex(
60 detectorDimensions(dimensions) {
61 // Determine the type based on the digitization string.
62 // The string constants are defined in gtouchableConventions.h : FLUXNAME, COUNTERNAME, DOSIMETERNAME.
63 if (digitization == FLUXNAME) { gType = flux; }
64 else if (digitization == COUNTERNAME) { gType = particleCounter; }
65 else if (digitization == DOSIMETERNAME) { gType = dosimeter; }
66 else { gType = readout; }
67
68 // Parse the gidentity string into (name,value) pairs.
69 // Expected format: "sector: 2, layer: 4, wire: 33"
70 // The identity vector order is preserved because comparisons assume the same schema/order.
71 std::vector<std::string> identity = gutilities::getStringVectorFromStringWithDelimiter(gidentityString, ",");
72 // Process each identifier token (e.g., "sector: 2").
73 for (auto& gid : identity) {
74 std::vector<std::string> identifier = gutilities::getStringVectorFromStringWithDelimiter(gid, ":");
75
76 // The parser assumes the token splits into [name, value].
77 // Note: In production, consider adding try-catch here to handle conversion errors.
78 const std::string& idName = identifier[0];
79 int idValue = std::stoi(identifier[1]);
80
81 gidentity.emplace_back(idName, idValue);
82 }
83 log->debug(CONSTRUCTOR, "GTouchable", gtouchable::to_string(gType), " ", getIdentityString());
84}
85
86// Overloaded "==" operator for the class 'GTouchable'
87bool GTouchable::operator==(const GTouchable& that) const {
88 // First, check if both gidentity vectors are the same size.
89 // this should never happen because the same sensitivity should be assigned the same identifier structure
90 if (this->gidentity.size() != that.gidentity.size()) {
91 log->debug(NORMAL, "Touchable sizes are different");
92 return false;
93 }
94
95 // Compare identifiers positionally.
96 // Only the identifier values are compared (schema/order is assumed identical for the same sensitivity).
97 log->debug(NORMAL, " + Touchable comparison: ");
98 for (size_t i = 0; i < this->gidentity.size(); ++i) {
99 bool equal = (this->gidentity[i].getValue() == that.gidentity[i].getValue());
100 std::string comparisonResult = equal ? " ✅" : " ❌";
101 log->debug(NORMAL, " ← ", this->gidentity[i], " → ", that.gidentity[i], comparisonResult);
102 if (!equal) { return false; }
103 }
104
105 bool typeComparison = false;
106 std::string result;
107
108 // All identity values matched; apply the type-specific discriminator.
109 switch (this->gType) {
110 case readout:
111 typeComparison = this->stepTimeAtElectronicsIndex == that.stepTimeAtElectronicsIndex;
112 result = typeComparison ? " ✅" : " ❌";
113 log->debug(NORMAL, " Touchable type is readout. Time cell comparison: ", this->stepTimeAtElectronicsIndex,
114 " ", that.stepTimeAtElectronicsIndex,
115 " result:", result);
116 break;
117 case flux:
118 typeComparison = this->trackId == that.trackId;
119 result = typeComparison ? " ✅" : " ❌";
120 log->debug(NORMAL, " Touchable type is flux. Track id comparison: ", this->trackId, " ", that.trackId,
121 " result:", result);
122 break;
123 case dosimeter:
124 typeComparison = this->trackId == that.trackId;
125 result = typeComparison ? " ✅" : " ❌";
126 log->debug(NORMAL, " Touchable type is dosimeter. Track id comparison: ", this->trackId, " ", that.trackId,
127 " result:", result);
128 break;
129 case particleCounter:
130 typeComparison = true;
131 log->debug(NORMAL, " Touchable type is particleCounter. No additional comparison needed, returning true ✅");
132 break;
133 }
134 return typeComparison;
135}
136
137// ostream GTouchable
138std::ostream& operator<<(std::ostream& stream, const GTouchable& gtouchable) {
139 stream << " GTouchable: ";
140 for (auto& gid : gtouchable.gidentity) {
141 stream << KRED << gid;
142 if (gid.getName() != gtouchable.gidentity.back().getName()) { stream << ", "; }
143 else { stream << RST; }
144 }
145 switch (gtouchable.gType) {
146 case readout:
147 // compare the time cell
148 stream << KGRN << " (readout), " << RST << " multiplier: " << gtouchable.eMultiplier << ", time cell index: " <<
149 gtouchable.stepTimeAtElectronicsIndex;
150 break;
151 case flux:
152 stream << KGRN << " (flux), " << RST << " g4 track id: " << gtouchable.trackId;
153 break;
154 case dosimeter:
155 stream << KGRN << " (dosimeter), " << RST << " g4 track id: " << gtouchable.trackId;
156 break;
157 case particleCounter:
158 stream << KGRN << " (particleCounter), " << RST << " g4 track id: " << gtouchable.trackId;
159 break;
160 }
161
162 return stream;
163}
164
166std::ostream& operator<<(std::ostream& stream, const GIdentifier& gidentifier) {
167 stream << gidentifier.idName << ": " << gidentifier.idValue;
168 return stream;
169}
std::shared_ptr< GLogger > log
void debug(debug_type type, Args &&... args) const
Represents a touchable sensitive detector element used as a hit-collection discriminator.
Definition gtouchable.h:140
GTouchable(const GTouchable &)=default
bool operator==(const GTouchable &gtouchable) const
Compares two GTouchable instances using the module comparison semantics.
Definition gtouchable.cc:87
std::string getIdentityString() const
Builds a human-readable identity string from the stored identifiers.
Definition gtouchable.h:265
CONSTRUCTOR
NORMAL
Conventions and constants used by the gtouchable module.
#define GTOUCHABLEUNSETTIMEINDEX
Sentinel value for an unset electronics time-cell index.
#define FLUXNAME
Digitization type name for flux-like detectors.
#define DOSIMETERNAME
Digitization type name for dosimeters.
#define COUNTERNAME
Digitization type name for simple particle counters.
std::ostream & operator<<(std::ostream &stream, const GTouchable &gtouchable)
@ flux
Flux-like discrimination using track id.
Definition gtouchable.h:36
@ particleCounter
Identity vector only; no additional discriminating factor.
Definition gtouchable.h:37
@ readout
Electronic readout with time-window discrimination (time-cell index).
Definition gtouchable.h:35
@ dosimeter
Radiation digitization; discrimination using track id.
Definition gtouchable.h:38
constexpr const char * TOUCHABLE_LOGGER
Logger name used by the gtouchable module.
#define KRED
#define KGRN
#define RST
const char * to_string(GTouchableType t)
Converts a GTouchableType value to a stable string for logging.
Definition gtouchable.h:56
vector< string > getStringVectorFromStringWithDelimiter(const string &input, const string &x)
A single (name,value) identifier element used to build a touchable identity vector.
Definition gtouchable.h:78