Process the event and put new data products into it.
167 {
168 auto start = std::chrono::high_resolution_clock::now();
169 nevents_++;
170
171
173 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
174
176
177 clearProcessor();
178
179
180
181
182 std::array<float, 3> recoil_p = {0., 0., 0.};
183 std::array<float, 3> recoil_pos = {-9999., -9999., -9999.};
184 std::array<float, 3> recoil_p_at_target = {0., 0., 0.};
185 std::array<float, 3> recoil_pos_at_target = {-9999., -9999., -9999.};
186
187 auto setup = std::chrono::high_resolution_clock::now();
188 profiling_map_["setup"] +=
189 std::chrono::duration<float, std::milli>(setup - start).count();
190
191 if (!recoil_from_tracking_ &&
192 event.
exists(ecal_sp_coll_name_, sp_pass_name_)) {
193 ldmx_log(trace) << " Loop through all of the sim particles and find the "
194 "recoil electron";
195
196
197
198
199
201 "SimParticles", sim_particles_passname_)};
202
203
205
206
208 ecal_sp_coll_name_, sp_pass_name_)};
209 float pmax = 0;
212 auto ecal_sp_momentum = sp_hit.getMomentum();
213 auto ecal_sp_position = sp_hit.getPosition();
214 if (hit_id.plane() != 31 || ecal_sp_momentum[2] <= 0) continue;
215
216 if (sp_hit.getTrackID() == recoil_track_id) {
217
218 if (sqrt((ecal_sp_momentum[0] * ecal_sp_momentum[0]) +
219 (ecal_sp_momentum[1] * ecal_sp_momentum[1]) +
220 (ecal_sp_momentum[2] * ecal_sp_momentum[2])) > pmax) {
221 recoil_p = {static_cast<float>(ecal_sp_momentum[0]),
222 static_cast<float>(ecal_sp_momentum[1]),
223 static_cast<float>(ecal_sp_momentum[2])};
224 recoil_pos = {(ecal_sp_position[0]), (ecal_sp_position[1]),
225 (ecal_sp_position[2])};
226 pmax = sqrt(recoil_p[0] * recoil_p[0] + recoil_p[1] * recoil_p[1] +
227 recoil_p[2] * recoil_p[2]);
228 }
229 }
230 }
231
232
233 if (event.
exists(target_sp_coll_name_, sp_pass_name_)) {
234 std::vector<ldmx::SimTrackerHit> target_sp_hits =
236 sp_pass_name_);
237 pmax = 0;
240 auto target_sp_momentum = sp_hit.getMomentum();
241 auto target_sp_position = sp_hit.getPosition();
242 if (hit_id.plane() != 1 || target_sp_momentum[2] <= 0) continue;
243
244 if (sp_hit.getTrackID() == recoil_track_id) {
245 if (sqrt((target_sp_momentum[0] * target_sp_momentum[0]) +
246 (target_sp_momentum[1] * target_sp_momentum[1]) +
247 (target_sp_momentum[2] * target_sp_momentum[2])) > pmax) {
248 recoil_p_at_target = {static_cast<float>(target_sp_momentum[0]),
249 static_cast<float>(target_sp_momentum[1]),
250 static_cast<float>(target_sp_momentum[2])};
251 recoil_pos_at_target = {target_sp_position[0],
252 target_sp_position[1],
253 target_sp_position[2]};
254
255 pmax = sqrt((recoil_p_at_target[0] * recoil_p_at_target[0]) +
256 (recoil_p_at_target[1] * recoil_p_at_target[1]) +
257 (recoil_p_at_target[2] * recoil_p_at_target[2]));
258 }
259 }
260 }
261 }
262 }
263
264
265 bool fiducial_in_tracker{false};
266 if (recoil_from_tracking_) {
267 ldmx_log(trace) << " Get recoil tracks collection";
268
269
270 auto recoil_tracks{
271 event.getCollection<
ldmx::Track>(track_collection_, track_pass_name_)};
272
273 ldmx_log(trace) << " Propagate the recoil ele to the ECAL";
274 ldmx::TrackStateType ts_type = ldmx::TrackStateType::AtECAL;
275 auto recoil_track_states_ecal =
277 ldmx_log(trace) << " Propagate the recoil ele to the Target";
278 ldmx::TrackStateType ts_type_target = ldmx::TrackStateType::AtTarget;
279 auto recoil_track_states_target =
281
282 ldmx_log(trace) << " Set recoil_pos and recoil_p";
283
284
285 if (!recoil_track_states_ecal.empty()) {
286 fiducial_in_tracker = true;
287 recoil_pos = {recoil_track_states_ecal[0], recoil_track_states_ecal[1],
288 recoil_track_states_ecal[2]};
289 recoil_p = {(recoil_track_states_ecal[3]), (recoil_track_states_ecal[4]),
290 (recoil_track_states_ecal[5])};
291 } else {
292 ldmx_log(trace) << " No recoil track at ECAL";
293 fiducial_in_tracker = false;
294 }
295 ldmx_log(debug) << " Set recoil_p = (" << recoil_p[0] << ", "
296 << recoil_p[1] << ", " << recoil_p[2]
297 << ") and recoil_pos = (" << recoil_pos[0] << ", "
298 << recoil_pos[1] << ", " << recoil_pos[2] << ")";
299
300
301 if (!recoil_track_states_target.empty()) {
302 recoil_pos_at_target = {(recoil_track_states_target[0]),
303 (recoil_track_states_target[1]),
304 (recoil_track_states_target[2])};
305 recoil_p_at_target = {recoil_track_states_target[3],
306 recoil_track_states_target[4],
307 recoil_track_states_target[5]};
308 }
309 ldmx_log(debug) << " Set recoil_p_at_target = (" << recoil_p_at_target[0]
310 << ", " << recoil_p_at_target[1] << ", "
311 << recoil_p_at_target[2] << ") and recoil_pos_at_target = ("
312 << recoil_pos_at_target[0] << ", "
313 << recoil_pos_at_target[1] << ", "
314 << recoil_pos_at_target[2] << ")";
315 }
316
317 ldmx_log(trace) << " Get projected trajectories for electron and photon";
318
319 auto recoil_electron = std::chrono::high_resolution_clock::now();
320 profiling_map_["recoil_electron"] +=
321 std::chrono::duration<float, std::milli>(recoil_electron - setup).count();
322
323
324 std::vector<XYCoords> ele_trajectory, photon_trajectory,
325 ele_trajectory_at_target;
326
327
328 if ((recoil_p[2] > 0.) && (recoil_p_at_target[2] > 0.) &&
329 (recoil_pos[0] != -9999.) && (recoil_pos_at_target[0] != -9999.)) {
330 ele_trajectory = getTrajectory(recoil_p, recoil_pos);
331 ele_trajectory_at_target =
332 getTrajectory(recoil_p_at_target, recoil_pos_at_target);
333
334
335 std::array<float, 3> photon_proj_momentum = {
336 -recoil_p_at_target[0], -recoil_p_at_target[1],
337 beam_energy_mev_ - recoil_p_at_target[2]};
338 photon_trajectory =
339 getTrajectory(photon_proj_momentum, recoil_pos_at_target);
340 } else {
341 ldmx_log(trace) << "Ele / photon trajectory cannot be determined, pZ = "
342 << recoil_p[2] << " pZAtTarget = " << recoil_p_at_target[2]
343 << " X = " << recoil_pos[0]
344 << " XAtTarget = " << recoil_pos_at_target[0];
345 }
346
347 float recoil_p_mag = (recoil_p[2] > 0.) ? sqrt((recoil_p[0] * recoil_p[0]) +
348 (recoil_p[1] * recoil_p[1]) +
349 (recoil_p[2] * recoil_p[2]))
350 : -1.0;
351 float recoil_theta =
352 recoil_p_mag > 0 ? acos(recoil_p[2] / recoil_p_mag) * 180.0 / M_PI : -1.0;
353
354 ldmx_log(trace) << " Build Radii of containment (ROC)";
355
356 auto trajectories = std::chrono::high_resolution_clock::now();
357 profiling_map_["trajectories"] +=
358 std::chrono::duration<float, std::milli>(trajectories - recoil_electron)
359 .count();
360
361
362 std::vector<float> roc_values_bin_0(roc_range_values_[0].begin() + 4,
363 roc_range_values_[0].end());
364 std::vector<float> ele_radii = roc_values_bin_0;
365 float theta_min, theta_max, p_min, p_max;
366 bool inrange;
367
368 for (int i = 0; i < roc_range_values_.size(); i++) {
369 theta_min = roc_range_values_[i][0];
370 theta_max = roc_range_values_[i][1];
371 p_min = roc_range_values_[i][2];
372 p_max = roc_range_values_[i][3];
373 inrange = true;
374
375 if (theta_min != -1.0) {
376 inrange = inrange && (recoil_theta >= theta_min);
377 }
378 if (theta_max != -1.0) {
379 inrange = inrange && (recoil_theta < theta_max);
380 }
381 if (p_min != -1.0) {
382 inrange = inrange && (recoil_p_mag >= p_min);
383 }
384 if (p_max != -1.0) {
385 inrange = inrange && (recoil_p_mag < p_max);
386 }
387 if (inrange) {
388 std::vector<float> roc_values_bini(roc_range_values_[i].begin() + 4,
389 roc_range_values_[i].end());
390 ele_radii = roc_values_bini;
391 }
392 }
393
394 std::vector<float> photon_radii = roc_values_bin_0;
395
396 auto roc_var = std::chrono::high_resolution_clock::now();
397 profiling_map_["roc_var"] +=
398 std::chrono::duration<float, std::milli>(roc_var - trajectories).count();
399
400
401 const std::vector<ldmx::EcalHit> ecal_rec_hits =
402 event.getCollection<
ldmx::EcalHit>(rec_coll_name_, rec_pass_name_);
403
405 getShowerCentroidIdAndRms(ecal_rec_hits, shower_rms_);
406
408 bool do_tight = true;
409
410 fillIsolatedHitMap(ecal_rec_hits, global_centroid, cell_map_,
411 cell_map_tight_iso_, do_tight);
412
413 auto fill_hitmaps = std::chrono::high_resolution_clock::now();
414 profiling_map_["fill_hitmaps"] +=
415 std::chrono::duration<float, std::milli>(fill_hitmaps - roc_var).count();
416
417
418
419
420 float w_avg_layer_hit = 0;
421 float x_mean = 0;
422 float y_mean = 0;
423
424
425 unsigned int n_regions = 5;
426 std::vector<float> electron_containment_energy(n_regions, 0.0);
427 std::vector<float> photon_containment_energy(n_regions, 0.0);
428 std::vector<float> outside_containment_energy(n_regions, 0.0);
429 std::vector<int> outside_containment_n_hits(n_regions, 0);
430 std::vector<float> outside_containment_x_mean(n_regions, 0.0);
431 std::vector<float> outside_containment_y_mean(n_regions, 0.0);
432 std::vector<float> outside_containment_x_std(n_regions, 0.0);
433 std::vector<float> outside_containment_y_std(n_regions, 0.0);
434
435 std::vector<int> seg_layers = {0, 6, 17, 32};
436 unsigned int n_segments = seg_layers.size() - 1;
437 std::vector<float> energy_seg(n_segments, 0.0);
438 std::vector<float> x_mean_seg(n_segments, 0.0);
439 std::vector<float> x_std_seg(n_segments, 0.0);
440 std::vector<float> y_mean_seg(n_segments, 0.0);
441 std::vector<float> y_std_seg(n_segments, 0.0);
442 std::vector<float> layer_mean_seg(n_segments, 0.0);
443 std::vector<float> layer_std_seg(n_segments, 0.0);
444 std::vector<std::vector<float>> e_cont_energy(
445 n_regions, std::vector<float>(n_segments, 0.0));
446 std::vector<std::vector<float>> e_cont_x_mean(
447 n_regions, std::vector<float>(n_segments, 0.0));
448 std::vector<std::vector<float>> e_cont_y_mean(
449 n_regions, std::vector<float>(n_segments, 0.0));
450 std::vector<std::vector<float>> g_cont_energy(
451 n_regions, std::vector<float>(n_segments, 0.0));
452 std::vector<std::vector<int>> g_cont_n_hits(n_regions,
453 std::vector<int>(n_segments, 0));
454 std::vector<std::vector<float>> g_cont_x_mean(
455 n_regions, std::vector<float>(n_segments, 0.0));
456 std::vector<std::vector<float>> g_cont_y_mean(
457 n_regions, std::vector<float>(n_segments, 0.0));
458 std::vector<std::vector<float>> o_cont_energy(
459 n_regions, std::vector<float>(n_segments, 0.0));
460 std::vector<std::vector<int>> o_cont_n_hits(n_regions,
461 std::vector<int>(n_segments, 0));
462 std::vector<std::vector<float>> o_cont_x_mean(
463 n_regions, std::vector<float>(n_segments, 0.0));
464 std::vector<std::vector<float>> o_cont_y_mean(
465 n_regions, std::vector<float>(n_segments, 0.0));
466 std::vector<std::vector<float>> o_cont_x_std(
467 n_regions, std::vector<float>(n_segments, 0.0));
468 std::vector<std::vector<float>> o_cont_y_std(
469 n_regions, std::vector<float>(n_segments, 0.0));
470 std::vector<std::vector<float>> o_cont_layer_mean(
471 n_regions, std::vector<float>(n_segments, 0.0));
472 std::vector<std::vector<float>> o_cont_layer_std(
473 n_regions, std::vector<float>(n_segments, 0.0));
474
475 auto containment_var = std::chrono::high_resolution_clock::now();
476 profiling_map_["containment_var"] +=
477 std::chrono::duration<float, std::milli>(containment_var - fill_hitmaps)
478 .count();
479
480
481
482
483 std::vector<ldmx::HitData> tracking_hit_list;
484
485 ldmx_log(trace)
486 << " Loop over the hits_ from the event to calculate the BDT features";
487
489
491 ecal_layer_edep_raw_[id.layer()] =
492 ecal_layer_edep_raw_[id.layer()] + hit.getEnergy();
493 if (id.layer() >= 20) ecal_back_energy_ += hit.getEnergy();
494 if (max_cell_dep_ < hit.getEnergy()) max_cell_dep_ = hit.getEnergy();
495 if (hit.getEnergy() <= 0) {
496 ldmx_log(fatal)
497 << "ECal hit has negative or zero energy, this should never happen, "
498 "check the threshold settings in HgcrocEmulator";
499 continue;
500 }
501 n_readout_hits_++;
502 ecal_layer_edep_readout_[id.layer()] += hit.getEnergy();
503 ecal_layer_time_[id.layer()] += (hit.getEnergy()) * hit.getTime();
505 x_mean += rechit_x * hit.getEnergy();
506 y_mean += rechit_y * hit.getEnergy();
507 avg_layer_hit_ += id.layer();
508 w_avg_layer_hit += id.layer() * hit.getEnergy();
509 if (deepest_layer_hit_ < id.layer()) {
510 deepest_layer_hit_ = id.layer();
511 }
512 XYCoords xy_pair = std::make_pair(rechit_x, rechit_y);
513 float distance_ele_trajectory =
514 ele_trajectory.size()
515 ? sqrt((xy_pair.first - ele_trajectory[id.layer()].first) *
516 (xy_pair.first - ele_trajectory[id.layer()].first) +
517 (xy_pair.second - ele_trajectory[id.layer()].second) *
518 (xy_pair.second - ele_trajectory[id.layer()].second))
519 : -1.0;
520 float distance_photon_trajectory =
521 photon_trajectory.size()
522 ? sqrt((xy_pair.first - photon_trajectory[id.layer()].first) *
523 (xy_pair.first - photon_trajectory[id.layer()].first) +
524 (xy_pair.second - photon_trajectory[id.layer()].second) *
525 (xy_pair.second - photon_trajectory[id.layer()].second))
526 : -1.0;
527
528
529 for (unsigned int iseg = 0; iseg < n_segments; iseg++) {
530 if (id.layer() >= seg_layers[iseg] &&
531 id.layer() <= seg_layers[iseg + 1] - 1) {
532 energy_seg[iseg] += hit.getEnergy();
533 x_mean_seg[iseg] += xy_pair.first * hit.getEnergy();
534 y_mean_seg[iseg] += xy_pair.second * hit.getEnergy();
535 layer_mean_seg[iseg] += id.layer() * hit.getEnergy();
536
537
538 for (unsigned int ireg = 0; ireg < n_regions; ireg++) {
539 if (distance_ele_trajectory >= ireg * ele_radii[id.layer()] &&
540 distance_ele_trajectory < (ireg + 1) * ele_radii[id.layer()]) {
541 e_cont_energy[ireg][iseg] += hit.getEnergy();
542 e_cont_x_mean[ireg][iseg] += xy_pair.first * hit.getEnergy();
543 e_cont_y_mean[ireg][iseg] += xy_pair.second * hit.getEnergy();
544 }
545 if (distance_photon_trajectory >= ireg * photon_radii[id.layer()] &&
546 distance_photon_trajectory <
547 (ireg + 1) * photon_radii[id.layer()]) {
548 g_cont_energy[ireg][iseg] += hit.getEnergy();
549 g_cont_n_hits[ireg][iseg] += 1;
550 g_cont_x_mean[ireg][iseg] += xy_pair.first * hit.getEnergy();
551 g_cont_y_mean[ireg][iseg] += xy_pair.second * hit.getEnergy();
552 }
553 if (distance_ele_trajectory > (ireg + 1) * ele_radii[id.layer()] &&
554 distance_photon_trajectory >
555 (ireg + 1) * photon_radii[id.layer()]) {
556 o_cont_energy[ireg][iseg] += hit.getEnergy();
557 o_cont_n_hits[ireg][iseg] += 1;
558 o_cont_x_mean[ireg][iseg] += xy_pair.first * hit.getEnergy();
559 o_cont_y_mean[ireg][iseg] += xy_pair.second * hit.getEnergy();
560 o_cont_layer_mean[ireg][iseg] += id.layer() * hit.getEnergy();
561 }
562 }
563 }
564 }
565
566
567 for (unsigned int ireg = 0; ireg < n_regions; ireg++) {
568 if (distance_ele_trajectory >= ireg * ele_radii[id.layer()] &&
569 distance_ele_trajectory < (ireg + 1) * ele_radii[id.layer()])
570 electron_containment_energy[ireg] += hit.getEnergy();
571 if (distance_photon_trajectory >= ireg * photon_radii[id.layer()] &&
572 distance_photon_trajectory < (ireg + 1) * photon_radii[id.layer()])
573 photon_containment_energy[ireg] += hit.getEnergy();
574 if (distance_ele_trajectory > (ireg + 1) * ele_radii[id.layer()] &&
575 distance_photon_trajectory > (ireg + 1) * photon_radii[id.layer()]) {
576 outside_containment_energy[ireg] += hit.getEnergy();
577 outside_containment_n_hits[ireg] += 1;
578 outside_containment_x_mean[ireg] += xy_pair.first * hit.getEnergy();
579 outside_containment_y_mean[ireg] += xy_pair.second * hit.getEnergy();
580 }
581 }
582
583
584
585 if (distance_ele_trajectory >= ele_radii[id.layer()] ||
586 distance_ele_trajectory == -1.0) {
588 hd.pos_ = ROOT::Math::XYZVector(xy_pair.first, xy_pair.second,
590 hd.layer_ = id.layer();
591 tracking_hit_list.push_back(hd);
592 }
593 }
594
596
597 for (const auto &[id, energy] : cell_map_tight_iso_) {
598 if (energy > 0) summed_tight_iso_ += energy;
599 }
600
601 for (int i_layer = 0; i_layer < ecal_layer_edep_readout_.size(); i_layer++) {
602 ecal_layer_time_[i_layer] =
603 ecal_layer_time_[i_layer] / ecal_layer_edep_readout_[i_layer];
604 summed_det_ += ecal_layer_edep_readout_[i_layer];
605 }
606
607 if (n_readout_hits_ > 0) {
608 avg_layer_hit_ /= n_readout_hits_;
609 w_avg_layer_hit /= summed_det_;
610 x_mean /= summed_det_;
611 y_mean /= summed_det_;
612 } else {
613 w_avg_layer_hit = 0;
614 avg_layer_hit_ = 0;
615 x_mean = 0;
616 y_mean = 0;
617 }
618
619
620 for (unsigned int iseg = 0; iseg < n_segments; iseg++) {
621 if (energy_seg[iseg] > 0) {
622 x_mean_seg[iseg] /= energy_seg[iseg];
623 y_mean_seg[iseg] /= energy_seg[iseg];
624 layer_mean_seg[iseg] /= energy_seg[iseg];
625 }
626 for (unsigned int ireg = 0; ireg < n_regions; ireg++) {
627 if (e_cont_energy[ireg][iseg] > 0) {
628 e_cont_x_mean[ireg][iseg] /= e_cont_energy[ireg][iseg];
629 e_cont_y_mean[ireg][iseg] /= e_cont_energy[ireg][iseg];
630 }
631 if (g_cont_energy[ireg][iseg] > 0) {
632 g_cont_x_mean[ireg][iseg] /= g_cont_energy[ireg][iseg];
633 g_cont_y_mean[ireg][iseg] /= g_cont_energy[ireg][iseg];
634 }
635 if (o_cont_energy[ireg][iseg] > 0) {
636 o_cont_x_mean[ireg][iseg] /= o_cont_energy[ireg][iseg];
637 o_cont_y_mean[ireg][iseg] /= o_cont_energy[ireg][iseg];
638 o_cont_layer_mean[ireg][iseg] /= o_cont_energy[ireg][iseg];
639 }
640 }
641 }
642
643 for (unsigned int ireg = 0; ireg < n_regions; ireg++) {
644 if (outside_containment_energy[ireg] > 0) {
645 outside_containment_x_mean[ireg] /= outside_containment_energy[ireg];
646 outside_containment_y_mean[ireg] /= outside_containment_energy[ireg];
647 }
648 }
649
650
654 if (hit.getEnergy() > 0) {
655 x_std_ += pow((rechit_x - x_mean), 2) * hit.getEnergy();
656 y_std_ += pow((rechit_y - y_mean), 2) * hit.getEnergy();
657 std_layer_hit_ +=
658 pow((id.layer() - w_avg_layer_hit), 2) * hit.getEnergy();
659 }
660 XYCoords xy_pair = std::make_pair(rechit_x, rechit_y);
661 float distance_ele_trajectory =
662 ele_trajectory.size()
663 ? sqrt(pow((xy_pair.first - ele_trajectory[id.layer()].first), 2) +
664 pow((xy_pair.second - ele_trajectory[id.layer()].second), 2))
665 : -1.0;
666 float distance_photon_trajectory =
667 photon_trajectory.size()
668 ? sqrt(pow((xy_pair.first - photon_trajectory[id.layer()].first),
669 2) +
670 pow((xy_pair.second - photon_trajectory[id.layer()].second),
671 2))
672 : -1.0;
673
674 for (unsigned int iseg = 0; iseg < n_segments; iseg++) {
675 if (id.layer() >= seg_layers[iseg] &&
676 id.layer() <= seg_layers[iseg + 1] - 1) {
677 x_std_seg[iseg] +=
678 pow((xy_pair.first - x_mean_seg[iseg]), 2) * hit.getEnergy();
679 y_std_seg[iseg] +=
680 pow((xy_pair.second - y_mean_seg[iseg]), 2) * hit.getEnergy();
681 layer_std_seg[iseg] +=
682 pow((id.layer() - layer_mean_seg[iseg]), 2) * hit.getEnergy();
683
684 for (unsigned int ireg = 0; ireg < n_regions; ireg++) {
685 if (distance_ele_trajectory > (ireg + 1) * ele_radii[id.layer()] &&
686 distance_photon_trajectory >
687 (ireg + 1) * photon_radii[id.layer()]) {
688 o_cont_x_std[ireg][iseg] +=
689 pow((xy_pair.first - o_cont_x_mean[ireg][iseg]), 2) *
690 hit.getEnergy();
691 o_cont_y_std[ireg][iseg] +=
692 pow((xy_pair.second - o_cont_y_mean[ireg][iseg]), 2) *
693 hit.getEnergy();
694 o_cont_layer_std[ireg][iseg] +=
695 pow((id.layer() - o_cont_layer_mean[ireg][iseg]), 2) *
696 hit.getEnergy();
697 }
698 }
699 }
700 }
701
702 for (unsigned int ireg = 0; ireg < n_regions; ireg++) {
703 if (distance_ele_trajectory > (ireg + 1) * ele_radii[id.layer()] &&
704 distance_photon_trajectory > (ireg + 1) * photon_radii[id.layer()]) {
705 outside_containment_x_std[ireg] +=
706 pow((xy_pair.first - outside_containment_x_mean[ireg]), 2) *
707 hit.getEnergy();
708 outside_containment_y_std[ireg] +=
709 pow((xy_pair.second - outside_containment_y_mean[ireg]), 2) *
710 hit.getEnergy();
711 }
712 }
713 }
714
715 if (n_readout_hits_ > 0) {
716 x_std_ = sqrt(x_std_ / summed_det_);
717 y_std_ = sqrt(y_std_ / summed_det_);
718 std_layer_hit_ = sqrt(std_layer_hit_ / summed_det_);
719 } else {
720 x_std_ = 0;
721 y_std_ = 0;
722 std_layer_hit_ = 0;
723 }
724
725
726
727 for (unsigned int iseg = 0; iseg < n_segments; iseg++) {
728 if (energy_seg[iseg] > 0) {
729 x_std_seg[iseg] = sqrt(x_std_seg[iseg] / energy_seg[iseg]);
730 y_std_seg[iseg] = sqrt(y_std_seg[iseg] / energy_seg[iseg]);
731 layer_std_seg[iseg] = sqrt(layer_std_seg[iseg] / energy_seg[iseg]);
732 }
733 for (unsigned int ireg = 0; ireg < n_regions; ireg++) {
734 if (o_cont_energy[ireg][iseg] > 0) {
735 o_cont_x_std[ireg][iseg] =
736 sqrt(o_cont_x_std[ireg][iseg] / o_cont_energy[ireg][iseg]);
737 o_cont_y_std[ireg][iseg] =
738 sqrt(o_cont_y_std[ireg][iseg] / o_cont_energy[ireg][iseg]);
739 o_cont_layer_std[ireg][iseg] =
740 sqrt(o_cont_layer_std[ireg][iseg] / o_cont_energy[ireg][iseg]);
741 }
742 }
743 }
744
745 for (unsigned int ireg = 0; ireg < n_regions; ireg++) {
746 if (outside_containment_energy[ireg] > 0) {
747 outside_containment_x_std[ireg] = sqrt(outside_containment_x_std[ireg] /
748 outside_containment_energy[ireg]);
749 outside_containment_y_std[ireg] = sqrt(outside_containment_y_std[ireg] /
750 outside_containment_energy[ireg]);
751 }
752 }
753
754 ldmx_log(trace) << " Find out if the recoil electron is fiducial";
755
756
757
758
759 const float dz_from_face =
761 float drifted_recoil_x{-9999.};
762 float drifted_recoil_y{-9999.};
763 if (recoil_p[2] > 0.) {
764 ldmx_log(trace) << " Recoil electron pX = " << recoil_p[0]
765 << " pY = " << recoil_p[1] << " pZ = " << recoil_p[2];
766 ldmx_log(trace) << " Recoil electron PosX = " << recoil_pos[0]
767 << " PosY = " << recoil_pos[1]
768 << " PosZ = " << recoil_pos[2];
769 drifted_recoil_x =
770 (dz_from_face * (recoil_p[0] / recoil_p[2])) + recoil_pos[0];
771 drifted_recoil_y =
772 (dz_from_face * (recoil_p[1] / recoil_p[2])) + recoil_pos[1];
773 }
774 const int recoil_layer_index = 0;
775
776
777 bool inside_ecal_cell{false};
778
779 const auto ecal_id =
geometry_->
getID(drifted_recoil_x, drifted_recoil_y,
780 recoil_layer_index, true);
781 if (!ecal_id.null()) {
782
783 const auto cell_id =
784 geometry_->
getID(drifted_recoil_x, drifted_recoil_y, recoil_layer_index,
785 ecal_id.getModuleID(), true);
786 if (!cell_id.null()) {
787 inside_ecal_cell = true;
788 }
789 }
790
791 ldmx_log(info) << " Is this event is fiducial in ECAL? "
792 << inside_ecal_cell;
793 ROOT::Math::XYZVector e_traj_start;
794 ROOT::Math::XYZVector e_traj_end;
795 ROOT::Math::XYZVector e_traj_target_start;
796 ROOT::Math::XYZVector e_traj_target_end;
797 ROOT::Math::XYZVector p_traj_start;
798 ROOT::Math::XYZVector p_traj_end;
799 if (!ele_trajectory.empty() && !photon_trajectory.empty()) {
800
801
802 e_traj_start.SetXYZ(ele_trajectory[0].first, ele_trajectory[0].second,
804 e_traj_end.SetXYZ(ele_trajectory[(n_ecal_layers_ - 1)].first,
805 ele_trajectory[(n_ecal_layers_ - 1)].second,
807 p_traj_start.SetXYZ(photon_trajectory[0].first, photon_trajectory[0].second,
809 p_traj_end.SetXYZ(photon_trajectory[(n_ecal_layers_ - 1)].first,
810 photon_trajectory[(n_ecal_layers_ - 1)].second,
812
813 ROOT::Math::XYZVector evec = e_traj_end - e_traj_start;
814 ROOT::Math::XYZVector e_norm = evec.Unit();
815 ROOT::Math::XYZVector pvec = p_traj_end - p_traj_start;
816 ROOT::Math::XYZVector p_norm = pvec.Unit();
817
818
819
822 ep_sep_ = sqrt(pow(e_traj_start.X() - p_traj_start.X(), 2) +
823 pow(e_traj_start.Y() - p_traj_start.Y(), 2));
824
825
826 if (!ele_trajectory_at_target.empty()) {
827 e_traj_target_start.SetXYZ(recoil_pos_at_target[0],
828 recoil_pos_at_target[1],
829 static_cast<float>(0.0));
830 e_traj_target_end.SetXYZ(ele_trajectory_at_target[(0)].first,
831 ele_trajectory_at_target[(0)].second,
833
834 ROOT::Math::XYZVector evec_target =
835 e_traj_target_end - e_traj_target_start;
836 ROOT::Math::XYZVector e_norm_target = evec_target.Unit();
839 }
840 ldmx_log(trace) << " Electron trajectory calculated";
841 } else {
842
843
844
845 ldmx_log(trace) << " Electron trajectory is missing";
847 e_traj_end = ROOT::Math::XYZVector(
849 p_traj_start =
851 p_traj_end = ROOT::Math::XYZVector(
853
859 }
860
862 ldmx_log(trace) << " Set up input info for MIP tracking";
863 ecal_mip_collection.setEleTrajectory(ele_trajectory);
864 ecal_mip_collection.setPhotonTrajectory(photon_trajectory);
865 ecal_mip_collection.setTrackingHitList(tracking_hit_list);
866 event.add("EcalTrajectoryInfo", ecal_mip_collection);
867
868 auto mip_tracking_setup = std::chrono::high_resolution_clock::now();
869 profiling_map_["mip_tracking_setup"] +=
870 std::chrono::duration<double, std::milli>(mip_tracking_setup - start)
871 .count();
874 summed_tight_iso_, max_cell_dep_, shower_rms_, x_std_, y_std_,
875 avg_layer_hit_, std_layer_hit_, ecal_back_energy_,
ep_ang_,
877 electron_containment_energy, photon_containment_energy,
878 outside_containment_energy, outside_containment_n_hits,
879 outside_containment_x_std, outside_containment_y_std, energy_seg,
880 x_mean_seg, y_mean_seg, x_std_seg, y_std_seg, layer_mean_seg,
881 layer_std_seg, e_cont_energy, e_cont_x_mean, e_cont_y_mean, g_cont_energy,
882 g_cont_n_hits, g_cont_x_mean, g_cont_y_mean, o_cont_energy, o_cont_n_hits,
883 o_cont_x_mean, o_cont_y_mean, o_cont_x_std, o_cont_y_std,
884 o_cont_layer_mean, o_cont_layer_std, ecal_layer_edep_readout_, recoil_p,
885 recoil_pos);
886
887 auto set_variables = std::chrono::high_resolution_clock::now();
888 profiling_map_["set_variables"] += std::chrono::duration<double, std::milli>(
889 set_variables - mip_tracking_setup)
890 .count();
892 ldmx::ort::FloatArrays inputs({bdt_features_});
893 float pred =
894 rt_->run({feature_list_name_}, inputs, {"probabilities"})[0].at(1);
895 ldmx_log(info) << " BDT was ran, score is " << pred;
896
897
898
899 result.setVetoResult(pred > bdt_cut_val_);
900 result.setDiscValue(pred);
901 ldmx_log(info) << " The pred > bdtCutVal = " << (pred > bdt_cut_val_);
902
903
904 result.setFiducial(inside_ecal_cell);
905 result.setTrackingFiducial(fiducial_in_tracker);
906
907
908
909 if (!inverse_skim_) {
912 } else {
914 }
915 } else {
916
919 } else {
921 }
922 }
923
925
926 auto bdt_variables = std::chrono::high_resolution_clock::now();
927 profiling_map_["bdt_variables"] +=
928 std::chrono::duration<float, std::milli>(bdt_variables - set_variables)
929 .count();
930
931 auto end = std::chrono::high_resolution_clock::now();
932 auto time_diff = end - start;
933 processing_time_ +=
934 std::chrono::duration<float, std::milli>(time_diff).count();
935}
std::tuple< int, const ldmx::SimParticle * > getRecoil(const std::map< int, ldmx::SimParticle > &particleMap)
Find and return the sim particle associated with the recoil electron.
std::vector< float > trackProp(const ldmx::Tracks &tracks, ldmx::TrackStateType ts_type, const std::string &ts_title)
Return a vector of parameters for a propagated recoil track.
void fillHitMap(const std::vector< ldmx::EcalHit > &ecal_rec_hits, std::map< ldmx::EcalID, float > &cell_map_)
Function to load up empty vector of hit maps.
void buildBDTFeatureVector(const ldmx::EcalVetoResult &result)
const T & getCondition(const std::string &condition_name)
Access a conditions object for the current event.
void setStorageHint(framework::StorageControl::Hint hint)
Mark the current event as having the given storage control hint from this module_.
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.
EcalID getID(double x, double y, double z, bool fallible=false) const
Get a cell's ID number from its position.
double getEcalFrontZ() const
Get the z-coordinate of the Ecal face.
bool passesVeto() const
Checks if the event passes the Ecal veto.
void setVariables(int n_readout_hits, int deepest_layer_hit, int n_tracking_hits, float summed_det, float summed_tight_iso, float max_cell_dep, float shower_rms, float x_std, float y_std, float avg_layer_hit, float std_layer_hit, float ecal_back_energy, float ep_ang, float ep_ang_at_target, float ep_sep, float ep_dot, float ep_dot_at_target, std::vector< float > electron_containment_energy, std::vector< float > photon_containment_energy, std::vector< float > outside_containment_energy, std::vector< int > outside_containment_n_hits, std::vector< float > outside_containment_x_std, std::vector< float > outside_containment_y_std, std::vector< float > energy_seg, std::vector< float > x_mean_seg, std::vector< float > y_mean_seg, std::vector< float > x_std_seg, std::vector< float > y_std_seg, std::vector< float > layer_mean_seg, std::vector< float > layer_std_seg, std::vector< std::vector< float > > e_cont_energy, std::vector< std::vector< float > > e_cont_x_mean, std::vector< std::vector< float > > e_cont_y_mean, std::vector< std::vector< float > > g_cont_energy, std::vector< std::vector< int > > g_cont_n_hits, std::vector< std::vector< float > > g_cont_x_mean, std::vector< std::vector< float > > g_cont_y_mean, std::vector< std::vector< float > > o_cont_energy, std::vector< std::vector< int > > o_cont_n_hits, std::vector< std::vector< float > > o_cont_x_mean, std::vector< std::vector< float > > o_cont_y_mean, std::vector< std::vector< float > > o_cont_x_std, std::vector< std::vector< float > > o_cont_y_std, std::vector< std::vector< float > > o_cont_layer_mean, std::vector< std::vector< float > > o_cont_layer_std, std::vector< float > ecal_layer_edep_readout, std::array< float, 3 > recoil_p, std::array< float, 3 > recoil_pos)
Set the sim particle and 'is findable' flag.
Class representing a simulated particle.
Implements detector ids for special simulation-derived hits like scoring planes.
Represents a simulated tracker hit in the simulation.
Implementation of a track object.
constexpr StorageControl::Hint HINT_SHOULD_DROP
storage control hint alias for backwards compatibility
constexpr StorageControl::Hint HINT_SHOULD_KEEP
storage control hint alias for backwards compatibility