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