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

feat: introduce navigation stream #3538

Merged
merged 21 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ add_subdirectory(src/Detector)
add_subdirectory(src/Geometry)
add_subdirectory(src/MagneticField)
add_subdirectory(src/Material)
add_subdirectory(src/Navigation)
add_subdirectory(src/Propagator)
add_subdirectory(src/Surfaces)
add_subdirectory(src/TrackFinding)
Expand Down
98 changes: 98 additions & 0 deletions Core/include/Acts/Navigation/NavigationStream.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// This file is part of the Acts project.
//
// Copyright (C) 2024 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Surfaces/BoundaryTolerance.hpp"
#include "Acts/Utilities/Intersection.hpp"

#include <tuple>
#include <vector>

namespace Acts {

// To be removed when the namespace Experimental is omitted
namespace Experimental {
class Portal;
}
using namespace Experimental;

class Surface;

/// @brief The NavigationStream is a container for the navigation candidates
///
/// The current candidates are stored in a vector of candidates, where an index
/// is used to indicate the current active candidate.
///
/// @todo the NavigationStream should hold also the current volume it is in
/// if it represents the geometry stream.
struct NavigationStream {
/// The query point for the navigation stream
///
/// This holds the position and direction from which the navigation stream
/// should either be initialized or updated.
struct QueryPoint {
/// The position of the query point
Vector3 position = Vector3::Zero();
/// The direction of the query point
Vector3 direction = Vector3::Zero();
};

/// This is a candidate object of the navigation stream, it holds:
///
/// - a Surface intersection
/// - a Portal : set if the surface represents a portal
/// - a BoundaryTolerance : the boundary tolerance used for the intersection
struct Candidate {
/// The intersection
ObjectIntersection<Surface> intersection =
ObjectIntersection<Surface>::invalid();
/// The portal
const Portal* portal = nullptr;
/// The boundary tolerance
BoundaryTolerance bTolerance = BoundaryTolerance::None();
/// Target flag: true if this Candidate represents an abortTarget
bool abortTarget = false;
asalzburger marked this conversation as resolved.
Show resolved Hide resolved
/// Convenience access to surface
const Surface& surface() const { return *intersection.object(); }
/// Cinvencience access to the path length
ActsScalar pathLength() const { return intersection.pathLength(); }
};

/// The candidates of this navigation stream
std::vector<Candidate> candidates;

/// The currently active candidate
std::size_t currentIndex = 0u;

/// Switch to next next candidate
///
/// @return true if a next candidate is available
bool switchToNextCandidate() {
if (currentIndex < candidates.size()) {
++currentIndex;
return true;
}
return false;
}

/// Const access the current candidate
const Candidate& currentCandidate() const {
return candidates.at(currentIndex);
}

/// Non-cost access the current candidate
Candidate& currentCandidate() { return candidates.at(currentIndex); }

/// The number of active candidates
std::size_t activeCandidates() const {
return (candidates.size() - currentIndex);
}
asalzburger marked this conversation as resolved.
Show resolved Hide resolved
};

} // namespace Acts
102 changes: 102 additions & 0 deletions Core/include/Acts/Navigation/NavigationStreamHelper.hpp
asalzburger marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// This file is part of the Acts project.
//
// Copyright (C) 2024 CERN for the benefit of the Acts project
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#pragma once

#include "Acts/Definitions/Algebra.hpp"
#include "Acts/Detector/Portal.hpp"
#include "Acts/Geometry/GeometryContext.hpp"
#include "Acts/Navigation/NavigationStream.hpp"
#include "Acts/Surfaces/BoundaryTolerance.hpp"
#include "Acts/Utilities/Intersection.hpp"

#include <vector>

namespace Acts {

using namespace Experimental;

class Surface;

namespace NavigationStreamHelper {

/// Helper struct that allows to fill a surface into the candidate vector
///
/// @param nStream the navigation stream that is being filled
/// @param surface the surface to be filled
/// @param bTolerance the boundary tolerance used for the intersection
/// @param abortTarget a boolean that indicates if this surface is an abort target
inline static void fillSurface(NavigationStream& nStream,
const Surface* surface,
BoundaryTolerance bTolerance,
bool abortTarget = false) {
nStream.candidates.push_back(NavigationStream::Candidate{
ObjectIntersection<Surface>(surface), nullptr, bTolerance, abortTarget});
}

/// Helper struct that allows to fill surfaces into the candidate vector
///
/// @param nStream the navigation stream that is being filled
/// @param surfaces the surfaces that are filled in
/// @param bTolerance the boundary tolerance used for the intersection
/// @param abortTarget a boolean that indicates if those surfaces are abort targets
inline static void fillSurfaces(NavigationStream& nStream,
const std::vector<const Surface*>& surfaces,
BoundaryTolerance bTolerance,
bool abortTarget = false) {
std::for_each(surfaces.begin(), surfaces.end(), [&](const auto& s) {
nStream.candidates.push_back(NavigationStream::Candidate{
ObjectIntersection<Surface>(s), nullptr, bTolerance, abortTarget});
});
}

/// Helper struct that allows to fill portals into the candidate vector
///
/// @param nStream the navigation stream that is being filled
/// @param portals the portals that are filled in
inline static void fillPortals(NavigationStream& nStream,
const std::vector<const Portal*>& portals) {
std::for_each(portals.begin(), portals.end(), [&](const auto& p) {
nStream.candidates.push_back(NavigationStream::Candidate{
ObjectIntersection<Surface>(&(p->surface())), p,
BoundaryTolerance::None()});
});
}

/// Initialize a stream that does not require a state object
///
/// @param stream [in, out] is the navigation stream to be updated
/// @param gctx is the geometry context
/// @param queryPoint holds current position, direction, etc.
/// @param cTolerance is the candidate search tolerance
///
/// This method will first de-duplicate the candidates on basis of the surface
/// pointer to make sure that the multi-intersections are handled correctly.
/// This will allow intializeStream() to be called even as a re-initialization
/// and still work correctly with at one time valid candidates.
///
/// @return true if the stream is active, false indicates that there are no valid candidates
bool initializeStream(NavigationStream& stream, const GeometryContext& gctx,
const NavigationStream::QueryPoint& queryPoint,
BoundaryTolerance cTolerance);

/// Convenience method to update a stream from a new query point,
/// this could be called from navigation delegates that do not require
/// a local state or from the navigator on the target stream
///
/// @param stream [in, out] is the navigation stream to be updated
/// @param gctx is the geometry context
/// @param queryPoint holds current position, direction, etc.
///
/// @return true if the stream is active, false indicate no valid candidates left
bool updateStream(NavigationStream& stream, const GeometryContext& gctx,
const NavigationStream::QueryPoint& queryPoint);
asalzburger marked this conversation as resolved.
Show resolved Hide resolved

} // namespace NavigationStreamHelper

} // namespace Acts
17 changes: 17 additions & 0 deletions Core/include/Acts/Utilities/Intersection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,16 @@ class Intersection {
/// Returns whether the intersection was successful or not
constexpr bool isValid() const { return m_status != Status::missed; }

/// Returns the position of the interseciton
constexpr const Position& position() const { return m_position; }

/// Returns the path length to the interseciton
constexpr ActsScalar pathLength() const { return m_pathLength; }

/// Returns the intersection status enum
constexpr Status status() const { return m_status; }

/// Static factory to creae an invalid instesection
constexpr static Intersection invalid() { return Intersection(); }

/// Comparison function for path length order i.e. intersection closest to
Expand Down Expand Up @@ -145,6 +149,14 @@ class ObjectIntersection {
const object_t* object, std::uint8_t index = 0)
: m_intersection(intersection), m_object(object), m_index(index) {}

/// Invalid object intersection - only holding the object itself
///
/// @param object is the object to be instersected
constexpr ObjectIntersection(const object_t* object)
: m_intersection(Intersection3D::invalid()),
m_object(object),
m_index(0) {}
asalzburger marked this conversation as resolved.
Show resolved Hide resolved

/// Returns whether the intersection was successful or not
/// @deprecated
[[deprecated("Use isValid() instead")]] constexpr explicit operator bool()
Expand All @@ -155,22 +167,27 @@ class ObjectIntersection {
/// Returns whether the intersection was successful or not
constexpr bool isValid() const { return m_intersection.isValid(); }

/// Returns the intersection
constexpr const Intersection3D& intersection() const {
return m_intersection;
}

/// Returns the position of the interseciton
constexpr const Intersection3D::Position& position() const {
return m_intersection.position();
}

/// Returns the path length to the interseciton
constexpr ActsScalar pathLength() const {
return m_intersection.pathLength();
}

/// Returns the status of the interseciton
constexpr Intersection3D::Status status() const {
return m_intersection.status();
}

/// Returns the object that has been intersected
constexpr const object_t* object() const { return m_object; }

constexpr std::uint8_t index() const { return m_index; }
Expand Down
1 change: 1 addition & 0 deletions Core/src/Navigation/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target_sources(ActsCore PRIVATE NavigationStreamHelper.cpp)
Loading
Loading