ATLAS Offline Software
Loading...
Searching...
No Matches
GaussianTrackDensity.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include "GaudiKernel/PhysicalConstants.h"
9#include "TrkTrack/Track.h"
10#include <algorithm>
11#include <cmath>
12#include <limits>
13
14namespace Trk
15{
20 double GaussianTrackDensity::globalMaximum (const std::vector<const Track*>& vectorTrk) const
21 {
22 std::vector<const TrackParameters*> perigeeList;
23 perigeeList.reserve(vectorTrk.size());
24
25 for (const Track* itrk : vectorTrk)
26 {
27 perigeeList.push_back(itrk->perigeeParameters());
28 }
29
31 return globalMaximumImpl (perigeeList, d);
32 }
33
34
40 double GaussianTrackDensity::globalMaximum (const std::vector<const Track*>& vectorTrk,
41 std::unique_ptr<ITrackDensity>& density) const
42 {
43 std::vector<const TrackParameters*> perigeeList;
44 perigeeList.reserve(vectorTrk.size());
45
46 for (const Track* itrk : vectorTrk)
47 {
48 perigeeList.push_back(itrk->perigeeParameters());
49 }
50 return globalMaximum (perigeeList, density);
51 }
52
57 double
58 GaussianTrackDensity::globalMaximum (const std::vector<const TrackParameters*>& perigeeList) const
59 {
61 return globalMaximumImpl (perigeeList, d);
62 }
63
69 double
70 GaussianTrackDensity::globalMaximum (const std::vector<const TrackParameters*>& perigeeList,
71 std::unique_ptr<ITrackDensity>& density) const
72 {
73 auto d = std::make_unique<TrackDensity> (m_gaussStep);
74 TrackDensity* dp = d.get();
75 density = std::move(d);
76 return globalMaximumImpl (perigeeList, *dp);
77 }
78
80 const std::vector<const TrackParameters*>& perigeeList) const {
82 return globalMaximumWithWidthImpl (perigeeList, d);
83 }
84
90 double GaussianTrackDensity::globalMaximumImpl (const std::vector<const TrackParameters*>& perigeeList,
91 TrackDensity& density) const
92 {
93 addTracks (perigeeList, density);
94 return density.globalMaximum ();
95 }
96
97 std::pair<double,double> GaussianTrackDensity::globalMaximumWithWidthImpl (const std::vector<const TrackParameters*>& perigeeList,
98 TrackDensity& density) const
99 {
100 addTracks (perigeeList, density);
101 return density.globalMaximumWithWidth ();
102 }
103
109 void GaussianTrackDensity::addTracks(const std::vector<const TrackParameters*>& perigeeList,
110 TrackDensity& density) const
111 {
112 const double d0SignificanceCut = m_d0MaxSignificance * m_d0MaxSignificance;
113 const double z0SignificanceCut = m_z0MaxSignificance * m_z0MaxSignificance;
114
115 for (const TrackParameters* iparam : perigeeList) {
116 if (iparam && iparam->surfaceType() == Trk::SurfaceType::Perigee) {
117 density.addTrack(*(static_cast<const Perigee*>(iparam)),
118 d0SignificanceCut,
119 z0SignificanceCut);
120 }
121 }
122 }
123
124
125 //***********************************************************************
131 {
132 double firstDeriv, secondDeriv = 0; // unused in this case
133 double density = 0;
134 // use the existing trackDensity method to avoid duplication of logic
135 trackDensity(z,density,firstDeriv,secondDeriv);
136 return density;
137 }
138
139
144 void
146 double& density,
147 double& firstDerivative,
148 double& secondDerivative) const
149 {
150 TrackDensityEval densityResult(z);
151 for (const auto & trackAndPerigeePair : m_lowerMap){
152 densityResult.addTrack(trackAndPerigeePair.first);
153 }
154 density = densityResult.density();
155 firstDerivative = densityResult.firstDerivative();
156 secondDerivative = densityResult.secondDerivative();
157 }
158
159 std::pair<double,double>
161 {
162 // strategy:
163 // the global maximum must be somewhere near a track...
164 // since we can calculate the first and second derivatives, at each point we can determine
165 // a) whether the function is curved up (minimum) or down (maximum)
166 // b) the distance to nearest maximum, assuming either Newton (parabolic) or Gaussian local behavior
167 //
168 // For each track where the second derivative is negative, find step to nearest maximum
169 // Take that step, and then do one final refinement
170 // The largest density encountered in this procedure (after checking all tracks) is considered the maximum
171 //
172 double maximumPosition = 0.0;
173 double maximumDensity = 0.0;
174 double maxCurvature = 0. ;
175 const std::pair<double,double> invalidResult(0.,std::numeric_limits<double>::quiet_NaN());
176 if (m_trackMap.empty()) return invalidResult;
177 for (const auto& entry : m_trackMap)
178 {
179 double trialZ = entry.first.parameters()[Trk::z0];
180 double density = 0.0;
181 double slope = 0.0;
182 double curvature = 0.0;
183 trackDensity( trialZ, density, slope, curvature );
184 if ( curvature >= 0.0 || density <= 0.0 ) {
185 continue;
186 }
187 updateMaximum( trialZ, density, curvature, maximumPosition, maximumDensity, maxCurvature);
188 trialZ += stepSize( density, slope, curvature );
189 trackDensity( trialZ, density, slope, curvature );
190 if ( curvature >= 0.0 || density <= 0.0 ) {
191 continue;
192 }
193 updateMaximum( trialZ, density, curvature, maximumPosition, maximumDensity, maxCurvature);
194 trialZ += stepSize( density, slope, curvature );
195 trackDensity( trialZ, density, slope, curvature );
196 if ( curvature >= 0.0 || density <= 0.0) {
197 continue;
198 }
199 updateMaximum( trialZ, density, curvature, maximumPosition, maximumDensity, maxCurvature);
200 }
201 if (maxCurvature == 0.) return invalidResult;
202 return {maximumPosition,std::sqrt(-maximumDensity/maxCurvature)};
203 }
204
209 double
214
215
223 const double d0SignificanceCut,
224 const double z0SignificanceCut)
225 {
226 if (m_trackMap.count(itrk) != 0) return;
227 const double d0 = itrk.parameters()[Trk::d0];
228 const double z0 = itrk.parameters()[Trk::z0];
229 const AmgSymMatrix(5) & perigeeCov = *(itrk.covariance());
230 const double cov_dd = perigeeCov(Trk::d0, Trk::d0);
231 if ( cov_dd <= 0 ) return;
232 if ( d0*d0/cov_dd > d0SignificanceCut ) return;
233 const double cov_zz = perigeeCov(Trk::z0, Trk::z0);
234 if (cov_zz <= 0 ) return;
235 const double cov_dz = perigeeCov(Trk::d0, Trk::z0);
236 const double covDeterminant = cov_dd*cov_zz - cov_dz*cov_dz;
237 if ( covDeterminant <= 0 ) return;
238 double constantTerm = -(d0*d0*cov_zz + z0*z0*cov_dd + 2*d0*z0*cov_dz) / (2*covDeterminant);
239 const double linearTerm = (d0*cov_dz + z0*cov_dd) / covDeterminant ; // minus signs and factors of 2 cancel...
240 const double quadraticTerm = -cov_dd / (2*covDeterminant);
241 double discriminant = linearTerm*linearTerm - 4*quadraticTerm*(constantTerm + 2*z0SignificanceCut);
242 if (discriminant < 0) return;
243 discriminant = std::sqrt(discriminant);
244 const double zMax = (-linearTerm - discriminant)/(2*quadraticTerm);
245 const double zMin = (-linearTerm + discriminant)/(2*quadraticTerm);
246 m_maxRange = std::max(m_maxRange, std::max(zMax-z0, z0-zMin));
247 constantTerm -= std::log(2*M_PI*std::sqrt(covDeterminant));
248 m_trackMap.emplace(std::piecewise_construct,
249 std::forward_as_tuple(itrk),
250 std::forward_as_tuple(constantTerm, linearTerm, quadraticTerm, zMin, zMax));
251 m_lowerMap.emplace(std::piecewise_construct,
252 std::forward_as_tuple(constantTerm, linearTerm, quadraticTerm, zMin, zMax),
253 std::forward_as_tuple(itrk));
254 }
255
256
258 if (entry.lowerBound < m_z && entry.upperBound > m_z) {
259 double delta = std::exp(entry.c_0+m_z*(entry.c_1 + m_z*entry.c_2));
260 double qPrime = entry.c_1 + 2*m_z*entry.c_2;
261 double deltaPrime = delta * qPrime;
262 m_density += delta;
263 m_firstDerivative += deltaPrime;
264 m_secondDerivative += 2*entry.c_2*delta + qPrime*deltaPrime;
265 }
266 }
267
268}
#define M_PI
#define AmgSymMatrix(dim)
void addTrack(const Perigee &itrk, const double d0SignificanceCut, const double z0SignificanceCut)
Add a track to the set being considered.
std::pair< double, double > globalMaximumWithWidth() const
Return position of global maximum with Gaussian width for density function.
double stepSize(double y, double dy, double ddy) const
virtual double trackDensity(double z) const override final
Evaluate the density function at the specified coordinate along the beamline.
void updateMaximum(double trialZ, double trialValue, double secondDerivative, double &maxZ, double &maxValue, double &maxSecondDerivative) const
double globalMaximum() const
Return position of global maximum for density function.
std::pair< double, double > globalMaximumWithWidthImpl(const std::vector< const TrackParameters * > &perigeeList, TrackDensity &density) const
Find position of global maximum with Gaussian width for density function.
virtual double globalMaximum(const std::vector< const Track * > &vectorTrk, std::unique_ptr< ITrackDensity > &density) const override final
Find position of global maximum for density function.
Gaudi::Property< double > m_d0MaxSignificance
virtual double globalMaximum(const std::vector< const Track * > &vectorTrk) const override final
Find position of global maximum for density function.
Gaudi::Property< bool > m_gaussStep
void addTracks(const std::vector< const TrackParameters * > &perigeeList, TrackDensity &density) const
Add a set of tracks to a density object.
virtual std::pair< double, double > globalMaximumWithWidth(const std::vector< const TrackParameters * > &perigeeList) const override final
Gaudi::Property< double > m_z0MaxSignificance
double globalMaximumImpl(const std::vector< const TrackParameters * > &perigeeList, TrackDensity &density) const
Find position of global maximum for density function.
Ensure that the ATLAS eigen extensions are properly loaded.
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
@ z
global position (cartesian)
Definition ParamDefs.h:57
@ d0
Definition ParamDefs.h:63
@ z0
Definition ParamDefs.h:64
ParametersBase< TrackParametersDim, Charged > TrackParameters