18 #include "TPolyLine3D.h" 19 #include "TPolyMarker3D.h" 26 : fUseCollectionOnly(pset.
get<bool>(
"UseCollectionOnly"))
27 , fPFParticleLabel(pset.
get<
art::InputTag>(
"PFParticleLabel"))
28 , fSCEXFlip(pset.
get<bool>(
"SCEXFlip"))
30 , fInitialTrackInputLabel(pset.
get<
std::string>(
"InitialTrackInputLabel"))
31 , fShowerStartPositionInputLabel(pset.
get<
std::string>(
"ShowerStartPositionInputLabel"))
32 , fShowerDirectionInputLabel(pset.
get<
std::string>(
"ShowerDirectionInputLabel"))
33 , fInitialTrackSpacePointsInputLabel(pset.
get<
std::string>(
"InitialTrackSpacePointsInputLabel"))
45 std::map<double, art::Ptr<recob::Hit>> OrderedHits;
57 TVector2 Shower2DStartPosition = {
59 ShowerStartPosition.X()};
65 TVector2 Shower2DDirection = {ShowerDirection.Dot(PlaneDirection), ShowerDirection.X()};
67 Shower2DDirection = Shower2DDirection.Unit();
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; });
97 TVector2 frontpos = fronthitcoord - Shower2DStartPosition;
101 TVector2 backpos = backhitcoord - Shower2DStartPosition;
103 double frontproj = frontpos * Shower2DDirection;
104 double backproj = backpos * Shower2DDirection;
106 std::reverse(showerHits.begin(), showerHits.end());
121 std::map<double, art::Ptr<recob::SpacePoint>> OrderedSpacePoints;
124 for (
auto const& sp : showersps) {
130 OrderedSpacePoints[perp] = sp;
135 for (
auto const& sp : OrderedSpacePoints) {
136 showersps.push_back(sp.second);
148 std::map<double, art::Ptr<recob::SpacePoint>> OrderedSpacePoints;
151 for (
auto const& sp : showersps) {
157 OrderedSpacePoints[len] = sp;
162 for (
auto const& sp : OrderedSpacePoints) {
163 showersps.push_back(sp.second);
171 std::map<double, art::Ptr<recob::SpacePoint>> OrderedSpacePoints;
174 for (
auto const& sp : showersps) {
177 double mag = (sp->position() - vertex).R();
180 OrderedSpacePoints[mag] = sp;
185 for (
auto const& sp : OrderedSpacePoints) {
186 showersps.push_back(sp.second);
193 if (showersps.empty())
return {};
198 for (
auto const& sp : showersps) {
199 auto const pos = sp->position();
205 centre_position *= (1. / showersps.size());
206 return centre_position;
215 float totalCharge = 0;
217 clockData, detProp, showerspcs, fmh, totalCharge);
226 float& totalCharge)
const 231 for (
auto const& sp : showersps) {
234 std::vector<art::Ptr<recob::Hit>>
const&
hits = fmh.at(sp.key());
239 for (
auto const&
hit : hits) {
243 charge =
hit->Integral();
263 float mean = charge / ((float)hits.size());
267 if (hits.size() > 1) {
268 rms = std::sqrt((charge2 - charge * charge) / ((
float)(hits.size() - 1)));
273 for (
auto const&
hit : hits) {
274 double lifetimecorrection = std::exp((
sampling_rate(clockData) *
hit->PeakTime()) /
276 if (
hit->Integral() * lifetimecorrection > (mean - 2 * rms) &&
277 hit->Integral() * lifetimecorrection < (mean + 2 * rms)) {
278 charge +=
hit->Integral() * lifetimecorrection;
284 mf::LogWarning(
"LArPandoraShowerAlg") <<
"no points used to make the charge value. \n";
291 auto const pos = sp->position();
292 double const x = pos.X();
293 double const y = pos.Y();
294 double const z = pos.Z();
297 chargePoint.X() + charge *
x, chargePoint.Y() + charge *
y, chargePoint.Z() + charge *
z);
298 totalCharge += charge;
301 mf::LogWarning(
"LArPandoraShowerAlg") <<
"Averaged charge, within 2 sigma, for a spacepoint " 302 "is zero, Maybe this not a good method. \n";
306 double intotalcharge = 1 / totalCharge;
307 return chargePoint * intotalcharge;
324 std::vector<art::Ptr<recob::Hit>>
const&
hits = fmh.at(sp.
key());
325 for (
auto const&
hit : hits) {
326 Charge +=
hit->Integral();
329 Charge /= (float)hits.size();
341 std::vector<art::Ptr<recob::Hit>>
const&
hits = fmh.at(sp.
key());
342 for (
auto const&
hit : hits) {
343 Time +=
hit->PeakTime();
346 Time /= (float)hits.size();
368 auto const pos = sp->
position() - vertex;
371 return pos.Dot(direction);
393 pos = pos - proj * direction;
403 const unsigned int nSegments)
const 407 <<
"Unable to calculate RMS Shower Gradient with 0 segments" << std::endl;
409 if (sps.size() < 3)
return 0;
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) {
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;
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;
470 if (perps.size() < 2)
return std::numeric_limits<double>::lowest();
473 for (
const auto& perp : perps) {
477 return std::sqrt(sum / (perps.size() - 1));
483 unsigned int const& TPC)
const 488 <<
"Trying to correct SCE pitch when service is not configured" << std::endl;
502 geo::Vector_t pitchVec{pitch * dir.X() + xFlip * (nextPosOffset.X() - posOffset.X()),
503 pitch * dir.Y() + (nextPosOffset.Y() - posOffset.Y()),
504 pitch * dir.Z() + (nextPosOffset.Z() - posOffset.Z())};
516 <<
"Trying to correct SCE EField when service is not configured" << std::endl;
523 EFieldOffsets *= EField;
525 return EFieldOffsets.r();
528 std::map<art::Ptr<recob::Hit>, std::vector<art::Ptr<recob::Hit>>>
536 typedef std::pair<unsigned, std::vector<unsigned>> OrganizedHits;
537 struct HitIdentifier {
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(
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);
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();
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; }
654 std::vector<art::Ptr<recob::SpacePoint>> trackSpacePoints;
659 double startXYZ[3] = {-999, -999, -999};
661 mf::LogError(
"LArPandoraShowerAlg") <<
"Start position not set, returning " << std::endl;
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());
689 mf::LogError(
"LArPandoraShowerAlg") <<
"Direction not set, returning " << std::endl;
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);
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());
743 mf::LogError(
"LArPandoraShowerAlg") <<
"TrackSpacePoints not set, returning " << std::endl;
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);
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;
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);
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));
851 x = TrajPositionPoint.X();
852 y = TrajPositionPoint.Y();
853 z = TrajPositionPoint.Z();
854 TrackTrajPoly->SetPoint(point, x, y, z);
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();
virtual bool EnableSimEfieldSCE() const =0
SubRunNumber_t subRun() const
double SCECorrectPitch(double const &pitch, geo::Point_t const &pos, geo::Vector_t const &dir, unsigned int const &TPC) const
Length_t WireCoordinate(Point_t const &pos, PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
double DistanceBetweenSpacePoints(art::Ptr< recob::SpacePoint > const &sp_a, art::Ptr< recob::SpacePoint > const &sp_b) const
void OrderShowerSpacePointsPerpendicular(std::vector< art::Ptr< recob::SpacePoint >> &showersps, geo::Point_t const &vertex, geo::Vector_t const &direction) const
Utilities related to art service access.
size_t Self() const
Returns the index of this particle.
void DebugEVD(art::Ptr< recob::PFParticle > const &pfparticle, art::Event const &Event, const reco::shower::ShowerElementHolder &ShowerEleHolder, std::string const &evd_disp_name_append="") const
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
static constexpr Flag_t NoPoint
The trajectory point is not defined.
double CalculateRMS(const std::vector< float > &perps) const
constexpr bool operator>(Interval< Q, Cat > const a, Quantity< Args... > const b) noexcept
T::provider_type const * providerFrom()
Returns a constant pointer to the provider of specified service.
virtual geo::Vector_t GetCalPosOffsets(geo::Point_t const &point, int const &TPCid) const =0
art::InputTag fPFParticleLabel
art::ServiceHandle< geo::Geometry const > fGeom
Declaration of signal hit object.
Point_t const & LocationAtPoint(size_t i) const
Access to track position at different points.
The data type to uniquely identify a Plane.
geo::Point_t position() const
Returns the position of the point in world coordinates [cm].
const std::string fInitialTrackInputLabel
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
constexpr auto abs(T v)
Returns the absolute value of the argument.
double ElectronLifetime() const
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
WireID_t Wire
Index of the wire within its plane.
geo::WireID const & WireID() const
Initial tdc tick for hit.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
double SpacePointTime(art::Ptr< recob::SpacePoint > const &sp, art::FindManyP< recob::Hit > const &fmh) const
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
PlaneGeo const & Plane(PlaneID const &planeid) const
Returns the specified wire.
LArPandoraShowerAlg(const fhicl::ParameterSet &pset)
double SpacePointPerpendicular(art::Ptr< recob::SpacePoint > const &sp, geo::Point_t const &vertex, geo::Vector_t const &direction) const
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
virtual geo::Vector_t GetPosOffsets(geo::Point_t const &point) const =0
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
const std::string fInitialTrackSpacePointsInputLabel
key_type key() const noexcept
std::map< art::Ptr< recob::Hit >, std::vector< art::Ptr< recob::Hit > > > OrganizeHits(const std::vector< art::Ptr< recob::Hit >> &hits) const
bool CheckElement(const std::string &Name) const
Provides recob::Track data product.
const std::string fShowerDirectionInputLabel
constexpr PlaneID const & asPlaneID() const
Conversion to PlaneID (for convenience of notation).
EventNumber_t event() const
int GetElement(const std::string &Name, T &Element) const
raw::TDCtick_t StartTick() const
Initial tdc tick for hit.
void OrderShowerHits(detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> &hits, geo::Point_t const &ShowerPosition, geo::Vector_t const &ShowerDirection) const
double SpacePointProjection(art::Ptr< recob::SpacePoint > const &sp, geo::Point_t const &vertex, geo::Vector_t const &direction) const
const std::string fShowerStartPositionInputLabel
Detector simulation of raw signals on wires.
double ConvertTicksToX(double ticks, int p, int t, int c) const
raw::TDCtick_t EndTick() const
Final tdc tick for hit.
double SpacePointCharge(art::Ptr< recob::SpacePoint > const &sp, art::FindManyP< recob::Hit > const &fmh) const
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
art::ServiceHandle< art::TFileService > tfs
virtual geo::Vector_t GetEfieldOffsets(geo::Point_t const &point) const =0
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
float PeakTime() const
Time of the signal peak, in tick units.
virtual bool EnableCalSpatialSCE() const =0
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
decltype(auto) get(T &&obj)
ADL-aware version of std::to_string.
LArSoft-specific namespace.
Contains all timing reference information for the detector.
geo::Point_t ShowerCentre(std::vector< art::Ptr< recob::SpacePoint >> const &showersps) const
TVector2 HitCoordinates(detinfo::DetectorPropertiesData const &detProp, art::Ptr< recob::Hit > const &hit) const
void OrderShowerSpacePoints(std::vector< art::Ptr< recob::SpacePoint >> &showersps, geo::Point_t const &vertex, geo::Vector_t const &direction) const
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
Vector_t const & GetIncreasingWireDirection() const
Returns the direction of increasing wires.
PointFlags_t const & FlagsAtPoint(size_t i) const
Access to i-th TrajectoryPoint or its Flags.
double RMSShowerGradient(std::vector< art::Ptr< recob::SpacePoint >> &sps, const geo::Point_t &ShowerCentre, const geo::Vector_t &Direction, const unsigned int nSegments) const
double SCECorrectEField(double const &EField, geo::Point_t const &pos) const
2D representation of charge deposited in the TDC/wire plane
constexpr PlaneID const & planeID() const
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
recob::tracking::Plane Plane
spacecharge::SpaceCharge const * fSCE
bool operator==(infinite_endcount_iterator< T > const &, count_iterator< T > const &)
Length_t WirePitch(PlaneID const &planeid=plane_zero) const
Returns the distance between two consecutive wires.
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
cet::coded_exception< error, detail::translate > exception
Event finding and building.
Signal from collection planes.