34 auto start = std::chrono::high_resolution_clock::now();
37 if (!event.
exists(hit_coll_name_, hit_coll_passname_))
return;
39 const auto calo_hits =
event.getObject<std::vector<TrigCaloHit>>(
40 hit_coll_name_, hit_coll_passname_);
42 if (calorimeter_type_is_hcal_) {
43 std::vector<TrigCaloHit> sorted_hits;
44 int even_matrix[24][5] = {};
45 int even_start[5] = {99, 99, 99, 99, 99};
47 int even_counts[5] = {};
48 int odd_matrix[24][5] = {};
49 int odd_start[5] = {99, 99, 99, 99, 99};
51 int odd_counts[5] = {};
53 constexpr int layer_start = 80;
55 for (
const auto& tp : calo_hits) {
56 if (tp.section() > 0 || tp.energy() < hcal_min_energy_ ||
61 sorted_hits.push_back(tp);
62 const int layer_index = tp.layer() / 2;
63 const int strip = tp.strip();
65 odd_matrix[layer_index][strip] = 1;
66 odd_start[strip] = std::min(odd_start[strip], tp.layer());
67 odd_end[strip] = std::max(odd_end[strip], tp.layer());
69 even_matrix[layer_index][strip] = 1;
70 even_start[strip] = std::min(even_start[strip], tp.layer());
71 even_end[strip] = std::max(even_end[strip], tp.layer());
75 for (
int i = 0; i < 24; i++) {
76 for (
int j = 0; j < 5; j++) {
77 if (even_matrix[i][j]) {
80 if (odd_matrix[i][j]) {
87 std::vector<TrigMip> mips;
89 for (
int i = 0; i < 5; i++) {
90 if (odd_start[i] < layer_start) {
92 m.setStartLayer(odd_start[i]);
93 m.setEndLayer(odd_end[i]);
94 m.setNHits(odd_counts[i]);
95 m.setLength(odd_end[i] - odd_start[i] + 1);
96 int holes = m.length() / 2 - m.nHits();
103 if (even_start[i] < layer_start) {
105 m.setStartLayer(even_start[i]);
106 m.setEndLayer(even_end[i]);
107 m.setNHits(even_counts[i]);
108 m.setLength(even_end[i] - even_start[i] + 1);
109 int holes = m.length() / 2 - m.nHits();
118 std::sort(mips.begin(), mips.end());
119 event.add(pass_coll_name_, mips);
121 auto end = std::chrono::high_resolution_clock::now();
122 auto time_diff = end - start;
124 std::chrono::duration<double, std::milli>(time_diff).count();
129 const float radius_cut_2 = search_radius_ * search_radius_;
130 std::map<int, std::vector<TrigCaloHit>> layer_hits;
131 std::set<const TrigCaloHit*> used_hits;
132 std::vector<std::vector<const TrigCaloHit*>> candidate_tracks;
133 std::map<const TrigCaloHit*, size_t> hit_to_best_track;
136 for (
const auto& hit : calo_hits) {
137 if (hit.section() > 0 || hit.layer() > max_layer_)
continue;
138 layer_hits[hit.layer()].push_back(hit);
142 for (
const auto& [seed_layer, seeds] : layer_hits) {
143 for (
const auto& seed : seeds) {
145 if (used_hits.count(&seed) || seed.energy() < ecal_min_energy_ ||
146 seed.energy() > ecal_max_energy_) {
150 std::vector<const TrigCaloHit*> track{&seed};
154 float growth_factor = 1.0f;
157 for (
int l = seed.layer() + 1; l <= max_layer_; ++l) {
160 float best_d_r_2 = radius_cut_2 * growth_factor * growth_factor;
162 for (
const auto& cand : layer_hits[l]) {
163 if (used_hits.count(&cand) || cand.energy() < ecal_min_energy_ ||
164 cand.energy() > ecal_max_energy_) {
169 const float layer_shift_last =
170 (last->layer() % 2 == 0) ? 0.0f : 4.82f;
171 const float layer_shift_cand =
172 (cand.layer() % 2 == 0) ? 0.0f : 4.82f;
173 const float dx = (cand.positionX() - layer_shift_cand) -
174 (last->positionX() - layer_shift_last);
175 const float dy = cand.positionY() - last->positionY();
176 const float d_r_2 = dx * dx + dy * dy;
178 if (d_r_2 < best_d_r_2) {
187 track.push_back(best_hit);
191 growth_factor = 1.0f;
195 growth_factor =
static_cast<float>(holes + 1);
199 bool is_isolated =
true;
200 if (track.size() >= min_track_length_) {
202 for (
const auto* hit : track) {
203 const int layer = hit->layer();
204 const float hit_x = hit->positionX();
205 const float hit_y = hit->positionY();
208 for (
const auto& cand : layer_hits[layer]) {
210 if (&cand == hit)
continue;
212 const float dx = cand.positionX() - hit_x;
213 const float dy = cand.positionY() - hit_y;
214 const float d_r_2 = dx * dx + dy * dy;
216 if (d_r_2 < radius_cut_2) {
217 sum_e += cand.energy();
221 if (sum_e >= isolation_e_cut_) {
224 used_hits.insert(hit);
234 const size_t i = candidate_tracks.size();
235 candidate_tracks.push_back(track);
237 for (
const auto* hit : track) {
238 if (!hit_to_best_track.count(hit) ||
239 candidate_tracks[i].size() >
240 candidate_tracks[hit_to_best_track[hit]].size()) {
241 hit_to_best_track[hit] = i;
243 used_hits.insert(hit);
250 std::set<size_t> valid_track_i_ds;
251 for (
const auto& [hit, idx] : hit_to_best_track) {
252 valid_track_i_ds.insert(idx);
255 std::vector<TrigMip> mips;
256 for (
const size_t idx : valid_track_i_ds) {
257 const auto& track = candidate_tracks[idx];
259 mip.setStartLayer(track.front()->layer());
260 mip.setEndLayer(track.back()->layer());
261 mip.setNHits(track.size());
262 mip.setLength(track.back()->layer() - track.front()->layer());
263 int holes = mip.length() - mip.nHits();
267 mip.setNHoles(holes);
269 const float hole_fraction =
270 static_cast<float>(mip.nHoles()) / mip.length();
272 if (hole_fraction >= hole_fraction_max_)
continue;
274 float total_isolation_e_sum = 0.0f;
275 for (
const auto* hit : track) {
276 const int layer = hit->layer();
277 const float hit_x = hit->positionX();
278 const float hit_y = hit->positionY();
279 for (
const auto& cand : layer_hits[layer]) {
280 if (&cand == hit)
continue;
281 const float dx = cand.positionX() - hit_x;
282 const float dy = cand.positionY() - hit_y;
283 const float d_r_2 = dx * dx + dy * dy;
284 if (d_r_2 < radius_cut_2) {
285 total_isolation_e_sum += cand.energy();
289 mip.setSumEinIsolationRegion(total_isolation_e_sum);
293 std::sort(mips.begin(), mips.end());
294 event.add(pass_coll_name_, mips);
297 auto end = std::chrono::high_resolution_clock::now();
298 auto time_diff = end - start;
300 std::chrono::duration<double, std::milli>(time_diff).count();