168 auto start = std::chrono::high_resolution_clock::now();
173 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
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.};
187 auto setup = std::chrono::high_resolution_clock::now();
188 profiling_map_[
"setup"] +=
189 std::chrono::duration<float, std::milli>(setup - start).count();
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 "
201 "SimParticles", sim_particles_passname_)};
204 auto [recoil_track_id, recoil_electron] = analysis::getRecoil(particle_map);
208 ecal_sp_coll_name_, sp_pass_name_)};
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;
216 if (sp_hit.getTrackID() == recoil_track_id) {
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]);
233 if (event.
exists(target_sp_coll_name_, sp_pass_name_)) {
234 std::vector<ldmx::SimTrackerHit> target_sp_hits =
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;
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]};
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]));
265 bool fiducial_in_tracker{
false};
266 if (recoil_from_tracking_) {
267 ldmx_log(trace) <<
" Get recoil tracks collection";
271 event.getCollection<
ldmx::Track>(track_collection_, track_pass_name_)};
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 =
282 ldmx_log(trace) <<
" Set recoil_pos and recoil_p";
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])};
292 ldmx_log(trace) <<
" No recoil track at ECAL";
293 fiducial_in_tracker =
false;
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] <<
")";
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]};
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] <<
")";
317 ldmx_log(trace) <<
" Get projected trajectories for electron and photon";
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();
324 std::vector<XYCoords> ele_trajectory, photon_trajectory,
325 ele_trajectory_at_target;
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);
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]};
339 getTrajectory(photon_proj_momentum, recoil_pos_at_target);
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];
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]))
352 recoil_p_mag > 0 ? acos(recoil_p[2] / recoil_p_mag) * 180.0 / M_PI : -1.0;
354 ldmx_log(trace) <<
" Build Radii of containment (ROC)";
356 auto trajectories = std::chrono::high_resolution_clock::now();
357 profiling_map_[
"trajectories"] +=
358 std::chrono::duration<float, std::milli>(trajectories - recoil_electron)
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;
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];
375 if (theta_min != -1.0) {
376 inrange = inrange && (recoil_theta >= theta_min);
378 if (theta_max != -1.0) {
379 inrange = inrange && (recoil_theta < theta_max);
382 inrange = inrange && (recoil_p_mag >= p_min);
385 inrange = inrange && (recoil_p_mag < p_max);
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;
394 std::vector<float> photon_radii = roc_values_bin_0;
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();
401 const std::vector<ldmx::EcalHit> ecal_rec_hits =
402 event.getCollection<
ldmx::EcalHit>(rec_coll_name_, rec_pass_name_);
405 getShowerCentroidIdAndRms(ecal_rec_hits, shower_rms_);
408 bool do_tight =
true;
410 fillIsolatedHitMap(ecal_rec_hits, global_centroid, cell_map_,
411 cell_map_tight_iso_, do_tight);
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();
420 float w_avg_layer_hit = 0;
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);
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));
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)
483 std::vector<ldmx::HitData> tracking_hit_list;
486 <<
" Loop over the hits_ from the event to calculate the BDT features";
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) {
497 <<
"ECal hit has negative or zero energy, this should never happen, "
498 "check the threshold settings in HgcrocEmulator";
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();
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))
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))
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();
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();
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();
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();
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();
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);
597 for (
const auto &[
id, energy] : cell_map_tight_iso_) {
598 if (energy > 0) summed_tight_iso_ += energy;
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];
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_;
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];
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];
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];
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];
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];
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();
658 pow((
id.layer() - w_avg_layer_hit), 2) * hit.getEnergy();
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))
666 float distance_photon_trajectory =
667 photon_trajectory.size()
668 ? sqrt(pow((xy_pair.first - photon_trajectory[
id.layer()].first),
670 pow((xy_pair.second - photon_trajectory[
id.layer()].second),
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) {
678 pow((xy_pair.first - x_mean_seg[iseg]), 2) * hit.getEnergy();
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();
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) *
691 o_cont_y_std[ireg][iseg] +=
692 pow((xy_pair.second - o_cont_y_mean[ireg][iseg]), 2) *
694 o_cont_layer_std[ireg][iseg] +=
695 pow((
id.layer() - o_cont_layer_mean[ireg][iseg]), 2) *
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) *
708 outside_containment_y_std[ireg] +=
709 pow((xy_pair.second - outside_containment_y_mean[ireg]), 2) *
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_);
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]);
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]);
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]);
754 ldmx_log(trace) <<
" Find out if the recoil electron is fiducial";
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];
770 (dz_from_face * (recoil_p[0] / recoil_p[2])) + recoil_pos[0];
772 (dz_from_face * (recoil_p[1] / recoil_p[2])) + recoil_pos[1];
774 const int recoil_layer_index = 0;
777 bool inside_ecal_cell{
false};
779 const auto ecal_id =
geometry_->
getID(drifted_recoil_x, drifted_recoil_y,
780 recoil_layer_index,
true);
781 if (!ecal_id.null()) {
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;
791 ldmx_log(info) <<
" Is this event is fiducial in ECAL? "
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()) {
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,
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();
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));
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,
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();
840 ldmx_log(trace) <<
" Electron trajectory calculated";
845 ldmx_log(trace) <<
" Electron trajectory is missing";
847 e_traj_end = ROOT::Math::XYZVector(
851 p_traj_end = ROOT::Math::XYZVector(
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);
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)
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,
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)
892 ldmx::ort::FloatArrays inputs({bdt_features_});
894 rt_->run({feature_list_name_}, inputs, {
"probabilities"})[0].at(1);
895 ldmx_log(info) <<
" BDT was ran, score is " << pred;
899 result.setVetoResult(pred > bdt_cut_val_);
900 result.setDiscValue(pred);
901 ldmx_log(info) <<
" The pred > bdtCutVal = " << (pred > bdt_cut_val_);
904 result.setFiducial(inside_ecal_cell);
905 result.setTrackingFiducial(fiducial_in_tracker);
909 if (!inverse_skim_) {
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)
931 auto end = std::chrono::high_resolution_clock::now();
932 auto time_diff = end - start;
934 std::chrono::duration<float, std::milli>(time_diff).count();