13 #include <Eigen/Dense>
21 void LArPcaHelper::RunPca(
const T &t, CartesianVector ¢roid,
EigenValues &outputEigenValues,
EigenVectors &outputEigenVectors)
25 for (
const auto &point : t)
26 weightedPointVector.push_back(std::make_pair(LArObjectHelper::TypeAdaptor::GetPosition(point), 1.));
28 return LArPcaHelper::RunPca(weightedPointVector, centroid, outputEigenValues, outputEigenVectors);
33 void LArPcaHelper::RunPca(
const WeightedPointVector &pointVector, CartesianVector ¢roid, EigenValues &outputEigenValues, EigenVectors &outputEigenVectors)
42 if (pointVector.empty())
44 std::cout <<
"LArPcaHelper::RunPca - no three dimensional hits provided" << std::endl;
45 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
48 double meanPosition[3] = {0., 0., 0.};
51 for (
const WeightedPoint &weightedPoint : pointVector)
53 const CartesianVector &point(weightedPoint.first);
54 const double weight(weightedPoint.second);
58 std::cout <<
"LArPcaHelper::RunPca - negative weight found" << std::endl;
59 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
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;
71 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
74 meanPosition[0] /= sumWeight;
75 meanPosition[1] /= sumWeight;
76 meanPosition[2] /= sumWeight;
77 centroid = CartesianVector(meanPosition[0], meanPosition[1], meanPosition[2]);
87 for (
const WeightedPoint &weightedPoint : pointVector)
89 const CartesianVector &point(weightedPoint.first);
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;
115 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
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));
142 template void LArPcaHelper::RunPca(
const CartesianPointVector &, CartesianVector &, EigenValues &, EigenVectors &);
143 template void LArPcaHelper::RunPca(
const CaloHitList &, CartesianVector &, EigenValues &, EigenVectors &);
process_name opflash particleana ie ie ie z
process_name opflash particleana ie x
pandora::CartesianVector EigenValues
std::vector< WeightedPoint > WeightedPointVector
Header file for the principal curve analysis helper class.
process_name opflash particleana ie ie y
Header file for the object helper class.
Header file for the cluster helper class.
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
std::vector< pandora::CartesianVector > EigenVectors
BEGIN_PROLOG could also be cout