166 auto start = std::chrono::high_resolution_clock::now();
171 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
180 std::array<float, 3> recoil_p = {0., 0., 0.};
181 std::array<float, 3> recoil_pos = {-9999., -9999., -9999.};
182 std::array<float, 3> recoil_p_at_target = {0., 0., 0.};
183 std::array<float, 3> recoil_pos_at_target = {-9999., -9999., -9999.};
185 auto setup = std::chrono::high_resolution_clock::now();
186 profiling_map_[
"setup"] +=
187 std::chrono::duration<float, std::milli>(setup - start).count();
189 if (!recoil_from_tracking_ &&
190 event.
exists(
"EcalScoringPlaneHits", sp_pass_name_)) {
191 ldmx_log(trace) <<
" Loop through all of the sim particles and find the "
199 "SimParticles", sim_particles_passname_)};
202 auto [recoil_track_id, recoil_electron] = analysis::getRecoil(particle_map);
206 "EcalScoringPlaneHits", sp_pass_name_)};
210 auto ecal_sp_momentum = sp_hit.getMomentum();
211 auto ecal_sp_position = sp_hit.getPosition();
212 if (hit_id.
plane() != 31 || ecal_sp_momentum[2] <= 0)
continue;
214 if (sp_hit.getTrackID() == recoil_track_id) {
216 if (sqrt((ecal_sp_momentum[0] * ecal_sp_momentum[0]) +
217 (ecal_sp_momentum[1] * ecal_sp_momentum[1]) +
218 (ecal_sp_momentum[2] * ecal_sp_momentum[2])) > pmax) {
219 recoil_p = {
static_cast<float>(ecal_sp_momentum[0]),
220 static_cast<float>(ecal_sp_momentum[1]),
221 static_cast<float>(ecal_sp_momentum[2])};
222 recoil_pos = {(ecal_sp_position[0]), (ecal_sp_position[1]),
223 (ecal_sp_position[2])};
224 pmax = sqrt(recoil_p[0] * recoil_p[0] + recoil_p[1] * recoil_p[1] +
225 recoil_p[2] * recoil_p[2]);
231 if (event.
exists(
"TargetScoringPlaneHits", sp_pass_name_)) {
232 std::vector<ldmx::SimTrackerHit> target_sp_hits =
238 auto target_sp_momentum = sp_hit.getMomentum();
239 auto target_sp_position = sp_hit.getPosition();
240 if (hit_id.
plane() != 1 || target_sp_momentum[2] <= 0)
continue;
242 if (sp_hit.getTrackID() == recoil_track_id) {
243 if (sqrt((target_sp_momentum[0] * target_sp_momentum[0]) +
244 (target_sp_momentum[1] * target_sp_momentum[1]) +
245 (target_sp_momentum[2] * target_sp_momentum[2])) > pmax) {
246 recoil_p_at_target = {
static_cast<float>(target_sp_momentum[0]),
247 static_cast<float>(target_sp_momentum[1]),
248 static_cast<float>(target_sp_momentum[2])};
249 recoil_pos_at_target = {target_sp_position[0],
250 target_sp_position[1],
251 target_sp_position[2]};
253 pmax = sqrt((recoil_p_at_target[0] * recoil_p_at_target[0]) +
254 (recoil_p_at_target[1] * recoil_p_at_target[1]) +
255 (recoil_p_at_target[2] * recoil_p_at_target[2]));
263 bool fiducial_in_tracker{
false};
264 if (recoil_from_tracking_) {
265 ldmx_log(trace) <<
" Get recoil tracks collection";
269 event.getCollection<
ldmx::Track>(track_collection_, track_pass_name_)};
271 ldmx_log(trace) <<
" Propagate the recoil ele to the ECAL";
272 ldmx::TrackStateType ts_type = ldmx::TrackStateType::AtECAL;
273 auto recoil_track_states_ecal =
275 ldmx_log(trace) <<
" Propagate the recoil ele to the Target";
276 ldmx::TrackStateType ts_type_target = ldmx::TrackStateType::AtTarget;
277 auto recoil_track_states_target =
280 ldmx_log(trace) <<
" Set recoil_pos and recoil_p";
283 if (!recoil_track_states_ecal.empty()) {
284 fiducial_in_tracker =
true;
285 recoil_pos = {recoil_track_states_ecal[0], recoil_track_states_ecal[1],
286 recoil_track_states_ecal[2]};
287 recoil_p = {(recoil_track_states_ecal[3]), (recoil_track_states_ecal[4]),
288 (recoil_track_states_ecal[5])};
290 ldmx_log(trace) <<
" No recoil track at ECAL";
291 fiducial_in_tracker =
false;
293 ldmx_log(debug) <<
" Set recoil_p = (" << recoil_p[0] <<
", "
294 << recoil_p[1] <<
", " << recoil_p[2]
295 <<
") and recoil_pos = (" << recoil_pos[0] <<
", "
296 << recoil_pos[1] <<
", " << recoil_pos[2] <<
")";
299 if (!recoil_track_states_target.empty()) {
300 recoil_pos_at_target = {(recoil_track_states_target[0]),
301 (recoil_track_states_target[1]),
302 (recoil_track_states_target[2])};
303 recoil_p_at_target = {recoil_track_states_target[3],
304 recoil_track_states_target[4],
305 recoil_track_states_target[5]};
307 ldmx_log(debug) <<
" Set recoil_p_at_target = (" << recoil_p_at_target[0]
308 <<
", " << recoil_p_at_target[1] <<
", "
309 << recoil_p_at_target[2] <<
") and recoil_pos_at_target = ("
310 << recoil_pos_at_target[0] <<
", "
311 << recoil_pos_at_target[1] <<
", "
312 << recoil_pos_at_target[2] <<
")";
315 ldmx_log(trace) <<
" Get projected trajectories for electron and photon";
317 auto recoil_electron = std::chrono::high_resolution_clock::now();
318 profiling_map_[
"recoil_electron"] +=
319 std::chrono::duration<float, std::milli>(recoil_electron - setup).count();
322 std::vector<XYCoords> ele_trajectory, photon_trajectory,
323 ele_trajectory_at_target;
326 if ((recoil_p[2] > 0.) && (recoil_p_at_target[2] > 0.) &&
327 (recoil_pos[0] != -9999.) && (recoil_pos_at_target[0] != -9999.)) {
328 ele_trajectory = getTrajectory(recoil_p, recoil_pos);
329 ele_trajectory_at_target =
330 getTrajectory(recoil_p_at_target, recoil_pos_at_target);
333 std::array<float, 3> photon_proj_momentum = {
334 -recoil_p_at_target[0], -recoil_p_at_target[1],
335 beam_energy_mev_ - recoil_p_at_target[2]};
337 getTrajectory(photon_proj_momentum, recoil_pos_at_target);
339 ldmx_log(trace) <<
"Ele / photon trajectory cannot be determined, pZ = "
340 << recoil_p[2] <<
" pZAtTarget = " << recoil_p_at_target[2]
341 <<
" X = " << recoil_pos[0]
342 <<
" XAtTarget = " << recoil_pos_at_target[0];
345 float recoil_p_mag = (recoil_p[2] > 0.) ? sqrt((recoil_p[0] * recoil_p[0]) +
346 (recoil_p[1] * recoil_p[1]) +
347 (recoil_p[2] * recoil_p[2]))
350 recoil_p_mag > 0 ? acos(recoil_p[2] / recoil_p_mag) * 180.0 / M_PI : -1.0;
352 ldmx_log(trace) <<
" Build Radii of containment (ROC)";
354 auto trajectories = std::chrono::high_resolution_clock::now();
355 profiling_map_[
"trajectories"] +=
356 std::chrono::duration<float, std::milli>(trajectories - recoil_electron)
360 std::vector<float> roc_values_bin_0(roc_range_values_[0].begin() + 4,
361 roc_range_values_[0].end());
362 std::vector<float> ele_radii = roc_values_bin_0;
363 float theta_min, theta_max, p_min, p_max;
366 for (
int i = 0; i < roc_range_values_.size(); i++) {
367 theta_min = roc_range_values_[i][0];
368 theta_max = roc_range_values_[i][1];
369 p_min = roc_range_values_[i][2];
370 p_max = roc_range_values_[i][3];
373 if (theta_min != -1.0) {
374 inrange = inrange && (recoil_theta >= theta_min);
376 if (theta_max != -1.0) {
377 inrange = inrange && (recoil_theta < theta_max);
380 inrange = inrange && (recoil_p_mag >= p_min);
383 inrange = inrange && (recoil_p_mag < p_max);
386 std::vector<float> roc_values_bini(roc_range_values_[i].begin() + 4,
387 roc_range_values_[i].end());
388 ele_radii = roc_values_bini;
392 std::vector<float> photon_radii = roc_values_bin_0;
394 auto roc_var = std::chrono::high_resolution_clock::now();
395 profiling_map_[
"roc_var"] +=
396 std::chrono::duration<float, std::milli>(roc_var - trajectories).count();
399 const std::vector<ldmx::EcalHit> ecal_rec_hits =
400 event.getCollection<
ldmx::EcalHit>(rec_coll_name_, rec_pass_name_);
403 getShowerCentroidIdAndRms(ecal_rec_hits, shower_rms_);
406 bool do_tight =
true;
408 fillIsolatedHitMap(ecal_rec_hits, global_centroid, cell_map_,
409 cell_map_tight_iso_, do_tight);
411 auto fill_hitmaps = std::chrono::high_resolution_clock::now();
412 profiling_map_[
"fill_hitmaps"] +=
413 std::chrono::duration<float, std::milli>(fill_hitmaps - roc_var).count();
418 float w_avg_layer_hit = 0;
423 unsigned int n_regions = 5;
424 std::vector<float> electron_containment_energy(n_regions, 0.0);
425 std::vector<float> photon_containment_energy(n_regions, 0.0);
426 std::vector<float> outside_containment_energy(n_regions, 0.0);
427 std::vector<int> outside_containment_n_hits(n_regions, 0);
428 std::vector<float> outside_containment_x_mean(n_regions, 0.0);
429 std::vector<float> outside_containment_y_mean(n_regions, 0.0);
430 std::vector<float> outside_containment_x_std(n_regions, 0.0);
431 std::vector<float> outside_containment_y_std(n_regions, 0.0);
433 std::vector<int> seg_layers = {0, 6, 17, 32};
434 unsigned int n_segments = seg_layers.size() - 1;
435 std::vector<float> energy_seg(n_segments, 0.0);
436 std::vector<float> x_mean_seg(n_segments, 0.0);
437 std::vector<float> x_std_seg(n_segments, 0.0);
438 std::vector<float> y_mean_seg(n_segments, 0.0);
439 std::vector<float> y_std_seg(n_segments, 0.0);
440 std::vector<float> layer_mean_seg(n_segments, 0.0);
441 std::vector<float> layer_std_seg(n_segments, 0.0);
442 std::vector<std::vector<float>> e_cont_energy(
443 n_regions, std::vector<float>(n_segments, 0.0));
444 std::vector<std::vector<float>> e_cont_x_mean(
445 n_regions, std::vector<float>(n_segments, 0.0));
446 std::vector<std::vector<float>> e_cont_y_mean(
447 n_regions, std::vector<float>(n_segments, 0.0));
448 std::vector<std::vector<float>> g_cont_energy(
449 n_regions, std::vector<float>(n_segments, 0.0));
450 std::vector<std::vector<int>> g_cont_n_hits(n_regions,
451 std::vector<int>(n_segments, 0));
452 std::vector<std::vector<float>> g_cont_x_mean(
453 n_regions, std::vector<float>(n_segments, 0.0));
454 std::vector<std::vector<float>> g_cont_y_mean(
455 n_regions, std::vector<float>(n_segments, 0.0));
456 std::vector<std::vector<float>> o_cont_energy(
457 n_regions, std::vector<float>(n_segments, 0.0));
458 std::vector<std::vector<int>> o_cont_n_hits(n_regions,
459 std::vector<int>(n_segments, 0));
460 std::vector<std::vector<float>> o_cont_x_mean(
461 n_regions, std::vector<float>(n_segments, 0.0));
462 std::vector<std::vector<float>> o_cont_y_mean(
463 n_regions, std::vector<float>(n_segments, 0.0));
464 std::vector<std::vector<float>> o_cont_x_std(
465 n_regions, std::vector<float>(n_segments, 0.0));
466 std::vector<std::vector<float>> o_cont_y_std(
467 n_regions, std::vector<float>(n_segments, 0.0));
468 std::vector<std::vector<float>> o_cont_layer_mean(
469 n_regions, std::vector<float>(n_segments, 0.0));
470 std::vector<std::vector<float>> o_cont_layer_std(
471 n_regions, std::vector<float>(n_segments, 0.0));
473 auto containment_var = std::chrono::high_resolution_clock::now();
474 profiling_map_[
"containment_var"] +=
475 std::chrono::duration<float, std::milli>(containment_var - fill_hitmaps)
481 std::vector<ldmx::HitData> tracking_hit_list;
484 <<
" Loop over the hits_ from the event to calculate the BDT features";
489 ecal_layer_edep_raw_[
id.layer()] =
490 ecal_layer_edep_raw_[
id.layer()] + hit.getEnergy();
491 if (
id.layer() >= 20) ecal_back_energy_ += hit.getEnergy();
492 if (max_cell_dep_ < hit.getEnergy()) max_cell_dep_ = hit.getEnergy();
493 if (hit.getEnergy() <= 0) {
495 <<
"ECal hit has negative or zero energy, this should never happen, "
496 "check the threshold settings in HgcrocEmulator";
500 ecal_layer_edep_readout_[
id.layer()] += hit.getEnergy();
501 ecal_layer_time_[
id.layer()] += (hit.getEnergy()) * hit.getTime();
503 x_mean += rechit_x * hit.getEnergy();
504 y_mean += rechit_y * hit.getEnergy();
505 avg_layer_hit_ +=
id.layer();
506 w_avg_layer_hit +=
id.layer() * hit.getEnergy();
507 if (deepest_layer_hit_ <
id.layer()) {
508 deepest_layer_hit_ =
id.layer();
510 XYCoords xy_pair = std::make_pair(rechit_x, rechit_y);
511 float distance_ele_trajectory =
512 ele_trajectory.size()
513 ? sqrt((xy_pair.first - ele_trajectory[
id.layer()].first) *
514 (xy_pair.first - ele_trajectory[
id.layer()].first) +
515 (xy_pair.second - ele_trajectory[
id.layer()].second) *
516 (xy_pair.second - ele_trajectory[
id.layer()].second))
518 float distance_photon_trajectory =
519 photon_trajectory.size()
520 ? sqrt((xy_pair.first - photon_trajectory[
id.layer()].first) *
521 (xy_pair.first - photon_trajectory[
id.layer()].first) +
522 (xy_pair.second - photon_trajectory[
id.layer()].second) *
523 (xy_pair.second - photon_trajectory[
id.layer()].second))
527 for (
unsigned int iseg = 0; iseg < n_segments; iseg++) {
528 if (
id.layer() >= seg_layers[iseg] &&
529 id.layer() <= seg_layers[iseg + 1] - 1) {
530 energy_seg[iseg] += hit.getEnergy();
531 x_mean_seg[iseg] += xy_pair.first * hit.getEnergy();
532 y_mean_seg[iseg] += xy_pair.second * hit.getEnergy();
533 layer_mean_seg[iseg] +=
id.layer() * hit.getEnergy();
536 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
537 if (distance_ele_trajectory >= ireg * ele_radii[
id.layer()] &&
538 distance_ele_trajectory < (ireg + 1) * ele_radii[
id.layer()]) {
539 e_cont_energy[ireg][iseg] += hit.getEnergy();
540 e_cont_x_mean[ireg][iseg] += xy_pair.first * hit.getEnergy();
541 e_cont_y_mean[ireg][iseg] += xy_pair.second * hit.getEnergy();
543 if (distance_photon_trajectory >= ireg * photon_radii[
id.layer()] &&
544 distance_photon_trajectory <
545 (ireg + 1) * photon_radii[
id.layer()]) {
546 g_cont_energy[ireg][iseg] += hit.getEnergy();
547 g_cont_n_hits[ireg][iseg] += 1;
548 g_cont_x_mean[ireg][iseg] += xy_pair.first * hit.getEnergy();
549 g_cont_y_mean[ireg][iseg] += xy_pair.second * hit.getEnergy();
551 if (distance_ele_trajectory > (ireg + 1) * ele_radii[
id.layer()] &&
552 distance_photon_trajectory >
553 (ireg + 1) * photon_radii[
id.layer()]) {
554 o_cont_energy[ireg][iseg] += hit.getEnergy();
555 o_cont_n_hits[ireg][iseg] += 1;
556 o_cont_x_mean[ireg][iseg] += xy_pair.first * hit.getEnergy();
557 o_cont_y_mean[ireg][iseg] += xy_pair.second * hit.getEnergy();
558 o_cont_layer_mean[ireg][iseg] +=
id.layer() * hit.getEnergy();
565 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
566 if (distance_ele_trajectory >= ireg * ele_radii[
id.layer()] &&
567 distance_ele_trajectory < (ireg + 1) * ele_radii[
id.layer()])
568 electron_containment_energy[ireg] += hit.getEnergy();
569 if (distance_photon_trajectory >= ireg * photon_radii[
id.layer()] &&
570 distance_photon_trajectory < (ireg + 1) * photon_radii[
id.layer()])
571 photon_containment_energy[ireg] += hit.getEnergy();
572 if (distance_ele_trajectory > (ireg + 1) * ele_radii[
id.layer()] &&
573 distance_photon_trajectory > (ireg + 1) * photon_radii[
id.layer()]) {
574 outside_containment_energy[ireg] += hit.getEnergy();
575 outside_containment_n_hits[ireg] += 1;
576 outside_containment_x_mean[ireg] += xy_pair.first * hit.getEnergy();
577 outside_containment_y_mean[ireg] += xy_pair.second * hit.getEnergy();
583 if (distance_ele_trajectory >= ele_radii[
id.layer()] ||
584 distance_ele_trajectory == -1.0) {
586 hd.pos_ = ROOT::Math::XYZVector(xy_pair.first, xy_pair.second,
588 hd.layer_ =
id.layer();
589 tracking_hit_list.push_back(hd);
595 for (
const auto &[
id, energy] : cell_map_tight_iso_) {
596 if (energy > 0) summed_tight_iso_ += energy;
599 for (
int i_layer = 0; i_layer < ecal_layer_edep_readout_.size(); i_layer++) {
600 ecal_layer_time_[i_layer] =
601 ecal_layer_time_[i_layer] / ecal_layer_edep_readout_[i_layer];
602 summed_det_ += ecal_layer_edep_readout_[i_layer];
605 if (n_readout_hits_ > 0) {
606 avg_layer_hit_ /= n_readout_hits_;
607 w_avg_layer_hit /= summed_det_;
608 x_mean /= summed_det_;
609 y_mean /= summed_det_;
618 for (
unsigned int iseg = 0; iseg < n_segments; iseg++) {
619 if (energy_seg[iseg] > 0) {
620 x_mean_seg[iseg] /= energy_seg[iseg];
621 y_mean_seg[iseg] /= energy_seg[iseg];
622 layer_mean_seg[iseg] /= energy_seg[iseg];
624 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
625 if (e_cont_energy[ireg][iseg] > 0) {
626 e_cont_x_mean[ireg][iseg] /= e_cont_energy[ireg][iseg];
627 e_cont_y_mean[ireg][iseg] /= e_cont_energy[ireg][iseg];
629 if (g_cont_energy[ireg][iseg] > 0) {
630 g_cont_x_mean[ireg][iseg] /= g_cont_energy[ireg][iseg];
631 g_cont_y_mean[ireg][iseg] /= g_cont_energy[ireg][iseg];
633 if (o_cont_energy[ireg][iseg] > 0) {
634 o_cont_x_mean[ireg][iseg] /= o_cont_energy[ireg][iseg];
635 o_cont_y_mean[ireg][iseg] /= o_cont_energy[ireg][iseg];
636 o_cont_layer_mean[ireg][iseg] /= o_cont_energy[ireg][iseg];
641 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
642 if (outside_containment_energy[ireg] > 0) {
643 outside_containment_x_mean[ireg] /= outside_containment_energy[ireg];
644 outside_containment_y_mean[ireg] /= outside_containment_energy[ireg];
652 if (hit.getEnergy() > 0) {
653 x_std_ += pow((rechit_x - x_mean), 2) * hit.getEnergy();
654 y_std_ += pow((rechit_y - y_mean), 2) * hit.getEnergy();
656 pow((
id.layer() - w_avg_layer_hit), 2) * hit.getEnergy();
658 XYCoords xy_pair = std::make_pair(rechit_x, rechit_y);
659 float distance_ele_trajectory =
660 ele_trajectory.size()
661 ? sqrt(pow((xy_pair.first - ele_trajectory[
id.layer()].first), 2) +
662 pow((xy_pair.second - ele_trajectory[
id.layer()].second), 2))
664 float distance_photon_trajectory =
665 photon_trajectory.size()
666 ? sqrt(pow((xy_pair.first - photon_trajectory[
id.layer()].first),
668 pow((xy_pair.second - photon_trajectory[
id.layer()].second),
672 for (
unsigned int iseg = 0; iseg < n_segments; iseg++) {
673 if (
id.layer() >= seg_layers[iseg] &&
674 id.layer() <= seg_layers[iseg + 1] - 1) {
676 pow((xy_pair.first - x_mean_seg[iseg]), 2) * hit.getEnergy();
678 pow((xy_pair.second - y_mean_seg[iseg]), 2) * hit.getEnergy();
679 layer_std_seg[iseg] +=
680 pow((
id.layer() - layer_mean_seg[iseg]), 2) * hit.getEnergy();
682 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
683 if (distance_ele_trajectory > (ireg + 1) * ele_radii[
id.layer()] &&
684 distance_photon_trajectory >
685 (ireg + 1) * photon_radii[
id.layer()]) {
686 o_cont_x_std[ireg][iseg] +=
687 pow((xy_pair.first - o_cont_x_mean[ireg][iseg]), 2) *
689 o_cont_y_std[ireg][iseg] +=
690 pow((xy_pair.second - o_cont_y_mean[ireg][iseg]), 2) *
692 o_cont_layer_std[ireg][iseg] +=
693 pow((
id.layer() - o_cont_layer_mean[ireg][iseg]), 2) *
700 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
701 if (distance_ele_trajectory > (ireg + 1) * ele_radii[
id.layer()] &&
702 distance_photon_trajectory > (ireg + 1) * photon_radii[
id.layer()]) {
703 outside_containment_x_std[ireg] +=
704 pow((xy_pair.first - outside_containment_x_mean[ireg]), 2) *
706 outside_containment_y_std[ireg] +=
707 pow((xy_pair.second - outside_containment_y_mean[ireg]), 2) *
713 if (n_readout_hits_ > 0) {
714 x_std_ = sqrt(x_std_ / summed_det_);
715 y_std_ = sqrt(y_std_ / summed_det_);
716 std_layer_hit_ = sqrt(std_layer_hit_ / summed_det_);
725 for (
unsigned int iseg = 0; iseg < n_segments; iseg++) {
726 if (energy_seg[iseg] > 0) {
727 x_std_seg[iseg] = sqrt(x_std_seg[iseg] / energy_seg[iseg]);
728 y_std_seg[iseg] = sqrt(y_std_seg[iseg] / energy_seg[iseg]);
729 layer_std_seg[iseg] = sqrt(layer_std_seg[iseg] / energy_seg[iseg]);
731 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
732 if (o_cont_energy[ireg][iseg] > 0) {
733 o_cont_x_std[ireg][iseg] =
734 sqrt(o_cont_x_std[ireg][iseg] / o_cont_energy[ireg][iseg]);
735 o_cont_y_std[ireg][iseg] =
736 sqrt(o_cont_y_std[ireg][iseg] / o_cont_energy[ireg][iseg]);
737 o_cont_layer_std[ireg][iseg] =
738 sqrt(o_cont_layer_std[ireg][iseg] / o_cont_energy[ireg][iseg]);
743 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
744 if (outside_containment_energy[ireg] > 0) {
745 outside_containment_x_std[ireg] = sqrt(outside_containment_x_std[ireg] /
746 outside_containment_energy[ireg]);
747 outside_containment_y_std[ireg] = sqrt(outside_containment_y_std[ireg] /
748 outside_containment_energy[ireg]);
752 ldmx_log(trace) <<
" Find out if the recoil electron is fiducial";
757 const float dz_from_face =
759 float drifted_recoil_x{-9999.};
760 float drifted_recoil_y{-9999.};
761 if (recoil_p[2] > 0.) {
762 ldmx_log(trace) <<
" Recoil electron pX = " << recoil_p[0]
763 <<
" pY = " << recoil_p[1] <<
" pZ = " << recoil_p[2];
764 ldmx_log(trace) <<
" Recoil electron PosX = " << recoil_pos[0]
765 <<
" PosY = " << recoil_pos[1]
766 <<
" PosZ = " << recoil_pos[2];
768 (dz_from_face * (recoil_p[0] / recoil_p[2])) + recoil_pos[0];
770 (dz_from_face * (recoil_p[1] / recoil_p[2])) + recoil_pos[1];
772 const int recoil_layer_index = 0;
775 bool inside_ecal_cell{
false};
777 const auto ecal_id =
geometry_->
getID(drifted_recoil_x, drifted_recoil_y,
778 recoil_layer_index,
true);
779 if (!ecal_id.null()) {
782 geometry_->
getID(drifted_recoil_x, drifted_recoil_y, recoil_layer_index,
783 ecal_id.getModuleID(),
true);
784 if (!cell_id.null()) {
785 inside_ecal_cell =
true;
789 ldmx_log(info) <<
" Is this event is fiducial in ECAL? "
791 ROOT::Math::XYZVector e_traj_start;
792 ROOT::Math::XYZVector e_traj_end;
793 ROOT::Math::XYZVector e_traj_target_start;
794 ROOT::Math::XYZVector e_traj_target_end;
795 ROOT::Math::XYZVector p_traj_start;
796 ROOT::Math::XYZVector p_traj_end;
797 if (!ele_trajectory.empty() && !photon_trajectory.empty()) {
800 e_traj_start.SetXYZ(ele_trajectory[0].first, ele_trajectory[0].second,
802 e_traj_end.SetXYZ(ele_trajectory[(n_ecal_layers_ - 1)].first,
803 ele_trajectory[(n_ecal_layers_ - 1)].second,
805 p_traj_start.SetXYZ(photon_trajectory[0].first, photon_trajectory[0].second,
807 p_traj_end.SetXYZ(photon_trajectory[(n_ecal_layers_ - 1)].first,
808 photon_trajectory[(n_ecal_layers_ - 1)].second,
811 ROOT::Math::XYZVector evec = e_traj_end - e_traj_start;
812 ROOT::Math::XYZVector e_norm = evec.Unit();
813 ROOT::Math::XYZVector pvec = p_traj_end - p_traj_start;
814 ROOT::Math::XYZVector p_norm = pvec.Unit();
820 ep_sep_ = sqrt(pow(e_traj_start.X() - p_traj_start.X(), 2) +
821 pow(e_traj_start.Y() - p_traj_start.Y(), 2));
824 if (!ele_trajectory_at_target.empty()) {
825 e_traj_target_start.SetXYZ(recoil_pos_at_target[0],
826 recoil_pos_at_target[1],
827 static_cast<float>(0.0));
828 e_traj_target_end.SetXYZ(ele_trajectory_at_target[(0)].first,
829 ele_trajectory_at_target[(0)].second,
832 ROOT::Math::XYZVector evec_target =
833 e_traj_target_end - e_traj_target_start;
834 ROOT::Math::XYZVector e_norm_target = evec_target.Unit();
838 ldmx_log(trace) <<
" Electron trajectory calculated";
843 ldmx_log(trace) <<
" Electron trajectory is missing";
845 e_traj_end = ROOT::Math::XYZVector(
849 p_traj_end = ROOT::Math::XYZVector(
860 ldmx_log(trace) <<
" Set up input info for MIP tracking";
861 ecal_mip_collection.setEleTrajectory(ele_trajectory);
862 ecal_mip_collection.setPhotonTrajectory(photon_trajectory);
863 ecal_mip_collection.setTrackingHitList(tracking_hit_list);
864 event.add(
"EcalTrajectoryInfo", ecal_mip_collection);
866 auto mip_tracking_setup = std::chrono::high_resolution_clock::now();
867 profiling_map_[
"mip_tracking_setup"] +=
868 std::chrono::duration<double, std::milli>(mip_tracking_setup - start)
872 summed_tight_iso_, max_cell_dep_, shower_rms_, x_std_, y_std_,
873 avg_layer_hit_, std_layer_hit_, ecal_back_energy_,
ep_ang_,
875 electron_containment_energy, photon_containment_energy,
876 outside_containment_energy, outside_containment_n_hits,
877 outside_containment_x_std, outside_containment_y_std, energy_seg,
878 x_mean_seg, y_mean_seg, x_std_seg, y_std_seg, layer_mean_seg,
879 layer_std_seg, e_cont_energy, e_cont_x_mean, e_cont_y_mean, g_cont_energy,
880 g_cont_n_hits, g_cont_x_mean, g_cont_y_mean, o_cont_energy, o_cont_n_hits,
881 o_cont_x_mean, o_cont_y_mean, o_cont_x_std, o_cont_y_std,
882 o_cont_layer_mean, o_cont_layer_std, ecal_layer_edep_readout_, recoil_p,
885 auto set_variables = std::chrono::high_resolution_clock::now();
886 profiling_map_[
"set_variables"] += std::chrono::duration<double, std::milli>(
887 set_variables - mip_tracking_setup)
890 ldmx::ort::FloatArrays inputs({bdt_features_});
892 rt_->run({feature_list_name_}, inputs, {
"probabilities"})[0].at(1);
893 ldmx_log(info) <<
" BDT was ran, score is " << pred;
897 result.setVetoResult(pred > bdt_cut_val_);
898 result.setDiscValue(pred);
899 ldmx_log(info) <<
" The pred > bdtCutVal = " << (pred > bdt_cut_val_);
902 result.setFiducial(inside_ecal_cell);
903 result.setTrackingFiducial(fiducial_in_tracker);
907 if (!inverse_skim_) {
924 auto bdt_variables = std::chrono::high_resolution_clock::now();
925 profiling_map_[
"bdt_variables"] +=
926 std::chrono::duration<float, std::milli>(bdt_variables - set_variables)
929 auto end = std::chrono::high_resolution_clock::now();
930 auto time_diff = end - start;
932 std::chrono::duration<float, std::milli>(time_diff).count();