175 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
184 std::vector<double> recoilP;
185 std::vector<float> recoilPos;
186 std::vector<double> recoilPAtTarget;
187 std::vector<float> recoilPosAtTarget;
190 ldmx_log(debug) <<
" Loop through all of the sim particles and find the "
194 if (event.
exists(
"EcalScoringPlaneHits")) {
203 auto [recoilTrackID, recoilElectron] = Analysis::getRecoil(particleMap);
211 if (hit_id.
plane() != 31 || spHit.getMomentum()[2] <= 0)
continue;
213 if (spHit.getTrackID() == recoilTrackID) {
214 if (sqrt(pow(spHit.getMomentum()[0], 2) +
215 pow(spHit.getMomentum()[1], 2) +
216 pow(spHit.getMomentum()[2], 2)) > pmax) {
217 recoilP = spHit.getMomentum();
218 recoilPos = spHit.getPosition();
219 pmax = sqrt(pow(recoilP[0], 2) + pow(recoilP[1], 2) +
226 if (event.
exists(
"TargetScoringPlaneHits")) {
227 std::vector<ldmx::SimTrackerHit> targetSpHits =
232 if (hit_id.
plane() != 1 || spHit.getMomentum()[2] <= 0)
continue;
234 if (spHit.getTrackID() == recoilTrackID) {
235 if (sqrt(pow(spHit.getMomentum()[0], 2) +
236 pow(spHit.getMomentum()[1], 2) +
237 pow(spHit.getMomentum()[2], 2)) > pmax) {
238 recoilPAtTarget = spHit.getMomentum();
239 recoilPosAtTarget = spHit.getPosition();
241 sqrt(pow(recoilPAtTarget[0], 2) + pow(recoilPAtTarget[1], 2) +
242 pow(recoilPAtTarget[2], 2));
249 if (recoil_from_tracking_) {
250 std::vector<float> recoil_track_states;
252 ldmx_log(debug) <<
" Propagate recoil tracks to ECAL face";
255 auto recoil_tracks{
event.getCollection<
ldmx::Track>(track_collection_)};
257 ldmx::TrackStateType ts_type = ldmx::TrackStateType::AtECAL;
258 recoil_track_states =
trackProp(recoil_tracks, ts_type,
"ecal");
261 recoilPos = recoil_track_states;
265 ldmx_log(debug) <<
" Get projected trajectories for electron and photon";
268 std::vector<XYCoords> ele_trajectory, photon_trajectory;
269 if (!recoilP.empty() && !recoilPos.empty()) {
270 ele_trajectory = getTrajectory(recoilP, recoilPos);
271 std::vector<double> pvec = recoilPAtTarget.size()
273 : std::vector<double>{0.0, 0.0, 0.0};
274 std::vector<float> posvec = recoilPosAtTarget.size()
276 : std::vector<float>{0.0, 0.0, 0.0};
278 getTrajectory({-pvec[0], -pvec[1], beamEnergyMeV_ - pvec[2]}, posvec);
283 ? sqrt(pow(recoilP[0], 2) + pow(recoilP[1], 2) + pow(recoilP[2], 2))
286 recoilPMag > 0 ? acos(recoilP[2] / recoilPMag) * 180.0 / M_PI : -1.0;
289 ldmx_log(debug) <<
" Build Radii of containment (ROC)";
292 std::vector<double> roc_values_bin0(roc_range_values_[0].begin() + 4,
293 roc_range_values_[0].end());
294 std::vector<double> ele_radii = roc_values_bin0;
295 double theta_min, theta_max, p_min, p_max;
298 for (
int i = 0; i < roc_range_values_.size(); i++) {
299 theta_min = roc_range_values_[i][0];
300 theta_max = roc_range_values_[i][1];
301 p_min = roc_range_values_[i][2];
302 p_max = roc_range_values_[i][3];
305 if (theta_min != -1.0) {
306 inrange = inrange && (recoilTheta >= theta_min);
308 if (theta_max != -1.0) {
309 inrange = inrange && (recoilTheta < theta_max);
312 inrange = inrange && (recoilPMag >= p_min);
315 inrange = inrange && (recoilPMag < p_max);
318 std::vector<double> roc_values_bini(roc_range_values_[i].begin() + 4,
319 roc_range_values_[i].end());
320 ele_radii = roc_values_bini;
324 std::vector<double> photon_radii = roc_values_bin0;
327 const std::vector<ldmx::EcalHit> ecalRecHits =
328 event.getCollection<
ldmx::EcalHit>(rec_coll_name_, rec_pass_name_);
331 GetShowerCentroidIDAndRMS(ecalRecHits, showerRMS_);
336 fillIsolatedHitMap(ecalRecHits, globalCentroid, cellMap_, cellMapTightIso_,
342 float wavgLayerHit = 0;
347 unsigned int nregions = 5;
348 std::vector<float> electronContainmentEnergy(nregions, 0.0);
349 std::vector<float> photonContainmentEnergy(nregions, 0.0);
350 std::vector<float> outsideContainmentEnergy(nregions, 0.0);
351 std::vector<int> outsideContainmentNHits(nregions, 0);
352 std::vector<float> outsideContainmentXmean(nregions, 0.0);
353 std::vector<float> outsideContainmentYmean(nregions, 0.0);
354 std::vector<float> outsideContainmentXstd(nregions, 0.0);
355 std::vector<float> outsideContainmentYstd(nregions, 0.0);
357 std::vector<int> segLayers = {0, 6, 17, 34};
358 unsigned int nsegments = segLayers.size() - 1;
359 std::vector<float> energySeg(nsegments, 0.0);
360 std::vector<float> xMeanSeg(nsegments, 0.0);
361 std::vector<float> xStdSeg(nsegments, 0.0);
362 std::vector<float> yMeanSeg(nsegments, 0.0);
363 std::vector<float> yStdSeg(nsegments, 0.0);
364 std::vector<float> layerMeanSeg(nsegments, 0.0);
365 std::vector<float> layerStdSeg(nsegments, 0.0);
366 std::vector<std::vector<float>> eContEnergy(
367 nregions, std::vector<float>(nsegments, 0.0));
368 std::vector<std::vector<float>> eContXMean(
369 nregions, std::vector<float>(nsegments, 0.0));
370 std::vector<std::vector<float>> eContYMean(
371 nregions, std::vector<float>(nsegments, 0.0));
372 std::vector<std::vector<float>> gContEnergy(
373 nregions, std::vector<float>(nsegments, 0.0));
374 std::vector<std::vector<int>> gContNHits(nregions,
375 std::vector<int>(nsegments, 0));
376 std::vector<std::vector<float>> gContXMean(
377 nregions, std::vector<float>(nsegments, 0.0));
378 std::vector<std::vector<float>> gContYMean(
379 nregions, std::vector<float>(nsegments, 0.0));
380 std::vector<std::vector<float>> oContEnergy(
381 nregions, std::vector<float>(nsegments, 0.0));
382 std::vector<std::vector<int>> oContNHits(nregions,
383 std::vector<int>(nsegments, 0));
384 std::vector<std::vector<float>> oContXMean(
385 nregions, std::vector<float>(nsegments, 0.0));
386 std::vector<std::vector<float>> oContYMean(
387 nregions, std::vector<float>(nsegments, 0.0));
388 std::vector<std::vector<float>> oContXStd(nregions,
389 std::vector<float>(nsegments, 0.0));
390 std::vector<std::vector<float>> oContYStd(nregions,
391 std::vector<float>(nsegments, 0.0));
392 std::vector<std::vector<float>> oContLayerMean(
393 nregions, std::vector<float>(nsegments, 0.0));
394 std::vector<std::vector<float>> oContLayerStd(
395 nregions, std::vector<float>(nsegments, 0.0));
400 std::vector<HitData> trackingHitList;
404 <<
" Loop over the hits from the event to calculate the BDT features";
410 ecalLayerEdepRaw_[
id.layer()] =
411 ecalLayerEdepRaw_[
id.layer()] + hit.getEnergy();
412 if (
id.layer() >= 20) ecalBackEnergy_ += hit.getEnergy();
413 if (maxCellDep_ < hit.getEnergy()) maxCellDep_ = hit.getEnergy();
414 if (hit.getEnergy() <= 0) {
416 <<
"ECal hit has negative or zero energy, this should never happen, "
417 "check the threshold settings in HgcrocEmulator";
421 ecalLayerEdepReadout_[
id.layer()] += hit.getEnergy();
422 ecalLayerTime_[
id.layer()] += (hit.getEnergy()) * hit.getTime();
424 xMean += x * hit.getEnergy();
425 yMean += y * hit.getEnergy();
426 avgLayerHit_ +=
id.layer();
427 wavgLayerHit +=
id.layer() * hit.getEnergy();
428 if (deepestLayerHit_ <
id.layer()) {
429 deepestLayerHit_ =
id.layer();
431 XYCoords xy_pair = std::make_pair(x, y);
432 float distance_ele_trajectory =
433 ele_trajectory.size()
434 ? sqrt(pow((xy_pair.first - ele_trajectory[
id.layer()].first), 2) +
435 pow((xy_pair.second - ele_trajectory[
id.layer()].second), 2))
437 float distance_photon_trajectory =
438 photon_trajectory.size()
439 ? sqrt(pow((xy_pair.first - photon_trajectory[
id.layer()].first),
441 pow((xy_pair.second - photon_trajectory[
id.layer()].second),
446 for (
unsigned int iseg = 0; iseg < nsegments; iseg++) {
447 if (
id.layer() >= segLayers[iseg] &&
448 id.layer() <= segLayers[iseg + 1] - 1) {
449 energySeg[iseg] += hit.getEnergy();
450 xMeanSeg[iseg] += xy_pair.first * hit.getEnergy();
451 yMeanSeg[iseg] += xy_pair.second * hit.getEnergy();
452 layerMeanSeg[iseg] +=
id.layer() * hit.getEnergy();
455 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
456 if (distance_ele_trajectory >= ireg * ele_radii[
id.layer()] &&
457 distance_ele_trajectory < (ireg + 1) * ele_radii[
id.layer()]) {
458 eContEnergy[ireg][iseg] += hit.getEnergy();
459 eContXMean[ireg][iseg] += xy_pair.first * hit.getEnergy();
460 eContYMean[ireg][iseg] += xy_pair.second * hit.getEnergy();
462 if (distance_photon_trajectory >= ireg * photon_radii[
id.layer()] &&
463 distance_photon_trajectory <
464 (ireg + 1) * photon_radii[
id.layer()]) {
465 gContEnergy[ireg][iseg] += hit.getEnergy();
466 gContNHits[ireg][iseg] += 1;
467 gContXMean[ireg][iseg] += xy_pair.first * hit.getEnergy();
468 gContYMean[ireg][iseg] += xy_pair.second * hit.getEnergy();
470 if (distance_ele_trajectory > (ireg + 1) * ele_radii[
id.layer()] &&
471 distance_photon_trajectory >
472 (ireg + 1) * photon_radii[
id.layer()]) {
473 oContEnergy[ireg][iseg] += hit.getEnergy();
474 oContNHits[ireg][iseg] += 1;
475 oContXMean[ireg][iseg] += xy_pair.first * hit.getEnergy();
476 oContYMean[ireg][iseg] += xy_pair.second * hit.getEnergy();
477 oContLayerMean[ireg][iseg] +=
id.layer() * hit.getEnergy();
484 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
485 if (distance_ele_trajectory >= ireg * ele_radii[
id.layer()] &&
486 distance_ele_trajectory < (ireg + 1) * ele_radii[
id.layer()])
487 electronContainmentEnergy[ireg] += hit.getEnergy();
488 if (distance_photon_trajectory >= ireg * photon_radii[
id.layer()] &&
489 distance_photon_trajectory < (ireg + 1) * photon_radii[
id.layer()])
490 photonContainmentEnergy[ireg] += hit.getEnergy();
491 if (distance_ele_trajectory > (ireg + 1) * ele_radii[
id.layer()] &&
492 distance_photon_trajectory > (ireg + 1) * photon_radii[
id.layer()]) {
493 outsideContainmentEnergy[ireg] += hit.getEnergy();
494 outsideContainmentNHits[ireg] += 1;
495 outsideContainmentXmean[ireg] += xy_pair.first * hit.getEnergy();
496 outsideContainmentYmean[ireg] += xy_pair.second * hit.getEnergy();
502 if (distance_ele_trajectory >= ele_radii[
id.layer()] ||
503 distance_ele_trajectory == -1.0) {
505 hd.pos = TVector3(xy_pair.first, xy_pair.second,
507 hd.layer =
id.layer();
508 trackingHitList.push_back(hd);
512 for (
const auto &[
id, energy] : cellMapTightIso_) {
513 if (energy > 0) summedTightIso_ += energy;
516 for (
int iLayer = 0; iLayer < ecalLayerEdepReadout_.size(); iLayer++) {
517 ecalLayerTime_[iLayer] =
518 ecalLayerTime_[iLayer] / ecalLayerEdepReadout_[iLayer];
519 summedDet_ += ecalLayerEdepReadout_[iLayer];
522 if (nReadoutHits_ > 0) {
523 avgLayerHit_ /= nReadoutHits_;
524 wavgLayerHit /= summedDet_;
535 for (
unsigned int iseg = 0; iseg < nsegments; iseg++) {
536 if (energySeg[iseg] > 0) {
537 xMeanSeg[iseg] /= energySeg[iseg];
538 yMeanSeg[iseg] /= energySeg[iseg];
539 layerMeanSeg[iseg] /= energySeg[iseg];
541 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
542 if (eContEnergy[ireg][iseg] > 0) {
543 eContXMean[ireg][iseg] /= eContEnergy[ireg][iseg];
544 eContYMean[ireg][iseg] /= eContEnergy[ireg][iseg];
546 if (gContEnergy[ireg][iseg] > 0) {
547 gContXMean[ireg][iseg] /= gContEnergy[ireg][iseg];
548 gContYMean[ireg][iseg] /= gContEnergy[ireg][iseg];
550 if (oContEnergy[ireg][iseg] > 0) {
551 oContXMean[ireg][iseg] /= oContEnergy[ireg][iseg];
552 oContYMean[ireg][iseg] /= oContEnergy[ireg][iseg];
553 oContLayerMean[ireg][iseg] /= oContEnergy[ireg][iseg];
558 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
559 if (outsideContainmentEnergy[ireg] > 0) {
560 outsideContainmentXmean[ireg] /= outsideContainmentEnergy[ireg];
561 outsideContainmentYmean[ireg] /= outsideContainmentEnergy[ireg];
569 if (hit.getEnergy() > 0) {
570 xStd_ += pow((x - xMean), 2) * hit.getEnergy();
571 yStd_ += pow((y - yMean), 2) * hit.getEnergy();
572 stdLayerHit_ += pow((
id.layer() - wavgLayerHit), 2) * hit.getEnergy();
574 XYCoords xy_pair = std::make_pair(x, y);
575 float distance_ele_trajectory =
576 ele_trajectory.size()
577 ? sqrt(pow((xy_pair.first - ele_trajectory[
id.layer()].first), 2) +
578 pow((xy_pair.second - ele_trajectory[
id.layer()].second), 2))
580 float distance_photon_trajectory =
581 photon_trajectory.size()
582 ? sqrt(pow((xy_pair.first - photon_trajectory[
id.layer()].first),
584 pow((xy_pair.second - photon_trajectory[
id.layer()].second),
588 for (
unsigned int iseg = 0; iseg < nsegments; iseg++) {
589 if (
id.layer() >= segLayers[iseg] &&
590 id.layer() <= segLayers[iseg + 1] - 1) {
592 pow((xy_pair.first - xMeanSeg[iseg]), 2) * hit.getEnergy();
594 pow((xy_pair.second - yMeanSeg[iseg]), 2) * hit.getEnergy();
596 pow((
id.layer() - layerMeanSeg[iseg]), 2) * hit.getEnergy();
598 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
599 if (distance_ele_trajectory > (ireg + 1) * ele_radii[
id.layer()] &&
600 distance_photon_trajectory >
601 (ireg + 1) * photon_radii[
id.layer()]) {
602 oContXStd[ireg][iseg] +=
603 pow((xy_pair.first - oContXMean[ireg][iseg]), 2) *
605 oContYStd[ireg][iseg] +=
606 pow((xy_pair.second - oContYMean[ireg][iseg]), 2) *
608 oContLayerStd[ireg][iseg] +=
609 pow((
id.layer() - oContLayerMean[ireg][iseg]), 2) *
616 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
617 if (distance_ele_trajectory > (ireg + 1) * ele_radii[
id.layer()] &&
618 distance_photon_trajectory > (ireg + 1) * photon_radii[
id.layer()]) {
619 outsideContainmentXstd[ireg] +=
620 pow((xy_pair.first - outsideContainmentXmean[ireg]), 2) *
622 outsideContainmentYstd[ireg] +=
623 pow((xy_pair.second - outsideContainmentYmean[ireg]), 2) *
629 if (nReadoutHits_ > 0) {
630 xStd_ = sqrt(xStd_ / summedDet_);
631 yStd_ = sqrt(yStd_ / summedDet_);
632 stdLayerHit_ = sqrt(stdLayerHit_ / summedDet_);
641 for (
unsigned int iseg = 0; iseg < nsegments; iseg++) {
642 if (energySeg[iseg] > 0) {
643 xStdSeg[iseg] = sqrt(xStdSeg[iseg] / energySeg[iseg]);
644 yStdSeg[iseg] = sqrt(yStdSeg[iseg] / energySeg[iseg]);
645 layerStdSeg[iseg] = sqrt(layerStdSeg[iseg] / energySeg[iseg]);
647 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
648 if (oContEnergy[ireg][iseg] > 0) {
649 oContXStd[ireg][iseg] =
650 sqrt(oContXStd[ireg][iseg] / oContEnergy[ireg][iseg]);
651 oContYStd[ireg][iseg] =
652 sqrt(oContYStd[ireg][iseg] / oContEnergy[ireg][iseg]);
653 oContLayerStd[ireg][iseg] =
654 sqrt(oContLayerStd[ireg][iseg] / oContEnergy[ireg][iseg]);
659 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
660 if (outsideContainmentEnergy[ireg] > 0) {
661 outsideContainmentXstd[ireg] =
662 sqrt(outsideContainmentXstd[ireg] / outsideContainmentEnergy[ireg]);
663 outsideContainmentYstd[ireg] =
664 sqrt(outsideContainmentYstd[ireg] / outsideContainmentEnergy[ireg]);
669 ldmx_log(debug) <<
" Find out if the recoil electron is fiducial";
675 const float dz_from_face{7.932};
676 float drifted_recoil_x{-9999.};
677 float drifted_recoil_y{-9999.};
678 if (!recoilP.empty()) {
680 (dz_from_face * (recoilP[0] / recoilP[2])) + recoilPos[0];
682 (dz_from_face * (recoilP[1] / recoilP[2])) + recoilPos[1];
684 const int recoil_layer_index = 0;
689 const auto ecalID =
geometry_->
getID(drifted_recoil_x, drifted_recoil_y,
690 recoil_layer_index,
true);
691 if (!ecalID.null()) {
694 geometry_->
getID(drifted_recoil_x, drifted_recoil_y, recoil_layer_index,
695 ecalID.getModuleID(),
true);
696 if (!cellID.null()) {
702 ldmx_log(info) <<
"This event is non-fiducial in ECAL";
714 TVector3 e_traj_start;
716 TVector3 p_traj_start;
718 if (!ele_trajectory.empty() && !photon_trajectory.empty()) {
721 e_traj_start.SetXYZ(ele_trajectory[0].first, ele_trajectory[0].second,
723 e_traj_end.SetXYZ(ele_trajectory[(nEcalLayers_ - 1)].first,
724 ele_trajectory[(nEcalLayers_ - 1)].second,
726 p_traj_start.SetXYZ(photon_trajectory[0].first, photon_trajectory[0].second,
728 p_traj_end.SetXYZ(photon_trajectory[(nEcalLayers_ - 1)].first,
729 photon_trajectory[(nEcalLayers_ - 1)].second,
732 TVector3 evec = e_traj_end - e_traj_start;
733 TVector3 e_norm = evec.Unit();
734 TVector3 pvec = p_traj_end - p_traj_start;
735 TVector3 p_norm = pvec.Unit();
736 epDot_ = e_norm.Dot(p_norm);
738 epSep_ = sqrt(pow(e_traj_start.X() - p_traj_start.X(), 2) +
739 pow(e_traj_start.Y() - p_traj_start.Y(), 2));
745 e_traj_end = TVector3(
748 p_traj_end = TVector3(
763 if (!photon_trajectory.empty()) {
764 for (std::vector<HitData>::iterator it = trackingHitList.begin();
765 it != trackingHitList.end(); ++it) {
767 sqrt(pow((*it).pos.X() - photon_trajectory[(*it).layer].first, 2) +
768 pow((*it).pos.Y() - photon_trajectory[(*it).layer].second, 2));
779 TVector3 gToe = (e_traj_start - p_traj_start).Unit();
780 TVector3 origin = p_traj_start + 0.5 * 8.7 * gToe;
781 if (!ele_trajectory.empty()) {
782 for (
auto &hitData : trackingHitList) {
783 TVector3 hitPos = hitData.pos;
784 TVector3 hitPrime = hitPos - origin;
785 if (hitPrime.Dot(gToe) <= 0) {
796 std::sort(trackingHitList.begin(), trackingHitList.end(),
802 std::vector<std::vector<HitData>> track_list;
806 ldmx_log(debug) <<
"====== Tracking hit list (original) length "
807 << trackingHitList.size() <<
" ======";
808 for (
int i = 0; i < trackingHitList.size(); i++) {
809 std::cout <<
"[" << trackingHitList[i].pos.X() <<
", "
810 << trackingHitList[i].pos.Y() <<
", "
811 << trackingHitList[i].layer <<
"], ";
813 std::cout << std::endl;
814 ldmx_log(debug) <<
"====== END OF Tracking hit list ======";
820 for (
int iHit = 0; iHit < trackingHitList.size(); iHit++) {
823 int currenthit{iHit};
833 while (jHit < trackingHitList.size()) {
834 if ((trackingHitList[jHit].layer ==
835 trackingHitList[currenthit].layer - 1 ||
836 trackingHitList[jHit].layer ==
837 trackingHitList[currenthit].layer - 2) &&
838 abs(trackingHitList[jHit].pos.X() -
839 trackingHitList[currenthit].pos.X()) <= 0.5 * cellWidth &&
840 abs(trackingHitList[jHit].pos.Y() -
841 trackingHitList[currenthit].pos.Y()) <= 0.5 * cellWidth) {
842 track[trackLen] = jHit;
850 if (trackLen < 2)
continue;
851 float closest_e =
distTwoLines(trackingHitList[track[0]].pos,
852 trackingHitList[track[trackLen - 1]].pos,
853 e_traj_start, e_traj_end);
854 float closest_p =
distTwoLines(trackingHitList[track[0]].pos,
855 trackingHitList[track[trackLen - 1]].pos,
856 p_traj_start, p_traj_end);
859 if (closest_p > cellWidth and closest_e < 2 * cellWidth)
continue;
860 if (trackLen < 4 and closest_e > closest_p)
continue;
862 ldmx_log(debug) <<
"====== After rejection for MIP tracking ======";
863 ldmx_log(debug) <<
"current hit: [" << trackingHitList[iHit].pos.X()
864 <<
", " << trackingHitList[iHit].pos.Y() <<
", "
865 << trackingHitList[iHit].layer <<
"]";
867 for (
int k = 0; k < trackLen; k++) {
868 ldmx_log(debug) <<
"track[" << k <<
"] position = ["
869 << trackingHitList[track[k]].pos.X() <<
", "
870 << trackingHitList[track[k]].pos.Y() <<
", "
871 << trackingHitList[track[k]].layer <<
"]";
878 std::vector<HitData> temp_track_list;
880 for (
int kHit = 0; kHit < trackLen; kHit++) {
881 temp_track_list.push_back(trackingHitList[track[kHit] - n_remove]);
882 trackingHitList.erase(trackingHitList.begin() + track[kHit] - n_remove);
887 ldmx_log(debug) <<
"====== Tracking hit list (after erase) length "
888 << trackingHitList.size() <<
" ======";
889 for (
int i = 0; i < trackingHitList.size(); i++) {
890 std::cout <<
"[" << trackingHitList[i].pos.X() <<
", "
891 << trackingHitList[i].pos.Y() <<
", "
892 << trackingHitList[i].layer <<
"] ";
894 std::cout << std::endl;
895 ldmx_log(debug) <<
"====== END OF Tracking hit list ======";
898 track_list.push_back(temp_track_list);
905 ldmx_log(debug) <<
"Straight tracks found (before merge): "
906 << track_list.size();
908 for (
int iTrack = 0; iTrack < track_list.size(); iTrack++) {
909 ldmx_log(debug) <<
"Track " << iTrack <<
":";
910 for (
int iHit = 0; iHit < track_list[iTrack].size(); iHit++) {
911 std::cout <<
" Hit " << iHit <<
": ["
912 << track_list[iTrack][iHit].pos.X() <<
", "
913 << track_list[iTrack][iHit].pos.Y() <<
", "
914 << track_list[iTrack][iHit].layer <<
"]" << std::endl;
916 std::cout << std::endl;
923 ldmx_log(debug) <<
"Beginning track merging using " << track_list.size()
926 for (
int track_i = 0; track_i < track_list.size(); track_i++) {
929 std::vector<HitData> base_track = track_list[track_i];
930 HitData tail_hitdata = base_track.back();
931 if (verbose_) ldmx_log(debug) <<
" Considering track " << track_i;
932 for (
int track_j = track_i + 1; track_j < track_list.size(); track_j++) {
933 std::vector<HitData> checking_track = track_list[track_j];
934 HitData head_hitdata = checking_track.front();
936 if ((head_hitdata.layer == tail_hitdata.layer + 1 ||
937 head_hitdata.layer == tail_hitdata.layer + 2) &&
938 pow(pow(head_hitdata.pos.X() - tail_hitdata.pos.X(), 2) +
939 pow(head_hitdata.pos.Y() - tail_hitdata.pos.Y(), 2),
945 ldmx_log(debug) <<
" ** Compatible track found at index "
947 ldmx_log(debug) <<
" Tail xylayer: " << head_hitdata.pos.X()
948 <<
"," << head_hitdata.pos.Y() <<
","
949 << head_hitdata.layer;
950 ldmx_log(debug) <<
" Head xylayer: " << tail_hitdata.pos.X()
951 <<
"," << tail_hitdata.pos.Y() <<
","
952 << tail_hitdata.layer;
954 for (
int hit_k = 0; hit_k < checking_track.size(); hit_k++) {
955 base_track.push_back(track_list[track_j][hit_k]);
957 track_list[track_i] = base_track;
958 track_list.erase(track_list.begin() + track_j);
965 ldmx_log(debug) <<
"Straight tracks found (after merge): "
967 for (
int track_i = 0; track_i < track_list.size(); track_i++) {
968 ldmx_log(debug) <<
"Track " << track_i <<
":";
969 for (
int hit_i = 0; hit_i < track_list[track_i].size(); hit_i++) {
970 ldmx_log(debug) <<
" Hit " << hit_i <<
": ["
971 << track_list[track_i][hit_i].pos.X() <<
", "
972 << track_list[track_i][hit_i].pos.Y() <<
", "
973 << track_list[track_i][hit_i].layer <<
"]";
979 ldmx_log(info) <<
"Finding linreg tracks from a total of "
980 << trackingHitList.size() <<
" hits using a radius of "
981 << linreg_radius_ <<
" mm";
983 for (
int iHit = 0; iHit < trackingHitList.size(); iHit++) {
985 std::vector<int> hitsInRegion;
991 float r_corr_best{0.0};
997 hitsInRegion.push_back(iHit);
999 for (
int jHit = 0; jHit < trackingHitList.size(); jHit++) {
1001 if (trackingHitList[iHit].pos(2) == trackingHitList[jHit].pos(2)) {
1005 (trackingHitList[iHit].pos - trackingHitList[jHit].pos).Mag();
1009 if (dstToHit <= 2 * linreg_radius_) {
1010 hitsInRegion.push_back(jHit);
1014 bool bestLinRegFound{
false};
1016 ldmx_log(debug) <<
"There are " << hitsInRegion.size()
1017 <<
" hits within a radius of " << linreg_radius_ <<
" mm";
1022 for (
int jHitInReg = 1; jHitInReg < hitsInRegion.size() - 1; jHitInReg++) {
1024 if (hitsInRegion.size() < 3)
break;
1025 hitNums[1] = hitsInRegion[jHitInReg];
1026 for (
int kHitReg = jHitInReg + 1; kHitReg < hitsInRegion.size();
1028 hitNums[2] = hitsInRegion[kHitReg];
1029 for (
int hInd = 0; hInd < 3; hInd++) {
1032 hmean(hInd) = (trackingHitList[hitNums[0]].pos(hInd) +
1033 trackingHitList[hitNums[1]].pos(hInd) +
1034 trackingHitList[hitNums[2]].pos(hInd)) /
1037 for (
int hInd = 0; hInd < 3; hInd++) {
1038 for (
int lInd = 0; lInd < 3; lInd++) {
1040 trackingHitList[hitNums[hInd]].pos(lInd) - hmean(lInd);
1046 double determinant =
1047 hdt(0, 0) * (hdt(1, 1) * hdt(2, 2) - hdt(1, 2) * hdt(2, 1)) -
1048 hdt(0, 1) * (hdt(1, 0) * hdt(2, 2) - hdt(1, 2) * hdt(2, 0)) +
1049 hdt(0, 2) * (hdt(1, 0) * hdt(2, 1) - hdt(1, 1) * hdt(2, 0));
1051 if (determinant == 0)
continue;
1053 TDecompSVD svdObj(hdt);
1054 bool decomposed = svdObj.Decompose();
1055 if (!decomposed)
continue;
1059 for (
int hInd = 0; hInd < 3; hInd++) {
1060 slopeVec(hInd) = Vm[0][hInd];
1063 hpoint = slopeVec + hmean;
1067 float closest_e =
distTwoLines(hmean, hpoint, e_traj_start, e_traj_end);
1068 float closest_p =
distTwoLines(hmean, hpoint, p_traj_start, p_traj_end);
1071 if (closest_p > cellWidth or closest_e < 1.5 * cellWidth)
continue;
1074 float vrnc = (trackingHitList[hitNums[0]].pos - hmean).Mag() +
1075 (trackingHitList[hitNums[1]].pos - hmean).Mag() +
1076 (trackingHitList[hitNums[2]].pos - hmean).Mag();
1079 distPtToLine(trackingHitList[hitNums[0]].pos, hmean, hpoint) +
1080 distPtToLine(trackingHitList[hitNums[1]].pos, hmean, hpoint) +
1081 distPtToLine(trackingHitList[hitNums[2]].pos, hmean, hpoint);
1082 float r_corr = 1 - sumerr / vrnc;
1086 if (r_corr > r_corr_best and r_corr > .6) {
1087 r_corr_best = r_corr;
1089 bestLinRegFound =
true;
1090 for (
int k = 0; k < 3; k++) {
1091 bestHitNums[k] = hitNums[k];
1098 if (!bestLinRegFound)
continue;
1102 for (
int finalHitIndx = 0; finalHitIndx < 3; finalHitIndx++) {
1103 ldmx_log(debug) <<
" Hit " << finalHitIndx <<
" ["
1104 << trackingHitList[bestHitNums[finalHitIndx]].pos(0)
1106 << trackingHitList[bestHitNums[finalHitIndx]].pos(1)
1108 << trackingHitList[bestHitNums[finalHitIndx]].pos(2)
1113 for (
int lHit = 0; lHit < 3; lHit++) {
1114 trackingHitList.erase(trackingHitList.begin() + bestHitNums[lHit]);
1121 <<
" lin-reg tracks";
1124 nReadoutHits_, deepestLayerHit_, summedDet_, summedTightIso_, maxCellDep_,
1125 showerRMS_, xStd_, yStd_, avgLayerHit_, stdLayerHit_, ecalBackEnergy_,
1128 photonContainmentEnergy, outsideContainmentEnergy,
1129 outsideContainmentNHits, outsideContainmentXstd, outsideContainmentYstd,
1130 energySeg, xMeanSeg, yMeanSeg, xStdSeg, yStdSeg, layerMeanSeg,
1131 layerStdSeg, eContEnergy, eContXMean, eContYMean, gContEnergy, gContNHits,
1132 gContXMean, gContYMean, oContEnergy, oContNHits, oContXMean, oContYMean,
1133 oContXStd, oContYStd, oContLayerMean, oContLayerStd,
1134 ecalLayerEdepReadout_, recoilP, recoilPos);
1137 ldmx::Ort::FloatArrays inputs({bdtFeatures_});
1138 float pred = rt_->run({featureListName_}, inputs, {
"probabilities"})[0].at(1);
1139 ldmx_log(info) <<
" BDT was ran, score is " << pred;
1144 result.setVetoResult(pred > bdtCutVal_ && passesTrackingVeto);
1145 result.setDiscValue(pred);
1146 ldmx_log(info) <<
" The pred > bdtCutVal = " << (pred > bdtCutVal_)
1147 <<
" and MIP tracking passed = " << passesTrackingVeto;
1150 result.setFiducial(inside);
1154 if (!inverse_skim_) {