Skip to content

Commit 97297fa

Browse files
authored
refactor!: Generalize navigation options for external surfaces (#5243)
Generalizes external surfaces from `Navigator::Options` to `NavigatorPlainOptions` which is the base for all our navigators. This way all navigators fulfill the interface necessary to deal with external surfaces. The `DirectNavigator` now also uses this central external surface list. Also - adapt `Navigator` to handle the new option vs the previous 2 lists - rename `Navigator::State::reset` to `resetForRenavigation` - rename `insertExternalSurface` to `appendExternalSurface` to hit that order is important - improve `appendExternalSurface` doc - downstream changes
1 parent e9c46da commit 97297fa

File tree

9 files changed

+76
-83
lines changed

9 files changed

+76
-83
lines changed

Core/include/Acts/Propagator/DirectNavigator.hpp

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
#include <limits>
2727
#include <memory>
28-
#include <vector>
2928

3029
namespace Acts {
3130

@@ -39,9 +38,6 @@ namespace Acts {
3938
///
4039
class DirectNavigator {
4140
public:
42-
/// The sequentially crossed surfaces
43-
using SurfaceSequence = std::vector<const Surface*>;
44-
4541
/// @brief The nested configuration struct
4642
struct Config {};
4743

@@ -52,9 +48,6 @@ class DirectNavigator {
5248
explicit Options(const GeometryContext& gctx)
5349
: NavigatorPlainOptions(gctx) {}
5450

55-
/// The Surface sequence
56-
SurfaceSequence surfaces;
57-
5851
/// The surface tolerance
5952
double surfaceTolerance = s_onSurfaceTolerance;
6053

@@ -93,7 +86,7 @@ class DirectNavigator {
9386
/// Index of the next surface to try
9487
/// @note -1 means before the first surface in the sequence and size()
9588
/// means after the last surface in the sequence
96-
int surfaceIndex = -1;
89+
std::int32_t surfaceIndex = -1;
9790

9891
/// Navigation state - external interface: the current surface
9992
const Surface* currentSurface = nullptr;
@@ -107,7 +100,7 @@ class DirectNavigator {
107100
/// Get the current navigation surface
108101
/// @return Reference to the surface at the current surface index
109102
const Surface& navSurface() const {
110-
return *options.surfaces.at(surfaceIndex);
103+
return *options.externalSurfaces.at(surfaceIndex);
111104
}
112105

113106
/// Move to the next surface in the sequence
@@ -124,7 +117,8 @@ class DirectNavigator {
124117
/// @return True if no more surfaces remain in the propagation direction
125118
bool endOfSurfaces() const {
126119
if (direction == Direction::Forward()) {
127-
return surfaceIndex >= static_cast<int>(options.surfaces.size());
120+
return surfaceIndex >=
121+
static_cast<int>(options.externalSurfaces.size());
128122
}
129123
return surfaceIndex < 0;
130124
}
@@ -133,7 +127,7 @@ class DirectNavigator {
133127
/// @return Number of surfaces left to process in the propagation direction
134128
int remainingSurfaces() const {
135129
if (direction == Direction::Forward()) {
136-
return options.surfaces.size() - surfaceIndex;
130+
return options.externalSurfaces.size() - surfaceIndex;
137131
}
138132
return surfaceIndex + 1;
139133
}
@@ -144,7 +138,7 @@ class DirectNavigator {
144138
void resetSurfaceIndex() {
145139
surfaceIndex = direction == Direction::Forward()
146140
? -1
147-
: static_cast<int>(options.surfaces.size());
141+
: static_cast<int>(options.externalSurfaces.size());
148142
}
149143
};
150144

@@ -232,7 +226,7 @@ class DirectNavigator {
232226
static_cast<void>(direction);
233227

234228
ACTS_VERBOSE("Initialize. Surface sequence for navigation:");
235-
for (const Surface* surface : state.options.surfaces) {
229+
for (const Surface* surface : state.options.externalSurfaces) {
236230
ACTS_VERBOSE(surface->geometryId()
237231
<< " - "
238232
<< surface->center(state.options.geoContext).transpose());
@@ -251,13 +245,14 @@ class DirectNavigator {
251245
}
252246

253247
// Find initial index.
254-
auto found =
255-
std::ranges::find(state.options.surfaces, state.options.startSurface);
248+
auto found = std::ranges::find(state.options.externalSurfaces,
249+
state.options.startSurface);
256250

257-
if (found != state.options.surfaces.end()) {
251+
if (found != state.options.externalSurfaces.end()) {
258252
// The index should be the index before the start surface, depending on
259253
// the direction
260-
state.surfaceIndex = std::distance(state.options.surfaces.begin(), found);
254+
state.surfaceIndex =
255+
std::distance(state.options.externalSurfaces.begin(), found);
261256
state.surfaceIndex += state.direction == Direction::Backward() ? 1 : -1;
262257
} else {
263258
ACTS_DEBUG(
@@ -300,7 +295,7 @@ class DirectNavigator {
300295
ACTS_VERBOSE("Next surface candidate is "
301296
<< state.navSurface().geometryId() << ". "
302297
<< state.remainingSurfaces() << " out of "
303-
<< state.options.surfaces.size()
298+
<< state.options.externalSurfaces.size()
304299
<< " surfaces remain to try.");
305300

306301
// Establish & update the surface status

Core/include/Acts/Propagator/Navigator.hpp

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88

99
#pragma once
1010

11-
#include "Acts/Definitions/Tolerance.hpp"
1211
#include "Acts/Geometry/GeometryIdentifier.hpp"
1312
#include "Acts/Geometry/Layer.hpp"
1413
#include "Acts/Geometry/TrackingGeometry.hpp"
@@ -94,9 +93,6 @@ class Navigator final {
9493
using NavigationCandidates =
9594
boost::container::small_vector<NavigationTarget, 10>;
9695

97-
/// Type alias for external surfaces container
98-
using ExternalSurfaces = std::vector<GeometryIdentifier>;
99-
10096
/// Type alias for geometry version enumeration
10197
using GeometryVersion = TrackingGeometry::GeometryVersion;
10298

@@ -128,21 +124,6 @@ class Navigator final {
128124
explicit Options(const GeometryContext& gctx)
129125
: NavigatorPlainOptions(gctx) {}
130126

131-
/// Externally provided surfaces - these are tried to be hit
132-
ExternalSurfaces externalSurfaces = {};
133-
/// Surfaces that are not part of the tracking geometry
134-
std::vector<const Surface*> freeSurfaces = {};
135-
136-
/// Insert an external surface to be considered during navigation
137-
/// @param surface: The surface to add to the list
138-
void insertExternalSurface(const Surface& surface) {
139-
if (surface.geometryId() != GeometryIdentifier{}) {
140-
externalSurfaces.push_back(surface.geometryId());
141-
} else {
142-
freeSurfaces.push_back(&surface);
143-
}
144-
}
145-
146127
/// Set the plain navigation options
147128
/// @param options The plain navigator options to set
148129
void setPlainOptions(const NavigatorPlainOptions& options) {
@@ -243,6 +224,9 @@ class Navigator final {
243224
/// Stream for navigation debugging and monitoring
244225
NavigationStream stream;
245226

227+
/// Surfaces that are not part of the tracking geometry
228+
std::vector<const Surface*> freeSurfaces;
229+
246230
/// Reset navigation state after switching layers
247231
void resetAfterLayerSwitch() {
248232
navSurfaces.clear();
@@ -266,19 +250,22 @@ class Navigator final {
266250
}
267251

268252
/// Completely reset navigation state to initial conditions
269-
void reset() {
253+
void resetForRenavigation() {
270254
resetAfterVolumeSwitch();
271255

272256
currentVolume = nullptr;
273257
currentSurface = nullptr;
274258

275259
navigationBreak = false;
276260
navigationStage = Stage::initial;
261+
277262
// Set the surface reached switches back to false
278263
std::ranges::for_each(freeCandidates,
279264
[](std::pair<const Surface*, bool>& freeSurface) {
280265
freeSurface.second = false;
281266
});
267+
268+
stream.reset();
282269
}
283270
};
284271

Core/include/Acts/Propagator/NavigatorOptions.hpp

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,29 @@ struct NavigatorPlainOptions {
4848
/// stream given the current volume and the track coordinates. If the
4949
/// delegate is set, it is called in each candidate resolution step
5050
/// for each surface that has not been marked as reached yet.
51-
/// @param gctx: Current geometry context carrying the alignment information
52-
/// @param currentVol: The current tracking volume in which the propagator resides
53-
/// @param pos: Position of the track in global coordinates
54-
/// @param dir: Direction vector of the track
55-
/// @param surface: Free surface candidate to test
56-
using FreeSurfaceSelctor_t = Delegate<bool(
51+
/// @param gctx Current geometry context carrying the alignment information
52+
/// @param currentVol The current tracking volume in which the propagator resides
53+
/// @param pos Position of the track in global coordinates
54+
/// @param dir Direction vector of the track
55+
/// @param surface Free surface candidate to test
56+
using FreeSurfaceSelctor = Delegate<bool(
5757
const GeometryContext& gctx, const TrackingVolume& currentVol,
5858
const Vector3& pos, const Vector3& dir, const Surface& candidate)>;
59+
5960
/// Delegate for selecting free surfaces during navigation
60-
FreeSurfaceSelctor_t freeSurfaceSelector{};
61+
FreeSurfaceSelctor freeSurfaceSelector;
62+
63+
/// Surfaces that are not part of the tracking geometry
64+
std::vector<const Surface*> externalSurfaces;
65+
66+
/// Append an external surface to be considered during navigation. The surface
67+
/// will be intersected without bounds check to force the propagation to
68+
/// resolve it. Note the surface must outlive the propagation and surfaces
69+
/// have to be added in the order they should be considered during navigation.
70+
/// @param surface The surface to add to the list
71+
void appendExternalSurface(const Surface& surface) {
72+
externalSurfaces.push_back(&surface);
73+
}
6174
};
6275

6376
} // namespace Acts

Core/include/Acts/TrackFitting/GaussianSumFitter.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ struct GaussianSumFitter {
116116

117117
propOptions.setPlainOptions(opts.propagatorPlainOptions);
118118

119-
propOptions.navigation.surfaces = sSequence;
119+
propOptions.navigation.externalSurfaces = sSequence;
120120
propOptions.actorList.template get<GsfActor>()
121121
.m_cfg.bethe_heitler_approx = m_betheHeitlerApproximation.get();
122122

@@ -132,7 +132,7 @@ struct GaussianSumFitter {
132132

133133
propOptions.setPlainOptions(opts.propagatorPlainOptions);
134134

135-
propOptions.navigation.surfaces = sSequence;
135+
propOptions.navigation.externalSurfaces = sSequence;
136136
propOptions.actorList.template get<GsfActor>()
137137
.m_cfg.bethe_heitler_approx = m_betheHeitlerApproximation.get();
138138

@@ -170,7 +170,7 @@ struct GaussianSumFitter {
170170

171171
if (options.useExternalSurfaces) {
172172
for (auto it = begin; it != end; ++it) {
173-
propOptions.navigation.insertExternalSurface(
173+
propOptions.navigation.appendExternalSurface(
174174
*options.extensions.surfaceAccessor(*it));
175175
}
176176
}
@@ -192,7 +192,7 @@ struct GaussianSumFitter {
192192

193193
if (options.useExternalSurfaces) {
194194
for (auto it = begin; it != end; ++it) {
195-
propOptions.navigation.insertExternalSurface(
195+
propOptions.navigation.appendExternalSurface(
196196
*options.extensions.surfaceAccessor(*it));
197197
}
198198
}

Core/include/Acts/TrackFitting/GlobalChiSquareFitter.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,7 +1264,7 @@ class Gx2Fitter {
12641264
// Add the measurement surface as external surface to the navigator.
12651265
// We will try to hit those surface by ignoring boundary checks.
12661266
for (const auto& [surface, _] : inputMeasurements) {
1267-
propagatorOptions.navigation.insertExternalSurface(*surface);
1267+
propagatorOptions.navigation.appendExternalSurface(*surface);
12681268
}
12691269

12701270
auto& gx2fActor = propagatorOptions.actorList.template get<GX2FActor>();
@@ -1430,7 +1430,7 @@ class Gx2Fitter {
14301430
// Add the measurement surface as external surface to the navigator.
14311431
// We will try to hit those surface by ignoring boundary checks.
14321432
for (const auto& [surface, _] : inputMeasurements) {
1433-
propagatorOptions.navigation.insertExternalSurface(*surface);
1433+
propagatorOptions.navigation.appendExternalSurface(*surface);
14341434
}
14351435

14361436
auto& gx2fActor = propagatorOptions.actorList.template get<GX2FActor>();

Core/include/Acts/TrackFitting/KalmanFitter.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -745,13 +745,13 @@ class KalmanFitter {
745745
// Add the measurement surface as external surface to navigator.
746746
// We will try to hit those surface by ignoring boundary checks.
747747
for (const auto& [surface, _] : inputMeasurements) {
748-
propagatorOptions.navigation.insertExternalSurface(*surface);
748+
propagatorOptions.navigation.appendExternalSurface(*surface);
749749
}
750750
} else {
751751
assert(sSequence != nullptr &&
752752
"DirectNavigator requires a surface sequence for KalmanFitter");
753753
// Set the surface sequence
754-
propagatorOptions.navigation.surfaces = *sSequence;
754+
propagatorOptions.navigation.externalSurfaces = *sSequence;
755755
}
756756

757757
// Catch the actor and set the measurements

Core/src/Navigation/Navigator.cpp

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include "Acts/Definitions/Units.hpp"
1212
#include "Acts/Geometry/BoundarySurfaceT.hpp"
13+
#include "Acts/Geometry/GeometryIdentifier.hpp"
1314
#include "Acts/Geometry/Portal.hpp"
1415
#include "Acts/Propagator/NavigatorError.hpp"
1516
#include "Acts/Surfaces/Surface.hpp"
@@ -89,7 +90,7 @@ Result<void> Navigator::initialize(State& state, const Vector3& position,
8990
ACTS_VERBOSE(volInfo(state) << "Geometry version is: "
9091
<< printGeometryVersion(m_geometryVersion));
9192

92-
state.reset();
93+
state.resetForRenavigation();
9394

9495
if (m_geometryVersion == GeometryVersion::Gen3) {
9596
// Empirical pre-allocation of candidates for the next navigation
@@ -98,9 +99,11 @@ Result<void> Navigator::initialize(State& state, const Vector3& position,
9899
state.stream.candidates().reserve(50);
99100

100101
state.freeCandidates.clear();
101-
state.freeCandidates.reserve(state.options.freeSurfaces.size());
102-
for (const Surface* candidate : state.options.freeSurfaces) {
103-
state.freeCandidates.emplace_back(candidate, false);
102+
state.freeCandidates.reserve(state.options.externalSurfaces.size());
103+
for (const Surface* candidate : state.options.externalSurfaces) {
104+
if (candidate->geometryId() == GeometryIdentifier{}) {
105+
state.freeCandidates.emplace_back(candidate, false);
106+
}
104107
}
105108
}
106109

@@ -215,7 +218,7 @@ NavigationTarget Navigator::nextTarget(State& state, const Vector3& position,
215218
return nextTarget;
216219
}
217220

218-
state.reset();
221+
state.resetForRenavigation();
219222
++state.statistics.nRenavigations;
220223

221224
// We might have punched through a boundary and entered another volume
@@ -573,20 +576,16 @@ void Navigator::resolveCandidates(State& state, const Vector3& position,
573576

574577
ACTS_VERBOSE(volInfo(state) << "Found " << state.stream.candidates().size()
575578
<< " navigation candidates.");
576-
if (!state.options.externalSurfaces.empty()) {
577-
for (const GeometryIdentifier& geoId : state.options.externalSurfaces) {
578-
// Don't add any surface which is not in the same volume (volume bits)
579-
// or sub volume (extra bits)
580-
if (geoId.volume() != state.currentVolume->geometryId().volume() ||
581-
geoId.extra() != state.currentVolume->geometryId().extra()) {
582-
continue;
583-
}
584-
const Surface* surface = m_cfg.trackingGeometry->findSurface(geoId);
585-
assert(surface != nullptr);
586-
ACTS_VERBOSE(volInfo(state) << "Try to navigate to " << surface->type()
587-
<< " surface " << geoId);
588-
appendOnly.addSurfaceCandidate(*surface, BoundaryTolerance::Infinite());
589-
};
579+
for (const Surface* surface : state.options.externalSurfaces) {
580+
const GeometryIdentifier geoId = surface->geometryId();
581+
// Don't add any surface which is not in the same volume (volume bits)
582+
// or sub volume (extra bits)
583+
if (geoId.withSensitive(0) != state.currentVolume->geometryId()) {
584+
continue;
585+
}
586+
ACTS_VERBOSE(volInfo(state) << "Try to navigate to " << surface->type()
587+
<< " surface " << geoId);
588+
appendOnly.addSurfaceCandidate(*surface, BoundaryTolerance::Infinite());
590589
}
591590
bool pruneFreeCand{false};
592591
if (!state.freeCandidates.empty()) {
@@ -681,12 +680,11 @@ void Navigator::resolveSurfaces(State& state, const Vector3& position,
681680
navOpts.nearLimit = state.options.nearLimit;
682681
navOpts.farLimit = state.options.farLimit;
683682

684-
if (!state.options.externalSurfaces.empty()) {
685-
const auto layerId = layerSurface->geometryId().layer();
686-
for (const GeometryIdentifier& id : state.options.externalSurfaces) {
687-
if (id.layer() == layerId) {
688-
navOpts.externalSurfaces.push_back(id);
689-
}
683+
const auto layerId = layerSurface->geometryId().layer();
684+
for (const Surface* surface : state.options.externalSurfaces) {
685+
const GeometryIdentifier geoId = surface->geometryId();
686+
if (geoId.layer() == layerId) {
687+
navOpts.externalSurfaces.push_back(geoId);
690688
}
691689
}
692690

Tests/UnitTests/Core/Propagator/DirectNavigatorTests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ void runTest(const rpropagator_t& rprop, const dpropagator_t& dprop, double pT,
147147
typename dpropagator_t::template Options<DirectActorList>;
148148
DirectOptions dOptions(tgContext, mfContext);
149149
// Set the surface sequence
150-
dOptions.navigation.surfaces = surfaceSequence;
150+
dOptions.navigation.externalSurfaces = surfaceSequence;
151151
// Surface collector configuration
152152
auto& dCollector = dOptions.actorList.template get<SurfaceCollector<>>();
153153
dCollector.selector.selectSensitive = true;
@@ -239,7 +239,7 @@ void runSimpleTest(const std::vector<const Surface*>& surfaces,
239239
DirectNavigator>::template Options<DirectActorList>;
240240
DirectOptions pOptions(tgContext, mfContext);
241241
pOptions.direction = direction;
242-
pOptions.navigation.surfaces = surfaces;
242+
pOptions.navigation.externalSurfaces = surfaces;
243243
pOptions.navigation.startSurface = startSurface;
244244
auto& dCollector = pOptions.actorList.template get<SurfaceCollector<>>();
245245
dCollector.selector.selectSensitive = true;

0 commit comments

Comments
 (0)