Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!: Decouple navigation and stepping #3449

Open
wants to merge 38 commits into
base: main
Choose a base branch
from

Conversation

andiwand
Copy link
Contributor

@andiwand andiwand commented Jul 27, 2024

This is a proposal to decouple navigation from stepping by

  • changing the navigator interface to only consume its state and not the propagation state
  • providing position and direction as an input to the navigation
  • putting the Propagator in charge of communicating the target and estimated distance to the stepper

Originally I wanted the navigator to return the next step size but that clashes with the multi stepper. The current solution allows the stepper to judge on the step size given a surface. This allows the stepper to tweak the step size or to just take what the navigator proposed. In case of the multi stepper we will still just run intersections with the individual components.

The navigator is reduced to providing surface candidates and the surface status will be purely determined by the stepper. The propagator passes the information so the navigator knows when to switch surface / layer / volume.

Ultimately this removes all the templating from the navigator and the interface captures well what the navigator is supposed to do by having dedicated and visible I/O paths.

In case this is where we want to go I would like to do something similar to the steppers.

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced NavigationTarget struct for better surface navigation handling.
    • Enhanced Navigator and DirectNavigator classes with improved target estimation and state management.
    • Added new methods for initializing navigation with position and direction parameters.
  • Bug Fixes

    • Improved error handling and target validation in the propagation process.
  • Tests

    • Streamlined test cases for navigation consistency and improved logging for better traceability.
    • Updated tests to reflect changes in method signatures and navigation logic.
  • Documentation

    • Enhanced comments and documentation for clarity in navigation classes and methods.

@andiwand andiwand added Needs Decision Needs decision or further information 🚧 WIP Work-in-progress labels Jul 27, 2024
@github-actions github-actions bot added Component - Core Affects the Core module Infrastructure Changes to build tools, continous integration, ... Component - Examples Affects the Examples module Track Finding Track Fitting labels Jul 27, 2024
@andiwand andiwand added this to the v37.0.0 milestone Jul 27, 2024
Copy link

github-actions bot commented Jul 28, 2024

📊: Physics performance monitoring for 004ed2c

Full contents

physmon summary

@andiwand andiwand force-pushed the decouple-navigation-stepping branch from 901d3e4 to cf443f5 Compare August 19, 2024 14:45
@github-actions github-actions bot removed the Infrastructure Changes to build tools, continous integration, ... label Aug 19, 2024
@andiwand andiwand force-pushed the decouple-navigation-stepping branch from cf443f5 to b2ef11b Compare August 19, 2024 15:02
@github-actions github-actions bot added the Infrastructure Changes to build tools, continous integration, ... label Aug 19, 2024
@andiwand andiwand force-pushed the decouple-navigation-stepping branch from 474eeca to b680a36 Compare August 20, 2024 06:07
@github-actions github-actions bot removed Infrastructure Changes to build tools, continous integration, ... Component - Examples Affects the Examples module Track Finding Track Fitting labels Aug 20, 2024
@andiwand andiwand force-pushed the decouple-navigation-stepping branch from f1eb04c to 3c2406b Compare August 21, 2024 11:53
@github-actions github-actions bot removed the Infrastructure Changes to build tools, continous integration, ... label Nov 25, 2024
@andiwand andiwand marked this pull request as ready for review November 25, 2024 16:30
@acts-project-service acts-project-service added the Fails Athena tests This PR causes a failure in the Athena tests label Nov 25, 2024
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 15

🧹 Outside diff range and nitpick comments (30)
Core/include/Acts/Propagator/NavigatorOptions.hpp (1)

19-24: Strong with the Force, this implementation is!

Reference wrapper for geometry context, wisely chosen it was. But documentation, improved it could be, young padawan.

Apply this documentation enhancement:

-  /// NavigatorPlainOptions with context
+  /// @brief Constructs navigator options with geometry context
+  /// @param gctx The geometry context to be used during navigation
   explicit NavigatorPlainOptions(const GeometryContext &gctx)
Core/include/Acts/Propagator/StepperOptions.hpp (1)

25-25: Hmmmm... More reasonable default step size, this is!

From unlimited steps to 10 meters, we go. Safer and more controlled propagation, this brings. Prevent excessive steps in particle tracking, it will. With the Force of explicit units through UnitConstants::m, clarity achieved, it is.

Consider documenting in comments why 10 meters was chosen as the default value, help future Padawans, it will.

Core/include/Acts/Propagator/NavigationTarget.hpp (3)

19-23: Documentation for the struct and its members, missing it is.

Add documentation, you must:

  • Purpose of the NavigationTarget struct
  • Meaning of surfaceIntersectionIndex
  • Impact of boundaryTolerance on navigation

Apply this diff, you should:

 namespace Acts {
 
 class Surface;
 
+/// @brief Represents a navigation target with its associated properties
+/// @details Used by navigator implementations to communicate target surfaces
+/// and their properties to the propagation system
 struct NavigationTarget {
+  /// Pointer to the target surface
   const Surface* surface = nullptr;
+  /// Index of the surface intersection to be considered
   std::uint8_t surfaceIntersectionIndex = 0;
+  /// Tolerance to be applied at surface boundaries
   BoundaryTolerance boundaryTolerance = BoundaryTolerance::None();

24-37: Improvements to method signatures and move semantics, suggest I do.

Good, the basic implementation is. Yet, enhance it further, we can:

  • Mark invalid() as noexcept
  • Use perfect forwarding for boundaryTolerance_
  • Mark isValid() as noexcept

Apply these changes, you should:

-  static NavigationTarget invalid() { return NavigationTarget(); }
+  static NavigationTarget invalid() noexcept { return NavigationTarget(); }

   NavigationTarget(const Surface& surface_,
                    std::uint8_t surfaceIntersectionIndex_,
-                   BoundaryTolerance boundaryTolerance_)
+                   BoundaryTolerance&& boundaryTolerance_)
       : surface(&surface_),
         surfaceIntersectionIndex(surfaceIntersectionIndex_),
-        boundaryTolerance(std::move(boundaryTolerance_)) {}
+        boundaryTolerance(std::forward<BoundaryTolerance>(boundaryTolerance_)) {}

-  bool isValid() const { return surface != nullptr; }
+  bool isValid() const noexcept { return surface != nullptr; }

19-38: Well-aligned with decoupling objectives, this struct is.

Clear separation of concerns, you have achieved:

  • Navigation target representation, isolated it is
  • Template-free interface, you have created
  • Clean boundary between navigation and stepping, established you have

Strong foundation for future Gen3 navigator, this provides. Pleased with this architectural direction, Master Paulgessinger was, hmm.

Core/include/Acts/Propagator/PropagatorState.hpp (1)

66-70: Document the new members, you should!

Good additions these Vector3 members are, aligning with the decoupling objectives they do. Yet, documentation for their purpose and usage, missing it is.

Add documentation like this, you should:

+  /// The current position in the global coordinate system
   Vector3 position = Vector3::Zero();

+  /// The current direction in the global coordinate system
   Vector3 direction = Vector3::Zero();
Core/include/Acts/Propagator/detail/SteppingHelper.hpp (2)

50-51: Wisdom in this change, I sense.

Responsibility for step size to the stepper, we now give. Clear separation of concerns, this brings. Hmmmm.


56-56: Document the wisdom behind unlimited boundaries, we should.

Clear the code is, yet documentation of intent, missing it remains. Add a comment explaining why maximum limit chosen was, young padawan.

+  // Use maximum possible range for intersection checks to allow stepper full control
   const double farLimit = std::numeric_limits<double>::max();
Core/include/Acts/Propagator/PropagatorOptions.hpp (1)

95-97: Reorder the initialization list, we should.

Though correct the implementation is, optimize the initialization order we can. Member variables in declaration order, initialize them we should.

Apply this change, you should:

  PropagatorOptions(const PropagatorPlainOptions& pOptions)
      : geoContext(pOptions.geoContext),
-       magFieldContext(pOptions.magFieldContext),
-       navigation(pOptions.geoContext) {
+       navigation(pOptions.geoContext),
+       magFieldContext(pOptions.magFieldContext) {
    setPlainOptions(pOptions);
  }

Match the order of member declarations this will, prevent potential compiler warnings it does.

Core/include/Acts/Propagator/detail/NavigationHelpers.hpp (2)

61-68: Clear separation of concerns, achieved we have!

Renamed and restructured, this navigation object is. Better reflects its purpose, the new name does. Separation between intersection and navigation logic, maintained it is. With the force of clean architecture, strong this change is!

Remember we must: This change supports the greater mission of decoupling navigation from stepping, as mentioned in PR objectives. A path to cleaner interfaces, this is.

Also applies to: 83-84


Line range hint 1-158: Wisdom about boundary tolerance, share I must.

Consistent handling of boundary tolerance throughout navigation system, crucial it is. As decouple navigation and stepping we do, consider we should:

  • Documenting boundary tolerance behavior in navigation interfaces
  • Ensuring consistent tolerance application across navigation boundaries
  • Making tolerance configuration more explicit in navigation setup

Help with implementing these suggestions, offer I do. Create detailed design document for boundary tolerance handling, shall we?

Core/include/Acts/Propagator/EigenStepper.hpp (1)

Line range hint 1-600: Hmmmm... Architectural wisdom, share I must!

Well-aligned with the decoupling mission, these changes are. But careful we must be! When propagating through the detector, the step size, a critical parameter it is. Monitor the propagation behavior in integration tests, you should.

To the dark side of infinite step sizes, returned we must not. A reasonable default, established we have. But flexible enough for specific use cases, remain we must.

Tests/UnitTests/Core/Propagator/PropagatorTests.cpp (2)

Line range hint 171-187: Constants as named variables, define them we should!

Magic numbers in test parameters, I sense. More readable and maintainable, the code would be, if constants were named.

+ // Test configuration constants
+ constexpr double MIN_PT = 0.4_GeV;
+ constexpr double MAX_PT = 10_GeV;
+ constexpr double MIN_THETA = 1.;
+ constexpr double MAX_THETA = std::numbers::pi - 1.;
+ constexpr double MIN_TIME = -1_ns;
+ constexpr double MAX_TIME = 1_ns;

  BOOST_DATA_TEST_CASE(
    cylinder_passage_observer_,
    bdata::random((bdata::engine = std::mt19937(), bdata::seed = 0,
-                  bdata::distribution = std::uniform_real_distribution<double>(
-                      0.4_GeV, 10_GeV))) ^
+                  bdata::distribution = std::uniform_real_distribution<double>(
+                      MIN_PT, MAX_PT))) ^

Line range hint 249-252: Document test coverage strategy, we must!

Missing documentation about the test coverage strategy and the significance of the chosen test parameters, I observe. Help future maintainers understand the test design, this would.

+ // Test strategy:
+ // - Tests propagation additivity by comparing single-step vs multi-step results
+ // - Validates both position and covariance matrix transport
+ // - Uses random parameters to ensure coverage of different particle trajectories
  BOOST_DATA_TEST_CASE(
    curvilinear_additive_,
Core/include/Acts/TrackFitting/GaussianSumFitter.hpp (2)

94-94: Approve the simplified actor list for DirectNavigator, I do.

Clean and focused, the actor list becomes. Removed NavigationBreakAborter is, as navigation decisions to the stepper now belong.

Wise decision this is, aligning with the decoupling strategy. Clearer responsibilities between navigation and stepping, it creates.


Line range hint 1-450: Architectural guidance on the decoupling strategy, provide I must.

Strong in the Force, this refactoring is. Clear separation of concerns between navigation and stepping, it achieves. Benefits observed:

  1. Cleaner interface boundaries
  2. Improved single responsibility principle
  3. Enhanced flexibility in stepping decisions
  4. Reduced coupling between components

Yet, careful we must be:

  1. Document the new responsibility boundaries in comments, you should
  2. Consider adding runtime assertions to prevent accidental navigation state access
  3. Update integration tests to verify the decoupling remains intact
Tests/IntegrationTests/NavigatorConsistency.cpp (4)

308-317: Well-structured type definitions, these are!

Yet, document the differences between Reference1 and Reference2 propagators, we should.

Add comments explaining the purpose and differences between Reference1 and Reference2 propagators:

+// Reference1 propagators use TryAllNavigator for exhaustive surface testing
 using Reference1StraightLinePropagator =
     Propagator<StraightLineStepper, TryAllNavigator>;
 using Reference1EigenPropagator = Propagator<EigenStepper, TryAllNavigator>;

+// Reference2 propagators use TryAllOverstepNavigator for testing with overstepping
 using Reference2StraightLinePropagator =
     Propagator<StraightLineStepper, TryAllOverstepNavigator>;
 using Reference2EigenPropagator =
     Propagator<EigenStepper, TryAllOverstepNavigator>;

370-376: Encapsulate parameter creation well, this function does. Yet validate input parameters, it should!

Add parameter validation to prevent invalid physics parameters:

 CurvilinearTrackParameters createStartParameters(double pT, double phi,
                                                  double theta, int charge) {
+  if (pT <= 0) {
+    throw std::invalid_argument("pT must be positive");
+  }
+  if (theta <= 0 || theta >= std::numbers::pi) {
+    throw std::invalid_argument("theta must be in (0, pi)");
+  }
+  if (charge != -1 && charge != 1) {
+    throw std::invalid_argument("charge must be -1 or 1");
+  }
   double p = pT / std::sin(theta);
   double q = -1 + 2 * charge;
   return CurvilinearTrackParameters(Vector4(0, 0, 0, 0), phi, theta, q / p,
                                     std::nullopt, ParticleHypothesis::pion());
 }

378-472: Well-structured test cases, these are. Yet reduce duplication, we must!

Extract common setup into a fixture:

+struct NavigatorTestFixture {
+  NavigatorTestFixture() {
+    ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel))
+  }
+
+  void runTest(double pT, double phi, double theta, int charge, int index) {
+    CurvilinearTrackParameters start =
+        createStartParameters(pT, phi, theta, charge);
+
+    ACTS_DEBUG(">>> Run navigation tests with:\n    pT = "
+               << pT << "\n    phi = " << phi << "\n    theta = " << theta
+               << "\n    charge = " << charge << "\n    index = " << index);
+
+    return start;
+  }
+};

 BOOST_DATA_TEST_CASE(NavigatorStraightLineSelfConsistency,
                      eventGen ^ bdata::xrange(nTestsSelfConsistency),
                      pT, phi, theta, charge, index) {
-  ACTS_LOCAL_LOGGER(Acts::getDefaultLogger("NavigatorTest", logLevel))
-  CurvilinearTrackParameters start =
-      createStartParameters(pT, phi, theta, charge);
-  ACTS_DEBUG(">>> Run navigation tests with:\n    pT = "...)
+  NavigatorTestFixture fixture;
+  auto start = fixture.runTest(pT, phi, theta, charge, index);
   runSelfConsistencyTest(slpropagator, start, logger());
 }
🧰 Tools
🪛 cppcheck (2.10-2)

[error] 378-378: syntax error

(syntaxError)


Line range hint 192-192: Incomplete tests, these TODO comments indicate!

Address the forward-forward and backward-backward step compatibility tests, we must.

Would you like me to help implement these missing test cases? Open a GitHub issue to track this task, I can.

Also applies to: 217-217

Tests/UnitTests/Core/Navigation/DetectorNavigatorTests.cpp (1)

124-126: Wise renaming, this is!

From preStep to estimateNextTarget, changed the method has been. Better reflects its true purpose, it does. Consistent with the initialization parameters, it remains. Strong with the Force, this change is!

A good pattern this establishes, where navigation concerns from stepping logic, separated they are. In future changes, follow this pattern we should.

Core/include/Acts/TrackFitting/detail/GsfActor.hpp (1)

322-333: Clean and focused implementation, this is! Hmmmm.

Well-structured the new checkAbort method is, matching class patterns it does. But documentation, missing it is!

Add this documentation block before the method, suggest I do:

/// @brief Check if the navigation should be aborted
/// @param state The propagator state
/// @param stepper The stepper instance
/// @param navigator The navigator instance
/// @param result The GSF result object
/// @param logger The logger instance
/// @return true if navigation should be aborted, false otherwise
Core/include/Acts/TrackFitting/KalmanFitter.hpp (1)

565-567: Wisdom for the future path, share I must.

Good steps towards decoupling, these changes are. But further clarity, achieve we can. When ready you are, similar approach to steppers apply you should. Clear boundaries between components, lead to better design they do.

Also applies to: 1049-1051

Core/include/Acts/Propagator/DirectNavigator.hpp (1)

30-37: Clarity in comments, improve we must.

The comment uses "either" with more than two options, inconsistent it is. Consider rephrasing for clarity.

Suggested change:

 /// This can either be used as a validation tool, for truth tracking, or track
-/// refitting.
+/// refitting.

Or rephrase:

 /// This can be used as a validation tool, for truth tracking, or for track
 /// refitting.
Core/include/Acts/Navigation/DetectorNavigator.hpp (2)

119-142: Initialize Method Refactored, Carefully You Have

The initialize method now position and direction accepts, setting up the state correctly. Unused parameter propagationDirection there is. If needed not, consider removing it you should.


194-201: 'checkTargetValid' Always Returns True, It Does

Currently, unconditionally true checkTargetValid returns. Implement validation logic, perhaps you should, or unnecessary if it is, remove the method.

Tests/UnitTests/Core/Propagator/NavigatorTests.cpp (1)

85-96: Remove debug print statements, you should.

Unnecessary, the 'std::cout' statements are. Clean the code by removing or replacing them with proper logging, you must.

Core/include/Acts/Propagator/Propagator.ipp (1)

88-160: Stepping loop structure sound is, but consider modularization

Handles propagation steps correctly, the loop does. Yet, lengthy it is. For readability and maintainability, consider refactoring into smaller functions, you should.

Core/include/Acts/Propagator/VoidNavigator.hpp (2)

65-69: Empty initialize method, necessary is it?

No operations the initialize method performs. If required for interface compliance it is, acceptable this may be. Else, consider removing to eliminate redundancy, you might.


82-86: Empty handleSurfaceReached method, intended this is?

Does nothing the handleSurfaceReached method does. If to satisfy interface requirements, you include it, acceptable this is. Otherwise, consider omitting unnecessary code, you should.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 2e74ffa and 004ed2c.

📒 Files selected for processing (26)
  • Core/include/Acts/Navigation/DetectorNavigator.hpp (8 hunks)
  • Core/include/Acts/Navigation/NavigationState.hpp (0 hunks)
  • Core/include/Acts/Propagator/DirectNavigator.hpp (6 hunks)
  • Core/include/Acts/Propagator/EigenStepper.hpp (3 hunks)
  • Core/include/Acts/Propagator/NavigationTarget.hpp (1 hunks)
  • Core/include/Acts/Propagator/Navigator.hpp (9 hunks)
  • Core/include/Acts/Propagator/NavigatorOptions.hpp (1 hunks)
  • Core/include/Acts/Propagator/Propagator.hpp (0 hunks)
  • Core/include/Acts/Propagator/Propagator.ipp (3 hunks)
  • Core/include/Acts/Propagator/PropagatorOptions.hpp (2 hunks)
  • Core/include/Acts/Propagator/PropagatorState.hpp (2 hunks)
  • Core/include/Acts/Propagator/StepperOptions.hpp (2 hunks)
  • Core/include/Acts/Propagator/TryAllNavigator.hpp (15 hunks)
  • Core/include/Acts/Propagator/VoidNavigator.hpp (2 hunks)
  • Core/include/Acts/Propagator/detail/NavigationHelpers.hpp (4 hunks)
  • Core/include/Acts/Propagator/detail/SteppingHelper.hpp (1 hunks)
  • Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp (1 hunks)
  • Core/include/Acts/TrackFitting/GaussianSumFitter.hpp (2 hunks)
  • Core/include/Acts/TrackFitting/KalmanFitter.hpp (2 hunks)
  • Core/include/Acts/TrackFitting/detail/GsfActor.hpp (1 hunks)
  • Tests/IntegrationTests/NavigatorConsistency.cpp (4 hunks)
  • Tests/UnitTests/Core/Navigation/DetectorNavigatorTests.cpp (2 hunks)
  • Tests/UnitTests/Core/Propagator/DirectNavigatorTests.cpp (0 hunks)
  • Tests/UnitTests/Core/Propagator/NavigatorTests.cpp (8 hunks)
  • Tests/UnitTests/Core/Propagator/PropagatorTests.cpp (1 hunks)
  • Tests/UnitTests/Fatras/Kernel/SimulationActorTests.cpp (0 hunks)
💤 Files with no reviewable changes (4)
  • Core/include/Acts/Navigation/NavigationState.hpp
  • Core/include/Acts/Propagator/Propagator.hpp
  • Tests/UnitTests/Core/Propagator/DirectNavigatorTests.cpp
  • Tests/UnitTests/Fatras/Kernel/SimulationActorTests.cpp
🧰 Additional context used
🪛 cppcheck (2.10-2)
Tests/IntegrationTests/NavigatorConsistency.cpp

[error] 378-378: syntax error

(syntaxError)

🔇 Additional comments (48)
Core/include/Acts/Propagator/NavigatorOptions.hpp (2)

11-15: Wise choices in header management, these are!

Forward declaration and minimal include, follow best practices they do. Compilation times, reduced they will be, hmmmm.


19-25: Verify the Force flows through all navigators, we must!

Ensure all navigator implementations, properly initialized with geometry context they are.

✅ Verification successful

Strong with the Force, all navigators are!

Verified, I have, that proper handling of geometry context flows through all navigator implementations:

  • DetectorNavigator, properly inherits and initializes it does
  • VoidNavigator, follows the sacred ways it does
  • DirectNavigator, maintains the balance it does
  • TryAllNavigator, respects the geometry context it does
  • Base Navigator class, sets the foundation for all it does

Through the Force, seen I have that each navigator:

  • Inherits from NavigatorPlainOptions they do
  • Explicit constructor with geometry context they possess
  • Proper setPlainOptions implementation they maintain

Clouded by darkness, this concern is not. Clear implementation pattern, observed throughout the codebase it is.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for navigator implementations to verify geometry context usage
ast-grep --pattern 'class $_ : public Navigator {
  $$$
}'

# Search for NavigatorPlainOptions usage
rg -A 5 "NavigatorPlainOptions"

Length of output: 6839

Core/include/Acts/Propagator/StepperOptions.hpp (2)

11-11: Wise addition of Units.hpp, this is!

Clear and explicit units handling, it brings. Good practices in physics code, this follows.


25-25: Verify consistency across the codebase, we must!

Check other steppers for alignment with this new default, we should.

✅ Verification successful

Consistent with the Force, the step sizes are

Through the Force, searched the codebase I have. Different steppers, different defaults they maintain:

  • EigenStepper: 10m default, matches the new value it does
  • AtlasStepper, SympyStepper, StraightLineStepper, MultiEigenStepperLoop: std::numeric_limits::max() they use

Hmm, natural this divergence is. Different steppers, different purposes they serve. The default in StepperOptions.hpp, a reasonable choice it remains, as:

  • Common base value it provides
  • Override it, specific steppers still can
  • In practice, propagator configurations often customize this value they do
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other step size definitions in stepper files
echo "Searching for step size definitions in other files..."
rg -A 2 "maxStepSize|ssize.*=.*m" Core/include/Acts/

Length of output: 5141

Core/include/Acts/Propagator/NavigationTarget.hpp (1)

1-18: Proper structure and minimal dependencies, I sense.

Well-organized, the file header is. Minimal dependencies and proper forward declarations, you have used. Strong with the Force, this code organization is.

Core/include/Acts/Propagator/PropagatorState.hpp (3)

11-11: Wise addition of Algebra.hpp, it is!

For the Vector3 definitions, necessary this include has become. Clear and purposeful, the dependency is.


57-58: Efficient use of reference_wrapper, I sense!

Prevent unnecessary copying of the GeometryContext, this change does. Memory efficiency, achieved it has.


63-65: Organized better, the member variables now are!

Logical grouping of related members, achieved we have. Clear structure, it provides.

Core/include/Acts/Propagator/detail/SteppingHelper.hpp (1)

50-56: Strong with the Force, this refactoring is.

A clear path to multi-stepper design, these changes create. Decoupled the navigation from stepping, we have. Hmmmm, yes. Future modifications, easier they will be.

Two suggestions for the path ahead:

  1. Consider adding debug assertions to validate step size updates
  2. Document the new stepping behavior in class documentation

Run this script to check for similar patterns that might need updating:

✅ Verification successful

Hmmmm, clear the path forward is now

Through the Force, seen the codebase patterns I have. No immediate concerns do I sense. The surface intersection pattern, consistent it remains across the codebase. The step size management, already well-handled it is.

Two observations, share I must:

  • In test files and benchmarks only, the basic intersection pattern appears
  • In core navigation components, proper boundary and surface tolerances, always used they are

The original changes, wisdom they show:

  • Clean separation of concerns, maintained it is
  • Proper error handling and tolerances, preserved they are
  • Multi-stepper design, supported it remains
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for similar step size management patterns that might need updating
ast-grep --pattern 'stepSize.release($$$)'

# Look for other intersection handlers that might need similar updates
ast-grep --pattern 'surface.intersect($$$)'

Length of output: 4744

Core/include/Acts/Propagator/PropagatorOptions.hpp (3)

61-61: Hmmmm, good this initialization is!

Proper initialization of navigation with geometry context, I see. Clear separation of concerns, this brings. Balance to the Force, it does restore.


91-91: Consistent with its plain cousin, this constructor is!

Mirror the wisdom of PropagatorPlainOptions, it does. Harmony in the codebase, this brings.


Line range hint 61-97: Verify the navigation changes across the galaxy, we must.

Changes align with the great mission of decoupling, they do. But verify the impact on other parts of the codebase, we should.

✅ Verification successful

Let me examine these patterns to ensure the navigation changes are harmonious with the Force, they are.


Deeper into the codebase, we must look. The Force guides us to examine the test implementations and core components, it does.


Safe, these navigation changes are, hmm.

Through the Force, seen the truth I have. The changes to PropagatorOptions align with the great decoupling mission, they do. No disturbance in the Force, I sense:

  • Properly encapsulated, the navigation initialization is
  • Consistent with the navigation framework changes, the implementation remains
  • In harmony with the existing usage patterns across the codebase, these modifications are

The extensive navigation-related changes in the codebase show deliberate and coordinated effort, they do. Part of a larger navigation framework enhancement, this change is.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for navigation-related changes in other files
echo "Search for files using PropagatorOptions we shall..."
rg -l "PropagatorOptions" | grep -v "PropagatorOptions.hpp"

echo "\nSearch for navigation initialization patterns we must..."
ast-grep --pattern 'navigation($$$)' 

Length of output: 1803


Script:

#!/bin/bash
# Check the usage patterns of PropagatorOptions in key files
echo "Examine the PropagatorOptions usage in Propagator.hpp, we shall..."
rg -A 5 "PropagatorOptions" "Core/include/Acts/Propagator/Propagator.hpp"

echo "\nInspect the navigation initialization in tests, we must..."
rg -A 5 "navigation" "Tests/UnitTests/Core/Propagator/PropagatorTests.cpp"

echo "\nSearch for navigation member access patterns, hmm..."
ast-grep --pattern 'options.navigation'

Length of output: 1147


Script:

#!/bin/bash
# Search for navigation initialization in test files
echo "Examine test implementations, we shall..."
rg -B 2 -A 3 "PropagatorOptions.*navigation" "Tests/UnitTests/Core/Propagator/"

echo "\nLook for navigation member usage in core components, hmm..."
rg -B 2 -A 3 "options\.navigation" "Core/"

echo "\nSearch for navigation-related changes in recent commits, we must..."
git diff --name-only HEAD~5 | grep -i "navigat"

Length of output: 1950

Core/include/Acts/Propagator/detail/NavigationHelpers.hpp (1)

40-42: Wise optimization, this is!

Store the intersection result locally, we now do. Prevent redundant calculations, this change does. Improved CPU performance, as mentioned in PR comments, achieved it has.

Core/include/Acts/Propagator/EigenStepper.hpp (2)

27-27: Explicit include of Surface.hpp, wise choice it is!

Direct dependency on Surface.hpp, now clearly shown it is. Better maintainability and clearer code dependencies, this brings.


87-87: 🛠️ Refactor suggestion

More reasonable default step size, implemented you have!

From infinite step size to 10 meters, changed the default has been. Hmmmm, yes... Prevents numerical instabilities, this does. With the Force, better aligned this default value is.

-double ssize = std::numeric_limits<double>::max()
+double ssize = 10 * Acts::UnitConstants::m

Verify impact of this change, we must:

Also applies to: 185-185

Tests/UnitTests/Core/Propagator/PropagatorTests.cpp (2)

28-28: Wise addition of NavigatorOptions.hpp, this is!

Necessary for the decoupling of navigation components, this include statement is. Well-placed in the include hierarchy, it stands.


Line range hint 466-485: Strong with the Force, these interface tests are!

Well-structured validation of the propagator interface, this is. Both straight line and eigen steppers, it tests. Static assertions for inheritance, it wisely includes.

Core/include/Acts/TrackFitting/GaussianSumFitter.hpp (1)

140-140: Approve the modified actor list for standard Navigator, I do.

EndOfWorldReached retained is, while NavigationBreakAborter removed is. Balanced approach this is.

Verify the impact of this change, we must:

✅ Verification successful

Safe this change is, approve it we must.

Through the Force, searched the entire codebase I have. No trace of NavigationBreakAborter remains, suggesting removed completely it was. The actor lists in other fitters - KalmanFitter and CombinatorialKalmanFilter - similar patterns they follow, using their specific actors they do.

Clear it is that:

  • NavigationBreakAborter, gone from the codebase it is
  • EndOfWorldReached, properly retained it was
  • Other fitters, similar actor list patterns they use
  • Clean and consistent with the codebase architecture, this change is
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any remaining NavigationBreakAborter usage
rg "NavigationBreakAborter" --type cpp

# Search for navigation break logic that might have moved to GsfActor
ast-grep --pattern 'struct GsfActor {
  $$$
  checkAbort($$$) {
    $$$
  }
  $$$
}'

Length of output: 125


Script:

#!/bin/bash
# Search for NavigationBreakAborter in the entire codebase with context
rg -A 5 "NavigationBreakAborter" 

# Search for GsfActor definition and its contents
ast-grep --pattern 'struct GsfActor {
  $$$
}'

# Search for any actor list definitions similar to the one being modified
rg -A 3 "using Actors = ActorList<" --type cpp

Length of output: 3027

Tests/IntegrationTests/NavigatorConsistency.cpp (2)

14-14: Wise additions to the headers, these are!

Support the new track parameters and logging functionality, they do.

Also applies to: 25-25


303-304: Appropriate logging level for integration tests, this is!

Clear visibility into test execution, it provides.

Tests/UnitTests/Core/Navigation/DetectorNavigatorTests.cpp (2)

120-122: Approve these changes, I do!

Clear separation of concerns, this brings. Position and direction parameters, explicitly passed they are now. Hmmmm.


Line range hint 1-694: Comprehensive test coverage, observe I do!

Strong with tests, this file is. All paths it covers:

  • Initialization scenarios
  • Forward and backward navigation
  • Edge cases with ambiguous surfaces
  • Multiple intersection handling

Well prepared for the changes, the tests were. Hmmmm.

Core/include/Acts/TrackFitting/KalmanFitter.hpp (2)

565-567: Approve this change, I do!

Clear and explicit, the new navigator initialization is. Position and direction, separately passed they are now. With the force of decoupling, align this does.


1049-1051: Consistent with the force, this change is!

In the finalization phase, the same pattern we see. Position and direction, clearly separated they are. Approve this consistency, I do.

Core/include/Acts/Navigation/DetectorNavigator.hpp (11)

17-17: Include Added, Correct It Is

The inclusion of "Acts/Propagator/NavigationTarget.hpp" necessary it is. Well done.


49-51: Options Constructor, Properly Initializes Base Class

Explicit constructor, added you have. NavigatorPlainOptions, correctly initialized it is.


63-64: State Constructor, Options It Accepts

The State constructor now options accepts, initializing state properly.


87-87: State Creation Simplified, It Is

Directly initializing State with options, you are. Cleaner and more efficient, this makes the code.


145-191: Candidate Surface Selection, Robust It Is

In estimateNextTarget, handling of candidate surfaces and portals, correctly done it is. Ensuring candidate validity, you are.


203-284: Surface Handling Logic, Proper It Appears

In handleSurfaceReached, the logic for portals and surfaces, correctly implemented it is. Exception handling for invalid cases, present it is.


293-295: Volume Information Function, Readable It Is

The volInfo function, returning the correct volume name it is.


299-301: Position Information Function, Well Designed

The posInfo function, providing position details it is. Useful for logging, yes.


Line range hint 311-317: Inactive Check, Correct Logic It Has

The inactive function, correctly determines if navigator inactive is. Conditions properly checked, they are.


336-350: Candidate Surfaces Updated, Carefully You Have

The updateCandidateSurfaces method, updating surfaces and sorting by path length, correctly it does.


353-356: Navigation State Filled, Properly It Is

The fillNavigationState method, position and direction updates in state. Efficient and clear, it is.

Tests/UnitTests/Core/Propagator/NavigatorTests.cpp (1)

43-45: Implemented 'step' function with step size correctly, you have.

Simplifies the stepping process, this function does. Correct and clear, it is.

Core/include/Acts/Propagator/Propagator.ipp (1)

37-49: Early termination logic implemented well is

Properly, the code checks for abort conditions before the stepping loop. Robust error handling, this ensures.

Core/include/Acts/Propagator/Navigator.hpp (4)

96-97: Added 'noTarget' to Stage enum, wise this is.

Enhances navigation control, the inclusion of 'noTarget' does. Clarifies stages, it will.


261-271: Parameters added to 'initialize', improve clarity they do.

Enhances configurability, adding 'position', 'direction', and 'propagationDirection' does. Positive change, this is.


343-460: 'estimateNextTarget' method refactored, streamlined logic it has.

Clarity improved, and consistent use of 'NavigationTarget' there is. Beneficial for maintainability, this change is.


472-477: Method 'checkTargetValid' always true returns, verify the need you should.

Does no validation, the method currently does. Ensure necessary checks are implemented, to confirm target validity.

Would you like assistance in implementing the validation logic?

Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp (1)

685-687: Updated correctly, the navigator initialization is.

Reflects the new interface, the parameters do. Pass the current position, direction, and propagation direction, you have. Good, this is.

Core/include/Acts/Propagator/VoidNavigator.hpp (6)

25-26: Changed from struct to class, intentional this change is?

From struct to class, you have changed VoidNavigator. Aware you must be that struct defaults to public access, while class defaults to private. Since public: you declare, impact minimal it is. Confirm that this aligns with design intentions, you should.


32-34: Constructor for Options, appropriately added it is.

An explicit constructor accepting GeometryContext, you have introduced. Consistent with changes in other navigators, this is. Enhances clarity, it does.


42-43: Initialization of State with Options, good this is.

State now initialized explicitly with Options. Improves readability and consistency, it does.


63-63: Method navigationBreak always returns true, intended this behavior is?

Unconditionally true, the navigationBreak method returns. Verify that this is desired for navigation flow control, you should.


71-75: Method estimateNextTarget returns invalid target, appropriate this is.

NavigationTarget::invalid() the method returns. For a navigator that does nothing, suitable this behavior is.


77-80: checkTargetValid always returns true, purpose this serves?

Always true the checkTargetValid method returns. Confirm that this method's unconditional return aligns with navigation logic, you must.

Comment on lines +51 to +71
auto getNextTarget = [&]() -> Result<NavigationTarget> {
// TODO max iterations?
for (int i = 0; i < 100; ++i) {
NavigationTarget nextTarget = m_navigator.estimateNextTarget(
state.navigation, state.position, state.direction);
if (!nextTarget.isValid()) {
return NavigationTarget::invalid();
}
// release actor and aborter constrains after step was performed
m_stepper.releaseStepSize(state.stepping, ConstrainedStep::actor);
m_stepper.releaseStepSize(state.stepping, ConstrainedStep::aborter);
// Post-stepping:
// navigator post step call - actor list act - actor list check
state.stage = PropagatorStage::postStep;
m_navigator.postStep(state, m_stepper);
state.options.actorList.act(state, m_stepper, m_navigator, logger());
if (state.options.actorList.checkAbort(state, m_stepper, m_navigator,
logger())) {
terminatedNormally = true;
break;
IntersectionStatus preStepSurfaceStatus = m_stepper.updateSurfaceStatus(
state.stepping, *nextTarget.surface,
nextTarget.surfaceIntersectionIndex, state.options.direction,
nextTarget.boundaryTolerance, state.options.surfaceTolerance,
logger());
if (preStepSurfaceStatus >= Acts::IntersectionStatus::reachable) {
return nextTarget;
}
}
} else {
ACTS_VERBOSE("Propagation terminated without going into stepping loop.");

ACTS_ERROR("getNextTarget failed to find a valid target surface.");
return Result<NavigationTarget>::failure(PropagatorError::Failure);
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Replace hardcoded iteration limit with configurable parameter

Hardcoded, the iteration limit of 100 is. Configurable, it should be, to allow flexibility and adaptability.

Apply this diff to make the iteration limit a parameter:

-    for (int i = 0; i < 100; ++i) {
+    for (int i = 0; i < state.options.maxNavigationIterations; ++i) {

Define maxNavigationIterations within state.options, ensure you do, and initialize it appropriately.

Committable suggestion skipped: line range outside the PR's diff.

Core/include/Acts/Propagator/Navigator.hpp Show resolved Hide resolved
Core/include/Acts/Propagator/Navigator.hpp Show resolved Hide resolved
Core/include/Acts/Propagator/Navigator.hpp Show resolved Hide resolved
Comment on lines +657 to +658
double stepDistance = step.norm();
Vector3 stepDirection = step.normalized();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Potential division by zero, there is.

If stepDistance equals zero, normalize step you should not, for division by zero it causes. Check stepDistance greater than zero is, before normalizing step.

Apply this diff to handle zero-distance case:

+if (stepDistance > std::numeric_limits<double>::epsilon()) {
+  Vector3 stepDirection = step.normalized();
+  // Proceed with existing code using stepDirection
+} else {
+  // Handle zero step distance appropriately, you must
+  // Perhaps skip normalization or set stepDirection to zero vector
+}

Committable suggestion skipped: line range outside the PR's diff.

Copy link

sonarcloud bot commented Nov 27, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Component - Core Affects the Core module Component - Fatras Affects the Fatras module Fails Athena tests This PR causes a failure in the Athena tests Needs Decision Needs decision or further information Track Finding Track Fitting
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants