From f935e2512cc72577eb9aa9934a6f7b52f4c0dd53 Mon Sep 17 00:00:00 2001 From: Paul Gessinger Date: Thu, 17 Oct 2024 13:49:03 +0200 Subject: [PATCH 01/14] fix: FPE monitoring boost discovery, addr2line fallback (#3747) This PR - Changes the way FPE monitoring configures `boost::stacktrace`: the fallback to `addr2line` is dropped as that doesn't work anyway - Change explicit `-Werror` in the CI to `CMAKE_COMPILE_WARNING_AS_ERROR=ON` - This is not applied in `try_compile`, which would otherwise cause false negatives because there are warnings we don't control. - Add a static method in `FpeMonitor` that returns if `backtrace` / symbolization support is on or not. - Make the sequencer fail early if it's configured to run the FPE monitor, has masks configured and symbolization is not supported. --- CMakePresets.json | 2 +- .../Framework/src/Framework/Sequencer.cpp | 7 ++++ Plugins/FpeMonitoring/CMakeLists.txt | 32 ++++++++----------- .../Acts/Plugins/FpeMonitoring/FpeMonitor.hpp | 2 ++ Plugins/FpeMonitoring/src/FpeMonitor.cpp | 8 +++++ 5 files changed, 31 insertions(+), 20 deletions(-) diff --git a/CMakePresets.json b/CMakePresets.json index bee5ab514df..2aef0f3fe94 100644 --- a/CMakePresets.json +++ b/CMakePresets.json @@ -46,7 +46,7 @@ "inherits": "common", "cacheVariables": { "CMAKE_BUILD_TYPE": "Release", - "CMAKE_CXX_FLAGS": "-Werror", + "CMAKE_COMPILE_WARNING_AS_ERROR": "ON", "ACTS_FORCE_ASSERTIONS": "ON", "ACTS_ENABLE_LOG_FAILURE_THRESHOLD": "ON", "ACTS_BUILD_BENCHMARKS": "ON", diff --git a/Examples/Framework/src/Framework/Sequencer.cpp b/Examples/Framework/src/Framework/Sequencer.cpp index 100f55cf93c..78444c58ac4 100644 --- a/Examples/Framework/src/Framework/Sequencer.cpp +++ b/Examples/Framework/src/Framework/Sequencer.cpp @@ -126,6 +126,13 @@ Sequencer::Sequencer(const Sequencer::Config& cfg) "ACTS_SEQUENCER_DISABLE_FPEMON"); m_cfg.trackFpes = false; } + + if (m_cfg.trackFpes && !m_cfg.fpeMasks.empty() && + !Acts::FpeMonitor::canSymbolize()) { + ACTS_ERROR("FPE monitoring is enabled but symbolization is not available"); + throw std::runtime_error( + "FPE monitoring is enabled but symbolization is not available"); + } } void Sequencer::addContextDecorator( diff --git a/Plugins/FpeMonitoring/CMakeLists.txt b/Plugins/FpeMonitoring/CMakeLists.txt index 05a6126e2f3..ccd7c7f4ceb 100644 --- a/Plugins/FpeMonitoring/CMakeLists.txt +++ b/Plugins/FpeMonitoring/CMakeLists.txt @@ -24,6 +24,11 @@ else() set(_backtrace_setup_complete FALSE) + find_path( + boost_stacktrace_include + NAMES "boost/stacktrace.hpp" + REQUIRED + ) if(Backtrace_FOUND) # check if we need to link against bracktrace or not set(backtrace_include "") @@ -44,6 +49,7 @@ else() "${CMAKE_BINARY_DIR}" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/backtrace.cpp" LINK_LIBRARIES ${dl_LIBRARY} + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${boost_stacktrace_include}" COMPILE_DEFINITIONS -DBOOST_STACKTRACE_USE_BACKTRACE OUTPUT_VARIABLE __OUTPUT ) @@ -54,9 +60,9 @@ else() message(CHECK_FAIL "no") file(GLOB hints "/usr/lib/gcc/*/*/include") - find_file(backtrace_header "backtrace.h" HINTS ${hints}) + find_file(backtrace_header NAMES "backtrace.h" HINTS ${hints}) - if(${backtrace_header} STREQUAL "backtrcae_header-NOTFOUND") + if(${backtrace_header} STREQUAL "backtrace_header-NOTFOUND") message(STATUS "Could not find backtrace header file") else() set(backtrace_include @@ -82,6 +88,8 @@ else() "${CMAKE_BINARY_DIR}" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/backtrace.cpp" LINK_LIBRARIES ${dl_LIBRARY} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${boost_stacktrace_include}" COMPILE_DEFINITIONS -DBOOST_STACKTRACE_USE_BACKTRACE ${backtrace_include} @@ -111,6 +119,7 @@ else() "${CMAKE_BINARY_DIR}" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/backtrace.cpp" LINK_LIBRARIES ${dl_LIBRARY} + CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${boost_stacktrace_include}" COMPILE_DEFINITIONS -DBOOST_STACKTRACE_USE_BACKTRACE ${backtrace_include} @@ -137,6 +146,8 @@ else() "${CMAKE_BINARY_DIR}" "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/backtrace.cpp" LINK_LIBRARIES backtrace ${dl_LIBRARY} + CMAKE_FLAGS + "-DINCLUDE_DIRECTORIES=${boost_stacktrace_include}" COMPILE_DEFINITIONS -DBOOST_STACKTRACE_USE_BACKTRACE ${backtrace_include} @@ -158,23 +169,6 @@ else() endif() endif() - if(NOT _backtrace_setup_complete) - message(CHECK_START "Is addr2line available") - if(addr2line_EXECUTABLE) - list(APPEND _fpe_options -DBOOST_STACKTRACE_USE_ADDR2LINE) - list( - APPEND - _fpe_options - -DBOOST_STACKTRACE_ADDR2LINE_LOCATION=${addr2line_EXECUTABLE} - ) - message(CHECK_PASS "yes") - - set(_backtrace_setup_complete TRUE) - else() - message(CHECK_FAIL "no") - endif() - endif() - if(NOT _backtrace_setup_complete) message(STATUS "Unable to set up stacktrace setup: use noop") list(APPEND _fpe_options -BOOST_STACKTRACE_USE_NOOP) diff --git a/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp b/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp index 99e39da96d0..d1b9fabec64 100644 --- a/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp +++ b/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp @@ -131,6 +131,8 @@ class FpeMonitor { std::size_t depth); static std::string getSourceLocation(const boost::stacktrace::frame &frame); + static bool canSymbolize(); + private: void enable(); void disable(); diff --git a/Plugins/FpeMonitoring/src/FpeMonitor.cpp b/Plugins/FpeMonitoring/src/FpeMonitor.cpp index 8b4feb5f1d2..db41dc1f8b2 100644 --- a/Plugins/FpeMonitoring/src/FpeMonitor.cpp +++ b/Plugins/FpeMonitoring/src/FpeMonitor.cpp @@ -332,4 +332,12 @@ std::string FpeMonitor::getSourceLocation( return frame.source_file() + ":" + std::to_string(frame.source_line()); } +bool FpeMonitor::canSymbolize() { +#if defined(BOOST_STACKTRACE_USE_NOOP) + return false; +#else + return true; +#endif +} + } // namespace Acts From bf36f464f98d32fd97dc9833013ed14f1c64166e Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Thu, 17 Oct 2024 19:29:54 +0200 Subject: [PATCH 02/14] feat: Allow reflection of track parameters (#3682) Add helper functions to reflect track parameters. This is useful when seed parameters are estimated for the spacepoints in reverse direction which is necessary for strip seeds. --- This pull request introduces functionality to reflect track parameters for both bound and free track parameters in the Acts framework. The key changes include adding new methods to reflect parameters and the corresponding implementation to handle the reflection logic. ### New Methods for Reflecting Track Parameters: * [`Core/include/Acts/EventData/GenericBoundTrackParameters.hpp`](diffhunk://#diff-b3a2aaa0a0f138a1b44e7e6494aae4f8b905ad83716a4253bbea6446623f0eb1R253-R263): Added `reflectInplace` and `reflect` methods to `GenericBoundTrackParameters` to enable in-place reflection and returning reflected parameters. * [`Core/include/Acts/EventData/GenericFreeTrackParameters.hpp`](diffhunk://#diff-35a3d07a1eb05110c620e3cdbc38968456e66270c9f9460472f49e65d8b43acdR177-R187): Added `reflectInplace` and `reflect` methods to `GenericFreeTrackParameters` to enable in-place reflection and returning reflected parameters. ### Helper Functions for Reflection: * [`Core/include/Acts/EventData/TransformationHelpers.hpp`](diffhunk://#diff-73d04b62535d54171256def2e580c39602c9a2ab36db1689ebd74d84b79c127dR21-R32): Introduced `reflectBoundParameters` and `reflectFreeParameters` functions to handle the reflection logic for bound and free track parameters. * [`Core/src/EventData/TransformationHelpers.cpp`](diffhunk://#diff-59ee8d8625a58700aca8eae78a6655d0162483f2644cdd2c77c668493d7d8b87R16-R40): Implemented the `reflectBoundParameters` and `reflectFreeParameters` functions to perform the actual reflection calculations. --- .../EventData/GenericBoundTrackParameters.hpp | 11 ++++++++ .../GenericCurvilinearTrackParameters.hpp | 8 ++++++ .../EventData/GenericFreeTrackParameters.hpp | 12 ++++++++ .../Acts/EventData/TransformationHelpers.hpp | 28 +++++++++++++++++++ .../EventData/BoundTrackParametersTests.cpp | 8 ++++++ .../CurvilinearTrackParametersTests.cpp | 9 ++++++ .../EventData/FreeTrackParametersTests.cpp | 8 ++++++ 7 files changed, 84 insertions(+) diff --git a/Core/include/Acts/EventData/GenericBoundTrackParameters.hpp b/Core/include/Acts/EventData/GenericBoundTrackParameters.hpp index 27b411a99cc..f624cd88aee 100644 --- a/Core/include/Acts/EventData/GenericBoundTrackParameters.hpp +++ b/Core/include/Acts/EventData/GenericBoundTrackParameters.hpp @@ -250,6 +250,17 @@ class GenericBoundTrackParameters { return m_surface->referenceFrame(geoCtx, position(geoCtx), momentum()); } + /// Reflect the parameters in place. + void reflectInPlace() { m_params = reflectBoundParameters(m_params); } + + /// Reflect the parameters. + /// @return Reflected parameters. + GenericBoundTrackParameters reflect() const { + GenericBoundTrackParameters reflected = *this; + reflected.reflectInPlace(); + return reflected; + } + private: BoundVector m_params; std::optional m_cov; diff --git a/Core/include/Acts/EventData/GenericCurvilinearTrackParameters.hpp b/Core/include/Acts/EventData/GenericCurvilinearTrackParameters.hpp index a42ac2f116f..6e4ed9bae7a 100644 --- a/Core/include/Acts/EventData/GenericCurvilinearTrackParameters.hpp +++ b/Core/include/Acts/EventData/GenericCurvilinearTrackParameters.hpp @@ -111,6 +111,14 @@ class GenericCurvilinearTrackParameters Vector3 position() const { return GenericBoundTrackParameters::position({}); } + + /// Reflect the parameters. + /// @return Reflected parameters. + GenericCurvilinearTrackParameters reflect() const { + GenericCurvilinearTrackParameters reflected = *this; + reflected.reflectInPlace(); + return reflected; + } }; } // namespace Acts diff --git a/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp b/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp index 1e7846318ef..857d6c328b9 100644 --- a/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp +++ b/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp @@ -12,6 +12,7 @@ #include "Acts/Definitions/Common.hpp" #include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/EventData/TrackParametersConcept.hpp" +#include "Acts/EventData/TransformationHelpers.hpp" #include "Acts/EventData/detail/PrintParameters.hpp" #include "Acts/Utilities/MathHelpers.hpp" #include "Acts/Utilities/UnitVectors.hpp" @@ -175,6 +176,17 @@ class GenericFreeTrackParameters { return m_particleHypothesis; } + /// Reflect the parameters in place. + void reflectInPlace() { m_params = reflectFreeParameters(m_params); } + + /// Reflect the parameters. + /// @return Reflected parameters. + GenericFreeTrackParameters reflect() const { + GenericFreeTrackParameters reflected = *this; + reflected.reflectInPlace(); + return reflected; + } + private: FreeVector m_params; std::optional m_cov; diff --git a/Core/include/Acts/EventData/TransformationHelpers.hpp b/Core/include/Acts/EventData/TransformationHelpers.hpp index 7fa297f4abc..39240bf469e 100644 --- a/Core/include/Acts/EventData/TransformationHelpers.hpp +++ b/Core/include/Acts/EventData/TransformationHelpers.hpp @@ -13,11 +13,39 @@ #include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Utilities/Result.hpp" +#include "Acts/Utilities/detail/periodic.hpp" namespace Acts { class Surface; +/// Reflect bound track parameters. +/// +/// @param boundParams Bound track parameters vector +/// @return Reflected bound track parameters vector +inline BoundVector reflectBoundParameters(const BoundVector& boundParams) { + BoundVector reflected = boundParams; + auto [phi, theta] = detail::normalizePhiTheta( + boundParams[eBoundPhi] - M_PI, M_PI - boundParams[eBoundTheta]); + reflected[eBoundPhi] = phi; + reflected[eBoundTheta] = theta; + reflected[eBoundQOverP] = -boundParams[eBoundQOverP]; + return reflected; +} + +/// Reflect free track parameters. +/// +/// @param freeParams Free track parameters vector +/// @return Reflected free track parameters vector +inline FreeVector reflectFreeParameters(const FreeVector& freeParams) { + FreeVector reflected = freeParams; + reflected[eFreeDir0] = -freeParams[eFreeDir0]; + reflected[eFreeDir1] = -freeParams[eFreeDir1]; + reflected[eFreeDir2] = -freeParams[eFreeDir2]; + reflected[eFreeQOverP] = -freeParams[eFreeQOverP]; + return reflected; +} + /// Transform bound track parameters into equivalent free track parameters. /// /// @param surface Surface onto which the input parameters are bound diff --git a/Tests/UnitTests/Core/EventData/BoundTrackParametersTests.cpp b/Tests/UnitTests/Core/EventData/BoundTrackParametersTests.cpp index a05d273f7a1..9daf24c8a79 100644 --- a/Tests/UnitTests/Core/EventData/BoundTrackParametersTests.cpp +++ b/Tests/UnitTests/Core/EventData/BoundTrackParametersTests.cpp @@ -76,6 +76,14 @@ void checkParameters(const BoundTrackParameters& params, double l0, double l1, eps); CHECK_CLOSE_OR_SMALL(params.momentum(), p * unitDir, eps, eps); BOOST_CHECK_EQUAL(params.charge(), q); + + // reflection + BoundTrackParameters reflectedParams = params; + reflectedParams.reflectInPlace(); + CHECK_CLOSE_OR_SMALL(params.reflect().parameters(), + reflectedParams.parameters(), eps, eps); + CHECK_CLOSE_OR_SMALL(reflectedParams.reflect().parameters(), + params.parameters(), eps, eps); } void runTest(const std::shared_ptr& surface, double l0, diff --git a/Tests/UnitTests/Core/EventData/CurvilinearTrackParametersTests.cpp b/Tests/UnitTests/Core/EventData/CurvilinearTrackParametersTests.cpp index 122d4b075d0..143515148d4 100644 --- a/Tests/UnitTests/Core/EventData/CurvilinearTrackParametersTests.cpp +++ b/Tests/UnitTests/Core/EventData/CurvilinearTrackParametersTests.cpp @@ -72,6 +72,15 @@ void checkParameters(const CurvilinearTrackParameters& params, double phi, // curvilinear reference surface CHECK_CLOSE_OR_SMALL(referenceSurface->center(geoCtx), pos, eps, eps); CHECK_CLOSE_OR_SMALL(referenceSurface->normal(geoCtx), unitDir, eps, eps); + + // reflection + CurvilinearTrackParameters reflectedParams = params; + reflectedParams.reflectInPlace(); + CHECK_CLOSE_OR_SMALL(params.reflect().parameters(), + reflectedParams.parameters(), eps, eps); + CHECK_CLOSE_OR_SMALL(reflectedParams.reflect().parameters(), + params.parameters(), eps, eps); + // TODO verify reference frame } diff --git a/Tests/UnitTests/Core/EventData/FreeTrackParametersTests.cpp b/Tests/UnitTests/Core/EventData/FreeTrackParametersTests.cpp index 71b0dc0a20e..fb7a11f3f68 100644 --- a/Tests/UnitTests/Core/EventData/FreeTrackParametersTests.cpp +++ b/Tests/UnitTests/Core/EventData/FreeTrackParametersTests.cpp @@ -67,6 +67,14 @@ void checkParameters(const FreeTrackParameters& params, const Vector4& pos4, eps); CHECK_CLOSE_OR_SMALL(params.time(), params.template get(), eps, eps); + + // reflection + FreeTrackParameters reflectedParams = params; + reflectedParams.reflectInPlace(); + CHECK_CLOSE_OR_SMALL(params.reflect().parameters(), + reflectedParams.parameters(), eps, eps); + CHECK_CLOSE_OR_SMALL(reflectedParams.reflect().parameters(), + params.parameters(), eps, eps); } } // namespace From 057d33d60918ef7e3c37b291827d15dfc6fb04a3 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Thu, 17 Oct 2024 21:48:39 +0200 Subject: [PATCH 03/14] feat: Add `estimateTrackParamCovariance` to Core (#3683) Add a `estimateTrackParamCovariance` function to Core to estimate the initial covariance of track parameters after seeding. blocked by - https://github.com/acts-project/acts/pull/3665 --- This pull request introduces a new function for estimating track parameter covariance and refactors existing code to utilize this new function. The changes improve code modularity and maintainability by centralizing the covariance estimation logic. ### New Functionality: * [`Core/include/Acts/Seeding/EstimateTrackParamsFromSeed.hpp`](diffhunk://#diff-1d63df6364bcd57d6eae717e4c8dea355f07a36f5fca41b0e9fefdbf3224c0a0R292-R335): Added `EstimateTrackParamCovarianceConfig` struct and `estimateTrackParamCovariance` function to estimate track parameter covariance. ### Refactoring: * [`Examples/Algorithms/TrackFinding/src/TrackParamsEstimationAlgorithm.cpp`](diffhunk://#diff-3fa61f411627effaf29755fa1d539c90bbd2c5155f04c4fa7a0d7f36d99340f3L38-L79): Removed the `makeInitialCovariance` function and replaced its usage with the new `estimateTrackParamCovariance` function. This change simplifies the code by removing redundant logic. [[1]](diffhunk://#diff-3fa61f411627effaf29755fa1d539c90bbd2c5155f04c4fa7a0d7f36d99340f3L38-L79) [[2]](diffhunk://#diff-3fa61f411627effaf29755fa1d539c90bbd2c5155f04c4fa7a0d7f36d99340f3L174-R144) * [`Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSmearing.cpp`](diffhunk://#diff-d4047681edb055a3b4ca13bb837f6fef194fd0c8b3205f337db73e97f4b6de82L131-R141): Updated the covariance calculation to use the new `estimateTrackParamCovariance` function, ensuring consistency across the codebase. ### Miscellaneous: * [`Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSmearing.cpp`](diffhunk://#diff-d4047681edb055a3b4ca13bb837f6fef194fd0c8b3205f337db73e97f4b6de82R14): Included the `EstimateTrackParamsFromSeed.hpp` header to access the new covariance estimation function. --- Core/CMakeLists.txt | 1 + .../Seeding/EstimateTrackParamsFromSeed.hpp | 37 +++++++++++++ Core/src/Seeding/CMakeLists.txt | 1 + .../Seeding/EstimateTrackParamsFromSeed.cpp | 50 +++++++++++++++++ .../src/TrackParamsEstimationAlgorithm.cpp | 53 ++++--------------- .../TruthTracking/ParticleSmearing.cpp | 32 ++++------- Examples/Python/tests/root_file_hashes.txt | 8 +-- 7 files changed, 111 insertions(+), 71 deletions(-) create mode 100644 Core/src/Seeding/CMakeLists.txt create mode 100644 Core/src/Seeding/EstimateTrackParamsFromSeed.cpp diff --git a/Core/CMakeLists.txt b/Core/CMakeLists.txt index eeb6bc8b92a..554656f514c 100644 --- a/Core/CMakeLists.txt +++ b/Core/CMakeLists.txt @@ -110,6 +110,7 @@ add_subdirectory(src/MagneticField) add_subdirectory(src/Material) add_subdirectory(src/Navigation) add_subdirectory(src/Propagator) +add_subdirectory(src/Seeding) add_subdirectory(src/Surfaces) add_subdirectory(src/TrackFinding) add_subdirectory(src/TrackFitting) diff --git a/Core/include/Acts/Seeding/EstimateTrackParamsFromSeed.hpp b/Core/include/Acts/Seeding/EstimateTrackParamsFromSeed.hpp index 7a5c597f626..f3850e102ce 100644 --- a/Core/include/Acts/Seeding/EstimateTrackParamsFromSeed.hpp +++ b/Core/include/Acts/Seeding/EstimateTrackParamsFromSeed.hpp @@ -287,4 +287,41 @@ std::optional estimateTrackParamsFromSeed( return params; } +/// Configuration for the estimation of the covariance matrix of the track +/// parameters with `estimateTrackParamCovariance`. +struct EstimateTrackParamCovarianceConfig { + /// The initial sigmas for the track parameters + BoundVector initialSigmas = {1. * UnitConstants::mm, + 1. * UnitConstants::mm, + 1. * UnitConstants::degree, + 1. * UnitConstants::degree, + 1. * UnitConstants::e / UnitConstants::GeV, + 1. * UnitConstants::ns}; + + /// The initial relative uncertainty of the q/pt + double initialSigmaPtRel = 0.1; + + /// The inflation factors for the variances of the track parameters + BoundVector initialVarInflation = {1., 1., 1., 1., 1., 1.}; + /// The inflation factor for time uncertainty if the time parameter was not + /// estimated + double noTimeVarInflation = 100.; +}; + +/// Estimate the covariance matrix of the given track parameters based on the +/// provided configuration. The assumption is that we can model the uncertainty +/// of the track parameters as a diagonal matrix with the provided initial +/// sigmas. The inflation factors are used to inflate the initial variances +/// based on the provided configuration. The uncertainty of q/p is estimated +/// based on the relative uncertainty of the q/pt and the theta uncertainty. +/// +/// @param config is the configuration for the estimation +/// @param params is the track parameters +/// @param hasTime is true if the track parameters have time +/// +/// @return the covariance matrix of the track parameters +BoundMatrix estimateTrackParamCovariance( + const EstimateTrackParamCovarianceConfig& config, const BoundVector& params, + bool hasTime); + } // namespace Acts diff --git a/Core/src/Seeding/CMakeLists.txt b/Core/src/Seeding/CMakeLists.txt new file mode 100644 index 00000000000..770037b1dfd --- /dev/null +++ b/Core/src/Seeding/CMakeLists.txt @@ -0,0 +1 @@ +target_sources(ActsCore PRIVATE EstimateTrackParamsFromSeed.cpp) diff --git a/Core/src/Seeding/EstimateTrackParamsFromSeed.cpp b/Core/src/Seeding/EstimateTrackParamsFromSeed.cpp new file mode 100644 index 00000000000..83d950fc3a1 --- /dev/null +++ b/Core/src/Seeding/EstimateTrackParamsFromSeed.cpp @@ -0,0 +1,50 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/. + +#include "Acts/Seeding/EstimateTrackParamsFromSeed.hpp" + +#include "Acts/Definitions/TrackParametrization.hpp" + +Acts::BoundMatrix Acts::estimateTrackParamCovariance( + const EstimateTrackParamCovarianceConfig& config, const BoundVector& params, + bool hasTime) { + assert((params[eBoundTheta] > 0 && params[eBoundTheta] < M_PI) && + "Theta must be in the range (0, pi)"); + + BoundSquareMatrix result = BoundSquareMatrix::Zero(); + + for (std::size_t i = eBoundLoc0; i < eBoundSize; ++i) { + double sigma = config.initialSigmas[i]; + double variance = sigma * sigma; + + if (i == eBoundQOverP) { + // note that we rely on the fact that sigma theta is already computed + double varianceTheta = result(eBoundTheta, eBoundTheta); + + // transverse momentum contribution + variance += std::pow(config.initialSigmaPtRel * params[eBoundQOverP], 2); + + // theta contribution + variance += + varianceTheta * + std::pow(params[eBoundQOverP] / std::tan(params[eBoundTheta]), 2); + } + + if (i == eBoundTime && !hasTime) { + // Inflate the time uncertainty if no time measurement is available + variance *= config.noTimeVarInflation; + } + + // Inflate the initial covariance + variance *= config.initialVarInflation[i]; + + result(i, i) = variance; + } + + return result; +} diff --git a/Examples/Algorithms/TrackFinding/src/TrackParamsEstimationAlgorithm.cpp b/Examples/Algorithms/TrackFinding/src/TrackParamsEstimationAlgorithm.cpp index a54b10d2e7d..c8a30c7147d 100644 --- a/Examples/Algorithms/TrackFinding/src/TrackParamsEstimationAlgorithm.cpp +++ b/Examples/Algorithms/TrackFinding/src/TrackParamsEstimationAlgorithm.cpp @@ -32,48 +32,6 @@ namespace ActsExamples { -namespace { - -Acts::BoundSquareMatrix makeInitialCovariance( - const TrackParamsEstimationAlgorithm::Config& config, - const Acts::BoundVector& params, const SimSpacePoint& sp) { - Acts::BoundSquareMatrix result = Acts::BoundSquareMatrix::Zero(); - - for (std::size_t i = Acts::eBoundLoc0; i < Acts::eBoundSize; ++i) { - double sigma = config.initialSigmas[i]; - double variance = sigma * sigma; - - if (i == Acts::eBoundQOverP) { - // note that we rely on the fact that sigma theta is already computed - double varianceTheta = result(Acts::eBoundTheta, Acts::eBoundTheta); - - // transverse momentum contribution - variance += - std::pow(config.initialSigmaPtRel * params[Acts::eBoundQOverP], 2); - - // theta contribution - variance += - varianceTheta * std::pow(params[Acts::eBoundQOverP] / - std::tan(params[Acts::eBoundTheta]), - 2); - } - - // Inflate the time uncertainty if no time measurement is available - if (i == Acts::eBoundTime && !sp.t().has_value()) { - variance *= config.noTimeVarInflation; - } - - // Inflate the initial covariance - variance *= config.initialVarInflation[i]; - - result(i, i) = variance; - } - - return result; -} - -} // namespace - TrackParamsEstimationAlgorithm::TrackParamsEstimationAlgorithm( TrackParamsEstimationAlgorithm::Config cfg, Acts::Logging::Level lvl) : IAlgorithm("TrackParamsEstimationAlgorithm", lvl), m_cfg(std::move(cfg)) { @@ -166,8 +124,15 @@ ProcessCode TrackParamsEstimationAlgorithm::execute( const auto& params = optParams.value(); - Acts::BoundSquareMatrix cov = - makeInitialCovariance(m_cfg, params, *bottomSP); + Acts::EstimateTrackParamCovarianceConfig config{ + .initialSigmas = + Eigen::Map{m_cfg.initialSigmas.data()}, + .initialSigmaPtRel = m_cfg.initialSigmaPtRel, + .initialVarInflation = Eigen::Map{ + m_cfg.initialVarInflation.data()}}; + + Acts::BoundSquareMatrix cov = Acts::estimateTrackParamCovariance( + config, params, bottomSP->t().has_value()); trackParameters.emplace_back(surface->getSharedPtr(), params, cov, m_cfg.particleHypothesis); diff --git a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSmearing.cpp b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSmearing.cpp index 937a5bc1863..cfc62ab9da9 100644 --- a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSmearing.cpp +++ b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSmearing.cpp @@ -11,6 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/EventData/ParticleHypothesis.hpp" +#include "Acts/Seeding/EstimateTrackParamsFromSeed.hpp" #include "Acts/Surfaces/PerigeeSurface.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Utilities/Helpers.hpp" @@ -128,31 +129,16 @@ ActsExamples::ProcessCode ActsExamples::ParticleSmearing::execute( Acts::BoundSquareMatrix cov = Acts::BoundSquareMatrix::Zero(); if (m_cfg.initialSigmas) { // use the initial sigmas if set - for (std::size_t i = Acts::eBoundLoc0; i < Acts::eBoundSize; ++i) { - double sigma = (*m_cfg.initialSigmas)[i]; - double variance = sigma * sigma; - - if (i == Acts::eBoundQOverP) { - // note that we rely on the fact that sigma theta is already - // computed - double varianceTheta = cov(Acts::eBoundTheta, Acts::eBoundTheta); - // transverse momentum contribution - variance += std::pow( - m_cfg.initialSigmaPtRel * params[Acts::eBoundQOverP], 2); + Acts::EstimateTrackParamCovarianceConfig config{ + .initialSigmas = + Eigen::Map{ + m_cfg.initialSigmas->data()}, + .initialSigmaPtRel = m_cfg.initialSigmaPtRel, + .initialVarInflation = Eigen::Map{ + m_cfg.initialVarInflation.data()}}; - // theta contribution - variance += varianceTheta * - std::pow(params[Acts::eBoundQOverP] / - std::tan(params[Acts::eBoundTheta]), - 2); - } - - // Inflate the initial covariance - variance *= m_cfg.initialVarInflation[i]; - - cov(i, i) = variance; - } + cov = Acts::estimateTrackParamCovariance(config, params, false); } else { // otherwise use the smearing sigmas diff --git a/Examples/Python/tests/root_file_hashes.txt b/Examples/Python/tests/root_file_hashes.txt index 6ddb1a405cd..39df454b3e8 100644 --- a/Examples/Python/tests/root_file_hashes.txt +++ b/Examples/Python/tests/root_file_hashes.txt @@ -39,16 +39,16 @@ test_ckf_tracks_example[generic-full_seeding]__performance_seeding_trees.root: 0 test_ckf_tracks_example[generic-truth_estimated]__trackstates_ckf.root: a8c5c6f6c1e6303b887d47b509b7f71a2ffa5f38638fe46ce5bce76fd20d64ca test_ckf_tracks_example[generic-truth_estimated]__tracksummary_ckf.root: 417f7326e1e1bb4519f1378145ac733bdda6653eb9871fd69e455e0269d996a6 test_ckf_tracks_example[generic-truth_estimated]__performance_seeding.root: 1facb05c066221f6361b61f015cdf0918e94d9f3fce2269ec7b6a4dffeb2bc7e -test_ckf_tracks_example[generic-truth_smeared]__trackstates_ckf.root: de11c0868a70ade0dcc80465d4e6dcf1dd7fcf8149603b47ee7d87d862a6534a -test_ckf_tracks_example[generic-truth_smeared]__tracksummary_ckf.root: f18e9ecce6d9585fd150c5aafc9ac225a5bab342aaab50a28283ba879691af1f +test_ckf_tracks_example[generic-truth_smeared]__trackstates_ckf.root: edf0b06ce9ee0e4fcb153e41859af7b5153271de18f49a6842a23ad2d66b7e09 +test_ckf_tracks_example[generic-truth_smeared]__tracksummary_ckf.root: 06d6ae1d05cb611b19df3c59531997c9b0108f5ef6027d76c4827bd2d9edb921 test_ckf_tracks_example[odd-full_seeding]__trackstates_ckf.root: 463d6aaed4d869652b5b184940e789cde0fb441bdd135813b85462a515e6480a test_ckf_tracks_example[odd-full_seeding]__tracksummary_ckf.root: a8ad83a07b48d4cfcf70d0e6fdc3c8997eb03c1f8c2a7be27ea888b099000d79 test_ckf_tracks_example[odd-full_seeding]__performance_seeding_trees.root: 43c58577aafe07645e5660c4f43904efadf91d8cda45c5c04c248bbe0f59814f test_ckf_tracks_example[odd-truth_estimated]__trackstates_ckf.root: 247dd581cc177625c0286718261c004e2149536d70c8281dfaf697879a84d76d test_ckf_tracks_example[odd-truth_estimated]__tracksummary_ckf.root: 1b08a80e73aedf5cf38a3a407794b82297bec37f556ad4efcda3489a1b17d4d2 test_ckf_tracks_example[odd-truth_estimated]__performance_seeding.root: 1a36b7017e59f1c08602ef3c2cb0483c51df248f112e3780c66594110719c575 -test_ckf_tracks_example[odd-truth_smeared]__trackstates_ckf.root: 7adfc2bf5ee35a126b713187dd8b11f4497cf864a4a83e57a40885688974413e -test_ckf_tracks_example[odd-truth_smeared]__tracksummary_ckf.root: 7a9de8a8bd1c09f7b4d1c547f824af6c8123afb044dd429180b0d13e47d6f975 +test_ckf_tracks_example[odd-truth_smeared]__trackstates_ckf.root: a9621b535ea2912d172142394f51f68e4e7dc255b32d479d6305fa599152b420 +test_ckf_tracks_example[odd-truth_smeared]__tracksummary_ckf.root: af1a6bb16a070db7ed8043e2188d56f0034843099fc3c332731c4cf86ba39c57 test_vertex_fitting_reading[Truth-False-100]__performance_vertexing.root: 76ef6084d758dfdfc0151ddec2170e12d73394424e3dac4ffe46f0f339ec8293 test_vertex_fitting_reading[Iterative-False-100]__performance_vertexing.root: 60372210c830a04f95ceb78c6c68a9b0de217746ff59e8e73053750c837b57eb test_vertex_fitting_reading[Iterative-True-100]__performance_vertexing.root: e34f217d524a5051dbb04a811d3407df3ebe2cc4bb7f54f6bda0847dbd7b52c3 From c862d2da097451a197b931c810c3ad667f1586c1 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Fri, 18 Oct 2024 00:27:00 +0200 Subject: [PATCH 04/14] fix: Handle Fatras immediate abort edge case (#3744) Currently Fatras might abort before reaching the pointer where we initialize the particle. This leads to desynchronization between initial and final particles which will then lead to warning/error logs downstream ``` ParticleSele WARNING No final particle found for 4|11|169|0|0 ``` The initial call of the actor is now caught be checking the propagation stage which then initializes the result object gracefully. Discovered in https://github.com/acts-project/acts/pull/3742 --- .../include/ActsFatras/Kernel/Simulation.hpp | 10 +++++- .../Kernel/detail/SimulationActor.hpp | 31 +++++++--------- .../Fatras/Kernel/SimulationActorTests.cpp | 36 +++++++++++++++++++ 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/Fatras/include/ActsFatras/Kernel/Simulation.hpp b/Fatras/include/ActsFatras/Kernel/Simulation.hpp index cbc1115225a..2d8280737f0 100644 --- a/Fatras/include/ActsFatras/Kernel/Simulation.hpp +++ b/Fatras/include/ActsFatras/Kernel/Simulation.hpp @@ -245,6 +245,9 @@ struct Simulation { continue; } + assert(result->particle.particleId() == initialParticle.particleId() && + "Particle id must not change during simulation"); + copyOutputs(result.value(), simulatedParticlesInitial, simulatedParticlesFinal, hits); // since physics processes are independent, there can be particle id @@ -256,6 +259,10 @@ struct Simulation { } } + assert( + (simulatedParticlesInitial.size() == simulatedParticlesFinal.size()) && + "Inconsistent final sizes of the simulated particle containers"); + // the overall function call succeeded, i.e. no fatal errors occurred. // yet, there might have been some particle for which the propagation // failed. thus, the successful result contains a list of failed particles. @@ -284,12 +291,13 @@ struct Simulation { // initial particle state was already pushed to the container before // store final particle state at the end of the simulation particlesFinal.push_back(result.particle); + std::copy(result.hits.begin(), result.hits.end(), std::back_inserter(hits)); + // move generated secondaries that should be simulated to the output std::copy_if( result.generatedParticles.begin(), result.generatedParticles.end(), std::back_inserter(particlesInitial), [this](const Particle &particle) { return selectParticle(particle); }); - std::copy(result.hits.begin(), result.hits.end(), std::back_inserter(hits)); } /// Renumber particle ids in the tail of the container. diff --git a/Fatras/include/ActsFatras/Kernel/detail/SimulationActor.hpp b/Fatras/include/ActsFatras/Kernel/detail/SimulationActor.hpp index cc6d7200868..acbaaaa713d 100644 --- a/Fatras/include/ActsFatras/Kernel/detail/SimulationActor.hpp +++ b/Fatras/include/ActsFatras/Kernel/detail/SimulationActor.hpp @@ -69,7 +69,17 @@ struct SimulationActor { void act(propagator_state_t &state, stepper_t &stepper, navigator_t &navigator, result_type &result, const Acts::Logger &logger) const { - assert(generator && "The generator pointer must be valid"); + assert(generator != nullptr && "The generator pointer must be valid"); + + if (state.stage == Acts::PropagatorStage::prePropagation) { + // first step is special: there is no previous state and we need to arm + // the decay simulation for all future steps. + result.particle = + makeParticle(initialParticle, state, stepper, navigator); + result.properTimeLimit = + decay.generateProperTimeLimit(*generator, initialParticle); + return; + } // actors are called once more after the propagation terminated if (!result.isAlive) { @@ -82,28 +92,11 @@ struct SimulationActor { return; } - // check if we are still on the start surface and skip if so - if ((navigator.startSurface(state.navigation) != nullptr) && - (navigator.startSurface(state.navigation) == - navigator.currentSurface(state.navigation))) { - return; - } - // update the particle state first. this also computes the proper time which // needs the particle state from the previous step for reference. that means // this must happen for every step (not just on surface) and before // everything, e.g. any interactions that could modify the state. - if (std::isnan(result.properTimeLimit)) { - // first step is special: there is no previous state and we need to arm - // the decay simulation for all future steps. - result.particle = - makeParticle(initialParticle, state, stepper, navigator); - result.properTimeLimit = - decay.generateProperTimeLimit(*generator, initialParticle); - } else { - result.particle = - makeParticle(result.particle, state, stepper, navigator); - } + result.particle = makeParticle(result.particle, state, stepper, navigator); // decay check. needs to happen at every step, not just on surfaces. if (std::isfinite(result.properTimeLimit) && diff --git a/Tests/UnitTests/Fatras/Kernel/SimulationActorTests.cpp b/Tests/UnitTests/Fatras/Kernel/SimulationActorTests.cpp index e52d586c30b..3306c5702d6 100644 --- a/Tests/UnitTests/Fatras/Kernel/SimulationActorTests.cpp +++ b/Tests/UnitTests/Fatras/Kernel/SimulationActorTests.cpp @@ -244,7 +244,13 @@ BOOST_AUTO_TEST_CASE(HitsOnEmptySurface) { BOOST_CHECK_EQUAL(f.actor.initialParticle.absoluteMomentum(), f.p); BOOST_CHECK_EQUAL(f.actor.initialParticle.energy(), f.e); + // call.actor: pre propagation + f.state.stage = Acts::PropagatorStage::prePropagation; + f.actor.act(f.state, f.stepper, f.navigator, f.result, + Acts::getDummyLogger()); + // call.actor: surface selection -> one hit, no material -> no secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -271,6 +277,7 @@ BOOST_AUTO_TEST_CASE(HitsOnEmptySurface) { BOOST_CHECK_EQUAL(f.state.stepping.p, f.result.particle.absoluteMomentum()); // call.actor again: one more hit, still no secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -317,7 +324,13 @@ BOOST_AUTO_TEST_CASE(HitsOnMaterialSurface) { BOOST_CHECK_EQUAL(f.actor.initialParticle.absoluteMomentum(), f.p); BOOST_CHECK_EQUAL(f.actor.initialParticle.energy(), f.e); + // call.actor: pre propagation + f.state.stage = Acts::PropagatorStage::prePropagation; + f.actor.act(f.state, f.stepper, f.navigator, f.result, + Acts::getDummyLogger()); + // call.actor: surface selection -> one hit, material -> one secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -346,6 +359,7 @@ BOOST_AUTO_TEST_CASE(HitsOnMaterialSurface) { tol); // call.actor again: one more hit, one more secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -392,7 +406,13 @@ BOOST_AUTO_TEST_CASE(NoHitsEmptySurface) { BOOST_CHECK_EQUAL(f.actor.initialParticle.absoluteMomentum(), f.p); BOOST_CHECK_EQUAL(f.actor.initialParticle.energy(), f.e); + // call.actor: pre propagation + f.state.stage = Acts::PropagatorStage::prePropagation; + f.actor.act(f.state, f.stepper, f.navigator, f.result, + Acts::getDummyLogger()); + // call.actor: no surface sel. -> no hit, no material -> no secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -419,6 +439,7 @@ BOOST_AUTO_TEST_CASE(NoHitsEmptySurface) { BOOST_CHECK_EQUAL(f.state.stepping.p, f.result.particle.absoluteMomentum()); // call.actor again: no hit, still no secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -455,7 +476,13 @@ BOOST_AUTO_TEST_CASE(NoHitsEmptySurface) { BOOST_AUTO_TEST_CASE(NoHitsMaterialSurface) { Fixture f(125_MeV, makeMaterialSurface()); + // call.actor: pre propagation + f.state.stage = Acts::PropagatorStage::prePropagation; + f.actor.act(f.state, f.stepper, f.navigator, f.result, + Acts::getDummyLogger()); + // call.actor: no surface sel. -> no hit, material -> one secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -483,6 +510,7 @@ BOOST_AUTO_TEST_CASE(NoHitsMaterialSurface) { tol); // call.actor again: still no hit, one more secondary + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -523,7 +551,13 @@ BOOST_AUTO_TEST_CASE(Decay) { // inverse Lorentz factor for proper time dilation: 1/gamma = m/E const auto gammaInv = f.m / f.e; + // call.actor: pre propagation + f.state.stage = Acts::PropagatorStage::prePropagation; + f.actor.act(f.state, f.stepper, f.navigator, f.result, + Acts::getDummyLogger()); + // first step w/ defaults leaves particle alive + f.state.stage = Acts::PropagatorStage::postStep; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); BOOST_CHECK(f.result.isAlive); @@ -536,6 +570,7 @@ BOOST_AUTO_TEST_CASE(Decay) { BOOST_CHECK_EQUAL(f.result.particle.properTime(), 0_ns); // second step w/ defaults increases proper time + f.state.stage = Acts::PropagatorStage::postStep; f.state.stepping.time += 1_ns; f.actor.act(f.state, f.stepper, f.navigator, f.result, Acts::getDummyLogger()); @@ -549,6 +584,7 @@ BOOST_AUTO_TEST_CASE(Decay) { CHECK_CLOSE_REL(f.result.particle.properTime(), gammaInv * 1_ns, tol); // third step w/ proper time limit decays the particle + f.state.stage = Acts::PropagatorStage::postStep; f.state.stepping.time += 1_ns; f.result.properTimeLimit = f.result.particle.properTime() + gammaInv * 0.5_ns; f.actor.act(f.state, f.stepper, f.navigator, f.result, From 4643170b29d7724339b9c0cb8d8c3e6adebef1b0 Mon Sep 17 00:00:00 2001 From: Tim Adye Date: Fri, 18 Oct 2024 01:47:42 +0100 Subject: [PATCH 05/14] fix: fix nMeasurements() comment (#3740) comments for mutable and const versions got mixed up. --- Core/include/Acts/EventData/TrackProxy.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Core/include/Acts/EventData/TrackProxy.hpp b/Core/include/Acts/EventData/TrackProxy.hpp index ce674e9cfa4..5939022e2e8 100644 --- a/Core/include/Acts/EventData/TrackProxy.hpp +++ b/Core/include/Acts/EventData/TrackProxy.hpp @@ -324,7 +324,8 @@ class TrackProxy { return std::distance(tsRange.begin(), tsRange.end()); } - /// Return the number of measurements for the track. Const version + /// Return a mutable reference to the number of measurements for the track. + /// Mutable version /// @note Only available if the track proxy is not read-only /// @return The number of measurements unsigned int& nMeasurements() @@ -333,8 +334,7 @@ class TrackProxy { return component(); } - /// Return a mutable reference to the number of measurements for the track. - /// Mutable version + /// Return the number of measurements for the track. Const version /// @return The number of measurements unsigned int nMeasurements() const { return component(); From 66d18541523bb00854ed754d190202b553909f50 Mon Sep 17 00:00:00 2001 From: Tim Adye Date: Fri, 18 Oct 2024 03:23:58 +0100 Subject: [PATCH 06/14] fix: TrackSelector remove broken m_noEtaCuts (#3640) `m_noEtaCuts` wasn't set correctly, and can be removed. Also check that eta-binned cuts don't themselves cut on eta. This was only tested previously in the case of a single bin. Also added `binIndexNoCheck(eta)` which is generally useful and saves having to check `eta` instead of the index. I think it would be better to have `getCuts(eta)` not `throw` but just return the first/last bin, but that would change the API - unless you added a no-`throw` variant. `binIndexNoCheck` at least helps in the meantime. --- .../Acts/TrackFinding/TrackSelector.hpp | 63 ++++++++++--------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/Core/include/Acts/TrackFinding/TrackSelector.hpp b/Core/include/Acts/TrackFinding/TrackSelector.hpp index d0e8526dc35..e782b7feb9d 100644 --- a/Core/include/Acts/TrackFinding/TrackSelector.hpp +++ b/Core/include/Acts/TrackFinding/TrackSelector.hpp @@ -142,7 +142,7 @@ class TrackSelector { std::vector cutSets = {}; /// Eta bin edges for varying cuts by eta - std::vector absEtaEdges = {}; + std::vector absEtaEdges = {0, inf}; /// Get the number of eta bins /// @return Number of eta bins @@ -150,7 +150,7 @@ class TrackSelector { /// Construct an empty (accepts everything) configuration. /// Results in a single cut set and one abs eta bin from 0 to infinity. - EtaBinnedConfig() : cutSets{{}}, absEtaEdges{{0, inf}} {}; + EtaBinnedConfig() : cutSets{{}} {}; /// Constructor to create a config object that is not upper-bounded. /// This is useful to use the "fluent" API to populate the configuration. @@ -163,13 +163,12 @@ class TrackSelector { /// @param absEtaEdgesIn is the vector of eta bin edges EtaBinnedConfig(std::vector absEtaEdgesIn) : absEtaEdges{std::move(absEtaEdgesIn)} { - cutSets.resize(absEtaEdges.size() - 1); + cutSets.resize(nEtaBins()); } /// Auto-converting constructor from a single cut configuration. /// Results in a single absolute eta bin from 0 to infinity. - EtaBinnedConfig(Config cutSet) - : cutSets{std::move(cutSet)}, absEtaEdges{{0, inf}} {} + EtaBinnedConfig(Config cutSet) : cutSets{std::move(cutSet)} {} /// Add a new eta bin with the given upper bound. /// @param etaMax Upper bound of the new eta bin @@ -195,11 +194,17 @@ class TrackSelector { /// @return True if the configuration has a bin for the given eta bool hasCuts(double eta) const; - /// Get the index of the eta bin for a given eta + /// Get the index of the eta bin for a given eta. + /// throws an exception if Eta is outside the abs eta bin edges. /// @param eta Eta value /// @return Index of the eta bin std::size_t binIndex(double eta) const; + /// Get the index of the eta bin for a given eta + /// @param eta Eta value + /// @return Index of the eta bin, or >= nEtaBins() if Eta is outside the abs eta bin edges. + std::size_t binIndexNoCheck(double eta) const; + /// Get the cuts for a given eta /// @param eta Eta value /// @return Cuts for the given eta @@ -237,8 +242,7 @@ class TrackSelector { private: EtaBinnedConfig m_cfg; - bool m_isUnbinned; - bool m_noEtaCuts; + bool m_isUnbinned = false; }; inline TrackSelector::Config& TrackSelector::Config::loc0(double min, @@ -350,14 +354,22 @@ inline bool TrackSelector::EtaBinnedConfig::hasCuts(double eta) const { } inline std::size_t TrackSelector::EtaBinnedConfig::binIndex(double eta) const { - if (!hasCuts(eta)) { + std::size_t index = binIndexNoCheck(eta); + if (!(index < nEtaBins())) { throw std::invalid_argument{"Eta is outside the abs eta bin edges"}; } + return index; +} +inline std::size_t TrackSelector::EtaBinnedConfig::binIndexNoCheck( + double eta) const { auto binIt = std::upper_bound(absEtaEdges.begin(), absEtaEdges.end(), std::abs(eta)); - std::size_t index = std::distance(absEtaEdges.begin(), binIt) - 1; - return index; + std::size_t index = std::distance(absEtaEdges.begin(), binIt); + if (index == 0) { + index = absEtaEdges.size() + 1; // positive value to check for underflow + } + return index - 1; } inline const TrackSelector::Config& TrackSelector::EtaBinnedConfig::getCuts( @@ -428,8 +440,8 @@ bool TrackSelector::isValidTrack(const track_proxy_t& track) const { return track.hasReferenceSurface() && within(track.transverseMomentum(), cuts.ptMin, cuts.ptMax) && - (m_noEtaCuts || (within(absEta(), cuts.absEtaMin, cuts.absEtaMax) && - within(_eta, cuts.etaMin, cuts.etaMax))) && + (!m_isUnbinned || (within(absEta(), cuts.absEtaMin, cuts.absEtaMax) && + within(_eta, cuts.etaMin, cuts.etaMax))) && within(track.phi(), cuts.phiMin, cuts.phiMax) && within(track.loc0(), cuts.loc0Min, cuts.loc0Max) && within(track.loc1(), cuts.loc1Min, cuts.loc1Max) && @@ -452,26 +464,19 @@ inline TrackSelector::TrackSelector( "TrackSelector cut / eta bin configuration is inconsistent"}; } - m_isUnbinned = false; if (m_cfg.nEtaBins() == 1) { static const std::vector infVec = {0, inf}; - bool limitEta = m_cfg.absEtaEdges != infVec; - m_isUnbinned = !limitEta; // single bin, no eta edges given - - const Config& cuts = m_cfg.cutSets[0]; - - if (limitEta && (cuts.etaMin != -inf || cuts.etaMax != inf || - cuts.absEtaMin != 0.0 || cuts.absEtaMax != inf)) { - throw std::invalid_argument{ - "Explicit eta cuts are only valid for single eta bin"}; - } + m_isUnbinned = + m_cfg.absEtaEdges == infVec; // single bin, no eta edges given } - m_noEtaCuts = m_isUnbinned; - for (const auto& cuts : m_cfg.cutSets) { - if (cuts.etaMin != -inf || cuts.etaMax != inf || cuts.absEtaMin != 0.0 || - cuts.absEtaMax != inf) { - m_noEtaCuts = false; + if (!m_isUnbinned) { + for (const auto& cuts : m_cfg.cutSets) { + if (cuts.etaMin != -inf || cuts.etaMax != inf || cuts.absEtaMin != 0.0 || + cuts.absEtaMax != inf) { + throw std::invalid_argument{ + "Explicit eta cuts are only valid for single eta bin"}; + } } } } From fbf332b17bf6f339b5a63fa206cc9b687f439fb7 Mon Sep 17 00:00:00 2001 From: "Alexander J. Pfleger" <70842573+AJPfleger@users.noreply.github.com> Date: Fri, 18 Oct 2024 05:53:07 +0200 Subject: [PATCH 07/14] refactor: explicit `hasStackTraces()` in FPE (#3727) Also fixes a typo --- .../Framework/src/Framework/Sequencer.cpp | 2 +- .../Acts/Plugins/FpeMonitoring/FpeMonitor.hpp | 6 ++-- Plugins/FpeMonitoring/src/FpeMonitor.cpp | 34 +++++++++---------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Examples/Framework/src/Framework/Sequencer.cpp b/Examples/Framework/src/Framework/Sequencer.cpp index 78444c58ac4..f6bb69d44c0 100644 --- a/Examples/Framework/src/Framework/Sequencer.cpp +++ b/Examples/Framework/src/Framework/Sequencer.cpp @@ -611,7 +611,7 @@ void Sequencer::fpeReport() const { auto merged = std::accumulate( fpe.begin(), fpe.end(), Acts::FpeMonitor::Result{}, [](const auto& lhs, const auto& rhs) { return lhs.merged(rhs); }); - if (!merged) { + if (!merged.hasStackTraces()) { // no FPEs to report continue; } diff --git a/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp b/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp index d1b9fabec64..022a07a3426 100644 --- a/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp +++ b/Plugins/FpeMonitoring/include/Acts/Plugins/FpeMonitoring/FpeMonitor.hpp @@ -40,7 +40,7 @@ std::ostream &operator<<(std::ostream &os, FpeType type); class FpeMonitor { public: struct Buffer { - Buffer(std::size_t bufferSize) + explicit Buffer(std::size_t bufferSize) : m_data{std::make_unique(bufferSize)}, m_size{bufferSize} {} @@ -105,12 +105,12 @@ class FpeMonitor { Result() = default; - operator bool() const { return !m_stracktraces.empty(); } + bool hasStackTraces() const { return !m_stackTraces.empty(); } void add(Acts::FpeType type, void *stackPtr, std::size_t bufferSize); private: - std::vector m_stracktraces; + std::vector m_stackTraces; std::array m_counts{}; friend FpeMonitor; diff --git a/Plugins/FpeMonitoring/src/FpeMonitor.cpp b/Plugins/FpeMonitoring/src/FpeMonitor.cpp index db41dc1f8b2..09dce1f4b0a 100644 --- a/Plugins/FpeMonitoring/src/FpeMonitor.cpp +++ b/Plugins/FpeMonitoring/src/FpeMonitor.cpp @@ -61,10 +61,10 @@ FpeMonitor::Result FpeMonitor::Result::merged(const Result &with) const { result.m_counts[i] = m_counts[i] + with.m_counts[i]; } - std::copy(with.m_stracktraces.begin(), with.m_stracktraces.end(), - std::back_inserter(result.m_stracktraces)); - std::copy(m_stracktraces.begin(), m_stracktraces.end(), - std::back_inserter(result.m_stracktraces)); + std::copy(with.m_stackTraces.begin(), with.m_stackTraces.end(), + std::back_inserter(result.m_stackTraces)); + std::copy(m_stackTraces.begin(), m_stackTraces.end(), + std::back_inserter(result.m_stackTraces)); result.deduplicate(); @@ -76,8 +76,8 @@ void FpeMonitor::Result::merge(const Result &with) { m_counts[i] = m_counts[i] + with.m_counts[i]; } - std::copy(with.m_stracktraces.begin(), with.m_stracktraces.end(), - std::back_inserter(m_stracktraces)); + std::copy(with.m_stackTraces.begin(), with.m_stackTraces.end(), + std::back_inserter(m_stackTraces)); deduplicate(); } @@ -87,20 +87,20 @@ void FpeMonitor::Result::add(FpeType type, void *stackPtr, auto st = std::make_unique( boost::stacktrace::stacktrace::from_dump(stackPtr, bufferSize)); - auto it = std::ranges::find_if(m_stracktraces, [&](const FpeInfo &el) { + auto it = std::ranges::find_if(m_stackTraces, [&](const FpeInfo &el) { return areFpesEquivalent({el.type, *el.st}, {type, *st}); }); - if (it != m_stracktraces.end()) { + if (it != m_stackTraces.end()) { it->count += 1; } else { - m_stracktraces.push_back({1, type, std::move(st)}); + m_stackTraces.push_back({1, type, std::move(st)}); } } bool FpeMonitor::Result::contains( FpeType type, const boost::stacktrace::stacktrace &st) const { - return std::ranges::any_of(m_stracktraces, [&](const FpeInfo &el) { + return std::ranges::any_of(m_stackTraces, [&](const FpeInfo &el) { return areFpesEquivalent({el.type, *el.st}, {type, st}); }); } @@ -128,12 +128,12 @@ unsigned int FpeMonitor::Result::count(FpeType type) const { } unsigned int FpeMonitor::Result::numStackTraces() const { - return m_stracktraces.size(); + return m_stackTraces.size(); } const std::vector & FpeMonitor::Result::stackTraces() const { - return m_stracktraces; + return m_stackTraces; } bool FpeMonitor::Result::encountered(FpeType type) const { @@ -161,18 +161,18 @@ void FpeMonitor::Result::summary(std::ostream &os, std::size_t depth) const { void FpeMonitor::Result::deduplicate() { std::vector copy{}; - copy = std::move(m_stracktraces); - m_stracktraces.clear(); + copy = std::move(m_stackTraces); + m_stackTraces.clear(); for (auto &info : copy) { - auto it = std::ranges::find_if(m_stracktraces, [&info](const FpeInfo &el) { + auto it = std::ranges::find_if(m_stackTraces, [&info](const FpeInfo &el) { return areFpesEquivalent({el.type, *el.st}, {info.type, *info.st}); }); - if (it != m_stracktraces.end()) { + if (it != m_stackTraces.end()) { it->count += info.count; continue; } - m_stracktraces.push_back({info.count, info.type, std::move(info.st)}); + m_stackTraces.push_back({info.count, info.type, std::move(info.st)}); } } From c06a60ad4407f30d1121868e8d35cd945b79c11c Mon Sep 17 00:00:00 2001 From: ssdetlab <113530373+ssdetlab@users.noreply.github.com> Date: Fri, 18 Oct 2024 09:59:30 +0300 Subject: [PATCH 08/14] feat: Track parameters json converter (#3724) Adding json converter for the different track parameters types. The converter follows the pattern outlined in [nlohmann::json documentation](https://json.nlohmann.me/features/arbitrary_types/#how-can-i-use-get-for-non-default-constructiblenon-copyable-types), rather than the one present in the codebase due to the a) track parameters types not being default constructible, b) use cases connected to the grid-of-of-track-parameters conversion. To keep the converter to one implementation of the json serializer, the liberty was taken to add one more constructor to the `FreeTrackParameters`. The `GridJsonConverter` code was modified a bit to be able to handle non-default constructible types. Header for the track parameters json converter in `GridJsonConverter.hpp` is required for the grid-of-of-track-parameters conversion to be possible by the `nlohmann::json` standard. As a side note, all the types in the framework that have `to_json`/`from_json` overloaded can have grid-of-type json conversion implemented for free, if the respective headers are added to the `GridJsonConverter.hpp`. --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../EventData/GenericFreeTrackParameters.hpp | 28 ++- .../Acts/Plugins/Json/GridJsonConverter.hpp | 11 +- .../Json/TrackParametersJsonConverter.hpp | 221 ++++++++++++++++++ Tests/UnitTests/Plugins/Json/CMakeLists.txt | 1 + .../TrackParametersJsonConverterTests.cpp | 97 ++++++++ 5 files changed, 352 insertions(+), 6 deletions(-) create mode 100644 Plugins/Json/include/Acts/Plugins/Json/TrackParametersJsonConverter.hpp create mode 100644 Tests/UnitTests/Plugins/Json/TrackParametersJsonConverterTests.cpp diff --git a/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp b/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp index 857d6c328b9..214aa2e1551 100644 --- a/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp +++ b/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp @@ -16,6 +16,7 @@ #include "Acts/EventData/detail/PrintParameters.hpp" #include "Acts/Utilities/MathHelpers.hpp" #include "Acts/Utilities/UnitVectors.hpp" +#include "Acts/Utilities/VectorHelpers.hpp" #include #include @@ -56,6 +57,29 @@ class GenericFreeTrackParameters { m_cov(std::move(cov)), m_particleHypothesis(std::move(particleHypothesis)) {} + /// Construct from four-position, direction, absolute momentum, and charge. + /// + /// @param pos4 Track position/time four-vector + /// @param dir Track direction three-vector; normalization is ignored. + /// @param qOverP Charge over momentum + /// @param cov Free parameters covariance matrix + /// @param particleHypothesis Particle hypothesis + GenericFreeTrackParameters(const Vector4& pos4, const Vector3& dir, + Scalar qOverP, std::optional cov, + ParticleHypothesis particleHypothesis) + : m_params(FreeVector::Zero()), + m_cov(std::move(cov)), + m_particleHypothesis(std::move(particleHypothesis)) { + m_params[eFreePos0] = pos4[ePos0]; + m_params[eFreePos1] = pos4[ePos1]; + m_params[eFreePos2] = pos4[ePos2]; + m_params[eFreeTime] = pos4[eTime]; + m_params[eFreeDir0] = dir[eMom0]; + m_params[eFreeDir1] = dir[eMom1]; + m_params[eFreeDir2] = dir[eMom2]; + m_params[eFreeQOverP] = qOverP; + } + /// Construct from four-position, angles, absolute momentum, and charge. /// /// @param pos4 Track position/time four-vector @@ -136,9 +160,9 @@ class GenericFreeTrackParameters { Scalar time() const { return m_params[eFreeTime]; } /// Phi direction. - Scalar phi() const { return phi(direction()); } + Scalar phi() const { return VectorHelpers::phi(direction()); } /// Theta direction. - Scalar theta() const { return theta(direction()); } + Scalar theta() const { return VectorHelpers::theta(direction()); } /// Charge over momentum. Scalar qOverP() const { return m_params[eFreeQOverP]; } diff --git a/Plugins/Json/include/Acts/Plugins/Json/GridJsonConverter.hpp b/Plugins/Json/include/Acts/Plugins/Json/GridJsonConverter.hpp index 20065d488bb..3215bd66eae 100644 --- a/Plugins/Json/include/Acts/Plugins/Json/GridJsonConverter.hpp +++ b/Plugins/Json/include/Acts/Plugins/Json/GridJsonConverter.hpp @@ -9,6 +9,7 @@ #pragma once #include "Acts/Plugins/Json/ActsJson.hpp" +#include "Acts/Plugins/Json/TrackParametersJsonConverter.hpp" #include "Acts/Utilities/AxisFwd.hpp" #include "Acts/Utilities/GridAccessHelpers.hpp" #include "Acts/Utilities/IAxis.hpp" @@ -266,15 +267,17 @@ auto fromJson(const nlohmann::json& jGrid, if constexpr (GridType::DIM == 1u) { for (const auto& jd : jData) { std::array lbin = jd[0u]; - value_type values = jd[1u]; - grid.atLocalBins(lbin) = values; + if (!jd[1u].is_null()) { + grid.atLocalBins(lbin) = jd[1u].get(); + } } } if constexpr (GridType::DIM == 2u) { for (const auto& jd : jData) { std::array lbin = jd[0u]; - value_type values = jd[1u]; - grid.atLocalBins(lbin) = values; + if (!jd[1u].is_null()) { + grid.atLocalBins(lbin) = jd[1u].get(); + } } } return grid; diff --git a/Plugins/Json/include/Acts/Plugins/Json/TrackParametersJsonConverter.hpp b/Plugins/Json/include/Acts/Plugins/Json/TrackParametersJsonConverter.hpp new file mode 100644 index 00000000000..ebf7d5c6054 --- /dev/null +++ b/Plugins/Json/include/Acts/Plugins/Json/TrackParametersJsonConverter.hpp @@ -0,0 +1,221 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/. + +#pragma once + +#include "Acts/EventData/TrackParameters.hpp" +#include "Acts/Plugins/Json/ActsJson.hpp" +#include "Acts/Plugins/Json/SurfaceJsonConverter.hpp" + +#include + +namespace { + +// Alias to bound adl_serializer specialization +// only to track parameters +template +concept TrackParameters = Acts::FreeTrackParametersConcept || + Acts::BoundTrackParametersConcept; + +// Shorthand for bound track parameters +template +concept IsGenericBound = + std::same_as>; + +} // namespace + +namespace Acts { +NLOHMANN_JSON_SERIALIZE_ENUM(Acts::PdgParticle, + + {{Acts::PdgParticle::eInvalid, "Invalid"}, + {Acts::PdgParticle::eElectron, "Electron"}, + {Acts::PdgParticle::eAntiElectron, + "AntiElectron"}, + {Acts::PdgParticle::ePositron, "Positron"}, + {Acts::PdgParticle::eMuon, "Muon"}, + {Acts::PdgParticle::eAntiMuon, "AntiMuon"}, + {Acts::PdgParticle::eTau, "Tau"}, + {Acts::PdgParticle::eAntiTau, "AntiTau"}, + {Acts::PdgParticle::eGamma, "Gamma"}, + {Acts::PdgParticle::ePionZero, "PionZero"}, + {Acts::PdgParticle::ePionPlus, "PionPlus"}, + {Acts::PdgParticle::ePionMinus, "PionMinus"}, + {Acts::PdgParticle::eKaonPlus, "KaonPlus"}, + {Acts::PdgParticle::eKaonMinus, "KaonMinus"}, + {Acts::PdgParticle::eNeutron, "Neutron"}, + {Acts::PdgParticle::eAntiNeutron, "AntiNeutron"}, + {Acts::PdgParticle::eProton, "Proton"}, + {Acts::PdgParticle::eAntiProton, "AntiProton"}, + {Acts::PdgParticle::eLead, "Lead"}} + +) +} + +namespace nlohmann { + +/// @brief Serialize a track parameters object to json +/// +/// nlohmann::json serializer specialized for track parameters +/// as they are not default constructible. Is able to serialize +/// either bound or free track parameters given that the constructor +/// convention is followed. +/// +/// @tparam parameters_t The track parameters type +template +struct adl_serializer { + /// Covariance matrix type attached to the parameters + using CovarianceMatrix = typename parameters_t::CovarianceMatrix; + + /// @brief Serialize track parameters object to json + /// + /// @param j Json object to write to + /// @param t Track parameters object to serialize + static void to_json(nlohmann::json& j, const parameters_t& t) { + // Serialize parameters + // common to all track parameters + j["direction"] = t.direction(); + j["qOverP"] = t.qOverP(); + j["particleHypothesis"] = t.particleHypothesis().absolutePdg(); + + // Covariance is optional + j["covariance"]; + if (t.covariance().has_value()) { + // Extract covariance matrix + // parameters and serialize + auto cov = t.covariance().value(); + constexpr unsigned int size = cov.rows(); + std::array covData{}; + for (std::size_t n = 0; n < size; ++n) { + for (std::size_t m = 0; m < size; ++m) { + covData[n * size + m] = cov(n, m); + } + } + j["covariance"] = covData; + } + // Bound track parameters have + // reference surface attached + // and position takes a geometry context + if constexpr (IsGenericBound) { + Acts::GeometryContext gctx; + j["position"] = t.fourPosition(gctx); + + j["referenceSurface"] = + Acts::SurfaceJsonConverter::toJson(gctx, t.referenceSurface()); + } else { + j["position"] = t.fourPosition(); + } + } + + /// @brief Deserialize track parameters object from json + /// + /// @param j Json object to read from + /// @return Track parameters object + static parameters_t from_json(const nlohmann::json& j) { + // Extract common parameters + std::array posData = j.at("position"); + Acts::Vector4 position(posData[0], posData[1], posData[2], posData[3]); + + std::array dirData = j.at("direction"); + Acts::Vector3 direction(dirData[0], dirData[1], dirData[2]); + + Acts::ActsScalar qOverP = j.at("qOverP"); + Acts::PdgParticle absPdg = j.at("particleHypothesis"); + + // Covariance is optional + std::optional cov; + if (j.at("covariance").is_null()) { + cov = std::nullopt; + } else { + // Extract covariance matrix + // parameters and deserialize + CovarianceMatrix mat; + constexpr unsigned int size = mat.rows(); + std::array covData = j.at("covariance"); + for (std::size_t n = 0; n < size; ++n) { + for (std::size_t m = 0; m < size; ++m) { + mat(n, m) = covData[n * size + m]; + } + } + cov.emplace(std::move(mat)); + } + + // Create particle hypothesis + typename parameters_t::ParticleHypothesis particle(absPdg); + + // Bound track parameters have + // reference surface attached + // and constructor is hidden + // behind a factory method + if constexpr (IsGenericBound) { + Acts::GeometryContext gctx; + auto referenceSurface = + Acts::SurfaceJsonConverter::fromJson(j.at("referenceSurface")); + + auto res = parameters_t::create(referenceSurface, gctx, position, + direction, qOverP, cov, particle); + + if (!res.ok()) { + throw std::invalid_argument("Invalid bound track parameters"); + } + return res.value(); + } else { + return parameters_t(position, direction, qOverP, cov, particle); + } + } +}; + +/// @brief Serialize a shared pointer to track parameters object to json +/// +/// nlohmann::json serializer specialized for shared pointers to track +/// parameters as they are not default constructible. Is able to serialize +/// either bound or free track parameters given that the constructor +/// convention is followed. +/// +/// @tparam parameters_t The track parameters type +template +struct adl_serializer> { + using CovarianceMatrix = typename parameters_t::CovarianceMatrix; + static void to_json(nlohmann::json& j, + const std::shared_ptr& t) { + if (t == nullptr) { + return; + } + j = *t; + } + + static std::shared_ptr from_json(const nlohmann::json& j) { + return std::make_shared(j.get()); + } +}; + +/// @brief Serialize a unique pointer to track parameters object to json +/// +/// nlohmann::json serializer specialized for unique pointers to track +/// parameters as they are not default constructible. Is able to serialize +/// either bound or free track parameters given that the constructor +/// convention is followed. +/// +/// @tparam parameters_t The track parameters type +template +struct adl_serializer> { + using CovarianceMatrix = typename parameters_t::CovarianceMatrix; + static void to_json(nlohmann::json& j, + const std::unique_ptr& t) { + if (t == nullptr) { + return; + } + j = *t; + } + + static std::unique_ptr from_json(const nlohmann::json& j) { + return std::make_unique(j.get()); + } +}; + +} // namespace nlohmann diff --git a/Tests/UnitTests/Plugins/Json/CMakeLists.txt b/Tests/UnitTests/Plugins/Json/CMakeLists.txt index 1f8573fdf50..141f86fb3fe 100644 --- a/Tests/UnitTests/Plugins/Json/CMakeLists.txt +++ b/Tests/UnitTests/Plugins/Json/CMakeLists.txt @@ -15,3 +15,4 @@ add_unittest(UtilitiesJsonConverter UtilitiesJsonConverterTests.cpp) add_unittest(SurfaceBoundsJsonConverter SurfaceBoundsJsonConverterTests.cpp) add_unittest(SurfaceJsonConverter SurfaceJsonConverterTests.cpp) add_unittest(VolumeBoundsJsonConverter VolumeBoundsJsonConverterTests.cpp) +add_unittest(TrackParametersJsonConverter TrackParametersJsonConverterTests.cpp) diff --git a/Tests/UnitTests/Plugins/Json/TrackParametersJsonConverterTests.cpp b/Tests/UnitTests/Plugins/Json/TrackParametersJsonConverterTests.cpp new file mode 100644 index 00000000000..566464a1889 --- /dev/null +++ b/Tests/UnitTests/Plugins/Json/TrackParametersJsonConverterTests.cpp @@ -0,0 +1,97 @@ +// This file is part of the ACTS project. +// +// Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/. + +#include + +#include "Acts/Plugins/Json/TrackParametersJsonConverter.hpp" +#include "Acts/Surfaces/PlaneSurface.hpp" +#include "Acts/Surfaces/RectangleBounds.hpp" +#include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" + +#include +#include + +#include + +BOOST_AUTO_TEST_SUITE(TrackParametersJsonIO) + +BOOST_AUTO_TEST_CASE(TrackParametersJsonIO) { + Acts::GeometryContext gctx; + + // Track parameters + Acts::Vector4 position(1., 2., 3., 4.); + Acts::ActsScalar phi = 0.1; + Acts::ActsScalar theta = 0.2; + Acts::ActsScalar qOverP = 3.0; + Acts::ParticleHypothesis particle = Acts::ParticleHypothesis::electron(); + Acts::FreeMatrix freeCov = Acts::FreeMatrix::Identity(); + Acts::BoundMatrix boundCov = Acts::BoundMatrix::Identity(); + + auto surface = Acts::Surface::makeShared( + Acts::Transform3::Identity(), + std::make_shared(10., 10.)); + surface->assignGeometryId(Acts::GeometryIdentifier(1u)); + + // Free track parameters conversion + Acts::FreeTrackParameters ftp(position, phi, theta, qOverP, freeCov, + particle); + + nlohmann::json ftpJson = ftp; + + Acts::FreeTrackParameters ftpRead = ftpJson; + + BOOST_CHECK_EQUAL(ftp.position(), ftpRead.position()); + BOOST_CHECK_EQUAL(ftp.direction(), ftpRead.direction()); + BOOST_CHECK_EQUAL(ftp.qOverP(), ftpRead.qOverP()); + BOOST_CHECK_EQUAL(ftp.covariance().value(), ftpRead.covariance().value()); + BOOST_CHECK_EQUAL(ftp.particleHypothesis(), ftpRead.particleHypothesis()); + + // Curvilinear track parameters conversion + Acts::CurvilinearTrackParameters ctp(position, phi, theta, qOverP, boundCov, + particle); + + nlohmann::json ctpJson = ctp; + + Acts::CurvilinearTrackParameters ctpRead = ctpJson; + + BOOST_CHECK_EQUAL(ctp.position(), ctpRead.position()); + BOOST_CHECK_EQUAL(ctp.direction(), ctpRead.direction()); + BOOST_CHECK_EQUAL(ctp.qOverP(), ctpRead.qOverP()); + BOOST_CHECK_EQUAL(ctp.covariance().value(), ctpRead.covariance().value()); + BOOST_CHECK_EQUAL(ctp.particleHypothesis(), ctpRead.particleHypothesis()); + + BOOST_CHECK(ctp.referenceSurface().transform(gctx).isApprox( + ctpRead.referenceSurface().transform(gctx))); + BOOST_CHECK_EQUAL(ctp.referenceSurface().geometryId(), + ctpRead.referenceSurface().geometryId()); + BOOST_CHECK_EQUAL(ctp.referenceSurface().bounds(), + ctpRead.referenceSurface().bounds()); + + // Bound track parameters conversion + Acts::BoundVector boundPosition{1., 2., 3., 4., 5., 6.}; + Acts::BoundTrackParameters btp(surface, boundPosition, boundCov, particle); + + nlohmann::json btpJson = btp; + + Acts::BoundTrackParameters btpRead = btpJson; + + BOOST_CHECK_EQUAL(btp.position(gctx), btpRead.position(gctx)); + BOOST_CHECK_EQUAL(btp.direction(), btpRead.direction()); + BOOST_CHECK_EQUAL(btp.qOverP(), btpRead.qOverP()); + BOOST_CHECK_EQUAL(btp.covariance().value(), btpRead.covariance().value()); + BOOST_CHECK_EQUAL(btp.particleHypothesis(), btpRead.particleHypothesis()); + + BOOST_CHECK(btp.referenceSurface().transform(gctx).isApprox( + btpRead.referenceSurface().transform(gctx))); + BOOST_CHECK_EQUAL(btp.referenceSurface().geometryId(), + btpRead.referenceSurface().geometryId()); + BOOST_CHECK_EQUAL(btp.referenceSurface().bounds(), + btpRead.referenceSurface().bounds()); +} + +BOOST_AUTO_TEST_SUITE_END() From 41066dc3e90520693fe52baafe494a46e62169db Mon Sep 17 00:00:00 2001 From: Benjamin Huth <37871400+benjaminhuth@users.noreply.github.com> Date: Fri, 18 Oct 2024 10:32:29 +0200 Subject: [PATCH 09/14] feat: Make it possible to turn off warnings in GSF (#3739) This adds an option that should disable the warnings appearing in the GSF in a meaningful way... Worksaround but does not solve #3738 --- .../Acts/TrackFitting/BetheHeitlerApprox.hpp | 31 +++++++++++++++---- Core/src/TrackFitting/BetheHeitlerApprox.cpp | 8 +++-- .../python/acts/examples/reconstruction.py | 7 ++++- Examples/Python/src/TrackFitting.cpp | 18 +++++++---- Examples/Python/tests/root_file_hashes.txt | 8 ++--- Examples/Python/tests/test_examples.py | 2 +- .../Python/truth_tracking_gsf_refitting.py | 7 ++++- 7 files changed, 59 insertions(+), 22 deletions(-) diff --git a/Core/include/Acts/TrackFitting/BetheHeitlerApprox.hpp b/Core/include/Acts/TrackFitting/BetheHeitlerApprox.hpp index 653bef7e899..666ebf6aa23 100644 --- a/Core/include/Acts/TrackFitting/BetheHeitlerApprox.hpp +++ b/Core/include/Acts/TrackFitting/BetheHeitlerApprox.hpp @@ -125,6 +125,7 @@ class AtlasBetheHeitlerApprox { constexpr static double m_singleGaussianLimit = 0.002; double m_lowLimit = 0.10; double m_highLimit = 0.20; + bool m_clampToRange = false; public: /// Construct the Bethe-Heitler approximation description with two @@ -138,16 +139,19 @@ class AtlasBetheHeitlerApprox { /// @param highTransform whether the high data need to be transformed /// @param lowLimit the upper limit for the low data /// @param highLimit the upper limit for the high data + /// @param clampToRange whether to clamp the input x/x0 to the allowed range constexpr AtlasBetheHeitlerApprox(const Data &lowData, const Data &highData, bool lowTransform, bool highTransform, double lowLimit = 0.1, - double highLimit = 0.2) + double highLimit = 0.2, + bool clampToRange = false) : m_lowData(lowData), m_highData(highData), m_lowTransform(lowTransform), m_highTransform(highTransform), m_lowLimit(lowLimit), - m_highLimit(highLimit) {} + m_highLimit(highLimit), + m_clampToRange(clampToRange) {} /// Returns the number of components the returned mixture will have constexpr auto numComponents() const { return NComponents; } @@ -155,7 +159,13 @@ class AtlasBetheHeitlerApprox { /// Checks if an input is valid for the parameterization /// /// @param x pathlength in terms of the radiation length - constexpr bool validXOverX0(ActsScalar x) const { return x < m_highLimit; } + constexpr bool validXOverX0(ActsScalar x) const { + if (m_clampToRange) { + return true; + } else { + return x < m_highLimit; + } + } /// Generates the mixture from the polynomials and reweights them, so /// that the sum of all weights is 1 @@ -164,6 +174,11 @@ class AtlasBetheHeitlerApprox { auto mixture(ActsScalar x) const { using Array = boost::container::static_vector; + + if (m_clampToRange) { + x = std::clamp(x, 0.0, m_highLimit); + } + // Build a polynom auto poly = [](ActsScalar xx, const std::array &coeffs) { @@ -238,9 +253,11 @@ class AtlasBetheHeitlerApprox { /// the parameterization for high x/x0 /// @param lowLimit the upper limit for the low x/x0-data /// @param highLimit the upper limit for the high x/x0-data + /// @param clampToRange forwarded to constructor static auto loadFromFiles(const std::string &low_parameters_path, const std::string &high_parameters_path, - double lowLimit = 0.1, double highLimit = 0.2) { + double lowLimit = 0.1, double highLimit = 0.2, + bool clampToRange = false) { auto read_file = [](const std::string &filepath) { std::ifstream file(filepath); @@ -284,7 +301,8 @@ class AtlasBetheHeitlerApprox { const auto [highData, highTransform] = read_file(high_parameters_path); return AtlasBetheHeitlerApprox(lowData, highData, lowTransform, - highTransform, lowLimit, highLimit); + highTransform, lowLimit, highLimit, + clampToRange); } }; @@ -292,6 +310,7 @@ class AtlasBetheHeitlerApprox { /// configuration, that are stored as static data in the source code. /// This may not be an optimal configuration, but should allow to run /// the GSF without the need to load files -AtlasBetheHeitlerApprox<6, 5> makeDefaultBetheHeitlerApprox(); +AtlasBetheHeitlerApprox<6, 5> makeDefaultBetheHeitlerApprox( + bool clampToRange = false); } // namespace Acts diff --git a/Core/src/TrackFitting/BetheHeitlerApprox.cpp b/Core/src/TrackFitting/BetheHeitlerApprox.cpp index b19b9921902..272d6e08c8d 100644 --- a/Core/src/TrackFitting/BetheHeitlerApprox.cpp +++ b/Core/src/TrackFitting/BetheHeitlerApprox.cpp @@ -8,7 +8,8 @@ #include "Acts/TrackFitting/BetheHeitlerApprox.hpp" -Acts::AtlasBetheHeitlerApprox<6, 5> Acts::makeDefaultBetheHeitlerApprox() { +Acts::AtlasBetheHeitlerApprox<6, 5> Acts::makeDefaultBetheHeitlerApprox( + bool clampToRange) { // Tracking/TrkFitter/TrkGaussianSumFilterUtils/Data/BetheHeitler_cdf_nC6_O5.par // clang-format off constexpr static AtlasBetheHeitlerApprox<6, 5>::Data cdf_cmps6_order5_data = {{ @@ -51,6 +52,7 @@ Acts::AtlasBetheHeitlerApprox<6, 5> Acts::makeDefaultBetheHeitlerApprox() { }}; // clang-format on - return AtlasBetheHeitlerApprox<6, 5>( - cdf_cmps6_order5_data, cdf_cmps6_order5_data, true, true, 0.2, 0.2); + return AtlasBetheHeitlerApprox<6, 5>(cdf_cmps6_order5_data, + cdf_cmps6_order5_data, true, true, 0.2, + 0.2, clampToRange); } diff --git a/Examples/Python/python/acts/examples/reconstruction.py b/Examples/Python/python/acts/examples/reconstruction.py index 3bb898ca998..371345a17b5 100644 --- a/Examples/Python/python/acts/examples/reconstruction.py +++ b/Examples/Python/python/acts/examples/reconstruction.py @@ -1375,8 +1375,13 @@ def addTruthTrackingGsf( ) -> None: customLogLevel = acts.examples.defaultLogging(s, logLevel) + # NOTE we specify clampToRange as True to silence warnings in the test about + # queries to the loss distribution outside the specified range, since no dedicated + # approximation for the ODD is done yet. + bha = acts.examples.AtlasBetheHeitlerApprox.makeDefault(clampToRange=True) + gsfOptions = { - "betheHeitlerApprox": acts.examples.AtlasBetheHeitlerApprox.makeDefault(), + "betheHeitlerApprox": bha, "maxComponents": 12, "componentMergeMethod": acts.examples.ComponentMergeMethod.maxWeight, "mixtureReductionAlgorithm": acts.examples.MixtureReductionAlgorithm.KLDistance, diff --git a/Examples/Python/src/TrackFitting.cpp b/Examples/Python/src/TrackFitting.cpp index 20c6010c8ee..c8dc72f9eef 100644 --- a/Examples/Python/src/TrackFitting.cpp +++ b/Examples/Python/src/TrackFitting.cpp @@ -39,6 +39,7 @@ namespace py = pybind11; using namespace ActsExamples; using namespace Acts; +using namespace py::literals; namespace Acts::Python { @@ -106,12 +107,17 @@ void addTrackFitting(Context& ctx) { .value("KLDistance", MixtureReductionAlgorithm::KLDistance); py::class_(mex, "AtlasBetheHeitlerApprox") - .def_static("loadFromFiles", - &ActsExamples::BetheHeitlerApprox::loadFromFiles, - py::arg("lowParametersPath"), py::arg("highParametersPath"), - py::arg("lowLimit") = 0.1, py::arg("highLimit") = 0.2) - .def_static("makeDefault", - []() { return Acts::makeDefaultBetheHeitlerApprox(); }); + .def_static( + "loadFromFiles", &ActsExamples::BetheHeitlerApprox::loadFromFiles, + "lowParametersPath"_a, "highParametersPath"_a, "lowLimit"_a = 0.1, + "highLimit"_a = 0.2, "clampToRange"_a = false) + .def_static( + "makeDefault", + [](bool clampToRange) { + return Acts::makeDefaultBetheHeitlerApprox(clampToRange); + }, + "clampToRange"_a = false); + mex.def( "makeGsfFitterFunction", [](std::shared_ptr trackingGeometry, diff --git a/Examples/Python/tests/root_file_hashes.txt b/Examples/Python/tests/root_file_hashes.txt index 39df454b3e8..54c81ea9ba1 100644 --- a/Examples/Python/tests/root_file_hashes.txt +++ b/Examples/Python/tests/root_file_hashes.txt @@ -74,10 +74,10 @@ test_exatrkx[cpu-torch]__performance_track_finding.root: 36b3045589c4c17c038dbc8 test_exatrkx[gpu-onnx]__performance_track_finding.root: 9090de10ffb1489d3f1993e2a3081a3038227e3e5c453e98a9a4f33ea3d6d817 test_exatrkx[gpu-torch]__performance_track_finding.root: 36b3045589c4c17c038dbc87943366f4af4440f7eea6887afb763871ac149b05 test_ML_Ambiguity_Solver__performance_ambiML.root: 284ff5c3a08c0b810938e4ac2f8ba8fe2babb17d4c202b624ed69fff731a9006 -test_refitting[odd]__trackstates_gsf_refit.root: a61fe2d80d5d10d3b3505000e8abb589d88302bf5f54b625948793418f2a7fe8 -test_refitting[odd]__tracksummary_gsf_refit.root: 082789fc1a85e578b3cf9a750723d2dcee01b5019e871c6a63e0b271f4e907b1 -test_refitting[generic]__trackstates_gsf_refit.root: 9fa7af9eff12081504c0d648f6debae64f6996e0ca610cf58187d23aa5a13251 -test_refitting[generic]__tracksummary_gsf_refit.root: 35b5ac6f208cae093fff94038d217a2e9915a5ce075da2a95718dda696f2d4a2 +test_refitting[odd]__trackstates_gsf_refit.root: e297749dc1e7eda3b8dea13defa0499986c584740d93e723a901b498b8e90c71 +test_refitting[odd]__tracksummary_gsf_refit.root: d5085882e45a0b699194dff9f40a36e9291227bf65f9aaaf9087f9242ef5ae22 +test_refitting[generic]__trackstates_gsf_refit.root: 4424fdf2f27575db825c1a59f8e53a1595946211cbd5b2c8d3a2f71cdcc77ae9 +test_refitting[generic]__tracksummary_gsf_refit.root: 562deecee4cfb97ceee72eff53d63da079e3249fb62d6bcd556e6f27d495dfd9 test_truth_tracking_kalman[generic-False-0.0]__trackstates_kf.root: 9f77962b92037cb760b1629a602b1dae61f45e659c45d9a87baa784f6190960e test_truth_tracking_kalman[generic-False-0.0]__tracksummary_kf.root: 562deecee4cfb97ceee72eff53d63da079e3249fb62d6bcd556e6f27d495dfd9 test_truth_tracking_kalman[generic-False-1000.0]__trackstates_kf.root: 56a1bd989b9c1316b9098c65fa75df9e6683e62e35ae68d8f72d27220be0fd7d diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index 0e34a8a3c1c..d5bb593ca9f 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -689,7 +689,7 @@ def test_refitting(tmp_path, detector_config, assert_root_hash): field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T)) seq = Sequencer( - events=3, + events=10, numThreads=1, ) diff --git a/Examples/Scripts/Python/truth_tracking_gsf_refitting.py b/Examples/Scripts/Python/truth_tracking_gsf_refitting.py index 797bfc59569..e8b41c9aae8 100755 --- a/Examples/Scripts/Python/truth_tracking_gsf_refitting.py +++ b/Examples/Scripts/Python/truth_tracking_gsf_refitting.py @@ -25,8 +25,13 @@ def runRefittingGsf( s=s, ) + # NOTE we specify clampToRange as True to silence warnings in the test about + # queries to the loss distribution outside the specified range, since no dedicated + # approximation for the ODD is done yet. + bha = acts.examples.AtlasBetheHeitlerApprox.makeDefault(clampToRange=True) + gsfOptions = { - "betheHeitlerApprox": acts.examples.AtlasBetheHeitlerApprox.makeDefault(), + "betheHeitlerApprox": bha, "maxComponents": 12, "componentMergeMethod": acts.examples.ComponentMergeMethod.maxWeight, "mixtureReductionAlgorithm": acts.examples.MixtureReductionAlgorithm.KLDistance, From 3fadd3eb572b08b074db49480a040b77675780b1 Mon Sep 17 00:00:00 2001 From: Paul Gessinger Date: Fri, 18 Oct 2024 12:57:16 +0200 Subject: [PATCH 10/14] fix: Don't use `mp.get_context("spawn")` in test (#3753) This is deprecated it seems. --- Examples/Python/tests/test_reader.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Examples/Python/tests/test_reader.py b/Examples/Python/tests/test_reader.py index 3d458cb8009..b83b1317cc8 100644 --- a/Examples/Python/tests/test_reader.py +++ b/Examples/Python/tests/test_reader.py @@ -290,8 +290,11 @@ def test_edm4hep_simhit_particle_reader(tmp_path): tmp_file = str(tmp_path / "output_edm4hep.root") odd_xml_file = str(getOpenDataDetectorDirectory() / "xml" / "OpenDataDetector.xml") - with multiprocessing.get_context("spawn").Pool() as pool: - pool.apply(generate_input_test_edm4hep_simhit_reader, (odd_xml_file, tmp_file)) + p = multiprocessing.Process( + target=generate_input_test_edm4hep_simhit_reader, args=(odd_xml_file, tmp_file) + ) + p.start() + p.join() assert os.path.exists(tmp_file) From 1d1ccbdec5411e259225130ff20d139df7da4f33 Mon Sep 17 00:00:00 2001 From: Paul Gessinger Date: Fri, 18 Oct 2024 14:07:27 +0200 Subject: [PATCH 11/14] fix: Move `default` constructor impl in CPP file (#3752) This (somehow) fixes a faulty `-Wnull-dereference` case in GCC 11 --- Core/include/Acts/Geometry/CylinderVolumeBounds.hpp | 2 +- Core/src/Geometry/CylinderVolumeBounds.cpp | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp b/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp index 1951d96b2da..002af04cd59 100644 --- a/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp +++ b/Core/include/Acts/Geometry/CylinderVolumeBounds.hpp @@ -128,7 +128,7 @@ class CylinderVolumeBounds : public VolumeBounds { /// Copy Constructor /// /// @param cylbo is the source cylinder volume bounds for the copy - CylinderVolumeBounds(const CylinderVolumeBounds& cylbo) = default; + CylinderVolumeBounds(const CylinderVolumeBounds& cylbo); ~CylinderVolumeBounds() override = default; CylinderVolumeBounds& operator=(const CylinderVolumeBounds& cylbo) = default; diff --git a/Core/src/Geometry/CylinderVolumeBounds.cpp b/Core/src/Geometry/CylinderVolumeBounds.cpp index c7bb8192f4a..d9af620ea45 100644 --- a/Core/src/Geometry/CylinderVolumeBounds.cpp +++ b/Core/src/Geometry/CylinderVolumeBounds.cpp @@ -309,4 +309,7 @@ void CylinderVolumeBounds::set( } } +CylinderVolumeBounds::CylinderVolumeBounds(const CylinderVolumeBounds& cylbo) = + default; + } // namespace Acts From 8925fb52f9619b11165b2d9a1e58033b694e53b7 Mon Sep 17 00:00:00 2001 From: Wouter Deconinck Date: Fri, 18 Oct 2024 08:47:28 -0500 Subject: [PATCH 12/14] fix: `#include ` in HoughTransformUtils for `std::sort` (#3758) With gcc-14, the following compilation failure is reported: ``` 438 In file included from /home/wdconinc/git/acts/Core/include/Acts/Seeding/HoughTransformUtils.hpp:374, 439 from /home/wdconinc/git/acts/Examples/Algorithms/TrackFinding/include/ActsExamples/TrackFinding/MuonHoughSeeder.hpp:12, 440 from /home/wdconinc/git/acts/Examples/Algorithms/TrackFinding/src/MuonHoughSeeder.cpp:9: 441 /home/wdconinc/git/acts/Core/include/Acts/Seeding/HoughTransformUtils.ipp: In member function 'std::vector::Maximum> Acts::HoughTransformUtils::PeakFind ers::IslandsAroundMax::findPeaks(const Acts::HoughTransformUtils::HoughPlane&, const Acts::HoughTransformUtils::HoughAxisRanges&)': >> 442 /home/wdconinc/git/acts/Core/include/Acts/Seeding/HoughTransformUtils.ipp:224:8: error: 'sort' is not a member of 'std'; did you mean 'qsort'? 443 224 | std::sort(candidates.begin(), candidates.end(), 444 | ^~~~ 445 | qsort >> 446 make[2]: *** [Examples/Algorithms/TrackFinding/CMakeFiles/ActsExamplesTrackFinding.dir/build.make:177: Examples/Algorithms/TrackFinding/CMakeFiles/ActsExamplesTrackFinding.dir/src/MuonHoughSeeder.cpp.o] Error 1 447 make[2]: *** Waiting for unfinished jobs.... ``` This appears to be due to a missing `#include ` before the use of `std::sort` in the `.ipp` file. This PR adds the `algorithm` header to the `.hpp` file. --- Core/include/Acts/Seeding/HoughTransformUtils.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Core/include/Acts/Seeding/HoughTransformUtils.hpp b/Core/include/Acts/Seeding/HoughTransformUtils.hpp index a7a84d8908c..4fcece48034 100644 --- a/Core/include/Acts/Seeding/HoughTransformUtils.hpp +++ b/Core/include/Acts/Seeding/HoughTransformUtils.hpp @@ -14,6 +14,7 @@ #include "Acts/Utilities/Logger.hpp" #include "Acts/Utilities/Result.hpp" +#include #include #include #include From a3e1303c703ea0a1f9843ebe42b3358f310e08f7 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Fri, 18 Oct 2024 17:45:01 +0200 Subject: [PATCH 13/14] refactor: Group all ROOT writers together (#3746) Our ROOT writers are quite scattered and I would like to group them back together. --- Examples/Io/CMakeLists.txt | 2 -- .../Io/NuclearInteractions/CMakeLists.txt | 20 ------------------- Examples/Io/Root/CMakeLists.txt | 7 +++++++ .../Io/Root}/CKFPerformanceWriter.hpp | 0 ...RootNuclearInteractionParametersWriter.hpp | 2 +- .../Io/Root}/SeedingPerformanceWriter.hpp | 0 .../Io/Root}/TrackFinderPerformanceWriter.hpp | 0 .../Io/Root}/TrackFitterPerformanceWriter.hpp | 0 .../Io/Root}/VertexPerformanceWriter.hpp | 0 .../NuclearInteractionParametrisation.hpp | 0 .../src}/CKFPerformanceWriter.cpp | 2 +- ...RootNuclearInteractionParametersWriter.cpp | 2 +- .../src}/SeedingPerformanceWriter.cpp | 2 +- .../src}/TrackFinderPerformanceWriter.cpp | 2 +- .../src}/TrackFitterPerformanceWriter.cpp | 2 +- .../src}/VertexPerformanceWriter.cpp | 2 +- .../NuclearInteractionParametrisation.cpp | 2 +- Examples/Python/CMakeLists.txt | 2 -- Examples/Python/src/Output.cpp | 12 +++++------ 19 files changed, 21 insertions(+), 38 deletions(-) delete mode 100644 Examples/Io/NuclearInteractions/CMakeLists.txt rename Examples/Io/{Performance/ActsExamples/Io/Performance => Root/include/ActsExamples/Io/Root}/CKFPerformanceWriter.hpp (100%) rename Examples/Io/{NuclearInteractions/include/ActsExamples/Io/NuclearInteractions => Root/include/ActsExamples/Io/Root}/RootNuclearInteractionParametersWriter.hpp (97%) rename Examples/Io/{Performance/ActsExamples/Io/Performance => Root/include/ActsExamples/Io/Root}/SeedingPerformanceWriter.hpp (100%) rename Examples/Io/{Performance/ActsExamples/Io/Performance => Root/include/ActsExamples/Io/Root}/TrackFinderPerformanceWriter.hpp (100%) rename Examples/Io/{Performance/ActsExamples/Io/Performance => Root/include/ActsExamples/Io/Root}/TrackFitterPerformanceWriter.hpp (100%) rename Examples/Io/{Performance/ActsExamples/Io/Performance => Root/include/ActsExamples/Io/Root}/VertexPerformanceWriter.hpp (100%) rename Examples/Io/{NuclearInteractions/include/ActsExamples/Io/NuclearInteractions => Root/include/ActsExamples/Io/Root}/detail/NuclearInteractionParametrisation.hpp (100%) rename Examples/Io/{Performance/ActsExamples/Io/Performance => Root/src}/CKFPerformanceWriter.cpp (99%) rename Examples/Io/{NuclearInteractions => Root}/src/RootNuclearInteractionParametersWriter.cpp (99%) rename Examples/Io/{Performance/ActsExamples/Io/Performance => Root/src}/SeedingPerformanceWriter.cpp (99%) rename Examples/Io/{Performance/ActsExamples/Io/Performance => Root/src}/TrackFinderPerformanceWriter.cpp (99%) rename Examples/Io/{Performance/ActsExamples/Io/Performance => Root/src}/TrackFitterPerformanceWriter.cpp (98%) rename Examples/Io/{Performance/ActsExamples/Io/Performance => Root/src}/VertexPerformanceWriter.cpp (99%) rename Examples/Io/{NuclearInteractions => Root}/src/detail/NuclearInteractionParametrisation.cpp (99%) diff --git a/Examples/Io/CMakeLists.txt b/Examples/Io/CMakeLists.txt index dcf7c16a0a1..8b7f2861a6e 100644 --- a/Examples/Io/CMakeLists.txt +++ b/Examples/Io/CMakeLists.txt @@ -2,8 +2,6 @@ add_subdirectory(Csv) add_subdirectory_if(EDM4hep ACTS_BUILD_EXAMPLES_EDM4HEP) add_subdirectory_if(HepMC3 ACTS_BUILD_EXAMPLES_HEPMC3) add_subdirectory(Json) -add_subdirectory(NuclearInteractions) add_subdirectory(Obj) -add_subdirectory(Performance) add_subdirectory(Root) add_subdirectory_if(Svg ACTS_BUILD_PLUGIN_ACTSVG) diff --git a/Examples/Io/NuclearInteractions/CMakeLists.txt b/Examples/Io/NuclearInteractions/CMakeLists.txt deleted file mode 100644 index 3f7ad2b9b9b..00000000000 --- a/Examples/Io/NuclearInteractions/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -add_library( - ActsExamplesIoNuclearInteractions - SHARED - src/RootNuclearInteractionParametersWriter.cpp - src/detail/NuclearInteractionParametrisation.cpp -) -target_include_directories( - ActsExamplesIoNuclearInteractions - PUBLIC $ -) -target_link_libraries( - ActsExamplesIoNuclearInteractions - PUBLIC ActsCore ActsExamplesFramework Threads::Threads - PRIVATE ROOT::Core ROOT::Hist ROOT::Tree -) - -install( - TARGETS ActsExamplesIoNuclearInteractions - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} -) diff --git a/Examples/Io/Root/CMakeLists.txt b/Examples/Io/Root/CMakeLists.txt index 3ac12286395..f384c291bc1 100644 --- a/Examples/Io/Root/CMakeLists.txt +++ b/Examples/Io/Root/CMakeLists.txt @@ -23,6 +23,13 @@ add_library( src/RootVertexReader.cpp src/RootVertexWriter.cpp src/RootAthenaDumpReader.cpp + src/RootNuclearInteractionParametersWriter.cpp + src/detail/NuclearInteractionParametrisation.cpp + src/CKFPerformanceWriter.cpp + src/SeedingPerformanceWriter.cpp + src/TrackFinderPerformanceWriter.cpp + src/TrackFitterPerformanceWriter.cpp + src/VertexPerformanceWriter.cpp ) target_include_directories( ActsExamplesIoRoot diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/CKFPerformanceWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/CKFPerformanceWriter.hpp similarity index 100% rename from Examples/Io/Performance/ActsExamples/Io/Performance/CKFPerformanceWriter.hpp rename to Examples/Io/Root/include/ActsExamples/Io/Root/CKFPerformanceWriter.hpp diff --git a/Examples/Io/NuclearInteractions/include/ActsExamples/Io/NuclearInteractions/RootNuclearInteractionParametersWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/RootNuclearInteractionParametersWriter.hpp similarity index 97% rename from Examples/Io/NuclearInteractions/include/ActsExamples/Io/NuclearInteractions/RootNuclearInteractionParametersWriter.hpp rename to Examples/Io/Root/include/ActsExamples/Io/Root/RootNuclearInteractionParametersWriter.hpp index 8edad2c2a7d..d688920fc76 100644 --- a/Examples/Io/NuclearInteractions/include/ActsExamples/Io/NuclearInteractions/RootNuclearInteractionParametersWriter.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/RootNuclearInteractionParametersWriter.hpp @@ -12,7 +12,7 @@ #include "ActsExamples/EventData/ExtractedSimulationProcess.hpp" #include "ActsExamples/Framework/ProcessCode.hpp" #include "ActsExamples/Framework/WriterT.hpp" -#include "ActsExamples/Io/NuclearInteractions/detail/NuclearInteractionParametrisation.hpp" +#include "ActsExamples/Io/Root/detail/NuclearInteractionParametrisation.hpp" #include #include diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/SeedingPerformanceWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/SeedingPerformanceWriter.hpp similarity index 100% rename from Examples/Io/Performance/ActsExamples/Io/Performance/SeedingPerformanceWriter.hpp rename to Examples/Io/Root/include/ActsExamples/Io/Root/SeedingPerformanceWriter.hpp diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/TrackFinderPerformanceWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/TrackFinderPerformanceWriter.hpp similarity index 100% rename from Examples/Io/Performance/ActsExamples/Io/Performance/TrackFinderPerformanceWriter.hpp rename to Examples/Io/Root/include/ActsExamples/Io/Root/TrackFinderPerformanceWriter.hpp diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/TrackFitterPerformanceWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/TrackFitterPerformanceWriter.hpp similarity index 100% rename from Examples/Io/Performance/ActsExamples/Io/Performance/TrackFitterPerformanceWriter.hpp rename to Examples/Io/Root/include/ActsExamples/Io/Root/TrackFitterPerformanceWriter.hpp diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/VertexPerformanceWriter.hpp similarity index 100% rename from Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.hpp rename to Examples/Io/Root/include/ActsExamples/Io/Root/VertexPerformanceWriter.hpp diff --git a/Examples/Io/NuclearInteractions/include/ActsExamples/Io/NuclearInteractions/detail/NuclearInteractionParametrisation.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/detail/NuclearInteractionParametrisation.hpp similarity index 100% rename from Examples/Io/NuclearInteractions/include/ActsExamples/Io/NuclearInteractions/detail/NuclearInteractionParametrisation.hpp rename to Examples/Io/Root/include/ActsExamples/Io/Root/detail/NuclearInteractionParametrisation.hpp diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/CKFPerformanceWriter.cpp b/Examples/Io/Root/src/CKFPerformanceWriter.cpp similarity index 99% rename from Examples/Io/Performance/ActsExamples/Io/Performance/CKFPerformanceWriter.cpp rename to Examples/Io/Root/src/CKFPerformanceWriter.cpp index e7fa1525615..7b5b5aaf291 100644 --- a/Examples/Io/Performance/ActsExamples/Io/Performance/CKFPerformanceWriter.cpp +++ b/Examples/Io/Root/src/CKFPerformanceWriter.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "ActsExamples/Io/Performance/CKFPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/CKFPerformanceWriter.hpp" #include "Acts/EventData/TrackParameters.hpp" #include "Acts/Utilities/VectorHelpers.hpp" diff --git a/Examples/Io/NuclearInteractions/src/RootNuclearInteractionParametersWriter.cpp b/Examples/Io/Root/src/RootNuclearInteractionParametersWriter.cpp similarity index 99% rename from Examples/Io/NuclearInteractions/src/RootNuclearInteractionParametersWriter.cpp rename to Examples/Io/Root/src/RootNuclearInteractionParametersWriter.cpp index 64a324242c8..e0d635443e5 100644 --- a/Examples/Io/NuclearInteractions/src/RootNuclearInteractionParametersWriter.cpp +++ b/Examples/Io/Root/src/RootNuclearInteractionParametersWriter.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "ActsExamples/Io/NuclearInteractions/RootNuclearInteractionParametersWriter.hpp" +#include "ActsExamples/Io/Root/RootNuclearInteractionParametersWriter.hpp" #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Common.hpp" diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/SeedingPerformanceWriter.cpp b/Examples/Io/Root/src/SeedingPerformanceWriter.cpp similarity index 99% rename from Examples/Io/Performance/ActsExamples/Io/Performance/SeedingPerformanceWriter.cpp rename to Examples/Io/Root/src/SeedingPerformanceWriter.cpp index b2d87be68f9..4ac7ea269ef 100644 --- a/Examples/Io/Performance/ActsExamples/Io/Performance/SeedingPerformanceWriter.cpp +++ b/Examples/Io/Root/src/SeedingPerformanceWriter.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "SeedingPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/SeedingPerformanceWriter.hpp" #include "Acts/Utilities/MultiIndex.hpp" #include "Acts/Utilities/VectorHelpers.hpp" diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/TrackFinderPerformanceWriter.cpp b/Examples/Io/Root/src/TrackFinderPerformanceWriter.cpp similarity index 99% rename from Examples/Io/Performance/ActsExamples/Io/Performance/TrackFinderPerformanceWriter.cpp rename to Examples/Io/Root/src/TrackFinderPerformanceWriter.cpp index abef2ef0664..14e04252283 100644 --- a/Examples/Io/Performance/ActsExamples/Io/Performance/TrackFinderPerformanceWriter.cpp +++ b/Examples/Io/Root/src/TrackFinderPerformanceWriter.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "ActsExamples/Io/Performance/TrackFinderPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/TrackFinderPerformanceWriter.hpp" #include "Acts/Definitions/Units.hpp" #include "ActsExamples/EventData/Index.hpp" diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/TrackFitterPerformanceWriter.cpp b/Examples/Io/Root/src/TrackFitterPerformanceWriter.cpp similarity index 98% rename from Examples/Io/Performance/ActsExamples/Io/Performance/TrackFitterPerformanceWriter.cpp rename to Examples/Io/Root/src/TrackFitterPerformanceWriter.cpp index 54441ad7aa8..2063f03b53b 100644 --- a/Examples/Io/Performance/ActsExamples/Io/Performance/TrackFitterPerformanceWriter.cpp +++ b/Examples/Io/Root/src/TrackFitterPerformanceWriter.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "ActsExamples/Io/Performance/TrackFitterPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/TrackFitterPerformanceWriter.hpp" #include "Acts/EventData/MultiTrajectoryHelpers.hpp" #include "Acts/EventData/TrackParameters.hpp" diff --git a/Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.cpp b/Examples/Io/Root/src/VertexPerformanceWriter.cpp similarity index 99% rename from Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.cpp rename to Examples/Io/Root/src/VertexPerformanceWriter.cpp index dfc790433f9..f032e39af35 100644 --- a/Examples/Io/Performance/ActsExamples/Io/Performance/VertexPerformanceWriter.cpp +++ b/Examples/Io/Root/src/VertexPerformanceWriter.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "ActsExamples/Io/Performance/VertexPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/VertexPerformanceWriter.hpp" #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/TrackParametrization.hpp" diff --git a/Examples/Io/NuclearInteractions/src/detail/NuclearInteractionParametrisation.cpp b/Examples/Io/Root/src/detail/NuclearInteractionParametrisation.cpp similarity index 99% rename from Examples/Io/NuclearInteractions/src/detail/NuclearInteractionParametrisation.cpp rename to Examples/Io/Root/src/detail/NuclearInteractionParametrisation.cpp index f9df3d38f85..91f59c56648 100644 --- a/Examples/Io/NuclearInteractions/src/detail/NuclearInteractionParametrisation.cpp +++ b/Examples/Io/Root/src/detail/NuclearInteractionParametrisation.cpp @@ -6,7 +6,7 @@ // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. -#include "ActsExamples/Io/NuclearInteractions/detail/NuclearInteractionParametrisation.hpp" +#include "ActsExamples/Io/Root/detail/NuclearInteractionParametrisation.hpp" #include "Acts/Definitions/Common.hpp" #include "ActsFatras/EventData/Particle.hpp" diff --git a/Examples/Python/CMakeLists.txt b/Examples/Python/CMakeLists.txt index ff1e5901f43..c932b3ef081 100644 --- a/Examples/Python/CMakeLists.txt +++ b/Examples/Python/CMakeLists.txt @@ -54,11 +54,9 @@ target_link_libraries( ActsExamplesDetectorTGeo ActsExamplesMagneticField ActsExamplesIoRoot - ActsExamplesIoNuclearInteractions ActsExamplesIoCsv ActsExamplesIoObj ActsExamplesIoJson - ActsExamplesIoPerformance ActsExamplesGenerators ActsExamplesPrinters ActsExamplesTrackFinding diff --git a/Examples/Python/src/Output.cpp b/Examples/Python/src/Output.cpp index 11472d8e203..3ef89801c41 100644 --- a/Examples/Python/src/Output.cpp +++ b/Examples/Python/src/Output.cpp @@ -26,16 +26,12 @@ #include "ActsExamples/Io/Csv/CsvTrackParameterWriter.hpp" #include "ActsExamples/Io/Csv/CsvTrackWriter.hpp" #include "ActsExamples/Io/Csv/CsvTrackingGeometryWriter.hpp" -#include "ActsExamples/Io/NuclearInteractions/RootNuclearInteractionParametersWriter.hpp" -#include "ActsExamples/Io/Performance/CKFPerformanceWriter.hpp" -#include "ActsExamples/Io/Performance/SeedingPerformanceWriter.hpp" -#include "ActsExamples/Io/Performance/TrackFinderPerformanceWriter.hpp" -#include "ActsExamples/Io/Performance/TrackFitterPerformanceWriter.hpp" -#include "ActsExamples/Io/Performance/VertexPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/CKFPerformanceWriter.hpp" #include "ActsExamples/Io/Root/RootBFieldWriter.hpp" #include "ActsExamples/Io/Root/RootMaterialTrackWriter.hpp" #include "ActsExamples/Io/Root/RootMaterialWriter.hpp" #include "ActsExamples/Io/Root/RootMeasurementWriter.hpp" +#include "ActsExamples/Io/Root/RootNuclearInteractionParametersWriter.hpp" #include "ActsExamples/Io/Root/RootParticleWriter.hpp" #include "ActsExamples/Io/Root/RootPropagationStepsWriter.hpp" #include "ActsExamples/Io/Root/RootPropagationSummaryWriter.hpp" @@ -46,6 +42,10 @@ #include "ActsExamples/Io/Root/RootTrackStatesWriter.hpp" #include "ActsExamples/Io/Root/RootTrackSummaryWriter.hpp" #include "ActsExamples/Io/Root/RootVertexWriter.hpp" +#include "ActsExamples/Io/Root/SeedingPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/TrackFinderPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/TrackFitterPerformanceWriter.hpp" +#include "ActsExamples/Io/Root/VertexPerformanceWriter.hpp" #include "ActsExamples/MaterialMapping/IMaterialWriter.hpp" #include "ActsExamples/Plugins/Obj/ObjPropagationStepsWriter.hpp" #include "ActsExamples/Plugins/Obj/ObjTrackingGeometryWriter.hpp" From 26d18cb6c0dbff65f5a708e33d01b65fd68bb3c1 Mon Sep 17 00:00:00 2001 From: Andreas Stefl Date: Fri, 18 Oct 2024 19:14:10 +0200 Subject: [PATCH 14/14] refactor: Rework particle selection in Examples (#3742) - remove `TruthSeedRanges` as this a duplication of `ParticleSelector ` - enhance `ParticleSelector` by also input/output final particle selections which are necessary to access the number of hits - raise some pT cuts to the usual 1 GeV - handle downstream changes blocked by - https://github.com/acts-project/acts/pull/3744 --- ...ance_vertexing_amvf_gauss_notime_hist.root | Bin 48549 -> 48441 bytes ...ormance_vertexing_amvf_grid_time_hist.root | Bin 48986 -> 48857 bytes .../tracksummary_ckf_hist.root | Bin 40304 -> 40310 bytes .../workflows/physmon_trackfinding_1muon.py | 10 ++- .../physmon_trackfinding_4muon_50vertices.py | 10 ++- .../physmon_trackfinding_ttbar_pu200.py | 7 +- .../TruthTracking/ParticleSelector.cpp | 70 ++++++++++------- .../TruthTracking/ParticleSelector.hpp | 14 +++- .../Io/Root/RootParticleWriter.hpp | 6 +- Examples/Io/Root/src/RootParticleWriter.cpp | 8 +- .../python/acts/examples/reconstruction.py | 74 ++---------------- .../Python/python/acts/examples/simulation.py | 54 ++++++------- Examples/Python/src/Output.cpp | 2 +- Examples/Python/src/TruthTracking.cpp | 3 +- Examples/Python/tests/root_file_hashes.txt | 4 +- Examples/Python/tests/test_examples.py | 9 ++- Examples/Scripts/Optimization/ckf.py | 8 +- Examples/Scripts/Python/ckf_tracks.py | 8 +- Examples/Scripts/Python/full_chain_itk.py | 13 +-- .../Scripts/Python/full_chain_itk_Gbts.py | 13 +-- Examples/Scripts/Python/full_chain_odd.py | 19 +++-- Examples/Scripts/Python/full_chain_odd_LRT.py | 18 +++-- Examples/Scripts/Python/hashing_seeding.py | 16 ++-- Examples/Scripts/Python/seeding.py | 9 ++- Examples/Scripts/Python/truth_tracking_gsf.py | 17 ++-- .../Python/truth_tracking_gsf_refitting.py | 8 +- .../Scripts/Python/truth_tracking_gx2f.py | 17 ++-- .../Scripts/Python/truth_tracking_kalman.py | 17 ++-- .../Python/truth_tracking_kalman_refitting.py | 8 +- 29 files changed, 223 insertions(+), 219 deletions(-) diff --git a/CI/physmon/reference/trackfinding_ttbar_pu200/performance_vertexing_amvf_gauss_notime_hist.root b/CI/physmon/reference/trackfinding_ttbar_pu200/performance_vertexing_amvf_gauss_notime_hist.root index 26472832eebf549bf73f890ecd9ae4e63a36ae89..64abc1fadafc7b2d4c68e0987cb93e581a30a9fc 100644 GIT binary patch delta 4682 zcmeHLdsI_L8oxILe8dv8zCwTi@0rxxiz<*-Lq%^*t7r0IX9X4&D`I7 z^L_LE<|DPQc&C5mNmEs-bc%X%o}#EYit6yBsIwZTy^ncDF;5|%`G{xQ4=Bnhfuem& zb@rd#9sh8j+rEqeyHmG8aGQhR0)=L&G7pJO%2K!ZGhe7lQ4^{W1M@J<=&ylB1g9?` zf@T>ZAS1th(r$>#P>J3LuNoxqBYF%in2x~^3|bjk@K*$mehxn6wMFHx*}ZpVtNpQo z;kNMTt5@oF83&fo&INr_2dFb2m#QaCRr;JC_uOsw?C6PZhpmSE_f2!)n`v@v%SZVI zm707XO2zy|-bzulJ6<3HTkS&86lJg-Y787{0osN$0{ExlHNKc0`#bZj-?7XQ&u0mM z#y|v8j06T~D_e~M&^NqnG@Hha*Q4T`*by5)u*om>M6eTETQ_5e}6fwinOxn-40vEdEMxPAb8y?5glb=~|9avLLupc9;V! z8i4}eS`HxB!FIWt1NhB{{(i0j8#zE|54;h|oe}mJ4u`P-j%UOaAk~SWcf-W82T8G&k@X)cqs`)Numpt9+oL)w>KjGnk~Nn^o0WuNTOBFDwY9TtaI4Da*` zA9XKe<-|U#qb7^H=bEh6j6Ub{Nxo&?u0e73jWef;?Z14vX#Wuhb&98Y>kp4BleLKr z%L=VKg zH{r9egx)!kubaBR3hr9pZvTf?2iV}=6)C0LPQHAxX8n{X=cvE;X5}nc{X@VGQL>G8 zoiNGCNeeY2_kBi|b#``kOU0?J0X4!I=AoM}9&4F%r#;uHZc3nA!N9W4=Pe`WU~|@! zGq0Ww{;iE?u_4j0DyMMlt&_Qa$J0tKRYxAXe4h^O*?z=HkTSYSFjEl54>#O1VYv0L zpWtal6^qD@L;QNuo=)`U_w47cmB1zFYalH%FufvRup8 zOMe>ve%I~Vr<;rZ)Yqqa^tB}L>Y+PLgSO*04KDV0ke@e3URf~zjG|vCPV4eE(hfNA z6|ygj>Z@l}w%$$Xx#E>jwP&?ur%#UhHSZrC=UvLfGZ@w8iE-ux;Q(UsTX_RCw@!i^ zR=pxIpN^vX@l%+&dV~No5fD8Lx5b$A@PWifCDsm%KoRVUwc(twbUAnw$I0c42C%S| z)6W_QyyKlQ3C@JLM<9#Igz|V+KRnS=Ypw!a^E9|I!HzKF{7tlk+Qd~HU~Lf`n-t3d zlAgir06#X9YXtY# z76D<4*=%%e;C|Axx7#;LPt8bA#Pb;2b9$GZ4qlvtZ_NYyEg>F9_4M;uB;YH)KndKhT_T(CS1Xy!giMV>W^e(A47;%AFz`Ofabc}3NIc0g;mA?oTqgos3Wa*JuuDa-sZc<4 zQ14eWI9T+Mli|e?@Y`ZbGE47S3AEWEBp~ZfxNz5K0^pdH_QK#Y2?1DV!Y#mx0IVlr zU4@9lfn7NT-riF}me>1pDlFS)%pu246~T)KrjeOAeGjVO(7_%8=-p}#?^acFwxcnI zr5bm_g}0+!4tuqMWCrU_Xm>c10N8|DTUb}Si2!(SM~*`0I<~yRj;oJ^H|r~DAxgE6 zP(+!3AefS~EXNa^ZxG^oxWB;;f4^$@Z;EkqpgA@MzgOmFhJrr}=PT#RV`<@ zBalYr;5~B+x$vBur=V&^0{7){fA*?Y^O2M)5B^SVmWO7|MR4D5FzIT|Lyya~-v$j6O(jqLxCz cJmshrw~l!pqShxt%&$5VP^-f;Yfd@!PmS{4)c^nh delta 4749 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 OsvmHxqksLJa^~NR_{^CA delta 4721 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 IFd6i}06v*i1ONa4 delta 15761 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 diff --git a/CI/physmon/workflows/physmon_trackfinding_1muon.py b/CI/physmon/workflows/physmon_trackfinding_1muon.py index d06f99fbdb6..3c87bdee32d 100755 --- a/CI/physmon/workflows/physmon_trackfinding_1muon.py +++ b/CI/physmon/workflows/physmon_trackfinding_1muon.py @@ -11,13 +11,13 @@ EtaConfig, PhiConfig, ParticleConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, ParticleSmearingSigmas, SeedFinderConfigArg, SeedFinderOptionsArg, @@ -72,6 +72,11 @@ def run_ckf_tracking(label, seeding): setup.field, enableInteractions=True, rnd=rnd, + postSelectParticles=ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + measurements=(9, None), + removeNeutral=True, + ), ) addDigitization( @@ -86,7 +91,6 @@ def run_ckf_tracking(label, seeding): s, setup.trackingGeometry, setup.field, - TruthSeedRanges(pt=(500 * u.MeV, None), nHits=(9, None)), ParticleSmearingSigmas( # only used by SeedingAlgorithm.TruthSmeared # zero eveything so the CKF has a chance to find the measurements d0=0, @@ -134,7 +138,7 @@ def run_ckf_tracking(label, seeding): setup.trackingGeometry, setup.field, TrackSelectorConfig( - pt=(500 * u.MeV, None), + pt=(0.9 * u.GeV, None), loc0=(-4.0 * u.mm, 4.0 * u.mm), nMeasurementsMin=6, maxHoles=2, diff --git a/CI/physmon/workflows/physmon_trackfinding_4muon_50vertices.py b/CI/physmon/workflows/physmon_trackfinding_4muon_50vertices.py index e1ece122c45..f6c3fe110fd 100755 --- a/CI/physmon/workflows/physmon_trackfinding_4muon_50vertices.py +++ b/CI/physmon/workflows/physmon_trackfinding_4muon_50vertices.py @@ -11,12 +11,12 @@ EtaConfig, PhiConfig, ParticleConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, SeedFinderConfigArg, SeedFinderOptionsArg, SeedingAlgorithm, @@ -69,6 +69,11 @@ setup.trackingGeometry, setup.field, rnd=rnd, + postSelectParticles=ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + measurements=(9, None), + removeNeutral=True, + ), ) addDigitization( @@ -83,7 +88,6 @@ s, setup.trackingGeometry, setup.field, - TruthSeedRanges(pt=(500.0 * u.MeV, None), nHits=(9, None)), SeedFinderConfigArg( r=(33 * u.mm, 200 * u.mm), deltaR=(1 * u.mm, 60 * u.mm), @@ -116,7 +120,7 @@ setup.trackingGeometry, setup.field, TrackSelectorConfig( - pt=(500 * u.MeV, None), + pt=(0.9 * u.GeV, None), loc0=(-4.0 * u.mm, 4.0 * u.mm), nMeasurementsMin=6, maxHoles=2, diff --git a/CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py b/CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py index 172fa55270a..c8b163c9022 100755 --- a/CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py +++ b/CI/physmon/workflows/physmon_trackfinding_ttbar_pu200.py @@ -13,7 +13,6 @@ ) from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, SeedFinderConfigArg, SeedFinderOptionsArg, SeedingAlgorithm, @@ -68,6 +67,11 @@ rho=(0.0, 24 * u.mm), absZ=(0.0, 1.0 * u.m), ), + postSelectParticles=ParticleSelectorConfig( + pt=(0.5 * u.GeV, None), + measurements=(9, None), + removeNeutral=True, + ), ) addDigitization( @@ -82,7 +86,6 @@ s, setup.trackingGeometry, setup.field, - TruthSeedRanges(pt=(500.0 * u.MeV, None), nHits=(9, None)), SeedFinderConfigArg( r=(33 * u.mm, 200 * u.mm), deltaR=(1 * u.mm, 60 * u.mm), diff --git a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.cpp b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.cpp index d9248358160..5fa3ee0e4b2 100644 --- a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.cpp +++ b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.cpp @@ -29,9 +29,16 @@ ActsExamples::ParticleSelector::ParticleSelector(const Config& config, if (m_cfg.outputParticles.empty()) { throw std::invalid_argument("Missing output particles collection"); } + if (!m_cfg.outputParticlesFinal.empty() && + m_cfg.inputParticlesFinal.empty()) { + throw std::invalid_argument( + "Output final particles collection requires input final particles"); + } m_inputParticles.initialize(m_cfg.inputParticles); + m_inputParticlesFinal.maybeInitialize(m_cfg.inputParticlesFinal); m_outputParticles.initialize(m_cfg.outputParticles); + m_outputParticlesFinal.maybeInitialize(m_cfg.outputParticlesFinal); ACTS_DEBUG("selection particle rho [" << m_cfg.rhoMin << "," << m_cfg.rhoMax << ")"); @@ -52,29 +59,15 @@ ActsExamples::ParticleSelector::ParticleSelector(const Config& config, ACTS_DEBUG("remove charged particles " << m_cfg.removeCharged); ACTS_DEBUG("remove neutral particles " << m_cfg.removeNeutral); ACTS_DEBUG("remove secondary particles " << m_cfg.removeSecondaries); - - // We only initialize this if we actually select on this - if (m_cfg.measurementsMin > 0 || - m_cfg.measurementsMax < std::numeric_limits::max()) { - m_inputMap.initialize(m_cfg.inputMeasurementParticlesMap); - ACTS_DEBUG("selection particle number of measurements [" - << m_cfg.measurementsMin << "," << m_cfg.measurementsMax << ")"); - } } ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute( const AlgorithmContext& ctx) const { - using ParticlesMeasurmentMap = - boost::container::flat_multimap; - // prepare input/ output types - const auto& inputParticles = m_inputParticles(ctx); - - // Make global particles measurement map if necessary - std::optional particlesMeasMap; - if (m_inputMap.isInitialized()) { - particlesMeasMap = invertIndexMultimap(m_inputMap(ctx)); - } + const SimParticleContainer& inputParticles = m_inputParticles(ctx); + const SimParticleContainer& inputParticlesFinal = + (m_inputParticlesFinal.isInitialized()) ? m_inputParticlesFinal(ctx) + : inputParticles; std::size_t nInvalidCharge = 0; std::size_t nInvalidMeasurementCount = 0; @@ -96,17 +89,14 @@ ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute( nInvalidCharge += static_cast(!validCharge); - // default valid measurement count to true and only change if we have loaded - // the measurement particles map bool validMeasurementCount = true; - if (particlesMeasMap) { - auto [b, e] = particlesMeasMap->equal_range(p.particleId()); + if (auto finalParticleIt = inputParticlesFinal.find(p.particleId()); + finalParticleIt != inputParticlesFinal.end()) { validMeasurementCount = - within(static_cast(std::distance(b, e)), - m_cfg.measurementsMin, m_cfg.measurementsMax); - - ACTS_VERBOSE("Found " << std::distance(b, e) << " measurements for " - << p.particleId()); + within(finalParticleIt->numberOfHits(), m_cfg.measurementsMin, + m_cfg.measurementsMax); + } else { + ACTS_WARNING("No final particle found for " << p.particleId()); } nInvalidMeasurementCount += @@ -136,14 +126,30 @@ ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute( SimParticleContainer outputParticles; outputParticles.reserve(inputParticles.size()); + SimParticleContainer outputParticlesFinal; + if (m_outputParticlesFinal.isInitialized()) { + outputParticlesFinal.reserve(inputParticles.size()); + } + // copy selected particles for (const auto& inputParticle : inputParticles) { - if (isValidParticle(inputParticle)) { - // the input parameters should already be - outputParticles.insert(outputParticles.end(), inputParticle); + if (!isValidParticle(inputParticle)) { + continue; + } + + outputParticles.insert(outputParticles.end(), inputParticle); + + if (m_outputParticlesFinal.isInitialized()) { + if (auto particleFinalIt = + inputParticlesFinal.find(inputParticle.particleId()); + particleFinalIt != inputParticlesFinal.end()) { + outputParticlesFinal.insert(outputParticlesFinal.end(), + *particleFinalIt); + } } } outputParticles.shrink_to_fit(); + outputParticlesFinal.shrink_to_fit(); ACTS_DEBUG("event " << ctx.eventNumber << " selected " << outputParticles.size() << " from " @@ -153,5 +159,9 @@ ActsExamples::ProcessCode ActsExamples::ParticleSelector::execute( << nInvalidMeasurementCount); m_outputParticles(ctx, std::move(outputParticles)); + if (m_outputParticlesFinal.isInitialized()) { + m_outputParticlesFinal(ctx, std::move(outputParticlesFinal)); + } + return ProcessCode::SUCCESS; } diff --git a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.hpp b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.hpp index d6c8440fdc7..de05bf621ca 100644 --- a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.hpp +++ b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSelector.hpp @@ -29,10 +29,14 @@ class ParticleSelector final : public IAlgorithm { struct Config { /// The input particles collection. std::string inputParticles; - /// Input measurement particles map (Optional) - std::string inputMeasurementParticlesMap; + /// Optional. The input final state particles collection. + /// If provided, this will be used to access the number of measurements. + std::string inputParticlesFinal; /// The output particles collection. std::string outputParticles; + /// Optional. The output final state particles collection. + std::string outputParticlesFinal; + // Minimum/maximum distance from the origin in the transverse plane. double rhoMin = 0; double rhoMax = std::numeric_limits::infinity(); @@ -79,11 +83,13 @@ class ParticleSelector final : public IAlgorithm { Config m_cfg; ReadDataHandle m_inputParticles{this, "InputParticles"}; - ReadDataHandle> m_inputMap{ - this, "InputMeasurementParticlesMap"}; + ReadDataHandle m_inputParticlesFinal{ + this, "InputParticlesFinal"}; WriteDataHandle m_outputParticles{this, "OutputParticles"}; + WriteDataHandle m_outputParticlesFinal{ + this, "OutputParticlesFinal"}; }; } // namespace ActsExamples diff --git a/Examples/Io/Root/include/ActsExamples/Io/Root/RootParticleWriter.hpp b/Examples/Io/Root/include/ActsExamples/Io/Root/RootParticleWriter.hpp index 99cf6b5cd61..8be9f05b735 100644 --- a/Examples/Io/Root/include/ActsExamples/Io/Root/RootParticleWriter.hpp +++ b/Examples/Io/Root/include/ActsExamples/Io/Root/RootParticleWriter.hpp @@ -39,7 +39,7 @@ class RootParticleWriter final : public WriterT { std::string inputParticles; /// Optional. If given, the the energy loss and traversed material is /// computed and written. - std::string inputFinalParticles; + std::string inputParticlesFinal; /// Path to the output file. std::string filePath; /// Output file access mode. @@ -74,8 +74,8 @@ class RootParticleWriter final : public WriterT { private: Config m_cfg; - ReadDataHandle m_inputFinalParticles{ - this, "InputFinalParticles"}; + ReadDataHandle m_inputParticlesFinal{ + this, "InputParticlesFinal"}; std::mutex m_writeMutex; diff --git a/Examples/Io/Root/src/RootParticleWriter.cpp b/Examples/Io/Root/src/RootParticleWriter.cpp index fbd1333c38c..436601eb97d 100644 --- a/Examples/Io/Root/src/RootParticleWriter.cpp +++ b/Examples/Io/Root/src/RootParticleWriter.cpp @@ -36,7 +36,7 @@ ActsExamples::RootParticleWriter::RootParticleWriter( throw std::invalid_argument("Missing tree name"); } - m_inputFinalParticles.maybeInitialize(m_cfg.inputFinalParticles); + m_inputParticlesFinal.maybeInitialize(m_cfg.inputParticlesFinal); // open root file and create the tree m_outputFile = TFile::Open(m_cfg.filePath.c_str(), m_cfg.fileMode.c_str()); @@ -73,7 +73,7 @@ ActsExamples::RootParticleWriter::RootParticleWriter( m_outputTree->Branch("generation", &m_generation); m_outputTree->Branch("sub_particle", &m_subParticle); - if (m_inputFinalParticles.isInitialized()) { + if (m_inputParticlesFinal.isInitialized()) { m_outputTree->Branch("e_loss", &m_eLoss); m_outputTree->Branch("total_x0", &m_pathInX0); m_outputTree->Branch("total_l0", &m_pathInL0); @@ -102,8 +102,8 @@ ActsExamples::ProcessCode ActsExamples::RootParticleWriter::finalize() { ActsExamples::ProcessCode ActsExamples::RootParticleWriter::writeT( const AlgorithmContext& ctx, const SimParticleContainer& particles) { const SimParticleContainer* finalParticles = nullptr; - if (m_inputFinalParticles.isInitialized()) { - finalParticles = &m_inputFinalParticles(ctx); + if (m_inputParticlesFinal.isInitialized()) { + finalParticles = &m_inputParticlesFinal(ctx); } // ensure exclusive access to tree/file while writing diff --git a/Examples/Python/python/acts/examples/reconstruction.py b/Examples/Python/python/acts/examples/reconstruction.py index 371345a17b5..38d64100fd3 100644 --- a/Examples/Python/python/acts/examples/reconstruction.py +++ b/Examples/Python/python/acts/examples/reconstruction.py @@ -14,12 +14,6 @@ "Default TruthSmeared TruthEstimated Orthogonal HoughTransform Gbts Hashing", ) -TruthSeedRanges = namedtuple( - "TruthSeedRanges", - ["rho", "z", "phi", "eta", "absEta", "pt", "nHits"], - defaults=[(None, None)] * 7, -) - ParticleSmearingSigmas = namedtuple( "ParticleSmearingSigmas", ["d0", "d0PtA", "d0PtB", "z0", "z0PtA", "z0PtB", "t0", "phi", "theta", "ptRel"], @@ -231,7 +225,6 @@ class VertexFinder(Enum): @acts.examples.NamedTypeArgs( seedingAlgorithm=SeedingAlgorithm, - truthSeedRanges=TruthSeedRanges, particleSmearingSigmas=ParticleSmearingSigmas, seedFinderConfigArg=SeedFinderConfigArg, seedFinderOptionsArg=SeedFinderOptionsArg, @@ -251,7 +244,6 @@ def addSeeding( layerMappingConfigFile: Optional[Union[Path, str]] = None, connector_inputConfigFile: Optional[Union[Path, str]] = None, seedingAlgorithm: SeedingAlgorithm = SeedingAlgorithm.Default, - truthSeedRanges: Optional[TruthSeedRanges] = TruthSeedRanges(), particleSmearingSigmas: ParticleSmearingSigmas = ParticleSmearingSigmas(), initialSigmas: Optional[list] = None, initialSigmaPtRel: Optional[float] = None, @@ -273,6 +265,7 @@ def addSeeding( acts.ParticleHypothesis ] = acts.ParticleHypothesis.pion, inputParticles: str = "particles", + selectedParticles: str = "particles_selected", outputDirRoot: Optional[Union[Path, str]] = None, outputDirCsv: Optional[Union[Path, str]] = None, logLevel: Optional[acts.logging.Level] = None, @@ -289,10 +282,6 @@ def addSeeding( Json file for space point geometry selection. Not required for SeedingAlgorithm.TruthSmeared. seedingAlgorithm : SeedingAlgorithm, Default seeding algorithm to use: one of Default (no truth information used), TruthSmeared, TruthEstimated - truthSeedRanges : TruthSeedRanges(rho, z, phi, eta, absEta, pt, nHits) - TruthSeedSelector configuration. Each range is specified as a tuple of (min,max). - Defaults of no cuts specified in Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/TruthSeedSelector.hpp - If specified as None, don't run ParticleSmearing at all (and use addCKFTracks(selectedParticles="particles")) particleSmearingSigmas : ParticleSmearingSigmas(d0, d0PtA, d0PtB, z0, z0PtA, z0PtB, t0, phi, theta, ptRel) ParticleSmearing configuration. Defaults specified in Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/ParticleSmearing.hpp @@ -324,6 +313,8 @@ def addSeeding( The hypothesis used for track finding. Defaults to pion. inputParticles : str, "particles" input particles name in the WhiteBoard + selectedParticles : str, "particles_selected" + selected particles name in the WhiteBoard outputDirRoot : Path|str, path, None the output folder for the Root output, None triggers no output logLevel : acts.logging.Level, None @@ -336,18 +327,6 @@ def addSeeding( logger = acts.logging.getLogger("addSeeding") logger.setLevel(logLevel) - if truthSeedRanges is not None: - selectedParticles = "truth_seeds_selected" - addSeedingTruthSelection( - s, - inputParticles, - selectedParticles, - truthSeedRanges, - logLevel, - ) - else: - selectedParticles = inputParticles - # Create starting parameters from either particle smearing or combined seed # finding and track parameters estimation if seedingAlgorithm == SeedingAlgorithm.TruthSmeared: @@ -506,41 +485,6 @@ def addSeeding( return s -def addSeedingTruthSelection( - s: acts.examples.Sequencer, - inputParticles: str, - outputParticles: str, - truthSeedRanges: TruthSeedRanges, - logLevel: acts.logging.Level = None, -): - """adds truth particles filtering before filtering - For parameters description see addSeeding - """ - selAlg = acts.examples.TruthSeedSelector( - **acts.examples.defaultKWArgs( - ptMin=truthSeedRanges.pt[0], - ptMax=truthSeedRanges.pt[1], - etaMin=truthSeedRanges.eta[0], - etaMax=truthSeedRanges.eta[1], - nHitsMin=truthSeedRanges.nHits[0], - nHitsMax=truthSeedRanges.nHits[1], - rhoMin=truthSeedRanges.rho[0], - rhoMax=truthSeedRanges.rho[1], - zMin=truthSeedRanges.z[0], - zMax=truthSeedRanges.z[1], - phiMin=truthSeedRanges.phi[0], - phiMax=truthSeedRanges.phi[1], - absEtaMin=truthSeedRanges.absEta[0], - absEtaMax=truthSeedRanges.absEta[1], - ), - level=logLevel, - inputParticles=inputParticles, - inputMeasurementParticlesMap="measurement_particles_map", - outputParticles=outputParticles, - ) - s.addAlgorithm(selAlg) - - def addTruthSmearedSeeding( s: acts.examples.Sequencer, rnd: Optional[acts.examples.RandomNumbers], @@ -1233,7 +1177,7 @@ def addSeedFilterML( from acts.examples.onnx import SeedFilterMLAlgorithm inputParticles = "particles" - selectedParticles = "truth_seeds_selected" + selectedParticles = "particles_selected" seeds = "seeds" estParams = "estimatedparameters" @@ -1678,10 +1622,6 @@ def addTrackWriters( trackStatesWriter = acts.examples.RootTrackStatesWriter( level=customLogLevel(), inputTracks=tracks, - # @note The full particles collection is used here to avoid lots of warnings - # since the unselected CKF track might have a majority particle not in the - # filtered particle collection. This could be avoided when a separate track - # selection algorithm is used. inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", inputSimHits="simhits", @@ -1696,10 +1636,6 @@ def addTrackWriters( trackSummaryWriter = acts.examples.RootTrackSummaryWriter( level=customLogLevel(), inputTracks=tracks, - # @note The full particles collection is used here to avoid lots of warnings - # since the unselected CKF track might have a majority particle not in the - # filtered particle collection. This could be avoided when a separate track - # selection algorithm is used. inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", filePath=str(outputDirRoot / f"tracksummary_{name}.root"), @@ -1713,7 +1649,7 @@ def addTrackWriters( ckfPerfWriter = acts.examples.CKFPerformanceWriter( level=customLogLevel(), inputTracks=tracks, - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", inputParticleTrackMatching="particle_track_matching", filePath=str(outputDirRoot / f"performance_{name}.root"), diff --git a/Examples/Python/python/acts/examples/simulation.py b/Examples/Python/python/acts/examples/simulation.py index b3b1046dc70..8f6b6d0e603 100644 --- a/Examples/Python/python/acts/examples/simulation.py +++ b/Examples/Python/python/acts/examples/simulation.py @@ -355,7 +355,8 @@ def addParticleSelection( config: ParticleSelectorConfig, inputParticles: str, outputParticles: str, - inputMeasurementParticlesMap: str = "", + inputParticlesFinal: Optional[str] = None, + outputParticlesFinal: Optional[str] = None, logLevel: Optional[acts.logging.Level] = None, ) -> None: """ @@ -371,12 +372,18 @@ def addParticleSelection( the identifier for the input particles to be selected outputParticles: str the identifier for the final selected particle collection + inputParticlesFinal: str, None + the identifier for the input final particles to be selected + outputParticlesFinal: str, None + the identifier for the final selected final particle collection """ customLogLevel = acts.examples.defaultLogging(s, logLevel) s.addAlgorithm( acts.examples.ParticleSelector( **acts.examples.defaultKWArgs( + inputParticlesFinal=inputParticlesFinal, + outputParticlesFinal=outputParticlesFinal, rhoMin=config.rho[0], rhoMax=config.rho[1], absZMin=config.absZ[0], @@ -402,7 +409,6 @@ def addParticleSelection( level=customLogLevel(), inputParticles=inputParticles, outputParticles=outputParticles, - inputMeasurementParticlesMap=inputMeasurementParticlesMap, ) ) @@ -489,27 +495,22 @@ def addFatras( # Selector if postSelectParticles is not None: particlesInitial = "fatras_particles_initial_selected" - addParticleSelection( - s, - postSelectParticles, - inputParticles=alg.config.outputParticlesInitial, - outputParticles=particlesInitial, - ) - particlesFinal = "fatras_particles_final_selected" addParticleSelection( s, postSelectParticles, - inputParticles=alg.config.outputParticlesFinal, - outputParticles=particlesFinal, + inputParticles=outputParticlesInitial, + inputParticlesFinal=outputParticlesFinal, + outputParticles=particlesInitial, + outputParticlesFinal=particlesFinal, ) - s.addWhiteboardAlias("particles_selected", particlesFinal) + s.addWhiteboardAlias("particles_selected", particlesInitial) else: - particlesInitial = alg.config.outputParticlesInitial - particlesFinal = alg.config.outputParticlesFinal + particlesInitial = outputParticlesInitial + particlesFinal = outputParticlesFinal # Only add alias for 'particles_initial' as this is the one we use most - s.addWhiteboardAlias("particles", particlesInitial) + s.addWhiteboardAlias("particles", outputParticlesInitial) # Output addSimWriters( @@ -573,7 +574,7 @@ def addSimWriters( acts.examples.RootParticleWriter( level=customLogLevel(), inputParticles=particlesInitial, - inputFinalParticles=particlesFinal, + inputParticlesFinal=particlesFinal, filePath=str(outputDirRoot / "particles_simulation.root"), ) ) @@ -739,27 +740,22 @@ def addGeant4( # Selector if postSelectParticles is not None: particlesInitial = "geant4_particles_initial_postselected" - addParticleSelection( - s, - postSelectParticles, - inputParticles=alg.config.outputParticlesInitial, - outputParticles=particlesInitial, - ) - particlesFinal = "geant4_particles_final_postselected" addParticleSelection( s, postSelectParticles, - inputParticles=alg.config.outputParticlesFinal, - outputParticles=particlesFinal, + inputParticles=outputParticlesInitial, + inputParticlesFinal=outputParticlesFinal, + outputParticles=particlesInitial, + outputParticlesFinal=particlesFinal, ) - s.addWhiteboardAlias("particles_selected", particlesFinal) + s.addWhiteboardAlias("particles_selected", particlesInitial) else: - particlesInitial = alg.config.outputParticlesInitial - particlesFinal = alg.config.outputParticlesFinal + particlesInitial = outputParticlesInitial + particlesFinal = outputParticlesFinal # Only add alias for 'particles_initial' as this is the one we use most - s.addWhiteboardAlias("particles", particlesInitial) + s.addWhiteboardAlias("particles", outputParticlesInitial) # Output addSimWriters( diff --git a/Examples/Python/src/Output.cpp b/Examples/Python/src/Output.cpp index 3ef89801c41..bda45b3cab7 100644 --- a/Examples/Python/src/Output.cpp +++ b/Examples/Python/src/Output.cpp @@ -194,7 +194,7 @@ void addOutput(Context& ctx) { ACTS_PYTHON_DECLARE_WRITER(ActsExamples::RootParticleWriter, mex, "RootParticleWriter", inputParticles, - inputFinalParticles, filePath, fileMode, treeName); + inputParticlesFinal, filePath, fileMode, treeName); ACTS_PYTHON_DECLARE_WRITER(ActsExamples::RootVertexWriter, mex, "RootVertexWriter", inputVertices, filePath, diff --git a/Examples/Python/src/TruthTracking.cpp b/Examples/Python/src/TruthTracking.cpp index 85d34698b7b..2c43b3cfc4d 100644 --- a/Examples/Python/src/TruthTracking.cpp +++ b/Examples/Python/src/TruthTracking.cpp @@ -108,8 +108,9 @@ void addTruthTracking(Context& ctx) { ACTS_PYTHON_STRUCT_BEGIN(c, Config); ACTS_PYTHON_MEMBER(inputParticles); - ACTS_PYTHON_MEMBER(inputMeasurementParticlesMap); + ACTS_PYTHON_MEMBER(inputParticlesFinal); ACTS_PYTHON_MEMBER(outputParticles); + ACTS_PYTHON_MEMBER(outputParticlesFinal); ACTS_PYTHON_MEMBER(rhoMin); ACTS_PYTHON_MEMBER(rhoMax); ACTS_PYTHON_MEMBER(absZMin); diff --git a/Examples/Python/tests/root_file_hashes.txt b/Examples/Python/tests/root_file_hashes.txt index 54c81ea9ba1..077296bac57 100644 --- a/Examples/Python/tests/root_file_hashes.txt +++ b/Examples/Python/tests/root_file_hashes.txt @@ -6,12 +6,12 @@ test_geant4__hits.root: adf5dcdf000a580412dc5089e17460897d6535c978eafa021584ba42 test_seeding__estimatedparams.root: 69c0e268f9025a0991a212ea2a7f26f53112fecf614b475605bd1cb08415ba56 test_seeding__performance_seeding.root: 992f9c611d30dde0d3f3ab676bab19ada61ab6a4442828e27b65ec5e5b7a2880 test_seeding__particles.root: 7855b021f39ad238bca098e4282667be0666f2d1630e5bcb9d51d3b5ee39fa14 -test_seeding__particles_simulation.root: 87d9c6c82422ca381a17735096b36c547eacb5dda2f26d7377614bd97a70ab1a +test_seeding__particles_simulation.root: f937a4cc474e80cfbb6eac4384e42e9c5c7ac981fcd6870d624cc898d1a0c006 test_hashing_seeding__estimatedparams.root: 1f43b760e80089b5674e106d00d962d74be564cbf33ae38222052ebb6f9cbf3a test_seeding_orthogonal__estimatedparams.root: ca5896ec325daf5c8012291bc454269c61c32fe3d7e33bd1fa3b812826930299 test_seeding_orthogonal__performance_seeding.root: 60fbedcf5cb2b37cd8e526251940564432890d3a159d231ed819e915a904682c test_seeding_orthogonal__particles.root: 7855b021f39ad238bca098e4282667be0666f2d1630e5bcb9d51d3b5ee39fa14 -test_seeding_orthogonal__particles_simulation.root: 87d9c6c82422ca381a17735096b36c547eacb5dda2f26d7377614bd97a70ab1a +test_seeding_orthogonal__particles_simulation.root: f937a4cc474e80cfbb6eac4384e42e9c5c7ac981fcd6870d624cc898d1a0c006 test_itk_seeding__estimatedparams.root: 1cc05f9f2aefb5f71a85b31e97bc4e5845fedfcef6c53199495a6340c6b6210b test_itk_seeding__performance_seeding.root: 78ebda54cd0f026ba4b7f316724ffd946de56a932735914baf1b7bba9505c29d test_itk_seeding__particles.root: 0b6f4ad438010ac48803d48ed98e80b5e87d310bae6c2c02b16cd94d7a4d7d07 diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index d5bb593ca9f..9a2c45c7657 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -407,6 +407,7 @@ def test_itk_seeding(tmp_path, trk_geo, field, assert_root_hash): EtaConfig, MomentumConfig, ParticleConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) @@ -428,6 +429,12 @@ def test_itk_seeding(tmp_path, trk_geo, field, assert_root_hash): outputDirCsv=tmp_path / "csv", outputDirRoot=str(tmp_path), rnd=rnd, + postSelectParticles=ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + eta=(-4, 4), + measurements=(9, None), + removeNeutral=True, + ), ) srcdir = Path(__file__).resolve().parent.parent.parent.parent @@ -442,7 +449,6 @@ def test_itk_seeding(tmp_path, trk_geo, field, assert_root_hash): from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, ) from acts.examples.itk import itkSeedingAlgConfig, InputSpacePointsType @@ -450,7 +456,6 @@ def test_itk_seeding(tmp_path, trk_geo, field, assert_root_hash): seq, trk_geo, field, - TruthSeedRanges(pt=(1.0 * u.GeV, None), eta=(-4, 4), nHits=(9, None)), *itkSeedingAlgConfig(InputSpacePointsType.PixelSpacePoints), acts.logging.VERBOSE, geoSelectionConfigFile=srcdir diff --git a/Examples/Scripts/Optimization/ckf.py b/Examples/Scripts/Optimization/ckf.py index bf927850ecc..c1761141262 100755 --- a/Examples/Scripts/Optimization/ckf.py +++ b/Examples/Scripts/Optimization/ckf.py @@ -116,13 +116,13 @@ def runCKFTracks( EtaConfig, PhiConfig, ParticleConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, ParticleSmearingSigmas, SeedFinderConfigArg, SeedFinderOptionsArg, @@ -169,6 +169,11 @@ def runCKFTracks( trackingGeometry, field, rnd=rnd, + postSelectParticles=ParticleSelectorConfig( + pt=(0.5 * u.GeV, None), + measurements=(9, None), + removeNeutral=True, + ), ) addDigitization( @@ -183,7 +188,6 @@ def runCKFTracks( s, trackingGeometry, field, - TruthSeedRanges(pt=(500.0 * u.MeV, None), nHits=(9, None)), ParticleSmearingSigmas( # only used by SeedingAlgorithm.TruthSmeared # zero eveything so the CKF has a chance to find the measurements d0=0, diff --git a/Examples/Scripts/Python/ckf_tracks.py b/Examples/Scripts/Python/ckf_tracks.py index 9dc665eb835..e2b24436c0a 100755 --- a/Examples/Scripts/Python/ckf_tracks.py +++ b/Examples/Scripts/Python/ckf_tracks.py @@ -27,13 +27,13 @@ def runCKFTracks( EtaConfig, PhiConfig, ParticleConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, ParticleSmearingSigmas, SeedFinderConfigArg, SeedFinderOptionsArg, @@ -80,6 +80,11 @@ def runCKFTracks( trackingGeometry, field, rnd=rnd, + postSelectParticles=ParticleSelectorConfig( + pt=(0.5 * u.GeV, None), + measurements=(9, None), + removeNeutral=True, + ), ) addDigitization( @@ -94,7 +99,6 @@ def runCKFTracks( s, trackingGeometry, field, - TruthSeedRanges(pt=(500.0 * u.MeV, None), nHits=(9, None)), ParticleSmearingSigmas( # only used by SeedingAlgorithm.TruthSmeared # zero eveything so the CKF has a chance to find the measurements d0=0, diff --git a/Examples/Scripts/Python/full_chain_itk.py b/Examples/Scripts/Python/full_chain_itk.py index 5e268f87fcb..51746c127a1 100755 --- a/Examples/Scripts/Python/full_chain_itk.py +++ b/Examples/Scripts/Python/full_chain_itk.py @@ -5,6 +5,7 @@ MomentumConfig, EtaConfig, ParticleConfig, + ParticleSelectorConfig, addPythia8, addFatras, ParticleSelectorConfig, @@ -13,7 +14,6 @@ from acts.examples.reconstruction import ( addSeeding, SeedingAlgorithm, - TruthSeedRanges, addCKFTracks, CkfConfig, TrackSelectorConfig, @@ -72,6 +72,12 @@ if ttbar_pu200 else ParticleSelectorConfig() ), + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-4.0, 4.0), + measurements=(9, None), + removeNeutral=True, + ), outputDirRoot=outputDir, ) @@ -88,11 +94,6 @@ s, trackingGeometry, field, - ( - TruthSeedRanges(pt=(1.0 * u.GeV, None), eta=(-4.0, 4.0), nHits=(9, None)) - if ttbar_pu200 - else TruthSeedRanges() - ), seedingAlgorithm=SeedingAlgorithm.Default, *acts.examples.itk.itkSeedingAlgConfig( acts.examples.itk.InputSpacePointsType.PixelSpacePoints diff --git a/Examples/Scripts/Python/full_chain_itk_Gbts.py b/Examples/Scripts/Python/full_chain_itk_Gbts.py index 7a45b7e5a71..a87f5ca6656 100755 --- a/Examples/Scripts/Python/full_chain_itk_Gbts.py +++ b/Examples/Scripts/Python/full_chain_itk_Gbts.py @@ -5,6 +5,7 @@ MomentumConfig, EtaConfig, ParticleConfig, + ParticleSelectorConfig, addPythia8, addFatras, ParticleSelectorConfig, @@ -13,7 +14,6 @@ from acts.examples.reconstruction import ( addSeeding, SeedingAlgorithm, - TruthSeedRanges, addCKFTracks, TrackSelectorConfig, ) @@ -67,6 +67,12 @@ if ttbar_pu200 else ParticleSelectorConfig() ), + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-4.0, 4.0), + measurements=(9, None), + removeNeutral=True, + ), outputDirRoot=outputDir, ) @@ -84,11 +90,6 @@ s, trackingGeometry, field, - ( - TruthSeedRanges(pt=(1.0 * u.GeV, None), eta=(-4.0, 4.0), nHits=(9, None)) - if ttbar_pu200 - else TruthSeedRanges() - ), seedingAlgorithm=SeedingAlgorithm.Gbts, *acts.examples.itk.itkSeedingAlgConfig( acts.examples.itk.InputSpacePointsType.PixelSpacePoints diff --git a/Examples/Scripts/Python/full_chain_odd.py b/Examples/Scripts/Python/full_chain_odd.py index 22f20d3b257..fd98f759577 100755 --- a/Examples/Scripts/Python/full_chain_odd.py +++ b/Examples/Scripts/Python/full_chain_odd.py @@ -13,6 +13,7 @@ EtaConfig, PhiConfig, ParticleConfig, + ParticleSelectorConfig, addPythia8, addFatras, addGeant4, @@ -22,7 +23,6 @@ ) from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, CkfConfig, addCKFTracks, TrackSelectorConfig, @@ -271,6 +271,12 @@ pt=(150 * u.MeV, None), removeNeutral=True, ), + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-3.0, 3.0), + measurements=(9, None), + removeNeutral=True, + ), outputDirRoot=outputDir if args.output_root else None, outputDirCsv=outputDir if args.output_csv else None, rnd=rnd, @@ -293,6 +299,12 @@ if args.ttbar else ParticleSelectorConfig() ), + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-3.0, 3.0), + measurements=(9, None), + removeNeutral=True, + ), enableInteractions=True, outputDirRoot=outputDir if args.output_root else None, outputDirCsv=outputDir if args.output_csv else None, @@ -314,11 +326,6 @@ s, trackingGeometry, field, - ( - TruthSeedRanges(pt=(1.0 * u.GeV, None), eta=(-3.0, 3.0), nHits=(9, None)) - if args.ttbar - else TruthSeedRanges() - ), initialSigmas=[ 1 * u.mm, 1 * u.mm, diff --git a/Examples/Scripts/Python/full_chain_odd_LRT.py b/Examples/Scripts/Python/full_chain_odd_LRT.py index a5fd294ceda..2188bb98d6b 100644 --- a/Examples/Scripts/Python/full_chain_odd_LRT.py +++ b/Examples/Scripts/Python/full_chain_odd_LRT.py @@ -21,7 +21,6 @@ ) from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, CkfConfig, addCKFTracks, TrackSelectorConfig, @@ -273,6 +272,12 @@ pt=(150 * u.MeV, None), removeNeutral=True, ), + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-3.0, 3.0), + measurements=(9, None), + removeNeutral=True, + ), outputDirRoot=outputDir if args.output_root else None, outputDirCsv=outputDir if args.output_csv else None, rnd=rnd, @@ -295,6 +300,12 @@ if args.ttbar else ParticleSelectorConfig() ), + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-3.0, 3.0), + measurements=(9, None), + removeNeutral=True, + ), enableInteractions=True, outputDirRoot=outputDir if args.output_root else None, outputDirCsv=outputDir if args.output_csv else None, @@ -316,11 +327,6 @@ s, trackingGeometry, field, - ( - TruthSeedRanges(pt=(1.0 * u.GeV, None), eta=(-3.0, 3.0), nHits=(9, None)) - if args.ttbar - else TruthSeedRanges() - ), geoSelectionConfigFile=oddSeedingSel, outputDirRoot=outputDir if args.output_root else None, outputDirCsv=outputDir if args.output_csv else None, diff --git a/Examples/Scripts/Python/hashing_seeding.py b/Examples/Scripts/Python/hashing_seeding.py index a5608a0f329..3148a03837d 100755 --- a/Examples/Scripts/Python/hashing_seeding.py +++ b/Examples/Scripts/Python/hashing_seeding.py @@ -14,7 +14,6 @@ from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, addCKFTracks, TrackSelectorConfig, SeedingAlgorithm, @@ -210,7 +209,15 @@ def runHashingSeeding( trackingGeometry, field, preSelectParticles=ParticleSelectorConfig( - eta=(-eta, eta), pt=(150 * u.MeV, None), removeNeutral=True + eta=(-eta, eta), + pt=(150 * u.MeV, None), + removeNeutral=True, + ), + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-eta, eta), + measurements=(9, None), + removeNeutral=True, ), enableInteractions=True, # outputDirRoot=outputDir, # RootParticle ERROR when setting the outputDirRoot @@ -272,7 +279,6 @@ def runHashingSeeding( seedFinderOptionsArg, hashingTrainingConfigArg, hashingAlgorithmConfigArg, - TruthSeedRanges(pt=(1.0 * u.GeV, None), eta=(-eta, eta), nHits=(9, None)), seedingAlgorithm=seedingAlgorithm, geoSelectionConfigFile=geoSelectionConfigFile, initialSigmas=initialSigmas, @@ -338,10 +344,6 @@ def runHashingSeeding( phiBins=phiBins, ) - truthSeedRanges = TruthSeedRanges( - pt=(1.0 * u.GeV, None), eta=(-eta, eta), nHits=(9, None) - ) - doHashing = config.doHashing bucketSize = config.bucketSize npileup = config.mu diff --git a/Examples/Scripts/Python/seeding.py b/Examples/Scripts/Python/seeding.py index 4c87ba9b82b..e50f9390c12 100755 --- a/Examples/Scripts/Python/seeding.py +++ b/Examples/Scripts/Python/seeding.py @@ -57,6 +57,7 @@ def runSeeding( EtaConfig, PhiConfig, ParticleConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) @@ -86,6 +87,12 @@ def runSeeding( outputDirRoot=outputDir, rnd=rnd, preSelectParticles=None, + postSelectParticles=ParticleSelectorConfig( + pt=(1.0 * u.GeV, None), + eta=(-2.5, 2.5), + measurements=(9, None), + removeNeutral=True, + ), ) srcdir = Path(__file__).resolve().parent.parent.parent.parent @@ -99,7 +106,6 @@ def runSeeding( ) from acts.examples.reconstruction import ( addSeeding, - TruthSeedRanges, SeedFinderConfigArg, SeedFinderOptionsArg, ) @@ -108,7 +114,6 @@ def runSeeding( s, trackingGeometry, field, - TruthSeedRanges(pt=(1.0 * u.GeV, None), eta=(-2.5, 2.5), nHits=(9, None)), SeedFinderConfigArg( r=(None, 200 * u.mm), # rMin=default, 33mm deltaR=(1 * u.mm, 60 * u.mm), diff --git a/Examples/Scripts/Python/truth_tracking_gsf.py b/Examples/Scripts/Python/truth_tracking_gsf.py index 82c99bb38aa..ae8aca06d6c 100755 --- a/Examples/Scripts/Python/truth_tracking_gsf.py +++ b/Examples/Scripts/Python/truth_tracking_gsf.py @@ -24,13 +24,13 @@ def runTruthTrackingGsf( EtaConfig, PhiConfig, MomentumConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) from acts.examples.reconstruction import ( addSeeding, SeedingAlgorithm, - TruthSeedRanges, addTruthTrackingGsf, ) @@ -77,6 +77,12 @@ def runTruthTrackingGsf( field, rnd=rnd, enableInteractions=True, + postSelectParticles=ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + measurements=(7, None), + removeNeutral=True, + removeSecondaries=True, + ), ) addDigitization( @@ -95,9 +101,6 @@ def runTruthTrackingGsf( inputParticles="particles_input", seedingAlgorithm=SeedingAlgorithm.TruthSmeared, particleHypothesis=acts.ParticleHypothesis.electron, - truthSeedRanges=TruthSeedRanges( - nHits=(7, None), - ), ) addTruthTrackingGsf( @@ -122,7 +125,7 @@ def runTruthTrackingGsf( acts.examples.RootTrackStatesWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", inputSimHits="simhits", inputMeasurementSimHitsMap="measurement_simhits_map", @@ -134,7 +137,7 @@ def runTruthTrackingGsf( acts.examples.RootTrackSummaryWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", filePath=str(outputDir / "tracksummary_gsf.root"), writeGsfSpecific=True, @@ -145,7 +148,7 @@ def runTruthTrackingGsf( acts.examples.TrackFitterPerformanceWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", filePath=str(outputDir / "performance_gsf.root"), ) diff --git a/Examples/Scripts/Python/truth_tracking_gsf_refitting.py b/Examples/Scripts/Python/truth_tracking_gsf_refitting.py index e8b41c9aae8..686f4af06c2 100755 --- a/Examples/Scripts/Python/truth_tracking_gsf_refitting.py +++ b/Examples/Scripts/Python/truth_tracking_gsf_refitting.py @@ -54,7 +54,7 @@ def runRefittingGsf( acts.examples.TrackTruthMatcher( level=acts.logging.INFO, inputTracks="gsf_refit_tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputMeasurementParticlesMap="measurement_particles_map", outputTrackParticleMatching="refit_track_particle_matching", outputParticleTrackMatching="refit_particle_track_matching", @@ -65,7 +65,7 @@ def runRefittingGsf( acts.examples.RootTrackStatesWriter( level=acts.logging.INFO, inputTracks="gsf_refit_tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="refit_track_particle_matching", inputSimHits="simhits", inputMeasurementSimHitsMap="measurement_simhits_map", @@ -77,7 +77,7 @@ def runRefittingGsf( acts.examples.RootTrackSummaryWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="refit_track_particle_matching", filePath=str(outputDir / "tracksummary_gsf_refit.root"), ) @@ -87,7 +87,7 @@ def runRefittingGsf( acts.examples.TrackFitterPerformanceWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", filePath=str(outputDir / "performance_gsf_refit.root"), ) diff --git a/Examples/Scripts/Python/truth_tracking_gx2f.py b/Examples/Scripts/Python/truth_tracking_gx2f.py index 46352ac8d21..8503dc982f4 100644 --- a/Examples/Scripts/Python/truth_tracking_gx2f.py +++ b/Examples/Scripts/Python/truth_tracking_gx2f.py @@ -23,13 +23,13 @@ def runTruthTrackingGx2f( EtaConfig, PhiConfig, MomentumConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) from acts.examples.reconstruction import ( addSeeding, SeedingAlgorithm, - TruthSeedRanges, addGx2fTracks, ) @@ -74,6 +74,12 @@ def runTruthTrackingGx2f( field, rnd=rnd, enableInteractions=True, + postSelectParticles=ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + measurements=(7, None), + removeNeutral=True, + removeSecondaries=True, + ), ) addDigitization( @@ -92,9 +98,6 @@ def runTruthTrackingGx2f( inputParticles="particles_input", seedingAlgorithm=SeedingAlgorithm.TruthSmeared, particleHypothesis=acts.ParticleHypothesis.muon, - truthSeedRanges=TruthSeedRanges( - nHits=(7, None), - ), ) addGx2fTracks( @@ -122,7 +125,7 @@ def runTruthTrackingGx2f( acts.examples.RootTrackStatesWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", inputSimHits="simhits", inputMeasurementSimHitsMap="measurement_simhits_map", @@ -134,7 +137,7 @@ def runTruthTrackingGx2f( acts.examples.RootTrackSummaryWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", filePath=str(outputDir / "tracksummary_gx2f.root"), writeGx2fSpecific=True, @@ -145,7 +148,7 @@ def runTruthTrackingGx2f( acts.examples.TrackFitterPerformanceWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", filePath=str(outputDir / "performance_gx2f.root"), ) diff --git a/Examples/Scripts/Python/truth_tracking_kalman.py b/Examples/Scripts/Python/truth_tracking_kalman.py index 276cb962c8f..91c18f1dd28 100755 --- a/Examples/Scripts/Python/truth_tracking_kalman.py +++ b/Examples/Scripts/Python/truth_tracking_kalman.py @@ -27,13 +27,13 @@ def runTruthTrackingKalman( EtaConfig, PhiConfig, MomentumConfig, + ParticleSelectorConfig, addFatras, addDigitization, ) from acts.examples.reconstruction import ( addSeeding, SeedingAlgorithm, - TruthSeedRanges, addKalmanTracks, ) @@ -82,6 +82,12 @@ def runTruthTrackingKalman( field, rnd=rnd, enableInteractions=True, + postSelectParticles=ParticleSelectorConfig( + pt=(0.9 * u.GeV, None), + measurements=(7, None), + removeNeutral=True, + removeSecondaries=True, + ), ) else: logger.info("Reading hits from %s", inputHitsPath.resolve()) @@ -110,9 +116,6 @@ def runTruthTrackingKalman( inputParticles="particles_input", seedingAlgorithm=SeedingAlgorithm.TruthSmeared, particleHypothesis=acts.ParticleHypothesis.muon, - truthSeedRanges=TruthSeedRanges( - nHits=(7, None), - ), ) addKalmanTracks( @@ -139,7 +142,7 @@ def runTruthTrackingKalman( acts.examples.RootTrackStatesWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", inputSimHits="simhits", inputMeasurementSimHitsMap="measurement_simhits_map", @@ -151,7 +154,7 @@ def runTruthTrackingKalman( acts.examples.RootTrackSummaryWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", filePath=str(outputDir / "tracksummary_kf.root"), ) @@ -161,7 +164,7 @@ def runTruthTrackingKalman( acts.examples.TrackFitterPerformanceWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", filePath=str(outputDir / "performance_kf.root"), ) diff --git a/Examples/Scripts/Python/truth_tracking_kalman_refitting.py b/Examples/Scripts/Python/truth_tracking_kalman_refitting.py index 7e795b9e310..46578423f33 100755 --- a/Examples/Scripts/Python/truth_tracking_kalman_refitting.py +++ b/Examples/Scripts/Python/truth_tracking_kalman_refitting.py @@ -51,7 +51,7 @@ def runRefittingKf( acts.examples.TrackTruthMatcher( level=acts.logging.INFO, inputTracks="kf_refit_tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputMeasurementParticlesMap="measurement_particles_map", outputTrackParticleMatching="refit_track_particle_matching", outputParticleTrackMatching="refit_particle_track_matching", @@ -62,7 +62,7 @@ def runRefittingKf( acts.examples.RootTrackStatesWriter( level=acts.logging.INFO, inputTracks="kf_refit_tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="refit_track_particle_matching", inputSimHits="simhits", inputMeasurementSimHitsMap="measurement_simhits_map", @@ -74,7 +74,7 @@ def runRefittingKf( acts.examples.RootTrackSummaryWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="refit_track_particle_matching", filePath=str(outputDir / "tracksummary_kf_refit.root"), ) @@ -84,7 +84,7 @@ def runRefittingKf( acts.examples.TrackFitterPerformanceWriter( level=acts.logging.INFO, inputTracks="tracks", - inputParticles="truth_seeds_selected", + inputParticles="particles_selected", inputTrackParticleMatching="track_particle_matching", filePath=str(outputDir / "performance_kf_refit.root"), )