From bd9d6dca7b8a852baca1fcf99dd86370fd603825 Mon Sep 17 00:00:00 2001 From: "Alexander J. Pfleger" <70842573+AJPfleger@users.noreply.github.com> Date: Mon, 9 Sep 2024 15:15:22 +0200 Subject: [PATCH 1/8] fix: remove pre-C++20 `std::identity` implementation (#3599) --- .../detail/GsfComponentMerging.hpp | 5 ++- Core/include/Acts/Utilities/Identity.hpp | 36 ------------------- .../TrackFitting/GsfComponentMergingTests.cpp | 7 ++-- 3 files changed, 5 insertions(+), 43 deletions(-) delete mode 100644 Core/include/Acts/Utilities/Identity.hpp diff --git a/Core/include/Acts/TrackFitting/detail/GsfComponentMerging.hpp b/Core/include/Acts/TrackFitting/detail/GsfComponentMerging.hpp index cf5bc4bf1b0..8881bf8a298 100644 --- a/Core/include/Acts/TrackFitting/detail/GsfComponentMerging.hpp +++ b/Core/include/Acts/TrackFitting/detail/GsfComponentMerging.hpp @@ -12,7 +12,6 @@ #include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/Surfaces/CylinderSurface.hpp" #include "Acts/TrackFitting/GsfOptions.hpp" -#include "Acts/Utilities/Identity.hpp" #include "Acts/Utilities/detail/periodic.hpp" #include @@ -123,7 +122,7 @@ auto gaussianMixtureCov(const components_t components, /// std::tuple< weight, mean, std::optional< cov > > /// @tparam angle_desc_t A angle description object which defines the cyclic /// angles in the bound parameters -template ::Desc> auto gaussianMixtureMeanCov(const components_t components, projector_t &&projector = projector_t{}, @@ -212,7 +211,7 @@ auto gaussianMixtureMeanCov(const components_t components, /// like a std::tuple< double, BoundVector, BoundMatrix > /// /// @return parameters and covariance as std::tuple< BoundVector, BoundMatrix > -template +template auto mergeGaussianMixture(const mixture_t &mixture, const Surface &surface, ComponentMergeMethod method, projector_t &&projector = projector_t{}) { diff --git a/Core/include/Acts/Utilities/Identity.hpp b/Core/include/Acts/Utilities/Identity.hpp deleted file mode 100644 index 2d5c759b595..00000000000 --- a/Core/include/Acts/Utilities/Identity.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// This file is part of the Acts project. -// -// Copyright (C) 2021 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 - -#if __cplusplus >= 202002L - -#include - -namespace Acts { -using Identity = std::identity; -} - -#else - -#include - -namespace Acts { - -/// @brief Function object which maps a value to itself by perfect forwarding -/// This is a backport of C++20's std::identity -struct Identity { - template - constexpr auto operator()(T &&v) const { - return std::forward(v); - } -}; - -} // namespace Acts - -#endif diff --git a/Tests/UnitTests/Core/TrackFitting/GsfComponentMergingTests.cpp b/Tests/UnitTests/Core/TrackFitting/GsfComponentMergingTests.cpp index f547ea89503..39959dfa0de 100644 --- a/Tests/UnitTests/Core/TrackFitting/GsfComponentMergingTests.cpp +++ b/Tests/UnitTests/Core/TrackFitting/GsfComponentMergingTests.cpp @@ -22,7 +22,6 @@ #include "Acts/Surfaces/Surface.hpp" #include "Acts/Surfaces/SurfaceBounds.hpp" #include "Acts/TrackFitting/detail/GsfComponentMerging.hpp" -#include "Acts/Utilities/Identity.hpp" #include "Acts/Utilities/Intersection.hpp" #include "Acts/Utilities/Result.hpp" #include "Acts/Utilities/detail/periodic.hpp" @@ -216,7 +215,7 @@ using LocPosArray = std::array, 4>; template void test_surface(const Surface &surface, const angle_description_t &desc, const LocPosArray &loc_pos, double expectedError) { - const auto proj = Identity{}; + const auto proj = std::identity{}; for (auto phi : {-175_degree, 0_degree, 175_degree}) { for (auto theta : {5_degree, 90_degree, 175_degree}) { @@ -271,7 +270,7 @@ BOOST_AUTO_TEST_CASE(test_with_data) { const auto boundCov_data = boundCov(samples, mean_data); const auto [mean_test, boundCov_test] = - detail::gaussianMixtureMeanCov(cmps, Identity{}, std::tuple<>{}); + detail::gaussianMixtureMeanCov(cmps, std::identity{}, std::tuple<>{}); CHECK_CLOSE_MATRIX(mean_data, mean_test, 1.e-1); CHECK_CLOSE_MATRIX(boundCov_data, boundCov_test, 1.e-1); @@ -302,7 +301,7 @@ BOOST_AUTO_TEST_CASE(test_with_data_circular) { using detail::CyclicAngle; const auto d = std::tuple, CyclicAngle>{}; const auto [mean_test, boundCov_test] = - detail::gaussianMixtureMeanCov(cmps, Identity{}, d); + detail::gaussianMixtureMeanCov(cmps, std::identity{}, d); BOOST_CHECK(std::abs(detail::difference_periodic(mean_data[0], mean_test[0], 2 * M_PI)) < 1.e-1); From 2798d98247ce73c3055ff38f54d586cd7f184ea5 Mon Sep 17 00:00:00 2001 From: Paul Gessinger Date: Mon, 9 Sep 2024 17:29:51 +0200 Subject: [PATCH 2/8] refactor: Volume holds bounds as mutable (#3595) This PR changes the internal storage of `VolumeBounds` inside `Volume` to be mutable. This allows transitive mutable access (which we need in a few cases). To prevent accidental mutable use of the contained bounds object (which can be shared with other objects), I'm moving the shared pointer member to be private, and allow access only via setters and getters. This way, in a const function of a derived class, only const access to the volume bounds is possible. --- .../Acts/Geometry/CylinderVolumeStack.hpp | 4 ++-- Core/include/Acts/Geometry/TrackingVolume.hpp | 8 +++----- Core/include/Acts/Geometry/Volume.hpp | 19 +++++++++++++------ Core/src/Geometry/CylinderVolumeStack.cpp | 19 +++++++++---------- Core/src/Geometry/TrackingVolume.cpp | 8 +++----- Core/src/Geometry/Volume.cpp | 14 +++++++++++--- Examples/Python/src/Base.cpp | 9 ++++++--- Examples/Python/src/Geometry.cpp | 7 ++----- 8 files changed, 49 insertions(+), 39 deletions(-) diff --git a/Core/include/Acts/Geometry/CylinderVolumeStack.hpp b/Core/include/Acts/Geometry/CylinderVolumeStack.hpp index 4c83b6c0678..1f1eb748947 100644 --- a/Core/include/Acts/Geometry/CylinderVolumeStack.hpp +++ b/Core/include/Acts/Geometry/CylinderVolumeStack.hpp @@ -87,7 +87,7 @@ class CylinderVolumeStack : public Volume { /// @param transform is the new transform /// @pre The volume bounds need to be of type /// @c CylinderVolumeBounds. - void update(std::shared_ptr volbounds, + void update(std::shared_ptr volbounds, std::optional transform = std::nullopt) override; /// Update the volume bounds and transform. This @@ -100,7 +100,7 @@ class CylinderVolumeStack : public Volume { /// @param logger is the logger /// @pre The volume bounds need to be of type /// @c CylinderVolumeBounds. - void update(std::shared_ptr newBounds, + void update(std::shared_ptr newBounds, std::optional transform, const Logger& logger); /// Access the gap volume that were created during attachment or resizing. diff --git a/Core/include/Acts/Geometry/TrackingVolume.hpp b/Core/include/Acts/Geometry/TrackingVolume.hpp index 9cea4b8653c..a343f40bf2d 100644 --- a/Core/include/Acts/Geometry/TrackingVolume.hpp +++ b/Core/include/Acts/Geometry/TrackingVolume.hpp @@ -125,7 +125,7 @@ class TrackingVolume : public Volume { /// @param volbounds is the description of the volume boundaries /// @param volumeName is a string identifier TrackingVolume(const Transform3& transform, - std::shared_ptr volbounds, + std::shared_ptr volbounds, const std::string& volumeName = "undefined"); /// Constructor for a full equipped Tracking Volume @@ -140,8 +140,7 @@ class TrackingVolume : public Volume { /// @param denseVolumeVector The contained dense volumes /// @param volumeName is a string identifier TrackingVolume( - const Transform3& transform, - std::shared_ptr volumeBounds, + const Transform3& transform, std::shared_ptr volumeBounds, std::shared_ptr volumeMaterial, std::unique_ptr staticLayerArray = nullptr, std::shared_ptr containedVolumeArray = nullptr, @@ -151,8 +150,7 @@ class TrackingVolume : public Volume { /// Constructor from a regular volume /// @param volume is the volume to be converted /// @param volumeName is a string identifier - TrackingVolume(const Volume& volume, - const std::string& volumeName = "undefined"); + TrackingVolume(Volume& volume, const std::string& volumeName = "undefined"); // @TODO: This needs to be refactored to include Gen3 volumes /// Return the associated sub Volume, returns THIS if no subVolume exists diff --git a/Core/include/Acts/Geometry/Volume.hpp b/Core/include/Acts/Geometry/Volume.hpp index 3df0b339fd9..65e3e8b9219 100644 --- a/Core/include/Acts/Geometry/Volume.hpp +++ b/Core/include/Acts/Geometry/Volume.hpp @@ -37,8 +37,7 @@ class Volume : public GeometryObject { /// /// @param transform is the transform to position the volume in 3D space /// @param volbounds is the volume boundary definitions - Volume(const Transform3& transform, - std::shared_ptr volbounds); + Volume(const Transform3& transform, std::shared_ptr volbounds); /// Copy Constructor - with optional shift /// @@ -65,20 +64,26 @@ class Volume : public GeometryObject { /// returns the center of the volume const Vector3& center() const; - /// Returns const reference to the volume bounds + /// Returns a const reference to the volume bounds const VolumeBounds& volumeBounds() const; + /// Returns a mutable reference to the volume bounds + VolumeBounds& volumeBounds(); + /// Returns shared pointer to the volume bounds std::shared_ptr volumeBoundsPtr() const; + /// Returns shared pointer to the volume bounds + std::shared_ptr volumeBoundsPtr(); + /// Set volume bounds and update volume bounding boxes implicitly /// @param volbounds The volume bounds to be assigned - void assignVolumeBounds(std::shared_ptr volbounds); + void assignVolumeBounds(std::shared_ptr volbounds); /// Set the volume bounds and optionally also update the volume transform /// @param volbounds The volume bounds to be assigned /// @param transform The transform to be assigned, can be optional - virtual void update(std::shared_ptr volbounds, + virtual void update(std::shared_ptr volbounds, std::optional transform = std::nullopt); /// Construct bounding box for this shape @@ -117,7 +122,9 @@ class Volume : public GeometryObject { Transform3 m_transform; Transform3 m_itransform; Vector3 m_center; - std::shared_ptr m_volumeBounds; + + private: + std::shared_ptr m_volumeBounds; }; /**Overload of << operator for std::ostream for debug output*/ diff --git a/Core/src/Geometry/CylinderVolumeStack.cpp b/Core/src/Geometry/CylinderVolumeStack.cpp index b6c75afb54f..9b4f05fc43e 100644 --- a/Core/src/Geometry/CylinderVolumeStack.cpp +++ b/Core/src/Geometry/CylinderVolumeStack.cpp @@ -150,7 +150,7 @@ void CylinderVolumeStack::initializeOuterVolume(BinningValue direction, const auto* cylBounds = dynamic_cast( &m_volumes.front()->volumeBounds()); assert(cylBounds != nullptr && "Volume bounds are not cylinder bounds"); - m_volumeBounds = std::make_shared(*cylBounds); + Volume::update(std::make_shared(*cylBounds)); return; } @@ -211,8 +211,8 @@ void CylinderVolumeStack::initializeOuterVolume(BinningValue direction, m_transform = m_groupTransform * Translation3{0, 0, midZ}; - m_volumeBounds = std::make_shared(minR, maxR, hlZ); - ACTS_DEBUG("Outer bounds are:\n" << *m_volumeBounds); + Volume::update(std::make_shared(minR, maxR, hlZ)); + ACTS_DEBUG("Outer bounds are:\n" << volumeBounds()); ACTS_DEBUG("Outer transform / new group transform is:\n" << m_transform.matrix()); @@ -269,9 +269,9 @@ void CylinderVolumeStack::initializeOuterVolume(BinningValue direction, m_transform = m_groupTransform * Translation3{0, 0, midZ}; - m_volumeBounds = std::make_shared(minR, maxR, hlZ); + Volume::update(std::make_shared(minR, maxR, hlZ)); - ACTS_DEBUG("Outer bounds are:\n" << *m_volumeBounds); + ACTS_DEBUG("Outer bounds are:\n" << volumeBounds()); ACTS_DEBUG("Outer transform is:\n" << m_transform.matrix()); // Update group transform to the new center @@ -625,13 +625,12 @@ std::pair CylinderVolumeStack::synchronizeZBounds( return {minZ, maxZ}; } -void CylinderVolumeStack::update(std::shared_ptr volbounds, +void CylinderVolumeStack::update(std::shared_ptr volbounds, std::optional transform) { if (volbounds == nullptr) { throw std::invalid_argument("New bounds are nullptr"); } - auto cylBounds = - std::dynamic_pointer_cast(volbounds); + auto cylBounds = std::dynamic_pointer_cast(volbounds); if (cylBounds == nullptr) { throw std::invalid_argument( "CylinderVolumeStack requires CylinderVolumeBounds"); @@ -641,7 +640,7 @@ void CylinderVolumeStack::update(std::shared_ptr volbounds, } void CylinderVolumeStack::update( - std::shared_ptr newBounds, + std::shared_ptr newBounds, std::optional transform, const Logger& logger) { ACTS_DEBUG( "Resizing CylinderVolumeStack with strategy: " << m_resizeStrategy); @@ -934,7 +933,7 @@ void CylinderVolumeStack::update( } m_transform = newVolume.globalTransform; - m_volumeBounds = std::move(newBounds); + Volume::update(std::move(newBounds)); } void CylinderVolumeStack::checkNoPhiOrBevel(const CylinderVolumeBounds& bounds, diff --git a/Core/src/Geometry/TrackingVolume.cpp b/Core/src/Geometry/TrackingVolume.cpp index dcf9e93a0da..bbed048efdd 100644 --- a/Core/src/Geometry/TrackingVolume.cpp +++ b/Core/src/Geometry/TrackingVolume.cpp @@ -31,8 +31,7 @@ namespace Acts { // constructor for arguments TrackingVolume::TrackingVolume( - const Transform3& transform, - std::shared_ptr volumeBounds, + const Transform3& transform, std::shared_ptr volumeBounds, std::shared_ptr volumeMaterial, std::unique_ptr staticLayerArray, std::shared_ptr containedVolumeArray, @@ -49,14 +48,13 @@ TrackingVolume::TrackingVolume( connectDenseBoundarySurfaces(denseVolumeVector); } -TrackingVolume::TrackingVolume(const Volume& volume, - const std::string& volumeName) +TrackingVolume::TrackingVolume(Volume& volume, const std::string& volumeName) : TrackingVolume(volume.transform(), volume.volumeBoundsPtr(), nullptr, nullptr, nullptr, MutableTrackingVolumeVector{}, volumeName) {} TrackingVolume::TrackingVolume(const Transform3& transform, - std::shared_ptr volbounds, + std::shared_ptr volbounds, const std::string& volumeName) : TrackingVolume(transform, std::move(volbounds), nullptr, nullptr, nullptr, {}, volumeName) {} diff --git a/Core/src/Geometry/Volume.cpp b/Core/src/Geometry/Volume.cpp index 79dcf5598dc..a04cab7b6f7 100644 --- a/Core/src/Geometry/Volume.cpp +++ b/Core/src/Geometry/Volume.cpp @@ -19,7 +19,7 @@ using namespace Acts::UnitLiterals; namespace Acts { Volume::Volume(const Transform3& transform, - std::shared_ptr volbounds) + std::shared_ptr volbounds) : GeometryObject(), m_transform(transform), m_itransform(m_transform.inverse()), @@ -74,11 +74,11 @@ Volume::BoundingBox Volume::orientedBoundingBox() const { this); } -void Volume::assignVolumeBounds(std::shared_ptr volbounds) { +void Volume::assignVolumeBounds(std::shared_ptr volbounds) { update(std::move(volbounds)); } -void Volume::update(std::shared_ptr volbounds, +void Volume::update(std::shared_ptr volbounds, std::optional transform) { if (volbounds) { m_volumeBounds = std::move(volbounds); @@ -104,10 +104,18 @@ const VolumeBounds& Volume::volumeBounds() const { return *m_volumeBounds; } +VolumeBounds& Volume::volumeBounds() { + return *m_volumeBounds; +} + std::shared_ptr Volume::volumeBoundsPtr() const { return m_volumeBounds; } +std::shared_ptr Volume::volumeBoundsPtr() { + return m_volumeBounds; +} + void Volume::setTransform(const Transform3& transform) { m_transform = transform; m_itransform = m_transform.inverse(); diff --git a/Examples/Python/src/Base.cpp b/Examples/Python/src/Base.cpp index b6582c15d1f..aae48a6a3b4 100644 --- a/Examples/Python/src/Base.cpp +++ b/Examples/Python/src/Base.cpp @@ -297,9 +297,12 @@ void addAlgebra(Acts::Python::Context& ctx) { Acts::Vector3(translation[0], translation[1], translation[2])); return t; })) - .def("getTranslation", [](const Acts::Transform3& self) { - return Vector3(self.translation()); - }); + .def("getTranslation", + [](const Acts::Transform3& self) { + return Vector3(self.translation()); + }) + .def_static("Identity", &Acts::Transform3::Identity); + ; } void addBinning(Context& ctx) { diff --git a/Examples/Python/src/Geometry.cpp b/Examples/Python/src/Geometry.cpp index 114e54e29a5..4f4752aa4ef 100644 --- a/Examples/Python/src/Geometry.cpp +++ b/Examples/Python/src/Geometry.cpp @@ -189,11 +189,8 @@ void addGeometry(Context& ctx) { py::class_>(m, "TrackingVolume") - .def(py::init([](std::shared_ptr bounds, - std::string name) { - return std::make_shared(Transform3::Identity(), - bounds, name); - })); + .def(py::init, + std::string>()); } { From 74d9aa24653027858659e28f3e6f0275cf799d6c Mon Sep 17 00:00:00 2001 From: "Alexander J. Pfleger" <70842573+AJPfleger@users.noreply.github.com> Date: Mon, 9 Sep 2024 19:47:39 +0200 Subject: [PATCH 3/8] refactor!: path handling to use `std::filesystem` (#3308) Switch to using `std::filesystem` for path operations to modernize code and improve readability. --- .../Acts/Visualization/GeometryView3D.hpp | 20 ++--- .../Acts/Visualization/IVisualization3D.hpp | 22 +----- .../Acts/Visualization/ObjVisualization3D.hpp | 7 +- .../Acts/Visualization/PlyVisualization3D.hpp | 7 +- .../include/Acts/Visualization/ViewConfig.hpp | 5 +- .../detail/ObjVisualization3D.ipp | 23 +++--- .../detail/PlyVisualization3D.ipp | 12 +-- Core/src/Visualization/CMakeLists.txt | 5 +- Core/src/Visualization/GeometryView3D.cpp | 77 ++++++------------- Core/src/Visualization/IVisualization3D.cpp | 23 ------ .../Io/Obj/src/ObjTrackingGeometryWriter.cpp | 6 +- 11 files changed, 73 insertions(+), 134 deletions(-) delete mode 100644 Core/src/Visualization/IVisualization3D.cpp diff --git a/Core/include/Acts/Visualization/GeometryView3D.hpp b/Core/include/Acts/Visualization/GeometryView3D.hpp index 0243e8e58ad..f1abba71424 100644 --- a/Core/include/Acts/Visualization/GeometryView3D.hpp +++ b/Core/include/Acts/Visualization/GeometryView3D.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2020 CERN for the benefit of the Acts project +// Copyright (C) 2020-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 @@ -14,6 +14,7 @@ #include "Acts/Visualization/IVisualization3D.hpp" #include "Acts/Visualization/ViewConfig.hpp" +#include #include namespace Acts { @@ -75,7 +76,7 @@ struct GeometryView3D { const ViewConfig& sensitiveConfig = s_viewSensitive, const ViewConfig& passiveConfig = s_viewPassive, const ViewConfig& gridConfig = s_viewGrid, - const std::string& outputDir = "."); + const std::filesystem::path& outputDir = std::filesystem::path(".")); /// Helper method to draw Volume objects /// @@ -132,12 +133,12 @@ struct GeometryView3D { /// @param sensitiveConfig The drawing configuration for sensitive surfaces /// @param gridConfig The drawing configuration for grid display /// @param outputDir Directory to write to - static void drawLayer(IVisualization3D& helper, const Layer& layer, - const GeometryContext& gctx, - const ViewConfig& layerConfig = s_viewPassive, - const ViewConfig& sensitiveConfig = s_viewSensitive, - const ViewConfig& gridConfig = s_viewGrid, - const std::string& outputDir = "."); + static void drawLayer( + IVisualization3D& helper, const Layer& layer, const GeometryContext& gctx, + const ViewConfig& layerConfig = s_viewPassive, + const ViewConfig& sensitiveConfig = s_viewSensitive, + const ViewConfig& gridConfig = s_viewGrid, + const std::filesystem::path& outputDir = std::filesystem::path(".")); /// Helper method to draw TrackingVolume objects /// @@ -161,7 +162,8 @@ struct GeometryView3D { const ViewConfig& layerView = s_viewPassive, const ViewConfig& sensitiveView = s_viewSensitive, const ViewConfig& gridView = s_viewGrid, bool writeIt = true, - const std::string& tag = "", const std::string& outputDir = "."); + const std::string& tag = "", + const std::filesystem::path& outputDir = std::filesystem::path(".")); /// Helper method to draw lines - base for all lines /// diff --git a/Core/include/Acts/Visualization/IVisualization3D.hpp b/Core/include/Acts/Visualization/IVisualization3D.hpp index 6daf34c4e2f..96af6328979 100644 --- a/Core/include/Acts/Visualization/IVisualization3D.hpp +++ b/Core/include/Acts/Visualization/IVisualization3D.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2019 CERN for the benefit of the Acts project +// Copyright (C) 2019-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 @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -67,28 +68,11 @@ class IVisualization3D { /// Write the content of the helper to an outstream. /// @param path is the file system path for writing the file - /// @note will change to std::filesystem::path once gcc9 is standard - virtual void write(const std::string& path) const = 0; + virtual void write(const std::filesystem::path& path) const = 0; /// Remove all contents of this helper /// virtual void clear() = 0; - - protected: - /// Helper: check for extension - /// - /// @note this is a placeholder for std::filesystem::has_extension - /// which needs special linking until gcc9 - /// @param path the path to be checked - bool hasExtension(const std::string& path) const; - - /// Helper: replace the extension - /// - /// @note this is a placeholder for std::filesystem::replace_extension - /// which needs special linking until gcc9 - /// @param path [in,out] the path to be changed - /// @param suffix the extension to be added - void replaceExtension(std::string& path, const std::string& suffix) const; }; /// Overload of the << operator to facilitate writing to streams. diff --git a/Core/include/Acts/Visualization/ObjVisualization3D.hpp b/Core/include/Acts/Visualization/ObjVisualization3D.hpp index a915ecadee8..79da56d3e9c 100644 --- a/Core/include/Acts/Visualization/ObjVisualization3D.hpp +++ b/Core/include/Acts/Visualization/ObjVisualization3D.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2019 CERN for the benefit of the Acts project +// Copyright (C) 2019-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 @@ -13,6 +13,7 @@ #include "Acts/Visualization/ViewConfig.hpp" #include +#include #include #include #include @@ -61,8 +62,8 @@ class ObjVisualization3D : public IVisualization3D { const std::vector& faces, ColorRGB color = {0, 0, 0}) final; - /// @copydoc Acts::IVisualization3D::write(const std::string&) const - void write(const std::string& path) const final; + /// @copydoc Acts::IVisualization3D::write(const std::filesystem::path&) const + void write(const std::filesystem::path& path) const final; /// @copydoc Acts::IVisualization3D::write(std::ostream&) const void write(std::ostream& os) const final; diff --git a/Core/include/Acts/Visualization/PlyVisualization3D.hpp b/Core/include/Acts/Visualization/PlyVisualization3D.hpp index b28783a0bcd..95f2fdacd28 100644 --- a/Core/include/Acts/Visualization/PlyVisualization3D.hpp +++ b/Core/include/Acts/Visualization/PlyVisualization3D.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2019 CERN for the benefit of the Acts project +// Copyright (C) 2019-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 @@ -13,6 +13,7 @@ #include "Acts/Visualization/ViewConfig.hpp" #include +#include #include #include #include @@ -50,8 +51,8 @@ class PlyVisualization3D : public IVisualization3D { void line(const Vector3& a, const Vector3& b, ColorRGB color = {120, 120, 120}) final; - /// @copydoc Acts::IVisualization3D::write(const std::string&) const - void write(const std::string& path) const final; + /// @copydoc Acts::IVisualization3D::write(const std::filesystem::path&) const + void write(const std::filesystem::path& path) const final; /// @copydoc Acts::IVisualization3D::write(std::ostream&) const void write(std::ostream& os) const final; diff --git a/Core/include/Acts/Visualization/ViewConfig.hpp b/Core/include/Acts/Visualization/ViewConfig.hpp index 06c4f7a675b..7e6e70dbdcc 100644 --- a/Core/include/Acts/Visualization/ViewConfig.hpp +++ b/Core/include/Acts/Visualization/ViewConfig.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2020 CERN for the benefit of the Acts project +// Copyright (C) 2020-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 @@ -9,6 +9,7 @@ #pragma once #include +#include #include namespace Acts { @@ -42,7 +43,7 @@ struct ViewConfig { /// Whether to triangulate or not bool triangulate = false; /// Write name - non-empty string indicates writing - std::string outputName = ""; + std::filesystem::path outputName = std::filesystem::path(""); }; } // namespace Acts diff --git a/Core/include/Acts/Visualization/detail/ObjVisualization3D.ipp b/Core/include/Acts/Visualization/detail/ObjVisualization3D.ipp index 51a0854b85e..e43bbb11f19 100644 --- a/Core/include/Acts/Visualization/detail/ObjVisualization3D.ipp +++ b/Core/include/Acts/Visualization/detail/ObjVisualization3D.ipp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2020 CERN for the benefit of the Acts project +// Copyright (C) 2020-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 @@ -69,18 +69,21 @@ void ObjVisualization3D::faces(const std::vector& vtxs, } template -void ObjVisualization3D::write(const std::string& path) const { +void ObjVisualization3D::write(const std::filesystem::path& path) const { std::ofstream os; - std::string objectpath = path; - if (!IVisualization3D::hasExtension(objectpath)) { - objectpath += std::string(".obj"); + std::filesystem::path objectpath = path; + if (!objectpath.has_extension()) { + objectpath.replace_extension(std::filesystem::path("obj")); } - os.open(objectpath); - std::string mtlpath = objectpath; - IVisualization3D::replaceExtension(mtlpath, ".mtl"); - os << "mtllib " << mtlpath << "\n"; + os.open(std::filesystem::absolute(objectpath).string()); + std::filesystem::path mtlpath = objectpath; + mtlpath.replace_extension(std::filesystem::path("mtl")); + + const std::string mtlpathString = std::filesystem::absolute(mtlpath).string(); + os << "mtllib " << mtlpathString << "\n"; std::ofstream mtlos; - mtlos.open(mtlpath); + mtlos.open(mtlpathString); + write(os, mtlos); os.close(); mtlos.close(); diff --git a/Core/include/Acts/Visualization/detail/PlyVisualization3D.ipp b/Core/include/Acts/Visualization/detail/PlyVisualization3D.ipp index b97dbde0fc9..c5c12b2dc89 100644 --- a/Core/include/Acts/Visualization/detail/PlyVisualization3D.ipp +++ b/Core/include/Acts/Visualization/detail/PlyVisualization3D.ipp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2020 CERN for the benefit of the Acts project +// Copyright (C) 2020-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 @@ -41,13 +41,13 @@ void PlyVisualization3D::line(const Vector3& a, const Vector3& b, } template -void PlyVisualization3D::write(const std::string& path) const { +void PlyVisualization3D::write(const std::filesystem::path& path) const { std::ofstream os; - std::string objectpath = path; - if (!IVisualization3D::hasExtension(path)) { - objectpath += std::string(".ply"); + std::filesystem::path objectpath = path; + if (!objectpath.has_extension()) { + objectpath.replace_extension(std::filesystem::path("ply")); } - os.open(objectpath); + os.open(std::filesystem::absolute(objectpath).string()); write(os); os.close(); } diff --git a/Core/src/Visualization/CMakeLists.txt b/Core/src/Visualization/CMakeLists.txt index ea2bd2427e6..5d4f916af1c 100644 --- a/Core/src/Visualization/CMakeLists.txt +++ b/Core/src/Visualization/CMakeLists.txt @@ -1,4 +1 @@ -target_sources( - ActsCore - PRIVATE IVisualization3D.cpp GeometryView3D.cpp EventDataView3D.cpp -) +target_sources(ActsCore PRIVATE GeometryView3D.cpp EventDataView3D.cpp) diff --git a/Core/src/Visualization/GeometryView3D.cpp b/Core/src/Visualization/GeometryView3D.cpp index 93f45c4e91d..14923b66a50 100644 --- a/Core/src/Visualization/GeometryView3D.cpp +++ b/Core/src/Visualization/GeometryView3D.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2020 CERN for the benefit of the Acts project +// Copyright (C) 2020-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 @@ -34,36 +34,12 @@ #include #include +#include #include #include #include #include -#include -#include - -namespace { - -std::string joinPaths(const std::string& a, const std::string& b) { - if (b.substr(0, 1) == "/" || a.empty()) { - return b; - } - - if (a.substr(a.size() - 1) == "/") { - return a.substr(a.size() - 1) + "/" + b; - } - - return a + "/" + b; -} - -std::string getWorkingDirectory() { - char buffer[PATH_MAX]; - return (getcwd(buffer, sizeof(buffer)) != nullptr ? std::string(buffer) - : std::string("")); -} - -} // namespace - namespace Acts::Experimental { ViewConfig s_viewSensitive = ViewConfig({0, 180, 240}); ViewConfig s_viewPassive = ViewConfig({240, 280, 0}); @@ -102,9 +78,7 @@ void Acts::GeometryView3D::drawSurfaceArray( IVisualization3D& helper, const SurfaceArray& surfaceArray, const GeometryContext& gctx, const Transform3& transform, const ViewConfig& sensitiveConfig, const ViewConfig& passiveConfig, - const ViewConfig& gridConfig, const std::string& _outputDir) { - std::string outputDir = - _outputDir == "." ? getWorkingDirectory() : _outputDir; + const ViewConfig& gridConfig, const std::filesystem::path& outputDir) { // Draw all the surfaces Extent arrayExtent; for (const auto& sf : surfaceArray.surfaces()) { @@ -117,7 +91,7 @@ void Acts::GeometryView3D::drawSurfaceArray( } if (!sensitiveConfig.outputName.empty()) { - helper.write(joinPaths(outputDir, sensitiveConfig.outputName)); + helper.write(outputDir / sensitiveConfig.outputName); helper.clear(); } @@ -181,7 +155,7 @@ void Acts::GeometryView3D::drawSurfaceArray( } if (!gridConfig.outputName.empty()) { - helper.write(joinPaths(outputDir, gridConfig.outputName)); + helper.write(outputDir / gridConfig.outputName); helper.clear(); } } @@ -239,10 +213,7 @@ void Acts::GeometryView3D::drawDetectorVolume( void Acts::GeometryView3D::drawLayer( IVisualization3D& helper, const Layer& layer, const GeometryContext& gctx, const ViewConfig& layerConfig, const ViewConfig& sensitiveConfig, - const ViewConfig& gridConfig, const std::string& _outputDir) { - std::string outputDir = - _outputDir == "." ? getWorkingDirectory() : _outputDir; - + const ViewConfig& gridConfig, const std::filesystem::path& outputDir) { if (layerConfig.visible) { auto layerVolume = layer.representingVolume(); if (layerVolume != nullptr) { @@ -254,7 +225,7 @@ void Acts::GeometryView3D::drawLayer( layerConfig); } if (!layerConfig.outputName.empty()) { - helper.write(joinPaths(outputDir, layerConfig.outputName)); + helper.write(outputDir / layerConfig.outputName); helper.clear(); } } @@ -273,9 +244,7 @@ void Acts::GeometryView3D::drawTrackingVolume( const GeometryContext& gctx, const ViewConfig& containerView, const ViewConfig& volumeView, const ViewConfig& layerView, const ViewConfig& sensitiveView, const ViewConfig& gridView, bool writeIt, - const std::string& tag, const std::string& _outputDir) { - std::string outputDir = - _outputDir == "." ? getWorkingDirectory() : _outputDir; + const std::string& tag, const std::filesystem::path& outputDir) { if (tVolume.confinedVolumes() != nullptr) { const auto& subVolumes = tVolume.confinedVolumes()->arrayObjects(); for (const auto& tv : subVolumes) { @@ -303,10 +272,9 @@ void Acts::GeometryView3D::drawTrackingVolume( } if (tVolume.confinedVolumes() == nullptr) { vcConfig = vConfig; - vcConfig.outputName = vname + std::string("_boundaries") + tag; + vcConfig.outputName = + std::filesystem::path(vname + std::string("_boundaries") + tag); } else { - std::stringstream vs; - vs << "Container"; std::vector ids{tVolume.geometryId().volume()}; for (const auto* current = &tVolume; current->motherVolume() != nullptr; @@ -314,11 +282,14 @@ void Acts::GeometryView3D::drawTrackingVolume( ids.push_back(current->motherVolume()->geometryId().volume()); } - for (std::size_t i = ids.size() - 1; i < ids.size(); --i) { - vs << "_v" << ids[i]; + std::ranges::reverse(ids); + vname = "Container"; + for (const auto& id : ids) { + vname += "_v" + std::to_string(id); } - vname = vs.str(); - vcConfig.outputName = vname + std::string("_boundaries") + tag; + + vcConfig.outputName = + std::filesystem::path(vname + std::string("_boundaries") + tag); } } @@ -328,7 +299,7 @@ void Acts::GeometryView3D::drawTrackingVolume( Transform3::Identity(), vcConfig); } if (writeIt) { - std::string outputName = joinPaths(outputDir, vcConfig.outputName); + const std::filesystem::path outputName = outputDir / vcConfig.outputName; helper.write(outputName); helper.clear(); } @@ -338,12 +309,12 @@ void Acts::GeometryView3D::drawTrackingVolume( std::size_t il = 0; for (const auto& tl : layers) { if (writeIt) { - lConfig.outputName = - vname + std::string("_passives_l") + std::to_string(il) + tag; - sConfig.outputName = - vname + std::string("_sensitives_l") + std::to_string(il) + tag; - gConfig.outputName = - vname + std::string("_grids_l") + std::to_string(il) + tag; + lConfig.outputName = std::filesystem::path( + vname + std::string("_passives_l") + std::to_string(il) + tag); + sConfig.outputName = std::filesystem::path( + vname + std::string("_sensitives_l") + std::to_string(il) + tag); + gConfig.outputName = std::filesystem::path( + vname + std::string("_grids_l") + std::to_string(il) + tag); } drawLayer(helper, *tl, gctx, lConfig, sConfig, gConfig, outputDir); ++il; diff --git a/Core/src/Visualization/IVisualization3D.cpp b/Core/src/Visualization/IVisualization3D.cpp deleted file mode 100644 index aad131a156d..00000000000 --- a/Core/src/Visualization/IVisualization3D.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// This file is part of the Acts project. -// -// Copyright (C) 2020 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/. - -#include "Acts/Visualization/IVisualization3D.hpp" - -bool Acts::IVisualization3D::hasExtension(const std::string& path) const { - return (path.find(".") != std::string::npos); -} - -void Acts::IVisualization3D::replaceExtension(std::string& path, - const std::string& suffix) const { - auto ppoint = path.find_last_of("."); - if (ppoint != std::string::npos) { - path.replace(ppoint, path.length(), suffix); - } else { - path += suffix; - } -} diff --git a/Examples/Io/Obj/src/ObjTrackingGeometryWriter.cpp b/Examples/Io/Obj/src/ObjTrackingGeometryWriter.cpp index 707add19bfd..a0f4948a1ff 100644 --- a/Examples/Io/Obj/src/ObjTrackingGeometryWriter.cpp +++ b/Examples/Io/Obj/src/ObjTrackingGeometryWriter.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2017 CERN for the benefit of the Acts project +// Copyright (C) 2017-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 @@ -14,6 +14,8 @@ #include #include +#include + ActsExamples::ObjTrackingGeometryWriter::ObjTrackingGeometryWriter( const ActsExamples::ObjTrackingGeometryWriter::Config& config, Acts::Logging::Level level) @@ -43,5 +45,5 @@ void ActsExamples::ObjTrackingGeometryWriter::write( Acts::GeometryView3D::drawTrackingVolume( objVis, tVolume, context.geoContext, m_cfg.containerView, m_cfg.volumeView, m_cfg.passiveView, m_cfg.sensitiveView, m_cfg.gridView, - true, "", m_cfg.outputDir); + true, "", std::filesystem::path(m_cfg.outputDir)); } From 13199a21c173193e83304f0dd96456a200b316a1 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Mon, 9 Sep 2024 21:16:17 +0200 Subject: [PATCH 4/8] refactor!: Replace `EigenStepper` extension list with single extension (#2865) Since we always only use one extension in the stepper and there are cases where it is beneficial to only worry about the state of a single extension I propose to remove the `Auctioneer` and the `StepperExtensionList`. This came up during working on the implementation of the covariance transport where our two default extensions would have to interact via state in the `EigenStepper` which is rather a mess. My proposed solution would move the state consistently to the extension. **issues** - https://github.com/acts-project/acts/issues/2868 --- Core/include/Acts/Propagator/EigenStepper.hpp | 22 +- Core/include/Acts/Propagator/EigenStepper.ipp | 128 +++++----- ...n.hpp => EigenStepperDefaultExtension.hpp} | 30 +-- ...EigenStepperDenseEnvironmentExtension.hpp} | 96 +++----- .../Acts/Propagator/MultiEigenStepperLoop.hpp | 23 +- .../Acts/Propagator/MultiEigenStepperLoop.ipp | 14 +- .../Acts/Propagator/StepperExtensionList.hpp | 232 ------------------ .../Acts/Propagator/detail/Auctioneer.hpp | 108 -------- .../TrackFitting/src/GsfFitterFunction.cpp | 9 +- .../PropagationDenseConstant.cpp | 7 +- .../Core/Propagator/AuctioneerTests.cpp | 52 ---- .../UnitTests/Core/Propagator/CMakeLists.txt | 1 - .../Core/Propagator/EigenStepperTests.cpp | 52 ++-- .../Core/Propagator/MultiStepperTests.cpp | 11 +- .../Core/Propagator/PropagatorTests.cpp | 8 +- .../Core/Propagator/SympyStepperTests.cpp | 4 - docs/core/propagation.md | 17 +- 17 files changed, 168 insertions(+), 646 deletions(-) rename Core/include/Acts/Propagator/{DefaultExtension.hpp => EigenStepperDefaultExtension.hpp} (91%) rename Core/include/Acts/Propagator/{DenseEnvironmentExtension.hpp => EigenStepperDenseEnvironmentExtension.hpp} (89%) delete mode 100644 Core/include/Acts/Propagator/StepperExtensionList.hpp delete mode 100644 Core/include/Acts/Propagator/detail/Auctioneer.hpp delete mode 100644 Tests/UnitTests/Core/Propagator/AuctioneerTests.cpp diff --git a/Core/include/Acts/Propagator/EigenStepper.hpp b/Core/include/Acts/Propagator/EigenStepper.hpp index f1c9f2995eb..52126c46fba 100644 --- a/Core/include/Acts/Propagator/EigenStepper.hpp +++ b/Core/include/Acts/Propagator/EigenStepper.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2016-2022 CERN for the benefit of the Acts project +// Copyright (C) 2016-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 @@ -15,20 +15,18 @@ #include "Acts/Definitions/Tolerance.hpp" #include "Acts/Definitions/Units.hpp" #include "Acts/EventData/TrackParameters.hpp" +#include "Acts/EventData/detail/CorrectedTransformationFreeToBound.hpp" +#include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/MagneticField/MagneticFieldContext.hpp" #include "Acts/MagneticField/MagneticFieldProvider.hpp" #include "Acts/Propagator/ConstrainedStep.hpp" -#include "Acts/Propagator/DefaultExtension.hpp" -#include "Acts/Propagator/DenseEnvironmentExtension.hpp" -#include "Acts/Propagator/EigenStepperError.hpp" +#include "Acts/Propagator/EigenStepperDefaultExtension.hpp" #include "Acts/Propagator/PropagatorTraits.hpp" -#include "Acts/Propagator/StepperExtensionList.hpp" #include "Acts/Propagator/StepperOptions.hpp" -#include "Acts/Propagator/detail/Auctioneer.hpp" #include "Acts/Propagator/detail/SteppingHelper.hpp" #include "Acts/Utilities/Intersection.hpp" #include "Acts/Utilities/Result.hpp" -#include #include #include #include @@ -47,8 +45,7 @@ namespace Acts { /// with s being the arc length of the track, q the charge of the particle, /// p the momentum magnitude and B the magnetic field /// -template , - typename auctioneer_t = detail::VoidAuctioneer> +template class EigenStepper { public: /// Jacobian, Covariance and State definitions @@ -155,11 +152,8 @@ class EigenStepper { /// The geometry context std::reference_wrapper geoContext; - /// List of algorithmic extensions - extensionlist_t extension; - - /// Auctioneer for choosing the extension - auctioneer_t auctioneer; + /// Algorithmic extension + extension_t extension; /// @brief Storage of magnetic field and the sub steps during a RKN4 step struct { diff --git a/Core/include/Acts/Propagator/EigenStepper.ipp b/Core/include/Acts/Propagator/EigenStepper.ipp index eb693a9148a..71aa342ed12 100644 --- a/Core/include/Acts/Propagator/EigenStepper.ipp +++ b/Core/include/Acts/Propagator/EigenStepper.ipp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2019-2022 CERN for the benefit of the Acts project +// Copyright (C) 2019-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 @@ -8,30 +8,31 @@ #include "Acts/EventData/TransformationHelpers.hpp" #include "Acts/Propagator/ConstrainedStep.hpp" +#include "Acts/Propagator/EigenStepperError.hpp" #include "Acts/Propagator/detail/CovarianceEngine.hpp" #include "Acts/Utilities/QuickMath.hpp" #include -template -Acts::EigenStepper::EigenStepper( +template +Acts::EigenStepper::EigenStepper( std::shared_ptr bField) : m_bField(std::move(bField)) {} -template -auto Acts::EigenStepper::makeState( +template +auto Acts::EigenStepper::makeState( std::reference_wrapper gctx, std::reference_wrapper mctx, const BoundTrackParameters& par, double ssize) const -> State { return State{gctx, m_bField->makeCache(mctx), par, ssize}; } -template -void Acts::EigenStepper::resetState(State& state, - const BoundVector& boundParams, - const BoundSquareMatrix& cov, - const Surface& surface, - const double stepSize) const { +template +void Acts::EigenStepper::resetState(State& state, + const BoundVector& boundParams, + const BoundSquareMatrix& cov, + const Surface& surface, + const double stepSize) const { FreeVector freeParams = transformBoundToFreeParameters(surface, state.geoContext, boundParams); @@ -50,8 +51,8 @@ void Acts::EigenStepper::resetState(State& state, state.derivative = FreeVector::Zero(); } -template -auto Acts::EigenStepper::boundState( +template +auto Acts::EigenStepper::boundState( State& state, const Surface& surface, bool transportCov, const FreeToBoundCorrection& freeToBoundCorrection) const -> Result { @@ -62,36 +63,32 @@ auto Acts::EigenStepper::boundState( freeToBoundCorrection); } -template +template template -bool Acts::EigenStepper::prepareCurvilinearState( +bool Acts::EigenStepper::prepareCurvilinearState( propagator_state_t& prop_state, const navigator_t& navigator) const { // test whether the accumulated path has still its initial value. if (prop_state.stepping.pathAccumulated == 0.) { // if no step was executed the path length derivates have not been // computed but are needed to compute the curvilinear covariance. The // derivates are given by k1 for a zero step width. - if (prop_state.stepping.extension.validExtensionForStep(prop_state, *this, - navigator)) { - // First Runge-Kutta point (at current position) - auto& sd = prop_state.stepping.stepData; - auto pos = position(prop_state.stepping); - auto fieldRes = getField(prop_state.stepping, pos); - if (fieldRes.ok()) { - sd.B_first = *fieldRes; - if (prop_state.stepping.extension.k1(prop_state, *this, navigator, - sd.k1, sd.B_first, sd.kQoP)) { - // dr/ds : - prop_state.stepping.derivative.template head<3>() = - prop_state.stepping.pars.template segment<3>(eFreeDir0); - // d (dr/ds) / ds : - prop_state.stepping.derivative.template segment<3>(4) = sd.k1; - // to set dt/ds : - prop_state.stepping.extension.finalize( - prop_state, *this, navigator, - prop_state.stepping.pathAccumulated); - return true; - } + // First Runge-Kutta point (at current position) + auto& sd = prop_state.stepping.stepData; + auto pos = position(prop_state.stepping); + auto fieldRes = getField(prop_state.stepping, pos); + if (fieldRes.ok()) { + sd.B_first = *fieldRes; + if (prop_state.stepping.extension.template k<0>( + prop_state, *this, navigator, sd.k1, sd.B_first, sd.kQoP)) { + // dr/ds : + prop_state.stepping.derivative.template head<3>() = + prop_state.stepping.pars.template segment<3>(eFreeDir0); + // d (dr/ds) / ds : + prop_state.stepping.derivative.template segment<3>(4) = sd.k1; + // to set dt/ds : + prop_state.stepping.extension.finalize( + prop_state, *this, navigator, prop_state.stepping.pathAccumulated); + return true; } } return false; @@ -99,8 +96,8 @@ bool Acts::EigenStepper::prepareCurvilinearState( return true; } -template -auto Acts::EigenStepper::curvilinearState( +template +auto Acts::EigenStepper::curvilinearState( State& state, bool transportCov) const -> CurvilinearState { return detail::curvilinearState( state.cov, state.jacobian, state.jacTransport, state.derivative, @@ -108,12 +105,11 @@ auto Acts::EigenStepper::curvilinearState( state.covTransport && transportCov, state.pathAccumulated); } -template -void Acts::EigenStepper::update(State& state, - const FreeVector& freeParams, - const BoundVector& /*boundParams*/, - const Covariance& covariance, - const Surface& surface) const { +template +void Acts::EigenStepper::update(State& state, const FreeVector& freeParams, + const BoundVector& /*boundParams*/, + const Covariance& covariance, + const Surface& surface) const { state.pars = freeParams; state.cov = covariance; state.jacToGlobal = surface.boundToFreeJacobian( @@ -121,26 +117,26 @@ void Acts::EigenStepper::update(State& state, freeParams.template segment<3>(eFreeDir0)); } -template -void Acts::EigenStepper::update(State& state, const Vector3& uposition, - const Vector3& udirection, double qOverP, - double time) const { +template +void Acts::EigenStepper::update(State& state, const Vector3& uposition, + const Vector3& udirection, double qOverP, + double time) const { state.pars.template segment<3>(eFreePos0) = uposition; state.pars.template segment<3>(eFreeDir0) = udirection; state.pars[eFreeTime] = time; state.pars[eFreeQOverP] = qOverP; } -template -void Acts::EigenStepper::transportCovarianceToCurvilinear( +template +void Acts::EigenStepper::transportCovarianceToCurvilinear( State& state) const { detail::transportCovarianceToCurvilinear(state.cov, state.jacobian, state.jacTransport, state.derivative, state.jacToGlobal, direction(state)); } -template -void Acts::EigenStepper::transportCovarianceToBound( +template +void Acts::EigenStepper::transportCovarianceToBound( State& state, const Surface& surface, const FreeToBoundCorrection& freeToBoundCorrection) const { detail::transportCovarianceToBound(state.geoContext.get(), surface, state.cov, @@ -149,9 +145,9 @@ void Acts::EigenStepper::transportCovarianceToBound( state.pars, freeToBoundCorrection); } -template +template template -Acts::Result Acts::EigenStepper::step( +Acts::Result Acts::EigenStepper::step( propagator_state_t& state, const navigator_t& navigator) const { // Runge-Kutta integrator state auto& sd = state.stepping.stepData; @@ -169,10 +165,8 @@ Acts::Result Acts::EigenStepper::step( return fieldRes.error(); } sd.B_first = *fieldRes; - if (!state.stepping.extension.validExtensionForStep(state, *this, - navigator) || - !state.stepping.extension.k1(state, *this, navigator, sd.k1, sd.B_first, - sd.kQoP)) { + if (!state.stepping.extension.template k<0>(state, *this, navigator, sd.k1, + sd.B_first, sd.kQoP)) { return 0.; } @@ -230,14 +224,16 @@ Acts::Result Acts::EigenStepper::step( } sd.B_middle = *field; - if (!state.stepping.extension.k2(state, *this, navigator, sd.k2, - sd.B_middle, sd.kQoP, half_h, sd.k1)) { + if (!state.stepping.extension.template k<1>(state, *this, navigator, sd.k2, + sd.B_middle, sd.kQoP, half_h, + sd.k1)) { return success(false); } // Third Runge-Kutta point - if (!state.stepping.extension.k3(state, *this, navigator, sd.k3, - sd.B_middle, sd.kQoP, half_h, sd.k2)) { + if (!state.stepping.extension.template k<2>(state, *this, navigator, sd.k3, + sd.B_middle, sd.kQoP, half_h, + sd.k2)) { return success(false); } @@ -248,8 +244,8 @@ Acts::Result Acts::EigenStepper::step( return failure(field.error()); } sd.B_last = *field; - if (!state.stepping.extension.k4(state, *this, navigator, sd.k4, sd.B_last, - sd.kQoP, h, sd.k3)) { + if (!state.stepping.extension.template k<3>(state, *this, navigator, sd.k4, + sd.B_last, sd.kQoP, h, sd.k3)) { return success(false); } @@ -373,7 +369,7 @@ Acts::Result Acts::EigenStepper::step( return h; } -template -void Acts::EigenStepper::setIdentityJacobian(State& state) const { +template +void Acts::EigenStepper::setIdentityJacobian(State& state) const { state.jacobian = BoundMatrix::Identity(); } diff --git a/Core/include/Acts/Propagator/DefaultExtension.hpp b/Core/include/Acts/Propagator/EigenStepperDefaultExtension.hpp similarity index 91% rename from Core/include/Acts/Propagator/DefaultExtension.hpp rename to Core/include/Acts/Propagator/EigenStepperDefaultExtension.hpp index 1ae901f42eb..cf6cadbbb41 100644 --- a/Core/include/Acts/Propagator/DefaultExtension.hpp +++ b/Core/include/Acts/Propagator/EigenStepperDefaultExtension.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2018-2023 CERN for the benefit of the Acts project +// Copyright (C) 2018-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 @@ -18,28 +18,15 @@ namespace Acts { /// @brief Default evaluater of the k_i's and elements of the transport matrix /// D of the RKN4 stepping. This is a pure implementation by textbook. -struct DefaultExtension { +struct EigenStepperDefaultExtension { using Scalar = ActsScalar; /// @brief Vector3 replacement for the custom scalar type using ThisVector3 = Eigen::Matrix; - /// @brief Control function if the step evaluation would be valid - /// - /// @tparam propagator_state_t Type of the state of the propagator - /// @tparam stepper_t Type of the stepper - /// @tparam navigator_t Type of the navigator - /// - /// @return Boolean flag if the step would be valid - template - int bid(const propagator_state_t& /*state*/, const stepper_t& /*stepper*/, - const navigator_t& /*navigator*/) const { - return 1; - } - /// @brief Evaluater of the k_i's of the RKN4. For the case of i = 0 this /// step sets up qop, too. /// + /// @tparam i Index of the k_i, i = [0, 3] /// @tparam propagator_state_t Type of the state of the propagator /// @tparam stepper_t Type of the stepper /// @tparam navigator_t Type of the navigator @@ -49,20 +36,21 @@ struct DefaultExtension { /// @param [out] knew Next k_i that is evaluated /// @param [in] bField B-Field at the evaluation position /// @param [out] kQoP k_i elements of the momenta - /// @param [in] i Index of the k_i, i = [0, 3] /// @param [in] h Step size (= 0. ^ 0.5 * StepSize ^ StepSize) /// @param [in] kprev Evaluated k_{i - 1} /// /// @return Boolean flag if the calculation is valid - template bool k(const propagator_state_t& state, const stepper_t& stepper, const navigator_t& /*navigator*/, ThisVector3& knew, - const Vector3& bField, std::array& kQoP, const int i = 0, - const double h = 0., const ThisVector3& kprev = ThisVector3::Zero()) { + const Vector3& bField, std::array& kQoP, + const double h = 0., const ThisVector3& kprev = ThisVector3::Zero()) + requires(i >= 0 && i <= 3) + { auto qop = stepper.qOverP(state.stepping); // First step does not rely on previous data - if (i == 0) { + if constexpr (i == 0) { knew = qop * stepper.direction(state.stepping).cross(bField); kQoP = {0., 0., 0., 0.}; } else { diff --git a/Core/include/Acts/Propagator/DenseEnvironmentExtension.hpp b/Core/include/Acts/Propagator/EigenStepperDenseEnvironmentExtension.hpp similarity index 89% rename from Core/include/Acts/Propagator/DenseEnvironmentExtension.hpp rename to Core/include/Acts/Propagator/EigenStepperDenseEnvironmentExtension.hpp index eed51e1e847..befab8f96ce 100644 --- a/Core/include/Acts/Propagator/DenseEnvironmentExtension.hpp +++ b/Core/include/Acts/Propagator/EigenStepperDenseEnvironmentExtension.hpp @@ -12,16 +12,11 @@ #include "Acts/Utilities/detail/ReferenceWrapperAnyCompat.hpp" #include "Acts/Definitions/Algebra.hpp" -#include "Acts/Definitions/PdgParticle.hpp" -#include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/Material/Interactions.hpp" -#include "Acts/Propagator/AbortList.hpp" -#include "Acts/Propagator/ActionList.hpp" +#include "Acts/Material/Material.hpp" +#include "Acts/Material/MaterialSlab.hpp" +#include "Acts/Propagator/EigenStepperDefaultExtension.hpp" #include "Acts/Propagator/Propagator.hpp" -#include "Acts/Utilities/VectorHelpers.hpp" - -#include -#include namespace Acts { @@ -30,11 +25,14 @@ namespace Acts { /// ioninisation, bremsstrahlung, pair production and photonuclear interaction /// in the propagation and the jacobian. These effects will only occur if the /// propagation is in a TrackingVolume with attached material. -struct DenseEnvironmentExtension { +struct EigenStepperDenseEnvironmentExtension { using Scalar = ActsScalar; /// @brief Vector3 replacement for the custom scalar type using ThisVector3 = Eigen::Matrix; + /// Fallback extension + EigenStepperDefaultExtension defaultExtension; + /// Momentum at a certain point Scalar currentMomentum = 0.; /// Particles momentum at k1 @@ -59,44 +57,11 @@ struct DenseEnvironmentExtension { /// Energy at each sub-step std::array energy{}; - /// @brief Control function if the step evaluation would be valid - /// - /// @tparam propagator_state_t Type of the state of the propagator - /// @tparam stepper_t Type of the stepper - /// @tparam navigator_t Type of the navigator - /// - /// @param [in] state State of the propagator - /// @param [in] stepper Stepper of the propagator - /// @param [in] navigator Navigator of the propagator - /// - /// @return Boolean flag if the step would be valid - template - int bid(const propagator_state_t& state, const stepper_t& stepper, - const navigator_t& navigator) const { - const auto& particleHypothesis = stepper.particleHypothesis(state.stepping); - float absQ = particleHypothesis.absoluteCharge(); - float mass = particleHypothesis.mass(); - - // Check for valid particle properties - if (absQ == 0. || mass == 0. || - stepper.absoluteMomentum(state.stepping) < - state.options.stepping.dense.momentumCutOff) { - return 0; - } - - // Check existence of a volume with material - if (!navigator.currentVolumeMaterial(state.navigation)) { - return 0; - } - - return 2; - } - /// @brief Evaluater of the k_i's of the RKN4. For the case of i = 0 this /// step sets up member parameters, too. /// - /// @tparam stepper_state_t Type of the state of the propagator + /// @tparam i Index of the k_i, i = [0, 3] + /// @tparam propagator_state_t Type of the state of the propagator /// @tparam stepper_t Type of the stepper /// @tparam navigator_t Type of the navigator /// @@ -106,30 +71,32 @@ struct DenseEnvironmentExtension { /// @param [out] knew Next k_i that is evaluated /// @param [out] kQoP k_i elements of the momenta /// @param [in] bField B-Field at the evaluation position - /// @param [in] i Index of the k_i, i = [0, 3] /// @param [in] h Step size (= 0. ^ 0.5 * StepSize ^ StepSize) /// @param [in] kprev Evaluated k_{i - 1} /// /// @return Boolean flag if the calculation is valid - template bool k(const propagator_state_t& state, const stepper_t& stepper, const navigator_t& navigator, ThisVector3& knew, const Vector3& bField, - std::array& kQoP, const int i = 0, const double h = 0., - const ThisVector3& kprev = ThisVector3::Zero()) { + std::array& kQoP, const double h = 0., + const ThisVector3& kprev = ThisVector3::Zero()) + requires(i >= 0 && i <= 3) + { + const auto* volumeMaterial = + navigator.currentVolumeMaterial(state.navigation); + if (volumeMaterial == nullptr) { + return defaultExtension.template k(state, stepper, navigator, knew, + bField, kQoP, h, kprev); + } + double q = stepper.charge(state.stepping); const auto& particleHypothesis = stepper.particleHypothesis(state.stepping); float mass = particleHypothesis.mass(); // i = 0 is used for setup and evaluation of k - if (i == 0) { - // Set up container for energy loss - const auto* volumeMaterial = - navigator.currentVolumeMaterial(state.navigation); - if (volumeMaterial == nullptr) { - // This function is very hot, so we prefer to terminate here - std::terminate(); - } + if constexpr (i == 0) { + // Set up for energy loss ThisVector3 position = stepper.position(state.stepping); material = volumeMaterial->material(position.template cast()); initialMomentum = stepper.absoluteMomentum(state.stepping); @@ -172,13 +139,20 @@ struct DenseEnvironmentExtension { /// /// @param [in] state State of the propagator /// @param [in] stepper Stepper of the propagator + /// @param [in] navigator Navigator of the propagator /// @param [in] h Step size /// /// @return Boolean flag if the calculation is valid template bool finalize(propagator_state_t& state, const stepper_t& stepper, - const navigator_t& /*navigator*/, const double h) const { + const navigator_t& navigator, const double h) const { + const auto* volumeMaterial = + navigator.currentVolumeMaterial(state.navigation); + if (volumeMaterial == nullptr) { + return defaultExtension.finalize(state, stepper, navigator, h); + } + const auto& particleHypothesis = stepper.particleHypothesis(state.stepping); float mass = particleHypothesis.mass(); @@ -231,6 +205,12 @@ struct DenseEnvironmentExtension { bool finalize(propagator_state_t& state, const stepper_t& stepper, const navigator_t& navigator, const double h, FreeMatrix& D) const { + const auto* volumeMaterial = + navigator.currentVolumeMaterial(state.navigation); + if (volumeMaterial == nullptr) { + return defaultExtension.finalize(state, stepper, navigator, h, D); + } + return finalize(state, stepper, navigator, h) && transportMatrix(state, stepper, h, D); } @@ -398,7 +378,7 @@ struct DenseEnvironmentExtension { energy[0] = std::hypot(initialMomentum, mass); // use unit length as thickness to compute the energy loss per unit length - Acts::MaterialSlab slab(material, 1); + MaterialSlab slab(material, 1); // Use the same energy loss throughout the step. if (state.options.stepping.dense.meanEnergyLoss) { g = -computeEnergyLossMean(slab, absPdg, mass, static_cast(qop[0]), diff --git a/Core/include/Acts/Propagator/MultiEigenStepperLoop.hpp b/Core/include/Acts/Propagator/MultiEigenStepperLoop.hpp index dce5c475bc8..357d6b7b4bb 100644 --- a/Core/include/Acts/Propagator/MultiEigenStepperLoop.hpp +++ b/Core/include/Acts/Propagator/MultiEigenStepperLoop.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2021-2023 CERN for the benefit of the Acts project +// Copyright (C) 2021-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 @@ -22,6 +22,7 @@ #include "Acts/Propagator/ConstrainedStep.hpp" #include "Acts/Propagator/EigenStepper.hpp" #include "Acts/Propagator/EigenStepperError.hpp" +#include "Acts/Propagator/MultiStepperError.hpp" #include "Acts/Propagator/Propagator.hpp" #include "Acts/Propagator/StepperOptions.hpp" #include "Acts/Propagator/detail/LoopStepperUtils.hpp" @@ -40,8 +41,6 @@ #include -#include "MultiStepperError.hpp" - namespace Acts { using namespace Acts::UnitLiterals; @@ -235,17 +234,14 @@ using MaxWeightReducerLoop = /// * There are certain redundancies between the global State and the /// component states /// * The components do not share a single magnetic-field-cache -/// @tparam extensionlist_t See EigenStepper for details +/// @tparam extension_t See EigenStepper for details /// @tparam component_reducer_t How to map the multi-component state to a single /// component -/// @tparam auctioneer_t See EigenStepper for details /// @tparam small_vector_size A size-hint how much memory should be allocated /// by the small vector -template , - typename component_reducer_t = WeightedComponentReducerLoop, - typename auctioneer_t = detail::VoidAuctioneer> -class MultiEigenStepperLoop - : public EigenStepper { +template +class MultiEigenStepperLoop : public EigenStepper { /// Limits the number of steps after at least one component reached the /// surface std::size_t m_stepLimitAfterFirstComponentOnSurface = 50; @@ -260,7 +256,7 @@ class MultiEigenStepperLoop public: /// @brief Typedef to the Single-Component Eigen Stepper - using SingleStepper = EigenStepper; + using SingleStepper = EigenStepper; /// @brief Typedef to the State of the single component Stepper using SingleState = typename SingleStepper::State; @@ -366,15 +362,14 @@ class MultiEigenStepperLoop MultiEigenStepperLoop(std::shared_ptr bField, std::unique_ptr logger = getDefaultLogger("GSF", Logging::INFO)) - : EigenStepper(std::move(bField)), + : EigenStepper(std::move(bField)), m_logger(std::move(logger)) {} /// Constructor from a configuration and optionally provided Logger MultiEigenStepperLoop(const Config& config, std::unique_ptr logger = getDefaultLogger("GSF", Logging::INFO)) - : EigenStepper(config), - m_logger(std::move(logger)) {} + : EigenStepper(config), m_logger(std::move(logger)) {} /// Construct and initialize a state State makeState(std::reference_wrapper gctx, diff --git a/Core/include/Acts/Propagator/MultiEigenStepperLoop.ipp b/Core/include/Acts/Propagator/MultiEigenStepperLoop.ipp index f743d059a2f..8f9d3216d6a 100644 --- a/Core/include/Acts/Propagator/MultiEigenStepperLoop.ipp +++ b/Core/include/Acts/Propagator/MultiEigenStepperLoop.ipp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2023 CERN for the benefit of the Acts project +// Copyright (C) 2023-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 @@ -11,8 +11,8 @@ namespace Acts { -template -auto MultiEigenStepperLoop::boundState( +template +auto MultiEigenStepperLoop::boundState( State& state, const Surface& surface, bool transportCov, const FreeToBoundCorrection& freeToBoundCorrection) const -> Result { @@ -62,8 +62,8 @@ auto MultiEigenStepperLoop::boundState( Jacobian::Zero(), accumulatedPathLength}; } -template -auto MultiEigenStepperLoop::curvilinearState( +template +auto MultiEigenStepperLoop::curvilinearState( State& state, bool transportCov) const -> CurvilinearState { assert(!state.components.empty()); @@ -89,9 +89,9 @@ auto MultiEigenStepperLoop::curvilinearState( Jacobian::Zero(), accumulatedPathLength}; } -template +template template -Result MultiEigenStepperLoop::step( +Result MultiEigenStepperLoop::step( propagator_state_t& state, const navigator_t& navigator) const { using Status = Acts::Intersection3D::Status; diff --git a/Core/include/Acts/Propagator/StepperExtensionList.hpp b/Core/include/Acts/Propagator/StepperExtensionList.hpp deleted file mode 100644 index 3454030dd5c..00000000000 --- a/Core/include/Acts/Propagator/StepperExtensionList.hpp +++ /dev/null @@ -1,232 +0,0 @@ -// This file is part of the Acts project. -// -// Copyright (C) 2021 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/Definitions/TrackParametrization.hpp" -#include "Acts/Propagator/detail/Auctioneer.hpp" -#include "Acts/Utilities/detail/Extendable.hpp" -#include "Acts/Utilities/detail/MPL/all_of.hpp" -#include "Acts/Utilities/detail/MPL/has_duplicates.hpp" - -#include - -namespace Acts { - -/// @brief Container of extensions used in the stepper of the propagation. This -/// struct allows a broadcast of function calls for each element in the list. -/// The broadcasts occur for a certain function at each step in a specific -/// order. -/// The first function is an evaluater if an extension is or how many extensions -/// are applicable for an upcoming step. -/// The next functions called are the evaluations of the k_1 - k_4 or the RKN4 -/// integration. -/// The last function call in a step is the finalize() method. This method is an -/// overloaded function (optionally propagates the covariance). -/// Each method has the possibility to break the evaluation of a given step if -/// an extension reports that something went wrong (e.g. a particle lost too -/// much momentum during the step) -/// @tparam extensions Types of the extensions -template -struct StepperExtensionList : private detail::Extendable { - private: - // Checkout for duplicates in the extensions - static_assert(!detail::has_duplicates_v, - "same extension type specified several times"); - - static constexpr unsigned int nExtensions = sizeof...(extensions); - - static_assert(nExtensions != 0, "no extension type specified"); - - // Access to all extensions - using detail::Extendable::tuple; - - // Vector of valid extensions for a step - std::array validExtensions{}; - - public: - // Access to an extension - using detail::Extendable::get; - - /// @brief Evaluation function to set valid extensions for an upcoming - /// integration step - /// - /// @tparam propagator_state_t Type of the state of the propagator - /// @tparam stepper_t Type of the stepper - /// @tparam navigtor_t Type of the navigator - /// - /// @param [in] state State of the propagator - /// @param [in] stepper Stepper of the propagation - /// @param [in] navigator Navigator of the propagation - template - bool validExtensionForStep(const propagator_state_t& state, - const stepper_t& stepper, - const navigtor_t& navigator) { - const auto bids = std::apply( - [&](const auto&... ext) { - return std::array{ - ext.bid(state, stepper, navigator)...}; - }, - tuple()); - - validExtensions = state.stepping.auctioneer(std::move(bids)); - - return (std::find(validExtensions.begin(), validExtensions.end(), true) != - validExtensions.end()); - } - - /// @brief This functions broadcasts the call for evaluating a generic k. It - /// collects all arguments and extensions, test their validity for the - /// evaluation and passes them forward for evaluation and returns a boolean as - /// indicator if the evaluation is valid. - template - bool k(const propagator_state_t& state, const stepper_t& stepper, - const navigator_t& navigator, Vector3& knew, const Vector3& bField, - std::array& kQoP, const int i, const double h = 0., - const Vector3& kprev = Vector3::Zero()) { - // TODO replace with integer-templated lambda with C++20 - auto impl = [&, i, h](auto intType, auto& implRef) { - constexpr int N = decltype(intType)::value; - - if constexpr (N == 0) { - return true; - } else { - // If element is invalid: continue - if (!std::get(validExtensions)) { - return implRef(std::integral_constant{}, implRef); - } - // Continue as long as evaluations are 'true' - if (std::get(this->tuple()) - .template k(state, stepper, navigator, knew, bField, kQoP, i, h, - kprev)) { - return implRef(std::integral_constant{}, implRef); - } else { - // Break at false - return false; - } - } - }; - - return impl(std::integral_constant{}, impl); - } - - /// @brief This functions broadcasts the call for evaluating k1. It collects - /// all arguments and extensions, test their validity for the evaluation and - /// passes them forward for evaluation and returns a boolean as indicator if - /// the evaluation is valid. - template - bool k1(const propagator_state_t& state, const stepper_t& stepper, - const navigator_t& navigator, Vector3& knew, const Vector3& bField, - std::array& kQoP) { - return k(state, stepper, navigator, knew, bField, kQoP, 0); - } - - /// @brief This functions broadcasts the call for evaluating k2. It collects - /// all arguments and extensions and passes them forward for evaluation and - /// returns a boolean as indicator if the evaluation is valid. - template - bool k2(const propagator_state_t& state, const stepper_t& stepper, - const navigator_t& navigator, Vector3& knew, const Vector3& bField, - std::array& kQoP, const double h, const Vector3& kprev) { - return k(state, stepper, navigator, knew, bField, kQoP, 1, h, kprev); - } - - /// @brief This functions broadcasts the call for evaluating k3. It collects - /// all arguments and extensions and passes them forward for evaluation and - /// returns a boolean as indicator if the evaluation is valid. - template - bool k3(const propagator_state_t& state, const stepper_t& stepper, - const navigator_t& navigator, Vector3& knew, const Vector3& bField, - std::array& kQoP, const double h, const Vector3& kprev) { - return k(state, stepper, navigator, knew, bField, kQoP, 2, h, kprev); - } - - /// @brief This functions broadcasts the call for evaluating k4. It collects - /// all arguments and extensions and passes them forward for evaluation and - /// returns a boolean as indicator if the evaluation is valid. - template - bool k4(const propagator_state_t& state, const stepper_t& stepper, - const navigator_t& navigator, Vector3& knew, const Vector3& bField, - std::array& kQoP, const double h, const Vector3& kprev) { - return k(state, stepper, navigator, knew, bField, kQoP, 3, h, kprev); - } - - /// @brief This functions broadcasts the call of the method finalize(). It - /// collects all extensions and arguments and passes them forward for - /// evaluation and returns a boolean. - template - bool finalize(propagator_state_t& state, const stepper_t& stepper, - const navigator_t& navigator, const double h, FreeMatrix& D) { - // TODO replace with integer-templated lambda with C++20 - auto impl = [&, h](auto intType, auto& implRef) { - constexpr int N = decltype(intType)::value; - - if constexpr (N == 0) { - return true; - } else { - // If element is invalid: continue - if (!std::get(validExtensions)) { - return implRef(std::integral_constant{}, implRef); - } - // Continue as long as evaluations are 'true' - if (std::get(this->tuple()) - .finalize(state, stepper, navigator, h, D)) { - return implRef(std::integral_constant{}, implRef); - } else { - // Break at false - return false; - } - } - }; - - return impl(std::integral_constant{}, impl); - } - - /// @brief This functions broadcasts the call of the method finalize(). It - /// collects all extensions and arguments and passes them forward for - /// evaluation and returns a boolean. - template - bool finalize(propagator_state_t& state, const stepper_t& stepper, - const navigator_t& navigator, const double h) { - // TODO replace with integer-templated lambda with C++20 - auto impl = [&, h](auto intType, auto& implRef) { - constexpr int N = decltype(intType)::value; - - if constexpr (N == 0) { - return true; - } else { - // If element is invalid: continue - if (!std::get(validExtensions)) { - return implRef(std::integral_constant{}, implRef); - } - - // Continue as long as evaluations are 'true' - if (std::get(this->tuple()) - .finalize(state, stepper, navigator, h)) { - return implRef(std::integral_constant{}, implRef); - } else { - // Break at false - return false; - } - } - }; - - return impl(std::integral_constant{}, impl); - } -}; - -} // namespace Acts diff --git a/Core/include/Acts/Propagator/detail/Auctioneer.hpp b/Core/include/Acts/Propagator/detail/Auctioneer.hpp deleted file mode 100644 index e086526d327..00000000000 --- a/Core/include/Acts/Propagator/detail/Auctioneer.hpp +++ /dev/null @@ -1,108 +0,0 @@ -// This file is part of the Acts project. -// -// Copyright (C) 2016-2018 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 -#include - -namespace Acts::detail { -/// The StepperExtensionList allows to add an arbitrary number of step -/// evaluation algorithms for the RKN4 evaluation. These can be categorised in -/// two general types: -/// a) Step evaluation that should not be evaluated along with other -/// extensions, or at least would overwrite partial results. This means that -/// in the best case unnecessary/redundant calculation would be performed, in -/// the worst case the evaluation would go wrong. -/// b) The step evaluation remains untouched and only further calculations are -/// performed (like additional features or data gathering) that can be treated -/// as independent of the basic step evaluation in type a). These types can be -/// added but do not require special treatment in order to not ruin the step -/// evaluation. -/// The concept of the auctioneers aims in the first place to judge which -/// extension of category a) is the one to go. Although every extension can -/// judge if it is valid based on the data given from the state of stepper, -/// multiple extensions from type a) could fulfill their dependencies. Since -/// an extension does not know about other extensions, the decision for the -/// best extension for the step can only be estimated on a global scope. This -/// is the job of the auctioneers. -/// -/// TODO: An anticipation of an optimal concept of the input (and maybe also -/// the output) of the call operator of an auctioneer cannot be performed at -/// the current stage. At the current stage, a real bid-system would be pure -/// guessing. - -/// @brief Auctioneer that takes all extensions as valid that make a valid bid -struct VoidAuctioneer { - /// @brief Default constructor - VoidAuctioneer() = default; - - /// @brief Call operator that returns the list of valid candidates as valids - /// - /// @param [in] vCandidates Candidates that are treated as valid extensions - /// @return The to vCandidates identical list of valid extensions - template - std::array operator()(std::array vCandidates) const { - std::array valids{}; - - for (unsigned int i = 0; i < vCandidates.size(); i++) { - valids[i] = (vCandidates[i] > 0) ? true : false; - } - return valids; - } -}; - -/// @brief Auctioneer that states only the first one that makes a valid bid -struct FirstValidAuctioneer { - /// @brief Default constructor - FirstValidAuctioneer() = default; - - /// @brief Call operator that states the first valid extension as the only - /// valid extension - /// - /// @param [in] vCandidates Candidates for a valid extension - /// @return List with at most one valid extension - template - std::array operator()(std::array vCandidates) const { - std::array valids = {}; - - for (unsigned int i = 0; i < vCandidates.size(); i++) { - if (vCandidates[i] > 0) { - valids[i] = true; - return valids; - } - } - return valids; - } -}; - -/// @brief Auctioneer that makes only the highest bidding extension valid. If -/// multiple elements have the same int, the first one with this value is -/// picked. -struct HighestValidAuctioneer { - /// @brief Default constructor - HighestValidAuctioneer() = default; - - /// @brief Call operator that states the highest bidding extension as the - /// only - /// valid extension - /// - /// @param [in] vCandidates Candidates for a valid extension - /// @return List with at most one valid extension - template - std::array operator()(std::array vCandidates) const { - std::array valids = {}; - - auto highscore = std::max_element(vCandidates.begin(), vCandidates.end()); - valids.at(std::distance(vCandidates.begin(), highscore)) = true; - - return valids; - } -}; - -} // namespace Acts::detail diff --git a/Examples/Algorithms/TrackFitting/src/GsfFitterFunction.cpp b/Examples/Algorithms/TrackFitting/src/GsfFitterFunction.cpp index bfadb103a25..8770b77bf52 100644 --- a/Examples/Algorithms/TrackFitting/src/GsfFitterFunction.cpp +++ b/Examples/Algorithms/TrackFitting/src/GsfFitterFunction.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2022 CERN for the benefit of the Acts project +// Copyright (C) 2022-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 @@ -19,7 +19,6 @@ #include "Acts/Propagator/MultiEigenStepperLoop.hpp" #include "Acts/Propagator/Navigator.hpp" #include "Acts/Propagator/Propagator.hpp" -#include "Acts/Propagator/StepperExtensionList.hpp" #include "Acts/TrackFitting/GainMatrixUpdater.hpp" #include "Acts/TrackFitting/GaussianSumFitter.hpp" #include "Acts/TrackFitting/GsfMixtureReduction.hpp" @@ -58,9 +57,9 @@ using namespace ActsExamples; namespace { -using MultiStepper = Acts::MultiEigenStepperLoop< - Acts::StepperExtensionList, - Acts::MaxWeightReducerLoop>; +using MultiStepper = + Acts::MultiEigenStepperLoop; using Propagator = Acts::Propagator; using DirectPropagator = Acts::Propagator; diff --git a/Tests/IntegrationTests/PropagationDenseConstant.cpp b/Tests/IntegrationTests/PropagationDenseConstant.cpp index 381e7639111..c27e38088b4 100644 --- a/Tests/IntegrationTests/PropagationDenseConstant.cpp +++ b/Tests/IntegrationTests/PropagationDenseConstant.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2020 CERN for the benefit of the Acts project +// Copyright (C) 2020-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 @@ -15,8 +15,8 @@ #include "Acts/MagneticField/ConstantBField.hpp" #include "Acts/MagneticField/MagneticFieldContext.hpp" #include "Acts/Material/HomogeneousVolumeMaterial.hpp" -#include "Acts/Propagator/DenseEnvironmentExtension.hpp" #include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/EigenStepperDenseEnvironmentExtension.hpp" #include "Acts/Propagator/Navigator.hpp" #include "Acts/Propagator/Propagator.hpp" #include "Acts/Propagator/RiddersPropagator.hpp" @@ -34,8 +34,7 @@ namespace ds = ActsTests::PropagationDatasets; using namespace Acts::UnitLiterals; using MagneticField = Acts::ConstantBField; -using Stepper = Acts::EigenStepper< - Acts::StepperExtensionList>; +using Stepper = Acts::EigenStepper; using Propagator = Acts::Propagator; using RiddersPropagator = Acts::RiddersPropagator; diff --git a/Tests/UnitTests/Core/Propagator/AuctioneerTests.cpp b/Tests/UnitTests/Core/Propagator/AuctioneerTests.cpp deleted file mode 100644 index 8d3a96158ea..00000000000 --- a/Tests/UnitTests/Core/Propagator/AuctioneerTests.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// This file is part of the Acts project. -// -// Copyright (C) 2016-2018 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/. - -#include - -#include "Acts/Propagator/detail/Auctioneer.hpp" - -#include - -namespace Acts::Test { - -BOOST_AUTO_TEST_CASE(AuctioneerTest_VoidAuctioneer) { - // Build arbitrary vector - std::array vecArb = {0, 2, -5, 4}; - std::array vecRes = {false, true, false, true}; - // Let it run through auction - detail::VoidAuctioneer va; - std::array resultVa = va(vecArb); - // Test that vector did not change - BOOST_CHECK_EQUAL_COLLECTIONS(vecRes.begin(), vecRes.end(), resultVa.begin(), - resultVa.end()); -} - -BOOST_AUTO_TEST_CASE(AuctioneerTest_FirstValidAuctioneer) { - // Build arbitrary vector - std::array vecArb = {0, 1, -2, 4}; - // Let it run through auction - detail::FirstValidAuctioneer fva; - std::array resultFva = fva(vecArb); - std::array expected = {false, true, false, false}; - // Test that vector did not change - BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), - resultFva.begin(), resultFva.end()); -} - -BOOST_AUTO_TEST_CASE(AuctioneerTest_HighestValidAuctioneer) { - // Build arbitrary vector - std::array vecArb = {0, 1, -2, 4}; - // Let it run through auction - detail::HighestValidAuctioneer fva; - std::array resultFva = fva(vecArb); - std::array expected = {false, false, false, true}; - // Test that vector did not change - BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), - resultFva.begin(), resultFva.end()); -} -} // namespace Acts::Test diff --git a/Tests/UnitTests/Core/Propagator/CMakeLists.txt b/Tests/UnitTests/Core/Propagator/CMakeLists.txt index fa90e29b22a..34f3e88f23f 100644 --- a/Tests/UnitTests/Core/Propagator/CMakeLists.txt +++ b/Tests/UnitTests/Core/Propagator/CMakeLists.txt @@ -1,5 +1,4 @@ add_unittest(AtlasStepper AtlasStepperTests.cpp) -add_unittest(Auctioneer AuctioneerTests.cpp) add_unittest(ConstrainedStep ConstrainedStepTests.cpp) add_unittest(CovarianceEngine CovarianceEngineTests.cpp) add_unittest(DirectNavigator DirectNavigatorTests.cpp) diff --git a/Tests/UnitTests/Core/Propagator/EigenStepperTests.cpp b/Tests/UnitTests/Core/Propagator/EigenStepperTests.cpp index 1fb907d25e8..fc7175aaf85 100644 --- a/Tests/UnitTests/Core/Propagator/EigenStepperTests.cpp +++ b/Tests/UnitTests/Core/Propagator/EigenStepperTests.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2018-2020 CERN for the benefit of the Acts project +// Copyright (C) 2018-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 @@ -12,7 +12,6 @@ #include "Acts/Definitions/Direction.hpp" #include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/Definitions/Units.hpp" -#include "Acts/EventData/Charge.hpp" #include "Acts/EventData/GenericBoundTrackParameters.hpp" #include "Acts/EventData/GenericCurvilinearTrackParameters.hpp" #include "Acts/EventData/ParticleHypothesis.hpp" @@ -34,15 +33,13 @@ #include "Acts/Propagator/AbortList.hpp" #include "Acts/Propagator/ActionList.hpp" #include "Acts/Propagator/ConstrainedStep.hpp" -#include "Acts/Propagator/DefaultExtension.hpp" -#include "Acts/Propagator/DenseEnvironmentExtension.hpp" #include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/EigenStepperDefaultExtension.hpp" +#include "Acts/Propagator/EigenStepperDenseEnvironmentExtension.hpp" #include "Acts/Propagator/EigenStepperError.hpp" #include "Acts/Propagator/MaterialInteractor.hpp" #include "Acts/Propagator/Navigator.hpp" #include "Acts/Propagator/Propagator.hpp" -#include "Acts/Propagator/StepperExtensionList.hpp" -#include "Acts/Propagator/detail/Auctioneer.hpp" #include "Acts/Surfaces/BoundaryTolerance.hpp" #include "Acts/Surfaces/CurvilinearSurface.hpp" #include "Acts/Surfaces/PlaneSurface.hpp" @@ -55,15 +52,11 @@ #include "Acts/Utilities/UnitVectors.hpp" #include -#include #include -#include #include -#include #include #include #include -#include #include #include #include @@ -370,7 +363,6 @@ BOOST_AUTO_TEST_CASE(eigen_stepper_test) { copy.geoContext = state.geoContext; copy.extension = state.extension; - copy.auctioneer = state.auctioneer; copy.stepData = state.stepData; return copy; @@ -544,14 +536,13 @@ BOOST_AUTO_TEST_CASE(eigen_stepper_test) { BOOST_CHECK_EQUAL(res.error(), EigenStepperError::StepSizeAdjustmentFailed); } -/// @brief This function tests the EigenStepper with the DefaultExtension and -/// the DenseEnvironmentExtension. The focus of this tests lies in the -/// choosing of the right extension for the individual use case. This is +/// @brief This function tests the EigenStepper with the EigenStepperDefaultExtension and +/// the EigenStepperDenseEnvironmentExtension. The focus of this tests lies in +/// the choosing of the right extension for the individual use case. This is /// performed with three different detectors: /// a) Pure vacuum -> DefaultExtension needs to act /// b) Pure Be -> DenseEnvironmentExtension needs to act -/// c) Vacuum - Be - Vacuum -> Both should act and switch during the -/// propagation +/// c) Vacuum - Be - Vacuum -> Both should act and switch during the propagation // Test case a). The DenseEnvironmentExtension should state that it is not // valid in this case. @@ -586,9 +577,7 @@ BOOST_AUTO_TEST_CASE(step_extension_vacuum_test) { const CurvilinearTrackParameters sbtp(Vector4::Zero(), startDir, 1_e / 1_GeV, cov, ParticleHypothesis::pion()); - using Stepper = EigenStepper< - StepperExtensionList, - detail::HighestValidAuctioneer>; + using Stepper = EigenStepper; using Propagator = Propagator; using PropagatorOptions = Propagator::Options, AbortList>; @@ -620,9 +609,7 @@ BOOST_AUTO_TEST_CASE(step_extension_vacuum_test) { CHECK_CLOSE_ABS(mom, startMom, 1_keV); } - using DefStepper = EigenStepper< - StepperExtensionList, - detail::HighestValidAuctioneer>; + using DefStepper = EigenStepper; using DefPropagator = Acts::Propagator; using DefPropagatorOptions = DefPropagator::Options, AbortList>; @@ -685,9 +672,7 @@ BOOST_AUTO_TEST_CASE(step_extension_material_test) { const CurvilinearTrackParameters sbtp(Vector4::Zero(), startDir, 1_e / 5_GeV, cov, ParticleHypothesis::pion()); - using Stepper = EigenStepper< - StepperExtensionList, - detail::HighestValidAuctioneer>; + using Stepper = EigenStepper; using Propagator = Propagator; using PropagatorOptions = Propagator::Options, AbortList>; @@ -728,9 +713,7 @@ BOOST_AUTO_TEST_CASE(step_extension_material_test) { } } - using DenseStepper = - EigenStepper, - detail::HighestValidAuctioneer>; + using DenseStepper = EigenStepper; using DensePropagator = Acts::Propagator; using DensePropagatorOptions = DensePropagator::Options, @@ -835,9 +818,7 @@ BOOST_AUTO_TEST_CASE(step_extension_vacmatvac_test) { 1_e / 5_GeV, Covariance::Identity(), ParticleHypothesis::pion()); - using Stepper = EigenStepper< - StepperExtensionList, - detail::HighestValidAuctioneer>; + using Stepper = EigenStepper; using Propagator = Acts::Propagator; using PropagatorOptions = Propagator::Options, AbortList>; @@ -891,7 +872,7 @@ BOOST_AUTO_TEST_CASE(step_extension_vacmatvac_test) { // Build launcher through vacuum // Set options for propagator - using DefStepper = EigenStepper>; + using DefStepper = EigenStepper; using DefPropagator = Acts::Propagator; using DefPropagatorOptions = DefPropagator::Options, AbortList>; @@ -941,8 +922,7 @@ BOOST_AUTO_TEST_CASE(step_extension_vacmatvac_test) { // Set initial parameters for the particle track by using the result of the // first volume - using DenseStepper = EigenStepper< - StepperExtensionList>; + using DenseStepper = EigenStepper; using DensePropagator = Acts::Propagator; using DensePropagatorOptions = DensePropagator::Options, @@ -1072,9 +1052,7 @@ BOOST_AUTO_TEST_CASE(step_extension_trackercalomdt_test) { 1_e / 1_GeV, Covariance::Identity(), ParticleHypothesis::pion()); - using Stepper = EigenStepper< - StepperExtensionList, - detail::HighestValidAuctioneer>; + using Stepper = EigenStepper; using Propagator = Acts::Propagator; using PropagatorOptions = Propagator::Options, diff --git a/Tests/UnitTests/Core/Propagator/MultiStepperTests.cpp b/Tests/UnitTests/Core/Propagator/MultiStepperTests.cpp index 2005e954e21..27625c5ea5c 100644 --- a/Tests/UnitTests/Core/Propagator/MultiStepperTests.cpp +++ b/Tests/UnitTests/Core/Propagator/MultiStepperTests.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2018-2020 CERN for the benefit of the Acts project +// Copyright (C) 2018-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 @@ -20,12 +20,11 @@ #include "Acts/MagneticField/ConstantBField.hpp" #include "Acts/MagneticField/MagneticFieldContext.hpp" #include "Acts/MagneticField/NullBField.hpp" -#include "Acts/Propagator/DefaultExtension.hpp" #include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/EigenStepperDefaultExtension.hpp" #include "Acts/Propagator/MultiEigenStepperLoop.hpp" #include "Acts/Propagator/Navigator.hpp" #include "Acts/Propagator/Propagator.hpp" -#include "Acts/Propagator/StepperExtensionList.hpp" #include "Acts/Surfaces/CurvilinearSurface.hpp" #include "Acts/Surfaces/PlaneSurface.hpp" #include "Acts/Surfaces/Surface.hpp" @@ -64,10 +63,8 @@ using namespace Acts::VectorHelpers; const MagneticFieldContext magCtx; const GeometryContext geoCtx; -using MultiStepperLoop = - MultiEigenStepperLoop, - MaxWeightReducerLoop>; -using SingleStepper = EigenStepper>; +using MultiStepperLoop = MultiEigenStepperLoop; +using SingleStepper = EigenStepper; const double defaultStepSize = 123.; const auto defaultNDir = Direction::Backward; diff --git a/Tests/UnitTests/Core/Propagator/PropagatorTests.cpp b/Tests/UnitTests/Core/Propagator/PropagatorTests.cpp index 01d02be6e3c..d53ae87eb96 100644 --- a/Tests/UnitTests/Core/Propagator/PropagatorTests.cpp +++ b/Tests/UnitTests/Core/Propagator/PropagatorTests.cpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2016-2019 CERN for the benefit of the Acts project +// Copyright (C) 2016-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 @@ -23,12 +23,11 @@ #include "Acts/Propagator/AbortList.hpp" #include "Acts/Propagator/ActionList.hpp" #include "Acts/Propagator/ConstrainedStep.hpp" -#include "Acts/Propagator/DenseEnvironmentExtension.hpp" #include "Acts/Propagator/EigenStepper.hpp" +#include "Acts/Propagator/EigenStepperDenseEnvironmentExtension.hpp" #include "Acts/Propagator/Navigator.hpp" #include "Acts/Propagator/Propagator.hpp" #include "Acts/Propagator/StandardAborters.hpp" -#include "Acts/Propagator/StepperExtensionList.hpp" #include "Acts/Propagator/StraightLineStepper.hpp" #include "Acts/Surfaces/CurvilinearSurface.hpp" #include "Acts/Surfaces/CylinderBounds.hpp" @@ -477,8 +476,7 @@ BOOST_AUTO_TEST_CASE(BasicPropagatorInterface) { BOOST_CHECK(resultCurv.ok()); } - EigenStepper> - denseEigenStepper{field}; + EigenStepper denseEigenStepper{field}; { Propagator propagator{denseEigenStepper, navigator}; diff --git a/Tests/UnitTests/Core/Propagator/SympyStepperTests.cpp b/Tests/UnitTests/Core/Propagator/SympyStepperTests.cpp index 676246bce15..13edeaeaf91 100644 --- a/Tests/UnitTests/Core/Propagator/SympyStepperTests.cpp +++ b/Tests/UnitTests/Core/Propagator/SympyStepperTests.cpp @@ -34,14 +34,10 @@ #include "Acts/Propagator/AbortList.hpp" #include "Acts/Propagator/ActionList.hpp" #include "Acts/Propagator/ConstrainedStep.hpp" -#include "Acts/Propagator/DefaultExtension.hpp" -#include "Acts/Propagator/DenseEnvironmentExtension.hpp" #include "Acts/Propagator/MaterialInteractor.hpp" #include "Acts/Propagator/Navigator.hpp" #include "Acts/Propagator/Propagator.hpp" -#include "Acts/Propagator/StepperExtensionList.hpp" #include "Acts/Propagator/SympyStepper.hpp" -#include "Acts/Propagator/detail/Auctioneer.hpp" #include "Acts/Surfaces/BoundaryTolerance.hpp" #include "Acts/Surfaces/CurvilinearSurface.hpp" #include "Acts/Surfaces/PlaneSurface.hpp" diff --git a/docs/core/propagation.md b/docs/core/propagation.md index 175278a0157..0c9b8259f76 100644 --- a/docs/core/propagation.md +++ b/docs/core/propagation.md @@ -108,22 +108,17 @@ The {class}`Acts::StraightLineStepper` is a very stripped down stepper that just ### EigenStepper -The {class}`Acts::EigenStepper` implements the same functionality as the ATLAS stepper, however, the stepping code is rewritten by using `Eigen` primitives. Thus, it also uses a 4th-order Runge-Kutta algorithm for the integration of the EOM. Additionally, the {class}`Acts::EigenStepper` allows to customize the concrete integration step via **extensions**. +The {class}`Acts::EigenStepper` implements the same functionality as the ATLAS stepper, however, the stepping code is rewritten by using `Eigen` primitives. Thus, it also uses a 4th-order Runge-Kutta algorithm for the integration of the EOM. Additionally, the {class}`Acts::EigenStepper` allows to customize the concrete integration step via **extension**. -The extensions encapsulate the relevant equations for different environments. There exists a {struct}`Acts::DefaultExtension` that is suited for propagation in a vacuum, and the {struct}`Acts::DenseEnvironmentExtension`, that contains additional code to handle the propagation inside materials. Which extension is used is selected by a bidding-system. +The extension encapsulate the relevant equations for different environments. There exists a {struct}`Acts::EigenStepperDefaultExtension` that is suited for propagation in a vacuum, and the {struct}`Acts::EigenStepperDenseEnvironmentExtension`, that contains additional code to handle the propagation inside materials. Which extension is used is decided by the user. -The extension can be configured via the {struct}`Acts::StepperExtensionList`: +The extension can be configured via the {class}`Acts::EigenStepper`: -```cpp -using Stepper = Acts::EigenStepper< - Acts::StepperExtensionList< - Acts::DefaultExtension, - Acts::DenseEnvironmentExtension - > - >; +```c++ +using Stepper = Acts::EigenStepper; ``` -By default, the {class}`Acts::EigenStepper` only uses the {struct}`Acts::DefaultExtension`. +By default, the {class}`Acts::EigenStepper` only uses the {struct}`Acts::EigenStepperDenseEnvironmentExtension`. ### MultiEigenStepperLoop From d80f91ff3752d895563a69ae01ef7daf0179b5f1 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Mon, 9 Sep 2024 23:30:48 +0200 Subject: [PATCH 5/8] fix: Stitch tracks correctly after second pass in Examples Track Finding (#3597) Stich tracks from first measurement not from first state otherwise we can end up with double counting material states. discovered in https://github.com/acts-project/acts/pull/3391 --- .../src/TrackFindingAlgorithm.cpp | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp b/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp index 432e546d4a3..03688c2c943 100644 --- a/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp +++ b/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp @@ -508,13 +508,9 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { // has already been updated seedNumber(trackCandidate) = nSeed - 1; - auto firstState = *std::next(trackCandidate.trackStatesReversed().begin(), - trackCandidate.nTrackStates() - 1); - assert(firstState.previous() == Acts::kTrackIndexInvalid); - if (m_cfg.twoWay) { std::optional - firstMeasurement; + firstMeasurementOpt; for (auto trackState : trackCandidate.trackStatesReversed()) { bool isMeasurement = trackState.typeFlags().test( Acts::TrackStateFlag::MeasurementFlag); @@ -524,13 +520,15 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { // decrease resolution because only the smoothing corrected the very // first prediction as filtering is not possible. if (isMeasurement && !isOutlier) { - firstMeasurement = trackState; + firstMeasurementOpt = trackState; } } - if (firstMeasurement.has_value()) { + if (firstMeasurementOpt.has_value()) { + auto& firstMeasurement = firstMeasurementOpt.value(); + Acts::BoundTrackParameters secondInitialParameters = - trackCandidate.createParametersFromState(*firstMeasurement); + trackCandidate.createParametersFromState(firstMeasurement); auto secondRootBranch = tracksTemp.makeTrack(); secondRootBranch.copyFrom(trackCandidate, false); @@ -542,6 +540,9 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { ACTS_WARNING("Second track finding failed for seed " << iSeed << " with error" << secondResult.error()); } else { + // store the original previous state to restore it later + auto originalFirstMeasurementPrevious = firstMeasurement.previous(); + auto& secondTracksForSeed = secondResult.value(); for (auto& secondTrack : secondTracksForSeed) { // TODO a copy of the track should not be necessary but is the @@ -556,7 +557,7 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { // processed secondTrackCopy.reverseTrackStates(true); - firstState.previous() = + firstMeasurement.previous() = secondTrackCopy.outermostTrackState().index(); trackCandidate.copyFrom(secondTrackCopy, false); @@ -609,6 +610,9 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { ++nSecond; } + + // restore the original previous state + firstMeasurement.previous() = originalFirstMeasurementPrevious; } } } @@ -617,7 +621,6 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { if (nSecond == 0) { // restore the track to the original state trackCandidate.copyFrom(firstTrack, false); - firstState.previous() = Acts::kTrackIndexInvalid; auto firstExtrapolationResult = Acts::extrapolateTrackToReferenceSurface( From eebeb36c4bd97348dfcf53d60239598225f18a03 Mon Sep 17 00:00:00 2001 From: "Alexander J. Pfleger" <70842573+AJPfleger@users.noreply.github.com> Date: Tue, 10 Sep 2024 13:54:14 +0200 Subject: [PATCH 6/8] refactor: replace `Acts::min_max` with `std::ranges::minmax_element` (#3601) --- Core/include/Acts/Utilities/Helpers.hpp | 22 ++++--------------- .../detail/CylindricalDetectorHelper.cpp | 6 ++--- .../UnitTests/Core/Utilities/HelpersTests.cpp | 14 ------------ 3 files changed, 7 insertions(+), 35 deletions(-) diff --git a/Core/include/Acts/Utilities/Helpers.hpp b/Core/include/Acts/Utilities/Helpers.hpp index 5d9d2ab22eb..99d068cf361 100644 --- a/Core/include/Acts/Utilities/Helpers.hpp +++ b/Core/include/Acts/Utilities/Helpers.hpp @@ -164,21 +164,7 @@ T clampValue(U value) { static_cast(std::numeric_limits::max())); } -/// Return min/max from a (optionally) sorted series, obsolete with C++20 -/// (ranges) -/// -/// @tparam T a numeric series -/// -/// @param tseries is the number series -/// -/// @return [ min, max ] in an array of length 2 -template -std::array min_max(const T& tseries) { - return {*std::min_element(tseries.begin(), tseries.end()), - *std::max_element(tseries.begin(), tseries.end())}; -} - -/// Return range and medium of a sorted numeric series +/// Return range and medium of an unsorted numeric series /// /// @tparam T a numeric series /// @@ -187,9 +173,9 @@ std::array min_max(const T& tseries) { /// @return [ range, medium ] in an tuple template std::tuple range_medium(const T& tseries) { - auto [min, max] = min_max(tseries); - typename T::value_type range = (max - min); - ActsScalar medium = static_cast((max + min) * 0.5); + auto [minIt, maxIt] = std::ranges::minmax_element(tseries); + typename T::value_type range = (*maxIt - *minIt); + ActsScalar medium = static_cast((*maxIt + *minIt) * 0.5); return std::tie(range, medium); } diff --git a/Core/src/Detector/detail/CylindricalDetectorHelper.cpp b/Core/src/Detector/detail/CylindricalDetectorHelper.cpp index 1a15d527765..7fce725b4f6 100644 --- a/Core/src/Detector/detail/CylindricalDetectorHelper.cpp +++ b/Core/src/Detector/detail/CylindricalDetectorHelper.cpp @@ -88,12 +88,12 @@ Acts::Experimental::PortalReplacement createDiscReplacement( ? Acts::BinningValue::binR : Acts::BinningValue::binPhi; // Estimate ranges - auto [minR, maxR] = Acts::min_max(rBoundaries); + auto [minRit, maxRit] = std::ranges::minmax_element(rBoundaries); auto [sectorPhi, avgPhi] = Acts::range_medium(phiBoundaries); // Transform and bounds - auto bounds = - std::make_unique(minR, maxR, 0.5 * sectorPhi, avgPhi); + auto bounds = std::make_unique(*minRit, *maxRit, + 0.5 * sectorPhi, avgPhi); // A new surface on the negative side over the full range auto surface = Acts::Surface::makeShared( transform, std::move(bounds)); diff --git a/Tests/UnitTests/Core/Utilities/HelpersTests.cpp b/Tests/UnitTests/Core/Utilities/HelpersTests.cpp index 28390a9089c..a92defd466c 100644 --- a/Tests/UnitTests/Core/Utilities/HelpersTests.cpp +++ b/Tests/UnitTests/Core/Utilities/HelpersTests.cpp @@ -193,20 +193,6 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(BlockedMatrixMultiplication, Matrices, } } -BOOST_AUTO_TEST_CASE(min_max) { - std::vector ordered = {-3., -2., -1., 0., 1., 2., 3.}; - auto [min0, max0] = Acts::min_max(ordered); - - CHECK_CLOSE_ABS(min0, -3., std::numeric_limits::epsilon()); - CHECK_CLOSE_ABS(max0, 3., std::numeric_limits::epsilon()); - - std::vector unordered = {3., -3., -2., -1., 0., 1., 2.}; - auto [min1, max1] = Acts::min_max(unordered); - - CHECK_CLOSE_ABS(min1, -3., std::numeric_limits::epsilon()); - CHECK_CLOSE_ABS(max1, 3., std::numeric_limits::epsilon()); -} - BOOST_AUTO_TEST_CASE(range_medium) { std::vector ordered = {-3., -2., -1., 0., 1., 2., 3.}; auto [range0, medium0] = Acts::range_medium(ordered); From c836ca50bbcad3365e60a211d88158d7bc7e962a Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Tue, 10 Sep 2024 17:46:20 +0200 Subject: [PATCH 7/8] refactor!: Rename `EigenStepper` dense extension (#3603) During Athena integration I realized that the naming is a bit inconsistent with `EigenStepperDefaultExtension` and `EigenStepperDenseEnvironmentExtension`. I think `EigenStepperDenseExtension` fits better. --- ...ion.hpp => EigenStepperDenseExtension.hpp} | 2 +- .../PropagationDenseConstant.cpp | 4 ++-- .../Core/Propagator/EigenStepperTests.cpp | 20 +++++++++---------- .../Core/Propagator/PropagatorTests.cpp | 4 ++-- docs/core/propagation.md | 6 +++--- 5 files changed, 18 insertions(+), 18 deletions(-) rename Core/include/Acts/Propagator/{EigenStepperDenseEnvironmentExtension.hpp => EigenStepperDenseExtension.hpp} (99%) diff --git a/Core/include/Acts/Propagator/EigenStepperDenseEnvironmentExtension.hpp b/Core/include/Acts/Propagator/EigenStepperDenseExtension.hpp similarity index 99% rename from Core/include/Acts/Propagator/EigenStepperDenseEnvironmentExtension.hpp rename to Core/include/Acts/Propagator/EigenStepperDenseExtension.hpp index befab8f96ce..155bc1637bc 100644 --- a/Core/include/Acts/Propagator/EigenStepperDenseEnvironmentExtension.hpp +++ b/Core/include/Acts/Propagator/EigenStepperDenseExtension.hpp @@ -25,7 +25,7 @@ namespace Acts { /// ioninisation, bremsstrahlung, pair production and photonuclear interaction /// in the propagation and the jacobian. These effects will only occur if the /// propagation is in a TrackingVolume with attached material. -struct EigenStepperDenseEnvironmentExtension { +struct EigenStepperDenseExtension { using Scalar = ActsScalar; /// @brief Vector3 replacement for the custom scalar type using ThisVector3 = Eigen::Matrix; diff --git a/Tests/IntegrationTests/PropagationDenseConstant.cpp b/Tests/IntegrationTests/PropagationDenseConstant.cpp index c27e38088b4..e95b0bc01a1 100644 --- a/Tests/IntegrationTests/PropagationDenseConstant.cpp +++ b/Tests/IntegrationTests/PropagationDenseConstant.cpp @@ -16,7 +16,7 @@ #include "Acts/MagneticField/MagneticFieldContext.hpp" #include "Acts/Material/HomogeneousVolumeMaterial.hpp" #include "Acts/Propagator/EigenStepper.hpp" -#include "Acts/Propagator/EigenStepperDenseEnvironmentExtension.hpp" +#include "Acts/Propagator/EigenStepperDenseExtension.hpp" #include "Acts/Propagator/Navigator.hpp" #include "Acts/Propagator/Propagator.hpp" #include "Acts/Propagator/RiddersPropagator.hpp" @@ -34,7 +34,7 @@ namespace ds = ActsTests::PropagationDatasets; using namespace Acts::UnitLiterals; using MagneticField = Acts::ConstantBField; -using Stepper = Acts::EigenStepper; +using Stepper = Acts::EigenStepper; using Propagator = Acts::Propagator; using RiddersPropagator = Acts::RiddersPropagator; diff --git a/Tests/UnitTests/Core/Propagator/EigenStepperTests.cpp b/Tests/UnitTests/Core/Propagator/EigenStepperTests.cpp index fc7175aaf85..bea4039ad3d 100644 --- a/Tests/UnitTests/Core/Propagator/EigenStepperTests.cpp +++ b/Tests/UnitTests/Core/Propagator/EigenStepperTests.cpp @@ -35,7 +35,7 @@ #include "Acts/Propagator/ConstrainedStep.hpp" #include "Acts/Propagator/EigenStepper.hpp" #include "Acts/Propagator/EigenStepperDefaultExtension.hpp" -#include "Acts/Propagator/EigenStepperDenseEnvironmentExtension.hpp" +#include "Acts/Propagator/EigenStepperDenseExtension.hpp" #include "Acts/Propagator/EigenStepperError.hpp" #include "Acts/Propagator/MaterialInteractor.hpp" #include "Acts/Propagator/Navigator.hpp" @@ -537,7 +537,7 @@ BOOST_AUTO_TEST_CASE(eigen_stepper_test) { } /// @brief This function tests the EigenStepper with the EigenStepperDefaultExtension and -/// the EigenStepperDenseEnvironmentExtension. The focus of this tests lies in +/// the EigenStepperDenseExtension. The focus of this tests lies in /// the choosing of the right extension for the individual use case. This is /// performed with three different detectors: /// a) Pure vacuum -> DefaultExtension needs to act @@ -577,7 +577,7 @@ BOOST_AUTO_TEST_CASE(step_extension_vacuum_test) { const CurvilinearTrackParameters sbtp(Vector4::Zero(), startDir, 1_e / 1_GeV, cov, ParticleHypothesis::pion()); - using Stepper = EigenStepper; + using Stepper = EigenStepper; using Propagator = Propagator; using PropagatorOptions = Propagator::Options, AbortList>; @@ -609,7 +609,7 @@ BOOST_AUTO_TEST_CASE(step_extension_vacuum_test) { CHECK_CLOSE_ABS(mom, startMom, 1_keV); } - using DefStepper = EigenStepper; + using DefStepper = EigenStepper; using DefPropagator = Acts::Propagator; using DefPropagatorOptions = DefPropagator::Options, AbortList>; @@ -672,7 +672,7 @@ BOOST_AUTO_TEST_CASE(step_extension_material_test) { const CurvilinearTrackParameters sbtp(Vector4::Zero(), startDir, 1_e / 5_GeV, cov, ParticleHypothesis::pion()); - using Stepper = EigenStepper; + using Stepper = EigenStepper; using Propagator = Propagator; using PropagatorOptions = Propagator::Options, AbortList>; @@ -713,7 +713,7 @@ BOOST_AUTO_TEST_CASE(step_extension_material_test) { } } - using DenseStepper = EigenStepper; + using DenseStepper = EigenStepper; using DensePropagator = Acts::Propagator; using DensePropagatorOptions = DensePropagator::Options, @@ -818,7 +818,7 @@ BOOST_AUTO_TEST_CASE(step_extension_vacmatvac_test) { 1_e / 5_GeV, Covariance::Identity(), ParticleHypothesis::pion()); - using Stepper = EigenStepper; + using Stepper = EigenStepper; using Propagator = Acts::Propagator; using PropagatorOptions = Propagator::Options, AbortList>; @@ -872,7 +872,7 @@ BOOST_AUTO_TEST_CASE(step_extension_vacmatvac_test) { // Build launcher through vacuum // Set options for propagator - using DefStepper = EigenStepper; + using DefStepper = EigenStepper; using DefPropagator = Acts::Propagator; using DefPropagatorOptions = DefPropagator::Options, AbortList>; @@ -922,7 +922,7 @@ BOOST_AUTO_TEST_CASE(step_extension_vacmatvac_test) { // Set initial parameters for the particle track by using the result of the // first volume - using DenseStepper = EigenStepper; + using DenseStepper = EigenStepper; using DensePropagator = Acts::Propagator; using DensePropagatorOptions = DensePropagator::Options, @@ -1052,7 +1052,7 @@ BOOST_AUTO_TEST_CASE(step_extension_trackercalomdt_test) { 1_e / 1_GeV, Covariance::Identity(), ParticleHypothesis::pion()); - using Stepper = EigenStepper; + using Stepper = EigenStepper; using Propagator = Acts::Propagator; using PropagatorOptions = Propagator::Options, diff --git a/Tests/UnitTests/Core/Propagator/PropagatorTests.cpp b/Tests/UnitTests/Core/Propagator/PropagatorTests.cpp index d53ae87eb96..4dbdc303771 100644 --- a/Tests/UnitTests/Core/Propagator/PropagatorTests.cpp +++ b/Tests/UnitTests/Core/Propagator/PropagatorTests.cpp @@ -24,7 +24,7 @@ #include "Acts/Propagator/ActionList.hpp" #include "Acts/Propagator/ConstrainedStep.hpp" #include "Acts/Propagator/EigenStepper.hpp" -#include "Acts/Propagator/EigenStepperDenseEnvironmentExtension.hpp" +#include "Acts/Propagator/EigenStepperDenseExtension.hpp" #include "Acts/Propagator/Navigator.hpp" #include "Acts/Propagator/Propagator.hpp" #include "Acts/Propagator/StandardAborters.hpp" @@ -476,7 +476,7 @@ BOOST_AUTO_TEST_CASE(BasicPropagatorInterface) { BOOST_CHECK(resultCurv.ok()); } - EigenStepper denseEigenStepper{field}; + EigenStepper denseEigenStepper{field}; { Propagator propagator{denseEigenStepper, navigator}; diff --git a/docs/core/propagation.md b/docs/core/propagation.md index 0c9b8259f76..dbd7b37a1b9 100644 --- a/docs/core/propagation.md +++ b/docs/core/propagation.md @@ -110,15 +110,15 @@ The {class}`Acts::StraightLineStepper` is a very stripped down stepper that just The {class}`Acts::EigenStepper` implements the same functionality as the ATLAS stepper, however, the stepping code is rewritten by using `Eigen` primitives. Thus, it also uses a 4th-order Runge-Kutta algorithm for the integration of the EOM. Additionally, the {class}`Acts::EigenStepper` allows to customize the concrete integration step via **extension**. -The extension encapsulate the relevant equations for different environments. There exists a {struct}`Acts::EigenStepperDefaultExtension` that is suited for propagation in a vacuum, and the {struct}`Acts::EigenStepperDenseEnvironmentExtension`, that contains additional code to handle the propagation inside materials. Which extension is used is decided by the user. +The extension encapsulate the relevant equations for different environments. There exists a {struct}`Acts::EigenStepperDefaultExtension` that is suited for propagation in a vacuum, and the {struct}`Acts::EigenStepperDenseExtension`, that contains additional code to handle the propagation inside materials. Which extension is used is decided by the user. The extension can be configured via the {class}`Acts::EigenStepper`: ```c++ -using Stepper = Acts::EigenStepper; +using Stepper = Acts::EigenStepper; ``` -By default, the {class}`Acts::EigenStepper` only uses the {struct}`Acts::EigenStepperDenseEnvironmentExtension`. +By default, the {class}`Acts::EigenStepper` only uses the {struct}`Acts::EigenStepperDenseExtension`. ### MultiEigenStepperLoop From 415b4e0e512fcbb9beb30fb983e42561d5eeeb91 Mon Sep 17 00:00:00 2001 From: "Alexander J. Pfleger" <70842573+AJPfleger@users.noreply.github.com> Date: Tue, 10 Sep 2024 20:13:30 +0200 Subject: [PATCH 8/8] refactor: update `to_array` (#3600) "This can be abandoned with C++20 to use the `std::to_array` method" I think this is not true, since `std::array` doesn't work with dynamically sized vectors. --- Core/include/Acts/Utilities/Helpers.hpp | 31 ++++++++++--------- Core/src/Detector/VolumeStructureBuilder.cpp | 12 +++---- .../GenericCuboidVolumeBoundsTests.cpp | 2 +- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/Core/include/Acts/Utilities/Helpers.hpp b/Core/include/Acts/Utilities/Helpers.hpp index 99d068cf361..53ca997e29d 100644 --- a/Core/include/Acts/Utilities/Helpers.hpp +++ b/Core/include/Acts/Utilities/Helpers.hpp @@ -11,6 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include +#include #include #include #include @@ -71,22 +72,24 @@ std::vector unpack_shared_const_vector( return rawPtrs; } -/// This can be abandoned with C++20 to use the std::to_array method +/// @brief Converts a vector to a fixed-size array with truncating or padding. /// -/// @note only the first kDIM elements will obviously be filled, if the -/// vector tends to be longer, it is truncated +/// This function copies elements from the input vector into a fixed-size array. +/// If the vector contains more than `kDIM` elements, the array is truncated to +/// fit. If the vector contains fewer elements than `kDIM`, the remaining array +/// elements are value-initialized (default-initialized, i.e., filled with zero +/// or default values). /// -/// @param vecvals the vector of bound values to be converted -/// @return an array with the filled values -template -std::array to_array(const std::vector& vecvals) { - std::array rarray = {}; - for (const auto [iv, v] : enumerate(vecvals)) { - if (iv < kDIM) { - rarray[iv] = v; - } - } - return rarray; +/// @tparam kDIM The size of the resulting array. +/// @tparam value_t The type of elements in the vector and the array. +/// @param vecvals The input vector to be converted to an array. +/// +/// @return An array containing the first `kDIM` elements of the vector. +template +std::array toArray(const std::vector& vecvals) { + std::array arr = {}; + std::copy_n(vecvals.begin(), std::min(vecvals.size(), kDIM), arr.begin()); + return arr; } /// @brief Dispatch a call based on a runtime value on a function taking the diff --git a/Core/src/Detector/VolumeStructureBuilder.cpp b/Core/src/Detector/VolumeStructureBuilder.cpp index 49dba260a52..afa10e45cd7 100644 --- a/Core/src/Detector/VolumeStructureBuilder.cpp +++ b/Core/src/Detector/VolumeStructureBuilder.cpp @@ -62,7 +62,7 @@ Acts::Experimental::VolumeStructureBuilder::construct( "object. It needs at least 5 parameters, while " + std::to_string(boundValues.size()) + " where given"); } - auto bArray = to_array( + auto bArray = toArray( boundValues); volumeBounds = std::make_unique(bArray); } break; @@ -94,7 +94,7 @@ Acts::Experimental::VolumeStructureBuilder::construct( std::to_string(boundValues.size()) + " where given"); } auto bArray = - to_array(boundValues); + toArray(boundValues); volumeBounds = std::make_unique(bArray); } break; case VolumeBounds::BoundsType::eCutoutCylinder: { @@ -108,7 +108,7 @@ Acts::Experimental::VolumeStructureBuilder::construct( std::to_string(boundValues.size()) + " where given"); } auto bArray = - to_array(boundValues); + toArray(boundValues); volumeBounds = std::make_unique(bArray); } break; case VolumeBounds::BoundsType::eCylinder: { @@ -150,7 +150,7 @@ Acts::Experimental::VolumeStructureBuilder::construct( << boundValues[2] << ", " << boundValues[3] << ", " << boundValues[4]); auto bArray = - to_array(boundValues); + toArray(boundValues); volumeBounds = std::make_unique(bArray); } break; case VolumeBounds::BoundsType::eGenericCuboid: { @@ -164,7 +164,7 @@ Acts::Experimental::VolumeStructureBuilder::construct( std::to_string(boundValues.size()) + " where given"); } auto bArray = - to_array(boundValues); + toArray(boundValues); volumeBounds = std::make_unique(bArray); } break; case VolumeBounds::BoundsType::eTrapezoid: { @@ -178,7 +178,7 @@ Acts::Experimental::VolumeStructureBuilder::construct( std::to_string(boundValues.size()) + " where given"); } auto bArray = - to_array(boundValues); + toArray(boundValues); volumeBounds = std::make_unique(bArray); } break; default: diff --git a/Tests/UnitTests/Core/Geometry/GenericCuboidVolumeBoundsTests.cpp b/Tests/UnitTests/Core/Geometry/GenericCuboidVolumeBoundsTests.cpp index 2fc5a25ca85..b62758ec815 100644 --- a/Tests/UnitTests/Core/Geometry/GenericCuboidVolumeBoundsTests.cpp +++ b/Tests/UnitTests/Core/Geometry/GenericCuboidVolumeBoundsTests.cpp @@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE(bounding_box_creation) { BOOST_CHECK_EQUAL(boundValues.size(), 24u); auto bValueArrray = - to_array( + toArray( boundValues); GenericCuboidVolumeBounds gcvbCopy(bValueArrray); BOOST_CHECK_EQUAL(gcvbCopy.values().size(), 24u);