diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index f9c6b53cff1..06bcd8864cb 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -390,6 +390,7 @@ jobs: -DACTS_FORCE_ASSERTIONS=ON -DACTS_BUILD_EXAMPLES_EDM4HEP=ON -DACTS_BUILD_PLUGIN_ACTSVG=ON + -DACTS_USE_SYSTEM_NLOHMANN_JSON=ON - name: Build run: cmake --build build - name: ccache stats diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 25ba774defd..542f12e6102 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -48,6 +48,7 @@ clang_tidy: clang-tidy/clang-tidy.json --exclude "*thirdparty*" --exclude "*ActsPodioEdm*" + --exclude "*build/_deps/*" # Check the combined report against the defined limits - CI/clang_tidy/check_clang_tidy.py --report clang-tidy/clang-tidy.json --config CI/clang_tidy/limits.yml diff --git a/CMakeLists.txt b/CMakeLists.txt index e82e70108ad..ceff42fd772 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,8 +37,6 @@ option(ACTS_BUILD_PLUGIN_PODIO "Build Podio plugin" OFF) 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_COVFIE "Build Covfie plugin" OFF) -option(ACTS_BUILD_PLUGIN_DETRAY "Build Detray plugin" OFF) option(ACTS_BUILD_PLUGIN_TRACCC "Build Traccc plugin" OFF) option(ACTS_USE_SYSTEM_GEOMODEL "Use a system-provided GeoModel installation" ${ACTS_USE_SYSTEM_LIBS}) option(ACTS_BUILD_PLUGIN_GEANT4 "Build Geant4 plugin" OFF) @@ -50,17 +48,17 @@ option(ACTS_BUILD_PLUGIN_JSON "Build json plugin" OFF) option(ACTS_USE_SYSTEM_NLOHMANN_JSON "Use nlohmann::json provided by the system instead of the bundled version" ${ACTS_USE_SYSTEM_LIBS}) option(ACTS_BUILD_PLUGIN_LEGACY "Build legacy plugin" OFF) option(ACTS_BUILD_PLUGIN_ONNX "Build ONNX plugin" OFF) -option(ACTS_SETUP_COVFIE "Explicitly set up covfie for the project" OFF) +option(ACTS_SETUP_COVFIE "Explicitly set up covfie for the project" ON) option(ACTS_USE_SYSTEM_COVFIE "Use a system-provided covfie installation" ${ACTS_USE_SYSTEM_LIBS}) -option(ACTS_SETUP_DETRAY "Explicitly set up detray for the project" OFF) +option(ACTS_SETUP_DETRAY "Explicitly set up detray for the project" ON) option(ACTS_USE_SYSTEM_DETRAY "Use a system-provided detray installation" ${ACTS_USE_SYSTEM_LIBS}) -option(ACTS_SETUP_TRACCC "Explicitly set up traccc for the project" OFF) +option(ACTS_SETUP_TRACCC "Explicitly set up traccc for the project" ON) option(ACTS_USE_SYSTEM_TRACCC "Use a system-provided traccc installation" ${ACTS_USE_SYSTEM_LIBS}) option(ACTS_SETUP_DFELIBS "Explicitly set up dfelibs for the project" ON) option(ACTS_USE_SYSTEM_DFELIBS "Use a system-provided dfelibs installation" ${ACTS_USE_SYSTEM_LIBS}) -option(ACTS_SETUP_VECMEM "Explicitly set up vecmem for the project" OFF) +option(ACTS_SETUP_VECMEM "Explicitly set up vecmem for the project" ON) option(ACTS_USE_SYSTEM_VECMEM "Use a system-provided vecmem installation" ${ACTS_USE_SYSTEM_LIBS}) -option(ACTS_SETUP_ALGEBRAPLUGINS "Explicitly set up algebra-plugins for the project" OFF) +option(ACTS_SETUP_ALGEBRAPLUGINS "Explicitly set up algebra-plugins for the project" ON) option(ACTS_USE_SYSTEM_ALGEBRAPLUGINS "Use a system-provided algebra-plugins installation" ${ACTS_USE_SYSTEM_LIBS}) option(ACTS_BUILD_PLUGIN_TGEO "Build TGeo plugin" OFF) # fatras related options @@ -68,7 +66,7 @@ option(ACTS_BUILD_FATRAS "Build FAst TRAcking Simulation package" OFF) option(ACTS_BUILD_FATRAS_GEANT4 "Build Geant4 Fatras package" OFF) # alignment related options option(ACTS_BUILD_ALIGNMENT "Build Alignment package" OFF) -# examples related options +# examples related optionsExplicitly set up vecmem for the project
type option(ACTS_BUILD_EXAMPLES "Build standalone examples" OFF) option(ACTS_BUILD_EXAMPLES_DD4HEP "Build DD4hep-based code in the examples" OFF) option(ACTS_BUILD_EXAMPLES_EDM4HEP "Build EDM4hep-based code in the examples" OFF) @@ -154,9 +152,11 @@ set_option_if( set_option_if( ACTS_BUILD_PLUGIN_TGEO ACTS_BUILD_PLUGIN_DD4HEP OR ACTS_BUILD_EXAMPLES OR ACTS_BUILD_EVERYTHING) +set_option_if(ACTS_BUILD_PLUGIN_TRACCC + ACTS_BUILD_EVERYTHING) set_option_if( ACTS_BUILD_PLUGIN_JSON - ACTS_BUILD_EXAMPLES OR ACTS_BUILD_EVERYTHING) + ACTS_BUILD_EXAMPLES OR ACTS_BUILD_EVERYTHING OR ACTS_BUILD_PLUGIN_TRACCC) set_option_if( ACTS_BUILD_FATRAS ACTS_BUILD_EXAMPLES OR ACTS_BUILD_EVERYTHING) @@ -164,6 +164,8 @@ set_option_if(ACTS_BUILD_PLUGIN_LEGACY ACTS_BUILD_EVERYTHING) set_option_if(ACTS_BUILD_PLUGIN_EXATRKX ACTS_BUILD_EXAMPLES_EXATRKX) set_option_if(ACTS_BUILD_PLUGIN_FPEMON ACTS_BUILD_EXAMPLES OR ACTS_BUILD_EVERYTHING) +set_option_if(ACTS_BUILD_PLUGIN_TRACCC + ACTS_BUILD_EXAMPLES OR ACTS_BUILD_EVERYTHING) # feature tests include(CheckCXXSourceCompiles) @@ -257,24 +259,6 @@ if (ACTS_SETUP_DFELIBS) endif() endif() -if (ACTS_SETUP_VECMEM) - if (ACTS_USE_SYSTEM_VECMEM) - find_package(vecmem ${_acts_vecmem_version} REQUIRED) - else() - add_subdirectory(thirdparty/vecmem) - # Make the "VecMem language code" available for the whole project. - include( "${VECMEM_LANGUAGE_DIR}/vecmem-check-language.cmake" ) - endif() -endif() - -if (ACTS_SETUP_ALGEBRAPLUGINS) - if (ACTS_USE_SYSTEM_ALGEBRAPLUGINS) - find_package(algebra-plugins ${_acts_algebraplugins_version} REQUIRED) - else() - add_subdirectory(thirdparty/algebra-plugins) - endif() -endif() - find_package(Filesystem REQUIRED) # the `_VERSION` variables set by `setup(... VERSION ...)` have @@ -308,28 +292,9 @@ endmacro() # the same package twice. This avoids having complex if/else trees to sort out # when a particular package is actually needed. +add_definitions(-DALGEBRA_PLUGINS_INCLUDE_ARRAY) + # plugin dependencies -if(ACTS_SETUP_COVFIE) - if(ACTS_USE_SYSTEM_COVFIE) - find_package(covfie ${_acts_covfie_version} REQUIRED CONFIG) - else() - add_subdirectory(thirdparty/covfie) - endif() -endif() -if(ACTS_SETUP_DETRAY) - if(ACTS_USE_SYSTEM_DETRAY) - find_package(detray ${_acts_detray_version} REQUIRED CONFIG) - else() - add_subdirectory(thirdparty/detray) - endif() -endif() -if(ACTS_SETUP_TRACCC) - if(ACTS_USE_SYSTEM_TRACCC) - find_package(traccc ${_acts_traccc_version} REQUIRED CONFIG) - else() - add_subdirectory(thirdparty/traccc) - endif() -endif() if(ACTS_BUILD_PLUGIN_ACTSVG) if(ACTS_USE_SYSTEM_ACTSVG) @@ -406,6 +371,49 @@ if(ACTS_BUILD_PLUGIN_GEANT4) find_package(Geant4 REQUIRED CONFIG COMPONENTS gdml) endif() +if (ACTS_BUILD_PLUGIN_TRACCC) + if (ACTS_SETUP_VECMEM) + if (ACTS_USE_SYSTEM_VECMEM) + find_package(vecmem ${_acts_vecmem_version} REQUIRED) + else() + add_subdirectory(thirdparty/vecmem) + endif() + endif() + + if (ACTS_SETUP_ALGEBRAPLUGINS) + if (ACTS_USE_SYSTEM_ALGEBRAPLUGINS) + find_package(algebra-plugins ${_acts_algebraplugins_version} REQUIRED) + else() + add_subdirectory(thirdparty/algebra-plugins) + endif() + endif() + + if(ACTS_SETUP_COVFIE) + if(ACTS_USE_SYSTEM_COVFIE) + find_package(covfie ${_acts_covfie_version} REQUIRED CONFIG) + else() + add_subdirectory(thirdparty/covfie) + endif() + endif() + + if(ACTS_SETUP_DETRAY) + if(ACTS_USE_SYSTEM_DETRAY) + find_package(detray ${_acts_detray_version} REQUIRED CONFIG) + else() + add_subdirectory(thirdparty/detray) + endif() + endif() + + if(ACTS_SETUP_TRACCC) + if(ACTS_USE_SYSTEM_TRACCC) + find_package(traccc ${_acts_traccc_version} REQUIRED CONFIG) + else() + add_subdirectory(thirdparty/traccc) + endif() + endif() + +endif() + # examples dependencies if(ACTS_BUILD_EXAMPLES) set(THREADS_PREFER_PTHREAD_FLAG ON) diff --git a/Core/include/Acts/EventData/MultiTrajectory.hpp b/Core/include/Acts/EventData/MultiTrajectory.hpp index 0caf463913c..de729c79514 100644 --- a/Core/include/Acts/EventData/MultiTrajectory.hpp +++ b/Core/include/Acts/EventData/MultiTrajectory.hpp @@ -89,6 +89,12 @@ class TrackStateRange { } } + Iterator operator++(int) { + Iterator tmp(*this); + operator++(); + return tmp; + } + bool operator==(const Iterator& other) const { if (!proxy && !other.proxy) { return true; @@ -108,8 +114,8 @@ class TrackStateRange { TrackStateRange(ProxyType _begin) : m_begin{_begin} {} TrackStateRange() : m_begin{std::nullopt} {} - Iterator begin() { return m_begin; } - Iterator end() { return Iterator{std::nullopt}; } + Iterator begin() const { return m_begin; } + Iterator end() const { return Iterator{std::nullopt}; } private: Iterator m_begin; diff --git a/Core/include/Acts/Geometry/GeometryHierarchyMap.hpp b/Core/include/Acts/Geometry/GeometryHierarchyMap.hpp index 1106761d372..63735ac0082 100644 --- a/Core/include/Acts/Geometry/GeometryHierarchyMap.hpp +++ b/Core/include/Acts/Geometry/GeometryHierarchyMap.hpp @@ -93,6 +93,16 @@ class GeometryHierarchyMap { /// Return the number of stored elements. Size size() const { return m_values.size(); } + // Return the geometry identifier - value pairs (i.e., it reconstructs the + // input). + const std::vector getElements() const { + std::vector res; + for (std::size_t i = 0; i < size(); i++) { + res.push_back({m_ids[i], m_values[i]}); + } + return res; + } + /// Access the geometry identifier for the i-th element with bounds check. /// /// @throws std::out_of_range for invalid indices diff --git a/Core/include/Acts/Utilities/BinningData.hpp b/Core/include/Acts/Utilities/BinningData.hpp index 01358a4f14c..e00f2c7c016 100644 --- a/Core/include/Acts/Utilities/BinningData.hpp +++ b/Core/include/Acts/Utilities/BinningData.hpp @@ -243,10 +243,10 @@ class BinningData { // ordered after occurrence if (binvalue == BinningValue::binR || binvalue == BinningValue::binRPhi || binvalue == BinningValue::binX || binvalue == BinningValue::binH) { - return lposition[0]; + return static_cast(lposition[0]); } - return lposition[1]; + return static_cast(lposition[1]); } /// Take the right float value @@ -260,19 +260,19 @@ class BinningData { using VectorHelpers::phi; // ordered after occurrence if (binvalue == BinningValue::binR || binvalue == BinningValue::binH) { - return (perp(position)); + return static_cast(perp(position)); } if (binvalue == BinningValue::binRPhi) { - return (perp(position) * phi(position)); + return static_cast(perp(position) * phi(position)); } if (binvalue == BinningValue::binEta) { - return (eta(position)); + return static_cast(eta(position)); } if (toUnderlying(binvalue) < 3) { - return position[toUnderlying(binvalue)]; + return static_cast(position[toUnderlying(binvalue)]); } // phi gauging - return phi(position); + return static_cast(phi(position)); } /// Get the center value of a bin @@ -284,7 +284,7 @@ class BinningData { const std::vector& bvals = boundaries(); // take the center between bin boundaries float value = - bin < (bvals.size() - 1) ? 0.5 * (bvals[bin] + bvals[bin + 1]) : 0.; + bin < (bvals.size() - 1) ? 0.5f * (bvals[bin] + bvals[bin + 1]) : 0.f; return value; } @@ -296,7 +296,7 @@ class BinningData { float width(std::size_t bin) const { const std::vector& bvals = boundaries(); // take the center between bin boundaries - float value = bin < (bvals.size() - 1) ? bvals[bin + 1] - bvals[bin] : 0.; + float value = bin < (bvals.size() - 1) ? bvals[bin + 1] - bvals[bin] : 0.f; return value; } @@ -419,11 +419,11 @@ class BinningData { /// @return the center value of the bin is given float centerValue(std::size_t bin) const { if (zdim) { - return 0.5 * (min + max); + return 0.5f * (min + max); } float bmin = m_boundaries[bin]; float bmax = bin < m_boundaries.size() ? m_boundaries[bin + 1] : max; - return 0.5 * (bmin + bmax); + return 0.5f * (bmin + bmax); } private: diff --git a/Examples/Algorithms/CMakeLists.txt b/Examples/Algorithms/CMakeLists.txt index bdfc0195b7a..1fce8f85245 100644 --- a/Examples/Algorithms/CMakeLists.txt +++ b/Examples/Algorithms/CMakeLists.txt @@ -18,3 +18,4 @@ add_subdirectory(Vertexing) add_subdirectory_if(Alignment ACTS_BUILD_ALIGNMENT) add_subdirectory(Utilities) add_subdirectory(AmbiguityResolution) +add_subdirectory_if(Traccc ACTS_BUILD_PLUGIN_TRACCC) \ No newline at end of file diff --git a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationAlgorithm.hpp b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationAlgorithm.hpp index 9fafaf0af21..1c8a0c8e322 100644 --- a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationAlgorithm.hpp +++ b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationAlgorithm.hpp @@ -96,6 +96,9 @@ class DigitizationAlgorithm final : public IAlgorithm { /// Geometric digtizer ActsFatras::Channelizer m_channelizer; + using CellsMap = + std::map>; + ReadDataHandle m_simContainerReadHandle{this, "SimHitContainer"}; @@ -103,6 +106,7 @@ class DigitizationAlgorithm final : public IAlgorithm { this, "SourceLinks"}; WriteDataHandle m_measurementWriteHandle{ this, "Measurements"}; + WriteDataHandle m_cellsWriteHandle{this, "Cells"}; WriteDataHandle m_clusterWriteHandle{this, "Clusters"}; WriteDataHandle> m_measurementParticlesMapWriteHandle{this, "MeasurementParticlesMap"}; diff --git a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationConfig.hpp b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationConfig.hpp index bea13649440..1a360c9dd1a 100644 --- a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationConfig.hpp +++ b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationConfig.hpp @@ -139,6 +139,8 @@ class DigitizationConfig { std::string outputSourceLinks = "sourcelinks"; /// Output measurements collection. std::string outputMeasurements = "measurements"; + /// Output cells map (geoID -> collection of cells). + std::string outputCells = "cells"; /// Output cluster collection. std::string outputClusters = "clusters"; /// Output collection to map measured hits to contributing particles. @@ -155,7 +157,7 @@ class DigitizationConfig { /// How close do parameters have to be to consider merged const double mergeNsigma; /// Consider clusters that share a corner as merged (8-cell connectivity) - const bool mergeCommonCorner; + bool mergeCommonCorner; /// Energy deposit threshold for accepting a hit /// For a generic readout frontend we assume 1000 e/h pairs, in Si each /// e/h-pair requiers on average an energy of 3.65 eV (PDG review 2023, diff --git a/Examples/Algorithms/Digitization/src/DigitizationAlgorithm.cpp b/Examples/Algorithms/Digitization/src/DigitizationAlgorithm.cpp index f3b04ac0aff..ddf3a16bc79 100644 --- a/Examples/Algorithms/Digitization/src/DigitizationAlgorithm.cpp +++ b/Examples/Algorithms/Digitization/src/DigitizationAlgorithm.cpp @@ -72,6 +72,7 @@ ActsExamples::DigitizationAlgorithm::DigitizationAlgorithm( m_simContainerReadHandle.initialize(m_cfg.inputSimHits); m_sourceLinkWriteHandle.initialize(m_cfg.outputSourceLinks); m_measurementWriteHandle.initialize(m_cfg.outputMeasurements); + m_cellsWriteHandle.initialize(m_cfg.outputCells); m_clusterWriteHandle.initialize(m_cfg.outputClusters); m_measurementParticlesMapWriteHandle.initialize( m_cfg.outputMeasurementParticlesMap); @@ -154,6 +155,10 @@ ActsExamples::ProcessCode ActsExamples::DigitizationAlgorithm::execute( // Some statistics std::size_t skippedHits = 0; + // Some algorithms do the clusterization themselves such as the traccc chain. + // Thus we need to store the cell data from the simulation. + CellsMap cellsMap; + ACTS_DEBUG("Starting loop over modules ..."); for (const auto& simHitsGroup : groupByModule(simHits)) { // Manual pair unpacking instead of using @@ -255,8 +260,18 @@ ActsExamples::ProcessCode ActsExamples::DigitizationAlgorithm::execute( moduleClusters.add(std::move(dParameters), simHitIdx); } - for (auto& [dParameters, simhits] : - moduleClusters.digitizedParameters()) { + auto digitizeParametersResult = moduleClusters.digitizedParameters(); + + // Store the data of the cells from the simulation. + std::vector cells; + for (auto& [dParameters, simhits] : digitizeParametersResult) { + for (auto cell : dParameters.cluster.channels) { + cells.push_back(std::move(cell)); + } + } + cellsMap.insert({moduleGeoId, cells}); + + for (auto& [dParameters, simhits] : digitizeParametersResult) { // The measurement container is unordered and the index under which // the measurement will be stored is known before adding it. Index measurementIdx = measurements.size(); @@ -293,6 +308,7 @@ ActsExamples::ProcessCode ActsExamples::DigitizationAlgorithm::execute( m_sourceLinkWriteHandle(ctx, std::move(sourceLinks)); m_measurementWriteHandle(ctx, std::move(measurements)); + m_cellsWriteHandle(ctx, std::move(cellsMap)); m_clusterWriteHandle(ctx, std::move(clusters)); m_measurementParticlesMapWriteHandle(ctx, std::move(measurementParticlesMap)); m_measurementSimHitsMapWriteHandle(ctx, std::move(measurementSimHitsMap)); diff --git a/Examples/Algorithms/Traccc/CMakeLists.txt b/Examples/Algorithms/Traccc/CMakeLists.txt new file mode 100644 index 00000000000..4f969248ae2 --- /dev/null +++ b/Examples/Algorithms/Traccc/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(Common) +add_subdirectory(Host) \ No newline at end of file diff --git a/Examples/Algorithms/Traccc/Common/CMakeLists.txt b/Examples/Algorithms/Traccc/Common/CMakeLists.txt new file mode 100644 index 00000000000..826632ec5f4 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/CMakeLists.txt @@ -0,0 +1,26 @@ +add_library( + ActsExamplesTracccCommon SHARED + src/TracccChainAlgorithmBase.cpp + 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/Common/Conversion/CellMapConversion.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Conversion/CellMapConversion.hpp new file mode 100644 index 00000000000..61ec39fe5cc --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Conversion/CellMapConversion.hpp @@ -0,0 +1,34 @@ +// 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" + +// Acts Examples include(s) +#include "ActsExamples/EventData/Cluster.hpp" + +// Traccc include(s) +#include "traccc/edm/cell.hpp" + +// System include(s). +#include +#include +#include +#include + +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/Common/Conversion/DigitizationConversion.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Conversion/DigitizationConversion.hpp new file mode 100644 index 00000000000..715962a5f52 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/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 Examples include(s) +#include "ActsExamples/Digitization/DigitizationConfig.hpp" + +// Traccc include(s) +#include "traccc/io/digitization_config.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. +traccc::digitization_config tracccConfig( + const Acts::GeometryHierarchyMap& config); + +} // namespace ActsExamples::Traccc::Common::Conversion diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Conversion/MeasurementConversion.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Conversion/MeasurementConversion.hpp new file mode 100644 index 00000000000..a2b66e9184b --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Conversion/MeasurementConversion.hpp @@ -0,0 +1,183 @@ +// 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" + +// 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 { + +/// @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 Creates an Acts measurement from a traccc measurement. +/// @tparam the dimension of the Acts measurement (subspace size). +/// @param m the traccc measurement. +/// @param sl the Acts source link to use for the Acts measurement. +/// @returns an Acts measurement with data copied from the traccc measurement +/// and with its source link set to the one provided to the function. +template +inline ActsExamples::FixedSizeMeasurement measurement( + const traccc::measurement& m, const Acts::SourceLink sl) { + // Currently, all traccc measurements have dim 2. + if constexpr (dim != 2) { + std::string errorMsg = + "Dimension is not 2 (dimension = " + std::to_string(m.meas_dim) + ")"; + throw std::runtime_error(errorMsg.c_str()); + } + auto params = Acts::TracccPlugin::detail::toActsVector(m.local); + std::array indices; + for (unsigned int i = 0; i < dim; i++) { + indices[i] = boundIndex(traccc::bound_indices(m.subs.get_indices()[i])); + } + auto cov = Eigen::DiagonalMatrix(dim)>( + Acts::TracccPlugin::detail::toActsVector(m.variance)) + .toDenseMatrix(); + return ActsExamples::FixedSizeMeasurement( + std::move(sl), indices, params, cov); +} + +/// @brief Creates an Acts bound variant measurement from a traccc measurement. +/// Using recursion, the functions determines the dimension of the traccc +/// measurement which is used for the Acts measurement that the bound variant +/// measurement holds. The dimension must lie between [0; max_dim]. +/// @tparam max_dim the largest possible dimension of any measurement type in the variant (default = 4). +/// @param m the traccc measurement. +/// @param sl the Acts source link to use for the Acts measurement. +/// @returns an Acts bound variant measurement with data copied from the traccc measurement +/// and with its source link set to the one provided to the function. +template +inline ActsExamples::BoundVariantMeasurement boundVariantMeasurement( + const traccc::measurement& m, const Acts::SourceLink sl) { + if constexpr (max_dim == 0UL) { + std::string errorMsg = "Invalid/mismatching measurement dimension: " + + std::to_string(m.meas_dim); + throw std::runtime_error(errorMsg.c_str()); + } else { + if (m.meas_dim == max_dim) { + return measurement(m, sl); + } + return boundVariantMeasurement(m, sl); + } +} + +/// @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::FixedSizeMeasurement& + 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::BoundVariantMeasurement& measurement) { + return std::visit([](auto& m) { return getLocal(m); }, measurement); +} + +/// @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::FixedSizeMeasurement& + 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::BoundVariantMeasurement& measurement) { + return std::visit([](auto& m) { return getVariance(m); }, measurement); +} + +/// @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 createActsMeasurements( + const detector_t& detector, + const std::vector& measurements) { + std::vector measurementContainer; + for (const traccc::measurement& m : measurements) { + Acts::GeometryIdentifier moduleGeoId( + detector.surface(m.surface_link).source); + Index measurementIdx = measurementContainer.size(); + IndexSourceLink idxSourceLink{moduleGeoId, measurementIdx}; + measurementContainer.push_back( + boundVariantMeasurement(m, Acts::SourceLink{idxSourceLink})); + } + return measurementContainer; +} + +} // namespace ActsExamples::Traccc::Common::Conversion diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Converter.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Converter.hpp new file mode 100644 index 00000000000..f1c547b7282 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Converter.hpp @@ -0,0 +1,231 @@ +// 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/Plugins/Traccc/CellConversion.hpp" +#include "Acts/Plugins/Traccc/TrackConversion.hpp" + +// Acts Examples include(s) +#include "ActsExamples/EventData/Track.hpp" +#include "ActsExamples/Traccc/Common/Conversion/CellMapConversion.hpp" +#include "ActsExamples/Traccc/Common/Conversion/DigitizationConversion.hpp" +#include "ActsExamples/Traccc/Common/Conversion/MeasurementConversion.hpp" +#include "ActsExamples/Traccc/Common/Measurement/Debug.hpp" +#include "ActsExamples/Traccc/Common/Measurement/MeasurementMatch.hpp" +#include "ActsExamples/Traccc/Common/Util/IndexMap.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" +#include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/EventData/Measurement.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 { + +/// @brief Class for converting Acts data to traccc data. +class Converter { + private: + using detector_t = + detray::detector; + + const Acts::TrackingGeometry& trackingGeometry; + const detector_t& detector; + + // Cache the converted digitalization configuration, the surface transforms, + // and the barcode map. + const traccc::digitization_config digitizationConfig; + const traccc::geometry surfaceTransforms; + const std::map barcodeMap; + + const Acts::Logger& actsLogger; + + /// @brief Writes the number of traccc measurements and Acts measurements to the logger. + /// If the number of measurements do not matching a warning is shown. + /// @param tracccMeasurements the traccc measurements. + /// @param measurements the Acts measurements. + template + void logMeasurementCountComparison( + const std::vector& tracccMeasurements, + const std::vector& measurements) + const { + if (tracccMeasurements.size() != measurements.size()) { + std::stringstream ss; + ss << "Number of measurements do not match (traccc: " + << tracccMeasurements.size() << ", acts: " << measurements.size() + << ")\n" + << "Perhaps mergeCommonCorner or doMerge is false in the digitization " + "algorithm config?"; + ACTS_WARNING(ss.str()); + } else { + std::stringstream ss; + ss << "Number of Acts and Traccc measurements match (count: " + << measurements.size() << ")"; + ACTS_INFO(ss.str()); + } + } + + /// @brief Creates a map from traccc measurements to acts measurements. + /// The traccc elements will map to an acts measurement that it is equivalent + /// to. The resulting map is assumed to be bijective, thus if any element is + /// unable to find a match an error is thrown. + /// @param tracccMeasurements the traccc measurements. + /// @param measurements the acts measurements. + /// @return A map from traccc measurement to acts bound variant measurement. + template + std::map + measurementConversionMap( + const std::vector& tracccMeasurements, + const std::vector& measurements) + const { + logMeasurementCountComparison(tracccMeasurements, measurements); + + auto convertedMeasurements = + Conversion::createActsMeasurements(detector, tracccMeasurements); + auto indexMap = Measurement::matchMap(convertedMeasurements, measurements); + + ACTS_DEBUG(std::string("Traccc (1) and Acts (2) measurement index pairing " + "information:\n") + + Measurement::pairingStatistics(convertedMeasurements, + measurements, indexMap)); + + return Util::referenceMap(tracccMeasurements, measurements, indexMap); + } + + template class holder_t> + void mapMeasurements( + Acts::TrackContainer& + trackContainer, + const std::map + map) const { + for (auto track : trackContainer) { + for (auto trackState : track.trackStates()) { + const auto tracccMeasurement = trackState.getUncalibratedSourceLink() + .template get(); + const ActsExamples::BoundVariantMeasurement& measurement = + map.at(tracccMeasurement); + std::visit( + [&trackState](auto& m) { + trackState.setUncalibratedSourceLink(m.sourceLink()); + + using MeasurementType = std::decay_t; + constexpr std::size_t size = MeasurementType::size(); + trackState.allocateCalibrated(m.size()); + assert(trackState.hasCalibrated()); + + trackState.template calibrated() = m.parameters(); + trackState.template calibratedCovariance() = m.covariance(); + trackState.setProjector(m.projector()); + }, + measurement); + } + } + } + + protected: + const Acts::Logger& logger() const { return actsLogger; } + + public: + Converter(const Acts::TrackingGeometry& tg, const detector_t& det, + const traccc::digitization_config& dc, const traccc::geometry& sf, + const std::map& bm, + const Acts::Logger& l) + : trackingGeometry(tg), + detector(det), + digitizationConfig(dc), + surfaceTransforms(sf), + barcodeMap(bm), + actsLogger(l) {} + + /// @brief Converts a map of cells to traccc cells and modules. + /// @param map The geometry id -> cell collection map which corresponds to each geometry's cells. + /// @param mr The memory resource to use. + /// @returns a tuple containing traccc input data, i.e. (cells, modules). + auto convertCells( + const std::map>& map, + vecmem::memory_resource* mr) const { + auto tcm = Conversion::tracccCellsMap(map); + auto res = Acts::TracccPlugin::createCellsAndModules( + mr, tcm, &surfaceTransforms, &digitizationConfig, &barcodeMap); + + std::stringstream ss; + ss << "Successfully converted Acts cells (obtained " + << std::get<0>(res).size() << " traccc cells and " + << std::get<1>(res).size() << " traccc modules)"; + ACTS_INFO(ss.str()); + + return res; + } + + /// @brief Converts a container of traccc tracks to a container of Acts tracks. + /// The given traccc measurements are compared with the given acts + /// measurements to determine the mapping between measurements and ensure that + /// the two collections of measurements are equivalent. The newly created Acts + /// tracks will use measurements from the acts measurement container. The Acts + /// measurements provided will be used for setting both the calibrated and + /// uncalibrated measurements/sourcelinks. + /// @param tracccTrackContainer The traccc tracks. + /// @param tracccMeasurements the traccc measurements. + /// @param measurements the Acts measurements. + /// @return An Acts const track container. + template + auto convertTracks( + traccc_track_container_t& tracccTrackContainer, + const std::vector& tracccMeasurements, + const std::vector& measurements) + const { + auto trackContainer = std::make_shared(); + auto trackStateContainer = std::make_shared(); + TrackContainer tracks(trackContainer, trackStateContainer); + + Acts::TracccPlugin::makeTracks(tracccTrackContainer, tracks, detector, + trackingGeometry); + + std::stringstream ss; + ss << "Converted " << tracccTrackContainer.size() << " traccc tracks"; + ACTS_INFO(ss.str()); + + auto mcm = measurementConversionMap(tracccMeasurements, measurements); + + ACTS_INFO( + "Found a 1:1 mapping of indexes between traccc and Acts measurements"); + + mapMeasurements(tracks, mcm); + + ACTS_INFO("Updated track state measurements"); + + ConstTrackContainer constTracks{ + std::make_shared( + std::move(*trackContainer)), + std::make_shared( + std::move(*trackStateContainer))}; + + return constTracks; + } +}; + +} // namespace ActsExamples::Traccc::Common diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Measurement/Debug.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Measurement/Debug.hpp new file mode 100644 index 00000000000..0e239582907 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Measurement/Debug.hpp @@ -0,0 +1,38 @@ +// 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" + +// 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 std::vector& measurements1, + const std::vector& measurements2, + const std::map& indexMap); + +} // namespace ActsExamples::Traccc::Common::Measurement diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Measurement/MeasurementMatch.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Measurement/MeasurementMatch.hpp new file mode 100644 index 00000000000..f5e88eb94dd --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Measurement/MeasurementMatch.hpp @@ -0,0 +1,99 @@ +// 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" + +// Acts examples include(s) +#include "ActsExamples/EventData/IndexSourceLink.hpp" +#include "ActsExamples/EventData/Measurement.hpp" +#include "ActsExamples/Traccc/Common/Util/IndexMap.hpp" + +// System include(s). +#include +#include +#include +#include +#include + +// This file is for matching similar measurements in two collections of +// measurements. + +namespace ActsExamples::Traccc::Common::Measurement { + +/// @brief Get the geometry ID from the measurement through its source link. +/// @note Sourcelink is assumed to be of type IndexSourceLink. +inline Acts::GeometryIdentifier getGeometryID( + const ActsExamples::BoundVariantMeasurement& measurement) { + return std::visit( + [](auto& m) { + return m.sourceLink() + .template get() + .geometryId(); + }, + measurement); +} + +/// @brief Checks if two measurements are equal based on their geometry ID and position alone. +/// @param measurement1 the first measurement. +/// @param measurement2 the second measurement. +/// @param maxDistance the tolerance of the difference in local position. +/// The maximum 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. +inline bool measurementEqual( + const ActsExamples::BoundVariantMeasurement& measurement1, + const ActsExamples::BoundVariantMeasurement& measurement2, + const double maxDistance = .001) { + auto gidEq = getGeometryID(measurement1) == getGeometryID(measurement2); + + auto sqNorm = + (Conversion::getLocal(measurement1) - Conversion::getLocal(measurement2)) + .squaredNorm(); + auto locEq = sqNorm <= maxDistance * maxDistance; + + 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. +inline std::size_t measurementHash( + const ActsExamples::BoundVariantMeasurement& measurement) { + // The hash function can be optimized to reduce collisions. + return static_cast(getGeometryID(measurement).value()); +} + +namespace { +const auto wrappedHash = + std::function( + measurementHash); +const auto wrappedEq = + std::function( + [](const ActsExamples::BoundVariantMeasurement& m1, + const ActsExamples::BoundVariantMeasurement& m2) { + return measurementEqual(m1, m2); + }); +} // namespace + +/// @brief Creates a match map by matching the elements in two collection based on their geometry id and approximate position. +/// The two collections of measurements are assumed to contain the same +/// measurements. However, equivalent measurements may be at different indices +/// in the collections. This function determines which indexes correspond to +/// matching measurements. +inline auto matchMap( + const std::vector& from, + const std::vector& to) { + return Util::matchMap(from, to, wrappedHash, wrappedEq); +} + +} // namespace ActsExamples::Traccc::Common::Measurement diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/TracccChainAlgorithmBase.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/TracccChainAlgorithmBase.hpp new file mode 100644 index 00000000000..63ae72ce345 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/TracccChainAlgorithmBase.hpp @@ -0,0 +1,107 @@ +// 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 + +// Acts include(s) +#include "Acts/Definitions/Algebra.hpp" +#include "Acts/Geometry/TrackingGeometry.hpp" +#include "Acts/MagneticField/ConstantBField.hpp" +#include "Acts/MagneticField/MagneticFieldProvider.hpp" +#include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/Digitization/DigitizationConfig.hpp" +#include "ActsExamples/EventData/Cluster.hpp" +#include "ActsExamples/EventData/IndexSourceLink.hpp" +#include "ActsExamples/EventData/Measurement.hpp" +#include "ActsExamples/Framework/DataHandle.hpp" +#include "ActsExamples/Framework/IAlgorithm.hpp" +#include "ActsExamples/Framework/ProcessCode.hpp" + +// Acts Examples include(s) +#include "ActsExamples/Traccc/Common/Converter.hpp" +#include "ActsExamples/Traccc/Common/TracccChainConfig.hpp" + +// Covfie Plugin include(s) +#include "Acts/Plugins/Covfie/FieldConversion.hpp" + +// Detray include(s). +#include "detray/core/detector.hpp" + +// VecMem include(s). +#include + +// System include(s) +#include +#include + +namespace ActsExamples::Traccc::Common { + +class TracccChainAlgorithmBase : public IAlgorithm { + public: + using DetectorHostType = + detray::detector; + using FieldType = Acts::CovfiePlugin::ConstantField; + using CellsMapType = + std::map>; + + struct Config { + std::string inputCells; + std::string inputMeasurements; + std::string outputTracks; + std::shared_ptr trackingGeometry = nullptr; + std::shared_ptr field; + Acts::GeometryHierarchyMap digitizationConfigs; + std::shared_ptr chainConfig; + }; + + /// Construct the traccc algorithm. + /// + /// @param cfg is the algorithm configuration + /// @param lvl is the logging level + TracccChainAlgorithmBase(Config cfg, Acts::Logging::Level lvl); + + /// Const access to the config + const Config& config() const { return m_cfg; } + + protected: + Config m_cfg; + + ReadDataHandle m_inputCells{this, "InputCells"}; + ReadDataHandle m_inputMeasurements{this, + "InputMeasurements"}; + WriteDataHandle m_outputTracks{this, "OutputTracks"}; + + // Memory resource, detector, and converter should be declared in that order + // to ensure order of destructor call. + vecmem::host_memory_resource hostMemoryResource; + const DetectorHostType detector; + const FieldType field; + const Converter converter; + + private: + /// @brief Test if the configuration is valid. + void TestValidConfig() { + if (m_cfg.inputCells.empty()) { + throw std::invalid_argument("Missing input cells"); + } + + if (m_cfg.field == nullptr) { + throw std::invalid_argument("Missing field"); + } + + if (m_cfg.trackingGeometry == nullptr) { + throw std::invalid_argument("Missing track geometry"); + } + + if (m_cfg.digitizationConfigs.empty()) { + throw std::invalid_argument("Missing digitization configuration"); + } + } +}; + +} // namespace ActsExamples::Traccc::Common diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/TracccChainConfig.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/TracccChainConfig.hpp new file mode 100644 index 00000000000..10b1584ac0c --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/TracccChainConfig.hpp @@ -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/. + +#pragma once + +// 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/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 { + using ScalarType = traccc::scalar; + + using SeedfinderConfigType = typename traccc::seedfinder_config; + using SpacepointGridConfigType = typename traccc::spacepoint_grid_config; + using SeedfilterConfigType = typename traccc::seedfilter_config; + using FindingConfigType = typename traccc::finding_config; + using FittingConfigType = typename traccc::fitting_config; + using AmbiguityResolutionConfigType = + typename traccc::greedy_ambiguity_resolution_algorithm::config_t; + + SeedfinderConfigType seedfinderConfig; + SpacepointGridConfigType spacepointGridConfig{seedfinderConfig}; + SeedfilterConfigType seedfilterConfig; + FindingConfigType findingConfig; + FittingConfigType fittingConfig; + AmbiguityResolutionConfigType ambiguityResolutionConfig; +}; + +} // namespace ActsExamples::Traccc::Common diff --git a/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Util/IndexMap.hpp b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Util/IndexMap.hpp new file mode 100644 index 00000000000..d1dc301af86 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/include/ActsExamples/Traccc/Common/Util/IndexMap.hpp @@ -0,0 +1,127 @@ +// 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 + +namespace ActsExamples::Traccc::Common::Util { + +/// @brief +/// @tparam T +/// @tparam A +/// @param out the index into the candidate indices vector. +/// Taking this index into the candidate indices vector will get the index in . +/// @param element +/// @param candidateIdxs +/// @param candidateVec +/// @param eqFn +/// @return +template +auto findMatchIdx(std::size_t* out, const T& element, + const std::vector& candidateIdxs, + const std::vector& candidateVec, + const std::function& eqFn) { + for (std::size_t i = 0; i < candidateIdxs.size(); i++) { + auto idx = candidateIdxs[i]; + if (eqFn(element, candidateVec[idx])) { + *out = i; + return true; + } + } + return false; +} + +/// @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(const std::vector& from, + const std::vector& to, + const std::function& lshFn, + const std::function& 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)". + + 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 (std::size_t toIdx = 0; toIdx < to.size(); toIdx++) { + auto& toElement = to[toIdx]; + auto toElementHash = lshFn(toElement); + map1[toElementHash].push_back(toIdx); + } + + // We can build the map "index in 'from' -> index in 'to'" directly. + std::map res; + for (std::size_t fromIdx = 0; fromIdx < from.size(); fromIdx++) { + auto& fromElement = from[fromIdx]; + auto fromElementHash = lshFn(fromElement); + // We now find the exact element to match fromElement with in the bucket. + auto& candidateIdxs = map1[fromElementHash]; + std::size_t idx; + if (candidateIdxs.empty() || + !findMatchIdx(&idx, fromElement, candidateIdxs, to, eqFn)) { + throw std::runtime_error("Could not find a match for an element"); + } + res[fromIdx] = candidateIdxs[idx]; + if (bijection) { + candidateIdxs.erase(candidateIdxs.begin() + idx); + } + } + return res; +} + +/// @brief Creates a map from elements in one vector to another. +/// The resulting map holds the elements by reference. +/// @param from the first collection. +/// @param to the second collection. +/// @param indexMap a map of indices in the first collection to indices in the second collection. +/// @returns the map: element in first collection -> element in second collection. +template +std::map referenceMap( + const std::vector& from, const std::vector& to, + const std::map& indexMap) { + assert(from.size() == to.size()); + std::map res; + for (const auto [i, j] : indexMap) { + res.emplace(std::piecewise_construct, std::forward_as_tuple(from[i]), + std::forward_as_tuple(to[j])); + } + return res; +} + +} // 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 00000000000..8cdaf21ed81 --- /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/Common/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 00000000000..dcd7e616dfe --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/src/Conversion/DigitizationConversion.cpp @@ -0,0 +1,48 @@ +// 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" +#include "ActsExamples/Traccc/Common/Conversion/DigitizationConversion.hpp" + +// Traccc include(s) +#include "traccc/io/digitization_config.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. +traccc::digitization_config tracccConfig( + const Acts::GeometryHierarchyMap& config) { + using ElementType = + std::pair; + std::vector vec; + for (auto& e : config.getElements()) { + vec.push_back({e.first, traccc::module_digitization_config{ + getSegmentation(e.second)}}); + } + return traccc::digitization_config(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 00000000000..d759770a324 --- /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/Common/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 00000000000..19a45592cde --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/src/Debug/Debug.cpp @@ -0,0 +1,117 @@ +// 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/Common/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 std::vector& measurements1, + const std::vector& measurements2, + const std::map& indexMap) { + std::vector table; + for (std::size_t idx1 = 0; idx1 < measurements1.size(); ++idx1) { + MeasurementMatchRow row; + auto measurement1 = measurements1[idx1]; + row.idx1 = idx1; + row.local1 = Conversion::getLocal(measurement1); + row.variance1 = Conversion::getVariance(measurement1); + + auto idx2 = indexMap.at(idx1); + auto measurement2 = measurements2[idx2]; + row.idx2 = idx2; + row.local2 = Conversion::getLocal(measurement2); + row.variance2 = Conversion::getVariance(measurement2); + + row.distanceLocal = (row.local1 - row.local2).norm(); + table.push_back(row); + } + 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 std::vector& measurements1, + const std::vector& 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/Common/src/TracccChainAlgorithmBase.cpp b/Examples/Algorithms/Traccc/Common/src/TracccChainAlgorithmBase.cpp new file mode 100644 index 00000000000..b9bf4813253 --- /dev/null +++ b/Examples/Algorithms/Traccc/Common/src/TracccChainAlgorithmBase.cpp @@ -0,0 +1,76 @@ +// 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/. + +// Traccc plugin include(s) +#include "ActsExamples/Traccc/Common/TracccChainAlgorithmBase.hpp" + +// Acts include(s) +#include "Acts/Utilities/Logger.hpp" +#include "ActsExamples/Framework/IAlgorithm.hpp" + +// Detray include(s). +#include "detray/core/detector.hpp" +#include "detray/io/frontend/detector_reader.hpp" + +// VecMem include(s). +#include + +// System include(s) +#include +#include + +namespace { + +// Temporarily used to get the corresponding detray detector for the Acts +// geometry. Will be replaced when the detray plugin containing geometry +// conversion is complete. +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 + +/// Construct the traccc algorithm. +/// +/// @param cfg is the algorithm configuration +/// @param lvl is the logging level +ActsExamples::Traccc::Common::TracccChainAlgorithmBase:: + TracccChainAlgorithmBase(Config cfg, Acts::Logging::Level lvl) + : ActsExamples::IAlgorithm("TracccChainAlgorithm", lvl), + m_cfg(std::move(cfg)), + detector((TestValidConfig(), readDetector( + &hostMemoryResource, + "/home/frederik/Desktop/CERN-TECH/input/" + "odd-detray_geometry_detray.json"))), + field(Acts::CovfiePlugin::covfieField(*m_cfg.field)), + converter{*m_cfg.trackingGeometry, + detector, + Conversion::tracccConfig(m_cfg.digitizationConfigs), + traccc::io::alt_read_geometry(detector), + Acts::TracccPlugin::createBarcodeMap(detector), + logger()} { + m_inputCells.initialize(m_cfg.inputCells); + m_inputMeasurements.initialize(m_cfg.inputMeasurements); + m_outputTracks.initialize(m_cfg.outputTracks); +} diff --git a/Examples/Algorithms/Traccc/Host/CMakeLists.txt b/Examples/Algorithms/Traccc/Host/CMakeLists.txt new file mode 100644 index 00000000000..afad5a72094 --- /dev/null +++ b/Examples/Algorithms/Traccc/Host/CMakeLists.txt @@ -0,0 +1,20 @@ +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 00000000000..23d33656ca3 --- /dev/null +++ b/Examples/Algorithms/Traccc/Host/include/ActsExamples/Traccc/Host/TracccChainAlgorithm.hpp @@ -0,0 +1,50 @@ +// 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 "ActsExamples/Traccc/Common/TracccChainAlgorithmBase.hpp" +#include "ActsExamples/Traccc/Host/Types.hpp" + +// VecMem include(s). +#include + +namespace ActsExamples::Traccc::Host { + +class TracccChainAlgorithm final : public Common::TracccChainAlgorithmBase { + public: + /// Construct the traccc algorithm. + /// + /// @param cfg is the algorithm configuration + /// @param lvl is the logging level + TracccChainAlgorithm(Config cfg, Acts::Logging::Level lvl); + + /// Run the algorithm. + /// + /// @param ctx is the algorithm context with event information + /// @return a process code indication success or failure + ProcessCode execute(const AlgorithmContext& ctx) const override; + + private: + using HostTypes = + typename ActsExamples::Chain::Host::Types; + + typename HostTypes::ClusterizationAlgorithmType clusterizationAlgorithm; + typename HostTypes::SpacepointFormationAlgorithmType + spacepointFormationAlgorithm; + typename HostTypes::SeedingAlgorithmType seedingAlgorithm; + typename HostTypes::TrackParametersEstimationAlgorithmType + trackParametersEstimationAlgorithm; + typename HostTypes::FindingAlgorithmType findingAlgorithm; + typename HostTypes::FittingAlgorithmType fittingAlgorithm; + typename HostTypes::AmbiguityResolutionAlgorithmType + ambiguityResolutionAlgorithm; +}; + +} // 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 00000000000..d3c904a66e7 --- /dev/null +++ b/Examples/Algorithms/Traccc/Host/include/ActsExamples/Traccc/Host/Types.hpp @@ -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/. + +#pragma once + +// 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/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::Chain::Host { + +template +struct Types { + using DetectorType = + detray::detector; + using StepperType = + detray::rk_stepper>; + using NavigatorType = detray::navigator; + using FitterType = traccc::kalman_fitter; + + 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::Chain::Host diff --git a/Examples/Algorithms/Traccc/Host/src/TracccChainAlgorithm.cpp b/Examples/Algorithms/Traccc/Host/src/TracccChainAlgorithm.cpp new file mode 100644 index 00000000000..fe8e9b310b6 --- /dev/null +++ b/Examples/Algorithms/Traccc/Host/src/TracccChainAlgorithm.cpp @@ -0,0 +1,98 @@ +// 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" + +// System include(s). +#include +#include +#include +#include +#include +#include +#include +#include + +ActsExamples::Traccc::Host::TracccChainAlgorithm::TracccChainAlgorithm( + Config cfg, Acts::Logging::Level lvl) + : ActsExamples::Traccc::Common::TracccChainAlgorithmBase(std::move(cfg), + std::move(lvl)), + clusterizationAlgorithm(hostMemoryResource), + spacepointFormationAlgorithm(hostMemoryResource), + seedingAlgorithm(m_cfg.chainConfig->seedfinderConfig, + m_cfg.chainConfig->spacepointGridConfig, + m_cfg.chainConfig->seedfilterConfig, hostMemoryResource), + trackParametersEstimationAlgorithm(hostMemoryResource), + findingAlgorithm(m_cfg.chainConfig->findingConfig), + fittingAlgorithm(m_cfg.chainConfig->fittingConfig), + ambiguityResolutionAlgorithm( + m_cfg.chainConfig->ambiguityResolutionConfig) {} + +ActsExamples::ProcessCode +ActsExamples::Traccc::Host::TracccChainAlgorithm::execute( + const ActsExamples::AlgorithmContext& ctx) const { + vecmem::host_memory_resource mr; + + typename HostTypes::ClusterizationAlgorithmType::output_type measurements{ + &mr}; + typename HostTypes::SpacepointFormationAlgorithmType::output_type spacepoints{ + &mr}; + typename HostTypes::SeedingAlgorithmType::output_type seeds{&mr}; + typename HostTypes::TrackParametersEstimationAlgorithmType::output_type + params{&mr}; + typename HostTypes::FindingAlgorithmType::output_type trackCandidates{&mr}; + typename HostTypes::FittingAlgorithmType::output_type trackStates{&mr}; + typename HostTypes::AmbiguityResolutionAlgorithmType::output_type + resolvedTrackStates{&mr}; + + const auto cellsMap = m_inputCells(ctx); + + auto [cells, modules] = converter.convertCells(cellsMap, &mr); + + measurements = clusterizationAlgorithm(vecmem::get_data(cells), + vecmem::get_data(modules)); + + ACTS_INFO("Ran the clusterization algorithm"); + + spacepoints = spacepointFormationAlgorithm(vecmem::get_data(measurements), + vecmem::get_data(modules)); + + ACTS_INFO("Ran the spacepoint formation algorithm"); + + seeds = seedingAlgorithm(spacepoints); + + ACTS_INFO("Ran the seeding algorithm"); + + const typename FieldType::view_t fieldView(field); + + // Traccc expects a field vector of a constant field. + params = trackParametersEstimationAlgorithm(spacepoints, seeds, + fieldView.at(0.f, 0.f, 0.f)); + + ACTS_INFO("Ran the parameters estimation algorithm"); + + trackCandidates = findingAlgorithm(detector, field, measurements, params); + + ACTS_INFO("Ran the finding algorithm"); + + trackStates = fittingAlgorithm(detector, field, trackCandidates); + + ACTS_INFO("Ran the fitting algorithm"); + + resolvedTrackStates = ambiguityResolutionAlgorithm(trackStates); + + ACTS_INFO("Ran the ambiguity resolution algorithm"); + + const auto actsMeasurements = m_inputMeasurements(ctx); + auto result = converter.convertTracks(resolvedTrackStates, measurements, + actsMeasurements); + + m_outputTracks(ctx, std::move(result)); + return ActsExamples::ProcessCode::SUCCESS; +} diff --git a/Examples/Python/CMakeLists.txt b/Examples/Python/CMakeLists.txt index d15a8cf8b7f..cda7ddeb500 100644 --- a/Examples/Python/CMakeLists.txt +++ b/Examples/Python/CMakeLists.txt @@ -84,13 +84,6 @@ else() target_sources(ActsPythonBindings PRIVATE src/GeoModelStub.cpp) endif() -if(ACTS_BUILD_PLUGIN_DETRAY) - target_link_libraries(ActsPythonBindings PUBLIC ActsPluginDetray) - target_sources(ActsPythonBindings PRIVATE src/Detray.cpp) -else() - target_sources(ActsPythonBindings PRIVATE src/DetrayStub.cpp) -endif() - if(ACTS_BUILD_PLUGIN_ACTSVG) target_link_libraries(ActsPythonBindings PUBLIC ActsExamplesIoSvg) target_sources(ActsPythonBindings PRIVATE src/Svg.cpp) @@ -204,6 +197,22 @@ else() target_sources(ActsPythonBindings PRIVATE src/OnnxNeuralCalibratorStub.cpp) endif() +if(ACTS_BUILD_PLUGIN_TRACCC) + target_link_libraries(ActsPythonBindings PUBLIC ActsPluginCovfie) + target_sources(ActsPythonBindings PRIVATE src/Covfie.cpp) + target_link_libraries(ActsPythonBindings PUBLIC ActsPluginDetray) + target_sources(ActsPythonBindings PRIVATE src/Detray.cpp) + target_link_libraries(ActsPythonBindings PUBLIC ActsExamplesTracccCommon) + target_link_libraries(ActsPythonBindings PUBLIC ActsExamplesTracccHost) + target_sources(ActsPythonBindings PRIVATE src/TracccChainHost.cpp) + target_sources(ActsPythonBindings PRIVATE src/TracccChainConfig.cpp) +else() + target_sources(ActsPythonBindings PRIVATE src/CovfieStub.cpp) + target_sources(ActsPythonBindings PRIVATE src/DetrayStub.cpp) + target_sources(ActsPythonBindings PRIVATE src/TracccChainHostStub.cpp) + target_sources(ActsPythonBindings PRIVATE src/TracccChainConfigStub.cpp) +endif() + configure_file(setup.sh.in ${_python_dir}/setup.sh @ONLY) install(FILES ${_python_dir}/setup.sh DESTINATION "python") diff --git a/Examples/Python/python/acts/examples/reconstruction.py b/Examples/Python/python/acts/examples/reconstruction.py index 596f6302674..b165376e40b 100644 --- a/Examples/Python/python/acts/examples/reconstruction.py +++ b/Examples/Python/python/acts/examples/reconstruction.py @@ -1860,7 +1860,7 @@ def addAmbiguityResolutionMLDBScan( addTrackWriters( s, name="ambiMLDBScan", - trajectories=alg.config.outputTracks, + tracks=alg.config.outputTracks, outputDirRoot=outputDirRoot, outputDirCsv=outputDirCsv, writeStates=writeTrajectories, @@ -2061,3 +2061,69 @@ def addSingleSeedVertexFinding( ) return s + + +def addTracccChain( + s: acts.examples.Sequencer, + trackingGeometry: acts.TrackingGeometry, + field: acts.MagneticFieldProvider, + digiConfigFile: Union[Path, str], + chainConfig, + inputCells: Optional[str] = "cells", # "InputCells", + inputMeasurements: Optional[str] = "measurements", + outputTracks: Optional[str] = "traccc_tracks", + outputDirRoot: Optional[Union[Path, str]] = None, + outputDirCsv: Optional[Union[Path, str]] = None, + logLevel: Optional[acts.logging.Level] = None, + writeTrajectories: bool = True, + writeCovMat=False, +) -> None: + from acts.examples import TracccChainAlgorithmHost + + customLogLevel = acts.examples.defaultLogging(s, logLevel) + + alg = TracccChainAlgorithmHost( + level=customLogLevel(), + inputCells=inputCells, + inputMeasurements=inputMeasurements, + outputTracks=outputTracks, + trackingGeometry=trackingGeometry, + field=field, + digitizationConfigs=acts.examples.readDigiConfigFromJson( + str(digiConfigFile), + ), + chainConfig=chainConfig, + ) + + s.addAlgorithm(alg) + s.addWhiteboardAlias("tracks", alg.config.outputTracks) + + matchAlg = acts.examples.TrackTruthMatcher( + level=customLogLevel(), + inputTracks=alg.config.outputTracks, + inputParticles="particles", + inputMeasurementParticlesMap="measurement_particles_map", + outputTrackParticleMatching="track_particle_matching", + outputParticleTrackMatching="particle_track_matching", + ) + s.addAlgorithm(matchAlg) + s.addWhiteboardAlias( + "track_particle_matching", matchAlg.config.outputTrackParticleMatching + ) + s.addWhiteboardAlias( + "particle_track_matching", matchAlg.config.outputParticleTrackMatching + ) + + addTrackWriters( + s, + name="traccc", + tracks=alg.config.outputTracks, + outputDirCsv=outputDirCsv, + outputDirRoot=outputDirRoot, + writeStates=writeTrajectories, + writeSummary=writeTrajectories, + writeCKFperformance=False, + logLevel=logLevel, + writeCovMat=writeCovMat, + ) + return s diff --git a/Examples/Python/python/acts/examples/simulation.py b/Examples/Python/python/acts/examples/simulation.py index 76cf0685aa8..f23a692a375 100644 --- a/Examples/Python/python/acts/examples/simulation.py +++ b/Examples/Python/python/acts/examples/simulation.py @@ -773,6 +773,7 @@ def addDigitization( outputDirRoot: Optional[Union[Path, str]] = None, rnd: Optional[acts.examples.RandomNumbers] = None, doMerge: Optional[bool] = None, + mergeCommonCorner: Optional[bool] = None, minEnergyDeposit: Optional[float] = None, logLevel: Optional[acts.logging.Level] = None, ) -> acts.examples.Sequencer: @@ -812,6 +813,7 @@ def addDigitization( outputMeasurementParticlesMap="measurement_particles_map", outputMeasurementSimHitsMap="measurement_simhits_map", doMerge=doMerge, + mergeCommonCorner=mergeCommonCorner, ) # Not sure how to do this in our style diff --git a/Examples/Python/src/Covfie.cpp b/Examples/Python/src/Covfie.cpp new file mode 100644 index 00000000000..cf29387ca3a --- /dev/null +++ b/Examples/Python/src/Covfie.cpp @@ -0,0 +1,62 @@ +// 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/Covfie/FieldConversion.hpp" +#include "Acts/Plugins/Python/Utilities.hpp" + +#include +#include + +namespace py = pybind11; +using namespace pybind11::literals; + +namespace Acts::Python { + +namespace { + +template +typename field_t::view_t newView(const field_t& field) { + typename field_t::view_t view(field); + return view; +} + +template +void declareCovfieField(py::module& m, const std::string& fieldName) { + using view_t = typename field_t::view_t; + m.def("newView", static_cast(&newView)); + py::class_>(m, fieldName.c_str()); + py::class_>( + m, (fieldName + std::string("View")).c_str()) + .def("at", &view_t::template at); +} + +} // namespace +void addCovfie(Context& ctx) { + auto main = ctx.get("main"); + auto m = main.def_submodule("covfie", "Submodule for covfie conversion"); + + declareCovfieField(m, + "CovfieConstantField"); + declareCovfieField( + m, "CovfieAffineLinearStridedField"); + + m.def("covfieField", + py::overload_cast( + &Acts::CovfiePlugin::covfieField)); + m.def("covfieField", py::overload_cast( + &Acts::CovfiePlugin::covfieField)); + m.def( + "covfieField", + py::overload_cast&, + const std::vector&, const std::vector&>( + &Acts::CovfiePlugin::covfieField)); +} + +} // namespace Acts::Python diff --git a/Examples/Python/src/CovfieStub.cpp b/Examples/Python/src/CovfieStub.cpp new file mode 100644 index 00000000000..49ec071fd8c --- /dev/null +++ b/Examples/Python/src/CovfieStub.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 addCovfie(Context& /* ctx */) {} + +} // namespace Acts::Python diff --git a/Examples/Python/src/Digitization.cpp b/Examples/Python/src/Digitization.cpp index 54ec8934ac1..b173edefa61 100644 --- a/Examples/Python/src/Digitization.cpp +++ b/Examples/Python/src/Digitization.cpp @@ -70,12 +70,12 @@ void addDigitization(Context& ctx) { ACTS_PYTHON_MEMBER(surfaceByIdentifier); ACTS_PYTHON_MEMBER(randomNumbers); ACTS_PYTHON_MEMBER(doMerge); + ACTS_PYTHON_MEMBER(mergeCommonCorner); ACTS_PYTHON_MEMBER(minEnergyDeposit); ACTS_PYTHON_MEMBER(digitizationConfigs); ACTS_PYTHON_STRUCT_END(); c.def_readonly("mergeNsigma", &Config::mergeNsigma); - c.def_readonly("mergeCommonCorner", &Config::mergeCommonCorner); patchKwargsConstructor(c); diff --git a/Examples/Python/src/MagneticField.cpp b/Examples/Python/src/MagneticField.cpp index a8279675696..603437b02c1 100644 --- a/Examples/Python/src/MagneticField.cpp +++ b/Examples/Python/src/MagneticField.cpp @@ -36,12 +36,26 @@ using namespace pybind11::literals; namespace Acts::Python { +/// @brief Get the field value without needing a cache. +/// @note Does not return an Acts::Result, so will throw an error if the lookup fails. +Acts::Vector3 getField(Acts::MagneticFieldProvider& self, + const Acts::Vector3& position) { + Acts::MagneticFieldContext mctx; + Acts::MagneticFieldProvider::Cache cache = self.makeCache(mctx); + auto lookupResult = self.getField(position, cache); + if (!lookupResult.ok()) { + throw std::runtime_error{"Field lookup failure"}; + } + return *lookupResult; +} + void addMagneticField(Context& ctx) { auto [m, mex, prop] = ctx.get("main", "examples", "propagation"); py::class_>( - m, "MagneticFieldProvider"); + m, "MagneticFieldProvider") + .def("getField", &getField); py::class_>( diff --git a/Examples/Python/src/ModuleEntry.cpp b/Examples/Python/src/ModuleEntry.cpp index 8b129e37fae..256c6c78734 100644 --- a/Examples/Python/src/ModuleEntry.cpp +++ b/Examples/Python/src/ModuleEntry.cpp @@ -78,6 +78,9 @@ void addSvg(Context& ctx); void addObj(Context& ctx); void addOnnx(Context& ctx); void addOnnxNeuralCalibrator(Context& ctx); +void addCovfie(Context& ctx); +void addTracccChainConfig(Context& ctx); +void addTracccChainHost(Context& ctx); } // namespace Acts::Python @@ -140,4 +143,7 @@ PYBIND11_MODULE(ActsPythonBindings, m) { addSvg(ctx); addOnnx(ctx); addOnnxNeuralCalibrator(ctx); + addCovfie(ctx); + addTracccChainConfig(ctx); + addTracccChainHost(ctx); } diff --git a/Examples/Python/src/TracccChainConfig.cpp b/Examples/Python/src/TracccChainConfig.cpp new file mode 100644 index 00000000000..e57a7dabf30 --- /dev/null +++ b/Examples/Python/src/TracccChainConfig.cpp @@ -0,0 +1,188 @@ +// 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/Common/TracccChainConfig.hpp" + +#include "Acts/Plugins/Python/Utilities.hpp" +#include "Acts/Utilities/TypeTraits.hpp" +#include "ActsExamples/EventData/Index.hpp" + +#include + +#include +#include + +namespace py = pybind11; + +namespace Acts::Python { + +void addSeedFinderConfig(pybind11::module_ m) { + using Config = typename ActsExamples::Traccc::Common::TracccChainConfig:: + SeedfinderConfigType; + + 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 = typename ActsExamples::Traccc::Common::TracccChainConfig:: + SpacepointGridConfigType; + + 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 = typename ActsExamples::Traccc::Common::TracccChainConfig:: + SeedfilterConfigType; + + 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 = typename ActsExamples::Traccc::Common::TracccChainConfig:: + FindingConfigType; + + 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_MEMBER(navigation_buffer_size_scaler); + ACTS_PYTHON_STRUCT_END(); +} + +void addFittingConfig(py::module_ m) { + using Config = typename ActsExamples::Traccc::Common::TracccChainConfig:: + FittingConfigType; + + 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 = typename ActsExamples::Traccc::Common::TracccChainConfig:: + AmbiguityResolutionConfigType; + + 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 m = ctx.get("examples"); + + 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 00000000000..04df303e0f7 --- /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 00000000000..1b937275823 --- /dev/null +++ b/Examples/Python/src/TracccChainHost.cpp @@ -0,0 +1,32 @@ +// 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 "Acts/Utilities/TypeTraits.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 m = ctx.get("examples"); + + ACTS_PYTHON_DECLARE_ALGORITHM( + ActsExamples::Traccc::Host::TracccChainAlgorithm, m, + "TracccChainAlgorithmHost", inputCells, inputMeasurements, outputTracks, + trackingGeometry, field, digitizationConfigs, chainConfig); +} + +} // namespace Acts::Python diff --git a/Examples/Python/src/TracccChainHostStub.cpp b/Examples/Python/src/TracccChainHostStub.cpp new file mode 100644 index 00000000000..fe00f976579 --- /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/Examples/Python/tests/helpers/__init__.py b/Examples/Python/tests/helpers/__init__.py index 67f337609c7..2237774bc30 100644 --- a/Examples/Python/tests/helpers/__init__.py +++ b/Examples/Python/tests/helpers/__init__.py @@ -58,6 +58,13 @@ except ImportError: onnxEnabled = False +try: + import acts.examples.covfie + + covfieEnabled = True +except ImportError: + covfieEnabled = False + try: import acts.examples diff --git a/Examples/Python/tests/test_covfie.py b/Examples/Python/tests/test_covfie.py new file mode 100644 index 00000000000..48080843318 --- /dev/null +++ b/Examples/Python/tests/test_covfie.py @@ -0,0 +1,60 @@ +import pathlib, acts, acts.examples +import pytest + +from helpers import covfieEnabled + + +@pytest.mark.skipif(not covfieEnabled, reason="Covfie plugin not available") +def test_constant_field_conversion(): + from acts import covfie + + v = acts.Vector3(1, 2, 3) + af = acts.ConstantBField(v) + cf = covfie.covfieField(af) + view = covfie.newView(cf) + points = [(0, 0, 1), (1, 1, 1), (1, 0, 2)] + for x, y, z in points: + assert view.at(x, y, z) == [1, 2, 3] + + +@pytest.mark.skipif(not covfieEnabled, reason="Covfie plugin not available") +def test_root_field_conversion(): + from acts import covfie + + current_file_path = pathlib.Path(__file__).resolve().parent + p = ( + current_file_path.parent.parent.parent + / "thirdparty" + / "OpenDataDetector" + / "data" + / "odd-bfield.root" + ) + + af = acts.examples.MagneticFieldMapXyz(str(p)) + cf = covfie.covfieField(af) + view = covfie.newView(cf) + points = [ + (9300.0, 4700.0, 11200.0), + (9999.0, 9999.0, 14300.0), + (-2900.0, -4700.0, 5200.0), + (-2900.0, -4800.0, 9100.0), + (-2900.0, -5200.0, -8800.0), + (-4400.0, 4800.0, -12700.0), + (-6600.0, 1900.0, 7700.0), + (-9700.0, -900.0, 12700.0), + (-9999.0, -9999.0, -13000.0), + (9999.0, 0, 14900.0), + ] + + error_margin_half_width = 0.0001 + for x, y, z in points: + val = af.getField(acts.Vector3(x, y, z)) + Bx1, By1, Bz1 = val[0], val[1], val[2] + + Bx2, By2, Bz2 = tuple(view.at(x, y, z)) + + assert ( + abs(Bx1 - Bx2) < error_margin_half_width + and abs(By1 - By2) < error_margin_half_width + and abs(Bz1 - Bz2) < error_margin_half_width + ) diff --git a/Examples/Scripts/Python/full_chain_odd_traccc.py b/Examples/Scripts/Python/full_chain_odd_traccc.py new file mode 100755 index 00000000000..14693b926d1 --- /dev/null +++ b/Examples/Scripts/Python/full_chain_odd_traccc.py @@ -0,0 +1,271 @@ +#!/usr/bin/env python3 + +import os +import argparse +import pathlib + +import acts +import acts.examples +from acts.examples.simulation import ( + addParticleGun, + MomentumConfig, + EtaConfig, + PhiConfig, + ParticleConfig, + addPythia8, + addFatras, + addGeant4, + ParticleSelectorConfig, + addDigitization, + addParticleSelection, +) + +from acts.examples.dd4hep import ( + DD4hepDetector, + DD4hepDetectorOptions, + DD4hepGeometryService, +) + +from acts.examples.reconstruction import ( + addTracccChain, +) + +from acts.examples.odd import getOpenDataDetector, getOpenDataDetectorDirectory + +u = acts.UnitConstants + +parser = argparse.ArgumentParser(description="Sim-digi chain with the OpenDataDetector") +parser.add_argument( + "--output", + "-o", + help="Output directory", + type=pathlib.Path, + default=pathlib.Path.cwd() / "traccc_output", +) +parser.add_argument("--events", "-n", help="Number of events", type=int, default=100) +parser.add_argument("--skip", "-s", help="Number of events", type=int, default=0) +parser.add_argument( + "--geant4", help="Use Geant4 instead of fatras", action="store_true" +) +parser.add_argument( + "--ttbar", + help="Use Pythia8 (ttbar, pile-up 200) instead of particle gun", + action="store_true", +) +parser.add_argument( + "--ttbar-pu", + help="Number of pile-up events for ttbar", + type=int, + default=200, +) +parser.add_argument( + "--gun-particles", + help="Particle multiplicity of the particle gun", + type=int, + default=200, +) +parser.add_argument( + "--gun-vertices", + help="Vertex mulitplicity for the particle gun", + type=int, + default=1, +) +parser.add_argument( + "--gun-eta-range", + nargs="+", + help="Eta range of the particle gun", + type=float, + default=[-3.0, 3.0], +) +parser.add_argument( + "--gun-pt-range", + nargs="+", + help="Pt range of the particle gun (GeV)", + type=float, + default=[0.1 * u.GeV, 100 * u.GeV], +) +parser.add_argument( + "--rnd-seed", + help="Random seed", + type=int, + default=42, +) +parser.add_argument( + "--digi-config", + help="Digitization configuration file", + type=str, + default="", +) + +parser.add_argument( + "--mat-map", + help="Material map file", + type=str, + default="", +) + +parser.add_argument( + "--experimental", + action=argparse.BooleanOptionalAction, + help="Construct experimental geometry", +) + +args = parser.parse_args() + +decorators = None +if args.mat_map != "": + decorators = acts.IMaterialDecorator.fromFile(args.map) + +if args.experimental: + odd_xml = getOpenDataDetectorDirectory() / "xml" / "OpenDataDetector.xml" + + # Create the dd4hep geometry service and detector + dd4hepConfig = DD4hepGeometryService.Config() + dd4hepConfig.logLevel = acts.logging.INFO + dd4hepConfig.xmlFileNames = [str(odd_xml)] + dd4hepGeometryService = DD4hepGeometryService(dd4hepConfig) + detector = DD4hepDetector(dd4hepGeometryService) + + cOptions = DD4hepDetectorOptions(logLevel=acts.logging.INFO, emulateToGraph="") + cOptions.materialDecorator = decorators + + # Context and options + geoContext = acts.GeometryContext() + [recoGeometry, contextors, store] = detector.finalize(geoContext, cOptions) + + +else: + [detector, recoGeometry, decorators] = getOpenDataDetector(decorators) + + +outputDir = args.output +oddDigiConfig = args.digi_config +# Field specifications +field = acts.ConstantBField(acts.Vector3(0.0, 0.0, 2.0 * u.T)) + +rnd = acts.examples.RandomNumbers(seed=args.rnd_seed) + +s = acts.examples.Sequencer( + events=args.events, + skip=args.skip, + numThreads=1 if args.geant4 else -1, + outputDir=str(outputDir), + trackFpes=False, +) + + +if not args.ttbar: + addParticleGun( + s, + MomentumConfig( + args.gun_pt_range[0] * u.GeV, + args.gun_pt_range[1] * u.GeV, + transverse=True, + ), + EtaConfig(args.gun_eta_range[0], args.gun_eta_range[1]), + PhiConfig(0.0, 360.0 * u.degree), + ParticleConfig( + args.gun_particles, acts.PdgParticle.eMuon, randomizeCharge=True + ), + vtxGen=acts.examples.GaussianVertexGenerator( + mean=acts.Vector4(0, 0, 0, 0), + stddev=acts.Vector4(0.0125 * u.mm, 0.0125 * u.mm, 55.5 * u.mm, 1.0 * u.ns), + ), + multiplicity=args.gun_vertices, + rnd=rnd, + ) +else: + addPythia8( + s, + hardProcess=["Top:qqbar2ttbar=on"], + npileup=args.ttbar_pu, + vtxGen=acts.examples.GaussianVertexGenerator( + mean=acts.Vector4(0, 0, 0, 0), + stddev=acts.Vector4(0.0125 * u.mm, 0.0125 * u.mm, 55.5 * u.mm, 5.0 * u.ns), + ), + rnd=rnd, + outputDirRoot=outputDir, + # outputDirCsv=outputDir, + ) + +if args.geant4: + if s.config.numThreads != 1: + raise ValueError("Geant 4 simulation does not support multi-threading") + + # Pythia can sometime simulate particles outside the world volume, a cut on the Z of the track help mitigate this effect + # Older version of G4 might not work, this as has been tested on version `geant4-11-00-patch-03` + # For more detail see issue #1578 + addGeant4( + s, + detector, + recoGeometry, + field, + preSelectParticles=ParticleSelectorConfig( + rho=(0.0, 24 * u.mm), + absZ=(0.0, 1.0 * u.m), + eta=(-3.0, 3.0), + pt=(150 * u.MeV, None), + removeNeutral=True, + ), + outputDirRoot=outputDir, + outputDirCsv=outputDir, + rnd=rnd, + killVolume=( + recoGeometry.worldVolume + if isinstance(recoGeometry, acts.TrackingGeometry) + else None + ), + killAfterTime=25 * u.ns, + ) +elif isinstance(recoGeometry, acts.TrackingGeometry): + addFatras( + s, + recoGeometry, + field, + preSelectParticles=( + ParticleSelectorConfig( + rho=(0.0, 24 * u.mm), + absZ=(0.0, 1.0 * u.m), + eta=(-3.0, 3.0), + pt=(150 * u.MeV, None), + removeNeutral=True, + ) + if args.ttbar + else ParticleSelectorConfig() + ), + enableInteractions=True, + outputDirRoot=outputDir, + outputDirCsv=outputDir, + rnd=rnd, + ) +else: + raise ValueError("Fatras simulation with Experimental::Detector not yet supported") + +addDigitization( + s, + recoGeometry, + field, + digiConfigFile=oddDigiConfig, + outputDirRoot=outputDir, + outputDirCsv=outputDir, + rnd=rnd, + minEnergyDeposit=0, + doMerge=True, + mergeCommonCorner=True, +) + +chainConfig = acts.examples.TracccChainConfig() + +addTracccChain( + s, + recoGeometry, + field, + digiConfigFile=oddDigiConfig, + inputCells="cells", + outputDirRoot=outputDir, + chainConfig=chainConfig, + logLevel=acts.logging.DEBUG, + # outputDirCsv=outputDir, +) + +s.run() diff --git a/Plugins/CMakeLists.txt b/Plugins/CMakeLists.txt index c961f82fd7f..cc92286d3d9 100644 --- a/Plugins/CMakeLists.txt +++ b/Plugins/CMakeLists.txt @@ -10,7 +10,9 @@ add_component_if(Json PluginJson ACTS_BUILD_PLUGIN_JSON) add_component_if(Legacy PluginLegacy ACTS_BUILD_PLUGIN_LEGACY) 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_DETRAY) +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) # dependent plugins. depend either on a independent plugins or on one another add_component_if(TGeo PluginTGeo ACTS_BUILD_PLUGIN_TGEO) diff --git a/Plugins/Covfie/CMakeLists.txt b/Plugins/Covfie/CMakeLists.txt new file mode 100644 index 00000000000..b17ede0cc02 --- /dev/null +++ b/Plugins/Covfie/CMakeLists.txt @@ -0,0 +1,22 @@ +add_library( + ActsPluginCovfie SHARED + src/FieldConversion.cpp) + +target_include_directories( + ActsPluginCovfie + PUBLIC + $ + $) +target_link_libraries( + ActsPluginCovfie + PUBLIC + ActsCore + covfie::core) + +install( + TARGETS ActsPluginCovfie + EXPORT ActsPluginCovfieTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install( + DIRECTORY include/Acts + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) diff --git a/Plugins/Covfie/include/Acts/Plugins/Covfie/FieldConversion.hpp b/Plugins/Covfie/include/Acts/Plugins/Covfie/FieldConversion.hpp new file mode 100644 index 00000000000..78da24fad31 --- /dev/null +++ b/Plugins/Covfie/include/Acts/Plugins/Covfie/FieldConversion.hpp @@ -0,0 +1,64 @@ +// 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// acts includes +#include "Acts/MagneticField/BFieldMapUtils.hpp" +#include "Acts/MagneticField/ConstantBField.hpp" +#include "Acts/MagneticField/MagneticFieldProvider.hpp" + +namespace Acts::CovfiePlugin { + +using BuilderBackend = + covfie::backend::strided>; + +using InterpolatedField = covfie::field>>>; + +using ConstantField = covfie::field< + covfie::backend::constant>; + +/// @brief Creates a covfie field from an interpolated magnetic field. +/// @param magneticField The acts interpolated magnetic field. +/// @return An affine linear strided covfie field. +InterpolatedField covfieField( + const Acts::InterpolatedMagneticField& magneticField); + +/// @brief Creates a covfie field from a constant B field. +/// @param magneticField The acts constant magnetic field. +/// @return A constant covfie field. +ConstantField covfieField(const Acts::ConstantBField& magneticField); + +/// @brief Creates a covfie field from a magnetic field provider by sampling it. +/// The field must be defined within min (inclusive) and max (inclusive). +/// @param magneticField The acts magnetic field provider. +/// @param cache The acts cache. +/// @param nBins 3D array of containing the number of bins for each axis. +/// @param min (min_x, min_y, min_z) +/// @param max (max_x, max_y, max_z) +/// @return An affine linear strided covfie field. +InterpolatedField covfieField(const Acts::MagneticFieldProvider& magneticField, + Acts::MagneticFieldProvider::Cache& cache, + const std::vector& nBins, + const std::vector& min, + const std::vector& max); + +} // namespace Acts::CovfiePlugin diff --git a/Plugins/Covfie/src/FieldConversion.cpp b/Plugins/Covfie/src/FieldConversion.cpp new file mode 100644 index 00000000000..571cb6a874d --- /dev/null +++ b/Plugins/Covfie/src/FieldConversion.cpp @@ -0,0 +1,208 @@ +// 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/. + +#include "Acts/Plugins/Covfie/FieldConversion.hpp" + +namespace Acts::CovfiePlugin { + +namespace { + +/// @brief Get the value of the interpolated field at a specific position in +/// min (inclusive) max (inclusive). +/// @note The unchecked lookup allows the access to the field value at the max edges +/// since the domain is typically min (inclusive) max (exclusive). +/// @param magneticField the interpolated magnetic field. +/// @param cache the magnetic field cache. +/// @param position the position of the field to look up. +/// @return the field value at the given position. +Acts::Vector3 getFieldEdgeInclusive( + const Acts::InterpolatedMagneticField& magneticField, + [[maybe_unused]] Acts::InterpolatedMagneticField::Cache& cache, + const Acts::Vector3& position) { + // Check if position in within [min; max]. + bool inBounds = position[0] <= magneticField.getMax()[0] && + position[1] <= magneticField.getMax()[1] && + position[2] <= magneticField.getMax()[2] && + position[0] >= magneticField.getMin()[0] && + position[1] >= magneticField.getMin()[1] && + position[2] >= magneticField.getMin()[2]; + if (!inBounds) { + throw std::runtime_error{ + "Field lookup failure (position not in [min, max])"}; + } + return magneticField.getFieldUnchecked(position); +} + +/// @brief Get the value of the field at a specific position of a general magnetic field. +/// @param magneticField the interpolated magnetic field. +/// @param cache the magnetic field cache. +/// @param position the position of the field to look up. +/// @return the field value at the given position. +Acts::Vector3 getFieldEdgeInclusive( + const Acts::MagneticFieldProvider& magneticField, + Acts::MagneticFieldProvider::Cache& cache, const Acts::Vector3& position) { + auto lookupResult = magneticField.getField(position, cache); + if (!lookupResult.ok()) { + throw std::runtime_error{"Field lookup failure"}; + } + return *lookupResult; +} + +} // namespace + +/// @brief Creates a strided covfie field that stores the values of the magnetic field in the volume given by min and max using a fixed sample spacing (determined by nBins). +/// @param magneticField The acts magnetic field. +/// @param cache The acts cache. +/// @param nBins 3D array of containing the number of bins for each axis. +/// @param min (min_x, min_y, min_z) +/// @param max (max_x, max_y, max_z) +/// @return A strided covfie field. +template +auto newBuilder(const magnetic_field_t& magneticField, + typename magnetic_field_t::Cache& cache, + const std::vector& nBins, + const std::vector& min, + const std::vector& max) { + using Field = covfie::field; + + Field field(covfie::make_parameter_pack( + Field::backend_t::configuration_t{nBins[0], nBins[1], nBins[2]})); + + Field::view_t view(field); + + std::array sampleSpacing = {(max[0] - min[0]) / (nBins[0] - 1), + (max[1] - min[1]) / (nBins[1] - 1), + (max[2] - min[2]) / (nBins[2] - 1)}; + + for (std::size_t x = 0; x < nBins[0]; x++) { + for (std::size_t y = 0; y < nBins[1]; y++) { + for (std::size_t z = 0; z < nBins[2]; z++) { + auto position = Acts::Vector3{x * sampleSpacing[0] + min[0], + y * sampleSpacing[1] + min[1], + z * sampleSpacing[2] + min[2]}; + + auto result = getFieldEdgeInclusive(magneticField, cache, position); + + Field::view_t::output_t& p = view.at(x, y, z); + p[0] = static_cast(result[0]); + p[1] = static_cast(result[1]); + p[2] = static_cast(result[2]); + } + } + } + return field; +} + +/// @brief Generate the affine covfie configuration (scaling and rotation) given the size of the field (min and max) +/// @param nBins 3D array of containing the number of bins for each axis. +/// @param min (min_x, min_y, min_z) +/// @param max (max_x, max_y, max_z) +/// @return The affine field configuration. +template +typename backend_t::configuration_t affineConfiguration( + const std::vector& nBins, + const std::vector& min, + const std::vector& max) { + auto scaling = covfie::algebra::affine<3>::scaling( + static_cast((nBins[0] - 1) / (max[0] - min[0])), + static_cast((nBins[1] - 1) / (max[1] - min[1])), + static_cast((nBins[2] - 1) / (max[2] - min[2]))); + + auto translation = covfie::algebra::affine<3>::translation( + static_cast(-min[0]), static_cast(-min[1]), + static_cast(-min[2])); + + return {scaling * translation}; +} + +/// @brief Uses std::nextafter to generates a clamp backend +/// configuration where arguments min and max hold floating point values. +/// @param min (min_x, min_y, min_z) +/// @param max (max_x, max_y, max_z) +/// @return The clamp field configuration. +template +typename backend_t::configuration_t clampConfigurationFloat( + const std::vector& min, + const std::vector& max) { + return {{std::nextafter(static_cast(min[0]), + std::numeric_limits::infinity()), + std::nextafter(static_cast(min[1]), + std::numeric_limits::infinity()), + std::nextafter(static_cast(min[2]), + std::numeric_limits::infinity())}, + {std::nextafter(static_cast(max[0]), + -std::numeric_limits::infinity()), + std::nextafter(static_cast(max[1]), + -std::numeric_limits::infinity()), + std::nextafter(static_cast(max[2]), + -std::numeric_limits::infinity())}}; +} + +/// @brief Creates a covfie field from a generic magnetic field. +/// @param magneticField The generic magnetic field. +/// @param cache The cache. +/// @param nBins 3D array of containing the number of bins for each axis. +/// @param min (min_x, min_y, min_z) +/// @param max (max_x, max_y, max_z) +/// @return A clamp affine linear strided covfie field. +template +InterpolatedField covfieFieldLinear(const magnetic_field_t& magneticField, + typename magnetic_field_t::Cache& cache, + const std::vector& nBins, + const std::vector& min, + const std::vector& max) { + auto builder = newBuilder(magneticField, cache, nBins, min, max); + InterpolatedField field(covfie::make_parameter_pack( + clampConfigurationFloat(min, max), + affineConfiguration(nBins, min, + max), + InterpolatedField::backend_t::backend_t::backend_t::configuration_t{}, + builder.backend())); + + return field; +} + +/// @brief Creates a covfie field from a magnetic field provider by sampling it. +/// @param magneticField The acts magnetic field provider. +/// @param cache The acts cache. +/// @param nBins 3D array of containing the number of bins for each axis. +/// @param min (min_x, min_y, min_z) +/// @param max (max_x, max_y, max_z) +/// @return A clamp affine linear strided covfie field. +InterpolatedField covfieField(const Acts::MagneticFieldProvider& magneticField, + Acts::MagneticFieldProvider::Cache& cache, + const std::vector& nBins, + const std::vector& min, + const std::vector& max) { + return covfieFieldLinear(magneticField, cache, nBins, min, max); +} + +/// @brief Creates a covfie field from an interpolated magnetic field. +/// @param magneticField The acts interpolated magnetic field. +/// @return A clamp affine linear strided covfie field. +InterpolatedField covfieField( + const Acts::InterpolatedMagneticField& magneticField) { + Acts::MagneticFieldContext ctx; + auto cache = magneticField.makeCache(ctx); + return covfieFieldLinear(magneticField, cache, magneticField.getNBins(), + magneticField.getMin(), magneticField.getMax()); +} + +/// @brief Creates a covfie field from a constant B field. +/// @param magneticField The acts constant magnetic field. +/// @return A constant covfie field. +ConstantField covfieField(const Acts::ConstantBField& magneticField) { + auto B = magneticField.getField(); + ConstantField field( + covfie::make_parameter_pack(ConstantField::backend_t::configuration_t{ + static_cast(B[0]), static_cast(B[1]), + static_cast(B[2])})); + return field; +} + +} // namespace Acts::CovfiePlugin diff --git a/Plugins/Detray/CMakeLists.txt b/Plugins/Detray/CMakeLists.txt index a2a1585063d..7fe99391398 100644 --- a/Plugins/Detray/CMakeLists.txt +++ b/Plugins/Detray/CMakeLists.txt @@ -2,11 +2,6 @@ add_library( ActsPluginDetray SHARED src/DetrayConverter.cpp) -add_dependencies(ActsPluginDetray - detray::core - covfie::core - vecmem::core) - target_include_directories( ActsPluginDetray PUBLIC @@ -21,7 +16,6 @@ target_link_libraries( detray::core_array detray::io detray::utils - detray::svgtools vecmem::core) install( diff --git a/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConversionHelper.hpp b/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConversionHelper.hpp index 5fdbd2d7002..c013ff706f7 100644 --- a/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConversionHelper.hpp +++ b/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConversionHelper.hpp @@ -91,23 +91,32 @@ inline static std::tuple> maskFromBounds( /// /// @return the acceleration link idnetifier template -inline static std::size_t accelerationLink(const binning_values_t& casts) { +inline static detray::io::accel_id accelerationLink( + const binning_values_t& casts) { // Default is `brute_force` - std::size_t accLink = detray::io::accel_id::brute_force; + detray::io::accel_id accLink = detray::io::accel_id::brute_force; if (casts.size() == 2u) { - if (casts[0u] == binX && casts[1u] == binY) { + if (casts[0u] == Acts::BinningValue::binX && + casts[1u] == Acts::BinningValue::binY) { accLink = detray::io::accel_id::cartesian2_grid; - } else if (casts[0u] == binR && casts[1u] == binPhi) { + } else if (casts[0u] == Acts::BinningValue::binR && + casts[1u] == Acts::BinningValue::binPhi) { accLink = detray::io::accel_id::polar2_grid; - } else if (casts[0u] == binZ && casts[1u] == binPhi) { + } else if (casts[0u] == Acts::BinningValue::binZ && + casts[1u] == Acts::BinningValue::binPhi) { accLink = detray::io::accel_id::cylinder2_grid; - } else if (casts[0u] == binZ && casts[1u] == binR) { + } else if (casts[0u] == Acts::BinningValue::binZ && + casts[1u] == Acts::BinningValue::binR) { accLink = detray::io::accel_id::cylinder3_grid; } } else if (casts.size() == 3u) { - if (casts[0u] == binX && casts[1u] == binY && casts[2u] == binZ) { + if (casts[0u] == Acts::BinningValue::binX && + casts[1u] == Acts::BinningValue::binY && + casts[2u] == Acts::BinningValue::binZ) { accLink = detray::io::accel_id::cuboid3_grid; - } else if (casts[0u] == binZ && casts[1u] == binPhi && casts[2u] == binR) { + } else if (casts[0u] == Acts::BinningValue::binZ && + casts[1u] == Acts::BinningValue::binPhi && + casts[2u] == Acts::BinningValue::binR) { accLink = detray::io::accel_id::cylinder3_grid; } } diff --git a/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConverter.hpp b/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConverter.hpp index 4de8a8bf5ac..204413998ee 100644 --- a/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConverter.hpp +++ b/Plugins/Detray/include/Acts/Plugins/Detray/DetrayConverter.hpp @@ -9,8 +9,12 @@ #pragma once #include "Acts/Definitions/Algebra.hpp" +#include "Acts/Detector/Detector.hpp" +#include "Acts/Detector/DetectorVolume.hpp" +#include "Acts/Detector/Portal.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/VolumeBounds.hpp" +#include "Acts/Surfaces/Surface.hpp" #include @@ -24,15 +28,6 @@ namespace Acts { -class Surface; -class SurfaceBounds; - -namespace Experimental { -class Detector; -class DetectorVolume; -class Portal; -} // namespace Experimental - namespace DetrayConverter { using DetrayDetector = detray::detector; diff --git a/Plugins/Detray/src/DetrayConverter.cpp b/Plugins/Detray/src/DetrayConverter.cpp index d3ce397923c..2aec9d55274 100644 --- a/Plugins/Detray/src/DetrayConverter.cpp +++ b/Plugins/Detray/src/DetrayConverter.cpp @@ -176,12 +176,14 @@ std::vector Acts::DetrayConverter::convertPortal( // Pick the surface dimension - via poly std::array clipRange = {0., 0.}; std::vector boundValues = surfaceAdjusted->bounds().values(); - if (surfaceType == Surface::SurfaceType::Cylinder && cast == binZ) { + if (surfaceType == Surface::SurfaceType::Cylinder && + cast == Acts::BinningValue::binZ) { ActsScalar zPosition = surfaceAdjusted->center(gctx).z(); clipRange = { zPosition - boundValues[CylinderBounds::BoundValues::eHalfLengthZ], zPosition + boundValues[CylinderBounds::BoundValues::eHalfLengthZ]}; - } else if (surfaceType == Surface::SurfaceType::Disc && cast == binR) { + } else if (surfaceType == Surface::SurfaceType::Disc && + cast == Acts::BinningValue::binR) { clipRange = {boundValues[RadialBounds::BoundValues::eMinR], boundValues[RadialBounds::BoundValues::eMaxR]}; } else { diff --git a/Plugins/Traccc/CMakeLists.txt b/Plugins/Traccc/CMakeLists.txt new file mode 100644 index 00000000000..e59112d2d03 --- /dev/null +++ b/Plugins/Traccc/CMakeLists.txt @@ -0,0 +1,28 @@ +add_library( + ActsPluginTraccc SHARED + src/Detail/Module.cpp + src/CellConversion.cpp) + +target_include_directories( + ActsPluginTraccc + PUBLIC + $ + $) +target_link_libraries( + ActsPluginTraccc + PUBLIC + ActsCore + traccc::core + traccc::io + vecmem::core + detray::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 00000000000..d468da4db82 --- /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 00000000000..9570f85aeb0 --- /dev/null +++ b/Plugins/Traccc/include/Acts/Plugins/Traccc/CellConversion.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 + +// 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/Detail/Module.hpp" + +// Detray include(s) +#include "detray/core/detector.hpp" + +// Traccc include(s) +#include "traccc/edm/cell.hpp" +#include "traccc/geometry/geometry.hpp" +#include "traccc/io/digitization_config.hpp" +#include "traccc/io/read_geometry.hpp" +#include "traccc/io/reader_edm.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, + const traccc::geometry* geom, const traccc::digitization_config* 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 00000000000..82f39080f16 --- /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/Detail/Module.hpp b/Plugins/Traccc/include/Acts/Plugins/Traccc/Detail/Module.hpp new file mode 100644 index 00000000000..58d06333fce --- /dev/null +++ b/Plugins/Traccc/include/Acts/Plugins/Traccc/Detail/Module.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/GeometryIdentifier.hpp" + +// Traccc include(s) +#include "traccc/edm/cell.hpp" +#include "traccc/geometry/geometry.hpp" +#include "traccc/io/digitization_config.hpp" + +namespace Acts::TracccPlugin::detail { + +/// @brief Helper function which finds module from csv::cell in the geometry and +/// digitization config, and initializes the modules limits with the cell's +/// properties. +traccc::cell_module getModule( + const Acts::GeometryIdentifier::Value geometryID, + const traccc::geometry* geom, const traccc::digitization_config* dconfig, + const Acts::GeometryIdentifier::Value originalGeometryID); + +} // namespace Acts::TracccPlugin::detail 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 00000000000..da46de10b58 --- /dev/null +++ b/Plugins/Traccc/include/Acts/Plugins/Traccc/TrackConversion.hpp @@ -0,0 +1,238 @@ +// 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/TrackContainer.hpp" +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/EventData/TrackProxy.hpp" +#include "Acts/EventData/detail/ParameterTraits.hpp" +#include "Acts/Geometry/TrackingGeometry.hpp" +#include "Acts/Utilities/detail/Subspace.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 { + +/// @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 copyFittingResult( + const traccc::fitting_result& source, + Acts::TrackProxy& + destination, + const detray::detector& detector, + const Acts::TrackingGeometry& trackingGeometry) { + const auto params = newParams(source.fit_params, 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::detail::FixedSizeSubspace subspace( + measurement.subs.get_indices()); + destination.setProjector(subspace.template projector()); +} + +/// @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(); + copyFittingResult(fittingResult, track, detector, trackingGeometry); + + // 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 00000000000..8a5baaa6c5b --- /dev/null +++ b/Plugins/Traccc/src/CellConversion.cpp @@ -0,0 +1,94 @@ +// 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/Detail/Module.hpp" + +// Detray include(s) +#include "detray/core/detector.hpp" + +// Traccc include(s) +#include "traccc/edm/cell.hpp" +#include "traccc/geometry/geometry.hpp" +#include "traccc/io/digitization_config.hpp" +#include "traccc/io/read_geometry.hpp" +#include "traccc/io/reader_edm.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, + const traccc::geometry* geom, const traccc::digitization_config* dconfig, + const std::map* + barcodeMap) { + traccc::io::cell_reader_output out(mr); + + // Sort the cells. + for (auto& [_, cells] : cellsMap) { + std::sort(cells.begin(), cells.end(), CellOrder()); + } + + // Fill the output containers with the ordered cells and modules. + for (const auto& [originalGeometryID, cells] : cellsMap) { + // Modify the geometry ID of the module if a barcode map is + // provided. + Acts::GeometryIdentifier::Value geometryID = + (barcodeMap != nullptr) ? barcodeMap->at(originalGeometryID).value() + : originalGeometryID; + + // Add the module and its cells to the output. + out.modules.push_back( + detail::getModule(geometryID, geom, dconfig, originalGeometryID)); + for (auto& cell : cells) { + out.cells.push_back(cell); + // Set the module link. + out.cells.back().module_link = out.modules.size() - 1; + } + } + return std::make_tuple(std::move(out.cells), std::move(out.modules)); +} + +} // namespace Acts::TracccPlugin diff --git a/Plugins/Traccc/src/Detail/Module.cpp b/Plugins/Traccc/src/Detail/Module.cpp new file mode 100644 index 00000000000..08d9e3c3395 --- /dev/null +++ b/Plugins/Traccc/src/Detail/Module.cpp @@ -0,0 +1,82 @@ +// 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/. + +// Plugin include(s) +#include "Acts/Plugins/Traccc/Detail/Module.hpp" + +// Acts include(s) +#include "Acts/Geometry/GeometryHierarchyMap.hpp" +#include "Acts/Geometry/GeometryIdentifier.hpp" + +// Detray include(s) +#include "detray/core/detector.hpp" + +// Traccc include(s) +#include "traccc/edm/cell.hpp" +#include "traccc/geometry/geometry.hpp" +#include "traccc/io/digitization_config.hpp" +#include "traccc/io/read_geometry.hpp" +#include "traccc/io/reader_edm.hpp" + +// System include(s) +#include +#include +#include +#include +#include +#include + +namespace Acts::TracccPlugin::detail { + +traccc::cell_module getModule( + const Acts::GeometryIdentifier::Value geometryID, + const traccc::geometry* geom, const traccc::digitization_config* dconfig, + const Acts::GeometryIdentifier::Value originalGeometryID) { + traccc::cell_module result; + result.surface_link = detray::geometry::barcode{geometryID}; + + // Find/set the 3D position of the detector module. + if (geom != nullptr) { + // Check if the module ID is known. + if (!geom->contains(result.surface_link.value())) { + throw std::runtime_error("Could not find placement for geometry ID " + + std::to_string(result.surface_link.value())); + } + + // Set the value on the module description. + result.placement = (*geom)[result.surface_link.value()]; + } + + // Find/set the digitization configuration of the detector module. + if (dconfig != nullptr) { + // Check if the module ID is known. + const traccc::digitization_config::Iterator geoIt = + dconfig->find(originalGeometryID); + if (geoIt == dconfig->end()) { + throw std::runtime_error( + "Could not find digitization config for geometry ID " + + std::to_string(originalGeometryID)); + } + + // Set the value on the module description. + const auto& binning_data = geoIt->segmentation.binningData(); + assert(binning_data.size() > 0); + result.pixel.min_corner_x = binning_data[0].min; + result.pixel.pitch_x = binning_data[0].step; + if (binning_data.size() > 1) { + result.pixel.min_corner_y = binning_data[1].min; + result.pixel.pitch_y = binning_data[1].step; + } + // result.pixel.dimension = geoIt->dimensions; + // result.pixel.variance_y = geoIt->variance_y; + } + + return result; +} + +} // namespace Acts::TracccPlugin::detail diff --git a/Tests/DownstreamProject/CMakeLists.txt b/Tests/DownstreamProject/CMakeLists.txt index f6901184ac7..91a9fc1dd4b 100644 --- a/Tests/DownstreamProject/CMakeLists.txt +++ b/Tests/DownstreamProject/CMakeLists.txt @@ -10,7 +10,10 @@ find_package( Fatras PluginJson PluginLegacy - PluginTGeo) + PluginTGeo + PluginCovfie + PluginDetray + PluginTraccc) # place artifacts in GNU-like paths, e.g. binaries in `/bin` include(GNUInstallDirs) @@ -27,7 +30,10 @@ target_link_libraries( ActsFatras ActsPluginJson ActsPluginLegacy - ActsPluginTGeo) + ActsPluginTGeo + ActsPluginCovfie + ActsPluginDetray + ActsPluginTraccc) option(DD4HEP "Build with DD4hep" ON) if(DD4HEP) diff --git a/Tests/UnitTests/Plugins/CMakeLists.txt b/Tests/UnitTests/Plugins/CMakeLists.txt index a3ce9f373ef..0b48b9782f8 100644 --- a/Tests/UnitTests/Plugins/CMakeLists.txt +++ b/Tests/UnitTests/Plugins/CMakeLists.txt @@ -9,3 +9,4 @@ add_subdirectory_if(TGeo ACTS_BUILD_PLUGIN_TGEO) add_subdirectory_if(EDM4hep ACTS_BUILD_PLUGIN_EDM4HEP) add_subdirectory_if(FpeMonitoring ACTS_BUILD_PLUGIN_FPEMON) add_subdirectory_if(Podio ACTS_BUILD_PLUGIN_PODIO) +add_subdirectory_if(Covfie ACTS_BUILD_PLUGIN_TRACCC) diff --git a/Tests/UnitTests/Plugins/Covfie/CMakeLists.txt b/Tests/UnitTests/Plugins/Covfie/CMakeLists.txt new file mode 100644 index 00000000000..9e9eb803189 --- /dev/null +++ b/Tests/UnitTests/Plugins/Covfie/CMakeLists.txt @@ -0,0 +1,2 @@ +set(unittest_extra_libraries ActsPluginCovfie) +add_unittest(CovfieFieldConversion CovfieFieldConversionTest.cpp) \ No newline at end of file diff --git a/Tests/UnitTests/Plugins/Covfie/CovfieFieldConversionTest.cpp b/Tests/UnitTests/Plugins/Covfie/CovfieFieldConversionTest.cpp new file mode 100644 index 00000000000..761d8f6f88f --- /dev/null +++ b/Tests/UnitTests/Plugins/Covfie/CovfieFieldConversionTest.cpp @@ -0,0 +1,218 @@ +// 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/Units.hpp" +#include "Acts/MagneticField/ConstantBField.hpp" +#include "Acts/MagneticField/MagneticFieldContext.hpp" +#include "Acts/MagneticField/MagneticFieldProvider.hpp" +#include "Acts/MagneticField/SolenoidBField.hpp" + +// Covfie Plugin include(s) +#include "Acts/Plugins/Covfie/FieldConversion.hpp" + +// System include(s) +#include +#include +#include +#include + +// Boost include(s) +#include + +using namespace Acts::UnitLiterals; + +template +void checkMagneticFieldEqual(const Acts::MagneticFieldProvider& fieldProvider, + Acts::MagneticFieldProvider::Cache& cache, + view_t view, iterator_t points, + float error_margin_half_width) { + for (auto point : points) { + auto x = point[0], y = point[1], z = point[2]; + + auto lookupResult = fieldProvider.getField(Acts::Vector3{x, y, z}, cache); + if (!lookupResult.ok()) { + throw std::runtime_error{"Field lookup failure"}; + } + auto actsValueX = (*lookupResult)[0], actsValueY = (*lookupResult)[1], + actsValueZ = (*lookupResult)[2]; + + auto covfieValues = view.at(x, y, z); + auto covfieValueX = covfieValues[0], covfieValueY = covfieValues[1], + covfieValueZ = covfieValues[2]; + + auto isEqual = + std::abs(covfieValueX - actsValueX) <= error_margin_half_width && + std::abs(covfieValueY - actsValueY) <= error_margin_half_width && + std::abs(covfieValueZ - actsValueZ) <= error_margin_half_width; + + std::stringstream ss; + ss << "Fields are not equal at position (" << x << ", " << y << ", " << z + << "). Acts: (" << actsValueX << ", " << actsValueY << ", " << actsValueZ + << "), Covfie: (" << covfieValueX << ", " << covfieValueY << ", " + << covfieValueZ << ")" << std::endl; + + BOOST_CHECK_MESSAGE(isEqual, ss.str()); + } +} + +BOOST_AUTO_TEST_SUITE(CovfiePlugin) + +BOOST_AUTO_TEST_CASE(InterpolatedMagneticField1) { + auto localToGlobalBin_xyz = [](std::array binsXYZ, + std::array nBinsXYZ) { + return (binsXYZ.at(0) * (nBinsXYZ.at(1) * nBinsXYZ.at(2)) + + binsXYZ.at(1) * nBinsXYZ.at(2) + binsXYZ.at(2)); + }; + + std::vector xPos = {0., 1., 2., 3.}; + std::vector yPos = {0., 1., 2., 3.}; + std::vector zPos = {0., 1., 2., 3.}; + + std::vector bField_xyz; + for (int i = 0; i < 64; i++) { + bField_xyz.push_back(Acts::Vector3(i, i, i)); + } + + Acts::MagneticFieldContext fieldContext; + auto actsField = Acts::fieldMapXYZ(localToGlobalBin_xyz, xPos, yPos, zPos, + bField_xyz, 1, 1, false); + Acts::MagneticFieldProvider::Cache cache = actsField.makeCache(fieldContext); + + Acts::CovfiePlugin::InterpolatedField field = + Acts::CovfiePlugin::covfieField(actsField); + typename Acts::CovfiePlugin::InterpolatedField::view_t view(field); + + std::array, 14> points = {{ + {0.f, 0.f, 0.f}, + {1.f, 1.f, 1.f}, + {2.f, 2.f, 2.f}, + {2.9f, 2.9f, 2.9f}, + {1.2f, 2.5f, 0.8f}, + {0.7f, 1.9f, 2.3f}, + {2.1f, 0.3f, 1.5f}, + {0.4f, 2.8f, 2.9f}, + {1.6f, 1.2f, 0.5f}, + {2.3f, 0.6f, 2.2f}, + {1.1f, 2.7f, 1.3f}, + {0.9f, 1.4f, 2.7f}, + {2.4f, 1.8f, 0.9f}, + {0.6f, 2.2f, 2.1f}, + }}; + + checkMagneticFieldEqual(actsField, cache, view, points, 0.0001); +} + +BOOST_AUTO_TEST_CASE(InterpolatedMagneticField2) { + auto localToGlobalBin_xyz = [](std::array binsXYZ, + std::array nBinsXYZ) { + return (binsXYZ.at(0) * (nBinsXYZ.at(1) * nBinsXYZ.at(2)) + + binsXYZ.at(1) * nBinsXYZ.at(2) + binsXYZ.at(2)); + }; + + std::vector xPos = {8., 12., 16., 20.}; + std::vector yPos = {8., 12., 16., 20.}; + std::vector zPos = {8., 12., 16., 20.}; + + std::vector bField_xyz; + for (int i = 0; i < 64; i++) { + bField_xyz.push_back(Acts::Vector3(i, i * i * 0.01, i)); + } + + Acts::MagneticFieldContext fieldContext; + auto actsField = Acts::fieldMapXYZ(localToGlobalBin_xyz, xPos, yPos, zPos, + bField_xyz, 1, 1, false); + Acts::MagneticFieldProvider::Cache cache = actsField.makeCache(fieldContext); + + Acts::CovfiePlugin::InterpolatedField field = + Acts::CovfiePlugin::covfieField(actsField); + typename Acts::CovfiePlugin::InterpolatedField::view_t view(field); + + std::array, 14> points = {{ + {8.f, 8.f, 8.f}, + {12.f, 12.f, 12.f}, + {16.f, 16.f, 16.f}, + {19.9, 19.9, 19.9}, + {8.1f, 10.2f, 12.3f}, + {9.4f, 11.5f, 13.6f}, + {10.7f, 12.8f, 14.9f}, + {11.0f, 13.1f, 15.2f}, + {12.3f, 14.4f, 16.5f}, + {13.6f, 15.7f, 17.8f}, + {14.9f, 16.0f, 18.1f}, + {16.2f, 17.3f, 19.4f}, + {17.5f, 18.6f, 19.7f}, + {18.8f, 19.9f, 14.0f}, + }}; + + checkMagneticFieldEqual(actsField, cache, view, points, 0.0001f); +} + +BOOST_AUTO_TEST_CASE(ConstantMagneticField1) { + Acts::ConstantBField actsField(Acts::Vector3{1.3f, 2.5f, 2.f}); + Acts::MagneticFieldContext ctx; + Acts::MagneticFieldProvider::Cache cache = actsField.makeCache(ctx); + + Acts::CovfiePlugin::ConstantField field = + Acts::CovfiePlugin::covfieField(actsField); + typename Acts::CovfiePlugin::ConstantField::view_t view(field); + + std::array, 13> points = {{ + {8.f, 8.f, 8.f}, + {12.f, 12.f, 12.f}, + {16.f, 16.f, 16.f}, + {8.1f, 10.2f, 12.3f}, + {9.4f, 11.5f, 13.6f}, + {10.7f, 12.8f, 14.9f}, + {11.0f, 13.1f, 15.2f}, + {12.3f, 14.4f, 16.5f}, + {13.6f, 15.7f, 17.8f}, + {14.9f, 16.0f, 18.1f}, + {16.2f, 17.3f, 19.4f}, + {17.5f, 18.6f, 19.7f}, + {18.8f, 19.9f, 14.0f}, + }}; + + checkMagneticFieldEqual(actsField, cache, view, points, 0.0901); +} + +BOOST_AUTO_TEST_CASE(SolenoidBField1) { + Acts::SolenoidBField::Config cfg{}; + cfg.length = 5.8_m; + cfg.radius = (2.56 + 2.46) * 0.5 * 0.5_m; + cfg.nCoils = 1154; + cfg.bMagCenter = 2_T; + Acts::SolenoidBField actsField(cfg); + Acts::MagneticFieldContext ctx; + Acts::MagneticFieldProvider::Cache cache = actsField.makeCache(ctx); + + Acts::CovfiePlugin::InterpolatedField field = Acts::CovfiePlugin::covfieField( + actsField, cache, std::vector{20UL, 20UL, 20UL}, std::vector{0., 0., 0.}, + std::vector{20., 20., 20.}); + typename Acts::CovfiePlugin::InterpolatedField::view_t view(field); + + std::array, 13> points = {{ + {8.f, 8.f, 8.f}, + {12.f, 12.f, 12.f}, + {16.f, 16.f, 16.f}, + {8.1f, 10.2f, 12.3f}, + {9.4f, 11.5f, 13.6f}, + {10.7f, 12.8f, 14.9f}, + {11.0f, 13.1f, 15.2f}, + {12.3f, 14.4f, 16.5f}, + {13.6f, 15.7f, 17.8f}, + {14.9f, 16.0f, 18.1f}, + {16.2f, 17.3f, 19.4f}, + {17.5f, 18.6f, 19.7f}, + {18.8f, 19.9f, 14.0f}, + }}; + + checkMagneticFieldEqual(actsField, cache, view, points, 0.0001); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/cmake/ActsConfig.cmake.in b/cmake/ActsConfig.cmake.in index 362f293ce19..dee5d9f87b4 100644 --- a/cmake/ActsConfig.cmake.in +++ b/cmake/ActsConfig.cmake.in @@ -81,6 +81,20 @@ if(PluginGeoModel IN_LIST Acts_COMPONENTS) find_dependency(GeoModelIO @GeoModel_VERSION@ CONFIG EXACT) endif() +if (PluginCovfie 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(algebra-plugins @algebra-plugins_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@) diff --git a/cmake/ActsExternSources.cmake b/cmake/ActsExternSources.cmake index 3aef0b52b25..3fa16822610 100644 --- a/cmake/ActsExternSources.cmake +++ b/cmake/ActsExternSources.cmake @@ -15,11 +15,11 @@ set( ACTS_COVFIE_SOURCE mark_as_advanced( ACTS_COVFIE_SOURCE ) set( ACTS_DETRAY_SOURCE - "URL;https://github.com/acts-project/detray/archive/refs/tags/v0.65.1.tar.gz;URL_MD5;fbf57a881565fa6019d79d13409b588f" CACHE STRING "Source to take DETRAY from") + "URL;https://github.com/acts-project/detray/archive/refs/tags/v0.70.0.tar.gz;URL_MD5;ce913a3dbd38d4453fb680b9667dfbaf" CACHE STRING "Source to take DETRAY from") mark_as_advanced( ACTS_DETRAY_SOURCE ) set( ACTS_TRACCC_SOURCE - "URL;https://github.com/acts-project/traccc/archive/refs/tags/v0.10.0.tar.gz;URL_MD5;131399d26e3280c4d7f7ca2995efd256" CACHE STRING "Source to take TRACCC from") + "GIT_REPOSITORY;https://github.com/fredevb/traccc;GIT_TAG;77473d3e67afaa535705cdb9dfe5a4337452be2a" CACHE STRING "Source to take TRACCC from") mark_as_advanced( ACTS_TRACCC_SOURCE ) set( ACTS_DFELIBS_SOURCE @@ -31,14 +31,14 @@ set( ACTS_FRNN_SOURCE mark_as_advanced( ACTS_FRNN_SOURCE ) set( ACTS_GEOMODEL_SOURCE - "GIT_REPOSITORY;https://gitlab.cern.ch/GeoModelDev/GeoModel;GIT_TAG;4.6.0;" CACHE STRING "Source to take GeoModel from") + "GIT_REPOSITORY;https://gitlab.cern.ch/GeoModelDev/GeoModel;GIT_TAG;4.6.0" CACHE STRING "Source to take GeoModel from") mark_as_advanced( ACTS_GEOMODEL_SOURCE ) set( ACTS_NLOHMANNJSON_SOURCE "URL;https://github.com/nlohmann/json/archive/refs/tags/v3.10.5.tar.gz;URL_HASH;SHA1=8969f5ad1a422e01f040ff48dcae9c0e6ad0811d" CACHE STRING "Source to take nlohmann_json from") mark_as_advanced( ACTS_NLOHMANN_JSON_SOURCE ) -string(REPLACE "." "_" _acts_boost_recommended_version_ ${_acts_boost_recommended_version}) +string(REPLACE "." "_" _acts_boost_recommended_version_ "${_acts_boost_recommended_version}") set( ACTS_BOOST_SOURCE "URL;https://boostorg.jfrog.io/artifactory/main/release/${_acts_boost_recommended_version}/source/boost_${_acts_boost_recommended_version_}.tar.gz" CACHE STRING "Source to take boost from") mark_as_advanced( ACTS_BOOST_SOURCE ) diff --git a/docs/getting_started.md b/docs/getting_started.md index 791768e067c..105161495fe 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -270,8 +270,6 @@ components. | ACTS_BUILD_PLUGIN_EDM4HEP | Build EDM4hep plugin
type: `bool`, default: `OFF` | | 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_COVFIE | Build Covfie plugin
type: `bool`, default: `OFF` | -| ACTS_BUILD_PLUGIN_DETRAY | Build Detray plugin
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_TRACCC | Build Traccc plugin
type: `bool`, default: `OFF` | | ACTS_USE_SYSTEM_GEOMODEL | Use a system-provided GeoModel
installation
type: `bool`, default: `ACTS_USE_SYSTEM_LIBS -> OFF` | | ACTS_BUILD_PLUGIN_GEANT4 | Build Geant4 plugin
type: `bool`, default: `OFF` | @@ -283,17 +281,17 @@ components. | ACTS_USE_SYSTEM_NLOHMANN_JSON | Use nlohmann::json provided by the
system instead of the bundled version
type: `bool`, default: `ACTS_USE_SYSTEM_LIBS -> OFF` | | ACTS_BUILD_PLUGIN_LEGACY | Build legacy plugin
type: `bool`, default: `OFF` | | ACTS_BUILD_PLUGIN_ONNX | Build ONNX plugin
type: `bool`, default: `OFF` | -| ACTS_SETUP_COVFIE | Explicitly set up covfie for the project
type: `bool`, default: `OFF` | +| ACTS_SETUP_COVFIE | Explicitly set up covfie for the project
type: `bool`, default: `ON` | | ACTS_USE_SYSTEM_COVFIE | Use a system-provided covfie
installation
type: `bool`, default: `ACTS_USE_SYSTEM_LIBS -> OFF` | -| ACTS_SETUP_DETRAY | Explicitly set up detray for the project
type: `bool`, default: `OFF` | +| ACTS_SETUP_DETRAY | Explicitly set up detray for the project
type: `bool`, default: `ON` | | ACTS_USE_SYSTEM_DETRAY | Use a system-provided detray
installation
type: `bool`, default: `ACTS_USE_SYSTEM_LIBS -> OFF` | -| ACTS_SETUP_TRACCC | Explicitly set up traccc for the project
type: `bool`, default: `OFF` | +| ACTS_SETUP_TRACCC | Explicitly set up traccc for the project
type: `bool`, default: `ON` | | ACTS_USE_SYSTEM_TRACCC | Use a system-provided traccc
installation
type: `bool`, default: `ACTS_USE_SYSTEM_LIBS -> OFF` | | ACTS_SETUP_DFELIBS | Explicitly set up dfelibs for the
project
type: `bool`, default: `ON` | | ACTS_USE_SYSTEM_DFELIBS | Use a system-provided dfelibs
installation
type: `bool`, default: `ACTS_USE_SYSTEM_LIBS -> OFF` | -| ACTS_SETUP_VECMEM | Explicitly set up vecmem for the project
type: `bool`, default: `OFF` | +| ACTS_SETUP_VECMEM | Explicitly set up vecmem for the project
type: `bool`, default: `ON` | | ACTS_USE_SYSTEM_VECMEM | Use a system-provided vecmem
installation
type: `bool`, default: `ACTS_USE_SYSTEM_LIBS -> OFF` | -| ACTS_SETUP_ALGEBRAPLUGINS | Explicitly set up algebra-plugins for
the project
type: `bool`, default: `OFF` | +| ACTS_SETUP_ALGEBRAPLUGINS | Explicitly set up algebra-plugins for
the project
type: `bool`, default: `ON` | | ACTS_USE_SYSTEM_ALGEBRAPLUGINS | Use a system-provided algebra-plugins
installation
type: `bool`, default: `ACTS_USE_SYSTEM_LIBS -> OFF` | | ACTS_BUILD_PLUGIN_TGEO | Build TGeo plugin
type: `bool`, default: `OFF` | | ACTS_BUILD_FATRAS | Build FAst TRAcking Simulation package
type: `bool`, default: `OFF` | diff --git a/thirdparty/README.md b/thirdparty/README.md index 2c3c037f3a7..ca89ca9e040 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -41,3 +41,23 @@ CMake instructions to build [Pybind11](https://github.com/pybind/pybind11), whic ## FRNN CMake instructions to build [FRNN](https://github.com/lxxue/FRNN), which is used by the Exa.TrkX plugin. + +## Algebra plugins + +CMake instruction to build [algebra-plugins](https://github.com/acts-project/algebra-plugins), which is used by the traccc plugin. + +## VecMem + +CMake instruction to build [VecMem](https://github.com/acts-project/vecmem), which is used by the traccc plugin. + +## Covfie + +CMake instruction to build [covfie](https://github.com/acts-project/covfie), which is used by the traccc plugin. + +## Detray + +CMake instruction to build [detray](https://github.com/acts-project/detray), which is used by the traccc plugin. + +## Traccc + +CMake instruction to build [traccc](https://github.com/acts-project/traccc), which is used by the traccc plugin. diff --git a/thirdparty/algebra-plugins/CMakeLists.txt b/thirdparty/algebra-plugins/CMakeLists.txt index a0126cece7f..1eab92a4ecf 100644 --- a/thirdparty/algebra-plugins/CMakeLists.txt +++ b/thirdparty/algebra-plugins/CMakeLists.txt @@ -20,8 +20,8 @@ set(ALGEBRA_PLUGINS_BUILD_TESTING FALSE CACHE BOOL "Turn off the build of the Algebra Plugins unit tests") set(ALGEBRA_PLUGINS_INCLUDE_EIGEN TRUE CACHE BOOL "Turn on the build of algebra::eigen") -set(ALGEBRA_PLUGINS_INCLUDE_VC TRUE CACHE BOOL - "Turn on the build of algebra::vc_array") +set(ALGEBRA_PLUGINS_INCLUDE_VC FALSE CACHE BOOL + "Turn off the build of algebra::vc_array") set(ALGEBRA_PLUGINS_INCLUDE_VECMEM TRUE CACHE BOOL "Turn on the build of algebra::vecmem_array") @@ -32,8 +32,8 @@ set(ALGEBRA_PLUGINS_INCLUDE_SMATRIX ${DETRAY_SMATRIX_PLUGIN} set(ALGEBRA_PLUGINS_SETUP_EIGEN3 OFF CACHE BOOL "Do not have Algebra Plugins set up Eigen3 for itself") -set(ALGEBRA_PLUGINS_SETUP_VC ON CACHE BOOL - "Have Algebra Plugins set up Vc for itself") +set(ALGEBRA_PLUGINS_SETUP_VC OFF CACHE BOOL + "Do not have Algebra Plugins set up Vc for itself") set(ALGEBRA_PLUGINS_USE_SYSTEM_VC OFF CACHE BOOL "Have Algebra Plugins build Vc itself") set(ALGEBRA_PLUGINS_SETUP_VECMEM FALSE CACHE BOOL diff --git a/thirdparty/detray/CMakeLists.txt b/thirdparty/detray/CMakeLists.txt index 961057df933..81dbf087fd8 100644 --- a/thirdparty/detray/CMakeLists.txt +++ b/thirdparty/detray/CMakeLists.txt @@ -28,8 +28,8 @@ set( DETRAY_BUILD_TUTORIALS OFF CACHE BOOL "Turn off the build of the Detray tutorials" ) set( DETRAY_EIGEN_PLUGIN ON CACHE BOOL "Turn on the build of the Detray Eigen code" ) -set( DETRAY_VC_PLUGIN ON CACHE BOOL - "Turn on the build of the Detray Vc code" ) +set( DETRAY_VC_PLUGIN OFF CACHE BOOL + "Turn off the build of the Detray Vc code" ) set( DETRAY_SETUP_VECMEM OFF CACHE BOOL "Do not set up VecMem as part of Detray" ) @@ -49,11 +49,10 @@ set( DETRAY_SETUP_ACTSVG OFF CACHE BOOL "Do not set up Actsvg as part of Detray" ) set( DETRAY_SETUP_DFELIBS OFF CACHE BOOL "Do not set up Dfelibs as part of Detray" ) -#set( DETRAY_VC_PLUGIN OFF CACHE BOOL -# "Do not build Vc based math plugin" ) -#set( DETRAY_SVG_DISPLAY ON CACHE BOOL -# "Build the ActSVG display module" ) - +set( DETRAY_SVG_DISPLAY ${ACTS_BUILD_PLUGIN_ACTSVG} CACHE BOOL + "Build the ActSVG display module depending on the ACTS_BUILD_PLUGIN_ACTSVG" ) +set ( DETRAY_BUILD_CUDA OFF CACHE BOOL + "Do not build Cuda sources in Detray" ) #Now set up its build. FetchContent_MakeAvailable(Detray) \ No newline at end of file diff --git a/thirdparty/dfelibs/README.MD b/thirdparty/dfelibs/README.MD new file mode 100644 index 00000000000..3cf5007073e --- /dev/null +++ b/thirdparty/dfelibs/README.MD @@ -0,0 +1,4 @@ +# Build Recipe for dfelibs + +This directory holds a simple build recipe for the +[dfelibs](https://github.com/acts-project/dfelibs) project. \ No newline at end of file diff --git a/thirdparty/traccc/CMakeLists.txt b/thirdparty/traccc/CMakeLists.txt index b62c9ba35f0..b7515577c2f 100644 --- a/thirdparty/traccc/CMakeLists.txt +++ b/thirdparty/traccc/CMakeLists.txt @@ -11,7 +11,7 @@ cmake_minimum_required(VERSION 3.14) include(FetchContent) # Tell the user what's happening. -message( STATUS "Building tracc as part of the Acts project" ) +message( STATUS "Building traccc as part of the Acts project" ) set( TRACCC_VERSION "${_acts_traccc_version}") @@ -34,6 +34,8 @@ set( TRACCC_SETUP_DETRAY OFF CACHE BOOL "Do not set up Detray as part of Traccc" ) set( TRACCC_SETUP_ACTS OFF CACHE BOOL "Do not set up ACTS as part of Traccc" ) +set( TRACCC_SETUP_TBB OFF CACHE BOOL + "Do not set up TBB as part of Traccc" ) set( TRACCC_BUILD_TESTING OFF CACHE BOOL "Turn off the build of the Traccc unit tests" ) diff --git a/thirdparty/vecmem/CMakeLists.txt b/thirdparty/vecmem/CMakeLists.txt index b6d74615471..decf6c6c7f7 100644 --- a/thirdparty/vecmem/CMakeLists.txt +++ b/thirdparty/vecmem/CMakeLists.txt @@ -26,3 +26,6 @@ set( VECMEM_BUILD_BENCHMARKING FALSE CACHE BOOL # Now set up its build. FetchContent_MakeAvailable( VecMem ) + +# Make the "VecMem language code" available for the whole project. +include( "${VECMEM_LANGUAGE_DIR}/vecmem-check-language.cmake" )