16 typename propagator_options_t>
26 getDistanceAndMomentum(gctx, trkParams, vtxPos, deltaR, momDir, state);
37 typename propagator_options_t>
48 getDistanceAndMomentum(gctx, trkParams, vtxPos, deltaR, momDir, state);
58 Vector3D corrDeltaR = deltaR - (deltaR.dot(momDir)) * momDir;
61 Vector3D perpDir = momDir.cross(corrDeltaR);
65 thePlane.matrix().block(0, 0, 3, 1) = corrDeltaR;
66 thePlane.matrix().block(0, 1, 3, 1) = perpDir;
67 thePlane.matrix().block(0, 2, 3, 1) = momDir;
69 thePlane.matrix().block(0, 3, 3, 1) = vtxPos;
71 std::shared_ptr<PlaneSurface> planeSurface =
72 Surface::makeShared<PlaneSurface>(thePlane);
76 propagator_options_t pOptions(gctx, mctx,
LoggerWrapper{*logger});
80 auto result = m_cfg.propagator->propagate(trkParams, *planeSurface, pOptions);
82 return std::move((*result).endParameters);
84 return result.error();
89 typename propagator_options_t>
95 if (trkParams ==
nullptr) {
96 return VertexingError::EmptyInput;
107 Vector3D xDirPlane = myRotation.col(0);
108 Vector3D yDirPlane = myRotation.col(1);
111 Vector3D vertexLocPlane = vertexPos - myTranslation;
114 Vector2D vertexLocXY{vertexLocPlane.dot(xDirPlane),
115 vertexLocPlane.dot(yDirPlane)};
127 return myXYpos.dot(myWeightXY * myXYpos);
130 template <
typename input_track_t,
typename propagator_t,
131 typename propagator_options_t>
134 propagator_options_t>::performNewtonApproximation(
const Vector3D& trkPos,
138 double sinNewPhi = -std::sin(phi);
142 bool hasConverged =
false;
144 double cotTheta = 1. / std::tan(theta);
147 while (!hasConverged && nIter < m_cfg.maxIterations) {
148 double x0 = trkPos.x();
149 double y0 = trkPos.y();
150 double z0 = trkPos.z();
152 double xc = vtxPos.x();
153 double yc = vtxPos.y();
154 double zc = vtxPos.z();
156 double derivative = (x0 - xc) * (-r * cosNewPhi) +
157 (y0 - yc) * r * sinNewPhi +
158 (z0 - zc - r * phi * cotTheta) * (-r * cotTheta);
159 double secDerivative = r * (-(x0 - xc) * sinNewPhi - (y0 - yc) * cosNewPhi +
160 r * cotTheta * cotTheta);
162 if (secDerivative < 0.) {
163 return VertexingError::NumericFailure;
166 double deltaPhi = -derivative / secDerivative;
169 sinNewPhi = -std::sin(phi);
174 if (
std::abs(deltaPhi) < m_cfg.precision) {
181 return VertexingError::NotConverged;
186 template <
typename input_track_t,
typename propagator_t,
187 typename propagator_options_t>
202 double sinTheta = std::sin(theta);
204 double cotTheta = 1. / std::tan(theta);
207 double bZ = m_cfg.bField.getField(trkSurfaceCenter, state.
fieldCache)[
eZ];
212 if (bZ == 0. ||
std::abs(qOvP) < m_cfg.minQoP) {
216 r = sinTheta * (1. / qOvP) / bZ;
221 z0 + r * phi * cotTheta);
225 auto res = performNewtonApproximation(vec0, vtxPos, phi, theta, r);
233 double sinPhi = std::sin(phi);
239 Vector3D pointCA3d = vec0 + r *
Vector3D(-sinPhi, cosPhi, -cotTheta * phi);
242 deltaR = pointCA3d - vtxPos;
247 template <
typename input_track_t,
typename propagator_t,
248 typename propagator_options_t>
259 const std::shared_ptr<PerigeeSurface> perigeeSurface =
260 Surface::makeShared<PerigeeSurface>(vtx.
position());
264 propagator_options_t pOptions(gctx, mctx,
LoggerWrapper{*logger});
268 auto result = m_cfg.propagator->propagate(track, *perigeeSurface, pOptions);
271 return result.error();
274 const auto& propRes = *result;
275 const auto& params = propRes.endParameters->parameters();
281 const double sinPhi = std::sin(phi);
282 const double sinTheta = std::sin(theta);
283 const double cosPhi =
std::cos(phi);
284 const double cosTheta =
std::cos(theta);
289 const auto& perigeeCov = *(propRes.endParameters->covariance());
295 newIPandSigma.
IPd0 = d0;
296 double d0_PVcontrib = d0JacXY.transpose() * (vrtXYCov * d0JacXY);
297 if (d0_PVcontrib >= 0) {
301 newIPandSigma.
PVsigmad0 = std::sqrt(d0_PVcontrib);
303 newIPandSigma.
sigmad0 = std::sqrt(
309 covPerigeeZ0Theta(0, 0) =
311 covPerigeeZ0Theta(0, 1) =
313 covPerigeeZ0Theta(1, 0) =
315 covPerigeeZ0Theta(1, 1) =
320 Vector2D z0JacZ0Theta(sinTheta, z0 * cosTheta);
325 z0JacZ0Theta.transpose() * (covPerigeeZ0Theta * z0JacZ0Theta) +
326 sinTheta * vtxZZCov * sinTheta);
329 newIPandSigma.
IPz0 = z0;
333 newIPandSigma.
PVsigmaz0 = std::sqrt(vtxZZCov);
337 double sigma2z0sinTheta =
338 (z0JacZ0Theta.transpose() * (covPerigeeZ0Theta * z0JacZ0Theta));
342 newIPandSigma.
IPz0 = z0;
343 newIPandSigma.
sigmaz0 = std::sqrt(
348 return newIPandSigma;