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// See header for API docs.
10
11// constructor from gopt, digitization and gidentity strings
12// called in GDetectorConstruction::ConstructSDandField
13GTouchable::GTouchable(const std::shared_ptr<GOptions>& gopt,
14 const std::string& digitization,
15 const std::string& gidentityString,
16 const std::vector<double>& dimensions,
17 const double& dm) :
19 trackId(0),
20 eMultiplier(1),
21 stepTimeAtElectronicsIndex(GTOUCHABLEUNSETTIMEINDEX),
22 detectorDimensions(dimensions),
23 mass(dm) {
24 // Determine the type based on the digitization string.
25 // The string constants are defined in gtouchableConventions.h.
26 if (digitization == FLUXNAME) { gType = flux; }
27 else if (digitization == GPHOTON_DETECTORNAME) { gType = gPhotonDetector; }
28 else if (digitization == COUNTERNAME) { gType = particle_counter; }
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,
56 const double& dm) :
57 GBase(logger),
58 trackId(0),
59 eMultiplier(1),
60 stepTimeAtElectronicsIndex(GTOUCHABLEUNSETTIMEINDEX),
61 detectorDimensions(dimensions),
62 mass(dm) {
63 // Determine the type based on the digitization string.
64 // The string constants are defined in gtouchableConventions.h.
65 if (digitization == FLUXNAME) { gType = flux; }
66 else if (digitization == GPHOTON_DETECTORNAME) { gType = gPhotonDetector; }
67 else if (digitization == COUNTERNAME) { gType = particle_counter; }
68 else if (digitization == DOSIMETERNAME) { gType = dosimeter; }
69 else { gType = readout; }
70
71 // Parse the gidentity string into (name,value) pairs.
72 // Expected format: "sector: 2, layer: 4, wire: 33"
73 // The identity vector order is preserved because comparisons assume the same schema/order.
74 std::vector<std::string> identity = gutilities::getStringVectorFromStringWithDelimiter(gidentityString, ",");
75 // Process each identifier token (e.g., "sector: 2").
76 for (auto& gid : identity) {
77 std::vector<std::string> identifier = gutilities::getStringVectorFromStringWithDelimiter(gid, ":");
78
79 // The parser assumes the token splits into [name, value].
80 // Note: In production, consider adding try-catch here to handle conversion errors.
81 const std::string& idName = identifier[0];
82 int idValue = std::stoi(identifier[1]);
83
84 gidentity.emplace_back(idName, idValue);
85 }
86 log->debug(CONSTRUCTOR, "GTouchable", gtouchable::to_string(gType), " ", getIdentityString());
87}
88
89// Overloaded "==" operator for the class 'GTouchable'
90bool GTouchable::operator==(const GTouchable& that) const {
91 // First, check if both gidentity vectors are the same size.
92 // this should never happen because the same sensitivity should be assigned the same identifier structure
93 if (this->gidentity.size() != that.gidentity.size()) {
94 log->debug(NORMAL, "Touchable sizes are different");
95 return false;
96 }
97
98 // Compare identifiers positionally.
99 // Only the identifier values are compared (schema/order is assumed identical for the same sensitivity).
100 log->debug(NORMAL, " + Touchable comparison: ");
101 for (size_t i = 0; i < this->gidentity.size(); ++i) {
102 bool equal = ( this->gidentity[i].getValue() == that.gidentity[i].getValue() );
103 std::string comparisonResult = equal ? " ✅" : " ❌";
104 log->debug(NORMAL, " ← ", this->gidentity[i], " → ", that.gidentity[i], comparisonResult);
105 if (!equal) { return false; }
106 }
107
108 bool typeComparison = false;
109 std::string result;
110
111 // All identity values matched; apply the type-specific discriminator.
112 switch (this->gType) {
113 case readout:
114 typeComparison = this->stepTimeAtElectronicsIndex == that.stepTimeAtElectronicsIndex;
115 result = typeComparison ? " ✅" : " ❌";
116 log->debug(NORMAL, " Touchable type is readout. Time cell comparison: ",
117 this->stepTimeAtElectronicsIndex,
118 " ", that.stepTimeAtElectronicsIndex,
119 " result:", result);
120 break;
121 case flux:
122 typeComparison = this->trackId == that.trackId;
123 result = typeComparison ? " ✅" : " ❌";
124 log->debug(NORMAL, " Touchable type is flux. Track id comparison: ", this->trackId, " ", that.trackId,
125 " result:", result);
126 break;
127 case gPhotonDetector:
128 typeComparison = this->trackId == that.trackId;
129 result = typeComparison ? " ✅" : " ❌";
130 log->debug(NORMAL, " Touchable type is gPhotonDetector. Track id comparison: ",
131 this->trackId, " ", that.trackId, " result:", result);
132 break;
133 case dosimeter:
134 typeComparison = true;
135 log->debug(NORMAL, " Touchable type is dosimeter. No additional comparison needed, returning true ✅");
136 break;
137
138 case particle_counter:
139 typeComparison = this->pid == that.pid;
140 result = typeComparison ? " ✅" : " ❌";
141 log->debug(NORMAL, " Touchable type is flux. Track id comparison: ", this->trackId, " ", that.trackId,
142 " result:", result);
143 break;
144
145 case integral_counter:
146 typeComparison = true;
147 log->debug(NORMAL,
148 " Touchable type is integral_counter. No additional comparison needed, returning true ✅");
149 break;
150 }
151 return typeComparison;
152}
153
154// Builds the hit-cell key with the same semantics as operator==: identity values plus the
155// type-specific discriminator. Kept allocation-light because it runs for every step in a
156// sensitive volume.
157std::string GTouchable::cellKey() const {
158 std::string key;
159 key.reserve(gidentity.size() * 8 + 12);
160 for (const auto& gid : gidentity) {
161 key += std::to_string(gid.getValue());
162 key += ',';
163 }
164 switch (gType) {
165 case readout: key += 'r'; key += std::to_string(stepTimeAtElectronicsIndex); break;
166 case flux:
167 case gPhotonDetector: key += 't'; key += std::to_string(trackId); break;
168 case particle_counter: key += 'p'; key += std::to_string(pid); break;
169 case dosimeter:
170 case integral_counter: break;
171 }
172 return key;
173}
174
175// ostream GTouchable
176std::ostream& operator<<(std::ostream& stream, const GTouchable& gtouchable) {
177 stream << " GTouchable: ";
178 for (auto& gid : gtouchable.gidentity) {
179 stream << KRED << gid;
180 if (gid.getName() != gtouchable.gidentity.back().getName()) { stream << ", "; }
181 else { stream << RST; }
182 }
183 switch (gtouchable.gType) {
184 case readout:
185 // compare the time cell
186 stream << KGRN << " (readout), " << RST << " multiplier: " << gtouchable.eMultiplier <<
187 ", time cell index: " <<
188 gtouchable.stepTimeAtElectronicsIndex;
189 break;
190 case flux:
191 stream << KGRN << " (flux), " << RST << " g4 track id: " << gtouchable.trackId;
192 break;
193 case gPhotonDetector:
194 stream << KGRN << " (gPhotonDetector), " << RST << " g4 track id: " << gtouchable.trackId;
195 break;
196 case dosimeter:
197 stream << KGRN << " (dosimeter), " << RST;
198 break;
199 case particle_counter:
200 stream << KGRN << " (particle_counter), " << RST << " particle id: " << gtouchable.pid;
201 break;
202 case integral_counter:
203 stream << KGRN << " (integral_counter), " << RST;
204 break;
205 }
206
207 return stream;
208}
209
211std::ostream& operator<<(std::ostream& stream, const GIdentifier& gidentifier) {
212 stream << gidentifier.idName << ": " << gidentifier.idValue;
213 return stream;
214}
GBase(const std::shared_ptr< GOptions > &gopt, std::string logger_name="")
std::shared_ptr< GLogger > log
GTouchable(const GTouchable &)=default
bool operator==(const GTouchable &gtouchable) const
Compares two GTouchable instances using the module comparison semantics.
Definition gtouchable.cc:90
std::string cellKey() const
Builds a compact key identifying the hit cell of this touchable.
std::string getIdentityString() const
Builds a human-readable identity string from the stored identifiers.
Definition gtouchable.h:302
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.
#define GPHOTON_DETECTORNAME
Digitization type name for optical-photon flux detectors.
std::ostream & operator<<(std::ostream &stream, const GTouchable &gtouchable)
@ flux
Definition gtouchable.h:35
@ integral_counter
Definition gtouchable.h:39
@ readout
Definition gtouchable.h:34
@ dosimeter
Definition gtouchable.h:38
@ particle_counter
Definition gtouchable.h:37
@ gPhotonDetector
Definition gtouchable.h:36
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:57
vector< string > getStringVectorFromStringWithDelimiter(const string &input, const string &x)
GIdentifier(const std::string &n, int v)
Constructs a GIdentifier.
Definition gtouchable.h:89