40 std::vector<art::Ptr<recob::Hit>>& hits,
41 geo::Point_t
const& ShowerStartPosition,
42 geo::Vector_t
const& ShowerDirection)
const
45 std::map<double, art::Ptr<recob::Hit>> OrderedHits;
46 art::Ptr<recob::Hit> startHit = hits.front();
49 const geo::WireID startWireID = startHit->WireID();
52 const geo::PlaneID planeid = startWireID.asPlaneID();
55 double pitch = fGeom->WirePitch(planeid);
57 TVector2 Shower2DStartPosition = {
58 fGeom->WireCoordinate(ShowerStartPosition, startHit->WireID().planeID()) * pitch,
59 ShowerStartPosition.X()};
62 auto const PlaneDirection = fGeom->Plane(planeid).GetIncreasingWireDirection();
65 TVector2 Shower2DDirection = {ShowerDirection.Dot(PlaneDirection), ShowerDirection.X()};
67 Shower2DDirection = Shower2DDirection.Unit();
69 for (
auto const& hit : hits) {
72 const geo::WireID WireID = hit->WireID();
74 if (WireID.asPlaneID() != startWireID.asPlaneID()) {
break; }
77 TVector2 hitcoord = HitCoordinates(detProp, hit);
80 TVector2 pos = hitcoord - Shower2DStartPosition;
81 OrderedHits[pos * Shower2DDirection] = hit;
85 std::vector<art::Ptr<recob::Hit>> showerHits;
86 std::transform(OrderedHits.begin(),
88 std::back_inserter(showerHits),
89 [](std::pair<
double, art::Ptr<recob::Hit>>
const& hit) { return hit.second; });
92 art::Ptr<recob::Hit> frontHit = showerHits.front();
93 art::Ptr<recob::Hit> backHit = showerHits.back();
96 TVector2 fronthitcoord = HitCoordinates(detProp, frontHit);
97 TVector2 frontpos = fronthitcoord - Shower2DStartPosition;
100 TVector2 backhitcoord = HitCoordinates(detProp, backHit);
101 TVector2 backpos = backhitcoord - Shower2DStartPosition;
103 double frontproj = frontpos * Shower2DDirection;
104 double backproj = backpos * Shower2DDirection;
105 if (std::abs(backproj) < std::abs(frontproj)) {
106 std::reverse(showerHits.begin(), showerHits.end());
401 const geo::Point_t& ShowerCentre,
402 const geo::Vector_t& Direction,
403 const unsigned int nSegments)
const
406 throw cet::exception(
"LArPandoraShowerAlg")
407 <<
"Unable to calculate RMS Shower Gradient with 0 segments" << std::endl;
409 if (sps.size() < 3)
return 0;
412 this->OrderShowerSpacePoints(sps, ShowerCentre, Direction);
415 const double minProj = this->SpacePointProjection(sps[0], ShowerCentre, Direction);
416 const double maxProj = this->SpacePointProjection(sps[sps.size() - 1], ShowerCentre, Direction);
418 const double length = (maxProj - minProj);
419 const double segmentsize = length / nSegments;
421 if (segmentsize < std::numeric_limits<double>::epsilon())
return 0;
423 std::map<int, std::vector<float>> len_segment_map;
426 for (
auto const& sp : sps) {
429 const double len = this->SpacePointProjection(sp, ShowerCentre, Direction);
432 const double len_perp = this->SpacePointPerpendicular(sp, ShowerCentre, Direction, len);
434 int sg_len = std::round(len / segmentsize);
435 len_segment_map[sg_len].push_back(len_perp);
445 for (
auto const& segment : len_segment_map) {
446 if (segment.second.size() < 2)
continue;
447 float RMS = this->CalculateRMS(segment.second);
450 if (RMS < 0)
continue;
453 sumx += segment.first;
455 sumx2 += segment.first * segment.first;
456 sumxy += RMS * segment.first;
460 const float denom = counter * sumx2 - sumx * sumx;
462 return std::abs(denom) < std::numeric_limits<float>::epsilon() ?
464 (counter * sumxy - sumx * sumy) / denom;
536 typedef std::pair<unsigned, std::vector<unsigned>> OrganizedHits;
537 struct HitIdentifier {
544 explicit HitIdentifier(
const recob::Hit& hit)
545 : startTick(hit.StartTick())
546 , endTick(hit.EndTick())
547 , wire(hit.WireID().Wire)
548 , integral(hit.Integral())
552 inline bool operator==(
const HitIdentifier& rhs)
const
554 return startTick == rhs.startTick && endTick == rhs.endTick && wire == rhs.wire;
558 inline bool operator>(
const HitIdentifier& rhs)
const {
return integral > rhs.integral; }
561 unsigned nplanes = 6;
562 std::vector<std::vector<OrganizedHits>> hits_org(nplanes);
563 std::vector<std::vector<HitIdentifier>> hit_idents(nplanes);
564 for (
unsigned i = 0; i < hits.size(); i++) {
565 HitIdentifier this_ident(*hits[i]);
568 bool found_snippet =
false;
569 for (
unsigned j = 0; j < hits_org[hits[i]->WireID().Plane].size(); j++) {
570 if (this_ident == hit_idents[hits[i]->WireID().Plane][j]) {
571 found_snippet =
true;
572 if (this_ident > hit_idents[hits[i]->WireID().Plane][j]) {
573 hits_org[hits[i]->WireID().Plane][j].second.push_back(
574 hits_org[hits[i]->WireID().Plane][j].first);
575 hits_org[hits[i]->WireID().Plane][j].first = i;
576 hit_idents[hits[i]->WireID().Plane][j] = this_ident;
579 hits_org[hits[i]->WireID().Plane][j].second.push_back(i);
584 if (!found_snippet) {
585 hits_org[hits[i]->WireID().Plane].push_back({i, {}});
586 hit_idents[hits[i]->WireID().Plane].push_back(this_ident);
589 std::map<art::Ptr<recob::Hit>, std::vector<art::Ptr<recob::Hit>>> ret;
590 for (
auto const& planeHits : hits_org) {
591 for (
const OrganizedHits& hit_org : planeHits) {
592 std::vector<art::Ptr<recob::Hit>> secondaryHits{};
593 for (
const unsigned secondaryID : hit_org.second) {
594 secondaryHits.push_back(hits[secondaryID]);
596 ret[hits[hit_org.first]] = std::move(secondaryHits);
603 art::Event
const& Event,
605 std::string
const& evd_disp_name_append)
const
608 std::cout <<
"Making Debug Event Display" << std::endl;
613 int run = Event.run();
614 int subRun = Event.subRun();
615 int event = Event.event();
616 int PFPID = pfparticle->Self();
619 TString canvasName = Form(
"canvas_%i_%i_%i_%i", run, subRun, event, PFPID);
620 if (evd_disp_name_append.length() > 0) canvasName +=
"_" + evd_disp_name_append;
621 TCanvas* canvas = tfs->make<TCanvas>(canvasName, canvasName);
628 double x_min = std::numeric_limits<double>::max(), x_max = -std::numeric_limits<double>::max();
629 double y_min = std::numeric_limits<double>::max(), y_max = -std::numeric_limits<double>::max();
630 double z_min = std::numeric_limits<double>::max(), z_max = -std::numeric_limits<double>::max();
636 auto const pfpHandle = Event.getValidHandle<std::vector<recob::PFParticle>>(fPFParticleLabel);
639 art::FindManyP<recob::SpacePoint> fmspp(pfpHandle, Event, fPFParticleLabel);
640 if (!fmspp.isValid()) {
641 throw cet::exception(
"LArPandoraShowerAlg") <<
"Trying to get the spacepoint and failed. Somet\
642 hing is not configured correctly. Stopping ";
646 std::vector<art::Ptr<recob::SpacePoint>>
const& spacePoints = fmspp.at(pfparticle.key());
649 if (spacePoints.empty()) {
return; }
652 geo::Point_t showerStartPosition = {-999, -999, -999};
653 geo::Vector_t showerDirection = {-999, -999, -999};
654 std::vector<art::Ptr<recob::SpacePoint>> trackSpacePoints;
659 double startXYZ[3] = {-999, -999, -999};
660 if (!ShowerEleHolder.
CheckElement(fShowerStartPositionInputLabel)) {
661 mf::LogError(
"LArPandoraShowerAlg") <<
"Start position not set, returning " << std::endl;
665 ShowerEleHolder.
GetElement(fShowerStartPositionInputLabel, showerStartPosition);
667 startXYZ[0] = showerStartPosition.X();
668 startXYZ[1] = showerStartPosition.Y();
669 startXYZ[2] = showerStartPosition.Z();
671 auto startPoly = std::make_unique<TPolyMarker3D>(1, startXYZ);
677 double xDirPoints[2] = {-999, -999};
678 double yDirPoints[2] = {-999, -999};
679 double zDirPoints[2] = {-999, -999};
685 auto allPoly = std::make_unique<TPolyMarker3D>(spacePoints.size());
687 if (!ShowerEleHolder.
CheckElement(fShowerDirectionInputLabel) &&
689 mf::LogError(
"LArPandoraShowerAlg") <<
"Direction not set, returning " << std::endl;
694 ShowerEleHolder.
GetElement(fShowerDirectionInputLabel, showerDirection);
697 double minProj = std::numeric_limits<double>::max();
698 double maxProj = -std::numeric_limits<double>::max();
703 for (
auto spacePoint : spacePoints) {
704 auto const pos = spacePoint->position();
708 allPoly->SetPoint(point, x, y, z);
711 x_min = std::min(x, x_min);
712 x_max = std::max(x, x_max);
713 y_min = std::min(y, y_min);
714 y_max = std::max(y, y_max);
715 z_min = std::min(z, z_min);
716 z_max = std::max(z, z_max);
720 spacePoint, showerStartPosition, showerDirection);
721 maxProj = std::max(proj, maxProj);
722 minProj = std::min(proj, minProj);
725 xDirPoints[0] = (showerStartPosition.X() + minProj * showerDirection.X());
726 xDirPoints[1] = (showerStartPosition.X() + maxProj * showerDirection.X());
728 yDirPoints[0] = (showerStartPosition.Y() + minProj * showerDirection.Y());
729 yDirPoints[1] = (showerStartPosition.Y() + maxProj * showerDirection.Y());
731 zDirPoints[0] = (showerStartPosition.Z() + minProj * showerDirection.Z());
732 zDirPoints[1] = (showerStartPosition.Z() + maxProj * showerDirection.Z());
735 auto dirPoly = std::make_unique<TPolyLine3D>(2, xDirPoints, yDirPoints, zDirPoints);
741 auto trackPoly = std::make_unique<TPolyMarker3D>(trackSpacePoints.size());
742 if (!ShowerEleHolder.
CheckElement(fInitialTrackSpacePointsInputLabel)) {
743 mf::LogError(
"LArPandoraShowerAlg") <<
"TrackSpacePoints not set, returning " << std::endl;
747 ShowerEleHolder.
GetElement(fInitialTrackSpacePointsInputLabel, trackSpacePoints);
749 for (
auto spacePoint : trackSpacePoints) {
750 auto const pos = spacePoint->position();
754 trackPoly->SetPoint(point, x, y, z);
756 x_min = std::min(x, x_min);
757 x_max = std::max(x, x_max);
758 y_min = std::min(y, y_min);
759 y_max = std::max(y, y_max);
760 z_min = std::min(z, z_min);
761 z_max = std::max(z, z_max);
771 std::vector<art::Ptr<recob::PFParticle>> pfps;
772 art::fill_ptr_vector(pfps, pfpHandle);
776 int pfpTrackCounter = 0;
777 int pfpShowerCounter = 0;
780 for (
auto const& pfp : pfps) {
781 std::vector<art::Ptr<recob::SpacePoint>>
const& sps = fmspp.at(pfp.key());
783 int pdg = abs(pfp->PdgCode());
784 if (pdg == 11 || pdg == 22) { pfpShowerCounter += sps.size(); }
786 pfpTrackCounter += sps.size();
790 auto pfpPolyTrack = std::make_unique<TPolyMarker3D>(pfpTrackCounter);
791 auto pfpPolyShower = std::make_unique<TPolyMarker3D>(pfpShowerCounter);
795 int showerPoints = 0;
797 for (
auto const& pfp : pfps) {
798 std::vector<art::Ptr<recob::SpacePoint>>
const& sps = fmspp.at(pfp.key());
799 int pdg = abs(pfp->PdgCode());
800 for (
auto const& sp : sps) {
801 auto const pos = sp->position();
805 x_min = std::min(x, x_min);
806 x_max = std::max(x, x_max);
807 y_min = std::min(y, y_min);
808 y_max = std::max(y, y_max);
809 z_min = std::min(z, z_min);
810 z_max = std::max(z, z_max);
813 if (pdg == 11 || pdg == 22) {
814 pfpPolyShower->SetPoint(showerPoints, x, y, z);
818 pfpPolyTrack->SetPoint(trackPoints, x, y, z);
831 auto TrackTrajPoly = std::make_unique<TPolyMarker3D>(TPolyMarker3D(1));
832 auto TrackInitTrajPoly = std::make_unique<TPolyMarker3D>(TPolyMarker3D(1));
834 if (ShowerEleHolder.
CheckElement(fInitialTrackInputLabel)) {
837 recob::Track InitialTrack;
838 ShowerEleHolder.
GetElement(fInitialTrackInputLabel, InitialTrack);
840 if (InitialTrack.NumberTrajectoryPoints() != 0) {
844 for (
unsigned int traj = 0; traj < InitialTrack.NumberTrajectoryPoints(); ++traj) {
847 auto flags = InitialTrack.FlagsAtPoint(traj);
848 if (flags.isSet(recob::TrajectoryPointFlagTraits::NoPoint)) {
continue; }
850 geo::Point_t TrajPositionPoint = InitialTrack.LocationAtPoint(traj);
851 x = TrajPositionPoint.X();
852 y = TrajPositionPoint.Y();
853 z = TrajPositionPoint.Z();
854 TrackTrajPoly->SetPoint(point, x, y, z);
858 geo::Point_t TrajInitPositionPoint = InitialTrack.LocationAtPoint(0);
859 x = TrajInitPositionPoint.X();
860 y = TrajInitPositionPoint.Y();
861 z = TrajInitPositionPoint.Z();
862 TrackInitTrajPoly->SetPoint(TrackInitTrajPoly->GetN(), x, y, z);
866 gStyle->SetOptStat(0);
867 TH3F axes(
"axes",
"", 1, x_min, x_max, 1, y_min, y_max, 1, z_min, z_max);
868 axes.SetDirectory(0);
869 axes.GetXaxis()->SetTitle(
"X");
870 axes.GetYaxis()->SetTitle(
"Y");
871 axes.GetZaxis()->SetTitle(
"Z");
875 pfpPolyShower->SetMarkerStyle(20);
876 pfpPolyShower->SetMarkerColor(4);
877 pfpPolyShower->Draw();
878 pfpPolyTrack->SetMarkerStyle(20);
879 pfpPolyTrack->SetMarkerColor(6);
880 pfpPolyTrack->Draw();
881 allPoly->SetMarkerStyle(20);
883 trackPoly->SetMarkerStyle(20);
884 trackPoly->SetMarkerColor(2);
886 startPoly->SetMarkerStyle(21);
887 startPoly->SetMarkerSize(0.5);
888 startPoly->SetMarkerColor(3);
890 dirPoly->SetLineWidth(1);
891 dirPoly->SetLineColor(6);
893 TrackTrajPoly->SetMarkerStyle(22);
894 TrackTrajPoly->SetMarkerColor(7);
895 TrackTrajPoly->Draw();
896 TrackInitTrajPoly->SetMarkerStyle(22);
897 TrackInitTrajPoly->SetMarkerColor(4);
898 TrackInitTrajPoly->Draw();