ATLAS Offline Software
Loading...
Searching...
No Matches
Navigator.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6// Navigator.cxx, (c) ATLAS Detector Software
8
9// Trk inlcudes
19#include "TrkSurfaces/Surface.h"
27#include "TrkTrack/Track.h"
28// Data Model
30// Amg
33
34#include <exception>
35namespace{
36const Trk::MagneticFieldProperties s_zeroMagneticField(Trk::NoField);
37}
38
39// constructor
40Trk::Navigator::Navigator(const std::string &t, const std::string &n, const IInterface *p) :
41 AthAlgTool(t, n, p)
42 {
43 declareInterface<INavigator>(this);
44 }
45
46
47// initialize
48StatusCode
50 //We can use conditions when the key is not empty
52 // get the TrackingGeometry
53 if (!m_useConditions) {
54 if (m_trackingGeometrySvc.retrieve().isSuccess()) {
55 ATH_MSG_DEBUG("Successfully retrieved " << m_trackingGeometrySvc);
56 m_trackingGeometryName = m_trackingGeometrySvc->trackingGeometryName();
57 } else {
58 ATH_MSG_WARNING("Couldn't retrieve " << m_trackingGeometrySvc << ". ");
59 ATH_MSG_WARNING(" -> Trying to retrieve default '"
60 << m_trackingGeometryName << "' from DetectorStore.");
61 }
62 }
63
65
69
70 return StatusCode::SUCCESS;
71}
72
74Trk::Navigator::volume(const EventContext& ctx, const Amg::Vector3D& gp) const
75{
76 return (trackingGeometry(ctx)->lowestTrackingVolume(gp));
77}
78
80Trk::Navigator::highestVolume(const EventContext& ctx) const
81{
82 return (trackingGeometry(ctx)->highestTrackingVolume());
83}
84
87 const Trk::IPropagator& prop,
88 const Trk::TrackParameters& parms,
89 Trk::PropDirection dir) const
90{
91 const Trk::TrackingVolume* trackingVolume = volume(ctx,parms.position());
92 if (trackingVolume) {
93 return (nextBoundarySurface(ctx,prop, parms, dir, *trackingVolume));
94 }
95 return nullptr;
96}
97
100 const Trk::IPropagator& prop,
101 const Trk::TrackParameters& parms,
103 const Trk::TrackingVolume& vol) const
104{
105 // get the surface accessor
107 parms.position(), dir * parms.momentum().normalized());
108 // initialize the currentBoundary surface
109 const Trk::BoundarySurface<Trk::TrackingVolume>* currentBoundary = nullptr;
110 bool outsideVolume = surfAcc.inverseRetrieval();
111 // attempt counter
112 int tryBoundary = 0;
113
114 // set the prop direction according to inverseRetrieval result
115 Trk::PropDirection searchDir = dir;
116 if (outsideVolume) {
117 searchDir =
119 }
120
121 // debug version
122 ATH_MSG_VERBOSE("g [N] Starting parameters are :" << parms);
123
124 // loop over the the boundary surfaces according to the accessor type
125 for (const Trk::ObjectAccessor::value_type& surface_id : surfAcc) {
126 ++tryBoundary;
127 // ----------------- output to screen if outputLevel() says so --------
128 ATH_MSG_VERBOSE(" [N] " << tryBoundary << ". try - BoundarySurface "
129 << surface_id << " of Volume: '"
130 << vol.volumeName() << "'.");
131 // get the boundary Surface according to the surfaceAccessor
132 currentBoundary = vol.boundarySurface(surface_id);
133 const Trk::Surface& currentSurface =
134 currentBoundary->surfaceRepresentation();
135
136 // do either RungeKutta (always after first unsuccessful try) or straight
137 // line
138 auto trackPar =
139 (!m_useStraightLineApproximation || tryBoundary > 1)
140 ? prop.propagateParameters(
141 ctx, parms, currentSurface, searchDir, true, m_fieldProperties)
142 : prop.propagateParameters(
143 ctx, parms, currentSurface, searchDir, true, s_zeroMagneticField);
144
145 if (trackPar) {
147 " [N] --> next BoundarySurface found with Parameters: " << *trackPar);
148 return currentBoundary;
149 }
150 }
151 return nullptr;
152}
153
156 const Trk::IPropagator& prop,
157 const Trk::TrackParameters& parms,
159 const Trk::TrackingVolume& vol) const
160{
161
162 bool first = false;
163 bool second = false;
164
165 // ---------------------------------------------------
166 // get the object accessor from the Volume
168 parms.position(), dir * parms.momentum().normalized());
169 // the object accessor already solved the outside question
170 bool outsideVolume = surfAcc.inverseRetrieval();
171 // initialize the boundary pointer / tracking volume pointer
172 const Trk::BoundarySurface<Trk::TrackingVolume>* currentBoundary = nullptr;
173 const Trk::TrackingVolume* nextVolume = nullptr;
174
175 // debug version
176 ATH_MSG_VERBOSE(" [N] Starting parameters are : " << parms);
177 ATH_MSG_VERBOSE(" [N] This corresponds to [r,z] = [ "
178 << parms.position().perp() << ", " << parms.position().z()
179 << "]");
180 ATH_MSG_VERBOSE(" [N] Boundary Surface accessor : " << surfAcc);
181
182 // set the prop direction according to inverseRetrieval result
183 Trk::PropDirection searchDir = dir;
184 if (outsideVolume) {
185 ATH_MSG_VERBOSE(" [N] Parameters have been flagged as being outside !");
186 searchDir =
188 }
189
190 // loop over boundary surfaces
191 int tryBoundary = 0;
192
193 for (const Trk::ObjectAccessor::value_type& surface_id : surfAcc) {
194 ++tryBoundary;
195 // get the boundary surface associated to the surfaceAccessor
196 currentBoundary = vol.boundarySurface(surface_id);
197
198 // ----------------- output to screen if outputLevel() says so --------
199 if (!currentBoundary) {
200 ATH_MSG_WARNING(" [N] " << tryBoundary << ". try - BoundarySurface "
201 << surface_id << " of Volume: '"
202 << vol.volumeName() << "' NOT FOUND.");
203 continue;
204 }
205 ATH_MSG_VERBOSE(" [N] " << tryBoundary << ". try - BoundarySurface "
206 << surface_id << " of Volume: '"
207 << vol.volumeName() << "'.");
208
209
210 const Trk::Surface& currentSurface =
211 currentBoundary->surfaceRepresentation();
212 // try the propagation
213 std::unique_ptr<Trk::TrackParameters> trackPar = nullptr;
214 // do either RungeKutta (always after first unsuccessful try) or straight
215 // line
216 if (!currentSurface.isOnSurface(parms.position(), true, 0., 0.)) {
217 trackPar =
218 (!m_useStraightLineApproximation || tryBoundary > 1)
219 ? prop.propagateParameters(
220 ctx, parms, currentSurface, searchDir, true, m_fieldProperties)
221 : prop.propagateParameters(
222 ctx, parms, currentSurface, searchDir, true, s_zeroMagneticField);
223 } else {
224 trackPar.reset(parms.clone()); //to be revisited
225 }
226 if (trackPar) {
227 // the next volume pointer
228 nextVolume = currentBoundary->attachedVolume(
229 trackPar->position(), trackPar->momentum().normalized(), dir);
230 return {nextVolume, std::move(trackPar),
231 Trk::BoundarySurfaceFace(surface_id)};
232 }
233
234 // ---------------------------------------------------
235 if (!first && searchDir == Trk::alongMomentum) {
236 first = true;
237 } else if (!second && searchDir == Trk::alongMomentum) {
238 second = true;
239 } else if (searchDir == Trk::alongMomentum) {
240 } else if (!first && searchDir == Trk::oppositeMomentum) {
241 first = true;
242 } else if (!second && searchDir == Trk::oppositeMomentum) {
243 second = true;
244 } else if (searchDir == Trk::oppositeMomentum) {
245 }
246 // ---------------------------------------------------
247 }
248 // return what you have : no idea
249 return {nullptr, nullptr};
250}
251
252bool
254 const Trk::TrackingVolume* vol,
256 const Trk::TrackingVolume*& nextVol,
257 double tol) const
258{
259 bool isAtBoundary = false;
260 nextVol = nullptr;
261 if (!vol) {
262 return isAtBoundary;
263 }
264 const auto& bounds = vol->boundarySurfaces();
265 for (unsigned int ib = 0; ib < bounds.size(); ib++) {
266 const Trk::Surface &surf = bounds[ib]->surfaceRepresentation();
267 if (surf.isOnSurface(parms->position(), true, tol, tol)) {
268
269 // sanity check to enforce the desired tolerance
271 dir * parms->momentum().unit());
272 if (distSol.currentDistance(false) < tol && distSol.numberOfSolutions() > 0) {
273 isAtBoundary = true;
274 const Trk::TrackingVolume* attachedVol =
275 (bounds[ib])
276 ->attachedVolume(parms->position(), parms->momentum(), dir);
277 if (!nextVol && attachedVol) {
278 nextVol = attachedVol;
279 }
280 // double good solution indicate tangential intersection : revert the attached volumes
281 if (distSol.numberOfSolutions() > 1 && std::abs(distSol.first()) < tol && std::abs(distSol.second()) < tol) {
282 if (!nextVol) {
283 ATH_MSG_WARNING("Tracking volume "
284 << (*vol)
285 << " has loose ends. because the navigation of "
286 << std::endl
287 << (*parms) << std::endl
288 << " failed. Please consult the experts or have a "
289 "look at ATLASRECTS-7147");
290 continue;
291 }
292 //surfing the beampipe seems to happen particularly often in a Trigger test.
293 //see https://its.cern.ch/jira/browse/ATR-24234
294 //in this case, I downgrade the 'warning' to 'verbose'
295 const bool surfingTheBeamPipe = (vol->geometrySignature() == Trk::BeamPipe) or (nextVol->geometrySignature() == Trk::BeamPipe);
296 if (not surfingTheBeamPipe) {
297 ATH_MSG_WARNING("navigator detects tangential intersection: switch of volumes reverted ");
298 } else {
299 ATH_MSG_VERBOSE("navigator detects particle entering and re-entering the beampipe");
300 }
301 if (nextVol and (not surfingTheBeamPipe)) {
302 ATH_MSG_WARNING(vol->volumeName() << "->" << nextVol->volumeName() << "->" << vol->volumeName());
303 }
304 isAtBoundary = false;
305 // revert attached volume
306 nextVol = vol;
307 }
308 }
309 }
310 }
311
312 return isAtBoundary;
313}
314
317 const Trk::Surface& sf) const
318{
319
320 // search with dedicated algorithms for cylinder/sl/perigee
321 // surface
322 const Trk::TrackParameters *closestTrackParameters = nullptr;
323
324 // policy change --- only measured parameters are taken
326 std::vector<const Trk::TrackParameters *> measuredParameters;
327 measuredParameters.reserve(trk.trackParameters()->size());
328 for (; it != trk.trackParameters()->end(); ++it) {
329 // dynamic cast the Measured ones
330 const Trk::TrackParameters *mtp = *it;
331 if (!mtp || !mtp->covariance()) {
332 continue;
333 }
334 measuredParameters.push_back(*it);
335 }
336
337 // new policy --- take only measured parameters
338 if (measuredParameters.empty()) {
339 return nullptr;
340 }
341
343 // loop over the track parameters and get the distance
344 std::vector<const Trk::TrackParameters *>::const_iterator tpIter = measuredParameters.begin();
345 std::vector<const Trk::TrackParameters *>::const_iterator tpIterEnd = measuredParameters.end();
346 // set a maximum distance
347 double closestDistance = 10e10;
348 const Trk::TrackParameters *currentClosestParameters = nullptr;
349
350 for (; tpIter != tpIterEnd; ++tpIter) {
351 // forward-backward solution
352 Amg::Vector3D tpDirection = (*tpIter)->momentum().normalized();
353
354 Trk::DistanceSolution currentDistance = sf.straightLineDistanceEstimate((*tpIter)->position(), tpDirection);
355 if (currentDistance.numberOfSolutions() > 0) {
356 // get the one/two solution(s)
357 double firstDistance = std::abs(currentDistance.first());
358 double secondDistance = currentDistance.numberOfSolutions() >
359 1 ? std::abs(currentDistance.second()) : firstDistance;
360 // now do the check
361 if (firstDistance < closestDistance || secondDistance < closestDistance) {
362 currentClosestParameters = (*tpIter);
363 closestDistance = firstDistance <= secondDistance ? firstDistance : secondDistance;
364 }
365 }
366 }
367
368 // return what has shown to be closest
369 return currentClosestParameters;
370 }
371
372 if (sf.type() == Trk::SurfaceType::Cylinder) {
373 Trk::TrkParametersComparisonFunction tParFinderCylinder(sf.bounds().r());
374 closestTrackParameters =
375 *(std::min_element(measuredParameters.begin(), measuredParameters.end(),
376 tParFinderCylinder));
377 return closestTrackParameters;
378 }
379
380 if (sf.type() == Trk::SurfaceType::Line ||
381 sf.type() == Trk::SurfaceType::Perigee) {
383 sf.center(), sf.transform().rotation().col(2));
384 closestTrackParameters = *(std::min_element(
385 measuredParameters.begin(), measuredParameters.end(), tParFinderLine));
386 return closestTrackParameters;
387 }
388
389 Trk::TrkParametersComparisonFunction tParFinderCenter(sf.center());
390 closestTrackParameters = *(std::min_element(measuredParameters.begin(), measuredParameters.end(), tParFinderCenter));
391
392 return closestTrackParameters;
393}
394
396Trk::Navigator::trackingGeometry(const EventContext& ctx) const
397{
398 if (m_useConditions) {
400 if (!handle.isValid()) {
401 throw std::runtime_error{
402 "Could not retrieve TrackingGeometry from Conditions Store."
403 };
404 }
405 return handle.cptr();
406 } else {
407 const TrackingGeometry* trackingGeometry = nullptr;
408 if (detStore()
410 .isFailure()) {
411 throw std::runtime_error{
412 "Could not retrieve TrackingGeometry from Detector Store."
413 };
414 }
415 return trackingGeometry;
416 }
417}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
An STL vector of pointers that by default owns its pointed-to elements.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
const ServiceHandle< StoreGateSvc > & detStore() const
DataModel_detail::const_iterator< DataVector > const_iterator
Standard const_iterator.
Definition DataVector.h:838
const_pointer_type cptr()
Description of a BoundarySurface inside the tracking realm, it extends the Surface description to mak...
virtual const Tvol * attachedVolume(const TrackParameters &parms, PropDirection dir) const =0
Get the next Volume depending on the TrackParameters and the requested direction.
virtual const Surface & surfaceRepresentation() const =0
The Surface Representation of this.
Access to distance solutions.
double second() const
Distance to second intersection solution along direction (for a cylinder surface)
double currentDistance(bool signedDist=false) const
Current distance to surface (spatial), signed (along/opposite to surface normal) if input argument tr...
int numberOfSolutions() const
Number of intersection solutions.
double first() const
Distance to first intersection solution along direction.
Interface class IPropagators It inherits from IAlgTool.
Definition IPropagator.h:55
virtual std::unique_ptr< TrackParameters > propagateParameters(const EventContext &ctx, const TrackParameters &parm, const Surface &sf, PropDirection dir, const BoundaryCheck &bcheck, const MagneticFieldProperties &mprop, ParticleHypothesis particle=pion, bool returnCurv=false, const TrackingVolume *tVol=nullptr) const =0
Main propagation method for parameters only.
magnetic field properties to steer the behavior of the extrapolation
Navigator(const std::string &, const std::string &, const IInterface *)
Constructor.
Definition Navigator.cxx:40
std::string m_trackingGeometryName
Name of the TrackingGeometry as given in Detector Store.
Definition Navigator.h:113
Trk::MagneticFieldProperties m_fieldProperties
Definition Navigator.h:123
virtual const TrackParameters * closestParameters(const Track &trk, const Surface &sf) const override final
INavigator interface method - getting the closest TrackParameters from a Track to a Surface.
virtual NavigationCell nextTrackingVolume(const EventContext &ctx, const IPropagator &prop, const TrackParameters &parms, PropDirection dir, const TrackingVolume &vol) const override final
INavigator interface method - getting the next Volume and the parameter for the next Navigation.
ServiceHandle< Trk::ITrackingGeometrySvc > m_trackingGeometrySvc
ToolHandle to the TrackingGeometrySvc.
Definition Navigator.h:110
BooleanProperty m_useStraightLineApproximation
Definition Navigator.h:124
virtual const BoundarySurface< TrackingVolume > * nextBoundarySurface(const EventContext &ctx, const IPropagator &prop, const TrackParameters &parms, PropDirection dir) const override final
INavigator interface methods - getting the next BoundarySurface not knowing the Volume.
Definition Navigator.cxx:86
virtual const TrackingVolume * volume(const EventContext &ctx, const Amg::Vector3D &gp) const override final
INavigator interface methods - global search for the Volume one is in.
Definition Navigator.cxx:74
bool m_useConditions
Definition Navigator.h:122
virtual const TrackingVolume * highestVolume(const EventContext &ctx) const override final
INavigator interface method - forward hightes TrackingVolume.
Definition Navigator.cxx:80
SG::ReadCondHandleKey< TrackingGeometry > m_trackingGeometryReadKey
Definition Navigator.h:105
BooleanProperty m_searchWithDistance
search with new distanceToSurface() method
Definition Navigator.h:128
virtual bool atVolumeBoundary(const Trk::TrackParameters *parms, const Trk::TrackingVolume *vol, Trk::PropDirection dir, const Trk::TrackingVolume *&nextVol, double tol) const override final
INavigator method to resolve navigation at boundary.
virtual StatusCode initialize() override
AlgTool initialize method.
Definition Navigator.cxx:49
virtual const TrackingGeometry * trackingGeometry(const EventContext &ctx) const override final
INavigator interface method - returns the TrackingGeometry used for navigation.
BooleanProperty m_fastField
Definition Navigator.h:131
bool inverseRetrieval() const
const Amg::Vector3D & momentum() const
Access method for the momentum.
virtual ParametersBase< DIM, T > * clone() const override=0
clone method for polymorphic deep copy
const Amg::Vector3D & position() const
Access method for the position.
Abstract Base Class for tracking surfaces.
virtual DistanceSolution straightLineDistanceEstimate(const Amg::Vector3D &pos, const Amg::Vector3D &dir) const =0
fast straight line distance evaluation to Surface
virtual bool isOnSurface(const Amg::Vector3D &glopo, const BoundaryCheck &bchk=true, double tol1=0., double tol2=0.) const
This method returns true if the GlobalPosition is on the Surface for both, within or without check of...
Definition Surface.cxx:123
const DataVector< const TrackParameters > * trackParameters() const
Return a pointer to a vector of TrackParameters.
The TrackingGeometry class is the owner of the constructed TrackingVolumes.
Full Volume description used in Tracking, it inherits from Volume to get the geometrical structure,...
GeometrySignature geometrySignature() const
return the Signature
std::vector< std::shared_ptr< BoundarySurface< TrackingVolume > > > & boundarySurfaces()
Method to return the BoundarySurfaces.
const std::string & volumeName() const
Returns the VolumeName - for debug reason, might be depreciated later.
const BoundarySurface< TrackingVolume > * boundarySurface(const ObjectAccessor::value_type &oa) const
Get the BoundarySurface to the appointed Accessor state.
ObjectAccessor boundarySurfaceAccessor(const Amg::Vector3D &gp, const Amg::Vector3D &mom, bool forceInside=false) const
Provide accessor for BoundarySurfaces.
Definition Volume.cxx:82
Eigen::Matrix< double, 3, 1 > Vector3D
PropDirection
PropDirection, enum for direction of the propagation.
@ oppositeMomentum
@ alongMomentum
BoundarySurfaceFace
Enum to describe the position of the BoundarySurface respectively to the frame orientatin of the volu...
ComparisonFunction< TrackParameters > TrkParametersComparisonFunction
@ FastField
call the fast field access method of the FieldSvc
@ NoField
Field is set to 0., 0., 0.,.
@ FullField
Field is set to be realistic, but within a given Volume.
ParametersBase< TrackParametersDim, Charged > TrackParameters
useful struct for a single navigation cell
Definition INavigator.h:38