10 #include "art/Utilities/ToolMacros.h"
24 #include <Eigen/Dense>
26 namespace ShowerRecoTools {
50 const std::vector<art::Ptr<recob::SpacePoint>>& spacePoints_pfp,
51 const art::FindManyP<recob::Hit>& fmh,
52 TVector3& ShowerCentre);
73 , fPFParticleLabel(pset.
get<art::InputTag>(
"PFParticleLabel"))
74 , fVerbose(pset.
get<int>(
"Verbose"))
75 , fNSegments(pset.
get<unsigned int>(
"NSegments"))
76 , fUseStartPosition(pset.
get<
bool>(
"UseStartPosition"))
77 , fChargeWeighted(pset.
get<
bool>(
"ChargeWeighted"))
78 , fShowerStartPositionInputLabel(pset.
get<
std::string>(
"ShowerStartPositionInputLabel"))
79 , fShowerDirectionOutputLabel(pset.
get<
std::string>(
"ShowerDirectionOutputLabel"))
80 , fShowerCentreOutputLabel(pset.
get<
std::string>(
"ShowerCentreOutputLabel"))
81 , fShowerPCAOutputLabel(pset.
get<
std::string>(
"ShowerPCAOutputLabel"))
88 InitialiseProduct<art::Assns<recob::Shower, recob::PCAxis>>(
"ShowerPCAxisAssn");
89 InitialiseProduct<art::Assns<recob::PFParticle, recob::PCAxis>>(
"PFParticlePCAxisAssn");
99 auto const pfpHandle = Event.getValidHandle<std::vector<recob::PFParticle>>(
fPFParticleLabel);
101 const art::FindManyP<recob::SpacePoint>& fmspp =
105 auto const spHandle = Event.getValidHandle<std::vector<recob::SpacePoint>>(
fPFParticleLabel);
107 const art::FindManyP<recob::Hit>& fmh =
111 std::vector<art::Ptr<recob::SpacePoint>> spacePoints_pfp = fmspp.at(pfparticle.key());
114 if (spacePoints_pfp.size() < 3) {
115 mf::LogWarning(
"ShowerPCADirection")
116 << spacePoints_pfp.size() <<
" spacepoints in shower, not calculating direction"
121 auto const clockData =
122 art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(Event);
124 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(Event, clockData);
127 TVector3 ShowerCentre;
132 TVector3 ShowerCentreErr = {-999, -999, -999};
140 mf::LogError(
"ShowerPCADirection")
141 <<
"fUseStartPosition is set but ShowerStartPosition is not set. Bailing" << std::endl;
145 TVector3 StartPositionVec = {-999, -999, -999};
149 TVector3 GeneralDir = (ShowerCentre - StartPositionVec).Unit();
152 double DotProduct = PCADirection.Dot(GeneralDir);
155 if (DotProduct < 0) {
156 PCADirection[0] = -PCADirection[0];
157 PCADirection[1] = -PCADirection[1];
158 PCADirection[2] = -PCADirection[2];
162 TVector3 PCADirectionErr = {-999, -999, -999};
169 spacePoints_pfp, ShowerCentre, PCADirection,
fNSegments);
173 if (RMSGradient < -std::numeric_limits<double>::epsilon()) {
174 PCADirection[0] = -PCADirection[0];
175 PCADirection[1] = -PCADirection[1];
176 PCADirection[2] = -PCADirection[2];
180 TVector3 PCADirectionErr = {-999, -999, -999};
190 const std::vector<art::Ptr<recob::SpacePoint>>& sps,
191 const art::FindManyP<recob::Hit>& fmh,
192 TVector3& ShowerCentre)
195 float TotalCharge = 0;
196 float sumWeights = 0;
207 clockData, detProp, sps, fmh, TotalCharge);
214 for (
auto& sp : sps) {
221 sp_position = sp_position - ShowerCentre;
235 wht *= std::sqrt(Charge / TotalCharge);
238 xx += sp_position.X() * sp_position.X() * wht;
239 yy += sp_position.Y() * sp_position.Y() * wht;
240 zz += sp_position.Z() * sp_position.Z() * wht;
241 xy += sp_position.X() * sp_position.Y() * wht;
242 xz += sp_position.X() * sp_position.Z() * wht;
243 yz += sp_position.Y() * sp_position.Z() * wht;
248 Eigen::Matrix3f matrix;
251 matrix << xx, xy, xz, xy, yy, yz, xz, yz, zz;
254 matrix /= sumWeights;
257 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigenMatrix(matrix);
259 Eigen::Vector3f eigenValuesVector = eigenMatrix.eigenvalues();
260 Eigen::Matrix3f eigenVectorsMatrix = eigenMatrix.eigenvectors();
263 const bool svdOk =
true;
264 const int nHits = sps.size();
266 const double eigenValues[3] = {
267 eigenValuesVector(2), eigenValuesVector(1), eigenValuesVector(0)};
268 std::vector<std::vector<double>> eigenVectors = {
269 {eigenVectorsMatrix(0, 2), eigenVectorsMatrix(1, 2), eigenVectorsMatrix(2, 2)},
270 {eigenVectorsMatrix(0, 1), eigenVectorsMatrix(1, 1), eigenVectorsMatrix(2, 1)},
271 {eigenVectorsMatrix(0, 0), eigenVectorsMatrix(1, 0), eigenVectorsMatrix(2, 0)}};
272 const double avePos[3] = {ShowerCentre[0], ShowerCentre[1], ShowerCentre[2]};
274 return recob::PCAxis(svdOk, nHits, eigenValues, eigenVectors, avePos);
284 return TVector3(EigenVector[0], EigenVector[1], EigenVector[2]);
295 if (
fVerbose) mf::LogError(
"ShowerPCADirection: Add Assns") <<
"PCA not set." << std::endl;
301 const art::Ptr<recob::PCAxis> pcaPtr =
303 const art::Ptr<recob::Shower> showerPtr =
304 GetProducedElementPtr<recob::Shower>(
"shower", ShowerEleHolder);
306 AddSingle<art::Assns<recob::Shower, recob::PCAxis>>(showerPtr, pcaPtr,
"ShowerPCAxisAssn");
307 AddSingle<art::Assns<recob::PFParticle, recob::PCAxis>>(pfpPtr, pcaPtr,
"PFParticlePCAxisAssn");
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
const EigenVectors & getEigenVectors() const
Declaration of signal hit object.
void SetElement(T &dataproduct, const std::string &Name, bool checktag=false)
double ElectronLifetime() const
const art::FindManyP< T1 > & GetFindManyP(const art::ValidHandle< std::vector< T2 > > &handle, const art::Event &evt, const art::InputTag &moduleTag)
double RMSShowerGradient(std::vector< art::Ptr< recob::SpacePoint >> &sps, const TVector3 &ShowerCentre, const TVector3 &Direction, const unsigned int nSegments) const
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.
bool CheckElement(const std::string &Name) const
int GetElement(const std::string &Name, T &Element) const
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
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
TVector3 SpacePointPosition(art::Ptr< recob::SpacePoint > const &sp) const