LDMX Software
HcalSimpleDigiAndRecProducer.cxx
1#include "Hcal/HcalSimpleDigiAndRecProducer.h"
2
4#include "DetDescr/HcalID.h"
8
9namespace hcal {
10
13 input_coll_name_ = ps.get<std::string>("input_coll_name");
14 input_pass_name_ = ps.get<std::string>("input_pass_name");
15 output_coll_name_ = ps.get<std::string>("output_coll_name");
16 mev_per_mip_ = ps.get<double>("mev_per_mip");
17 pe_per_mip_ = ps.get<double>("pe_per_mip");
18 attenuation_length_ = ps.get<double>("attenuation_length");
19 readout_threshold_ = ps.get<int>("readout_threshold");
20 mean_noise_ = ps.get<double>("mean_noise");
21 position_resolution_smear_ =
22 std::make_unique<std::normal_distribution<double>>(
23 0.0, ps.get<double>("position_resolution"));
24}
25
27 noise_generator_ = std::make_unique<ldmx::NoiseGenerator>(mean_noise_, false);
28 // hard-code this number, create noise hits_ for non-zero PEs!
29 noise_generator_->setNoiseThreshold(1);
33 noise_generator_->seedGenerator(
34 rseed.getSeed("HcalSimpleDigiAndRecProducer::NoiseGenerator"));
35 rng_.seed(rseed.getSeed("HcalSimpleDigiAndRecProducer"));
36}
37
39 const auto& hcal_geometry = getCondition<ldmx::HcalGeometry>(
41
42 std::vector<ldmx::HcalHit> hcal_rec_hits;
43
44 auto sim_hits{event.getCollection<ldmx::SimCalorimeterHit>(input_coll_name_,
45 input_pass_name_)};
46 std::unordered_map<unsigned int, std::vector<const ldmx::SimCalorimeterHit*>>
47 hits_by_id{};
48 // Important, has to be a reference so that we don't take the address of a
49 // variable that goes out of scope!
50 for (const auto& hit : sim_hits) {
51 auto id{hit.getID()};
52 auto found{hits_by_id.find(id)};
53 if (found == hits_by_id.end()) {
54 hits_by_id[id] = std::vector<const ldmx::SimCalorimeterHit*>{&hit};
55 } else {
56 hits_by_id[id].push_back(&hit);
57 }
58 }
59 for (const auto& [barID, simhits_in_bar] : hits_by_id) {
60 ldmx::HcalHit& rec_hit = hcal_rec_hits.emplace_back();
61 double edep{};
62 double time{};
63 std::vector<double> pos{0, 0, 0};
64 for (auto hit : simhits_in_bar) {
65 edep += hit->getEdep();
66 double edep_hit = hit->getEdep();
67 time += hit->getTime() * edep_hit;
68 auto hit_pos{hit->getPosition()};
69 pos[0] += hit_pos[0] * edep_hit;
70 pos[1] += hit_pos[1] * edep_hit;
71 pos[2] += hit_pos[2] * edep_hit;
72 }
73 ldmx::HcalID hit_id{barID};
74
75 // Position smearing
76 double mean_pe{(edep / mev_per_mip_) * pe_per_mip_};
77 double xpos{pos[0] / edep};
78 double ypos{pos[1] / edep};
79 double zpos{pos[2] / edep};
80 time /= edep;
81
82 auto orientation{hcal_geometry.getScintillatorOrientation(barID)};
83 double half_total_width{
84 hcal_geometry.getHalfTotalWidth(hit_id.section(), hit_id.layer())};
85 double scint_bar_length{hcal_geometry.getScintillatorLength(hit_id)};
86
87 auto strip_center{hcal_geometry.getStripCenterPosition(hit_id)};
88 if (hit_id.section() == ldmx::HcalID::HcalSection::BACK) {
89 double distance_along_bar =
90 (orientation ==
91 ldmx::HcalGeometry::ScintillatorOrientation::horizontal)
92 ? xpos
93 : ypos;
94 if (orientation ==
95 ldmx::HcalGeometry::ScintillatorOrientation::horizontal) {
96 ypos = strip_center.y();
97 xpos += (*position_resolution_smear_)(rng_);
98 } else {
99 xpos = strip_center.x();
100 ypos += (*position_resolution_smear_)(rng_);
101 }
102 zpos = strip_center.z();
103 // Attenuation
104 mean_pe *= exp(1. / attenuation_length_);
105 double mean_pe_close =
106 mean_pe * exp(-1. *
107 ((half_total_width - distance_along_bar) /
108 (scint_bar_length * 0.5)) /
109 attenuation_length_);
110 double mean_pe_far =
111 mean_pe * exp(-1. *
112 ((half_total_width + distance_along_bar) /
113 (scint_bar_length * 0.5)) /
114 attenuation_length_);
115 int pe_close{
116 std::poisson_distribution<int>(mean_pe_close + mean_noise_)(rng_)};
117 int pe_far{
118 std::poisson_distribution<int>(mean_pe_far + mean_noise_)(rng_)};
119 rec_hit.setPE(pe_close + pe_far);
120 rec_hit.setMinPE(std::min(pe_close, pe_far));
121 } else {
122 // Side HCAL, no attenuation business since single ended readout
123 int pe{std::poisson_distribution<int>(mean_pe + mean_noise_)(rng_)};
124 rec_hit.setPE(pe);
125 rec_hit.setMinPE(pe);
126
127 // Checks orientation of side Hcal bars, sets center positions and add
128 // smearing along bar orientation axis
129 if (orientation ==
130 ldmx::HcalGeometry::ScintillatorOrientation::horizontal) {
131 xpos += (*position_resolution_smear_)(rng_);
132 ypos = strip_center.y();
133 zpos = strip_center.z();
134 } else if (orientation ==
135 ldmx::HcalGeometry::ScintillatorOrientation::vertical) {
136 xpos = strip_center.x();
137 ypos += (*position_resolution_smear_)(rng_);
138 zpos = strip_center.z();
139 } else if (orientation ==
140 ldmx::HcalGeometry::ScintillatorOrientation::depth) {
141 xpos = strip_center.x();
142 ypos = strip_center.y();
143 zpos += (*position_resolution_smear_)(rng_);
144 } else {
145 xpos = strip_center.x();
146 ypos = strip_center.y();
147 zpos = strip_center.z();
148 ldmx_log(warn) << "Bar orientation not found. Hit" << hit_id.raw()
149 << "positioned at bar center.";
150 }
151 }
152
153 rec_hit.setID(hit_id.raw());
154 rec_hit.setXPos(xpos);
155 rec_hit.setNoise(false);
156 rec_hit.setYPos(ypos);
157 rec_hit.setZPos(zpos);
158 rec_hit.setTime(time);
159 rec_hit.setSection(hit_id.section());
160 rec_hit.setStrip(hit_id.strip());
161 rec_hit.setLayer(hit_id.layer());
162 rec_hit.setEnergy(edep);
163 rec_hit.setOrientation(static_cast<int>(orientation));
164 }
165 event.add(output_coll_name_, hcal_rec_hits);
166}
167
168} // namespace hcal
169
#define DECLARE_PRODUCER(CLASS)
Macro which allows the framework to construct a producer 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 that defines an HCal sensitive detector.
Conditions object for random number seeds.
Class which stores simulated calorimeter hit information.
const T & getCondition(const std::string &condition_name)
Access a conditions object for the current event.
Implements an event buffer system for storing event data.
Definition Event.h:40
System for consistent seeding of random number generators.
static const std::string CONDITIONS_OBJECT_NAME
Conditions object name.
uint64_t getSeed(const std::string &name) const
Access a given seed by name.
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
void produce(framework::Event &event) override
Process the event and put new data products into it.
void onNewRun(const ldmx::RunHeader &runHeader) override
Callback for the EventProcessor to take any necessary action when the run being processed changes.
void configure(framework::config::Parameters &ps) override
Callback for the EventProcessor to configure itself from the given set of parameters.
void setYPos(float ypos)
Set the Y position of the hit [mm].
void setID(int id)
Set the detector ID.
void setZPos(float zpos)
Set the Z position of the hit [mm].
void setXPos(float xpos)
Set the X position of the hit [mm].
void setTime(float time)
Set the time of the hit [ns].
void setEnergy(float energy)
Set the calorimetric energy of the hit, corrected for sampling factors [MeV].
void setNoise(bool yes)
Set if this hit is a noise hit.
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
void setSection(int section)
Set the section for this hit.
Definition HcalHit.h:166
void setMinPE(float minpe)
Set the minimum number of photoelectrons estimated for this hit.
Definition HcalHit.h:160
void setOrientation(int orientation)
Set if the bar is orientied in X / Y / Z meanig 0 / 1 / 2, respectively.
Definition HcalHit.h:234
void setStrip(int strip)
Set the strip for this hit.
Definition HcalHit.h:178
void setLayer(int layer)
Set the layer for this hit.
Definition HcalHit.h:172
void setPE(float pe)
Set the number of photoelectrons estimated for this hit.
Definition HcalHit.h:153
Implements detector ids for HCal subdetector.
Definition HcalID.h:19
Run-specific configuration and data stored in its own output TTree alongside the event TTree in the o...
Definition RunHeader.h:68
Stores simulated calorimeter hit information.