LDMX Software
HcalGeometryVerfifier.cxx
1#include "DQM/HcalGeometryVerifier.h"
2namespace dqm {
3
6 hcalSimHitsCollection_ =
7 parameters.getParameter<std::string>("sim_coll_name");
8 hcalRecHitsCollection_ =
9 parameters.getParameter<std::string>("rec_coll_name");
10 hcalSimHitsPassName_ = parameters.getParameter<std::string>("sim_pass_name");
11 hcalRecHitsPassName_ = parameters.getParameter<std::string>("rec_pass_name");
12 stop_on_error = parameters.getParameter<bool>("stop_on_error");
13 tolerance = parameters.getParameter<double>("tolerance");
14}
16 const auto hcalSimHits = event.getCollection<ldmx::SimCalorimeterHit>(
17 hcalSimHitsCollection_, hcalSimHitsPassName_);
18 const auto hcalRecHits = event.getCollection<ldmx::HcalHit>(
19 hcalRecHitsCollection_, hcalRecHitsPassName_);
20
21 for (const auto &hit : hcalSimHits) {
22 const ldmx::HcalID id{static_cast<unsigned int>(hit.getID())};
23 const auto position{hit.getPosition()};
24 auto ok{hit_ok(id, {position[0], position[1], position[2]})};
25 histograms_.fill("passes_sim", ok);
26 switch (id.section()) {
27 case ldmx::HcalID::HcalSection::BACK:
28 histograms_.fill("passes_sim_back", ok);
29 break;
30 case ldmx::HcalID::HcalSection::TOP:
31 histograms_.fill("passes_sim_top", ok);
32 break;
33 case ldmx::HcalID::HcalSection::BOTTOM:
34 histograms_.fill("passes_sim_bottom", ok);
35 break;
36 case ldmx::HcalID::HcalSection::LEFT:
37 histograms_.fill("passes_sim_left", ok);
38 break;
39 case ldmx::HcalID::HcalSection::RIGHT:
40 histograms_.fill("passes_sim_right", ok);
41 break;
42 }
43 }
44 for (const auto &hit : hcalRecHits) {
45 const ldmx::HcalID id{static_cast<unsigned int>(hit.getID())};
46 auto ok{hit_ok(id, {hit.getXPos(), hit.getYPos(), hit.getZPos()})};
47 histograms_.fill("passes_rec", ok);
48 switch (id.section()) {
49 case ldmx::HcalID::HcalSection::BACK:
50 histograms_.fill("passes_rec_back", ok);
51 break;
52 case ldmx::HcalID::HcalSection::TOP:
53 histograms_.fill("passes_rec_top", ok);
54 break;
55 case ldmx::HcalID::HcalSection::BOTTOM:
56 histograms_.fill("passes_rec_bottom", ok);
57 break;
58 case ldmx::HcalID::HcalSection::LEFT:
59 histograms_.fill("passes_rec_left", ok);
60 break;
61 case ldmx::HcalID::HcalSection::RIGHT:
62 histograms_.fill("passes_rec_right", ok);
63 break;
64 }
65 }
66
67} // Analyze
68bool HcalGeometryVerifier::hit_ok(const ldmx::HcalID id,
69 const std::array<double, 3> &position) {
70 const auto &geometry = getCondition<ldmx::HcalGeometry>(
72 auto [index_along, index_across, index_through]{determine_indices(id)};
73 const auto center{geometry.getStripCenterPosition(id)};
74 const auto length{geometry.getScintillatorLength(id)};
75 bool outside_bounds_along{
76 std::abs(position[index_along] - center[index_along]) >
77 length / 2 + tolerance};
78
79 const auto width{geometry.getScintillatorWidth()};
80 bool outside_bounds_across{
81 std::abs(position[index_across] - center[index_across]) >
82 width / 2 + tolerance};
83
84 const auto thickness{geometry.getScintillatorThickness()};
85 bool outside_bounds_through{
86 std::abs(position[index_through] - center[index_through]) >
87 thickness / 2 + tolerance};
88
89 if (outside_bounds_along || outside_bounds_across || outside_bounds_through) {
90 std::stringstream ss;
91 if (tolerance < 1) {
92 // Assume tolerance is of form 1e-N
93 //
94 // Set precision so it will be clear if it is a floating point precision
95 // issue or a problem
96 ss.precision(-std::log10(tolerance) + 1);
97 }
98 ss << std::boolalpha;
99 double x{position[0]};
100 double y{position[1]};
101 double z{position[2]};
102 ss << id << " has hit position at (" << x << ", " << y << ", " << z
103 << ")\nwhich is not within the bounds of the Hcal strip center ("
104 << center[0] << ", " << center[1] << ", " << center[2]
105 << ") with tolerance " << tolerance << std::endl;
106 ss << "Position along the bar: " << position[index_along] << " outside "
107 << center[index_along] << " +- " << length / 2 << "? "
108 << outside_bounds_along << std::endl;
109 ss << "Position across the bar: " << position[index_across] << " outside "
110 << center[index_across] << " +- " << width / 2 << "? "
111 << outside_bounds_across << std::endl;
112 ss << "Position through the bar: " << position[index_through] << " outside "
113 << center[index_through] << " +- " << thickness / 2 << "? "
114 << outside_bounds_through << std::endl;
115
116 if (stop_on_error) {
117 EXCEPTION_RAISE("InvalidPosition", ss.str());
118 } else {
119 ldmx_log(warn) << ss.str();
120 }
121 return false;
122 }
123 return true;
124}
125std::array<int, 3> HcalGeometryVerifier::determine_indices(
126 const ldmx::HcalID id) {
127 const auto &geometry = getCondition<ldmx::HcalGeometry>(
129 const auto orientation{geometry.getScintillatorOrientation(id)};
130 const auto isLR{id.section() == ldmx::HcalID::HcalSection::LEFT ||
131 id.section() == ldmx::HcalID::HcalSection::RIGHT};
132
133 int index_along{};
134 int index_across{};
135 int index_through{};
136 if (id.section() == ldmx::HcalID::HcalSection::BACK) {
137 index_through = 2; // z
138 if (orientation ==
139 ldmx::HcalGeometry::ScintillatorOrientation::horizontal) {
140 index_along = 0; // x
141 index_across = 1; // y
142 } else {
143 index_across = 0; // x
144 index_along = 1; // y
145 }
146 } else if (geometry.hasSide3DReadout()) {
147 switch (orientation) {
148 case ldmx::HcalGeometry::ScintillatorOrientation::horizontal:
149 index_across = 2; // z
150 index_along = 0; // x
151 index_through = 1; // y
152 // Horizontal bar in side hcal -> x length, z width, y thick
153 break;
154 case ldmx::HcalGeometry::ScintillatorOrientation::vertical:
155 // Vertical bar in side hcal -> y length, z width, x thick
156 index_across = 2; // z
157 index_along = 1; // y
158 index_through = 0; // x
159 break;
160 case ldmx::HcalGeometry::ScintillatorOrientation::depth:
161 index_along = 2; // z
162 if (isLR) {
163 // Depth bar in side hcal (LR) -> z length, x thick, y width
164 index_through = 0; // x
165 index_across = 1; // y
166 } else {
167 // Depth bar in side hcal (TB) -> z length, y thick, x width
168 index_through = 1; // y
169 index_across = 0; // x
170 }
171 break;
172 }
173 } else {
174 // v12 Side hcal
175 index_across = 2; // z
176 if (orientation ==
177 ldmx::HcalGeometry::ScintillatorOrientation::horizontal) {
178 index_along = 0; // x
179 index_through = 1; // y
180 } else {
181 index_along = 1; // y
182 index_through = 0; // x
183 }
184 }
185 return {index_along, index_across, index_through};
186}
187} // namespace dqm
188DECLARE_ANALYZER_NS(dqm, HcalGeometryVerifier);
#define DECLARE_ANALYZER_NS(NS, CLASS)
Macro which allows the framework to construct an analyzer given its name during configuration.
void configure(framework::config::Parameters &parameters) override
Callback for the EventProcessor to configure itself from the given set of parameters.
void analyze(const framework::Event &event) override
Process the event and make histograms or summaries.
HistogramHelper histograms_
Interface class for making and filling histograms.
Implements an event buffer system for storing event data.
Definition Event.h:41
void fill(const std::string &name, const double &val)
Fill a 1D histogram.
Definition Histograms.h:166
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:27
T getParameter(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:89
static constexpr const char * CONDITIONS_OBJECT_NAME
Conditions object: The name of the python configuration calling this class (Hcal/python/HcalGeometry....
Stores reconstructed hit information from the HCAL.
Definition HcalHit.h:23
Implements detector ids for HCal subdetector.
Definition HcalID.h:19
Stores simulated calorimeter hit information.