32 auto start = std::chrono::high_resolution_clock::now();
39 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
43 ecal_collection_name_, ecal_pass_name_);
45 mip_collection_name_, mip_pass_name_);
46 std::vector<XYCoords> ele_trajectory, photon_trajectory,
47 ele_trajectory_at_target;
48 std::vector<ldmx::HitData> tracking_hit_list;
49 ldmx_log(trace) <<
"EcalMipTrackingProcessor::produce() called";
50 ele_trajectory = ecal_trajectory_info.getEleTrajectory();
51 photon_trajectory = ecal_trajectory_info.getPhotonTrajectory();
52 tracking_hit_list = ecal_trajectory_info.getTrackingHitList();
53 n_readout_hits_ = ecal_veto_result.getNReadoutHits();
65 ROOT::Math::XYZVector e_traj_start;
66 ROOT::Math::XYZVector e_traj_end;
67 ROOT::Math::XYZVector p_traj_start;
68 ROOT::Math::XYZVector p_traj_end;
69 if (!ele_trajectory.empty() && !photon_trajectory.empty()) {
72 e_traj_start.SetXYZ(ele_trajectory[0].first, ele_trajectory[0].second,
74 e_traj_end.SetXYZ(ele_trajectory[(n_ecal_layers_ - 1)].first,
75 ele_trajectory[(n_ecal_layers_ - 1)].second,
77 p_traj_start.SetXYZ(photon_trajectory[0].first, photon_trajectory[0].second,
79 p_traj_end.SetXYZ(photon_trajectory[(n_ecal_layers_ - 1)].first,
80 photon_trajectory[(n_ecal_layers_ - 1)].second,
86 e_traj_end = ROOT::Math::XYZVector(
90 p_traj_end = ROOT::Math::XYZVector(
100 ldmx_log(trace) <<
"Finding first near photon layer_";
101 if (!photon_trajectory.empty()) {
102 for (std::vector<ldmx::HitData>::iterator it = tracking_hit_list.begin();
103 it != tracking_hit_list.end(); ++it) {
105 sqrt(pow((*it).pos_.X() - photon_trajectory[(*it).layer_].first, 2) +
106 pow((*it).pos_.Y() - photon_trajectory[(*it).layer_].second, 2));
119 ROOT::Math::XYZVector g_toe = (e_traj_start - p_traj_start).Unit();
121 ROOT::Math::XYZVector origin = p_traj_start + 0.5 * 8.7 * g_toe;
122 ldmx_log(trace) <<
"Origin of photon territory: " << origin.X() <<
", "
123 << origin.Y() <<
", " << origin.Z();
124 if (!ele_trajectory.empty()) {
125 for (
auto& hit_data : tracking_hit_list) {
126 ROOT::Math::XYZVector hit_pos = hit_data.pos_;
127 ROOT::Math::XYZVector hit_prime = hit_pos - origin;
128 if (hit_prime.Dot(g_toe) <= 0) {
141 tracking_hit_list.begin(), tracking_hit_list.end(),
147 std::vector<std::vector<ldmx::HitData>> track_list;
151 ldmx_log(trace) <<
"====== Tracking hit list (original) length "
152 << tracking_hit_list.size() <<
" ======";
153 for (
int i = 0; i < tracking_hit_list.size(); i++) {
154 ldmx_log(trace) <<
"[" << tracking_hit_list[i].pos_.X() <<
", "
155 << tracking_hit_list[i].pos_.Y() <<
", "
156 << tracking_hit_list[i].layer_ <<
"], ";
158 ldmx_log(trace) <<
"====== END OF Tracking hit list ======";
163 for (
int i_hit = 0; i_hit < tracking_hit_list.size(); i_hit++) {
166 int current_hit{i_hit};
176 while (j_hit < tracking_hit_list.size()) {
177 if ((tracking_hit_list[j_hit].layer_ ==
178 tracking_hit_list[current_hit].layer_ - 1 ||
179 tracking_hit_list[j_hit].layer_ ==
180 tracking_hit_list[current_hit].layer_ - 2) &&
181 std::abs(tracking_hit_list[j_hit].pos_.X() -
182 tracking_hit_list[current_hit].pos_.X()) <=
184 std::abs(tracking_hit_list[j_hit].pos_.Y() -
185 tracking_hit_list[current_hit].pos_.Y()) <=
187 track[track_len] = j_hit;
195 if (track_len < 2)
continue;
197 tracking_hit_list[track[0]].pos_,
198 tracking_hit_list[track[track_len - 1]].pos_, e_traj_start, e_traj_end);
200 tracking_hit_list[track[0]].pos_,
201 tracking_hit_list[track[track_len - 1]].pos_, p_traj_start, p_traj_end);
204 if (closest_p > cell_width and closest_e < 2 * cell_width)
continue;
205 if (track_len < 4 and closest_e > closest_p)
continue;
207 ldmx_log(debug) <<
"====== After rejection for MIP tracking ======";
208 ldmx_log(debug) <<
"current hit: [" << tracking_hit_list[i_hit].pos_.X()
209 <<
", " << tracking_hit_list[i_hit].pos_.Y() <<
", "
210 << tracking_hit_list[i_hit].layer_ <<
"]";
212 for (
int k = 0; k < track_len; k++) {
213 ldmx_log(debug) <<
"track[" << k <<
"] position = ["
214 << tracking_hit_list[track[k]].pos_.X() <<
", "
215 << tracking_hit_list[track[k]].pos_.Y() <<
", "
216 << tracking_hit_list[track[k]].layer_ <<
"]";
221 if (track_len >= 2) {
222 std::vector<ldmx::HitData> temp_track_list;
224 for (
int k_hit = 0; k_hit < track_len; k_hit++) {
225 temp_track_list.push_back(tracking_hit_list[track[k_hit] - n_remove]);
226 tracking_hit_list.erase(tracking_hit_list.begin() + track[k_hit] -
232 ldmx_log(trace) <<
"====== Tracking hit list (after erase) length "
233 << tracking_hit_list.size() <<
" ======";
234 for (
int i = 0; i < tracking_hit_list.size(); i++) {
235 ldmx_log(trace) <<
"[" << tracking_hit_list[i].pos_.X() <<
", "
236 << tracking_hit_list[i].pos_.Y() <<
", "
237 << tracking_hit_list[i].layer_ <<
"] ";
239 ldmx_log(trace) <<
"====== END OF Tracking hit list ======";
241 track_list.push_back(temp_track_list);
249 ldmx_log(debug) <<
"Straight tracks found (before merge): "
250 << track_list.size();
252 for (
int i_track = 0; i_track < track_list.size(); i_track++) {
253 ldmx_log(trace) <<
"Track " << i_track <<
":";
254 for (
int i_hit = 0; i_hit < track_list[i_track].size(); i_hit++) {
255 ldmx_log(trace) <<
" Hit " << i_hit <<
": ["
256 << track_list[i_track][i_hit].pos_.X() <<
", "
257 << track_list[i_track][i_hit].pos_.Y() <<
", "
258 << track_list[i_track][i_hit].layer_ <<
"]" << std::endl;
265 ldmx_log(debug) <<
"Beginning track merging using " << track_list.size()
268 for (
int track_i = 0; track_i < track_list.size(); track_i++) {
271 std::vector<ldmx::HitData> base_track = track_list[track_i];
274 ldmx_log(trace) <<
" Considering track " << track_i;
275 for (
int track_j = track_i + 1; track_j < track_list.size(); track_j++) {
276 std::vector<ldmx::HitData> checking_track = track_list[track_j];
277 if (checking_track.empty()) {
278 ldmx_log(error) <<
"Broken logic: a straight ecal track had no hits in "
284 if ((head_hitdata.layer_ == tail_hitdata.layer_ + 1 ||
285 head_hitdata.layer_ == tail_hitdata.layer_ + 2) &&
286 pow(pow(head_hitdata.pos_.X() - tail_hitdata.pos_.X(), 2) +
287 pow(head_hitdata.pos_.Y() - tail_hitdata.pos_.Y(), 2),
288 0.5) <= cell_width) {
292 ldmx_log(trace) <<
" ** Compatible track found at index_ "
294 ldmx_log(trace) <<
" Tail xylayer: " << head_hitdata.pos_.X() <<
","
295 << head_hitdata.pos_.Y() <<
"," << head_hitdata.layer_;
296 ldmx_log(trace) <<
" Head xylayer: " << tail_hitdata.pos_.X() <<
","
297 << tail_hitdata.pos_.Y() <<
"," << tail_hitdata.layer_;
298 for (
int hit_k = 0; hit_k < checking_track.size(); hit_k++) {
299 base_track.push_back(track_list[track_j][hit_k]);
301 track_list[track_i] = base_track;
302 track_list.erase(track_list.begin() + track_j);
309 ldmx_log(debug) <<
"Straight tracks found (after merge): "
311 for (
int track_i = 0; track_i < track_list.size(); track_i++) {
312 ldmx_log(debug) <<
"Track " << track_i <<
":";
313 for (
int hit_i = 0; hit_i < track_list[track_i].size(); hit_i++) {
314 ldmx_log(debug) <<
" Hit " << hit_i <<
": ["
315 << track_list[track_i][hit_i].pos_.X() <<
", "
316 << track_list[track_i][hit_i].pos_.Y() <<
", "
317 << track_list[track_i][hit_i].layer_ <<
"]";
321 auto straight_tracks = std::chrono::high_resolution_clock::now();
322 profiling_map_[
"straight_tracks"] +=
323 std::chrono::duration<double, std::milli>(straight_tracks - start)
327 ldmx_log(info) <<
"Finding linreg tracks from a total of "
328 << tracking_hit_list.size() <<
" hits using a radius of "
329 << linreg_radius_ <<
" mm";
331 for (
int i_hit = 0; i_hit < 0; i_hit++) {
334 std::vector<int> hits_in_region;
337 ROOT::Math::XYZVector slope_vec;
338 ROOT::Math::XYZVector h_mean;
339 ROOT::Math::XYZVector h_point;
340 float r_corr_best{0.0};
344 int best_hit_nums[3];
346 hits_in_region.push_back(i_hit);
348 for (
int j_hit = 0; j_hit < tracking_hit_list.size(); j_hit++) {
350 if (tracking_hit_list[i_hit].pos_.Z() ==
351 tracking_hit_list[j_hit].pos_.Z()) {
355 (tracking_hit_list[i_hit].pos_ - tracking_hit_list[j_hit].pos_).R();
359 if (dist_to_hit <= 2 * linreg_radius_) {
360 hits_in_region.push_back(j_hit);
364 bool best_lin_reg_found{
false};
366 ldmx_log(debug) <<
"There are " << hits_in_region.size()
367 <<
" hits within a radius of " << linreg_radius_ <<
" mm";
371 for (
int j_hit_in_reg = 1; j_hit_in_reg < hits_in_region.size() - 1;
374 if (hits_in_region.size() < 3)
break;
375 hit_nums[1] = hits_in_region[j_hit_in_reg];
376 for (
int k_hit_reg = j_hit_in_reg + 1; k_hit_reg < hits_in_region.size();
378 hit_nums[2] = hits_in_region[k_hit_reg];
379 const auto& p0 = tracking_hit_list[hit_nums[0]].pos_;
380 const auto& p1 = tracking_hit_list[hit_nums[1]].pos_;
381 const auto& p2 = tracking_hit_list[hit_nums[2]].pos_;
383 h_mean = (p0 + p1 + p2) / 3.0;
385 double p_arr[3][3] = {{p0.X(), p0.Y(), p0.Z()},
386 {p1.X(), p1.Y(), p1.Z()},
387 {p2.X(), p2.Y(), p2.Z()}};
390 double mean_arr[3] = {(p0.X() + p1.X() + p2.X()) / 3.0,
391 (p0.Y() + p1.Y() + p2.Y()) / 3.0,
392 (p0.Z() + p1.Z() + p2.Z()) / 3.0};
394 for (
int h_ind = 0; h_ind < 3; ++h_ind) {
395 for (
int l_ind = 0; l_ind < 3; ++l_ind) {
396 hdt(h_ind, l_ind) = p_arr[h_ind][l_ind] - mean_arr[l_ind];
403 hdt(0, 0) * (hdt(1, 1) * hdt(2, 2) - hdt(1, 2) * hdt(2, 1)) -
404 hdt(0, 1) * (hdt(1, 0) * hdt(2, 2) - hdt(1, 2) * hdt(2, 0)) +
405 hdt(0, 2) * (hdt(1, 0) * hdt(2, 1) - hdt(1, 1) * hdt(2, 0));
407 if (determinant == 0)
continue;
409 TDecompSVD svd_obj(hdt);
410 bool decomposed = svd_obj.Decompose();
411 if (!decomposed)
continue;
415 slope_vec.SetX(vm[0][0]);
416 slope_vec.SetY(vm[0][1]);
417 slope_vec.SetZ(vm[0][2]);
419 h_point = slope_vec + h_mean;
429 if (closest_p > cell_width or closest_e < 1.5 * cell_width)
continue;
432 float vrnc = (tracking_hit_list[hit_nums[0]].pos_ - h_mean).R() +
433 (tracking_hit_list[hit_nums[1]].pos_ - h_mean).R() +
434 (tracking_hit_list[hit_nums[2]].pos_ - h_mean).R();
442 float r_corr = 1 - sumerr / vrnc;
446 if (r_corr > r_corr_best and r_corr > .6) {
447 r_corr_best = r_corr;
449 best_lin_reg_found =
true;
450 for (
int k = 0; k < 3; k++) {
451 best_hit_nums[k] = hit_nums[k];
458 if (!best_lin_reg_found)
continue;
462 for (
int final_hit_index = 0; final_hit_index < 3; final_hit_index++) {
464 <<
" Hit " << final_hit_index <<
" ["
465 << tracking_hit_list[best_hit_nums[final_hit_index]].pos_.X() <<
", "
466 << tracking_hit_list[best_hit_nums[final_hit_index]].pos_.Y() <<
", "
467 << tracking_hit_list[best_hit_nums[final_hit_index]].pos_.Z() <<
"] ";
471 for (
int l_hit = 0; l_hit < 3; l_hit++) {
472 tracking_hit_list.erase(tracking_hit_list.begin() + best_hit_nums[l_hit]);
478 <<
" lin-reg tracks";
480 auto linreg_tracks = std::chrono::high_resolution_clock::now();
481 profiling_map_[
"linreg_tracks"] +=
482 std::chrono::duration<double, std::milli>(linreg_tracks - straight_tracks)
489 event.add(mip_result_name_, mip_result);
491 auto end = std::chrono::high_resolution_clock::now();
492 auto time_diff = end - start;
494 std::chrono::duration<double, std::milli>(time_diff).count();