From cd6a6979dbf1a25624897fba82a183a30582de99 Mon Sep 17 00:00:00 2001 From: Frederik Verdoner Barba Date: Fri, 27 Sep 2024 14:42:30 +0200 Subject: [PATCH] feat: Conversion and chain code in traccc This PR adds conversion code as well as the code to run simple host-side chain algorithms using traccc. Co-authored-by: Stephen Nicholas Swatman --- CMakeLists.txt | 5 + Examples/Algorithms/Traccc/CMakeLists.txt | 6 + .../Algorithms/Traccc/Common/CMakeLists.txt | 23 ++ .../Traccc/Conversion/CellMapConversion.hpp | 29 ++ .../Conversion/DigitizationConversion.hpp | 29 ++ .../Conversion/MeasurementConversion.hpp | 206 ++++++++++++++ .../Traccc/Conversion/MeasurementMatch.hpp | 65 +++++ .../Traccc/Conversion/SeedConversion.hpp | 134 ++++++++++ .../Conversion/SpacePointConversion.hpp | 120 +++++++++ .../Traccc/Conversion/TrackConversion.hpp | 104 +++++++ .../ActsExamples/Traccc/DetrayPropagator.hpp | 0 .../ActsExamples/Traccc/DetrayStore.hpp | 0 .../ActsExamples/Traccc/Io/ReadDetector.hpp | 39 +++ .../ActsExamples/Traccc/Measurement/Debug.hpp | 60 +++++ .../ActsExamples/Traccc/TracccChainConfig.hpp | 56 ++++ .../ActsExamples/Traccc/Util/IndexMap.hpp | 110 ++++++++ .../ActsExamples/Traccc/Util/MapUtil.hpp | 150 +++++++++++ .../src/Conversion/CellMapConversion.cpp | 83 ++++++ .../src/Conversion/DigitizationConversion.cpp | 51 ++++ .../src/Conversion/MeasurementConversion.cpp | 44 +++ .../Traccc/Common/src/Debug/Debug.cpp | 114 ++++++++ .../Algorithms/Traccc/Host/CMakeLists.txt | 13 + .../Traccc/Host/TracccChainAlgorithm.hpp | 101 +++++++ .../ActsExamples/Traccc/Host/Types.hpp | 60 +++++ .../Traccc/Host/src/TracccChainAlgorithm.cpp | 242 +++++++++++++++++ Examples/Python/CMakeLists.txt | 4 + Examples/Python/src/ModuleEntry.cpp | 4 + Examples/Python/src/Traccc.cpp | 39 ++- Examples/Python/src/TracccChainConfig.cpp | 181 +++++++++++++ Examples/Python/src/TracccChainConfigStub.cpp | 20 ++ Examples/Python/src/TracccChainHost.cpp | 37 +++ Examples/Python/src/TracccChainHostStub.cpp | 14 + Plugins/CMakeLists.txt | 1 + Plugins/Traccc/CMakeLists.txt | 25 ++ .../Acts/Plugins/Traccc/BarcodeMap.hpp | 42 +++ .../Acts/Plugins/Traccc/CellConversion.hpp | 55 ++++ .../Traccc/Detail/AlgebraConversion.hpp | 40 +++ .../Plugins/Traccc/DigitizationConfig.hpp | 27 ++ .../Acts/Plugins/Traccc/ReadGeometry.hpp | 35 +++ .../Acts/Plugins/Traccc/SurfaceMap.hpp | 43 +++ .../Acts/Plugins/Traccc/TrackConversion.hpp | 253 ++++++++++++++++++ Plugins/Traccc/src/CellConversion.cpp | 132 +++++++++ cmake/ActsConfig.cmake.in | 28 +- docs/getting_started.md | 1 + thirdparty/detray/CMakeLists.txt | 5 + thirdparty/traccc/CMakeLists.txt | 6 + thirdparty/vecmem/CMakeLists.txt | 5 + 47 files changed, 2809 insertions(+), 32 deletions(-) create mode 100644 Examples/Algorithms/Traccc/Common/CMakeLists.txt create mode 100644 Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/CellMapConversion.hpp create mode 100644 Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/DigitizationConversion.hpp create mode 100644 Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/MeasurementConversion.hpp create mode 100644 Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/MeasurementMatch.hpp create mode 100644 Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/SeedConversion.hpp create mode 100644 Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/SpacePointConversion.hpp create mode 100644 Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/TrackConversion.hpp rename Examples/Algorithms/Traccc/{ => Common}/include/ActsExamples/Traccc/DetrayPropagator.hpp (100%) rename Examples/Algorithms/Traccc/{ => Common}/include/ActsExamples/Traccc/DetrayStore.hpp (100%) create mode 100644 Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Io/ReadDetector.hpp create mode 100644 Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Measurement/Debug.hpp create mode 100644 Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/TracccChainConfig.hpp create mode 100644 Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Util/IndexMap.hpp create mode 100644 Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Util/MapUtil.hpp create mode 100644 Examples/Algorithms/Traccc/Common/src/Conversion/CellMapConversion.cpp create mode 100644 Examples/Algorithms/Traccc/Common/src/Conversion/DigitizationConversion.cpp create mode 100644 Examples/Algorithms/Traccc/Common/src/Conversion/MeasurementConversion.cpp create mode 100644 Examples/Algorithms/Traccc/Common/src/Debug/Debug.cpp create mode 100644 Examples/Algorithms/Traccc/Host/CMakeLists.txt create mode 100644 Examples/Algorithms/Traccc/Host/include/ActsExamples/Traccc/Host/TracccChainAlgorithm.hpp create mode 100644 Examples/Algorithms/Traccc/Host/include/ActsExamples/Traccc/Host/Types.hpp create mode 100644 Examples/Algorithms/Traccc/Host/src/TracccChainAlgorithm.cpp create mode 100644 Examples/Python/src/TracccChainConfig.cpp create mode 100644 Examples/Python/src/TracccChainConfigStub.cpp create mode 100644 Examples/Python/src/TracccChainHost.cpp create mode 100644 Examples/Python/src/TracccChainHostStub.cpp create mode 100644 Plugins/Traccc/CMakeLists.txt create mode 100644 Plugins/Traccc/include/Acts/Plugins/Traccc/BarcodeMap.hpp create mode 100644 Plugins/Traccc/include/Acts/Plugins/Traccc/CellConversion.hpp create mode 100644 Plugins/Traccc/include/Acts/Plugins/Traccc/Detail/AlgebraConversion.hpp create mode 100644 Plugins/Traccc/include/Acts/Plugins/Traccc/DigitizationConfig.hpp create mode 100644 Plugins/Traccc/include/Acts/Plugins/Traccc/ReadGeometry.hpp create mode 100644 Plugins/Traccc/include/Acts/Plugins/Traccc/SurfaceMap.hpp create mode 100644 Plugins/Traccc/include/Acts/Plugins/Traccc/TrackConversion.hpp create mode 100644 Plugins/Traccc/src/CellConversion.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bbfae3efa86..9849b6d2f868 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,6 +49,7 @@ option(ACTS_BUILD_PLUGIN_EDM4HEP "Build EDM4hep plugin" OFF) option(ACTS_BUILD_PLUGIN_FPEMON "Build FPE monitoring plugin" OFF) option(ACTS_BUILD_PLUGIN_GEOMODEL "Build GeoModel plugin" OFF) option(ACTS_BUILD_PLUGIN_TRACCC "Build Traccc plugin" OFF) +option(ACTS_TRACCC_ENABLE_CUDA "Enable CUDA for the traccc plugin" OFF) option(ACTS_BUILD_PLUGIN_GEANT4 "Build Geant4 plugin" OFF) option(ACTS_BUILD_PLUGIN_EXATRKX "Build the Exa.TrkX plugin" OFF) option(ACTS_EXATRKX_ENABLE_ONNX "Build the Onnx backend for the exatrkx plugin" OFF) @@ -443,6 +444,10 @@ if(ACTS_BUILD_PLUGIN_GEANT4) endif() if(ACTS_BUILD_PLUGIN_TRACCC) + # TODO: Algebra-plugins should set this up itself! + # Can be removed with traccc 0.16.0. + add_definitions(-DALGEBRA_PLUGINS_INCLUDE_ARRAY) + if(ACTS_USE_SYSTEM_ALGEBRAPLUGINS) find_package(algebra-plugins ${_acts_algebraplugins_version} REQUIRED) else() diff --git a/Examples/Algorithms/Traccc/CMakeLists.txt b/Examples/Algorithms/Traccc/CMakeLists.txt index 11837f122987..b3f4781ecd79 100644 --- a/Examples/Algorithms/Traccc/CMakeLists.txt +++ b/Examples/Algorithms/Traccc/CMakeLists.txt @@ -14,4 +14,10 @@ target_link_libraries( ActsPluginDetray ) +add_subdirectory(Common) +target_link_libraries(ActsExamplesTraccc INTERFACE ActsExamplesTracccCommon) + +add_subdirectory(Host) +target_link_libraries(ActsExamplesTraccc INTERFACE ActsExamplesTracccHost) + install(TARGETS ActsExamplesTraccc LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) diff --git a/Examples/Algorithms/Traccc/Common/CMakeLists.txt b/Examples/Algorithms/Traccc/Common/CMakeLists.txt new file mode 100644 index 000000000000..96118583f958 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/CMakeLists.txt @@ -0,0 +1,23 @@ +add_library( + ActsExamplesTracccCommon + SHARED + src/Conversion/CellMapConversion.cpp + src/Conversion/DigitizationConversion.cpp + src/Conversion/MeasurementConversion.cpp + src/Debug/Debug.cpp +) + +target_include_directories( + ActsExamplesTracccCommon + PUBLIC $ +) + +target_link_libraries( + ActsExamplesTracccCommon + PUBLIC ActsPluginTraccc ActsExamplesFramework ActsExamplesDigitization +) + +install( + TARGETS ActsExamplesTracccCommon + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} +) diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/CellMapConversion.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/CellMapConversion.hpp new file mode 100644 index 000000000000..f8add8cb8401 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/CellMapConversion.hpp @@ -0,0 +1,29 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2024 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include "Acts/Geometry/GeometryIdentifier.hpp" +#include "ActsExamples/EventData/Cluster.hpp" + +#include +#include +#include +#include + +#include "traccc/edm/cell.hpp" + +namespace ActsExamples::Traccc::Common::Conversion { + +/// @brief Converts a "geometry ID -> generic cell collection type" map to a "geometry ID -> traccc cell collection" map. +/// @note The function sets the module link of the cells in the output to 0. +/// @return Map from geometry ID to its cell data (as a vector of traccc cell data) +std::map> tracccCellsMap( + const std::map>& map); + +} // namespace ActsExamples::Traccc::Common::Conversion diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/DigitizationConversion.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/DigitizationConversion.hpp new file mode 100644 index 000000000000..7d251240e9ad --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/DigitizationConversion.hpp @@ -0,0 +1,29 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Acts include(s) +#include "Acts/Geometry/GeometryHierarchyMap.hpp" + +// Acts plugin include(s) +#include "Acts/Plugins/Traccc/DigitizationConfig.hpp" + +// Acts Examples include(s) +#include "ActsExamples/Digitization/DigitizationConfig.hpp" + +namespace ActsExamples::Traccc::Common::Conversion { + +/// @brief Creates a traccc digitalization config from an Acts geometry hierarchy map +/// that contains the digitization configuration. +/// @param config the Acts geometry hierarchy map that contains the digitization configuration. +/// @return a traccc digitization config. +Acts::TracccPlugin::DigitizationConfig tracccConfig( + const Acts::GeometryHierarchyMap& config); + +} // namespace ActsExamples::Traccc::Common::Conversion diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/MeasurementConversion.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/MeasurementConversion.hpp new file mode 100644 index 000000000000..523ca5ceb6a3 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/MeasurementConversion.hpp @@ -0,0 +1,206 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Plugin include(s) +#include "Acts/Plugins/Traccc/Detail/AlgebraConversion.hpp" + +// Acts include(s) +#include "Acts/Definitions/Algebra.hpp" +#include "Acts/Definitions/TrackParametrization.hpp" +#include "Acts/EventData/SourceLink.hpp" +#include "Acts/Geometry/GeometryIdentifier.hpp" +#include "ActsExamples/EventData/Measurement.hpp" + +// Acts Examples include(s) +#include "ActsExamples/EventData/IndexSourceLink.hpp" +#include "ActsExamples/Traccc/Util/MapUtil.hpp" + +// Detray include(s) +#include "detray/core/detector.hpp" +#include "detray/tracks/bound_track_parameters.hpp" + +// Traccc include(s) +#include "traccc/definitions/qualifiers.hpp" +#include "traccc/definitions/track_parametrization.hpp" +#include "traccc/edm/measurement.hpp" +#include "traccc/edm/track_state.hpp" + +// System include(s) +#include +#include +#include +#include +#include + +namespace ActsExamples::Traccc::Common::Conversion { + +// Custom hash and equals functions +// as some are not defined by std::hash and std::equal_to + +struct TracccMeasurementHash { + std::size_t operator()(const traccc::measurement& s) const noexcept { + return s.measurement_id; + } +}; + +struct ActsMeasurementHash { + std::size_t operator()( + const ActsExamples::MeasurementContainer::ConstVariableProxy& s) + const noexcept { + return static_cast( + s.sourceLink().get().index()); + } +}; + +struct ActsMeasurementEquals { + bool operator()( + const ActsExamples::MeasurementContainer::ConstVariableProxy& m1, + const ActsExamples::MeasurementContainer::ConstVariableProxy& m2) const { + auto lhsIdx = m1.sourceLink().get().index(); + auto rhsIdx = m2.sourceLink().get().index(); + return lhsIdx == rhsIdx; + } +}; + +/// @brief Converts a traccc bound index to an Acts bound index. +/// @param tracccBoundIndex the traccc bound index. +/// @returns an Acts bound index. +Acts::BoundIndices boundIndex(const traccc::bound_indices tracccBoundIndex); + +/// @brief Gets the the local position of the measurement. +/// @param measurement the Acts measurement. +/// @returns A two-dimensional vector containing the local position. +/// The first item in the vector is local position on axis 0 and +/// I.e., [local position (axis 0), local position (axis 1)]. +/// @note if the dimension is less than 2 then the remaining values are set to 0. +template +inline Acts::ActsVector<2> getLocal( + const ActsExamples::MeasurementContainer::ConstFixedProxy& + measurement) { + traccc::scalar loc0 = 0; + traccc::scalar loc1 = 0; + if constexpr (dim > Acts::BoundIndices::eBoundLoc0) { + loc0 = measurement.parameters()(Acts::BoundIndices::eBoundLoc0); + } + if constexpr (dim > Acts::BoundIndices::eBoundLoc1) { + loc1 = measurement.parameters()(Acts::BoundIndices::eBoundLoc1); + } + return Acts::ActsVector<2>(loc0, loc1); +} + +/// @brief Get the the local position of the measurement. +/// @param measurement the Acts bound variant measurement. +/// @return A two-dimensional vector containing the local position. +/// I.e., [local position (axis 0), local position (axis 1)]. +/// @note if the dimension is less than 2 then the remaining values are set to 0. +inline Acts::ActsVector<2> getLocal( + const ActsExamples::MeasurementContainer::ConstVariableProxy& measurement) { + traccc::scalar loc0 = 0; + traccc::scalar loc1 = 0; + if (measurement.size() > Acts::BoundIndices::eBoundLoc0) { + loc0 = measurement.parameters()(Acts::BoundIndices::eBoundLoc0); + } + if (measurement.size() > Acts::BoundIndices::eBoundLoc1) { + loc1 = measurement.parameters()(Acts::BoundIndices::eBoundLoc1); + } + return Acts::ActsVector<2>(loc0, loc1); +} + +/// @brief Get the the variance of the measurement. +/// @param measurement the Acts measurement. +/// @return A two-dimensional vector containing the variance. +/// I.e., [variance (axis 0), variance (axis 1)]. +/// @note if the dimension is less than 2 then the remaining values are set to 0. +template +inline Acts::ActsVector<2> getVariance( + const ActsExamples::MeasurementContainer::ConstFixedProxy& + measurement) { + traccc::scalar var0 = 0; + traccc::scalar var1 = 0; + if constexpr (dim >= Acts::BoundIndices::eBoundLoc0) { + var0 = measurement.covariance()(Acts::BoundIndices::eBoundLoc0, + Acts::BoundIndices::eBoundLoc0); + } + if constexpr (dim > Acts::BoundIndices::eBoundLoc1) { + var1 = measurement.covariance()(Acts::BoundIndices::eBoundLoc1, + Acts::BoundIndices::eBoundLoc1); + } + return Acts::ActsVector<2>(var0, var1); +} + +/// @brief Get the the variance of the measurement. +/// @param measurement the Acts bound variant measurement. +/// @return A two-dimensional vector containing the variance. +/// I.e., [variance (axis 0), variance (axis 1)]. +/// @note if the dimension is less than 2 then the remaining values are set to 0. +inline Acts::ActsVector<2> getVariance( + const ActsExamples::MeasurementContainer::ConstVariableProxy& measurement) { + traccc::scalar var0 = 0; + traccc::scalar var1 = 0; + if (measurement.size() >= Acts::BoundIndices::eBoundLoc0) { + var0 = measurement.covariance()(Acts::BoundIndices::eBoundLoc0, + Acts::BoundIndices::eBoundLoc0); + } + if (measurement.size() > Acts::BoundIndices::eBoundLoc1) { + var1 = measurement.covariance()(Acts::BoundIndices::eBoundLoc1, + Acts::BoundIndices::eBoundLoc1); + } + return Acts::ActsVector<2>(var0, var1); +} + +/// @brief Get the geometry ID from the measurement through its source link. +/// @note The sourcelink is assumed to be of type IndexSourceLink. +inline Acts::GeometryIdentifier getGeometryID( + const ActsExamples::MeasurementContainer::ConstVariableProxy& measurement) { + return measurement.sourceLink() + .template get() + .geometryId(); +} + +/// @brief Converts traccc measurements to acts measurements. +/// @param detector The detray detector, +/// @param measurements The traccc measurements, +/// @return A vector of Acts bound variant measurements. +/// @note The type IndexSourceLink is used for the measurements' source links. +template +inline auto convertMeasurements(const detector_t& detector, + iterator_t measurements_begin, + iterator_t measurements_end, + MeasurementContainer& measurementContainer) { + for (iterator_t i = measurements_begin; i != measurements_end; ++i) { + Acts::GeometryIdentifier moduleGeoId( + detector.surface((*i).surface_link).source); + Index measurementIdx = measurementContainer.size(); + IndexSourceLink idxSourceLink{moduleGeoId, measurementIdx}; + + Eigen::Matrix + indices(2); + + for (unsigned int j = 0; j < 2; j++) { + indices[j] = + boundIndex(traccc::bound_indices((*i).subs.get_indices()[j])); + } + + measurementContainer.emplaceMeasurement<2>( + Acts::SourceLink{idxSourceLink}, indices, + Acts::TracccPlugin::detail::toActsVector<2>((*i).local), + Eigen::DiagonalMatrix(2)>( + Acts::TracccPlugin::detail::toActsVector<2>((*i).variance)) + .toDenseMatrix()); + } + + return Util::makeConversionOneToOne( + measurements_begin, measurements_end, measurementContainer.cbegin(), + measurementContainer.cend(), TracccMeasurementHash{}, + std::equal_to{}); +} + +} // namespace ActsExamples::Traccc::Common::Conversion diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/MeasurementMatch.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/MeasurementMatch.hpp new file mode 100644 index 000000000000..31ea6f4d45b9 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/MeasurementMatch.hpp @@ -0,0 +1,65 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Acts include(s) +#include "ActsExamples/EventData/Measurement.hpp" + +// Acts Examples include(s) +#include "ActsExamples/Traccc/Conversion/MeasurementConversion.hpp" +#include "ActsExamples/Traccc/Util/IndexMap.hpp" +#include "ActsExamples/Traccc/Util/MapUtil.hpp" + +// Traccc include(s) +#include "traccc/edm/measurement.hpp" + +// System include(s) +#include +#include +#include +#include +#include + +namespace ActsExamples::Traccc::Common::Conversion { + +/// @brief Checks if two measurements are equal based on their geometry ID and position alone. +/// @note max_dist is the tolerance of distance in local position. +/// The distance between the local positions of the measurements must be +/// less or equal to this value to be considered equal. +/// @returns true or false depending on whether they are considered equal. +struct MeasurementAproxEquals { + bool operator()(const ActsExamples::MeasurementContainer::ConstVariableProxy& + measurement1, + const ActsExamples::MeasurementContainer::ConstVariableProxy& + measurement2) const { + auto gidEq = Conversion::getGeometryID(measurement1) == + Conversion::getGeometryID(measurement2); + + auto sqNorm = (Conversion::getLocal(measurement1) - + Conversion::getLocal(measurement2)) + .squaredNorm(); + auto locEq = sqNorm <= .001 * .001; + + return gidEq && locEq; + } +}; + +/// @brief Generates a hash for the measurement. +/// This hash is used for the locality sensitive hashing to calculate the match +/// map. Thus, this hash is not sensitive to small variations in position that +/// could could from numerical errors. +struct MeasurementGeoIDHash { + std::size_t operator()( + const ActsExamples::MeasurementContainer::ConstVariableProxy& measurement) + const { + return static_cast( + Conversion::getGeometryID(measurement).value()); + } +}; +} // namespace ActsExamples::Traccc::Common::Conversion diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/SeedConversion.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/SeedConversion.hpp new file mode 100644 index 000000000000..3b4713103c07 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/SeedConversion.hpp @@ -0,0 +1,134 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Acts include(s) +#include "Acts/EventData/Seed.hpp" + +// Acts Examples include(s) +#include "ActsExamples/EventData/SimSeed.hpp" +#include "ActsExamples/Traccc/Util/MapUtil.hpp" + +// Traccc include(s) +#include "traccc/edm/seed.hpp" +#include "traccc/edm/spacepoint.hpp" + +// VecMem include(s) +#include "vecmem/containers/vector.hpp" + +// System include(s) +#include +#include + +namespace ActsExamples::Traccc::Common::Conversion { + +// Custom hash and equals functions +// as some are not defined by std::hash and std::equal_to + +struct TracccSeedHash { + std::size_t operator()(const traccc::seed& s) const noexcept { + return s.spB_link ^ s.spM_link ^ s.spT_link; + } +}; + +struct TracccSeedEquals { + bool operator()(const traccc::seed& lhs, const traccc::seed& rhs) const { + return lhs.spB_link == rhs.spB_link && lhs.spM_link == rhs.spM_link && + lhs.spT_link == rhs.spT_link && lhs.weight == rhs.weight && + lhs.z_vertex == rhs.z_vertex; + } +}; + +struct ActsSeedHash { + std::size_t operator()(const SimSeed& s) const noexcept { + auto getIdx = [](auto sp) { + assert(sp->sourceLinks().size() >= 1); + auto sl = sp->sourceLinks()[0]; + return sl.template get().index(); + }; + std::vector indices; + std::transform(s.sp().begin(), s.sp().end(), std::back_inserter(indices), + getIdx); + return indices[0] ^ indices[1] ^ indices[2]; + } +}; + +struct ActsSeedEquals { + bool operator()(const SimSeed& lhs, const SimSeed& rhs) const { + auto getIdx = [](auto sp) { + assert(sp->sourceLinks().size() >= 1); + auto sl = sp->sourceLinks()[0]; + return sl.template get().index(); + }; + std::vector lhsIndices; + std::transform(lhs.sp().begin(), lhs.sp().end(), + std::back_inserter(lhsIndices), getIdx); + std::vector rhsIndices; + std::transform(rhs.sp().begin(), rhs.sp().end(), + std::back_inserter(rhsIndices), getIdx); + return lhsIndices[0] == rhsIndices[0] && lhsIndices[1] == rhsIndices[1] && + lhsIndices[2] == rhsIndices[2]; + } +}; + +/// @brief Converts a traccc seed to an acts seed. +/// @param seed the traccc seed. +/// @param spacePointConv the space point ConversionData (traccc space point -> acts space point). +/// @returns An acts seed. +template +SimSeed convertSeed(const traccc::seed& seed, T& spacePointConv) { + return SimSeed(spacePointConv.indexToValue(seed.spB_link), + spacePointConv.indexToValue(seed.spM_link), + spacePointConv.indexToValue(seed.spT_link)); +} + +/// @brief Converts a collection of traccc seeds and appends the result to the given outputContainer. +/// @param seeds the traccc seeds +/// @param SpacePointConv the spacepoint ConversionData (traccc space point -> acts space point). +/// @param outputContainer the container to put the converted space points into (an empty container is expected). +/// @returns The seed ConversionData (traccc seed -> acts seed). +template +auto convertSeeds(std::vector& seeds, + T& spacePointConv, output_container_t& outputContainer) { + auto fn = [&spacePointConv](auto& seed) { + return convertSeed(seed, spacePointConv); + }; + return Util::convert(seeds, fn, + outputContainer); +} + +/// @brief Converts a seed to a traccc seed. +/// @param seed the seed. +/// @param spacePointConv the space point ConversionData (acts space point -> traccc space point). +/// @returns A traccc seed. +template +traccc::seed convertSeed(const SimSeed& seed, T& spacePointConv) { + using Scalar = typename traccc::point3::value_type; + return traccc::seed{spacePointConv.valueToIndex(*seed.sp()[0]), + spacePointConv.valueToIndex(*seed.sp()[1]), + spacePointConv.valueToIndex(*seed.sp()[2]), + static_cast(seed.z()), seed.seedQuality()}; +} + +/// @brief Converts a collection of seeds to traccc seeds and appends the result to the given outputContainer. +/// @param seeds theseeds +/// @param SpacePointConv the spacepoint ConversionData (acts space point -> traccc space point). +/// @param outputContainer the container to put the converted space points into (an empty container is expected). +/// @returns The seed ConversionData (acts seed -> traccc seed). +template +auto convertSeeds(const SimSeedContainer& seeds, T& spacePointConv, + output_container_t& outputContainer) { + auto fn = [&spacePointConv](const SimSeed& seed) { + return convertSeed(seed, spacePointConv); + }; + return Util::convert(seeds, fn, + outputContainer); +} + +} // namespace ActsExamples::Traccc::Common::Conversion diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/SpacePointConversion.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/SpacePointConversion.hpp new file mode 100644 index 000000000000..5afd9ac8fd7d --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/SpacePointConversion.hpp @@ -0,0 +1,120 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Acts include(s) +#include "Acts/Definitions/Algebra.hpp" +#include "Acts/EventData/SourceLink.hpp" + +// Acts Examples include(s) +#include "ActsExamples/EventData/Measurement.hpp" +#include "ActsExamples/EventData/SimSpacePoint.hpp" +#include "ActsExamples/Traccc/Util/MapUtil.hpp" + +// Traccc include(s) +#include "traccc/edm/spacepoint.hpp" + +// System include(s) +#include +#include +#include +#include +#include + +namespace ActsExamples::Traccc::Common::Conversion { + +// Custom hash functions +// as some are not defined by std::hash and std::equal_to + +struct TracccSpacePointHash { + std::size_t operator()(const traccc::spacepoint& s) const noexcept { + return s.meas.measurement_id; + } +}; + +struct ActsSpacePointHash { + std::size_t operator()(const SimSpacePoint& s) const noexcept { + assert(!s.sourceLinks().empty()); + return s.sourceLinks()[0].get().index(); + } +}; + +/// @brief Converts a traccc space point to an acts space point. +/// @param spacePoint the traccc space point. +/// @param measurementConv the measurement ConversionData (traccc measurement -> acts bound variant measurement). +/// @returns An acts space point. +template +SimSpacePoint convertSpacePoint(traccc::spacepoint& spacePoint, + T& measurementConv) { + using Scalar = Acts::ActsScalar; + const Acts::Vector3 globalPos(spacePoint.x(), spacePoint.y(), spacePoint.z()); + const std::optional t = std::nullopt; + const Scalar varRho = 0; + const Scalar varZ = 0; + const std::optional varT = std::nullopt; + const Acts::SourceLink sourceLink = + measurementConv.valueToValue(spacePoint.meas).sourceLink(); + + boost::container::static_vector sourceLinks = { + sourceLink}; + + return SimSpacePoint(globalPos, t, varRho, varZ, varT, + std::move(sourceLinks)); +} + +/// @brief Converts a collection of traccc space points and appends the result to the given outputContainer. +/// @param spacepoints the traccc spacepoints. +/// @param meausrementConv the measurement ConversionData (traccc measurement -> acts bound variant measurement). +/// @param outputContainer the container to put the converted space points into (an empty container is expected). +/// @returns The spacepoint ConversionData (traccc space point -> acts space point) +template +auto convertSpacePoints( + std::vector& spacePoints, + T& measurementConv, output_container_t& outputContainer) { + auto fn = [&measurementConv](traccc::spacepoint& spacePoint) { + return convertSpacePoint(spacePoint, measurementConv); + }; + return Util::convert>( + spacePoints, fn, outputContainer); +} + +/// @brief Converts a space point to a traccc space point. +/// @param spacePoint the space point. +/// @param measurementConv the measurement ConversionData ( bound variant measurement -> traccc measurement). +/// @returns A traccc space point. +template +traccc::spacepoint convertSpacePoint(const SimSpacePoint& spacePoint, + T& measurementConv) { + using Scalar = typename traccc::point3::value_type; + auto idx = + spacePoint.sourceLinks()[0].get().index(); + + traccc::point3 global{static_cast(spacePoint.x()), + static_cast(spacePoint.y()), + static_cast(spacePoint.z())}; + return traccc::spacepoint{global, measurementConv.indexToValue(idx)}; +} + +/// @brief Converts a collection of space points to traccc space points and appends the result to the given outputContainer. +/// @param spacepoints the traccc space points. +/// @param meausrementConv the measurement ConversionData (acts bound variant measurement -> traccc measurement). +/// @param outputContainer the container to put the converted space points into (an empty container is expected). +/// @returns The spacepoint ConversionData (acts space point -> traccc space point) +template +auto convertSpacePoints(const SimSpacePointContainer& spacePoints, + T& measurementConv, + output_container_t& outputContainer) { + auto fn = [&measurementConv](const SimSpacePoint& spacePoint) { + return convertSpacePoint(spacePoint, measurementConv); + }; + return Util::convert>( + spacePoints, fn, outputContainer); +} + +} // namespace ActsExamples::Traccc::Common::Conversion diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/TrackConversion.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/TrackConversion.hpp new file mode 100644 index 000000000000..53ccace34838 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Conversion/TrackConversion.hpp @@ -0,0 +1,104 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2020 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Traccc Plugin include(s) +#include "Acts/EventData/SourceLink.hpp" +#include "Acts/Plugins/Traccc/TrackConversion.hpp" + +// Acts Examples include(s) +#include "ActsExamples/EventData/Track.hpp" +#include "ActsExamples/Traccc/Conversion/MeasurementConversion.hpp" + +// Acts include(s) +#include "Acts/Definitions/Algebra.hpp" +#include "Acts/EventData//TrackContainer.hpp" +#include "Acts/EventData/VectorMultiTrajectory.hpp" +#include "Acts/EventData/VectorTrackContainer.hpp" +#include "Acts/Geometry/TrackingGeometry.hpp" + +// Detray include(s). +#include "detray/core/detector.hpp" + +// Traccc include(s). +#include "traccc/geometry/geometry.hpp" + +// VecMem include(s). +#include + +// System include(s) +#include +#include +#include + +namespace ActsExamples::Traccc::Common::Conversion { + +/// @brief Maps the measurements of the track states from traccc measurements to acts measurements. +/// @param trackContainer the track container +/// @param map the measurement map. +template class holder_t, typename T> +void mapTrackStateMeasurements( + Acts::TrackContainer& + trackContainer, + const T& measurementConv) { + for (auto track : trackContainer) { + for (auto trackState : track.trackStates()) { + auto tracccMeasurement = trackState.getUncalibratedSourceLink() + .template get(); + const ActsExamples::MeasurementContainer::ConstVariableProxy& + measurement = measurementConv.valueToValue(tracccMeasurement); + + trackState.setUncalibratedSourceLink( + Acts::SourceLink{measurement.sourceLink()}); + + // Set the calibrated source link, + trackState.allocateCalibrated(measurement.size()); + assert(trackState.hasCalibrated()); + + trackState.template calibrated<2>() = measurement.parameters(); + trackState.template calibratedCovariance<2>() = measurement.covariance(); + trackState.setBoundSubspaceIndices( + {Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc1}); + } + } +} + +/// @brief Converts a container of traccc tracks to a container of Acts tracks. The +/// measurements conversion data provided will be used for updating both the +/// calibrated and uncalibrated measurements/sourcelinks. +/// @param tracccTrackContainer The traccc tracks. +/// @param measurementConv the traccc measurements to acts measurement conversion data. +/// @param trackingGeometry the tracking geometry. +/// @param trackingGeometry the detray detector. +/// @return An Acts const track container. +template +auto convertTracks(traccc_track_container_t& tracccTrackContainer, + const T& measurementConv, + const Acts::TrackingGeometry& trackingGeometry, + const detector_t& detector) { + auto trackContainer = std::make_shared(); + auto trackStateContainer = std::make_shared(); + TrackContainer tracks(trackContainer, trackStateContainer); + + Acts::TracccPlugin::makeTracks(tracccTrackContainer, tracks, detector, + trackingGeometry); + + mapTrackStateMeasurements(tracks, measurementConv); + + ConstTrackContainer constTracks{ + std::make_shared( + std::move(*trackContainer)), + std::make_shared( + std::move(*trackStateContainer))}; + + return constTracks; +} + +} // namespace ActsExamples::Traccc::Common::Conversion diff --git a/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/DetrayPropagator.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/DetrayPropagator.hpp similarity index 100% rename from Examples/Algorithms/Traccc/include/ActsExamples/Traccc/DetrayPropagator.hpp rename to Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/DetrayPropagator.hpp diff --git a/Examples/Algorithms/Traccc/include/ActsExamples/Traccc/DetrayStore.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/DetrayStore.hpp similarity index 100% rename from Examples/Algorithms/Traccc/include/ActsExamples/Traccc/DetrayStore.hpp rename to Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/DetrayStore.hpp diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Io/ReadDetector.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Io/ReadDetector.hpp new file mode 100644 index 000000000000..f5dfd5496685 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Io/ReadDetector.hpp @@ -0,0 +1,39 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2024 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Acts include(s) +#include "Acts/Geometry/GeometryIdentifier.hpp" + +// Acts Examples include(s) +#include "ActsExamples/EventData/Cluster.hpp" + +#include + +namespace ActsExamples::Traccc::Common::Io { +template +inline auto readDetector(vecmem::memory_resource* mr, + const std::string& detectorFilePath, + const std::string& materialFilePath = "", + const std::string& gridFilePath = "") { + // Set up the detector reader configuration. + detray::io::detector_reader_config cfg; + cfg.add_file(detectorFilePath); + if (!materialFilePath.empty()) { + cfg.add_file(materialFilePath); + } + if (!gridFilePath.empty()) { + cfg.add_file(gridFilePath); + } + + // Read the detector. + auto [det, names] = detray::io::read_detector(*mr, cfg); + return std::move(det); +} +} // namespace ActsExamples::Traccc::Common::Io diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Measurement/Debug.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Measurement/Debug.hpp new file mode 100644 index 000000000000..9bf337af0de6 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Measurement/Debug.hpp @@ -0,0 +1,60 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Acts include(s) +#include "ActsExamples/EventData/Measurement.hpp" + +// Acts Examples include(s) +#include "ActsExamples/Traccc/Conversion/MeasurementMatch.hpp" +#include "ActsExamples/Traccc/Util/IndexMap.hpp" + +// System include(s). +#include +#include +#include +#include +#include + +// This file is for debugging and for getting the matching between two +// collections of measurements as a string. + +namespace ActsExamples::Traccc::Common::Measurement { + +/// @brief Creates a string with the data of the measurements and their relation according to the index map. +/// @param measurements1 the measurements (1). +/// @param measurements2 the measurements (2). +/// @param indexMap the index map: measurements1 indices -> measurement2 indices. +/// The index map describes which elements are related in the two measurement +/// collections. +/// @return a string formatted as a table. +std::string pairingStatistics( + const MeasurementContainer& measurements1, + const MeasurementContainer& measurements2, + const std::map& indexMap); + +/// @brief Pairs the measurements by equivalency and creates a string containing debug information. +template +std::string pairingStatistics( + const std::vector& tracccMeasurements, + const MeasurementContainer& measurements, const detector_t& detector) { + MeasurementContainer convertedMeasurements; + Conversion::convertMeasurements(detector, tracccMeasurements.cbegin(), + tracccMeasurements.cend(), + convertedMeasurements); + + std::map indexMap = Util::matchMap( + convertedMeasurements.cbegin(), convertedMeasurements.cend(), + measurements.cbegin(), measurements.cend(), + Conversion::MeasurementGeoIDHash{}, Conversion::MeasurementAproxEquals{}); + + return pairingStatistics(convertedMeasurements, measurements, indexMap); +} + +} // namespace ActsExamples::Traccc::Common::Measurement diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/TracccChainConfig.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/TracccChainConfig.hpp new file mode 100644 index 000000000000..bab8d9600a02 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/TracccChainConfig.hpp @@ -0,0 +1,56 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Traccc include(s) +#include "Acts/Geometry/TrackingGeometry.hpp" +#include "Acts/MagneticField/ConstantBField.hpp" +#include "ActsExamples/Digitization/DigitizationConfig.hpp" + +#include "traccc/ambiguity_resolution/greedy_ambiguity_resolution_algorithm.hpp" +#include "traccc/clusterization/clusterization_algorithm.hpp" +#include "traccc/clusterization/spacepoint_formation_algorithm.hpp" +#include "traccc/definitions/primitives.hpp" +#include "traccc/finding/finding_algorithm.hpp" +#include "traccc/finding/finding_config.hpp" +#include "traccc/fitting/fitting_algorithm.hpp" +#include "traccc/fitting/fitting_config.hpp" +#include "traccc/seeding/seeding_algorithm.hpp" +#include "traccc/seeding/track_params_estimation.hpp" + +namespace ActsExamples::Traccc::Common { + +struct TracccChainConfig { + std::string detectorFilePath, materialFilePath, gridFilePath; + + std::string inputCells; + std::string inputMeasurements; + std::string inputSpacePoints; + std::string inputSeeds; + std::string outputSpacePoints; + std::string outputSeeds; + std::string outputTracks; + + bool enableAmbiguityResolution; + bool reconstructionOnly; + + std::shared_ptr trackingGeometry = nullptr; + std::shared_ptr field; + Acts::GeometryHierarchyMap digitizationConfigs; + + traccc::seedfinder_config seedfinderConfig; + traccc::spacepoint_grid_config spacepointGridConfig{seedfinderConfig}; + traccc::seedfilter_config seedfilterConfig; + traccc::finding_config findingConfig; + traccc::fitting_config fittingConfig; + traccc::greedy_ambiguity_resolution_algorithm::config_t + ambiguityResolutionConfig; +}; + +} // namespace ActsExamples::Traccc::Common diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Util/IndexMap.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Util/IndexMap.hpp new file mode 100644 index 000000000000..e4f60df8cedf --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Util/IndexMap.hpp @@ -0,0 +1,110 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// System include(s). +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ActsExamples::Traccc::Common::Util { + +/// @brief Helper function for matchMap to find the index of a match. +/// The index is return true the out parameter. +/// The function returns false if no match was found. +template +std::optional findMatchIdx( + const T& element, const std::vector& candidateIdxs, + It candidate_begin, It candidate_end, const equal_fn_t& eqFn) { + for (It i = candidate_begin; i != candidate_end; i++) { + std::size_t idx = candidateIdxs[std::distance(candidate_begin, i)]; + if (eqFn(element, *i)) { + return idx; + } + } + return {}; +} + +/// @brief Determines which pairs of indices in the two vectors contain items that are equal. +/// Each item in the vector 'from' must be equal to at least 1 item in the +/// vector 'to'. Furthermore, if the flag 'bijection' is enabled each element in +/// ̈́'to' and 'from' can only be paired with exactly 1 element. +/// @note When 'bijection' is corresponds to the assumption that the two vectors contain exactly the same elements. +/// The ordering in the vectors may however be different (determining the +/// difference in the order is where this function can be helpful). +/// @param from a vector (the retutned map's domain). +/// @param to a vector (the returned map's codomain). +/// @param lshFn the hashing function used for locality sensitive hashing. Any items that could potential be equal should have the same hash value. +/// @param eqFn the function for determining if two items are equal. +/// @param bijection flag indicatiing whether the map should be a bijection. +/// @return a map: index ('from' vector) -> index ('to' vector). +template +inline auto matchMap(It1 from_begin, It1 from_end, It2 to_begin, It2 to_end, + const hash_fn_t& lshFn, const equal_fn_t& eqFn, + const bool bijection = true) { + // By composition of functions, we can combine the maps "index ('from' vector) + // -> hash value" and "hash value -> index ('to' vector)" to obtain "index + // ('from' vector) -> index ('to' vector)". + + std::size_t from_size = std::distance(from_begin, from_end); + std::size_t to_size = std::distance(to_begin, to_end); + + if (bijection && from_size != to_size) { + throw std::runtime_error( + "Cannot create a bijection as domain and codomain do not have the same " + "cardinality"); + } + + // We start by creating the map "hash value -> index ('to' vector)". + + // Since there can be collisions with the hash values + // each hash value maps to a bucket of indices rather than a single index. + + std::unordered_map> map1; + for (It2 toIdx = to_begin; toIdx != to_end; toIdx++) { + const auto& toElement = *toIdx; + auto toElementHash = lshFn(toElement); + map1[toElementHash].push_back(std::distance(to_begin, toIdx)); + } + + // We can build the map "index in 'from' -> index in 'to'" directly. + std::map res; + + for (It1 fromIdx = from_begin; fromIdx != to_end; fromIdx++) { + const auto& fromElement = *fromIdx; + auto fromElementHash = lshFn(fromElement); + // We now find the exact element to match fromElement with in the bucket. + std::vector& candidateIdxs = map1[fromElementHash]; + + std::optional idx; + + if (!candidateIdxs.empty()) { + idx = findMatchIdx(fromElement, candidateIdxs, to_begin, to_end, eqFn); + } + + if (!idx) { + throw std::runtime_error("Could not find a match for an element"); + } + + res[std::distance(from_begin, fromIdx)] = candidateIdxs[*idx]; + + if (bijection) { + candidateIdxs.erase(candidateIdxs.begin() + *idx); + } + } + + return res; +} + +} // namespace ActsExamples::Traccc::Common::Util diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Util/MapUtil.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Util/MapUtil.hpp new file mode 100644 index 000000000000..85d6c27540d7 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Util/MapUtil.hpp @@ -0,0 +1,150 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// System include(s). +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ActsExamples::Traccc::Common::Util { + +/// @brief Class representing a mapping between two collections. +/// Functions for mapping from/to value and indexes are provided. +/// The class is useful as it allows you to obtain a reference to +/// the item mapped in the output collection. +template +class ConversionData { + public: + using K = typename std::iterator_traits::value_type; + using V = typename std::iterator_traits::value_type; + + ConversionData() = delete; + + const K& inputAt(std::size_t i) { + It1 it = input_begin; + std::advance(it, i); + return *it; + } + + std::size_t valueToIndex(const K& inputValue) const { + return keyToIdxMap.at(inputValue); + } + + std::size_t indexToIndex(std::size_t index) const { + It1 i = input_begin; + std::advance(i, index); + return valueToIndex(*i); + } + + std::conditional_t, const V&, V> indexToValue( + std::size_t index) const { + It2 i = output_begin; + std::advance(i, indexToIndex(index)); + return *i; + } + + std::conditional_t, const V&, V> valueToValue( + const K& inputValue) const { + It2 i = output_begin; + std::advance(i, valueToIndex(inputValue)); + return *i; + } + + std::size_t size() { return keyToIdxMap.size(); } + + ConversionData(It1 i_beg, It1 i_end, It2 o_beg, It2 o_end, + std::unordered_map&& map) + : input_begin(i_beg), + input_end(i_end), + output_begin(o_beg), + output_end(o_end), + keyToIdxMap(std::move(map)) {} + + template + ConversionData invert(_Hash&& new_hash, + _Equals&& new_equals) { + std::unordered_map::value_type, + std::size_t, _Hash, _Equals> + map(64, std::forward<_Hash>(new_hash), + std::forward<_Equals>(new_equals)); + + for (std::size_t idx = 0; idx < size(); idx++) { + auto value = valueToValue(inputAt(idx)); + map.emplace(std::piecewise_construct, std::forward_as_tuple(value), + std::forward_as_tuple(idx)); + } + + return ConversionData{ + output_begin, output_end, input_begin, input_end, std::move(map)}; + } + + private: + It1 input_begin, input_end; + It2 output_begin, output_end; + std::unordered_map keyToIdxMap; +}; + +/// @brief Creates an instance of the ConversionData class where the given indexMap parameter determines how the elements +/// depending on their index in the input container map to the elements of the +/// output container depending on their index. +template +auto makeConversionFromIndexMap( + It1 i_beg, It1 i_end, It2 o_beg, It2 o_end, + const std::map& indexMap, Hash&& hash = {}, + Equals&& equals = {}) { + std::unordered_map::value_type, + std::size_t, Hash, Equals> + map(64, std::forward(hash), std::forward(equals)); + + for (It1 i = i_beg; i != i_end; i++) { + auto outputIdx = indexMap.at(std::distance(i_beg, i)); + map.emplace(std::piecewise_construct, std::forward_as_tuple(*i), + std::forward_as_tuple(outputIdx)); + } + return ConversionData(i_beg, i_end, o_beg, o_end, + std::move(map)); +} + +template +ConversionData makeConversionOneToOne( + It1 i_beg, It1 i_end, It2 o_beg, It2 o_end, Hash&& hash = {}, + Equals&& equals = {}) { + std::unordered_map::value_type, + std::size_t, Hash, Equals> + map(64, std::forward(hash), std::forward(equals)); + + for (It1 i = i_beg; i != i_end; i++) { + map.emplace(std::piecewise_construct, std::forward_as_tuple(*i), + std::forward_as_tuple(std::distance(i_beg, i))); + } + + return ConversionData(i_beg, i_end, o_beg, o_end, + std::move(map)); +} + +/// @brief Creates an instance of the ConversionData class where the mapping and output container is generated +/// by the provided function. +template +auto convert(input_container_t& inputs, fn_t fn, output_container_t& outputs) { + std::transform(inputs.begin(), inputs.end(), std::back_inserter(outputs), fn); + + return makeConversionOneToOne(inputs.cbegin(), inputs.cend(), + outputs.cbegin(), outputs.cend(), hash_t{}, + equals_t{}); +} + +} // namespace ActsExamples::Traccc::Common::Util diff --git a/Examples/Algorithms/Traccc/Common/src/Conversion/CellMapConversion.cpp b/Examples/Algorithms/Traccc/Common/src/Conversion/CellMapConversion.cpp new file mode 100644 index 000000000000..eb749d5c3f16 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/src/Conversion/CellMapConversion.cpp @@ -0,0 +1,83 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Acts include(s) +#include "Acts/Geometry/GeometryIdentifier.hpp" + +// Acts Examples include(s) +#include "ActsExamples/EventData/Cluster.hpp" +#include "ActsExamples/Traccc/Conversion/CellMapConversion.hpp" + +// Traccc include(s) +#include "traccc/edm/cell.hpp" + +// System include(s). +#include +#include +#include +#include + +namespace ActsExamples::Traccc::Common::Conversion { + +/// @brief Gets the time of the cell. +/// @note Currently, it always returns 0. +inline float getTime(const Cluster::Cell& /*cell*/) { + return 0.f; +} + +/// @brief Gets the activation of the cell. +inline float getActivation(const Cluster::Cell& cell) { + return static_cast(cell.activation); +} + +/// @brief Gets the row of the cell. +inline unsigned int getRow(const Cluster::Cell& cell) { + if (cell.bin[0] > UINT_MAX) { + throw std::runtime_error( + "Overflow will occur when casting to unsigned int."); + } + return static_cast(cell.bin[0]); +} + +/// @brief Gets the column of the cell. +inline unsigned int getColumn(const Cluster::Cell& cell) { + if (cell.bin[0] > UINT_MAX) { + throw std::runtime_error( + "Overflow will occur when casting to unsigned int."); + } + return static_cast(cell.bin[1]); +} + +/// @brief Creates a traccc cell from a generic cell type. +/// @param cell the cell. +/// @param moduleLink the module link value to set for the traccc cell that is created. +/// @returns a traccc cell. +/// @note the functions getRow(cell_t), getColumn(cell_t), getActivation(cell_t), getTime(cell_t) are expected. +inline traccc::cell tracccCell(const Cluster::Cell& cell, + const traccc::cell::link_type moduleLink = 0) { + return traccc::cell{getRow(cell), getColumn(cell), getActivation(cell), + getTime(cell), moduleLink}; +} + +/// @brief Converts a "geometry ID -> generic cell collection type" map to a "geometry ID -> traccc cell collection" map. +/// @note The function sets the module link of the cells in the output to 0. +/// @return Map from geometry ID to its cell data (as a vector of traccc cell data) +std::map> tracccCellsMap( + const std::map>& map) { + std::map> tracccCellMap; + for (const auto& [geometryID, cells] : map) { + std::vector tracccCells; + for (const auto& cell : cells) { + tracccCells.push_back(tracccCell(cell)); + } + tracccCellMap.insert({geometryID.value(), std::move(tracccCells)}); + } + return tracccCellMap; +} + +} // namespace ActsExamples::Traccc::Common::Conversion diff --git a/Examples/Algorithms/Traccc/Common/src/Conversion/DigitizationConversion.cpp b/Examples/Algorithms/Traccc/Common/src/Conversion/DigitizationConversion.cpp new file mode 100644 index 000000000000..fce62e0cdacc --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/src/Conversion/DigitizationConversion.cpp @@ -0,0 +1,51 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Acts include(s) +#include "Acts/Geometry/GeometryHierarchyMap.hpp" +#include "Acts/Geometry/GeometryIdentifier.hpp" +#include "Acts/Utilities/BinUtility.hpp" + +// Acts Examples include(s) +#include "ActsExamples/Digitization/DigitizationConfig.hpp" + +// Acts Traccc plugin include(s) +#include "Acts/Plugins/Traccc/DigitizationConfig.hpp" +#include "ActsExamples/Traccc/Conversion/DigitizationConversion.hpp" + +// System include(s). +#include +#include + +namespace ActsExamples::Traccc::Common::Conversion { + +/// @brief Get the segmentation from a DigiComponentsConfig. +inline Acts::BinUtility getSegmentation(const DigiComponentsConfig& dcc) { + return dcc.geometricDigiConfig.segmentation; +} + +/// @brief Creates a traccc digitalization config from an Acts geometry hierarchy map +/// that contains the digitization configuration. +/// @param config the Acts geometry hierarchy map that contains the digitization configuration. +/// @return a traccc digitization config. +Acts::TracccPlugin::DigitizationConfig tracccConfig( + const Acts::GeometryHierarchyMap& config) { + using ElementType = std::pair; + + std::vector vec; + + for (std::size_t i = 0; i < config.size(); i++) { + vec.push_back({config.idAt(i), Acts::TracccPlugin::ModuleDigitizationConfig{ + getSegmentation(config.valueAt(i))}}); + } + + return Acts::TracccPlugin::DigitizationConfig(vec); +} + +} // namespace ActsExamples::Traccc::Common::Conversion diff --git a/Examples/Algorithms/Traccc/Common/src/Conversion/MeasurementConversion.cpp b/Examples/Algorithms/Traccc/Common/src/Conversion/MeasurementConversion.cpp new file mode 100644 index 000000000000..43faffc701f0 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/src/Conversion/MeasurementConversion.cpp @@ -0,0 +1,44 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Acts include(s) +#include "Acts/Definitions/TrackParametrization.hpp" + +// Acts Examples include(s) +#include "ActsExamples/Traccc/Conversion/MeasurementConversion.hpp" + +// Traccc include(s) +#include "traccc/definitions/track_parametrization.hpp" + +namespace ActsExamples::Traccc::Common::Conversion { + +/// @brief Converts a traccc bound index to an Acts bound index. +/// @param tracccBoundIndex the traccc bound index. +/// @returns an Acts bound index. +Acts::BoundIndices boundIndex(const traccc::bound_indices tracccBoundIndex) { + switch (tracccBoundIndex) { + case traccc::bound_indices::e_bound_loc0: + return Acts::BoundIndices::eBoundLoc0; + case traccc::bound_indices::e_bound_loc1: + return Acts::BoundIndices::eBoundLoc1; + case traccc::bound_indices::e_bound_phi: + return Acts::BoundIndices::eBoundPhi; + case traccc::bound_indices::e_bound_theta: + return Acts::BoundIndices::eBoundTheta; + case traccc::bound_indices::e_bound_qoverp: + return Acts::BoundIndices::eBoundQOverP; + case traccc::bound_indices::e_bound_time: + return Acts::BoundIndices::eBoundTime; + case traccc::bound_indices::e_bound_size: + return Acts::BoundIndices::eBoundSize; + default: + throw std::runtime_error("Could not convert traccc bound index"); + } +} + +} // namespace ActsExamples::Traccc::Common::Conversion diff --git a/Examples/Algorithms/Traccc/Common/src/Debug/Debug.cpp b/Examples/Algorithms/Traccc/Common/src/Debug/Debug.cpp new file mode 100644 index 000000000000..0365a6fb8f51 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/src/Debug/Debug.cpp @@ -0,0 +1,114 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Acts include(s) +#include "Acts/Definitions/Algebra.hpp" + +// Acts Examples include(s) +#include "ActsExamples/EventData/Measurement.hpp" +#include "ActsExamples/Traccc/Conversion/MeasurementConversion.hpp" + +// System include(s). +#include +#include +#include +#include +#include + +// This file is for debugging and for getting the matching between two +// collections of measurements as a string. + +namespace ActsExamples::Traccc::Common::Measurement { + +namespace { + +/// @returns a nicely formatted string of a vector representing a point. +std::string toString(const Acts::ActsVector<2>& vec) { + std::stringstream ss; + ss << "(" << vec[0] << ", " << vec[1] << ")"; + return ss.str(); +} + +/// @brief Structure to hold table data +struct MeasurementMatchRow { + std::size_t idx1{}; + Acts::ActsVector<2> local1; + Acts::ActsVector<2> variance1; + + std::size_t idx2{}; + Acts::ActsVector<2> local2; + Acts::ActsVector<2> variance2; + + Acts::ActsScalar distanceLocal{}; +}; + +/// @brief Creates a table with data and measurements aligned according to the index map. +/// @param measurements1 the measurements (1). +/// @param measurements2 the measurements (2). +/// @param indexMap the index map: measurements1 indices -> measurement2 indices. +/// The index map describes which elements are related in the two measurement +/// collections. +/// @return a vector of MeasurementMatchRow. +auto createTable(const MeasurementContainer& measurements1, + const MeasurementContainer& measurements2, + const std::map& indexMap) { + std::vector table; + for (std::size_t idx1 = 0; idx1 < measurements1.size(); ++idx1) { + auto idx2 = indexMap.at(idx1); + MeasurementContainer::ConstVariableProxy measurement1 = + measurements1.getMeasurement(idx1); + MeasurementContainer::ConstVariableProxy measurement2 = + measurements2.getMeasurement(idx2); + + Acts::ActsVector<2> local1 = Conversion::getLocal(measurement1); + Acts::ActsVector<2> local2 = Conversion::getLocal(measurement2); + + table.emplace_back(idx1, local1, Conversion::getVariance(measurement1), + idx2, local2, Conversion::getVariance(measurement2), + (local1 - local2).norm()); + } + return table; +} + +} // namespace + +/// @brief Creates a string with the data of the measurements and their relation according to the index map. +/// @param measurements1 the measurements (1). +/// @param measurements2 the measurements (2). +/// @param indexMap the index map: measurements1 indices -> measurement2 indices. +/// The index map describes which elements are related in the two measurement +/// collections. +/// @return a string formatted as a table. +std::string pairingStatistics( + const MeasurementContainer& measurements1, + const MeasurementContainer& measurements2, + const std::map& indexMap) { + auto table = createTable(measurements1, measurements2, indexMap); + + std::stringstream ss; + + // Column headers + ss << std::setw(6) << "Idx1" << std::setw(25) << "Local1" << std::setw(35) + << "Variance1" << std::setw(20) << "Idx2" << std::setw(25) << "Local2" + << std::setw(35) << "Variance2" << std::setw(25) << "Distance Local" + << std::endl; + + // Line separator + ss << std::string(173, '-') << std::endl; + + // Print each row + for (const auto& row : table) { + ss << std::setw(6) << row.idx1 << std::setw(25) << toString(row.local1) + << std::setw(35) << toString(row.variance1) << std::setw(20) << row.idx2 + << std::setw(25) << toString(row.local2) << std::setw(35) + << toString(row.variance2) << std::setw(25) << std::fixed + << std::setprecision(2) << row.distanceLocal << std::endl; + } + return ss.str(); +} +} // namespace ActsExamples::Traccc::Common::Measurement diff --git a/Examples/Algorithms/Traccc/Host/CMakeLists.txt b/Examples/Algorithms/Traccc/Host/CMakeLists.txt new file mode 100644 index 000000000000..4c1583194b51 --- /dev/null +++ b/Examples/Algorithms/Traccc/Host/CMakeLists.txt @@ -0,0 +1,13 @@ +add_library(ActsExamplesTracccHost SHARED src/TracccChainAlgorithm.cpp) + +target_include_directories( + ActsExamplesTracccHost + PUBLIC $ +) + +target_link_libraries(ActsExamplesTracccHost PUBLIC ActsExamplesTracccCommon) + +install( + TARGETS ActsExamplesTracccHost + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} +) diff --git a/Examples/Algorithms/Traccc/Host/include/ActsExamples/Traccc/Host/TracccChainAlgorithm.hpp b/Examples/Algorithms/Traccc/Host/include/ActsExamples/Traccc/Host/TracccChainAlgorithm.hpp new file mode 100644 index 000000000000..1c4f22716cb9 --- /dev/null +++ b/Examples/Algorithms/Traccc/Host/include/ActsExamples/Traccc/Host/TracccChainAlgorithm.hpp @@ -0,0 +1,101 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2020 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +#include "Acts/Plugins/Covfie/FieldConversion.hpp" +#include "Acts/Plugins/Traccc/DigitizationConfig.hpp" +#include "ActsExamples/EventData/Cluster.hpp" +#include "ActsExamples/EventData/IndexSourceLink.hpp" +#include "ActsExamples/EventData/Measurement.hpp" +#include "ActsExamples/EventData/SimSeed.hpp" +#include "ActsExamples/EventData/Track.hpp" +#include "ActsExamples/Framework/DataHandle.hpp" +#include "ActsExamples/Framework/IAlgorithm.hpp" +#include "ActsExamples/Traccc/Host/Types.hpp" +#include "ActsExamples/Traccc/TracccChainConfig.hpp" + +#include +#include + +#include "traccc/geometry/geometry.hpp" + +namespace ActsExamples::Traccc::Host { + +class TracccChainAlgorithm : public IAlgorithm { + public: + using Config = Common::TracccChainConfig; + + /// Construct the traccc algorithm. + /// + /// @param cfg is the algorithm configuration + /// @param lvl is the logging level + TracccChainAlgorithm(const Config& cfg, Acts::Logging::Level lvl); + + private: + using field_t = + covfie::field>; + using detector_t = + detray::detector; + using cell_map_t = + std::map>; + + Config m_cfg; + vecmem::host_memory_resource m_hostMemoryResource; + const detector_t m_detector; + const field_t m_field; + const traccc::geometry m_surfaceTransforms; + const std::map m_barcodeMap; + const Acts::TracccPlugin::DigitizationConfig m_digitizationConfig; + + using Types = ActsExamples::Traccc::Host::Types; + + typename Types::ClusterizationAlgorithmType clusterizationAlgorithm; + typename Types::SpacepointFormationAlgorithmType spacepointFormationAlgorithm; + typename Types::SeedingAlgorithmType seedingAlgorithm; + typename Types::TrackParametersEstimationAlgorithmType + trackParametersEstimationAlgorithm; + typename Types::FindingAlgorithmType findingAlgorithm; + typename Types::FittingAlgorithmType fittingAlgorithm; + typename Types::AmbiguityResolutionAlgorithmType ambiguityResolutionAlgorithm; + + ReadDataHandle m_inputCells{this, "InputCells"}; + ReadDataHandle m_inputMeasurements{this, + "InputMeasurements"}; + ReadDataHandle m_inputSpacePoints{this, + "InputSpacePoints"}; + ReadDataHandle m_inputSeeds{this, "InputSeeds"}; + WriteDataHandle> m_outputSpacePoints{ + this, "OutputSpacePoints"}; + WriteDataHandle> m_outputSeeds{this, "OutputSeeds"}; + WriteDataHandle m_outputTracks{this, "OutputTracks"}; + + protected: + std::tuple, + vecmem::vector, vecmem::vector> + runClusterization( + const vecmem::vector& cells, + const Types::SiliconDetectorDescriptionType::const_view& detector_desc, + vecmem::host_memory_resource& mr) const; + + traccc::host_container, + traccc::track_state> + runReconstruction(const vecmem::vector& measurements, + const vecmem::vector& spacepoints, + const vecmem::vector& seeds, + vecmem::host_memory_resource& mr) const; + + public: + ActsExamples::ProcessCode execute( + const ActsExamples::AlgorithmContext& ctx) const override; + + const Config& config() const { return m_cfg; } +}; + +} // namespace ActsExamples::Traccc::Host diff --git a/Examples/Algorithms/Traccc/Host/include/ActsExamples/Traccc/Host/Types.hpp b/Examples/Algorithms/Traccc/Host/include/ActsExamples/Traccc/Host/Types.hpp new file mode 100644 index 000000000000..8cb675c04745 --- /dev/null +++ b/Examples/Algorithms/Traccc/Host/include/ActsExamples/Traccc/Host/Types.hpp @@ -0,0 +1,60 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Covfie include(s) +#include +#include + +// Traccc include(s) +#include "traccc/ambiguity_resolution/greedy_ambiguity_resolution_algorithm.hpp" +#include "traccc/clusterization/clusterization_algorithm.hpp" +#include "traccc/clusterization/spacepoint_formation_algorithm.hpp" +#include "traccc/finding/finding_algorithm.hpp" +#include "traccc/finding/finding_config.hpp" +#include "traccc/fitting/fitting_algorithm.hpp" +#include "traccc/fitting/fitting_config.hpp" +#include "traccc/geometry/silicon_detector_description.hpp" +#include "traccc/seeding/seeding_algorithm.hpp" +#include "traccc/seeding/track_params_estimation.hpp" + +// Detray include(s). +#include "detray/core/detector.hpp" +#include "detray/propagator/rk_stepper.hpp" + +namespace ActsExamples::Traccc::Host { + +struct Types { + using FieldType = + covfie::field>; + using DetectorType = + detray::detector; + using StepperType = + detray::rk_stepper>; + using NavigatorType = detray::navigator; + using FitterType = traccc::kalman_fitter; + + using SiliconDetectorDescriptionType = traccc::silicon_detector_description; + + using ClusterizationAlgorithmType = traccc::host::clusterization_algorithm; + using SpacepointFormationAlgorithmType = + traccc::host::spacepoint_formation_algorithm; + using SeedingAlgorithmType = traccc::seeding_algorithm; + using TrackParametersEstimationAlgorithmType = + traccc::track_params_estimation; + using FindingAlgorithmType = + traccc::finding_algorithm; + using FittingAlgorithmType = traccc::fitting_algorithm; + using AmbiguityResolutionAlgorithmType = + traccc::greedy_ambiguity_resolution_algorithm; +}; + +} // namespace ActsExamples::Traccc::Host diff --git a/Examples/Algorithms/Traccc/Host/src/TracccChainAlgorithm.cpp b/Examples/Algorithms/Traccc/Host/src/TracccChainAlgorithm.cpp new file mode 100644 index 000000000000..bf6702f23a9b --- /dev/null +++ b/Examples/Algorithms/Traccc/Host/src/TracccChainAlgorithm.cpp @@ -0,0 +1,242 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2020 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Acts Examples include(s) +#include "ActsExamples/Traccc/Host/TracccChainAlgorithm.hpp" + +#include "Acts/Plugins/Traccc/BarcodeMap.hpp" +#include "Acts/Plugins/Traccc/CellConversion.hpp" +#include "Acts/Plugins/Traccc/SurfaceMap.hpp" +#include "Acts/Plugins/Traccc/TrackConversion.hpp" +#include "ActsExamples/Traccc/Conversion/CellMapConversion.hpp" +#include "ActsExamples/Traccc/Conversion/DigitizationConversion.hpp" +#include "ActsExamples/Traccc/Conversion/MeasurementMatch.hpp" +#include "ActsExamples/Traccc/Conversion/SeedConversion.hpp" +#include "ActsExamples/Traccc/Conversion/SpacePointConversion.hpp" +#include "ActsExamples/Traccc/Conversion/TrackConversion.hpp" +#include "ActsExamples/Traccc/Io/ReadDetector.hpp" +#include "ActsExamples/Traccc/Measurement/Debug.hpp" +#include "ActsExamples/Traccc/Util/IndexMap.hpp" + +#include "vecmem/utils/tuple.hpp" + +ActsExamples::Traccc::Host::TracccChainAlgorithm::TracccChainAlgorithm( + const Common::TracccChainConfig& cfg, Acts::Logging::Level lvl) + : IAlgorithm("TracccHostChain", lvl), + m_cfg(cfg), + m_detector(Common::Io::readDetector( + &m_hostMemoryResource, cfg.detectorFilePath, cfg.materialFilePath, + cfg.gridFilePath)), + m_field(Acts::CovfiePlugin::covfieField(*m_cfg.field)), + m_surfaceTransforms{Acts::TracccPlugin::createSurfaceMap(m_detector)}, + m_barcodeMap{Acts::TracccPlugin::createBarcodeMap(m_detector)}, + m_digitizationConfig{ + Common::Conversion::tracccConfig(m_cfg.digitizationConfigs)}, + clusterizationAlgorithm(m_hostMemoryResource), + spacepointFormationAlgorithm(m_hostMemoryResource), + seedingAlgorithm(m_cfg.seedfinderConfig, m_cfg.spacepointGridConfig, + m_cfg.seedfilterConfig, m_hostMemoryResource), + trackParametersEstimationAlgorithm(m_hostMemoryResource), + findingAlgorithm(m_cfg.findingConfig), + fittingAlgorithm(m_cfg.fittingConfig), + ambiguityResolutionAlgorithm(m_cfg.ambiguityResolutionConfig) {} + +std::tuple, + vecmem::vector, vecmem::vector> +ActsExamples::Traccc::Host::TracccChainAlgorithm::runClusterization( + const vecmem::vector& cells, + const Types::SiliconDetectorDescriptionType::const_view& detector_desc, + vecmem::host_memory_resource& mr) const { + typename Types::ClusterizationAlgorithmType::output_type measurements{&mr}; + typename Types::SpacepointFormationAlgorithmType::output_type spacepoints{ + &mr}; + typename Types::SeedingAlgorithmType::output_type seeds{&mr}; + + measurements = + clusterizationAlgorithm(vecmem::get_data(cells), detector_desc); + ACTS_INFO("Ran the clusterization algorithm"); + + spacepoints = spacepointFormationAlgorithm(vecmem::get_data(measurements), + detector_desc); + ACTS_INFO("Ran the spacepoint formation algorithm"); + + seeds = seedingAlgorithm(spacepoints); + ACTS_INFO("Ran the seeding algorithm"); + + return std::make_tuple(std::move(measurements), std::move(spacepoints), + std::move(seeds)); +} + +traccc::host_container, + traccc::track_state> +ActsExamples::Traccc::Host::TracccChainAlgorithm::runReconstruction( + const vecmem::vector& measurements, + const vecmem::vector& spacepoints, + const vecmem::vector& seeds, + vecmem::host_memory_resource& mr) const { + typename Types::TrackParametersEstimationAlgorithmType::output_type params{ + &mr}; + typename Types::FindingAlgorithmType::output_type trackCandidates{&mr}; + typename Types::FittingAlgorithmType::output_type tracks{&mr}; + + const field_t::view_t fieldView(m_field); + + // Traccc expects a field vector of a constant field. + auto bv = fieldView.at(0.f, 0.f, 0.f); + + params = trackParametersEstimationAlgorithm(spacepoints, seeds, + {bv[0], bv[1], bv[2]}); + ACTS_INFO("Ran the parameters estimation algorithm"); + + trackCandidates = findingAlgorithm(m_detector, field_t::view_t(m_field), + measurements, params); + ACTS_INFO("Ran the finding algorithm"); + + tracks = + fittingAlgorithm(m_detector, field_t::view_t(m_field), trackCandidates); + ACTS_INFO("Ran the fitting algorithm"); + + if (m_cfg.enableAmbiguityResolution) { + tracks = ambiguityResolutionAlgorithm(tracks); + ACTS_INFO("Ran the ambiguity resolution algorithm"); + } else { + ACTS_INFO("Skipped the ambiguity resolution algorithm"); + } + + return tracks; +} + +ActsExamples::ProcessCode +ActsExamples::Traccc::Host::TracccChainAlgorithm::execute( + const ActsExamples::AlgorithmContext& ctx) const { + vecmem::host_memory_resource mr; + + // Read the cells + const auto cellsMap = m_inputCells(ctx); + + // Convert the cells + auto tcm = Common::Conversion::tracccCellsMap(cellsMap); + auto [cells, modules] = Acts::TracccPlugin::createCellsAndModules( + mr, std::move(tcm), m_surfaceTransforms, m_digitizationConfig, + m_barcodeMap); + + // Run the traccc digitization + auto [measurements, spacepoints, seeds] = + runClusterization(cells, vecmem::get_data(modules), mr); + + // Now we have both traccc measurements and acts measurements + // We have run the traccc digitization and we expect that Acts digitization + // has also been run, since otherwise we cannot do compare and do truth + // matching. + + // Read the acts measurements + auto& actsMeasurements = m_inputMeasurements(ctx); + // Determine which traccc measurements are equivalent to which Acts + // measurements. This is needed since we cannot guarantee that the + // measurements have the same ordering. We run the following to obtain a + // mapping between the two measurement collections. Note: if the number of + // measurements don't match during the perhaps mergeCommonCorner or doMerge + // is false in the digitization algorithm configuration. + MeasurementContainer convertedMeasurements; + Common::Conversion::convertMeasurements(m_detector, measurements.cbegin(), + measurements.cend(), + convertedMeasurements); + + std::map indexMap = Common::Util::matchMap( + convertedMeasurements.cbegin(), convertedMeasurements.cend(), + actsMeasurements.cbegin(), actsMeasurements.cend(), + Common::Conversion::MeasurementGeoIDHash{}, + Common::Conversion::MeasurementAproxEquals{}); + + auto measurementConv = Common::Util::makeConversionFromIndexMap( + measurements.cbegin(), measurements.cend(), actsMeasurements.cbegin(), + actsMeasurements.cend(), indexMap, + Common::Conversion::TracccMeasurementHash{}, + std::equal_to{}); + + ACTS_DEBUG(std::string("Traccc (1) and Acts (2) measurement index pairing " + "information:\n") + + Common::Measurement::pairingStatistics( + measurements, actsMeasurements, m_detector)); + + // Check if we want to fetch the measurements, spacepoints, and seeds + // instead of use the ones created by traccc. + if (!m_cfg.reconstructionOnly) { + // Convert the traccc spacepoints to traccc space points. + // Create an empty container to hold the converted space points. + SimSpacePointContainer convertedSpacePoints; + auto spacePointConv = + ActsExamples::Traccc::Common::Conversion::convertSpacePoints( + spacepoints, measurementConv, convertedSpacePoints); + + // Repeat the process for the traccc seeds to obtain the seeds converted + // to the Acts edm. + SimSeedContainer convertedSeeds; + ActsExamples::Traccc::Common::Conversion::convertSeeds( + seeds, spacePointConv, convertedSeeds); + + // We have now obtained the traccc seeds as Acts seeds which is useful for + // comparison. The converted seeds will be outputted along with the + // converted tracks. + + // We now want to obtain the converted tracks. + // We run the reconstruction with traccc. + auto tracks = runReconstruction(measurements, spacepoints, seeds, mr); + + // Now we convert the traccc tracks to acts tracks. + auto convertedTracks = Common::Conversion::convertTracks( + tracks, measurementConv, *m_cfg.trackingGeometry, m_detector); + + // Write results. + m_outputSpacePoints(ctx, std::move(convertedSpacePoints)); + m_outputSeeds(ctx, std::move(convertedSeeds)); + m_outputTracks(ctx, std::move(convertedTracks)); + + } else { + // Use externally generated measurements, spacepoints, and seeds instead + // of the ones generated by traccc. + ACTS_INFO( + "Flag 'reconstruction only' set to true - discarding traccc " + "digitization data and using external measurements, spacepoints, and " + "seeds"); + + auto invMeasurementConv = + measurementConv.invert(Common::Conversion::ActsMeasurementHash{}, + Common::Conversion::ActsMeasurementEquals{}); + + // We have previously ensured that the traccc measurement and the + // externally generated acts measurements are the same and obtained their + // conversion data. Thus we do not need to convert the acts measurements + // to traccc measurements. + + // Read the exteranlly generated spacepoints and convert them. + auto& actsSpacePoints = m_inputSpacePoints(ctx); + spacepoints.clear(); + auto spacePointConv = + ActsExamples::Traccc::Common::Conversion::convertSpacePoints( + actsSpacePoints, invMeasurementConv, spacepoints); + + // Read the exteranlly generated seeds and convert them. + auto& actsSeeds = m_inputSeeds(ctx); + seeds.clear(); + ActsExamples::Traccc::Common::Conversion::convertSeeds( + actsSeeds, spacePointConv, seeds); + + // We run the reconstruction with traccc. + auto tracks = runReconstruction(measurements, spacepoints, seeds, mr); + + // Now we convert the traccc tracks to acts tracks. + auto convertedTracks = Common::Conversion::convertTracks( + tracks, measurementConv, *m_cfg.trackingGeometry, m_detector); + + // Write results. + m_outputTracks(ctx, std::move(convertedTracks)); + } + + return ActsExamples::ProcessCode::SUCCESS; +} diff --git a/Examples/Python/CMakeLists.txt b/Examples/Python/CMakeLists.txt index ff1e5901f43a..fd82a744c8fe 100644 --- a/Examples/Python/CMakeLists.txt +++ b/Examples/Python/CMakeLists.txt @@ -101,10 +101,14 @@ if(ACTS_BUILD_PLUGIN_TRACCC) target_sources(ActsPythonBindings PRIVATE src/Covfie.cpp) target_link_libraries(ActsPythonBindings PUBLIC ActsExamplesTraccc) target_sources(ActsPythonBindings PRIVATE src/Traccc.cpp) + target_sources(ActsPythonBindings PRIVATE src/TracccChainHost.cpp) + target_sources(ActsPythonBindings PRIVATE src/TracccChainConfig.cpp) else() target_sources(ActsPythonBindings PRIVATE src/DetrayStub.cpp) target_sources(ActsPythonBindings PRIVATE src/CovfieStub.cpp) target_sources(ActsPythonBindings PRIVATE src/TracccStub.cpp) + target_sources(ActsPythonBindings PRIVATE src/TracccChainHostStub.cpp) + target_sources(ActsPythonBindings PRIVATE src/TracccChainConfigStub.cpp) endif() if(ACTS_BUILD_PLUGIN_ACTSVG) diff --git a/Examples/Python/src/ModuleEntry.cpp b/Examples/Python/src/ModuleEntry.cpp index 791eabc327b0..7e36aebdd89a 100644 --- a/Examples/Python/src/ModuleEntry.cpp +++ b/Examples/Python/src/ModuleEntry.cpp @@ -84,6 +84,8 @@ void addOnnx(Context& ctx); void addOnnxNeuralCalibrator(Context& ctx); void addCovfie(Context& ctx); void addTraccc(Context& ctx); +void addTracccChainConfig(Context& ctx); +void addTracccChainHost(Context& ctx); void addHashing(Context& ctx); } // namespace Acts::Python @@ -153,5 +155,7 @@ PYBIND11_MODULE(ActsPythonBindings, m) { addOnnxNeuralCalibrator(ctx); addCovfie(ctx); addTraccc(ctx); + addTracccChainConfig(ctx); + addTracccChainHost(ctx); addHashing(ctx); } diff --git a/Examples/Python/src/Traccc.cpp b/Examples/Python/src/Traccc.cpp index f590b0e6c29c..7d0620377db9 100644 --- a/Examples/Python/src/Traccc.cpp +++ b/Examples/Python/src/Traccc.cpp @@ -35,45 +35,44 @@ using namespace ActsExamples; namespace Acts::Python { void addTraccc(Context& ctx) { - auto [m, mex] = ctx.get("main", "examples"); - - auto traccc = mex.def_submodule("traccc"); + auto [_, mex] = ctx.get("main", "examples"); + auto m = mex.def_submodule("_traccc"); + ctx.modules["traccc"] = m; /// Define host detray store { py::class_>( - traccc, "DetrayHostStore"); + m, "DetrayHostStore"); /// Convert the detector and create a DetrayHostStore /// /// @param gctx the geometry context /// @param detector the detector to be converted /// @param options the conversion options - traccc.def("convertDetectorHost", [](const GeometryContext& gctx, - const Experimental::Detector& detector, - DetrayConverter::Options options) { + m.def("convertDetectorHost", [](const GeometryContext& gctx, + const Experimental::Detector& detector, + DetrayConverter::Options options) { return DetrayHostStore::create(gctx, detector, options); }); } /// Define the DetrayPropagator { - traccc.def( - "createSlPropagatorHost", - [](std::shared_ptr detrayStore, - bool sterile = false) { - std::shared_ptr detrayProagator = nullptr; + m.def("createSlPropagatorHost", + [](std::shared_ptr detrayStore, + bool sterile = false) { + std::shared_ptr detrayProagator = nullptr; - using DetrayLineStepper = - detray::line_stepper; + using DetrayLineStepper = + detray::line_stepper; - using DetrayPropagator = - DetrayPropagator; + using DetrayPropagator = + DetrayPropagator; - DetrayPropagator::Config cfg{detrayStore, sterile}; - detrayProagator = std::make_shared(cfg); - return detrayProagator; - }); + DetrayPropagator::Config cfg{detrayStore, sterile}; + detrayProagator = std::make_shared(cfg); + return detrayProagator; + }); } } } // namespace Acts::Python diff --git a/Examples/Python/src/TracccChainConfig.cpp b/Examples/Python/src/TracccChainConfig.cpp new file mode 100644 index 000000000000..af81a1ec7314 --- /dev/null +++ b/Examples/Python/src/TracccChainConfig.cpp @@ -0,0 +1,181 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2021 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "ActsExamples/Traccc/TracccChainConfig.hpp" + +#include "Acts/Plugins/Python/Utilities.hpp" +#include "ActsExamples/EventData/Index.hpp" + +#include + +#include +#include + +namespace py = pybind11; + +namespace Acts::Python { + +void addSeedFinderConfig(pybind11::module_ &m) { + using Config = traccc::seedfinder_config; + + auto c = py::class_(m, "SeedFinderConfig").def(py::init<>()); + + ACTS_PYTHON_STRUCT_BEGIN(c, Config); + ACTS_PYTHON_MEMBER(zMin); + ACTS_PYTHON_MEMBER(zMax); + ACTS_PYTHON_MEMBER(rMax); + ACTS_PYTHON_MEMBER(rMin); + ACTS_PYTHON_MEMBER(collisionRegionMin); + ACTS_PYTHON_MEMBER(collisionRegionMax); + ACTS_PYTHON_MEMBER(phiMin); + ACTS_PYTHON_MEMBER(phiMax); + ACTS_PYTHON_MEMBER(minPt); + ACTS_PYTHON_MEMBER(cotThetaMax); + ACTS_PYTHON_MEMBER(deltaRMin); + ACTS_PYTHON_MEMBER(deltaRMax); + ACTS_PYTHON_MEMBER(impactMax); + ACTS_PYTHON_MEMBER(sigmaScattering); + ACTS_PYTHON_MEMBER(maxPtScattering); + ACTS_PYTHON_MEMBER(maxSeedsPerSpM); + ACTS_PYTHON_MEMBER(bFieldInZ); + ACTS_PYTHON_MEMBER(beamPos); + ACTS_PYTHON_MEMBER(radLengthPerSeed); + ACTS_PYTHON_MEMBER(zAlign); + ACTS_PYTHON_MEMBER(rAlign); + ACTS_PYTHON_MEMBER(sigmaError); + ACTS_PYTHON_MEMBER(highland); + ACTS_PYTHON_MEMBER(maxScatteringAngle2); + ACTS_PYTHON_MEMBER(pTPerHelixRadius); + ACTS_PYTHON_MEMBER(minHelixDiameter2); + ACTS_PYTHON_MEMBER(pT2perRadius); + ACTS_PYTHON_MEMBER(phiBinDeflectionCoverage); + ACTS_PYTHON_MEMBER(neighbor_scope); + ACTS_PYTHON_STRUCT_END(); +} + +void addSpacePointGridConfig(py::module_ &m) { + using Config = traccc::spacepoint_grid_config; + + auto c = py::class_(m, "SpacePointGridConfig") + .def(py::init()); + + ACTS_PYTHON_STRUCT_BEGIN(c, Config); + ACTS_PYTHON_MEMBER(bFieldInZ); + ACTS_PYTHON_MEMBER(minPt); + ACTS_PYTHON_MEMBER(rMax); + ACTS_PYTHON_MEMBER(zMax); + ACTS_PYTHON_MEMBER(zMin); + ACTS_PYTHON_MEMBER(deltaRMax); + ACTS_PYTHON_MEMBER(cotThetaMax); + ACTS_PYTHON_MEMBER(impactMax); + ACTS_PYTHON_MEMBER(phiMin); + ACTS_PYTHON_MEMBER(phiMax); + ACTS_PYTHON_MEMBER(phiBinDeflectionCoverage); + ACTS_PYTHON_STRUCT_END(); +} + +void addSeedFilterConfig(py::module_ &m) { + using Config = traccc::seedfilter_config; + + auto c = py::class_(m, "SeedFilterConfig").def(py::init<>()); + + ACTS_PYTHON_STRUCT_BEGIN(c, Config); + ACTS_PYTHON_MEMBER(deltaInvHelixDiameter); + ACTS_PYTHON_MEMBER(impactWeightFactor); + ACTS_PYTHON_MEMBER(compatSeedWeight); + ACTS_PYTHON_MEMBER(deltaRMin); + ACTS_PYTHON_MEMBER(maxSeedsPerSpM); + ACTS_PYTHON_MEMBER(compatSeedLimit); + ACTS_PYTHON_MEMBER(max_triplets_per_spM); + ACTS_PYTHON_MEMBER(good_spB_min_radius); + ACTS_PYTHON_MEMBER(good_spB_weight_increase); + ACTS_PYTHON_MEMBER(good_spT_max_radius); + ACTS_PYTHON_MEMBER(good_spT_weight_increase); + ACTS_PYTHON_MEMBER(good_spB_min_weight); + ACTS_PYTHON_MEMBER(seed_min_weight); + ACTS_PYTHON_MEMBER(spB_min_radius); + ACTS_PYTHON_STRUCT_END(); +} + +void addFindingConfig(py::module_ &m) { + using Config = traccc::finding_config; + + auto c = py::class_(m, "FindingConfig").def(py::init<>()); + + ACTS_PYTHON_STRUCT_BEGIN(c, Config); + ACTS_PYTHON_MEMBER(max_num_branches_per_seed); + ACTS_PYTHON_MEMBER(max_num_branches_per_surface); + ACTS_PYTHON_MEMBER(min_track_candidates_per_track); + ACTS_PYTHON_MEMBER(max_track_candidates_per_track); + ACTS_PYTHON_MEMBER(max_num_skipping_per_cand); + ACTS_PYTHON_MEMBER(min_step_length_for_next_surface); + ACTS_PYTHON_MEMBER(max_step_counts_for_next_surface); + ACTS_PYTHON_MEMBER(chi2_max); + ACTS_PYTHON_MEMBER(propagation); + ACTS_PYTHON_MEMBER(n_measurements_per_thread); + ACTS_PYTHON_STRUCT_END(); +} + +void addFittingConfig(py::module_ &m) { + using Config = traccc::fitting_config; + + auto c = py::class_(m, "FittingConfig").def(py::init<>()); + + ACTS_PYTHON_STRUCT_BEGIN(c, Config); + ACTS_PYTHON_MEMBER(n_iterations); + ACTS_PYTHON_MEMBER(propagation); + ACTS_PYTHON_STRUCT_END(); +} + +void addGreedyAmbiguityResolutionAlgorithmConfig(py::module_ &m) { + using Config = traccc::greedy_ambiguity_resolution_algorithm::config_t; + + auto c = py::class_(m, "GreedyAmbiguityResolutionAlgorithmConfig") + .def(py::init<>()); + + ACTS_PYTHON_STRUCT_BEGIN(c, Config); + ACTS_PYTHON_MEMBER(maximum_shared_hits); + ACTS_PYTHON_MEMBER(maximum_iterations); + ACTS_PYTHON_MEMBER(n_measurements_min); + ACTS_PYTHON_MEMBER(check_obvious_errs); + ACTS_PYTHON_MEMBER(measurement_id_0_warning_threshold); + ACTS_PYTHON_MEMBER(verbose_error); + ACTS_PYTHON_MEMBER(verbose_warning); + ACTS_PYTHON_MEMBER(verbose_info); + ACTS_PYTHON_MEMBER(verbose_debug); + ACTS_PYTHON_STRUCT_END(); +} + +void addTracccChainConfig(Context &ctx) { + auto [_, mex] = ctx.get("main", "examples"); + auto m = mex.def_submodule("_traccc"); + ctx.modules["traccc"] = m; + + addSeedFinderConfig(m); + addSpacePointGridConfig(m); + addSeedFilterConfig(m); + addFindingConfig(m); + addFittingConfig(m); + addGreedyAmbiguityResolutionAlgorithmConfig(m); + + using Config = typename ActsExamples::Traccc::Common::TracccChainConfig; + + auto c = py::class_>(m, "TracccChainConfig") + .def(py::init<>()); + + ACTS_PYTHON_STRUCT_BEGIN(c, Config); + ACTS_PYTHON_MEMBER(seedfinderConfig); + ACTS_PYTHON_MEMBER(spacepointGridConfig); + ACTS_PYTHON_MEMBER(seedfilterConfig); + ACTS_PYTHON_MEMBER(findingConfig); + ACTS_PYTHON_MEMBER(fittingConfig); + ACTS_PYTHON_MEMBER(ambiguityResolutionConfig); + ACTS_PYTHON_STRUCT_END(); +} + +} // namespace Acts::Python diff --git a/Examples/Python/src/TracccChainConfigStub.cpp b/Examples/Python/src/TracccChainConfigStub.cpp new file mode 100644 index 000000000000..04df303e0f71 --- /dev/null +++ b/Examples/Python/src/TracccChainConfigStub.cpp @@ -0,0 +1,20 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2021 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "Acts/Plugins/Python/Utilities.hpp" + +#include +#include + +namespace py = pybind11; +using namespace pybind11::literals; + +namespace Acts::Python { +void addTracccChainConfig(Context& /* ctx */) {} + +} // namespace Acts::Python diff --git a/Examples/Python/src/TracccChainHost.cpp b/Examples/Python/src/TracccChainHost.cpp new file mode 100644 index 000000000000..89138337d816 --- /dev/null +++ b/Examples/Python/src/TracccChainHost.cpp @@ -0,0 +1,37 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2021 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "Acts/Plugins/Python/Utilities.hpp" +#include "ActsExamples/EventData/Index.hpp" +#include "ActsExamples/Traccc/Host/TracccChainAlgorithm.hpp" + +#include + +#include +#include + +namespace py = pybind11; + +namespace Acts::Python { + +void addTracccChainHost(Context& ctx) { + auto [_, mex] = ctx.get("main", "examples"); + auto m = mex.def_submodule("_traccc"); + ctx.modules["traccc"] = m; + + ACTS_PYTHON_DECLARE_ALGORITHM( + ActsExamples::Traccc::Host::TracccChainAlgorithm, m, + "TracccChainAlgorithmHost", detectorFilePath, materialFilePath, + gridFilePath, inputCells, inputMeasurements, inputSpacePoints, inputSeeds, + outputSpacePoints, outputSeeds, outputTracks, enableAmbiguityResolution, + reconstructionOnly, trackingGeometry, field, digitizationConfigs, + seedfinderConfig, seedfilterConfig, findingConfig, fittingConfig, + ambiguityResolutionConfig); +} + +} // namespace Acts::Python diff --git a/Examples/Python/src/TracccChainHostStub.cpp b/Examples/Python/src/TracccChainHostStub.cpp new file mode 100644 index 000000000000..fe00f9765792 --- /dev/null +++ b/Examples/Python/src/TracccChainHostStub.cpp @@ -0,0 +1,14 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2021 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "Acts/Plugins/Python/Utilities.hpp" + +namespace Acts::Python { +void addTracccChainHost(Context& /* ctx */) {} + +} // namespace Acts::Python diff --git a/Plugins/CMakeLists.txt b/Plugins/CMakeLists.txt index f766f8d12931..83f0dc89aaae 100644 --- a/Plugins/CMakeLists.txt +++ b/Plugins/CMakeLists.txt @@ -12,6 +12,7 @@ add_component_if(Onnx PluginOnnx ACTS_BUILD_PLUGIN_ONNX) add_component_if(ExaTrkX PluginExaTrkX ACTS_BUILD_PLUGIN_EXATRKX) add_component_if(Detray PluginDetray ACTS_BUILD_PLUGIN_TRACCC) add_component_if(Covfie PluginCovfie ACTS_BUILD_PLUGIN_TRACCC) +add_component_if(Traccc PluginTraccc ACTS_BUILD_PLUGIN_TRACCC) add_component_if(Hashing PluginHashing ACTS_BUILD_PLUGIN_HASHING) # dependent plugins. depend either on a independent plugins or on one another diff --git a/Plugins/Traccc/CMakeLists.txt b/Plugins/Traccc/CMakeLists.txt new file mode 100644 index 000000000000..bd7e54ae9bee --- /dev/null +++ b/Plugins/Traccc/CMakeLists.txt @@ -0,0 +1,25 @@ +add_library(ActsPluginTraccc SHARED src/CellConversion.cpp) + +target_include_directories( + ActsPluginTraccc + PUBLIC + $ + $ +) +target_link_libraries( + ActsPluginTraccc + PUBLIC + ActsCore + traccc::core + vecmem::core + detray::test_utils + detray::io + ActsPluginCovfie +) + +install( + TARGETS ActsPluginTraccc + EXPORT ActsPluginTracccTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} +) +install(DIRECTORY include/Acts DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/Plugins/Traccc/include/Acts/Plugins/Traccc/BarcodeMap.hpp b/Plugins/Traccc/include/Acts/Plugins/Traccc/BarcodeMap.hpp new file mode 100644 index 000000000000..d468da4db827 --- /dev/null +++ b/Plugins/Traccc/include/Acts/Plugins/Traccc/BarcodeMap.hpp @@ -0,0 +1,42 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Acts include(s) +#include "Acts/Geometry/GeometryIdentifier.hpp" + +// Detray include(s) +#include "detray/core/detector.hpp" + +// System include(s) +#include +#include +#include +#include +#include +#include + +namespace Acts::TracccPlugin { + +/// @brief Creates a map from Acts geometry ID (value) to detray barcode. +/// @param detector the detray detector. +/// @return A map (key = geometry ID value, value = detray geometry barcode). +template +inline std::map +createBarcodeMap(const detray::detector& detector) { + // Construct a map from Acts surface identifiers to Detray barcodes. + std::map + barcodeMap; + for (const auto& surface : detector.surfaces()) { + barcodeMap[surface.source] = surface.barcode(); + } + return barcodeMap; +} + +} // namespace Acts::TracccPlugin diff --git a/Plugins/Traccc/include/Acts/Plugins/Traccc/CellConversion.hpp b/Plugins/Traccc/include/Acts/Plugins/Traccc/CellConversion.hpp new file mode 100644 index 000000000000..175065a84dc7 --- /dev/null +++ b/Plugins/Traccc/include/Acts/Plugins/Traccc/CellConversion.hpp @@ -0,0 +1,55 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Acts include(s) +#include "Acts/Geometry/GeometryHierarchyMap.hpp" +#include "Acts/Geometry/GeometryIdentifier.hpp" + +// Plugin include(s) +#include "Acts/Plugins/Traccc/BarcodeMap.hpp" +#include "Acts/Plugins/Traccc/DigitizationConfig.hpp" + +// Detray include(s) +#include "detray/core/detector.hpp" + +// Traccc include(s) +#include "traccc/edm/cell.hpp" +#include "traccc/geometry/geometry.hpp" +#include "traccc/geometry/silicon_detector_description.hpp" + +// System include(s) +#include +#include +#include +#include +#include +#include + +namespace Acts::TracccPlugin { + +/// @brief Converts a "geometry ID -> traccc cells" map to traccc cells and modules. +/// @param mr The memory resource to use. +/// @param cellsMap A map from Acts geometry ID value to traccc cells. +/// @param geom The traccc geometry. +/// @param dconfig The traccc digitization configuration. +/// @param barcode_map A map from Acts geometry ID value to detray barcode. +/// @return A tuple containing the traccc cells (first item) and traccc modules (second item). +std::tuple +createCellsAndModules( + vecmem::memory_resource& mr, + std::map>&& + cellsMap, + std::optional> geom, + const DigitizationConfig& dconfig, + const std::map& + barcodeMap); + +} // namespace Acts::TracccPlugin diff --git a/Plugins/Traccc/include/Acts/Plugins/Traccc/Detail/AlgebraConversion.hpp b/Plugins/Traccc/include/Acts/Plugins/Traccc/Detail/AlgebraConversion.hpp new file mode 100644 index 000000000000..82f39080f166 --- /dev/null +++ b/Plugins/Traccc/include/Acts/Plugins/Traccc/Detail/AlgebraConversion.hpp @@ -0,0 +1,40 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Acts include(s) +#include "Acts/Definitions/Algebra.hpp" + +// System include(s) +#include + +namespace Acts::TracccPlugin::detail { + +/// @brief Creates a new Acts vector from another vector type. +template +inline Acts::ActsVector toActsVector(const dvector_t& dvec) { + Acts::ActsVector res; + for (std::size_t i = 0; i < N; i++) { + res(i) = static_cast(dvec[i]); + } + return res; +} +/// @brief Creates a new Acts square matrix from another square matrix type. +template +inline Acts::ActsSquareMatrix toActsSquareMatrix(const matrixNxN_t& mat) { + Acts::ActsSquareMatrix res; + for (std::size_t x = 0; x < N; x++) { + for (std::size_t y = 0; y < N; y++) { + res(x, y) = static_cast(mat[x][y]); + } + } + return res; +} + +} // namespace Acts::TracccPlugin::detail diff --git a/Plugins/Traccc/include/Acts/Plugins/Traccc/DigitizationConfig.hpp b/Plugins/Traccc/include/Acts/Plugins/Traccc/DigitizationConfig.hpp new file mode 100644 index 000000000000..8e84f6b859dd --- /dev/null +++ b/Plugins/Traccc/include/Acts/Plugins/Traccc/DigitizationConfig.hpp @@ -0,0 +1,27 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Acts include(s) +#include "Acts/Geometry/GeometryHierarchyMap.hpp" +#include "Acts/Utilities/BinUtility.hpp" + +namespace Acts::TracccPlugin { + +/// Type describing the digitization configuration of a detector module +struct ModuleDigitizationConfig { + Acts::BinUtility segmentation; + char dimensions = 2; + float variance_y = 0.f; +}; + +/// Type describing the digitization configuration for the whole detector +using DigitizationConfig = Acts::GeometryHierarchyMap; + +} // namespace Acts::TracccPlugin diff --git a/Plugins/Traccc/include/Acts/Plugins/Traccc/ReadGeometry.hpp b/Plugins/Traccc/include/Acts/Plugins/Traccc/ReadGeometry.hpp new file mode 100644 index 000000000000..065785c7927e --- /dev/null +++ b/Plugins/Traccc/include/Acts/Plugins/Traccc/ReadGeometry.hpp @@ -0,0 +1,35 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Traccc include(s). +#include "traccc/geometry/geometry.hpp" + +// Detray include(s). +#include "detray/geometry/tracking_surface.hpp" + +namespace Acts::TracccPlugin { + +/// Read in the detector geometry description from a detector object +template +traccc::geometry altReadGeometry(const detector_t& det) { + std::map maps; + using cxt_t = typename detector_t::geometry_context; + const cxt_t ctx0{}; + + for (const auto& surfaceDesc : det.surfaces()) { + const detray::tracking_surface sf{det, surfaceDesc.barcode()}; + + maps.insert({sf.barcode().value(), sf.transform(ctx0)}); + } + + return maps; +} + +} // namespace Acts::TracccPlugin diff --git a/Plugins/Traccc/include/Acts/Plugins/Traccc/SurfaceMap.hpp b/Plugins/Traccc/include/Acts/Plugins/Traccc/SurfaceMap.hpp new file mode 100644 index 000000000000..cb23ebd4fe1f --- /dev/null +++ b/Plugins/Traccc/include/Acts/Plugins/Traccc/SurfaceMap.hpp @@ -0,0 +1,43 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Acts include(s) +#include "Acts/Geometry/GeometryIdentifier.hpp" + +// Detray include(s) +#include "detray/core/detector.hpp" +#include "traccc/definitions/primitives.hpp" + +// System include(s) +#include + +namespace Acts::TracccPlugin { + +/// @brief Creates a map from Acts geometry ID (value) to detray barcode. +/// @param detector the detray detector. +/// @return A map (key = geometry ID value, value = detray geometry barcode). +template +std::map createSurfaceMap( + const detray::detector& detector) { + std::map maps; + + const typename detray::detector::geometry_context + ctx0{}; + + for (const auto& sf_desc : detector.surfaces()) { + const detray::tracking_surface sf{detector, sf_desc.barcode()}; + + maps.insert({sf.barcode().value(), sf.transform(ctx0)}); + } + + return maps; +} + +} // namespace Acts::TracccPlugin diff --git a/Plugins/Traccc/include/Acts/Plugins/Traccc/TrackConversion.hpp b/Plugins/Traccc/include/Acts/Plugins/Traccc/TrackConversion.hpp new file mode 100644 index 000000000000..56d4c2caded8 --- /dev/null +++ b/Plugins/Traccc/include/Acts/Plugins/Traccc/TrackConversion.hpp @@ -0,0 +1,253 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#pragma once + +// Plugin include(s) +#include "Acts/Plugins/Traccc/Detail/AlgebraConversion.hpp" + +// Acts include(s) +#include "Acts/Definitions/Algebra.hpp" +#include "Acts/Definitions/TrackParametrization.hpp" +#include "Acts/EventData/ParticleHypothesis.hpp" +#include "Acts/EventData/SourceLink.hpp" +#include "Acts/EventData/SubspaceHelpers.hpp" +#include "Acts/EventData/TrackContainer.hpp" +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/EventData/TrackProxy.hpp" +#include "Acts/EventData/detail/ParameterTraits.hpp" +#include "Acts/Geometry/TrackingGeometry.hpp" + +// Detray include(s) +#include "detray/core/detector.hpp" +#include "detray/tracks/bound_track_parameters.hpp" + +// Traccc include(s) +#include "traccc/edm/track_state.hpp" + +// Boost include(s) +#include + +// System include(s) +#include +#include +#include + +namespace Acts::TracccPlugin { + +template +inline std::size_t nMeasurements( + const std::vector, allocator_t> + trackStates) { + std::set uniqueMeasurements; + for (const auto& trackState : trackStates) { + uniqueMeasurements.insert(trackState.get_measurement()); + } + return uniqueMeasurements.size(); +} + +/// @brief Creates a new Acts bound track parameters from detray bound track parameters. +/// @param dparams the detray bound track parameters. +/// @param detector the detray detector. +/// @param trackingGeometry the Acts tracking geometry. +/// @return An Acts BoundTrackParameters with data copied from a detray bound_track_parameters. +template +inline auto newParams(const detray::bound_track_parameters& dparams, + const detray::detector& detector, + const Acts::TrackingGeometry& trackingGeometry) { + constexpr std::size_t kFullSize = + Acts::detail::kParametersSize; + Acts::ActsVector parameterVector = + detail::toActsVector(dparams.vector()[0]); + typename Acts::BoundTrackParameters::CovarianceMatrix cov = + detail::toActsSquareMatrix(dparams.covariance()); + Acts::ParticleHypothesis particleHypothesis = + Acts::ParticleHypothesis::pion(); + + auto geoID = + Acts::GeometryIdentifier(detector.surface(dparams.surface_link()).source); + + auto surface = trackingGeometry.findSurface(geoID); + + if (surface == nullptr) { + throw std::runtime_error( + "Mismatch between Acts geometry and detray detector: Acts tracking " + "geometry does not contain geometry ID " + + std::to_string(geoID.value())); + } + + Acts::BoundTrackParameters params(surface->getSharedPtr(), parameterVector, + std::make_optional(std::move(cov)), + particleHypothesis); + + return params; +} + +/// @brief Copies data from a traccc fitting result to an Acts track proxy. +/// @param source the traccc track fitting result to copy from. +/// @param destination the Acts track proxy to copy to. +/// @param detector the detray detector of the traccc track fitting result. +/// @param trackingGeometry the Acts tracking geometry. +template class holder_t, typename metadata_t, + typename container_t> +inline void copyParams( + const detray::bound_track_parameters& dparams, + Acts::TrackProxy& + destination, + const detray::detector& detector, + const Acts::TrackingGeometry& trackingGeometry) { + const auto params = newParams(dparams, detector, trackingGeometry); + destination.parameters() = params.parameters(); + destination.covariance() = params.covariance().value(); + destination.setReferenceSurface(params.referenceSurface().getSharedPtr()); +} + +/// @brief Copies data from a traccc track state to a Acts track state proxy. +/// @param source the traccc track state to copy from. +/// @param destination the Acts track state proxy to copy to. +/// @param detector the detray detector of the traccc track track state. +/// @param trackingGeometry the Acts tracking geometry. +/// @note Sets the uncalibrated source link and calibrated measurement to the traccc measurement. +template +inline void copyTrackState( + const traccc::track_state& source, + Acts::TrackStateProxy& destination, + const detray::detector& detector, + const Acts::TrackingGeometry& trackingGeometry) { + constexpr std::size_t kFullSize = + Acts::detail::kParametersSize; + constexpr std::size_t kSize = 2UL; + + auto geoID = + Acts::GeometryIdentifier(detector.surface(source.surface_link()).source); + auto surface = trackingGeometry.findSurface(geoID)->getSharedPtr(); + destination.setReferenceSurface(surface); + + using Parameters = + typename Acts::TrackStateProxy::Parameters; + using Covariance = + typename Acts::TrackStateProxy::Covariance; + + destination.predicted() = Parameters( + detail::toActsVector(source.predicted().vector()[0]).data()); + destination.predictedCovariance() = Covariance( + detail::toActsSquareMatrix(source.predicted().covariance()) + .data()); + + destination.smoothed() = Parameters( + detail::toActsVector(source.smoothed().vector()[0]).data()); + destination.smoothedCovariance() = Covariance( + detail::toActsSquareMatrix(source.smoothed().covariance()) + .data()); + + destination.filtered() = Parameters( + detail::toActsVector(source.filtered().vector()[0]).data()); + destination.filteredCovariance() = Covariance( + detail::toActsSquareMatrix(source.filtered().covariance()) + .data()); + + destination.jacobian() = Covariance( + detail::toActsSquareMatrix(source.jacobian()).data()); + + destination.chi2() = source.smoothed_chi2(); + + auto typeFlags = destination.typeFlags(); + typeFlags.set(TrackStateFlag::ParameterFlag); + if (surface->surfaceMaterial() != nullptr) { + typeFlags.set(TrackStateFlag::MaterialFlag); + } + if (source.is_hole) { + typeFlags.set(TrackStateFlag::HoleFlag); + } + typeFlags.set(TrackStateFlag::MeasurementFlag); + + const traccc::measurement& measurement = source.get_measurement(); + + destination.setUncalibratedSourceLink(Acts::SourceLink{measurement}); + + destination.allocateCalibrated(kSize); + + destination.template calibrated() = + detail::toActsVector(measurement.local); + + auto cov = Eigen::DiagonalMatrix( + detail::toActsVector(measurement.variance)) + .toDenseMatrix(); + destination.template calibratedCovariance() = cov; + + Acts::FixedSubspaceHelper subspace( + measurement.subs.get_indices()); + destination.setBoundSubspaceIndices( + {Acts::BoundIndices::eBoundLoc0, Acts::BoundIndices::eBoundLoc1}); +} + +/// @brief Creates a new track in the Acts track container. +/// This new track will contain data copied from the traccc track container +/// element (track and track state data). +/// @param tracccTrack The traccc container element to copy from. +/// @param trackContainer The Acts track container. The new tracks will be added to this container. +/// @param detector The detray detector. +/// @param trackingGeometry The Acts tracking geometry. +/// @note Sets the uncalibrated source link and calibrated measurement to the traccc measurement. +template class holder_t, typename metadata_t, + typename container_t> +inline auto makeTrack( + const traccc::container_element& + tracccTrack, + Acts::TrackContainer& + trackContainer, + const detray::detector& detector, + const Acts::TrackingGeometry& trackingGeometry) { + auto fittingResult = tracccTrack.header; + auto trackStates = tracccTrack.items; + + auto track = trackContainer.makeTrack(); + copyParams(fittingResult.fit_params, track, detector, trackingGeometry); + track.chi2() = fittingResult.chi2; + track.nDoF() = static_cast(fittingResult.ndf); + track.nMeasurements() = nMeasurements(trackStates); + + // Make the track states. + for (const auto& tstate : trackStates) { + auto state = track.appendTrackState(); + copyTrackState(tstate, state, detector, trackingGeometry); + } + + track.linkForward(); + + return track; +} + +/// @brief Creates a new track in the Acts track container for each track in the traccc track container. +/// The new tracks will contain data copied from the traccc track container +/// element (track and track state data). +/// @param tracccTrackContainer The traccc container containing the traccc tracks. +/// @param trackContainer The Acts track container. The new tracks will be added to this container. +/// @param detector The detray detector. +/// @param trackingGeometry The Acts tracking geometry. +/// @note Sets the uncalibrated source link and calibrated measurement to the traccc measurement. +template class holder_t, + typename metadata_t, typename container_t> +inline void makeTracks( + const traccc_track_container_t& tracccTrackContainer, + Acts::TrackContainer& + trackContainer, + const detray::detector& detector, + const Acts::TrackingGeometry& trackingGeometry) { + for (std::size_t i = 0; i < tracccTrackContainer.size(); i++) { + makeTrack(tracccTrackContainer[i], trackContainer, detector, + trackingGeometry); + } +} + +} // namespace Acts::TracccPlugin diff --git a/Plugins/Traccc/src/CellConversion.cpp b/Plugins/Traccc/src/CellConversion.cpp new file mode 100644 index 000000000000..7ef1b73cb90f --- /dev/null +++ b/Plugins/Traccc/src/CellConversion.cpp @@ -0,0 +1,132 @@ +// This file is part of the Acts project. +// +// Copyright (C) 2023 CERN for the benefit of the Acts project +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +// Acts include(s) +#include "Acts/Geometry/GeometryHierarchyMap.hpp" +#include "Acts/Geometry/GeometryIdentifier.hpp" + +// Plugin include(s) +#include "Acts/Plugins/Traccc/BarcodeMap.hpp" +#include "Acts/Plugins/Traccc/DigitizationConfig.hpp" + +// Detray include(s) +#include "detray/core/detector.hpp" + +// Traccc include(s) +#include "traccc/edm/cell.hpp" +#include "traccc/geometry/geometry.hpp" +#include "traccc/geometry/silicon_detector_description.hpp" + +// VecMem include(s) +#include "vecmem/memory/memory_resource.hpp" + +// System include(s) +#include +#include +#include +#include +#include +#include + +namespace { + +/// Comparator used for sorting cells. This sorting is one of the assumptions +/// made in the clusterization algorithm +struct CellOrder { + bool operator()(const traccc::cell& lhs, const traccc::cell& rhs) const { + if (lhs.module_link != rhs.module_link) { + return lhs.module_link < rhs.module_link; + } else if (lhs.channel1 != rhs.channel1) { + return (lhs.channel1 < rhs.channel1); + } else { + return (lhs.channel0 < rhs.channel0); + } + } +}; // struct CellOrder + +} // namespace + +namespace Acts::TracccPlugin { + +std::tuple +createCellsAndModules( + vecmem::memory_resource& mr, + std::map>&& + cellsMap, + std::optional> geom, + const DigitizationConfig& dconfig, + const std::map& + barcodeMap) { + traccc::cell_collection_types::host cells(&mr); + traccc::silicon_detector_description::host modules(mr); + + // Sort the cells. + for (auto& [_, mapCells] : cellsMap) { + std::sort(mapCells.begin(), mapCells.end(), CellOrder()); + } + + modules.resize(cellsMap.size()); + + std::size_t module_idx = 0; + + // Fill the output containers with the ordered cells and modules. + for (const auto& [originalGeometryID, mapCells] : cellsMap) { + // Modify the geometry ID of the module if a barcode map is + // provided. + Acts::GeometryIdentifier::Value geometryID = + barcodeMap.at(originalGeometryID).value(); + + // Add the module and its cells to the output. + modules.geometry_id().at(module_idx) = + detray::geometry::barcode{geometryID}; + modules.acts_geometry_id().at(module_idx) = originalGeometryID; + modules.threshold().at(module_idx) = 0.f; + + const DigitizationConfig::Iterator digi_it = + dconfig.find(originalGeometryID); + if (digi_it == dconfig.end()) { + std::ostringstream msg; + msg << "Could not find digitization config for geometry ID: " + << originalGeometryID; + throw std::runtime_error(msg.str()); + } + + // Find/set the 3D position of the detector module. + if (geom) { + const traccc::geometry& g = (*geom).get(); + + // Check if the module ID is known. + if (g.contains(originalGeometryID)) { + throw std::runtime_error("Could not find placement for geometry ID " + + std::to_string(originalGeometryID)); + } + + // Set the value on the module description. + modules.placement().at(module_idx) = g.at(originalGeometryID); + } + + const auto binning_data = digi_it->segmentation.binningData(); + modules.reference_x().at(module_idx) = binning_data.at(0).min; + modules.reference_y().at(module_idx) = binning_data.at(1).min; + modules.pitch_x().at(module_idx) = binning_data.at(0).step; + modules.pitch_y().at(module_idx) = binning_data.at(1).step; + modules.dimensions().back() = digi_it->dimensions; + + module_idx++; + + for (auto& cell : mapCells) { + cells.push_back(cell); + // Set the module link. + cells.back().module_link = modules.size() - 1; + } + } + return std::make_tuple(std::move(cells), std::move(modules)); +} + +} // namespace Acts::TracccPlugin diff --git a/cmake/ActsConfig.cmake.in b/cmake/ActsConfig.cmake.in index b66c5ae3544a..6ff9cc9028a1 100644 --- a/cmake/ActsConfig.cmake.in +++ b/cmake/ActsConfig.cmake.in @@ -84,6 +84,22 @@ if (PluginHashing IN_LIST Acts_COMPONENTS) find_dependency(Annoy @ANNOY_VERSION@ CONFIG EXACT) endif() +if (PluginCovfie IN_LIST Acts_COMPONENTS OR PluginDetray IN_LIST Acts_COMPONENTS OR PluginTraccc IN_LIST Acts_COMPONENTS) + find_dependency(covfie @covfie_VERSION@ CONFIG EXACT) +endif() + +if(PluginDetray IN_LIST Acts_COMPONENTS OR PluginTraccc IN_LIST Acts_COMPONENTS) + find_dependency(vecmem @vecmem_VERSION@ CONFIG EXACT) + find_dependency(covfie @cofvie_VERSION@ CONFIG EXACT) + find_dependency(algebra-plugins @algebra-plugins_VERSION@ CONFIG EXACT) + find_dependency(actsvg @actsvg_VERSION@ CONFIG EXACT) + find_dependency(detray @detray_VERSION@ CONFIG EXACT) +endif() + +if(PluginTraccc IN_LIST Acts_COMPONENTS) + find_dependency(traccc @traccc_VERSION@ CONFIG EXACT) +endif() + # dependencies that we have built ourselves but cannot be # straightforwardly handed to cmake if(NOT @ACTS_USE_SYSTEM_BOOST@) @@ -99,18 +115,6 @@ if(PluginPodio IN_LIST Acts_COMPONENTS) include(${CMAKE_CURRENT_LIST_DIR}/ActsPodioEdmTargets.cmake) endif() -if(PluginDetray IN_LIST Acts_COMPONENTS) - find_dependency(vecmem @vecmem_VERSION@ CONFIG EXACT) - find_dependency(covfie @cofvie_VERSION@ CONFIG EXACT) - find_dependency(algebra-plugins @algebra-plugins_VERSION@ CONFIG EXACT) - find_dependency(actsvg @actsvg_VERSION@ CONFIG EXACT) - find_dependency(detray @detray_VERSION@ CONFIG EXACT) -endif() - -if (PluginCovfie IN_LIST Acts_COMPONENTS) - find_dependency(covfie @covfie_VERSION@ CONFIG EXACT) -endif() - # load **all** available components. we can not just include the requested # components since there can be interdependencies between them. if(NOT Acts_FIND_QUIETLY) diff --git a/docs/getting_started.md b/docs/getting_started.md index fbc247a3e054..f51cf013456d 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -281,6 +281,7 @@ components. | ACTS_BUILD_PLUGIN_FPEMON | Build FPE monitoring plugin
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_GEOMODEL | Build GeoModel plugin
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_TRACCC | Build Traccc plugin
type: `bool`, default: `OFF` | +| ACTS_TRACCC_ENABLE_CUDA | Enable CUDA for the traccc plugin
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_GEANT4 | Build Geant4 plugin
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_EXATRKX | Build the Exa.TrkX plugin
type: `bool`, default: `OFF` | | ACTS_EXATRKX_ENABLE_ONNX | Build the Onnx backend for the exatrkx
plugin
type: `bool`, default: `OFF` | diff --git a/thirdparty/detray/CMakeLists.txt b/thirdparty/detray/CMakeLists.txt index f2f7b24a86d2..07a99f5d875e 100644 --- a/thirdparty/detray/CMakeLists.txt +++ b/thirdparty/detray/CMakeLists.txt @@ -93,6 +93,11 @@ set(DETRAY_SETUP_DFELIBS "Do not set up Dfelibs as part of Detray" ) set(DETRAY_SVG_DISPLAY OFF CACHE BOOL "No not build the ActSVG display module") +set(DETRAY_BUILD_CUDA + ${ACTS_TRACCC_ENABLE_CUDA} + CACHE BOOL + "Turn on/off the detray CUDA build" +) #Now set up its build. FetchContent_MakeAvailable(Detray) diff --git a/thirdparty/traccc/CMakeLists.txt b/thirdparty/traccc/CMakeLists.txt index 705593f34d84..5d7f1a8f1a2d 100644 --- a/thirdparty/traccc/CMakeLists.txt +++ b/thirdparty/traccc/CMakeLists.txt @@ -67,6 +67,12 @@ set(TRACCC_BUILD_BENCHMARKS CACHE BOOL "Turn off the build of the Traccc benchmarks" ) +set(TRACCC_BUILD_IO OFF CACHE BOOL "Turn off the build of the Traccc IO code") +set(TRACCC_BUILD_CUDA + ${ACTS_TRACCC_ENABLE_CUDA} + CACHE BOOL + "Turn on/off the traccc CUDA build" +) # Now set up its build. FetchContent_MakeAvailable(traccc) diff --git a/thirdparty/vecmem/CMakeLists.txt b/thirdparty/vecmem/CMakeLists.txt index 637ea1800b75..0adaea7f64ac 100644 --- a/thirdparty/vecmem/CMakeLists.txt +++ b/thirdparty/vecmem/CMakeLists.txt @@ -28,6 +28,11 @@ set(VECMEM_BUILD_BENCHMARKING CACHE BOOL "Turn off the build of VecMem benchmarking" ) +set(VECMEM_BUILD_CUDA_LIBRARY + ${ACTS_TRACCC_ENABLE_CUDA} + CACHE BOOL + "Turn on/off the vecmem CUDA build" +) # Now set up its build. FetchContent_MakeAvailable(VecMem)