39 auto start = std::chrono::high_resolution_clock::now();
42 if (!event.
exists(hit_coll_name_, hit_coll_passname_))
return;
44 const auto calo_hits =
event.getObject<std::vector<TrigCaloHit>>(
45 hit_coll_name_, hit_coll_passname_);
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};
52 int even_counts[5] = {};
53 int odd_matrix[24][5] = {};
54 int odd_start[5] = {99, 99, 99, 99, 99};
56 int odd_counts[5] = {};
58 constexpr int layer_start = 80;
60 for (
const auto& tp : calo_hits) {
61 if (tp.section() > 0 || tp.energy() < hcal_min_energy_ ||
66 sorted_hits.push_back(tp);
67 const int layer_index = tp.layer() / 2;
68 const int strip = tp.strip();
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());
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());
80 for (
int i = 0; i < 24; i++) {
81 for (
int j = 0; j < 5; j++) {
82 if (even_matrix[i][j]) {
85 if (odd_matrix[i][j]) {
92 std::vector<TrigMip> mips;
94 for (
int i = 0; i < 5; i++) {
95 if (odd_start[i] < layer_start) {
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();
108 if (even_start[i] < layer_start) {
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();
123 std::sort(mips.begin(), mips.end());
124 event.add(pass_coll_name_, mips);
126 auto end = std::chrono::high_resolution_clock::now();
127 auto time_diff = end - start;
129 std::chrono::duration<double, std::milli>(time_diff).count();
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;
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);
147 for (
const auto& [seed_layer, seeds] : layer_hits) {
148 for (
const auto& seed : seeds) {
150 if (used_hits.count(&seed) || seed.energy() < ecal_min_energy_ ||
151 seed.energy() > ecal_max_energy_) {
155 std::vector<const TrigCaloHit*> track{&seed};
159 float growth_factor = 1.0f;
162 for (
int l = seed.layer() + 1; l <= max_layer_; ++l) {
165 float best_d_r_2 = radius_cut_2 * growth_factor * growth_factor;
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_) {
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;
183 if (d_r_2 < best_d_r_2) {
192 track.push_back(best_hit);
196 growth_factor = 1.0f;
200 growth_factor =
static_cast<float>(holes + 1);
204 bool is_isolated =
true;
205 if (track.size() >= min_track_length_) {
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();
213 for (
const auto& cand : layer_hits[layer]) {
215 if (&cand == hit)
continue;
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;
221 if (d_r_2 < radius_cut_2) {
222 sum_e += cand.energy();
226 if (sum_e >= isolation_e_cut_) {
229 used_hits.insert(hit);
239 const size_t i = candidate_tracks.size();
240 candidate_tracks.push_back(track);
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;
248 used_hits.insert(hit);
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);
260 std::vector<TrigMip> mips;
261 for (
const size_t idx : valid_track_i_ds) {
262 const auto& track = candidate_tracks[idx];
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();
272 mip.setNHoles(holes);
274 const float hole_fraction =
275 static_cast<float>(mip.nHoles()) / mip.length();
277 if (hole_fraction >= hole_fraction_max_)
continue;
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();
294 mip.setSumEinIsolationRegion(total_isolation_e_sum);
298 std::sort(mips.begin(), mips.end());
299 event.add(pass_coll_name_, mips);
302 auto end = std::chrono::high_resolution_clock::now();
303 auto time_diff = end - start;
305 std::chrono::duration<double, std::milli>(time_diff).count();