EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GaussianTrackDensity.ipp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file GaussianTrackDensity.ipp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2020 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #include <math.h>
10 
11 template <typename input_track_t>
12 std::pair<double, double>
14  State& state, const std::vector<const input_track_t*>& trackList,
15  const std::function<BoundTrackParameters(input_track_t)>& extractParameters)
16  const {
17  addTracks(state, trackList, extractParameters);
18 
19  double maxPosition = 0.;
20  double maxDensity = 0.;
21  double maxSecondDerivative = 0.;
22 
23  for (const auto& track : state.trackEntries) {
24  double trialZ = track.z;
25 
26  auto [density, firstDerivative, secondDerivative] =
27  trackDensityAndDerivatives(state, trialZ);
28  if (secondDerivative >= 0. || density <= 0.) {
29  continue;
30  }
31  std::tie(maxPosition, maxDensity, maxSecondDerivative) =
32  updateMaximum(trialZ, density, secondDerivative, maxPosition,
33  maxDensity, maxSecondDerivative);
34 
35  trialZ += stepSize(density, firstDerivative, secondDerivative);
36  std::tie(density, firstDerivative, secondDerivative) =
37  trackDensityAndDerivatives(state, trialZ);
38 
39  if (secondDerivative >= 0. || density <= 0.) {
40  continue;
41  }
42  std::tie(maxPosition, maxDensity, maxSecondDerivative) =
43  updateMaximum(trialZ, density, secondDerivative, maxPosition,
44  maxDensity, maxSecondDerivative);
45  trialZ += stepSize(density, firstDerivative, secondDerivative);
46  std::tie(density, firstDerivative, secondDerivative) =
47  trackDensityAndDerivatives(state, trialZ);
48  if (secondDerivative >= 0. || density <= 0.) {
49  continue;
50  }
51  std::tie(maxPosition, maxDensity, maxSecondDerivative) =
52  updateMaximum(trialZ, density, secondDerivative, maxPosition,
53  maxDensity, maxSecondDerivative);
54  }
55 
56  return std::make_pair(maxPosition,
57  std::sqrt(-(maxDensity / maxSecondDerivative)));
58 }
59 
60 template <typename input_track_t>
62  State& state, const std::vector<const input_track_t*>& trackList,
63  const std::function<BoundTrackParameters(input_track_t)>& extractParameters)
64  const {
65  return globalMaximumWithWidth(state, trackList, extractParameters).first;
66 }
67 
68 template <typename input_track_t>
70  State& state, const std::vector<const input_track_t*>& trackList,
71  const std::function<BoundTrackParameters(input_track_t)>& extractParameters)
72  const {
73  for (auto trk : trackList) {
74  const BoundTrackParameters& boundParams = extractParameters(*trk);
75  // Get required track parameters
76  const double d0 = boundParams.parameters()[BoundIndices::eBoundLoc0];
77  const double z0 = boundParams.parameters()[BoundIndices::eBoundLoc1];
78  // Get track covariance
79  const auto perigeeCov = *(boundParams.covariance());
80  const double covDD =
82  const double covZZ =
84  const double covDZ =
86  const double covDeterminant = (perigeeCov.block<2, 2>(0, 0)).determinant();
87 
88  // Do track selection based on track cov matrix and m_cfg.d0SignificanceCut
89  if ((covDD <= 0) || (d0 * d0 / covDD > m_cfg.d0SignificanceCut) ||
90  (covZZ <= 0) || (covDeterminant <= 0)) {
91  continue;
92  }
93 
94  // Calculate track density quantities
95  double constantTerm =
96  -(d0 * d0 * covZZ + z0 * z0 * covDD + 2. * d0 * z0 * covDZ) /
97  (2. * covDeterminant);
98  const double linearTerm =
99  (d0 * covDZ + z0 * covDD) /
100  covDeterminant; // minus signs and factors of 2 cancel...
101  const double quadraticTerm = -covDD / (2. * covDeterminant);
102  double discriminant =
103  linearTerm * linearTerm -
104  4. * quadraticTerm * (constantTerm + 2. * m_cfg.z0SignificanceCut);
105  if (discriminant < 0) {
106  continue;
107  }
108 
109  // Add the track to the current maps in the state
110  discriminant = std::sqrt(discriminant);
111  const double zMax = (-linearTerm - discriminant) / (2. * quadraticTerm);
112  const double zMin = (-linearTerm + discriminant) / (2. * quadraticTerm);
113  constantTerm -= std::log(2. * M_PI * std::sqrt(covDeterminant));
114 
115  state.trackEntries.emplace_back(z0, constantTerm, linearTerm, quadraticTerm,
116  zMin, zMax);
117  }
118 }
119 
120 template <typename input_track_t>
121 std::tuple<double, double, double>
123  State& state, double z) const {
124  GaussianTrackDensityStore densityResult(z);
125  for (const auto& trackEntry : state.trackEntries) {
126  densityResult.addTrackToDensity(trackEntry);
127  }
128  return densityResult.densityAndDerivatives();
129 }
130 
131 template <typename input_track_t>
132 std::tuple<double, double, double>
134  double newZ, double newValue, double newSecondDerivative, double maxZ,
135  double maxValue, double maxSecondDerivative) const {
136  if (newValue > maxValue) {
137  maxZ = newZ;
138  maxValue = newValue;
139  maxSecondDerivative = newSecondDerivative;
140  }
141  return {maxZ, maxValue, maxSecondDerivative};
142 }
143 
144 template <typename input_track_t>
146  double ddy) const {
147  return (m_cfg.isGaussianShaped ? (y * dy) / (dy * dy - y * ddy) : -dy / ddy);
148 }
149 
150 template <typename input_track_t>
153  // Take track only if it's within bounds
154  if (entry.lowerBound < m_z && m_z < entry.upperBound) {
155  double delta = std::exp(entry.c0 + m_z * (entry.c1 + m_z * entry.c2));
156  double qPrime = entry.c1 + 2. * m_z * entry.c2;
157  double deltaPrime = delta * qPrime;
158  m_density += delta;
159  m_firstDerivative += deltaPrime;
160  m_secondDerivative += 2. * entry.c2 * delta + qPrime * deltaPrime;
161  }
162 }