ATLAS Offline Software
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 
14 namespace 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
211  {
213  }
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 }
TileDCSDataPlotter.dp
dp
Definition: TileDCSDataPlotter.py:840
Trk::GaussianTrackDensity::globalMaximumWithWidth
virtual std::pair< double, double > globalMaximumWithWidth(const std::vector< const TrackParameters * > &perigeeList) const override final
Definition: GaussianTrackDensity.cxx:79
Trk::z
@ z
global position (cartesian)
Definition: ParamDefs.h:57
Trk::GaussianTrackDensity::globalMaximum
virtual double globalMaximum(const std::vector< const Track * > &vectorTrk) const override final
Find position of global maximum for density function.
Definition: GaussianTrackDensity.cxx:20
hist_file_dump.d
d
Definition: hist_file_dump.py:137
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
Trk::ParametersT
Dummy class used to allow special convertors to be called for surfaces owned by a detector element.
Definition: EMErrorDetail.h:25
Trk::GaussianTrackDensity::TrackDensity::trackDensity
virtual double trackDensity(double z) const override final
Evaluate the density function at the specified coordinate along the beamline.
Definition: GaussianTrackDensity.cxx:130
M_PI
#define M_PI
Definition: ActiveFraction.h:11
Trk::GaussianTrackDensity::TrackDensityEval::density
double density() const
Definition: GaussianTrackDensity.h:104
Trk::z0
@ z0
Definition: ParamDefs.h:64
Trk::GaussianTrackDensity::TrackDensity
Definition: GaussianTrackDensity.h:114
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
ParamDefs.h
Track.h
Trk::AmgSymMatrix
AmgSymMatrix(5) &GXFTrackState
Definition: GXFTrackState.h:156
Trk::GaussianTrackDensity::TrackDensity::globalMaximumWithWidth
std::pair< double, double > globalMaximumWithWidth() const
Return position of global maximum with Gaussian width for density function.
Definition: GaussianTrackDensity.cxx:160
GaussianTrackDensity.h
Trk::GaussianTrackDensity::TrackDensityEval::firstDerivative
double firstDerivative() const
Definition: GaussianTrackDensity.h:105
Trk::GaussianTrackDensity::globalMaximum
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.
Definition: GaussianTrackDensity.cxx:40
Trk::GaussianTrackDensity::TrackDensity::globalMaximum
double globalMaximum() const
Return position of global maximum for density function.
Definition: GaussianTrackDensity.cxx:210
Trk::ParametersBase
Definition: ParametersBase.h:55
Trk::GaussianTrackDensity::TrackDensityEval::addTrack
void addTrack(const TrackEntry &entry)
Definition: GaussianTrackDensity.cxx:257
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
Trk::GaussianTrackDensity::TrackDensityEval::secondDerivative
double secondDerivative() const
Definition: GaussianTrackDensity.h:106
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
Trk::SurfaceType::Perigee
@ Perigee
Trk::GaussianTrackDensity::addTracks
void addTracks(const std::vector< const TrackParameters * > &perigeeList, TrackDensity &density) const
Add a set of tracks to a density object.
Definition: GaussianTrackDensity.cxx:109
TauJetParameters::discriminant
@ discriminant
Definition: TauJetParameters.h:166
Trk::d0
@ d0
Definition: ParamDefs.h:63
Trk::GaussianTrackDensity::TrackDensityEval
Definition: GaussianTrackDensity.h:95
Trk::GaussianTrackDensity::m_d0MaxSignificance
Gaudi::Property< double > m_d0MaxSignificance
Definition: GaussianTrackDensity.h:230
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
Trk::GaussianTrackDensity::TrackEntry
Definition: GaussianTrackDensity.h:74
Track
Definition: TriggerChamberClusterOnTrackCreator.h:21
Trk::GaussianTrackDensity::TrackDensity::addTrack
void addTrack(const Perigee &itrk, const double d0SignificanceCut, const double z0SignificanceCut)
Add a track to the set being considered.
Definition: GaussianTrackDensity.cxx:222
Trk::GaussianTrackDensity::globalMaximumImpl
double globalMaximumImpl(const std::vector< const TrackParameters * > &perigeeList, TrackDensity &density) const
Find position of global maximum for density function.
Definition: GaussianTrackDensity.cxx:90
Trk::GaussianTrackDensity::m_gaussStep
Gaudi::Property< bool > m_gaussStep
Definition: GaussianTrackDensity.h:249
Trk::GaussianTrackDensity::m_z0MaxSignificance
Gaudi::Property< double > m_z0MaxSignificance
Definition: GaussianTrackDensity.h:239
Trk::GaussianTrackDensity::globalMaximumWithWidthImpl
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.
Definition: GaussianTrackDensity.cxx:97