22struct MeanAndCovariance {
39findMeanAndCovariance(const Trk::MultiComponentState& uncombinedState) {
41 MeanAndCovariance toReturn;
42 toReturn.mean.setZero();
44 covariancePart1.setZero();
46 covariancePart2.setZero();
47 const
double phiOfFirst = uncombinedState[0].params->parameters()[2];
48 const
size_t numComponents = uncombinedState.size();
49 for (
size_t i = 0; i < numComponents; ++i) {
51 const double weight = uncombinedState[
i].weight;
52 AmgVector(5) parameters = trackParameters->parameters();
55 const
double deltaPhi = phiOfFirst - parameters[2];
65 const AmgSymMatrix(5)* measuredCov = trackParameters->covariance();
68 covariancePart1 +=
weight * (*measuredCov);
71 for (
size_t j = i + 1; j < numComponents; ++j) {
73 parameters - uncombinedState[j].params->parameters();
74 const
double remainingWeight = uncombinedState[j].weight;
75 covariancePart2 += weight * remainingWeight * parameterDifference *
76 parameterDifference.transpose();
81 toReturn.
mean /= toReturn.sumW;
83 toReturn.
mean[2] = CxxUtils::wrapToPi(toReturn.
mean[2]);
84 toReturn.covariance = covariancePart1 / toReturn.sumW + covariancePart2 / (toReturn.sumW * toReturn.sumW);
91Trk::ComponentParameters combineToSingleImpl(
92 const Trk::MultiComponentState& uncombinedState, const
bool useMode) {
94 if (uncombinedState.empty()) {
99 if (uncombinedState.size() == 1) {
100 return {uncombinedState.front().params->uniqueClone(),
101 uncombinedState.front().weight};
104 MeanAndCovariance
res = findMeanAndCovariance (uncombinedState);
106 const int dimension = (uncombinedState.front()).params->parameters().rows();
107 if (useMode && dimension == 5) {
109 std::array<double, 10>
modes =
119 if (modes[5 + 0] > 0) {
120 double currentErr = sqrt((
res.covariance)(0, 0));
121 currentErr =
modes[5 + 0] / currentErr;
123 res.covariance.fillSymmetric(1, 0, (
res.covariance)(1, 0) * currentErr);
124 res.covariance.fillSymmetric(2, 0, (
res.covariance)(2, 0) * currentErr);
125 res.covariance.fillSymmetric(3, 0, (
res.covariance)(3, 0) * currentErr);
126 res.covariance.fillSymmetric(4, 0, (
res.covariance)(4, 0) * currentErr);
128 if (modes[5 + 1] > 0) {
129 double currentErr = sqrt((
res.covariance)(1, 1));
130 currentErr =
modes[5 + 1] / currentErr;
131 res.covariance.fillSymmetric(1, 0, (
res.covariance)(1, 0) * currentErr);
133 res.covariance.fillSymmetric(2, 1, (
res.covariance)(2, 1) * currentErr);
134 res.covariance.fillSymmetric(3, 1, (
res.covariance)(3, 1) * currentErr);
135 res.covariance.fillSymmetric(4, 1, (
res.covariance)(4, 1) * currentErr);
137 if (modes[5 + 2] > 0) {
138 double currentErr = sqrt((
res.covariance)(2, 2));
139 currentErr =
modes[5 + 2] / currentErr;
140 res.covariance.fillSymmetric(2, 0, (
res.covariance)(2, 0) * currentErr);
141 res.covariance.fillSymmetric(2, 1, (
res.covariance)(2, 1) * currentErr);
143 res.covariance.fillSymmetric(3, 2, (
res.covariance)(3, 2) * currentErr);
144 res.covariance.fillSymmetric(4, 2, (
res.covariance)(4, 2) * currentErr);
146 if (modes[5 + 3] > 0) {
147 double currentErr = sqrt((
res.covariance)(3, 3));
148 currentErr =
modes[5 + 3] / currentErr;
149 res.covariance.fillSymmetric(3, 0, (
res.covariance)(3, 0) * currentErr);
150 res.covariance.fillSymmetric(3, 1, (
res.covariance)(3, 1) * currentErr);
151 res.covariance.fillSymmetric(3, 2, (
res.covariance)(3, 2) * currentErr);
153 res.covariance.fillSymmetric(4, 3, (
res.covariance)(4, 3) * currentErr);
155 if (modes[5 + 4] > 0) {
156 double currentErr = sqrt((
res.covariance)(4, 4));
157 currentErr =
modes[5 + 4] / currentErr;
158 res.covariance.fillSymmetric(4, 0, (
res.covariance)(4, 0) * currentErr);
159 res.covariance.fillSymmetric(4, 1, (
res.covariance)(4, 1) * currentErr);
160 res.covariance.fillSymmetric(4, 2, (
res.covariance)(4, 2) * currentErr);
161 res.covariance.fillSymmetric(4, 3, (
res.covariance)(4, 3) * currentErr);
168 std::unique_ptr<Trk::TrackParameters> combinedTrackParameters =
nullptr;
174 const AmgSymMatrix(5)* firstMeasuredCov = firstParameters->covariance();
175 if (firstMeasuredCov) {
176 combinedTrackParameters =
178 loc1, loc2,
phi,
theta, qoverp, std::move(
res.covariance));
180 combinedTrackParameters =
182 loc1, loc2,
phi,
theta, qoverp, std::nullopt);
185 return {std::move(combinedTrackParameters),
res.sumW};
189std::unique_ptr<Trk::TrackParameters>
193 return std::move(combinedComponent.
params);
205 const double secondWeight)
207 double const totalWeight = firstWeight + secondWeight;
208 double const invTotalWeight = 1.0/totalWeight;
209 double const deltaPhi = firstParameters[2] - secondParameters[2];
211 firstParameters[2] -= 2 *
M_PI;
213 firstParameters[2] += 2 *
M_PI;
216 (firstWeight * firstParameters + secondWeight * secondParameters) *
220 firstWeight = totalWeight;
230 const double firstWeight,
233 const double secondWeight)
235 double const invTotalWeight = 1.0/(firstWeight + secondWeight);
236 AmgVector(5) parameterDifference = firstParameters - secondParameters;
238 parameterDifference *= invTotalWeight;
239 firstMeasuredCov = (firstWeight * firstMeasuredCov + secondWeight * secondMeasuredCov) * invTotalWeight;
240 firstMeasuredCov += firstWeight * secondWeight * parameterDifference * parameterDifference.transpose();
Scalar deltaPhi(const MatrixBase< Derived > &vec) const
Scalar phi() const
phi method
Scalar theta() const
theta method
#define AmgSymMatrix(dim)
std::pair< std::vector< unsigned int >, bool > res
virtual const Surface & associatedSurface() const override=0
Access to the Surface associated to the Parameters.
virtual ChargedTrackParametersUniquePtr createUniqueTrackParameters(double l1, double l2, double phi, double theat, double qop, std::optional< AmgSymMatrix(5)> cov=std::nullopt) const =0
Use the Surface as a ParametersBase constructor, from local parameters - charged.
void mean(std::vector< double > &bins, std::vector< double > &values, const std::vector< std::string > &files, const std::string &histname, const std::string &tplotname, const std::string &label="")
float modes(const std::vector< float > &mus, const std::vector< float > &log_sigma2s, const std::vector< float > &alphas)
T wrapToPi(T phi)
Wrap angle in radians to [-pi, pi].
void combineParametersWithWeight(AmgVector(5) &firstParameters, double &firstWeight, const AmgVector(5) &secondParameters, const double secondWeight)
Combine parameters based on their relevant weigths.
void combineCovWithWeight(const AmgVector(5) &firstParameters, AmgSymMatrix(5) &firstMeasuredCov, const double firstWeight, const AmgVector(5) &secondParameters, const AmgSymMatrix(5) &secondMeasuredCov, const double secondWeight)
Combine cov matrices based on their relevant weights.
std::unique_ptr< Trk::TrackParameters > combineToSingle(const MultiComponentState &, const bool useMode=false)
@bried Calculate combined state of many components
std::array< double, 10 > calculateMode(const MultiComponentState &)
Method to calculate mode with MultiComponentState state as input.
std::vector< ComponentParameters > MultiComponentState
@ loc2
generic first and second local coordinate
ParametersBase< TrackParametersDim, Charged > TrackParameters
Helper for azimuthal angle calculations.
std::unique_ptr< Trk::TrackParameters > params