Process the event and put new data products into it.
173 {
174 auto start = std::chrono::high_resolution_clock::now();
175 nevents_++;
176
177
179 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
180
182
183 clearProcessor();
184
185
186
187
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.};
192
193 auto setup = std::chrono::high_resolution_clock::now();
194 profiling_map_["setup"] +=
195 std::chrono::duration<float, std::milli>(setup - start).count();
196
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 "
200 "recoil electron";
201
202
203
204
205
207 sim_particles_coll_name_, sim_particles_passname_)};
208
209
211
212
214 ecal_sp_coll_name_, sp_pass_name_)};
215 float pmax = 0;
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;
221
222 if (sp_hit.getTrackID() == recoil_track_id) {
223
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]);
234 }
235 }
236 }
237
238
239 if (event.
exists(target_sp_coll_name_, sp_pass_name_)) {
240 std::vector<ldmx::SimTrackerHit> target_sp_hits =
242 sp_pass_name_);
243 pmax = 0;
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;
249
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]};
260
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]));
264 }
265 }
266 }
267 }
268 }
269
270
271 bool fiducial_in_tracker{false};
272 if (recoil_from_tracking_) {
273 ldmx_log(trace) << " Get recoil tracks collection";
274
275
276 auto recoil_tracks{
277 event.getCollection<
ldmx::Track>(track_collection_, track_pass_name_)};
278
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 =
287
288 ldmx_log(trace) << " Set recoil_pos and recoil_p";
289
290
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])};
297 } else {
298 ldmx_log(trace) << " No recoil track at ECAL";
299 fiducial_in_tracker = false;
300 }
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] << ")";
305
306
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]};
314 }
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] << ")";
321 }
322
323 ldmx_log(trace) << " Get projected trajectories for electron and photon";
324
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();
328
329
330 std::vector<XYCoords> ele_trajectory, photon_trajectory,
331 ele_trajectory_at_target;
332
333
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);
339
340
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]};
344 photon_trajectory =
345 getTrajectory(photon_proj_momentum, recoil_pos_at_target);
346 } else {
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];
351 }
352
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]))
356 : -1.0;
357 float recoil_theta =
358 recoil_p_mag > 0 ? acos(recoil_p[2] / recoil_p_mag) * 180.0 / M_PI : -1.0;
359
360 ldmx_log(trace) << " Build Radii of containment (ROC)";
361
362 auto trajectories = std::chrono::high_resolution_clock::now();
363 profiling_map_["trajectories"] +=
364 std::chrono::duration<float, std::milli>(trajectories - recoil_electron)
365 .count();
366
367
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;
372 bool inrange;
373
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];
379 inrange = true;
380
381 if (theta_min != -1.0) {
382 inrange = inrange && (recoil_theta >= theta_min);
383 }
384 if (theta_max != -1.0) {
385 inrange = inrange && (recoil_theta < theta_max);
386 }
387 if (p_min != -1.0) {
388 inrange = inrange && (recoil_p_mag >= p_min);
389 }
390 if (p_max != -1.0) {
391 inrange = inrange && (recoil_p_mag < p_max);
392 }
393 if (inrange) {
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;
397 }
398 }
399
400 std::vector<float> photon_radii = roc_values_bin_0;
401
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();
405
406
407 const std::vector<ldmx::EcalHit> ecal_rec_hits =
408 event.getCollection<
ldmx::EcalHit>(rec_coll_name_, rec_pass_name_);
409
411 getShowerCentroidIdAndRms(ecal_rec_hits, shower_rms_);
412
414 bool do_tight = true;
415
416 fillIsolatedHitMap(ecal_rec_hits, global_centroid, cell_map_,
417 cell_map_tight_iso_, do_tight);
418
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();
422
423
424
425
426 float w_avg_layer_hit = 0;
427 float x_mean = 0;
428 float y_mean = 0;
429
430
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);
440
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));
480
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)
484 .count();
485
486
487
488
489 std::vector<ldmx::HitData> tracking_hit_list;
490
491 ldmx_log(trace)
492 << " Loop over the hits_ from the event to calculate the BDT features";
493
495
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) {
502 ldmx_log(fatal)
503 << "ECal hit has negative or zero energy, this should never happen, "
504 "check the threshold settings in HgcrocEmulator";
505 continue;
506 }
507 n_readout_hits_++;
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();
517 }
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))
525 : -1.0;
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))
532 : -1.0;
533
534
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();
542
543
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();
550 }
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();
558 }
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();
567 }
568 }
569 }
570 }
571
572
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();
586 }
587 }
588
589
590
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);
598 }
599 }
600
602
603 for (const auto& [id, energy] : cell_map_tight_iso_) {
604 if (energy > 0) summed_tight_iso_ += energy;
605 }
606
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];
611 }
612
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_;
618 } else {
619 w_avg_layer_hit = 0;
620 avg_layer_hit_ = 0;
621 x_mean = 0;
622 y_mean = 0;
623 }
624
625
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];
631 }
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];
636 }
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];
640 }
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];
645 }
646 }
647 }
648
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];
653 }
654 }
655
656
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();
663 std_layer_hit_ +=
664 pow((id.layer() - w_avg_layer_hit), 2) * hit.getEnergy();
665 }
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))
671 : -1.0;
672 float distance_photon_trajectory =
673 photon_trajectory.size()
674 ? sqrt(pow((xy_pair.first - photon_trajectory[id.layer()].first),
675 2) +
676 pow((xy_pair.second - photon_trajectory[id.layer()].second),
677 2))
678 : -1.0;
679
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) {
683 x_std_seg[iseg] +=
684 pow((xy_pair.first - x_mean_seg[iseg]), 2) * hit.getEnergy();
685 y_std_seg[iseg] +=
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();
689
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) *
696 hit.getEnergy();
697 o_cont_y_std[ireg][iseg] +=
698 pow((xy_pair.second - o_cont_y_mean[ireg][iseg]), 2) *
699 hit.getEnergy();
700 o_cont_layer_std[ireg][iseg] +=
701 pow((id.layer() - o_cont_layer_mean[ireg][iseg]), 2) *
702 hit.getEnergy();
703 }
704 }
705 }
706 }
707
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) *
713 hit.getEnergy();
714 outside_containment_y_std[ireg] +=
715 pow((xy_pair.second - outside_containment_y_mean[ireg]), 2) *
716 hit.getEnergy();
717 }
718 }
719 }
720
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_);
725 } else {
726 x_std_ = 0;
727 y_std_ = 0;
728 std_layer_hit_ = 0;
729 }
730
731
732
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]);
738 }
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]);
747 }
748 }
749 }
750
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]);
757 }
758 }
759
760 ldmx_log(trace) << " Find out if the recoil electron is fiducial";
761
762
763
764
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];
775 drifted_recoil_x =
776 (dz_from_face * (recoil_p[0] / recoil_p[2])) + recoil_pos[0];
777 drifted_recoil_y =
778 (dz_from_face * (recoil_p[1] / recoil_p[2])) + recoil_pos[1];
779 }
780 const int recoil_layer_index = 0;
781
782
783 bool inside_ecal_cell{false};
784
785 const auto ecal_id =
geometry_->
getID(drifted_recoil_x, drifted_recoil_y,
786 recoil_layer_index, true);
787 if (!ecal_id.null()) {
788
789 const auto cell_id =
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;
794 }
795 }
796
797 ldmx_log(info) << " Is this event is fiducial in ECAL? "
798 << inside_ecal_cell;
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()) {
806
807
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,
818
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();
823
824
825
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));
830
831
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,
839
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();
845 }
846 ldmx_log(trace) << " Electron trajectory calculated";
847 } else {
848
849
850
851 ldmx_log(trace) << " Electron trajectory is missing";
853 e_traj_end = ROOT::Math::XYZVector(
855 p_traj_start =
857 p_traj_end = ROOT::Math::XYZVector(
859
865 }
866
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);
873
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)
877 .count();
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,
891 recoil_pos);
892
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)
896 .count();
898 ldmx::ort::FloatArrays inputs({bdt_features_});
899 float pred =
900 rt_->run({feature_list_name_}, inputs, {"probabilities"})[0].at(1);
901 ldmx_log(info) << " BDT was ran, score is " << pred;
902
903
904
905 result.setVetoResult(pred > bdt_cut_val_);
906 result.setDiscValue(pred);
907 ldmx_log(info) << " The pred > bdtCutVal = " << (pred > bdt_cut_val_);
908
909
910 result.setFiducial(inside_ecal_cell);
911 result.setTrackingFiducial(fiducial_in_tracker);
912
913
914
915 if (!inverse_skim_) {
918 } else {
920 }
921 } else {
922
925 } else {
927 }
928 }
929
931
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)
935 .count();
936
937 auto end = std::chrono::high_resolution_clock::now();
938 auto time_diff = end - start;
939 processing_time_ +=
940 std::chrono::duration<float, std::milli>(time_diff).count();
941}
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