27 rec_hit_coll_name_, rec_hit_pass_name_)};
29 ecal_sim_hit_coll_, ecal_sim_hit_pass_)};
31 cluster_coll_name_, cluster_pass_name_)};
35 int nbr_of_electrons{
event.getElectronCount()};
41 std::map<int, int> layer_cluster_count;
42 for (
const auto& cluster : ecal_clusters) {
43 auto layer = cluster.getLayer();
44 layer_cluster_count[layer]++;
47 int total_clusters = 0;
48 for (
const auto& [layer, count] : layer_cluster_count) {
49 total_clusters += count;
52 int n_ecal_clusters = 0;
53 if (layer_cluster_count.size() != 0) {
54 n_ecal_clusters =
static_cast<int>(std::round(
55 static_cast<double>(total_clusters) / layer_cluster_count.size()));
58 ldmx_log(info) <<
"Avg number of clusters per layer: " << n_ecal_clusters;
62 histograms_.
fill(
"number_of_clusters_first_layer", layer_cluster_count[0]);
65 if (n_ecal_clusters == nbr_of_electrons) {
68 }
else if (n_ecal_clusters < nbr_of_electrons) {
71 }
else if (n_ecal_clusters > nbr_of_electrons) {
76 std::unordered_map<int, std::pair<int, std::vector<double>>> hit_info;
77 hit_info.reserve(ecal_rec_hits.size());
80 std::vector<std::vector<float>> sp_electron_positions;
82 "EcalScoringPlaneHits", ecal_sp_hits_passname_)};
84 std::vector<ldmx::SimTrackerHit> sorted_sp_hits = ecal_sp_hits;
85 std::sort(sorted_sp_hits.begin(), sorted_sp_hits.end(),
87 return a.getTrackID() < b.getTrackID();
90 ldmx_log(trace) <<
"Number of ECal Scoring Plane Hits: "
91 << sorted_sp_hits.size();
95 unsigned int n_filled = 0;
97 if (sp_hit.getPdgID() != 11)
continue;
98 if (sp_hit.getMomentum()[2] <= 0)
continue;
101 if (hit_id.
plane() != 31)
continue;
102 if (n_filled < nbr_of_electrons) {
103 ldmx_log(trace) <<
"\tSP Hit to be added with Track ID : "
104 << sp_hit.getTrackID() <<
", SP Hit Position ("
105 << sp_hit.getPosition()[0] <<
", "
106 << sp_hit.getPosition()[1] <<
", "
107 << sp_hit.getPosition()[2] <<
") mm";
108 sp_electron_positions.push_back(sp_hit.getPosition());
113 ldmx_log(info) <<
"Number of ECal CLUE clusters: " << n_ecal_clusters
114 <<
", TS counted electrons: " << nbr_of_electrons
115 <<
", SP electrons: " << sp_electron_positions.size();
117 double sp_ele_dist{9999.};
118 if (nbr_of_electrons == 2 && sp_electron_positions.size() > 1) {
121 std::vector<float> pos1;
122 std::vector<float> pos2;
123 pos1 = sp_electron_positions[0];
124 pos2 = sp_electron_positions[1];
125 sp_ele_dist = std::sqrt((pos1[0] - pos2[0]) * (pos1[0] - pos2[0]) +
126 (pos1[1] - pos2[1]) * (pos1[1] - pos2[1]));
130 ldmx_log(trace) <<
"Distance between the two e- in the ECal scoring plane: "
131 << sp_ele_dist <<
" mm";
134 ldmx_log(trace) <<
"Loop over the rechits and find the matching simhits";
135 for (
const auto& hit : ecal_rec_hits) {
136 auto it = std::find_if(
137 ecal_sim_hits.begin(), ecal_sim_hits.end(),
138 [&hit](
const auto& sim_hit) { return sim_hit.getID() == hit.getID(); });
139 if (it != ecal_sim_hits.end()) {
142 int prev_ancestor = 0;
145 std::vector<double> edep;
146 edep.resize(nbr_of_electrons + 1);
147 for (
int i = 0; i < it->getNumberOfContribs(); i++) {
149 const auto& contrib = it->getContrib(i);
151 ancestor = contrib.origin_id_;
153 if (ancestor <= nbr_of_electrons) edep[ancestor] += contrib.edep_;
154 if (!tagged && i != 0 && prev_ancestor != ancestor) {
160 prev_ancestor = ancestor;
167 hit_info.insert({hit.getID(), std::make_pair(tag, edep)});
172 int clustered_hits = 0;
173 ldmx_log(trace) <<
"Loop over the clusters, N = " << n_ecal_clusters;
174 for (
const auto& cl : ecal_clusters) {
175 auto layer = cl.getLayer();
176 ldmx_log(trace) <<
"Cluster in layer " << layer
177 <<
", energy: " << cl.getEnergy()
178 <<
", number of hits: " << cl.getHitIDs().size();
179 auto cluster_centroid_x = cl.getCentroidX();
180 auto cluster_centroid_y = cl.getCentroidY();
181 auto cluster_rms_x = cl.getRMSX();
182 auto cluster_rms_y = cl.getRMSY();
185 double min_distance = 9999.;
186 double sp_clue_x_residuals = 9999.;
187 double sp_clue_y_residuals = 9999.;
188 for (
const auto& sp_pos : sp_electron_positions) {
189 double distance = std::sqrt(
190 (sp_pos[0] - cluster_centroid_x) * (sp_pos[0] - cluster_centroid_x) +
191 (sp_pos[1] - cluster_centroid_y) * (sp_pos[1] - cluster_centroid_y));
192 if (distance < min_distance) {
193 min_distance = distance;
194 sp_clue_x_residuals = sp_pos[0] - cluster_centroid_x;
195 sp_clue_y_residuals = sp_pos[1] - cluster_centroid_y;
199 ldmx_log(trace) <<
"\tCluster centroid: (" << cluster_centroid_x <<
" +/- "
200 << cluster_rms_x <<
", " << cluster_centroid_y <<
" +/- "
202 <<
" mm; min distance to SP electron: " << min_distance
213 std::vector<double> n_hits_from_electron;
214 n_hits_from_electron.resize(nbr_of_electrons + 1);
216 std::vector<double> energy_from_electron;
217 energy_from_electron.resize(nbr_of_electrons + 1);
218 double energy_sum = 0.;
221 const auto& hit_ids = cl.getHitIDs();
222 for (
const auto&
id : hit_ids) {
224 auto it = hit_info.find(
id);
225 if (it != hit_info.end()) {
228 auto id_electron = t.first;
230 auto energies = t.second;
232 n_hits_from_electron[id_electron]++;
235 double hit_energy_sum = 0.;
236 for (
int i = 1; i < nbr_of_electrons + 1; i++) {
238 if (energies[i] > 0.) {
239 energy_sum += energies[i];
242 energy_from_electron[i] += energies[i];
247 if (id_electron == 0) energy_from_electron[0] += hit_energy_sum;
248 energy_sum += hit_energy_sum;
254 if (energy_sum > 0) {
256 double max_energy_contribution = *max_element(
257 energy_from_electron.begin(), energy_from_electron.end());
260 100. * (max_energy_contribution / energy_sum));
261 if (energy_from_electron[0] > 0.)
263 100. * (energy_from_electron[0] / energy_sum));
266 cl.getHitIDs().size());
268 100. * (max_energy_contribution / energy_sum));
270 if (nbr_of_electrons == 2) {
272 100. * (max_energy_contribution / energy_sum));
276 double n_max = *max_element(n_hits_from_electron.begin(),
277 n_hits_from_electron.end());
282 histograms_.
fill(
"clusterless_hits", (ecal_rec_hits.size() - clustered_hits));
285 "clusterless_hits_percentage",
286 100. * (ecal_rec_hits.size() - clustered_hits) / ecal_rec_hits.size());
290 if (n_ecal_clusters > n_ecal_clusters_min_) {
297 if (n_ecal_clusters > n_ecal_clusters_min_) {