15 template <
typename input_track_t>
16 std::pair<double, double>
18 State&
state,
const std::vector<const input_track_t*>& trackList,
21 auto result = addTracks(state, trackList, extractParameters);
22 if (not result.ok()) {
23 return std::make_pair(0., 0.);
26 double maxPosition = 0.;
27 double maxDensity = 0.;
28 double maxSecondDerivative = 0.;
31 double trialZ = track.z;
33 auto [density, firstDerivative, secondDerivative] =
34 trackDensityAndDerivatives(state, trialZ);
35 if (secondDerivative >= 0. || density <= 0.) {
38 std::tie(maxPosition, maxDensity, maxSecondDerivative) =
39 updateMaximum(trialZ, density, secondDerivative, maxPosition,
40 maxDensity, maxSecondDerivative);
42 trialZ +=
stepSize(density, firstDerivative, secondDerivative);
43 std::tie(density, firstDerivative, secondDerivative) =
44 trackDensityAndDerivatives(state, trialZ);
46 if (secondDerivative >= 0. || density <= 0.) {
49 std::tie(maxPosition, maxDensity, maxSecondDerivative) =
50 updateMaximum(trialZ, density, secondDerivative, maxPosition,
51 maxDensity, maxSecondDerivative);
52 trialZ +=
stepSize(density, firstDerivative, secondDerivative);
53 std::tie(density, firstDerivative, secondDerivative) =
54 trackDensityAndDerivatives(state, trialZ);
55 if (secondDerivative >= 0. || density <= 0.) {
58 std::tie(maxPosition, maxDensity, maxSecondDerivative) =
59 updateMaximum(trialZ, density, secondDerivative, maxPosition,
60 maxDensity, maxSecondDerivative);
63 return (maxSecondDerivative == 0.)
64 ? std::make_pair(0., 0.)
65 : std::make_pair(maxPosition,
66 std::sqrt(-(maxDensity / maxSecondDerivative)));
69 template <
typename input_track_t>
71 State& state,
const std::vector<const input_track_t*>& trackList,
74 return globalMaximumWithWidth(state, trackList, extractParameters).first;
77 template <
typename input_track_t>
79 State& state,
const std::vector<const input_track_t*>& trackList,
82 for (
auto trk : trackList) {
88 if (not boundParams.
covariance().has_value()) {
89 return VertexingError::NoCovariance;
91 const auto perigeeCov = *(boundParams.
covariance());
98 const double covDeterminant = (perigeeCov.block<2, 2>(0, 0)).determinant();
101 if ((covDD <= 0) || (d0 * d0 / covDD >
m_cfg.d0SignificanceCut) ||
102 (covZZ <= 0) || (covDeterminant <= 0)) {
107 double constantTerm =
108 -(d0 * d0 * covZZ + z0 * z0 * covDD + 2. * d0 * z0 * covDZ) /
109 (2. * covDeterminant);
110 const double linearTerm =
111 (d0 * covDZ + z0 * covDD) /
113 const double quadraticTerm = -covDD / (2. * covDeterminant);
114 double discriminant =
115 linearTerm * linearTerm -
116 4. * quadraticTerm * (constantTerm + 2. *
m_cfg.z0SignificanceCut);
117 if (discriminant < 0) {
122 discriminant = std::sqrt(discriminant);
123 const double zMax = (-linearTerm - discriminant) / (2. * quadraticTerm);
124 const double zMin = (-linearTerm + discriminant) / (2. * quadraticTerm);
125 constantTerm -= std::log(2. * M_PI * std::sqrt(covDeterminant));
127 state.
trackEntries.emplace_back(z0, constantTerm, linearTerm, quadraticTerm,
133 template <
typename input_track_t>
134 std::tuple<double, double, double>
136 State& state,
double z)
const {
144 template <
typename input_track_t>
145 std::tuple<double, double, double>
147 double newZ,
double newValue,
double newSecondDerivative,
double maxZ,
148 double maxValue,
double maxSecondDerivative)
const {
149 if (newValue > maxValue) {
152 maxSecondDerivative = newSecondDerivative;
154 return {
maxZ, maxValue, maxSecondDerivative};
157 template <
typename input_track_t>
160 return (
m_cfg.isGaussianShaped ? (y * dy) / (dy * dy - y * ddy) : -dy / ddy);
163 template <
typename input_track_t>
168 double delta = std::exp(entry.
c0 + m_z * (entry.
c1 + m_z * entry.
c2));
169 double qPrime = entry.
c1 + 2. * m_z * entry.
c2;
170 double deltaPrime = delta * qPrime;
172 m_firstDerivative += deltaPrime;
173 m_secondDerivative += 2. * entry.
c2 * delta + qPrime * deltaPrime;