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