Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
ShowerPandoraSlidingFitTrackFinder_tool.cc
Go to the documentation of this file.
1//#############################################################################
2//### Name: ShowerPandoraSlidingFitTrackFinder ###
3//### Author: Dominic Barker (dominic.barker@sheffield.ac.uk ###
4//### Date: 30.07.19 ###
5//### Description: Tool for finding the initial shower track using the ###
6//### pandora sliding fit calculation. This method is derived ###
7//### from the PandoraTrackCreationModule.cc ###
8//#############################################################################
9
10//Framework Includes
11#include "art/Utilities/ToolMacros.h"
12
13//LArSoft Includes
14#include "lardata/DetectorInfoServices/DetectorClocksService.h"
15#include "lardata/DetectorInfoServices/DetectorPropertiesService.h"
16#include "lardataobj/RecoBase/Hit.h"
17#include "lardataobj/RecoBase/Shower.h"
18#include "lardataobj/RecoBase/SpacePoint.h"
19#include "lardataobj/RecoBase/Track.h"
24
25namespace ShowerRecoTools {
26
28 public:
29 ShowerPandoraSlidingFitTrackFinder(const fhicl::ParameterSet& pset);
30
31 //Generic Track Finder
32 int CalculateElement(const art::Ptr<recob::PFParticle>& pfparticle,
33 art::Event& Event,
34 reco::shower::ShowerElementHolder& ShowerEleHolder) override;
35
36 private:
37 void InitialiseProducers() override;
38
39 //Function to add the assoctions
40 int AddAssociations(const art::Ptr<recob::PFParticle>& pfpPtr,
41 art::Event& Event,
42 reco::shower::ShowerElementHolder& ShowerEleHolder) override;
43
44 // Define standard art tool interface.
45 art::ServiceHandle<geo::Geometry> fGeom;
46
47 //fcl paramaters
49 float fSlidingFitHalfWindow; //To Describe
50 float fMinTrajectoryPoints; //Minimum number of trajectory point to say the track is good.
57 };
58
60 const fhicl::ParameterSet& pset)
61 : IShowerTool(pset.get<fhicl::ParameterSet>("BaseTools"))
62 , fVerbose(pset.get<int>("Verbose"))
63 , fSlidingFitHalfWindow(pset.get<float>("SlidingFitHalfWindow"))
64 , fMinTrajectoryPoints(pset.get<float>("MinTrajectoryPoints"))
65 , fInitialTrackOutputLabel(pset.get<std::string>("InitialTrackOutputLabel"))
66 , fInitialTrackLengthOutputLabel(pset.get<std::string>("InitialTrackLengthOutputLabel"))
67 , fShowerStartPositionInputLabel(pset.get<std::string>("ShowerStartPositionInputLabel"))
68 , fShowerDirectionInputLabel(pset.get<std::string>("ShowerDirectionInputLabel"))
69 , fInitialTrackSpacePointsInputLabel(pset.get<std::string>("InitialTrackSpacePointsInputLabel"))
70 , fInitialTrackHitsInputLabel(pset.get<std::string>("InitialTrackHitsInputLabel"))
71 {}
72
74 {
75
76 InitialiseProduct<std::vector<recob::Track>>(fInitialTrackOutputLabel);
77 InitialiseProduct<art::Assns<recob::Shower, recob::Track>>("ShowerTrackAssn");
78 InitialiseProduct<art::Assns<recob::Track, recob::Hit>>("ShowerTrackHitAssn");
79 }
80
81 //This whole idea is stolen from PandoraTrackCreationModule so credit goes to the Pandora guys.
83 const art::Ptr<recob::PFParticle>& pfparticle,
84 art::Event& Event,
85 reco::shower::ShowerElementHolder& ShowerEleHolder)
86 {
87 //This is all based on the shower vertex being known. If it is not lets not do the track
88 if (!ShowerEleHolder.CheckElement(fShowerStartPositionInputLabel)) {
89 if (fVerbose)
90 mf::LogError("ShowerPandoraSlidingFitTrackFinder")
91 << "Start position not set, returning " << std::endl;
92 return 1;
93 }
94 if (!ShowerEleHolder.CheckElement(fShowerDirectionInputLabel)) {
95 if (fVerbose)
96 mf::LogError("ShowerPandoraSlidingFitTrackFinder")
97 << "Direction not set, returning " << std::endl;
98 return 1;
99 }
100 if (!ShowerEleHolder.CheckElement(fInitialTrackSpacePointsInputLabel)) {
101 if (fVerbose)
102 mf::LogError("ShowerPandoraSlidingFitTrackFinder")
103 << "Initial Spacepoints not set, returning " << std::endl;
104 return 1;
105 }
106
107 geo::Point_t ShowerStartPosition = {-999, -999, -999};
108 ShowerEleHolder.GetElement(fShowerStartPositionInputLabel, ShowerStartPosition);
109
110 geo::Vector_t ShowerDirection = {-999, -999, -999};
111 ShowerEleHolder.GetElement(fShowerDirectionInputLabel, ShowerDirection);
112
113 std::vector<art::Ptr<recob::SpacePoint>> spacepoints;
114 ShowerEleHolder.GetElement(fInitialTrackSpacePointsInputLabel, spacepoints);
115
116 // The track fitter tries to create a traj point from each spacepoint so if we don't have enough
117 // spacepoints we will not get enough traj points, so let's not even try
118 if (spacepoints.size() < fMinTrajectoryPoints) {
119 if (fVerbose)
120 mf::LogWarning("ShowerPandoraSlidingFitTrackFinder")
121 << "Insufficient space points points to build track: " << spacepoints.size();
122 return 1;
123 }
126 // 'wirePitchW` is here used only to provide length scale for binning hits and performing sliding/local linear fits.
127 const float wirePitchW(detType->WirePitchW());
128
129 const pandora::CartesianVector vertexPosition(
130 ShowerStartPosition.X(), ShowerStartPosition.Y(), ShowerStartPosition.Z());
131
132 pandora::CartesianPointVector cartesianPointVector;
133 for (const art::Ptr<recob::SpacePoint> spacePoint : spacepoints)
134 cartesianPointVector.emplace_back(
135 pandora::CartesianVector(spacePoint->XYZ()[0], spacePoint->XYZ()[1], spacePoint->XYZ()[2]));
136
137 lar_content::LArTrackStateVector trackStateVector;
138 pandora::IntVector indexVector;
139 try {
141 vertexPosition,
143 wirePitchW,
144 trackStateVector,
145 &indexVector);
146 }
147 catch (const pandora::StatusCodeException&) {
148 if (fVerbose)
149 mf::LogWarning("ShowerPandoraSlidingFitTrackFinder")
150 << "Unable to extract sliding fit trajectory" << std::endl;
151 return 1;
152 }
153 if (trackStateVector.size() < fMinTrajectoryPoints) {
154 if (fVerbose)
155 mf::LogWarning("ShowerPandoraSlidingFitTrackFinder")
156 << "Insufficient input trajectory points to build track: " << trackStateVector.size();
157 return 1;
158 }
159
160 if (trackStateVector.empty())
161 throw cet::exception("ShowerPandoraSlidingFitTrackFinder")
162 << "BuildTrack - No input trajectory points provided " << std::endl;
163
164 recob::tracking::Positions_t xyz;
165 recob::tracking::Momenta_t pxpypz;
166 recob::TrackTrajectory::Flags_t flags;
167
168 for (const lar_content::LArTrackState& trackState : trackStateVector) {
169 xyz.emplace_back(recob::tracking::Point_t(trackState.GetPosition().GetX(),
170 trackState.GetPosition().GetY(),
171 trackState.GetPosition().GetZ()));
172 pxpypz.emplace_back(recob::tracking::Vector_t(trackState.GetDirection().GetX(),
173 trackState.GetDirection().GetY(),
174 trackState.GetDirection().GetZ()));
175
176 // Set flag NoPoint if point has bogus coordinates, otherwise use clean flag set
177 if (std::fabs(trackState.GetPosition().GetX() - util::kBogusF) <
178 std::numeric_limits<float>::epsilon() &&
179 std::fabs(trackState.GetPosition().GetY() - util::kBogusF) <
180 std::numeric_limits<float>::epsilon() &&
181 std::fabs(trackState.GetPosition().GetZ() - util::kBogusF) <
182 std::numeric_limits<float>::epsilon()) {
183 flags.emplace_back(recob::TrajectoryPointFlags(recob::TrajectoryPointFlags::InvalidHitIndex,
184 recob::TrajectoryPointFlagTraits::NoPoint));
185 }
186 else {
187 flags.emplace_back(recob::TrajectoryPointFlags());
188 }
189 }
190
191 // note from gc: eventually we should produce a TrackTrajectory, not a Track with empty covariance matrix and bogus chi2, etc.
192 recob::Track InitialTrack = recob::Track(
193 recob::TrackTrajectory(std::move(xyz), std::move(pxpypz), std::move(flags), false),
194 util::kBogusI,
195 util::kBogusF,
196 util::kBogusI,
197 recob::tracking::SMatrixSym55(),
198 recob::tracking::SMatrixSym55(),
199 pfparticle.key());
200
201 ShowerEleHolder.SetElement(InitialTrack, fInitialTrackOutputLabel);
202
203 float tracklength = (InitialTrack.Start() - InitialTrack.End()).R();
204
205 ShowerEleHolder.SetElement(tracklength, fInitialTrackLengthOutputLabel);
206
207 return 0;
208 }
209
211 const art::Ptr<recob::PFParticle>& pfpPtr,
212 art::Event& Event,
213 reco::shower::ShowerElementHolder& ShowerEleHolder)
214 {
215
216 //Check the track has been set
217 if (!ShowerEleHolder.CheckElement(fInitialTrackOutputLabel)) {
218 if (fVerbose)
219 mf::LogError("ShowerPandoraSlidingFitTrackFinderAddAssn")
220 << "Track not set so the assocation can not be made " << std::endl;
221 return 1;
222 }
223
224 //Get the size of the ptr as it is.
225 int trackptrsize = GetVectorPtrSize(fInitialTrackOutputLabel);
226
227 const art::Ptr<recob::Track> trackptr = GetProducedElementPtr<recob::Track>(
228 fInitialTrackOutputLabel, ShowerEleHolder, trackptrsize - 1);
229 const art::Ptr<recob::Shower> showerptr =
230 GetProducedElementPtr<recob::Shower>("shower", ShowerEleHolder);
231
232 AddSingle<art::Assns<recob::Shower, recob::Track>>(showerptr, trackptr, "ShowerTrackAssn");
233
234 std::vector<art::Ptr<recob::Hit>> TrackHits;
235 ShowerEleHolder.GetElement(fInitialTrackHitsInputLabel, TrackHits);
236
237 for (auto const& TrackHit : TrackHits) {
238 AddSingle<art::Assns<recob::Track, recob::Hit>>(trackptr, TrackHit, "ShowerTrackHitAssn");
239 }
240
241 return 0;
242 }
243
244}
245
Helper functions for extracting detector geometry for use in reconsruction.
Header file for the pfo helper class.
int GetVectorPtrSize(std::string Name)
int AddAssociations(const art::Ptr< recob::PFParticle > &pfpPtr, art::Event &Event, reco::shower::ShowerElementHolder &ShowerEleHolder) override
int CalculateElement(const art::Ptr< recob::PFParticle > &pfparticle, art::Event &Event, reco::shower::ShowerElementHolder &ShowerEleHolder) override
static void GetSlidingFitTrajectory(const pandora::CartesianPointVector &pointVector, const pandora::CartesianVector &vertexPosition, const unsigned int layerWindow, const float layerPitch, LArTrackStateVector &trackStateVector, pandora::IntVector *const pIndexVector=nullptr)
Apply 3D sliding fit to a set of 3D points and return track trajectory.
LArTrackState class.
Empty interface to map pandora to specifics in the LArSoft geometry.
virtual float WirePitchW() const =0
The wire pitch of the mapped W view.
CartesianVector class.
StatusCodeException class.
int GetElement(const std::string &Name, T &Element) const
void SetElement(T &dataproduct, const std::string &Name, bool checktag=false)
bool CheckElement(const std::string &Name) const
std::vector< LArTrackState > LArTrackStateVector
LArPandoraDetectorType * GetDetectorType()
Factory class that returns the correct detector type interface.
std::vector< int > IntVector
std::vector< CartesianVector > CartesianPointVector