diff --git a/CI/physmon/workflows/physmon_simulation.py b/CI/physmon/workflows/physmon_simulation.py index c88d4a081e8..746c68c39aa 100755 --- a/CI/physmon/workflows/physmon_simulation.py +++ b/CI/physmon/workflows/physmon_simulation.py @@ -87,7 +87,7 @@ rnd, preSelectParticles=None, postSelectParticles=ParticleSelectorConfig(removeSecondaries=True), - killVolume=setup.trackingGeometry.worldVolume, + killVolume=setup.trackingGeometry.highestTrackingVolume, killAfterTime=25 * u.ns, killSecondaries=True, inputParticles="particles_input", diff --git a/CMakeLists.txt b/CMakeLists.txt index f13ea348110..75bb59c4336 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -168,6 +168,10 @@ set_option_if( ACTS_BUILD_PLUGIN_JSON ACTS_BUILD_PLUGIN_TRACCC ) +set_option_if( + ACTS_BUILD_PLUGIN_ACTSVG + ACTS_BUILD_PLUGIN_TRACCC +) set_option_if( ACTS_BUILD_PLUGIN_HASHING ACTS_BUILD_EXAMPLES_HASHING @@ -221,8 +225,7 @@ endif() # minimal dependency versions. they are defined here in a single place so # they can be easily upgraded, although they might not be used if the # dependency is included via `add_subdirectory(...)`. -set(_acts_actsvg_version 0.4.40) -set(_acts_autodiff_version 0.6) +set(_acts_actsvg_version 0.4.47) set(_acts_boost_version 1.71.0) set(_acts_dd4hep_version 1.21) set(_acts_edm4hep_version 0.7) @@ -232,13 +235,14 @@ set(_acts_podio_version 1.0.1) # will try this first set(_acts_podio_fallback_version 0.16) # if not found, will try this one set(_acts_doxygen_version 1.9.4) set(_acts_hepmc3_version 3.2.1) -set(_acts_nlohmanjson_version 3.2.0) +set(_acts_nlohmanjson_version 3.10.5) set(_acts_onnxruntime_version 1.12.0) set(_acts_root_version 6.20) set(_acts_tbb_version 2020.1) set(_acts_pythia8_version 8.309) -set(_acts_detray_version 0.72.0) -set(_acts_traccc_version 0.13.0) +set(_acts_pybind11_version 2.13.1) +set(_acts_detray_version 0.75.2) +set(_acts_traccc_version 0.16.0) set(_acts_covfie_version 0.10.0) set(_acts_vecmem_version 1.4.0) set(_acts_algebraplugins_version 0.22.0) diff --git a/CMakePresets.json b/CMakePresets.json index 35b461e3c93..bee5ab514df 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -96,7 +96,6 @@ "displayName": "GitLab-CI", "inherits": "ci-common", "cacheVariables": { - "ACTS_BUILD_PLUGIN_ACTSVG": "OFF", "ACTS_BUILD_ODD": "OFF", "ACTS_BUILD_EXAMPLES_PYTHON_BINDINGS": "OFF", "ACTS_RUN_CLANG_TIDY": "ON" diff --git a/Core/include/Acts/AmbiguityResolution/ScoreBasedAmbiguityResolution.ipp b/Core/include/Acts/AmbiguityResolution/ScoreBasedAmbiguityResolution.ipp index 8041188b5cf..3dcf1a20a01 100644 --- a/Core/include/Acts/AmbiguityResolution/ScoreBasedAmbiguityResolution.ipp +++ b/Core/include/Acts/AmbiguityResolution/ScoreBasedAmbiguityResolution.ipp @@ -46,7 +46,7 @@ ScoreBasedAmbiguityResolution::computeInitialState( for (const auto& ts : track.trackStatesReversed()) { if (!ts.hasReferenceSurface()) { - ACTS_ERROR("Track state has no reference surface"); + ACTS_DEBUG("Track state has no reference surface"); continue; } auto iVolume = ts.referenceSurface().geometryId().volume(); diff --git a/Core/include/Acts/Clusterization/Clusterization.ipp b/Core/include/Acts/Clusterization/Clusterization.ipp index 44f8abd1267..16047295912 100644 --- a/Core/include/Acts/Clusterization/Clusterization.ipp +++ b/Core/include/Acts/Clusterization/Clusterization.ipp @@ -1,11 +1,12 @@ // 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 // file, You can obtain one at http://mozilla.org/MPL/2.0/. +#include #include #include @@ -273,7 +274,7 @@ void labelClusters(CellCollection& cells, Connect connect) { internal::DisjointSets ds{}; // Sort cells by position to enable in-order scan - std::sort(cells.begin(), cells.end(), internal::Compare()); + std::ranges::sort(cells, internal::Compare()); // First pass: Allocate labels and record equivalences for (auto it = cells.begin(); it != cells.end(); ++it) { @@ -308,9 +309,7 @@ ClusterCollection mergeClusters(CellCollection& cells) { if constexpr (GridDim > 1) { // Sort the cells by their cluster label, only needed if more than // one spatial dimension - std::sort(cells.begin(), cells.end(), [](Cell& lhs, Cell& rhs) { - return getCellLabel(lhs) < getCellLabel(rhs); - }); + std::ranges::sort(cells, {}, [](Cell& c) { return getCellLabel(c); }); } return internal::mergeClustersImpl(cells); diff --git a/Core/include/Acts/Detector/detail/IndexedGridFiller.hpp b/Core/include/Acts/Detector/detail/IndexedGridFiller.hpp index b79cafa93ad..c8f7d416f31 100644 --- a/Core/include/Acts/Detector/detail/IndexedGridFiller.hpp +++ b/Core/include/Acts/Detector/detail/IndexedGridFiller.hpp @@ -17,6 +17,7 @@ #include "Acts/Utilities/Delegate.hpp" #include "Acts/Utilities/Enumerate.hpp" #include "Acts/Utilities/GridAccessHelpers.hpp" +#include "Acts/Utilities/Helpers.hpp" #include "Acts/Utilities/IAxis.hpp" #include "Acts/Utilities/Logger.hpp" @@ -193,7 +194,7 @@ struct IndexedGridFiller { // Loop over the surfaces to be filled for (auto [io, o] : enumerate(iObjects)) { // Exclude indices that should be handled differently - if (std::find(aToAll.begin(), aToAll.end(), io) != aToAll.end()) { + if (rangeContainsValue(aToAll, io)) { continue; } // Get the reference positions @@ -216,7 +217,7 @@ struct IndexedGridFiller { // Now fill the surface indices for (const auto& li : lIndices) { auto& bContent = iGrid.grid.atLocalBins(li); - if (std::find(bContent.begin(), bContent.end(), io) == bContent.end()) { + if (!rangeContainsValue(bContent, io)) { bContent.push_back(io); } } @@ -238,7 +239,7 @@ struct IndexedGridFiller { for (std::size_t gi = 0; gi < iGrid.grid.size(true); ++gi) { auto& bContent = iGrid.grid.at(gi); for (const auto& io : idcs) { - if (std::find(bContent.begin(), bContent.end(), io) == bContent.end()) { + if (!rangeContainsValue(bContent, io)) { bContent.push_back(io); } } diff --git a/Core/include/Acts/EventData/MultiTrajectory.hpp b/Core/include/Acts/EventData/MultiTrajectory.hpp index 4b1add782b1..0499f66bc6a 100644 --- a/Core/include/Acts/EventData/MultiTrajectory.hpp +++ b/Core/include/Acts/EventData/MultiTrajectory.hpp @@ -87,6 +87,12 @@ class TrackStateRange { } } + Iterator operator++(int) { + Iterator tmp(*this); + operator++(); + return tmp; + } + bool operator==(const Iterator& other) const { if (!proxy && !other.proxy) { return true; @@ -109,6 +115,9 @@ class TrackStateRange { Iterator begin() { return m_begin; } Iterator end() { return Iterator{std::nullopt}; } + Iterator cbegin() const { return m_begin; } + Iterator cend() const { return Iterator{std::nullopt}; } + private: Iterator m_begin; }; @@ -689,13 +698,10 @@ class MultiTrajectory { self().allocateCalibrated_impl(istate, measdim); } - // This function will move to an rvalue reference in the next major version - template - void setUncalibratedSourceLink(IndexType istate, source_link_t&& sourceLink) + void setUncalibratedSourceLink(IndexType istate, SourceLink&& sourceLink) requires(!ReadOnly) { - self().setUncalibratedSourceLink_impl( - istate, std::forward(sourceLink)); + self().setUncalibratedSourceLink_impl(istate, std::move(sourceLink)); } SourceLink getUncalibratedSourceLink(IndexType istate) const { diff --git a/Core/include/Acts/EventData/MultiTrajectoryHelpers.hpp b/Core/include/Acts/EventData/MultiTrajectoryHelpers.hpp index 84d4c763a7b..2a5fac9b2d6 100644 --- a/Core/include/Acts/EventData/MultiTrajectoryHelpers.hpp +++ b/Core/include/Acts/EventData/MultiTrajectoryHelpers.hpp @@ -14,6 +14,7 @@ #include "Acts/Geometry/Layer.hpp" #include "Acts/Geometry/TrackingVolume.hpp" #include "Acts/Surfaces/Surface.hpp" +#include "Acts/Utilities/Helpers.hpp" #include #include @@ -102,8 +103,7 @@ VolumeTrajectoryStateContainer trajectoryState( const auto& volume = geoID.volume(); const auto& layer = geoID.layer(); // Check if the track info for this sub-detector is requested - auto it = std::find(volumeIds.begin(), volumeIds.end(), volume); - if (it == volumeIds.end()) { + if (!rangeContainsValue(volumeIds, volume)) { return true; } // The trajectory state for this volume diff --git a/Core/include/Acts/EventData/TrackStateProxy.hpp b/Core/include/Acts/EventData/TrackStateProxy.hpp index 8e62d07f2eb..7b90e0a1ac9 100644 --- a/Core/include/Acts/EventData/TrackStateProxy.hpp +++ b/Core/include/Acts/EventData/TrackStateProxy.hpp @@ -767,25 +767,12 @@ class TrackStateProxy { /// @return The uncalibrated measurement source link SourceLink getUncalibratedSourceLink() const; - // This function will move to an rvalue reference in the next major version /// Set an uncalibrated source link /// @param sourceLink The uncalibrated source link to set - template - void setUncalibratedSourceLink(source_link_t&& sourceLink) + void setUncalibratedSourceLink(SourceLink&& sourceLink) requires(!ReadOnly) { - m_traj->setUncalibratedSourceLink(m_istate, - std::forward(sourceLink)); - } - - /// Set an uncalibrated source link - /// @param sourceLink The uncalibrated source link to set - /// @note Use the overload with an rvalue reference, this - /// overload will be removed ith the next major version - void setUncalibratedSourceLink(const SourceLink& sourceLink) - requires(!ReadOnly) - { - m_traj->setUncalibratedSourceLink(m_istate, SourceLink{sourceLink}); + m_traj->setUncalibratedSourceLink(m_istate, std::move(sourceLink)); } /// Check if the point has an associated uncalibrated measurement. diff --git a/Core/include/Acts/Geometry/GeometryHierarchyMap.hpp b/Core/include/Acts/Geometry/GeometryHierarchyMap.hpp index 1106761d372..b2b10b9e52f 100644 --- a/Core/include/Acts/Geometry/GeometryHierarchyMap.hpp +++ b/Core/include/Acts/Geometry/GeometryHierarchyMap.hpp @@ -64,13 +64,13 @@ class GeometryHierarchyMap { /// Combined geometry identifier and value element. Only used for input. using InputElement = typename std::pair; using Iterator = typename std::vector::const_iterator; - using Size = typename std::vector::size_type; using Value = value_t; /// Construct the container from the given elements. /// /// @param elements input elements (must be unique with respect to identifier) GeometryHierarchyMap(std::vector elements); + /// Construct the container from an initializer list. /// /// @param elements input initializer list @@ -86,21 +86,25 @@ class GeometryHierarchyMap { /// Return an iterator pointing to the beginning of the stored values. Iterator begin() const { return m_values.begin(); } + /// Return an iterator pointing to the end of the stored values. Iterator end() const { return m_values.end(); } + /// Check if any elements are stored. bool empty() const { return m_values.empty(); } + /// Return the number of stored elements. - Size size() const { return m_values.size(); } + std::size_t size() const { return m_values.size(); } /// Access the geometry identifier for the i-th element with bounds check. /// /// @throws std::out_of_range for invalid indices - GeometryIdentifier idAt(Size index) const { return m_ids.at(index); } + GeometryIdentifier idAt(std::size_t index) const { return m_ids.at(index); } + /// Access the value of the i-th element in the container with bounds check. /// /// @throws std::out_of_range for invalid indices - const Value& valueAt(Size index) const { return m_values.at(index); } + const Value& valueAt(std::size_t index) const { return m_values.at(index); } /// Find the most specific value for a given geometry identifier. /// @@ -111,7 +115,7 @@ class GeometryHierarchyMap { /// @param id geometry identifier for which information is requested /// @retval iterator to an existing value /// @retval `.end()` iterator if no matching element exists - Iterator find(GeometryIdentifier id) const; + Iterator find(const GeometryIdentifier& id) const; private: // NOTE this class assumes that it knows the ordering of the levels within @@ -171,25 +175,26 @@ class GeometryHierarchyMap { // no valid levels; all bits are zero. return Identifier{0u}; } + /// Construct a mask where only the highest level is set. static constexpr Identifier makeHighestLevelMask() { return makeLeadingLevelsMask(GeometryIdentifier(0u).setVolume(1u)); } + /// Compare the two identifiers only within the masked bits. static constexpr bool equalWithinMask(Identifier lhs, Identifier rhs, Identifier mask) { return (lhs & mask) == (rhs & mask); } + /// Ensure identifier ordering and uniqueness. - template - static void sortAndCheckDuplicates(iterator_t beg, iterator_t end); + static void sortAndCheckDuplicates(std::vector& elements); /// Fill the container from the input elements. /// /// This assumes that the elements are ordered and unique with respect to /// their identifiers. - template - void fill(iterator_t beg, iterator_t end); + void fill(const std::vector& elements); }; // implementations @@ -197,8 +202,8 @@ class GeometryHierarchyMap { template inline GeometryHierarchyMap::GeometryHierarchyMap( std::vector elements) { - sortAndCheckDuplicates(elements.begin(), elements.end()); - fill(elements.begin(), elements.end()); + sortAndCheckDuplicates(elements); + fill(elements); } template @@ -208,43 +213,44 @@ inline GeometryHierarchyMap::GeometryHierarchyMap( std::vector(elements.begin(), elements.end())) {} template -template inline void GeometryHierarchyMap::sortAndCheckDuplicates( - iterator_t beg, iterator_t end) { + std::vector& elements) { // ensure elements are sorted by identifier - std::sort(beg, end, [=](const auto& lhs, const auto& rhs) { + std::ranges::sort(elements, [=](const auto& lhs, const auto& rhs) { return lhs.first < rhs.first; }); - // check that all elements have unique identifier - auto dup = std::adjacent_find(beg, end, [](const auto& lhs, const auto& rhs) { - return lhs.first == rhs.first; - }); - if (dup != end) { + + // Check that all elements have unique identifier + auto dup = std::ranges::adjacent_find( + elements, + [](const auto& lhs, const auto& rhs) { return lhs.first == rhs.first; }); + + if (dup != elements.end()) { throw std::invalid_argument("Input elements contain duplicates"); } } template -template -inline void GeometryHierarchyMap::fill(iterator_t beg, - iterator_t end) { - const auto n = std::distance(beg, end); +inline void GeometryHierarchyMap::fill( + const std::vector& elements) { m_ids.clear(); - m_ids.reserve(n); m_masks.clear(); - m_masks.reserve(n); m_values.clear(); - m_values.reserve(n); - for (; beg != end; ++beg) { - m_ids.push_back(beg->first.value()); - m_masks.push_back(makeLeadingLevelsMask(beg->first.value())); - m_values.push_back(std::move(beg->second)); + + m_ids.reserve(elements.size()); + m_masks.reserve(elements.size()); + m_values.reserve(elements.size()); + + for (const auto& element : elements) { + m_ids.push_back(element.first.value()); + m_masks.push_back(makeLeadingLevelsMask(element.first.value())); + m_values.push_back(std::move(element.second)); } } template -inline auto GeometryHierarchyMap::find(GeometryIdentifier id) const - -> Iterator { +inline auto GeometryHierarchyMap::find( + const GeometryIdentifier& id) const -> Iterator { assert((m_ids.size() == m_values.size()) && "Inconsistent container state: #ids != # values"); assert((m_masks.size() == m_values.size()) && diff --git a/Core/include/Acts/Geometry/Polyhedron.hpp b/Core/include/Acts/Geometry/Polyhedron.hpp index 69ae109c52d..e8a55d17d93 100644 --- a/Core/include/Acts/Geometry/Polyhedron.hpp +++ b/Core/include/Acts/Geometry/Polyhedron.hpp @@ -10,12 +10,15 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Geometry/Extent.hpp" +#include "Acts/Visualization/ViewConfig.hpp" #include #include namespace Acts { +class IVisualization3D; + /// @class Polyhedron /// /// Struct which contains a cartesian approximation for any surface type. @@ -79,5 +82,8 @@ struct Polyhedron { /// /// @return ranges that describe the space taken by this surface Extent extent(const Transform3& transform = Transform3::Identity()) const; + + void visualize(IVisualization3D& helper, + const ViewConfig& viewConfig = {}) const; }; } // namespace Acts diff --git a/Core/include/Acts/Geometry/TrackingGeometry.hpp b/Core/include/Acts/Geometry/TrackingGeometry.hpp index d9a7081239a..ea3d8b7efe6 100644 --- a/Core/include/Acts/Geometry/TrackingGeometry.hpp +++ b/Core/include/Acts/Geometry/TrackingGeometry.hpp @@ -17,7 +17,6 @@ #include "Acts/Utilities/Logger.hpp" #include -#include #include #include @@ -29,9 +28,6 @@ class PerigeeSurface; class IMaterialDecorator; class TrackingVolume; -using TrackingVolumePtr = std::shared_ptr; -using MutableTrackingVolumePtr = std::shared_ptr; - /// @class TrackingGeometry /// /// The TrackingGeometry class is the owner of the constructed TrackingVolumes. @@ -52,7 +48,7 @@ class TrackingGeometry { /// surface or volume based material to the TrackingVolume /// @param hook Identifier hook to be applied to surfaces /// @param logger instance of a logger (defaulting to the "silent" one) - TrackingGeometry(const MutableTrackingVolumePtr& highestVolume, + TrackingGeometry(const std::shared_ptr& highestVolume, const IMaterialDecorator* materialDecorator = nullptr, const GeometryIdentifierHook& hook = {}, const Logger& logger = getDummyLogger()); @@ -66,8 +62,7 @@ class TrackingGeometry { /// Access to the world volume /// @return shared pointer to the world volume - const std::shared_ptr& highestTrackingVolumeShared() - const; + std::shared_ptr highestTrackingVolumePtr() const; /// return the lowest tracking Volume /// @@ -87,19 +82,6 @@ class TrackingGeometry { const Layer* associatedLayer(const GeometryContext& gctx, const Vector3& gp) const; - /// Register the beam tube - /// - /// @param beam is the beam line surface - void registerBeamTube(std::shared_ptr beam); - - /// @brief surface representing the beam pipe - /// - /// @note The ownership is not passed, e.g. do not delete the pointer - /// - /// @return raw pointer to surface representing the beam pipe - /// (could be a null pointer) - const Surface* getBeamline() const; - /// @brief Visit all reachable surfaces /// /// @tparam visitor_t Type of the callable visitor @@ -108,7 +90,7 @@ class TrackingGeometry { /// that is found, a selection of the surfaces can be done in the visitor /// @param restrictToSensitives If true, only sensitive surfaces are visited /// - /// @note If a context is needed for the visit, the vistitor has to provide + /// @note If a context is needed for the visit, the visitor has to provide /// this, e.g. as a private member template void visitSurfaces(visitor_t&& visitor, bool restrictToSensitives) const { @@ -123,7 +105,7 @@ class TrackingGeometry { /// @param visitor The callable. Will be called for each sensitive surface /// that is found, a selection of the surfaces can be done in the visitor /// - /// @note If a context is needed for the visit, the vistitor has to provide + /// @note If a context is needed for the visit, the visitor has to provide /// this, e.g. as a private member template void visitSurfaces(visitor_t&& visitor) const { @@ -137,7 +119,7 @@ class TrackingGeometry { /// @param visitor The callable. Will be called for each reachable volume /// that is found, a selection of the volumes can be done in the visitor /// - /// @note If a context is needed for the visit, the vistitor has to provide + /// @note If a context is needed for the visit, the visitor has to provide /// this, e.g. as a private member template void visitVolumes(visitor_t&& visitor) const { @@ -165,9 +147,7 @@ class TrackingGeometry { private: // the known world - TrackingVolumePtr m_world; - // beam line - std::shared_ptr m_beam; + std::shared_ptr m_world; // lookup containers std::unordered_map m_volumesById; std::unordered_map m_surfacesById; diff --git a/Core/include/Acts/Geometry/TrackingVolume.hpp b/Core/include/Acts/Geometry/TrackingVolume.hpp index a343f40bf2d..c5590e1168d 100644 --- a/Core/include/Acts/Geometry/TrackingVolume.hpp +++ b/Core/include/Acts/Geometry/TrackingVolume.hpp @@ -264,7 +264,7 @@ class TrackingVolume : public Volume { const IVolumeMaterial* volumeMaterial() const; /// Return the material of the volume as shared pointer - const std::shared_ptr& volumeMaterialSharedPtr() const; + const std::shared_ptr& volumeMaterialPtr() const; /// Set the volume material description /// diff --git a/Core/include/Acts/Geometry/Volume.hpp b/Core/include/Acts/Geometry/Volume.hpp index 65e3e8b9219..3a6a592ffb0 100644 --- a/Core/include/Acts/Geometry/Volume.hpp +++ b/Core/include/Acts/Geometry/Volume.hpp @@ -118,6 +118,13 @@ class Volume : public GeometryObject { bool operator==(const Volume& other) const; bool operator!=(const Volume& other) const; + /// Produces a 3D visualization of this volume + /// @param helper The visualization helper describing the output format + /// @param gctx The geometry context + /// @param viewConfig The view configuration + void visualize(IVisualization3D& helper, const GeometryContext& gctx, + const ViewConfig& viewConfig = {}) const; + protected: Transform3 m_transform; Transform3 m_itransform; diff --git a/Core/include/Acts/Geometry/VolumeBounds.hpp b/Core/include/Acts/Geometry/VolumeBounds.hpp index f2f4407cde5..c065440383b 100644 --- a/Core/include/Acts/Geometry/VolumeBounds.hpp +++ b/Core/include/Acts/Geometry/VolumeBounds.hpp @@ -57,16 +57,19 @@ class VolumeBounds { // @enum BoundsType /// This is nested to the VolumeBounds, as also SurfaceBounds will have /// Bounds Type. - enum BoundsType : int { - eCone = 0, - eCuboid = 1, - eCutoutCylinder = 2, - eCylinder = 3, - eGenericCuboid = 4, - eTrapezoid = 5, - eOther = 6 + enum class BoundsType { + eCone, + eCuboid, + eCutoutCylinder, + eCylinder, + eGenericCuboid, + eTrapezoid, + eOther, + }; + using enum BoundsType; + /// Static member to get the name of the BoundsType static const std::vector s_boundsTypeNames; @@ -168,4 +171,6 @@ inline bool operator==(const VolumeBounds& lhs, const VolumeBounds& rhs) { return (lhs.type() == rhs.type()) && (lhs.values() == rhs.values()); } +std::ostream& operator<<(std::ostream& sl, const VolumeBounds::BoundsType& bt); + } // namespace Acts diff --git a/Core/include/Acts/Material/MaterialComposition.hpp b/Core/include/Acts/Material/MaterialComposition.hpp index 1b11901e032..00073a2b1f0 100644 --- a/Core/include/Acts/Material/MaterialComposition.hpp +++ b/Core/include/Acts/Material/MaterialComposition.hpp @@ -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 @@ -100,10 +100,10 @@ class MaterialComposition { /// Rescales the fractions so they all add up to unity within the accuracy. MaterialComposition(std::vector elements) : m_elements(std::move(elements)) { - std::sort(m_elements.begin(), m_elements.end()); + std::ranges::sort(m_elements, std::less{}); // compute the total weight first unsigned total = 0u; - for (auto element : m_elements) { + for (const auto& element : m_elements) { total += element.m_fraction; } // compute scale factor into the [0, 256) range diff --git a/Core/include/Acts/Navigation/DetectorNavigator.hpp b/Core/include/Acts/Navigation/DetectorNavigator.hpp index 02522888f14..eb18295ecef 100644 --- a/Core/include/Acts/Navigation/DetectorNavigator.hpp +++ b/Core/include/Acts/Navigation/DetectorNavigator.hpp @@ -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 @@ -22,6 +22,7 @@ #include "Acts/Surfaces/Surface.hpp" #include "Acts/Utilities/Logger.hpp" +#include #include #include #include @@ -405,13 +406,9 @@ class DetectorNavigator { // Sort properly the surface candidates auto& nCandidates = nState.surfaceCandidates; - std::sort(nCandidates.begin(), nCandidates.end(), - [&](const auto& a, const auto& b) { - // The two path lengths - ActsScalar pathToA = a.objectIntersection.pathLength(); - ActsScalar pathToB = b.objectIntersection.pathLength(); - return pathToA < pathToB; - }); + std::ranges::sort(nCandidates, {}, [](const auto& c) { + return c.objectIntersection.pathLength(); + }); // Set the surface candidate nState.surfaceCandidateIndex = 0; } diff --git a/Core/include/Acts/Navigation/MultiLayerNavigation.hpp b/Core/include/Acts/Navigation/MultiLayerNavigation.hpp index 15042881147..12d48e5dcaa 100644 --- a/Core/include/Acts/Navigation/MultiLayerNavigation.hpp +++ b/Core/include/Acts/Navigation/MultiLayerNavigation.hpp @@ -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 @@ -14,8 +14,10 @@ #include "Acts/Navigation/NavigationStateUpdaters.hpp" #include "Acts/Utilities/VectorHelpers.hpp" +#include #include #include +#include namespace Acts::Experimental { @@ -105,16 +107,11 @@ class MultiLayerNavigation : public IInternalNavigation { void resolveDuplicates(const GeometryContext& gctx, std::vector& surfaces) const { // sorting the surfaces according to their radial distance - std::sort(surfaces.begin(), surfaces.end(), - [&gctx](const auto& surf1, const auto& surf2) { - if (surf1->center(gctx).x() != surf2->center(gctx).x()) { - return surf1->center(gctx).x() < surf2->center(gctx).x(); - } - if (surf1->center(gctx).y() != surf2->center(gctx).y()) { - return surf1->center(gctx).y() < surf2->center(gctx).y(); - } - return surf1->center(gctx).z() < surf2->center(gctx).z(); - }); + std::ranges::sort(surfaces, {}, [&gctx](const auto& s) { + assert(s != nullptr && "Uninitialized surface"); + const auto& center = s->center(gctx); + return std::make_tuple(center.x(), center.y(), center.z()); + }); // Remove the duplicates surfaces.erase(std::unique(surfaces.begin(), surfaces.end()), diff --git a/Core/include/Acts/Navigation/NavigationStateUpdaters.hpp b/Core/include/Acts/Navigation/NavigationStateUpdaters.hpp index 3903d1e123c..b5e4d90f53b 100644 --- a/Core/include/Acts/Navigation/NavigationStateUpdaters.hpp +++ b/Core/include/Acts/Navigation/NavigationStateUpdaters.hpp @@ -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 @@ -20,6 +20,7 @@ #include "Acts/Utilities/IAxis.hpp" #include "Acts/Utilities/VectorHelpers.hpp" +#include #include #include @@ -65,11 +66,9 @@ inline void intitializeCandidates(const GeometryContext& gctx, } } - std::sort(confirmedCandidates.begin(), confirmedCandidates.end(), - [&](const auto& a, const auto& b) { - return a.objectIntersection.pathLength() < - b.objectIntersection.pathLength(); - }); + std::ranges::sort(confirmedCandidates, {}, [](const auto& c) { + return c.objectIntersection.pathLength(); + }); nState.surfaceCandidates = std::move(confirmedCandidates); nState.surfaceCandidateIndex = 0; diff --git a/Core/include/Acts/Propagator/EigenStepperDenseEnvironmentExtension.hpp b/Core/include/Acts/Propagator/EigenStepperDenseExtension.hpp similarity index 99% rename from Core/include/Acts/Propagator/EigenStepperDenseEnvironmentExtension.hpp rename to Core/include/Acts/Propagator/EigenStepperDenseExtension.hpp index befab8f96ce..155bc1637bc 100644 --- a/Core/include/Acts/Propagator/EigenStepperDenseEnvironmentExtension.hpp +++ b/Core/include/Acts/Propagator/EigenStepperDenseExtension.hpp @@ -25,7 +25,7 @@ namespace Acts { /// ioninisation, bremsstrahlung, pair production and photonuclear interaction /// in the propagation and the jacobian. These effects will only occur if the /// propagation is in a TrackingVolume with attached material. -struct EigenStepperDenseEnvironmentExtension { +struct EigenStepperDenseExtension { using Scalar = ActsScalar; /// @brief Vector3 replacement for the custom scalar type using ThisVector3 = Eigen::Matrix; diff --git a/Core/include/Acts/Propagator/Navigator.hpp b/Core/include/Acts/Propagator/Navigator.hpp index 73e928b762e..dba15d46ac9 100644 --- a/Core/include/Acts/Propagator/Navigator.hpp +++ b/Core/include/Acts/Propagator/Navigator.hpp @@ -20,6 +20,7 @@ #include "Acts/Utilities/Logger.hpp" #include "Acts/Utilities/StringHelpers.hpp" +#include #include #include @@ -889,11 +890,10 @@ class Navigator { state.geoContext, stepper.position(state.stepping), state.options.direction * stepper.direction(state.stepping), navOpts, logger()); - std::sort(state.navigation.navBoundaries.begin(), - state.navigation.navBoundaries.end(), - [](const auto& a, const auto& b) { - return SurfaceIntersection::pathLengthOrder(a.first, b.first); - }); + std::ranges::sort( + state.navigation.navBoundaries, [](const auto& a, const auto& b) { + return SurfaceIntersection::pathLengthOrder(a.first, b.first); + }); // Print boundary information if (logger().doPrint(Logging::VERBOSE)) { @@ -1011,9 +1011,8 @@ class Navigator { state.navigation.navSurfaces = currentLayer->compatibleSurfaces( state.geoContext, stepper.position(state.stepping), state.options.direction * stepper.direction(state.stepping), navOpts); - std::sort(state.navigation.navSurfaces.begin(), - state.navigation.navSurfaces.end(), - SurfaceIntersection::pathLengthOrder); + std::ranges::sort(state.navigation.navSurfaces, + SurfaceIntersection::pathLengthOrder); // Print surface information if (logger().doPrint(Logging::VERBOSE)) { @@ -1079,11 +1078,10 @@ class Navigator { state.geoContext, stepper.position(state.stepping), state.options.direction * stepper.direction(state.stepping), navOpts); - std::sort(state.navigation.navLayers.begin(), - state.navigation.navLayers.end(), - [](const auto& a, const auto& b) { - return SurfaceIntersection::pathLengthOrder(a.first, b.first); - }); + std::ranges::sort( + state.navigation.navLayers, [](const auto& a, const auto& b) { + return SurfaceIntersection::pathLengthOrder(a.first, b.first); + }); // Print layer information if (logger().doPrint(Logging::VERBOSE)) { diff --git a/Core/include/Acts/Propagator/TryAllNavigator.hpp b/Core/include/Acts/Propagator/TryAllNavigator.hpp index a516a3292d2..2ba9cc6a80e 100644 --- a/Core/include/Acts/Propagator/TryAllNavigator.hpp +++ b/Core/include/Acts/Propagator/TryAllNavigator.hpp @@ -354,8 +354,8 @@ class TryAllNavigator : public TryAllNavigatorBase { } } - std::sort(intersectionCandidates.begin(), intersectionCandidates.end(), - detail::IntersectionCandidate::forwardOrder); + std::ranges::sort(intersectionCandidates, + detail::IntersectionCandidate::forwardOrder); ACTS_VERBOSE(volInfo(state) << "found " << intersectionCandidates.size() << " intersections"); @@ -766,9 +766,8 @@ class TryAllOverstepNavigator : public TryAllNavigatorBase { } } - std::sort(state.navigation.activeCandidates.begin(), - state.navigation.activeCandidates.end(), - detail::IntersectionCandidate::forwardOrder); + std::ranges::sort(state.navigation.activeCandidates, + detail::IntersectionCandidate::forwardOrder); state.navigation.activeCandidateIndex = 0; diff --git a/Core/include/Acts/Seeding/GbtsDataStorage.hpp b/Core/include/Acts/Seeding/GbtsDataStorage.hpp index 11debd64d7f..5f088e4138e 100644 --- a/Core/include/Acts/Seeding/GbtsDataStorage.hpp +++ b/Core/include/Acts/Seeding/GbtsDataStorage.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2021 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 @@ -105,8 +105,8 @@ class GbtsEtaBin { } void sortByPhi() { - std::sort(m_vn.begin(), m_vn.end(), - typename Acts::GbtsNode::CompareByPhi()); + std::ranges::sort(m_vn, + typename Acts::GbtsNode::CompareByPhi()); } bool empty() const { return m_vn.empty(); } diff --git a/Core/include/Acts/Seeding/GbtsTrackingFilter.hpp b/Core/include/Acts/Seeding/GbtsTrackingFilter.hpp index 7ce93170b9a..83a8aa2b362 100644 --- a/Core/include/Acts/Seeding/GbtsTrackingFilter.hpp +++ b/Core/include/Acts/Seeding/GbtsTrackingFilter.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2021 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 @@ -138,8 +138,8 @@ class GbtsTrackingFilter { if (m_stateVec.empty()) { return; } - std::sort(m_stateVec.begin(), m_stateVec.end(), - typename GbtsEdgeState::Compare()); + std::ranges::sort(m_stateVec, + typename GbtsEdgeState::Compare()); GbtsEdgeState* best = (*m_stateVec.begin()); diff --git a/Core/include/Acts/Seeding/HoughTransformUtils.ipp b/Core/include/Acts/Seeding/HoughTransformUtils.ipp index d6777d1918d..37ebe3ec9d9 100644 --- a/Core/include/Acts/Seeding/HoughTransformUtils.ipp +++ b/Core/include/Acts/Seeding/HoughTransformUtils.ipp @@ -1,12 +1,13 @@ // 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 // file, You can obtain one at http://mozilla.org/MPL/2.0/. #include +#include template template @@ -263,16 +264,9 @@ Acts::HoughTransformUtils::PeakFinders::IslandsAroundMax< } } // sort the candidate cells descending in content - std::sort(candidates.begin(), candidates.end(), - [&yieldMap](const std::size_t bin1, const std::size_t bin2) { - YieldType h1 = yieldMap[bin1]; - YieldType h2 = yieldMap[bin2]; - - if (h1 != h2) { - return h1 > h2; - } - return bin1 > bin2; - }); + std::ranges::sort(candidates, std::greater{}, [&yieldMap](std::size_t c) { + return std::make_tuple(yieldMap[c], c); + }); // now we build islands from the candidate cells, starting with the most // populated one diff --git a/Core/include/Acts/Seeding/SeedFilter.ipp b/Core/include/Acts/Seeding/SeedFilter.ipp index 71d2a6250ce..284ab2932e3 100644 --- a/Core/include/Acts/Seeding/SeedFilter.ipp +++ b/Core/include/Acts/Seeding/SeedFilter.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 @@ -69,11 +69,10 @@ void SeedFilter::filterSeeds_2SpFixed( if (topSpVec.size() > 2) { // sort indexes based on comparing values in invHelixDiameterVec - std::sort( - topSPIndexVec.begin(), topSPIndexVec.end(), - [&invHelixDiameterVec](const std::size_t i1, const std::size_t i2) { - return invHelixDiameterVec[i1] < invHelixDiameterVec[i2]; - }); + std::ranges::sort(topSPIndexVec, {}, + [&invHelixDiameterVec](const std::size_t t) { + return invHelixDiameterVec[t]; + }); } // vector containing the radius of all compatible seeds diff --git a/Core/include/Acts/Seeding/SeedFinder.ipp b/Core/include/Acts/Seeding/SeedFinder.ipp index ba36b260909..f65a26e3f58 100644 --- a/Core/include/Acts/Seeding/SeedFinder.ipp +++ b/Core/include/Acts/Seeding/SeedFinder.ipp @@ -496,17 +496,13 @@ SeedFinder::filterCandidates( if constexpr (detailedMeasurement == Acts::DetectorMeasurementInfo::eDefault) { - std::sort(sorted_bottoms.begin(), sorted_bottoms.end(), - [&state](const std::size_t a, const std::size_t b) -> bool { - return state.linCircleBottom[a].cotTheta < - state.linCircleBottom[b].cotTheta; - }); - - std::sort(sorted_tops.begin(), sorted_tops.end(), - [&state](const std::size_t a, const std::size_t b) -> bool { - return state.linCircleTop[a].cotTheta < - state.linCircleTop[b].cotTheta; - }); + std::ranges::sort(sorted_bottoms, {}, [&state](const std::size_t s) { + return state.linCircleBottom[s].cotTheta; + }); + + std::ranges::sort(sorted_tops, {}, [&state](const std::size_t s) { + return state.linCircleTop[s].cotTheta; + }); } // Reserve enough space, in case current capacity is too little diff --git a/Core/include/Acts/Seeding/SeedFinderGbts.ipp b/Core/include/Acts/Seeding/SeedFinderGbts.ipp index 92cc7cd1963..5872707754e 100644 --- a/Core/include/Acts/Seeding/SeedFinderGbts.ipp +++ b/Core/include/Acts/Seeding/SeedFinderGbts.ipp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2021 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 @@ -17,6 +17,7 @@ #include "Acts/Seeding/SeedFinderUtils.hpp" #include "Acts/Utilities/BinningType.hpp" +#include #include #include #include @@ -352,8 +353,8 @@ void SeedFinderGbts::runGbts_TrackFinder( out_sort[outIdx].first = pS->m_p[0]; } - std::sort(in_sort.begin(), in_sort.end()); - std::sort(out_sort.begin(), out_sort.end()); + std::ranges::sort(in_sort); + std::ranges::sort(out_sort); unsigned int last_out = 0; @@ -495,8 +496,8 @@ void SeedFinderGbts::runGbts_TrackFinder( m_triplets.clear(); - std::sort(vSeeds.begin(), vSeeds.end(), - typename Acts::GbtsEdge::CompareLevel()); + std::ranges::sort( + vSeeds, typename Acts::GbtsEdge::CompareLevel()); if (vSeeds.empty()) { return; diff --git a/Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp b/Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp index 31757e3e72a..7caad023cf4 100644 --- a/Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp +++ b/Core/include/Acts/Seeding/SeedFinderOrthogonal.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 @@ -13,6 +13,7 @@ #include "Acts/Seeding/SeedFinderUtils.hpp" #include "Acts/Utilities/BinningType.hpp" +#include #include #include #include @@ -311,16 +312,14 @@ void SeedFinderOrthogonal::filterCandidates( sorted_tops[i] = i; } - std::sort( - sorted_bottoms.begin(), sorted_bottoms.end(), - [&linCircleBottom](const std::size_t a, const std::size_t b) -> bool { - return linCircleBottom[a].cotTheta < linCircleBottom[b].cotTheta; - }); + std::ranges::sort(sorted_bottoms, {}, + [&linCircleBottom](const std::size_t s) { + return linCircleBottom[s].cotTheta; + }); - std::sort(sorted_tops.begin(), sorted_tops.end(), - [&linCircleTop](const std::size_t a, const std::size_t b) -> bool { - return linCircleTop[a].cotTheta < linCircleTop[b].cotTheta; - }); + std::ranges::sort(sorted_tops, {}, [&linCircleTop](const std::size_t s) { + return linCircleTop[s].cotTheta; + }); std::vector tanMT; tanMT.reserve(top.size()); diff --git a/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp b/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp index 5a88fc341ac..19d7beddbf7 100644 --- a/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp +++ b/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp @@ -236,9 +236,6 @@ void Acts::CylindricalSpacePointGridCreator::fillGrid( /// sort SPs in R for each filled bin for (std::size_t binIndex : rBinsIndex) { auto& rbin = grid.atPosition(binIndex); - std::sort(rbin.begin(), rbin.end(), - [](const auto& a, const auto& b) -> bool { - return a->radius() < b->radius(); - }); + std::ranges::sort(rbin, {}, [](const auto& rb) { return rb->radius(); }); } } diff --git a/Core/include/Acts/Surfaces/Surface.hpp b/Core/include/Acts/Surfaces/Surface.hpp index 1ca13d48600..d2f62e0bf31 100644 --- a/Core/include/Acts/Surfaces/Surface.hpp +++ b/Core/include/Acts/Surfaces/Surface.hpp @@ -25,6 +25,7 @@ #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Intersection.hpp" #include "Acts/Utilities/Result.hpp" +#include "Acts/Visualization/ViewConfig.hpp" #include #include @@ -484,6 +485,9 @@ class Surface : public virtual GeometryObject, virtual ActsMatrix<2, 3> localCartesianToBoundLocalDerivative( const GeometryContext& gctx, const Vector3& position) const = 0; + void visualize(IVisualization3D& helper, const GeometryContext& gctx, + const ViewConfig& viewConfig = {}) const; + protected: /// Output Method for std::ostream, to be overloaded by child classes /// diff --git a/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp b/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp index ada401ba401..e94ab519902 100644 --- a/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp +++ b/Core/include/Acts/TrackFitting/GaussianSumFitter.hpp @@ -16,6 +16,7 @@ #include "Acts/Surfaces/BoundaryTolerance.hpp" #include "Acts/TrackFitting/GsfOptions.hpp" #include "Acts/TrackFitting/detail/GsfActor.hpp" +#include "Acts/Utilities/Helpers.hpp" #include "Acts/Utilities/Logger.hpp" #include "Acts/Utilities/TrackHelpers.hpp" @@ -432,8 +433,8 @@ struct GaussianSumFitter { for (auto state : fwdGsfResult.fittedStates->reverseTrackStateRange( fwdGsfResult.currentTip)) { - const bool found = std::find(foundBwd.begin(), foundBwd.end(), - &state.referenceSurface()) != foundBwd.end(); + const bool found = + rangeContainsValue(foundBwd, &state.referenceSurface()); if (!found && state.typeFlags().test(MeasurementFlag)) { state.typeFlags().set(OutlierFlag); state.typeFlags().reset(MeasurementFlag); diff --git a/Core/include/Acts/TrackFitting/MbfSmoother.hpp b/Core/include/Acts/TrackFitting/MbfSmoother.hpp index 61f28e1d7b4..57cdd0dd483 100644 --- a/Core/include/Acts/TrackFitting/MbfSmoother.hpp +++ b/Core/include/Acts/TrackFitting/MbfSmoother.hpp @@ -51,21 +51,21 @@ class MbfSmoother { using TrackStateProxy = typename traj_t::TrackStateProxy; - TrackStateProxy start_ts = trajectory.getTrackState(entryIndex); + TrackStateProxy startTs = trajectory.getTrackState(entryIndex); // Notation consistent with the Wikipedia article // https://en.wikipedia.org/wiki/Kalman_filter - BoundMatrix big_lambda_hat = BoundMatrix::Zero(); - BoundVector small_lambda_hat = BoundVector::Zero(); + BoundMatrix bigLambdaHat = BoundMatrix::Zero(); + BoundVector smallLambdaHat = BoundVector::Zero(); - trajectory.applyBackwards(start_ts.index(), [&](TrackStateProxy ts) { + trajectory.applyBackwards(startTs.index(), [&](TrackStateProxy ts) { // ensure the track state has a smoothed component ts.addComponents(TrackStatePropMask::Smoothed); InternalTrackState internalTrackState(ts); // Smoothe the current state - calculateSmoothed(internalTrackState, big_lambda_hat, small_lambda_hat); + calculateSmoothed(internalTrackState, bigLambdaHat, smallLambdaHat); // We smoothed the last state - no need to update the lambdas if (!ts.hasPrevious()) { @@ -74,10 +74,9 @@ class MbfSmoother { // Update the lambdas depending on the type of track state if (ts.typeFlags().test(TrackStateFlag::MeasurementFlag)) { - visitMeasurement(internalTrackState, big_lambda_hat, small_lambda_hat); + visitMeasurement(internalTrackState, bigLambdaHat, smallLambdaHat); } else { - visitNonMeasurement(internalTrackState, big_lambda_hat, - small_lambda_hat); + visitNonMeasurement(internalTrackState, bigLambdaHat, smallLambdaHat); } }); @@ -143,18 +142,17 @@ class MbfSmoother { /// Calculate the smoothed parameters and covariance. void calculateSmoothed(InternalTrackState& ts, - const BoundMatrix& big_lambda_hat, - const BoundVector& small_lambda_hat) const; + const BoundMatrix& bigLambdaHat, + const BoundVector& smallLambdaHat) const; /// Visit a non-measurement track state and update the lambdas. void visitNonMeasurement(const InternalTrackState& ts, - BoundMatrix& big_lambda_hat, - BoundVector& small_lambda_hat) const; + BoundMatrix& bigLambdaHat, + BoundVector& smallLambdaHat) const; /// Visit a measurement track state and update the lambdas. - void visitMeasurement(const InternalTrackState& ts, - BoundMatrix& big_lambda_hat, - BoundVector& small_lambda_hat) const; + void visitMeasurement(const InternalTrackState& ts, BoundMatrix& bigLambdaHat, + BoundVector& smallLambdaHat) const; }; } // namespace Acts diff --git a/Core/include/Acts/TrackFitting/detail/GsfActor.hpp b/Core/include/Acts/TrackFitting/detail/GsfActor.hpp index 56d6cecd262..7db377d1ced 100644 --- a/Core/include/Acts/TrackFitting/detail/GsfActor.hpp +++ b/Core/include/Acts/TrackFitting/detail/GsfActor.hpp @@ -23,6 +23,7 @@ #include "Acts/TrackFitting/detail/GsfComponentMerging.hpp" #include "Acts/TrackFitting/detail/GsfUtils.hpp" #include "Acts/TrackFitting/detail/KalmanUpdateHelpers.hpp" +#include "Acts/Utilities/Helpers.hpp" #include "Acts/Utilities/Zip.hpp" #include @@ -195,9 +196,7 @@ struct GsfActor { // Early return if we already were on this surface TODO why is this // necessary - const bool visited = - std::find(result.visitedSurfaces.begin(), result.visitedSurfaces.end(), - &surface) != result.visitedSurfaces.end(); + const bool visited = rangeContainsValue(result.visitedSurfaces, &surface); if (visited) { ACTS_VERBOSE("Already visited surface, return"); diff --git a/Core/include/Acts/Utilities/BinnedArrayXD.hpp b/Core/include/Acts/Utilities/BinnedArrayXD.hpp index 4b78b1026bc..281bd9d11b3 100644 --- a/Core/include/Acts/Utilities/BinnedArrayXD.hpp +++ b/Core/include/Acts/Utilities/BinnedArrayXD.hpp @@ -13,6 +13,7 @@ #pragma once #include "Acts/Utilities/BinUtility.hpp" #include "Acts/Utilities/BinnedArray.hpp" +#include "Acts/Utilities/Helpers.hpp" #include #include @@ -74,8 +75,7 @@ class BinnedArrayXD : public BinnedArray { /// fill the data m_objectGrid[bins[2]][bins[1]][bins[0]] = tap.first; /// fill the unique m_arrayObjects - if (std::find(m_arrayObjects.begin(), m_arrayObjects.end(), - tap.first) == m_arrayObjects.end()) { + if (!rangeContainsValue(m_arrayObjects, tap.first)) { m_arrayObjects.push_back(tap.first); } } @@ -103,8 +103,7 @@ class BinnedArrayXD : public BinnedArray { for (auto& o0 : o1) { if (o0) { /// fill the unique m_arrayObjects - if (std::find(m_arrayObjects.begin(), m_arrayObjects.end(), o0) == - m_arrayObjects.end()) { + if (!rangeContainsValue(m_arrayObjects, o0)) { m_arrayObjects.push_back(o0); } } diff --git a/Core/include/Acts/Utilities/BinningData.hpp b/Core/include/Acts/Utilities/BinningData.hpp index ed8668a3aca..e4fcf700c9a 100644 --- a/Core/include/Acts/Utilities/BinningData.hpp +++ b/Core/include/Acts/Utilities/BinningData.hpp @@ -1,6 +1,6 @@ // This file is part of the Acts project. // -// Copyright (C) 2016-2018 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 @@ -481,7 +481,7 @@ class BinningData { } } // sort the total boundary vector - std::sort(m_totalBoundaries.begin(), m_totalBoundaries.end()); + std::ranges::sort(m_totalBoundaries); } } diff --git a/Core/include/Acts/Utilities/BoundingBox.hpp b/Core/include/Acts/Utilities/BoundingBox.hpp index 72c2b0d2572..aee5ec8d016 100644 --- a/Core/include/Acts/Utilities/BoundingBox.hpp +++ b/Core/include/Acts/Utilities/BoundingBox.hpp @@ -20,22 +20,16 @@ namespace Acts { -/** - * Implementation of an Axis Aligned Bounding Box. This type is compatible - * with 2D and 3D boxes - */ +/// Implementation of an Axis Aligned Bounding Box. This type is compatible +/// with 2D and 3D boxes template class AxisAlignedBoundingBox { private: - /** - * Private self type to capture template parameters - */ + /// Private self type to capture template parameters using self_t = AxisAlignedBoundingBox; - /** - * Strong type helper, not public - * This is only used to provide sensible tag-dispatch below. - */ + /// Strong type helper, not public + /// This is only used to provide sensible tag-dispatch below. template class NamedType { public: @@ -48,265 +42,195 @@ class AxisAlignedBoundingBox { T m_value; }; - /** - * SizeParameter Tag - */ + /// SizeParameter Tag struct SizeParameter {}; public: - /** - * The value type used by this class - */ - + /// The value type used by this class using value_type = value_t; - /** - * Re-export vertex type based on value type given - */ + /// Re-export vertex type based on value type given using VertexType = Eigen::Matrix; - /** - * Associated array value to `VertexType` - */ + /// Associated array value to `VertexType` using vertex_array_type = Eigen::Array; - /** - * Type of stored entity - */ + /// Type of stored entity using entity_type = entity_t; - /** - * The transform type based on the `value_type` - */ + /// The transform type based on the `value_type` using transform_type = Eigen::Transform; - /** - * Strong type to select the correct constructor - */ + /// Strong type to select the correct constructor using Size = NamedType; - /** - * Re-export dimension from template parameter - */ + /// Re-export dimension from template parameter static const std::size_t dim = DIM; - /** - * Copy constructor from other bounding box. - * @param other The other AABB - */ + /// Copy constructor from other bounding box. AxisAlignedBoundingBox(const self_t& other) = default; - /** - * Copy assignment operator from other bounding box. - * @param other The other AABB - */ + /// Copy assignment operator from other bounding box. + /// @param other The other AABB AxisAlignedBoundingBox& operator=(const self_t& other) = default; - /** - * Constructor from an entity pointer, and the min and max vertices. - * @param entity The entity to store - * @param vmin The minimum vertex. - * @param vmax The maximum vertex. - */ + /// Constructor from an entity pointer, and the min and max vertices. + /// @param entity The entity to store + /// @param vmin The minimum vertex. + /// @param vmax The maximum vertex. AxisAlignedBoundingBox(const entity_t* entity, const VertexType& vmin, const VertexType& vmax); - /** - * Constructor from a center position, and a width and height. - * @param entity The entity to store - * @param center The center position - * @param size The size (width and height) of the box. - * @note The special type @c size is required to disambiguate this constructor - * from the other one above. It is a wrapper around a simple @c Vector3. - */ + /// Constructor from a center position, and a width and height. + /// @param entity The entity to store + /// @param center The center position + /// @param size The size (width and height) of the box. + /// @note The special type @c size is required to disambiguate this constructor + /// from the other one above. It is a wrapper around a simple @c Vector3. AxisAlignedBoundingBox(const entity_t* entity, const VertexType& center, const Size& size); - /** - * Constructor from a list of child boxes. This box will wrap around all boxes - * contained in @p boxes, and additional envelope can be given. - * @param boxes Vector of child boxes to store in this bounding box. - * @param envelope Envelope that will be added/subtracted to the dimension. - */ + /// Constructor from a list of child boxes. This box will wrap around all + /// boxes + /// contained in @p boxes, and additional envelope can be given. + /// @param boxes Vector of child boxes to store in this bounding box. + /// @param envelope Envelope that will be added/subtracted to the dimension. AxisAlignedBoundingBox( const std::vector& boxes, vertex_array_type envelope = vertex_array_type::Zero()); - /** - * Helper function to calculate the size of a bounding box enclosing @p boxes. - * @param boxes The boxes to wrap (const pointers) - * @param envelope Optional envelop to add/subtract to dimension. - * @return Pair of vertices: min and max. - */ + /// Helper function to calculate the size of a bounding box enclosing @p boxes. + /// @param boxes The boxes to wrap (const pointers) + /// @param envelope Optional envelop to add/subtract to dimension. + /// @return Pair of vertices: min and max. static std::pair wrap( const std::vector& boxes, vertex_array_type envelope = vertex_array_type::Zero()); - /** - * Helper function to calculate the size of a bounding box enclosing @p boxes. - * Overload which accepts non-const boxes in @p boxes. - * @param boxes The boxes to wrap (non-const pointers) - * @param envelope Optional envelop to add/subtract to dimension. - * @return Pair of vertices: min and max. - */ + /// Helper function to calculate the size of a bounding box enclosing @p boxes. + /// Overload which accepts non-const boxes in @p boxes. + /// @param boxes The boxes to wrap (non-const pointers) + /// @param envelope Optional envelop to add/subtract to dimension. + /// @return Pair of vertices: min and max. static std::pair wrap( const std::vector& boxes, vertex_array_type envelope = vertex_array_type::Zero()); - /** - * Helper function to calculate the size of a bounding box enclosing @p boxes. - * Overload which accepts a vector in @p boxes which owns the instances - * @param boxes The boxes to wrap (by-value vector) - * @param envelope Optional envelop to add/subtract to dimension. - * @return Pair of vertices: min and max. - */ + /// Helper function to calculate the size of a bounding box enclosing @p boxes. + /// Overload which accepts a vector in @p boxes which owns the instances + /// @param boxes The boxes to wrap (by-value vector) + /// @param envelope Optional envelop to add/subtract to dimension. + /// @return Pair of vertices: min and max. static std::pair wrap( const std::vector& boxes, vertex_array_type envelope = vertex_array_type::Zero()); - /** - * Calculate whether a point is inside this box. - * @param point The point to test. - * @return Whether the point is inside or not. - */ + /// Calculate whether a point is inside this box. + /// @param point The point to test. + /// @return Whether the point is inside or not. bool intersect(const VertexType& point) const; - /** - * @brief Implements the slab method for Ray/AABB intersections. - * - * See https://tavianator.com/fast-branchless-raybounding-box-intersections/, - * https://tavianator.com/fast-branchless-raybounding-box-intersections-part-2-nans/, - * https://medium.com/@bromanz/another-view-on-the-classic-ray-aabb-intersection-algorithm-for-bvh-traversal-41125138b525 - * The original algorithms is described in "Graphics Gems (1990)" [1] - * (https://doi.org/10.1016/B978-0-08-050753-8.50084-X) - * - * @note This implementation may treat parallel rays on any of the slabs - * as **outside** due to how @c NaNs are handled by Eigen. - * See https://eigen.tuxfamily.org/bz/show_bug.cgi?id=564 - * @param ray The ray to intersect with - * @return Whether the ray intersects this AABB - */ + /// @brief Implements the slab method for Ray/AABB intersections. + /// + /// See https://tavianator.com/fast-branchless-raybounding-box-intersections/, + /// https://tavianator.com/fast-branchless-raybounding-box-intersections-part-2-nans/, + /// https://medium.com/@bromanz/another-view-on-the-classic-ray-aabb-intersection-algorithm-for-bvh-traversal-41125138b525 + /// The original algorithms is described in "Graphics Gems (1990)" [1] + /// (https://doi.org/10.1016/B978-0-08-050753-8.50084-X) + /// + /// @note This implementation may treat parallel rays on any of the slabs + /// as **outside** due to how @c NaNs are handled by Eigen. + /// See https://eigen.tuxfamily.org/bz/show_bug.cgi?id=564 + /// @param ray The ray to intersect with + /// @return Whether the ray intersects this AABB bool intersect(const Ray& ray) const; - /** - * Check if a frustum intersects with this bounding box. - * - * This method implements an algorithm similar to the one described in - * "Optimized View Frustum Culling Algorithms for Bounding Boxes (2012)" [2] - * (https://doi.org/10.1080/10867651.2000.10487517), but drops some of the - * more sophisticated optimization. - * - * @param fr The frustum - * @return Whether the frustum intersects this AABB - */ + /// Check if a frustum intersects with this bounding box. + /// + /// This method implements an algorithm similar to the one described in + /// "Optimized View Frustum Culling Algorithms for Bounding Boxes (2012)" [2] + /// (https://doi.org/10.1080/10867651.2000.10487517), but drops some of the + /// more sophisticated optimization. + /// + /// @param fr The frustum + /// @return Whether the frustum intersects this AABB template bool intersect(const Frustum& fr) const; - /** - * Set the skip node (bounding box) - * @param skip The target skip node pointer - */ + /// Set the skip node (bounding box) + /// @param skip The target skip node pointer void setSkip(self_t* skip); - /** - * Get the skip node for this box - * @return The skip node pointer - */ + /// Get the skip node for this box + /// @return The skip node pointer const self_t* getSkip() const; - /** - * Get the left child (i.e. the first of the children that are inside this - * bounding box). - * @return The lest most child. - */ + /// Get the left child (i.e. the first of the children that are inside this + /// bounding box). + /// @return The lest most child. const self_t* getLeftChild() const; - /** - * Check whether this node as an associated entity. If it does not have one, - * this is a purely abstract container box. - * @return Whether the box has an entity attached. - */ + /// Check whether this node as an associated entity. If it does not have one, + /// this is a purely abstract container box. + /// @return Whether the box has an entity attached. bool hasEntity() const; - /** - * Return the entity associated with this box. This might be nullptr if there - * is no entity attached. - * @return The entity pointer, might be nullptr - */ + /// Return the entity associated with this box. This might be nullptr if there + /// is no entity attached. + /// @return The entity pointer, might be nullptr const entity_t* entity() const; - /** - * Set the entity associated with with this box. - * @param entity The entity - */ + /// Set the entity associated with with this box. + /// @param entity The entity void setEntity(const entity_t* entity); - /** - * Get the center position of this bounding box. - * @return The center position - */ + /// Get the center position of this bounding box. + /// @return The center position const VertexType& center() const; - /** - * Get the minimum vertex - * @return The minimum vertex - */ + /// Get the minimum vertex + /// @return The minimum vertex const VertexType& min() const; - /** - * Get the maximum vertex - * @return The maximum vertex - */ + /// Get the maximum vertex + /// @return The maximum vertex const VertexType& max() const; - /** - * Write information about this bounding box to a stream. - * @param os The output stream. - * @return The stream given as an argument. - */ + /// Write information about this bounding box to a stream. + /// @param os The output stream. + /// @return The stream given as an argument. std::ostream& toStream(std::ostream& os) const; - /** - * Transforms this bounding box using the given transform. This method - * modifies the box it is called on. - * @param trf The transform - */ + /// Transforms this bounding box using the given transform. This method + /// modifies the box it is called on. + /// @param trf The transform void transform(const transform_type& trf); - /** - * Transforms this bounding box using the given transform. This method returns - * a copy of this box, with the transformation applied, and leaves this - * instance unchanged. - * @param trf The transform - * @return The transformed bounding box - */ + /// Transforms this bounding box using the given transform. This method + /// returns a copy of this box, with the transformation applied, and leaves + /// this instance unchanged. + /// @param trf The transform + /// @return The transformed bounding box self_t transformed(const transform_type& trf) const; - /** - * Draw this bounding box using the given visualization helper. This method is - * only available for the 3D case. - * @tparam D (used for SFINAE) - * @param helper The visualization helper to write to - * @param color The color to use for drawing - * @param trf An optional transform to apply first. - */ - void draw(IVisualization3D& helper, - std::array color = {120, 120, 120}, + /// Draw this bounding box using the given visualization helper. This method + /// is only available for the 3D case. + /// @param helper The visualization helper to write to + /// @param color The color to use for drawing + /// @param trf An optional transform to apply first. + void draw(IVisualization3D& helper, Color color = {120, 120, 120}, const transform_type& trf = transform_type::Identity()) const requires(DIM == 3); - /** - * Draw this bounding box as SVG. This method is only available for the 2D - * case. - * @tparam D (used for SFINAE) - * @param os The output stream to write to - * @param w The width of the output SVG. - * @param h The height of the output SVG. - * @param unit A scale factor to apply before drawing - * @param label A label to put next to the box. - * @param fillcolor Color to fill the box with. - * @return The outstream given in @p os. - */ + /// Draw this bounding box as SVG. This method is only available for the 2D + /// case. + /// @param os The output stream to write to + /// @param w The width of the output SVG. + /// @param h The height of the output SVG. + /// @param unit A scale factor to apply before drawing + /// @param label A label to put next to the box. + /// @param fillcolor Color to fill the box with. + /// @return The outstream given in @p os. std::ostream& svg(std::ostream& os, value_type w, value_type h, value_type unit = 10, const std::string& label = "", const std::string& fillcolor = "grey") const @@ -333,32 +257,28 @@ class AxisAlignedBoundingBox { self_t* m_skip{nullptr}; }; -/** - * Build an octree from a list of bounding boxes. - * @note @p store and @p prims do not need to contain the same objects. @p store - * is only used to pass ownership back to the caller while preserving memory - * location. - * @tparam box_t Works will all box types. - * @param store Owns the created boxes by means of `std::unique_ptr`. - * @param prims Boxes to store. This is a read only vector. - * @param max_depth No subdivisions beyond this level. - * @param envelope1 Envelope to add/subtract to dimensions in all directions. - * @return Pointer to the top most bounding box, containing the entire octree - */ +/// Build an octree from a list of bounding boxes. +/// @note @p store and @p prims do not need to contain the same objects. @p store +/// is only used to pass ownership back to the caller while preserving memory +/// location. +/// @tparam box_t Works will all box types. +/// @param store Owns the created boxes by means of `std::unique_ptr`. +/// @param prims Boxes to store. This is a read only vector. +/// @param max_depth No subdivisions beyond this level. +/// @param envelope1 Envelope to add/subtract to dimensions in all directions. +/// @return Pointer to the top most bounding box, containing the entire octree template box_t* make_octree(std::vector>& store, const std::vector& prims, std::size_t max_depth = 1, typename box_t::value_type envelope1 = 0); -/** - * Overload of the << operator for bounding boxes. - * @tparam T entity type - * @tparam U value type - * @tparam V dimension - * @param os The output stream - * @param box The bounding box - * @return The given output stream. - */ +/// Overload of the << operator for bounding boxes. +/// @tparam T entity type +/// @tparam U value type +/// @tparam V dimension +/// @param os The output stream +/// @param box The bounding box +/// @return The given output stream. template std::ostream& operator<<(std::ostream& os, const AxisAlignedBoundingBox& box); diff --git a/Core/include/Acts/Utilities/BoundingBox.ipp b/Core/include/Acts/Utilities/BoundingBox.ipp index 8dcb2612b48..bce97e29825 100644 --- a/Core/include/Acts/Utilities/BoundingBox.ipp +++ b/Core/include/Acts/Utilities/BoundingBox.ipp @@ -353,8 +353,7 @@ Acts::AxisAlignedBoundingBox::transformed( template void Acts::AxisAlignedBoundingBox::draw( - IVisualization3D& helper, std::array color, - const transform_type& trf) const + IVisualization3D& helper, Color color, const transform_type& trf) const requires(DIM == 3) { static_assert(DIM == 3, "PLY output only supported in 3D"); diff --git a/Core/include/Acts/Utilities/GraphViz.hpp b/Core/include/Acts/Utilities/GraphViz.hpp new file mode 100644 index 00000000000..2aeb75dba5f --- /dev/null +++ b/Core/include/Acts/Utilities/GraphViz.hpp @@ -0,0 +1,110 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2024 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include +#include + +namespace Acts::GraphViz { + +enum class Shape { + Box, + Polygon, + Ellipse, + Oval, + Circle, + Point, + Egg, + Triangle, + Plaintext, + Plain, + Diamond, + Trapezium, + Parallelogram, + House, + Pentagon, + Hexagon, + Septagon, + Octagon, + DoubleCircle, + DoubleOctagon, + TripleOctagon, + InvTriangle, + InvTrapezium, + InvHouse, + Mdiamond, + Msquare, + Mcircle, + Rect, + Rectangle, + Square, + Star, + None, + Underline, + Cylinder, + Note, + Tab, + Folder, + Box3d, + Component, + Promoter, + Cds, + Terminator, + Utr, + PrimerSite, + RestrictionSite, + FivePOverhang, + ThreePOverhang, + NOverhang, + Assembly, + Signature, + Insulator, + Ribosite, + RNAStab, + ProteaseSite, + ProteinStab, + RPromoter, + RArrow, + LArrow, + LPromoter +}; + +std::ostream& operator<<(std::ostream& os, const Shape& shape); + +enum class Style { + Filled, + Invisible, + Diagonals, + Rounded, + Dashed, + Dotted, + Solid, + Bold +}; + +std::ostream& operator<<(std::ostream& os, const Style& style); + +struct Node { + std::string id; + std::string label; + Shape shape = Shape::Ellipse; + std::vector