LDMX Software
HcalGeometryVerfifier.cxx
1#include "DQM/HcalGeometryVerifier.h"
2namespace dqm {
3
6 hcal_sim_hits_collection_ = parameters.get<std::string>("sim_coll_name");
7 hcal_rec_hits_collection_ = parameters.get<std::string>("rec_coll_name");
8 hcal_sim_hits_pass_name_ = parameters.get<std::string>("sim_pass_name");
9 hcal_rec_hits_pass_name_ = parameters.get<std::string>("rec_pass_name");
10 stop_on_error_ = parameters.get<bool>("stop_on_error");
11 tolerance_ = parameters.get<double>("tolerance_");
12}
14 const auto hcal_sim_hits = event.getCollection<ldmx::SimCalorimeterHit>(
15 hcal_sim_hits_collection_, hcal_sim_hits_pass_name_);
16 const auto hcal_rec_hits = event.getCollection<ldmx::HcalHit>(
17 hcal_rec_hits_collection_, hcal_rec_hits_pass_name_);
18
19 for (const auto &hit : hcal_sim_hits) {
20 const ldmx::HcalID id{static_cast<unsigned int>(hit.getID())};
21 const auto position{hit.getPosition()};
22 auto ok{hitOk(id, {position[0], position[1], position[2]})};
23 histograms_.fill("passes_sim", ok);
24 switch (id.section()) {
25 case ldmx::HcalID::HcalSection::BACK:
26 histograms_.fill("passes_sim_back", ok);
27 break;
28 case ldmx::HcalID::HcalSection::TOP:
29 histograms_.fill("passes_sim_top", ok);
30 break;
31 case ldmx::HcalID::HcalSection::BOTTOM:
32 histograms_.fill("passes_sim_bottom", ok);
33 break;
34 case ldmx::HcalID::HcalSection::LEFT:
35 histograms_.fill("passes_sim_left", ok);
36 break;
37 case ldmx::HcalID::HcalSection::RIGHT:
38 histograms_.fill("passes_sim_right", ok);
39 break;
40 }
41 }
42 for (const auto &hit : hcal_rec_hits) {
43 const ldmx::HcalID id{static_cast<unsigned int>(hit.getID())};
44 auto ok{hitOk(id, {hit.getXPos(), hit.getYPos(), hit.getZPos()})};
45 histograms_.fill("passes_rec", ok);
46 switch (id.section()) {
47 case ldmx::HcalID::HcalSection::BACK:
48 histograms_.fill("passes_rec_back", ok);
49 break;
50 case ldmx::HcalID::HcalSection::TOP:
51 histograms_.fill("passes_rec_top", ok);
52 break;
53 case ldmx::HcalID::HcalSection::BOTTOM:
54 histograms_.fill("passes_rec_bottom", ok);
55 break;
56 case ldmx::HcalID::HcalSection::LEFT:
57 histograms_.fill("passes_rec_left", ok);
58 break;
59 case ldmx::HcalID::HcalSection::RIGHT:
60 histograms_.fill("passes_rec_right", ok);
61 break;
62 }
63 }
64
65} // Analyze
66bool HcalGeometryVerifier::hitOk(const ldmx::HcalID id,
67 const std::array<double, 3> &position) {
68 const auto &geometry = getCondition<ldmx::HcalGeometry>(
70 auto [index_along, index_across, index_through]{determineIndices(id)};
71 const auto center_vec = geometry.getStripCenterPosition(id);
72 const std::array<double, 3> center{center_vec.X(), center_vec.Y(),
73 center_vec.Z()};
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::determineIndices(
126 const ldmx::HcalID id) {
127 const auto &geometry = getCondition<ldmx::HcalGeometry>(
129 const auto orientation{geometry.getScintillatorOrientation(id)};
130 const auto is_lr{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 (is_lr) {
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
#define DECLARE_ANALYZER(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.
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:42
void fill(const std::string &name, const T &val)
Fill a 1D histogram.
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:29
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78
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.