Process the event and put new data products into it.
35 {
38
39 std::vector<ldmx::HcalHit> hcalRecHits;
40
42 input_pass_name_)};
43 std::unordered_map<unsigned int, std::vector<const ldmx::SimCalorimeterHit*>>
44 hits_by_id{};
45
46
47 for (const auto& hit : simHits) {
48 auto id{hit.getID()};
49 auto found{hits_by_id.find(id)};
50 if (found == hits_by_id.end()) {
51 hits_by_id[id] = std::vector<const ldmx::SimCalorimeterHit*>{&hit};
52 } else {
53 hits_by_id[id].push_back(&hit);
54 }
55 }
56 for (const auto& [barID, simhits_in_bar] : hits_by_id) {
58 double edep{};
59 double time{};
60 std::vector<double> pos{0, 0, 0};
61 for (auto hit : simhits_in_bar) {
62 edep += hit->getEdep();
63 double edep_hit = hit->getEdep();
64 time += hit->getTime() * edep_hit;
65 auto hitPos{hit->getPosition()};
66 pos[0] += hitPos[0] * edep_hit;
67 pos[1] += hitPos[1] * edep_hit;
68 pos[2] += hitPos[2] * edep_hit;
69 }
71
72
73 double mean_pe{(edep / mev_per_mip_) * pe_per_mip_};
74 double xpos{pos[0] / edep};
75 double ypos{pos[1] / edep};
76 double zpos{pos[2] / edep};
77 time /= edep;
78
79 auto orientation{hcalGeometry.getScintillatorOrientation(barID)};
80 double half_total_width{
81 hcalGeometry.getHalfTotalWidth(hitID.section(), hitID.layer())};
82 double scint_bar_length{hcalGeometry.getScintillatorLength(hitID)};
83
84 auto stripCenter{hcalGeometry.getStripCenterPosition(hitID)};
85 if (hitID.section() == ldmx::HcalID::HcalSection::BACK) {
86 double distance_along_bar =
87 (orientation ==
88 ldmx::HcalGeometry::ScintillatorOrientation::horizontal)
89 ? xpos
90 : ypos;
91 if (orientation ==
92 ldmx::HcalGeometry::ScintillatorOrientation::horizontal) {
93 ypos = stripCenter.y();
94 xpos += (*position_resolution_smear_)(rng_);
95 } else {
96 xpos = stripCenter.x();
97 ypos += (*position_resolution_smear_)(rng_);
98 }
99 zpos = stripCenter.z();
100
101 mean_pe *= exp(1. / attenuation_length_);
102 double mean_pe_close =
103 mean_pe * exp(-1. *
104 ((half_total_width - distance_along_bar) /
105 (scint_bar_length * 0.5)) /
106 attenuation_length_);
107 double mean_pe_far =
108 mean_pe * exp(-1. *
109 ((half_total_width + distance_along_bar) /
110 (scint_bar_length * 0.5)) /
111 attenuation_length_);
112 int PE_close{
113 std::poisson_distribution<int>(mean_pe_close + mean_noise_)(rng_)};
114 int PE_far{
115 std::poisson_distribution<int>(mean_pe_far + mean_noise_)(rng_)};
116 recHit.
setPE(PE_close + PE_far);
117 recHit.
setMinPE(std::min(PE_close, PE_far));
118 } else {
119
120 int PE{std::poisson_distribution<int>(mean_pe + mean_noise_)(rng_)};
123
124
125
126 if (orientation ==
127 ldmx::HcalGeometry::ScintillatorOrientation::horizontal) {
128 xpos += (*position_resolution_smear_)(rng_);
129 ypos = stripCenter.y();
130 zpos = stripCenter.z();
131 } else if (orientation ==
132 ldmx::HcalGeometry::ScintillatorOrientation::vertical) {
133 xpos = stripCenter.x();
134 ypos += (*position_resolution_smear_)(rng_);
135 zpos = stripCenter.z();
136 } else if (orientation ==
137 ldmx::HcalGeometry::ScintillatorOrientation::depth) {
138 xpos = stripCenter.x();
139 ypos = stripCenter.y();
140 zpos += (*position_resolution_smear_)(rng_);
141 } else {
142 xpos = stripCenter.x();
143 ypos = stripCenter.y();
144 zpos = stripCenter.z();
145 ldmx_log(warn) << "Bar orientation not found. Hit" << hitID.raw()
146 << "positioned at bar center.";
147 }
148 }
149
150 recHit.
setID(hitID.raw());
161 }
162 event.add(output_coll_name_, hcalRecHits);
163}
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.
void setSection(int section)
Set the section for this hit.
void setMinPE(float minpe)
Set the minimum number of photoelectrons estimated for this hit.
void setOrientation(int orientation)
Set if the bar is orientied in X / Y / Z meanig 0 / 1 / 2, respectively.
void setStrip(int strip)
Set the strip for this hit.
void setLayer(int layer)
Set the layer for this hit.
void setPE(float pe)
Set the number of photoelectrons estimated for this hit.
Implements detector ids for HCal subdetector.
Stores simulated calorimeter hit information.