From 6709342a54da278364c8b8acb59aa3935147d0d9 Mon Sep 17 00:00:00 2001 From: Paul Gessinger Date: Sun, 13 Oct 2024 21:40:05 +0200 Subject: [PATCH 01/21] refactor: Python binding bits and pieces (#3717) This is a collection of python bindings bits that have accumulated. Related #3502. --- This pull request includes several updates to the `Acts` geometry and Python binding code. The most important changes involve the introduction of new enums and the addition of Python bindings for new geometry classes and methods. ### Geometry and Enum Updates: * Added `Face` enum to `CylinderVolumeBounds` to describe possible faces of a cylinder volume. (`Core/include/Acts/Geometry/CylinderVolumeBounds.hpp`) * Refactored `PortalShellBase` to use the `Face` enum from `CylinderVolumeBounds` instead of defining its own. (`Core/include/Acts/Geometry/PortalShell.hpp`) ### Python Bindings Enhancements: * Added new binning values to the `addBinning` function in `Base.cpp`. (`Examples/Python/src/Base.cpp`) * Extended `addGeometry` function to include new methods and enums for `CylinderVolumeBounds` and `ExtentEnvelope`. (`Examples/Python/src/Geometry.cpp`) [[1]](diffhunk://#diff-a103b5682fb7c6e7ea58777983e4381b62783b2facd3e367e03ff0a7aa49816dL181-R213) [[2]](diffhunk://#diff-a103b5682fb7c6e7ea58777983e4381b62783b2facd3e367e03ff0a7aa49816dL212-R303) * Introduced Python bindings for `CylinderVolumeStack` and its enums `AttachmentStrategy` and `ResizeStrategy`. (`Examples/Python/src/Geometry.cpp`) ### Code Cleanup: * Removed redundant includes and updated include paths to reflect new dependencies. (`Core/include/Acts/Geometry/PortalShell.hpp`, `Examples/Python/src/Geometry.cpp`) [[1]](diffhunk://#diff-80595cf723b4c4b0a2cf3de28ac0da38793f2955a2e0ce1dc4fd87381fac79aeL11-R11) [[2]](diffhunk://#diff-a103b5682fb7c6e7ea58777983e4381b62783b2facd3e367e03ff0a7aa49816dR40) [[3]](diffhunk://#diff-a103b5682fb7c6e7ea58777983e4381b62783b2facd3e367e03ff0a7aa49816dR51) These changes improve the modularity and functionality of the geometry components and enhance the Python interface for better usability. --- .../Acts/Geometry/CylinderVolumeBounds.hpp | 13 ++ Core/include/Acts/Geometry/PortalShell.hpp | 18 +-- Core/src/Geometry/PortalShell.cpp | 2 +- Examples/Python/src/Base.cpp | 12 +- Examples/Python/src/Geometry.cpp | 133 ++++++++++++++---- .../Core/Geometry/PortalShellTests.cpp | 14 +- 6 files changed, 139 insertions(+), 53 deletions(-) diff --git a/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp b/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp index c92e001fa9f..1951d96b2da 100644 --- a/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp +++ b/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp @@ -9,6 +9,7 @@ #pragma once #include "Acts/Definitions/Algebra.hpp" +#include "Acts/Geometry/BoundarySurfaceFace.hpp" #include "Acts/Geometry/Volume.hpp" #include "Acts/Geometry/VolumeBounds.hpp" #include "Acts/Utilities/BinningType.hpp" @@ -80,6 +81,18 @@ class CylinderVolumeBounds : public VolumeBounds { eSize }; + /// Enum describing the possible faces of a cylinder volume + /// @note These values are synchronized with the BoundarySurfaceFace enum. + /// Once Gen1 is removed, this can be changed. + enum class Face : unsigned int { + PositiveDisc = BoundarySurfaceFace::positiveFaceXY, + NegativeDisc = BoundarySurfaceFace::negativeFaceXY, + OuterCylinder = BoundarySurfaceFace::tubeOuterCover, + InnerCylinder = BoundarySurfaceFace::tubeInnerCover, + NegativePhiPlane = BoundarySurfaceFace::tubeSectorNegativePhi, + PositivePhiPlane = BoundarySurfaceFace::tubeSectorPositivePhi + }; + CylinderVolumeBounds() = delete; /// Constructor diff --git a/Core/include/Acts/Geometry/PortalShell.hpp b/Core/include/Acts/Geometry/PortalShell.hpp index 39e60b8774b..7405a64ad0a 100644 --- a/Core/include/Acts/Geometry/PortalShell.hpp +++ b/Core/include/Acts/Geometry/PortalShell.hpp @@ -8,7 +8,7 @@ #pragma once -#include "Acts/Geometry/BoundarySurfaceFace.hpp" +#include "Acts/Geometry/CylinderVolumeBounds.hpp" #include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Logger.hpp" @@ -68,19 +68,9 @@ class PortalShellBase { /// volumes class CylinderPortalShell : public PortalShellBase { public: - /// Enum describing the possible faces of a cylinder portal shell - /// @note These values are synchronized with the BoundarySurfaceFace enum. - /// Once Gen1 is removed, this can be changed. - enum class Face : unsigned int { - PositiveDisc = BoundarySurfaceFace::positiveFaceXY, - NegativeDisc = BoundarySurfaceFace::negativeFaceXY, - OuterCylinder = BoundarySurfaceFace::tubeOuterCover, - InnerCylinder = BoundarySurfaceFace::tubeInnerCover, - NegativePhiPlane = BoundarySurfaceFace::tubeSectorNegativePhi, - PositivePhiPlane = BoundarySurfaceFace::tubeSectorPositivePhi - }; - - using enum Face; + using Face = CylinderVolumeBounds::Face; + + using enum CylinderVolumeBounds::Face; /// Retrieve the portal associated to the given face. Can be nullptr if unset. /// @param face The face to retrieve the portal for diff --git a/Core/src/Geometry/PortalShell.cpp b/Core/src/Geometry/PortalShell.cpp index 59c83c1529f..b9baf403812 100644 --- a/Core/src/Geometry/PortalShell.cpp +++ b/Core/src/Geometry/PortalShell.cpp @@ -367,7 +367,7 @@ std::string CylinderStackPortalShell::label() const { std::ostream& operator<<(std::ostream& os, CylinderPortalShell::Face face) { switch (face) { - using enum CylinderPortalShell::Face; + using enum CylinderVolumeBounds::Face; case PositiveDisc: return os << "PositiveDisc"; case NegativeDisc: diff --git a/Examples/Python/src/Base.cpp b/Examples/Python/src/Base.cpp index 4d5eec557bd..cc8a5f67dc1 100644 --- a/Examples/Python/src/Base.cpp +++ b/Examples/Python/src/Base.cpp @@ -364,12 +364,16 @@ void addBinning(Context& ctx) { .value("binY", Acts::BinningValue::binY) .value("binZ", Acts::BinningValue::binZ) .value("binR", Acts::BinningValue::binR) - .value("binPhi", Acts::BinningValue::binPhi); + .value("binPhi", Acts::BinningValue::binPhi) + .value("binRPhi", Acts::BinningValue::binRPhi) + .value("binH", Acts::BinningValue::binH) + .value("binEta", Acts::BinningValue::binEta) + .value("binMag", Acts::BinningValue::binMag); auto boundaryType = py::enum_(m, "AxisBoundaryType") - .value("bound", Acts::AxisBoundaryType::Bound) - .value("closed", Acts::AxisBoundaryType::Closed) - .value("open", Acts::AxisBoundaryType::Open); + .value("Bound", Acts::AxisBoundaryType::Bound) + .value("Closed", Acts::AxisBoundaryType::Closed) + .value("Open", Acts::AxisBoundaryType::Open); auto axisType = py::enum_(m, "AxisType") .value("equidistant", Acts::AxisType::Equidistant) diff --git a/Examples/Python/src/Geometry.cpp b/Examples/Python/src/Geometry.cpp index 8ec8ed97ef1..d676dbe6243 100644 --- a/Examples/Python/src/Geometry.cpp +++ b/Examples/Python/src/Geometry.cpp @@ -25,6 +25,7 @@ #include "Acts/Detector/interface/IInternalStructureBuilder.hpp" #include "Acts/Detector/interface/IRootVolumeFinderBuilder.hpp" #include "Acts/Geometry/CylinderVolumeBounds.hpp" +#include "Acts/Geometry/CylinderVolumeStack.hpp" #include "Acts/Geometry/Extent.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/GeometryHierarchyMap.hpp" @@ -36,6 +37,7 @@ #include "Acts/Plugins/Python/Utilities.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Surfaces/SurfaceArray.hpp" +#include "Acts/Utilities/BinningType.hpp" #include "Acts/Utilities/Helpers.hpp" #include "Acts/Utilities/RangeXD.hpp" #include "Acts/Visualization/ViewConfig.hpp" @@ -46,6 +48,7 @@ #include #include +#include #include #include @@ -106,7 +109,12 @@ void addGeometry(Context& ctx) { .def("approach", &Acts::GeometryIdentifier::approach) .def("sensitive", &Acts::GeometryIdentifier::sensitive) .def("extra", &Acts::GeometryIdentifier::extra) - .def("value", &Acts::GeometryIdentifier::value); + .def("value", &Acts::GeometryIdentifier::value) + .def("__str__", [](const Acts::GeometryIdentifier& self) { + std::stringstream ss; + ss << self; + return ss.str(); + }); } { @@ -178,15 +186,31 @@ void addGeometry(Context& ctx) { { py::class_>( - m, "VolumeBounds"); - - py::class_, Acts::VolumeBounds>( - m, "CylinderVolumeBounds") - .def(py::init(), - "rmin"_a, "rmax"_a, "halfz"_a, "halfphi"_a = M_PI, "avgphi"_a = 0., - "bevelMinZ"_a = 0., "bevelMaxZ"_a = 0.); + m, "VolumeBounds") + .def("type", &Acts::VolumeBounds::type) + .def("__str__", [](const Acts::VolumeBounds& self) { + std::stringstream ss; + ss << self; + return ss.str(); + }); + + auto cvb = + py::class_, + Acts::VolumeBounds>(m, "CylinderVolumeBounds") + .def(py::init(), + "rmin"_a, "rmax"_a, "halfz"_a, "halfphi"_a = M_PI, + "avgphi"_a = 0., "bevelMinZ"_a = 0., "bevelMaxZ"_a = 0.); + + py::enum_(cvb, "Face") + .value("PositiveDisc", CylinderVolumeBounds::Face::PositiveDisc) + .value("NegativeDisc", CylinderVolumeBounds::Face::NegativeDisc) + .value("OuterCylinder", CylinderVolumeBounds::Face::OuterCylinder) + .value("InnerCylinder", CylinderVolumeBounds::Face::InnerCylinder) + .value("NegativePhiPlane", CylinderVolumeBounds::Face::NegativePhiPlane) + .value("PositivePhiPlane", + CylinderVolumeBounds::Face::PositivePhiPlane); } { @@ -209,22 +233,72 @@ void addGeometry(Context& ctx) { })); } + py::class_(m, "ExtentEnvelope") + .def(py::init<>()) + .def(py::init()) + .def(py::init([](Envelope x, Envelope y, Envelope z, Envelope r, + Envelope phi, Envelope rPhi, Envelope h, Envelope eta, + Envelope mag) { + return ExtentEnvelope({.x = x, + .y = y, + .z = z, + .r = r, + .phi = phi, + .rPhi = rPhi, + .h = h, + .eta = eta, + .mag = mag}); + }), + py::arg("x") = zeroEnvelope, py::arg("y") = zeroEnvelope, + py::arg("z") = zeroEnvelope, py::arg("r") = zeroEnvelope, + py::arg("phi") = zeroEnvelope, py::arg("rPhi") = zeroEnvelope, + py::arg("h") = zeroEnvelope, py::arg("eta") = zeroEnvelope, + py::arg("mag") = zeroEnvelope) + .def_static("Zero", &ExtentEnvelope::Zero) + .def("__getitem__", [](ExtentEnvelope& self, + BinningValue bValue) { return self[bValue]; }) + .def("__setitem__", [](ExtentEnvelope& self, BinningValue bValue, + const Envelope& value) { self[bValue] = value; }) + .def("__str__", [](const ExtentEnvelope& self) { + std::array values; + + std::stringstream ss; + for (BinningValue val : allBinningValues()) { + ss << val << "=(" << self[val][0] << ", " << self[val][1] << ")"; + values.at(toUnderlying(val)) = ss.str(); + ss.str(""); + } + + ss.str(""); + ss << "ExtentEnvelope("; + ss << boost::algorithm::join(values, ", "); + ss << ")"; + return ss.str(); + }); + + py::class_(m, "Extent") + .def(py::init(), + py::arg("envelope") = ExtentEnvelope::Zero()) + .def("range", + [](const Acts::Extent& self, + Acts::BinningValue bval) -> std::array { + return {self.min(bval), self.max(bval)}; + }) + .def("__str__", &Extent::toString); + { - py::class_(m, "Extent") - .def(py::init( - [](const std::vector>>& - franges) { - Acts::Extent extent; - for (const auto& [bval, frange] : franges) { - extent.set(bval, frange[0], frange[1]); - } - return extent; - })) - .def("range", [](const Acts::Extent& self, Acts::BinningValue bval) { - return std::array{self.min(bval), - self.max(bval)}; - }); + auto cylStack = py::class_(m, "CylinderVolumeStack"); + + py::enum_(cylStack, + "AttachmentStrategy") + .value("Gap", CylinderVolumeStack::AttachmentStrategy::Gap) + .value("First", CylinderVolumeStack::AttachmentStrategy::First) + .value("Second", CylinderVolumeStack::AttachmentStrategy::Second) + .value("Midpoint", CylinderVolumeStack::AttachmentStrategy::Midpoint); + + py::enum_(cylStack, "ResizeStrategy") + .value("Gap", CylinderVolumeStack::ResizeStrategy::Gap) + .value("Expand", CylinderVolumeStack::ResizeStrategy::Expand); } } @@ -307,10 +381,15 @@ void addExperimentalGeometry(Context& ctx) { // Be able to construct a proto binning py::class_(m, "ProtoBinning") .def(py::init&, std::size_t>()) + const std::vector&, std::size_t>(), + "bValue"_a, "bType"_a, "e"_a, "exp"_a = 0u) .def(py::init()); + std::size_t>(), + "bValue"_a, "bType"_a, "minE"_a, "maxE"_a, "nbins"_a, "exp"_a = 0u) + .def(py::init(), + "bValue"_a, "bType"_a, "nbins"_a, "exp"_a = 0u); } { diff --git a/Tests/UnitTests/Core/Geometry/PortalShellTests.cpp b/Tests/UnitTests/Core/Geometry/PortalShellTests.cpp index 4c44617524a..15c5a9c7953 100644 --- a/Tests/UnitTests/Core/Geometry/PortalShellTests.cpp +++ b/Tests/UnitTests/Core/Geometry/PortalShellTests.cpp @@ -68,7 +68,7 @@ BOOST_AUTO_TEST_CASE(ConstructionFromVolume) { SingleCylinderPortalShell shell1{cyl1}; BOOST_CHECK_EQUAL(shell1.size(), 4); - using enum CylinderPortalShell::Face; + using enum CylinderVolumeBounds::Face; const auto* pDisc = shell1.portal(PositiveDisc); BOOST_REQUIRE_NE(pDisc, nullptr); @@ -299,7 +299,7 @@ BOOST_AUTO_TEST_CASE(ConstructionFromVolume) { // inner cylinder BOOST_AUTO_TEST_CASE(PortalAssignment) { - using enum CylinderPortalShell::Face; + using enum CylinderVolumeBounds::Face; TrackingVolume vol( Transform3::Identity(), std::make_shared(30_mm, 100_mm, 100_mm)); @@ -350,7 +350,7 @@ BOOST_AUTO_TEST_CASE(PortalAssignment) { BOOST_AUTO_TEST_SUITE(CylinderStack) BOOST_AUTO_TEST_CASE(ZDirection) { - using enum CylinderPortalShell::Face; + using enum CylinderVolumeBounds::Face; BOOST_TEST_CONTEXT("rMin>0") { TrackingVolume vol1( Transform3{Translation3{Vector3::UnitZ() * -100_mm}}, @@ -447,7 +447,7 @@ BOOST_AUTO_TEST_CASE(ZDirection) { } BOOST_AUTO_TEST_CASE(RDirection) { - using enum CylinderPortalShell::Face; + using enum CylinderVolumeBounds::Face; BOOST_TEST_CONTEXT("rMin>0") { TrackingVolume vol1( Transform3::Identity(), @@ -610,7 +610,7 @@ BOOST_AUTO_TEST_CASE(NestedStacks) { gctx, {&stack, &shell3}, BinningValue::binZ, *logger}; BOOST_CHECK(stack2.isValid()); - using enum CylinderPortalShell::Face; + using enum CylinderVolumeBounds::Face; auto lookup = [](auto& shell, CylinderPortalShell::Face face, Vector3 position, @@ -726,7 +726,7 @@ BOOST_AUTO_TEST_CASE(ConnectOuter) { SingleCylinderPortalShell shell{cyl1}; - using enum CylinderPortalShell::Face; + using enum CylinderVolumeBounds::Face; BOOST_CHECK_EQUAL( shell.portal(OuterCylinder)->getLink(Direction::AlongNormal), nullptr); BOOST_CHECK_EQUAL( @@ -749,7 +749,7 @@ BOOST_AUTO_TEST_CASE(ConnectOuter) { } BOOST_AUTO_TEST_CASE(RegisterInto) { - using enum CylinderPortalShell::Face; + using enum CylinderVolumeBounds::Face; TrackingVolume vol1( Transform3::Identity(), std::make_shared(0_mm, 100_mm, 100_mm)); From a108ee92e518d413c3d1b2f1bd67e6ceb4ddef89 Mon Sep 17 00:00:00 2001 From: Andreas Salzburger Date: Mon, 14 Oct 2024 16:40:40 +0200 Subject: [PATCH 02/21] feat: adding dot graph possibility (#3730) This PR adds the option to create a dot graph from GeoModel in the Gen2 geometry, which will help debugging as long as Gen2 is alive and around. --- Core/src/Detector/detail/BlueprintDrawer.cpp | 41 +++++++++++-------- Examples/Python/src/GeoModel.cpp | 5 ++- .../GeoModel/GeoModelBlueprintCreater.hpp | 2 + .../GeoModel/src/GeoModelBlueprintCreater.cpp | 11 +++++ 4 files changed, 40 insertions(+), 19 deletions(-) diff --git a/Core/src/Detector/detail/BlueprintDrawer.cpp b/Core/src/Detector/detail/BlueprintDrawer.cpp index bc17c4c5922..b518266dc4d 100644 --- a/Core/src/Detector/detail/BlueprintDrawer.cpp +++ b/Core/src/Detector/detail/BlueprintDrawer.cpp @@ -57,28 +57,35 @@ std::string labelStr( void Acts::Experimental::detail::BlueprintDrawer::dotStream( std::ostream& ss, const Acts::Experimental::Blueprint::Node& node, const Options& options) { + // Replace the "/" in node names + std::string nodeName = node.name; + std::replace(nodeName.begin(), nodeName.end(), '/', '_'); + // Root / leaf or branch if (node.isRoot()) { ss << "digraph " << options.graphName << " {" << '\n'; - ss << node.name << " " << labelStr(options.root, node.name, node.auxiliary) + ss << nodeName << " " << labelStr(options.root, nodeName, node.auxiliary) << '\n'; - ss << node.name << " " << shapeStr(options.root) << '\n'; + ss << nodeName << " " << shapeStr(options.root) << '\n'; } else if (node.isLeaf()) { - ss << node.name << " " << labelStr(options.leaf, node.name, node.auxiliary) + ss << nodeName << " " << labelStr(options.leaf, nodeName, node.auxiliary) << '\n'; - ss << node.name << " " + ss << nodeName << " " << ((node.internalsBuilder != nullptr) ? shapeStr(options.leaf) : shapeStr(options.gap)) << '\n'; } else { - ss << node.name << " " - << labelStr(options.branch, node.name, node.auxiliary) << '\n'; - ss << node.name << " " << shapeStr(options.branch) << '\n'; + ss << nodeName << " " << labelStr(options.branch, nodeName, node.auxiliary) + << '\n'; + ss << nodeName << " " << shapeStr(options.branch) << '\n'; } // Recursive for children for (const auto& c : node.children) { - ss << node.name << " -> " << c->name << ";" << '\n'; + // Replace the "/" in node names + std::string childName = c->name; + std::replace(childName.begin(), childName.end(), '/', '_'); + ss << nodeName << " -> " << childName << ";" << '\n'; dotStream(ss, *c, options); } @@ -86,29 +93,29 @@ void Acts::Experimental::detail::BlueprintDrawer::dotStream( Options::Node shape = node.isLeaf() ? options.shape : options.virtualShape; std::stringstream bts; bts << node.boundsType; - ss << node.name + "_shape " << shapeStr(shape) << '\n'; - ss << node.name + "_shape " + ss << nodeName + "_shape " << shapeStr(shape) << '\n'; + ss << nodeName + "_shape " << labelStr(shape, bts.str(), {"t = " + toString(node.transform.translation(), 1), "b = " + toString(node.boundaryValues, 1)}) << '\n'; - ss << node.name << " -> " << node.name + "_shape [ arrowhead = \"none\" ];" + ss << nodeName << " -> " << nodeName + "_shape [ arrowhead = \"none\" ];" << '\n'; // Sub node detection if (node.internalsBuilder != nullptr) { - ss << node.name + "_int " << shapeStr(options.internals) << '\n'; - ss << node.name << " -> " << node.name + "_int;" << '\n'; + ss << nodeName + "_int " << shapeStr(options.internals) << '\n'; + ss << nodeName << " -> " << nodeName + "_int;" << '\n'; } if (node.geoIdGenerator != nullptr) { - ss << node.name + "_geoID " << shapeStr(options.geoID) << '\n'; - ss << node.name << " -> " << node.name + "_geoID;" << '\n'; + ss << nodeName + "_geoID " << shapeStr(options.geoID) << '\n'; + ss << nodeName << " -> " << nodeName + "_geoID;" << '\n'; } if (node.rootVolumeFinderBuilder != nullptr) { - ss << node.name + "_roots " << shapeStr(options.roots) << '\n'; - ss << node.name << " -> " << node.name + "_roots;" << '\n'; + ss << nodeName + "_roots " << shapeStr(options.roots) << '\n'; + ss << nodeName << " -> " << nodeName + "_roots;" << '\n'; } if (node.isRoot()) { diff --git a/Examples/Python/src/GeoModel.cpp b/Examples/Python/src/GeoModel.cpp index eb9b4406808..58609a573d5 100644 --- a/Examples/Python/src/GeoModel.cpp +++ b/Examples/Python/src/GeoModel.cpp @@ -192,8 +192,9 @@ void addGeoModel(Context& ctx) { .def_readwrite( "topBoundsOverride", &Acts::GeoModelBlueprintCreater::Options::topBoundsOverride) - .def_readwrite("table", - &Acts::GeoModelBlueprintCreater::Options::table); + .def_readwrite("table", &Acts::GeoModelBlueprintCreater::Options::table) + .def_readwrite("dotGraph", + &Acts::GeoModelBlueprintCreater::Options::dotGraph); } gm.def( diff --git a/Plugins/GeoModel/include/Acts/Plugins/GeoModel/GeoModelBlueprintCreater.hpp b/Plugins/GeoModel/include/Acts/Plugins/GeoModel/GeoModelBlueprintCreater.hpp index df895eb0741..c6358bdbec2 100644 --- a/Plugins/GeoModel/include/Acts/Plugins/GeoModel/GeoModelBlueprintCreater.hpp +++ b/Plugins/GeoModel/include/Acts/Plugins/GeoModel/GeoModelBlueprintCreater.hpp @@ -58,6 +58,8 @@ class GeoModelBlueprintCreater { std::string topEntry; /// Optionally override the top node bounds std::string topBoundsOverride = ""; + /// Export dot graph + std::string dotGraph = ""; }; /// The Blueprint return object diff --git a/Plugins/GeoModel/src/GeoModelBlueprintCreater.cpp b/Plugins/GeoModel/src/GeoModelBlueprintCreater.cpp index 93712d5d911..0b3d2f66e42 100644 --- a/Plugins/GeoModel/src/GeoModelBlueprintCreater.cpp +++ b/Plugins/GeoModel/src/GeoModelBlueprintCreater.cpp @@ -10,6 +10,7 @@ #include "Acts/Detector/GeometryIdGenerator.hpp" #include "Acts/Detector/LayerStructureBuilder.hpp" +#include "Acts/Detector/detail/BlueprintDrawer.hpp" #include "Acts/Detector/detail/BlueprintHelper.hpp" #include "Acts/Detector/interface/IGeometryIdGenerator.hpp" #include "Acts/Plugins/GeoModel/GeoModelTree.hpp" @@ -20,6 +21,8 @@ #include "Acts/Utilities/Helpers.hpp" #include "Acts/Utilities/RangeXD.hpp" +#include + #include using namespace Acts::detail; @@ -128,6 +131,14 @@ Acts::GeoModelBlueprintCreater::create(const GeometryContext& gctx, blueprint.topNode = createNode(cache, gctx, topEntry->second, blueprintTableMap, Extent()); + // Export to dot graph if configured + if (!options.dotGraph.empty()) { + std::ofstream dotFile(options.dotGraph); + Experimental::detail::BlueprintDrawer::dotStream(dotFile, + *blueprint.topNode); + dotFile.close(); + } + // Return the ready-to-use blueprint return blueprint; } From e3b33ccf43a02d41e59dd9e9b666f28b28d61b48 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Mon, 14 Oct 2024 19:08:00 +0200 Subject: [PATCH 03/21] refactor: Combine material, measurement and hole handling in Core CKF `filter` (#3723) Combines the handling of material, measurements and holes in the Core CKF. --- This pull request includes several changes to the `CombinatorialKalmanFilter` class in the `Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp` file to improve error handling, state management, and logging. Additionally, there is a minor change in the `MeasurementSelector` class to handle empty measurement candidates more gracefully. ### Error Handling and State Management: * Added checks and logging for empty active branches to ensure the filter stops correctly when no branches are active. (`Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp`) [[1]](diffhunk://#diff-55dd901875f5a87b6a9fee495de245296efbfd45aa9f9483036bcd299a277e09R583-R590) [[2]](diffhunk://#diff-55dd901875f5a87b6a9fee495de245296efbfd45aa9f9483036bcd299a277e09R660-R673) * Modified the filter to reset and stop properly when all branches are stopped or when certain conditions are met, improving the robustness of the filtering process. (`Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp`) [[1]](diffhunk://#diff-55dd901875f5a87b6a9fee495de245296efbfd45aa9f9483036bcd299a277e09L592-R600) [[2]](diffhunk://#diff-55dd901875f5a87b6a9fee495de245296efbfd45aa9f9483036bcd299a277e09L623-L642) ### Logging Improvements: * Enhanced logging to provide more detailed information about the state transitions and decisions made during the filtering process. (`Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp`) [[1]](diffhunk://#diff-55dd901875f5a87b6a9fee495de245296efbfd45aa9f9483036bcd299a277e09L716-R761) [[2]](diffhunk://#diff-55dd901875f5a87b6a9fee495de245296efbfd45aa9f9483036bcd299a277e09L749-L925) [[3]](diffhunk://#diff-55dd901875f5a87b6a9fee495de245296efbfd45aa9f9483036bcd299a277e09L950-R907) ### Code Simplification and Cleanup: * Simplified the handling of material and measurement surfaces by refactoring conditional checks and removing redundant code. (`Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp`) [[1]](diffhunk://#diff-55dd901875f5a87b6a9fee495de245296efbfd45aa9f9483036bcd299a277e09L716-R761) [[2]](diffhunk://#diff-55dd901875f5a87b6a9fee495de245296efbfd45aa9f9483036bcd299a277e09L749-L925) ### Minor Change in MeasurementSelector: * Updated the `MeasurementSelector::select` method to return a success result when no measurement candidates are found, instead of returning an error. (`Core/include/Acts/TrackFinding/MeasurementSelector.ipp`) --- .../CombinatorialKalmanFilter.hpp | 328 ++++++++---------- .../Acts/TrackFinding/MeasurementSelector.ipp | 17 +- 2 files changed, 149 insertions(+), 196 deletions(-) diff --git a/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp b/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp index afb74140b8d..05e236e1e29 100644 --- a/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp +++ b/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp @@ -34,6 +34,7 @@ #include #include #include +#include #include namespace Acts { @@ -579,8 +580,14 @@ class CombinatorialKalmanFilter { ACTS_ERROR("Error in filter: " << res.error()); result.lastError = res.error(); } + + if (result.finished) { + return; + } } + assert(!result.activeBranches.empty() && "No active branches"); + const bool isEndOfWorldReached = endOfWorldReached.checkAbort(state, stepper, navigator, logger()); const bool isVolumeConstraintReached = volumeConstraintAborter.checkAbort( @@ -589,9 +596,8 @@ class CombinatorialKalmanFilter { state, stepper, navigator, logger()); const bool isTargetReached = targetReached.checkAbort(state, stepper, navigator, logger()); - const bool allBranchesStopped = result.activeBranches.empty(); - if (isEndOfWorldReached || isPathLimitReached || isTargetReached || - allBranchesStopped || isVolumeConstraintReached) { + if (isEndOfWorldReached || isVolumeConstraintReached || + isPathLimitReached || isTargetReached) { if (isEndOfWorldReached) { ACTS_VERBOSE("End of world reached"); } else if (isVolumeConstraintReached) { @@ -620,26 +626,12 @@ class CombinatorialKalmanFilter { stepper.releaseStepSize(state.stepping, ConstrainedStep::actor); } - if (!allBranchesStopped) { - // Record the active branch and remove it from the list - storeLastActiveBranch(result); - result.activeBranches.pop_back(); - } else { - // This can happen if we stopped all branches in the filter step - ACTS_VERBOSE("All branches stopped"); - } + // Record the active branch and remove it from the list + storeLastActiveBranch(result); + result.activeBranches.pop_back(); - // If no more active branches, done with filtering; Otherwise, reset - // propagation state to track state at next active branch - if (!result.activeBranches.empty()) { - ACTS_VERBOSE("Propagation jumps to branch with tip = " - << result.activeBranches.back().tipIndex()); - reset(state, stepper, navigator, result); - } else { - ACTS_VERBOSE("Stop Kalman filtering with " - << result.collectedTracks.size() << " found tracks"); - result.finished = true; - } + // Reset propagation state to track state at next active branch + reset(state, stepper, navigator, result); } } @@ -665,9 +657,20 @@ class CombinatorialKalmanFilter { typename navigator_t> void reset(propagator_state_t& state, const stepper_t& stepper, const navigator_t& navigator, result_type& result) const { + if (result.activeBranches.empty()) { + ACTS_VERBOSE("Stop CKF with " << result.collectedTracks.size() + << " found tracks"); + result.finished = true; + + return; + } + auto currentBranch = result.activeBranches.back(); auto currentState = currentBranch.outermostTrackState(); + ACTS_VERBOSE("Propagation jumps to branch with tip = " + << currentBranch.tipIndex()); + // Reset the stepping state stepper.resetState(state.stepping, currentState.filtered(), currentState.filteredCovariance(), @@ -713,40 +716,67 @@ class CombinatorialKalmanFilter { using PM = TrackStatePropMask; bool isSensitive = surface->associatedDetectorElement() != nullptr; - bool isMaterial = surface->surfaceMaterial() != nullptr; - - std::size_t nBranchesOnSurface = 0; + bool hasMaterial = surface->surfaceMaterial() != nullptr; + bool isMaterialOnly = hasMaterial && !isSensitive; + bool expectMeasurements = isSensitive; - if (auto [slBegin, slEnd] = m_sourceLinkAccessor(*surface); - slBegin != slEnd) { - // Screen output message + if (isSensitive) { ACTS_VERBOSE("Measurement surface " << surface->geometryId() << " detected."); + } else if (isMaterialOnly) { + ACTS_VERBOSE("Material surface " << surface->geometryId() + << " detected."); + } else { + ACTS_VERBOSE("Passive surface " << surface->geometryId() + << " detected."); + return Result::success(); + } - // Transport the covariance to the surface + using SourceLinkRange = decltype(m_sourceLinkAccessor(*surface)); + std::optional slRange = std::nullopt; + bool hasMeasurements = false; + if (isSensitive) { + slRange = m_sourceLinkAccessor(*surface); + hasMeasurements = slRange->first != slRange->second; + } + bool isHole = isSensitive && !hasMeasurements; + + if (isHole) { + ACTS_VERBOSE("Detected hole before measurement selection on surface " + << surface->geometryId()); + } + + // Transport the covariance to the surface + if (isHole || isMaterialOnly) { + stepper.transportCovarianceToCurvilinear(state.stepping); + } else { stepper.transportCovarianceToBound(state.stepping, *surface); + } - // Update state and stepper with pre material effects - materialInteractor(surface, state, stepper, navigator, - MaterialUpdateStage::PreUpdate); + // Update state and stepper with pre material effects + materialInteractor(surface, state, stepper, navigator, + MaterialUpdateStage::PreUpdate); - // Bind the transported state to the current surface - auto boundStateRes = - stepper.boundState(state.stepping, *surface, false); - if (!boundStateRes.ok()) { - return boundStateRes.error(); - } - auto& boundState = *boundStateRes; - auto& [boundParams, jacobian, pathLength] = boundState; - boundParams.covariance() = state.stepping.cov; + // Bind the transported state to the current surface + auto boundStateRes = stepper.boundState(state.stepping, *surface, false); + if (!boundStateRes.ok()) { + return boundStateRes.error(); + } + auto& boundState = *boundStateRes; + auto& [boundParams, jacobian, pathLength] = boundState; + boundParams.covariance() = state.stepping.cov; + + auto currentBranch = result.activeBranches.back(); + TrackIndexType prevTip = currentBranch.tipIndex(); - auto currentBranch = result.activeBranches.back(); - TrackIndexType prevTip = currentBranch.tipIndex(); + // Create trackstates for all source links (will be filtered later) + using TrackStatesResult = + Acts::Result>; + TrackStatesResult tsRes = TrackStatesResult::success({}); + if (hasMeasurements) { + auto [slBegin, slEnd] = *slRange; - // Create trackstates for all source links (will be filtered later) - using TrackStatesResult = - Acts::Result>; - TrackStatesResult tsRes = trackStateCandidateCreator( + tsRes = trackStateCandidateCreator( state.geoContext, *calibrationContextPtr, *surface, boundState, slBegin, slEnd, prevTip, *result.trackStates, result.trackStateCandidates, *result.trackStates, logger()); @@ -755,175 +785,98 @@ class CombinatorialKalmanFilter { "Processing of selected track states failed: " << tsRes.error()); return tsRes.error(); } - const CkfTypes::BranchVector& newTrackStateList = - *tsRes; - - if (newTrackStateList.empty()) { - ACTS_VERBOSE("Detected hole after measurement selection on surface " - << surface->geometryId()); - - // Setting the number of branches on the surface to 1 as the hole - // still counts as a branch - nBranchesOnSurface = 1; - - auto stateMask = PM::Predicted | PM::Jacobian; - - // Add a hole track state to the multitrajectory - TrackIndexType currentTip = addNonSourcelinkState( - stateMask, boundState, result, true, prevTip); - auto nonSourcelinkState = - result.trackStates->getTrackState(currentTip); - currentBranch.tipIndex() = currentTip; - currentBranch.nHoles()++; + } + const CkfTypes::BranchVector& newTrackStateList = *tsRes; + + if (!newTrackStateList.empty()) { + Result procRes = + processNewTrackStates(state.geoContext, newTrackStateList, result); + if (!procRes.ok()) { + ACTS_ERROR("Processing of selected track states failed: " + << procRes.error()); + return procRes.error(); + } + unsigned int nBranchesOnSurface = *procRes; - BranchStopperResult branchStopperResult = - m_extensions.branchStopper(currentBranch, nonSourcelinkState); + if (nBranchesOnSurface == 0) { + ACTS_VERBOSE("All branches on surface " << surface->geometryId() + << " have been stopped"); - // Check the branch - if (branchStopperResult == BranchStopperResult::Continue) { - // Remembered the active branch and its state - } else { - // No branch on this surface - nBranchesOnSurface = 0; - if (branchStopperResult == BranchStopperResult::StopAndKeep) { - storeLastActiveBranch(result); - } - // Remove the branch from list - result.activeBranches.pop_back(); - } - } else { - Result procRes = processNewTrackStates( - state.geoContext, newTrackStateList, result); - if (!procRes.ok()) { - ACTS_ERROR("Processing of selected track states failed: " - << procRes.error()); - return procRes.error(); - } - nBranchesOnSurface = *procRes; + reset(state, stepper, navigator, result); - if (nBranchesOnSurface == 0) { - // All branches on the surface have been stopped. Reset happens at - // the end of the function - ACTS_VERBOSE("All branches on surface " << surface->geometryId() - << " have been stopped"); - } else { - // `currentBranch` is invalidated after `processNewTrackStates` - currentBranch = result.activeBranches.back(); - prevTip = currentBranch.tipIndex(); - - auto currentState = currentBranch.outermostTrackState(); - - if (currentState.typeFlags().test(TrackStateFlag::OutlierFlag)) { - // We don't need to update the stepper given an outlier state - ACTS_VERBOSE("Outlier state detected on surface " - << surface->geometryId()); - } else { - // If there are measurement track states on this surface - ACTS_VERBOSE("Filtering step successful with " - << nBranchesOnSurface << " branches"); - // Update stepping state using filtered parameters of last track - // state on this surface - stepper.update(state.stepping, - MultiTrajectoryHelpers::freeFiltered( - state.options.geoContext, currentState), - currentState.filtered(), - currentState.filteredCovariance(), *surface); - ACTS_VERBOSE( - "Stepping state is updated with filtered parameter:"); - ACTS_VERBOSE("-> " << currentState.filtered().transpose() - << " of track state with tip = " - << currentState.index()); - } - } + return Result::success(); } - // Update state and stepper with post material effects - materialInteractor(surface, state, stepper, navigator, - MaterialUpdateStage::PostUpdate); - } else if (isSensitive || isMaterial) { - ACTS_VERBOSE("Handle " << (isSensitive ? "sensitive" : "passive") - << " surface: " << surface->geometryId() - << " without measurements"); - - // No splitting on the surface without source links. Set it to one - // first, but could be changed later - nBranchesOnSurface = 1; - - auto currentBranch = result.activeBranches.back(); - TrackIndexType prevTip = currentBranch.tipIndex(); + // `currentBranch` is invalidated after `processNewTrackStates` + currentBranch = result.activeBranches.back(); + prevTip = currentBranch.tipIndex(); + } else { + if (expectMeasurements) { + ACTS_VERBOSE("Detected hole after measurement selection on surface " + << surface->geometryId()); + } - // No source links on surface, add either hole or passive material - // TrackState. No storage allocation for uncalibrated/calibrated - // measurement and filtered parameter auto stateMask = PM::Predicted | PM::Jacobian; - // Transport the covariance to a curvilinear surface - stepper.transportCovarianceToCurvilinear(state.stepping); - - // Update state and stepper with pre material effects - materialInteractor(surface, state, stepper, navigator, - MaterialUpdateStage::PreUpdate); - - // Transport & bind the state to the current surface - auto boundStateRes = - stepper.boundState(state.stepping, *surface, false); - if (!boundStateRes.ok()) { - return boundStateRes.error(); - } - auto& boundState = *boundStateRes; - auto& [boundParams, jacobian, pathLength] = boundState; - boundParams.covariance() = state.stepping.cov; - // Add a hole or material track state to the multitrajectory TrackIndexType currentTip = addNonSourcelinkState( - stateMask, boundState, result, isSensitive, prevTip); - auto nonSourcelinkState = result.trackStates->getTrackState(currentTip); + stateMask, boundState, result, expectMeasurements, prevTip); currentBranch.tipIndex() = currentTip; - - if (isSensitive) { + auto currentState = currentBranch.outermostTrackState(); + if (expectMeasurements) { currentBranch.nHoles()++; } BranchStopperResult branchStopperResult = - m_extensions.branchStopper(currentBranch, nonSourcelinkState); + m_extensions.branchStopper(currentBranch, currentState); // Check the branch if (branchStopperResult == BranchStopperResult::Continue) { // Remembered the active branch and its state } else { // No branch on this surface - nBranchesOnSurface = 0; if (branchStopperResult == BranchStopperResult::StopAndKeep) { storeLastActiveBranch(result); } // Remove the branch from list result.activeBranches.pop_back(); - } - // Update state and stepper with post material effects - materialInteractor(surface, state, stepper, navigator, - MaterialUpdateStage::PostUpdate); - } else { - // Neither measurement nor material on surface, this branch is still - // valid. Count the branch on current surface - nBranchesOnSurface = 1; - } + // Branch on the surface has been stopped - reset + ACTS_VERBOSE("Branch on surface " << surface->geometryId() + << " has been stopped"); - // Reset current branch if there is no branch on current surface - if (nBranchesOnSurface == 0) { - ACTS_DEBUG("Branch on surface " << surface->geometryId() - << " is stopped"); - if (!result.activeBranches.empty()) { - ACTS_VERBOSE("Propagation jumps to branch with tip = " - << result.activeBranches.back().tipIndex()); reset(state, stepper, navigator, result); - } else { - ACTS_VERBOSE("Stop Kalman filtering with " - << result.collectedTracks.size() << " found tracks"); - result.finished = true; + + return Result::success(); } } + auto currentState = currentBranch.outermostTrackState(); + + if (currentState.typeFlags().test(TrackStateFlag::OutlierFlag)) { + // We don't need to update the stepper given an outlier state + ACTS_VERBOSE("Outlier state detected on surface " + << surface->geometryId()); + } else if (currentState.typeFlags().test( + TrackStateFlag::MeasurementFlag)) { + // If there are measurement track states on this surface + // Update stepping state using filtered parameters of last track + // state on this surface + stepper.update(state.stepping, + MultiTrajectoryHelpers::freeFiltered( + state.options.geoContext, currentState), + currentState.filtered(), + currentState.filteredCovariance(), *surface); + ACTS_VERBOSE("Stepping state is updated with filtered parameter:"); + ACTS_VERBOSE("-> " << currentState.filtered().transpose() + << " of track state with tip = " + << currentState.index()); + } + + // Update state and stepper with post material effects + materialInteractor(surface, state, stepper, navigator, + MaterialUpdateStage::PostUpdate); + return Result::success(); } @@ -947,12 +900,13 @@ class CombinatorialKalmanFilter { auto rootBranch = result.activeBranches.back(); - // Build the new branches by forking the root branch. Reverse the order to - // process the best candidate first + // Build the new branches by forking the root branch. Reverse the order + // to process the best candidate first CkfTypes::BranchVector newBranches; for (auto it = newTrackStateList.rbegin(); it != newTrackStateList.rend(); ++it) { - // Keep the root branch as the first branch, make a copy for the others + // Keep the root branch as the first branch, make a copy for the + // others auto newBranch = (it == newTrackStateList.rbegin()) ? rootBranch : rootBranch.shallowCopy(); diff --git a/Core/include/Acts/TrackFinding/MeasurementSelector.ipp b/Core/include/Acts/TrackFinding/MeasurementSelector.ipp index 3e32c884585..30d09c002be 100644 --- a/Core/include/Acts/TrackFinding/MeasurementSelector.ipp +++ b/Core/include/Acts/TrackFinding/MeasurementSelector.ipp @@ -21,9 +21,9 @@ MeasurementSelector::select( ACTS_VERBOSE("Invoked MeasurementSelector"); - // Return error if no measurement + // Return if no measurement if (candidates.empty()) { - return CombinatorialKalmanFilterError::MeasurementSelectionFailed; + return Result::success(std::pair(candidates.begin(), candidates.end())); } // Get geoID of this surface @@ -92,20 +92,19 @@ MeasurementSelector::select( "No measurement candidate. Return an outlier measurement chi2=" << minChi2); isOutlier = true; - return Result::success(std::make_pair(candidates.begin() + minIndex, - candidates.begin() + minIndex + 1)); + return Result::success(std::pair(candidates.begin() + minIndex, + candidates.begin() + minIndex + 1)); } else { ACTS_VERBOSE("No measurement candidate. Return empty chi2=" << minChi2); - return Result::success( - std::make_pair(candidates.begin(), candidates.begin())); + return Result::success(std::pair(candidates.begin(), candidates.begin())); } } if (passedCandidates <= 1ul) { // return single item range, no sorting necessary ACTS_VERBOSE("Returning only 1 element chi2=" << minChi2); - return Result::success(std::make_pair(candidates.begin() + minIndex, - candidates.begin() + minIndex + 1)); + return Result::success(std::pair(candidates.begin() + minIndex, + candidates.begin() + minIndex + 1)); } std::sort( @@ -115,7 +114,7 @@ MeasurementSelector::select( ACTS_VERBOSE("Number of selected measurements: " << passedCandidates << ", max: " << cuts.numMeasurements); - return Result::success(std::make_pair( + return Result::success(std::pair( candidates.begin(), candidates.begin() + std::min(cuts.numMeasurements, passedCandidates))); } From fb3ddf48fdcf2bc08052e0a925a0c0531fa056f8 Mon Sep 17 00:00:00 2001 From: Carlo Varni <75478407+CarloVarni@users.noreply.github.com> Date: Tue, 15 Oct 2024 10:31:05 +0200 Subject: [PATCH 04/21] refactor: Add some requirements (#3720) Add some concept in order to request specific requirements on objects/functions used by the seeding --- Core/include/Acts/Seeding/SeedFinder.hpp | 39 +++++++++++++------ Core/include/Acts/Seeding/SeedFinder.ipp | 4 +- .../detail/CylindricalSpacePointGrid.hpp | 30 +++++++++++++- .../detail/CylindricalSpacePointGrid.ipp | 14 +++++++ .../Acts/Seeding/detail/UtilityFunctions.hpp | 17 +++++--- .../TrackFinding/src/SeedingAlgorithm.cpp | 5 +-- 6 files changed, 86 insertions(+), 23 deletions(-) diff --git a/Core/include/Acts/Seeding/SeedFinder.hpp b/Core/include/Acts/Seeding/SeedFinder.hpp index 120610b36a1..cfe9908574c 100644 --- a/Core/include/Acts/Seeding/SeedFinder.hpp +++ b/Core/include/Acts/Seeding/SeedFinder.hpp @@ -17,12 +17,14 @@ #include "Acts/Seeding/SeedFinderConfig.hpp" #include "Acts/Seeding/SeedFinderUtils.hpp" #include "Acts/Seeding/SpacePointGrid.hpp" +#include "Acts/Seeding/detail/UtilityFunctions.hpp" #include #include #include #include #include +#include #include #include #include @@ -30,6 +32,17 @@ namespace Acts { +template +concept GridBinCollection = + std::ranges::random_access_range && + std::same_as; + +template +concept CollectionStoresSeedsTo = requires(Coll coll, external_t sp) { + Acts::detail::pushBackOrInsertAtEnd(coll, + Acts::Seed(sp, sp, sp)); +}; + enum class SpacePointCandidateType : short { eBottom, eTop }; enum class DetectorMeasurementInfo : short { eDefault, eDetailed }; @@ -44,32 +57,32 @@ class SeedFinder { public: struct SeedingState { // bottom space point - std::vector compatBottomSP; - std::vector compatTopSP; + std::vector compatBottomSP{}; + std::vector compatTopSP{}; // contains parameters required to calculate circle with linear equation // ...for bottom-middle - std::vector linCircleBottom; + std::vector linCircleBottom{}; // ...for middle-top - std::vector linCircleTop; + std::vector linCircleTop{}; // create vectors here to avoid reallocation in each loop - std::vector topSpVec; - std::vector curvatures; - std::vector impactParameters; + std::vector topSpVec{}; + std::vector curvatures{}; + std::vector impactParameters{}; // managing seed candidates for SpM - CandidatesForMiddleSp candidates_collector; + CandidatesForMiddleSp candidates_collector{}; // managing doublet candidates boost::container::small_vector, Acts::detail::ipow(3, grid_t::DIM)> - bottomNeighbours; + bottomNeighbours{}; boost::container::small_vector, Acts::detail::ipow(3, grid_t::DIM)> - topNeighbours; + topNeighbours{}; // Mutable variables for Space points used in the seeding - Acts::SpacePointMutableData spacePointMutableData; + Acts::SpacePointMutableData spacePointMutableData{}; }; /// The only constructor. Requires a config object. @@ -97,7 +110,9 @@ class SeedFinder { /// @param rMiddleSPRange range object containing the minimum and maximum r for middle SP for a certain z bin. /// @note Ranges must return pointers. /// @note Ranges must be separate objects for each parallel call. - template + template + requires Acts::CollectionStoresSeedsTo void createSeedsForGroup(const Acts::SeedFinderOptions& options, SeedingState& state, const grid_t& grid, container_t& outputCollection, diff --git a/Core/include/Acts/Seeding/SeedFinder.ipp b/Core/include/Acts/Seeding/SeedFinder.ipp index f05e14fa0fb..2896fba925f 100644 --- a/Core/include/Acts/Seeding/SeedFinder.ipp +++ b/Core/include/Acts/Seeding/SeedFinder.ipp @@ -36,7 +36,9 @@ SeedFinder::SeedFinder( } template -template +template + requires Acts::CollectionStoresSeedsTo void SeedFinder::createSeedsForGroup( const Acts::SeedFinderOptions& options, SeedingState& state, const grid_t& grid, container_t& outputCollection, diff --git a/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.hpp b/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.hpp index 7b020010771..4410f1c125b 100644 --- a/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.hpp +++ b/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.hpp @@ -17,9 +17,18 @@ namespace Acts { +/// Concept to check the provided external space point type +/// can be used to fill the space point grid +template +concept CylindricalGridElement = requires(external_spacepoint_t sp) { + { sp.phi() } -> std::same_as; + { sp.z() } -> std::same_as; + { sp.radius() } -> std::same_as; +}; + /// Cylindrical Space Point bin is a 2D grid with (phi, z) bins /// It stores a vector of internal space points to external space points -template +template using CylindricalSpacePointGrid = Acts::Grid< std::vector, Acts::Axis, @@ -90,6 +99,13 @@ struct CylindricalSpacePointGridConfig { config.zMin /= 1_mm; config.deltaRMax /= 1_mm; + for (float& val : config.zBinEdges) { + val /= 1_mm; + } + for (float& val : config.rBinEdges) { + val /= 1_mm; + } + if (config.phiMin < -std::numbers::pi_v || config.phiMax > std::numbers::pi_v) { throw std::runtime_error( @@ -119,7 +135,7 @@ struct CylindricalSpacePointGridConfig { struct CylindricalSpacePointGridOptions { // magnetic field - float bFieldInZ = 0.; + float bFieldInZ = 0. * Acts::UnitConstants::T; bool isInInternalUnits = false; CylindricalSpacePointGridOptions toInternalUnits() const { if (isInInternalUnits) { @@ -152,6 +168,16 @@ class CylindricalSpacePointGridCreator { Acts::CylindricalSpacePointGrid& grid, external_spacepoint_iterator_t spBegin, external_spacepoint_iterator_t spEnd); + + template + requires std::ranges::range && + std::same_as + static void fillGrid( + const Acts::SeedFinderConfig& config, + const Acts::SeedFinderOptions& options, + Acts::CylindricalSpacePointGrid& grid, + const external_collection_t& collection); }; } // namespace Acts diff --git a/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp b/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp index 062aa7595ef..523d470eae5 100644 --- a/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp +++ b/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp @@ -214,3 +214,17 @@ void Acts::CylindricalSpacePointGridCreator::fillGrid( std::ranges::sort(rbin, {}, [](const auto& rb) { return rb->radius(); }); } } + +template + requires std::ranges::range && + std::same_as +void Acts::CylindricalSpacePointGridCreator::fillGrid( + const Acts::SeedFinderConfig& config, + const Acts::SeedFinderOptions& options, + Acts::CylindricalSpacePointGrid& grid, + const external_collection_t& collection) { + Acts::CylindricalSpacePointGridCreator::fillGrid( + config, options, grid, std::ranges::begin(collection), + std::ranges::end(collection)); +} diff --git a/Core/include/Acts/Seeding/detail/UtilityFunctions.hpp b/Core/include/Acts/Seeding/detail/UtilityFunctions.hpp index 369906d7f46..9cc61c4fe3f 100644 --- a/Core/include/Acts/Seeding/detail/UtilityFunctions.hpp +++ b/Core/include/Acts/Seeding/detail/UtilityFunctions.hpp @@ -30,16 +30,23 @@ concept isCollectionThatSupportsInsert = }; // Define some functions -template -void pushBackOrInsertAtEnd( - Acts::detail::isCollectionThatSupportsPushBack auto& storage, - value_t&& value) { +template + requires requires(storage_t coll, value_t value) { + coll.push_back(value); + coll.push_back(std::move(value)); + } +void pushBackOrInsertAtEnd(storage_t& storage, value_t&& value) { storage.push_back(std::forward(value)); } template requires(!Acts::detail::isCollectionThatSupportsPushBack && - Acts::detail::isCollectionThatSupportsInsert) + Acts::detail::isCollectionThatSupportsInsert && + requires(storage_t coll, value_t value) { + coll.insert(std::ranges::end(coll), value); + coll.insert(std::ranges::end(coll), std::move(value)); + }) void pushBackOrInsertAtEnd(storage_t& storage, value_t&& value) { storage.insert(std::ranges::end(storage), std::forward(value)); } diff --git a/Examples/Algorithms/TrackFinding/src/SeedingAlgorithm.cpp b/Examples/Algorithms/TrackFinding/src/SeedingAlgorithm.cpp index d8bd6265f27..ed5b11e4df2 100644 --- a/Examples/Algorithms/TrackFinding/src/SeedingAlgorithm.cpp +++ b/Examples/Algorithms/TrackFinding/src/SeedingAlgorithm.cpp @@ -246,9 +246,8 @@ ActsExamples::ProcessCode ActsExamples::SeedingAlgorithm::execute( Acts::CylindricalSpacePointGridCreator::createGrid( m_cfg.gridConfig, m_cfg.gridOptions); - Acts::CylindricalSpacePointGridCreator::fillGrid( - m_cfg.seedFinderConfig, m_cfg.seedFinderOptions, grid, - spContainer.begin(), spContainer.end()); + Acts::CylindricalSpacePointGridCreator::fillGrid( + m_cfg.seedFinderConfig, m_cfg.seedFinderOptions, grid, spContainer); // Compute radius Range // we rely on the fact the grid is storing the proxies From dd49200b5a8c704849cd63b8cfc93bd5f0cdb8f2 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Tue, 15 Oct 2024 13:42:52 +0200 Subject: [PATCH 05/21] refactor: Integrate source link container into measurements container in Examples (#3732) The source link container seems not to carry any additional information compared to the measurement container. The only important difference between them is that the source link container is sorted by geometry. I integrated a sorted container into the measurement container, even though this might not be strictly necessary it plays nicer with the existing functionality of accessing such a sorted container. --- .../Alignment/AlignmentAlgorithm.hpp | 5 -- .../Alignment/src/AlignmentAlgorithm.cpp | 19 ++---- .../Digitization/DigitizationAlgorithm.hpp | 3 - .../Digitization/DigitizationConfig.hpp | 2 - .../Digitization/MeasurementCreation.hpp | 10 +-- .../src/DigitizationAlgorithm.cpp | 17 +---- .../Digitization/src/MeasurementCreation.cpp | 9 ++- .../TrackFinding/GbtsSeedingAlgorithm.hpp | 5 -- .../TrackFinding/HoughTransformSeeder.hpp | 6 -- .../TrackFinding/SpacePointMaker.hpp | 6 -- .../TrackFinding/TrackFindingAlgorithm.hpp | 61 +---------------- .../TrackFinding/src/GbtsSeedingAlgorithm.cpp | 2 - .../TrackFinding/src/HoughTransformSeeder.cpp | 10 +-- .../TrackFinding/src/SpacePointMaker.cpp | 8 +-- .../src/TrackFindingAlgorithm.cpp | 60 +++++++++++++++-- .../TrackFindingFromPrototrackAlgorithm.hpp | 6 -- .../TrackFindingFromPrototrackAlgorithm.cpp | 10 +-- .../TrackFitting/TrackFittingAlgorithm.hpp | 2 - .../src/TrackFittingAlgorithm.cpp | 8 ++- .../Utilities/MeasurementMapSelector.hpp | 22 +++---- .../Utilities/src/PrototracksToTracks.cpp | 18 ++--- .../src/TrajectoriesToPrototracks.cpp | 2 +- .../EventData/IndexSourceLink.hpp | 6 +- .../ActsExamples/EventData/Measurement.hpp | 65 ++++++++++--------- .../EventData/MeasurementConcept.hpp | 3 +- .../Framework/src/EventData/Measurement.cpp | 26 ++++++-- .../Io/Csv/CsvMeasurementReader.hpp | 7 -- Examples/Io/Csv/src/CsvMeasurementReader.cpp | 15 +---- Examples/Io/Csv/src/CsvMeasurementWriter.cpp | 4 +- Examples/Io/Csv/src/CsvTrackWriter.cpp | 4 -- .../Io/EDM4hep/EDM4hepMeasurementReader.hpp | 5 -- .../EDM4hep/src/EDM4hepMeasurementReader.cpp | 3 - Examples/Io/EDM4hep/src/EDM4hepUtil.cpp | 8 +-- Examples/Io/Root/src/RootAthenaDumpReader.cpp | 17 ++--- .../Io/Root/src/RootMeasurementWriter.cpp | 4 +- .../Io/Root/src/RootTrackStatesWriter.cpp | 2 - .../python/acts/examples/reconstruction.py | 5 -- .../Python/python/acts/examples/simulation.py | 1 - Examples/Python/src/Digitization.cpp | 1 - Examples/Python/src/EDM4hepComponent.cpp | 2 +- Examples/Python/src/ExaTrkXTrackFinding.cpp | 5 +- Examples/Python/src/Input.cpp | 4 +- Examples/Python/src/TrackFinding.cpp | 18 +++-- Examples/Python/src/Utilities.cpp | 2 +- Examples/Python/tests/test_reader.py | 6 +- .../CommonHelpers/WhiteBoardUtilities.hpp | 2 + .../Examples/EventData/MeasurementTests.cpp | 33 ++++------ .../Io/Csv/MeasurementReaderWriterTests.cpp | 22 +++---- 48 files changed, 215 insertions(+), 346 deletions(-) diff --git a/Examples/Algorithms/Alignment/include/ActsExamples/Alignment/AlignmentAlgorithm.hpp b/Examples/Algorithms/Alignment/include/ActsExamples/Alignment/AlignmentAlgorithm.hpp index fe3442b1a29..db5833e5549 100644 --- a/Examples/Algorithms/Alignment/include/ActsExamples/Alignment/AlignmentAlgorithm.hpp +++ b/Examples/Algorithms/Alignment/include/ActsExamples/Alignment/AlignmentAlgorithm.hpp @@ -11,7 +11,6 @@ #include "Acts/Geometry/GeometryHierarchyMap.hpp" #include "Acts/TrackFitting/KalmanFitter.hpp" #include "ActsAlignment/Kernel/Alignment.hpp" -#include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/Measurement.hpp" #include "ActsExamples/EventData/ProtoTrack.hpp" #include "ActsExamples/EventData/Track.hpp" @@ -88,8 +87,6 @@ class AlignmentAlgorithm final : public IAlgorithm { struct Config { /// Input measurements collection. std::string inputMeasurements; - /// Input source links collection. - std::string inputSourceLinks; /// Input proto tracks collection, i.e. groups of hit indices. std::string inputProtoTracks; /// Input initial track parameter estimates for for each proto track. @@ -133,8 +130,6 @@ class AlignmentAlgorithm final : public IAlgorithm { ReadDataHandle m_inputMeasurements{this, "InputMeasurements"}; - ReadDataHandle m_inputSourceLinks{ - this, "InputSourceLinks"}; ReadDataHandle m_inputInitialTrackParameters{ this, "InputInitialTrackParameters"}; ReadDataHandle m_inputProtoTracks{this, diff --git a/Examples/Algorithms/Alignment/src/AlignmentAlgorithm.cpp b/Examples/Algorithms/Alignment/src/AlignmentAlgorithm.cpp index aa685217f05..2f1f450e23c 100644 --- a/Examples/Algorithms/Alignment/src/AlignmentAlgorithm.cpp +++ b/Examples/Algorithms/Alignment/src/AlignmentAlgorithm.cpp @@ -11,6 +11,7 @@ #include "Acts/Surfaces/PerigeeSurface.hpp" #include "Acts/TrackFitting/GainMatrixSmoother.hpp" #include "Acts/TrackFitting/GainMatrixUpdater.hpp" +#include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/MeasurementCalibration.hpp" #include "ActsExamples/EventData/ProtoTrack.hpp" #include "ActsExamples/EventData/Trajectories.hpp" @@ -23,9 +24,6 @@ ActsExamples::AlignmentAlgorithm::AlignmentAlgorithm(Config cfg, if (m_cfg.inputMeasurements.empty()) { throw std::invalid_argument("Missing input measurement collection"); } - if (m_cfg.inputSourceLinks.empty()) { - throw std::invalid_argument("Missing input source links collection"); - } if (m_cfg.inputProtoTracks.empty()) { throw std::invalid_argument("Missing input proto tracks collection"); } @@ -39,7 +37,6 @@ ActsExamples::AlignmentAlgorithm::AlignmentAlgorithm(Config cfg, } m_inputMeasurements.initialize(m_cfg.inputMeasurements); - m_inputSourceLinks.initialize(m_cfg.inputSourceLinks); m_inputProtoTracks.initialize(m_cfg.inputProtoTracks); m_inputInitialTrackParameters.initialize(m_cfg.inputInitialTrackParameters); m_outputAlignmentParameters.initialize(m_cfg.outputAlignmentParameters); @@ -49,7 +46,6 @@ ActsExamples::ProcessCode ActsExamples::AlignmentAlgorithm::execute( const ActsExamples::AlgorithmContext& ctx) const { // Read input data const auto& measurements = m_inputMeasurements(ctx); - const auto& sourceLinks = m_inputSourceLinks(ctx); const auto& protoTracks = m_inputProtoTracks(ctx); const auto& initialParameters = m_inputInitialTrackParameters(ctx); @@ -79,14 +75,11 @@ ActsExamples::ProcessCode ActsExamples::AlignmentAlgorithm::execute( trackSourceLinks.reserve(protoTrack.size()); // Fill the source links via their indices from the container - for (auto hitIndex : protoTrack) { - auto sourceLink = sourceLinks.nth(hitIndex); - if (sourceLink == sourceLinks.end()) { - ACTS_FATAL("Proto track " << itrack << " contains invalid hit index" - << hitIndex); - return ProcessCode::ABORT; - } - trackSourceLinks.push_back(*sourceLink); + for (auto measIndex : protoTrack) { + const ConstVariableBoundMeasurementProxy measurement = + measurements.getMeasurement(measIndex); + IndexSourceLink sourceLink(measurement.geometryId(), measIndex); + trackSourceLinks.push_back(sourceLink); } sourceLinkTrackContainer.push_back(trackSourceLinks); } diff --git a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationAlgorithm.hpp b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationAlgorithm.hpp index 560fcc9b3e5..fd8937bd300 100644 --- a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationAlgorithm.hpp +++ b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationAlgorithm.hpp @@ -18,7 +18,6 @@ #include "ActsExamples/Digitization/SmearingConfig.hpp" #include "ActsExamples/EventData/Cluster.hpp" #include "ActsExamples/EventData/Index.hpp" -#include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/Measurement.hpp" #include "ActsExamples/EventData/SimHit.hpp" #include "ActsExamples/Framework/DataHandle.hpp" @@ -102,8 +101,6 @@ class DigitizationAlgorithm final : public IAlgorithm { ReadDataHandle m_simContainerReadHandle{this, "SimHitContainer"}; - WriteDataHandle m_sourceLinkWriteHandle{ - this, "SourceLinks"}; WriteDataHandle m_measurementWriteHandle{ this, "Measurements"}; WriteDataHandle m_cellsWriteHandle{this, "Cells"}; diff --git a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationConfig.hpp b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationConfig.hpp index 941d01ae494..3521d0bef7d 100644 --- a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationConfig.hpp +++ b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationConfig.hpp @@ -135,8 +135,6 @@ class DigitizationConfig { /// Input collection of simulated hits. std::string inputSimHits = "simhits"; - /// Output source links collection. - std::string outputSourceLinks = "sourcelinks"; /// Output measurements collection. std::string outputMeasurements = "measurements"; /// Output cells map (geoID -> collection of cells). diff --git a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/MeasurementCreation.hpp b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/MeasurementCreation.hpp index b2c76a9820e..667e0c9f4c3 100644 --- a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/MeasurementCreation.hpp +++ b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/MeasurementCreation.hpp @@ -10,8 +10,8 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/TrackParametrization.hpp" +#include "Acts/Geometry/GeometryIdentifier.hpp" #include "ActsExamples/EventData/Cluster.hpp" -#include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/Measurement.hpp" #include @@ -20,7 +20,6 @@ #include namespace ActsExamples { -class IndexSourceLink; /// Struct to identify digitized parameters /// @@ -35,15 +34,16 @@ struct DigitizedParameters { /// Helper method for created a measurement from digitized parameters /// +/// @param container The measurement container to insert into +/// @param geometryId The geometry ID of the measurement surface /// @param dParams The digitized parameters of variable size -/// @param isl The indexed source link for the measurement /// /// To be used also by the e I/O system /// /// @return the measurement proxy ActsExamples::VariableBoundMeasurementProxy createMeasurement( - MeasurementContainer& container, const DigitizedParameters& dParams, - const IndexSourceLink& isl) noexcept(false); + MeasurementContainer& container, Acts::GeometryIdentifier geometryId, + const DigitizedParameters& dParams) noexcept(false); /// Construct the constituents of a measurement. /// diff --git a/Examples/Algorithms/Digitization/src/DigitizationAlgorithm.cpp b/Examples/Algorithms/Digitization/src/DigitizationAlgorithm.cpp index d6babfe24d0..72f3905ab57 100644 --- a/Examples/Algorithms/Digitization/src/DigitizationAlgorithm.cpp +++ b/Examples/Algorithms/Digitization/src/DigitizationAlgorithm.cpp @@ -18,7 +18,6 @@ #include "ActsExamples/Digitization/ModuleClusters.hpp" #include "ActsExamples/EventData/GeometryContainers.hpp" #include "ActsExamples/EventData/Index.hpp" -#include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/SimHit.hpp" #include "ActsExamples/Framework/AlgorithmContext.hpp" #include "ActsExamples/Utilities/GroupBy.hpp" @@ -55,9 +54,6 @@ ActsExamples::DigitizationAlgorithm::DigitizationAlgorithm( } if (m_cfg.doClusterization) { - if (m_cfg.outputSourceLinks.empty()) { - throw std::invalid_argument("Missing source links output collection"); - } if (m_cfg.outputMeasurements.empty()) { throw std::invalid_argument("Missing measurements output collection"); } @@ -73,7 +69,6 @@ ActsExamples::DigitizationAlgorithm::DigitizationAlgorithm( "Missing hit-to-simulated-hits map output collection"); } - m_sourceLinkWriteHandle.initialize(m_cfg.outputSourceLinks); m_measurementWriteHandle.initialize(m_cfg.outputMeasurements); m_clusterWriteHandle.initialize(m_cfg.outputClusters); m_measurementParticlesMapWriteHandle.initialize( @@ -152,12 +147,10 @@ ActsExamples::ProcessCode ActsExamples::DigitizationAlgorithm::execute( // Prepare output containers // need list here for stable addresses - IndexSourceLinkContainer sourceLinks; MeasurementContainer measurements; ClusterContainer clusters; IndexMultimap measurementParticlesMap; IndexMultimap measurementSimHitsMap; - sourceLinks.reserve(simHits.size()); measurements.reserve(simHits.size()); measurementParticlesMap.reserve(simHits.size()); measurementSimHitsMap.reserve(simHits.size()); @@ -292,15 +285,8 @@ ActsExamples::ProcessCode ActsExamples::DigitizationAlgorithm::execute( // The measurement container is unordered and the index under // which the measurement will be stored is known before adding it. Index measurementIdx = measurements.size(); - IndexSourceLink sourceLink{moduleGeoId, measurementIdx}; - - // Add to output containers: - // index map and source link container are geometry-ordered. - // since the input is also geometry-ordered, new items can - // be added at the end. - sourceLinks.insert(sourceLinks.end(), sourceLink); - createMeasurement(measurements, dParameters, sourceLink); + createMeasurement(measurements, moduleGeoId, dParameters); clusters.emplace_back(std::move(dParameters.cluster)); // this digitization does hit merging so there can be more than // one mapping entry for each digitized hit. @@ -328,7 +314,6 @@ ActsExamples::ProcessCode ActsExamples::DigitizationAlgorithm::execute( } if (m_cfg.doClusterization) { - m_sourceLinkWriteHandle(ctx, std::move(sourceLinks)); m_measurementWriteHandle(ctx, std::move(measurements)); m_clusterWriteHandle(ctx, std::move(clusters)); m_measurementParticlesMapWriteHandle(ctx, diff --git a/Examples/Algorithms/Digitization/src/MeasurementCreation.cpp b/Examples/Algorithms/Digitization/src/MeasurementCreation.cpp index e7a9e6b379e..9d5169ca6c9 100644 --- a/Examples/Algorithms/Digitization/src/MeasurementCreation.cpp +++ b/Examples/Algorithms/Digitization/src/MeasurementCreation.cpp @@ -10,6 +10,7 @@ #include "Acts/EventData/MeasurementHelpers.hpp" #include "Acts/EventData/SourceLink.hpp" +#include "Acts/Geometry/GeometryIdentifier.hpp" #include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/Measurement.hpp" @@ -18,10 +19,8 @@ #include ActsExamples::VariableBoundMeasurementProxy ActsExamples::createMeasurement( - MeasurementContainer& container, const DigitizedParameters& dParams, - const IndexSourceLink& isl) { - Acts::SourceLink sl{isl}; - + MeasurementContainer& container, Acts::GeometryIdentifier geometryId, + const DigitizedParameters& dParams) { if (dParams.indices.size() > 4u) { std::string errorMsg = "Invalid/mismatching measurement dimension: " + std::to_string(dParams.indices.size()); @@ -31,6 +30,6 @@ ActsExamples::VariableBoundMeasurementProxy ActsExamples::createMeasurement( return Acts::visit_measurement( dParams.indices.size(), [&](auto dim) -> VariableBoundMeasurementProxy { auto [indices, par, cov] = measurementConstituents(dParams); - return container.emplaceMeasurement(sl, indices, par, cov); + return container.emplaceMeasurement(geometryId, indices, par, cov); }); } diff --git a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/GbtsSeedingAlgorithm.hpp b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/GbtsSeedingAlgorithm.hpp index b931c72f979..b422eab9e85 100644 --- a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/GbtsSeedingAlgorithm.hpp +++ b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/GbtsSeedingAlgorithm.hpp @@ -44,8 +44,6 @@ class GbtsSeedingAlgorithm final : public IAlgorithm { std::vector geometrySelection; - std::string inputSourceLinks; - std::shared_ptr trackingGeometry; std::map, std::pair> ActsGbtsMap; @@ -88,9 +86,6 @@ class GbtsSeedingAlgorithm final : public IAlgorithm { WriteDataHandle m_outputSeeds{this, "OutputSeeds"}; - ReadDataHandle m_inputSourceLinks{ - this, "InputSourceLinks"}; - ReadDataHandle m_inputClusters{this, "InputClusters"}; }; diff --git a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/HoughTransformSeeder.hpp b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/HoughTransformSeeder.hpp index 6ea2400a712..b74047ca6a2 100644 --- a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/HoughTransformSeeder.hpp +++ b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/HoughTransformSeeder.hpp @@ -76,7 +76,6 @@ #include "Acts/Utilities/Logger.hpp" #include "Acts/Utilities/Result.hpp" #include "ActsExamples/EventData/Index.hpp" -#include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/Measurement.hpp" #include "ActsExamples/EventData/ProtoTrack.hpp" #include "ActsExamples/EventData/SimSpacePoint.hpp" @@ -168,8 +167,6 @@ class HoughTransformSeeder final : public IAlgorithm { std::string outputSeeds; /// Output hough track collection. std::string outputProtoTracks; - /// Input source links collection. - std::string inputSourceLinks; /// Tracking geometry required to access global-to-local transforms. std::shared_ptr trackingGeometry; /// For which part of the detector geometry should space points be created. @@ -281,9 +278,6 @@ class HoughTransformSeeder final : public IAlgorithm { ReadDataHandle m_inputMeasurements{this, "InputMeasurements"}; - ReadDataHandle m_inputSourceLinks{ - this, "InputSourceLinks"}; - //////////////////////////////////////////////////////////////////////// /// Convenience diff --git a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/SpacePointMaker.hpp b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/SpacePointMaker.hpp index 0d5604e5ec4..db4678a6200 100644 --- a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/SpacePointMaker.hpp +++ b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/SpacePointMaker.hpp @@ -11,7 +11,6 @@ #include "Acts/Geometry/GeometryIdentifier.hpp" #include "Acts/SpacePointFormation/SpacePointBuilder.hpp" #include "Acts/Utilities/Logger.hpp" -#include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/Measurement.hpp" #include "ActsExamples/EventData/SimSpacePoint.hpp" #include "ActsExamples/Framework/DataHandle.hpp" @@ -46,8 +45,6 @@ struct AlgorithmContext; class SpacePointMaker final : public IAlgorithm { public: struct Config { - /// Input source links collection. - std::string inputSourceLinks; /// Input measurements collection. std::string inputMeasurements; /// Output space points collection. @@ -86,9 +83,6 @@ class SpacePointMaker final : public IAlgorithm { Acts::SpacePointBuilder m_spacePointBuilder; - ReadDataHandle m_inputSourceLinks{ - this, "InputSourceLinks"}; - ReadDataHandle m_inputMeasurements{this, "InputMeasurements"}; diff --git a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp index f63581470e6..deb15750a5f 100644 --- a/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp +++ b/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/TrackFindingAlgorithm.hpp @@ -80,8 +80,6 @@ class TrackFindingAlgorithm final : public IAlgorithm { struct Config { /// Input measurements collection. std::string inputMeasurements; - /// Input source links collection. - std::string inputSourceLinks; /// Input initial track parameter estimates for for each proto track. std::string inputInitialTrackParameters; /// Input seeds. These are optional and allow for seed deduplication. @@ -156,9 +154,8 @@ class TrackFindingAlgorithm final : public IAlgorithm { const Config& config() const { return m_cfg; } private: - template - void computeSharedHits(const source_link_accessor_container_t& sourceLinks, - TrackContainer& tracks) const; + void computeSharedHits(TrackContainer& tracks, + const MeasurementContainer& measurements) const; ActsExamples::ProcessCode finalize() override; @@ -168,8 +165,6 @@ class TrackFindingAlgorithm final : public IAlgorithm { ReadDataHandle m_inputMeasurements{this, "InputMeasurements"}; - ReadDataHandle m_inputSourceLinks{ - this, "InputSourceLinks"}; ReadDataHandle m_inputInitialTrackParameters{ this, "InputInitialTrackParameters"}; ReadDataHandle m_inputSeeds{this, "InputSeeds"}; @@ -192,56 +187,4 @@ class TrackFindingAlgorithm final : public IAlgorithm { }}; }; -// TODO this is somewhat duplicated in AmbiguityResolutionAlgorithm.cpp -// TODO we should make a common implementation in the core at some point -template -void TrackFindingAlgorithm::computeSharedHits( - const source_link_accessor_container_t& sourceLinks, - TrackContainer& tracks) const { - // Compute shared hits from all the reconstructed tracks - // Compute nSharedhits and Update ckf results - // hit index -> list of multi traj indexes [traj, meas] - - std::vector firstTrackOnTheHit( - sourceLinks.size(), std::numeric_limits::max()); - std::vector firstStateOnTheHit( - sourceLinks.size(), std::numeric_limits::max()); - - for (auto track : tracks) { - for (auto state : track.trackStatesReversed()) { - if (!state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag)) { - continue; - } - - std::size_t hitIndex = state.getUncalibratedSourceLink() - .template get() - .index(); - - // Check if hit not already used - if (firstTrackOnTheHit.at(hitIndex) == - std::numeric_limits::max()) { - firstTrackOnTheHit.at(hitIndex) = track.index(); - firstStateOnTheHit.at(hitIndex) = state.index(); - continue; - } - - // if already used, control if first track state has been marked - // as shared - int indexFirstTrack = firstTrackOnTheHit.at(hitIndex); - int indexFirstState = firstStateOnTheHit.at(hitIndex); - - auto firstState = tracks.getTrack(indexFirstTrack) - .container() - .trackStateContainer() - .getTrackState(indexFirstState); - if (!firstState.typeFlags().test(Acts::TrackStateFlag::SharedHitFlag)) { - firstState.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag); - } - - // Decorate this track state - state.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag); - } - } -} - } // namespace ActsExamples diff --git a/Examples/Algorithms/TrackFinding/src/GbtsSeedingAlgorithm.cpp b/Examples/Algorithms/TrackFinding/src/GbtsSeedingAlgorithm.cpp index 835b027862f..385a3db7ec1 100644 --- a/Examples/Algorithms/TrackFinding/src/GbtsSeedingAlgorithm.cpp +++ b/Examples/Algorithms/TrackFinding/src/GbtsSeedingAlgorithm.cpp @@ -61,8 +61,6 @@ ActsExamples::GbtsSeedingAlgorithm::GbtsSeedingAlgorithm( m_outputSeeds.initialize(m_cfg.outputSeeds); - m_inputSourceLinks.initialize(m_cfg.inputSourceLinks); - m_inputClusters.initialize(m_cfg.inputClusters); // map diff --git a/Examples/Algorithms/TrackFinding/src/HoughTransformSeeder.cpp b/Examples/Algorithms/TrackFinding/src/HoughTransformSeeder.cpp index 02b112fe6b4..c8126773194 100644 --- a/Examples/Algorithms/TrackFinding/src/HoughTransformSeeder.cpp +++ b/Examples/Algorithms/TrackFinding/src/HoughTransformSeeder.cpp @@ -76,13 +76,7 @@ ActsExamples::HoughTransformSeeder::HoughTransformSeeder( "HoughTransformSeeder: Missing hough track seeds output collection"); } - if (m_cfg.inputSourceLinks.empty()) { - throw std::invalid_argument( - "HoughTransformSeeder: Missing source link input collection"); - } - m_outputProtoTracks.initialize(m_cfg.outputProtoTracks); - m_inputSourceLinks.initialize(m_cfg.inputSourceLinks); m_inputMeasurements.initialize(m_cfg.inputMeasurements); if (!m_cfg.trackingGeometry) { @@ -503,14 +497,14 @@ void ActsExamples::HoughTransformSeeder::addSpacePoints( void ActsExamples::HoughTransformSeeder::addMeasurements( const AlgorithmContext& ctx) const { const auto& measurements = m_inputMeasurements(ctx); - const auto& sourceLinks = m_inputSourceLinks(ctx); ACTS_DEBUG("Inserting " << measurements.size() << " space points from " << m_cfg.inputMeasurements); for (Acts::GeometryIdentifier geoId : m_cfg.geometrySelection) { // select volume/layer depending on what is set in the geometry id - auto range = selectLowestNonZeroGeometryObject(sourceLinks, geoId); + auto range = + selectLowestNonZeroGeometryObject(measurements.orderedIndices(), geoId); // groupByModule only works with geometry containers, not with an // arbitrary range. do the equivalent grouping manually auto groupedByModule = makeGroupBy(range, detail::GeometryIdGetter()); diff --git a/Examples/Algorithms/TrackFinding/src/SpacePointMaker.cpp b/Examples/Algorithms/TrackFinding/src/SpacePointMaker.cpp index e6fed997a02..673ffa8b103 100644 --- a/Examples/Algorithms/TrackFinding/src/SpacePointMaker.cpp +++ b/Examples/Algorithms/TrackFinding/src/SpacePointMaker.cpp @@ -32,9 +32,6 @@ ActsExamples::SpacePointMaker::SpacePointMaker(Config cfg, Acts::Logging::Level lvl) : IAlgorithm("SpacePointMaker", lvl), m_cfg(std::move(cfg)) { - if (m_cfg.inputSourceLinks.empty()) { - throw std::invalid_argument("Missing source link input collection"); - } if (m_cfg.inputMeasurements.empty()) { throw std::invalid_argument("Missing measurement input collection"); } @@ -48,7 +45,6 @@ ActsExamples::SpacePointMaker::SpacePointMaker(Config cfg, throw std::invalid_argument("Missing space point maker geometry selection"); } - m_inputSourceLinks.initialize(m_cfg.inputSourceLinks); m_inputMeasurements.initialize(m_cfg.inputMeasurements); m_outputSpacePoints.initialize(m_cfg.outputSpacePoints); @@ -119,7 +115,6 @@ ActsExamples::SpacePointMaker::SpacePointMaker(Config cfg, ActsExamples::ProcessCode ActsExamples::SpacePointMaker::execute( const AlgorithmContext& ctx) const { - const auto& sourceLinks = m_inputSourceLinks(ctx); const auto& measurements = m_inputMeasurements(ctx); // TODO Support strip measurements @@ -136,7 +131,8 @@ ActsExamples::ProcessCode ActsExamples::SpacePointMaker::execute( SimSpacePointContainer spacePoints; for (Acts::GeometryIdentifier geoId : m_cfg.geometrySelection) { // select volume/layer depending on what is set in the geometry id - auto range = selectLowestNonZeroGeometryObject(sourceLinks, geoId); + auto range = + selectLowestNonZeroGeometryObject(measurements.orderedIndices(), geoId); // groupByModule only works with geometry containers, not with an // arbitrary range. do the equivalent grouping manually auto groupedByModule = makeGroupBy(range, detail::GeometryIdGetter()); diff --git a/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp b/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp index ed9918c4f84..2a36701dc3b 100644 --- a/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp +++ b/Examples/Algorithms/TrackFinding/src/TrackFindingAlgorithm.cpp @@ -32,6 +32,7 @@ #include "Acts/Utilities/Logger.hpp" #include "Acts/Utilities/TrackHelpers.hpp" #include "ActsExamples/EventData/IndexSourceLink.hpp" +#include "ActsExamples/EventData/Measurement.hpp" #include "ActsExamples/EventData/MeasurementCalibration.hpp" #include "ActsExamples/EventData/SimSeed.hpp" #include "ActsExamples/EventData/Track.hpp" @@ -262,9 +263,6 @@ TrackFindingAlgorithm::TrackFindingAlgorithm(Config config, if (m_cfg.inputMeasurements.empty()) { throw std::invalid_argument("Missing measurements input collection"); } - if (m_cfg.inputSourceLinks.empty()) { - throw std::invalid_argument("Missing source links input collection"); - } if (m_cfg.inputInitialTrackParameters.empty()) { throw std::invalid_argument( "Missing initial track parameters input collection"); @@ -293,7 +291,6 @@ TrackFindingAlgorithm::TrackFindingAlgorithm(Config config, } m_inputMeasurements.initialize(m_cfg.inputMeasurements); - m_inputSourceLinks.initialize(m_cfg.inputSourceLinks); m_inputInitialTrackParameters.initialize(m_cfg.inputInitialTrackParameters); m_inputSeeds.maybeInitialize(m_cfg.inputSeeds); m_outputTracks.initialize(m_cfg.outputTracks); @@ -302,7 +299,6 @@ TrackFindingAlgorithm::TrackFindingAlgorithm(Config config, ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { // Read input data const auto& measurements = m_inputMeasurements(ctx); - const auto& sourceLinks = m_inputSourceLinks(ctx); const auto& initialParameters = m_inputInitialTrackParameters(ctx); const SimSeedContainer* seeds = nullptr; @@ -339,7 +335,7 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { extensions.branchStopper.connect<&BranchStopper::operator()>(&branchStopper); IndexSourceLinkAccessor slAccessor; - slAccessor.container = &sourceLinks; + slAccessor.container = &measurements.orderedIndices(); Acts::SourceLinkAccessorDelegate slAccessorDelegate; slAccessorDelegate.connect<&IndexSourceLinkAccessor::range>(&slAccessor); @@ -648,7 +644,7 @@ ProcessCode TrackFindingAlgorithm::execute(const AlgorithmContext& ctx) const { // Compute shared hits from all the reconstructed tracks if (m_cfg.computeSharedHits) { - computeSharedHits(sourceLinks, tracks); + computeSharedHits(tracks, measurements); } ACTS_DEBUG("Finalized track finding with " << tracks.size() @@ -698,4 +694,54 @@ ProcessCode TrackFindingAlgorithm::finalize() { return ProcessCode::SUCCESS; } +// TODO this is somewhat duplicated in AmbiguityResolutionAlgorithm.cpp +// TODO we should make a common implementation in the core at some point +void TrackFindingAlgorithm::computeSharedHits( + TrackContainer& tracks, const MeasurementContainer& measurements) const { + // Compute shared hits from all the reconstructed tracks + // Compute nSharedhits and Update ckf results + // hit index -> list of multi traj indexes [traj, meas] + + std::vector firstTrackOnTheHit( + measurements.size(), std::numeric_limits::max()); + std::vector firstStateOnTheHit( + measurements.size(), std::numeric_limits::max()); + + for (auto track : tracks) { + for (auto state : track.trackStatesReversed()) { + if (!state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag)) { + continue; + } + + std::size_t hitIndex = state.getUncalibratedSourceLink() + .template get() + .index(); + + // Check if hit not already used + if (firstTrackOnTheHit.at(hitIndex) == + std::numeric_limits::max()) { + firstTrackOnTheHit.at(hitIndex) = track.index(); + firstStateOnTheHit.at(hitIndex) = state.index(); + continue; + } + + // if already used, control if first track state has been marked + // as shared + int indexFirstTrack = firstTrackOnTheHit.at(hitIndex); + int indexFirstState = firstStateOnTheHit.at(hitIndex); + + auto firstState = tracks.getTrack(indexFirstTrack) + .container() + .trackStateContainer() + .getTrackState(indexFirstState); + if (!firstState.typeFlags().test(Acts::TrackStateFlag::SharedHitFlag)) { + firstState.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag); + } + + // Decorate this track state + state.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag); + } + } +} + } // namespace ActsExamples diff --git a/Examples/Algorithms/TrackFindingExaTrkX/include/ActsExamples/TrackFindingExaTrkX/TrackFindingFromPrototrackAlgorithm.hpp b/Examples/Algorithms/TrackFindingExaTrkX/include/ActsExamples/TrackFindingExaTrkX/TrackFindingFromPrototrackAlgorithm.hpp index 91b3ce43cdb..abfc29b462c 100644 --- a/Examples/Algorithms/TrackFindingExaTrkX/include/ActsExamples/TrackFindingExaTrkX/TrackFindingFromPrototrackAlgorithm.hpp +++ b/Examples/Algorithms/TrackFindingExaTrkX/include/ActsExamples/TrackFindingExaTrkX/TrackFindingFromPrototrackAlgorithm.hpp @@ -16,7 +16,6 @@ #include "Acts/TrackFitting/GainMatrixSmoother.hpp" #include "Acts/TrackFitting/GainMatrixUpdater.hpp" #include "Acts/Utilities/Zip.hpp" -#include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/Measurement.hpp" #include "ActsExamples/EventData/ProtoTrack.hpp" #include "ActsExamples/EventData/Trajectories.hpp" @@ -44,9 +43,6 @@ class TrackFindingFromPrototrackAlgorithm final : public IAlgorithm { /// Input measurements std::string inputMeasurements; - /// Input source links - std::string inputSourceLinks; - /// Input track parameters std::string inputInitialTrackParameters; @@ -98,8 +94,6 @@ class TrackFindingFromPrototrackAlgorithm final : public IAlgorithm { "InputProtoTracks"}; ReadDataHandle m_inputMeasurements{this, "InputMeasurements"}; - ReadDataHandle m_inputSourceLinks{ - this, "InputSourceLinks"}; ReadDataHandle m_inputInitialTrackParameters{ this, "InputInitialTrackParameters"}; diff --git a/Examples/Algorithms/TrackFindingExaTrkX/src/TrackFindingFromPrototrackAlgorithm.cpp b/Examples/Algorithms/TrackFindingExaTrkX/src/TrackFindingFromPrototrackAlgorithm.cpp index 4eef98a6f83..bf28b1743ba 100644 --- a/Examples/Algorithms/TrackFindingExaTrkX/src/TrackFindingFromPrototrackAlgorithm.cpp +++ b/Examples/Algorithms/TrackFindingExaTrkX/src/TrackFindingFromPrototrackAlgorithm.cpp @@ -48,6 +48,7 @@ struct ProtoTrackSourceLinkAccessor return {Iterator{begin}, Iterator{end}}; } }; + } // namespace namespace ActsExamples { @@ -58,14 +59,12 @@ TrackFindingFromPrototrackAlgorithm::TrackFindingFromPrototrackAlgorithm( m_inputInitialTrackParameters.initialize(m_cfg.inputInitialTrackParameters); m_inputMeasurements.initialize(m_cfg.inputMeasurements); m_inputProtoTracks.initialize(m_cfg.inputProtoTracks); - m_inputSourceLinks.initialize(m_cfg.inputSourceLinks); m_outputTracks.initialize(m_cfg.outputTracks); } ActsExamples::ProcessCode TrackFindingFromPrototrackAlgorithm::execute( const ActsExamples::AlgorithmContext& ctx) const { const auto& measurements = m_inputMeasurements(ctx); - const auto& sourceLinks = m_inputSourceLinks(ctx); const auto& protoTracks = m_inputProtoTracks(ctx); const auto& initialParameters = m_inputInitialTrackParameters(ctx); @@ -98,7 +97,7 @@ ActsExamples::ProcessCode TrackFindingFromPrototrackAlgorithm::execute( // The source link accessor ProtoTrackSourceLinkAccessor sourceLinkAccessor; sourceLinkAccessor.loggerPtr = logger().clone("SourceLinkAccessor"); - sourceLinkAccessor.container = &sourceLinks; + sourceLinkAccessor.container = &measurements.orderedIndices(); Acts::SourceLinkAccessorDelegate slAccessorDelegate; @@ -133,7 +132,8 @@ ActsExamples::ProcessCode TrackFindingFromPrototrackAlgorithm::execute( // Fill the source links via their indices from the container for (const auto hitIndex : protoTracks.at(i)) { - if (auto it = sourceLinks.nth(hitIndex); it != sourceLinks.end()) { + if (auto it = measurements.orderedIndices().nth(hitIndex); + it != measurements.orderedIndices().end()) { sourceLinkAccessor.protoTrackSourceLinks.insert(*it); } else { ACTS_FATAL("Proto track " << i << " contains invalid hit index" @@ -177,7 +177,7 @@ ActsExamples::ProcessCode TrackFindingFromPrototrackAlgorithm::execute( // once this is done. // Compute shared hits from all the reconstructed tracks if // (m_cfg.computeSharedHits) { - // computeSharedHits(sourceLinks, tracks); + // computeSharedHits(measurements, tracks); // } ACTS_INFO("Event " << ctx.eventNumber << ": " << nFailed << " / " << nSeed diff --git a/Examples/Algorithms/TrackFitting/include/ActsExamples/TrackFitting/TrackFittingAlgorithm.hpp b/Examples/Algorithms/TrackFitting/include/ActsExamples/TrackFitting/TrackFittingAlgorithm.hpp index 3c3a62c4c4c..934203aeeaa 100644 --- a/Examples/Algorithms/TrackFitting/include/ActsExamples/TrackFitting/TrackFittingAlgorithm.hpp +++ b/Examples/Algorithms/TrackFitting/include/ActsExamples/TrackFitting/TrackFittingAlgorithm.hpp @@ -72,8 +72,6 @@ class TrackFittingAlgorithm final : public IAlgorithm { ReadDataHandle m_inputMeasurements{this, "InputMeasurements"}; - ReadDataHandle m_inputSourceLinks{ - this, "InputSourceLinks"}; ReadDataHandle m_inputProtoTracks{this, "InputProtoTracks"}; ReadDataHandle m_inputInitialTrackParameters{ diff --git a/Examples/Algorithms/TrackFitting/src/TrackFittingAlgorithm.cpp b/Examples/Algorithms/TrackFitting/src/TrackFittingAlgorithm.cpp index 49ed2c285cd..50360e3d3b4 100644 --- a/Examples/Algorithms/TrackFitting/src/TrackFittingAlgorithm.cpp +++ b/Examples/Algorithms/TrackFitting/src/TrackFittingAlgorithm.cpp @@ -18,6 +18,7 @@ #include "Acts/Surfaces/PerigeeSurface.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Utilities/Result.hpp" +#include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/Measurement.hpp" #include "ActsExamples/EventData/MeasurementCalibration.hpp" #include "ActsExamples/EventData/ProtoTrack.hpp" @@ -126,10 +127,11 @@ ActsExamples::ProcessCode ActsExamples::TrackFittingAlgorithm::execute( trackSourceLinks.reserve(protoTrack.size()); // Fill the source links via their indices from the container - for (auto hitIndex : protoTrack) { + for (auto measIndex : protoTrack) { ConstVariableBoundMeasurementProxy measurement = - measurements.getMeasurement(hitIndex); - trackSourceLinks.push_back(measurement.sourceLink()); + measurements.getMeasurement(measIndex); + IndexSourceLink sourceLink(measurement.geometryId(), measIndex); + trackSourceLinks.push_back(Acts::SourceLink(sourceLink)); } ACTS_DEBUG("Invoke direct fitter for track " << itrack); diff --git a/Examples/Algorithms/Utilities/include/ActsExamples/Utilities/MeasurementMapSelector.hpp b/Examples/Algorithms/Utilities/include/ActsExamples/Utilities/MeasurementMapSelector.hpp index 3cf5eace6d9..ef495b3a9a9 100644 --- a/Examples/Algorithms/Utilities/include/ActsExamples/Utilities/MeasurementMapSelector.hpp +++ b/Examples/Algorithms/Utilities/include/ActsExamples/Utilities/MeasurementMapSelector.hpp @@ -17,6 +17,7 @@ #include "ActsFatras/EventData/Barcode.hpp" #include +#include #include namespace ActsExamples { @@ -30,12 +31,12 @@ class MeasurementMapSelector final : public IAlgorithm { public: struct Config { + /// Input measurements + std::string inputMeasurements; + /// Input spacepoints collection. std::string inputMeasurementParticleMap; - /// Input source links - std::string inputSourceLinks; - /// Output protoTracks collection. std::string outputMeasurementParticleMap; @@ -48,27 +49,26 @@ class MeasurementMapSelector final : public IAlgorithm { /// @param cfg is the config struct to configure the algorithm /// @param level is the logging level MeasurementMapSelector(Config cfg, Acts::Logging::Level lvl) - : IAlgorithm("MeasurementMapSelector", lvl), m_cfg(cfg) { - m_inputSourceLinks.initialize(m_cfg.inputSourceLinks); + : IAlgorithm("MeasurementMapSelector", lvl), m_cfg(std::move(cfg)) { + m_inputMeasurements.initialize(m_cfg.inputMeasurements); m_inputMap.initialize(m_cfg.inputMeasurementParticleMap); m_outputMap.initialize(m_cfg.outputMeasurementParticleMap); } - virtual ~MeasurementMapSelector() = default; - /// Filter the measurements /// /// @param ctx is the algorithm context that holds event-wise information /// @return a process code to steer the algorithm flow ActsExamples::ProcessCode execute( const ActsExamples::AlgorithmContext& ctx) const final { - const auto& inputSourceLinks = m_inputSourceLinks(ctx); + const auto& inputMeasurements = m_inputMeasurements(ctx); const auto& inputMap = m_inputMap(ctx); Map outputMap; for (const auto geoId : m_cfg.geometrySelection) { - auto range = selectLowestNonZeroGeometryObject(inputSourceLinks, geoId); + auto range = selectLowestNonZeroGeometryObject( + inputMeasurements.orderedIndices(), geoId); for (const auto& sl : range) { const auto [begin, end] = inputMap.equal_range(sl.index()); outputMap.insert(begin, end); @@ -86,8 +86,8 @@ class MeasurementMapSelector final : public IAlgorithm { // configuration Config m_cfg; - ReadDataHandle m_inputSourceLinks{ - this, "InputSourceLinks"}; + ReadDataHandle m_inputMeasurements{this, + "InputMeasurements"}; ReadDataHandle m_inputMap{this, "InputMeasurementParticleMap"}; WriteDataHandle m_outputMap{this, "OutputMeasurementParticleMap"}; }; diff --git a/Examples/Algorithms/Utilities/src/PrototracksToTracks.cpp b/Examples/Algorithms/Utilities/src/PrototracksToTracks.cpp index 01e2fac6a38..12a2b70e6cf 100644 --- a/Examples/Algorithms/Utilities/src/PrototracksToTracks.cpp +++ b/Examples/Algorithms/Utilities/src/PrototracksToTracks.cpp @@ -8,6 +8,7 @@ #include "ActsExamples/Utilities/ProtoTracksToTracks.hpp" +#include "Acts/EventData/SourceLink.hpp" #include "Acts/Surfaces/PerigeeSurface.hpp" #include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/ProtoTrack.hpp" @@ -27,16 +28,12 @@ PrototracksToTracks::PrototracksToTracks(Config cfg, Acts::Logging::Level lvl) } ProcessCode PrototracksToTracks::execute(const AlgorithmContext& ctx) const { + const auto& measurements = m_inputMeasurements(ctx); + auto trackContainer = std::make_shared(); auto mtj = std::make_shared(); TrackContainer tracks(trackContainer, mtj); - boost::container::flat_map slMap; - for (const auto& m : m_inputMeasurements(ctx)) { - const auto idx = m.sourceLink().template get().index(); - slMap.insert(std::pair{idx, m.sourceLink()}); - } - const auto& prototracks = m_inputProtoTracks(ctx); ACTS_DEBUG("Received " << prototracks.size() << " prototracks"); @@ -54,12 +51,15 @@ ProcessCode PrototracksToTracks::execute(const AlgorithmContext& ctx) const { maxSize = std::max(maxSize, protoTrack.size()); auto track = tracks.makeTrack(); - for (auto idx : protoTrack) { + for (auto measIndex : protoTrack) { + ConstVariableBoundMeasurementProxy measurement = + measurements.getMeasurement(measIndex); + IndexSourceLink sourceLink(measurement.geometryId(), measIndex); + auto trackStateProxy = track.appendTrackState(Acts::TrackStatePropMask::None); trackStateProxy.typeFlags().set(Acts::TrackStateFlag::MeasurementFlag); - trackStateProxy.setUncalibratedSourceLink( - Acts::SourceLink{slMap.at(idx)}); + trackStateProxy.setUncalibratedSourceLink(Acts::SourceLink(sourceLink)); } track.nMeasurements() = static_cast(protoTrack.size()); diff --git a/Examples/Algorithms/Utilities/src/TrajectoriesToPrototracks.cpp b/Examples/Algorithms/Utilities/src/TrajectoriesToPrototracks.cpp index cd961ab6141..c92d985d492 100644 --- a/Examples/Algorithms/Utilities/src/TrajectoriesToPrototracks.cpp +++ b/Examples/Algorithms/Utilities/src/TrajectoriesToPrototracks.cpp @@ -9,6 +9,7 @@ #include "ActsExamples/Utilities/TrajectoriesToPrototracks.hpp" #include "Acts/EventData/MultiTrajectory.hpp" +#include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/ProtoTrack.hpp" #include "ActsExamples/EventData/Trajectories.hpp" @@ -16,7 +17,6 @@ #include namespace ActsExamples { -class IndexSourceLink; struct AlgorithmContext; TrajectoriesToPrototracks::TrajectoriesToPrototracks(Config cfg, diff --git a/Examples/Framework/include/ActsExamples/EventData/IndexSourceLink.hpp b/Examples/Framework/include/ActsExamples/EventData/IndexSourceLink.hpp index cc2e6249a2e..ea60a030b96 100644 --- a/Examples/Framework/include/ActsExamples/EventData/IndexSourceLink.hpp +++ b/Examples/Framework/include/ActsExamples/EventData/IndexSourceLink.hpp @@ -84,11 +84,6 @@ struct IndexSourceLinkSurfaceAccessor { } // namespace Experimental -/// Container of index source links. -/// -/// Since the source links provide a `.geometryId()` accessor, they can be -/// stored in an ordered geometry container. -using IndexSourceLinkContainer = GeometryIdMultiset; /// Accessor for the above source link container /// /// It wraps up a few lookup methods to be used in the Combinatorial Kalman @@ -105,4 +100,5 @@ struct IndexSourceLinkAccessor : GeometryIdMultisetAccessor { return {Iterator{begin}, Iterator{end}}; } }; + } // namespace ActsExamples diff --git a/Examples/Framework/include/ActsExamples/EventData/Measurement.hpp b/Examples/Framework/include/ActsExamples/EventData/Measurement.hpp index 8703806a164..12286417c61 100644 --- a/Examples/Framework/include/ActsExamples/EventData/Measurement.hpp +++ b/Examples/Framework/include/ActsExamples/EventData/Measurement.hpp @@ -11,13 +11,15 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/EventData/MeasurementHelpers.hpp" -#include "Acts/EventData/SourceLink.hpp" #include "Acts/EventData/SubspaceHelpers.hpp" #include "Acts/EventData/Types.hpp" #include "Acts/EventData/detail/CalculateResiduals.hpp" #include "Acts/EventData/detail/ParameterTraits.hpp" #include "Acts/EventData/detail/PrintParameters.hpp" +#include "Acts/Geometry/GeometryIdentifier.hpp" #include "Acts/Utilities/Iterator.hpp" +#include "ActsExamples/EventData/GeometryContainers.hpp" +#include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/MeasurementConcept.hpp" #include @@ -69,6 +71,7 @@ class MeasurementContainer { using ConstFixedProxy = FixedMeasurementProxy; using VariableProxy = VariableMeasurementProxy; using ConstVariableProxy = VariableMeasurementProxy; + using OrderedIndices = GeometryIdMultiset; MeasurementContainer(); @@ -82,8 +85,9 @@ class MeasurementContainer { /// @brief Add a measurement of a given size /// @param size The size of the measurement + /// @param geometryId The geometry identifier of the measurement surface /// @return The index of the added measurement - Index addMeasurement(std::uint8_t size); + Index addMeasurement(std::uint8_t size, Acts::GeometryIdentifier geometryId); /// @brief Get a variable-size measurement proxy /// @param index The index of the measurement @@ -122,21 +126,29 @@ class MeasurementContainer { /// @brief Make a measurement of a given size /// @param size The size of the measurement + /// @param geometryId The geometry identifier of the measurement surface /// @return The variable-size measurement proxy - VariableProxy makeMeasurement(std::uint8_t size); + VariableProxy makeMeasurement(std::uint8_t size, + Acts::GeometryIdentifier geometryId); /// @brief Make a fixed-size measurement /// @tparam Size The size of the measurement + /// @param geometryId The geometry identifier of the measurement surface /// @return The fixed-size measurement proxy template - FixedProxy makeMeasurement() { - return getMeasurement(addMeasurement(Size)); + FixedProxy makeMeasurement(Acts::GeometryIdentifier geometryId) { + return getMeasurement(addMeasurement(Size, geometryId)); } template - VariableProxy emplaceMeasurement(std::uint8_t size, Args&&... args); + VariableProxy emplaceMeasurement(std::uint8_t size, + Acts::GeometryIdentifier geometryId, + Args&&... args); template - FixedProxy emplaceMeasurement(Args&&... args); + FixedProxy emplaceMeasurement(Acts::GeometryIdentifier geometryId, + Args&&... args); + + const OrderedIndices& orderedIndices() const; using iterator = Acts::ContainerIndexIterator; @@ -161,10 +173,12 @@ class MeasurementContainer { std::vector m_entries; - std::vector> m_sourceLinks; + std::vector m_geometryIds; std::vector m_subspaceIndices; std::vector m_parameters; std::vector m_covariances; + + OrderedIndices m_orderedIndices; }; /// @brief Base class for measurement proxies @@ -223,18 +237,10 @@ class MeasurementProxyBase { return self().subspaceHelper().indexOf(i); } - /// @brief Set the source link of the measurement - /// @param sourceLink The source link - void setSourceLink(const Acts::SourceLink& sourceLink) - requires(!ReadOnly) - { - container().m_sourceLinks.at(m_index) = sourceLink; - } - - /// @brief Get the source link of the measurement - /// @return The source link - const Acts::SourceLink& sourceLink() const { - return container().m_sourceLinks.at(m_index).value(); + /// @brief Get the geometry ID of the measurement + /// @return The geometry ID + Acts::GeometryIdentifier geometryId() const { + return container().m_geometryIds.at(m_index); } /// @brief Set the subspace indices of the measurement @@ -262,23 +268,22 @@ class MeasurementProxyBase { return self().subspaceHelper().expandMatrix(self().covariance()); } - /// @brief Construct the measurement from a sourcelink, subspace vector, + /// @brief Construct the measurement from a subspace vector, /// parameters, and covariance. /// template - void fill(const Acts::SourceLink& source_link, Subspace&& subspace, + void fill(Subspace&& subspace, const Eigen::DenseBase& parameters, const Eigen::DenseBase& covariance) requires(!ReadOnly) { - setSourceLink(source_link); self().setSubspaceIndices(std::forward(subspace)); self().parameters() = parameters; self().covariance() = covariance; } - /// @brief Construct the measurement from a sourcelink, subspace vector, + /// @brief Construct the measurement from a subspace vector, /// parameters, and covariance. /// template @@ -286,8 +291,7 @@ class MeasurementProxyBase { requires(!ReadOnly) { assert(size() == other.size() && "Size mismatch"); - fill(other.sourceLink(), other.subspaceIndexVector(), other.parameters(), - other.covariance()); + fill(other.subspaceIndexVector(), other.parameters(), other.covariance()); } /// @brief Copy the data from another measurement @@ -493,8 +497,8 @@ class VariableMeasurementProxy template MeasurementContainer::VariableProxy MeasurementContainer::emplaceMeasurement( - std::uint8_t size, Args&&... args) { - VariableProxy meas = makeMeasurement(size); + std::uint8_t size, Acts::GeometryIdentifier geometryId, Args&&... args) { + VariableProxy meas = makeMeasurement(size, geometryId); meas.fill(std::forward(args)...); @@ -503,8 +507,8 @@ MeasurementContainer::VariableProxy MeasurementContainer::emplaceMeasurement( template MeasurementContainer::FixedProxy MeasurementContainer::emplaceMeasurement( - Args&&... args) { - FixedProxy meas = makeMeasurement(); + Acts::GeometryIdentifier geometryId, Args&&... args) { + FixedProxy meas = makeMeasurement(geometryId); meas.fill(std::forward(args)...); @@ -514,4 +518,5 @@ MeasurementContainer::FixedProxy MeasurementContainer::emplaceMeasurement( static_assert( std::random_access_iterator && std::random_access_iterator); + } // namespace ActsExamples diff --git a/Examples/Framework/include/ActsExamples/EventData/MeasurementConcept.hpp b/Examples/Framework/include/ActsExamples/EventData/MeasurementConcept.hpp index f95ab117728..14627a78c53 100644 --- a/Examples/Framework/include/ActsExamples/EventData/MeasurementConcept.hpp +++ b/Examples/Framework/include/ActsExamples/EventData/MeasurementConcept.hpp @@ -9,6 +9,7 @@ #pragma once #include "Acts/EventData/SourceLink.hpp" +#include "Acts/Geometry/GeometryIdentifier.hpp" #include @@ -17,7 +18,7 @@ namespace ActsExamples { template concept MeasurementConcept = requires(const T& m) { { m.size() } -> std::integral; - { m.sourceLink() } -> Acts::Concepts::decayed_same_as; + { m.geometryId() } -> std::same_as; { m.subspaceIndexVector() }; { m.parameters() }; { m.covariance() }; diff --git a/Examples/Framework/src/EventData/Measurement.cpp b/Examples/Framework/src/EventData/Measurement.cpp index f37661948db..ab2dad07489 100644 --- a/Examples/Framework/src/EventData/Measurement.cpp +++ b/Examples/Framework/src/EventData/Measurement.cpp @@ -8,6 +8,9 @@ #include "ActsExamples/EventData/Measurement.hpp" +#include "Acts/Geometry/GeometryIdentifier.hpp" +#include "ActsExamples/EventData/IndexSourceLink.hpp" + namespace ActsExamples { MeasurementContainer::MeasurementContainer() = default; @@ -17,20 +20,26 @@ std::size_t MeasurementContainer::size() const { } void MeasurementContainer::reserve(std::size_t size) { - m_sourceLinks.reserve(size); + m_geometryIds.reserve(size); m_subspaceIndices.reserve(size * 2); m_parameters.reserve(size * 2); m_covariances.reserve(size * 2 * 2); } -std::size_t MeasurementContainer::addMeasurement(std::uint8_t size) { +std::size_t MeasurementContainer::addMeasurement( + std::uint8_t size, Acts::GeometryIdentifier geometryId) { m_entries.push_back({m_subspaceIndices.size(), m_parameters.size(), m_covariances.size(), size}); - m_sourceLinks.emplace_back(); + m_geometryIds.emplace_back(geometryId); m_subspaceIndices.resize(m_subspaceIndices.size() + size); m_parameters.resize(m_parameters.size() + size); m_covariances.resize(m_covariances.size() + size * size); - return m_entries.size() - 1; + + std::size_t index = m_entries.size() - 1; + IndexSourceLink sourceLink(geometryId, index); + m_orderedIndices.emplace_hint(m_orderedIndices.end(), sourceLink); + + return index; } MeasurementContainer::VariableProxy MeasurementContainer::at( @@ -54,8 +63,13 @@ MeasurementContainer::ConstVariableProxy MeasurementContainer::getMeasurement( } MeasurementContainer::VariableProxy MeasurementContainer::makeMeasurement( - std::uint8_t size) { - return getMeasurement(addMeasurement(size)); + std::uint8_t size, Acts::GeometryIdentifier geometryId) { + return getMeasurement(addMeasurement(size, geometryId)); +} + +const MeasurementContainer::OrderedIndices& +MeasurementContainer::orderedIndices() const { + return m_orderedIndices; } MeasurementContainer::iterator MeasurementContainer::begin() { diff --git a/Examples/Io/Csv/include/ActsExamples/Io/Csv/CsvMeasurementReader.hpp b/Examples/Io/Csv/include/ActsExamples/Io/Csv/CsvMeasurementReader.hpp index c26387e1260..d3c5359d16e 100644 --- a/Examples/Io/Csv/include/ActsExamples/Io/Csv/CsvMeasurementReader.hpp +++ b/Examples/Io/Csv/include/ActsExamples/Io/Csv/CsvMeasurementReader.hpp @@ -13,7 +13,6 @@ #include "ActsExamples/EventData/Cluster.hpp" #include "ActsExamples/EventData/GeometryContainers.hpp" #include "ActsExamples/EventData/Index.hpp" -#include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/Measurement.hpp" #include "ActsExamples/EventData/SimHit.hpp" #include "ActsExamples/EventData/SimParticle.hpp" @@ -32,7 +31,6 @@ class Surface; } namespace ActsExamples { -class IndexSourceLink; struct AlgorithmContext; /// Read in a measurement cluster collection in comma-separated-value format. @@ -60,8 +58,6 @@ class CsvMeasurementReader final : public IReader { std::string outputMeasurements; /// Output measurement to sim hit collection. std::string outputMeasurementSimHitsMap; - /// Output source links collection. - std::string outputSourceLinks; /// Output cluster collection (optional). std::string outputClusters; @@ -102,9 +98,6 @@ class CsvMeasurementReader final : public IReader { WriteDataHandle> m_outputMeasurementSimHitsMap{ this, "OutputMeasurementSimHitsMap"}; - WriteDataHandle> m_outputSourceLinks{ - this, "OutputSourceLinks"}; - WriteDataHandle m_outputClusters{this, "OutputClusters"}; WriteDataHandle> diff --git a/Examples/Io/Csv/src/CsvMeasurementReader.cpp b/Examples/Io/Csv/src/CsvMeasurementReader.cpp index cbc030c6939..f426784ea30 100644 --- a/Examples/Io/Csv/src/CsvMeasurementReader.cpp +++ b/Examples/Io/Csv/src/CsvMeasurementReader.cpp @@ -45,7 +45,6 @@ ActsExamples::CsvMeasurementReader::CsvMeasurementReader( m_outputMeasurements.initialize(m_cfg.outputMeasurements); m_outputMeasurementSimHitsMap.initialize(m_cfg.outputMeasurementSimHitsMap); - m_outputSourceLinks.initialize(m_cfg.outputSourceLinks); m_outputClusters.maybeInitialize(m_cfg.outputClusters); m_outputMeasurementParticlesMap.maybeInitialize( m_cfg.outputMeasurementParticlesMap); @@ -196,15 +195,11 @@ ActsExamples::ProcessCode ActsExamples::CsvMeasurementReader::read( MeasurementContainer tmpMeasurements; GeometryIdMultimap orderedMeasurements; IndexMultimap measurementSimHitsMap; - IndexSourceLinkContainer sourceLinks; - // need list here for stable addresses - std::list sourceLinkStorage; tmpMeasurements.reserve(measurementData.size()); orderedMeasurements.reserve(measurementData.size()); // Safe long as we have single particle to sim hit association measurementSimHitsMap.reserve(measurementData.size()); - sourceLinks.reserve(measurementData.size()); auto measurementSimHitLinkData = readEverything( @@ -252,10 +247,7 @@ ActsExamples::ProcessCode ActsExamples::CsvMeasurementReader::read( // The measurement container is unordered and the index under which // the measurement will be stored is known before adding it. - const Index index = orderedMeasurements.size(); - IndexSourceLink& sourceLink = sourceLinkStorage.emplace_back(geoId, index); - auto measurement = - createMeasurement(tmpMeasurements, dParameters, sourceLink); + auto measurement = createMeasurement(tmpMeasurements, geoId, dParameters); // Due to the previous sorting of the raw hit data by geometry id, new // measurements should always end up at the end of the container. previous @@ -267,13 +259,11 @@ ActsExamples::ProcessCode ActsExamples::CsvMeasurementReader::read( ACTS_FATAL("Something went horribly wrong with the hit sorting"); return ProcessCode::ABORT; } - - sourceLinks.insert(sourceLinks.end(), std::cref(sourceLink)); } MeasurementContainer measurements; for (auto& [_, meas] : orderedMeasurements) { - measurements.emplaceMeasurement(meas.size(), meas); + measurements.emplaceMeasurement(meas.size(), meas.geometryId(), meas); } // Generate measurement-particles-map @@ -294,7 +284,6 @@ ActsExamples::ProcessCode ActsExamples::CsvMeasurementReader::read( // Write the data to the EventStore m_outputMeasurements(ctx, std::move(measurements)); m_outputMeasurementSimHitsMap(ctx, std::move(measurementSimHitsMap)); - m_outputSourceLinks(ctx, std::move(sourceLinks)); ///////////////////////// // Cluster information // diff --git a/Examples/Io/Csv/src/CsvMeasurementWriter.cpp b/Examples/Io/Csv/src/CsvMeasurementWriter.cpp index f421c8c2501..851966e8fba 100644 --- a/Examples/Io/Csv/src/CsvMeasurementWriter.cpp +++ b/Examples/Io/Csv/src/CsvMeasurementWriter.cpp @@ -13,7 +13,6 @@ #include "Acts/Geometry/GeometryIdentifier.hpp" #include "ActsExamples/EventData/Cluster.hpp" #include "ActsExamples/EventData/Index.hpp" -#include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/Measurement.hpp" #include "ActsExamples/Framework/AlgorithmContext.hpp" #include "ActsExamples/Io/Csv/CsvInputOutput.hpp" @@ -101,8 +100,7 @@ ActsExamples::ProcessCode ActsExamples::CsvMeasurementWriter::writeT( writerMeasurementSimHitMap.append({measIdx, simHitIdx}); } - Acts::GeometryIdentifier geoId = - measurement.sourceLink().template get().geometryId(); + Acts::GeometryIdentifier geoId = measurement.geometryId(); // MEASUREMENT information ------------------------------------ // Encoded geometry identifier. same for all hits on the module diff --git a/Examples/Io/Csv/src/CsvTrackWriter.cpp b/Examples/Io/Csv/src/CsvTrackWriter.cpp index 26ac3ad2e6b..9f6d74ec730 100644 --- a/Examples/Io/Csv/src/CsvTrackWriter.cpp +++ b/Examples/Io/Csv/src/CsvTrackWriter.cpp @@ -33,10 +33,6 @@ #include #include -namespace ActsExamples { -class IndexSourceLink; -} // namespace ActsExamples - using namespace ActsExamples; CsvTrackWriter::CsvTrackWriter(const CsvTrackWriter::Config& config, diff --git a/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepMeasurementReader.hpp b/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepMeasurementReader.hpp index a81341f0edc..34a95d3709a 100644 --- a/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepMeasurementReader.hpp +++ b/Examples/Io/EDM4hep/include/ActsExamples/Io/EDM4hep/EDM4hepMeasurementReader.hpp @@ -41,8 +41,6 @@ class EDM4hepMeasurementReader final : public IReader { std::string outputMeasurements; /// Output measurement to sim hit collection. std::string outputMeasurementSimHitsMap; - /// Output source links collection. - std::string outputSourceLinks; /// Output cluster collection (optional). std::string outputClusters; }; @@ -79,9 +77,6 @@ class EDM4hepMeasurementReader final : public IReader { WriteDataHandle> m_outputMeasurementSimHitsMap{ this, "OutputMeasurementSimHitsMap"}; - WriteDataHandle> m_outputSourceLinks{ - this, "OutputSourceLinks"}; - WriteDataHandle m_outputClusters{this, "OutputClusters"}; }; diff --git a/Examples/Io/EDM4hep/src/EDM4hepMeasurementReader.cpp b/Examples/Io/EDM4hep/src/EDM4hepMeasurementReader.cpp index 5a9d6840999..237ff19e3b6 100644 --- a/Examples/Io/EDM4hep/src/EDM4hepMeasurementReader.cpp +++ b/Examples/Io/EDM4hep/src/EDM4hepMeasurementReader.cpp @@ -37,7 +37,6 @@ EDM4hepMeasurementReader::EDM4hepMeasurementReader( m_outputMeasurements.initialize(m_cfg.outputMeasurements); m_outputMeasurementSimHitsMap.initialize(m_cfg.outputMeasurementSimHitsMap); - m_outputSourceLinks.initialize(m_cfg.outputSourceLinks); m_outputClusters.maybeInitialize(m_cfg.outputClusters); } @@ -55,7 +54,6 @@ ProcessCode EDM4hepMeasurementReader::read(const AlgorithmContext& ctx) { ClusterContainer clusters; // TODO what about those? IndexMultimap measurementSimHitsMap; - IndexSourceLinkContainer sourceLinks; podio::Frame frame = reader().readEntry("events", ctx.eventNumber); @@ -76,7 +74,6 @@ ProcessCode EDM4hepMeasurementReader::read(const AlgorithmContext& ctx) { // Write the data to the EventStore m_outputMeasurements(ctx, std::move(measurements)); m_outputMeasurementSimHitsMap(ctx, std::move(measurementSimHitsMap)); - m_outputSourceLinks(ctx, std::move(sourceLinks)); if (!m_cfg.outputClusters.empty()) { m_outputClusters(ctx, std::move(clusters)); } diff --git a/Examples/Io/EDM4hep/src/EDM4hepUtil.cpp b/Examples/Io/EDM4hep/src/EDM4hepUtil.cpp index ef6b794cc4c..09dcbc6331b 100644 --- a/Examples/Io/EDM4hep/src/EDM4hepUtil.cpp +++ b/Examples/Io/EDM4hep/src/EDM4hepUtil.cpp @@ -152,9 +152,6 @@ VariableBoundMeasurementProxy EDM4hepUtil::readMeasurement( // no need for digitization as we only want to identify the sensor Acts::GeometryIdentifier geometryId = geometryMapper(from.getCellID()); - IndexSourceLink sourceLink{ - geometryId, static_cast(podioObjectIDToInteger(from.id()))}; - auto pos = from.getPosition(); auto cov = from.getCovMatrix(); @@ -173,7 +170,7 @@ VariableBoundMeasurementProxy EDM4hepUtil::readMeasurement( dParameters.values.push_back(pos.z); dParameters.variances.push_back(cov[5]); - auto to = createMeasurement(container, dParameters, sourceLink); + auto to = createMeasurement(container, geometryId, dParameters); if (fromClusters != nullptr) { for (const auto objectId : from.getRawHits()) { @@ -202,8 +199,7 @@ void EDM4hepUtil::writeMeasurement( edm4hep::MutableTrackerHitPlane to, const Cluster* fromCluster, edm4hep::TrackerHitCollection& toClusters, const MapGeometryIdTo& geometryMapper) { - Acts::GeometryIdentifier geoId = - from.sourceLink().template get().geometryId(); + Acts::GeometryIdentifier geoId = from.geometryId(); if (geometryMapper) { // no need for digitization as we only want to identify the sensor diff --git a/Examples/Io/Root/src/RootAthenaDumpReader.cpp b/Examples/Io/Root/src/RootAthenaDumpReader.cpp index 3ea44e78016..eea524fe544 100644 --- a/Examples/Io/Root/src/RootAthenaDumpReader.cpp +++ b/Examples/Io/Root/src/RootAthenaDumpReader.cpp @@ -299,7 +299,6 @@ RootAthenaDumpReader::readMeasurements( IndexMultimap measPartMap; // We cannot use im for the index since we might skip measurements - std::size_t idx = 0; std::unordered_map imIdxMap; for (int im = 0; im < nCL; im++) { @@ -375,7 +374,7 @@ RootAthenaDumpReader::readMeasurements( << CLloc_direction3[im]); const auto& locCov = CLlocal_cov->at(im); - std::optional sl; + Acts::GeometryIdentifier geoId; std::vector localParams; if (m_cfg.geometryIdMap && m_cfg.trackingGeometry) { const auto& geoIdMap = m_cfg.geometryIdMap->left; @@ -384,8 +383,7 @@ RootAthenaDumpReader::readMeasurements( continue; } - auto geoId = m_cfg.geometryIdMap->left.at(CLmoduleID[im]); - sl = IndexSourceLink(geoId, idx); + geoId = m_cfg.geometryIdMap->left.at(CLmoduleID[im]); auto surface = m_cfg.trackingGeometry->findSurface(geoId); if (surface == nullptr) { @@ -427,7 +425,7 @@ RootAthenaDumpReader::readMeasurements( // bounds? localParams = std::vector(loc->begin(), loc->end()); } else { - sl = IndexSourceLink(Acts::GeometryIdentifier(CLmoduleID[im]), idx); + geoId = Acts::GeometryIdentifier(CLmoduleID[im]); localParams = {CLloc_direction1[im], CLloc_direction2[im]}; } @@ -444,7 +442,8 @@ RootAthenaDumpReader::readMeasurements( digiPars.values = {localParams[0]}; } - createMeasurement(measurements, digiPars, *sl); + std::size_t measIndex = measurements.size(); + createMeasurement(measurements, geoId, digiPars); // Create measurement particles map and particles container for (const auto& [subevt, barcode] : @@ -459,12 +458,10 @@ RootAthenaDumpReader::readMeasurements( particles.emplace(dummyBarcode, Acts::PdgParticle::eInvalid); } measPartMap.insert( - std::pair{idx, dummyBarcode}); + std::pair{measIndex, dummyBarcode}); } - // Finally increment the measurement index - imIdxMap.emplace(im, idx); - ++idx; + imIdxMap.emplace(im, measIndex); } if (measurements.size() < static_cast(nCL)) { diff --git a/Examples/Io/Root/src/RootMeasurementWriter.cpp b/Examples/Io/Root/src/RootMeasurementWriter.cpp index a716cb721a3..b7ab332fdea 100644 --- a/Examples/Io/Root/src/RootMeasurementWriter.cpp +++ b/Examples/Io/Root/src/RootMeasurementWriter.cpp @@ -12,7 +12,6 @@ #include "Acts/Utilities/Enumerate.hpp" #include "ActsExamples/EventData/AverageSimHits.hpp" #include "ActsExamples/EventData/Index.hpp" -#include "ActsExamples/EventData/IndexSourceLink.hpp" #include "ActsExamples/EventData/Measurement.hpp" #include "ActsExamples/Framework/AlgorithmContext.hpp" #include "ActsExamples/Utilities/Range.hpp" @@ -270,8 +269,7 @@ ProcessCode RootMeasurementWriter::writeT( const ConstVariableBoundMeasurementProxy meas = measurements.getMeasurement(hitIdx); - Acts::GeometryIdentifier geoId = - meas.sourceLink().template get().geometryId(); + Acts::GeometryIdentifier geoId = meas.geometryId(); // find the corresponding surface auto surfaceItr = m_cfg.surfaceByIdentifier.find(geoId); if (surfaceItr == m_cfg.surfaceByIdentifier.end()) { diff --git a/Examples/Io/Root/src/RootTrackStatesWriter.cpp b/Examples/Io/Root/src/RootTrackStatesWriter.cpp index ad8467f239c..160eada776b 100644 --- a/Examples/Io/Root/src/RootTrackStatesWriter.cpp +++ b/Examples/Io/Root/src/RootTrackStatesWriter.cpp @@ -44,8 +44,6 @@ namespace ActsExamples { -class IndexSourceLink; - using Acts::VectorHelpers::eta; using Acts::VectorHelpers::perp; using Acts::VectorHelpers::phi; diff --git a/Examples/Python/python/acts/examples/reconstruction.py b/Examples/Python/python/acts/examples/reconstruction.py index 7ac0989744f..3bb898ca998 100644 --- a/Examples/Python/python/acts/examples/reconstruction.py +++ b/Examples/Python/python/acts/examples/reconstruction.py @@ -403,7 +403,6 @@ def addSeeding( logger.info("Using Hough Transform seeding") houghTransformConfig.inputSpacePoints = [spacePoints] houghTransformConfig.inputMeasurements = "measurements" - houghTransformConfig.inputSourceLinks = "sourcelinks" houghTransformConfig.outputProtoTracks = "prototracks" houghTransformConfig.outputSeeds = "seeds" houghTransformConfig.trackingGeometry = trackingGeometry @@ -635,7 +634,6 @@ def addSpacePointsMaking( logLevel = acts.examples.defaultLogging(sequence, logLevel)() spAlg = acts.examples.SpacePointMaker( level=logLevel, - inputSourceLinks="sourcelinks", inputMeasurements="measurements", outputSpacePoints="spacepoints", trackingGeometry=trackingGeometry, @@ -1168,7 +1166,6 @@ def addGbtsSeeding( geometrySelection=acts.examples.readJsonGeometryList( str(geoSelectionConfigFile) ), - inputSourceLinks="sourcelinks", trackingGeometry=trackingGeometry, fill_module_csv=False, inputClusters="clusters", @@ -1528,7 +1525,6 @@ def addCKFTracks( ] ), inputMeasurements="measurements", - inputSourceLinks="sourcelinks", inputInitialTrackParameters="estimatedparameters", inputSeeds=( "estimatedseeds" @@ -1813,7 +1809,6 @@ def addExaTrkX( s.addAlgorithm( acts.examples.SpacePointMaker( level=customLogLevel(), - inputSourceLinks="sourcelinks", inputMeasurements="measurements", outputSpacePoints="spacepoints", trackingGeometry=trackingGeometry, diff --git a/Examples/Python/python/acts/examples/simulation.py b/Examples/Python/python/acts/examples/simulation.py index 125ce422c16..b3b1046dc70 100644 --- a/Examples/Python/python/acts/examples/simulation.py +++ b/Examples/Python/python/acts/examples/simulation.py @@ -818,7 +818,6 @@ def addDigitization( surfaceByIdentifier=trackingGeometry.geoIdSurfaceMap(), randomNumbers=rnd, inputSimHits="simhits", - outputSourceLinks="sourcelinks", outputMeasurements="measurements", outputMeasurementParticlesMap="measurement_particles_map", outputMeasurementSimHitsMap="measurement_simhits_map", diff --git a/Examples/Python/src/Digitization.cpp b/Examples/Python/src/Digitization.cpp index a68d4871724..c392d6dcc8c 100644 --- a/Examples/Python/src/Digitization.cpp +++ b/Examples/Python/src/Digitization.cpp @@ -62,7 +62,6 @@ void addDigitization(Context& ctx) { ACTS_PYTHON_STRUCT_BEGIN(c, Config); ACTS_PYTHON_MEMBER(inputSimHits); - ACTS_PYTHON_MEMBER(outputSourceLinks); ACTS_PYTHON_MEMBER(outputMeasurements); ACTS_PYTHON_MEMBER(outputClusters); ACTS_PYTHON_MEMBER(outputMeasurementParticlesMap); diff --git a/Examples/Python/src/EDM4hepComponent.cpp b/Examples/Python/src/EDM4hepComponent.cpp index 5017596b7db..75746587be8 100644 --- a/Examples/Python/src/EDM4hepComponent.cpp +++ b/Examples/Python/src/EDM4hepComponent.cpp @@ -42,7 +42,7 @@ PYBIND11_MODULE(ActsPythonBindingsEDM4hep, m) { ACTS_PYTHON_DECLARE_READER(ActsExamples::EDM4hepMeasurementReader, m, "EDM4hepMeasurementReader", inputPath, outputMeasurements, outputMeasurementSimHitsMap, - outputSourceLinks, outputClusters); + outputClusters); ACTS_PYTHON_DECLARE_WRITER(ActsExamples::EDM4hepMeasurementWriter, m, "EDM4hepMeasurementWriter", inputMeasurements, diff --git a/Examples/Python/src/ExaTrkXTrackFinding.cpp b/Examples/Python/src/ExaTrkXTrackFinding.cpp index db9190e7f66..3778e8576f5 100644 --- a/Examples/Python/src/ExaTrkXTrackFinding.cpp +++ b/Examples/Python/src/ExaTrkXTrackFinding.cpp @@ -251,9 +251,8 @@ void addExaTrkXTrackFinding(Context &ctx) { ACTS_PYTHON_DECLARE_ALGORITHM( ActsExamples::TrackFindingFromPrototrackAlgorithm, mex, "TrackFindingFromPrototrackAlgorithm", inputProtoTracks, - inputMeasurements, inputSourceLinks, inputInitialTrackParameters, - outputTracks, measurementSelectorCfg, trackingGeometry, magneticField, - findTracks, tag); + inputMeasurements, inputInitialTrackParameters, outputTracks, + measurementSelectorCfg, trackingGeometry, magneticField, findTracks, tag); } } // namespace Acts::Python diff --git a/Examples/Python/src/Input.cpp b/Examples/Python/src/Input.cpp index e876efaa69c..b3ad9e1f657 100644 --- a/Examples/Python/src/Input.cpp +++ b/Examples/Python/src/Input.cpp @@ -63,8 +63,8 @@ void addInput(Context& ctx) { ACTS_PYTHON_DECLARE_READER( ActsExamples::CsvMeasurementReader, mex, "CsvMeasurementReader", inputDir, - outputMeasurements, outputMeasurementSimHitsMap, outputSourceLinks, - outputClusters, outputMeasurementParticlesMap, inputSimHits); + outputMeasurements, outputMeasurementSimHitsMap, outputClusters, + outputMeasurementParticlesMap, inputSimHits); ACTS_PYTHON_DECLARE_READER(ActsExamples::CsvSimHitReader, mex, "CsvSimHitReader", inputDir, inputStem, diff --git a/Examples/Python/src/TrackFinding.cpp b/Examples/Python/src/TrackFinding.cpp index 4179d58d94a..ad3ad364ce7 100644 --- a/Examples/Python/src/TrackFinding.cpp +++ b/Examples/Python/src/TrackFinding.cpp @@ -58,10 +58,9 @@ namespace Acts::Python { void addTrackFinding(Context& ctx) { auto [m, mex] = ctx.get("main", "examples"); - ACTS_PYTHON_DECLARE_ALGORITHM(ActsExamples::SpacePointMaker, mex, - "SpacePointMaker", inputSourceLinks, - inputMeasurements, outputSpacePoints, - trackingGeometry, geometrySelection); + ACTS_PYTHON_DECLARE_ALGORITHM( + ActsExamples::SpacePointMaker, mex, "SpacePointMaker", inputMeasurements, + outputSpacePoints, trackingGeometry, geometrySelection); { using Config = Acts::SeedFilterConfig; @@ -274,14 +273,14 @@ void addTrackFinding(Context& ctx) { ACTS_PYTHON_DECLARE_ALGORITHM( ActsExamples::GbtsSeedingAlgorithm, mex, "GbtsSeedingAlgorithm", inputSpacePoints, outputSeeds, seedFilterConfig, seedFinderConfig, - seedFinderOptions, layerMappingFile, geometrySelection, inputSourceLinks, - trackingGeometry, ActsGbtsMap, fill_module_csv, inputClusters); + seedFinderOptions, layerMappingFile, geometrySelection, trackingGeometry, + ActsGbtsMap, fill_module_csv, inputClusters); ACTS_PYTHON_DECLARE_ALGORITHM( ActsExamples::HoughTransformSeeder, mex, "HoughTransformSeeder", - inputSpacePoints, outputProtoTracks, inputSourceLinks, trackingGeometry, - geometrySelection, inputMeasurements, subRegions, nLayers, xMin, xMax, - yMin, yMax, houghHistSize_x, houghHistSize_y, hitExtend_x, threshold, + inputSpacePoints, outputProtoTracks, trackingGeometry, geometrySelection, + inputMeasurements, subRegions, nLayers, xMin, xMax, yMin, yMax, + houghHistSize_x, houghHistSize_y, hitExtend_x, threshold, localMaxWindowSize, kA); ACTS_PYTHON_DECLARE_ALGORITHM(ActsExamples::MuonHoughSeeder, mex, @@ -323,7 +322,6 @@ void addTrackFinding(Context& ctx) { auto c = py::class_(alg, "Config").def(py::init<>()); ACTS_PYTHON_STRUCT_BEGIN(c, Config); ACTS_PYTHON_MEMBER(inputMeasurements); - ACTS_PYTHON_MEMBER(inputSourceLinks); ACTS_PYTHON_MEMBER(inputInitialTrackParameters); ACTS_PYTHON_MEMBER(inputSeeds); ACTS_PYTHON_MEMBER(outputTracks); diff --git a/Examples/Python/src/Utilities.cpp b/Examples/Python/src/Utilities.cpp index 7a68a6a3bdb..8993da1c46a 100644 --- a/Examples/Python/src/Utilities.cpp +++ b/Examples/Python/src/Utilities.cpp @@ -51,7 +51,7 @@ void addUtilities(Context& ctx) { ACTS_PYTHON_DECLARE_ALGORITHM( ActsExamples::MeasurementMapSelector, mex, "MeasurementMapSelector", - inputMeasurementParticleMap, inputSourceLinks, + inputMeasurements, inputMeasurementParticleMap, outputMeasurementParticleMap, geometrySelection); ACTS_PYTHON_DECLARE_ALGORITHM(ActsExamples::PrototracksToTracks, mex, diff --git a/Examples/Python/tests/test_reader.py b/Examples/Python/tests/test_reader.py index f4e803776d5..3d458cb8009 100644 --- a/Examples/Python/tests/test_reader.py +++ b/Examples/Python/tests/test_reader.py @@ -206,7 +206,6 @@ def test_csv_meas_reader(tmp_path, fatras, trk_geo, conf_const): level=acts.logging.WARNING, outputMeasurements="measurements", outputMeasurementSimHitsMap="simhitsmap", - outputSourceLinks="sourcelinks", outputMeasurementParticlesMap="meas_ptcl_map", inputSimHits=simAlg.config.outputSimHits, inputDir=str(out), @@ -215,7 +214,7 @@ def test_csv_meas_reader(tmp_path, fatras, trk_geo, conf_const): algs = [ AssertCollectionExistsAlg(k, f"check_alg_{k}", acts.logging.WARNING) - for k in ("measurements", "simhitsmap", "sourcelinks", "meas_ptcl_map") + for k in ("measurements", "simhitsmap", "meas_ptcl_map") ] for alg in algs: s.addAlgorithm(alg) @@ -363,14 +362,13 @@ def test_edm4hep_measurement_reader(tmp_path, fatras, conf_const): level=acts.logging.WARNING, outputMeasurements="measurements", outputMeasurementSimHitsMap="simhitsmap", - outputSourceLinks="sourcelinks", inputPath=str(out), ) ) algs = [ AssertCollectionExistsAlg(k, f"check_alg_{k}", acts.logging.WARNING) - for k in ("measurements", "simhitsmap", "sourcelinks") + for k in ("measurements", "simhitsmap") ] for alg in algs: s.addAlgorithm(alg) diff --git a/Tests/CommonHelpers/Acts/Tests/CommonHelpers/WhiteBoardUtilities.hpp b/Tests/CommonHelpers/Acts/Tests/CommonHelpers/WhiteBoardUtilities.hpp index f40f658e63e..85a760bd6af 100644 --- a/Tests/CommonHelpers/Acts/Tests/CommonHelpers/WhiteBoardUtilities.hpp +++ b/Tests/CommonHelpers/Acts/Tests/CommonHelpers/WhiteBoardUtilities.hpp @@ -15,6 +15,7 @@ #include namespace Acts::Test { + struct DummySequenceElement : public ActsExamples::SequenceElement { ActsExamples::ProcessCode initialize() override { return {}; }; ActsExamples::ProcessCode finalize() override { return {}; }; @@ -102,4 +103,5 @@ struct GenericReadWriteTool { return get(get, std::tuple<>{}, std::integral_constant{}); } }; + } // namespace Acts::Test diff --git a/Tests/UnitTests/Examples/EventData/MeasurementTests.cpp b/Tests/UnitTests/Examples/EventData/MeasurementTests.cpp index fc3d33d801f..d59ff4a135e 100644 --- a/Tests/UnitTests/Examples/EventData/MeasurementTests.cpp +++ b/Tests/UnitTests/Examples/EventData/MeasurementTests.cpp @@ -11,9 +11,8 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/TrackParametrization.hpp" -#include "Acts/EventData/SourceLink.hpp" #include "Acts/EventData/detail/GenerateParameters.hpp" -#include "Acts/EventData/detail/TestSourceLink.hpp" +#include "Acts/Geometry/GeometryIdentifier.hpp" #include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" #include "ActsExamples/EventData/Measurement.hpp" @@ -30,15 +29,13 @@ using namespace Acts; using namespace Acts::detail::Test; using namespace ActsExamples; -using SourceLink = Acts::detail::Test::TestSourceLink; namespace bd = boost::unit_test::data; namespace { constexpr BoundIndices boundIndices[] = { eBoundLoc0, eBoundLoc1, eBoundTime, eBoundPhi, eBoundTheta, eBoundQOverP, }; -const TestSourceLink sourceOrig; -const Acts::SourceLink source{sourceOrig}; +constexpr Acts::GeometryIdentifier geoId = 1; // fix seed for reproducible tests std::default_random_engine rng(123); } // namespace @@ -54,8 +51,7 @@ BOOST_DATA_TEST_CASE(VariableBoundOne, bd::make(boundIndices), index) { auto [params, cov] = generateParametersCovariance(rng); - FixedBoundMeasurementProxy<1> meas = container.makeMeasurement<1>(); - meas.setSourceLink(source); + FixedBoundMeasurementProxy<1> meas = container.makeMeasurement<1>(geoId); meas.setSubspaceIndices(std::array{index}); meas.parameters() = params; meas.covariance() = cov; @@ -66,8 +62,7 @@ BOOST_DATA_TEST_CASE(VariableBoundOne, bd::make(boundIndices), index) { } BOOST_CHECK_EQUAL(meas.parameters(), params); BOOST_CHECK_EQUAL(meas.covariance(), cov); - BOOST_CHECK_EQUAL(meas.sourceLink().template get(), - sourceOrig); + BOOST_CHECK_EQUAL(meas.geometryId(), geoId); } BOOST_DATA_TEST_CASE(VariableBoundOneEmplace, bd::make(boundIndices), index) { @@ -76,7 +71,7 @@ BOOST_DATA_TEST_CASE(VariableBoundOneEmplace, bd::make(boundIndices), index) { auto [params, cov] = generateParametersCovariance(rng); FixedBoundMeasurementProxy<1> meas = - container.emplaceMeasurement<1>(source, std::array{index}, params, cov); + container.emplaceMeasurement<1>(geoId, std::array{index}, params, cov); BOOST_CHECK_EQUAL(meas.size(), 1); for (auto i : boundIndices) { @@ -84,8 +79,7 @@ BOOST_DATA_TEST_CASE(VariableBoundOneEmplace, bd::make(boundIndices), index) { } BOOST_CHECK_EQUAL(meas.parameters(), params); BOOST_CHECK_EQUAL(meas.covariance(), cov); - BOOST_CHECK_EQUAL(meas.sourceLink().template get(), - sourceOrig); + BOOST_CHECK_EQUAL(meas.geometryId(), geoId); } BOOST_AUTO_TEST_CASE(VariableBoundAll) { @@ -94,8 +88,7 @@ BOOST_AUTO_TEST_CASE(VariableBoundAll) { auto [params, cov] = generateBoundParametersCovariance(rng); FixedBoundMeasurementProxy meas = - container.makeMeasurement(); - meas.setSourceLink(source); + container.makeMeasurement(geoId); meas.setSubspaceIndices(std::array{eBoundLoc0, eBoundLoc1, eBoundTime, eBoundPhi, eBoundTheta, eBoundQOverP}); meas.parameters() = params; @@ -107,7 +100,7 @@ BOOST_AUTO_TEST_CASE(VariableBoundAll) { } BOOST_CHECK_EQUAL(meas.parameters(), params); BOOST_CHECK_EQUAL(meas.covariance(), cov); - BOOST_CHECK_EQUAL(meas.sourceLink().get(), sourceOrig); + BOOST_CHECK_EQUAL(meas.geometryId(), geoId); } BOOST_AUTO_TEST_CASE(VariableBoundAllEmplace) { @@ -117,7 +110,7 @@ BOOST_AUTO_TEST_CASE(VariableBoundAllEmplace) { FixedBoundMeasurementProxy meas = container.emplaceMeasurement( - source, + geoId, std::array{eBoundLoc0, eBoundLoc1, eBoundTime, eBoundPhi, eBoundTheta, eBoundQOverP}, params, cov); @@ -128,7 +121,7 @@ BOOST_AUTO_TEST_CASE(VariableBoundAllEmplace) { } BOOST_CHECK_EQUAL(meas.parameters(), params); BOOST_CHECK_EQUAL(meas.covariance(), cov); - BOOST_CHECK_EQUAL(meas.sourceLink().get(), sourceOrig); + BOOST_CHECK_EQUAL(meas.geometryId(), geoId); } BOOST_AUTO_TEST_CASE(VariableBoundReassign) { @@ -137,8 +130,7 @@ BOOST_AUTO_TEST_CASE(VariableBoundReassign) { // generate w/ two parameter auto [params1, cov1] = generateParametersCovariance(rng); - VariableBoundMeasurementProxy meas = container.makeMeasurement(2); - meas.setSourceLink(source); + VariableBoundMeasurementProxy meas = container.makeMeasurement(2, geoId); meas.setSubspaceIndices(std::array{eBoundPhi, eBoundTheta}); meas.parameters() = params1; meas.covariance() = cov1; @@ -154,8 +146,7 @@ BOOST_AUTO_TEST_CASE(VariableBoundReassign) { // reassign w/ all parameters auto [paramsN, covN] = generateBoundParametersCovariance(rng); - meas = container.makeMeasurement(eBoundSize); - meas.setSourceLink(source); + meas = container.makeMeasurement(eBoundSize, geoId); meas.setSubspaceIndices(std::array{eBoundLoc0, eBoundLoc1, eBoundTime, eBoundPhi, eBoundTheta, eBoundQOverP}); meas.parameters() = paramsN; diff --git a/Tests/UnitTests/Examples/Io/Csv/MeasurementReaderWriterTests.cpp b/Tests/UnitTests/Examples/Io/Csv/MeasurementReaderWriterTests.cpp index 7786a5ec8a1..c9c21b0983a 100644 --- a/Tests/UnitTests/Examples/Io/Csv/MeasurementReaderWriterTests.cpp +++ b/Tests/UnitTests/Examples/Io/Csv/MeasurementReaderWriterTests.cpp @@ -29,7 +29,6 @@ using namespace ActsExamples; using namespace Acts::Test; BOOST_AUTO_TEST_CASE(CsvMeasurementRoundTrip) { - IndexSourceLinkContainer sourceLinksOriginal; MeasurementContainer measOriginal; ClusterContainer clusterOriginal; IndexMultimap mapOriginal; @@ -45,14 +44,11 @@ BOOST_AUTO_TEST_CASE(CsvMeasurementRoundTrip) { std::uniform_real_distribution distf(0.0, 1.0); for (auto i = 0ul; i < nMeasurements; ++i) { - IndexSourceLink sl(someGeoId, static_cast(i)); - sourceLinksOriginal.insert(sl); - Acts::Vector2 p = Acts::Vector2::Random(); Acts::SquareMatrix2 c = Acts::SquareMatrix2::Random(); - FixedBoundMeasurementProxy<2> m = measOriginal.makeMeasurement<2>(); - m.setSourceLink(Acts::SourceLink(sl)); + FixedBoundMeasurementProxy<2> m = + measOriginal.makeMeasurement<2>(someGeoId); m.setSubspaceIndices(std::array{Acts::eBoundLoc0, Acts::eBoundLoc1}); m.parameters() = p; m.covariance() = c; @@ -118,14 +114,12 @@ BOOST_AUTO_TEST_CASE(CsvMeasurementRoundTrip) { readerConfig.outputMeasurementSimHitsMap = writerConfig.inputMeasurementSimHitsMap; readerConfig.outputClusters = writerConfig.inputClusters; - readerConfig.outputSourceLinks = "sourcelinks"; CsvMeasurementReader reader(readerConfig, Acts::Logging::WARNING); - auto readTool = - writeTool.add(readerConfig.outputSourceLinks, sourceLinksOriginal); + auto readTool = writeTool.add(readerConfig.outputMeasurements, measOriginal); - const auto [measRead, clusterRead, mapRead, sourceLinksRead] = + const auto [measRead, clusterRead, mapRead, measRead2] = readTool.read(reader); /////////// @@ -164,10 +158,10 @@ BOOST_AUTO_TEST_CASE(CsvMeasurementRoundTrip) { BOOST_REQUIRE(a == b); } - static_assert(std::is_same_v, - decltype(sourceLinksOriginal)>); - BOOST_REQUIRE(sourceLinksRead.size() == sourceLinksOriginal.size()); - for (const auto &[a, b] : Acts::zip(sourceLinksRead, sourceLinksOriginal)) { + static_assert( + std::is_same_v, decltype(measOriginal)>); + BOOST_REQUIRE(measRead.size() == measOriginal.size()); + for (const auto &[a, b] : Acts::zip(measRead, measOriginal)) { BOOST_REQUIRE(a.geometryId() == b.geometryId()); BOOST_REQUIRE(a.index() == b.index()); } From 4417bb6368d3975f899da0ddc8053a51e3977b9b Mon Sep 17 00:00:00 2001 From: Paul Gessinger Date: Tue, 15 Oct 2024 15:22:48 +0200 Subject: [PATCH 06/21] fix: Incorrect sanity check in TrackingVolume removed (#3734) This is not actually correct, as the boundary surfaces are created unconditionally. --- Core/src/Geometry/TrackingVolume.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Core/src/Geometry/TrackingVolume.cpp b/Core/src/Geometry/TrackingVolume.cpp index ad2c939fcbd..e7d069b80c5 100644 --- a/Core/src/Geometry/TrackingVolume.cpp +++ b/Core/src/Geometry/TrackingVolume.cpp @@ -347,15 +347,6 @@ void TrackingVolume::closeGeometry( std::unordered_map& volumeMap, std::size_t& vol, const GeometryIdentifierHook& hook, const Logger& logger) { - if (!boundarySurfaces().empty() && !portals().empty()) { - ACTS_ERROR( - "TrackingVolume::closeGeometry: Volume " - << volumeName() - << " has both boundary surfaces and portals. This is not supported."); - throw std::invalid_argument( - "Volume has both boundary surfaces and portals"); - } - if (m_confinedVolumes && !volumes().empty()) { ACTS_ERROR( "TrackingVolume::closeGeometry: Volume " From 9981b76022b62107252f607398265d2b7a4ef8ec Mon Sep 17 00:00:00 2001 From: Paul Gessinger Date: Wed, 16 Oct 2024 07:52:43 +0200 Subject: [PATCH 07/21] build: Pick up GeoModel v6 or v7 (#3736) --- CMakeLists.txt | 22 ++++++++-- docs/getting_started.md | 91 ++++++++++++++++++++--------------------- 2 files changed, 62 insertions(+), 51 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bbfae3efa8..e8e9ab3f583 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,7 +31,6 @@ option(ACTS_FORCE_ASSERTIONS "Force assertions regardless of build type" OFF) option(ACTS_USE_SYSTEM_LIBS "Use system libraries by default" OFF) # plugins related options option(ACTS_USE_SYSTEM_ACTSVG "Use the ActSVG system library" ${ACTS_USE_SYSTEM_LIBS}) -option(ACTS_USE_SYSTEM_GEOMODEL "Use a system-provided GeoModel installation" ${ACTS_USE_SYSTEM_LIBS}) option(ACTS_USE_SYSTEM_COVFIE "Use a system-provided covfie installation" ${ACTS_USE_SYSTEM_LIBS}) option(ACTS_USE_SYSTEM_DETRAY "Use a system-provided detray installation" ${ACTS_USE_SYSTEM_LIBS}) option(ACTS_USE_SYSTEM_TRACCC "Use a system-provided traccc installation" ${ACTS_USE_SYSTEM_LIBS}) @@ -229,7 +228,6 @@ set(_acts_actsvg_version 0.4.50) set(_acts_boost_version 1.71.0) set(_acts_dd4hep_version 1.21) set(_acts_edm4hep_version 0.7) -set(_acts_geomodel_version 6.3.0) set(_acts_eigen3_version 3.4.0) 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 @@ -374,8 +372,24 @@ if(ACTS_BUILD_PLUGIN_JSON) endif() endif() if(ACTS_BUILD_PLUGIN_GEOMODEL) - find_package(GeoModelCore ${_acts_geomodel_version} REQUIRED CONFIG) - find_package(GeoModelIO ${_acts_geomodel_version} REQUIRED CONFIG) + find_package(GeoModelCore CONFIG) + if(NOT GeoModelCore_FOUND) + message( + FATAL_ERROR + "GeoModel not found. Please install GeoModel or set ACTS_BUILD_PLUGIN_GEOMODEL to OFF." + ) + endif() + + set(_gm_ver_min 6.3.0) + + if(GeoModelCore_VERSION VERSION_LESS _gm_ver_min) + message( + FATAL_ERROR + "GeoModel version ${GeoModelCore_VERSION} is insufficient. Please install GeoModel version ${_gm_ver_min} or newer." + ) + endif() + # find other GeoModel components of EXACT same version + find_package(GeoModelIO ${GeoModelCore_VERSION} REQUIRED EXACT CONFIG) endif() if(ACTS_BUILD_PLUGIN_TGEO) find_package( diff --git a/docs/getting_started.md b/docs/getting_started.md index fbc247a3e05..f17ec5abcf1 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -9,9 +9,9 @@ following commands will clone the repository, configure, and build the core library: ```console -$ git clone https://github.com/acts-project/acts -$ cmake -B -S -$ cmake --build +git clone https://github.com/acts-project/acts +cmake -B -S +cmake --build ``` For a full list of dependencies, including specific versions, see the @@ -23,27 +23,27 @@ section. The following dependencies are required to build the ACTS core library: -- A C++17 compatible compiler (recent versions of either gcc and clang should work) -- [CMake](https://cmake.org) >= 3.14 -- [Boost](https://www.boost.org) >= 1.71 with `filesystem`, `program_options`, and `unit_test_framework` -- [Eigen](https://eigen.tuxfamily.org) >= 3.3.7 +- A C++17 compatible compiler (recent versions of either gcc and clang should work) +- [CMake](https://cmake.org) >= 3.14 +- [Boost](https://www.boost.org) >= 1.71 with `filesystem`, `program_options`, and `unit_test_framework` +- [Eigen](https://eigen.tuxfamily.org) >= 3.3.7 The following dependencies are optional and are needed to build additional components: -- [CUDA](https://developer.nvidia.com/cuda-zone) for the CUDA plugin and the Exa.TrkX plugin and its examples -- [DD4hep](http://dd4hep.cern.ch) >= 1.11 for the DD4hep plugin and some examples -- [Doxygen](http://doxygen.org) >= 1.8.15 for the documentation -- [Geant4](https://geant4.org/) for some examples -- [HepMC](https://gitlab.cern.ch/hepmc/HepMC3) >= 3.2.1 for some examples -- [Intel Threading Building Blocks](https://github.com/oneapi-src/oneTBB) >= 2020.1 for the examples -- [ONNX Runtime](https://onnxruntime.ai/) >= 1.12.0 for the ONNX plugin, the Exa.TrkX plugin and some examples -- [Pythia8](https://pythia.org) for some examples -- [ROOT](https://root.cern.ch) >= 6.20 for the TGeo plugin and the examples -- [Sphinx](https://www.sphinx-doc.org) >= 2.0 with [Breathe](https://breathe.readthedocs.io/en/latest/), [Exhale](https://exhale.readthedocs.io/en/latest/), and [recommonmark](https://recommonmark.readthedocs.io/en/latest/index.html) extensions for the documentation -- [cugraph](https://github.com/rapidsai/cugraph) for the Exa.TrkX plugin -- [libtorch](https://pytorch.org/cppdocs/installing.html) for the Exa.TrkX plugin -- [Pybind11](https://github.com/pybind/pybind11) for the Python bindings of the examples +- [CUDA](https://developer.nvidia.com/cuda-zone) for the CUDA plugin and the Exa.TrkX plugin and its examples +- [DD4hep](http://dd4hep.cern.ch) >= 1.11 for the DD4hep plugin and some examples +- [Doxygen](http://doxygen.org) >= 1.8.15 for the documentation +- [Geant4](https://geant4.org/) for some examples +- [HepMC](https://gitlab.cern.ch/hepmc/HepMC3) >= 3.2.1 for some examples +- [Intel Threading Building Blocks](https://github.com/oneapi-src/oneTBB) >= 2020.1 for the examples +- [ONNX Runtime](https://onnxruntime.ai/) >= 1.12.0 for the ONNX plugin, the Exa.TrkX plugin and some examples +- [Pythia8](https://pythia.org) for some examples +- [ROOT](https://root.cern.ch) >= 6.20 for the TGeo plugin and the examples +- [Sphinx](https://www.sphinx-doc.org) >= 2.0 with [Breathe](https://breathe.readthedocs.io/en/latest/), [Exhale](https://exhale.readthedocs.io/en/latest/), and [recommonmark](https://recommonmark.readthedocs.io/en/latest/index.html) extensions for the documentation +- [cugraph](https://github.com/rapidsai/cugraph) for the Exa.TrkX plugin +- [libtorch](https://pytorch.org/cppdocs/installing.html) for the Exa.TrkX plugin +- [Pybind11](https://github.com/pybind/pybind11) for the Python bindings of the examples There are some additional dependencies that are automatically provided as part of the build system. @@ -69,7 +69,7 @@ runs the configuration and searches for the dependencies. The `` directory is automatically created. ```console -$ cmake -B -S +cmake -B -S ``` The build can be configured via various options that are listed in detail in the @@ -77,19 +77,19 @@ The build can be configured via various options that are listed in detail in the The previous command could be e.g. modified to ```console -$ cmake -B -S -DACTS_BUILD_UNITTESTS=on -DACTS_BUILD_FATRAS=on +cmake -B -S -DACTS_BUILD_UNITTESTS=on -DACTS_BUILD_FATRAS=on ``` After the configuration succeeded, the software is build. This is also done with cmake via the following command ```console -$ cmake --build +cmake --build ``` This automatically calls the configure build tool, e.g. Make or Ninja. To build only a specific target, the target names has to be separated from the CMake options by `--`, i.e. ```console -$ cmake --build -- ActsFatras # to build the Fatras library +cmake --build -- ActsFatras # to build the Fatras library ``` The build commands are the same regardless of where you are building the @@ -103,8 +103,8 @@ e.g. CERNs lxplus login machines, the dependencies can be easily satisfied via a LCG releases available through CVMFS. A setup script is provided to activate a compatible releases that can be used as follows: ```console -$ cd -$ source CI/setup_cvmfs_lcg.sh +cd +source CI/setup_cvmfs_lcg.sh ``` After sourcing the setup script, you can build ACTS as described above. The @@ -112,10 +112,10 @@ following commands will build ACTS in the `/build` directory with the Fatras component. ```console -$ cd -$ source CI/setup_cvmfs_lcg.sh -$ cmake -B build -S . -DACTS_BUILD_FATRAS=on -$ cmake --build build +cd +source CI/setup_cvmfs_lcg.sh +cmake -B build -S . -DACTS_BUILD_FATRAS=on +cmake --build build ``` ### In a container @@ -144,13 +144,13 @@ available tags, e.g. for the `ubuntu2004` image, you can use the following command: ```console -$ docker search --list-tags ghcr.io/acts-project/ubuntu2404 +docker search --list-tags ghcr.io/acts-project/ubuntu2404 ``` The following command then downloads a stable tag of the `ubuntu2404` image: ```console -$ docker pull ghcr.io/acts-project/ubuntu2404:51 +docker pull ghcr.io/acts-project/ubuntu2404:51 ``` This should print the image id as part of the output. You can also find out the @@ -163,7 +163,7 @@ following command will make the source directory available as `/acts` in the container and start an interactive `bash` shell ```console -$ docker run --volume=:/acts:ro --interactive --tty /bin/bash +docker run --volume=:/acts:ro --interactive --tty /bin/bash ``` where `` is the image id that was previously mentioned. If you are using the Ubuntu-based image you are already good to go. For the images based on LCG releases, you can now activate the LCG release in the container shell by sourcing a setup script: @@ -191,6 +191,7 @@ install ACTS' dependencies; see the [building with Spack](misc/spack) page for more information. (build_docs)= + ## Building the documentation The documentation uses [Doxygen][doxygen] to extract the source code @@ -201,8 +202,8 @@ need to have [Doxygen][doxygen] version `1.9.5` or newer installed. package manager `pip`: ```console -$ cd -$ pip install -r docs/requirements.txt +cd +pip install -r docs/requirements.txt ``` :::{tip} @@ -211,8 +212,8 @@ environment](https://realpython.com/python-virtual-environments-a-primer/) for this purpose! For example, run ```console -$ python -m venv docvenv -$ source docvenv/bin/activate +python -m venv docvenv +source docvenv/bin/activate ``` to create a local virtual environment, and then run the `pip` command above. @@ -221,13 +222,13 @@ to create a local virtual environment, and then run the `pip` command above. To activate the documentation build targets, the `ACTS_BUILD_DOCS` option has to be set ```console -$ cmake -B -S -DACTS_BUILD_DOCS=on +cmake -B -S -DACTS_BUILD_DOCS=on ``` Then the documentation can be build with this target ```console -$ cmake --build --target docs +cmake --build --target docs ``` The default option includes the Doxygen, Sphinx, and the Breathe extension, @@ -239,8 +240,6 @@ of errors you will need to manually pull in symbols to be documented. [doxygen]: https://doxygen.nl/ [sphinx]: https://www.sphinx-doc.org [breathe]: https://breathe.readthedocs.io -[exhale]: https://exhale.readthedocs.io -[rtd_acts]: https://acts.readthedocs.io ## Build options @@ -248,7 +247,7 @@ CMake options can be set by adding `-D