21 template <
typename input_track_t>
23 BilloirTrack(
const input_track_t* params) : originalTrack(params) {}
25 BilloirTrack(
const BilloirTrack& arg) =
default;
27 const input_track_t* originalTrack;
45 struct BilloirVertex {
58 template <
typename input_track_t,
typename linearizer_t>
61 const std::vector<const input_track_t*>& paramVector,
65 unsigned int nTracks = paramVector.size();
66 double chi2 = std::numeric_limits<double>::max();
80 int ndf = 3 * nTracks - 3;
93 std::vector<BilloirTrack<input_track_t>> billoirTracks;
94 std::vector<Vector3> trackMomenta;
100 billoirTracks.clear();
102 BilloirVertex billoirVertex;
107 const std::shared_ptr<PerigeeSurface> perigeeSurface =
108 Surface::makeShared<PerigeeSurface>(linPointPos);
111 for (std::size_t iTrack = 0; iTrack < nTracks; ++iTrack) {
112 const input_track_t* trackContainer = paramVector[iTrack];
114 const auto& trackParams = extractParameters(*trackContainer);
116 auto result = linearizer.linearizeTrack(
117 trackParams, linPoint[3], *perigeeSurface,
121 return result.error();
124 const auto& linTrack = *result;
125 const auto& parametersAtPCA = linTrack.parametersAtPCA;
136 trackMomenta.push_back(
Vector3(phi, theta, qOverP));
142 double fPhi = trackMomenta[iTrack][0];
143 double fTheta = trackMomenta[iTrack][1];
144 double fQOvP = trackMomenta[iTrack][2];
146 BilloirTrack<input_track_t> billoirTrack(trackContainer);
148 billoirTrack.deltaQ << d0, z0, phi - fPhi, theta - fTheta, qOverP - fQOvP,
166 billoirTrack.C = EtW *
E;
167 billoirTrack.B = DtW *
E;
168 billoirTrack.U = EtW * billoirTrack.deltaQ;
169 billoirTrack.Cinv = (billoirTrack.C).inverse();
171 billoirTrack.B * billoirTrack.Cinv;
174 billoirVertex.T += DtW * billoirTrack.deltaQ;
175 billoirVertex.A += DtW * D;
176 billoirVertex.sumBCinvU +=
177 billoirTrack.BCinv * billoirTrack.U;
178 billoirVertex.sumBCinvBt +=
180 billoirTrack.B.transpose();
182 billoirTracks.push_back(billoirTrack);
188 Vector4 deltaVFac = billoirVertex.T - billoirVertex.sumBCinvU;
193 SquareMatrix4 invCovV = billoirVertex.A - billoirVertex.sumBCinvBt;
200 vertexingOptions.
constraint.fullPosition() - linPoint;
205 deltaVFac += vertexingOptions.
constraint.fullCovariance().inverse() *
208 invCovV += vertexingOptions.
constraint.fullCovariance().inverse();
214 Vector4 deltaV = covV * deltaVFac;
218 std::vector<std::optional<BoundSquareMatrix>> covDeltaP(nTracks);
222 for (std::size_t iTrack = 0; iTrack < billoirTracks.size(); ++iTrack) {
223 auto& billoirTrack = billoirTracks[iTrack];
225 Vector3 deltaP = (billoirTrack.Cinv) *
226 (billoirTrack.U - billoirTrack.B.transpose() * deltaV);
229 trackMomenta[iTrack] += deltaP;
233 trackMomenta[iTrack][0], trackMomenta[iTrack][1]);
234 trackMomenta[iTrack][0] = correctedPhiTheta.first;
235 trackMomenta[iTrack][1] = correctedPhiTheta.second;
239 billoirTrack.E * deltaP;
240 billoirTrack.chi2 = diffQ.transpose().dot(billoirTrack.W * diffQ);
242 newChi2 += billoirTrack.chi2;
256 transMat.block<2, 2>(0, 0) = billoirTrack.D.template block<2, 2>(0, 0);
271 billoirTrack.BCinv.transpose() * covV * billoirTrack.BCinv;
275 cov.block<4, 4>(0, 0) = covV;
276 cov.block<4, 3>(0, 4) = covVP;
277 cov.block<3, 4>(4, 0) = covVP.transpose();
278 cov.block<3, 3>(4, 4) = covP;
280 covDeltaP[iTrack] = transMat * cov * transMat.transpose();
292 vertexingOptions.
constraint.fullPosition() - linPoint;
295 (posInBilloirFrame.transpose())
296 .dot(vertexingOptions.
constraint.fullCovariance().inverse() *
300 if (!std::isnormal(newChi2)) {
301 return VertexingError::NumericFailure;
304 if (newChi2 < chi2) {
311 std::vector<TrackAtVertex<input_track_t>> tracksAtVertex;
313 std::shared_ptr<PerigeeSurface> perigee =
314 Surface::makeShared<PerigeeSurface>(
317 for (std::size_t iTrack = 0; iTrack < billoirTracks.size(); ++iTrack) {
318 const auto& billoirTrack = billoirTracks[iTrack];
326 paramVec[
eBoundPhi] = trackMomenta[iTrack](0);
331 perigee, paramVec, covDeltaP[iTrack],
332 extractParameters(*billoirTrack.originalTrack)
333 .particleHypothesis());
335 billoirTrack.chi2, refittedParams, billoirTrack.originalTrack);
336 tracksAtVertex.push_back(
std::move(trackAtVertex));