8#include "Framework/Exception/Exception.h"
21 ecal_dy_ = ps.
get<
double>(
"ecal_dy");
23 back_horizontal_parity_ = ps.
get<
int>(
"back_horizontal_parity");
24 side_3d_readout_ = ps.
get<
int>(
"side_3d_readout");
25 y_offset_ = ps.
get<
double>(
"y_offset");
27 auto detectors_valid = ps.
get<std::vector<std::string>>(
"detectors_valid");
30 is_prototype_ = std::find_if(detectors_valid.cbegin(), detectors_valid.cend(),
31 [](
const auto detector) {
32 return detector.find(
"ldmx-hcal-prototype") !=
34 }) != detectors_valid.cend();
38 ps.
get<std::vector<std::vector<double>>>(
"half_total_width");
39 zero_strip_ = ps.
get<std::vector<std::vector<double>>>(
"zero_strip");
43 layer_z_ = ps.
get<std::vector<std::vector<double>>>(
"layer_z", {});
45 ps.
get<std::vector<std::vector<int>>>(
"layer_long_axis", {});
47 ps.
get<std::vector<std::vector<double>>>(
"layer_bar_center", {});
49 ps.
get<std::vector<std::vector<double>>>(
"layer_strip_zero", {});
53 const auto n{
static_cast<std::size_t
>(
num_layers_.at(section))};
54 if (
layer_z_.at(section).size() != n ||
61 "Explicit layout does not match num_layers in section " +
62 std::to_string(section));
76 switch (getScintillatorOrientation(
id)) {
77 case ScintillatorOrientation::horizontal:
78 return x - center.X();
79 case ScintillatorOrientation::vertical:
80 return y - center.Y();
82 return z - center.Z();
87 const std::vector<double>& globalPosition,
const ldmx::HcalID&
id)
const {
88 const auto orientation{getScintillatorOrientation(
id)};
90 const unsigned int section{
92 ?
static_cast<unsigned int>(ldmx::HcalID::HcalSection::BACK)
95 case ldmx::HcalID::HcalSection::BACK:
96 switch (orientation) {
97 case ScintillatorOrientation::horizontal:
98 return {globalPosition[2], globalPosition[1], globalPosition[0]};
99 case ScintillatorOrientation::vertical:
100 return {globalPosition[2], globalPosition[0], globalPosition[1]};
102 EXCEPTION_RAISE(
"InvalidRotation",
103 "Attempted to rotate into an invalid "
104 "orientation for a scintillator bar!");
106 case ldmx::HcalID::HcalSection::TOP:
108 case ldmx::HcalID::HcalSection::BOTTOM:
109 switch (orientation) {
110 case ScintillatorOrientation::horizontal:
111 return {globalPosition[1], globalPosition[2], globalPosition[0]};
112 case ScintillatorOrientation::depth:
113 return {globalPosition[1], globalPosition[0], globalPosition[2]};
115 EXCEPTION_RAISE(
"InvalidRotation",
116 "Attempted to rotate into an invalid "
117 "orientation for a scintillator bar!");
119 case ldmx::HcalID::HcalSection::LEFT:
121 case ldmx::HcalID::HcalSection::RIGHT:
122 switch (orientation) {
123 case ScintillatorOrientation::vertical:
124 return {globalPosition[0], globalPosition[2], globalPosition[1]};
125 case ScintillatorOrientation::depth:
126 return globalPosition;
128 EXCEPTION_RAISE(
"InvalidRotation",
129 "Attempted to rotate into an invalid "
130 "orientation for a scintillator bar!");
136 EXCEPTION_RAISE(
"InvalidRotation",
137 "Attempted to rotate into an invalid "
138 "orientation for a scintillator bar!");
146 ? ScintillatorOrientation::horizontal
147 : ScintillatorOrientation::vertical;
151 switch (
id.section()) {
152 case ldmx::HcalID::HcalSection::TOP:
153 case ldmx::HcalID::HcalSection::BOTTOM:
156 return id.layer() % 2 == 0 ? ScintillatorOrientation::horizontal
157 : ScintillatorOrientation::depth;
159 case ldmx::HcalID::HcalSection::LEFT:
160 case ldmx::HcalID::HcalSection::RIGHT:
163 return id.layer() % 2 == 0 ? ScintillatorOrientation::vertical
164 : ScintillatorOrientation::depth;
165 case ldmx::HcalID::HcalSection::BACK:
167 return id.layer() % 2 == back_horizontal_parity_
168 ? ScintillatorOrientation::horizontal
169 : ScintillatorOrientation::vertical;
176 return id.layer() % 2 == back_horizontal_parity_
177 ? ScintillatorOrientation::horizontal
178 : ScintillatorOrientation::vertical;
181 switch (
id.section()) {
184 case ldmx::HcalID::HcalSection::TOP:
185 case ldmx::HcalID::HcalSection::BOTTOM:
186 return ScintillatorOrientation::horizontal;
187 case ldmx::HcalID::HcalSection::LEFT:
188 case ldmx::HcalID::HcalSection::RIGHT:
189 return ScintillatorOrientation::vertical;
190 case ldmx::HcalID::HcalSection::BACK:
192 return id.layer() % 2 == back_horizontal_parity_
193 ? ScintillatorOrientation::horizontal
194 : ScintillatorOrientation::vertical;
199 EXCEPTION_RAISE(
"InvalidRotation",
200 "Attempted to rotate into an invalid "
201 "orientation for a scintillator bar!");
205 for (
int layer = 1; layer <=
num_layers_[section]; ++layer) {
206 for (
int strip = 0; strip <
getNumStrips(section, layer); ++strip) {
207 HcalID id(section, layer, strip);
209 auto x = center_position.X();
210 auto y = center_position.Y();
211 auto z = center_position.Z();
212 std::cout <<
id <<
": Center position: (" << x <<
", " << y <<
", " << z
220 for (
unsigned int section = 0; section <
num_sections_; section++) {
221 for (
unsigned int layer = 1; layer <=
num_layers_[section]; layer++) {
222 for (
unsigned int strip = 0; strip <
getNumStrips(section, layer);
225 double x{-99999}, y{-99999}, z{-99999};
232 const auto orientation{getScintillatorOrientation(
id)};
242 const auto i_layer{layer - 1};
246 if (orientation == ScintillatorOrientation::horizontal) {
253 z =
layer_z_.at(section).at(i_layer);
254 }
else if (hcalsection == ldmx::HcalID::HcalSection::BACK) {
273 if (orientation == ScintillatorOrientation::horizontal) {
281 if (side_3d_readout_) {
292 switch (hcalsection) {
293 case ldmx::HcalID::HcalSection::BACK:
295 case ldmx::HcalID::HcalSection::LEFT:
296 case ldmx::HcalID::HcalSection::RIGHT:
297 if (orientation == ScintillatorOrientation::vertical) {
306 }
else if (orientation == ScintillatorOrientation::depth) {
313 if (section == ldmx::HcalID::HcalSection::LEFT) {
319 case ldmx::HcalID::HcalSection::BOTTOM:
320 case ldmx::HcalID::HcalSection::TOP:
321 if (orientation == ScintillatorOrientation::horizontal) {
336 if (orientation == ScintillatorOrientation::depth) {
343 if (section == ldmx::HcalID::HcalSection::BOTTOM) {
362 if (hcalsection == ldmx::HcalID::HcalSection::TOP or
363 hcalsection == ldmx::HcalID::HcalSection::BOTTOM) {
366 if (hcalsection == ldmx::HcalID::HcalSection::BOTTOM) {
374 if (hcalsection == ldmx::HcalID::HcalSection::RIGHT) {
383 ROOT::Math::XYZVector pos;
Class that translates HCal ID into positions of strip hits.
Class encapsulating parameters for configuring a processor.
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Implementation of HCal strip readout.
std::vector< double > layer_thickness_
Thickness of the layers in each section [mm].
bool hasSide3DReadout() const
Does the Side Hcal have 3D readout?
std::vector< int > double_ended_
Explicit layout: section read out at both ends.
std::vector< double > zero_layer_
Front of HCal relative to world geometry for each section [mm].
double ecal_dx_
Lenght of the Ecal (in x and y)
void buildStripPositionMap()
Map builder of HcalID and position.
std::vector< std::vector< double > > zero_strip_
The plane of the zero'th strip of each section [mm].
ROOT::Math::XYZVector getStripCenterPosition(ldmx::HcalID id) const
Get a strip center position from a combined hcal ID.
std::map< ldmx::HcalID, ROOT::Math::XYZVector > strip_position_map_
Map of the HcalID position of strip centers relative to world geometry.
double getDistanceAlongBar(ldmx::HcalID id, double x, double y, double z) const
Signed distance along the bar from the strip center [mm].
int getZeroStrip(int isection, int layer=1) const
Get the location of the zeroStrip in a given section and layer.
bool hasExplicitLayout() const
Are the strip positions given layer by layer (e.g.
std::vector< std::vector< double > > layer_bar_center_
Explicit layout: world along-bar coordinate of the bar centers [mm].
double getScintillatorLength(ldmx::HcalID id) const
Get the length of a scintillator bar.
void printPositionMap() const
Debugging utility, prints out the HcalID and corresponding value of all entries in the strip_position...
std::vector< std::vector< double > > scint_length_
Length of strips [mm].
std::vector< std::vector< double > > layer_z_
Explicit layout: world z of each layer center [mm].
HcalGeometry(const framework::config::Parameters &ps)
Class constructor, for use only by the provider.
int verbose_
Parameters that apply to all types of geometries Verbosity, not configurable but helpful if developin...
std::vector< std::vector< double > > half_total_width_
Half Total Width of Strips [mm].
double scint_width_
Width of Scintillator Strip [mm].
std::vector< double > rotateGlobalToLocalBarPosition(const std::vector< double > &globalPosition, const ldmx::HcalID &id) const
Coordinates that are given by Geant4 are typically global.
double getScintillatorWidth() const
Get the scitillator width.
double scint_thickness_
Thickness of scintillator.
std::vector< int > num_layers_
Number of layers in each section.
ScintillatorOrientation
Encodes the orientation of a bar.
int getNumStrips(int isection, int layer=1) const
Get the number of strips per layer for that section and layer.
std::vector< std::vector< double > > layer_strip_zero_
Explicit layout: world transverse coordinate of strip 0 [mm].
std::vector< std::vector< int > > num_strips_
Number of strips per layer in each section and each layer.
std::vector< std::vector< int > > layer_long_axis_
Explicit layout: 0 = bar long along x, 1 = along y.
double getHalfTotalWidth(int isection, int layer=1) const
Get the half total width of a layer for a given section(strip) for back(side) Hcal.
int num_sections_
Number of sections.
Implements detector ids for HCal subdetector.
HcalSection
Encodes the section of the HCal based on the 'section' field value.
All classes in the ldmx-sw project use this namespace.