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