ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TrackDensity.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file TrackDensity.cpp
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 
10 #include <math.h>
11 
13  const double d0SignificanceCut,
14  const double z0SignificanceCut) const {
15  // Get required track parameters
16  const double d0 = trk.parameters()[ParID_t::eLOC_D0];
17  const double z0 = trk.parameters()[ParID_t::eLOC_Z0];
18  // Get track covariance
19  const auto perigeeCov = *(trk.covariance());
20  const double covDD = perigeeCov(ParID_t::eLOC_D0, ParID_t::eLOC_D0);
21  const double covZZ = perigeeCov(ParID_t::eLOC_Z0, ParID_t::eLOC_Z0);
22  const double covDZ = perigeeCov(ParID_t::eLOC_D0, ParID_t::eLOC_Z0);
23  const double covDeterminant = covDD * covZZ - covDZ * covDZ;
24 
25  // Do track selection based on track cov matrix and d0SignificanceCut
26  if ((covDD <= 0) || (d0 * d0 / covDD > d0SignificanceCut) || (covZZ <= 0) ||
27  (covDeterminant <= 0)) {
28  return;
29  }
30 
31  // Calculate track density quantities
32  double constantTerm =
33  -(d0 * d0 * covZZ + z0 * z0 * covDD + 2. * d0 * z0 * covDZ) /
34  (2. * covDeterminant);
35  const double linearTerm =
36  (d0 * covDZ + z0 * covDD) /
37  covDeterminant; // minus signs and factors of 2 cancel...
38  const double quadraticTerm = -covDD / (2. * covDeterminant);
39  double discriminant =
40  linearTerm * linearTerm -
41  4. * quadraticTerm * (constantTerm + 2. * z0SignificanceCut);
42  if (discriminant < 0) {
43  return;
44  }
45 
46  // Add the track to the current maps in the state
47  discriminant = std::sqrt(discriminant);
48  const double zMax = (-linearTerm - discriminant) / (2. * quadraticTerm);
49  const double zMin = (-linearTerm + discriminant) / (2. * quadraticTerm);
50  constantTerm -= std::log(2. * M_PI * std::sqrt(covDeterminant));
51  state.trackEntries.emplace_back(z0, constantTerm, linearTerm, quadraticTerm,
52  zMin, zMax);
53 }
54 
56  State& state) const {
57  double maxPosition = 0.;
58  double maxDensity = 0.;
59  double maxSecondDerivative = 0.;
60 
61  for (const auto& track : state.trackEntries) {
62  double trialZ = track.z;
63  double density = 0.;
64  double firstDerivative = 0.;
65  double secondDerivative = 0.;
66  density = trackDensity(state, trialZ, firstDerivative, secondDerivative);
67  if (secondDerivative >= 0. || density <= 0.) {
68  continue;
69  }
70  updateMaximum(trialZ, density, secondDerivative, maxPosition, maxDensity,
71  maxSecondDerivative);
72  trialZ += stepSize(density, firstDerivative, secondDerivative);
73  density = trackDensity(state, trialZ, firstDerivative, secondDerivative);
74  if (secondDerivative >= 0. || density <= 0.) {
75  continue;
76  }
77  updateMaximum(trialZ, density, secondDerivative, maxPosition, maxDensity,
78  maxSecondDerivative);
79  trialZ += stepSize(density, firstDerivative, secondDerivative);
80  density = trackDensity(state, trialZ, firstDerivative, secondDerivative);
81  if (secondDerivative >= 0. || density <= 0.) {
82  continue;
83  }
84  updateMaximum(trialZ, density, secondDerivative, maxPosition, maxDensity,
85  maxSecondDerivative);
86  }
87 
88  return std::make_pair(maxPosition,
89  std::sqrt(-(maxDensity / maxSecondDerivative)));
90 }
91 
93  return globalMaximumWithWidth(state).first;
94 }
95 
96 double Acts::TrackDensity::trackDensity(State& state, double z) const {
97  double firstDerivative = 0;
98  double secondDerivative = 0;
99  return trackDensity(state, z, firstDerivative, secondDerivative);
100 }
101 
103  double& firstDerivative,
104  double& secondDerivative) const {
105  TrackDensityStore densityResult(z);
106  for (const auto& trackEntry : state.trackEntries) {
107  densityResult.addTrackToDensity(trackEntry);
108  }
109  firstDerivative = densityResult.firstDerivative();
110  secondDerivative = densityResult.secondDerivative();
111 
112  return densityResult.density();
113 }
114 
115 void Acts::TrackDensity::updateMaximum(double newZ, double newValue,
116  double newSecondDerivative, double& maxZ,
117  double& maxValue,
118  double& maxSecondDerivative) const {
119  if (newValue > maxValue) {
120  maxZ = newZ;
121  maxValue = newValue;
122  maxSecondDerivative = newSecondDerivative;
123  }
124 }
125 
126 double Acts::TrackDensity::stepSize(double y, double dy, double ddy) const {
127  return (m_cfg.isGaussianShaped ? (y * dy) / (dy * dy - y * ddy) : -dy / ddy);
128 }
129 
131  const TrackEntry& entry) {
132  // Take track only if it's within bounds
133  if (entry.lowerBound < m_z && m_z < entry.upperBound) {
134  double delta = std::exp(entry.c0 + m_z * (entry.c1 + m_z * entry.c2));
135  double qPrime = entry.c1 + 2. * m_z * entry.c2;
136  double deltaPrime = delta * qPrime;
137  m_density += delta;
138  m_firstDerivative += deltaPrime;
139  m_secondDerivative += 2. * entry.c2 * delta + qPrime * deltaPrime;
140  }
141 }