42 if (pointVector.empty())
44 std::cout <<
"LArPcaHelper::RunPca - no three dimensional hits provided" << std::endl;
48 double meanPosition[3] = {0., 0., 0.};
54 const double weight(weightedPoint.second);
58 std::cout <<
"LArPcaHelper::RunPca - negative weight found" << std::endl;
62 meanPosition[0] +=
static_cast<double>(point.
GetX()) * weight;
63 meanPosition[1] +=
static_cast<double>(point.
GetY()) * weight;
64 meanPosition[2] +=
static_cast<double>(point.
GetZ()) * weight;
68 if (std::fabs(sumWeight) < std::numeric_limits<double>::epsilon())
70 std::cout <<
"LArPcaHelper::RunPca - sum of weights is zero" << std::endl;
74 meanPosition[0] /= sumWeight;
75 meanPosition[1] /= sumWeight;
76 meanPosition[2] /= sumWeight;
77 centroid =
CartesianVector(meanPosition[0], meanPosition[1], meanPosition[2]);
90 const double weight(weightedPoint.second);
91 const double x(
static_cast<double>((point.
GetX()) - meanPosition[0]));
92 const double y(
static_cast<double>((point.
GetY()) - meanPosition[1]));
93 const double z(
static_cast<double>((point.
GetZ()) - meanPosition[2]));
95 xi2 += x * x * weight;
96 xiyi += x * y * weight;
97 xizi += x * z * weight;
98 yi2 += y * y * weight;
99 yizi += y * z * weight;
100 zi2 += z * z * weight;
106 sig << xi2, xiyi, xizi, xiyi, yi2, yizi, xizi, yizi, zi2;
108 sig *= 1. / sumWeight;
110 Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> eigenMat(sig);
112 if (eigenMat.info() != Eigen::ComputationInfo::Success)
114 std::cout <<
"LArPcaHelper::RunPca - decomposition failure, nThreeDHits = " << pointVector.size() << std::endl;
118 typedef std::pair<float, size_t> EigenValColPair;
119 typedef std::vector<EigenValColPair> EigenValColVector;
121 EigenValColVector eigenValColVector;
122 const auto &resultEigenMat(eigenMat.eigenvalues());
123 eigenValColVector.emplace_back(resultEigenMat(0), 0);
124 eigenValColVector.emplace_back(resultEigenMat(1), 1);
125 eigenValColVector.emplace_back(resultEigenMat(2), 2);
127 std::sort(eigenValColVector.begin(), eigenValColVector.end(),
128 [](
const EigenValColPair &left,
const EigenValColPair &right) { return left.first > right.first; });
131 outputEigenValues =
CartesianVector(eigenValColVector.at(0).first, eigenValColVector.at(1).first, eigenValColVector.at(2).first);
134 const Eigen::Matrix3f &eigenVecs(eigenMat.eigenvectors());
136 for (
const EigenValColPair &pair : eigenValColVector)
137 outputEigenVectors.emplace_back(eigenVecs(0, pair.second), eigenVecs(1, pair.second), eigenVecs(2, pair.second));
static pandora::CartesianVector GetPosition(const T &t)
Get the associated position.
std::vector< WeightedPoint > WeightedPointVector
std::vector< pandora::CartesianVector > EigenVectors
std::pair< const pandora::CartesianVector, double > WeightedPoint
static void RunPca(const T &t, pandora::CartesianVector ¢roid, EigenValues &outputEigenValues, EigenVectors &outputEigenVectors)
Run principal component analysis using input calo hits (TPC_VIEW_U,V,W or TPC_3D; all treated as 3D p...