170 geometry_ = &getCondition<ldmx::EcalGeometry>(
171 ldmx::EcalGeometry::CONDITIONS_OBJECT_NAME);
180 std::vector<double> recoilP;
181 std::vector<float> recoilPos;
182 std::vector<double> recoilPAtTarget;
183 std::vector<float> recoilPosAtTarget;
186 ldmx_log(debug) <<
" Loop through all of the sim particles and find the "
190 if (event.
exists(
"EcalScoringPlaneHits")) {
199 auto [recoilTrackID, recoilElectron] = Analysis::getRecoil(particleMap);
207 if (hit_id.
plane() != 31 || spHit.getMomentum()[2] <= 0)
continue;
209 if (spHit.getTrackID() == recoilTrackID) {
210 if (sqrt(pow(spHit.getMomentum()[0], 2) +
211 pow(spHit.getMomentum()[1], 2) +
212 pow(spHit.getMomentum()[2], 2)) > pmax) {
213 recoilP = spHit.getMomentum();
214 recoilPos = spHit.getPosition();
215 pmax = sqrt(pow(recoilP[0], 2) + pow(recoilP[1], 2) +
222 if (event.
exists(
"TargetScoringPlaneHits")) {
223 std::vector<ldmx::SimTrackerHit> targetSpHits =
228 if (hit_id.
plane() != 1 || spHit.getMomentum()[2] <= 0)
continue;
230 if (spHit.getTrackID() == recoilTrackID) {
231 if (sqrt(pow(spHit.getMomentum()[0], 2) +
232 pow(spHit.getMomentum()[1], 2) +
233 pow(spHit.getMomentum()[2], 2)) > pmax) {
234 recoilPAtTarget = spHit.getMomentum();
235 recoilPosAtTarget = spHit.getPosition();
237 sqrt(pow(recoilPAtTarget[0], 2) + pow(recoilPAtTarget[1], 2) +
238 pow(recoilPAtTarget[2], 2));
246 ldmx_log(debug) <<
" Get projected trajectories for electron and photon";
249 std::vector<XYCoords> ele_trajectory, photon_trajectory;
250 if (recoilP.size() > 0) {
251 ele_trajectory = getTrajectory(recoilP, recoilPos);
252 std::vector<double> pvec = recoilPAtTarget.size()
254 : std::vector<double>{0.0, 0.0, 0.0};
255 std::vector<float> posvec = recoilPosAtTarget.size()
257 : std::vector<float>{0.0, 0.0, 0.0};
259 getTrajectory({-pvec[0], -pvec[1], beamEnergyMeV_ - pvec[2]}, posvec);
264 ? sqrt(pow(recoilP[0], 2) + pow(recoilP[1], 2) + pow(recoilP[2], 2))
267 recoilPMag > 0 ? acos(recoilP[2] / recoilPMag) * 180.0 / M_PI : -1.0;
270 ldmx_log(debug) <<
" Build Radii of containment (ROC)";
273 std::vector<double> roc_values_bin0(roc_range_values_[0].begin() + 4,
274 roc_range_values_[0].end());
275 std::vector<double> ele_radii = roc_values_bin0;
276 double theta_min, theta_max, p_min, p_max;
279 for (
int i = 0; i < roc_range_values_.size(); i++) {
280 theta_min = roc_range_values_[i][0];
281 theta_max = roc_range_values_[i][1];
282 p_min = roc_range_values_[i][2];
283 p_max = roc_range_values_[i][3];
286 if (theta_min != -1.0) {
287 inrange = inrange && (recoilTheta >= theta_min);
289 if (theta_max != -1.0) {
290 inrange = inrange && (recoilTheta < theta_max);
293 inrange = inrange && (recoilPMag >= p_min);
296 inrange = inrange && (recoilPMag < p_max);
299 std::vector<double> roc_values_bini(roc_range_values_[i].begin() + 4,
300 roc_range_values_[i].end());
301 ele_radii = roc_values_bini;
305 std::vector<double> photon_radii = roc_values_bin0;
308 const std::vector<ldmx::EcalHit> ecalRecHits =
309 event.getCollection<
ldmx::EcalHit>(rec_coll_name_, rec_pass_name_);
312 GetShowerCentroidIDAndRMS(ecalRecHits, showerRMS_);
317 fillIsolatedHitMap(ecalRecHits, globalCentroid, cellMap_, cellMapTightIso_,
323 float wavgLayerHit = 0;
328 unsigned int nregions = 5;
329 std::vector<float> electronContainmentEnergy(nregions, 0.0);
330 std::vector<float> photonContainmentEnergy(nregions, 0.0);
331 std::vector<float> outsideContainmentEnergy(nregions, 0.0);
332 std::vector<int> outsideContainmentNHits(nregions, 0);
333 std::vector<float> outsideContainmentXmean(nregions, 0.0);
334 std::vector<float> outsideContainmentYmean(nregions, 0.0);
335 std::vector<float> outsideContainmentXstd(nregions, 0.0);
336 std::vector<float> outsideContainmentYstd(nregions, 0.0);
338 std::vector<int> segLayers = {0, 6, 17, 34};
339 unsigned int nsegments = segLayers.size() - 1;
340 std::vector<float> energySeg(nsegments, 0.0);
341 std::vector<float> xMeanSeg(nsegments, 0.0);
342 std::vector<float> xStdSeg(nsegments, 0.0);
343 std::vector<float> yMeanSeg(nsegments, 0.0);
344 std::vector<float> yStdSeg(nsegments, 0.0);
345 std::vector<float> layerMeanSeg(nsegments, 0.0);
346 std::vector<float> layerStdSeg(nsegments, 0.0);
347 std::vector<std::vector<float>> eContEnergy(
348 nregions, std::vector<float>(nsegments, 0.0));
349 std::vector<std::vector<float>> eContXMean(
350 nregions, std::vector<float>(nsegments, 0.0));
351 std::vector<std::vector<float>> eContYMean(
352 nregions, std::vector<float>(nsegments, 0.0));
353 std::vector<std::vector<float>> gContEnergy(
354 nregions, std::vector<float>(nsegments, 0.0));
355 std::vector<std::vector<int>> gContNHits(nregions,
356 std::vector<int>(nsegments, 0));
357 std::vector<std::vector<float>> gContXMean(
358 nregions, std::vector<float>(nsegments, 0.0));
359 std::vector<std::vector<float>> gContYMean(
360 nregions, std::vector<float>(nsegments, 0.0));
361 std::vector<std::vector<float>> oContEnergy(
362 nregions, std::vector<float>(nsegments, 0.0));
363 std::vector<std::vector<int>> oContNHits(nregions,
364 std::vector<int>(nsegments, 0));
365 std::vector<std::vector<float>> oContXMean(
366 nregions, std::vector<float>(nsegments, 0.0));
367 std::vector<std::vector<float>> oContYMean(
368 nregions, std::vector<float>(nsegments, 0.0));
369 std::vector<std::vector<float>> oContXStd(nregions,
370 std::vector<float>(nsegments, 0.0));
371 std::vector<std::vector<float>> oContYStd(nregions,
372 std::vector<float>(nsegments, 0.0));
373 std::vector<std::vector<float>> oContLayerMean(
374 nregions, std::vector<float>(nsegments, 0.0));
375 std::vector<std::vector<float>> oContLayerStd(
376 nregions, std::vector<float>(nsegments, 0.0));
381 std::vector<HitData> trackingHitList;
385 <<
" Loop over the hits from the event to calculate the BDT features";
391 ecalLayerEdepRaw_[
id.layer()] =
392 ecalLayerEdepRaw_[
id.layer()] + hit.getEnergy();
393 if (
id.layer() >= 20) ecalBackEnergy_ += hit.getEnergy();
394 if (maxCellDep_ < hit.getEnergy()) maxCellDep_ = hit.getEnergy();
395 if (hit.getEnergy() > 0) {
397 ecalLayerEdepReadout_[
id.layer()] += hit.getEnergy();
398 ecalLayerTime_[
id.layer()] += (hit.getEnergy()) * hit.getTime();
400 xMean += x * hit.getEnergy();
401 yMean += y * hit.getEnergy();
402 avgLayerHit_ +=
id.layer();
403 wavgLayerHit +=
id.layer() * hit.getEnergy();
404 if (deepestLayerHit_ <
id.layer()) {
405 deepestLayerHit_ =
id.layer();
407 XYCoords xy_pair = std::make_pair(x, y);
408 float distance_ele_trajectory =
409 ele_trajectory.size()
411 pow((xy_pair.first - ele_trajectory[
id.layer()].first), 2) +
412 pow((xy_pair.second - ele_trajectory[
id.layer()].second),
415 float distance_photon_trajectory =
416 photon_trajectory.size()
418 pow((xy_pair.first - photon_trajectory[
id.layer()].first),
420 pow((xy_pair.second - photon_trajectory[
id.layer()].second),
425 for (
unsigned int iseg = 0; iseg < nsegments; iseg++) {
426 if (
id.layer() >= segLayers[iseg] &&
427 id.layer() <= segLayers[iseg + 1] - 1) {
428 energySeg[iseg] += hit.getEnergy();
429 xMeanSeg[iseg] += xy_pair.first * hit.getEnergy();
430 yMeanSeg[iseg] += xy_pair.second * hit.getEnergy();
431 layerMeanSeg[iseg] +=
id.layer() * hit.getEnergy();
434 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
435 if (distance_ele_trajectory >= ireg * ele_radii[
id.layer()] &&
436 distance_ele_trajectory < (ireg + 1) * ele_radii[
id.layer()]) {
437 eContEnergy[ireg][iseg] += hit.getEnergy();
438 eContXMean[ireg][iseg] += xy_pair.first * hit.getEnergy();
439 eContYMean[ireg][iseg] += xy_pair.second * hit.getEnergy();
441 if (distance_photon_trajectory >= ireg * photon_radii[
id.layer()] &&
442 distance_photon_trajectory <
443 (ireg + 1) * photon_radii[
id.layer()]) {
444 gContEnergy[ireg][iseg] += hit.getEnergy();
445 gContNHits[ireg][iseg] += 1;
446 gContXMean[ireg][iseg] += xy_pair.first * hit.getEnergy();
447 gContYMean[ireg][iseg] += xy_pair.second * hit.getEnergy();
449 if (distance_ele_trajectory > (ireg + 1) * ele_radii[
id.layer()] &&
450 distance_photon_trajectory >
451 (ireg + 1) * photon_radii[
id.layer()]) {
452 oContEnergy[ireg][iseg] += hit.getEnergy();
453 oContNHits[ireg][iseg] += 1;
454 oContXMean[ireg][iseg] += xy_pair.first * hit.getEnergy();
455 oContYMean[ireg][iseg] += xy_pair.second * hit.getEnergy();
456 oContLayerMean[ireg][iseg] +=
id.layer() * hit.getEnergy();
463 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
464 if (distance_ele_trajectory >= ireg * ele_radii[
id.layer()] &&
465 distance_ele_trajectory < (ireg + 1) * ele_radii[
id.layer()])
466 electronContainmentEnergy[ireg] += hit.getEnergy();
467 if (distance_photon_trajectory >= ireg * photon_radii[
id.layer()] &&
468 distance_photon_trajectory < (ireg + 1) * photon_radii[
id.layer()])
469 photonContainmentEnergy[ireg] += 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 outsideContainmentEnergy[ireg] += hit.getEnergy();
474 outsideContainmentNHits[ireg] += 1;
475 outsideContainmentXmean[ireg] += xy_pair.first * hit.getEnergy();
476 outsideContainmentYmean[ireg] += xy_pair.second * hit.getEnergy();
482 if (distance_ele_trajectory >= ele_radii[
id.layer()] ||
483 distance_ele_trajectory == -1.0) {
485 hd.pos = TVector3(xy_pair.first, xy_pair.second,
487 hd.layer =
id.layer();
488 trackingHitList.push_back(hd);
493 for (
const auto &[
id, energy] : cellMapTightIso_) {
494 if (energy > 0) summedTightIso_ += energy;
497 for (
int iLayer = 0; iLayer < ecalLayerEdepReadout_.size(); iLayer++) {
498 ecalLayerTime_[iLayer] =
499 ecalLayerTime_[iLayer] / ecalLayerEdepReadout_[iLayer];
500 summedDet_ += ecalLayerEdepReadout_[iLayer];
503 if (nReadoutHits_ > 0) {
504 avgLayerHit_ /= nReadoutHits_;
505 wavgLayerHit /= summedDet_;
516 for (
unsigned int iseg = 0; iseg < nsegments; iseg++) {
517 if (energySeg[iseg] > 0) {
518 xMeanSeg[iseg] /= energySeg[iseg];
519 yMeanSeg[iseg] /= energySeg[iseg];
520 layerMeanSeg[iseg] /= energySeg[iseg];
522 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
523 if (eContEnergy[ireg][iseg] > 0) {
524 eContXMean[ireg][iseg] /= eContEnergy[ireg][iseg];
525 eContYMean[ireg][iseg] /= eContEnergy[ireg][iseg];
527 if (gContEnergy[ireg][iseg] > 0) {
528 gContXMean[ireg][iseg] /= gContEnergy[ireg][iseg];
529 gContYMean[ireg][iseg] /= gContEnergy[ireg][iseg];
531 if (oContEnergy[ireg][iseg] > 0) {
532 oContXMean[ireg][iseg] /= oContEnergy[ireg][iseg];
533 oContYMean[ireg][iseg] /= oContEnergy[ireg][iseg];
534 oContLayerMean[ireg][iseg] /= oContEnergy[ireg][iseg];
539 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
540 if (outsideContainmentEnergy[ireg] > 0) {
541 outsideContainmentXmean[ireg] /= outsideContainmentEnergy[ireg];
542 outsideContainmentYmean[ireg] /= outsideContainmentEnergy[ireg];
550 if (hit.getEnergy() > 0) {
551 xStd_ += pow((x - xMean), 2) * hit.getEnergy();
552 yStd_ += pow((y - yMean), 2) * hit.getEnergy();
553 stdLayerHit_ += pow((
id.layer() - wavgLayerHit), 2) * hit.getEnergy();
555 XYCoords xy_pair = std::make_pair(x, y);
556 float distance_ele_trajectory =
557 ele_trajectory.size()
558 ? sqrt(pow((xy_pair.first - ele_trajectory[
id.layer()].first), 2) +
559 pow((xy_pair.second - ele_trajectory[
id.layer()].second), 2))
561 float distance_photon_trajectory =
562 photon_trajectory.size()
563 ? sqrt(pow((xy_pair.first - photon_trajectory[
id.layer()].first),
565 pow((xy_pair.second - photon_trajectory[
id.layer()].second),
569 for (
unsigned int iseg = 0; iseg < nsegments; iseg++) {
570 if (
id.layer() >= segLayers[iseg] &&
571 id.layer() <= segLayers[iseg + 1] - 1) {
573 pow((xy_pair.first - xMeanSeg[iseg]), 2) * hit.getEnergy();
575 pow((xy_pair.second - yMeanSeg[iseg]), 2) * hit.getEnergy();
577 pow((
id.layer() - layerMeanSeg[iseg]), 2) * hit.getEnergy();
579 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
580 if (distance_ele_trajectory > (ireg + 1) * ele_radii[
id.layer()] &&
581 distance_photon_trajectory >
582 (ireg + 1) * photon_radii[
id.layer()]) {
583 oContXStd[ireg][iseg] +=
584 pow((xy_pair.first - oContXMean[ireg][iseg]), 2) *
586 oContYStd[ireg][iseg] +=
587 pow((xy_pair.second - oContYMean[ireg][iseg]), 2) *
589 oContLayerStd[ireg][iseg] +=
590 pow((
id.layer() - oContLayerMean[ireg][iseg]), 2) *
597 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
598 if (distance_ele_trajectory > (ireg + 1) * ele_radii[
id.layer()] &&
599 distance_photon_trajectory > (ireg + 1) * photon_radii[
id.layer()]) {
600 outsideContainmentXstd[ireg] +=
601 pow((xy_pair.first - outsideContainmentXmean[ireg]), 2) *
603 outsideContainmentYstd[ireg] +=
604 pow((xy_pair.second - outsideContainmentYmean[ireg]), 2) *
610 if (nReadoutHits_ > 0) {
611 xStd_ = sqrt(xStd_ / summedDet_);
612 yStd_ = sqrt(yStd_ / summedDet_);
613 stdLayerHit_ = sqrt(stdLayerHit_ / summedDet_);
622 for (
unsigned int iseg = 0; iseg < nsegments; iseg++) {
623 if (energySeg[iseg] > 0) {
624 xStdSeg[iseg] = sqrt(xStdSeg[iseg] / energySeg[iseg]);
625 yStdSeg[iseg] = sqrt(yStdSeg[iseg] / energySeg[iseg]);
626 layerStdSeg[iseg] = sqrt(layerStdSeg[iseg] / energySeg[iseg]);
628 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
629 if (oContEnergy[ireg][iseg] > 0) {
630 oContXStd[ireg][iseg] =
631 sqrt(oContXStd[ireg][iseg] / oContEnergy[ireg][iseg]);
632 oContYStd[ireg][iseg] =
633 sqrt(oContYStd[ireg][iseg] / oContEnergy[ireg][iseg]);
634 oContLayerStd[ireg][iseg] =
635 sqrt(oContLayerStd[ireg][iseg] / oContEnergy[ireg][iseg]);
640 for (
unsigned int ireg = 0; ireg < nregions; ireg++) {
641 if (outsideContainmentEnergy[ireg] > 0) {
642 outsideContainmentXstd[ireg] =
643 sqrt(outsideContainmentXstd[ireg] / outsideContainmentEnergy[ireg]);
644 outsideContainmentYstd[ireg] =
645 sqrt(outsideContainmentYstd[ireg] / outsideContainmentEnergy[ireg]);
650 ldmx_log(debug) <<
" Find out if the recoil electron is fiducial";
656 const float dz_from_face{7.932};
657 float drifted_recoil_x{-9999.};
658 float drifted_recoil_y{-9999.};
659 if (recoilP.size() > 0) {
661 (dz_from_face * (recoilP[0] / recoilP[2])) + recoilPos[0];
663 (dz_from_face * (recoilP[1] / recoilP[2])) + recoilPos[1];
665 const int recoil_layer_index = 0;
670 const auto ecalID =
geometry_->
getID(drifted_recoil_x, drifted_recoil_y,
671 recoil_layer_index,
true);
672 if (!ecalID.null()) {
675 geometry_->
getID(drifted_recoil_x, drifted_recoil_y, recoil_layer_index,
676 ecalID.getModuleID(),
true);
677 if (!cellID.null()) {
683 ldmx_log(info) <<
"This event is non-fiducial in ECAL";
695 TVector3 e_traj_start;
697 TVector3 p_traj_start;
699 if (ele_trajectory.size() > 0 && photon_trajectory.size() > 0) {
702 e_traj_start.SetXYZ(ele_trajectory[0].first, ele_trajectory[0].second,
704 e_traj_end.SetXYZ(ele_trajectory[(nEcalLayers_ - 1)].first,
705 ele_trajectory[(nEcalLayers_ - 1)].second,
707 p_traj_start.SetXYZ(photon_trajectory[0].first, photon_trajectory[0].second,
709 p_traj_end.SetXYZ(photon_trajectory[(nEcalLayers_ - 1)].first,
710 photon_trajectory[(nEcalLayers_ - 1)].second,
713 TVector3 evec = e_traj_end - e_traj_start;
714 TVector3 e_norm = evec.Unit();
715 TVector3 pvec = p_traj_end - p_traj_start;
716 TVector3 p_norm = pvec.Unit();
717 epDot_ = e_norm.Dot(p_norm);
719 epSep_ = sqrt(pow(e_traj_start.X() - p_traj_start.X(), 2) +
720 pow(e_traj_start.Y() - p_traj_start.Y(), 2));
726 e_traj_end = TVector3(
729 p_traj_end = TVector3(
743 if (photon_trajectory.size() !=
745 for (std::vector<HitData>::iterator it = trackingHitList.begin();
746 it != trackingHitList.end(); ++it) {
748 sqrt(pow((*it).pos.X() - photon_trajectory[(*it).layer].first, 2) +
749 pow((*it).pos.Y() - photon_trajectory[(*it).layer].second, 2));
760 TVector3 gToe = (e_traj_start - p_traj_start).Unit();
761 TVector3 origin = p_traj_start + 0.5 * 8.7 * gToe;
762 if (ele_trajectory.size() > 0) {
763 for (
auto &hitData : trackingHitList) {
764 TVector3 hitPos = hitData.pos;
765 TVector3 hitPrime = hitPos - origin;
766 if (hitPrime.Dot(gToe) <= 0) {
777 std::sort(trackingHitList.begin(), trackingHitList.end(),
783 std::vector<std::vector<HitData>> track_list;
787 ldmx_log(debug) <<
"====== Tracking hit list (original) length "
788 << trackingHitList.size() <<
" ======";
789 for (
int i = 0; i < trackingHitList.size(); i++) {
790 std::cout <<
"[" << trackingHitList[i].pos.X() <<
", "
791 << trackingHitList[i].pos.Y() <<
", "
792 << trackingHitList[i].layer <<
"], ";
794 std::cout << std::endl;
795 ldmx_log(debug) <<
"====== END OF Tracking hit list ======";
801 for (
int iHit = 0; iHit < trackingHitList.size(); iHit++) {
804 int currenthit{iHit};
814 while (jHit < trackingHitList.size()) {
815 if ((trackingHitList[jHit].layer ==
816 trackingHitList[currenthit].layer - 1 ||
817 trackingHitList[jHit].layer ==
818 trackingHitList[currenthit].layer - 2) &&
819 abs(trackingHitList[jHit].pos.X() -
820 trackingHitList[currenthit].pos.X()) <= 0.5 * cellWidth &&
821 abs(trackingHitList[jHit].pos.Y() -
822 trackingHitList[currenthit].pos.Y()) <= 0.5 * cellWidth) {
823 track[trackLen] = jHit;
831 if (trackLen < 2)
continue;
832 float closest_e =
distTwoLines(trackingHitList[track[0]].pos,
833 trackingHitList[track[trackLen - 1]].pos,
834 e_traj_start, e_traj_end);
835 float closest_p =
distTwoLines(trackingHitList[track[0]].pos,
836 trackingHitList[track[trackLen - 1]].pos,
837 p_traj_start, p_traj_end);
840 if (closest_p > cellWidth and closest_e < 2 * cellWidth)
continue;
841 if (trackLen < 4 and closest_e > closest_p)
continue;
843 ldmx_log(debug) <<
"====== After rejection for MIP tracking ======";
844 ldmx_log(debug) <<
"current hit: [" << trackingHitList[iHit].pos.X()
845 <<
", " << trackingHitList[iHit].pos.Y() <<
", "
846 << trackingHitList[iHit].layer <<
"]";
848 for (
int k = 0; k < trackLen; k++) {
849 ldmx_log(debug) <<
"track[" << k <<
"] position = ["
850 << trackingHitList[track[k]].pos.X() <<
", "
851 << trackingHitList[track[k]].pos.Y() <<
", "
852 << trackingHitList[track[k]].layer <<
"]";
859 std::vector<HitData> temp_track_list;
861 for (
int kHit = 0; kHit < trackLen; kHit++) {
862 temp_track_list.push_back(trackingHitList[track[kHit] - n_remove]);
863 trackingHitList.erase(trackingHitList.begin() + track[kHit] - n_remove);
868 ldmx_log(debug) <<
"====== Tracking hit list (after erase) length "
869 << trackingHitList.size() <<
" ======";
870 for (
int i = 0; i < trackingHitList.size(); i++) {
871 std::cout <<
"[" << trackingHitList[i].pos.X() <<
", "
872 << trackingHitList[i].pos.Y() <<
", "
873 << trackingHitList[i].layer <<
"] ";
875 std::cout << std::endl;
876 ldmx_log(debug) <<
"====== END OF Tracking hit list ======";
879 track_list.push_back(temp_track_list);
886 ldmx_log(debug) <<
"Straight tracks found (before merge): "
887 << track_list.size();
889 for (
int iTrack = 0; iTrack < track_list.size(); iTrack++) {
890 ldmx_log(debug) <<
"Track " << iTrack <<
":";
891 for (
int iHit = 0; iHit < track_list[iTrack].size(); iHit++) {
892 std::cout <<
" Hit " << iHit <<
": ["
893 << track_list[iTrack][iHit].pos.X() <<
", "
894 << track_list[iTrack][iHit].pos.Y() <<
", "
895 << track_list[iTrack][iHit].layer <<
"]" << std::endl;
897 std::cout << std::endl;
904 ldmx_log(debug) <<
"Beginning track merging using " << track_list.size()
907 for (
int track_i = 0; track_i < track_list.size(); track_i++) {
910 std::vector<HitData> base_track = track_list[track_i];
911 HitData tail_hitdata = base_track.back();
912 if (verbose_) ldmx_log(debug) <<
" Considering track " << track_i;
913 for (
int track_j = track_i + 1; track_j < track_list.size(); track_j++) {
914 std::vector<HitData> checking_track = track_list[track_j];
915 HitData head_hitdata = checking_track.front();
917 if ((head_hitdata.layer == tail_hitdata.layer + 1 ||
918 head_hitdata.layer == tail_hitdata.layer + 2) &&
919 pow(pow(head_hitdata.pos.X() - tail_hitdata.pos.X(), 2) +
920 pow(head_hitdata.pos.Y() - tail_hitdata.pos.Y(), 2),
926 ldmx_log(debug) <<
" ** Compatible track found at index "
928 ldmx_log(debug) <<
" Tail xylayer: " << head_hitdata.pos.X()
929 <<
"," << head_hitdata.pos.Y() <<
","
930 << head_hitdata.layer;
931 ldmx_log(debug) <<
" Head xylayer: " << tail_hitdata.pos.X()
932 <<
"," << tail_hitdata.pos.Y() <<
","
933 << tail_hitdata.layer;
935 for (
int hit_k = 0; hit_k < checking_track.size(); hit_k++) {
936 base_track.push_back(track_list[track_j][hit_k]);
938 track_list[track_i] = base_track;
939 track_list.erase(track_list.begin() + track_j);
946 ldmx_log(debug) <<
"Straight tracks found (after merge): "
948 for (
int track_i = 0; track_i < track_list.size(); track_i++) {
949 ldmx_log(debug) <<
"Track " << track_i <<
":";
950 for (
int hit_i = 0; hit_i < track_list[track_i].size(); hit_i++) {
951 ldmx_log(debug) <<
" Hit " << hit_i <<
": ["
952 << track_list[track_i][hit_i].pos.X() <<
", "
953 << track_list[track_i][hit_i].pos.Y() <<
", "
954 << track_list[track_i][hit_i].layer <<
"]";
960 ldmx_log(debug) <<
"Finding linreg tracks from " << trackingHitList.size()
963 for (
int iHit = 0; iHit < trackingHitList.size(); iHit++) {
970 int nHitsInRegion{1};
976 float r_corr_best{0.0};
981 for (
int jHit = 0; jHit < trackingHitList.size(); jHit++) {
983 if (trackingHitList[iHit].pos(2) == trackingHitList[jHit].pos(2)) {
987 (trackingHitList[iHit].pos - trackingHitList[jHit].pos).Mag();
990 if (dstToHit <= 2 * cellWidth) {
999 for (
int jHit = 1; jHit < nHitsInRegion - 1; jHit++) {
1000 if (trackingHitList.size() < 3)
break;
1002 for (
int kHit = jHit + 1; kHit < nHitsInRegion; kHit++) {
1004 for (
int hInd = 0; hInd < 3; hInd++) {
1007 hmean(hInd) = (trackingHitList[hitNums[0]].pos(hInd) +
1008 trackingHitList[hitNums[1]].pos(hInd) +
1009 trackingHitList[hitNums[2]].pos(hInd)) /
1012 for (
int hInd = 0; hInd < 3; hInd++) {
1013 for (
int lInd = 0; lInd < 3; lInd++) {
1015 trackingHitList[hitNums[hInd]].pos(lInd) - hmean(lInd);
1021 double determinant =
1022 hdt(0, 0) * (hdt(1, 1) * hdt(2, 2) - hdt(1, 2) * hdt(2, 1)) -
1023 hdt(0, 1) * (hdt(1, 0) * hdt(2, 2) - hdt(1, 2) * hdt(2, 0)) +
1024 hdt(0, 2) * (hdt(1, 0) * hdt(2, 1) - hdt(1, 1) * hdt(2, 0));
1026 if (determinant == 0)
continue;
1028 TDecompSVD svdObj(hdt);
1029 bool decomposed = svdObj.Decompose();
1030 if (!decomposed)
continue;
1034 for (
int hInd = 0; hInd < 3; hInd++) {
1035 slopeVec(hInd) = Vm[0][hInd];
1038 hpoint = slopeVec + hmean;
1042 float closest_e =
distTwoLines(hmean, hpoint, e_traj_start, e_traj_end);
1043 float closest_p =
distTwoLines(hmean, hpoint, p_traj_start, p_traj_end);
1046 if (closest_p > cellWidth or closest_e < 1.5 * cellWidth)
continue;
1049 float vrnc = (trackingHitList[hitNums[0]].pos - hmean).Mag() +
1050 (trackingHitList[hitNums[1]].pos - hmean).Mag() +
1051 (trackingHitList[hitNums[2]].pos - hmean).Mag();
1054 distPtToLine(trackingHitList[hitNums[0]].pos, hmean, hpoint) +
1055 distPtToLine(trackingHitList[hitNums[1]].pos, hmean, hpoint) +
1056 distPtToLine(trackingHitList[hitNums[2]].pos, hmean, hpoint);
1057 float r_corr = 1 - sumerr / vrnc;
1061 if (r_corr > r_corr_best and r_corr > .6) {
1062 r_corr_best = r_corr;
1065 for (
int k = 0; k < 3; k++) {
1066 track[k] = hitNums[k];
1074 if (trackLen == 0)
continue;
1079 if (trackLen >= 2) {
1081 for (
int kHit = 0; kHit < trackLen; kHit++) {
1082 trackingHitList.erase(trackingHitList.begin() + track[kHit]);
1090 <<
" lin-reg tracks";
1093 nReadoutHits_, deepestLayerHit_, summedDet_, summedTightIso_, maxCellDep_,
1094 showerRMS_, xStd_, yStd_, avgLayerHit_, stdLayerHit_, ecalBackEnergy_,
1097 photonContainmentEnergy, outsideContainmentEnergy,
1098 outsideContainmentNHits, outsideContainmentXstd, outsideContainmentYstd,
1099 energySeg, xMeanSeg, yMeanSeg, xStdSeg, yStdSeg, layerMeanSeg,
1100 layerStdSeg, eContEnergy, eContXMean, eContYMean, gContEnergy, gContNHits,
1101 gContXMean, gContYMean, oContEnergy, oContNHits, oContXMean, oContYMean,
1102 oContXStd, oContYStd, oContLayerMean, oContLayerStd,
1103 ecalLayerEdepReadout_, recoilP, recoilPos);
1106 ldmx::Ort::FloatArrays inputs({bdtFeatures_});
1107 float pred = rt_->run({featureListName_}, inputs, {
"probabilities"})[0].at(1);
1112 result.setVetoResult(pred > bdtCutVal_ && passesTrackingVeto);
1113 result.setDiscValue(pred);
1114 ldmx_log(debug) <<
" The pred > bdtCutVal = " << (pred > bdtCutVal_);
1117 result.setFiducial(inside);