LDMX Software
EcalMipTrackingProcessor.cxx
2
3namespace ecal {
4
6 profiling_map_["straight_tracks"] = 0.;
7 profiling_map_["linreg_tracks"] = 0.;
8 profiling_map_["processing_time_"] = 0;
9}
10
13 n_ecal_layers_ = parameters.get<int>("num_ecal_layers");
14 linreg_radius_ = parameters.get<double>("linreg_radius");
15 ecal_collection_name_ = parameters.get<std::string>("ecal_collection_name");
16 ecal_pass_name_ = parameters.get<std::string>("ecal_pass_name");
17 mip_collection_name_ = parameters.get<std::string>("mip_collection_name");
18 mip_pass_name_ = parameters.get<std::string>("mip_pass_name");
19 mip_result_name_ = parameters.get<std::string>("mip_result_name");
20}
21
22void EcalMipTrackingProcessor::clearProcessor() {
23 // MIP tracking
29}
30
32 auto start = std::chrono::high_resolution_clock::now();
33
34 ldmx::EcalMipResult mip_result;
35 clearProcessor();
36
37 // Get the Ecal Geometry
39 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
40
41 // Read in hits near photon from EcalVetoProcessor
42 auto ecal_veto_result = event.getObject<ldmx::EcalVetoResult>(
43 ecal_collection_name_, ecal_pass_name_);
44 auto ecal_trajectory_info = event.getObject<ldmx::EcalTrajectoryInfo>(
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();
54 nevents_++;
55 // Now inputting Lines 753-1178 of the original EcalVetoProcessor
56 // ------------------------------------------------------
57 // MIP tracking starts here
58
59 /* Goal: Calculate
60 * n_straight_tracks (self-explanatory),
61 * n_linreg_tracks (tracks found by linreg algorithm),
62 */
63
64 // Find epAng and epSep, and prepare EP trajectory vectors:
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()) {
70 // Create TVector3s marking the start and endpoints of each projected
71 // trajectory
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,
76 geometry_->getZPosition((n_ecal_layers_ - 1)));
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,
81 geometry_->getZPosition((n_ecal_layers_ - 1)));
82 } else {
83 // Electron trajectory is missing, so place trajectories far outside the
84 // ECal to ensure they don't interfere with tracking.
85 e_traj_start = ROOT::Math::XYZVector(999, 999, geometry_->getZPosition(0));
86 e_traj_end = ROOT::Math::XYZVector(
87 999, 999, geometry_->getZPosition((n_ecal_layers_ - 1)));
88 p_traj_start =
89 ROOT::Math::XYZVector(1000, 1000, geometry_->getZPosition(0));
90 p_traj_end = ROOT::Math::XYZVector(
91 1000, 1000, geometry_->getZPosition((n_ecal_layers_ - 1)));
92 }
93 // Near photon step: Find the first layer_ of the ECal where a hit near the
94 // projected photon trajectory is found Currently unusued pending further
95 // study; performance has dropped between v9 and v12. Currently used in
96 // segmipBDT
97 first_near_ph_layer_ = n_ecal_layers_ - 1;
98
99 // If no photon trajectory, leave this at the default (ECal back)
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) {
104 float eh_dist =
105 sqrt(pow((*it).pos_.X() - photon_trajectory[(*it).layer_].first, 2) +
106 pow((*it).pos_.Y() - photon_trajectory[(*it).layer_].second, 2));
107 // TODO: this 8.7 should be not hardcoded
108 if (eh_dist < 8.7) {
110 if ((*it).layer_ < first_near_ph_layer_) {
111 first_near_ph_layer_ = (*it).layer_;
112 }
113 }
114 }
115 ldmx_log(trace) << "First near photon layer_: " << first_near_ph_layer_;
116 }
117
118 // Territories limited to tracking_hit_list
119 ROOT::Math::XYZVector g_toe = (e_traj_start - p_traj_start).Unit();
120 // TODO what is this 8.7 here???
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) {
130 }
131 }
132 ldmx_log(trace) << "Photon territory hits: " << photon_territory_hits_;
133 } else {
134 photon_territory_hits_ = n_readout_hits_;
135 }
136
137 // ------------------------------------------------------
138 // Find straight MIP tracks:
139
140 std::sort(
141 tracking_hit_list.begin(), tracking_hit_list.end(),
142 [](ldmx::HitData ha, ldmx::HitData hb) { return ha.layer_ > hb.layer_; });
143 // For merging tracks: Need to keep track of existing tracks
144 // Candidate tracks to merge in will always be in front of the current track
145 // (lower z_), so only store the last hit 3-layer_ vector: each track =
146 // vector of 3-tuples (xy+layer_).
147 std::vector<std::vector<ldmx::HitData>> track_list;
148
149 // print tracking_hit_list
150
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_ << "], ";
157 }
158 ldmx_log(trace) << "====== END OF Tracking hit list ======";
159
160 // in v14 minR is 4.17 mm
161 // while maxR is 4.81 mm
162 float cell_width = 2 * geometry_->getCellMaxR();
163 for (int i_hit = 0; i_hit < tracking_hit_list.size(); i_hit++) {
164 // list of hit numbers in track (34 = maximum theoretical length)
165 int track[34];
166 int current_hit{i_hit};
167 int track_len{1};
168
169 track[0] = i_hit;
170
171 // Search for hits to add to the track:
172 // repeatedly find hits in the front two layers with same x- & y-positions
173 // but since v14 the odd layers are offset, so we allow half a cell_width
174 // deviation and then add to track until no more hits are found
175 int j_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()) <=
183 0.5 * cell_width &&
184 std::abs(tracking_hit_list[j_hit].pos_.Y() -
185 tracking_hit_list[current_hit].pos_.Y()) <=
186 0.5 * cell_width) {
187 track[track_len] = j_hit;
188 track_len++;
189 current_hit = j_hit;
190 }
191 j_hit++;
192 }
193
194 // Confirm that the track is valid:
195 if (track_len < 2) continue; // Track must contain at least 2 hits
196 float closest_e = ecal::distTwoLines(
197 tracking_hit_list[track[0]].pos_,
198 tracking_hit_list[track[track_len - 1]].pos_, e_traj_start, e_traj_end);
199 float closest_p = ecal::distTwoLines(
200 tracking_hit_list[track[0]].pos_,
201 tracking_hit_list[track[track_len - 1]].pos_, p_traj_start, p_traj_end);
202 // Make sure that the track is near the photon trajectory and away from the
203 // electron trajectory Details of these constraints may be revised
204 if (closest_p > cell_width and closest_e < 2 * cell_width) continue;
205 if (track_len < 4 and closest_e > closest_p) continue;
206
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_ << "]";
211
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_ << "]";
217 }
218
219 // if track found, increment n_straight_tracks and remove all hits in track
220 // from future consideration
221 if (track_len >= 2) {
222 std::vector<ldmx::HitData> temp_track_list;
223 int n_remove = 0;
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] -
227 n_remove);
228 n_remove++;
229 }
230 // print tracking_hit_list
231
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_ << "] ";
238 }
239 ldmx_log(trace) << "====== END OF Tracking hit list ======";
240
241 track_list.push_back(temp_track_list);
242 // The *current* hit will have been removed, so i_hit is currently
243 // pointing to the next hit. Decrement i_hit so no hits will get skipped
244 // by i_hit++
245 i_hit--;
246 }
247 }
248
249 ldmx_log(debug) << "Straight tracks found (before merge): "
250 << track_list.size();
251
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;
259 }
260 }
261
262 // Optional addition: Merge nearby straight tracks. Not necessary for veto.
263 // Criteria: consider tail of track. Merge if head of next track is 1/2
264 // layers behind, within 1 cell of xy position.
265 ldmx_log(debug) << "Beginning track merging using " << track_list.size()
266 << " tracks";
267
268 for (int track_i = 0; track_i < track_list.size(); track_i++) {
269 // for each track, check the remainder of the track list for compatible
270 // tracks
271 std::vector<ldmx::HitData> base_track = track_list[track_i];
272 ldmx::HitData tail_hitdata =
273 base_track.back(); // xylayer of last hit in track
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 ldmx::HitData head_hitdata = checking_track.front();
278 // if 1-2 layers behind, and xy within one cell...
279 if ((head_hitdata.layer_ == tail_hitdata.layer_ + 1 ||
280 head_hitdata.layer_ == tail_hitdata.layer_ + 2) &&
281 pow(pow(head_hitdata.pos_.X() - tail_hitdata.pos_.X(), 2) +
282 pow(head_hitdata.pos_.Y() - tail_hitdata.pos_.Y(), 2),
283 0.5) <= cell_width) {
284 // ...then append the second track to the first one and delete it
285 // NOTE: TO ADD: (tracking_hit_list[i_hit].pos_ -
286 // tracking_hit_list[j_hit].pos_).R()
287 ldmx_log(trace) << " ** Compatible track found at index_ "
288 << track_j;
289 ldmx_log(trace) << " Tail xylayer: " << head_hitdata.pos_.X() << ","
290 << head_hitdata.pos_.Y() << "," << head_hitdata.layer_;
291 ldmx_log(trace) << " Head xylayer: " << tail_hitdata.pos_.X() << ","
292 << tail_hitdata.pos_.Y() << "," << tail_hitdata.layer_;
293 for (int hit_k = 0; hit_k < checking_track.size(); hit_k++) {
294 base_track.push_back(track_list[track_j][hit_k]);
295 }
296 track_list[track_i] = base_track;
297 track_list.erase(track_list.begin() + track_j);
298 break;
299 }
300 }
301 }
302 n_straight_tracks_ = track_list.size();
303 // print the track list
304 ldmx_log(debug) << "Straight tracks found (after merge): "
306 for (int track_i = 0; track_i < track_list.size(); track_i++) {
307 ldmx_log(debug) << "Track " << track_i << ":";
308 for (int hit_i = 0; hit_i < track_list[track_i].size(); hit_i++) {
309 ldmx_log(debug) << " Hit " << hit_i << ": ["
310 << track_list[track_i][hit_i].pos_.X() << ", "
311 << track_list[track_i][hit_i].pos_.Y() << ", "
312 << track_list[track_i][hit_i].layer_ << "]";
313 }
314 }
315
316 auto straight_tracks = std::chrono::high_resolution_clock::now();
317 profiling_map_["straight_tracks"] +=
318 std::chrono::duration<double, std::milli>(straight_tracks - start)
319 .count();
320 // ------------------------------------------------------
321 // Linreg tracking:
322 ldmx_log(info) << "Finding linreg tracks from a total of "
323 << tracking_hit_list.size() << " hits using a radius of "
324 << linreg_radius_ << " mm";
325
326 for (int i_hit = 0; i_hit < 0; i_hit++) {
327 // for (int i_hit = 0; i_hit < tracking_hit_list.size(); i_hit++) {
328 // Hits being considered at a given time
329 std::vector<int> hits_in_region;
330 TMatrixD vm(3, 3);
331 TMatrixD hdt(3, 3);
332 ROOT::Math::XYZVector slope_vec;
333 ROOT::Math::XYZVector h_mean;
334 ROOT::Math::XYZVector h_point;
335 float r_corr_best{0.0};
336 // Temp array having 3 potential hits
337 int hit_nums[3];
338 // From the above which are passing the correlation reqs
339 int best_hit_nums[3];
340
341 hits_in_region.push_back(i_hit);
342 // Find all hits within 2 cells of the primary hit:
343 for (int j_hit = 0; j_hit < tracking_hit_list.size(); j_hit++) {
344 // Dont try to put hits on the same layer_ to the lin-reg track
345 if (tracking_hit_list[i_hit].pos_.Z() ==
346 tracking_hit_list[j_hit].pos_.Z()) {
347 continue;
348 }
349 float dist_to_hit =
350 (tracking_hit_list[i_hit].pos_ - tracking_hit_list[j_hit].pos_).R();
351 // This distance optimized to give the best significance
352 // it used to be 2*cell_width, i.e. 4.81 mm
353 // note, the layers in the back have a separation of 22.3
354 if (dist_to_hit <= 2 * linreg_radius_) {
355 hits_in_region.push_back(j_hit);
356 }
357 }
358 // Found a track that passed the lin-reg reqs
359 bool best_lin_reg_found{false};
360
361 ldmx_log(debug) << "There are " << hits_in_region.size()
362 << " hits within a radius of " << linreg_radius_ << " mm";
363 // Look at combinations of hits within the region (do not consider the same
364 // combination twice):
365 hit_nums[0] = i_hit;
366 for (int j_hit_in_reg = 1; j_hit_in_reg < hits_in_region.size() - 1;
367 j_hit_in_reg++) {
368 // We require (exactly) 3 hits for the lin-reg track building
369 if (hits_in_region.size() < 3) break;
370 hit_nums[1] = hits_in_region[j_hit_in_reg];
371 for (int k_hit_reg = j_hit_in_reg + 1; k_hit_reg < hits_in_region.size();
372 k_hit_reg++) {
373 hit_nums[2] = hits_in_region[k_hit_reg];
374 const auto &p0 = tracking_hit_list[hit_nums[0]].pos_;
375 const auto &p1 = tracking_hit_list[hit_nums[1]].pos_;
376 const auto &p2 = tracking_hit_list[hit_nums[2]].pos_;
377
378 h_mean = (p0 + p1 + p2) / 3.0;
379
380 double p_arr[3][3] = {{p0.X(), p0.Y(), p0.Z()},
381 {p1.X(), p1.Y(), p1.Z()},
382 {p2.X(), p2.Y(), p2.Z()}};
383
384 // Compute mean in an indexable array
385 double mean_arr[3] = {(p0.X() + p1.X() + p2.X()) / 3.0,
386 (p0.Y() + p1.Y() + p2.Y()) / 3.0,
387 (p0.Z() + p1.Z() + p2.Z()) / 3.0};
388
389 for (int h_ind = 0; h_ind < 3; ++h_ind) {
390 for (int l_ind = 0; l_ind < 3; ++l_ind) {
391 hdt(h_ind, l_ind) = p_arr[h_ind][l_ind] - mean_arr[l_ind];
392 }
393 }
394
395 // Perform "linreg" on selected points
396 // Calculate the determinant of the matrix
397 double determinant =
398 hdt(0, 0) * (hdt(1, 1) * hdt(2, 2) - hdt(1, 2) * hdt(2, 1)) -
399 hdt(0, 1) * (hdt(1, 0) * hdt(2, 2) - hdt(1, 2) * hdt(2, 0)) +
400 hdt(0, 2) * (hdt(1, 0) * hdt(2, 1) - hdt(1, 1) * hdt(2, 0));
401 // Exit early if the matrix is singular (i.e. det = 0)
402 if (determinant == 0) continue;
403 // Perform matrix decomposition with SVD
404 TDecompSVD svd_obj(hdt);
405 bool decomposed = svd_obj.Decompose();
406 if (!decomposed) continue;
407
408 // First col of V matrix is the slope of the best-fit line
409 vm = svd_obj.GetV();
410 slope_vec.SetX(vm[0][0]);
411 slope_vec.SetY(vm[0][1]);
412 slope_vec.SetZ(vm[0][2]);
413 // h_mean, h_point are points on the best-fit line
414 h_point = slope_vec + h_mean;
415 // linreg complete: Now have best-fit line for 3 hits under
416 // consideration Check whether the track is valid: r^2 must be high,
417 // and the track must plausibly originate from the photon
418 float closest_e =
419 ecal::distTwoLines(h_mean, h_point, e_traj_start, e_traj_end);
420 float closest_p =
421 ecal::distTwoLines(h_mean, h_point, p_traj_start, p_traj_end);
422 // Projected track must be close to the photon; details may change after
423 // future study.
424 if (closest_p > cell_width or closest_e < 1.5 * cell_width) continue;
425 // find r^2
426 // ~variance
427 float vrnc = (tracking_hit_list[hit_nums[0]].pos_ - h_mean).R() +
428 (tracking_hit_list[hit_nums[1]].pos_ - h_mean).R() +
429 (tracking_hit_list[hit_nums[2]].pos_ - h_mean).R();
430 // sum of |errors|
431 float sumerr = ecal::distPtToLine(tracking_hit_list[hit_nums[0]].pos_,
432 h_mean, h_point) +
433 ecal::distPtToLine(tracking_hit_list[hit_nums[1]].pos_,
434 h_mean, h_point) +
435 ecal::distPtToLine(tracking_hit_list[hit_nums[2]].pos_,
436 h_mean, h_point);
437 float r_corr = 1 - sumerr / vrnc;
438 // Check whether r^2 exceeds a low minimum r_corr: "Fake" tracks are
439 // still much more common in background, so making the algorithm
440 // oversensitive doesn't lower performance significantly
441 if (r_corr > r_corr_best and r_corr > .6) {
442 r_corr_best = r_corr;
443 // Only looking for 3-hit tracks currently
444 best_lin_reg_found = true;
445 for (int k = 0; k < 3; k++) {
446 best_hit_nums[k] = hit_nums[k];
447 }
448 }
449 } // end loop on hits in the region
450 } // end 2nd loop on hits in the region
451
452 // Continue early if not hits on track
453 if (!best_lin_reg_found) continue;
454 // Otherwise increase the number of lin-reg tracks
456 ldmx_log(debug) << " Lin-reg track " << n_linreg_tracks_;
457 for (int final_hit_index = 0; final_hit_index < 3; final_hit_index++) {
458 ldmx_log(debug)
459 << " Hit " << final_hit_index << " ["
460 << tracking_hit_list[best_hit_nums[final_hit_index]].pos_.X() << ", "
461 << tracking_hit_list[best_hit_nums[final_hit_index]].pos_.Y() << ", "
462 << tracking_hit_list[best_hit_nums[final_hit_index]].pos_.Z() << "] ";
463 }
464
465 // Exclude all hits in a found track from further consideration:
466 for (int l_hit = 0; l_hit < 3; l_hit++) {
467 tracking_hit_list.erase(tracking_hit_list.begin() + best_hit_nums[l_hit]);
468 }
469 i_hit--;
470 } // end loop on all hits
471 ldmx_log(info) << " MIP tracking completed; found " << n_straight_tracks_
472 << " straight tracks and " << n_linreg_tracks_
473 << " lin-reg tracks";
474
475 auto linreg_tracks = std::chrono::high_resolution_clock::now();
476 profiling_map_["linreg_tracks"] +=
477 std::chrono::duration<double, std::milli>(linreg_tracks - straight_tracks)
478 .count();
479
480 mip_result.setVariables(n_straight_tracks_, n_linreg_tracks_,
483
484 event.add(mip_result_name_, mip_result);
485
486 auto end = std::chrono::high_resolution_clock::now();
487 auto time_diff = end - start;
488 processing_time_ +=
489 std::chrono::duration<double, std::milli>(time_diff).count();
490}
491
493 ldmx_log(info) << "AVG Time/Event: " << std::fixed << std::setprecision(2)
494 << processing_time_ / nevents_ << " ms";
495
496 ldmx_log(info) << "Breakdown::";
497
498 ldmx_log(info) << "straight_tracks Avg Time/Event = " << std::fixed
499 << std::setprecision(3)
500 << profiling_map_["straight_tracks"] / nevents_ << " ms";
501
502 ldmx_log(info) << "linreg_tracks Avg Time/Event = " << std::fixed
503 << std::setprecision(3)
504 << profiling_map_["linreg_tracks"] / nevents_ << " ms";
505}
506
507} // namespace ecal
508
float distPtToLine(ROOT::Math::XYZVector h1, ROOT::Math::XYZVector p1, ROOT::Math::XYZVector p2)
Return the minimum distance between the point h1 and the line passing through points p1 and p2.
float distTwoLines(ROOT::Math::XYZVector v1, ROOT::Math::XYZVector v2, ROOT::Math::XYZVector w1, ROOT::Math::XYZVector w2)
Returns the distance between the lines v and w, with v defined to pass through the points (v1,...
Class that determines MIP tracking information using ECAL hit information.
#define DECLARE_PRODUCER(CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
const ldmx::EcalGeometry * geometry_
handle to current geometry (to share with member functions)
int photon_territory_hits_
Number of hits in the photon territory.
void produce(framework::Event &event) override
Process the event and put new data products into it.
void onProcessEnd() override
Callback for the EventProcessor to take any necessary action when the processing of events finishes,...
int n_linreg_tracks_
Number of "linreg" tracks found in the event.
void onNewRun(const ldmx::RunHeader &rh) override
onNewRun is the first function called for each processor after the conditions are fully configured an...
int n_near_ph_hits_
Number of hits near the photon trajectory.
void configure(framework::config::Parameters &parameters) override
Configure the processor using the given user specified parameters.
int first_near_ph_layer_
Earliest ECal layer in which a hit is found near the projected photon trajectory.
int n_straight_tracks_
Number of "straight" tracks found in the event.
const T & getCondition(const std::string &condition_name)
Access a conditions object for the current event.
Implements an event buffer system for storing event data.
Definition Event.h:42
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:29
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78
double getZPosition(int layer) const
Get the z-coordinate given the layer id.
double getCellMaxR() const
Get the center-to-corner radius of the cell hexagons.
Run-specific configuration and data stored in its own output TTree alongside the event TTree in the o...
Definition RunHeader.h:57