All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ShowerTrackPCADirection_tool.cc
Go to the documentation of this file.
1 //############################################################################
2 //### Name: ShowerTrackPCADirection ###
3 //### Author: Dominic Barker ###
4 //### Date: 13.05.19 ###
5 //### Description: Tool for finding the shower direction using PCA ###
6 //### methods using the initial track hits ###
7 //############################################################################
8 
9 //Framework Includes
10 #include "art/Utilities/ToolMacros.h"
11 
12 //LArSoft Includes
19 
20 //Root Includes
21 #include "TPrincipal.h"
22 
23 namespace ShowerRecoTools {
24 
26 
27  public:
28  ShowerTrackPCADirection(const fhicl::ParameterSet& pset);
29 
30  //Generic Direction Finder
31  int CalculateElement(const art::Ptr<recob::PFParticle>& pfparticle,
32  art::Event& Event,
33  reco::shower::ShowerElementHolder& ShowerEleHolder) override;
34 
35  private:
36  TVector3 ShowerPCAVector(const detinfo::DetectorClocksData& clockData,
38  std::vector<art::Ptr<recob::SpacePoint>>& spacePoints_pfp,
39  const art::FindManyP<recob::Hit>& fmh,
40  TVector3& ShowerCentre);
41 
42  //fcl
43  art::InputTag fPFParticleLabel;
44  art::InputTag fHitModuleLabel;
45  int fVerbose;
46  bool fChargeWeighted; //Should we charge weight the PCA.
47  unsigned int fMinPCAPoints; //Number of spacepoints needed to do the analysis.
48 
52  };
53 
54  ShowerTrackPCADirection::ShowerTrackPCADirection(const fhicl::ParameterSet& pset)
55  : IShowerTool(pset.get<fhicl::ParameterSet>("BaseTools"))
56  , fPFParticleLabel(pset.get<art::InputTag>("PFParticleLabel"))
57  , fHitModuleLabel(pset.get<art::InputTag>("HitModuleLabel"))
58  , fVerbose(pset.get<int>("Verbose"))
59  , fChargeWeighted(pset.get<bool>("ChargeWeighted"))
60  , fMinPCAPoints(pset.get<unsigned int>("MinPCAPoints"))
61  , fShowerStartPositionInputLabel(pset.get<std::string>("ShowerStartPositionInputLabel"))
62  , fInitialTrackSpacePointsInputLabel(pset.get<std::string>("InitialTrackSpacePointsInputLabel"))
63  , fShowerDirectionOutputLabel(pset.get<std::string>("ShowerDirectionOutputLabel"))
64  {}
65 
66  int
67  ShowerTrackPCADirection::CalculateElement(const art::Ptr<recob::PFParticle>& pfparticle,
68  art::Event& Event,
69  reco::shower::ShowerElementHolder& ShowerEleHolder)
70  {
71 
72  if (!ShowerEleHolder.CheckElement(fShowerStartPositionInputLabel)) {
73  if (fVerbose)
74  mf::LogError("ShowerTrackPCA") << "Start Position not set. Stopping" << std::endl;
75  ;
76  return 1;
77  }
78  if (!ShowerEleHolder.CheckElement(fInitialTrackSpacePointsInputLabel)) {
79  if (fVerbose)
80  mf::LogError("ShowerTrackPCA") << "TrackSpacePoints not set, returning " << std::endl;
81  return 1;
82  }
83 
84  //Get the spacepoints handle and the hit assoication
85  auto const spHandle = Event.getValidHandle<std::vector<recob::SpacePoint>>(fPFParticleLabel);
86 
87  const art::FindManyP<recob::Hit>& fmh =
88  ShowerEleHolder.GetFindManyP<recob::Hit>(spHandle, Event, fPFParticleLabel);
89 
90  std::vector<art::Ptr<recob::SpacePoint>> trackSpacePoints;
91  ShowerEleHolder.GetElement(fInitialTrackSpacePointsInputLabel, trackSpacePoints);
92 
93  //We cannot progress with no spacepoints.
94  if (trackSpacePoints.size() < fMinPCAPoints) {
95  if (fVerbose)
96  mf::LogError("ShowerTrackPCA") << "Not enough spacepoints for PCA, returning " << std::endl;
97  return 1;
98  }
99 
100  auto const clockData =
101  art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(Event);
102  auto const detProp =
103  art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(Event, clockData);
104 
105  //Find the PCA vector
106  TVector3 trackCentre;
107  TVector3 Eigenvector = ShowerPCAVector(clockData, detProp, trackSpacePoints, fmh, trackCentre);
108 
109  //Get the General direction as the vector between the start position and the centre
110  TVector3 StartPositionVec = {-999, -999, -999};
111  ShowerEleHolder.GetElement(fShowerStartPositionInputLabel, StartPositionVec);
112  TVector3 GeneralDir = (trackCentre - StartPositionVec).Unit();
113 
114  //Dot product
115  double DotProduct = Eigenvector.Dot(GeneralDir);
116 
117  //If the dotproduct is negative the Direction needs Flipping
118  if (DotProduct < 0) {
119  Eigenvector[0] = -Eigenvector[0];
120  Eigenvector[1] = -Eigenvector[1];
121  Eigenvector[2] = -Eigenvector[2];
122  }
123 
124  TVector3 EigenvectorErr = {-999, -999, -999};
125 
126  ShowerEleHolder.SetElement(Eigenvector, EigenvectorErr, fShowerDirectionOutputLabel);
127 
128  return 0;
129  }
130 
131  //Function to calculate the shower direction using a charge weight 3D PCA calculation.
132  TVector3
135  std::vector<art::Ptr<recob::SpacePoint>>& sps,
136  const art::FindManyP<recob::Hit>& fmh,
137  TVector3& ShowerCentre)
138  {
139 
140  //Initialise the the PCA.
141  TPrincipal* pca = new TPrincipal(3, "");
142 
143  float TotalCharge = 0;
144 
145  //Get the Shower Centre
146  ShowerCentre =
147  IShowerTool::GetLArPandoraShowerAlg().ShowerCentre(clockData, detProp, sps, fmh, TotalCharge);
148 
149  //Normalise the spacepoints, charge weight and add to the PCA.
150  for (auto& sp : sps) {
151 
152  TVector3 sp_position = IShowerTool::GetLArPandoraShowerAlg().SpacePointPosition(sp);
153 
154  float wht = 1;
155 
156  //Normalise the spacepoint position.
157  sp_position = sp_position - ShowerCentre;
158 
159  if (fChargeWeighted) {
160 
161  //Get the charge.
162  float Charge = IShowerTool::GetLArPandoraShowerAlg().SpacePointCharge(sp, fmh);
163 
164  //Get the time of the spacepoint
165  float Time = IShowerTool::GetLArPandoraShowerAlg().SpacePointTime(sp, fmh);
166 
167  //Correct for the lifetime at the moment.
168  Charge *= std::exp((sampling_rate(clockData) * Time) / (detProp.ElectronLifetime() * 1e3));
169 
170  //Charge Weight
171  wht *= std::sqrt(Charge / TotalCharge);
172  }
173 
174  double sp_coord[3];
175  sp_coord[0] = sp_position.X() * wht;
176  sp_coord[1] = sp_position.Y() * wht;
177  sp_coord[2] = sp_position.Z() * wht;
178 
179  //Add to the PCA
180  pca->AddRow(sp_coord);
181  }
182 
183  //Evaluate the PCA
184  pca->MakePrincipals();
185 
186  //Get the Eigenvectors.
187  const TMatrixD* Eigenvectors = pca->GetEigenVectors();
188 
189  TVector3 Eigenvector = {(*Eigenvectors)[0][0], (*Eigenvectors)[1][0], (*Eigenvectors)[2][0]};
190 
191  delete pca;
192 
193  return Eigenvector;
194  }
195 }
196 
197 DEFINE_ART_CLASS_TOOL(ShowerRecoTools::ShowerTrackPCADirection)
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
Definition: UtilFunc.cxx:42
ShowerTrackPCADirection(const fhicl::ParameterSet &pset)
Declaration of signal hit object.
void SetElement(T &dataproduct, const std::string &Name, bool checktag=false)
static constexpr bool
const art::FindManyP< T1 > & GetFindManyP(const art::ValidHandle< std::vector< T2 > > &handle, const art::Event &evt, const art::InputTag &moduleTag)
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.
Definition: DumpUtils.h:265
bool CheckElement(const std::string &Name) const
int GetElement(const std::string &Name, T &Element) const
const shower::LArPandoraShowerAlg & GetLArPandoraShowerAlg() const
Definition: IShowerTool.h:88
double SpacePointCharge(art::Ptr< recob::SpacePoint > const &sp, art::FindManyP< recob::Hit > const &fmh) const
Contains all timing reference information for the detector.
TVector3 ShowerCentre(std::vector< art::Ptr< recob::SpacePoint >> const &showersps) const
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
int CalculateElement(const art::Ptr< recob::PFParticle > &pfparticle, art::Event &Event, reco::shower::ShowerElementHolder &ShowerEleHolder) override
TVector3 ShowerPCAVector(const detinfo::DetectorClocksData &clockData, const detinfo::DetectorPropertiesData &detProp, std::vector< art::Ptr< recob::SpacePoint >> &spacePoints_pfp, const art::FindManyP< recob::Hit > &fmh, TVector3 &ShowerCentre)
auto const detProp
TVector3 SpacePointPosition(art::Ptr< recob::SpacePoint > const &sp) const