Process the event and put new data products into it.
38 {
39 auto start = std::chrono::high_resolution_clock::now();
40 nevents_++;
41
42 if (!event.
exists(hit_coll_name_, hit_coll_passname_))
return;
43
44 const auto calo_hits = event.getObject<std::vector<TrigCaloHit>>(
45 hit_coll_name_, hit_coll_passname_);
46
47 if (calorimeter_type_is_hcal_) {
48 std::vector<TrigCaloHit> sorted_hits;
49 int even_matrix[24][5] = {};
50 int even_start[5] = {99, 99, 99, 99, 99};
51 int even_end[5] = {};
52 int even_counts[5] = {};
53 int odd_matrix[24][5] = {};
54 int odd_start[5] = {99, 99, 99, 99, 99};
55 int odd_end[5] = {};
56 int odd_counts[5] = {};
57
58 constexpr int layer_start = 80;
59
60 for (const auto& tp : calo_hits) {
61 if (tp.section() > 0 || tp.energy() < hcal_min_energy_ ||
62 tp.layer() > 47) {
63 continue;
64 }
65
66 sorted_hits.push_back(tp);
67 const int layer_index = tp.layer() / 2;
68 const int strip = tp.strip();
69 if (tp.layer() % 2) {
70 odd_matrix[layer_index][strip] = 1;
71 odd_start[strip] = std::min(odd_start[strip], tp.layer());
72 odd_end[strip] = std::max(odd_end[strip], tp.layer());
73 } else {
74 even_matrix[layer_index][strip] = 1;
75 even_start[strip] = std::min(even_start[strip], tp.layer());
76 even_end[strip] = std::max(even_end[strip], tp.layer());
77 }
78 }
79
80 for (int i = 0; i < 24; i++) {
81 for (int j = 0; j < 5; j++) {
82 if (even_matrix[i][j]) {
83 even_counts[j]++;
84 }
85 if (odd_matrix[i][j]) {
86 odd_counts[j]++;
87 }
88 }
89 }
90
91
92 std::vector<TrigMip> mips;
93
94 for (int i = 0; i < 5; i++) {
95 if (odd_start[i] < layer_start) {
96 TrigMip m;
97 m.setStartLayer(odd_start[i]);
98 m.setEndLayer(odd_end[i]);
99 m.setNHits(odd_counts[i]);
100 m.setLength(odd_end[i] - odd_start[i] + 1);
101 int holes = m.length() / 2 - m.nHits();
102 if (holes < 0) {
103 holes = 0;
104 }
105 m.setNHoles(holes);
106 mips.push_back(m);
107 }
108 if (even_start[i] < layer_start) {
109 TrigMip m;
110 m.setStartLayer(even_start[i]);
111 m.setEndLayer(even_end[i]);
112 m.setNHits(even_counts[i]);
113 m.setLength(even_end[i] - even_start[i] + 1);
114 int holes = m.length() / 2 - m.nHits();
115 if (holes < 0) {
116 holes = 0;
117 }
118 m.setNHoles(holes);
119 mips.push_back(m);
120 }
121 }
122
123 std::sort(mips.begin(), mips.end());
124 event.add(pass_coll_name_, mips);
125
126 auto end = std::chrono::high_resolution_clock::now();
127 auto time_diff = end - start;
128 processing_time_ +=
129 std::chrono::duration<double, std::milli>(time_diff).count();
130
131 return;
132
133 } else {
134 const float radius_cut_2 = search_radius_ * search_radius_;
135 std::map<int, std::vector<TrigCaloHit>> layer_hits;
136 std::set<const TrigCaloHit*> used_hits;
137 std::vector<std::vector<const TrigCaloHit*>> candidate_tracks;
138 std::map<const TrigCaloHit*, size_t> hit_to_best_track;
139
140
141 for (const auto& hit : calo_hits) {
142 if (hit.section() > 0 || hit.layer() > max_layer_) continue;
143 layer_hits[hit.layer()].push_back(hit);
144 }
145
146
147 for (const auto& [seed_layer, seeds] : layer_hits) {
148 for (const auto& seed : seeds) {
149
150 if (used_hits.count(&seed) || seed.energy() < ecal_min_energy_ ||
151 seed.energy() > ecal_max_energy_) {
152 continue;
153 }
154
155 std::vector<const TrigCaloHit*> track{&seed};
156
157 const TrigCaloHit* last = &seed;
158 int holes = 0;
159 float growth_factor = 1.0f;
160
161
162 for (int l = seed.layer() + 1; l <= max_layer_; ++l) {
163 const TrigCaloHit* best_hit = nullptr;
164
165 float best_d_r_2 = radius_cut_2 * growth_factor * growth_factor;
166
167 for (const auto& cand : layer_hits[l]) {
168 if (used_hits.count(&cand) || cand.energy() < ecal_min_energy_ ||
169 cand.energy() > ecal_max_energy_) {
170 continue;
171 }
172
173
174 const float layer_shift_last =
175 (last->layer() % 2 == 0) ? 0.0f : 4.82f;
176 const float layer_shift_cand =
177 (cand.layer() % 2 == 0) ? 0.0f : 4.82f;
178 const float dx = (cand.positionX() - layer_shift_cand) -
179 (last->positionX() - layer_shift_last);
180 const float dy = cand.positionY() - last->positionY();
181 const float d_r_2 = dx * dx + dy * dy;
182
183 if (d_r_2 < best_d_r_2) {
184 best_d_r_2 = d_r_2;
185
186 best_hit = &cand;
187 }
188 }
189
190 if (best_hit) {
191
192 track.push_back(best_hit);
193 last = best_hit;
194 holes = 0;
195
196 growth_factor = 1.0f;
197 } else {
198 holes++;
199
200 growth_factor = static_cast<float>(holes + 1);
201 }
202 }
203
204 bool is_isolated = true;
205 if (track.size() >= min_track_length_) {
206
207 for (const auto* hit : track) {
208 const int layer = hit->layer();
209 const float hit_x = hit->positionX();
210 const float hit_y = hit->positionY();
211 float sum_e = 0.0f;
212
213 for (const auto& cand : layer_hits[layer]) {
214
215 if (&cand == hit) continue;
216
217 const float dx = cand.positionX() - hit_x;
218 const float dy = cand.positionY() - hit_y;
219 const float d_r_2 = dx * dx + dy * dy;
220
221 if (d_r_2 < radius_cut_2) {
222 sum_e += cand.energy();
223 }
224 }
225
226 if (sum_e >= isolation_e_cut_) {
227 is_isolated = false;
228
229 used_hits.insert(hit);
230 break;
231 }
232 }
233
234 if (!is_isolated) {
235
236 continue;
237 }
238
239 const size_t i = candidate_tracks.size();
240 candidate_tracks.push_back(track);
241
242 for (const auto* hit : track) {
243 if (!hit_to_best_track.count(hit) ||
244 candidate_tracks[i].size() >
245 candidate_tracks[hit_to_best_track[hit]].size()) {
246 hit_to_best_track[hit] = i;
247
248 used_hits.insert(hit);
249 }
250 }
251 }
252 }
253 }
254
255 std::set<size_t> valid_track_i_ds;
256 for (const auto& [hit, idx] : hit_to_best_track) {
257 valid_track_i_ds.insert(idx);
258 }
259
260 std::vector<TrigMip> mips;
261 for (const size_t idx : valid_track_i_ds) {
262 const auto& track = candidate_tracks[idx];
263 TrigMip mip;
264 mip.setStartLayer(track.front()->layer());
265 mip.setEndLayer(track.back()->layer());
266 mip.setNHits(track.size());
267 mip.setLength(track.back()->layer() - track.front()->layer());
268 int holes = mip.length() - mip.nHits();
269 if (holes < 0) {
270 holes = 0;
271 }
272 mip.setNHoles(holes);
273
274 const float hole_fraction =
275 static_cast<float>(mip.nHoles()) / mip.length();
276
277 if (hole_fraction >= hole_fraction_max_) continue;
278
279 float total_isolation_e_sum = 0.0f;
280 for (const auto* hit : track) {
281 const int layer = hit->layer();
282 const float hit_x = hit->positionX();
283 const float hit_y = hit->positionY();
284 for (const auto& cand : layer_hits[layer]) {
285 if (&cand == hit) continue;
286 const float dx = cand.positionX() - hit_x;
287 const float dy = cand.positionY() - hit_y;
288 const float d_r_2 = dx * dx + dy * dy;
289 if (d_r_2 < radius_cut_2) {
290 total_isolation_e_sum += cand.energy();
291 }
292 }
293 }
294 mip.setSumEinIsolationRegion(total_isolation_e_sum);
295 mips.push_back(mip);
296 }
297
298 std::sort(mips.begin(), mips.end());
299 event.add(pass_coll_name_, mips);
300 }
301
302 auto end = std::chrono::high_resolution_clock::now();
303 auto time_diff = end - start;
304 processing_time_ +=
305 std::chrono::duration<double, std::milli>(time_diff).count();
306}
bool exists(const std::string &name, const std::string &passName, bool unique=true) const
Check for the existence of an object or collection with the given name and pass name in the event.