22 struct MeanAndCovariance {
41 MeanAndCovariance toReturn;
42 toReturn.mean.setZero();
44 covariancePart1.setZero();
46 covariancePart2.setZero();
48 const size_t numComponents = uncombinedState.
size();
49 for (
size_t i = 0;
i < numComponents; ++
i) {
51 const double weight = uncombinedState[
i].weight;
65 const AmgSymMatrix(5)* measuredCov = trackParameters->covariance();
68 covariancePart1 +=
weight * (*measuredCov);
71 for (
size_t j =
i + 1; j < numComponents; ++j) {
74 const double remainingWeight = uncombinedState[j].
weight;
75 covariancePart2 +=
weight * remainingWeight * parameterDifference *
76 parameterDifference.transpose();
81 toReturn.
mean /= toReturn.sumW;
84 toReturn.covariance = covariancePart1 / toReturn.sumW + covariancePart2 / (toReturn.sumW * toReturn.sumW);
91 Trk::ComponentParameters combineToSingleImpl(
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 =
113 res.mean[0] = modes[0];
114 res.mean[1] = modes[1];
115 res.mean[2] = modes[2];
116 res.mean[3] = modes[3];
117 res.mean[4] = modes[4];
119 if (modes[5 + 0] > 0) {
120 double currentErr = sqrt((
res.covariance)(0, 0));
121 currentErr = modes[5 + 0] / currentErr;
122 (
res.covariance)(0, 0) = modes[5 + 0] * modes[5 + 0];
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);
132 (
res.covariance)(1, 1) = modes[5 + 1] * modes[5 + 1];
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);
142 (
res.covariance)(2, 2) = modes[5 + 2] * modes[5 + 2];
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);
152 (
res.covariance)(3, 3) = modes[5 + 3] * modes[5 + 3];
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);
162 (
res.covariance)(4, 4) = modes[5 + 4] * modes[5 + 4];
168 std::unique_ptr<Trk::TrackParameters> combinedTrackParameters =
nullptr;
174 const AmgSymMatrix(5)* firstMeasuredCov = firstParameters->covariance();
175 if (firstMeasuredCov) {
176 combinedTrackParameters =
180 combinedTrackParameters =
185 return {std::move(combinedTrackParameters),
res.sumW};
189 std::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();