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/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/EigenStepperDenseExtension.hpp similarity index 89% rename from Core/include/Acts/Propagator/DenseEnvironmentExtension.hpp rename to Core/include/Acts/Propagator/EigenStepperDenseExtension.hpp index eed51e1e847..155bc1637bc 100644 --- a/Core/include/Acts/Propagator/DenseEnvironmentExtension.hpp +++ b/Core/include/Acts/Propagator/EigenStepperDenseExtension.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 EigenStepperDenseExtension { 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/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/Helpers.hpp b/Core/include/Acts/Utilities/Helpers.hpp index 5488f86debf..34248fd9047 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 @@ -164,21 +167,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 +176,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/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/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/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/Core/src/Detector/detail/CylindricalDetectorHelper.cpp b/Core/src/Detector/detail/CylindricalDetectorHelper.cpp index cdfe50991cc..2ed29f0b35a 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/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/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/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( 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/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)); } 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 93cc2ae9482..89e2493c764 100644 --- a/Examples/Python/src/Geometry.cpp +++ b/Examples/Python/src/Geometry.cpp @@ -188,11 +188,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>()); } { diff --git a/Tests/IntegrationTests/PropagationDenseConstant.cpp b/Tests/IntegrationTests/PropagationDenseConstant.cpp index 381e7639111..e95b0bc01a1 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/EigenStepperDenseExtension.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/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); 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..bea4039ad3d 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/EigenStepperDenseExtension.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 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 /// 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..4dbdc303771 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/EigenStepperDenseExtension.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/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); 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); diff --git a/docs/core/propagation.md b/docs/core/propagation.md index 175278a0157..dbd7b37a1b9 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::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 {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::EigenStepperDenseExtension`. ### MultiEigenStepperLoop