18 #include <Eigen/Dense> 45 const art::FindManyP<recob::Hit>& fmh,
46 TVector3& ShowerCentre);
82 InitialiseProduct<art::Assns<recob::Shower, recob::PCAxis>>(
"ShowerPCAxisAssn");
83 InitialiseProduct<art::Assns<recob::PFParticle, recob::PCAxis>>(
"PFParticlePCAxisAssn");
95 const art::FindManyP<recob::SpacePoint>& fmspp =
99 auto const spHandle = Event.getValidHandle<std::vector<recob::SpacePoint>>(
fPFParticleLabel);
101 const art::FindManyP<recob::Hit>& fmh =
105 std::vector<art::Ptr<recob::SpacePoint>> spacePoints_pfp = fmspp.at(pfparticle.
key());
108 if (spacePoints_pfp.size() < 3) {
110 << spacePoints_pfp.size() <<
" spacepoints in shower, not calculating direction" 115 auto const clockData =
121 TVector3 ShowerCentre;
126 TVector3 ShowerCentreErr = {-999, -999, -999};
135 <<
"fUseStartPosition is set but ShowerStartPosition is not set. Bailing" <<
std::endl;
139 TVector3 StartPositionVec = {-999, -999, -999};
143 TVector3 GeneralDir = (ShowerCentre - StartPositionVec).Unit();
146 double DotProduct = PCADirection.Dot(GeneralDir);
149 if (DotProduct < 0) {
150 PCADirection[0] = -PCADirection[0];
151 PCADirection[1] = -PCADirection[1];
152 PCADirection[2] = -PCADirection[2];
156 TVector3 PCADirectionErr = {-999, -999, -999};
163 spacePoints_pfp, ShowerCentre, PCADirection,
fNSegments);
167 if (RMSGradient < -std::numeric_limits<double>::epsilon()) {
168 PCADirection[0] = -PCADirection[0];
169 PCADirection[1] = -PCADirection[1];
170 PCADirection[2] = -PCADirection[2];
174 TVector3 PCADirectionErr = {-999, -999, -999};
185 const art::FindManyP<recob::Hit>& fmh,
186 TVector3& ShowerCentre)
189 float TotalCharge = 0;
190 float sumWeights = 0;
201 clockData, detProp, sps, fmh, TotalCharge);
208 for (
auto& sp : sps) {
215 sp_position = sp_position - ShowerCentre;
229 wht *= std::sqrt(Charge / TotalCharge);
232 xx += sp_position.X() * sp_position.X() * wht;
233 yy += sp_position.Y() * sp_position.Y() * wht;
234 zz += sp_position.Z() * sp_position.Z() * wht;
235 xy += sp_position.X() * sp_position.Y() * wht;
236 xz += sp_position.X() * sp_position.Z() * wht;
237 yz += sp_position.Y() * sp_position.Z() * wht;
242 Eigen::Matrix3f matrix;
245 matrix << xx, xy, xz, xy, yy, yz, xz, yz, zz;
248 matrix /= sumWeights;
251 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigenMatrix(matrix);
253 Eigen::Vector3f eigenValuesVector = eigenMatrix.eigenvalues();
254 Eigen::Matrix3f eigenVectorsMatrix = eigenMatrix.eigenvectors();
257 const bool svdOk =
true;
258 const int nHits = sps.size();
260 const double eigenValues[3] = {
261 eigenValuesVector(2), eigenValuesVector(1), eigenValuesVector(0)};
262 std::vector<std::vector<double>> eigenVectors = {
263 {eigenVectorsMatrix(0, 2), eigenVectorsMatrix(1, 2), eigenVectorsMatrix(2, 2)},
264 {eigenVectorsMatrix(0, 1), eigenVectorsMatrix(1, 1), eigenVectorsMatrix(2, 1)},
265 {eigenVectorsMatrix(0, 0), eigenVectorsMatrix(1, 0), eigenVectorsMatrix(2, 0)}};
266 const double avePos[3] = {ShowerCentre[0], ShowerCentre[1], ShowerCentre[2]};
268 return recob::PCAxis(svdOk, nHits, eigenValues, eigenVectors, avePos);
278 return TVector3(EigenVector[0], EigenVector[1], EigenVector[2]);
298 GetProducedElementPtr<recob::Shower>(
"shower", ShowerEleHolder);
300 AddSingle<art::Assns<recob::Shower, recob::PCAxis>>(showerPtr, pcaPtr,
"ShowerPCAxisAssn");
301 AddSingle<art::Assns<recob::PFParticle, recob::PCAxis>>(pfpPtr, pcaPtr,
"PFParticlePCAxisAssn");
const EigenVectors & getEigenVectors() const
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
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
double SpacePointTime(art::Ptr< recob::SpacePoint > const &sp, art::FindManyP< recob::Hit > const &fmh) const
key_type key() const noexcept
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
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.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
TVector3 ShowerCentre(std::vector< art::Ptr< recob::SpacePoint >> const &showersps) const
2D representation of charge deposited in the TDC/wire plane
auto const & get(AssnsNode< L, R, D > const &r)
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
QTextStream & endl(QTextStream &s)
TVector3 SpacePointPosition(art::Ptr< recob::SpacePoint > const &sp) const