174 auto start = std::chrono::high_resolution_clock::now();
179 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
188 std::array<float, 3> recoil_p = {0., 0., 0.};
189 std::array<float, 3> recoil_pos = {-9999., -9999., -9999.};
190 std::array<float, 3> recoil_p_at_target = {0., 0., 0.};
191 std::array<float, 3> recoil_pos_at_target = {-9999., -9999., -9999.};
193 auto setup = std::chrono::high_resolution_clock::now();
194 profiling_map_[
"setup"] +=
195 std::chrono::duration<float, std::milli>(setup - start).count();
197 if (!recoil_from_tracking_ &&
198 event.
exists(ecal_sp_coll_name_, sp_pass_name_)) {
199 ldmx_log(trace) <<
" Loop through all of the sim particles and find the "
207 sim_particles_coll_name_, sim_particles_passname_)};
210 auto [recoil_track_id, recoil_electron] = analysis::getRecoil(particle_map);
214 ecal_sp_coll_name_, sp_pass_name_)};
218 auto ecal_sp_momentum = sp_hit.getMomentum();
219 auto ecal_sp_position = sp_hit.getPosition();
220 if (hit_id.
plane() != 31 || ecal_sp_momentum[2] <= 0)
continue;
222 if (sp_hit.getTrackID() == recoil_track_id) {
224 if (sqrt((ecal_sp_momentum[0] * ecal_sp_momentum[0]) +
225 (ecal_sp_momentum[1] * ecal_sp_momentum[1]) +
226 (ecal_sp_momentum[2] * ecal_sp_momentum[2])) > pmax) {
227 recoil_p = {
static_cast<float>(ecal_sp_momentum[0]),
228 static_cast<float>(ecal_sp_momentum[1]),
229 static_cast<float>(ecal_sp_momentum[2])};
230 recoil_pos = {(ecal_sp_position[0]), (ecal_sp_position[1]),
231 (ecal_sp_position[2])};
232 pmax = sqrt(recoil_p[0] * recoil_p[0] + recoil_p[1] * recoil_p[1] +
233 recoil_p[2] * recoil_p[2]);
239 if (event.
exists(target_sp_coll_name_, sp_pass_name_)) {
240 std::vector<ldmx::SimTrackerHit> target_sp_hits =
246 auto target_sp_momentum = sp_hit.getMomentum();
247 auto target_sp_position = sp_hit.getPosition();
248 if (hit_id.
plane() != 1 || target_sp_momentum[2] <= 0)
continue;
250 if (sp_hit.getTrackID() == recoil_track_id) {
251 if (sqrt((target_sp_momentum[0] * target_sp_momentum[0]) +
252 (target_sp_momentum[1] * target_sp_momentum[1]) +
253 (target_sp_momentum[2] * target_sp_momentum[2])) > pmax) {
254 recoil_p_at_target = {
static_cast<float>(target_sp_momentum[0]),
255 static_cast<float>(target_sp_momentum[1]),
256 static_cast<float>(target_sp_momentum[2])};
257 recoil_pos_at_target = {target_sp_position[0],
258 target_sp_position[1],
259 target_sp_position[2]};
261 pmax = sqrt((recoil_p_at_target[0] * recoil_p_at_target[0]) +
262 (recoil_p_at_target[1] * recoil_p_at_target[1]) +
263 (recoil_p_at_target[2] * recoil_p_at_target[2]));
271 bool fiducial_in_tracker{
false};
272 if (recoil_from_tracking_) {
273 ldmx_log(trace) <<
" Get recoil tracks collection";
277 event.getCollection<
ldmx::Track>(track_collection_, track_pass_name_)};
279 ldmx_log(trace) <<
" Propagate the recoil ele to the ECAL";
280 ldmx::TrackStateType ts_type = ldmx::AtECAL;
281 auto recoil_track_states_ecal =
283 ldmx_log(trace) <<
" Propagate the recoil ele to the Target";
284 ldmx::TrackStateType ts_type_target = ldmx::AtTarget;
285 auto recoil_track_states_target =
288 ldmx_log(trace) <<
" Set recoil_pos and recoil_p";
291 if (!recoil_track_states_ecal.empty()) {
292 fiducial_in_tracker =
true;
293 recoil_pos = {recoil_track_states_ecal[0], recoil_track_states_ecal[1],
294 recoil_track_states_ecal[2]};
295 recoil_p = {(recoil_track_states_ecal[3]), (recoil_track_states_ecal[4]),
296 (recoil_track_states_ecal[5])};
298 ldmx_log(trace) <<
" No recoil track at ECAL";
299 fiducial_in_tracker =
false;
301 ldmx_log(debug) <<
" Set recoil_p = (" << recoil_p[0] <<
", "
302 << recoil_p[1] <<
", " << recoil_p[2]
303 <<
") and recoil_pos = (" << recoil_pos[0] <<
", "
304 << recoil_pos[1] <<
", " << recoil_pos[2] <<
")";
307 if (!recoil_track_states_target.empty()) {
308 recoil_pos_at_target = {(recoil_track_states_target[0]),
309 (recoil_track_states_target[1]),
310 (recoil_track_states_target[2])};
311 recoil_p_at_target = {recoil_track_states_target[3],
312 recoil_track_states_target[4],
313 recoil_track_states_target[5]};
315 ldmx_log(debug) <<
" Set recoil_p_at_target = (" << recoil_p_at_target[0]
316 <<
", " << recoil_p_at_target[1] <<
", "
317 << recoil_p_at_target[2] <<
") and recoil_pos_at_target = ("
318 << recoil_pos_at_target[0] <<
", "
319 << recoil_pos_at_target[1] <<
", "
320 << recoil_pos_at_target[2] <<
")";
323 ldmx_log(trace) <<
" Get projected trajectories for electron and photon";
325 auto recoil_electron = std::chrono::high_resolution_clock::now();
326 profiling_map_[
"recoil_electron"] +=
327 std::chrono::duration<float, std::milli>(recoil_electron - setup).count();
330 std::vector<XYCoords> ele_trajectory, photon_trajectory,
331 ele_trajectory_at_target;
334 if ((recoil_p[2] > 0.) && (recoil_p_at_target[2] > 0.) &&
335 (recoil_pos[0] != -9999.) && (recoil_pos_at_target[0] != -9999.)) {
336 ele_trajectory = getTrajectory(recoil_p, recoil_pos);
337 ele_trajectory_at_target =
338 getTrajectory(recoil_p_at_target, recoil_pos_at_target);
341 std::array<float, 3> photon_proj_momentum = {
342 -recoil_p_at_target[0], -recoil_p_at_target[1],
343 beam_energy_mev_ - recoil_p_at_target[2]};
345 getTrajectory(photon_proj_momentum, recoil_pos_at_target);
347 ldmx_log(trace) <<
"Ele / photon trajectory cannot be determined, pZ = "
348 << recoil_p[2] <<
" pZAtTarget = " << recoil_p_at_target[2]
349 <<
" X = " << recoil_pos[0]
350 <<
" XAtTarget = " << recoil_pos_at_target[0];
353 float recoil_p_mag = (recoil_p[2] > 0.) ? sqrt((recoil_p[0] * recoil_p[0]) +
354 (recoil_p[1] * recoil_p[1]) +
355 (recoil_p[2] * recoil_p[2]))
358 recoil_p_mag > 0 ? acos(recoil_p[2] / recoil_p_mag) * 180.0 / M_PI : -1.0;
360 ldmx_log(trace) <<
" Build Radii of containment (ROC)";
362 auto trajectories = std::chrono::high_resolution_clock::now();
363 profiling_map_[
"trajectories"] +=
364 std::chrono::duration<float, std::milli>(trajectories - recoil_electron)
368 std::vector<float> roc_values_bin_0(roc_range_values_[0].begin() + 4,
369 roc_range_values_[0].end());
370 std::vector<float> ele_radii = roc_values_bin_0;
371 float theta_min, theta_max, p_min, p_max;
374 for (
int i = 0; i < roc_range_values_.size(); i++) {
375 theta_min = roc_range_values_[i][0];
376 theta_max = roc_range_values_[i][1];
377 p_min = roc_range_values_[i][2];
378 p_max = roc_range_values_[i][3];
381 if (theta_min != -1.0) {
382 inrange = inrange && (recoil_theta >= theta_min);
384 if (theta_max != -1.0) {
385 inrange = inrange && (recoil_theta < theta_max);
388 inrange = inrange && (recoil_p_mag >= p_min);
391 inrange = inrange && (recoil_p_mag < p_max);
394 std::vector<float> roc_values_bini(roc_range_values_[i].begin() + 4,
395 roc_range_values_[i].end());
396 ele_radii = roc_values_bini;
400 std::vector<float> photon_radii = roc_values_bin_0;
402 auto roc_var = std::chrono::high_resolution_clock::now();
403 profiling_map_[
"roc_var"] +=
404 std::chrono::duration<float, std::milli>(roc_var - trajectories).count();
407 const std::vector<ldmx::EcalHit> ecal_rec_hits =
408 event.getCollection<
ldmx::EcalHit>(rec_coll_name_, rec_pass_name_);
411 getShowerCentroidIdAndRms(ecal_rec_hits, shower_rms_);
414 bool do_tight =
true;
416 fillIsolatedHitMap(ecal_rec_hits, global_centroid, cell_map_,
417 cell_map_tight_iso_, do_tight);
419 auto fill_hitmaps = std::chrono::high_resolution_clock::now();
420 profiling_map_[
"fill_hitmaps"] +=
421 std::chrono::duration<float, std::milli>(fill_hitmaps - roc_var).count();
426 float w_avg_layer_hit = 0;
431 unsigned int n_regions = 5;
432 std::vector<float> electron_containment_energy(n_regions, 0.0);
433 std::vector<float> photon_containment_energy(n_regions, 0.0);
434 std::vector<float> outside_containment_energy(n_regions, 0.0);
435 std::vector<int> outside_containment_n_hits(n_regions, 0);
436 std::vector<float> outside_containment_x_mean(n_regions, 0.0);
437 std::vector<float> outside_containment_y_mean(n_regions, 0.0);
438 std::vector<float> outside_containment_x_std(n_regions, 0.0);
439 std::vector<float> outside_containment_y_std(n_regions, 0.0);
441 std::vector<int> seg_layers = {0, 6, 17, 32};
442 unsigned int n_segments = seg_layers.size() - 1;
443 std::vector<float> energy_seg(n_segments, 0.0);
444 std::vector<float> x_mean_seg(n_segments, 0.0);
445 std::vector<float> x_std_seg(n_segments, 0.0);
446 std::vector<float> y_mean_seg(n_segments, 0.0);
447 std::vector<float> y_std_seg(n_segments, 0.0);
448 std::vector<float> layer_mean_seg(n_segments, 0.0);
449 std::vector<float> layer_std_seg(n_segments, 0.0);
450 std::vector<std::vector<float>> e_cont_energy(
451 n_regions, std::vector<float>(n_segments, 0.0));
452 std::vector<std::vector<float>> e_cont_x_mean(
453 n_regions, std::vector<float>(n_segments, 0.0));
454 std::vector<std::vector<float>> e_cont_y_mean(
455 n_regions, std::vector<float>(n_segments, 0.0));
456 std::vector<std::vector<float>> g_cont_energy(
457 n_regions, std::vector<float>(n_segments, 0.0));
458 std::vector<std::vector<int>> g_cont_n_hits(n_regions,
459 std::vector<int>(n_segments, 0));
460 std::vector<std::vector<float>> g_cont_x_mean(
461 n_regions, std::vector<float>(n_segments, 0.0));
462 std::vector<std::vector<float>> g_cont_y_mean(
463 n_regions, std::vector<float>(n_segments, 0.0));
464 std::vector<std::vector<float>> o_cont_energy(
465 n_regions, std::vector<float>(n_segments, 0.0));
466 std::vector<std::vector<int>> o_cont_n_hits(n_regions,
467 std::vector<int>(n_segments, 0));
468 std::vector<std::vector<float>> o_cont_x_mean(
469 n_regions, std::vector<float>(n_segments, 0.0));
470 std::vector<std::vector<float>> o_cont_y_mean(
471 n_regions, std::vector<float>(n_segments, 0.0));
472 std::vector<std::vector<float>> o_cont_x_std(
473 n_regions, std::vector<float>(n_segments, 0.0));
474 std::vector<std::vector<float>> o_cont_y_std(
475 n_regions, std::vector<float>(n_segments, 0.0));
476 std::vector<std::vector<float>> o_cont_layer_mean(
477 n_regions, std::vector<float>(n_segments, 0.0));
478 std::vector<std::vector<float>> o_cont_layer_std(
479 n_regions, std::vector<float>(n_segments, 0.0));
481 auto containment_var = std::chrono::high_resolution_clock::now();
482 profiling_map_[
"containment_var"] +=
483 std::chrono::duration<float, std::milli>(containment_var - fill_hitmaps)
489 std::vector<ldmx::HitData> tracking_hit_list;
492 <<
" Loop over the hits_ from the event to calculate the BDT features";
497 ecal_layer_edep_raw_[
id.layer()] =
498 ecal_layer_edep_raw_[
id.layer()] + hit.getEnergy();
499 if (
id.layer() >= 20) ecal_back_energy_ += hit.getEnergy();
500 if (max_cell_dep_ < hit.getEnergy()) max_cell_dep_ = hit.getEnergy();
501 if (hit.getEnergy() <= 0) {
503 <<
"ECal hit has negative or zero energy, this should never happen, "
504 "check the threshold settings in HgcrocEmulator";
508 ecal_layer_edep_readout_[
id.layer()] += hit.getEnergy();
509 ecal_layer_time_[
id.layer()] += (hit.getEnergy()) * hit.getTime();
511 x_mean += rechit_x * hit.getEnergy();
512 y_mean += rechit_y * hit.getEnergy();
513 avg_layer_hit_ +=
id.layer();
514 w_avg_layer_hit +=
id.layer() * hit.getEnergy();
515 if (deepest_layer_hit_ <
id.layer()) {
516 deepest_layer_hit_ =
id.layer();
518 XYCoords xy_pair = std::make_pair(rechit_x, rechit_y);
519 float distance_ele_trajectory =
520 ele_trajectory.size()
521 ? sqrt((xy_pair.first - ele_trajectory[
id.layer()].first) *
522 (xy_pair.first - ele_trajectory[
id.layer()].first) +
523 (xy_pair.second - ele_trajectory[
id.layer()].second) *
524 (xy_pair.second - ele_trajectory[
id.layer()].second))
526 float distance_photon_trajectory =
527 photon_trajectory.size()
528 ? sqrt((xy_pair.first - photon_trajectory[
id.layer()].first) *
529 (xy_pair.first - photon_trajectory[
id.layer()].first) +
530 (xy_pair.second - photon_trajectory[
id.layer()].second) *
531 (xy_pair.second - photon_trajectory[
id.layer()].second))
535 for (
unsigned int iseg = 0; iseg < n_segments; iseg++) {
536 if (
id.layer() >= seg_layers[iseg] &&
537 id.layer() <= seg_layers[iseg + 1] - 1) {
538 energy_seg[iseg] += hit.getEnergy();
539 x_mean_seg[iseg] += xy_pair.first * hit.getEnergy();
540 y_mean_seg[iseg] += xy_pair.second * hit.getEnergy();
541 layer_mean_seg[iseg] +=
id.layer() * hit.getEnergy();
544 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
545 if (distance_ele_trajectory >= ireg * ele_radii[
id.layer()] &&
546 distance_ele_trajectory < (ireg + 1) * ele_radii[
id.layer()]) {
547 e_cont_energy[ireg][iseg] += hit.getEnergy();
548 e_cont_x_mean[ireg][iseg] += xy_pair.first * hit.getEnergy();
549 e_cont_y_mean[ireg][iseg] += xy_pair.second * hit.getEnergy();
551 if (distance_photon_trajectory >= ireg * photon_radii[
id.layer()] &&
552 distance_photon_trajectory <
553 (ireg + 1) * photon_radii[
id.layer()]) {
554 g_cont_energy[ireg][iseg] += hit.getEnergy();
555 g_cont_n_hits[ireg][iseg] += 1;
556 g_cont_x_mean[ireg][iseg] += xy_pair.first * hit.getEnergy();
557 g_cont_y_mean[ireg][iseg] += xy_pair.second * hit.getEnergy();
559 if (distance_ele_trajectory > (ireg + 1) * ele_radii[
id.layer()] &&
560 distance_photon_trajectory >
561 (ireg + 1) * photon_radii[
id.layer()]) {
562 o_cont_energy[ireg][iseg] += hit.getEnergy();
563 o_cont_n_hits[ireg][iseg] += 1;
564 o_cont_x_mean[ireg][iseg] += xy_pair.first * hit.getEnergy();
565 o_cont_y_mean[ireg][iseg] += xy_pair.second * hit.getEnergy();
566 o_cont_layer_mean[ireg][iseg] +=
id.layer() * hit.getEnergy();
573 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
574 if (distance_ele_trajectory >= ireg * ele_radii[
id.layer()] &&
575 distance_ele_trajectory < (ireg + 1) * ele_radii[
id.layer()])
576 electron_containment_energy[ireg] += hit.getEnergy();
577 if (distance_photon_trajectory >= ireg * photon_radii[
id.layer()] &&
578 distance_photon_trajectory < (ireg + 1) * photon_radii[
id.layer()])
579 photon_containment_energy[ireg] += hit.getEnergy();
580 if (distance_ele_trajectory > (ireg + 1) * ele_radii[
id.layer()] &&
581 distance_photon_trajectory > (ireg + 1) * photon_radii[
id.layer()]) {
582 outside_containment_energy[ireg] += hit.getEnergy();
583 outside_containment_n_hits[ireg] += 1;
584 outside_containment_x_mean[ireg] += xy_pair.first * hit.getEnergy();
585 outside_containment_y_mean[ireg] += xy_pair.second * hit.getEnergy();
591 if (distance_ele_trajectory >= ele_radii[
id.layer()] ||
592 distance_ele_trajectory == -1.0) {
594 hd.pos_ = ROOT::Math::XYZVector(xy_pair.first, xy_pair.second,
596 hd.layer_ =
id.layer();
597 tracking_hit_list.push_back(hd);
603 for (
const auto& [
id, energy] : cell_map_tight_iso_) {
604 if (energy > 0) summed_tight_iso_ += energy;
607 for (
int i_layer = 0; i_layer < ecal_layer_edep_readout_.size(); i_layer++) {
608 ecal_layer_time_[i_layer] =
609 ecal_layer_time_[i_layer] / ecal_layer_edep_readout_[i_layer];
610 summed_det_ += ecal_layer_edep_readout_[i_layer];
613 if (n_readout_hits_ > 0) {
614 avg_layer_hit_ /= n_readout_hits_;
615 w_avg_layer_hit /= summed_det_;
616 x_mean /= summed_det_;
617 y_mean /= summed_det_;
626 for (
unsigned int iseg = 0; iseg < n_segments; iseg++) {
627 if (energy_seg[iseg] > 0) {
628 x_mean_seg[iseg] /= energy_seg[iseg];
629 y_mean_seg[iseg] /= energy_seg[iseg];
630 layer_mean_seg[iseg] /= energy_seg[iseg];
632 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
633 if (e_cont_energy[ireg][iseg] > 0) {
634 e_cont_x_mean[ireg][iseg] /= e_cont_energy[ireg][iseg];
635 e_cont_y_mean[ireg][iseg] /= e_cont_energy[ireg][iseg];
637 if (g_cont_energy[ireg][iseg] > 0) {
638 g_cont_x_mean[ireg][iseg] /= g_cont_energy[ireg][iseg];
639 g_cont_y_mean[ireg][iseg] /= g_cont_energy[ireg][iseg];
641 if (o_cont_energy[ireg][iseg] > 0) {
642 o_cont_x_mean[ireg][iseg] /= o_cont_energy[ireg][iseg];
643 o_cont_y_mean[ireg][iseg] /= o_cont_energy[ireg][iseg];
644 o_cont_layer_mean[ireg][iseg] /= o_cont_energy[ireg][iseg];
649 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
650 if (outside_containment_energy[ireg] > 0) {
651 outside_containment_x_mean[ireg] /= outside_containment_energy[ireg];
652 outside_containment_y_mean[ireg] /= outside_containment_energy[ireg];
660 if (hit.getEnergy() > 0) {
661 x_std_ += pow((rechit_x - x_mean), 2) * hit.getEnergy();
662 y_std_ += pow((rechit_y - y_mean), 2) * hit.getEnergy();
664 pow((
id.layer() - w_avg_layer_hit), 2) * hit.getEnergy();
666 XYCoords xy_pair = std::make_pair(rechit_x, rechit_y);
667 float distance_ele_trajectory =
668 ele_trajectory.size()
669 ? sqrt(pow((xy_pair.first - ele_trajectory[
id.layer()].first), 2) +
670 pow((xy_pair.second - ele_trajectory[
id.layer()].second), 2))
672 float distance_photon_trajectory =
673 photon_trajectory.size()
674 ? sqrt(pow((xy_pair.first - photon_trajectory[
id.layer()].first),
676 pow((xy_pair.second - photon_trajectory[
id.layer()].second),
680 for (
unsigned int iseg = 0; iseg < n_segments; iseg++) {
681 if (
id.layer() >= seg_layers[iseg] &&
682 id.layer() <= seg_layers[iseg + 1] - 1) {
684 pow((xy_pair.first - x_mean_seg[iseg]), 2) * hit.getEnergy();
686 pow((xy_pair.second - y_mean_seg[iseg]), 2) * hit.getEnergy();
687 layer_std_seg[iseg] +=
688 pow((
id.layer() - layer_mean_seg[iseg]), 2) * hit.getEnergy();
690 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
691 if (distance_ele_trajectory > (ireg + 1) * ele_radii[
id.layer()] &&
692 distance_photon_trajectory >
693 (ireg + 1) * photon_radii[
id.layer()]) {
694 o_cont_x_std[ireg][iseg] +=
695 pow((xy_pair.first - o_cont_x_mean[ireg][iseg]), 2) *
697 o_cont_y_std[ireg][iseg] +=
698 pow((xy_pair.second - o_cont_y_mean[ireg][iseg]), 2) *
700 o_cont_layer_std[ireg][iseg] +=
701 pow((
id.layer() - o_cont_layer_mean[ireg][iseg]), 2) *
708 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
709 if (distance_ele_trajectory > (ireg + 1) * ele_radii[
id.layer()] &&
710 distance_photon_trajectory > (ireg + 1) * photon_radii[
id.layer()]) {
711 outside_containment_x_std[ireg] +=
712 pow((xy_pair.first - outside_containment_x_mean[ireg]), 2) *
714 outside_containment_y_std[ireg] +=
715 pow((xy_pair.second - outside_containment_y_mean[ireg]), 2) *
721 if (n_readout_hits_ > 0) {
722 x_std_ = sqrt(x_std_ / summed_det_);
723 y_std_ = sqrt(y_std_ / summed_det_);
724 std_layer_hit_ = sqrt(std_layer_hit_ / summed_det_);
733 for (
unsigned int iseg = 0; iseg < n_segments; iseg++) {
734 if (energy_seg[iseg] > 0) {
735 x_std_seg[iseg] = sqrt(x_std_seg[iseg] / energy_seg[iseg]);
736 y_std_seg[iseg] = sqrt(y_std_seg[iseg] / energy_seg[iseg]);
737 layer_std_seg[iseg] = sqrt(layer_std_seg[iseg] / energy_seg[iseg]);
739 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
740 if (o_cont_energy[ireg][iseg] > 0) {
741 o_cont_x_std[ireg][iseg] =
742 sqrt(o_cont_x_std[ireg][iseg] / o_cont_energy[ireg][iseg]);
743 o_cont_y_std[ireg][iseg] =
744 sqrt(o_cont_y_std[ireg][iseg] / o_cont_energy[ireg][iseg]);
745 o_cont_layer_std[ireg][iseg] =
746 sqrt(o_cont_layer_std[ireg][iseg] / o_cont_energy[ireg][iseg]);
751 for (
unsigned int ireg = 0; ireg < n_regions; ireg++) {
752 if (outside_containment_energy[ireg] > 0) {
753 outside_containment_x_std[ireg] = sqrt(outside_containment_x_std[ireg] /
754 outside_containment_energy[ireg]);
755 outside_containment_y_std[ireg] = sqrt(outside_containment_y_std[ireg] /
756 outside_containment_energy[ireg]);
760 ldmx_log(trace) <<
" Find out if the recoil electron is fiducial";
765 const float dz_from_face =
767 float drifted_recoil_x{-9999.};
768 float drifted_recoil_y{-9999.};
769 if (recoil_p[2] > 0.) {
770 ldmx_log(trace) <<
" Recoil electron pX = " << recoil_p[0]
771 <<
" pY = " << recoil_p[1] <<
" pZ = " << recoil_p[2];
772 ldmx_log(trace) <<
" Recoil electron PosX = " << recoil_pos[0]
773 <<
" PosY = " << recoil_pos[1]
774 <<
" PosZ = " << recoil_pos[2];
776 (dz_from_face * (recoil_p[0] / recoil_p[2])) + recoil_pos[0];
778 (dz_from_face * (recoil_p[1] / recoil_p[2])) + recoil_pos[1];
780 const int recoil_layer_index = 0;
783 bool inside_ecal_cell{
false};
785 const auto ecal_id =
geometry_->
getID(drifted_recoil_x, drifted_recoil_y,
786 recoil_layer_index,
true);
787 if (!ecal_id.null()) {
790 geometry_->
getID(drifted_recoil_x, drifted_recoil_y, recoil_layer_index,
791 ecal_id.getModuleID(),
true);
792 if (!cell_id.null()) {
793 inside_ecal_cell =
true;
797 ldmx_log(info) <<
" Is this event is fiducial in ECAL? "
799 ROOT::Math::XYZVector e_traj_start;
800 ROOT::Math::XYZVector e_traj_end;
801 ROOT::Math::XYZVector e_traj_target_start;
802 ROOT::Math::XYZVector e_traj_target_end;
803 ROOT::Math::XYZVector p_traj_start;
804 ROOT::Math::XYZVector p_traj_end;
805 if (!ele_trajectory.empty() && !photon_trajectory.empty()) {
808 e_traj_start.SetXYZ(ele_trajectory[0].first, ele_trajectory[0].second,
810 e_traj_end.SetXYZ(ele_trajectory[(n_ecal_layers_ - 1)].first,
811 ele_trajectory[(n_ecal_layers_ - 1)].second,
813 p_traj_start.SetXYZ(photon_trajectory[0].first, photon_trajectory[0].second,
815 p_traj_end.SetXYZ(photon_trajectory[(n_ecal_layers_ - 1)].first,
816 photon_trajectory[(n_ecal_layers_ - 1)].second,
819 ROOT::Math::XYZVector evec = e_traj_end - e_traj_start;
820 ROOT::Math::XYZVector e_norm = evec.Unit();
821 ROOT::Math::XYZVector pvec = p_traj_end - p_traj_start;
822 ROOT::Math::XYZVector p_norm = pvec.Unit();
828 ep_sep_ = sqrt(pow(e_traj_start.X() - p_traj_start.X(), 2) +
829 pow(e_traj_start.Y() - p_traj_start.Y(), 2));
832 if (!ele_trajectory_at_target.empty()) {
833 e_traj_target_start.SetXYZ(recoil_pos_at_target[0],
834 recoil_pos_at_target[1],
835 static_cast<float>(0.0));
836 e_traj_target_end.SetXYZ(ele_trajectory_at_target[(0)].first,
837 ele_trajectory_at_target[(0)].second,
840 ROOT::Math::XYZVector evec_target =
841 e_traj_target_end - e_traj_target_start;
842 ROOT::Math::XYZVector e_norm_target = evec_target.Unit();
846 ldmx_log(trace) <<
" Electron trajectory calculated";
851 ldmx_log(trace) <<
" Electron trajectory is missing";
853 e_traj_end = ROOT::Math::XYZVector(
857 p_traj_end = ROOT::Math::XYZVector(
868 ldmx_log(trace) <<
" Set up input info for MIP tracking";
869 ecal_mip_collection.setEleTrajectory(ele_trajectory);
870 ecal_mip_collection.setPhotonTrajectory(photon_trajectory);
871 ecal_mip_collection.setTrackingHitList(tracking_hit_list);
872 event.add(
"EcalTrajectoryInfo", ecal_mip_collection);
874 auto mip_tracking_setup = std::chrono::high_resolution_clock::now();
875 profiling_map_[
"mip_tracking_setup"] +=
876 std::chrono::duration<double, std::milli>(mip_tracking_setup - start)
880 summed_tight_iso_, max_cell_dep_, shower_rms_, x_std_, y_std_,
881 avg_layer_hit_, std_layer_hit_, ecal_back_energy_,
ep_ang_,
883 electron_containment_energy, photon_containment_energy,
884 outside_containment_energy, outside_containment_n_hits,
885 outside_containment_x_std, outside_containment_y_std, energy_seg,
886 x_mean_seg, y_mean_seg, x_std_seg, y_std_seg, layer_mean_seg,
887 layer_std_seg, e_cont_energy, e_cont_x_mean, e_cont_y_mean, g_cont_energy,
888 g_cont_n_hits, g_cont_x_mean, g_cont_y_mean, o_cont_energy, o_cont_n_hits,
889 o_cont_x_mean, o_cont_y_mean, o_cont_x_std, o_cont_y_std,
890 o_cont_layer_mean, o_cont_layer_std, ecal_layer_edep_readout_, recoil_p,
893 auto set_variables = std::chrono::high_resolution_clock::now();
894 profiling_map_[
"set_variables"] += std::chrono::duration<double, std::milli>(
895 set_variables - mip_tracking_setup)
898 ldmx::ort::FloatArrays inputs({bdt_features_});
900 rt_->run({feature_list_name_}, inputs, {
"probabilities"})[0].at(1);
901 ldmx_log(info) <<
" BDT was ran, score is " << pred;
905 result.setVetoResult(pred > bdt_cut_val_);
906 result.setDiscValue(pred);
907 ldmx_log(info) <<
" The pred > bdtCutVal = " << (pred > bdt_cut_val_);
910 result.setFiducial(inside_ecal_cell);
911 result.setTrackingFiducial(fiducial_in_tracker);
915 if (!inverse_skim_) {
932 auto bdt_variables = std::chrono::high_resolution_clock::now();
933 profiling_map_[
"bdt_variables"] +=
934 std::chrono::duration<float, std::milli>(bdt_variables - set_variables)
937 auto end = std::chrono::high_resolution_clock::now();
938 auto time_diff = end - start;
940 std::chrono::duration<float, std::milli>(time_diff).count();