diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 9a17048cdd5..c2ece0d20f2 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,41 +1,7 @@ -PLEASE FOLLOW THE CHECKLIST BELOW WHEN CREATING A NEW PULL REQUEST. THE -CHECKLIST IS FOR YOUR INFORMATION AND MUST BE REMOVED BEFORE SUBMITTING THE PULL -REQUEST. +PLEASE DESCRIBE YOUR CHANGES. +THIS MESSAGE ENDS UP AS THE COMMIT MESSAGE. +DO NOT USE @-MENTIONS HERE! -## Checklist +--- END COMMIT MESSAGE --- -- [ ] Does the PR title follow the `: title` scheme? - - The prefix must be one of: - - - `fix`: for a bugfix - - `feat`: for a new feature - - `refactor`: for an improvement of an existing feature - - `perf`, `test`: for performance- or test-related changes - - `docs`: for documentation-related changes - - `build`, `ci`, `chore`: as appropriated for infrastructure changes - -- [ ] Does this modify the public API as defined in `docs/versioning.rst`? - - - [ ] Does the PR title contain a `!` to indicate a breaking change? - - [ ] Is there section starting with `BREAKING CHANGE:` in the PR body - that explains the breaking change? - -- [ ] Is the PR ready to be merged? - - - [ ] If not: is it marked as a draft PR? - -- [ ] Does this PR close an existing issue? - - - [ ] Is the issue correctly linked so it will be automatically closed - upon successful merge (See closing keywords link in the sidebar)? - -- The CI will initially report a missing milestone. One of the maintainers will - handle assigning a milestone for book-keeping. - -- An automated workflow will assign labels based on changed files, and whether - or not reference files were changed. These do not have to be set manually. - -- If you push updates, and you know they will be superseded later on, consider adding - `[skip ci]` in the commit message. This will instruct the CI system not to run any - jobs on this commit. +Any further description goes here, @-mentions are ok here! diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml index c946b38cd66..f33bb927f40 100644 --- a/.github/workflows/analysis.yml +++ b/.github/workflows/analysis.yml @@ -22,7 +22,7 @@ env: CCACHE_MAXSIZE: 1.25G CCACHE_KEY_SUFFIX: r2 ACTS_LOG_FAILURE_THRESHOLD: WARNING - DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.v4.tar.zst + DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.v5.tar.zst # NOTE this only builds core unittests to reduce the output size. if we # found a way to have Github actions not fail regularly with this job diff --git a/.github/workflows/builds.yml b/.github/workflows/builds.yml index 010b7ff8963..2d565795d9f 100644 --- a/.github/workflows/builds.yml +++ b/.github/workflows/builds.yml @@ -20,6 +20,7 @@ env: CCACHE_DIR: ${{ github.workspace }}/ccache CCACHE_MAXSIZE: 500M CCACHE_KEY_SUFFIX: r2 + DEPENDENCY_TAG: v5 jobs: linux_ubuntu: @@ -28,7 +29,6 @@ jobs: env: INSTALL_DIR: ${{ github.workspace }}/install ACTS_LOG_FAILURE_THRESHOLD: WARNING - DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.v4.tar.zst steps: - uses: actions/checkout@v4 @@ -36,6 +36,9 @@ jobs: submodules: true lfs: true + - name: Set dependencies URL + run: echo "DEPENDENCY_URL=https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.${DEPENDENCY_TAG}.tar.zst" >> $GITHUB_ENV + - name: Install dependencies run: CI/dependencies.sh @@ -114,7 +117,6 @@ jobs: needs: [linux_ubuntu] env: ACTS_SEQUENCER_DISABLE_FPEMON: true - DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.v4.tar.zst steps: - uses: actions/checkout@v4 @@ -122,6 +124,9 @@ jobs: submodules: true lfs: true + - name: Set dependencies URL + run: echo "DEPENDENCY_URL=https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.${DEPENDENCY_TAG}.tar.zst" >> $GITHUB_ENV + - name: Install dependencies run: CI/dependencies.sh @@ -152,7 +157,6 @@ jobs: needs: [linux_ubuntu] env: ACTS_SEQUENCER_DISABLE_FPEMON: true - DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.v4.tar.zst steps: - uses: actions/checkout@v4 @@ -161,6 +165,10 @@ jobs: lfs: true - run: apt-get update && apt-get install -y time + + - name: Set dependencies URL + run: echo "DEPENDENCY_URL=https://acts.web.cern.ch/ACTS/ci/ubuntu-24.04/deps.${DEPENDENCY_TAG}.tar.zst" >> $GITHUB_ENV + - name: Install dependencies run: CI/dependencies.sh @@ -246,13 +254,16 @@ jobs: env: INSTALL_DIR: ${{ github.workspace }}/install ACTS_LOG_FAILURE_THRESHOLD: WARNING - DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/ubuntu-22.04/deps.v4.tar.zst + steps: - uses: actions/checkout@v4 with: submodules: true lfs: true + - name: Set dependencies URL + run: echo "DEPENDENCY_URL=https://acts.web.cern.ch/ACTS/ci/ubuntu-22.04/deps.${DEPENDENCY_TAG}.tar.zst" >> $GITHUB_ENV + - name: Install dependencies run: CI/dependencies.sh @@ -320,7 +331,7 @@ jobs: env: INSTALL_DIR: ${{ github.workspace }}/install_acts ACTS_LOG_FAILURE_THRESHOLD: WARNING - DEPENDENCY_URL: https://acts.web.cern.ch/ACTS/ci/macos-14/deps.v4.tar.zst + steps: - uses: actions/checkout@v4 with: @@ -330,6 +341,9 @@ jobs: - name: Print architecture run: uname -p + - name: Set dependencies URL + run: echo "DEPENDENCY_URL=https://acts.web.cern.ch/ACTS/ci/macos-14/deps.${DEPENDENCY_TAG}.tar.zst" >> $GITHUB_ENV + - name: Install dependencies run: > brew install cmake ninja ccache xerces-c diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a5cbbce542e..4c6a7b166fc 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,7 +4,7 @@ variables: CCACHE_KEY_SUFFIX: r2 CTEST_OUTPUT_ON_FAILURE: 1 - DEPENDENCY_TAG: v4 + DEPENDENCY_TAG: v5 clang_tidy: stage: build diff --git a/.kodiak.toml b/.kodiak.toml index b5be47df1ee..651905f7ce0 100644 --- a/.kodiak.toml +++ b/.kodiak.toml @@ -2,7 +2,7 @@ version = 1 merge.message.title = "pull_request_title" merge.message.body = "pull_request_body" -merge.message.cut_body_before = "--- BEGIN COMMIT MESSAGE ---" +merge.message.cut_body_after = "--- END COMMIT MESSAGE ---" merge.message.cut_body_and_text = true merge.method = "squash" merge.message.include_coauthors = true diff --git a/CI/check_unused_files.py b/CI/check_unused_files.py index 420ba932d14..c1f099d672a 100755 --- a/CI/check_unused_files.py +++ b/CI/check_unused_files.py @@ -41,8 +41,6 @@ def main(): ".gitignore", "README.md", "CMakeLists.txt", - "DetUtils.h", - "CommandLineArguments.h", # Filename not completed in source "vertexing_event_mu20_beamspot.csv", "vertexing_event_mu20_tracks.csv", diff --git a/CI/physmon/workflows/physmon_simulation.py b/CI/physmon/workflows/physmon_simulation.py index 746c68c39aa..37874663187 100755 --- a/CI/physmon/workflows/physmon_simulation.py +++ b/CI/physmon/workflows/physmon_simulation.py @@ -64,6 +64,14 @@ ) ) + s.addWriter( + acts.examples.RootParticleWriter( + level=acts.logging.INFO, + inputParticles="particles_input", + filePath=tp / "particles.root", + ) + ) + addFatras( s, setup.trackingGeometry, @@ -100,6 +108,7 @@ s.run() for file, name in [ + (tp / "particles.root", "particles_gun.root"), (tp / "fatras" / "particles_simulation.root", "particles_fatras.root"), (tp / "geant4" / "particles_simulation.root", "particles_geant4.root"), ]: @@ -135,8 +144,8 @@ s.run() for file, name in [ - (tp / "pythia8_particles.root", "particles_ttbar.root"), - (tp / "pythia8_vertices.root", "vertices_ttbar.root"), + (tp / "particles.root", "particles_ttbar.root"), + (tp / "vertices.root", "vertices_ttbar.root"), ]: assert file.exists(), "file not found" shutil.copy(file, setup.outdir / name) diff --git a/CMakeLists.txt b/CMakeLists.txt index f81002cab83..f5209e0d210 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,7 +73,6 @@ option(ACTS_BUILD_EXAMPLES_HEPMC3 "Build HepMC3-based code in the examples" OFF) option(ACTS_BUILD_EXAMPLES_HASHING "Build Hashing-based code in the examples" OFF) option(ACTS_BUILD_EXAMPLES_PYTHIA8 "Build Pythia8-based code in the examples" OFF) option(ACTS_BUILD_EXAMPLES_PYTHON_BINDINGS "Build python bindings for the examples" OFF) -option(ACTS_USE_EXAMPLES_TBB "Use Threading Building Blocks library in the examples" ON) option(ACTS_BUILD_ANALYSIS_APPS "Build Analysis applications in the examples" OFF) # test related options option(ACTS_BUILD_BENCHMARKS "Build benchmarks" OFF) diff --git a/Core/include/Acts/EventData/GenericBoundTrackParameters.hpp b/Core/include/Acts/EventData/GenericBoundTrackParameters.hpp index f624cd88aee..38f297764b1 100644 --- a/Core/include/Acts/EventData/GenericBoundTrackParameters.hpp +++ b/Core/include/Acts/EventData/GenericBoundTrackParameters.hpp @@ -9,6 +9,7 @@ #pragma once #include "Acts/Definitions/Tolerance.hpp" +#include "Acts/EventData/TrackParameterHelpers.hpp" #include "Acts/EventData/TransformationHelpers.hpp" #include "Acts/EventData/detail/PrintParameters.hpp" #include "Acts/Surfaces/Surface.hpp" @@ -18,7 +19,6 @@ #include #include #include -#include namespace Acts { @@ -61,7 +61,10 @@ class GenericBoundTrackParameters { m_cov(std::move(cov)), m_surface(std::move(surface)), m_particleHypothesis(std::move(particleHypothesis)) { - assert(m_surface); + // TODO set `validateAngleRange` to `true` after fixing caller code + assert(isBoundVectorValid(m_params, false) && + "Invalid bound parameters vector"); + assert(m_surface != nullptr && "Reference surface must not be null"); normalizePhiTheta(); } diff --git a/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp b/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp index 214aa2e1551..7a2b4b46522 100644 --- a/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp +++ b/Core/include/Acts/EventData/GenericFreeTrackParameters.hpp @@ -11,6 +11,7 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/Common.hpp" #include "Acts/Definitions/TrackParametrization.hpp" +#include "Acts/EventData/TrackParameterHelpers.hpp" #include "Acts/EventData/TrackParametersConcept.hpp" #include "Acts/EventData/TransformationHelpers.hpp" #include "Acts/EventData/detail/PrintParameters.hpp" @@ -18,10 +19,8 @@ #include "Acts/Utilities/UnitVectors.hpp" #include "Acts/Utilities/VectorHelpers.hpp" -#include #include #include -#include namespace Acts { @@ -55,7 +54,9 @@ class GenericFreeTrackParameters { ParticleHypothesis particleHypothesis) : m_params(params), m_cov(std::move(cov)), - m_particleHypothesis(std::move(particleHypothesis)) {} + m_particleHypothesis(std::move(particleHypothesis)) { + assert(isFreeVectorValid(m_params) && "Invalid free parameters vector"); + } /// Construct from four-position, direction, absolute momentum, and charge. /// @@ -78,6 +79,8 @@ class GenericFreeTrackParameters { m_params[eFreeDir1] = dir[eMom1]; m_params[eFreeDir2] = dir[eMom2]; m_params[eFreeQOverP] = qOverP; + + assert(isFreeVectorValid(m_params) && "Invalid free parameters vector"); } /// Construct from four-position, angles, absolute momentum, and charge. @@ -103,6 +106,8 @@ class GenericFreeTrackParameters { m_params[eFreeDir1] = dir[eMom1]; m_params[eFreeDir2] = dir[eMom2]; m_params[eFreeQOverP] = qOverP; + + assert(isFreeVectorValid(m_params) && "Invalid free parameters vector"); } /// Converts a free track parameter with a different hypothesis. diff --git a/Core/include/Acts/EventData/Seed.hpp b/Core/include/Acts/EventData/Seed.hpp index db93b319dcb..f3c6707b2e1 100644 --- a/Core/include/Acts/EventData/Seed.hpp +++ b/Core/include/Acts/EventData/Seed.hpp @@ -14,8 +14,9 @@ namespace Acts { template - requires(N >= 3ul) class Seed { + static_assert(N >= 3ul); + public: using value_type = external_spacepoint_t; static constexpr std::size_t DIM = N; diff --git a/Core/include/Acts/EventData/Seed.ipp b/Core/include/Acts/EventData/Seed.ipp index 74f2c0e4169..e977a3d67d7 100644 --- a/Core/include/Acts/EventData/Seed.ipp +++ b/Core/include/Acts/EventData/Seed.ipp @@ -9,7 +9,6 @@ namespace Acts { template - requires(N >= 3ul) template requires(sizeof...(args_t) == N) && (std::same_as && ...) @@ -17,32 +16,27 @@ Seed::Seed(const args_t&... points) : m_spacepoints({&points...}) {} template - requires(N >= 3ul) void Seed::setVertexZ(float vertex) { m_vertexZ = vertex; } template - requires(N >= 3ul) void Seed::setQuality(float seedQuality) { m_seedQuality = seedQuality; } template - requires(N >= 3ul) const std::array& Seed::sp() const { return m_spacepoints; } template - requires(N >= 3ul) float Seed::z() const { return m_vertexZ; } template - requires(N >= 3ul) float Seed::seedQuality() const { return m_seedQuality; } diff --git a/Core/include/Acts/EventData/TrackParameterHelpers.hpp b/Core/include/Acts/EventData/TrackParameterHelpers.hpp index cd68b5ae6a4..df40c934824 100644 --- a/Core/include/Acts/EventData/TrackParameterHelpers.hpp +++ b/Core/include/Acts/EventData/TrackParameterHelpers.hpp @@ -8,12 +8,41 @@ #pragma once -#include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/Utilities/detail/periodic.hpp" +#include + namespace Acts { +/// Check if a bound vector is valid. This checks the following: +/// - All values are finite +/// - (optionally) The phi value is in the range [-pi, pi) +/// - (optionally) The theta value is in the range [0, pi] +/// +/// @param v The bound vector to check +/// @param validateAngleRange If true, the phi and theta values are range checked +/// @param epsilon The epsilon to use for the checks +/// @param maxAbsEta The maximum allowed eta value +/// +/// @return True if the bound vector is valid +bool isBoundVectorValid( + const BoundVector& v, bool validateAngleRange, double epsilon = 1e-6, + double maxAbsEta = std::numeric_limits::infinity()); + +/// Check if a free vector is valid. This checks the following: +/// - All values are finite +/// - Direction is normalized +/// +/// @param v The free vector to check +/// @param epsilon The epsilon to use for the checks +/// @param maxAbsEta The maximum allowed eta value +/// +/// @return True if the free vector is valid +bool isFreeVectorValid( + const FreeVector& v, double epsilon = 1e-6, + double maxAbsEta = std::numeric_limits::infinity()); + /// Normalize the bound parameter angles /// /// @param boundParams The bound parameters to normalize @@ -26,8 +55,20 @@ inline BoundVector normalizeBoundParameters(const BoundVector& boundParams) { return result; } +/// Add bound parameters and take care of angle periodicity for phi and theta. +/// This is intended for small differences only i.e. KF updates. +/// +/// @param lhs The left hand side bound parameters +/// @param rhs The right hand side bound parameters +/// +/// @return The sum of the bound parameters +inline BoundVector addBoundParameters(const BoundVector& lhs, + const BoundVector& rhs) { + return normalizeBoundParameters(lhs + rhs); +} + /// Subtract bound parameters and take care of angle periodicity for phi and -/// theta. +/// theta. This is intended for small differences only i.e. KF updates. /// /// @param lhs The left hand side bound parameters /// @param rhs The right hand side bound parameters @@ -36,8 +77,8 @@ inline BoundVector normalizeBoundParameters(const BoundVector& boundParams) { inline BoundVector subtractBoundParameters(const BoundVector& lhs, const BoundVector& rhs) { BoundVector result = lhs - rhs; - result[eBoundPhi] = - detail::difference_periodic(lhs[eBoundPhi], rhs[eBoundPhi], 2 * M_PI); + result[eBoundPhi] = detail::radian_sym(result[eBoundPhi]); + result[eBoundTheta] = detail::radian_sym(result[eBoundTheta]); return result; } diff --git a/Core/include/Acts/EventData/TrackParametersConcept.hpp b/Core/include/Acts/EventData/TrackParametersConcept.hpp index b39255e5ef7..5e4982545a4 100644 --- a/Core/include/Acts/EventData/TrackParametersConcept.hpp +++ b/Core/include/Acts/EventData/TrackParametersConcept.hpp @@ -12,9 +12,7 @@ #include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/Geometry/GeometryContext.hpp" -#include #include -#include namespace Acts { @@ -68,4 +66,5 @@ concept BoundTrackParametersConcept = { p.position(c) } -> std::same_as; }; }; + } // namespace Acts diff --git a/Core/include/Acts/EventData/detail/GenerateParameters.hpp b/Core/include/Acts/EventData/detail/GenerateParameters.hpp index 0d38bb8d966..1b591dbcd7a 100644 --- a/Core/include/Acts/EventData/detail/GenerateParameters.hpp +++ b/Core/include/Acts/EventData/detail/GenerateParameters.hpp @@ -8,33 +8,48 @@ #pragma once +#include "Acts/Definitions/Algebra.hpp" #include "Acts/Definitions/TrackParametrization.hpp" -#include "Acts/Utilities/detail/periodic.hpp" +#include "Acts/Definitions/Units.hpp" +#include "Acts/Utilities/AngleHelpers.hpp" #include +#include #include #include namespace Acts::detail::Test { -/// Generate a random parameters vector and covariance matrix. -/// -/// @return std:::pair template -inline auto generateParametersCovariance(generator_t& rng) - -> std::pair, - Eigen::Matrix> { +inline auto generateParameters(generator_t& rng) + -> Eigen::Matrix { + using Scalar = scalar_t; + using ParametersVector = Eigen::Matrix; + + std::normal_distribution standardNormal(0, 1); + + ParametersVector params; + for (auto i = 0u; i < kSize; ++i) { + params[i] = standardNormal(rng); + } + + return params; +} + +template +inline auto generateCovariance(generator_t& rng) + -> Eigen::Matrix { using Scalar = scalar_t; using ParametersVector = Eigen::Matrix; using CovarianceMatrix = Eigen::Matrix; - std::normal_distribution distNormal(0, 1); + std::normal_distribution standardNormal(0, 1); std::uniform_real_distribution distCorr(-1, 1); // generate standard deviations ParametersVector stddev; for (auto i = 0u; i < kSize; ++i) { - stddev[i] = std::abs(distNormal(rng)); + stddev[i] = std::abs(standardNormal(rng)); } // generate correlation matrix CovarianceMatrix corr; @@ -48,32 +63,224 @@ inline auto generateParametersCovariance(generator_t& rng) // construct the covariance matrix CovarianceMatrix cov = stddev.asDiagonal() * corr * stddev.asDiagonal(); - // generate random parameters - // this is ignoring the correlations; since this does not need to generate - // credible data, this should be fine. - ParametersVector params; - for (auto i = 0u; i < kSize; ++i) { - params[i] = stddev[i] * distNormal(rng); + return cov; +} + +/// Generate a random parameters vector and covariance matrix. +/// +/// @return std:::pair +template +inline auto generateParametersCovariance(generator_t& rng) + -> std::pair, + Eigen::Matrix> { + auto params = generateParameters(rng); + auto cov = generateCovariance(rng); + return {params, cov}; +} + +struct GenerateBoundDirectionOptions { + /// Low, high (exclusive) for the transverse direction angle. + double phiMin = -std::numbers::pi; + double phiMax = std::numbers::pi; + + /// Low, high (inclusive) for the longitudinal direction angle. + /// + /// This intentionally uses theta instead of eta so it can represent the + /// full direction space with finite values. + /// + /// @note This is the standard generation, for detector performance + /// classification, where a flat distribution in eta can be useful, + /// this can be set by the etaUniform flag; + /// + double thetaMin = AngleHelpers::thetaFromEta(6.0); + double thetaMax = AngleHelpers::thetaFromEta(-6.0); + + bool etaUniform = true; +}; + +template +inline std::pair generateBoundDirection( + generator_t& rng, const GenerateBoundDirectionOptions& options) { + using UniformReal = std::uniform_real_distribution; + + // since we want to draw the direction uniform on the unit sphere, we must + // draw from cos(theta) instead of theta. see e.g. + // https://mathworld.wolfram.com/SpherePointPicking.html + double cosThetaMin = std::cos(options.thetaMin); + // ensure upper bound is included. see e.g. + // https://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution + double cosThetaMax = std::nextafter(std::cos(options.thetaMax), + std::numeric_limits::max()); + + // in case we force uniform eta generation + double etaMin = Acts::AngleHelpers::etaFromTheta(options.thetaMin); + double etaMax = Acts::AngleHelpers::etaFromTheta(options.thetaMax); + + UniformReal phiDist(options.phiMin, options.phiMax); + UniformReal cosThetaDist(cosThetaMin, cosThetaMax); + UniformReal etaDist(etaMin, etaMax); + + // draw parameters + double phi = phiDist(rng); + + double theta = 0; + if (!options.etaUniform) { + const double cosTheta = cosThetaDist(rng); + theta = std::acos(cosTheta); + } else { + const double eta = etaDist(rng); + theta = AngleHelpers::thetaFromEta(eta); } + return {phi, theta}; +} + +struct GenerateQoverPOptions { + /// Low, high (exclusive) for absolute/transverse momentum. + double pMin = 1 * UnitConstants::GeV; + double pMax = 100 * UnitConstants::GeV; + + /// Indicate if the momentum referse to transverse momentum + bool pTransverse = true; + + /// Charge of the parameters. + double charge = 1; + + /// Randomize the charge and flip the PDG particle number sign accordingly. + bool randomizeCharge = true; +}; + +template +inline double generateQoverP(generator_t& rng, + const GenerateQoverPOptions& options, + double theta) { + using UniformIndex = std::uniform_int_distribution; + using UniformReal = std::uniform_real_distribution; + + // choose between particle/anti-particle if requested + // the upper limit of the distribution is inclusive + UniformIndex particleTypeChoice(0u, options.randomizeCharge ? 1u : 0u); + // (anti-)particle choice is one random draw but defines two properties + const double qChoices[] = { + options.charge, + -options.charge, + }; + UniformReal pDist(options.pMin, options.pMax); + + // draw parameters + const std::uint8_t type = particleTypeChoice(rng); + const double q = qChoices[type]; + + const double p = + pDist(rng) * (options.pTransverse ? 1. / std::sin(theta) : 1.); + const double qOverP = (q != 0) ? q / p : 1 / p; + + return qOverP; +} + +struct GenerateBoundParametersOptions { + struct { + double loc0Mean = 0 * UnitConstants::mm; + double loc0Std = 1 * UnitConstants::mm; + + double loc1Mean = 0 * UnitConstants::mm; + double loc1Std = 1 * UnitConstants::mm; + + double timeMean = 0 * UnitConstants::ns; + double timeStd = 1 * UnitConstants::ns; + } position; + + GenerateBoundDirectionOptions direction; + + GenerateQoverPOptions qOverP; +}; + +inline BoundVector someBoundParametersA() { + return {0.0, 0.0, 0.0, std::numbers::pi / 2, 1.0, 0.0}; +} + +template +inline BoundVector generateBoundParameters( + generator_t& rng, const GenerateBoundParametersOptions& options) { + std::normal_distribution standardNormal(0, 1); + + const double loc0 = options.position.loc0Mean + + options.position.loc0Std * standardNormal(rng); + const double loc1 = options.position.loc1Mean + + options.position.loc1Std * standardNormal(rng); + + auto [phi, theta] = generateBoundDirection(rng, options.direction); + auto qOverP = generateQoverP(rng, options.qOverP, theta); + + const double time = options.position.timeMean + + options.position.timeStd * standardNormal(rng); + + return {loc0, loc1, phi, theta, qOverP, time}; +} + +template +inline std::pair generateBoundParametersCovariance( + generator_t& rng, const GenerateBoundParametersOptions& options) { + auto params = generateBoundParameters(rng, options); + auto cov = generateCovariance(rng); return {params, cov}; } -/// Generate a random bound parameters vector and covariance matrix. +struct GenerateFreeParametersOptions { + struct { + double xMean = 0 * UnitConstants::mm; + double xStd = 1 * UnitConstants::mm; + + double yMean = 0 * UnitConstants::mm; + double yStd = 1 * UnitConstants::mm; + + double zMean = 0 * UnitConstants::mm; + double zStd = 1 * UnitConstants::mm; + + double timeMean = 0 * UnitConstants::ns; + double timeStd = 1 * UnitConstants::ns; + } position; + + GenerateBoundDirectionOptions direction; + + GenerateQoverPOptions qOverP; +}; + +inline FreeVector someFreeParametersA() { + return {0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0}; +} + template -inline auto generateBoundParametersCovariance(generator_t& rng) { - auto parCov = generateParametersCovariance(rng); - auto [phi, theta] = detail::normalizePhiTheta(parCov.first[eBoundPhi], - parCov.first[eBoundTheta]); - parCov.first[eBoundPhi] = phi; - parCov.first[eBoundTheta] = theta; - return parCov; +inline FreeVector generateFreeParameters( + generator_t& rng, const GenerateFreeParametersOptions& options) { + std::normal_distribution standardNormal(0, 1); + + const double x = + options.position.xMean + options.position.xStd * standardNormal(rng); + const double y = + options.position.yMean + options.position.yStd * standardNormal(rng); + const double z = + options.position.zMean + options.position.zStd * standardNormal(rng); + const double time = options.position.timeMean + + options.position.timeStd * standardNormal(rng); + + auto [phi, theta] = generateBoundDirection(rng, options.direction); + + Vector3 direction = makeDirectionFromPhiTheta(phi, theta); + + auto qOverP = generateQoverP(rng, options.qOverP, theta); + + FreeVector freeParams; + freeParams << x, y, z, time, direction, qOverP; + return freeParams; } -/// Generate a random free parameters vector and covariance matrix. template -inline auto generateFreeParametersCovariance(generator_t& rng) { - return generateParametersCovariance(rng); +inline std::pair generateFreeParametersCovariance( + generator_t& rng, const GenerateFreeParametersOptions& options) { + auto params = generateFreeParameters(rng, options); + auto cov = generateCovariance(rng); + return {params, cov}; } } // namespace Acts::detail::Test diff --git a/Core/include/Acts/EventData/detail/MultiTrajectoryTestsCommon.hpp b/Core/include/Acts/EventData/detail/MultiTrajectoryTestsCommon.hpp index ec64dbe5241..93ef7a3eb7c 100644 --- a/Core/include/Acts/EventData/detail/MultiTrajectoryTestsCommon.hpp +++ b/Core/include/Acts/EventData/detail/MultiTrajectoryTestsCommon.hpp @@ -331,7 +331,7 @@ class MultiTrajectoryTestsCommon { auto tsb = traj.getTrackState(index); // then modify one and check that the other was modified as well { - auto [par, cov] = generateBoundParametersCovariance(rng); + auto [par, cov] = generateBoundParametersCovariance(rng, {}); tsb.predicted() = par; tsb.predictedCovariance() = cov; BOOST_CHECK_EQUAL(tsa.predicted(), par); @@ -340,7 +340,7 @@ class MultiTrajectoryTestsCommon { BOOST_CHECK_EQUAL(tsb.predictedCovariance(), cov); } { - auto [par, cov] = generateBoundParametersCovariance(rng); + auto [par, cov] = generateBoundParametersCovariance(rng, {}); tsb.filtered() = par; tsb.filteredCovariance() = cov; BOOST_CHECK_EQUAL(tsa.filtered(), par); @@ -349,7 +349,7 @@ class MultiTrajectoryTestsCommon { BOOST_CHECK_EQUAL(tsb.filteredCovariance(), cov); } { - auto [par, cov] = generateBoundParametersCovariance(rng); + auto [par, cov] = generateBoundParametersCovariance(rng, {}); tsb.smoothed() = par; tsb.smoothedCovariance() = cov; BOOST_CHECK_EQUAL(tsa.smoothed(), par); @@ -377,7 +377,7 @@ class MultiTrajectoryTestsCommon { } { // reset measurements w/ full parameters - auto [measPar, measCov] = generateBoundParametersCovariance(rng); + auto [measPar, measCov] = generateBoundParametersCovariance(rng, {}); tsb.allocateCalibrated(eBoundSize); tsb.template calibrated() = measPar; tsb.template calibratedCovariance() = measCov; @@ -390,7 +390,7 @@ class MultiTrajectoryTestsCommon { } { // reset only the effective measurements - auto [measPar, measCov] = generateBoundParametersCovariance(rng); + auto [measPar, measCov] = generateBoundParametersCovariance(rng, {}); std::size_t nMeasurements = tsb.effectiveCalibrated().rows(); auto effPar = measPar.head(nMeasurements); auto effCov = measCov.topLeftCorner(nMeasurements, nMeasurements); diff --git a/Core/include/Acts/EventData/detail/TestTrackState.hpp b/Core/include/Acts/EventData/detail/TestTrackState.hpp index 3a83f401cd3..514ae073c2f 100644 --- a/Core/include/Acts/EventData/detail/TestTrackState.hpp +++ b/Core/include/Acts/EventData/detail/TestTrackState.hpp @@ -38,11 +38,11 @@ struct TestTrackState { : surface( CurvilinearSurface(Vector3::Zero(), Vector3::UnitZ()).surface()), // set bogus parameters first since they are not default-constructible - predicted(surface, BoundVector::Zero(), std::nullopt, + predicted(surface, someBoundParametersA(), std::nullopt, ParticleHypothesis::pion()), - filtered(surface, BoundVector::Zero(), std::nullopt, + filtered(surface, someBoundParametersA(), std::nullopt, ParticleHypothesis::pion()), - smoothed(surface, BoundVector::Zero(), std::nullopt, + smoothed(surface, someBoundParametersA(), std::nullopt, ParticleHypothesis::pion()), jacobian(BoundMatrix::Identity()), chi2(std::chi_squared_distribution(measdim)(rng)), @@ -65,7 +65,7 @@ struct TestTrackState { } // create track parameters - auto [trkPar, trkCov] = generateBoundParametersCovariance(rng); + auto [trkPar, trkCov] = generateBoundParametersCovariance(rng, {}); // trkPar[eBoundPhi] = 45_degree; // trkPar[eBoundTheta] = 90_degree; // trkPar[eBoundQOverP] = 5.; diff --git a/Core/include/Acts/Geometry/NavigationPolicyFactory.hpp b/Core/include/Acts/Geometry/NavigationPolicyFactory.hpp new file mode 100644 index 00000000000..ed9acce9aa2 --- /dev/null +++ b/Core/include/Acts/Geometry/NavigationPolicyFactory.hpp @@ -0,0 +1,215 @@ +// 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/Navigation/INavigationPolicy.hpp" +#include "Acts/Navigation/MultiNavigationPolicy.hpp" + +#include +#include +namespace Acts { + +class TrackingVolume; +class GeometryContext; +class Logger; +class INavigationPolicy; + +namespace detail { +template +class NavigationPolicyFactoryImpl; +} + +/// Base class for navigation policy factories. The factory can be assembled +/// iteratively by using `make` followed by a number of calls to the `add` +/// function of the helper type. Example: +/// +/// ```cpp +/// auto factory = NavigationPolicyFactory::make() +/// .add(arg1, arg2) +/// .add(/*no args*/) +/// .asUniquePtr(); +/// ``` +class NavigationPolicyFactory { + public: + virtual ~NavigationPolicyFactory() = default; + + // This needs to be listed here, but the return type cannot be spelled out + // yet. + static auto make(); + + // This will potentially get serialization interface and deserialization + // functionality + + virtual std::unique_ptr build( + const GeometryContext& gctx, const TrackingVolume& volume, + const Logger& logger) const = 0; +}; + +namespace detail { + +template +concept NavigationPolicyIsolatedFactoryConcept = requires( + F f, const GeometryContext& gctx, const TrackingVolume& volume, + const Logger& logger, Args&&... args) { + { f(gctx, volume, logger, args...) } -> std::derived_from; + + requires NavigationPolicyConcept; + + requires(std::is_copy_constructible_v && ...); +}; + +template <> +class NavigationPolicyFactoryImpl<> { + public: + template + friend class NavigationPolicyFactoryImpl; + NavigationPolicyFactoryImpl() = default; + + /// Create a factory with the specified policy added + /// @tparam P The policy type to add + /// @param args The arguments to pass to the policy constructor + /// @note Arguments need to be copy constructible because the factory must be + /// able to execute multiple times. + /// @return A new policy factory including the @c P policy. + template + requires(std::is_constructible_v && + (std::is_copy_constructible_v && ...)) + constexpr auto add(Args&&... args) && { + auto factory = [=](const GeometryContext& gctx, + const TrackingVolume& volume, const Logger& logger) { + return P{gctx, volume, logger, args...}; + }; + + return NavigationPolicyFactoryImpl{ + std::make_tuple(std::move(factory))}; + } + + /// Create a factory with a policy returned by a factory function + /// @tparam Fn The type of the function to construct the policy + /// @param args The arguments to pass to the policy factory + /// @note Arguments need to be copy constructible because the factory must be + /// able to execute multiple times. + /// @return A new policy factory including the function + template + requires(NavigationPolicyIsolatedFactoryConcept) + constexpr auto add(Fn&& fn, Args&&... args) { + auto factory = [=](const GeometryContext& gctx, + const TrackingVolume& volume, const Logger& logger) { + return fn(gctx, volume, logger, args...); + }; + + return NavigationPolicyFactoryImpl{ + std::make_tuple(std::move(factory))}; + } +}; + +template +class NavigationPolicyFactoryImpl : public NavigationPolicyFactory { + public: + /// Create a factory with the specified policy added + /// @tparam P The policy type to add + /// @param args The arguments to pass to the policy constructor + /// @note Arguments need to be copy constructible because the factory must be + /// able to execute multiple times. + /// @return A new policy factory including the @c P policy. + template + requires(std::is_constructible_v && + (std::is_copy_constructible_v && ...)) + constexpr auto add(Args&&... args) && { + auto factory = [=](const GeometryContext& gctx, + const TrackingVolume& volume, const Logger& logger) { + return P{gctx, volume, logger, args...}; + }; + + return NavigationPolicyFactoryImpl{ + std::tuple_cat(std::move(m_factories), + std::make_tuple(std::move(factory)))}; + } + + /// Create a factory with a policy returned by a factory function + /// @tparam Fn The type of the function to construct the policy + /// @param args The arguments to pass to the policy factory + /// @note Arguments need to be copy constructible because the factory must be + /// able to execute multiple times. + /// @return A new policy factory including the function + template + requires(NavigationPolicyIsolatedFactoryConcept) + constexpr auto add(Fn&& fn, Args&&... args) && { + auto factory = [=](const GeometryContext& gctx, + const TrackingVolume& volume, const Logger& logger) { + return fn(gctx, volume, logger, args...); + }; + + return NavigationPolicyFactoryImpl{ + std::tuple_cat(std::move(m_factories), + std::make_tuple(std::move(factory)))}; + } + + /// Move the factory into a unique pointer + /// @note Only callable on rvalue references + /// @return A unique pointer to the factory + constexpr std::unique_ptr> + asUniquePtr() && { + return std::make_unique>( + std::move(*this)); + } + + /// Construct a navigation policy using the factories + /// @param gctx The geometry context + /// @param volume The tracking volume + /// @param logger The logger + auto operator()(const GeometryContext& gctx, const TrackingVolume& volume, + const Logger& logger) const { + return std::apply( + [&](auto&&... factories) { + // Deduce policy type explicitly here... + using policy_type = decltype(MultiNavigationPolicy{ + std::invoke(factories, std::declval(), + std::declval(), + std::declval())...}); + + // ... so we can create a unique_ptr of the concrete type here rather + // than the base. (`make_unique` can't do type deduction) + return std::make_unique( + std::invoke(factories, gctx, volume, logger)...); + }, + m_factories); + } + + /// Construct a navigation policy using the factories + /// @param gctx The geometry context + /// @param volume The tracking volume + /// @param logger The logger + std::unique_ptr build( + const GeometryContext& gctx, const TrackingVolume& volume, + const Logger& logger) const override { + return operator()(gctx, volume, logger); + } + + private: + template + friend class NavigationPolicyFactoryImpl; + + explicit NavigationPolicyFactoryImpl(std::tuple&& factories) + : m_factories(std::move(factories)) {} + + std::tuple m_factories; +}; + +} // namespace detail + +inline auto NavigationPolicyFactory::make() { + return detail::NavigationPolicyFactoryImpl<>{}; +} + +} // namespace Acts diff --git a/Core/include/Acts/Geometry/TrackingVolume.hpp b/Core/include/Acts/Geometry/TrackingVolume.hpp index c980314fa6d..664faa39d46 100644 --- a/Core/include/Acts/Geometry/TrackingVolume.hpp +++ b/Core/include/Acts/Geometry/TrackingVolume.hpp @@ -13,13 +13,13 @@ #include "Acts/Geometry/BoundarySurfaceT.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Geometry/GeometryIdentifier.hpp" -#include "Acts/Geometry/GlueVolumesDescriptor.hpp" #include "Acts/Geometry/Layer.hpp" #include "Acts/Geometry/Portal.hpp" #include "Acts/Geometry/TrackingVolumeVisitorConcept.hpp" #include "Acts/Geometry/Volume.hpp" #include "Acts/Material/IVolumeMaterial.hpp" -#include "Acts/Surfaces/BoundaryTolerance.hpp" +#include "Acts/Navigation/NavigationDelegate.hpp" +#include "Acts/Navigation/NavigationStream.hpp" #include "Acts/Surfaces/Surface.hpp" #include "Acts/Surfaces/SurfaceArray.hpp" #include "Acts/Surfaces/SurfaceVisitorConcept.hpp" @@ -35,7 +35,7 @@ #include #include -#include +#include namespace Acts { @@ -43,7 +43,6 @@ class GlueVolumesDescriptor; class VolumeBounds; template struct NavigationOptions; -class GeometryIdentifier; class IMaterialDecorator; class ISurfaceMaterial; class IVolumeMaterial; @@ -51,6 +50,7 @@ class Surface; class TrackingVolume; struct GeometryIdentifierHook; class Portal; +class INavigationPolicy; /// Interface types of the Gen1 geometry model /// @note This interface is being replaced, and is subject to removal @@ -117,8 +117,8 @@ class TrackingVolume : public Volume { ~TrackingVolume() override; TrackingVolume(const TrackingVolume&) = delete; TrackingVolume& operator=(const TrackingVolume&) = delete; - TrackingVolume(TrackingVolume&&) = default; - TrackingVolume& operator=(TrackingVolume&&) = default; + TrackingVolume(TrackingVolume&&) noexcept; + TrackingVolume& operator=(TrackingVolume&&) noexcept; /// Constructor for a container Volume /// - vacuum filled volume either as a for other tracking volumes @@ -155,7 +155,6 @@ class TrackingVolume : public Volume { /// @param volumeName is a string identifier TrackingVolume(Volume& volume, const std::string& volumeName = "undefined"); - // @TODO: This needs to be refactored to include Gen3 volumes /// Return the associated sub Volume, returns THIS if no subVolume exists /// @param gctx The current geometry context object, e.g. alignment /// @param position is the global position associated with that search @@ -498,6 +497,21 @@ class TrackingVolume : public Volume { const ViewConfig& portalViewConfig, const ViewConfig& sensitiveViewConfig) const; + /// Register a navigation policy with this volume. The argument can not be + /// nullptr. + /// @param policy is the navigation policy to be registered + void setNavigationPolicy(std::unique_ptr policy); + + /// Populate the navigation stream with navigation candidates from this + /// volume. Internally, this consults the registered navigation policy, where + /// the default is a noop. + /// @param args are the navigation arguments + /// @param stream is the navigation stream to be updated + /// @param logger is the logger + void initializeNavigationCandidates(const NavigationArguments& args, + AppendOnlyNavigationStream& stream, + const Logger& logger) const; + private: void connectDenseBoundarySurfaces( MutableTrackingVolumeVector& confinedDenseVolumes); @@ -561,6 +575,10 @@ class TrackingVolume : public Volume { std::vector> m_volumes; std::vector> m_portals; std::vector> m_surfaces; + + std::unique_ptr m_navigationPolicy; + + NavigationDelegate m_navigationDelegate{}; }; } // namespace Acts diff --git a/Core/include/Acts/Navigation/INavigationPolicy.hpp b/Core/include/Acts/Navigation/INavigationPolicy.hpp new file mode 100644 index 00000000000..de98f8d26c3 --- /dev/null +++ b/Core/include/Acts/Navigation/INavigationPolicy.hpp @@ -0,0 +1,75 @@ +// 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/Navigation/NavigationDelegate.hpp" +#include "Acts/Navigation/NavigationStream.hpp" +#include "Acts/Utilities/DelegateChainBuilder.hpp" + +#include + +namespace Acts { + +class TrackingVolume; +class INavigationPolicy; + +/// Concept for a navigation policy +/// This exists so `updateState` can be a non-virtual method and we still have a +/// way to enforce it exists. +template +concept NavigationPolicyConcept = requires { + requires std::is_base_of_v; + // Has a conforming update method + requires requires(T policy, const NavigationArguments& args) { + policy.initializeCandidates(args, + std::declval(), + std::declval()); + }; +}; + +/// Base class for all navigation policies. The policy needs to be *connected* +/// to a delegate via a virtual method for it to become active. The update +/// method is not part of the class interface. The conventional `updateState` +/// method is only required for use with the navigation policy factory, +/// otherwise `connect` is free to connect any function. +class INavigationPolicy { + public: + /// Noop update function that is suitable as a default for default navigation + /// delegates. + static void noopInitializeCandidates( + const NavigationArguments& /*unused*/, + const AppendOnlyNavigationStream& /*unused*/, const Logger& /*unused*/) { + // This is a noop + } + + /// Virtual destructor so policies can be held through this base class. + virtual ~INavigationPolicy() = default; + + /// Connect a policy with a delegate (usually a member of a volume). + /// This method exists to allow a policy to ensure a non-virtual function is + /// registered with the delegate. + /// @param delegate The delegate to connect to + virtual void connect(NavigationDelegate& delegate) const = 0; + + protected: + /// Internal helper function for derived classes that conform to the concept + /// and have a conventional `updateState` method. Mainly used to save some + /// boilerplate. + /// @tparam T The type of the navigation policy + /// @param delegate The delegate to connect to + template + void connectDefault(NavigationDelegate& delegate) const { + // This cannot be a concept because we use it in CRTP below + const auto* self = static_cast(this); + DelegateChainBuilder{delegate}.add<&T::initializeCandidates>(self).store( + delegate); + } +}; + +} // namespace Acts diff --git a/Core/include/Acts/Navigation/MultiNavigationPolicy.hpp b/Core/include/Acts/Navigation/MultiNavigationPolicy.hpp new file mode 100644 index 00000000000..e66872fc39e --- /dev/null +++ b/Core/include/Acts/Navigation/MultiNavigationPolicy.hpp @@ -0,0 +1,78 @@ +// 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/Navigation/INavigationPolicy.hpp" + +namespace Acts { + +/// Base class for multi navigation policies +class MultiNavigationPolicyBase : public INavigationPolicy {}; + +/// Combined navigation policy that calls all contained other navigation +/// policies. This class only works with policies complying with +/// `NavigationPolicyConcept`, which means that they have a conventional +/// `updateState` method. +/// +/// Internally, this uses a delegate chain factory to produce an unrolled +/// delegate chain. +/// +/// @tparam Policies The navigation policies to be combined +template + requires(sizeof...(Policies) > 0) +class MultiNavigationPolicy final : public MultiNavigationPolicyBase { + public: + /// Constructor from a set of child policies. + /// @param policies The child policies + explicit MultiNavigationPolicy(Policies&&... policies) + : m_policies{std::move(policies)...} {} + + /// Implementation of the connection to a navigation delegate. + /// It uses the delegate chain factory to produce a delegate chain and stores + /// that chain in the owning navigation delegate. + /// @param delegate The navigation delegate to connect to + void connect(NavigationDelegate& delegate) const override { + auto factory = add(DelegateChainBuilder{delegate}, + std::index_sequence_for{}); + + factory.store(delegate); + } + + /// Access the contained policies + /// @return The contained policies + const std::tuple& policies() const { return m_policies; } + + private: + /// Internal helper to build the delegate chain + template + constexpr auto add( + auto factory, + std::integer_sequence /*unused*/) const { + return add(factory); + } + + /// Internal helper to build the delegate chain + template + constexpr auto add(auto factory) const { + using policy_type = std::tuple_element_t; + auto* policy = &std::get(m_policies); + + auto added = + factory.template add<&policy_type::initializeCandidates>(policy); + + if constexpr (sizeof...(Is) > 0) { + return add(added); + } else { + return added; + } + } + + std::tuple m_policies; +}; +} // namespace Acts diff --git a/Core/include/Acts/Navigation/NavigationDelegate.hpp b/Core/include/Acts/Navigation/NavigationDelegate.hpp new file mode 100644 index 00000000000..8e243818d30 --- /dev/null +++ b/Core/include/Acts/Navigation/NavigationDelegate.hpp @@ -0,0 +1,35 @@ +// 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/Definitions/Algebra.hpp" +#include "Acts/Navigation/NavigationStream.hpp" +#include "Acts/Surfaces/BoundaryTolerance.hpp" +#include "Acts/Utilities/Delegate.hpp" + +namespace Acts { + +class NavigationStream; +class Logger; + +/// Struct that serves as the argument to the navigation delegate. +/// It is not supposed to be used as an lvalue. +struct NavigationArguments { + Vector3 position; + Vector3 direction; + + BoundaryTolerance tolerance = BoundaryTolerance::None(); +}; + +/// Central alias for the navigation delegate. This type is owning to support +/// (type-erased) navigation delegate chains (i.e. multiple policies). +using NavigationDelegate = OwningDelegate; + +} // namespace Acts diff --git a/Core/include/Acts/Navigation/NavigationStream.hpp b/Core/include/Acts/Navigation/NavigationStream.hpp index 71443e48915..97e154214d7 100644 --- a/Core/include/Acts/Navigation/NavigationStream.hpp +++ b/Core/include/Acts/Navigation/NavigationStream.hpp @@ -10,9 +10,11 @@ #include "Acts/Definitions/Algebra.hpp" #include "Acts/Geometry/GeometryContext.hpp" +#include "Acts/Geometry/Portal.hpp" #include "Acts/Surfaces/BoundaryTolerance.hpp" #include "Acts/Utilities/Intersection.hpp" +#include #include #include @@ -22,7 +24,6 @@ namespace Acts { namespace Experimental { class Portal; } -using namespace Experimental; class Surface; @@ -55,6 +56,7 @@ class NavigationStream { ObjectIntersection intersection = ObjectIntersection::invalid(); /// The portal + const Acts::Experimental::Portal* gen2Portal = nullptr; const Portal* portal = nullptr; /// The boundary tolerance BoundaryTolerance bTolerance = BoundaryTolerance::None(); @@ -116,25 +118,27 @@ class NavigationStream { /// /// @param surface the surface to be filled /// @param bTolerance the boundary tolerance used for the intersection - void addSurfaceCandidate(const Surface* surface, + void addSurfaceCandidate(const Surface& surface, const BoundaryTolerance& bTolerance); /// Fill n surfaces into the candidate vector /// /// @param surfaces the surfaces that are filled in /// @param bTolerance the boundary tolerance used for the intersection - void addSurfaceCandidates(const std::vector& surfaces, + void addSurfaceCandidates(std::span surfaces, const BoundaryTolerance& bTolerance); /// Fill one portal into the candidate vector /// + void addPortalCandidate(const Experimental::Portal& portal); /// @param portal the portals that are filled in - void addPortalCandidate(const Portal* portal); + + void addPortalCandidate(const Portal& portal); /// Fill n portals into the candidate vector /// /// @param portals the portals that are filled in - void addPortalCandidates(const std::vector& portals); + void addPortalCandidates(std::span portals); /// Initialize the stream from a query point /// @@ -175,4 +179,14 @@ class NavigationStream { std::size_t m_currentIndex = 0u; }; +struct AppendOnlyNavigationStream { + explicit AppendOnlyNavigationStream(NavigationStream& stream); + void addSurfaceCandidate(const Surface& surface, + const BoundaryTolerance& bTolerance); + void addPortalCandidate(const Portal& portal); + + private: + NavigationStream* m_stream; +}; + } // namespace Acts diff --git a/Core/include/Acts/Navigation/SurfaceArrayNavigationPolicy.hpp b/Core/include/Acts/Navigation/SurfaceArrayNavigationPolicy.hpp new file mode 100644 index 00000000000..731122caff7 --- /dev/null +++ b/Core/include/Acts/Navigation/SurfaceArrayNavigationPolicy.hpp @@ -0,0 +1,84 @@ +// 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/Navigation/INavigationPolicy.hpp" + +#pragma once + +namespace Acts { + +class SurfaceArray; + +/// A navigation policy that internally uses the Gen1 @c SurfaceArray class +class SurfaceArrayNavigationPolicy : public INavigationPolicy { + public: + /// Enum for configuring which type of surface array to produce. This affects + /// the projection that is used for creating the binning structure. + enum class LayerType { Cylinder, Disc, Plane }; + + /// Config struct to configure the surface array navigation + struct Config { + /// The type of the layer + LayerType layerType = LayerType::Cylinder; + /// The number of bins in the local directions. The interpretation depends + /// on the layer type. + std::pair bins; + }; + + /// Main constructor, which internally creates the surface array acceleration + /// structure. + /// @note Expects that all relevant surfaces are registered with @p volume. + /// Only selects sensitive surfaces for the surface array. + /// @param gctx The geometry context + /// @param volume The *layer volume* to construct the surface array from + /// @param logger A logging instance + /// @param config The configuration for the surface array + explicit SurfaceArrayNavigationPolicy(const GeometryContext& gctx, + const TrackingVolume& volume, + const Logger& logger, Config config); + + /// Update the navigation state from the surface array + /// @param args The navigation arguments + /// @param stream The navigation stream to update + /// @param logger The logger + void initializeCandidates(const NavigationArguments& args, + AppendOnlyNavigationStream& stream, + const Logger& logger) const; + + /// Connect this policy with a navigation delegate + /// @param delegate The navigation delegate to connect to + void connect(NavigationDelegate& delegate) const override; + + /// Output stream operator for the contained layer type enum + /// @param os The output stream + /// @param layerType The layer type to print + friend std::ostream& operator<<(std::ostream& os, + const LayerType& layerType) { + switch (layerType) { + using enum LayerType; + case Cylinder: + os << "Cylinder"; + break; + case Disc: + os << "Disc"; + break; + case Plane: + os << "Plane"; + break; + } + return os; + } + + private: + std::unique_ptr m_surfaceArray{}; + const TrackingVolume& m_volume; +}; + +static_assert(NavigationPolicyConcept); + +} // namespace Acts diff --git a/Core/include/Acts/Navigation/TryAllNavigationPolicy.hpp b/Core/include/Acts/Navigation/TryAllNavigationPolicy.hpp new file mode 100644 index 00000000000..e7dc4bb3ddc --- /dev/null +++ b/Core/include/Acts/Navigation/TryAllNavigationPolicy.hpp @@ -0,0 +1,63 @@ +// 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/Navigation/INavigationPolicy.hpp" +#include "Acts/Navigation/NavigationStream.hpp" + +namespace Acts { + +class TrackingVolume; +class GeometryContext; +class Logger; + +/// Policy which adds **all** candidates of the configured type to the +/// stream +class TryAllNavigationPolicy final : public INavigationPolicy { + public: + struct Config { + bool portals = true; + bool sensitives = true; + }; + + /// Constructor from a volume + /// @param config The configuration for the policy + /// @param gctx is the geometry context + /// @param volume is the volume to navigate + /// @param logger is the logger + TryAllNavigationPolicy(const Config& config, const GeometryContext& gctx, + const TrackingVolume& volume, const Logger& logger); + + /// Constructor from a volume + /// @param gctx is the geometry context + /// @param volume is the volume to navigate + /// @param logger is the logger + TryAllNavigationPolicy(const GeometryContext& gctx, + const TrackingVolume& volume, const Logger& logger); + + /// Add all candidates to the stream + /// @param args are the navigation arguments + /// @param stream is the navigation stream to update + /// @param logger is the logger + void initializeCandidates(const NavigationArguments& args, + AppendOnlyNavigationStream& stream, + const Logger& logger) const; + + /// Connect the policy to a navigation delegate + /// @param delegate is the navigation delegate + void connect(NavigationDelegate& delegate) const override; + + private: + Config m_cfg; + const TrackingVolume* m_volume; +}; + +static_assert(NavigationPolicyConcept); + +} // namespace Acts diff --git a/Core/include/Acts/Seeding/SeedFilter.hpp b/Core/include/Acts/Seeding/SeedFilter.hpp index 3c8720c42f0..94ceb17ae87 100644 --- a/Core/include/Acts/Seeding/SeedFilter.hpp +++ b/Core/include/Acts/Seeding/SeedFilter.hpp @@ -13,6 +13,7 @@ #include "Acts/Seeding/CandidatesForMiddleSp.hpp" #include "Acts/Seeding/IExperimentCuts.hpp" #include "Acts/Seeding/SeedFilterConfig.hpp" +#include "Acts/Utilities/Logger.hpp" #include #include @@ -37,8 +38,15 @@ struct SeedFilterState { template class SeedFilter final { public: - SeedFilter(SeedFilterConfig config, + SeedFilter(const SeedFilterConfig& config, IExperimentCuts* expCuts = nullptr); + SeedFilter(const SeedFilterConfig& config, + std::unique_ptr logger, + IExperimentCuts* expCuts = nullptr); + SeedFilter(const SeedFilter&) = delete; + SeedFilter& operator=(const SeedFilter&) = delete; + SeedFilter(SeedFilter&&) noexcept = default; + SeedFilter& operator=(SeedFilter&&) noexcept = default; SeedFilter() = delete; ~SeedFilter() = default; @@ -95,7 +103,11 @@ class SeedFilter final { } private: + const Logger& logger() const { return *m_logger; } + const SeedFilterConfig m_cfg; + std::unique_ptr m_logger = + Acts::getDefaultLogger("SeedFilter", Logging::Level::INFO); const IExperimentCuts* m_experimentCuts; }; } // namespace Acts diff --git a/Core/include/Acts/Seeding/SeedFilter.ipp b/Core/include/Acts/Seeding/SeedFilter.ipp index 5e54789b714..66498916a7e 100644 --- a/Core/include/Acts/Seeding/SeedFilter.ipp +++ b/Core/include/Acts/Seeding/SeedFilter.ipp @@ -16,7 +16,7 @@ namespace Acts { // constructor template SeedFilter::SeedFilter( - SeedFilterConfig config, + const SeedFilterConfig& config, IExperimentCuts* expCuts /* = 0*/) : m_cfg(config), m_experimentCuts(expCuts) { if (!config.isInInternalUnits) { @@ -24,6 +24,18 @@ SeedFilter::SeedFilter( "SeedFilterConfig not in ACTS internal units in SeedFilter"); } } + +template +SeedFilter::SeedFilter( + const SeedFilterConfig& config, std::unique_ptr logger, + IExperimentCuts* expCuts /* = 0*/) + : m_cfg(config), m_logger(std::move(logger)), m_experimentCuts(expCuts) { + if (!config.isInInternalUnits) { + throw std::runtime_error( + "SeedFilterConfig not in ACTS internal units in SeedFilter"); + } +} + // function to filter seeds based on all seeds with same bottom- and // middle-spacepoint. // return vector must contain weight of each seed @@ -295,10 +307,14 @@ void SeedFilter::filterSeeds_1SpFixed( seed.setVertexZ(zOrigin); seed.setQuality(bestSeedQuality); + ACTS_VERBOSE("Adding seed: [b=" << bottom->index() << ", m=" + << medium->index() << ", t=" << top->index() + << "], quality=" << bestSeedQuality + << ", vertexZ=" << zOrigin); Acts::detail::pushBackOrInsertAtEnd(outputCollection, std::move(seed)); - ++numTotalSeeds; } + ACTS_VERBOSE("Identified " << numTotalSeeds << " seeds"); } } // namespace Acts diff --git a/Core/include/Acts/Seeding/SeedFinder.hpp b/Core/include/Acts/Seeding/SeedFinder.hpp index cfe9908574c..3e2e7ae8bad 100644 --- a/Core/include/Acts/Seeding/SeedFinder.hpp +++ b/Core/include/Acts/Seeding/SeedFinder.hpp @@ -18,6 +18,7 @@ #include "Acts/Seeding/SeedFinderUtils.hpp" #include "Acts/Seeding/SpacePointGrid.hpp" #include "Acts/Seeding/detail/UtilityFunctions.hpp" +#include "Acts/Utilities/Logger.hpp" #include #include @@ -37,11 +38,11 @@ concept GridBinCollection = std::ranges::random_access_range && std::same_as; -template -concept CollectionStoresSeedsTo = requires(Coll coll, external_t sp) { - Acts::detail::pushBackOrInsertAtEnd(coll, - Acts::Seed(sp, sp, sp)); -}; +template +concept CollectionStoresSeedsTo = + requires(collection_t coll, Acts::Seed seed) { + Acts::detail::pushBackOrInsertAtEnd(coll, seed); + }; enum class SpacePointCandidateType : short { eBottom, eTop }; @@ -87,7 +88,14 @@ class SeedFinder { /// The only constructor. Requires a config object. /// @param config the configuration for the SeedFinder - SeedFinder(const Acts::SeedFinderConfig& config); + /// @param logger the ACTS logger + SeedFinder(const Acts::SeedFinderConfig& config, + std::unique_ptr logger = + getDefaultLogger("SeedFinder", Logging::Level::INFO)); + SeedFinder(SeedFinder&&) noexcept = + default; + SeedFinder& operator=(SeedFinder&&) noexcept = default; ~SeedFinder() = default; /** @name Disallow default instantiation, copy, assignment */ //@{ @@ -95,7 +103,7 @@ class SeedFinder { SeedFinder(const SeedFinder&) = delete; SeedFinder& operator=( - const SeedFinder&) = default; + const SeedFinder&) = delete; //@} /// Create all seeds from the space points in the three iterators. @@ -172,7 +180,10 @@ class SeedFinder { SeedingState& state) const; private: + const Logger& logger() const { return *m_logger; } + Acts::SeedFinderConfig m_config; + std::unique_ptr m_logger{nullptr}; }; } // namespace Acts diff --git a/Core/include/Acts/Seeding/SeedFinder.ipp b/Core/include/Acts/Seeding/SeedFinder.ipp index 45b95ec05d5..e6ccb9f589f 100644 --- a/Core/include/Acts/Seeding/SeedFinder.ipp +++ b/Core/include/Acts/Seeding/SeedFinder.ipp @@ -15,8 +15,9 @@ namespace Acts { template SeedFinder::SeedFinder( - const Acts::SeedFinderConfig& config) - : m_config(config) { + const Acts::SeedFinderConfig& config, + std::unique_ptr logger) + : m_config(config), m_logger(std::move(logger)) { if (!config.isInInternalUnits) { throw std::runtime_error( "SeedFinderConfig not in ACTS internal units in SeedFinder"); @@ -110,6 +111,12 @@ void SeedFinder::createSeedsForGroup( // same z-bin auto [minRadiusRangeForMiddle, maxRadiusRangeForMiddle] = retrieveRadiusRangeForMiddle(*middleSPs.front(), rMiddleSPRange); + ACTS_VERBOSE("Current global bin: " << middleSPsIdx << ", z value of " + << middleSPs.front()->z()); + ACTS_VERBOSE("Validity range (radius) for the middle space point is [" + << minRadiusRangeForMiddle << ", " << maxRadiusRangeForMiddle + << "]"); + for (const external_spacepoint_t* spM : middleSPs) { const float rM = spM->radius(); @@ -136,6 +143,7 @@ void SeedFinder::createSeedsForGroup( // no top SP found -> try next spM if (state.compatTopSP.empty()) { + ACTS_VERBOSE("No compatible Tops, moving to next middle candidate"); continue; } @@ -157,6 +165,10 @@ void SeedFinder::createSeedsForGroup( seedFilterState.rMaxSeedConf = seedConfRange.rMaxSeedConf; // continue if number of top SPs is smaller than minimum if (state.compatTopSP.size() < seedFilterState.nTopSeedConf) { + ACTS_VERBOSE( + "Number of top SPs is " + << state.compatTopSP.size() + << " and is smaller than minimum, moving to next middle candidate"); continue; } } @@ -170,9 +182,14 @@ void SeedFinder::createSeedsForGroup( // no bottom SP found -> try next spM if (state.compatBottomSP.empty()) { + ACTS_VERBOSE("No compatible Bottoms, moving to next middle candidate"); continue; } + ACTS_VERBOSE("Candidates: " << state.compatBottomSP.size() + << " bottoms and " << state.compatTopSP.size() + << " tops for middle candidate indexed " + << spM->index()); // filter candidates if (m_config.useDetailedDoubleMeasurementInfo) { filterCandidates( diff --git a/Core/include/Acts/Seeding/SeedFinderGbts.ipp b/Core/include/Acts/Seeding/SeedFinderGbts.ipp index 91f5f3f64e4..347ca8e1e13 100644 --- a/Core/include/Acts/Seeding/SeedFinderGbts.ipp +++ b/Core/include/Acts/Seeding/SeedFinderGbts.ipp @@ -159,7 +159,7 @@ void SeedFinderGbts::runGbts_TrackFinder( .m_phiSliceWidth; // the default sliding window along phi if (m_config.m_useEtaBinning) { - deltaPhi = 0.001f + m_maxCurv * std::fabs(rb2 - rb1); + deltaPhi = 0.001f + m_maxCurv * std::abs(rb2 - rb1); } unsigned int first_it = 0; @@ -219,7 +219,7 @@ void SeedFinderGbts::runGbts_TrackFinder( float dz = z2 - z1; float tau = dz / dr; - float ftau = std::fabs(tau); + float ftau = std::abs(tau); if (ftau > 36.0) { continue; } @@ -288,17 +288,18 @@ void SeedFinderGbts::runGbts_TrackFinder( float tau2 = edgeStorage.at(n2_in_idx).m_p[0]; float tau_ratio = tau2 * uat_1 - 1.0f; - if (std::fabs(tau_ratio) > - m_config.cut_tau_ratio_max) { // bad - // match + // bad match + if (std::abs(tau_ratio) > m_config.cut_tau_ratio_max) { continue; } - isGood = true; // good match found + + // good match found + isGood = true; break; } } if (!isGood) { - continue; // no moatch found, skip creating [n1 <- n2] edge + continue; // no match found, skip creating [n1 <- n2] edge } float curv = D * std::sqrt(L2); // signed curvature diff --git a/Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp b/Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp index edd8e0f3074..056b6cc6831 100644 --- a/Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp +++ b/Core/include/Acts/Seeding/SeedFinderOrthogonal.ipp @@ -226,7 +226,7 @@ bool SeedFinderOrthogonal::validTuple( * Cut: Ensure that the forward angle (z / r) lies within reasonable bounds, * which is to say the absolute value must be smaller than the max cot(θ). */ - if (std::fabs(cotTheta) > m_config.cotThetaMax) { + if (std::abs(cotTheta) > m_config.cotThetaMax) { return false; } diff --git a/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.hpp b/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.hpp index 4410f1c125b..a2a214fa39b 100644 --- a/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.hpp +++ b/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.hpp @@ -11,6 +11,7 @@ #include "Acts/Seeding/BinnedGroup.hpp" #include "Acts/Seeding/SeedFinderConfig.hpp" #include "Acts/Utilities/Grid.hpp" +#include "Acts/Utilities/Logger.hpp" #include #include @@ -158,7 +159,8 @@ class CylindricalSpacePointGridCreator { template static Acts::CylindricalSpacePointGrid createGrid( const Acts::CylindricalSpacePointGridConfig& _config, - const Acts::CylindricalSpacePointGridOptions& _options); + const Acts::CylindricalSpacePointGridOptions& _options, + const Acts::Logger& logger = Acts::getDummyLogger()); template @@ -167,7 +169,8 @@ class CylindricalSpacePointGridCreator { const Acts::SeedFinderOptions& options, Acts::CylindricalSpacePointGrid& grid, external_spacepoint_iterator_t spBegin, - external_spacepoint_iterator_t spEnd); + external_spacepoint_iterator_t spEnd, + const Acts::Logger& logger = Acts::getDummyLogger()); template requires std::ranges::range && @@ -177,7 +180,8 @@ class CylindricalSpacePointGridCreator { const Acts::SeedFinderConfig& config, const Acts::SeedFinderOptions& options, Acts::CylindricalSpacePointGrid& grid, - const external_collection_t& collection); + const external_collection_t& collection, + const Acts::Logger& logger = Acts::getDummyLogger()); }; } // namespace Acts diff --git a/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp b/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp index 523d470eae5..b99cdbdfaf9 100644 --- a/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp +++ b/Core/include/Acts/Seeding/detail/CylindricalSpacePointGrid.ipp @@ -12,7 +12,8 @@ template Acts::CylindricalSpacePointGrid Acts::CylindricalSpacePointGridCreator::createGrid( const Acts::CylindricalSpacePointGridConfig& config, - const Acts::CylindricalSpacePointGridOptions& options) { + const Acts::CylindricalSpacePointGridOptions& options, + const Acts::Logger& logger) { if (!config.isInInternalUnits) { throw std::runtime_error( "CylindricalSpacePointGridConfig not in ACTS internal units in " @@ -30,6 +31,9 @@ Acts::CylindricalSpacePointGridCreator::createGrid( // for no magnetic field, create 100 phi-bins if (options.bFieldInZ == 0) { phiBins = 100; + ACTS_VERBOSE( + "B-Field is 0 (z-coordinate), setting the number of bins in phi to " + << phiBins); } else { // calculate circle intersections of helix and max detector radius float minHelixRadius = @@ -39,7 +43,7 @@ Acts::CylindricalSpacePointGridCreator::createGrid( // = pT[MeV] / (300 *Bz[kT]) // sanity check: if yOuter takes the square root of a negative number - if (minHelixRadius < config.rMax / 2) { + if (minHelixRadius < config.rMax * 0.5) { throw std::domain_error( "The value of minHelixRadius cannot be smaller than rMax / 2. Please " "check the configuration of bFieldInZ and minPt"); @@ -141,6 +145,12 @@ Acts::CylindricalSpacePointGridCreator::createGrid( Axis zAxis(std::move(zValues)); Axis rAxis(std::move(rValues)); + + ACTS_VERBOSE("Defining Grid:"); + ACTS_VERBOSE("- Phi Axis: " << phiAxis); + ACTS_VERBOSE("- Z axis : " << zAxis); + ACTS_VERBOSE("- R axis : " << rAxis); + return Acts::CylindricalSpacePointGrid( std::make_tuple(std::move(phiAxis), std::move(zAxis), std::move(rAxis))); } @@ -152,7 +162,7 @@ void Acts::CylindricalSpacePointGridCreator::fillGrid( const Acts::SeedFinderOptions& options, Acts::CylindricalSpacePointGrid& grid, external_spacepoint_iterator_t spBegin, - external_spacepoint_iterator_t spEnd) { + external_spacepoint_iterator_t spEnd, const Acts::Logger& logger) { if (!config.isInInternalUnits) { throw std::runtime_error( "SeedFinderConfig not in ACTS internal units in BinnedSPGroup"); @@ -180,9 +190,10 @@ void Acts::CylindricalSpacePointGridCreator::fillGrid( std::vector rBinsIndex; rBinsIndex.reserve(grid.size()); + ACTS_VERBOSE("Fetching " << std::distance(spBegin, spEnd) + << " space points to the grid"); std::size_t counter = 0ul; - for (external_spacepoint_iterator_t it = spBegin; it != spEnd; - it++, ++counter) { + for (external_spacepoint_iterator_t it = spBegin; it != spEnd; ++it) { const external_spacepoint_t& sp = *it; // remove SPs according to experiment specific cuts @@ -199,6 +210,7 @@ void Acts::CylindricalSpacePointGridCreator::fillGrid( std::size_t globIndex = grid.globalBinFromPosition(position); auto& rbin = grid.at(globIndex); rbin.push_back(&sp); + ++counter; // keep track of the bins we modify so that we can later sort the SPs in // those bins only @@ -213,6 +225,9 @@ void Acts::CylindricalSpacePointGridCreator::fillGrid( auto& rbin = grid.atPosition(binIndex); std::ranges::sort(rbin, {}, [](const auto& rb) { return rb->radius(); }); } + + ACTS_VERBOSE( + "Number of space points inserted (within grid range): " << counter); } template @@ -223,8 +238,8 @@ void Acts::CylindricalSpacePointGridCreator::fillGrid( const Acts::SeedFinderConfig& config, const Acts::SeedFinderOptions& options, Acts::CylindricalSpacePointGrid& grid, - const external_collection_t& collection) { + const external_collection_t& collection, const Acts::Logger& logger) { Acts::CylindricalSpacePointGridCreator::fillGrid( config, options, grid, std::ranges::begin(collection), - std::ranges::end(collection)); + std::ranges::end(collection), logger); } diff --git a/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp b/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp index 05e236e1e29..35acbc49feb 100644 --- a/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp +++ b/Core/include/Acts/TrackFinding/CombinatorialKalmanFilter.hpp @@ -399,7 +399,7 @@ class CombinatorialKalmanFilter { measurementSelector(trackStateCandidates, isOutlier, logger); if (!selectorResult.ok()) { ACTS_ERROR("Selection of calibrated measurements failed: " - << selectorResult.error()); + << selectorResult.error().message()); resultTrackStateList = ResultTrackStateList::failure(selectorResult.error()); } else { diff --git a/Core/include/Acts/TrackFinding/TrackSelector.hpp b/Core/include/Acts/TrackFinding/TrackSelector.hpp index bca7fa8d2a0..459ab996857 100644 --- a/Core/include/Acts/TrackFinding/TrackSelector.hpp +++ b/Core/include/Acts/TrackFinding/TrackSelector.hpp @@ -427,8 +427,9 @@ bool TrackSelector::isValidTrack(const track_proxy_t& track) const { const Config* cutsPtr{nullptr}; if (!m_isUnbinned) { - if (absEta() < m_cfg.absEtaEdges.front() || - _absEta >= m_cfg.absEtaEdges.back()) { + // return false if |eta| is outside its range, or nan. + if (!(absEta() >= m_cfg.absEtaEdges.front() && + _absEta < m_cfg.absEtaEdges.back())) { return false; } cutsPtr = &m_cfg.getCuts(_eta); diff --git a/Core/include/Acts/TrackFitting/GlobalChiSquareFitter.hpp b/Core/include/Acts/TrackFitting/GlobalChiSquareFitter.hpp index 92a6a4f76ba..968843fa479 100644 --- a/Core/include/Acts/TrackFitting/GlobalChiSquareFitter.hpp +++ b/Core/include/Acts/TrackFitting/GlobalChiSquareFitter.hpp @@ -18,6 +18,7 @@ #include "Acts/EventData/SourceLink.hpp" #include "Acts/EventData/TrackContainerFrontendConcept.hpp" #include "Acts/EventData/TrackParameters.hpp" +#include "Acts/EventData/TrackProxyConcept.hpp" #include "Acts/EventData/VectorMultiTrajectory.hpp" #include "Acts/EventData/VectorTrackContainer.hpp" #include "Acts/Geometry/GeometryContext.hpp" @@ -372,30 +373,30 @@ void addMeasurementToGx2fSums(Eigen::MatrixXd& aMatrixExtended, ACTS_VERBOSE( "Contributions in addMeasurementToGx2fSums:\n" - << "kMeasDim: " << kMeasDim << "\n" - << "predicted" << predicted.transpose() << "\n" - << "measurement: " << measurement.transpose() << "\n" - << "covarianceMeasurement:\n" + << " kMeasDim: " << kMeasDim << "\n" + << " predicted: " << predicted.transpose() << "\n" + << " measurement: " << measurement.transpose() << "\n" + << " covarianceMeasurement:\n" << covarianceMeasurement << "\n" - << "projector:\n" + << " projector:\n" << projector.eval() << "\n" - << "projJacobian:\n" + << " projJacobian:\n" << projJacobian.eval() << "\n" - << "projPredicted: " << (projPredicted.transpose()).eval() << "\n" - << "residual: " << (residual.transpose()).eval() << "\n" - << "extendedJacobian:\n" + << " projPredicted: " << (projPredicted.transpose()).eval() << "\n" + << " residual: " << (residual.transpose()).eval() << "\n" + << " extendedJacobian:\n" << extendedJacobian << "\n" - << "aMatrixMeas:\n" + << " aMatrix contribution:\n" << (projJacobian.transpose() * (*safeInvCovMeasurement) * projJacobian) .eval() << "\n" - << "bVectorMeas: " + << " bVector contribution: " << (residual.transpose() * (*safeInvCovMeasurement) * projJacobian).eval() << "\n" - << "chi2sumMeas: " + << " chi2sum contribution: " << (residual.transpose() * (*safeInvCovMeasurement) * residual)(0, 0) << "\n" - << "safeInvCovMeasurement:\n" + << " safeInvCovMeasurement:\n" << (*safeInvCovMeasurement)); return; @@ -459,8 +460,8 @@ void addMaterialToGx2fSums( ACTS_VERBOSE( "Contributions in addMaterialToGx2fSums:\n" - << " invCov: " << invCov << "\n" - << " sinThetaLoc: " << sinThetaLoc << "\n" + << " invCov: " << invCov << "\n" + << " sinThetaLoc: " << sinThetaLoc << "\n" << " deltaPosition: " << deltaPosition << "\n" << " Phi:\n" << " scattering angle: " << scatteringAngles[eBoundPhi] << "\n" @@ -485,6 +486,103 @@ void addMaterialToGx2fSums( return; } +/// @brief Fill the GX2F system with data from a track +/// +/// This function processes a track proxy and updates the aMatrix, bVector, and +/// chi2 values for the GX2F fitting system. It considers material only if +/// multiple scattering is enabled. +/// +/// @tparam track_proxy_t The type of the track proxy +/// +/// @param track A mutable track proxy to operate on +/// @param aMatrixExtended The aMatrix, summing over second derivatives for the fitting system +/// @param bVectorExtended The bVector, summing over first derivatives for the fitting system +/// @param chi2sum Accumulated chi2 value of the system +/// @param countNdf The number of degrees of freedom counted so far +/// @param multipleScattering Flag to consider multiple scattering in the calculation +/// @param scatteringMap Map of geometry identifiers to scattering properties, containing all scattering angles and covariances +/// @param geoIdVector A vector to store geometry identifiers for tracking processed elements +/// @param logger A logger instance +template +void fillGx2fSystem( + const track_proxy_t track, Eigen::MatrixXd& aMatrixExtended, + Eigen::VectorXd& bVectorExtended, double& chi2sum, std::size_t& countNdf, + const bool multipleScattering, + const std::unordered_map& + scatteringMap, + std::vector& geoIdVector, const Logger& logger) { + std::vector jacobianFromStart; + jacobianFromStart.emplace_back(BoundMatrix::Identity()); + + for (const auto& trackState : track.trackStates()) { + // Get and store geoId for the current surface + const GeometryIdentifier geoId = trackState.referenceSurface().geometryId(); + ACTS_DEBUG("Start to investigate trackState on surface " << geoId); + const auto typeFlags = trackState.typeFlags(); + const bool stateHasMeasurement = + typeFlags.test(TrackStateFlag::MeasurementFlag); + const bool stateHasMaterial = typeFlags.test(TrackStateFlag::MaterialFlag); + + // First we figure out, if we would need to look into material + // surfaces at all. Later, we also check, if the material slab is + // valid, otherwise we modify this flag to ignore the material + // completely. + bool doMaterial = multipleScattering && stateHasMaterial; + if (doMaterial) { + const auto scatteringMapId = scatteringMap.find(geoId); + assert(scatteringMapId != scatteringMap.end() && + "No scattering angles found for material surface."); + doMaterial = doMaterial && scatteringMapId->second.materialIsValid(); + } + + // We only consider states with a measurement (and/or material) + if (!stateHasMeasurement && !doMaterial) { + ACTS_DEBUG(" Skip state."); + continue; + } + + // update all Jacobians from start + for (auto& jac : jacobianFromStart) { + jac = trackState.jacobian() * jac; + } + + // Handle measurement + if (stateHasMeasurement) { + ACTS_DEBUG(" Handle measurement."); + + const auto measDim = trackState.calibratedSize(); + + if (measDim < 1 || 6 < measDim) { + ACTS_ERROR("Can not process state with measurement with " + << measDim << " dimensions."); + throw std::domain_error( + "Found measurement with less than 1 or more than 6 dimension(s)."); + } + + countNdf += measDim; + + visit_measurement(measDim, [&](auto N) { + addMeasurementToGx2fSums(aMatrixExtended, bVectorExtended, chi2sum, + jacobianFromStart, trackState, logger); + }); + } + + // Handle material + if (doMaterial) { + ACTS_DEBUG(" Handle material"); + // Add for this material a new Jacobian, starting from this surface. + jacobianFromStart.emplace_back(BoundMatrix::Identity()); + + // Add the material contribution to the system + addMaterialToGx2fSums(aMatrixExtended, bVectorExtended, chi2sum, + geoIdVector.size(), scatteringMap, trackState, + logger); + + geoIdVector.emplace_back(geoId); + } + } +} + /// @brief Calculate and update the covariance of the fitted parameters /// /// This function calculates the covariance of the fitted parameters using @@ -727,13 +825,15 @@ class Gx2Fitter { if (doMaterial) { ACTS_DEBUG(" Update parameters with scattering angles."); const auto scatteringMapId = scatteringMap->find(geoId); - ACTS_VERBOSE(" scatteringAngles:\n" - << scatteringMapId->second.scatteringAngles() - << "\n boundParams before the update:\n" - << boundParams); + ACTS_VERBOSE( + " scatteringAngles: " + << scatteringMapId->second.scatteringAngles().transpose()); + ACTS_VERBOSE(" boundParams before the update: " + << boundParams.parameters().transpose()); boundParams.parameters() += scatteringMapId->second.scatteringAngles(); - ACTS_VERBOSE(" boundParams after the update:\n" << boundParams); + ACTS_VERBOSE(" boundParams after the update: " + << boundParams.parameters().transpose()); } // Fill the track state @@ -829,13 +929,15 @@ class Gx2Fitter { // multipleScattering and have material ACTS_DEBUG(" Update parameters with scattering angles."); const auto scatteringMapId = scatteringMap->find(geoId); - ACTS_VERBOSE(" scatteringAngles:\n" - << scatteringMapId->second.scatteringAngles() - << "\n boundParams before the update:\n" - << boundParams); + ACTS_VERBOSE( + " scatteringAngles: " + << scatteringMapId->second.scatteringAngles().transpose()); + ACTS_VERBOSE(" boundParams before the update: " + << boundParams.parameters().transpose()); boundParams.parameters() += scatteringMapId->second.scatteringAngles(); - ACTS_VERBOSE(" boundParams after the update:\n" << boundParams); + ACTS_VERBOSE(" boundParams after the update: " + << boundParams.parameters().transpose()); // Fill the track state trackStateProxy.smoothed() = boundParams.parameters(); @@ -998,7 +1100,7 @@ class Gx2Fitter { requires(!isDirectNavigator) { // Preprocess Measurements (SourceLinks -> map) - // To be able to find measurements later, we put them into a map + // To be able to find measurements later, we put them into a map. // We need to copy input SourceLinks anyway, so the map can own them. ACTS_VERBOSE("Preparing " << std::distance(it, end) << " input measurements"); @@ -1009,7 +1111,6 @@ class Gx2Fitter { auto geoId = gx2fOptions.extensions.surfaceAccessor(sl)->geometryId(); inputMeasurements.emplace(geoId, std::move(sl)); } - ACTS_VERBOSE("inputMeasurements.size() = " << inputMeasurements.size()); // Store, if we want to do multiple scattering. We still need to pass this // option to the Actor. @@ -1056,21 +1157,21 @@ class Gx2Fitter { // track parameters. BoundMatrix fullCovariancePredicted = BoundMatrix::Identity(); - ACTS_VERBOSE("params:\n" << params); + ACTS_VERBOSE("Initial parameters: " << params.parameters().transpose()); /// Actual Fitting ///////////////////////////////////////////////////////// ACTS_DEBUG("Start to iterate"); // Iterate the fit and improve result. Abort after n steps or after - // convergence - // nUpdate is initialized outside to save its state for the track + // convergence. + // nUpdate is initialized outside to save its state for the track. std::size_t nUpdate = 0; for (nUpdate = 0; nUpdate < gx2fOptions.nUpdateMax; nUpdate++) { ACTS_DEBUG("nUpdate = " << nUpdate + 1 << "/" << gx2fOptions.nUpdateMax); // update params params.parameters() += deltaParams; - ACTS_VERBOSE("updated params:\n" << params); + ACTS_VERBOSE("Updated parameters: " << params.parameters().transpose()); // set up propagator and co Acts::GeometryContext geoCtx = gx2fOptions.geoContext; @@ -1130,9 +1231,8 @@ class Gx2Fitter { tipIndex = gx2fResult.lastMeasurementIndex; // It could happen, that no measurements were found. Then the track would - // be empty and the following operations would be invalid. - // Usually, this only happens during the first iteration, due to bad - // initial parameters. + // be empty and the following operations would be invalid. Usually, this + // only happens during the first iteration, due to bad initial parameters. if (tipIndex == Acts::MultiTrajectoryTraits::kInvalid) { ACTS_INFO("Did not find any measurements in nUpdate " << nUpdate + 1 << "/" << gx2fOptions.nUpdateMax); @@ -1185,85 +1285,15 @@ class Gx2Fitter { Eigen::VectorXd bVectorExtended = Eigen::VectorXd::Zero(dimsExtendedParams); - std::vector jacobianFromStart; - jacobianFromStart.emplace_back(BoundMatrix::Identity()); - // This vector stores the IDs for each visited material in order. We use // it later for updating the scattering angles. We cannot use // scatteringMap directly, since we cannot guarantee, that we will visit // all stored material in each propagation. std::vector geoIdVector; - for (const auto& trackState : track.trackStates()) { - // Get and store geoId for the current surface - const GeometryIdentifier geoId = - trackState.referenceSurface().geometryId(); - ACTS_DEBUG("Start to investigate trackState on surface " << geoId); - const auto typeFlags = trackState.typeFlags(); - const bool stateHasMeasurement = - typeFlags.test(TrackStateFlag::MeasurementFlag); - const bool stateHasMaterial = - typeFlags.test(TrackStateFlag::MaterialFlag); - - // First we figure out, if we would need to look into material surfaces - // at all. Later, we also check, if the material slab is valid, - // otherwise we modify this flag to ignore the material completely. - bool doMaterial = multipleScattering && stateHasMaterial; - if (doMaterial) { - const auto scatteringMapId = scatteringMap.find(geoId); - assert(scatteringMapId != scatteringMap.end() && - "No scattering angles found for material surface."); - doMaterial = doMaterial && scatteringMapId->second.materialIsValid(); - } - - // We only consider states with a measurement (and/or material) - if (!stateHasMeasurement && !doMaterial) { - ACTS_DEBUG(" Skip state."); - continue; - } - - // update all Jacobians from start - for (auto& jac : jacobianFromStart) { - jac = trackState.jacobian() * jac; - } - - // Handle measurement - if (stateHasMeasurement) { - ACTS_DEBUG(" Handle measurement."); - - const auto measDim = trackState.calibratedSize(); - - if (measDim < 1 || 6 < measDim) { - ACTS_ERROR("Can not process state with measurement with " - << measDim << " dimensions."); - throw std::domain_error( - "Found measurement with less than 1 or more than 6 " - "dimension(s)."); - } - - countNdf += measDim; - - visit_measurement(measDim, [&](auto N) { - addMeasurementToGx2fSums(aMatrixExtended, bVectorExtended, - chi2sum, jacobianFromStart, trackState, - *m_addToSumLogger); - }); - } - - // Handle material - if (doMaterial) { - ACTS_DEBUG(" Handle material"); - // Add for this material a new Jacobian, starting from this surface. - jacobianFromStart.emplace_back(BoundMatrix::Identity()); - - // Add the material contribution to the system - addMaterialToGx2fSums(aMatrixExtended, bVectorExtended, chi2sum, - geoIdVector.size(), scatteringMap, trackState, - *m_addToSumLogger); - - geoIdVector.emplace_back(geoId); - } - } + fillGx2fSystem(track, aMatrixExtended, bVectorExtended, chi2sum, countNdf, + multipleScattering, scatteringMap, geoIdVector, + *m_addToSumLogger); // Get required number of degrees of freedom ndfSystem. // We have only 3 cases, because we always have l0, l1, phi, theta @@ -1279,12 +1309,11 @@ class Gx2Fitter { } // This check takes into account the evaluated dimensions of the - // measurements. To fit, we need at least NDF+1 measurements. However, - // we count n-dimensional measurements for n measurements, reducing the - // effective number of needed measurements. - // We might encounter the case, where we cannot use some (parts of a) - // measurements, maybe if we do not support that kind of measurement. This - // is also taken into account here. + // measurements. To fit, we need at least NDF+1 measurements. However, we + // count n-dimensional measurements for n measurements, reducing the + // effective number of needed measurements. We might encounter the case, + // where we cannot use some (parts of a) measurements, maybe if we do not + // support that kind of measurement. This is also taken into account here. // We skip the check during the first iteration, since we cannot guarantee // to hit all/enough measurement surfaces with the initial parameter // guess. @@ -1371,7 +1400,7 @@ class Gx2Fitter { oldChi2sum = chi2sum; } ACTS_DEBUG("Finished to iterate"); - ACTS_VERBOSE("final params:\n" << params); + ACTS_VERBOSE("Final parameters: " << params.parameters().transpose()); /// Finish Fitting ///////////////////////////////////////////////////////// ACTS_VERBOSE("Final scattering angles:"); @@ -1384,7 +1413,7 @@ class Gx2Fitter { << " )"); } - ACTS_VERBOSE("final covariance:\n" << fullCovariancePredicted); + ACTS_VERBOSE("Final covariance:\n" << fullCovariancePredicted); // Propagate again with the final covariance matrix. This is necessary to // obtain the propagated covariance for each state. @@ -1392,7 +1421,7 @@ class Gx2Fitter { // step, we will not ignore the boundary checks for measurement surfaces. We // want to create trackstates only on surfaces, that we actually hit. if (gx2fOptions.nUpdateMax > 0) { - ACTS_VERBOSE("final deltaParams:\n" << deltaParams); + ACTS_VERBOSE("Final delta parameters: " << deltaParams.transpose()); ACTS_VERBOSE("Propagate with the final covariance."); // update covariance params.covariance() = fullCovariancePredicted; diff --git a/Core/include/Acts/Utilities/DelegateChainBuilder.hpp b/Core/include/Acts/Utilities/DelegateChainBuilder.hpp index 6e4f2c89650..a24ab98ddb8 100644 --- a/Core/include/Acts/Utilities/DelegateChainBuilder.hpp +++ b/Core/include/Acts/Utilities/DelegateChainBuilder.hpp @@ -102,7 +102,7 @@ class DelegateChainBuilder, template static constexpr auto invoke(result_ptr result, const tuple_type* payloads, - callable_args... args) { + callable_args&&... args) { const auto& callable = findCallable(); if constexpr (!std::is_same_v, @@ -134,7 +134,7 @@ class DelegateChainBuilder, tuple_type m_payloads{}; - auto dispatch(callable_args... args) const { + auto dispatch(callable_args&&... args) const { if constexpr (std::is_same_v) { invoke(nullptr, &m_payloads, std::forward(args)...); } else { diff --git a/Core/src/EventData/CMakeLists.txt b/Core/src/EventData/CMakeLists.txt index 08a69711378..c425d533649 100644 --- a/Core/src/EventData/CMakeLists.txt +++ b/Core/src/EventData/CMakeLists.txt @@ -8,4 +8,5 @@ target_sources( TrackStatePropMask.cpp VectorMultiTrajectory.cpp VectorTrackContainer.cpp + TrackParameterHelpers.cpp ) diff --git a/Core/src/EventData/TrackParameterHelpers.cpp b/Core/src/EventData/TrackParameterHelpers.cpp new file mode 100644 index 00000000000..9e7ddb40abf --- /dev/null +++ b/Core/src/EventData/TrackParameterHelpers.cpp @@ -0,0 +1,64 @@ +// 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/EventData/TrackParameterHelpers.hpp" + +#include "Acts/Utilities/AngleHelpers.hpp" +#include "Acts/Utilities/VectorHelpers.hpp" + +#include + +bool Acts::isBoundVectorValid(const BoundVector& v, bool validateAngleRange, + double epsilon, double maxAbsEta) { + constexpr auto pi = std::numbers::pi_v; + + bool loc0Valid = std::isfinite(v[eBoundLoc0]); + bool loc1Valid = std::isfinite(v[eBoundLoc1]); + bool phiValid = std::isfinite(v[eBoundPhi]); + bool thetaValid = std::isfinite(v[eBoundTheta]); + bool qOverPValid = std::isfinite(v[eBoundQOverP]); + bool timeValid = std::isfinite(v[eBoundTime]); + + if (validateAngleRange) { + phiValid = phiValid && (v[eBoundPhi] + epsilon >= -pi) && + (v[eBoundPhi] - epsilon < pi); + thetaValid = thetaValid && (v[eBoundTheta] + epsilon >= 0) && + (v[eBoundTheta] - epsilon <= pi); + } + + bool etaValid = true; + if (std::isfinite(maxAbsEta)) { + double eta = AngleHelpers::etaFromTheta(v[eBoundTheta]); + etaValid = std::isfinite(eta) && (std::abs(eta) - epsilon <= maxAbsEta); + } + + return loc0Valid && loc1Valid && phiValid && thetaValid && qOverPValid && + timeValid && etaValid; +} + +bool Acts::isFreeVectorValid(const FreeVector& v, double epsilon, + double maxAbsEta) { + bool pos0Valid = std::isfinite(v[eFreePos0]); + bool pos1Valid = std::isfinite(v[eFreePos1]); + bool pos2Valid = std::isfinite(v[eFreePos2]); + bool dir0Valid = std::isfinite(v[eFreeDir0]); + bool dir1Valid = std::isfinite(v[eFreeDir1]); + bool dir2Valid = std::isfinite(v[eFreeDir2]); + bool dirValid = (std::abs(v.segment<3>(eFreeDir0).norm() - 1) - epsilon <= 0); + bool qOverPValid = std::isfinite(v[eFreeQOverP]); + bool timeValid = std::isfinite(v[eFreeTime]); + + bool etaValid = true; + if (std::isfinite(maxAbsEta)) { + double eta = VectorHelpers::eta(v.segment<3>(eFreeDir0)); + etaValid = std::isfinite(eta) && (std::abs(eta) - epsilon <= maxAbsEta); + } + + return pos0Valid && pos1Valid && pos2Valid && dir0Valid && dir1Valid && + dir2Valid && dirValid && qOverPValid && timeValid && etaValid; +} diff --git a/Core/src/Geometry/TrackingVolume.cpp b/Core/src/Geometry/TrackingVolume.cpp index e7d069b80c5..bbe9b60fc98 100644 --- a/Core/src/Geometry/TrackingVolume.cpp +++ b/Core/src/Geometry/TrackingVolume.cpp @@ -16,6 +16,8 @@ #include "Acts/Material/IMaterialDecorator.hpp" #include "Acts/Material/IVolumeMaterial.hpp" #include "Acts/Material/ProtoVolumeMaterial.hpp" +#include "Acts/Navigation/INavigationPolicy.hpp" +#include "Acts/Navigation/NavigationStream.hpp" #include "Acts/Propagator/Navigator.hpp" #include "Acts/Surfaces/RegularSurface.hpp" #include "Acts/Surfaces/Surface.hpp" @@ -28,6 +30,8 @@ #include #include +#include + namespace Acts { // constructor for arguments @@ -47,6 +51,10 @@ TrackingVolume::TrackingVolume( createBoundarySurfaces(); interlinkLayers(); connectDenseBoundarySurfaces(denseVolumeVector); + + DelegateChainBuilder{m_navigationDelegate} + .add<&INavigationPolicy::noopInitializeCandidates>() + .store(m_navigationDelegate); } TrackingVolume::TrackingVolume(Volume& volume, const std::string& volumeName) @@ -61,6 +69,8 @@ TrackingVolume::TrackingVolume(const Transform3& transform, {}, volumeName) {} TrackingVolume::~TrackingVolume() = default; +TrackingVolume::TrackingVolume(TrackingVolume&&) noexcept = default; +TrackingVolume& TrackingVolume::operator=(TrackingVolume&&) noexcept = default; const TrackingVolume* TrackingVolume::lowestTrackingVolume( const GeometryContext& gctx, const Vector3& position, @@ -735,4 +745,20 @@ void TrackingVolume::visualize(IVisualization3D& helper, } } +void TrackingVolume::setNavigationPolicy( + std::unique_ptr policy) { + if (policy == nullptr) { + throw std::invalid_argument("Navigation policy is nullptr"); + } + + m_navigationPolicy = std::move(policy); + m_navigationPolicy->connect(m_navigationDelegate); +} + +void TrackingVolume::initializeNavigationCandidates( + const NavigationArguments& args, AppendOnlyNavigationStream& stream, + const Logger& logger) const { + m_navigationDelegate(args, stream, logger); +} + } // namespace Acts diff --git a/Core/src/MagneticField/BFieldMapUtils.cpp b/Core/src/MagneticField/BFieldMapUtils.cpp index e7216aa3bf9..b5b92191589 100644 --- a/Core/src/MagneticField/BFieldMapUtils.cpp +++ b/Core/src/MagneticField/BFieldMapUtils.cpp @@ -58,8 +58,8 @@ Acts::fieldMapRZ( double zMax = zPos[nBinsZ - 1]; // calculate maxima (add one last bin, because bin value always corresponds to // left boundary) - double stepZ = std::fabs(zMax - zMin) / (nBinsZ - 1); - double stepR = std::fabs(rMax - rMin) / (nBinsR - 1); + double stepZ = std::abs(zMax - zMin) / (nBinsZ - 1); + double stepR = std::abs(rMax - rMin) / (nBinsR - 1); rMax += stepR; zMax += stepZ; if (firstQuadrant) { @@ -172,9 +172,9 @@ Acts::fieldMapXYZ( double zMax = zPos[nBinsZ - 1]; // calculate maxima (add one last bin, because bin value always corresponds to // left boundary) - double stepZ = std::fabs(zMax - zMin) / (nBinsZ - 1); - double stepY = std::fabs(yMax - yMin) / (nBinsY - 1); - double stepX = std::fabs(xMax - xMin) / (nBinsX - 1); + double stepZ = std::abs(zMax - zMin) / (nBinsZ - 1); + double stepY = std::abs(yMax - yMin) / (nBinsY - 1); + double stepX = std::abs(xMax - xMin) / (nBinsX - 1); xMax += stepX; yMax += stepY; zMax += stepZ; diff --git a/Core/src/Material/MaterialGridHelper.cpp b/Core/src/Material/MaterialGridHelper.cpp index a6d1a90416a..83c7946f77c 100644 --- a/Core/src/Material/MaterialGridHelper.cpp +++ b/Core/src/Material/MaterialGridHelper.cpp @@ -32,8 +32,8 @@ Acts::Grid2D Acts::createGrid(Acts::MaterialGridAxisData gridAxis1, // calculate maxima (add one last bin, because bin value always corresponds // to // left boundary) - double stepAxis1 = std::fabs(maxAxis1 - minAxis1) / (nBinsAxis1 - 1); - double stepAxis2 = std::fabs(maxAxis2 - minAxis2) / (nBinsAxis2 - 1); + double stepAxis1 = std::abs(maxAxis1 - minAxis1) / (nBinsAxis1 - 1); + double stepAxis2 = std::abs(maxAxis2 - minAxis2) / (nBinsAxis2 - 1); maxAxis1 += stepAxis1; maxAxis2 += stepAxis2; @@ -64,11 +64,11 @@ Acts::Grid3D Acts::createGrid(Acts::MaterialGridAxisData gridAxis1, // to // left boundary) double stepAxis1 = - std::fabs(maxAxis1 - minAxis1) / std::max(nBinsAxis1 - 1, std::size_t{1}); + std::abs(maxAxis1 - minAxis1) / std::max(nBinsAxis1 - 1, std::size_t{1}); double stepAxis2 = - std::fabs(maxAxis2 - minAxis2) / std::max(nBinsAxis2 - 1, std::size_t{1}); + std::abs(maxAxis2 - minAxis2) / std::max(nBinsAxis2 - 1, std::size_t{1}); double stepAxis3 = - std::fabs(maxAxis3 - minAxis3) / std::max(nBinsAxis3 - 1, std::size_t{1}); + std::abs(maxAxis3 - minAxis3) / std::max(nBinsAxis3 - 1, std::size_t{1}); maxAxis1 += stepAxis1; maxAxis2 += stepAxis2; maxAxis3 += stepAxis3; diff --git a/Core/src/Material/MaterialMapUtils.cpp b/Core/src/Material/MaterialMapUtils.cpp index a9b04275925..b51b1a3e223 100644 --- a/Core/src/Material/MaterialMapUtils.cpp +++ b/Core/src/Material/MaterialMapUtils.cpp @@ -64,8 +64,8 @@ auto Acts::materialMapperRZ( double zMax = *minMaxZ.second; // calculate maxima (add one last bin, because bin value always corresponds to // left boundary) - double stepZ = std::fabs(zMax - zMin) / (nBinsZ - 1); - double stepR = std::fabs(rMax - rMin) / (nBinsR - 1); + double stepZ = std::abs(zMax - zMin) / (nBinsZ - 1); + double stepR = std::abs(rMax - rMin) / (nBinsR - 1); rMax += stepR; zMax += stepZ; @@ -156,9 +156,9 @@ auto Acts::materialMapperXYZ( double zMax = *minMaxZ.second; // calculate maxima (add one last bin, because bin value always corresponds to // left boundary) - double stepZ = std::fabs(zMax - zMin) / (nBinsZ - 1); - double stepY = std::fabs(yMax - yMin) / (nBinsY - 1); - double stepX = std::fabs(xMax - xMin) / (nBinsX - 1); + double stepZ = std::abs(zMax - zMin) / (nBinsZ - 1); + double stepY = std::abs(yMax - yMin) / (nBinsY - 1); + double stepX = std::abs(xMax - xMin) / (nBinsX - 1); xMax += stepX; yMax += stepY; zMax += stepZ; diff --git a/Core/src/Navigation/CMakeLists.txt b/Core/src/Navigation/CMakeLists.txt index 81cbf616d44..72bbf65b853 100644 --- a/Core/src/Navigation/CMakeLists.txt +++ b/Core/src/Navigation/CMakeLists.txt @@ -1 +1,7 @@ -target_sources(ActsCore PRIVATE NavigationStream.cpp) +target_sources( + ActsCore + PRIVATE + NavigationStream.cpp + TryAllNavigationPolicy.cpp + SurfaceArrayNavigationPolicy.cpp +) diff --git a/Core/src/Navigation/NavigationStream.cpp b/Core/src/Navigation/NavigationStream.cpp index bf15367cd3b..c36eed12bbe 100644 --- a/Core/src/Navigation/NavigationStream.cpp +++ b/Core/src/Navigation/NavigationStream.cpp @@ -13,10 +13,12 @@ #include -bool Acts::NavigationStream::initialize(const GeometryContext& gctx, - const QueryPoint& queryPoint, - const BoundaryTolerance& cTolerance, - ActsScalar onSurfaceTolerance) { +namespace Acts { + +bool NavigationStream::initialize(const GeometryContext& gctx, + const QueryPoint& queryPoint, + const BoundaryTolerance& cTolerance, + ActsScalar onSurfaceTolerance) { // Position and direction from the query point const Vector3& position = queryPoint.position; const Vector3& direction = queryPoint.direction; @@ -36,7 +38,7 @@ bool Acts::NavigationStream::initialize(const GeometryContext& gctx, // A container collecting additional candidates from multiple // valid interseciton std::vector additionalCandidates = {}; - for (auto& [sIntersection, portal, bTolerance] : m_candidates) { + for (auto& [sIntersection, gen2Portal, portal, bTolerance] : m_candidates) { // Get the surface from the object intersection const Surface* surface = sIntersection.object(); // Intersect the surface @@ -58,7 +60,10 @@ bool Acts::NavigationStream::initialize(const GeometryContext& gctx, originalCandidateUpdated = true; } else { additionalCandidates.emplace_back( - Candidate{rsIntersection, portal, bTolerance}); + Candidate{.intersection = rsIntersection, + .gen2Portal = gen2Portal, + .portal = portal, + .bTolerance = bTolerance}); } } } @@ -74,7 +79,7 @@ bool Acts::NavigationStream::initialize(const GeometryContext& gctx, // The we find the first invalid candidate auto firstInvalid = std::ranges::find_if(m_candidates, [](const Candidate& a) { - const auto& [aIntersection, aPortal, aTolerance] = a; + const auto& [aIntersection, aGen2Portal, aPortal, aTolerance] = a; return !aIntersection.isValid(); }); @@ -88,32 +93,28 @@ bool Acts::NavigationStream::initialize(const GeometryContext& gctx, return true; } -bool Acts::NavigationStream::update(const GeometryContext& gctx, - const QueryPoint& queryPoint, - ActsScalar onSurfaceTolerance) { - // Position and direction from the query point - const Vector3& position = queryPoint.position; - const Vector3& direction = queryPoint.direction; - +bool NavigationStream::update(const GeometryContext& gctx, + const QueryPoint& queryPoint, + ActsScalar onSurfaceTolerance) { // Loop over the (currently valid) candidates and update for (; m_currentIndex < m_candidates.size(); ++m_currentIndex) { // Get the candidate, and resolve the tuple Candidate& candidate = currentCandidate(); - auto& [sIntersection, portal, bTolerance] = candidate; // Get the surface from the object intersection - const Surface* surface = sIntersection.object(); + const Surface* surface = candidate.intersection.object(); // (re-)Intersect the surface - auto multiIntersection = surface->intersect(gctx, position, direction, - bTolerance, onSurfaceTolerance); + auto multiIntersection = + surface->intersect(gctx, queryPoint.position, queryPoint.direction, + candidate.bTolerance, onSurfaceTolerance); // Split them into valid intersections for (const auto& rsIntersection : multiIntersection.split()) { // Skip wrong index solution - if (rsIntersection.index() != sIntersection.index()) { + if (rsIntersection.index() != candidate.intersection.index()) { continue; } // Valid solution is either on surface or updates the distance if (rsIntersection.isValid()) { - sIntersection = rsIntersection; + candidate.intersection = rsIntersection; return true; } } @@ -122,32 +123,57 @@ bool Acts::NavigationStream::update(const GeometryContext& gctx, return false; } -void Acts::NavigationStream::addSurfaceCandidate( - const Surface* surface, const BoundaryTolerance& bTolerance) { - m_candidates.emplace_back(Candidate{ - ObjectIntersection::invalid(surface), nullptr, bTolerance}); +void NavigationStream::addSurfaceCandidate( + const Surface& surface, const BoundaryTolerance& bTolerance) { + m_candidates.emplace_back( + Candidate{.intersection = ObjectIntersection::invalid(&surface), + .bTolerance = bTolerance}); } -void Acts::NavigationStream::addSurfaceCandidates( - const std::vector& surfaces, - const BoundaryTolerance& bTolerance) { +void NavigationStream::addSurfaceCandidates( + std::span surfaces, const BoundaryTolerance& bTolerance) { std::ranges::for_each(surfaces, [&](const auto* surface) { - m_candidates.emplace_back(Candidate{ - ObjectIntersection::invalid(surface), nullptr, bTolerance}); + m_candidates.emplace_back( + Candidate{.intersection = ObjectIntersection::invalid(surface), + .bTolerance = bTolerance}); }); } -void Acts::NavigationStream::addPortalCandidate(const Portal* portal) { - m_candidates.emplace_back( - Candidate{ObjectIntersection::invalid(&(portal->surface())), - portal, BoundaryTolerance::None()}); +void NavigationStream::addPortalCandidate(const Experimental::Portal& portal) { + m_candidates.emplace_back(Candidate{ + .intersection = ObjectIntersection::invalid(&portal.surface()), + .gen2Portal = &portal, + .bTolerance = BoundaryTolerance::None()}); +} + +void NavigationStream::addPortalCandidate(const Portal& portal) { + m_candidates.emplace_back(Candidate{ + .intersection = ObjectIntersection::invalid(&portal.surface()), + .portal = &portal, + .bTolerance = BoundaryTolerance::None()}); } -void Acts::NavigationStream::addPortalCandidates( - const std::vector& portals) { +void NavigationStream::addPortalCandidates( + std::span portals) { std::ranges::for_each(portals, [&](const auto& portal) { - m_candidates.emplace_back( - Candidate{ObjectIntersection::invalid(&(portal->surface())), - portal, BoundaryTolerance::None()}); + m_candidates.emplace_back(Candidate{ + .intersection = + ObjectIntersection::invalid(&(portal->surface())), + .gen2Portal = portal, + .bTolerance = BoundaryTolerance::None()}); }); } + +AppendOnlyNavigationStream::AppendOnlyNavigationStream(NavigationStream& stream) + : m_stream{&stream} {} + +void AppendOnlyNavigationStream::addPortalCandidate(const Portal& portal) { + m_stream->addPortalCandidate(portal); +} + +void AppendOnlyNavigationStream::addSurfaceCandidate( + const Surface& surface, const BoundaryTolerance& bTolerance) { + m_stream->addSurfaceCandidate(surface, bTolerance); +} + +} // namespace Acts diff --git a/Core/src/Navigation/SurfaceArrayNavigationPolicy.cpp b/Core/src/Navigation/SurfaceArrayNavigationPolicy.cpp new file mode 100644 index 00000000000..f60bbbf6839 --- /dev/null +++ b/Core/src/Navigation/SurfaceArrayNavigationPolicy.cpp @@ -0,0 +1,81 @@ +// 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/Navigation/SurfaceArrayNavigationPolicy.hpp" + +#include "Acts/Geometry/SurfaceArrayCreator.hpp" +#include "Acts/Geometry/TrackingVolume.hpp" +#include "Acts/Navigation/NavigationStream.hpp" + +#include + +namespace Acts { + +SurfaceArrayNavigationPolicy::SurfaceArrayNavigationPolicy( + const GeometryContext& gctx, const TrackingVolume& volume, + const Logger& logger, Config config) + : m_volume(volume) { + ACTS_VERBOSE("Constructing SurfaceArrayNavigationPolicy for volume " + << volume.volumeName()); + ACTS_VERBOSE("~> Layer type is " << config.layerType); + ACTS_VERBOSE("~> bins: " << config.bins.first << " x " << config.bins.second); + + SurfaceArrayCreator::Config sacConfig; + SurfaceArrayCreator sac{sacConfig, logger.clone("SrfArrCrtr")}; + + std::vector> surfaces; + surfaces.reserve(volume.surfaces().size()); + for (const auto& surface : volume.surfaces()) { + if (surface.associatedDetectorElement() == nullptr) { + continue; + } + surfaces.push_back(surface.getSharedPtr()); + } + + if (config.layerType == LayerType::Disc) { + auto [binsR, binsPhi] = config.bins; + m_surfaceArray = + sac.surfaceArrayOnDisc(gctx, std::move(surfaces), binsPhi, binsR); + } else if (config.layerType == LayerType::Cylinder) { + auto [binsPhi, binsZ] = config.bins; + m_surfaceArray = + sac.surfaceArrayOnCylinder(gctx, std::move(surfaces), binsPhi, binsZ); + } else if (config.layerType == LayerType::Plane) { + ACTS_ERROR("Plane layers are not yet supported"); + throw std::invalid_argument("Plane layers are not yet supported"); + } else { + throw std::invalid_argument("Unknown layer type"); + } + + if (!m_surfaceArray) { + ACTS_ERROR("Failed to create surface array"); + throw std::runtime_error("Failed to create surface array"); + } +} + +void SurfaceArrayNavigationPolicy::initializeCandidates( + const NavigationArguments& args, AppendOnlyNavigationStream& stream, + const Logger& logger) const { + ACTS_VERBOSE("SrfArrNavPol (volume=" << m_volume.volumeName() << ")"); + + ACTS_VERBOSE("Querying sensitive surfaces at " << args.position.transpose()); + const std::vector& sensitiveSurfaces = + m_surfaceArray->neighbors(args.position); + ACTS_VERBOSE("~> Surface array reports " << sensitiveSurfaces.size() + << " sensitive surfaces"); + + for (const auto* surface : sensitiveSurfaces) { + stream.addSurfaceCandidate(*surface, args.tolerance); + }; +} + +void SurfaceArrayNavigationPolicy::connect(NavigationDelegate& delegate) const { + connectDefault(delegate); +} + +} // namespace Acts diff --git a/Core/src/Navigation/TryAllNavigationPolicy.cpp b/Core/src/Navigation/TryAllNavigationPolicy.cpp new file mode 100644 index 00000000000..40ca70c4079 --- /dev/null +++ b/Core/src/Navigation/TryAllNavigationPolicy.cpp @@ -0,0 +1,54 @@ +// 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/Navigation/TryAllNavigationPolicy.hpp" + +#include "Acts/Geometry/TrackingVolume.hpp" +#include "Acts/Navigation/NavigationStream.hpp" + +namespace Acts { + +TryAllNavigationPolicy::TryAllNavigationPolicy(const Config& config, + const GeometryContext& /*gctx*/, + const TrackingVolume& volume, + const Logger& logger) + : m_cfg{config}, m_volume(&volume) { + assert(m_volume != nullptr); + ACTS_VERBOSE("TryAllNavigationPolicy created for volume " + << m_volume->volumeName()); +} + +TryAllNavigationPolicy::TryAllNavigationPolicy(const GeometryContext& gctx, + const TrackingVolume& volume, + const Logger& logger) + : TryAllNavigationPolicy({}, gctx, volume, logger) {} + +void TryAllNavigationPolicy::initializeCandidates( + const NavigationArguments& args, AppendOnlyNavigationStream& stream, + const Logger& logger) const { + ACTS_VERBOSE("TryAllNavigationPolicy"); + assert(m_volume != nullptr); + + if (m_cfg.portals) { + for (const auto& portal : m_volume->portals()) { + stream.addPortalCandidate(portal); + } + } + + if (m_cfg.sensitives) { + for (const auto& surface : m_volume->surfaces()) { + stream.addSurfaceCandidate(surface, args.tolerance); + }; + } +} + +void TryAllNavigationPolicy::connect(NavigationDelegate& delegate) const { + connectDefault(delegate); +} + +} // namespace Acts diff --git a/Core/src/Surfaces/CylinderBounds.cpp b/Core/src/Surfaces/CylinderBounds.cpp index 27123d29ec0..64d3e9f547f 100644 --- a/Core/src/Surfaces/CylinderBounds.cpp +++ b/Core/src/Surfaces/CylinderBounds.cpp @@ -69,8 +69,8 @@ bool Acts::CylinderBounds::inside( double localx = lposition[0] > radius ? 2 * radius - lposition[0] : lposition[0]; Vector2 shiftedlposition = shifted(lposition); - if ((std::fabs(shiftedlposition[0]) <= halfPhi && - std::fabs(shiftedlposition[1]) <= halfLengthZ)) { + if ((std::abs(shiftedlposition[0]) <= halfPhi && + std::abs(shiftedlposition[1]) <= halfLengthZ)) { return true; } diff --git a/Core/src/Surfaces/CylinderSurface.cpp b/Core/src/Surfaces/CylinderSurface.cpp index a39dce4a4fa..4b3cd2db7be 100644 --- a/Core/src/Surfaces/CylinderSurface.cpp +++ b/Core/src/Surfaces/CylinderSurface.cpp @@ -180,7 +180,7 @@ double Acts::CylinderSurface::pathCorrection( const Acts::Vector3& direction) const { Vector3 normalT = normal(gctx, position); double cosAlpha = normalT.dot(direction); - return std::fabs(1. / cosAlpha); + return std::abs(1. / cosAlpha); } const Acts::CylinderBounds& Acts::CylinderSurface::bounds() const { diff --git a/Core/src/TrackFinding/MeasurementSelector.cpp b/Core/src/TrackFinding/MeasurementSelector.cpp index 130c8381536..f3de466f5df 100644 --- a/Core/src/TrackFinding/MeasurementSelector.cpp +++ b/Core/src/TrackFinding/MeasurementSelector.cpp @@ -29,6 +29,11 @@ MeasurementSelector::MeasurementSelector(const MeasurementSelectorCuts& cuts) : MeasurementSelector({{GeometryIdentifier(), cuts}}) {} MeasurementSelector::MeasurementSelector(const Config& config) { + if (config.empty()) { + throw std::invalid_argument( + "MeasurementSelector: Configuration must not be empty"); + } + std::vector tmp; tmp.reserve(config.size()); for (std::size_t i = 0; i < config.size(); ++i) { diff --git a/Core/src/Utilities/SpacePointUtility.cpp b/Core/src/Utilities/SpacePointUtility.cpp index 4b79fc03cc3..7018db37830 100644 --- a/Core/src/Utilities/SpacePointUtility.cpp +++ b/Core/src/Utilities/SpacePointUtility.cpp @@ -204,8 +204,8 @@ Result SpacePointUtility::calculateStripSPPosition( } // Check if m and n can be resolved in the interval (-1, 1) - if (fabs(spParams.m) <= spParams.limit && - fabs(spParams.n) <= spParams.limit) { + if (std::abs(spParams.m) <= spParams.limit && + std::abs(spParams.n) <= spParams.limit) { return Result::success(); } return Result::failure(m_error); @@ -226,7 +226,7 @@ Result SpacePointUtility::recoverSpacePoint( spParams.limit + stripLengthGapTolerance / spParams.mag_firstBtmToTop; // Check if m is just slightly outside - if (fabs(spParams.m) > spParams.limitExtended) { + if (std::abs(spParams.m) > spParams.limitExtended) { return Result::failure(m_error); } // Calculate n if not performed previously @@ -236,7 +236,7 @@ Result SpacePointUtility::recoverSpacePoint( spParams.secondBtmToTop.dot(spParams.firstBtmToTopXvtxToFirstMid2); } // Check if n is just slightly outside - if (fabs(spParams.n) > spParams.limitExtended) { + if (std::abs(spParams.n) > spParams.limitExtended) { return Result::failure(m_error); } /// The following code considers an overshoot of m and n in the same direction @@ -275,8 +275,8 @@ Result SpacePointUtility::recoverSpacePoint( spParams.n -= (biggerOvershoot / secOnFirstScale); // Check if this recovered the space point - if (fabs(spParams.m) < spParams.limit && - fabs(spParams.n) < spParams.limit) { + if (std::abs(spParams.m) < spParams.limit && + std::abs(spParams.n) < spParams.limit) { return Result::success(); } else { return Result::failure(m_error); @@ -294,8 +294,8 @@ Result SpacePointUtility::recoverSpacePoint( spParams.m += biggerOvershoot; spParams.n += (biggerOvershoot / secOnFirstScale); // Check if this recovered the space point - if (fabs(spParams.m) < spParams.limit && - fabs(spParams.n) < spParams.limit) { + if (std::abs(spParams.m) < spParams.limit && + std::abs(spParams.n) < spParams.limit) { return Result::success(); } } @@ -325,7 +325,7 @@ Result SpacePointUtility::calcPerpendicularProjection( double qr = (spParams.firstBtmToTop).dot(spParams.secondBtmToTop); double denom = spParams.firstBtmToTop.dot(spParams.firstBtmToTop) - qr * qr; // Check for numerical stability - if (fabs(denom) > 1e-6) { + if (std::abs(denom) > 1e-6) { // Return lambda0 return Result::success( (ac.dot(spParams.secondBtmToTop) * qr - diff --git a/Examples/Algorithms/Digitization/CMakeLists.txt b/Examples/Algorithms/Digitization/CMakeLists.txt index 14729f2784f..de98c7e74d4 100644 --- a/Examples/Algorithms/Digitization/CMakeLists.txt +++ b/Examples/Algorithms/Digitization/CMakeLists.txt @@ -3,6 +3,7 @@ add_library( SHARED src/DigitizationAlgorithm.cpp src/DigitizationConfig.cpp + src/DigitizationCoordinatesConverter.cpp src/MeasurementCreation.cpp src/DigitizationConfigurator.cpp src/ModuleClusters.cpp diff --git a/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationCoordinatesConverter.hpp b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationCoordinatesConverter.hpp new file mode 100644 index 00000000000..21c4f619b8a --- /dev/null +++ b/Examples/Algorithms/Digitization/include/ActsExamples/Digitization/DigitizationCoordinatesConverter.hpp @@ -0,0 +1,39 @@ +// 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 "ActsExamples/Digitization/DigitizationConfig.hpp" + +namespace ActsExamples { + +/// Utility that converts hit coordinates. +class DigitizationCoordinatesConverter final { + public: + /// Construct the converter + /// + /// @param config is the configuration + explicit DigitizationCoordinatesConverter(DigitizationConfig config); + + /// Get const access to the config + const DigitizationConfig& config() const { return m_cfg; } + + /// Convert the hit coordinates to the local frame. + std::tuple globalToLocal(std::uint64_t moduleId, double x, + double y, double z) const; + + /// Convert the hit coordinates to the global frame. + std::tuple localToGlobal(std::uint64_t moduleId, + double x, double y) const; + + private: + /// Configuration + DigitizationConfig m_cfg; +}; + +} // namespace ActsExamples diff --git a/Examples/Algorithms/Digitization/src/DigitizationCoordinatesConverter.cpp b/Examples/Algorithms/Digitization/src/DigitizationCoordinatesConverter.cpp new file mode 100644 index 00000000000..e83e7be995b --- /dev/null +++ b/Examples/Algorithms/Digitization/src/DigitizationCoordinatesConverter.cpp @@ -0,0 +1,63 @@ +// 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 "ActsExamples/Digitization/DigitizationCoordinatesConverter.hpp" + +#include "Acts/Definitions/Algebra.hpp" +#include "Acts/Geometry/GeometryContext.hpp" + +#include +#include +#include + +ActsExamples::DigitizationCoordinatesConverter:: + DigitizationCoordinatesConverter(DigitizationConfig config) + : m_cfg(std::move(config)) { + if (m_cfg.surfaceByIdentifier.empty()) { + throw std::invalid_argument("Missing Surface-GeometryID association map"); + } +} + +std::tuple +ActsExamples::DigitizationCoordinatesConverter::globalToLocal( + std::uint64_t moduleId, double x, double y, double z) const { + const Acts::GeometryIdentifier moduleGeoId = moduleId; + auto surfaceItr = m_cfg.surfaceByIdentifier.find(moduleGeoId); + if (surfaceItr == m_cfg.surfaceByIdentifier.end()) { + throw std::runtime_error("Surface not found for moduleGeoId"); + } + + // Transform the position into the local surface frame + const Acts::Surface* surfacePtr = surfaceItr->second; + const auto& invTransform = + surfacePtr->transform(Acts::GeometryContext()).inverse(); + + const Acts::Vector3 pos(x, y, z); + Acts::Vector2 pos2Local = (invTransform * pos).segment<2>(0); + + return {pos2Local.x(), pos2Local.y()}; +} + +std::tuple +ActsExamples::DigitizationCoordinatesConverter::localToGlobal( + std::uint64_t moduleId, double x, double y) const { + const Acts::GeometryIdentifier moduleGeoId = moduleId; + auto surfaceItr = m_cfg.surfaceByIdentifier.find(moduleGeoId); + if (surfaceItr == m_cfg.surfaceByIdentifier.end()) { + throw std::runtime_error("Surface not found for moduleGeoId"); + } + + // Transform the position into the global frame + const Acts::Surface* surfacePtr = surfaceItr->second; + const auto& transform = surfacePtr->transform(Acts::GeometryContext()); + + const Acts::Vector3 pos(x, y, 0); + Acts::Vector3 pos2Global = (transform * pos); + + return {pos2Global.x(), pos2Global.y(), pos2Global.z()}; +} diff --git a/Examples/Algorithms/Generators/ActsExamples/Generators/ParametricParticleGenerator.cpp b/Examples/Algorithms/Generators/ActsExamples/Generators/ParametricParticleGenerator.cpp index d6b6bb9eb30..dcc7ac573f3 100644 --- a/Examples/Algorithms/Generators/ActsExamples/Generators/ParametricParticleGenerator.cpp +++ b/Examples/Algorithms/Generators/ActsExamples/Generators/ParametricParticleGenerator.cpp @@ -89,7 +89,7 @@ ParametricParticleGenerator::operator()(RandomEngine& rng) { sinTheta = std::sqrt(1 - cosTheta * cosTheta); } else { const double eta = etaDist(rng); - const double theta = 2 * std::atan(std::exp(-eta)); + const double theta = Acts::AngleHelpers::thetaFromEta(eta); sinTheta = std::sin(theta); cosTheta = std::cos(theta); } diff --git a/Examples/Algorithms/TrackFinding/src/SeedingAlgorithm.cpp b/Examples/Algorithms/TrackFinding/src/SeedingAlgorithm.cpp index ed5b11e4df2..2cea4b7b505 100644 --- a/Examples/Algorithms/TrackFinding/src/SeedingAlgorithm.cpp +++ b/Examples/Algorithms/TrackFinding/src/SeedingAlgorithm.cpp @@ -45,9 +45,8 @@ ActsExamples::SeedingAlgorithm::SeedingAlgorithm( // internal units m_cfg.seedFilterConfig = m_cfg.seedFilterConfig.toInternalUnits(); m_cfg.seedFinderConfig.seedFilter = - std::make_shared>( - m_cfg.seedFilterConfig); - + std::make_unique>( + m_cfg.seedFilterConfig, logger().cloneWithSuffix("SeedFilter")); m_cfg.seedFinderConfig = m_cfg.seedFinderConfig.toInternalUnits().calculateDerivedQuantities(); m_cfg.seedFinderOptions = @@ -195,13 +194,10 @@ ActsExamples::SeedingAlgorithm::SeedingAlgorithm( m_topBinFinder = std::make_unique>( m_cfg.numPhiNeighbors, m_cfg.zBinNeighborsTop, 0); - m_cfg.seedFinderConfig.seedFilter = - std::make_unique>( - m_cfg.seedFilterConfig); m_seedFinder = Acts::SeedFinder>( - m_cfg.seedFinderConfig); + m_cfg.seedFinderConfig, logger().cloneWithSuffix("SeedFinder")); } ActsExamples::ProcessCode ActsExamples::SeedingAlgorithm::execute( @@ -244,10 +240,11 @@ ActsExamples::ProcessCode ActsExamples::SeedingAlgorithm::execute( Acts::CylindricalSpacePointGrid grid = Acts::CylindricalSpacePointGridCreator::createGrid( - m_cfg.gridConfig, m_cfg.gridOptions); + m_cfg.gridConfig, m_cfg.gridOptions, logger()); Acts::CylindricalSpacePointGridCreator::fillGrid( - m_cfg.seedFinderConfig, m_cfg.seedFinderOptions, grid, spContainer); + m_cfg.seedFinderConfig, m_cfg.seedFinderOptions, grid, spContainer, + logger()); // Compute radius Range // we rely on the fact the grid is storing the proxies diff --git a/Examples/Algorithms/TrackFitting/src/KalmanFitterFunction.cpp b/Examples/Algorithms/TrackFitting/src/KalmanFitterFunction.cpp index 6a5d2e0059b..6f835c5c967 100644 --- a/Examples/Algorithms/TrackFitting/src/KalmanFitterFunction.cpp +++ b/Examples/Algorithms/TrackFitting/src/KalmanFitterFunction.cpp @@ -62,7 +62,7 @@ struct SimpleReverseFilteringLogic { bool doBackwardFiltering( Acts::VectorMultiTrajectory::ConstTrackStateProxy trackState) const { - auto momentum = fabs(1 / trackState.filtered()[Acts::eBoundQOverP]); + auto momentum = std::abs(1 / trackState.filtered()[Acts::eBoundQOverP]); return (momentum <= momentumThreshold); } }; diff --git a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/TruthSeedSelector.cpp b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/TruthSeedSelector.cpp deleted file mode 100644 index 49640e5079f..00000000000 --- a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/TruthSeedSelector.cpp +++ /dev/null @@ -1,89 +0,0 @@ -// 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 "ActsExamples/TruthTracking/TruthSeedSelector.hpp" - -#include "Acts/Utilities/MultiIndex.hpp" -#include "Acts/Utilities/VectorHelpers.hpp" -#include "ActsExamples/EventData/Index.hpp" -#include "ActsExamples/EventData/SimParticle.hpp" -#include "ActsExamples/Utilities/Range.hpp" -#include "ActsFatras/EventData/Barcode.hpp" -#include "ActsFatras/EventData/Particle.hpp" - -#include -#include -#include - -namespace ActsExamples { -struct AlgorithmContext; -} // namespace ActsExamples - -using namespace ActsExamples; - -TruthSeedSelector::TruthSeedSelector(const Config& config, - Acts::Logging::Level level) - : IAlgorithm("TruthSeedSelector", level), m_cfg(config) { - if (m_cfg.inputParticles.empty()) { - throw std::invalid_argument("Missing input truth particles collection"); - } - if (m_cfg.inputMeasurementParticlesMap.empty()) { - throw std::invalid_argument("Missing input hit-particles map collection"); - } - if (m_cfg.outputParticles.empty()) { - throw std::invalid_argument("Missing output truth particles collection"); - } - - m_inputParticles.initialize(m_cfg.inputParticles); - m_inputMeasurementParticlesMap.initialize(m_cfg.inputMeasurementParticlesMap); - m_outputParticles.initialize(m_cfg.outputParticles); -} - -ProcessCode TruthSeedSelector::execute(const AlgorithmContext& ctx) const { - // prepare input collections - const auto& inputParticles = m_inputParticles(ctx); - const auto& hitParticlesMap = m_inputMeasurementParticlesMap(ctx); - // compute particle_id -> {hit_id...} map from the - // hit_id -> {particle_id...} map on the fly. - const auto& particleHitsMap = invertIndexMultimap(hitParticlesMap); - - // prepare output collection - SimParticleContainer selectedParticles; - selectedParticles.reserve(inputParticles.size()); - - auto within = [](double x, double min, double max) { - return (min <= x) && (x < max); - }; - auto isValidparticle = [&](const auto& p) { - const auto eta = Acts::VectorHelpers::eta(p.direction()); - const auto phi = Acts::VectorHelpers::phi(p.direction()); - const auto rho = Acts::VectorHelpers::perp(p.position()); - // find the corresponding hits for this particle - const auto& hits = makeRange(particleHitsMap.equal_range(p.particleId())); - // number of recorded hits - std::size_t nHits = hits.size(); - return within(rho, 0., m_cfg.rhoMax) && - within(p.position().z(), m_cfg.zMin, m_cfg.zMax) && - within(std::abs(eta), m_cfg.absEtaMin, m_cfg.absEtaMax) && - within(eta, m_cfg.etaMin, m_cfg.etaMax) && - within(phi, m_cfg.phiMin, m_cfg.phiMax) && - within(p.transverseMomentum(), m_cfg.ptMin, m_cfg.ptMax) && - within(nHits, m_cfg.nHitsMin, m_cfg.nHitsMax) && - (m_cfg.keepNeutral || (p.charge() != 0)); - }; - - // create prototracks for all input particles - for (const auto& particle : inputParticles) { - if (isValidparticle(particle)) { - selectedParticles.insert(particle); - } - } - - m_outputParticles(ctx, std::move(selectedParticles)); - return ProcessCode::SUCCESS; -} diff --git a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/TruthSeedSelector.hpp b/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/TruthSeedSelector.hpp deleted file mode 100644 index 1bb12042aa3..00000000000 --- a/Examples/Algorithms/TruthTracking/ActsExamples/TruthTracking/TruthSeedSelector.hpp +++ /dev/null @@ -1,92 +0,0 @@ -// 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/Utilities/Logger.hpp" -#include "ActsExamples/EventData/SimHit.hpp" -#include "ActsExamples/EventData/SimParticle.hpp" -#include "ActsExamples/Framework/DataHandle.hpp" -#include "ActsExamples/Framework/IAlgorithm.hpp" -#include "ActsExamples/Framework/ProcessCode.hpp" - -#include -#include -#include - -namespace ActsFatras { -class Barcode; -} // namespace ActsFatras - -namespace ActsExamples { -struct AlgorithmContext; - -/// Select truth particles to be used as 'seeds' of reconstruction algorithms, -/// e.g. track fitting and track finding. -/// -/// This pre-selection could help guarantee quality of the 'seeds', i.e. to -/// avoid empty proto track (no recorded hits for the particle). In addition, it -/// could help save unnecessary reconstruction time. For instance, when -/// investigating performance of CombinatorialKalmanFilter (CKF), we might be -/// interested in its performance for only truth particles with pT and number of -/// recorded hits (on sensitive detectors) safistying provided criteria (input -/// measurements of CKF are still recorded hits from all possible particles). -/// Then we could use particles only satisfying provided criteria as the 'seeds' -/// of CKF instead of handling all the truth particles. -// -class TruthSeedSelector final : public IAlgorithm { - public: - struct Config { - /// The input truth particles that should be used to create proto tracks. - std::string inputParticles; - /// The input hit-particles map collection. - std::string inputMeasurementParticlesMap; - /// The output proto tracks collection. - std::string outputParticles; - /// Maximum distance from the origin in the transverse plane - double rhoMin = 0.; - double rhoMax = std::numeric_limits::max(); - /// Minimum/Maximum absolute distance from the origin along z - double zMin = std::numeric_limits::lowest(); - double zMax = std::numeric_limits::max(); - // Truth particle kinematic cuts - double phiMin = std::numeric_limits::lowest(); - double phiMax = std::numeric_limits::max(); - double etaMin = std::numeric_limits::lowest(); - double etaMax = std::numeric_limits::max(); - double absEtaMin = std::numeric_limits::lowest(); - double absEtaMax = std::numeric_limits::max(); - double ptMin = 0.0; - double ptMax = std::numeric_limits::max(); - /// Keep neutral particles - bool keepNeutral = false; - /// Requirement on number of recorded hits - //@TODO: implement detector-specific requirements - std::size_t nHitsMin = 0; - std::size_t nHitsMax = std::numeric_limits::max(); - }; - - TruthSeedSelector(const Config& config, Acts::Logging::Level level); - - ProcessCode execute(const AlgorithmContext& ctx) const final; - - /// Get readonly access to the config parameters - const Config& config() const { return m_cfg; } - - private: - Config m_cfg; - - ReadDataHandle m_inputParticles{this, "InputParticles"}; - ReadDataHandle m_inputMeasurementParticlesMap{ - this, "InputMeasurementParticlesMap"}; - - WriteDataHandle m_outputParticles{this, - "OutputParticles"}; -}; - -} // namespace ActsExamples diff --git a/Examples/Algorithms/TruthTracking/CMakeLists.txt b/Examples/Algorithms/TruthTracking/CMakeLists.txt index 7c1eff1ed51..4594cdb7480 100644 --- a/Examples/Algorithms/TruthTracking/CMakeLists.txt +++ b/Examples/Algorithms/TruthTracking/CMakeLists.txt @@ -6,7 +6,6 @@ add_library( ActsExamples/TruthTracking/TrackParameterSelector.cpp ActsExamples/TruthTracking/TrackModifier.cpp ActsExamples/TruthTracking/TrackTruthMatcher.cpp - ActsExamples/TruthTracking/TruthSeedSelector.cpp ActsExamples/TruthTracking/TruthTrackFinder.cpp ActsExamples/TruthTracking/TruthVertexFinder.cpp ActsExamples/TruthTracking/TruthSeedingAlgorithm.cpp diff --git a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp index 9ce1ca5f2e9..edbb720825c 100644 --- a/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp +++ b/Examples/Detectors/DD4hepDetector/include/ActsExamples/DD4hepDetector/DD4hepGeometryService.hpp @@ -52,7 +52,7 @@ class DD4hepGeometryService { /// Log level for the geometry service. Acts::Logging::Level logLevel = Acts::Logging::Level::INFO; /// Log level for DD4hep itself - Acts::Logging::Level dd4hepLogLevel = Acts::Logging::Level::INFO; + Acts::Logging::Level dd4hepLogLevel = Acts::Logging::Level::WARNING; /// XML-file with the detector description std::vector xmlFileNames; /// The name of the service diff --git a/Examples/Framework/CMakeLists.txt b/Examples/Framework/CMakeLists.txt index efe06302800..db45cffc925 100644 --- a/Examples/Framework/CMakeLists.txt +++ b/Examples/Framework/CMakeLists.txt @@ -46,30 +46,15 @@ target_compile_definitions( PRIVATE BOOST_FILESYSTEM_NO_DEPRECATED ) -if(ACTS_USE_EXAMPLES_TBB) - # newer DD4hep version require TBB and search internally for TBB in - # config-only mode. to avoid mismatches we explicitly search using - # config-only mode first to be sure that we find the same version. - find_package(TBB ${_acts_tbb_version} CONFIG) - if(NOT TBB_FOUND) - # no version check possible when using the find module - find_package(TBB ${_acts_tbb_version} MODULE) - endif() -else() - set(TBB_FOUND FALSE) -endif() -if(TBB_FOUND) - target_link_libraries(ActsExamplesFramework PUBLIC TBB::tbb) -else() - message( - STATUS - "disable TBB for Examples/Framework - only single-threaded running will be supported" - ) - target_compile_definitions( - ActsExamplesFramework - PUBLIC -DACTS_EXAMPLES_NO_TBB - ) +# newer DD4hep version require TBB and search internally for TBB in +# config-only mode. to avoid mismatches we explicitly search using +# config-only mode first to be sure that we find the same version. +find_package(TBB ${_acts_tbb_version} CONFIG) +if(NOT TBB_FOUND) + # no version check possible when using the find module + find_package(TBB ${_acts_tbb_version} MODULE REQUIRED) endif() +target_link_libraries(ActsExamplesFramework PUBLIC TBB::tbb) install( TARGETS ActsExamplesFramework diff --git a/Examples/Framework/include/ActsExamples/Utilities/tbbWrap.hpp b/Examples/Framework/include/ActsExamples/Utilities/tbbWrap.hpp index 84784c55d31..79969369221 100644 --- a/Examples/Framework/include/ActsExamples/Utilities/tbbWrap.hpp +++ b/Examples/Framework/include/ActsExamples/Utilities/tbbWrap.hpp @@ -8,20 +8,11 @@ #pragma once -// uncomment to remove all use of tbb library. -// #define ACTS_EXAMPLES_NO_TBB - -#ifdef ACTS_EXAMPLES_NO_TBB -#define ACTS_EXAMPLES_WITH_TBB(a) -#include -#else -#define ACTS_EXAMPLES_WITH_TBB(a) a #include #include #include #include -#endif /// Wrapper for most of the tbb functions that we use in Sequencer. /// @@ -30,34 +21,9 @@ /// tbb::blocked_range (which doesn't require any thread setup) is still taken /// from the tbb library. /// -/// However, if ACTS_EXAMPLES_NO_TBB is defined, then don't use tbb library at -/// all (requires nthreads=1 or -1). This allows the ACTS Examples to be built -/// without the tbb library (and reduces the dependency on ROOT). -/// In this case, we provide our own minimal implementation of -/// tbb::blocked_range. -/// /// Based on an idea from /// https://stackoverflow.com/questions/59736661/how-to-completely-switch-off-threading-in-tbb-code -#ifdef ACTS_EXAMPLES_NO_TBB -namespace ActsExamples::tbb { -namespace task_arena { -constexpr int automatic = -1; -} // namespace task_arena - -template -struct blocked_range { - blocked_range(Value begin_, Value end_) : my_end(end_), my_begin(begin_) {} - Value begin() const { return my_begin; } - Value end() const { return my_end; } - - private: - Value my_end; - Value my_begin; -}; -} // namespace ActsExamples::tbb -#endif - namespace ActsExamples::tbbWrap { /// enableTBB keeps a record of whether we are multi-threaded (nthreads!=1) or /// not. This is set once in task_arena and stored globally. @@ -67,17 +33,10 @@ namespace ActsExamples::tbbWrap { static bool enableTBB(int nthreads = -99) { static bool setting = false; if (nthreads != -99) { -#ifdef ACTS_EXAMPLES_NO_TBB - if (nthreads > 1) { - throw std::runtime_error( - "tbb is not available, so can't do multi-threading."); - } -#else bool newSetting = (nthreads != 1); if (!setting && newSetting) { setting = newSetting; } -#endif } return setting; } @@ -87,28 +46,20 @@ static bool enableTBB(int nthreads = -99) { /// That should be fine because the task_arena is initialised before spawning /// any threads. class task_arena { -#ifndef ACTS_EXAMPLES_NO_TBB std::optional tbb; -#endif public: - task_arena(int nthreads = tbb::task_arena::automatic, - unsigned ACTS_EXAMPLES_WITH_TBB(res) = 1) { + task_arena(int nthreads = tbb::task_arena::automatic, unsigned res = 1) { if (enableTBB(nthreads)) { -#ifndef ACTS_EXAMPLES_NO_TBB tbb.emplace(nthreads, res); -#endif } } template void execute(const F& f) { -#ifndef ACTS_EXAMPLES_NO_TBB if (tbb) { tbb->execute(f); - } else -#endif - { + } else { f(); } } @@ -119,12 +70,9 @@ class parallel_for { public: template parallel_for(const R& r, const F& f) { -#ifndef ACTS_EXAMPLES_NO_TBB if (enableTBB()) { tbb::parallel_for(r, f); - } else -#endif - { + } else { for (auto i = r.begin(); i != r.end(); ++i) { // use default grainsize=1 f(R(i, i + 1)); } @@ -134,39 +82,29 @@ class parallel_for { /// Small wrapper for tbb::queuing_mutex and tbb::queuing_mutex::scoped_lock. class queuing_mutex { -#ifndef ACTS_EXAMPLES_NO_TBB std::optional tbb; -#endif public: queuing_mutex() { -#ifndef ACTS_EXAMPLES_NO_TBB if (enableTBB()) { tbb.emplace(); } -#endif } class scoped_lock { -#ifndef ACTS_EXAMPLES_NO_TBB std::optional tbb; -#endif public: scoped_lock() { -#ifndef ACTS_EXAMPLES_NO_TBB if (enableTBB()) { tbb.emplace(); } -#endif } - explicit scoped_lock(queuing_mutex& ACTS_EXAMPLES_WITH_TBB(m)) { -#ifndef ACTS_EXAMPLES_NO_TBB + explicit scoped_lock(queuing_mutex& m) { if (enableTBB()) { tbb.emplace(*m.tbb); } -#endif } }; }; diff --git a/Examples/Framework/src/Framework/Sequencer.cpp b/Examples/Framework/src/Framework/Sequencer.cpp index 5c1a76b5bd4..eb9bf8fd1c0 100644 --- a/Examples/Framework/src/Framework/Sequencer.cpp +++ b/Examples/Framework/src/Framework/Sequencer.cpp @@ -42,15 +42,11 @@ #include #include -#include - -#ifndef ACTS_EXAMPLES_NO_TBB #include -#endif - #include #include #include +#include namespace ActsExamples { @@ -108,16 +104,12 @@ Sequencer::Sequencer(const Sequencer::Config& cfg) m_taskArena((m_cfg.numThreads < 0) ? tbb::task_arena::automatic : m_cfg.numThreads), m_logger(Acts::getDefaultLogger("Sequencer", m_cfg.logLevel)) { -#ifndef ACTS_EXAMPLES_NO_TBB if (m_cfg.numThreads == 1) { -#endif ACTS_INFO("Create Sequencer (single-threaded)"); -#ifndef ACTS_EXAMPLES_NO_TBB } else { ROOT::EnableThreadSafety(); ACTS_INFO("Create Sequencer with " << m_cfg.numThreads << " threads"); } -#endif const char* envvar = std::getenv("ACTS_SEQUENCER_DISABLE_FPEMON"); if (envvar != nullptr) { @@ -267,10 +259,13 @@ void Sequencer::addWhiteboardAlias(const std::string& aliasName, auto [it, success] = m_whiteboardObjectAliases.insert({objectName, aliasName}); if (!success) { - throw std::invalid_argument("Alias to '" + aliasName + "' -> '" + - objectName + "' already set"); + ACTS_INFO("Key '" << objectName << "' aliased to '" << aliasName + << "' already set"); + return; } + ACTS_INFO("Key '" << objectName << "' aliased to '" << aliasName << "'"); + if (auto oit = m_whiteBoardState.find(objectName); oit != m_whiteBoardState.end()) { m_whiteBoardState[aliasName] = oit->second; diff --git a/Examples/Io/Csv/src/CsvSeedWriter.cpp b/Examples/Io/Csv/src/CsvSeedWriter.cpp index 96dd04b07a4..fe9d881c24f 100644 --- a/Examples/Io/Csv/src/CsvSeedWriter.cpp +++ b/Examples/Io/Csv/src/CsvSeedWriter.cpp @@ -123,10 +123,10 @@ ActsExamples::ProcessCode ActsExamples::CsvSeedWriter::writeT( // Compute the distance between the truth and estimated directions float truthPhi = phi(truthUnitDir); float truthEta = std::atanh(std::cos(theta(truthUnitDir))); - float dEta = fabs(truthEta - seedEta); - float dPhi = fabs(truthPhi - seedPhi) < M_PI - ? fabs(truthPhi - seedPhi) - : fabs(truthPhi - seedPhi) - M_PI; + float dEta = std::abs(truthEta - seedEta); + float dPhi = std::abs(truthPhi - seedPhi) < M_PI + ? std::abs(truthPhi - seedPhi) + : std::abs(truthPhi - seedPhi) - M_PI; truthDistance = sqrt(dPhi * dPhi + dEta * dEta); // If the seed is truth matched, check if it is the closest one for the // contributing particle diff --git a/Examples/Python/CMakeLists.txt b/Examples/Python/CMakeLists.txt index 0a834ae546f..0eb4b1ff4ec 100644 --- a/Examples/Python/CMakeLists.txt +++ b/Examples/Python/CMakeLists.txt @@ -21,6 +21,7 @@ pybind11_add_module(ActsPythonBindings src/Output.cpp src/Input.cpp src/Propagation.cpp + src/Navigation.cpp src/Generators.cpp src/Obj.cpp src/TruthTracking.cpp diff --git a/Examples/Python/python/acts/examples/odd.py b/Examples/Python/python/acts/examples/odd.py index a28058af78b..5e187948ee2 100644 --- a/Examples/Python/python/acts/examples/odd.py +++ b/Examples/Python/python/acts/examples/odd.py @@ -90,7 +90,7 @@ def geoid_hook(geoid, surface): dd4hepConfig = acts.examples.dd4hep.DD4hepGeometryService.Config( xmlFileNames=[str(odd_xml)], logLevel=customLogLevel(), - dd4hepLogLevel=customLogLevel(), + dd4hepLogLevel=customLogLevel(minLevel=acts.logging.WARNING), geometryIdentifierHook=acts.GeometryIdentifierHook(geoid_hook), ) detector = acts.examples.dd4hep.DD4hepDetector() diff --git a/Examples/Python/python/acts/examples/reconstruction.py b/Examples/Python/python/acts/examples/reconstruction.py index fd02c6bddac..846de8995f2 100644 --- a/Examples/Python/python/acts/examples/reconstruction.py +++ b/Examples/Python/python/acts/examples/reconstruction.py @@ -1741,21 +1741,6 @@ def addExaTrkX( ) -> None: customLogLevel = acts.examples.defaultLogging(s, logLevel) - # Run the particle selection - # The pre-selection will select truth particles satisfying provided criteria - # from all particles read in by particle reader for further processing. It - # has no impact on the truth hits themselves - s.addAlgorithm( - acts.examples.TruthSeedSelector( - level=customLogLevel(), - ptMin=500 * u.MeV, - nHitsMin=9, - inputParticles="particles_initial", - inputMeasurementParticlesMap="measurement_particles_map", - outputParticles="particles_seed_selected", - ) - ) - # Create space points s.addAlgorithm( acts.examples.SpacePointMaker( diff --git a/Examples/Python/python/acts/examples/simulation.py b/Examples/Python/python/acts/examples/simulation.py index 8f6b6d0e603..15883f4c648 100644 --- a/Examples/Python/python/acts/examples/simulation.py +++ b/Examples/Python/python/acts/examples/simulation.py @@ -335,7 +335,7 @@ def addPythia8( acts.examples.RootParticleWriter( level=customLogLevel(), inputParticles=evGen.config.outputParticles, - filePath=str(outputDirRoot / "pythia8_particles.root"), + filePath=str(outputDirRoot / "particles.root"), ) ) @@ -343,7 +343,7 @@ def addPythia8( acts.examples.RootVertexWriter( level=customLogLevel(), inputVertices=evGen.config.outputVertices, - filePath=str(outputDirRoot / "pythia8_vertices.root"), + filePath=str(outputDirRoot / "vertices.root"), ) ) diff --git a/Examples/Python/src/Digitization.cpp b/Examples/Python/src/Digitization.cpp index c392d6dcc8c..948bcc9593b 100644 --- a/Examples/Python/src/Digitization.cpp +++ b/Examples/Python/src/Digitization.cpp @@ -13,6 +13,7 @@ #include "ActsExamples/Digitization/DigitizationAlgorithm.hpp" #include "ActsExamples/Digitization/DigitizationConfig.hpp" #include "ActsExamples/Digitization/DigitizationConfigurator.hpp" +#include "ActsExamples/Digitization/DigitizationCoordinatesConverter.hpp" #include "ActsExamples/Framework/AlgorithmContext.hpp" #include "ActsExamples/Io/Json/JsonDigitizationConfig.hpp" @@ -101,6 +102,19 @@ void addDigitization(Context& ctx) { ACTS_PYTHON_MEMBER(outputDigiComponents); ACTS_PYTHON_STRUCT_END(); } + + { + py::class_>( + mex, "DigitizationCoordinatesConverter") + .def(py::init(), py::arg("config")) + .def_property_readonly( + "config", &ActsExamples::DigitizationCoordinatesConverter::config) + .def("globalToLocal", + &ActsExamples::DigitizationCoordinatesConverter::globalToLocal) + .def("localToGlobal", + &ActsExamples::DigitizationCoordinatesConverter::localToGlobal); + } } } // namespace Acts::Python diff --git a/Examples/Python/src/ModuleEntry.cpp b/Examples/Python/src/ModuleEntry.cpp index 1a0e27db907..a74d277f7a5 100644 --- a/Examples/Python/src/ModuleEntry.cpp +++ b/Examples/Python/src/ModuleEntry.cpp @@ -50,6 +50,7 @@ void addBinning(Context& ctx); void addEventData(Context& ctx); void addPropagation(Context& ctx); +void addNavigation(Context& ctx); void addGeometry(Context& ctx); void addGeometryBuildingGen1(Context& ctx); @@ -123,6 +124,7 @@ PYBIND11_MODULE(ActsPythonBindings, m) { addOutput(ctx); addPropagation(ctx); + addNavigation(ctx); addGeometryBuildingGen1(ctx); addGeometry(ctx); addExperimentalGeometry(ctx); diff --git a/Examples/Python/src/Navigation.cpp b/Examples/Python/src/Navigation.cpp new file mode 100644 index 00000000000..733bbe1a151 --- /dev/null +++ b/Examples/Python/src/Navigation.cpp @@ -0,0 +1,203 @@ +// 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/Geometry/CylinderVolumeBounds.hpp" +#include "Acts/Geometry/NavigationPolicyFactory.hpp" +#include "Acts/Geometry/TrackingVolume.hpp" +#include "Acts/Navigation/SurfaceArrayNavigationPolicy.hpp" +#include "Acts/Navigation/TryAllNavigationPolicy.hpp" +#include "Acts/Plugins/Python/Utilities.hpp" +#include "Acts/Surfaces/CylinderBounds.hpp" +#include "Acts/Surfaces/CylinderSurface.hpp" +#include "Acts/Utilities/Logger.hpp" +#include "Acts/Utilities/TypeTag.hpp" + +#include +#include +#include + +#include +#include +#include + +namespace py = pybind11; +using namespace pybind11::literals; + +namespace Acts::Python { + +struct AnyNavigationPolicyFactory : public Acts::NavigationPolicyFactory { + virtual std::unique_ptr add( + TypeTag /*type*/) = 0; + + virtual std::unique_ptr add( + TypeTag /*type*/, + SurfaceArrayNavigationPolicy::Config config) = 0; +}; + +template , + typename... Policies> +struct NavigationPolicyFactoryT : public AnyNavigationPolicyFactory { + explicit NavigationPolicyFactoryT(Factory impl) + requires(sizeof...(Policies) > 0) + : m_impl(std::move(impl)) {} + + NavigationPolicyFactoryT() + requires(sizeof...(Policies) == 0) + : m_impl{} {} + + std::unique_ptr add( + TypeTag /*type*/) override { + return add(); + } + + std::unique_ptr add( + TypeTag /*type*/, + SurfaceArrayNavigationPolicy::Config config) override { + return add(std::move(config)); + } + + std::unique_ptr build( + const GeometryContext& gctx, const TrackingVolume& volume, + const Logger& logger) const override { + if constexpr (sizeof...(Policies) > 0) { + return m_impl.build(gctx, volume, logger); + } else { + throw std::runtime_error("No policies added to the factory"); + } + } + + private: + template + std::unique_ptr add(Args&&... args) { + if constexpr (!(std::is_same_v || ...)) { + auto impl = + std::move(m_impl).template add(std::forward(args)...); + return std::make_unique< + NavigationPolicyFactoryT>( + std::move(impl)); + } else { + throw std::invalid_argument("Policy already added to the factory"); + } + } + + Factory m_impl; +}; + +class NavigationPolicyFactory : public Acts::NavigationPolicyFactory { + public: + // This overload is for all the navigation policies that don't have extra + // arguments + NavigationPolicyFactory& addNoArguments(const py::object& cls) { + auto m = py::module_::import("acts"); + if (py::object o = m.attr("TryAllNavigationPolicy"); cls.is(o)) { + m_impl = m_impl->add(Type); + } + // Add other policies here + return *this; + } + + NavigationPolicyFactory& addSurfaceArray( + const py::object& /*cls*/, + const SurfaceArrayNavigationPolicy::Config& config) { + m_impl = m_impl->add(Type, config); + return *this; + } + + std::unique_ptr build( + const GeometryContext& gctx, const TrackingVolume& volume, + const Logger& logger) const override { + return m_impl->build(gctx, volume, logger); + } + + private: + std::unique_ptr m_impl = + std::make_unique>(); +}; + +namespace Test { +class DetectorElementStub : public DetectorElementBase { + public: + DetectorElementStub() : DetectorElementBase() {} + + const Transform3& transform(const GeometryContext&) const override { + return m_transform; + } + + /// Return surface representation - const return pattern + const Surface& surface() const override { + throw std::runtime_error("Not implemented"); + } + + /// Non-const return pattern + Surface& surface() override { throw std::runtime_error("Not implemented"); } + + /// Returns the thickness of the module + /// @return double that indicates the thickness of the module + double thickness() const override { return 0; } + + private: + Transform3 m_transform; +}; + +} // namespace Test + +void addNavigation(Context& ctx) { + auto m = ctx.get("main"); + + py::class_>( + m, "_NavigationPolicyFactory"); + + py::class_(m, "TryAllNavigationPolicy"); + + py::class_>( + m, "NavigationPolicyFactory") + // only to mirror the C++ API + .def_static("make", []() { return NavigationPolicyFactory{}; }) + .def("add", &NavigationPolicyFactory::addNoArguments) + .def("add", &NavigationPolicyFactory::addSurfaceArray) + .def("_buildTest", [](NavigationPolicyFactory& self) { + auto vol1 = std::make_shared( + Transform3::Identity(), + std::make_shared(30, 40, 100)); + vol1->setVolumeName("TestVolume"); + + auto detElem = std::make_unique(); + + auto surface = Surface::makeShared( + Transform3::Identity(), std::make_shared(30, 40)); + surface->assignDetectorElement(*detElem); + + vol1->addSurface(std::move(surface)); + + std::unique_ptr result = + self.build(GeometryContext{}, *vol1, + *getDefaultLogger("Test", Logging::VERBOSE)); + }); + + { + auto saPolicy = py::class_( + m, "SurfaceArrayNavigationPolicy"); + + using LayerType = SurfaceArrayNavigationPolicy::LayerType; + py::enum_(saPolicy, "LayerType") + .value("Cylinder", LayerType::Cylinder) + .value("Disc", LayerType::Disc) + .value("Plane", LayerType::Plane); + + using Config = SurfaceArrayNavigationPolicy::Config; + auto c = py::class_(saPolicy, "Config").def(py::init<>()); + ACTS_PYTHON_STRUCT_BEGIN(c, Config); + ACTS_PYTHON_MEMBER(layerType); + ACTS_PYTHON_MEMBER(bins); + ACTS_PYTHON_STRUCT_END(); + } +} + +} // namespace Acts::Python diff --git a/Examples/Python/src/TruthTracking.cpp b/Examples/Python/src/TruthTracking.cpp index 2c43b3cfc4d..7278b3f821f 100644 --- a/Examples/Python/src/TruthTracking.cpp +++ b/Examples/Python/src/TruthTracking.cpp @@ -13,15 +13,11 @@ #include "ActsExamples/TruthTracking/TrackModifier.hpp" #include "ActsExamples/TruthTracking/TrackParameterSelector.hpp" #include "ActsExamples/TruthTracking/TrackTruthMatcher.hpp" -#include "ActsExamples/TruthTracking/TruthSeedSelector.hpp" #include "ActsExamples/TruthTracking/TruthSeedingAlgorithm.hpp" #include "ActsExamples/TruthTracking/TruthTrackFinder.hpp" #include "ActsExamples/TruthTracking/TruthVertexFinder.hpp" #include "ActsExamples/Utilities/HitSelector.hpp" -#include "ActsExamples/Utilities/Range.hpp" -#include -#include #include #include @@ -45,48 +41,6 @@ void addTruthTracking(Context& ctx) { ActsExamples::TruthTrackFinder, mex, "TruthTrackFinder", inputParticles, inputMeasurementParticlesMap, outputProtoTracks); - { - using Alg = ActsExamples::TruthSeedSelector; - using Config = Alg::Config; - - auto alg = py::class_>( - mex, "TruthSeedSelector") - .def(py::init(), - py::arg("config"), py::arg("level")) - .def_property_readonly("config", &Alg::config); - - auto c = py::class_(alg, "Config").def(py::init<>()); - - ACTS_PYTHON_STRUCT_BEGIN(c, Config); - ACTS_PYTHON_MEMBER(inputParticles); - ACTS_PYTHON_MEMBER(inputMeasurementParticlesMap); - ACTS_PYTHON_MEMBER(outputParticles); - ACTS_PYTHON_MEMBER(rhoMin); - ACTS_PYTHON_MEMBER(rhoMax); - ACTS_PYTHON_MEMBER(zMin); - ACTS_PYTHON_MEMBER(zMax); - ACTS_PYTHON_MEMBER(phiMin); - ACTS_PYTHON_MEMBER(phiMax); - ACTS_PYTHON_MEMBER(etaMin); - ACTS_PYTHON_MEMBER(etaMax); - ACTS_PYTHON_MEMBER(absEtaMin); - ACTS_PYTHON_MEMBER(absEtaMax); - ACTS_PYTHON_MEMBER(ptMin); - ACTS_PYTHON_MEMBER(ptMax); - ACTS_PYTHON_MEMBER(keepNeutral); - ACTS_PYTHON_MEMBER(nHitsMin); - ACTS_PYTHON_MEMBER(nHitsMax); - ACTS_PYTHON_STRUCT_END(); - - pythonRangeProperty(c, "rho", &Config::rhoMin, &Config::rhoMax); - pythonRangeProperty(c, "z", &Config::zMin, &Config::zMax); - pythonRangeProperty(c, "phi", &Config::phiMin, &Config::phiMax); - pythonRangeProperty(c, "eta", &Config::etaMin, &Config::etaMax); - pythonRangeProperty(c, "absEta", &Config::absEtaMin, &Config::absEtaMax); - pythonRangeProperty(c, "pt", &Config::ptMin, &Config::ptMax); - pythonRangeProperty(c, "nHits", &Config::nHitsMin, &Config::nHitsMax); - } - ACTS_PYTHON_DECLARE_ALGORITHM( ActsExamples::ParticleSmearing, mex, "ParticleSmearing", inputParticles, outputTrackParameters, sigmaD0, sigmaD0PtA, sigmaD0PtB, sigmaZ0, diff --git a/Examples/Python/tests/root_file_hashes.txt b/Examples/Python/tests/root_file_hashes.txt index 3ade64a68ed..2ecf8b57c94 100644 --- a/Examples/Python/tests/root_file_hashes.txt +++ b/Examples/Python/tests/root_file_hashes.txt @@ -1,4 +1,4 @@ -test_pythia8__pythia8_particles.root: 91c852f3e0e20bcd382c616a7b643985d092decd42bdd653deae67ed8652e8d8 +test_pythia8__particles.root: 91c852f3e0e20bcd382c616a7b643985d092decd42bdd653deae67ed8652e8d8 test_fatras__particles_simulation.root: bc970873fef0c2efd86ed5413623802353d2cd04abea72de14e8cdfc0e40076f test_fatras__hits.root: 6e4beb045fa1712c4d14c280ba33c3fa13e4aff9de88d55c3e32f62ad226f724 test_geant4__particles_simulation.root: 49926c71a9b54e13aa1cc7596d3302baf3c87d8e2c1d0267cb4523f6abdc0ac2 diff --git a/Examples/Python/tests/test_algorithms.py b/Examples/Python/tests/test_algorithms.py index ede2610f604..4cca7199291 100644 --- a/Examples/Python/tests/test_algorithms.py +++ b/Examples/Python/tests/test_algorithms.py @@ -11,7 +11,6 @@ EventGenerator, FatrasSimulation, MaterialMapping, - TruthSeedSelector, TruthTrackFinder, ParticleSelector, TruthVertexFinder, @@ -42,7 +41,6 @@ EventGenerator, FatrasSimulation, MaterialMapping, - TruthSeedSelector, TruthTrackFinder, ParticleSelector, TruthVertexFinder, diff --git a/Examples/Python/tests/test_detectors.py b/Examples/Python/tests/test_detectors.py index e99406c69d6..c4d2c6ea9ed 100644 --- a/Examples/Python/tests/test_detectors.py +++ b/Examples/Python/tests/test_detectors.py @@ -1,4 +1,5 @@ import pytest +from pathlib import Path from helpers import dd4hepEnabled @@ -157,3 +158,34 @@ def eq(self, other): v = Volume(**{key: (4, None)}) assert getattr(v, key) == Interval(4, None) + + +def test_coordinate_converter(trk_geo): + digiCfg = acts.examples.DigitizationConfig( + acts.examples.readDigiConfigFromJson( + str( + Path(__file__).parent.parent.parent.parent + / "Examples/Algorithms/Digitization/share/default-smearing-config-generic.json" + ) + ), + surfaceByIdentifier=trk_geo.geoIdSurfaceMap(), + ) + converter = acts.examples.DigitizationCoordinatesConverter(digiCfg) + + def test_surface(surface): + gctx = acts.GeometryContext() + geo_id = surface.geometryId().value() + geo_center = surface.center(gctx) + x, y, z = geo_center[0], geo_center[1], geo_center[2] + + # test if surface center can be reproduced + assert converter.globalToLocal(geo_id, x, y, z) == (0, 0) + assert converter.localToGlobal(geo_id, 0, 0) == (x, y, z) + + # test if we can get back to the same local coordinates + global_shifted = converter.localToGlobal(geo_id, 5, 5) + local_shifted = converter.globalToLocal(geo_id, *global_shifted) + assert abs(local_shifted[0] - 5) / 5 < 1e-6 + assert abs(local_shifted[1] - 5) / 5 < 1e-6 + + trk_geo.visitSurfaces(test_surface) diff --git a/Examples/Python/tests/test_examples.py b/Examples/Python/tests/test_examples.py index 26f69f4aa82..69f06101fdd 100644 --- a/Examples/Python/tests/test_examples.py +++ b/Examples/Python/tests/test_examples.py @@ -87,14 +87,14 @@ def test_pythia8(tmp_path, seq, assert_root_hash): (tmp_path / "csv").mkdir() - assert not (tmp_path / "pythia8_particles.root").exists() + assert not (tmp_path / "particles.root").exists() assert len(list((tmp_path / "csv").iterdir())) == 0 events = seq.config.events runPythia8(str(tmp_path), outputRoot=True, outputCsv=True, s=seq).run() - fp = tmp_path / "pythia8_particles.root" + fp = tmp_path / "particles.root" assert fp.exists() assert fp.stat().st_size > 2**10 * 50 assert_entries(fp, "particles", events) diff --git a/Examples/Python/tests/test_navigation.py b/Examples/Python/tests/test_navigation.py new file mode 100644 index 00000000000..55ec8ac9540 --- /dev/null +++ b/Examples/Python/tests/test_navigation.py @@ -0,0 +1,42 @@ +import pytest + +import acts + +import acts.examples + + +def test_navigation_policy_factory(): + + policy = ( + acts.NavigationPolicyFactory.make() + .add(acts.TryAllNavigationPolicy) + .add( + acts.SurfaceArrayNavigationPolicy, + acts.SurfaceArrayNavigationPolicy.Config( + layerType=acts.SurfaceArrayNavigationPolicy.LayerType.Disc, + bins=(10, 10), + ), + ) + ) + + policy._buildTest() + + policy = acts.NavigationPolicyFactory.make().add(acts.TryAllNavigationPolicy) + + policy._buildTest() + + +def test_navigation_policy_factory_build_empty(): + policy = acts.NavigationPolicyFactory.make() + + with pytest.raises(RuntimeError): + policy._buildTest() + + +def test_navigation_policy_factory_add_multiple(): + with pytest.raises(ValueError): + ( + acts.NavigationPolicyFactory.make() + .add(acts.TryAllNavigationPolicy) + .add(acts.TryAllNavigationPolicy) + ) diff --git a/Examples/Scripts/MaterialMapping/Mat_map.C b/Examples/Scripts/MaterialMapping/Mat_map.C index 9f58e605244..60c70fa2339 100644 --- a/Examples/Scripts/MaterialMapping/Mat_map.C +++ b/Examples/Scripts/MaterialMapping/Mat_map.C @@ -57,7 +57,7 @@ void Draw_ratio(TCanvas* c, TProfile* h1, TProfile* h2, TLegend* leg, std::strin h5->SetStats(0); // No statistics on lower plot h5->Divide(h1); - double maxi = min( max( fabs(h5->GetMinimum()-0.1*h5->GetMinimum()),h5->GetMaximum()+0.1*h5->GetMaximum() ), 10. ); + double maxi = min( max( std::abs(h5->GetMinimum()-0.1*h5->GetMinimum()),h5->GetMaximum()+0.1*h5->GetMaximum() ), 10. ); h5->SetMinimum( 0.5 ); // Define Y .. h5->SetMaximum( 1.1 ); // .. range @@ -145,7 +145,7 @@ void Mat_map(std::string Val = "", std::string geantino = "", std::string name = // 2D map for Validation input TCanvas *VM = new TCanvas("VM","Validation Map") ; - Val_file->Draw("mat_y:mat_z","fabs(mat_x)<1"); + Val_file->Draw("mat_y:mat_z","std::abs(mat_x)<1"); eta_0->Draw("Same"); eta_1p->Draw("Same"); @@ -206,7 +206,7 @@ void Mat_map(std::string Val = "", std::string geantino = "", std::string name = // 2D map for Geantino input TCanvas *GM = new TCanvas("GM","Geantino Map") ; - geantino_file->Draw("mat_y:mat_z","fabs(mat_x)<1"); + geantino_file->Draw("mat_y:mat_z","std::abs(mat_x)<1"); eta_0->Draw("Same"); eta_1p->Draw("Same"); diff --git a/Examples/Scripts/Optimization/ckf.py b/Examples/Scripts/Optimization/ckf.py index c1761141262..ba18291735c 100755 --- a/Examples/Scripts/Optimization/ckf.py +++ b/Examples/Scripts/Optimization/ckf.py @@ -263,7 +263,7 @@ def runCKFTracks( field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T)) - inputParticlePath = Path(Inputdir) / "pythia8_particles.root" + inputParticlePath = Path(Inputdir) / "particles.root" if not inputParticlePath.exists(): inputParticlePath = None diff --git a/Fatras/include/ActsFatras/Physics/NuclearInteraction/NuclearInteraction.hpp b/Fatras/include/ActsFatras/Physics/NuclearInteraction/NuclearInteraction.hpp index dea8a0ae334..b1066919dc7 100644 --- a/Fatras/include/ActsFatras/Physics/NuclearInteraction/NuclearInteraction.hpp +++ b/Fatras/include/ActsFatras/Physics/NuclearInteraction/NuclearInteraction.hpp @@ -41,7 +41,7 @@ struct NuclearInteraction { /// The storage of the parameterisation detail::MultiParticleNuclearInteractionParametrisation multiParticleParameterisation; - /// The number of trials to match momenta and inveriant masses + /// The number of trials to match momenta and invariant masses //~ unsigned int nMatchingTrials = std::numeric_limits::max(); unsigned int nMatchingTrials = 100; unsigned int nMatchingTrialsTotal = 1000; @@ -56,7 +56,7 @@ struct NuclearInteraction { template std::pair generatePathLimits(generator_t& generator, const Particle& particle) const { - // Fast exit: No paramtrization provided + // Fast exit: No parameterisation provided if (multiParticleParameterisation.empty()) { return std::make_pair(std::numeric_limits::infinity(), std::numeric_limits::infinity()); @@ -416,7 +416,7 @@ Acts::ActsDynamicVector NuclearInteraction::sampleInvariantMasses( for (unsigned int i = 0; i < size; i++) { float variance = parametrisation.eigenvaluesInvariantMass[i]; std::normal_distribution dist{ - parametrisation.meanInvariantMass[i], sqrtf(variance)}; + parametrisation.meanInvariantMass[i], std::sqrt(variance)}; parameters[i] = dist(generator); } // Transform to multivariate normal distribution @@ -446,7 +446,7 @@ Acts::ActsDynamicVector NuclearInteraction::sampleMomenta( for (unsigned int i = 0; i < size; i++) { float variance = parametrisation.eigenvaluesMomentum[i]; std::normal_distribution dist{ - parametrisation.meanMomentum[i], sqrtf(variance)}; + parametrisation.meanMomentum[i], std::sqrt(variance)}; parameters[i] = dist(generator); } diff --git a/Plugins/DD4hep/src/ConvertDD4hepDetector.cpp b/Plugins/DD4hep/src/ConvertDD4hepDetector.cpp index ae80bb1a0c7..848de200db0 100644 --- a/Plugins/DD4hep/src/ConvertDD4hepDetector.cpp +++ b/Plugins/DD4hep/src/ConvertDD4hepDetector.cpp @@ -429,7 +429,8 @@ std::shared_ptr volumeBuilder_dd4hep( plbConfig.layerIdentification = subDetector.name(); plbConfig.centralLayerRadii = std::vector(1, 0.5 * (rMax + rMin)); plbConfig.centralLayerHalflengthZ = std::vector(1, halfZ); - plbConfig.centralLayerThickness = std::vector(1, fabs(rMax - rMin)); + plbConfig.centralLayerThickness = + std::vector(1, std::abs(rMax - rMin)); plbConfig.centralLayerMaterial = {plMaterial}; auto pcLayerBuilder = std::make_shared( plbConfig, logger.clone(std::string("D2A_PL:") + subDetector.name())); diff --git a/Plugins/DD4hep/src/DD4hepLayerBuilder.cpp b/Plugins/DD4hep/src/DD4hepLayerBuilder.cpp index 3b85391ab84..c7cffaaf5aa 100644 --- a/Plugins/DD4hep/src/DD4hepLayerBuilder.cpp +++ b/Plugins/DD4hep/src/DD4hepLayerBuilder.cpp @@ -208,8 +208,8 @@ const Acts::LayerVector Acts::DD4hepLayerBuilder::endcapLayers( // create the share disc bounds auto dBounds = std::make_shared( pl.min(Acts::BinningValue::binR), pl.max(Acts::BinningValue::binR)); - double thickness = std::fabs(pl.max(Acts::BinningValue::binZ) - - pl.min(Acts::BinningValue::binZ)); + double thickness = std::abs(pl.max(Acts::BinningValue::binZ) - + pl.min(Acts::BinningValue::binZ)); // Create the layer containing the sensitive surface endcapLayer = DiscLayer::create(transform, dBounds, std::move(sArray), thickness, nullptr, Acts::active); @@ -357,8 +357,8 @@ const Acts::LayerVector Acts::DD4hepLayerBuilder::centralLayers( double layerR = (pl.min(Acts::BinningValue::binR) + pl.max(Acts::BinningValue::binR)) * 0.5; - double thickness = std::fabs(pl.max(Acts::BinningValue::binR) - - pl.min(Acts::BinningValue::binR)); + double thickness = std::abs(pl.max(Acts::BinningValue::binR) - + pl.min(Acts::BinningValue::binR)); auto cBounds = std::make_shared(layerR, halfZ); // Create the layer containing the sensitive surface centralLayer = diff --git a/Plugins/GeoModel/src/detail/GeoPolygonConverter.cpp b/Plugins/GeoModel/src/detail/GeoPolygonConverter.cpp index 6b0642d25e8..11a0f983f1a 100644 --- a/Plugins/GeoModel/src/detail/GeoPolygonConverter.cpp +++ b/Plugins/GeoModel/src/detail/GeoPolygonConverter.cpp @@ -47,9 +47,9 @@ Acts::detail::GeoPolygonConverter::operator()( // sort based on the y-coordinate std::ranges::sort(vertices, {}, [](const auto& v) { return v[1]; }); if (nVertices == 4) { - double hlxnegy = fabs(vertices[0][0] - vertices[1][0]) / 2; - double hlxposy = fabs(vertices[2][0] - vertices[3][0]) / 2; - double hly = fabs(vertices[0][1] - vertices[3][1]) / 2; + double hlxnegy = std::abs(vertices[0][0] - vertices[1][0]) / 2; + double hlxposy = std::abs(vertices[2][0] - vertices[3][0]) / 2; + double hly = std::abs(vertices[0][1] - vertices[3][1]) / 2; std::vector halfLengths = {hlxnegy, hlxposy, hly}; // Create the surface @@ -78,10 +78,10 @@ Acts::detail::GeoPolygonConverter::operator()( // Return the detector element and surface return std::make_tuple(detectorElement, surface); } else if (nVertices == 6) { - double hlxnegy = fabs(vertices[0][0] - vertices[1][0]) / 2; - double hlxzeroy = fabs(vertices[2][0] - vertices[3][0]) / 2; - double hlxposy = fabs(vertices[4][0] - vertices[5][0]) / 2; - double hly = fabs(vertices[0][1] - vertices[4][1]) / 2; + double hlxnegy = std::abs(vertices[0][0] - vertices[1][0]) / 2; + double hlxzeroy = std::abs(vertices[2][0] - vertices[3][0]) / 2; + double hlxposy = std::abs(vertices[4][0] - vertices[5][0]) / 2; + double hly = std::abs(vertices[0][1] - vertices[4][1]) / 2; std::vector halfLengths = {hlxnegy, hlxzeroy, hlxposy, hly, hly}; diff --git a/Plugins/Legacy/include/Acts/Seeding/AtlasSeedFinder.hpp b/Plugins/Legacy/include/Acts/Seeding/AtlasSeedFinder.hpp index 12b3137682c..b7e060a1f80 100644 --- a/Plugins/Legacy/include/Acts/Seeding/AtlasSeedFinder.hpp +++ b/Plugins/Legacy/include/Acts/Seeding/AtlasSeedFinder.hpp @@ -318,7 +318,7 @@ inline SPForSeed* AtlasSeedFinder::newSpacePoint( if (m_checketa) { // filter SP outside of eta-range - float z = (fabs(r[2]) + m_zmax); + float z = std::abs(r[2]) + m_zmax; float x = r[0] * m_dzdrmin; float y = r[1] * m_dzdrmin; if ((z * z) < (x * x + y * y)) { diff --git a/Plugins/Legacy/include/Acts/Seeding/AtlasSeedFinder.ipp b/Plugins/Legacy/include/Acts/Seeding/AtlasSeedFinder.ipp index ce4f4d5525a..4b5b5c60875 100644 --- a/Plugins/Legacy/include/Acts/Seeding/AtlasSeedFinder.ipp +++ b/Plugins/Legacy/include/Acts/Seeding/AtlasSeedFinder.ipp @@ -205,7 +205,7 @@ void Acts::Legacy::AtlasSeedFinder::findNext() { /////////////////////////////////////////////////////////////////// template void Acts::Legacy::AtlasSeedFinder::buildFrameWork() { - m_ptmin = fabs(m_ptmin); + m_ptmin = std::abs(m_ptmin); if (m_ptmin < 100.) { m_ptmin = 100.; @@ -218,7 +218,7 @@ void Acts::Legacy::AtlasSeedFinder::buildFrameWork() { m_divermax = m_diversss; } - if (fabs(m_etamin) < .1) { + if (std::abs(m_etamin) < 0.1) { m_etamin = -m_etamax; } m_dzdrmax0 = 1. / tan(2. * atan(exp(-m_etamax))); @@ -227,7 +227,7 @@ void Acts::Legacy::AtlasSeedFinder::buildFrameWork() { // scattering factor. depends on error, forward direction and distance between // SP m_COF = 134 * .05 * 9.; - m_ipt = 1. / fabs(.9 * m_ptmin); + m_ipt = 1. / std::abs(0.9 * m_ptmin); m_ipt2 = m_ipt * m_ipt; m_K = 0.; @@ -646,7 +646,7 @@ void Acts::Legacy::AtlasSeedFinder::production3Sp( } // forward direction of SP duplet float Tz = (Z - (*r)->z()) / dR; - float aTz = fabs(Tz); + float aTz = std::abs(Tz); // why also exclude seeds with small pseudorapidity?? if (aTz < m_dzdrmin || aTz > m_dzdrmax) { continue; @@ -690,7 +690,7 @@ void Acts::Legacy::AtlasSeedFinder::production3Sp( } float Tz = ((*r)->z() - Z) / dR; - float aTz = fabs(Tz); + float aTz = std::abs(Tz); if (aTz < m_dzdrmin || aTz > m_dzdrmax) { continue; @@ -793,14 +793,14 @@ void Acts::Legacy::AtlasSeedFinder::production3Sp( continue; } - float Im = fabs((A - B * R) * R); + float Im = std::abs((A - B * R) * R); if (Im <= imax) { // Add penalty factor dependent on difference between cot(theta) to // the quality Im (previously Impact) float dr = 0; m_R[t] < m_R[b] ? dr = m_R[t] : dr = m_R[b]; - Im += fabs((Tzb - m_Tz[t]) / (dr * sTzb2)); + Im += std::abs((Tzb - m_Tz[t]) / (dr * sTzb2)); // B/sqrt(S2) = 1/helixradius m_CmSp.push_back(std::make_pair(B / sqrt(S2), m_SP[t])); m_SP[t]->setParam(Im); @@ -926,7 +926,7 @@ void Acts::Legacy::AtlasSeedFinder:: } // Compared seeds should have at least deltaRMin distance float Rj = (*j).second->radius(); - if (fabs(Rj - Ri) < m_drmin) { + if (std::abs(Rj - Ri) < m_drmin) { continue; } diff --git a/README.md b/README.md index 6cb20bfbe6c..7b75acee190 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ or *A Common Tracking Software* if you do not like recursive acronyms [![10.5281/zenodo.5141418](https://zenodo.org/badge/DOI/10.5281/zenodo.5141418.svg)](https://doi.org/10.5281/zenodo.5141418) [![Chat on Mattermost](https://badgen.net/badge/chat/on%20mattermost/cyan)](https://mattermost.web.cern.ch/acts/) -[![codecov](https://codecov.io/gh/acts-project/acts/graph/badge.svg)](https://codecov.io/gh/acts-project/acts) +[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=acts-project_acts&metric=coverage)](https://sonarcloud.io/summary/new_code?id=acts-project_acts) [![Latest release](https://badgen.net/github/release/acts-project/acts)](https://github.com/acts-project/acts/releases) [![Status](https://badgen.net/github/checks/acts-project/acts/main)](https://github.com/acts-project/acts/actions) [![Metrics](https://badgen.net/badge/metric/tracker/purple)](https://acts-project.github.io/metrics/) diff --git a/Tests/UnitTests/Core/EventData/CMakeLists.txt b/Tests/UnitTests/Core/EventData/CMakeLists.txt index 61b5079da8e..1efda4cff29 100644 --- a/Tests/UnitTests/Core/EventData/CMakeLists.txt +++ b/Tests/UnitTests/Core/EventData/CMakeLists.txt @@ -16,5 +16,6 @@ add_unittest(MultiTrajectoryHelpers MultiTrajectoryHelpersTests.cpp) add_unittest(SubspaceHelpers SubspaceHelpersTests.cpp) add_unittest(SeedEdm SeedEdmTests.cpp) add_unittest(SpacePointContainerEdm SpacePointContainerEdmTests.cpp) +add_unittest(TrackParameterHelpers TrackParameterHelpersTests.cpp) add_non_compile_test(MultiTrajectory TrackContainerComplianceTests.cpp) diff --git a/Tests/UnitTests/Core/EventData/TrackParameterHelpersTests.cpp b/Tests/UnitTests/Core/EventData/TrackParameterHelpersTests.cpp new file mode 100644 index 00000000000..bba77ff8ef2 --- /dev/null +++ b/Tests/UnitTests/Core/EventData/TrackParameterHelpersTests.cpp @@ -0,0 +1,53 @@ +// 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/Definitions/TrackParametrization.hpp" +#include "Acts/EventData/TrackParameterHelpers.hpp" +#include "Acts/Tests/CommonHelpers/FloatComparisons.hpp" + +BOOST_AUTO_TEST_SUITE(TrackParameterHelpers) + +BOOST_AUTO_TEST_CASE(isBoundVectorValid) { + BOOST_CHECK(!Acts::isBoundVectorValid({1, 2, 3, 4, 5, 6}, true)); + BOOST_CHECK(Acts::isBoundVectorValid({1, 2, 1, 1, 5, 6}, true)); +} + +BOOST_AUTO_TEST_CASE(isFreeVectorValid) { + BOOST_CHECK(!Acts::isFreeVectorValid({1, 2, 3, 4, 5, 6, 7, 8})); + BOOST_CHECK(Acts::isFreeVectorValid({1, 2, 3, 4, 1, 0, 0, 8})); +} + +BOOST_AUTO_TEST_CASE(normalizeBoundParameters) { + CHECK_CLOSE_OR_SMALL(Acts::normalizeBoundParameters({1, 2, 3, 4, 5, 6}), + Acts::BoundVector(1, 2, -0.141593, 2.28319, 5, 6), 1e-3, + 1e-3); +} + +BOOST_AUTO_TEST_CASE(addBoundParameters) { + CHECK_CLOSE_OR_SMALL( + Acts::addBoundParameters({1, 2, 3, 4, 5, 6}, {0, 0, 0, 0, 0, 0}), + Acts::normalizeBoundParameters({1, 2, 3, 4, 5, 6}), 1e-3, 1e-3); + CHECK_CLOSE_OR_SMALL( + Acts::addBoundParameters({1, 2, 3, 4, 5, 6}, {0, 0, 1, 1, 0, 0}), + Acts::normalizeBoundParameters({1, 2, 4, 5, 5, 6}), 1e-3, 1e-3); +} + +BOOST_AUTO_TEST_CASE(subtractBoundParameters) { + CHECK_CLOSE_OR_SMALL( + Acts::subtractBoundParameters({1, 2, 3, 4, 5, 6}, {1, 2, 3, 4, 5, 6}), + Acts::BoundVector(0, 0, 0, 0, 0, 0), 1e-3, 1e-3); + CHECK_CLOSE_OR_SMALL( + Acts::addBoundParameters( + Acts::subtractBoundParameters({1, 2, 3, 4, 5, 6}, {0, 0, 1, 1, 0, 0}), + {0, 0, 1, 1, 0, 0}), + Acts::normalizeBoundParameters({1, 2, 3, 4, 5, 6}), 1e-3, 1e-3); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/Tests/UnitTests/Core/Material/MaterialGridHelperTests.cpp b/Tests/UnitTests/Core/Material/MaterialGridHelperTests.cpp index 514da1ddd74..dde3a05edba 100644 --- a/Tests/UnitTests/Core/Material/MaterialGridHelperTests.cpp +++ b/Tests/UnitTests/Core/Material/MaterialGridHelperTests.cpp @@ -60,10 +60,8 @@ BOOST_AUTO_TEST_CASE(Square_Grid_test) { BOOST_CHECK_EQUAL(Grid.minPosition()[0], bd[0].min); BOOST_CHECK_EQUAL(Grid.minPosition()[1], bd[1].min); - float max1 = - bd[0].max + std::fabs(bd[0].max - bd[0].min) / (bd[0].bins() - 1); - float max2 = - bd[1].max + std::fabs(bd[1].max - bd[1].min) / (bd[1].bins() - 1); + float max1 = bd[0].max + std::abs(bd[0].max - bd[0].min) / (bd[0].bins() - 1); + float max2 = bd[1].max + std::abs(bd[1].max - bd[1].min) / (bd[1].bins() - 1); BOOST_CHECK_EQUAL(Grid.maxPosition()[0], max1); BOOST_CHECK_EQUAL(Grid.maxPosition()[1], max2); @@ -152,10 +150,8 @@ BOOST_AUTO_TEST_CASE(PhiZ_Grid_test) { BOOST_CHECK_EQUAL(Grid.minPosition()[0], bd[0].min); BOOST_CHECK_EQUAL(Grid.minPosition()[1], bd[1].min); - float max1 = - bd[0].max + std::fabs(bd[0].max - bd[0].min) / (bd[0].bins() - 1); - float max2 = - bd[1].max + std::fabs(bd[1].max - bd[1].min) / (bd[1].bins() - 1); + float max1 = bd[0].max + std::abs(bd[0].max - bd[0].min) / (bd[0].bins() - 1); + float max2 = bd[1].max + std::abs(bd[1].max - bd[1].min) / (bd[1].bins() - 1); BOOST_CHECK_EQUAL(Grid.maxPosition()[0], max1); BOOST_CHECK_EQUAL(Grid.maxPosition()[1], max2); @@ -244,12 +240,9 @@ BOOST_AUTO_TEST_CASE(Cubic_Grid_test) { BOOST_CHECK_EQUAL(Grid.minPosition()[1], bd[1].min); BOOST_CHECK_EQUAL(Grid.minPosition()[2], bd[2].min); - float max1 = - bd[0].max + std::fabs(bd[0].max - bd[0].min) / (bd[0].bins() - 1); - float max2 = - bd[1].max + std::fabs(bd[1].max - bd[1].min) / (bd[1].bins() - 1); - float max3 = - bd[2].max + std::fabs(bd[2].max - bd[2].min) / (bd[2].bins() - 1); + float max1 = bd[0].max + std::abs(bd[0].max - bd[0].min) / (bd[0].bins() - 1); + float max2 = bd[1].max + std::abs(bd[1].max - bd[1].min) / (bd[1].bins() - 1); + float max3 = bd[2].max + std::abs(bd[2].max - bd[2].min) / (bd[2].bins() - 1); BOOST_CHECK_EQUAL(Grid.maxPosition()[0], max1); BOOST_CHECK_EQUAL(Grid.maxPosition()[1], max2); @@ -341,12 +334,9 @@ BOOST_AUTO_TEST_CASE(Cylindrical_Grid_test) { BOOST_CHECK_EQUAL(Grid.minPosition()[1], bd[1].min); BOOST_CHECK_EQUAL(Grid.minPosition()[2], bd[2].min); - float max1 = - bd[0].max + std::fabs(bd[0].max - bd[0].min) / (bd[0].bins() - 1); - float max2 = - bd[1].max + std::fabs(bd[1].max - bd[1].min) / (bd[1].bins() - 1); - float max3 = - bd[2].max + std::fabs(bd[2].max - bd[2].min) / (bd[2].bins() - 1); + float max1 = bd[0].max + std::abs(bd[0].max - bd[0].min) / (bd[0].bins() - 1); + float max2 = bd[1].max + std::abs(bd[1].max - bd[1].min) / (bd[1].bins() - 1); + float max3 = bd[2].max + std::abs(bd[2].max - bd[2].min) / (bd[2].bins() - 1); BOOST_CHECK_EQUAL(Grid.maxPosition()[0], max1); BOOST_CHECK_EQUAL(Grid.maxPosition()[1], max2); diff --git a/Tests/UnitTests/Core/Navigation/CMakeLists.txt b/Tests/UnitTests/Core/Navigation/CMakeLists.txt index edca953321d..a18c2d34c9c 100644 --- a/Tests/UnitTests/Core/Navigation/CMakeLists.txt +++ b/Tests/UnitTests/Core/Navigation/CMakeLists.txt @@ -5,3 +5,4 @@ add_unittest(NavigationStream NavigationStreamTests.cpp) add_unittest(NavigationStateUpdaters NavigationStateUpdatersTests.cpp) add_unittest(DetectorNavigator DetectorNavigatorTests.cpp) add_unittest(MultiWireNavigation MultiWireNavigationTests.cpp) +add_unittest(NavigationPolicy NavigationPolicyTests.cpp) diff --git a/Tests/UnitTests/Core/Navigation/NavigationPolicyTests.cpp b/Tests/UnitTests/Core/Navigation/NavigationPolicyTests.cpp new file mode 100644 index 00000000000..181e1ad2a1f --- /dev/null +++ b/Tests/UnitTests/Core/Navigation/NavigationPolicyTests.cpp @@ -0,0 +1,240 @@ +// 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/Definitions/Units.hpp" +#include "Acts/Geometry/CylinderVolumeBounds.hpp" +#include "Acts/Geometry/NavigationPolicyFactory.hpp" +#include "Acts/Geometry/TrackingVolume.hpp" +#include "Acts/Navigation/INavigationPolicy.hpp" +#include "Acts/Navigation/MultiNavigationPolicy.hpp" +#include "Acts/Navigation/NavigationDelegate.hpp" +#include "Acts/Navigation/NavigationStream.hpp" +#include "Acts/Navigation/TryAllNavigationPolicy.hpp" + +using namespace Acts; +using namespace Acts::UnitLiterals; + +BOOST_AUTO_TEST_SUITE(NavigationPolicyTests) + +GeometryContext gctx; +auto logger = getDefaultLogger("NavigationPolicyTests", Logging::VERBOSE); + +struct APolicy : public INavigationPolicy { + APolicy(const GeometryContext& /*gctx*/, const TrackingVolume& /*volume*/, + const Logger& /*logger*/) {} + + void initializeCandidates(const NavigationArguments& /*unused*/, + AppendOnlyNavigationStream& /*unused*/, + const Logger& /*unused*/) const { + const_cast(this)->executed = true; + } + + void connect(NavigationDelegate& delegate) const override { + connectDefault(delegate); + } + + bool executed = false; +}; + +struct BPolicy : public INavigationPolicy { + struct Config { + int value; + }; + + BPolicy(const GeometryContext& /*gctx*/, const TrackingVolume& /*volume*/, + const Logger& /*logger*/, Config config) + : m_config(config) {} + + void connect(NavigationDelegate& delegate) const override { + connectDefault(delegate); + } + + void initializeCandidates(const NavigationArguments& /*unused*/, + AppendOnlyNavigationStream& /*unused*/, + const Logger& /*unused*/) const { + const_cast(this)->executed = true; + const_cast(this)->value = m_config.value; + } + + bool executed = false; + int value = 0; + + Config m_config; +}; + +BOOST_AUTO_TEST_CASE(DirectTest) { + TrackingVolume volume{ + Transform3::Identity(), + std::make_shared(250_mm, 400_mm, 310_mm), + "PixelLayer3"}; + + MultiNavigationPolicy policy{APolicy{gctx, volume, *logger}, + BPolicy{gctx, volume, *logger, {.value = 4242}}}; + + NavigationDelegate delegate; + policy.connect(delegate); + + NavigationStream main; + AppendOnlyNavigationStream stream{main}; + delegate(NavigationArguments{.position = Vector3::Zero(), + .direction = Vector3::Zero()}, + stream, *logger); + + BOOST_CHECK(std::get(policy.policies()).executed); + BOOST_CHECK(std::get(policy.policies()).executed); + BOOST_CHECK_EQUAL(std::get(policy.policies()).value, 4242); +} + +BOOST_AUTO_TEST_CASE(FactoryTest) { + TrackingVolume volume{ + Transform3::Identity(), + std::make_shared(250_mm, 400_mm, 310_mm), + "PixelLayer3"}; + + BPolicy::Config config{.value = 42}; + + std::function( + const GeometryContext&, const TrackingVolume&, const Logger&)> + factory = NavigationPolicyFactory::make() + .add() // no arguments + .add(config); // config struct as argument + + auto policyBase = factory(gctx, volume, *logger); + auto policyBase2 = factory(gctx, volume, *logger); + + auto& policy = + dynamic_cast&>(*policyBase); + + NavigationDelegate delegate; + policy.connect(delegate); + + NavigationStream main; + AppendOnlyNavigationStream stream{main}; + delegate(NavigationArguments{.position = Vector3::Zero(), + .direction = Vector3::Zero()}, + stream, *logger); + + BOOST_CHECK(std::get(policy.policies()).executed); + BOOST_CHECK(std::get(policy.policies()).executed); + BOOST_CHECK_EQUAL(std::get(policy.policies()).value, 42); + + auto& policy2 = + dynamic_cast&>(*policyBase2); + + NavigationDelegate delegate2; + policyBase2->connect(delegate2); + + delegate2(NavigationArguments{.position = Vector3::Zero(), + .direction = Vector3::Zero()}, + stream, *logger); + + BOOST_CHECK(std::get(policy2.policies()).executed); + BOOST_CHECK(std::get(policy2.policies()).executed); + BOOST_CHECK_EQUAL(std::get(policy2.policies()).value, 42); +} + +BOOST_AUTO_TEST_CASE(AsUniquePtrTest) { + TrackingVolume volume{ + Transform3::Identity(), + std::make_shared(250_mm, 400_mm, 310_mm), + "PixelLayer3"}; + + std::unique_ptr factory = + NavigationPolicyFactory::make().add().asUniquePtr(); + + auto policyBase = factory->build(gctx, volume, *logger); + auto& policy = dynamic_cast&>(*policyBase); + + NavigationDelegate delegate; + policyBase->connect(delegate); + + NavigationStream main; + AppendOnlyNavigationStream stream{main}; + delegate(NavigationArguments{.position = Vector3::Zero(), + .direction = Vector3::Zero()}, + stream, *logger); + + BOOST_CHECK(std::get(policy.policies()).executed); +} + +struct CPolicy : public INavigationPolicy {}; + +template +struct CPolicySpecialized : public CPolicy { + struct Config { + T value; + }; + + CPolicySpecialized(const TrackingVolume& /*volume*/, Config config) + : m_config(config) {} + + void connect(NavigationDelegate& delegate) const override { + connectDefault>(delegate); + } + + void initializeCandidates(const NavigationArguments& /*unused*/, + AppendOnlyNavigationStream& /*stream*/, + const Logger& /*logger*/) const { + auto* self = const_cast*>(this); + self->executed = true; + self->value = m_config.value; + } + + bool executed = false; + int value = 0; + + Config m_config; +}; + +struct IsolatedConfig { + int value; +}; + +auto makeCPolicy(const GeometryContext& /*gctx*/, const TrackingVolume& volume, + const Logger& /*logger*/, IsolatedConfig config) { + // I can do arbitrary stuff here + CPolicySpecialized::Config config2{.value = config.value}; + return CPolicySpecialized(volume, config2); +} + +BOOST_AUTO_TEST_CASE(IsolatedFactory) { + TrackingVolume volume{ + Transform3::Identity(), + std::make_shared(250_mm, 400_mm, 310_mm), + "PixelLayer3"}; + + IsolatedConfig config{.value = 44}; + auto factory = + NavigationPolicyFactory::make().add().add(makeCPolicy, config); + + auto factory2 = + NavigationPolicyFactory::make().add(makeCPolicy, config).add(); + + auto policyBase = factory(gctx, volume, *logger); + auto& policy = + dynamic_cast>&>( + *policyBase); + + NavigationDelegate delegate; + policyBase->connect(delegate); + + NavigationStream main; + AppendOnlyNavigationStream stream{main}; + delegate(NavigationArguments{.position = Vector3::Zero(), + .direction = Vector3::Zero()}, + stream, *logger); + + BOOST_CHECK(std::get(policy.policies()).executed); + BOOST_CHECK(std::get>(policy.policies()).executed); + BOOST_CHECK_EQUAL(std::get>(policy.policies()).value, + 44); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/Tests/UnitTests/Core/Navigation/NavigationStreamTests.cpp b/Tests/UnitTests/Core/Navigation/NavigationStreamTests.cpp index 097dde2ed64..9ca578b0aba 100644 --- a/Tests/UnitTests/Core/Navigation/NavigationStreamTests.cpp +++ b/Tests/UnitTests/Core/Navigation/NavigationStreamTests.cpp @@ -94,7 +94,7 @@ BOOST_AUTO_TEST_CASE(NavigationStream_InitializePlanes) { NavigationStream nStreamTemplate; for (const auto& surface : surfaces) { - nStreamTemplate.addSurfaceCandidate(surface.get(), + nStreamTemplate.addSurfaceCandidate(*surface, Acts::BoundaryTolerance::None()); } BOOST_CHECK_EQUAL(nStreamTemplate.remainingCandidates(), 4u); @@ -140,7 +140,7 @@ BOOST_AUTO_TEST_CASE(NavigationStream_InitializePlanes) { // (5) Test de-duplication nStream = nStreamTemplate; - nStreamTemplate.addSurfaceCandidate(surfaces[0].get(), + nStreamTemplate.addSurfaceCandidate(*surfaces.at(0), Acts::BoundaryTolerance::None()); // One surface is duplicated in the stream BOOST_CHECK_EQUAL(nStreamTemplate.remainingCandidates(), 5u); @@ -159,7 +159,7 @@ BOOST_AUTO_TEST_CASE(NavigationStream_UpdatePlanes) { // reachable and intersections inside bounds NavigationStream nStreamTemplate; for (const auto& surface : surfaces) { - nStreamTemplate.addSurfaceCandidate(surface.get(), + nStreamTemplate.addSurfaceCandidate(*surface, Acts::BoundaryTolerance::None()); } BOOST_CHECK_EQUAL(nStreamTemplate.remainingCandidates(), 4u); @@ -231,7 +231,8 @@ BOOST_AUTO_TEST_CASE(NavigationStream_InitializeCylinders) { // Let us fill the surfaces into the navigation stream NavigationStream nStreamTemplate; for (const auto& surface : surfaces) { - nStreamTemplate.addSurfaceCandidates({surface.get()}, + const Surface* pointer = surface.get(); + nStreamTemplate.addSurfaceCandidates({&pointer, 1}, Acts::BoundaryTolerance::None()); } BOOST_CHECK_EQUAL(nStreamTemplate.remainingCandidates(), 4u); diff --git a/Tests/UnitTests/Core/Propagator/MultiStepperTests.cpp b/Tests/UnitTests/Core/Propagator/MultiStepperTests.cpp index b9842b55420..e7edefb1f03 100644 --- a/Tests/UnitTests/Core/Propagator/MultiStepperTests.cpp +++ b/Tests/UnitTests/Core/Propagator/MultiStepperTests.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -124,9 +125,30 @@ auto makeDefaultBoundPars(bool cov = true, std::size_t n = 4, return c; }; + // note that we are using the default random device + std::mt19937 gen; + std::uniform_real_distribution<> locDis(-10.0, 10.0); + std::uniform_real_distribution<> phiDis(-M_PI, M_PI); + std::uniform_real_distribution<> thetaDis(0, M_PI); + std::uniform_real_distribution<> qOverPDis(-10.0, 10.0); + std::uniform_real_distribution<> timeDis(0.0, 100.0); + for (auto i = 0ul; i < n; ++i) { - cmps.push_back({1. / n, ext_pars ? *ext_pars : BoundVector::Random(), - cov ? Opt{make_random_sym_matrix()} : Opt{}}); + BoundVector params = BoundVector::Zero(); + + if (ext_pars) { + params = *ext_pars; + } else { + params[eBoundLoc0] = locDis(gen); + params[eBoundLoc1] = locDis(gen); + params[eBoundPhi] = phiDis(gen); + params[eBoundTheta] = thetaDis(gen); + params[eBoundQOverP] = qOverPDis(gen); + params[eBoundTime] = timeDis(gen); + } + + cmps.push_back( + {1. / n, params, cov ? Opt{make_random_sym_matrix()} : Opt{}}); } auto surface = Acts::CurvilinearSurface(Vector3::Zero(), Vector3{1., 0., 0.}) @@ -430,7 +452,8 @@ void test_multi_stepper_surface_status_update() { std::vector>> cmps(2, {0.5, BoundVector::Zero(), std::nullopt}); std::get(cmps[0])[eBoundTheta] = M_PI_2; - std::get(cmps[1])[eBoundTheta] = -M_PI_2; + std::get(cmps[1])[eBoundPhi] = M_PI; + std::get(cmps[1])[eBoundTheta] = M_PI_2; std::get(cmps[0])[eBoundQOverP] = 1.0; std::get(cmps[1])[eBoundQOverP] = 1.0; @@ -541,7 +564,8 @@ void test_component_bound_state() { std::vector>> cmps(2, {0.5, BoundVector::Zero(), std::nullopt}); std::get(cmps[0])[eBoundTheta] = M_PI_2; - std::get(cmps[1])[eBoundTheta] = -M_PI_2; + std::get(cmps[1])[eBoundPhi] = M_PI; + std::get(cmps[1])[eBoundTheta] = M_PI_2; std::get(cmps[0])[eBoundQOverP] = 1.0; std::get(cmps[1])[eBoundQOverP] = 1.0; @@ -703,18 +727,7 @@ void test_single_component_interface_function() { using MultiState = typename multi_stepper_t::State; using MultiStepper = multi_stepper_t; - std::vector>> - cmps; - for (int i = 0; i < 4; ++i) { - cmps.push_back({0.25, BoundVector::Random(), BoundSquareMatrix::Random()}); - } - - auto surface = - Acts::CurvilinearSurface(Vector3::Zero(), Vector3::Ones().normalized()) - .planeSurface(); - - MultiComponentBoundTrackParameters multi_pars(surface, cmps, - particleHypothesis); + MultiComponentBoundTrackParameters multi_pars = makeDefaultBoundPars(true, 4); MultiState multi_state(geoCtx, magCtx, defaultBField, multi_pars, defaultStepSize); diff --git a/Tests/UnitTests/Core/Seeding/SeedFinderTest.cpp b/Tests/UnitTests/Core/Seeding/SeedFinderTest.cpp index 9d89c1c96c6..8368bdbc3f2 100644 --- a/Tests/UnitTests/Core/Seeding/SeedFinderTest.cpp +++ b/Tests/UnitTests/Core/Seeding/SeedFinderTest.cpp @@ -186,8 +186,8 @@ int main(int argc, char** argv) { Acts::SeedFilterConfig sfconf; Acts::ATLASCuts atlasCuts = Acts::ATLASCuts(); - config.seedFilter = std::make_unique>( - Acts::SeedFilter(sfconf, &atlasCuts)); + config.seedFilter = + std::make_unique>(sfconf, &atlasCuts); Acts::SeedFinder> a; // test creation of unconfigured finder a = Acts::SeedFinder>( diff --git a/Tests/UnitTests/Core/Surfaces/AlignmentHelperTests.cpp b/Tests/UnitTests/Core/Surfaces/AlignmentHelperTests.cpp index 437db0f30cf..3688d49a28b 100644 --- a/Tests/UnitTests/Core/Surfaces/AlignmentHelperTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/AlignmentHelperTests.cpp @@ -14,6 +14,7 @@ #include #include +#include #include namespace Acts::Test { @@ -23,9 +24,9 @@ namespace Acts::Test { BOOST_AUTO_TEST_CASE(alignment_helper_test) { // (a) Test with non-identity rotation matrix // Rotation angle parameters - const double alpha = M_PI; - const double beta = 0; - const double gamma = M_PI / 2; + const double alpha = std::numbers::pi; + const double beta = 0.; + const double gamma = std::numbers::pi / 2.; // rotation around x axis AngleAxis3 rotX(alpha, Vector3(1., 0., 0.)); // rotation around y axis diff --git a/Tests/UnitTests/Core/Surfaces/AnnulusBoundsTests.cpp b/Tests/UnitTests/Core/Surfaces/AnnulusBoundsTests.cpp index 9f09fb2c213..60ecc7f84e4 100644 --- a/Tests/UnitTests/Core/Surfaces/AnnulusBoundsTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/AnnulusBoundsTests.cpp @@ -23,12 +23,12 @@ namespace Acts::Test { BOOST_AUTO_TEST_SUITE(Surfaces) -ActsScalar minRadius = 7.2; -ActsScalar maxRadius = 12.0; -ActsScalar minPhi = 0.74195; -ActsScalar maxPhi = 1.33970; +const ActsScalar minRadius = 7.2; +const ActsScalar maxRadius = 12.0; +const ActsScalar minPhi = 0.74195; +const ActsScalar maxPhi = 1.33970; -Vector2 offset(-2., 2.); +const Vector2 offset(-2., 2.); // Unit tests for AnnulusBounds constructors BOOST_AUTO_TEST_CASE(AnnulusBoundsConstruction) { @@ -60,13 +60,13 @@ BOOST_AUTO_TEST_CASE(AnnulusBoundsExcpetion) { // Exception for swapped radii BOOST_CHECK_THROW(AnnulusBounds(maxRadius, minRadius, minPhi, maxPhi, offset), std::logic_error); - // Exception for out of range min phi + // Exception for out of range min phi BOOST_CHECK_THROW(AnnulusBounds(minRadius, maxRadius, -4., maxPhi, offset), std::logic_error); - // Exception for out of range max phi + // Exception for out of range max phi BOOST_CHECK_THROW(AnnulusBounds(minRadius, maxRadius, minPhi, 4., offset), std::logic_error); - // Exception for out of range max phi + // Exception for out of range max phi BOOST_CHECK_THROW(AnnulusBounds(minRadius, maxRadius, maxPhi, minPhi, offset), std::logic_error); } @@ -76,7 +76,6 @@ BOOST_AUTO_TEST_CASE(AnnulusBoundsProperties) { /// Test construction with radii and default sector AnnulusBounds aBounds(minRadius, maxRadius, minPhi, maxPhi, offset); - // /// Test type() (redundant; already used in constructor confirmation) BOOST_CHECK_EQUAL(aBounds.type(), SurfaceBounds::eAnnulus); diff --git a/Tests/UnitTests/Core/Surfaces/BoundaryToleranceTests.cpp b/Tests/UnitTests/Core/Surfaces/BoundaryToleranceTests.cpp index cd49b409f5b..edc401e9b83 100644 --- a/Tests/UnitTests/Core/Surfaces/BoundaryToleranceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/BoundaryToleranceTests.cpp @@ -20,8 +20,6 @@ #include #include -#include "BoundaryToleranceTestsRefs.hpp" - namespace Acts::Test { BOOST_AUTO_TEST_SUITE(Surfaces) @@ -42,6 +40,7 @@ BOOST_AUTO_TEST_CASE(BoundaryCheckBoxSimple) { BOOST_CHECK( !detail::insideAlignedBox(ll, ur, tolerance, {2, 0}, std::nullopt)); } + // Aligned box w/ tolerance check along first axis BOOST_AUTO_TEST_CASE(BoundaryCheckBoxToleranceLoc0) { boost::execution_monitor em; @@ -73,7 +72,7 @@ BOOST_AUTO_TEST_CASE(BoundaryCheckBoxCovariance) { cov << 1, 0.5, 0.5, 2; Vector2 ll(-1, -1); Vector2 ur(1, 1); - auto tolerance = BoundaryTolerance::Chi2Bound(cov.inverse(), 3.0); + auto tolerance = BoundaryTolerance::Chi2Bound(cov.inverse(), 3.); BOOST_CHECK( detail::insideAlignedBox(ll, ur, tolerance, {0, 0}, std::nullopt)); BOOST_CHECK( @@ -190,7 +189,7 @@ BOOST_AUTO_TEST_CASE(BoundaryCheckDifferentTolerances) { { auto tolerance = - BoundaryTolerance::Chi2Bound(SquareMatrix2::Identity(), 1.0); + BoundaryTolerance::Chi2Bound(SquareMatrix2::Identity(), 1.); BOOST_CHECK( detail::insideAlignedBox(ll, ur, tolerance, {0, 0}, std::nullopt)); BOOST_CHECK( diff --git a/Tests/UnitTests/Core/Surfaces/BoundaryToleranceTestsRefs.hpp b/Tests/UnitTests/Core/Surfaces/BoundaryToleranceTestsRefs.hpp deleted file mode 100644 index a59053b8273..00000000000 --- a/Tests/UnitTests/Core/Surfaces/BoundaryToleranceTestsRefs.hpp +++ /dev/null @@ -1,216 +0,0 @@ -// 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/Definitions/Algebra.hpp" - -// clang-format off -const std::vector rectVertices = { - {-2.000000, -1.000000}, - {2.000000, -1.000000}, - {2.000000, 1.000000}, - {-2.000000, 1.000000} -}; - -const struct { - double xmin = -2; - double xmax = 2; - double ymin = -1; - double ymax = 1; -} rectDimensions; - -const std::vector rectTestPoints = { - {-3.00, -2.00}, {-3.00, -1.60}, {-3.00, -1.20}, {-3.00, -0.80}, {-3.00, -0.40}, - {-3.00, 0.00}, {-3.00, 0.40}, {-3.00, 0.80}, {-3.00, 1.20}, {-3.00, 1.60}, - {-3.00, 2.00}, {-2.40, -2.00}, {-2.40, -1.60}, {-2.40, -1.20}, {-2.40, -0.80}, - {-2.40, -0.40}, {-2.40, 0.00}, {-2.40, 0.40}, {-2.40, 0.80}, {-2.40, 1.20}, - {-2.40, 1.60}, {-2.40, 2.00}, {-1.80, -2.00}, {-1.80, -1.60}, {-1.80, -1.20}, - {-1.80, -0.80}, {-1.80, -0.40}, {-1.80, 0.00}, {-1.80, 0.40}, {-1.80, 0.80}, - {-1.80, 1.20}, {-1.80, 1.60}, {-1.80, 2.00}, {-1.20, -2.00}, {-1.20, -1.60}, - {-1.20, -1.20}, {-1.20, -0.80}, {-1.20, -0.40}, {-1.20, 0.00}, {-1.20, 0.40}, - {-1.20, 0.80}, {-1.20, 1.20}, {-1.20, 1.60}, {-1.20, 2.00}, {-0.60, -2.00}, - {-0.60, -1.60}, {-0.60, -1.20}, {-0.60, -0.80}, {-0.60, -0.40}, {-0.60, 0.00}, - {-0.60, 0.40}, {-0.60, 0.80}, {-0.60, 1.20}, {-0.60, 1.60}, {-0.60, 2.00}, - {0.00, -2.00}, {0.00, -1.60}, {0.00, -1.20}, {0.00, -0.80}, {0.00, -0.40}, - {0.00, 0.00}, {0.00, 0.40}, {0.00, 0.80}, {0.00, 1.20}, {0.00, 1.60}, - {0.00, 2.00}, {0.60, -2.00}, {0.60, -1.60}, {0.60, -1.20}, {0.60, -0.80}, - {0.60, -0.40}, {0.60, 0.00}, {0.60, 0.40}, {0.60, 0.80}, {0.60, 1.20}, - {0.60, 1.60}, {0.60, 2.00}, {1.20, -2.00}, {1.20, -1.60}, {1.20, -1.20}, - {1.20, -0.80}, {1.20, -0.40}, {1.20, 0.00}, {1.20, 0.40}, {1.20, 0.80}, - {1.20, 1.20}, {1.20, 1.60}, {1.20, 2.00}, {1.80, -2.00}, {1.80, -1.60}, - {1.80, -1.20}, {1.80, -0.80}, {1.80, -0.40}, {1.80, 0.00}, {1.80, 0.40}, - {1.80, 0.80}, {1.80, 1.20}, {1.80, 1.60}, {1.80, 2.00}, {2.40, -2.00}, - {2.40, -1.60}, {2.40, -1.20}, {2.40, -0.80}, {2.40, -0.40}, {2.40, 0.00}, - {2.40, 0.40}, {2.40, 0.80}, {2.40, 1.20}, {2.40, 1.60}, {2.40, 2.00}, - {3.00, -2.00}, {3.00, -1.60}, {3.00, -1.20}, {3.00, -0.80}, {3.00, -0.40}, - {3.00, 0.00}, {3.00, 0.40}, {3.00, 0.80}, {3.00, 1.20}, {3.00, 1.60}, - {3.00, 2.00} -}; -//const std::vector rectClosestPoints = { -// {-2.00, -1.00}, {-2.00, -1.00}, {-2.00, -1.00}, {-2.00, -0.80}, {-2.00, -0.40}, -// {-2.00, 0.00}, {-2.00, 0.40}, {-2.00, 0.80}, {-2.00, 1.00}, {-2.00, 1.00}, -// {-2.00, 1.00}, {-2.00, -1.00}, {-2.00, -1.00}, {-2.00, -1.00}, {-2.00, -0.80}, -// {-2.00, -0.40}, {-2.00, 0.00}, {-2.00, 0.40}, {-2.00, 0.80}, {-2.00, 1.00}, -// {-2.00, 1.00}, {-2.00, 1.00}, {-1.80, -1.00}, {-1.80, -1.00}, {-1.80, -1.00}, -// {-2.00, -0.80}, {-2.00, -0.40}, {-2.00, 0.00}, {-2.00, 0.40}, {-1.80, 1.00}, -// {-1.80, 1.00}, {-1.80, 1.00}, {-1.80, 1.00}, {-1.20, -1.00}, {-1.20, -1.00}, -// {-1.20, -1.00}, {-1.20, -1.00}, {-1.20, -1.00}, {-2.00, 0.00}, {-1.20, 1.00}, -// {-1.20, 1.00}, {-1.20, 1.00}, {-1.20, 1.00}, {-1.20, 1.00}, {-0.60, -1.00}, -// {-0.60, -1.00}, {-0.60, -1.00}, {-0.60, -1.00}, {-0.60, -1.00}, {-0.60, -1.00}, -// {-0.60, 1.00}, {-0.60, 1.00}, {-0.60, 1.00}, {-0.60, 1.00}, {-0.60, 1.00}, -// {0.00, -1.00}, {0.00, -1.00}, {0.00, -1.00}, {0.00, -1.00}, {0.00, -1.00}, -// {0.00, -1.00}, {0.00, 1.00}, {0.00, 1.00}, {0.00, 1.00}, {0.00, 1.00}, -// {0.00, 1.00}, {0.60, -1.00}, {0.60, -1.00}, {0.60, -1.00}, {0.60, -1.00}, -// {0.60, -1.00}, {0.60, -1.00}, {0.60, 1.00}, {0.60, 1.00}, {0.60, 1.00}, -// {0.60, 1.00}, {0.60, 1.00}, {1.20, -1.00}, {1.20, -1.00}, {1.20, -1.00}, -// {1.20, -1.00}, {1.20, -1.00}, {2.00, 0.00}, {1.20, 1.00}, {1.20, 1.00}, -// {1.20, 1.00}, {1.20, 1.00}, {1.20, 1.00}, {1.80, -1.00}, {1.80, -1.00}, -// {1.80, -1.00}, {1.80, -1.00}, {2.00, -0.40}, {2.00, 0.00}, {2.00, 0.40}, -// {1.80, 1.00}, {1.80, 1.00}, {1.80, 1.00}, {1.80, 1.00}, {2.00, -1.00}, -// {2.00, -1.00}, {2.00, -1.00}, {2.00, -0.80}, {2.00, -0.40}, {2.00, 0.00}, -// {2.00, 0.40}, {2.00, 0.80}, {2.00, 1.00}, {2.00, 1.00}, {2.00, 1.00}, -// {2.00, -1.00}, {2.00, -1.00}, {2.00, -1.00}, {2.00, -0.80}, {2.00, -0.40}, -// {2.00, 0.00}, {2.00, 0.40}, {2.00, 0.80}, {2.00, 1.00}, {2.00, 1.00}, -// {2.00, 1.00} -//}; -const std::vector rectDistances = { - 1.4142135623730951, 1.1661903789690602, 1.019803902718557, 1.0, 1.0, 1.0, 1.0, - 1.0, 1.019803902718557, 1.1661903789690602, 1.4142135623730951, - 1.0770329614269007, 0.7211102550927979, 0.4472135954999578, 0.3999999999999999, - 0.3999999999999999, 0.3999999999999999, 0.3999999999999999, 0.3999999999999999, - 0.4472135954999579, 0.7211102550927979, 1.0770329614269007, 1.0, - 0.6000000000000001, 0.19999999999999996, -0.19999999999999996, - -0.19999999999999996, -0.19999999999999996, -0.19999999999999996, - -0.19999999999999973, 0.20000000000000018, 0.6000000000000001, 1.0, 1.0, - 0.6000000000000001, 0.19999999999999996, -0.20000000000000018, - -0.6000000000000001, -0.7999999999999998, -0.5999999999999996, - -0.19999999999999973, 0.20000000000000018, 0.6000000000000001, 1.0, 1.0, - 0.6000000000000001, 0.19999999999999996, -0.20000000000000018, - -0.6000000000000001, -1.0, -0.5999999999999996, -0.19999999999999973, - 0.20000000000000018, 0.6000000000000001, 1.0, 1.0, 0.6000000000000001, - 0.19999999999999996, -0.20000000000000018, -0.6000000000000001, -1.0, - -0.5999999999999996, -0.19999999999999973, 0.20000000000000018, - 0.6000000000000001, 1.0, 1.0, 0.6000000000000001, 0.19999999999999996, - -0.20000000000000018, -0.6000000000000001, -1.0, -0.5999999999999996, - -0.19999999999999973, 0.20000000000000018, 0.6000000000000001, 1.0, 1.0, - 0.6000000000000001, 0.19999999999999996, -0.20000000000000018, - -0.6000000000000001, -0.7999999999999998, -0.5999999999999996, - -0.19999999999999973, 0.20000000000000018, 0.6000000000000001, 1.0, 1.0, - 0.6000000000000001, 0.19999999999999996, -0.20000000000000018, - -0.20000000000000018, -0.20000000000000018, -0.20000000000000018, - -0.19999999999999973, 0.20000000000000018, 0.6000000000000001, 1.0, - 1.0770329614269007, 0.7211102550927977, 0.44721359549995743, - 0.39999999999999947, 0.39999999999999947, 0.39999999999999947, - 0.39999999999999947, 0.39999999999999947, 0.44721359549995754, - 0.7211102550927977, 1.0770329614269007, 1.4142135623730951, 1.1661903789690602, - 1.019803902718557, 1.0, 1.0, 1.0, 1.0, 1.0, 1.019803902718557, - 1.1661903789690602, 1.4142135623730951 -}; - -const std::vector rectShiftedVertices = { - {1.000000, 2.000000}, - {3.000000, 2.000000}, - {3.000000, 4.000000}, - {1.000000, 4.000000} -}; - -const struct { - double xmin = 1; - double xmax = 3; - double ymin = 2; - double ymax = 4; -} rectShiftedDimensions; - -const std::vector rectShiftedTestPoints = { - {0.00, 1.50}, {0.00, 1.80}, {0.00, 2.10}, {0.00, 2.40}, {0.00, 2.70}, - {0.00, 3.00}, {0.00, 3.30}, {0.00, 3.60}, {0.00, 3.90}, {0.00, 4.20}, - {0.00, 4.50}, {0.40, 1.50}, {0.40, 1.80}, {0.40, 2.10}, {0.40, 2.40}, - {0.40, 2.70}, {0.40, 3.00}, {0.40, 3.30}, {0.40, 3.60}, {0.40, 3.90}, - {0.40, 4.20}, {0.40, 4.50}, {0.80, 1.50}, {0.80, 1.80}, {0.80, 2.10}, - {0.80, 2.40}, {0.80, 2.70}, {0.80, 3.00}, {0.80, 3.30}, {0.80, 3.60}, - {0.80, 3.90}, {0.80, 4.20}, {0.80, 4.50}, {1.20, 1.50}, {1.20, 1.80}, - {1.20, 2.10}, {1.20, 2.40}, {1.20, 2.70}, {1.20, 3.00}, {1.20, 3.30}, - {1.20, 3.60}, {1.20, 3.90}, {1.20, 4.20}, {1.20, 4.50}, {1.60, 1.50}, - {1.60, 1.80}, {1.60, 2.10}, {1.60, 2.40}, {1.60, 2.70}, {1.60, 3.00}, - {1.60, 3.30}, {1.60, 3.60}, {1.60, 3.90}, {1.60, 4.20}, {1.60, 4.50}, - {2.00, 1.50}, {2.00, 1.80}, {2.00, 2.10}, {2.00, 2.40}, {2.00, 2.70}, - {2.00, 3.00}, {2.00, 3.30}, {2.00, 3.60}, {2.00, 3.90}, {2.00, 4.20}, - {2.00, 4.50}, {2.40, 1.50}, {2.40, 1.80}, {2.40, 2.10}, {2.40, 2.40}, - {2.40, 2.70}, {2.40, 3.00}, {2.40, 3.30}, {2.40, 3.60}, {2.40, 3.90}, - {2.40, 4.20}, {2.40, 4.50}, {2.80, 1.50}, {2.80, 1.80}, {2.80, 2.10}, - {2.80, 2.40}, {2.80, 2.70}, {2.80, 3.00}, {2.80, 3.30}, {2.80, 3.60}, - {2.80, 3.90}, {2.80, 4.20}, {2.80, 4.50}, {3.20, 1.50}, {3.20, 1.80}, - {3.20, 2.10}, {3.20, 2.40}, {3.20, 2.70}, {3.20, 3.00}, {3.20, 3.30}, - {3.20, 3.60}, {3.20, 3.90}, {3.20, 4.20}, {3.20, 4.50}, {3.60, 1.50}, - {3.60, 1.80}, {3.60, 2.10}, {3.60, 2.40}, {3.60, 2.70}, {3.60, 3.00}, - {3.60, 3.30}, {3.60, 3.60}, {3.60, 3.90}, {3.60, 4.20}, {3.60, 4.50}, - {4.00, 1.50}, {4.00, 1.80}, {4.00, 2.10}, {4.00, 2.40}, {4.00, 2.70}, - {4.00, 3.00}, {4.00, 3.30}, {4.00, 3.60}, {4.00, 3.90}, {4.00, 4.20}, - {4.00, 4.50} -}; -//const std::vector rectShiftedClosestPoints = { -// {1.00, 2.00}, {1.00, 2.00}, {1.00, 2.10}, {1.00, 2.40}, {1.00, 2.70}, -// {1.00, 3.00}, {1.00, 3.30}, {1.00, 3.60}, {1.00, 3.90}, {1.00, 4.00}, -// {1.00, 4.00}, {1.00, 2.00}, {1.00, 2.00}, {1.00, 2.10}, {1.00, 2.40}, -// {1.00, 2.70}, {1.00, 3.00}, {1.00, 3.30}, {1.00, 3.60}, {1.00, 3.90}, -// {1.00, 4.00}, {1.00, 4.00}, {1.00, 2.00}, {1.00, 2.00}, {1.00, 2.10}, -// {1.00, 2.40}, {1.00, 2.70}, {1.00, 3.00}, {1.00, 3.30}, {1.00, 3.60}, -// {1.00, 3.90}, {1.00, 4.00}, {1.00, 4.00}, {1.20, 2.00}, {1.20, 2.00}, -// {1.20, 2.00}, {1.00, 2.40}, {1.00, 2.70}, {1.00, 3.00}, {1.00, 3.30}, -// {1.00, 3.60}, {1.20, 4.00}, {1.20, 4.00}, {1.20, 4.00}, {1.60, 2.00}, -// {1.60, 2.00}, {1.60, 2.00}, {1.60, 2.00}, {1.00, 2.70}, {1.00, 3.00}, -// {1.00, 3.30}, {1.60, 4.00}, {1.60, 4.00}, {1.60, 4.00}, {1.60, 4.00}, -// {2.00, 2.00}, {2.00, 2.00}, {2.00, 2.00}, {2.00, 2.00}, {2.00, 2.00}, -// {2.00, 2.00}, {2.00, 4.00}, {2.00, 4.00}, {2.00, 4.00}, {2.00, 4.00}, -// {2.00, 4.00}, {2.40, 2.00}, {2.40, 2.00}, {2.40, 2.00}, {2.40, 2.00}, -// {3.00, 2.70}, {3.00, 3.00}, {3.00, 3.30}, {2.40, 4.00}, {2.40, 4.00}, -// {2.40, 4.00}, {2.40, 4.00}, {2.80, 2.00}, {2.80, 2.00}, {2.80, 2.00}, -// {3.00, 2.40}, {3.00, 2.70}, {3.00, 3.00}, {3.00, 3.30}, {3.00, 3.60}, -// {2.80, 4.00}, {2.80, 4.00}, {2.80, 4.00}, {3.00, 2.00}, {3.00, 2.00}, -// {3.00, 2.10}, {3.00, 2.40}, {3.00, 2.70}, {3.00, 3.00}, {3.00, 3.30}, -// {3.00, 3.60}, {3.00, 3.90}, {3.00, 4.00}, {3.00, 4.00}, {3.00, 2.00}, -// {3.00, 2.00}, {3.00, 2.10}, {3.00, 2.40}, {3.00, 2.70}, {3.00, 3.00}, -// {3.00, 3.30}, {3.00, 3.60}, {3.00, 3.90}, {3.00, 4.00}, {3.00, 4.00}, -// {3.00, 2.00}, {3.00, 2.00}, {3.00, 2.10}, {3.00, 2.40}, {3.00, 2.70}, -// {3.00, 3.00}, {3.00, 3.30}, {3.00, 3.60}, {3.00, 3.90}, {3.00, 4.00}, -// {3.00, 4.00} -//}; -const std::vector rectShiftedDistances = { - 1.118033988749895, 1.019803902718557, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, - 1.0198039027185568, 1.118033988749895, 0.7810249675906654, 0.6324555320336759, - 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6, 0.6324555320336757, 0.7810249675906654, - 0.5385164807134504, 0.28284271247461895, 0.19999999999999996, - 0.19999999999999996, 0.19999999999999996, 0.19999999999999996, - 0.19999999999999996, 0.19999999999999996, 0.19999999999999996, - 0.28284271247461845, 0.5385164807134504, 0.5, 0.19999999999999996, - -0.10000000000000009, -0.20000000000000018, -0.20000000000000018, - -0.20000000000000018, -0.20000000000000018, -0.20000000000000018, - -0.10000000000000009, 0.1999999999999993, 0.5, 0.5, 0.19999999999999996, - -0.10000000000000009, -0.3999999999999999, -0.6000000000000001, - -0.6000000000000001, -0.6000000000000001, -0.3999999999999999, - -0.10000000000000009, 0.1999999999999993, 0.5, 0.5, 0.19999999999999996, - -0.10000000000000009, -0.3999999999999999, -0.7000000000000002, -1.0, - -0.7000000000000002, -0.3999999999999999, -0.10000000000000009, - 0.1999999999999993, 0.5, 0.5, 0.19999999999999996, -0.10000000000000009, - -0.3999999999999999, -0.5999999999999996, -0.5999999999999996, - -0.5999999999999996, -0.3999999999999999, -0.10000000000000009, - 0.1999999999999993, 0.5, 0.5, 0.19999999999999996, -0.10000000000000009, - -0.19999999999999973, -0.19999999999999973, -0.19999999999999973, - -0.19999999999999973, -0.19999999999999973, -0.10000000000000009, - 0.1999999999999993, 0.5, 0.5385164807134505, 0.28284271247461906, - 0.20000000000000018, 0.20000000000000018, 0.20000000000000018, - 0.20000000000000018, 0.20000000000000018, 0.20000000000000018, - 0.20000000000000018, 0.2828427124746186, 0.5385164807134505, 0.7810249675906655, - 0.6324555320336759, 0.6000000000000001, 0.6000000000000001, 0.6000000000000001, - 0.6000000000000001, 0.6000000000000001, 0.6000000000000001, 0.6000000000000001, - 0.6324555320336757, 0.7810249675906655, 1.118033988749895, 1.019803902718557, - 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0198039027185568, 1.118033988749895 -}; - -// clang-format on diff --git a/Tests/UnitTests/Core/Surfaces/ConeBoundsTests.cpp b/Tests/UnitTests/Core/Surfaces/ConeBoundsTests.cpp index 887a14391c5..ba38f5d11c1 100644 --- a/Tests/UnitTests/Core/Surfaces/ConeBoundsTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/ConeBoundsTests.cpp @@ -17,132 +17,140 @@ #include #include #include +#include #include #include -/* Note on nomenclature: - alpha = cone opening half angle - z is the axis of symmetry - zmin, zmax define limits for truncated cone - phi is clock angle around cone, with x axis corresponding to phi=0 - Cone segments may be defined with the avphi (central position of segment) and - halfphi (extent in phi of cone segment either side of the avphi) - Local coords are z, rphi -*/ +// Note on nomenclature: +// - alpha = cone opening half angle +// - z is the axis of symmetry +// - zMin, zMax define limits for truncated cone +// - phi is clock angle around cone, with x axis corresponding to phi=0 +// - Cone segments may be defined with the averagePhi (central position of +// segment) and halfPhi (extent in phi of cone segment either side of the +// averagePhi) +// - Local coords are z, rphi + namespace Acts::Test { BOOST_AUTO_TEST_SUITE(Surfaces) +const double alpha = std::numbers::pi / 8.; +const double zMin = 3.; +const double zMax = 6.; +const double halfPhi = std::numbers::pi / 4.; +const double averagePhi = 0.; +const bool symmetric = false; + /// Unit test for creating compliant/non-compliant ConeBounds object BOOST_AUTO_TEST_CASE(ConeBoundsConstruction) { - // test default construction - // ConeBounds defaultConstructedConeBounds; // deleted - double alpha(M_PI / 8.0), zMin(3.), zMax(6.), halfPhi(M_PI / 4.0), - averagePhi(0.); - const bool symmetric(false); + /// Test default construction + // default construction is deleted + BOOST_TEST_CHECKPOINT("Four parameter constructor (last two at default)"); ConeBounds defaultConeBounds(alpha, symmetric); BOOST_CHECK_EQUAL(defaultConeBounds.type(), SurfaceBounds::eCone); + BOOST_TEST_CHECKPOINT("Four parameter constructor"); ConeBounds fourParameterConstructed(alpha, symmetric, halfPhi, averagePhi); BOOST_CHECK_EQUAL(fourParameterConstructed.type(), SurfaceBounds::eCone); + BOOST_TEST_CHECKPOINT("Five parameter constructor (last two at default)"); ConeBounds defaulted5ParamConeBounds(alpha, zMin, zMax); BOOST_CHECK_EQUAL(defaulted5ParamConeBounds.type(), SurfaceBounds::eCone); + BOOST_TEST_CHECKPOINT("Five parameter constructor)"); ConeBounds fiveParamConstructedConeBounds(alpha, zMin, zMax, halfPhi, averagePhi); BOOST_CHECK_EQUAL(fiveParamConstructedConeBounds.type(), SurfaceBounds::eCone); + BOOST_TEST_CHECKPOINT("Copy constructor"); ConeBounds copyConstructedConeBounds(fiveParamConstructedConeBounds); BOOST_CHECK_EQUAL(copyConstructedConeBounds, fiveParamConstructedConeBounds); } -// Streaning and recreation test +/// Streaning and recreation test BOOST_AUTO_TEST_CASE(ConeBoundsRecreation) { - double alpha(M_PI / 8.0), zMin(3.), zMax(6.), halfPhi(M_PI / 4.0), - averagePhi(0.); - // const bool symmetric(false); ConeBounds original(alpha, zMin, zMax, halfPhi, averagePhi); auto valvector = original.values(); std::array values{}; std::copy_n(valvector.begin(), ConeBounds::eSize, values.begin()); ConeBounds recreated(values); + BOOST_CHECK_EQUAL(recreated, original); } -// Unit tests for AnnulusBounds exception throwing +/// Unit tests for AnnulusBounds exception throwing BOOST_AUTO_TEST_CASE(ConeBoundsExceptions) { - double alpha(M_PI / 8.0), zMin(3.), zMax(6.), halfPhi(M_PI / 4.0), - averagePhi(0.); - // Exception for opening angle smaller 0 BOOST_CHECK_THROW(ConeBounds(-alpha, zMin, zMax, halfPhi, averagePhi), std::logic_error); - // Exception for opening angle bigger M_PI - BOOST_CHECK_THROW(ConeBounds(M_PI, zMin, zMax, halfPhi, averagePhi), - std::logic_error); + + // Exception for opening angle bigger std::numbers::pi + BOOST_CHECK_THROW( + ConeBounds(std::numbers::pi, zMin, zMax, halfPhi, averagePhi), + std::logic_error); + // Exception for swapped zMin and zMax BOOST_CHECK_THROW(ConeBounds(alpha, zMax, zMin, halfPhi, averagePhi), std::logic_error); + // Exception for negative half sector phi BOOST_CHECK_THROW(ConeBounds(alpha, zMin, zMax, -halfPhi, averagePhi), std::logic_error); - // Exception for out of range phi positioning - BOOST_CHECK_THROW(ConeBounds(alpha, zMin, zMax, halfPhi, 2 * M_PI), - std::logic_error); + + // Exception for out of range phi positioning + BOOST_CHECK_THROW( + ConeBounds(alpha, zMin, zMax, halfPhi, 2 * std::numbers::pi), + std::logic_error); } /// Unit tests for properties of ConeBounds object BOOST_AUTO_TEST_CASE(ConeBoundsProperties) { - double alpha(M_PI / 8.0), zMin(3.), zMax(6.), halfPhi(M_PI / 4.0), - averagePhi(0.); - // const bool symmetric(false); const Vector2 origin(0, 0); const Vector2 somewhere(4., 4.); ConeBounds coneBoundsObject(alpha, zMin, zMax, halfPhi, averagePhi); - // - /// test for type (redundant) + + /// Test for type (redundant) BOOST_CHECK_EQUAL(coneBoundsObject.type(), SurfaceBounds::eCone); - // - /// test for inside + + /// Test for inside BOOST_CHECK(!coneBoundsObject.inside(origin)); - // - /// test for r + + /// Test for r CHECK_CLOSE_REL(coneBoundsObject.r(zMin), zMin * std::tan(alpha), 1e-6); - // - /// test for tanAlpha + + /// Test for tanAlpha CHECK_CLOSE_REL(coneBoundsObject.tanAlpha(), std::tan(alpha), 1e-6); - // - /// test for alpha + + /// Test for alpha CHECK_CLOSE_REL(coneBoundsObject.get(ConeBounds::eAlpha), alpha, 1e-6); - // - /// test for minZ + + /// Test for minZ CHECK_CLOSE_REL(coneBoundsObject.get(ConeBounds::eMinZ), zMin, 1e-6); - // - /// test for maxZ + + /// Test for maxZ CHECK_CLOSE_REL(coneBoundsObject.get(ConeBounds::eMaxZ), zMax, 1e-6); - // - /// test for averagePhi + + /// Test for averagePhi CHECK_CLOSE_REL(coneBoundsObject.get(ConeBounds::eHalfPhiSector), halfPhi, 1e-6); - /// test for dump - boost::test_tools::output_test_stream dumpOuput; - coneBoundsObject.toStream(dumpOuput); - BOOST_CHECK(dumpOuput.is_equal( + + /// Test for dump + boost::test_tools::output_test_stream dumpOutput; + coneBoundsObject.toStream(dumpOutput); + BOOST_CHECK(dumpOutput.is_equal( "Acts::ConeBounds: (tanAlpha, minZ, maxZ, halfPhiSector, averagePhi) = " "(0.4142136, 3.0000000, 6.0000000, 0.7853982, 0.0000000)")); } // Unit test for testing ConeBounds assignment BOOST_AUTO_TEST_CASE(ConeBoundsAssignment) { - double alpha(M_PI / 8.0), zMin(3.), zMax(6.), halfPhi(M_PI / 4.0), - averagePhi(0.); - // const bool symmetric(false); ConeBounds originalConeBounds(alpha, zMin, zMax, halfPhi, averagePhi); ConeBounds assignedConeBounds(0.1, 2.3, 4.5, 1.2, 2.1); assignedConeBounds = originalConeBounds; + BOOST_CHECK_EQUAL(assignedConeBounds, originalConeBounds); } diff --git a/Tests/UnitTests/Core/Surfaces/ConeSurfaceTests.cpp b/Tests/UnitTests/Core/Surfaces/ConeSurfaceTests.cpp index e994d2dbc5a..5d0102653b2 100644 --- a/Tests/UnitTests/Core/Surfaces/ConeSurfaceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/ConeSurfaceTests.cpp @@ -7,6 +7,7 @@ // file, You can obtain one at https://mozilla.org/MPL/2.0/. #include +#include #include #include "Acts/Definitions/Algebra.hpp" @@ -25,6 +26,7 @@ #include #include #include +#include #include namespace Acts::Test { @@ -36,13 +38,17 @@ BOOST_AUTO_TEST_SUITE(ConeSurfaces) /// Unit test for creating compliant/non-compliant ConeSurface object BOOST_AUTO_TEST_CASE(ConeSurfaceConstruction) { - // ConeSurface default constructor is deleted - // - /// Constructor with transform, alpha and symmetry - /// indicator - double alpha{M_PI / 8.}, halfPhiSector{M_PI / 16.}, zMin{1.0}, zMax{10.}; - bool symmetric(false); - Translation3 translation{0., 1., 2.}; + /// Test default construction + // default construction is deleted + + /// Constructor with transform, alpha and symmetry indicator + const double alpha = std::numbers::pi / 8.; + const double halfPhiSector = std::numbers::pi / 16.; + const double zMin = 1.; + const double zMax = 10.; + const bool symmetric = false; + const Translation3 translation{0., 1., 2.}; + auto pTransform = Transform3(translation); BOOST_CHECK_EQUAL( Surface::makeShared(Transform3::Identity(), alpha, symmetric) @@ -51,7 +57,7 @@ BOOST_AUTO_TEST_CASE(ConeSurfaceConstruction) { BOOST_CHECK_EQUAL( Surface::makeShared(pTransform, alpha, symmetric)->type(), Surface::Cone); - // + /// Constructor with transform pointer, alpha,z min and max, halfPhiSector BOOST_CHECK_EQUAL(Surface::makeShared(pTransform, alpha, zMin, zMax, halfPhiSector) @@ -59,22 +65,19 @@ BOOST_AUTO_TEST_CASE(ConeSurfaceConstruction) { Surface::Cone); /// Constructor with transform and ConeBounds pointer - // ConeBounds (double alpha, double zmin, double zmax, double halfphi=M_PI, - // double avphi=0.) auto pConeBounds = std::make_shared(alpha, zMin, zMax, halfPhiSector, 0.); BOOST_CHECK_EQUAL( Surface::makeShared(pTransform, pConeBounds)->type(), Surface::Cone); - // - // + /// Copy constructor auto coneSurfaceObject = Surface::makeShared(pTransform, alpha, symmetric); auto copiedConeSurface = Surface::makeShared(*coneSurfaceObject); BOOST_CHECK_EQUAL(copiedConeSurface->type(), Surface::Cone); BOOST_CHECK(*copiedConeSurface == *coneSurfaceObject); - // + /// Copied and transformed auto copiedTransformedConeSurface = Surface::makeShared( tgContext, *coneSurfaceObject, pTransform); @@ -85,28 +88,29 @@ BOOST_AUTO_TEST_CASE(ConeSurfaceConstruction) { Transform3::Identity(), nullptr), AssertionFailureException); } -// + /// Unit test for testing ConeSurface properties BOOST_AUTO_TEST_CASE(ConeSurfaceProperties) { /// Test clone method - double alpha{M_PI / 8.} /*,halfPhiSector{M_PI/16.}, zMin{1.0}, zMax{10.}*/; - bool symmetric(false); - Translation3 translation{0., 1., 2.}; + const double alpha = std::numbers::pi / 8.; + const bool symmetric = false; + const Translation3 translation{0., 1., 2.}; + auto pTransform = Transform3(translation); auto coneSurfaceObject = Surface::makeShared(pTransform, alpha, symmetric); - // + /// Test type (redundant) BOOST_CHECK_EQUAL(coneSurfaceObject->type(), Surface::Cone); - // + /// Test binningPosition Vector3 binningPosition{0., 1., 2.}; CHECK_CLOSE_ABS( coneSurfaceObject->binningPosition(tgContext, BinningValue::binPhi), binningPosition, 1e-6); - // + /// Test referenceFrame - Vector3 globalPosition{2.0, 2.0, 2.0}; + Vector3 globalPosition{2., 2., 2.}; Vector3 momentum{1.e6, 1.e6, 1.e6}; double rootHalf = std::sqrt(0.5); RotationMatrix3 expectedFrame; @@ -114,45 +118,43 @@ BOOST_AUTO_TEST_CASE(ConeSurfaceProperties) { CHECK_CLOSE_OR_SMALL( coneSurfaceObject->referenceFrame(tgContext, globalPosition, momentum), expectedFrame, 1e-6, 1e-9); - // + /// Test normal, given 3D position Vector3 origin{0., 0., 0.}; Vector3 normal3D = {0., -1., 0.}; CHECK_CLOSE_ABS(coneSurfaceObject->normal(tgContext, origin), normal3D, 1e-6); - // + /// Test normal given 2D rphi position - Vector2 positionPiBy2(1.0, M_PI / 2.); + Vector2 positionPiBy2(1., std::numbers::pi / 2.); Vector3 normalAtPiBy2{0.0312768, 0.92335, -0.382683}; CHECK_CLOSE_OR_SMALL(coneSurfaceObject->normal(tgContext, positionPiBy2), normalAtPiBy2, 1e-2, 1e-9); - // + /// Test rotational symmetry axis Vector3 symmetryAxis{0., 0., 1.}; CHECK_CLOSE_ABS(coneSurfaceObject->rotSymmetryAxis(tgContext), symmetryAxis, 1e-6); - // + /// Test bounds BOOST_CHECK_EQUAL(coneSurfaceObject->bounds().type(), SurfaceBounds::eCone); - // + /// Test localToGlobal - Vector2 localPosition{1.0, M_PI / 2.0}; + Vector2 localPosition{1., std::numbers::pi / 2.}; globalPosition = coneSurfaceObject->localToGlobal(tgContext, localPosition, momentum); - // std::cout<globalToLocal(tgContext, globalPosition, momentum) .value(); - // std::cout<isOnSurface( @@ -164,40 +166,41 @@ BOOST_AUTO_TEST_CASE(ConeSurfaceProperties) { CHECK_CLOSE_REL(coneSurfaceObject->pathCorrection(tgContext, offSurface, momentum.normalized()), 0.40218866453252877, 0.01); - // + /// Test name BOOST_CHECK_EQUAL(coneSurfaceObject->name(), std::string("Acts::ConeSurface")); - // + /// Test dump - // TODO 2017-04-12 msmk: check how to correctly check output - // boost::test_tools::output_test_stream dumpOuput; - // coneSurfaceObject.toStream(dumpOuput); - // BOOST_CHECK(dumpOuput.is_equal( - // "Acts::ConeSurface\n" - // " Center position (x, y, z) = (0.0000, 1.0000, 2.0000)\n" - // " Rotation: colX = (1.000000, 0.000000, 0.000000)\n" - // " colY = (0.000000, 1.000000, 0.000000)\n" - // " colZ = (0.000000, 0.000000, 1.000000)\n" - // " Bounds : Acts::ConeBounds: (tanAlpha, minZ, maxZ, averagePhi, - // halfPhiSector) = (0.4142136, 0.0000000, inf, 0.0000000, - // 3.1415927)")); + boost::test_tools::output_test_stream dumpOutput; + dumpOutput << coneSurfaceObject->toStream(tgContext); + BOOST_CHECK(dumpOutput.is_equal( + "Acts::ConeSurface\n" + " Center position (x, y, z) = (0.0000, 1.0000, 2.0000)\n" + " Rotation: colX = (1.000000, 0.000000, 0.000000)\n" + " colY = (0.000000, 1.000000, 0.000000)\n" + " colZ = (0.000000, 0.000000, 1.000000)\n" + " Bounds : Acts::ConeBounds: (tanAlpha, minZ, maxZ, halfPhiSector, " + "averagePhi) = (0.4142136, 0.0000000, inf, 3.1415927, 0.0000000)" + + )); } BOOST_AUTO_TEST_CASE(ConeSurfaceEqualityOperators) { - double alpha{M_PI / 8.} /*, halfPhiSector{M_PI/16.}, zMin{1.0}, zMax{10.}*/; - bool symmetric(false); - Translation3 translation{0., 1., 2.}; + const double alpha = std::numbers::pi / 8.; + const bool symmetric = false; + const Translation3 translation{0., 1., 2.}; + auto pTransform = Transform3(translation); auto coneSurfaceObject = Surface::makeShared(pTransform, alpha, symmetric); - // + auto coneSurfaceObject2 = Surface::makeShared(pTransform, alpha, symmetric); - // + /// Test equality operator BOOST_CHECK(*coneSurfaceObject == *coneSurfaceObject2); - // + BOOST_TEST_CHECKPOINT( "Create and then assign a ConeSurface object to the existing one"); /// Test assignment @@ -209,11 +212,13 @@ BOOST_AUTO_TEST_CASE(ConeSurfaceEqualityOperators) { } BOOST_AUTO_TEST_CASE(ConeSurfaceExtent) { - double alpha{M_PI / 8.}, zMin{0.}, zMax{10.}; - - Translation3 translation{0., 0., 0.}; + const double alpha = std::numbers::pi / 8.; + const double halfPhiSector = std::numbers::pi / 8.; // != pi/16 + const double zMin = 0.; // != 1. + const double zMax = 10.; + const Translation3 translation{0., 0., 0.}; // != {0., 1., 2.} - // Testing a Full cone + /// Testing a Full cone auto pTransform = Transform3(translation); auto pConeBounds = std::make_shared(alpha, zMin, zMax); auto pCone = Surface::makeShared(pTransform, pConeBounds); @@ -237,8 +242,7 @@ BOOST_AUTO_TEST_CASE(ConeSurfaceExtent) { CHECK_CLOSE_ABS(rMax, pConeExtent.max(BinningValue::binY), s_onSurfaceTolerance); - // Now a sector - double halfPhiSector = M_PI / 8.; + /// Now a sector pConeBounds = std::make_shared(alpha, zMin, zMax, halfPhiSector, 0.); pCone = Surface::makeShared(pTransform, pConeBounds); @@ -256,9 +260,10 @@ BOOST_AUTO_TEST_CASE(ConeSurfaceExtent) { /// Unit test for testing ConeSurface alignment derivatives BOOST_AUTO_TEST_CASE(ConeSurfaceAlignment) { - double alpha{M_PI / 8.}; - bool symmetric(false); - Translation3 translation{0., 1., 2.}; + const double alpha = std::numbers::pi / 8.; + const bool symmetric = false; + const Translation3 translation{0., 1., 2.}; + auto pTransform = Transform3(translation); auto coneSurfaceObject = Surface::makeShared(pTransform, alpha, symmetric); @@ -279,7 +284,7 @@ BOOST_AUTO_TEST_CASE(ConeSurfaceAlignment) { globalPosition); // Check if the result is as expected ActsMatrix<2, 3> expLoc3DToLocBound = ActsMatrix<2, 3>::Zero(); - expLoc3DToLocBound << -1, 0, M_PI / 2. * std::tan(alpha), 0, 0, 1; + expLoc3DToLocBound << -1, 0, std::numbers::pi / 2. * std::tan(alpha), 0, 0, 1; CHECK_CLOSE_ABS(loc3DToLocBound, expLoc3DToLocBound, 1e-10); } diff --git a/Tests/UnitTests/Core/Surfaces/CylinderBoundsTests.cpp b/Tests/UnitTests/Core/Surfaces/CylinderBoundsTests.cpp index 88636494152..14cafdd045b 100644 --- a/Tests/UnitTests/Core/Surfaces/CylinderBoundsTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/CylinderBoundsTests.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -27,34 +28,42 @@ BOOST_AUTO_TEST_SUITE(Surfaces) /// Unit test for creating compliant/non-compliant CylinderBounds object BOOST_AUTO_TEST_CASE(CylinderBoundsConstruction) { - /// test default construction - // CylinderBounds defaultConstructedCylinderBounds; // deleted - double radius(0.5), halfz(10.), halfphi(M_PI / 2.0), averagePhi(M_PI / 2.0), - minBevelZ(-M_PI / 4), maxBevelZ(M_PI / 6); - BOOST_CHECK_EQUAL(CylinderBounds(radius, halfz).type(), - SurfaceBounds::eCylinder); - BOOST_CHECK_EQUAL(CylinderBounds(radius, halfz, halfphi).type(), + /// Test default construction + // default construction is deleted + + const double radius = 0.5; + const double halfZ = 10.; + const double halfPhi = std::numbers::pi / 2.; + const double averagePhi = std::numbers::pi / 2.; + const double bevelMinZ = -std::numbers::pi / 4.; + const double bevelMaxZ = std::numbers::pi / 6.; + + BOOST_CHECK_EQUAL(CylinderBounds(radius, halfZ).type(), SurfaceBounds::eCylinder); - BOOST_CHECK_EQUAL(CylinderBounds(radius, halfz, halfphi, averagePhi).type(), + BOOST_CHECK_EQUAL(CylinderBounds(radius, halfZ, halfPhi).type(), SurfaceBounds::eCylinder); - BOOST_CHECK_EQUAL(CylinderBounds(radius, halfz, M_PI, 0., minBevelZ).type(), + BOOST_CHECK_EQUAL(CylinderBounds(radius, halfZ, halfPhi, averagePhi).type(), SurfaceBounds::eCylinder); BOOST_CHECK_EQUAL( - CylinderBounds(radius, halfz, M_PI, 0., minBevelZ, maxBevelZ).type(), + CylinderBounds(radius, halfZ, std::numbers::pi, 0., bevelMinZ).type(), SurfaceBounds::eCylinder); - // - /// test copy construction; - CylinderBounds cylinderBounds(radius, halfz); + BOOST_CHECK_EQUAL( + CylinderBounds(radius, halfZ, std::numbers::pi, 0., bevelMinZ, bevelMaxZ) + .type(), + SurfaceBounds::eCylinder); + + /// Test copy construction; + CylinderBounds cylinderBounds(radius, halfZ); CylinderBounds copyConstructedCylinderBounds(cylinderBounds); BOOST_CHECK_EQUAL(copyConstructedCylinderBounds, cylinderBounds); } BOOST_AUTO_TEST_CASE(CylinderBoundsRecreation) { - /// test default construction - // CylinderBounds defaultConstructedCylinderBounds; // deleted - double radius(0.5), halfz(10.); + const double radius = 0.5; + const double halfZ = 10.; + // Test construction with radii and default sector - auto original = CylinderBounds(radius, halfz); + auto original = CylinderBounds(radius, halfZ); auto valvector = original.values(); std::array values{}; std::copy_n(valvector.begin(), CylinderBounds::eSize, values.begin()); @@ -63,60 +72,64 @@ BOOST_AUTO_TEST_CASE(CylinderBoundsRecreation) { } BOOST_AUTO_TEST_CASE(CylinderBoundsException) { - double radius(0.5), halfz(10.), halfphi(M_PI / 2.0), averagePhi(M_PI / 2.0); + const double radius = 0.5; + const double halfZ = 10.; + const double halfPhi = std::numbers::pi / 2.; + const double averagePhi = std::numbers::pi / 2.; - // Negative radius - BOOST_CHECK_THROW(CylinderBounds(-radius, halfz, halfphi, averagePhi), + /// Negative radius + BOOST_CHECK_THROW(CylinderBounds(-radius, halfZ, halfPhi, averagePhi), std::logic_error); - // Negative half length in z - BOOST_CHECK_THROW(CylinderBounds(radius, -halfz, halfphi, averagePhi), + /// Negative half length in z + BOOST_CHECK_THROW(CylinderBounds(radius, -halfZ, halfPhi, averagePhi), std::logic_error); - // Negative half sector in phi - BOOST_CHECK_THROW(CylinderBounds(radius, halfz, -halfphi, averagePhi), + /// Negative half sector in phi + BOOST_CHECK_THROW(CylinderBounds(radius, halfZ, -halfPhi, averagePhi), std::logic_error); - // Half sector in phi out of bounds - BOOST_CHECK_THROW(CylinderBounds(radius, halfz, 4., averagePhi), + /// Half sector in phi out of bounds + BOOST_CHECK_THROW(CylinderBounds(radius, halfZ, 4., averagePhi), std::logic_error); - // Phi position out of bounds - BOOST_CHECK_THROW(CylinderBounds(radius, halfz, halfphi, 4.), + /// Phi position out of bounds + BOOST_CHECK_THROW(CylinderBounds(radius, halfZ, halfPhi, 4.), std::logic_error); } /// Unit tests for CylinderBounds properties BOOST_AUTO_TEST_CASE(CylinderBoundsProperties) { - // CylinderBounds object of radius 0.5 and halfz 20 - double nominalRadius{0.5}; - double nominalHalfLength{20.}; - double halfphi(M_PI / 4.0); - double averagePhi(0.0); - double bevelMinZ(M_PI / 4); - double bevelMaxZ(M_PI / 6); - CylinderBounds cylinderBoundsObject(nominalRadius, nominalHalfLength); - CylinderBounds cylinderBoundsSegment(nominalRadius, nominalHalfLength, - halfphi, averagePhi); - CylinderBounds cylinderBoundsBeveledObject(nominalRadius, nominalHalfLength, - M_PI, 0., bevelMinZ, bevelMaxZ); - - /// test for type() + // CylinderBounds object of radius 0.5 and halfZ 20 + const double radius = 0.5; + const double halfZ = 20.; // != 10. + const double halfPhi = std::numbers::pi / 4.; // != pi/2 + const double averagePhi = 0.; // != pi/2 + const double bevelMinZ = std::numbers::pi / 4.; // != -pi/4 + const double bevelMaxZ = std::numbers::pi / 6.; + + CylinderBounds cylinderBoundsObject(radius, halfZ); + CylinderBounds cylinderBoundsSegment(radius, halfZ, halfPhi, averagePhi); + CylinderBounds cylinderBoundsBeveledObject(radius, halfZ, std::numbers::pi, + 0., bevelMinZ, bevelMaxZ); + + /// Test for type() BOOST_CHECK_EQUAL(cylinderBoundsObject.type(), SurfaceBounds::eCylinder); - /// test for inside(), 2D coords are r or phi ,z? : needs clarification + /// Test for inside(), 2D coords are r or phi ,z? : needs clarification const Vector2 origin{0., 0.}; - const Vector2 atPiBy2{M_PI / 2., 0.0}; - const Vector2 atPi{M_PI, 0.0}; - const Vector2 beyondEnd{0, 30.0}; - const Vector2 unitZ{0.0, 1.0}; - const Vector2 unitPhi{1.0, 0.0}; + const Vector2 atPiBy2{std::numbers::pi / 2., 0.}; + const Vector2 atPi{std::numbers::pi, 0.}; + const Vector2 beyondEnd{0, 30.}; + const Vector2 unitZ{0., 1.}; + const Vector2 unitPhi{1., 0.}; const Vector2 withinBevelMin{0.5, -20.012}; const Vector2 outsideBevelMin{0.5, -40.}; const BoundaryTolerance tolerance = BoundaryTolerance::AbsoluteBound(0.1, 0.1); const BoundaryTolerance lessTolerance = BoundaryTolerance::AbsoluteBound(0.01, 0.01); + BOOST_CHECK(cylinderBoundsObject.inside(atPiBy2, tolerance)); BOOST_CHECK(!cylinderBoundsSegment.inside(unitPhi, tolerance)); BOOST_CHECK(cylinderBoundsObject.inside(origin, tolerance)); @@ -127,44 +140,46 @@ BOOST_AUTO_TEST_CASE(CylinderBoundsProperties) { BOOST_CHECK( !cylinderBoundsBeveledObject.inside(outsideBevelMin, lessTolerance)); - /// test for r() - CHECK_CLOSE_REL(cylinderBoundsObject.get(CylinderBounds::eR), nominalRadius, - 1e-6); + /// Test for r() + CHECK_CLOSE_REL(cylinderBoundsObject.get(CylinderBounds::eR), radius, 1e-6); - /// test for averagePhi + /// Test for averagePhi CHECK_CLOSE_OR_SMALL(cylinderBoundsObject.get(CylinderBounds::eAveragePhi), averagePhi, 1e-6, 1e-6); - /// test for halfPhiSector + /// Test for halfPhiSector CHECK_CLOSE_REL(cylinderBoundsSegment.get(CylinderBounds::eHalfPhiSector), - halfphi, + halfPhi, 1e-6); // fail - /// test for halflengthZ (NOTE: Naming violation) - CHECK_CLOSE_REL(cylinderBoundsObject.get(CylinderBounds::eHalfLengthZ), - nominalHalfLength, 1e-6); + /// Test for halflengthZ (NOTE: Naming violation) + CHECK_CLOSE_REL(cylinderBoundsObject.get(CylinderBounds::eHalfLengthZ), halfZ, + 1e-6); - /// test for bevelMinZ/MaxZ + /// Test for bevelMinZ/MaxZ CHECK_CLOSE_REL(cylinderBoundsBeveledObject.get(CylinderBounds::eBevelMinZ), bevelMinZ, 1e-6); CHECK_CLOSE_REL(cylinderBoundsBeveledObject.get(CylinderBounds::eBevelMaxZ), bevelMaxZ, 1e-6); - /// test for dump - boost::test_tools::output_test_stream dumpOuput; - cylinderBoundsObject.toStream(dumpOuput); - BOOST_CHECK(dumpOuput.is_equal( + /// Test for dump + boost::test_tools::output_test_stream dumpOutput; + cylinderBoundsObject.toStream(dumpOutput); + BOOST_CHECK(dumpOutput.is_equal( "Acts::CylinderBounds: (radius, halfLengthZ, halfPhiSector, " "averagePhi, bevelMinZ, bevelMaxZ) = (0.5000000, 20.0000000, 3.1415927, " "0.0000000, 0.0000000, 0.0000000)")); } + /// Unit test for testing CylinderBounds assignment BOOST_AUTO_TEST_CASE(CylinderBoundsAssignment) { - double nominalRadius{0.5}; - double nominalHalfLength{20.}; - CylinderBounds cylinderBoundsObject(nominalRadius, nominalHalfLength); + const double radius = 0.5; + const double halfZ = 20.; // != 10. + + CylinderBounds cylinderBoundsObject(radius, halfZ); CylinderBounds assignedCylinderBounds(10.5, 6.6); assignedCylinderBounds = cylinderBoundsObject; + BOOST_CHECK_EQUAL(assignedCylinderBounds.get(CylinderBounds::eR), cylinderBoundsObject.get(CylinderBounds::eR)); BOOST_CHECK_EQUAL(assignedCylinderBounds, cylinderBoundsObject); diff --git a/Tests/UnitTests/Core/Surfaces/CylinderSurfaceTests.cpp b/Tests/UnitTests/Core/Surfaces/CylinderSurfaceTests.cpp index 1bc3b41db06..4dd6f7f6905 100644 --- a/Tests/UnitTests/Core/Surfaces/CylinderSurfaceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/CylinderSurfaceTests.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -54,16 +55,20 @@ GeometryContext testContext = GeometryContext(); BOOST_AUTO_TEST_SUITE(CylinderSurfaces) /// Unit test for creating compliant/non-compliant CylinderSurface object BOOST_AUTO_TEST_CASE(CylinderSurfaceConstruction) { - // CylinderSurface default constructor is deleted - // + /// Test default construction + // default construction is deleted + /// Constructor with transform, radius and halfZ - double radius(1.0), halfZ(10.), halfPhiSector(M_PI / 8.); - Translation3 translation{0., 1., 2.}; + const double radius = 1.; + const double halfZ = 10.; + const double halfPhiSector = std::numbers::pi / 8.; + const Translation3 translation{0., 1., 2.}; + auto pTransform = Transform3(translation); BOOST_CHECK_EQUAL( Surface::makeShared(pTransform, radius, halfZ)->type(), Surface::Cylinder); - // + /// Constructor with transform pointer, radius, halfZ and halfPhiSector BOOST_CHECK_EQUAL(Surface::makeShared(pTransform, radius, halfZ, halfPhiSector) @@ -75,8 +80,7 @@ BOOST_AUTO_TEST_CASE(CylinderSurfaceConstruction) { BOOST_CHECK_EQUAL( Surface::makeShared(pTransform, pCylinderBounds)->type(), Surface::Cylinder); - // - // + /// Copy constructor auto cylinderSurfaceObject = Surface::makeShared(pTransform, radius, halfZ); @@ -84,7 +88,7 @@ BOOST_AUTO_TEST_CASE(CylinderSurfaceConstruction) { Surface::makeShared(*cylinderSurfaceObject); BOOST_CHECK_EQUAL(copiedCylinderSurface->type(), Surface::Cylinder); BOOST_CHECK(*copiedCylinderSurface == *cylinderSurfaceObject); - // + /// Copied and transformed auto copiedTransformedCylinderSurface = Surface::makeShared( testContext, *cylinderSurfaceObject, pTransform); @@ -96,33 +100,35 @@ BOOST_AUTO_TEST_CASE(CylinderSurfaceConstruction) { Transform3::Identity(), nullptr), AssertionFailureException); } -// + /// Unit test for testing CylinderSurface properties BOOST_AUTO_TEST_CASE(CylinderSurfaceProperties) { /// Test clone method - double radius(1.0), halfZ(10.); - Translation3 translation{0., 1., 2.}; + const double radius = 1.; + const double halfZ = 10.; + const Translation3 translation{0., 1., 2.}; + auto pTransform = Transform3(translation); auto cylinderSurfaceObject = Surface::makeShared(pTransform, radius, halfZ); - // + /// Test type (redundant) BOOST_CHECK_EQUAL(cylinderSurfaceObject->type(), Surface::Cylinder); - // + /// Test binningPosition Vector3 binningPosition{0., 1., 2.}; CHECK_CLOSE_ABS( cylinderSurfaceObject->binningPosition(testContext, BinningValue::binPhi), binningPosition, 1e-9); - // + /// Test referenceFrame - double rootHalf = std::sqrt(0.5); - Vector3 globalPosition{rootHalf, 1. - rootHalf, 0.}; - Vector3 globalPositionZ{rootHalf, 1. - rootHalf, 2.0}; + const double invSqrt2 = 1. / std::numbers::sqrt2; + Vector3 globalPosition{invSqrt2, 1. - invSqrt2, 0.}; + Vector3 globalPositionZ{invSqrt2, 1. - invSqrt2, 2.}; Vector3 momentum{15., 15., 15.}; Vector3 momentum2{6.6, -3., 2.}; RotationMatrix3 expectedFrame; - expectedFrame << rootHalf, 0., rootHalf, rootHalf, 0., -rootHalf, 0., 1., 0.; + expectedFrame << invSqrt2, 0., invSqrt2, invSqrt2, 0., -invSqrt2, 0., 1., 0.; // check without shift CHECK_CLOSE_OR_SMALL(cylinderSurfaceObject->referenceFrame( testContext, globalPosition, momentum), @@ -131,53 +137,52 @@ BOOST_AUTO_TEST_CASE(CylinderSurfaceProperties) { CHECK_CLOSE_OR_SMALL(cylinderSurfaceObject->referenceFrame( testContext, globalPositionZ, momentum2), expectedFrame, 1e-6, 1e-9); - // + /// Test normal, given 3D position Vector3 origin{0., 0., 0.}; Vector3 normal3D = {0., -1., 0.}; CHECK_CLOSE_ABS(cylinderSurfaceObject->normal(testContext, origin), normal3D, 1e-9); - Vector3 pos45deg = {rootHalf, 1 + rootHalf, 0.}; - Vector3 pos45degZ = {rootHalf, 1 + rootHalf, 4.}; - Vector3 normal45deg = {rootHalf, rootHalf, 0.}; + Vector3 pos45deg = {invSqrt2, 1 + invSqrt2, 0.}; + Vector3 pos45degZ = {invSqrt2, 1 + invSqrt2, 4.}; + Vector3 normal45deg = {invSqrt2, invSqrt2, 0.}; // test the normal vector CHECK_CLOSE_ABS(cylinderSurfaceObject->normal(testContext, pos45deg), - normal45deg, 1e-6 * rootHalf); + normal45deg, 1e-6 * invSqrt2); // test that the normal vector is independent of z coordinate CHECK_CLOSE_ABS(cylinderSurfaceObject->normal(testContext, pos45degZ), - normal45deg, 1e-6 * rootHalf); - // + normal45deg, 1e-6 * invSqrt2); + /// Test normal given 2D rphi position - Vector2 positionPiBy2(1.0, 0.); + Vector2 positionPiBy2(1., 0.); Vector3 normalAtPiBy2{std::cos(1.), std::sin(1.), 0.}; CHECK_CLOSE_ABS(cylinderSurfaceObject->normal(testContext, positionPiBy2), normalAtPiBy2, 1e-9); - // /// Test rotational symmetry axis Vector3 symmetryAxis{0., 0., 1.}; CHECK_CLOSE_ABS(cylinderSurfaceObject->rotSymmetryAxis(testContext), symmetryAxis, 1e-9); - // + /// Test bounds BOOST_CHECK_EQUAL(cylinderSurfaceObject->bounds().type(), SurfaceBounds::eCylinder); - // + /// Test localToGlobal Vector2 localPosition{0., 0.}; globalPosition = cylinderSurfaceObject->localToGlobal( testContext, localPosition, momentum); Vector3 expectedPosition{1, 1, 2}; BOOST_CHECK_EQUAL(globalPosition, expectedPosition); - // + /// Testing globalToLocal localPosition = cylinderSurfaceObject ->globalToLocal(testContext, globalPosition, momentum) .value(); Vector2 expectedLocalPosition{0., 0.}; BOOST_CHECK_EQUAL(localPosition, expectedLocalPosition); - // + /// Test isOnSurface Vector3 offSurface{100, 1, 2}; BOOST_CHECK(cylinderSurfaceObject->isOnSurface( @@ -188,8 +193,8 @@ BOOST_AUTO_TEST_CASE(CylinderSurfaceProperties) { testContext, offSurface, momentum, BoundaryTolerance::None())); BOOST_CHECK(!cylinderSurfaceObject->isOnSurface(testContext, offSurface, BoundaryTolerance::None())); - // - /// intersection test + + /// Intersection test Vector3 direction{-1., 0, 0}; auto sfIntersection = cylinderSurfaceObject->intersect( testContext, offSurface, direction, BoundaryTolerance::Infinite()); @@ -208,16 +213,15 @@ BOOST_AUTO_TEST_CASE(CylinderSurfaceProperties) { BOOST_CHECK_LT(std::abs(pn), std::abs(pa)); BOOST_CHECK_EQUAL(sfIntersection.object(), cylinderSurfaceObject.get()); - // /// Test pathCorrection CHECK_CLOSE_REL(cylinderSurfaceObject->pathCorrection(testContext, offSurface, momentum.normalized()), - std::sqrt(3.), 0.01); - // + std::numbers::sqrt3, 0.01); + /// Test name BOOST_CHECK_EQUAL(cylinderSurfaceObject->name(), std::string("Acts::CylinderSurface")); - // + /// Test dump boost::test_tools::output_test_stream dumpOutput; std::string expected = @@ -232,18 +236,20 @@ BOOST_AUTO_TEST_CASE(CylinderSurfaceProperties) { } BOOST_AUTO_TEST_CASE(CylinderSurfaceEqualityOperators) { - double radius(1.0), halfZ(10.); - Translation3 translation{0., 1., 2.}; + const double radius = 1.; + const double halfZ = 10.; + const Translation3 translation{0., 1., 2.}; + auto pTransform = Transform3(translation); auto cylinderSurfaceObject = Surface::makeShared(pTransform, radius, halfZ); - // + auto cylinderSurfaceObject2 = Surface::makeShared(pTransform, radius, halfZ); - // + /// Test equality operator BOOST_CHECK(*cylinderSurfaceObject == *cylinderSurfaceObject2); - // + BOOST_TEST_CHECKPOINT( "Create and then assign a CylinderSurface object to the existing one"); /// Test assignment @@ -257,8 +263,10 @@ BOOST_AUTO_TEST_CASE(CylinderSurfaceEqualityOperators) { /// Unit test for testing CylinderSurface properties BOOST_AUTO_TEST_CASE(CylinderSurfaceExtent) { // Some radius and half length - double radius(1.0), halfZ(10.); - Translation3 translation{0., 0., 2.}; + const double radius = 1.; + const double halfZ = 10.; + const Translation3 translation{0., 0., 2.}; // != {0., 1., 2.} + auto pTransform = Transform3(translation); auto cylinderSurface = Surface::makeShared(pTransform, radius, halfZ); @@ -286,8 +294,10 @@ BOOST_AUTO_TEST_CASE(CylinderSurfaceExtent) { /// Unit test for testing CylinderSurface alignment derivatives BOOST_AUTO_TEST_CASE(CylinderSurfaceAlignment) { - double radius(1.0), halfZ(10.); - Translation3 translation{0., 1., 2.}; + const double radius = 1.; + const double halfZ = 10.; + const Translation3 translation{0., 1., 2.}; + auto pTransform = Transform3(translation); auto cylinderSurfaceObject = Surface::makeShared(pTransform, radius, halfZ); @@ -322,8 +332,8 @@ BOOST_AUTO_TEST_CASE(CylinderSurfaceBinningPosition) { double halfZ = 330; double averagePhi = 0.1; - auto bounds = - std::make_shared(r, halfZ, M_PI / 8, averagePhi); + auto bounds = std::make_shared(r, halfZ, std::numbers::pi / 8, + averagePhi); auto cylinder = Acts::Surface::makeShared(trf, bounds); Vector3 exp = Vector3{r * std::cos(averagePhi), r * std::sin(averagePhi), 0}; @@ -409,15 +419,15 @@ BOOST_DATA_TEST_CASE(IncompatibleZDirection, // Cylinder with bevel auto cyl4 = Surface::makeShared( - base * Translation3{Vector3::UnitZ() * 200_mm}, 30_mm, 100_mm, M_PI, 0, - M_PI / 8.0); + base * Translation3{Vector3::UnitZ() * 200_mm}, 30_mm, 100_mm, + std::numbers::pi, 0, std::numbers::pi / 8.); BOOST_CHECK_THROW( cyl->mergedWith(*cyl4, Acts::BinningValue::binZ, false, *logger), SurfaceMergingException); auto cyl5 = Surface::makeShared( - base * Translation3{Vector3::UnitZ() * 200_mm}, 30_mm, 100_mm, M_PI, 0, 0, - M_PI / 8.0); + base * Translation3{Vector3::UnitZ() * 200_mm}, 30_mm, 100_mm, + std::numbers::pi, 0, 0, std::numbers::pi / 8.); BOOST_CHECK_THROW( cyl->mergedWith(*cyl5, Acts::BinningValue::binZ, false, *logger), SurfaceMergingException); @@ -605,7 +615,7 @@ BOOST_DATA_TEST_CASE(RPhiDirection, BOOST_CHECK_SMALL( detail::difference_periodic(bounds.get(CylinderBounds::eAveragePhi), - a(85_degree), 2 * M_PI), + a(85_degree), 2 * std::numbers::pi), 1e-6); BOOST_CHECK_CLOSE(bounds.get(CylinderBounds::eHalfPhiSector), 55_degree, 0.1); @@ -629,7 +639,7 @@ BOOST_DATA_TEST_CASE(RPhiDirection, BOOST_CHECK_SMALL(detail::difference_periodic( cyl45->bounds().get(CylinderBounds::eAveragePhi), - a(180_degree), 2 * M_PI), + a(180_degree), 2 * std::numbers::pi), 1e-6); BOOST_CHECK_CLOSE(cyl45->bounds().get(CylinderBounds::eHalfPhiSector), 30_degree, 1e-6); @@ -656,7 +666,7 @@ BOOST_DATA_TEST_CASE(RPhiDirection, BOOST_CHECK_SMALL(detail::difference_periodic( cyl67->bounds().get(CylinderBounds::eAveragePhi), - a(180_degree), 2 * M_PI), + a(180_degree), 2 * std::numbers::pi), 1e-6); BOOST_CHECK_CLOSE(cyl67->bounds().get(CylinderBounds::eHalfPhiSector), 180_degree, 1e-6); diff --git a/Tests/UnitTests/Core/Surfaces/DiamondBoundsTests.cpp b/Tests/UnitTests/Core/Surfaces/DiamondBoundsTests.cpp index ecd5909f932..1869cde057d 100644 --- a/Tests/UnitTests/Core/Surfaces/DiamondBoundsTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/DiamondBoundsTests.cpp @@ -24,22 +24,26 @@ namespace Acts::Test { BOOST_AUTO_TEST_SUITE(Surfaces) /// Unit test for creating compliant/non-compliant DiamondBounds object BOOST_AUTO_TEST_CASE(DiamondBoundsConstruction) { - double minHalfX(10.), midHalfX(20.), maxHalfX(15.), halfY1(5.), halfY2(7.); - // test default construction - // DiamondBounds defaultConstructedDiamondBounds; //deleted - // + /// Test default construction + // default construction is deleted + + const double minHalfX = 10.; + const double midHalfX = 20.; + const double maxHalfX = 15.; + const double halfY1 = 5.; + const double halfY2 = 7.; + /// Test construction with dimensions - // DiamondBounds d(minHalfX, midHalfX, maxHalfX, halfY1, halfY2); BOOST_CHECK_EQUAL( DiamondBounds(minHalfX, midHalfX, maxHalfX, halfY1, halfY2).type(), SurfaceBounds::eDiamond); - // + /// Copy constructor DiamondBounds original(minHalfX, midHalfX, maxHalfX, halfY1, halfY2); DiamondBounds copied(original); BOOST_CHECK_EQUAL(copied.type(), SurfaceBounds::eDiamond); - // invalid inputs + /// Test invalid inputs BOOST_CHECK_THROW( DiamondBounds db(midHalfX, minHalfX, maxHalfX, halfY1, halfY2), std::logic_error); @@ -47,66 +51,66 @@ BOOST_AUTO_TEST_CASE(DiamondBoundsConstruction) { DiamondBounds db(minHalfX, maxHalfX, midHalfX, halfY1, halfY2), std::logic_error); } + /// Unit tests for DiamondBounds properties BOOST_AUTO_TEST_CASE(DiamondBoundsProperties) { - double minHalfX(10.), midHalfX(50.), maxHalfX(30.), halfY1(10.), halfY2(20.); + const double minHalfX = 10.; + const double midHalfX = 50.; // != 20. + const double maxHalfX = 30.; // != 15. + const double halfY1 = 10.; // != 5. + const double halfY2 = 20.; // != 7. + /// Test clone DiamondBounds diamondBoundsObject(minHalfX, midHalfX, maxHalfX, halfY1, halfY2); - // + /// Test type() (redundant; already used in constructor confirmation) BOOST_CHECK_EQUAL(diamondBoundsObject.type(), SurfaceBounds::eDiamond); - // //redundant test - // + /// Test the half length at negative y BOOST_CHECK_EQUAL(diamondBoundsObject.get(DiamondBounds::eHalfLengthXnegY), minHalfX); - // + /// Test the half length at the x axis BOOST_CHECK_EQUAL(diamondBoundsObject.get(DiamondBounds::eHalfLengthXzeroY), midHalfX); - // + /// Test the half length at positive y BOOST_CHECK_EQUAL(diamondBoundsObject.get(DiamondBounds::eHalfLengthXposY), maxHalfX); - // + /// Test half length into the negative side BOOST_CHECK_EQUAL(diamondBoundsObject.get(DiamondBounds::eHalfLengthYneg), halfY1); - // + /// Test half length into the positive side BOOST_CHECK_EQUAL(diamondBoundsObject.get(DiamondBounds::eHalfLengthYpos), halfY2); - // + /// Test boundingBox BOOST_CHECK_EQUAL(diamondBoundsObject.boundingBox(), RectangleBounds(Vector2{-50., -10.}, Vector2{50., 20.})); - // - // clone already tested - // + /// Test distanceToBoundary Vector2 origin(0., 0.); Vector2 outsideBy10(0., 30.); Vector2 inRectangle(15., 0.); /// Test dump - // Acts::DiamondBounds: (minHlengthX, medHlengthX, maxHlengthX, hlengthY1, - // hlengthY2 ) = (30.0000000, 10.0000000, 50.0000000, 10.0000000, - // 20.0000000) diamondBoundsObject.toStream(std::cout); - boost::test_tools::output_test_stream dumpOuput; - diamondBoundsObject.toStream(dumpOuput); + boost::test_tools::output_test_stream dumpOutput; + diamondBoundsObject.toStream(dumpOutput); BOOST_CHECK( - dumpOuput.is_equal("Acts::DiamondBounds: (halfXatYneg, halfXatYzero, " - "halfXatYpos, halfYneg, halfYpos) = (10.0000000, " - "50.0000000, 30.0000000, 10.0000000, 20.0000000)")); - // + dumpOutput.is_equal("Acts::DiamondBounds: (halfXatYneg, halfXatYzero, " + "halfXatYpos, halfYneg, halfYpos) = (10.0000000, " + "50.0000000, 30.0000000, 10.0000000, 20.0000000)")); + /// Test inside BOOST_CHECK(diamondBoundsObject.inside(origin, BoundaryTolerance::None())); // dont understand why this is so: BOOST_CHECK( !diamondBoundsObject.inside(outsideBy10, BoundaryTolerance::None())); - // + /// Test vertices (does this need to be implemented in this class?? // auto v=diamondBoundsObject.vertices(); std::vector referenceVertices{ @@ -117,20 +121,28 @@ BOOST_AUTO_TEST_CASE(DiamondBoundsProperties) { referenceVertices.cbegin(), referenceVertices.cend()); } + /// Unit test for testing DiamondBounds assignment BOOST_AUTO_TEST_CASE(DiamondBoundsAssignment) { - double minHalfX(10.), midHalfX(20.), maxHalfX(15.), halfY1(5.), halfY2(7.); + const double minHalfX = 10.; + const double midHalfX = 20.; + const double maxHalfX = 15.; + const double halfY1 = 5.; + const double halfY2 = 7.; + DiamondBounds diamondBoundsObject(minHalfX, midHalfX, maxHalfX, halfY1, halfY2); DiamondBounds similarlyConstructeDiamondBoundsObject( minHalfX, midHalfX, maxHalfX, halfY1, halfY2); + /// Test operator == BOOST_CHECK_EQUAL(diamondBoundsObject, similarlyConstructeDiamondBoundsObject); - // + /// Test assignment DiamondBounds assignedDiamondBoundsObject( 2 * minHalfX, 2 * midHalfX, 2 * maxHalfX, 2 * halfY1, 2 * halfY2); + // object, in some sense assignedDiamondBoundsObject = diamondBoundsObject; BOOST_CHECK_EQUAL(assignedDiamondBoundsObject, diamondBoundsObject); diff --git a/Tests/UnitTests/Core/Surfaces/DiscSurfaceTests.cpp b/Tests/UnitTests/Core/Surfaces/DiscSurfaceTests.cpp index 3012f71217e..b5d1eec5f43 100644 --- a/Tests/UnitTests/Core/Surfaces/DiscSurfaceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/DiscSurfaceTests.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -53,30 +54,32 @@ auto logger = Acts::getDefaultLogger("UnitTests", Acts::Logging::VERBOSE); BOOST_AUTO_TEST_SUITE(Surfaces) /// Unit tests for creating DiscSurface object BOOST_AUTO_TEST_CASE(DiscSurfaceConstruction) { - // default constructor is deleted - // scaffolding... - double rMin(1.0), rMax(5.0), halfPhiSector(M_PI / 8.); - // + /// Test default construction + // default construction is deleted + + const double rMin = 1.; + const double rMax = 5.; + const double halfPhiSector = std::numbers::pi / 8.; + /// Test DiscSurface constructor with default halfPhiSector BOOST_CHECK_NO_THROW( Surface::makeShared(Transform3::Identity(), rMin, rMax)); - // + /// Test DiscSurface constructor with a transform specified Translation3 translation{0., 1., 2.}; auto pTransform = Transform3(translation); BOOST_CHECK_NO_THROW( Surface::makeShared(pTransform, rMin, rMax, halfPhiSector)); - // + /// Copy constructed DiscSurface auto anotherDiscSurface = Surface::makeShared(pTransform, rMin, rMax, halfPhiSector); // N.B. Just using // BOOST_CHECK_NO_THROW(Surface::makeShared(anotherDiscSurface)) - // tries to call - // the (deleted) default constructor. + // tries to call the (deleted) default constructor. auto copiedSurface = Surface::makeShared(*anotherDiscSurface); BOOST_TEST_MESSAGE("Copy constructed DiscSurface ok"); - // + /// Copied and transformed DiscSurface BOOST_CHECK_NO_THROW(Surface::makeShared( tgContext, *anotherDiscSurface, pTransform)); @@ -90,67 +93,66 @@ BOOST_AUTO_TEST_CASE(DiscSurfaceConstruction) { /// Unit tests of all named methods BOOST_AUTO_TEST_CASE(DiscSurfaceProperties) { - Vector3 origin3D{0, 0, 0}; - double rMin(1.0), rMax(5.0), halfPhiSector(M_PI / 8.); + const double rMin = 1.; + const double rMax = 5.; + const double halfPhiSector = std::numbers::pi / 8.; + + const Vector3 origin3D{0, 0, 0}; + auto discSurfaceObject = Surface::makeShared( Transform3::Identity(), rMin, rMax, halfPhiSector); - // + /// Test type BOOST_CHECK_EQUAL(discSurfaceObject->type(), Surface::Disc); - // + /// Test normal, no local position specified Vector3 zAxis{0, 0, 1}; BOOST_CHECK_EQUAL(discSurfaceObject->normal(tgContext), zAxis); - // + /// Test normal, local position specified - Vector2 lpos(2.0, 0.05); + Vector2 lpos(2., 0.05); BOOST_CHECK_EQUAL(discSurfaceObject->normal(tgContext, lpos), zAxis); - // + /// Test binningPosition - // auto binningPosition= - // discSurfaceObject.binningPosition(BinningValue::BinningValue::binRPhi ); - // std::cout<binningPosition(tgContext, BinningValue::binRPhi), origin3D); - // + /// Test bounds BOOST_CHECK_EQUAL(discSurfaceObject->bounds().type(), SurfaceBounds::eDisc); - // + Vector3 ignoredMomentum{0., 0., 0.}; /// Test isOnSurface() - Vector3 point3DNotInSector{0.0, 1.2, 0}; - Vector3 point3DOnSurface{1.2, 0.0, 0}; - BOOST_CHECK(!discSurfaceObject->isOnSurface( - tgContext, point3DNotInSector, ignoredMomentum, - BoundaryTolerance::None())); // passes - BOOST_CHECK( - !discSurfaceObject->isOnSurface(tgContext, point3DNotInSector, - BoundaryTolerance::None())); // passes + Vector3 point3DNotInSector{0., 1.2, 0}; + Vector3 point3DOnSurface{1.2, 0., 0}; + BOOST_CHECK(!discSurfaceObject->isOnSurface(tgContext, point3DNotInSector, + ignoredMomentum, + BoundaryTolerance::None())); + BOOST_CHECK(!discSurfaceObject->isOnSurface(tgContext, point3DNotInSector, + BoundaryTolerance::None())); BOOST_CHECK(discSurfaceObject->isOnSurface( - tgContext, point3DOnSurface, ignoredMomentum, - BoundaryTolerance::None())); // passes - BOOST_CHECK( - discSurfaceObject->isOnSurface(tgContext, point3DOnSurface, - BoundaryTolerance::None())); // passes - // + tgContext, point3DOnSurface, ignoredMomentum, BoundaryTolerance::None())); + BOOST_CHECK(discSurfaceObject->isOnSurface(tgContext, point3DOnSurface, + BoundaryTolerance::None())); + /// Test localToGlobal Vector3 returnedPosition{10.9, 8.7, 6.5}; Vector3 expectedPosition{1.2, 0, 0}; - Vector2 rPhiOnDisc{1.2, 0.0}; - Vector2 rPhiNotInSector{1.2, M_PI}; // outside sector at Phi=0, +/- pi/8 + Vector2 rPhiOnDisc{1.2, 0.}; + Vector2 rPhiNotInSector{ + 1.2, std::numbers::pi}; // outside sector at Phi=0, +/- pi/8 returnedPosition = discSurfaceObject->localToGlobal(tgContext, rPhiOnDisc, ignoredMomentum); CHECK_CLOSE_ABS(returnedPosition, expectedPosition, 1e-6); - // + returnedPosition = discSurfaceObject->localToGlobal( tgContext, rPhiNotInSector, ignoredMomentum); Vector3 expectedNonPosition{-1.2, 0, 0}; CHECK_CLOSE_ABS(returnedPosition, expectedNonPosition, 1e-6); - // + /// Test globalToLocal Vector2 returnedLocalPosition{33., 44.}; - Vector2 expectedLocalPosition{1.2, 0.0}; + Vector2 expectedLocalPosition{1.2, 0.}; returnedLocalPosition = discSurfaceObject ->globalToLocal(tgContext, point3DOnSurface, ignoredMomentum) @@ -162,51 +164,51 @@ BOOST_AUTO_TEST_CASE(DiscSurfaceProperties) { discSurfaceObject ->globalToLocal(tgContext, point3DNotInSector, ignoredMomentum) .value(); - // - Vector3 pointOutsideR{0.0, 100., 0}; + + Vector3 pointOutsideR{0., 100., 0}; returnedLocalPosition = discSurfaceObject ->globalToLocal(tgContext, pointOutsideR, ignoredMomentum) .value(); - // + /// Test localPolarToCartesian - Vector2 rPhi1_1{std::sqrt(2.), M_PI / 4.}; + Vector2 rPhi1_1{std::numbers::sqrt2, std::numbers::pi / 4.}; Vector2 cartesian1_1{1., 1.}; CHECK_CLOSE_REL(discSurfaceObject->localPolarToCartesian(rPhi1_1), cartesian1_1, 1e-6); - // + /// Test localCartesianToPolar CHECK_CLOSE_REL(discSurfaceObject->localCartesianToPolar(cartesian1_1), rPhi1_1, 1e-6); - // + /// Test localPolarToLocalCartesian CHECK_CLOSE_REL(discSurfaceObject->localPolarToLocalCartesian(rPhi1_1), cartesian1_1, 1e-6); - // + /// Test localCartesianToGlobal Vector3 cartesian3D1_1{1., 1., 0.}; CHECK_CLOSE_ABS( discSurfaceObject->localCartesianToGlobal(tgContext, cartesian1_1), cartesian3D1_1, 1e-6); - // + /// Test globalToLocalCartesian CHECK_CLOSE_REL( discSurfaceObject->globalToLocalCartesian(tgContext, cartesian3D1_1), cartesian1_1, 1e-6); - // + /// Test pathCorrection - double projected3DMomentum = std::sqrt(3.) * 1.e6; + double projected3DMomentum = std::numbers::sqrt3 * 1.e6; Vector3 momentum{projected3DMomentum, projected3DMomentum, projected3DMomentum}; Vector3 ignoredPosition = discSurfaceObject->center(tgContext); CHECK_CLOSE_REL(discSurfaceObject->pathCorrection(tgContext, ignoredPosition, momentum.normalized()), - std::sqrt(3), 0.01); - // + std::numbers::sqrt3, 0.01); + /// intersection test - Vector3 globalPosition{1.2, 0.0, -10.}; + Vector3 globalPosition{1.2, 0., -10.}; Vector3 direction{0., 0., 1.}; // must be normalised - Vector3 expected{1.2, 0.0, 0.0}; + Vector3 expected{1.2, 0., 0.}; // intersect is a struct of (Vector3) position, pathLength, distance and // (bool) valid, it's contained in a Surface intersection @@ -223,29 +225,31 @@ BOOST_AUTO_TEST_CASE(DiscSurfaceProperties) { 1e-9); BOOST_CHECK_EQUAL(sfIntersection.object(), discSurfaceObject.get()); - // /// Test name boost::test_tools::output_test_stream nameOuput; nameOuput << discSurfaceObject->name(); BOOST_CHECK(nameOuput.is_equal("Acts::DiscSurface")); } -// + /// Unit test for testing DiscSurface assignment and equality BOOST_AUTO_TEST_CASE(DiscSurfaceAssignment) { - Vector3 origin3D{0, 0, 0}; - double rMin(1.0), rMax(5.0), halfPhiSector(M_PI / 8.); + const double rMin = 1.; + const double rMax = 5.; + const double halfPhiSector = std::numbers::pi / 8.; + auto discSurfaceObject = Surface::makeShared( Transform3::Identity(), rMin, rMax, halfPhiSector); auto assignedDisc = Surface::makeShared(Transform3::Identity(), 2.2, 4.4, 0.07); - // + BOOST_CHECK_NO_THROW(*assignedDisc = *discSurfaceObject); BOOST_CHECK((*assignedDisc) == (*discSurfaceObject)); } /// Unit test for testing DiscSurface assignment and equality BOOST_AUTO_TEST_CASE(DiscSurfaceExtent) { - double rMin(1.0), rMax(5.0); + const double rMin = 1.; + const double rMax = 5.; auto pDisc = Surface::makeShared(Transform3::Identity(), 0., rMax); @@ -267,9 +271,9 @@ BOOST_AUTO_TEST_CASE(DiscSurfaceExtent) { s_onSurfaceTolerance); CHECK_CLOSE_ABS(rMax, pDiscExtent.max(BinningValue::binY), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(-M_PI, pDiscExtent.min(BinningValue::binPhi), + CHECK_CLOSE_ABS(-std::numbers::pi, pDiscExtent.min(BinningValue::binPhi), s_onSurfaceTolerance); - CHECK_CLOSE_ABS(M_PI, pDiscExtent.max(BinningValue::binPhi), + CHECK_CLOSE_ABS(std::numbers::pi, pDiscExtent.max(BinningValue::binPhi), s_onSurfaceTolerance); auto pRing = @@ -298,7 +302,10 @@ BOOST_AUTO_TEST_CASE(DiscSurfaceExtent) { BOOST_AUTO_TEST_CASE(DiscSurfaceAlignment) { Translation3 translation{0., 1., 2.}; Transform3 transform(translation); - double rMin(1.0), rMax(5.0), halfPhiSector(M_PI / 8.); + const double rMin = 1.; + const double rMax = 5.; + const double halfPhiSector = std::numbers::pi / 8.; + auto discSurfaceObject = Surface::makeShared(transform, rMin, rMax, halfPhiSector); @@ -330,7 +337,7 @@ BOOST_AUTO_TEST_CASE(DiscSurfaceAlignment) { globalPosition); // Check if the result is as expected ActsMatrix<2, 3> expLoc3DToLocBound = ActsMatrix<2, 3>::Zero(); - expLoc3DToLocBound << 0, 1, 0, -1.0 / 3, 0, 0; + expLoc3DToLocBound << 0, 1, 0, -1. / 3, 0, 0; CHECK_CLOSE_ABS(loc3DToLocBound, expLoc3DToLocBound, 1e-10); } @@ -345,7 +352,8 @@ BOOST_AUTO_TEST_CASE(DiscSurfaceBinningPosition) { { // Radial Bounds - auto bounds = std::make_shared(minR, maxR, M_PI / 8, 0.1); + auto bounds = + std::make_shared(minR, maxR, std::numbers::pi / 8, 0.1); auto disc = Acts::Surface::makeShared(trf, bounds); Vector3 bp = disc->binningPosition(tgContext, BinningValue::binR); @@ -409,11 +417,12 @@ BOOST_AUTO_TEST_CASE(DiscSurfaceBinningPosition) { BOOST_AUTO_TEST_SUITE(DiscSurfaceMerging) namespace { -std::shared_ptr makeDisc(const Transform3& transform, double rmin, - double rmax, double halfPhi = M_PI, +std::shared_ptr makeDisc(const Transform3& transform, double rMin, + double rMax, + double halfPhi = std::numbers::pi, double avgPhi = 0) { return Surface::makeShared( - transform, std::make_shared(rmin, rmax, halfPhi, avgPhi)); + transform, std::make_shared(rMin, rMax, halfPhi, avgPhi)); } } // namespace @@ -657,7 +666,7 @@ BOOST_DATA_TEST_CASE(PhiDirection, BOOST_CHECK_SMALL( detail::difference_periodic(bounds->get(RadialBounds::eAveragePhi), - a(85_degree), 2 * M_PI), + a(85_degree), 2 * std::numbers::pi), 1e-6); BOOST_CHECK_CLOSE(bounds->get(RadialBounds::eHalfPhiSector), 55_degree, 1e-6); @@ -682,7 +691,7 @@ BOOST_DATA_TEST_CASE(PhiDirection, BOOST_CHECK_SMALL( detail::difference_periodic(bounds45->get(RadialBounds::eAveragePhi), - a(180_degree), 2 * M_PI), + a(180_degree), 2 * std::numbers::pi), 1e-6); BOOST_CHECK_CLOSE(bounds45->get(RadialBounds::eHalfPhiSector), 30_degree, 1e-6); @@ -714,7 +723,7 @@ BOOST_DATA_TEST_CASE(PhiDirection, BOOST_REQUIRE_NE(bounds67, nullptr); BOOST_CHECK_SMALL( detail::difference_periodic(bounds67->get(RadialBounds::eAveragePhi), - a(90_degree), 2 * M_PI), + a(90_degree), 2 * std::numbers::pi), 1e-6); BOOST_CHECK_CLOSE(bounds67->get(RadialBounds::eHalfPhiSector), 180_degree, 1e-6); @@ -798,8 +807,8 @@ BOOST_DATA_TEST_CASE(PhiDirection, // bounds should be equal however BOOST_CHECK_EQUAL(disc76->bounds(), disc67->bounds()); - BOOST_CHECK(!reversed76); // not reversed either because you get the - // ordering you put in + // not reversed either because you get the ordering you put in + BOOST_CHECK(!reversed76); const auto* bounds67 = dynamic_cast(&disc67->bounds()); BOOST_REQUIRE_NE(bounds67, nullptr); diff --git a/Tests/UnitTests/Core/Surfaces/DiscTrapezoidBoundsTests.cpp b/Tests/UnitTests/Core/Surfaces/DiscTrapezoidBoundsTests.cpp index 1515ef79292..8f6117ef1b0 100644 --- a/Tests/UnitTests/Core/Surfaces/DiscTrapezoidBoundsTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/DiscTrapezoidBoundsTests.cpp @@ -24,22 +24,26 @@ namespace Acts::Test { BOOST_AUTO_TEST_SUITE(Surfaces) -/// Unit tests for DiscTrapezoidBounds constrcuctors +const double minHalfX = 1.; +const double maxHalfX = 5.; +const double rMin = 2.; +const double rMax = 6.; +const double averagePhi = 0.; +const double stereo = 0.1; + +/// Unit tests for DiscTrapezoidBounds constructors BOOST_AUTO_TEST_CASE(DiscTrapezoidBoundsConstruction) { - double minHalfX(1.0), maxHalfX(5.0), rMin(2.0), rMax(6.0), averagePhi(0.0), - stereo(0.1); - // /// Test construction with dimensions and default stereo BOOST_CHECK_EQUAL( DiscTrapezoidBounds(minHalfX, maxHalfX, rMin, rMax, averagePhi).type(), SurfaceBounds::eDiscTrapezoid); - // + /// Test construction with all dimensions BOOST_CHECK_EQUAL( DiscTrapezoidBounds(minHalfX, maxHalfX, rMin, rMax, averagePhi, stereo) .type(), SurfaceBounds::eDiscTrapezoid); - // + /// Copy constructor DiscTrapezoidBounds original(minHalfX, maxHalfX, rMin, rMax, averagePhi); DiscTrapezoidBounds copied(original); @@ -48,9 +52,6 @@ BOOST_AUTO_TEST_CASE(DiscTrapezoidBoundsConstruction) { // Streaning and recreation test BOOST_AUTO_TEST_CASE(DiscTrapezoidBoundsRecreation) { - double minHalfX(1.0), maxHalfX(5.0), rMin(2.0), rMax(6.0), averagePhi(0.0), - stereo(0.1); - DiscTrapezoidBounds original(minHalfX, maxHalfX, rMin, rMax, averagePhi, stereo); auto valvector = original.values(); @@ -62,9 +63,6 @@ BOOST_AUTO_TEST_CASE(DiscTrapezoidBoundsRecreation) { // Unit tests for AnnulusBounds exception throwing BOOST_AUTO_TEST_CASE(DiscTrapezoidBoundsExceptions) { - double minHalfX(1.0), maxHalfX(5.0), rMin(2.0), rMax(6.0), averagePhi(0.0), - stereo(0.1); - // Exception for opening neg min half x < 0 BOOST_CHECK_THROW( DiscTrapezoidBounds(-minHalfX, maxHalfX, rMin, rMax, averagePhi, stereo), @@ -103,74 +101,72 @@ BOOST_AUTO_TEST_CASE(DiscTrapezoidBoundsExceptions) { /// Unit tests for DiscTrapezoidBounds properties BOOST_AUTO_TEST_CASE(DiscTrapezoidBoundsProperties) { - double minHalfX(1.0), maxHalfX(5.0), rMin(2.0), rMax(6.0), - averagePhi(0.0) /*, stereo(0.1)*/; /// Test clone DiscTrapezoidBounds DiscTrapezoidBoundsObject(minHalfX, maxHalfX, rMin, rMax, averagePhi); - // + /// Test type() (redundant; already used in constructor confirmation) BOOST_CHECK_EQUAL(DiscTrapezoidBoundsObject.type(), SurfaceBounds::eDiscTrapezoid); - // + /// Test distanceToBoundary Vector2 origin(0., 0.); Vector2 outside(30., 0.); - Vector2 inSurface(2.5, 0.0); - // + Vector2 inSurface(2.5, 0.); + /// Test dump - boost::test_tools::output_test_stream dumpOuput; - DiscTrapezoidBoundsObject.toStream(dumpOuput); - BOOST_CHECK(dumpOuput.is_equal( + boost::test_tools::output_test_stream dumpOutput; + DiscTrapezoidBoundsObject.toStream(dumpOutput); + BOOST_CHECK(dumpOutput.is_equal( "Acts::DiscTrapezoidBounds: (innerRadius, outerRadius, halfLengthXminR, " "halfLengthXmaxR, halfLengthY, halfPhiSector, averagePhi, rCenter, " "stereo) = " "(2.0000000, 6.0000000, 1.0000000, 5.0000000, 0.7922870, 0.9851108, " "0.0000000, 2.5243378, 0.0000000)")); - // + /// Test inside BOOST_CHECK( DiscTrapezoidBoundsObject.inside(inSurface, BoundaryTolerance::None())); BOOST_CHECK( !DiscTrapezoidBoundsObject.inside(outside, BoundaryTolerance::None())); - // + /// Test rMin CHECK_CLOSE_REL(DiscTrapezoidBoundsObject.rMin(), rMin, 1e-6); - // + /// Test rMax CHECK_CLOSE_REL(DiscTrapezoidBoundsObject.rMax(), rMax, 1e-6); - // + /// Test averagePhi CHECK_SMALL(DiscTrapezoidBoundsObject.get(DiscTrapezoidBounds::eAveragePhi), 1e-9); - // + /// Test rCenter (redundant; not configurable) CHECK_CLOSE_REL(DiscTrapezoidBoundsObject.rCenter(), 2.524337798, 1e-6); - // + /// Test halfPhiSector (redundant; not configurable) CHECK_SMALL(DiscTrapezoidBoundsObject.stereo(), 1e-6); - // - /// Test minHalflengthX + + /// Test minHalfLengthX CHECK_CLOSE_REL( DiscTrapezoidBoundsObject.get(DiscTrapezoidBounds::eHalfLengthXminR), minHalfX, 1e-6); - // - /// Test maxHalflengthX + + /// Test maxHalfLengthX CHECK_CLOSE_REL( DiscTrapezoidBoundsObject.get(DiscTrapezoidBounds::eHalfLengthXmaxR), maxHalfX, 1e-6); - // - /// Test halflengthY + + /// Test halfLengthY CHECK_CLOSE_REL(DiscTrapezoidBoundsObject.halfLengthY(), 0.792286991, 1e-6); } /// Unit test for testing DiscTrapezoidBounds assignment BOOST_AUTO_TEST_CASE(DiscTrapezoidBoundsAssignment) { - double minHalfX(1.0), maxHalfX(5.0), rMin(2.0), rMax(6.0), averagePhi(0.0), - stereo(0.1); DiscTrapezoidBounds DiscTrapezoidBoundsObject(minHalfX, maxHalfX, rMin, rMax, averagePhi, stereo); - // operator == not implemented in this class - // + + /// Test operator == + // not implemented in this class + /// Test assignment DiscTrapezoidBounds assignedDiscTrapezoidBoundsObject(2.1, 6.6, 3.4, 4.2, 0.3, 0.); diff --git a/Tests/UnitTests/Core/Surfaces/EllipseBoundsTests.cpp b/Tests/UnitTests/Core/Surfaces/EllipseBoundsTests.cpp index 7d7391428f3..0ed78e656f6 100644 --- a/Tests/UnitTests/Core/Surfaces/EllipseBoundsTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/EllipseBoundsTests.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -25,20 +26,25 @@ namespace Acts::Test { BOOST_AUTO_TEST_SUITE(Surfaces) +const double innerRx = 10.; +const double innerRy = 15.; +const double phiSector = std::numbers::pi / 2.; +const double averagePhi = 0.; + /// Unit test for creating compliant/non-compliant EllipseBounds object BOOST_AUTO_TEST_CASE(EllipseBoundsConstruction) { - double innerRx(10.), innerRy(15.), outerRx(25.), outerRy(30.), - phiSector(M_PI / 2.), averagePhi(0.); + const double outerRx = 25.; + const double outerRy = 30.; + + /// Test default construction + // default construction is deleted - // test default construction - // EllipseBounds defaultConstructedEllipseBounds; //deleted - // /// Test construction with dimensions BOOST_CHECK_EQUAL( EllipseBounds(innerRx, innerRy, outerRx, outerRy, phiSector, averagePhi) .type(), SurfaceBounds::eEllipse); - // + /// Copy constructor EllipseBounds original(innerRx, innerRy, outerRx, outerRy, phiSector, averagePhi); @@ -48,9 +54,9 @@ BOOST_AUTO_TEST_CASE(EllipseBoundsConstruction) { // Streaning and recreation test BOOST_AUTO_TEST_CASE(EllipseBoundsRecreation) { - double innerRx(10.), innerRy(15.), outerRx(25.), outerRy(30.), - phiSector(M_PI / 2.), averagePhi(0.); - // const bool symmetric(false); + const double outerRx = 25.; + const double outerRy = 30.; + EllipseBounds original(innerRx, innerRy, outerRx, outerRy, phiSector, averagePhi); auto valvector = original.values(); @@ -62,44 +68,54 @@ BOOST_AUTO_TEST_CASE(EllipseBoundsRecreation) { // Unit tests for AnnulusBounds exception throwing BOOST_AUTO_TEST_CASE(ConeBoundsExceptions) { - double innerRx(10.), innerRy(15.), outerRx(25.), outerRy(30.), - phiSector(M_PI / 2.), averagePhi(0.); + const double outerRx = 25.; + const double outerRy = 30.; + // Exception for innerRx < 0 BOOST_CHECK_THROW( EllipseBounds(-innerRx, innerRy, outerRx, outerRy, phiSector, averagePhi), std::logic_error); + // Exception for innerRy < 0 BOOST_CHECK_THROW( EllipseBounds(innerRx, -innerRy, outerRx, outerRy, phiSector, averagePhi), std::logic_error); + // Exception for innerRx < 0 and innerRy < 0 BOOST_CHECK_THROW(EllipseBounds(-innerRx, -innerRy, outerRx, outerRy, phiSector, averagePhi), std::logic_error); + // Exception for opening outerRx <= 0 BOOST_CHECK_THROW( EllipseBounds(innerRx, innerRy, 0., outerRy, phiSector, averagePhi), std::logic_error); + // Exception for opening outerRy <= 0 BOOST_CHECK_THROW( EllipseBounds(innerRx, innerRy, outerRx, 0., phiSector, averagePhi), std::logic_error); + // Exception for iouterRx < 0 and outerRy < 0 BOOST_CHECK_THROW(EllipseBounds(innerRx, innerRy, -outerRx, -outerRy, phiSector, averagePhi), std::logic_error); + // Exception for innerRx > outerRx BOOST_CHECK_THROW( EllipseBounds(outerRx, innerRy, innerRx, outerRy, phiSector, averagePhi), std::logic_error); + // Exception for innerRxy > outerRy BOOST_CHECK_THROW( EllipseBounds(innerRx, outerRy, outerRx, innerRy, phiSector, averagePhi), std::logic_error); + // Exception for negative phiSector BOOST_CHECK_THROW( EllipseBounds(innerRx, innerRy, outerRx, outerRy, -phiSector, averagePhi), std::logic_error); + // Exception for average phi out of bound BOOST_CHECK_THROW( EllipseBounds(innerRx, innerRy, outerRx, outerRy, phiSector, 4.), @@ -108,74 +124,71 @@ BOOST_AUTO_TEST_CASE(ConeBoundsExceptions) { /// Unit tests for EllipseBounds properties BOOST_AUTO_TEST_CASE(EllipseBoundsProperties) { - double innerRx(10.), outerRx(15.), innerRy(15.), outerRy(20.), averagePhi(0.), - phiSector(M_PI / 2.); + const double outerRx = 15.; // != 25 + const double outerRy = 20.; // != 30 + /// Test clone EllipseBounds ellipseBoundsObject(innerRx, innerRy, outerRx, outerRy, phiSector, averagePhi); - // + /// Test type() (redundant; already used in constructor confirmation) BOOST_CHECK_EQUAL(ellipseBoundsObject.type(), SurfaceBounds::eEllipse); - // - // clone already tested - // + /// Test distanceToBoundary - Vector2 origin(0., 0.); - Vector2 outsideBy15(0., 30.); - Vector2 inRectangle(17., 11.); - // + Vector2 origin{0., 0.}; + Vector2 outsideBy15{0., 30.}; + Vector2 inRectangle{17., 11.}; + /// Test rMinX BOOST_CHECK_EQUAL(ellipseBoundsObject.get(EllipseBounds::eInnerRx), innerRx); - // + /// Test rMinY BOOST_CHECK_EQUAL(ellipseBoundsObject.get(EllipseBounds::eOuterRx), outerRx); - // + /// Test rMaxX BOOST_CHECK_EQUAL(ellipseBoundsObject.get(EllipseBounds::eInnerRy), innerRy); - // + /// Test rMaxY BOOST_CHECK_EQUAL(ellipseBoundsObject.get(EllipseBounds::eOuterRy), outerRy); - // + /// Test averagePhi BOOST_CHECK_EQUAL(ellipseBoundsObject.get(EllipseBounds::eAveragePhi), averagePhi); - // + /// Test vertices // std::vector expectedVertices{{15, 0}, {0, 20}, {-15, 0}, {0, // -20}}; const auto& actualVertices = ellipseBoundsObject.vertices(4); // BOOST_CHECK_EQUAL_COLLECTIONS(actualVertices.cbegin(), - // actualVertices.cend(), - // expectedVertices.cbegin(), - // expectedVertices.cend()); - // + // actualVertices.cend(), expectedVertices.cbegin(), expectedVertices.cend()); + /// Test boundingBox BOOST_CHECK_EQUAL(ellipseBoundsObject.boundingBox(), RectangleBounds(15., 20.)); - // + /// Test halfPhiSector BOOST_CHECK_EQUAL(ellipseBoundsObject.get(EllipseBounds::eHalfPhiSector), - M_PI / 2.); - // + std::numbers::pi / 2.); + /// Test dump - boost::test_tools::output_test_stream dumpOuput; - ellipseBoundsObject.toStream(dumpOuput); - BOOST_CHECK(dumpOuput.is_equal( + boost::test_tools::output_test_stream dumpOutput; + ellipseBoundsObject.toStream(dumpOutput); + BOOST_CHECK(dumpOutput.is_equal( "Acts::EllipseBounds: (innerRadius0, outerRadius0, innerRadius1, " "outerRadius1, hPhiSector, averagePhi) = (10.0000000, 15.0000000, " - "15.0000000, " - "20.0000000, 0.0000000, 1.5707963, 0.0000000)")); - // + "15.0000000, 20.0000000, 0.0000000, 1.5707963, 0.0000000)")); + /// Test inside BOOST_CHECK( !ellipseBoundsObject.inside(inRectangle, BoundaryTolerance::None())); - // dont understand why this is so: + // don't understand why this is so: BOOST_CHECK( !ellipseBoundsObject.inside(outsideBy15, BoundaryTolerance::None())); } /// Unit test for testing EllipseBounds assignment BOOST_AUTO_TEST_CASE(EllipseBoundsAssignment) { - double innerRx(10.), outerRx(15.), innerRy(15.), outerRy(20.), averagePhi(0.), - phiSector(M_PI / 2.); + const double outerRx = 15.; // != 25 + const double outerRy = 20.; // != 30 + EllipseBounds ellipseBoundsObject(innerRx, outerRx, innerRy, outerRy, averagePhi, phiSector); EllipseBounds similarlyConstructeEllipseBoundsObject( @@ -183,7 +196,7 @@ BOOST_AUTO_TEST_CASE(EllipseBoundsAssignment) { /// Test operator == BOOST_CHECK_EQUAL(ellipseBoundsObject, similarlyConstructeEllipseBoundsObject); - // + /// Test assignment EllipseBounds assignedEllipseBoundsObject(11., 12., 17., 18., 1.); // object, in some sense diff --git a/Tests/UnitTests/Core/Surfaces/InfiniteBoundsTests.cpp b/Tests/UnitTests/Core/Surfaces/InfiniteBoundsTests.cpp index d0097695286..b0c7fa0c94f 100644 --- a/Tests/UnitTests/Core/Surfaces/InfiniteBoundsTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/InfiniteBoundsTests.cpp @@ -29,19 +29,19 @@ BOOST_AUTO_TEST_CASE(InfiniteBoundsConstruction) { /// Unit tests for InfiniteBounds properties BOOST_AUTO_TEST_CASE(InfiniteBoundsProperties) { InfiniteBounds infiniteBoundsObject; - /// test for type() + /// Test for type() BOOST_CHECK_EQUAL(infiniteBoundsObject.type(), SurfaceBounds::eBoundless); - /// test for inside() + /// Test for inside() const Vector2 anyVector{0., 1.}; const BoundaryTolerance anyTolerance = BoundaryTolerance::None(); BOOST_CHECK(infiniteBoundsObject.inside(anyVector, anyTolerance)); - /// test for dump - boost::test_tools::output_test_stream dumpOuput; - infiniteBoundsObject.toStream(dumpOuput); + /// Test for dump + boost::test_tools::output_test_stream dumpOutput; + infiniteBoundsObject.toStream(dumpOutput); BOOST_CHECK( - dumpOuput.is_equal("Acts::InfiniteBounds ... boundless surface\n")); + dumpOutput.is_equal("Acts::InfiniteBounds ... boundless surface\n")); } BOOST_AUTO_TEST_SUITE_END() diff --git a/Tests/UnitTests/Core/Surfaces/LineBoundsTests.cpp b/Tests/UnitTests/Core/Surfaces/LineBoundsTests.cpp index f972529bed0..c8022a9174c 100644 --- a/Tests/UnitTests/Core/Surfaces/LineBoundsTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/LineBoundsTests.cpp @@ -24,20 +24,24 @@ namespace Acts::Test { BOOST_AUTO_TEST_SUITE(Surfaces) /// Unit test for creating compliant/non-compliant LineBounds object BOOST_AUTO_TEST_CASE(LineBoundsConstruction) { - /// test LineBounds(double, double) - double radius(0.5), halfz(10.); - LineBounds lineBounds(radius, halfz); + const double radius = 0.5; + const double halfZ = 10.; + + /// Test LineBounds(double, double) + LineBounds lineBounds(radius, halfZ); BOOST_CHECK_EQUAL(lineBounds.type(), SurfaceBounds::eLine); - /// test copy construction; + + /// Test copy construction; LineBounds copyConstructedLineBounds(lineBounds); // implicit BOOST_CHECK_EQUAL(copyConstructedLineBounds.type(), SurfaceBounds::eLine); } /// Unit test for testing LineBounds recreation from streaming BOOST_AUTO_TEST_CASE(LineBoundsRecreation) { - double nominalRadius{0.5}; - double nominalHalfLength{20.}; - LineBounds original(nominalRadius, nominalHalfLength); + const double radius = 0.5; + const double halfZ = 20.; // != 10. + + LineBounds original(radius, halfZ); LineBounds recreated(original); auto valvector = original.values(); std::array values{}; @@ -47,45 +51,45 @@ BOOST_AUTO_TEST_CASE(LineBoundsRecreation) { /// Unit test for testing LineBounds exceptions BOOST_AUTO_TEST_CASE(LineBoundsExceptions) { - double nominalRadius{0.5}; - double nominalHalfLength{20.}; + const double radius = 0.5; + const double halfZ = 20.; // != 10. + // Negative radius - BOOST_CHECK_THROW(LineBounds(-nominalRadius, nominalHalfLength), - std::logic_error); + BOOST_CHECK_THROW(LineBounds(-radius, halfZ), std::logic_error); + // Negative half length - BOOST_CHECK_THROW(LineBounds(nominalRadius, -nominalHalfLength), - std::logic_error); + BOOST_CHECK_THROW(LineBounds(radius, -halfZ), std::logic_error); // Negative radius and half length - BOOST_CHECK_THROW(LineBounds(-nominalRadius, -nominalHalfLength), - std::logic_error); + BOOST_CHECK_THROW(LineBounds(-radius, -halfZ), std::logic_error); } /// Unit test for testing LineBounds assignment BOOST_AUTO_TEST_CASE(LineBoundsAssignment) { - double nominalRadius{0.5}; - double nominalHalfLength{20.}; - LineBounds lineBoundsObject(nominalRadius, nominalHalfLength); + const double radius = 0.5; + const double halfZ = 20.; // != 10. + + LineBounds lineBoundsObject(radius, halfZ); LineBounds assignedLineBounds = lineBoundsObject; BOOST_CHECK_EQUAL(assignedLineBounds, lineBoundsObject); } /// Unit tests for LineBounds properties BOOST_AUTO_TEST_CASE(LineBoundsProperties) { - // LineBounds object of radius 0.5 and halfz 20 - double nominalRadius{0.5}; - double nominalHalfLength{20.}; - LineBounds lineBoundsObject(nominalRadius, nominalHalfLength); + const double radius = 0.5; + const double halfZ = 20.; // != 10. - /// test for type() + LineBounds lineBoundsObject(radius, halfZ); + + /// Test for type() BOOST_CHECK_EQUAL(lineBoundsObject.type(), SurfaceBounds::eLine); - /// test for inside() + /// Test for inside() const Vector2 origin{0., 0.}; const Vector2 atRadius{0.5, 10.}; - const Vector2 beyondEnd{0.0, 30.0}; - const Vector2 unitZ{0.0, 1.0}; - const Vector2 unitR{1.0, 0.0}; + const Vector2 beyondEnd{0., 30.}; + const Vector2 unitZ{0., 1.}; + const Vector2 unitR{1., 0.}; const BoundaryTolerance tolerance = BoundaryTolerance::AbsoluteBound(0.1, 0.1); // This fails because the bounds are not inclusive. @@ -94,22 +98,20 @@ BOOST_AUTO_TEST_CASE(LineBoundsProperties) { BOOST_CHECK(lineBoundsObject.inside(unitZ, tolerance)); BOOST_CHECK(!lineBoundsObject.inside(unitR, tolerance)); - /// Test negative redius inside - + /// Test negative radius inside BOOST_CHECK(lineBoundsObject.inside(Vector2{-0.2, 10}, tolerance)); BOOST_CHECK(!lineBoundsObject.inside(Vector2{-0.8, 10}, tolerance)); - /// test for r() - BOOST_CHECK_EQUAL(lineBoundsObject.get(LineBounds::eR), nominalRadius); + /// Test for r() + BOOST_CHECK_EQUAL(lineBoundsObject.get(LineBounds::eR), radius); - /// test for halflengthZ (NOTE: Naming violation) - BOOST_CHECK_EQUAL(lineBoundsObject.get(LineBounds::eHalfLengthZ), - nominalHalfLength); + /// Test for halfLengthZ + BOOST_CHECK_EQUAL(lineBoundsObject.get(LineBounds::eHalfLengthZ), halfZ); - /// test for dump - boost::test_tools::output_test_stream dumpOuput; - lineBoundsObject.toStream(dumpOuput); - BOOST_CHECK(dumpOuput.is_equal( + /// Test for dump + boost::test_tools::output_test_stream dumpOutput; + lineBoundsObject.toStream(dumpOutput); + BOOST_CHECK(dumpOutput.is_equal( "Acts::LineBounds: (radius, halflengthInZ) = (0.5000000, 20.0000000)")); } diff --git a/Tests/UnitTests/Core/Surfaces/LineSurfaceTests.cpp b/Tests/UnitTests/Core/Surfaces/LineSurfaceTests.cpp index 71dbf0827de..15d930929af 100644 --- a/Tests/UnitTests/Core/Surfaces/LineSurfaceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/LineSurfaceTests.cpp @@ -14,6 +14,7 @@ #include "Acts/Definitions/TrackParametrization.hpp" #include "Acts/EventData/ParticleHypothesis.hpp" #include "Acts/EventData/TrackParameters.hpp" +#include "Acts/EventData/detail/GenerateParameters.hpp" #include "Acts/Geometry/GeometryContext.hpp" #include "Acts/Material/HomogeneousSurfaceMaterial.hpp" #include "Acts/Propagator/Propagator.hpp" @@ -35,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -55,28 +57,34 @@ BOOST_AUTO_TEST_SUITE(Surfaces) /// Unit test for creating compliant/non-compliant LineSurface object BOOST_AUTO_TEST_CASE(LineSurface_Constructors_test) { - // Default ctor is deleted - // LineSurfaceStub l; - // ctor with translation, radius, halfz + /// Test default construction + // default construction is deleted + Translation3 translation{0., 1., 2.}; Transform3 transform(translation); auto pTransform = Transform3(translation); - const double radius{2.0}, halfz{20.}; - BOOST_CHECK(LineSurfaceStub(pTransform, radius, halfz).constructedOk()); - // ctor with nullptr for LineBounds + const double radius = 2.; + const double halfZ = 20.; + BOOST_CHECK(LineSurfaceStub(pTransform, radius, halfZ).constructedOk()); + + /// ctor with nullptr for LineBounds BOOST_CHECK(LineSurfaceStub(pTransform).constructedOk()); - // ctor with LineBounds - auto pLineBounds = std::make_shared(2., 10.0); + + /// ctor with LineBounds + auto pLineBounds = std::make_shared(2., 10.); BOOST_CHECK(LineSurfaceStub(pTransform, pLineBounds).constructedOk()); - // ctor with LineBounds, detector element, Identifier + + /// ctor with LineBounds, detector element, Identifier auto pMaterial = std::make_shared(makePercentSlab()); DetectorElementStub detElement{pTransform, pLineBounds, 0.2, pMaterial}; BOOST_CHECK(LineSurfaceStub(pLineBounds, detElement).constructedOk()); - LineSurfaceStub lineToCopy(pTransform, 2.0, 20.); - // Copy ctor + LineSurfaceStub lineToCopy(pTransform, 2., 20.); + + /// Copy ctor BOOST_CHECK(LineSurfaceStub(lineToCopy).constructedOk()); - // Copied and transformed ctor + + /// Copied and transformed ctor BOOST_CHECK( LineSurfaceStub(tgContext, lineToCopy, transform).constructedOk()); @@ -94,18 +102,18 @@ BOOST_AUTO_TEST_CASE(LineSurface_allNamedMethods_test) { // binningPosition() Translation3 translation{0., 1., 2.}; Transform3 transform(translation); - LineSurfaceStub line(transform, 2.0, 20.); + LineSurfaceStub line(transform, 2., 20.); Vector3 referencePosition{0., 1., 2.}; CHECK_CLOSE_ABS(referencePosition, line.binningPosition(tgContext, BinningValue::binX), 1e-6); - // + // bounds() - auto pLineBounds = std::make_shared(2., 10.0); + auto pLineBounds = std::make_shared(2., 10.); LineSurfaceStub boundedLine(transform, pLineBounds); const LineBounds& bounds = dynamic_cast(boundedLine.bounds()); - BOOST_CHECK_EQUAL(bounds, LineBounds(2., 10.0)); - // + BOOST_CHECK_EQUAL(bounds, LineBounds(2., 10.)); + // globalToLocal() Vector3 gpos{0., 1., 0.}; const Vector3 mom{20., 0., 0.}; // needs more realistic parameters @@ -113,7 +121,7 @@ BOOST_AUTO_TEST_CASE(LineSurface_allNamedMethods_test) { line.globalToLocal(tgContext, gpos, mom.normalized()).value(); const Vector2 expectedResult{0, -2}; CHECK_CLOSE_ABS(expectedResult, localPosition, 1e-6); - // + // intersection { const Vector3 direction{0., 1., 2.}; @@ -127,7 +135,7 @@ BOOST_AUTO_TEST_CASE(LineSurface_allNamedMethods_test) { 1e-6); // need more tests.. BOOST_CHECK_EQUAL(sfIntersection.object(), &line); } - // + // isOnSurface const Vector3 insidePosition{0., 2.5, 0.}; BOOST_CHECK(line.isOnSurface( @@ -136,7 +144,7 @@ BOOST_AUTO_TEST_CASE(LineSurface_allNamedMethods_test) { const Vector3 outsidePosition{100., 100., 200.}; BOOST_CHECK(!line.isOnSurface(tgContext, outsidePosition, mom, BoundaryTolerance::None())); - // + // localToGlobal Vector3 returnedGlobalPosition{0., 0., 0.}; // Vector2 localPosition{0., 0.}; @@ -145,7 +153,7 @@ BOOST_AUTO_TEST_CASE(LineSurface_allNamedMethods_test) { line.localToGlobal(tgContext, localPosition, momentum.normalized()); const Vector3 expectedGlobalPosition{0, 1, 0}; CHECK_CLOSE_ABS(returnedGlobalPosition, expectedGlobalPosition, 1e-6); - // + // referenceFrame Vector3 globalPosition{0., 0., 0.}; auto returnedRotationMatrix = @@ -154,42 +162,38 @@ BOOST_AUTO_TEST_CASE(LineSurface_allNamedMethods_test) { double v1 = std::sin(std::atan(2. / 3.)); RotationMatrix3 expectedRotationMatrix; expectedRotationMatrix << -v1, 0., v0, v0, 0., v1, 0., 1., -0.; - // std::cout< expLoc3DToLocBound = ActsMatrix<2, 3>::Zero(); - expLoc3DToLocBound << 1 / std::sqrt(2), 1 / std::sqrt(2), 0, 0, 0, 1; + expLoc3DToLocBound << 1 / std::numbers::sqrt2, 1 / std::numbers::sqrt2, 0, 0, + 0, 1; CHECK_CLOSE_ABS(loc3DToLocBound, expLoc3DToLocBound, 1e-10); } @@ -282,7 +287,7 @@ BOOST_AUTO_TEST_CASE(LineSurfaceTransformRoundTripEtaStability) { for (double eta : etas) { Vector3 pca = {5, 0, 0}; - Vector3 dir = makeDirectionFromPhiEta(M_PI_2, eta); + Vector3 dir = makeDirectionFromPhiEta(std::numbers::pi / 2., eta); Vector3 pos = pca + dir; auto intersection = surface.intersect(tgContext, pos, dir).closest(); @@ -339,8 +344,9 @@ BOOST_AUTO_TEST_CASE(LineSurfaceIntersection) { .closest(); CHECK_CLOSE_ABS(intersection.pathLength(), pathLimit, eps); - BoundTrackParameters endParameters{surface, BoundVector::Zero(), std::nullopt, - ParticleHypothesis::pion()}; + BoundTrackParameters endParameters{surface, + detail::Test::someBoundParametersA(), + std::nullopt, ParticleHypothesis::pion()}; { PropagatorOptions options(tgContext, {}); options.direction = Acts::Direction::Forward; diff --git a/Tests/UnitTests/Core/Surfaces/PerigeeSurfaceTests.cpp b/Tests/UnitTests/Core/Surfaces/PerigeeSurfaceTests.cpp index b2346434293..3ccf47b4e11 100644 --- a/Tests/UnitTests/Core/Surfaces/PerigeeSurfaceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/PerigeeSurfaceTests.cpp @@ -25,45 +25,46 @@ GeometryContext tgContext = GeometryContext(); BOOST_AUTO_TEST_SUITE(PerigeeSurfaces) /// Unit test for creating compliant/non-compliant PerigeeSurface object BOOST_AUTO_TEST_CASE(PerigeeSurfaceConstruction) { - // PerigeeSurface default constructor is deleted - // + /// Test default construction + // default construction is deleted + /// Constructor with Vector3 Vector3 unitXYZ{1., 1., 1.}; auto perigeeSurfaceObject = Surface::makeShared(unitXYZ); BOOST_CHECK_EQUAL(Surface::makeShared(unitXYZ)->type(), Surface::Perigee); - // + /// Constructor with transform Translation3 translation{0., 1., 2.}; auto pTransform = Transform3(translation); BOOST_CHECK_EQUAL(Surface::makeShared(pTransform)->type(), Surface::Perigee); - // + /// Copy constructor auto copiedPerigeeSurface = Surface::makeShared(*perigeeSurfaceObject); BOOST_CHECK_EQUAL(copiedPerigeeSurface->type(), Surface::Perigee); BOOST_CHECK(*copiedPerigeeSurface == *perigeeSurfaceObject); - // + /// Copied and transformed auto copiedTransformedPerigeeSurface = Surface::makeShared( tgContext, *perigeeSurfaceObject, pTransform); BOOST_CHECK_EQUAL(copiedTransformedPerigeeSurface->type(), Surface::Perigee); } -// + /// Unit test for testing PerigeeSurface properties BOOST_AUTO_TEST_CASE(PerigeeSurfaceProperties) { /// Test clone method Vector3 unitXYZ{1., 1., 1.}; auto perigeeSurfaceObject = Surface::makeShared(unitXYZ); - // + /// Test type (redundant) BOOST_CHECK_EQUAL(perigeeSurfaceObject->type(), Surface::Perigee); - // + /// Test name BOOST_CHECK_EQUAL(perigeeSurfaceObject->name(), std::string("Acts::PerigeeSurface")); - // + /// Test dump boost::test_tools::output_test_stream dumpOutput; dumpOutput << perigeeSurfaceObject->toStream(tgContext); @@ -74,15 +75,18 @@ BOOST_AUTO_TEST_CASE(PerigeeSurfaceProperties) { BOOST_AUTO_TEST_CASE(EqualityOperators) { Vector3 unitXYZ{1., 1., 1.}; - Vector3 invalidPosition{0.0, 0.0, 0.0}; + Vector3 invalidPosition{0., 0., 0.}; auto perigeeSurfaceObject = Surface::makeShared(unitXYZ); auto perigeeSurfaceObject2 = Surface::makeShared(unitXYZ); auto assignedPerigeeSurface = Surface::makeShared(invalidPosition); + /// Test equality operator BOOST_CHECK(*perigeeSurfaceObject == *perigeeSurfaceObject2); + /// Test assignment *assignedPerigeeSurface = *perigeeSurfaceObject; + /// Test equality of assigned to original BOOST_CHECK(*assignedPerigeeSurface == *perigeeSurfaceObject); } diff --git a/Tests/UnitTests/Core/Surfaces/PlaneSurfaceTests.cpp b/Tests/UnitTests/Core/Surfaces/PlaneSurfaceTests.cpp index ee91782dca2..99d0569b9d2 100644 --- a/Tests/UnitTests/Core/Surfaces/PlaneSurfaceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/PlaneSurfaceTests.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 +#include #include #include "Acts/Definitions/Algebra.hpp" @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -44,16 +45,20 @@ GeometryContext tgContext = GeometryContext(); BOOST_AUTO_TEST_SUITE(PlaneSurfaces) /// Unit test for creating compliant/non-compliant PlaneSurface object BOOST_AUTO_TEST_CASE(PlaneSurfaceConstruction) { - // PlaneSurface default constructor is deleted + /// Test default construction + // default construction is deleted + // bounds object, rectangle type auto rBounds = std::make_shared(3., 4.); /// Constructor with transform and bounds Translation3 translation{0., 1., 2.}; auto pTransform = Transform3(translation); - // constructor with transform + + /// Constructor with transform BOOST_CHECK_EQUAL( Surface::makeShared(pTransform, rBounds)->type(), Surface::Plane); + /// Copy constructor auto planeSurfaceObject = Surface::makeShared(pTransform, rBounds); @@ -61,7 +66,7 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceConstruction) { Surface::makeShared(*planeSurfaceObject); BOOST_CHECK_EQUAL(copiedPlaneSurface->type(), Surface::Plane); BOOST_CHECK(*copiedPlaneSurface == *planeSurfaceObject); - // + /// Copied and transformed auto copiedTransformedPlaneSurface = Surface::makeShared( tgContext, *planeSurfaceObject, pTransform); @@ -73,11 +78,12 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceConstruction) { auto nullBounds = Surface::makeShared(nullptr, detElem), AssertionFailureException); } -// + /// Unit test for testing PlaneSurface properties BOOST_AUTO_TEST_CASE(PlaneSurfaceProperties) { // bounds object, rectangle type auto rBounds = std::make_shared(3., 4.); + /// Test clone method Translation3 translation{0., 1., 2.}; auto pTransform = Transform3(translation); @@ -88,17 +94,18 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceProperties) { auto pTransform2 = Transform3(translation2); auto planeSurfaceObject2 = Surface::makeShared(pTransform2, rBounds); + /// Test type (redundant) BOOST_CHECK_EQUAL(planeSurfaceObject->type(), Surface::Plane); - // + /// Test binningPosition Vector3 binningPosition{0., 1., 2.}; BOOST_CHECK_EQUAL( planeSurfaceObject->binningPosition(tgContext, BinningValue::binX), binningPosition); - // + /// Test referenceFrame - Vector3 arbitraryGlobalPosition{2.0, 2.0, 2.0}; + Vector3 arbitraryGlobalPosition{2., 2., 2.}; Vector3 momentum{1.e6, 1.e6, 1.e6}; RotationMatrix3 expectedFrame; expectedFrame << 1., 0., 0., 0., 1., 0., 0., 0., 1.; @@ -106,11 +113,11 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceProperties) { CHECK_CLOSE_OR_SMALL(planeSurfaceObject->referenceFrame( tgContext, arbitraryGlobalPosition, momentum), expectedFrame, 1e-6, 1e-9); - // + /// Test normal, given 3D position Vector3 normal3D(0., 0., 1.); BOOST_CHECK_EQUAL(planeSurfaceObject->normal(tgContext), normal3D); - // + /// Test bounds BOOST_CHECK_EQUAL(planeSurfaceObject->bounds().type(), SurfaceBounds::eRectangle); @@ -119,13 +126,12 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceProperties) { Vector2 localPosition{1.5, 1.7}; Vector3 globalPosition = planeSurfaceObject->localToGlobal(tgContext, localPosition, momentum); - // // expected position is the translated one Vector3 expectedPosition{1.5 + translation.x(), 1.7 + translation.y(), translation.z()}; CHECK_CLOSE_REL(globalPosition, expectedPosition, 1e-2); - // + /// Testing globalToLocal localPosition = planeSurfaceObject->globalToLocal(tgContext, globalPosition, momentum) @@ -158,8 +164,8 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceProperties) { BoundaryTolerance::None())); BOOST_CHECK(!planeSurfaceObject->isOnSurface(tgContext, offSurface, BoundaryTolerance::None())); - // - // Test intersection + + /// Test intersection Vector3 direction{0., 0., 1.}; auto sfIntersection = planeSurfaceObject ->intersect(tgContext, offSurface, direction, @@ -172,30 +178,30 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceProperties) { BOOST_CHECK_EQUAL(sfIntersection.pathLength(), expectedIntersect.pathLength()); BOOST_CHECK_EQUAL(sfIntersection.object(), planeSurfaceObject.get()); - // /// Test pathCorrection CHECK_CLOSE_REL(planeSurfaceObject->pathCorrection(tgContext, offSurface, momentum.normalized()), - std::sqrt(3), 0.01); - // + std::numbers::sqrt3, 0.01); + /// Test name BOOST_CHECK_EQUAL(planeSurfaceObject->name(), std::string("Acts::PlaneSurface")); - // + /// Test dump - // TODO 2017-04-12 msmk: check how to correctly check output - // boost::test_tools::output_test_stream dumpOuput; - // planeSurfaceObject.toStream(dumpOuput); - // BOOST_CHECK(dumpOuput.is_equal( - // "Acts::PlaneSurface\n" - // " Center position (x, y, z) = (0.0000, 1.0000, 2.0000)\n" - // " Rotation: colX = (1.000000, 0.000000, 0.000000)\n" - // " colY = (0.000000, 1.000000, 0.000000)\n" - // " colZ = (0.000000, 0.000000, 1.000000)\n" - // " Bounds : Acts::ConeBounds: (tanAlpha, minZ, maxZ, averagePhi, - // halfPhiSector) = (0.4142136, 0.0000000, inf, 0.0000000, - // 3.1415927)")); + boost::test_tools::output_test_stream dumpOutput; + dumpOutput << planeSurfaceObject->toStream(tgContext); + BOOST_CHECK(dumpOutput.is_equal( + "Acts::PlaneSurface\n" + " Center position (x, y, z) = (0.0000, 1.0000, 2.0000)\n" + " Rotation: colX = (1.000000, 0.000000, 0.000000)\n" + " colY = (0.000000, 1.000000, 0.000000)\n" + " colZ = (0.000000, 0.000000, 1.000000)\n" + " Bounds : Acts::RectangleBounds: (hlX, hlY) = (3.0000000, " + "4.0000000)\n" + "(lower left, upper right):\n" + "-3.0000000 -4.0000000\n" + "3.0000000 4.0000000")); } BOOST_AUTO_TEST_CASE(PlaneSurfaceEqualityOperators) { @@ -207,16 +213,18 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceEqualityOperators) { Surface::makeShared(pTransform, rBounds); auto planeSurfaceObject2 = Surface::makeShared(pTransform, rBounds); - // + /// Test equality operator BOOST_CHECK(*planeSurfaceObject == *planeSurfaceObject2); - // + BOOST_TEST_CHECKPOINT( "Create and then assign a PlaneSurface object to the existing one"); + /// Test assignment auto assignedPlaneSurface = Surface::makeShared(Transform3::Identity(), nullptr); *assignedPlaneSurface = *planeSurfaceObject; + /// Test equality of assigned to original BOOST_CHECK(*assignedPlaneSurface == *planeSurfaceObject); } @@ -224,9 +232,10 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceEqualityOperators) { /// Unit test for testing PlaneSurface extent via Polyhedron representation BOOST_AUTO_TEST_CASE(PlaneSurfaceExtent) { // First test - non-rotated - static const Transform3 planeZX = AngleAxis3(-0.5 * M_PI, Vector3::UnitX()) * - AngleAxis3(-0.5 * M_PI, Vector3::UnitZ()) * - Transform3::Identity(); + static const Transform3 planeZX = + AngleAxis3(-std::numbers::pi / 2., Vector3::UnitX()) * + AngleAxis3(-std::numbers::pi / 2., Vector3::UnitZ()) * + Transform3::Identity(); double rHx = 2.; double rHy = 4.; @@ -281,10 +290,10 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceExtent) { } BOOST_AUTO_TEST_CASE(RotatedTrapezoid) { - double shortHalfX{100.}; - double longHalfX{200.}; - double halfY{300.}; - double rotAngle{45._degree}; + const double shortHalfX = 100.; + const double longHalfX = 200.; + const double halfY = 300.; + const double rotAngle = 45._degree; Vector2 edgePoint{longHalfX - 10., halfY}; @@ -309,7 +318,7 @@ BOOST_AUTO_TEST_CASE(PlaneSurfaceAlignment) { auto rBounds = std::make_shared(3., 4.); // Test clone method Translation3 translation{0., 1., 2.}; - double rotationAngle = M_PI_2; + const double rotationAngle = std::numbers::pi / 2.; AngleAxis3 rotation(rotationAngle, Vector3::UnitY()); RotationMatrix3 rotationMat = rotation.toRotationMatrix(); diff --git a/Tests/UnitTests/Core/Surfaces/RadialBoundsTests.cpp b/Tests/UnitTests/Core/Surfaces/RadialBoundsTests.cpp index b95d9674bee..a25eeb4d352 100644 --- a/Tests/UnitTests/Core/Surfaces/RadialBoundsTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/RadialBoundsTests.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -24,30 +25,32 @@ namespace Acts::Test { BOOST_AUTO_TEST_SUITE(Surfaces) -/// Unit tests for RadialBounds constrcuctors +const double rMin = 1.; +const double rMax = 5.; +const double halfPhiSector = std::numbers::pi / 8.; +const double avgPhi = 0.1; + +/// Unit tests for RadialBounds constructors BOOST_AUTO_TEST_CASE(RadialBoundsConstruction) { - double minRadius(1.0), maxRadius(5.0), halfPhiSector(M_PI / 8.0); - // test default construction - // RadialBounds defaultConstructedRadialBounds; should be deleted - // + /// Test default construction + // default construction is deleted + /// Test construction with radii and default sector - BOOST_CHECK_EQUAL(RadialBounds(minRadius, maxRadius).type(), - SurfaceBounds::eDisc); - // + BOOST_CHECK_EQUAL(RadialBounds(rMin, rMax).type(), SurfaceBounds::eDisc); + /// Test construction with radii and sector half angle - BOOST_CHECK_EQUAL(RadialBounds(minRadius, maxRadius, halfPhiSector).type(), + BOOST_CHECK_EQUAL(RadialBounds(rMin, rMax, halfPhiSector).type(), SurfaceBounds::eDisc); - // + /// Copy constructor - RadialBounds original(minRadius, maxRadius); + RadialBounds original(rMin, rMax); RadialBounds copied(original); BOOST_CHECK_EQUAL(copied, original); } // Streaning and recreation test BOOST_AUTO_TEST_CASE(RadialBoundsRecreation) { - double minRadius(1.0), maxRadius(5.0), halfPhiSector(M_PI / 8.0), avgPhi(0.1); - RadialBounds original(minRadius, maxRadius, halfPhiSector, avgPhi); + RadialBounds original(rMin, rMax, halfPhiSector, avgPhi); // const bool symmetric(false); auto valvector = original.values(); std::array values{}; @@ -58,75 +61,72 @@ BOOST_AUTO_TEST_CASE(RadialBoundsRecreation) { // Streaning and recreation test BOOST_AUTO_TEST_CASE(RadialBoundsException) { - double minRadius(1.0), maxRadius(5.0), halfPhiSector(M_PI / 8.0), avgPhi(0.1); - // Negative inner radius - BOOST_CHECK_THROW(RadialBounds(-minRadius, maxRadius, halfPhiSector, avgPhi), + BOOST_CHECK_THROW(RadialBounds(-rMin, rMax, halfPhiSector, avgPhi), std::logic_error); // Negative outer radius - BOOST_CHECK_THROW(RadialBounds(minRadius, -maxRadius, halfPhiSector, avgPhi), + BOOST_CHECK_THROW(RadialBounds(rMin, -rMax, halfPhiSector, avgPhi), std::logic_error); // Negative inner and outer radius - BOOST_CHECK_THROW(RadialBounds(-minRadius, -maxRadius, halfPhiSector, avgPhi), + BOOST_CHECK_THROW(RadialBounds(-rMin, -rMax, halfPhiSector, avgPhi), std::logic_error); // Swapped radii - BOOST_CHECK_THROW(RadialBounds(maxRadius, minRadius, halfPhiSector, avgPhi), + BOOST_CHECK_THROW(RadialBounds(rMax, rMin, halfPhiSector, avgPhi), std::logic_error); // Out of bound phi sector - BOOST_CHECK_THROW(RadialBounds(minRadius, -maxRadius, -5., avgPhi), - std::logic_error); + BOOST_CHECK_THROW(RadialBounds(rMin, -rMax, -5., avgPhi), std::logic_error); // Out of bound phi position - BOOST_CHECK_THROW(RadialBounds(minRadius, -maxRadius, halfPhiSector, 5.), + BOOST_CHECK_THROW(RadialBounds(rMin, -rMax, halfPhiSector, 5.), std::logic_error); } /// Unit tests for RadialBounds properties BOOST_AUTO_TEST_CASE(RadialBoundsProperties) { - double minRadius(1.0), maxRadius(5.0), halfPhiSector(M_PI / 8.0); /// Test type() (redundant; already used in constructor confirmation) - RadialBounds radialBoundsObject(minRadius, maxRadius, halfPhiSector); + RadialBounds radialBoundsObject(rMin, rMax, halfPhiSector); BOOST_CHECK_EQUAL(radialBoundsObject.type(), SurfaceBounds::eDisc); - // + /// Test distanceToBoundary Vector2 outside(30., 0.); - Vector2 inSurface(2., 0.0); + Vector2 inSurface(2., 0.); /// Test dump - boost::test_tools::output_test_stream dumpOuput; - radialBoundsObject.toStream(dumpOuput); + boost::test_tools::output_test_stream dumpOutput; + radialBoundsObject.toStream(dumpOutput); BOOST_CHECK( - dumpOuput.is_equal("Acts::RadialBounds: (innerRadius, outerRadius, " - "hPhiSector, averagePhi) = (1.0000000, " - "5.0000000, 0.3926991, 0.0000000)")); - // + dumpOutput.is_equal("Acts::RadialBounds: (innerRadius, outerRadius, " + "hPhiSector, averagePhi) = (1.0000000, " + "5.0000000, 0.3926991, 0.0000000)")); + /// Test inside BOOST_CHECK(radialBoundsObject.inside(inSurface, BoundaryTolerance::None())); BOOST_CHECK(!radialBoundsObject.inside(outside, BoundaryTolerance::None())); - // + /// Test rMin - BOOST_CHECK_EQUAL(radialBoundsObject.get(RadialBounds::eMinR), minRadius); - // + BOOST_CHECK_EQUAL(radialBoundsObject.get(RadialBounds::eMinR), rMin); + /// Test rMax - BOOST_CHECK_EQUAL(radialBoundsObject.get(RadialBounds::eMaxR), maxRadius); - // + BOOST_CHECK_EQUAL(radialBoundsObject.get(RadialBounds::eMaxR), rMax); + /// Test averagePhi (should be a redundant method, this is not configurable) - BOOST_CHECK_EQUAL(radialBoundsObject.get(RadialBounds::eAveragePhi), 0.0); - // + BOOST_CHECK_EQUAL(radialBoundsObject.get(RadialBounds::eAveragePhi), 0.); + /// Test halfPhiSector BOOST_CHECK_EQUAL(radialBoundsObject.get(RadialBounds::eHalfPhiSector), halfPhiSector); } /// Unit test for testing RadialBounds assignment BOOST_AUTO_TEST_CASE(RadialBoundsAssignment) { - double minRadius(1.0), maxRadius(5.0), halfPhiSector(M_PI / 8.0); - RadialBounds radialBoundsObject(minRadius, maxRadius, halfPhiSector); - // operator == not implemented in this class - // + RadialBounds radialBoundsObject(rMin, rMax, halfPhiSector); + + /// Test operator == + // not implemented in this class + /// Test assignment RadialBounds assignedRadialBoundsObject(10.1, 123.); assignedRadialBoundsObject = radialBoundsObject; diff --git a/Tests/UnitTests/Core/Surfaces/RectangleBoundsTests.cpp b/Tests/UnitTests/Core/Surfaces/RectangleBoundsTests.cpp index 53c4df54861..ad310e393cf 100644 --- a/Tests/UnitTests/Core/Surfaces/RectangleBoundsTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/RectangleBoundsTests.cpp @@ -28,30 +28,35 @@ BOOST_AUTO_TEST_SUITE(Surfaces) /// Unit test for creating compliant/non-compliant RectangleBounds object BOOST_AUTO_TEST_CASE(RectangleBoundsConstruction) { - const double halfX(10.), halfY(5.); + const double halfX = 10.; + const double halfY = 5.; RectangleBounds twentyByTenRectangle(halfX, halfY); BOOST_CHECK_EQUAL(twentyByTenRectangle.type(), Acts::SurfaceBounds::eRectangle); - // + // nonsensical bounds are also permitted, but maybe should not be - const double zeroHalfX(0.), zeroHalfY(0.); - const double infHalfX(inf), infHalfY(inf); - // - // BOOST_TEST_MESSAGE("Initialise with zero dimensions"); + const double zeroHalfX = 0.; + const double zeroHalfY = 0.; + const double infHalfX = inf; + const double infHalfY = inf; + + // Initialise with zero dimensions RectangleBounds zeroDimensionsRectangle(zeroHalfX, zeroHalfY); BOOST_CHECK_EQUAL(zeroDimensionsRectangle.type(), Acts::SurfaceBounds::eRectangle); - // - // BOOST_TEST_MESSAGE("Initialise with infinite dimensions"); + + // Initialise with infinite dimensions RectangleBounds infinite(infHalfX, infHalfY); BOOST_CHECK_EQUAL(infinite.type(), Acts::SurfaceBounds::eRectangle); } /// Recreation BOOST_AUTO_TEST_CASE(RectangleBoundsRecreation) { - const double halfX(10.), halfY(2.); + const double halfX = 10.; + const double halfY = 2.; // != 5. + RectangleBounds original(halfX, halfY); - // const bool symmetric(false); + auto valvector = original.values(); std::array values{}; std::copy_n(valvector.begin(), RectangleBounds::eSize, values.begin()); @@ -61,7 +66,8 @@ BOOST_AUTO_TEST_CASE(RectangleBoundsRecreation) { // Exception tests BOOST_AUTO_TEST_CASE(RadialBoundsException) { - const double halfX(10.), halfY(2.); + const double halfX = 10.; + const double halfY = 2.; // != 5. // Negative x half length BOOST_CHECK_THROW(RectangleBounds(-halfX, halfY), std::logic_error); @@ -73,29 +79,33 @@ BOOST_AUTO_TEST_CASE(RadialBoundsException) { /// Unit test for testing RectangleBounds properties BOOST_TEST_DECORATOR(*boost::unit_test::tolerance(1e-10)) BOOST_AUTO_TEST_CASE(RectangleBoundsProperties) { - const double halfX(10.), halfY(5.); + const double halfX = 10.; + const double halfY = 5.; + RectangleBounds rect(halfX, halfY); - BOOST_CHECK_EQUAL(rect.halfLengthX(), 10.); - BOOST_CHECK_EQUAL(rect.halfLengthY(), 5.); + BOOST_CHECK_EQUAL(rect.halfLengthX(), halfX); + BOOST_CHECK_EQUAL(rect.halfLengthY(), halfY); CHECK_CLOSE_ABS(rect.min(), Vector2(-halfX, -halfY), 1e-6); CHECK_CLOSE_ABS(rect.max(), Vector2(halfX, halfY), 1e-6); const std::vector coords = { - {-10., -5.}, {10., -5.}, {10., 5.}, {-10., 5.}}; + {-halfX, -halfY}, {halfX, -halfY}, {halfX, halfY}, {-halfX, halfY}}; // equality, ensure ordering is ok const auto& rectVertices = rect.vertices(); BOOST_CHECK_EQUAL_COLLECTIONS(coords.cbegin(), coords.cend(), rectVertices.cbegin(), rectVertices.cend()); - const Vector2 pointA{1.0, 1.0}; + const Vector2 pointA{1., 1.}; // distance is signed, from boundary to point. (doesn't seem right, given BoundaryTolerance tolerance = BoundaryTolerance::None(); BOOST_CHECK(rect.inside(pointA, tolerance)); } BOOST_AUTO_TEST_CASE(RectangleBoundsAssignment) { - const double halfX(10.), halfY(2.); + const double halfX = 10.; + const double halfY = 2.; // != 5. + RectangleBounds rectA(halfX, halfY); - RectangleBounds rectB(0.0, 0.0); + RectangleBounds rectB(0., 0.); rectB = rectA; const auto originalVertices = rectA.vertices(); const auto assignedVertices = rectB.vertices(); diff --git a/Tests/UnitTests/Core/Surfaces/StrawSurfaceTests.cpp b/Tests/UnitTests/Core/Surfaces/StrawSurfaceTests.cpp index 9756800eed2..2998ad0e799 100644 --- a/Tests/UnitTests/Core/Surfaces/StrawSurfaceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/StrawSurfaceTests.cpp @@ -30,13 +30,17 @@ namespace Acts::Test { GeometryContext tgContext = GeometryContext(); BOOST_AUTO_TEST_SUITE(StrawSurfaces) + +const double radius = 1.; +const double halfZ = 10.; +Translation3 translation{0., 1., 2.}; + /// Unit test for creating compliant/non-compliant StrawSurface object BOOST_AUTO_TEST_CASE(StrawSurfaceConstruction) { - // StrawSurface default constructor is deleted - // + /// Test default construction + // default construction is deleted + /// Constructor with transform, radius and halfZ - double radius(1.0), halfZ(10.); - Translation3 translation{0., 1., 2.}; auto pTransform = Transform3(translation); BOOST_CHECK_EQUAL( Surface::makeShared(Transform3::Identity(), radius, halfZ) @@ -45,21 +49,21 @@ BOOST_AUTO_TEST_CASE(StrawSurfaceConstruction) { BOOST_CHECK_EQUAL( Surface::makeShared(pTransform, radius, halfZ)->type(), Surface::Straw); - // + /// Constructor with transform and LineBounds pointer auto pLineBounds = std::make_shared(radius, halfZ); BOOST_CHECK_EQUAL( Surface::makeShared(pTransform, pLineBounds)->type(), Surface::Straw); - // + /// Constructor with LineBounds ptr, DetectorElement std::shared_ptr p = std::make_shared(1., 10.); - DetectorElementStub detElement{pTransform, p, 1.0, nullptr}; + DetectorElementStub detElement{pTransform, p, 1., nullptr}; BOOST_CHECK_EQUAL( Surface::makeShared(pLineBounds, detElement)->type(), Surface::Straw); - // + /// Copy constructor auto strawSurfaceObject = Surface::makeShared(pTransform, radius, halfZ); @@ -67,29 +71,27 @@ BOOST_AUTO_TEST_CASE(StrawSurfaceConstruction) { Surface::makeShared(*strawSurfaceObject); BOOST_CHECK_EQUAL(copiedStrawSurface->type(), Surface::Straw); BOOST_CHECK(*copiedStrawSurface == *strawSurfaceObject); - // + /// Copied and transformed auto copiedTransformedStrawSurface = Surface::makeShared( tgContext, *strawSurfaceObject, pTransform); BOOST_CHECK_EQUAL(copiedTransformedStrawSurface->type(), Surface::Straw); } -// + /// Unit test for testing StrawSurface properties BOOST_AUTO_TEST_CASE(StrawSurfaceProperties) { /// Test clone method - double radius(1.0), halfZ(10.); - Translation3 translation{0., 1., 2.}; auto pTransform = Transform3(translation); auto strawSurfaceObject = Surface::makeShared(pTransform, radius, halfZ); - // + /// Test type (redundant) BOOST_CHECK_EQUAL(strawSurfaceObject->type(), Surface::Straw); - // + /// Test name BOOST_CHECK_EQUAL(strawSurfaceObject->name(), std::string("Acts::StrawSurface")); - // + /// Test dump boost::test_tools::output_test_stream dumpOutput; dumpOutput << strawSurfaceObject->toStream(tgContext); @@ -103,24 +105,24 @@ BOOST_AUTO_TEST_CASE(StrawSurfaceProperties) { } BOOST_AUTO_TEST_CASE(EqualityOperators) { - double radius(1.0), halfZ(10.); - Translation3 translation{0., 1., 2.}; auto pTransform = Transform3(translation); auto strawSurfaceObject = Surface::makeShared(pTransform, radius, halfZ); - // + auto strawSurfaceObject2 = Surface::makeShared(pTransform, radius, halfZ); - // + /// Test equality operator BOOST_CHECK(*strawSurfaceObject == *strawSurfaceObject2); - // + BOOST_TEST_CHECKPOINT( "Create and then assign a StrawSurface object to the existing one"); + /// Test assignment auto assignedStrawSurface = Surface::makeShared(Transform3::Identity(), 6.6, 33.33); *assignedStrawSurface = *strawSurfaceObject; + /// Test equality of assigned to original BOOST_CHECK(*assignedStrawSurface == *strawSurfaceObject); } diff --git a/Tests/UnitTests/Core/Surfaces/SurfaceArrayTests.cpp b/Tests/UnitTests/Core/Surfaces/SurfaceArrayTests.cpp index 348b6cceed6..2d62f29f4e4 100644 --- a/Tests/UnitTests/Core/Surfaces/SurfaceArrayTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/SurfaceArrayTests.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -54,7 +55,7 @@ struct SurfaceArrayFixture { double zbase = 0, double r = 10) { SrfVec res; - double phiStep = 2 * M_PI / n; + double phiStep = 2 * std::numbers::pi / n; for (std::size_t i = 0; i < n; ++i) { double z = zbase + ((i % 2 == 0) ? 1 : -1) * 0.2; @@ -76,11 +77,11 @@ struct SurfaceArrayFixture { } SrfVec fullPhiTestSurfacesBRL(int n = 10, double shift = 0, double zbase = 0, - double incl = M_PI / 9., double w = 2, - double h = 1.5) { + double incl = std::numbers::pi / 9., + double w = 2, double h = 1.5) { SrfVec res; - double phiStep = 2 * M_PI / n; + double phiStep = 2 * std::numbers::pi / n; for (int i = 0; i < n; ++i) { double z = zbase; @@ -89,7 +90,7 @@ struct SurfaceArrayFixture { trans.rotate(Eigen::AngleAxisd(i * phiStep + shift, Vector3(0, 0, 1))); trans.translate(Vector3(10, 0, z)); trans.rotate(Eigen::AngleAxisd(incl, Vector3(0, 0, 1))); - trans.rotate(Eigen::AngleAxisd(M_PI / 2., Vector3(0, 1, 0))); + trans.rotate(Eigen::AngleAxisd(std::numbers::pi / 2., Vector3(0, 1, 0))); auto bounds = std::make_shared(w, h); std::shared_ptr srf = @@ -112,8 +113,8 @@ struct SurfaceArrayFixture { Transform3 trans; trans.setIdentity(); trans.translate(origin + dir * step * i); - // trans.rotate(AngleAxis3(M_PI/9., Vector3(0, 0, 1))); - trans.rotate(AngleAxis3(M_PI / 2., Vector3(1, 0, 0))); + // trans.rotate(AngleAxis3(std::numbers::pi/9., Vector3(0, 0, 1))); + trans.rotate(AngleAxis3(std::numbers::pi / 2., Vector3(1, 0, 0))); trans = trans * pretrans; auto bounds = std::make_shared(2, 1.5); @@ -135,8 +136,8 @@ struct SurfaceArrayFixture { for (int i = 0; i < nZ; i++) { double z = i * w * 2 + z0; - // std::cout << "z=" << z << std::endl; - SrfVec ring = fullPhiTestSurfacesBRL(nPhi, 0, z, M_PI / 9., w, h); + SrfVec ring = + fullPhiTestSurfacesBRL(nPhi, 0, z, std::numbers::pi / 9., w, h); res.insert(res.end(), ring.begin(), ring.end()); } @@ -185,11 +186,11 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArray_create, SurfaceArrayFixture) { std::vector brlRaw = unpack_shared_vector(brl); draw_surfaces(brl, "SurfaceArray_create_BRL_1.obj"); - Axis phiAxis(-M_PI, M_PI, - 30u); + Axis phiAxis( + -std::numbers::pi, std::numbers::pi, 30u); Axis zAxis(-14, 14, 7u); - double angleShift = 2 * M_PI / 30. / 2.; + double angleShift = 2 * std::numbers::pi / 30. / 2.; auto transform = [angleShift](const Vector3& pos) { return Vector2(phi(pos) + angleShift, pos.z()); }; @@ -225,7 +226,7 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArray_create, SurfaceArrayFixture) { SurfaceArray::SurfaceGridLookup>( transform, itransform, std::make_tuple(std::move(phiAxis), std::move(zAxis))); - // do NOT fill, only completebinning + // do NOT fill, only complete binning sl2->completeBinning(tgContext, brlRaw); SurfaceArray sa2(std::move(sl2), brl); sa.toStream(tgContext, std::cout); @@ -239,7 +240,8 @@ BOOST_FIXTURE_TEST_CASE(SurfaceArray_create, SurfaceArrayFixture) { } BOOST_AUTO_TEST_CASE(SurfaceArray_singleElement) { - double w = 3, h = 4; + const double w = 3; + const double h = 4; auto bounds = std::make_shared(w, h); auto srf = Surface::makeShared(Transform3::Identity(), bounds); @@ -253,7 +255,8 @@ BOOST_AUTO_TEST_CASE(SurfaceArray_singleElement) { } BOOST_AUTO_TEST_CASE(SurfaceArray_manyElementsSingleLookup) { - double w = 3, h = 4; + const double w = 3; + const double h = 4; auto bounds = std::make_shared(w, h); auto srf0 = Surface::makeShared(Transform3::Identity(), bounds); auto srf1 = Surface::makeShared(Transform3::Identity(), bounds); diff --git a/Tests/UnitTests/Core/Surfaces/SurfaceBoundsTests.cpp b/Tests/UnitTests/Core/Surfaces/SurfaceBoundsTests.cpp index 3de53a2b628..e150e9a64c9 100644 --- a/Tests/UnitTests/Core/Surfaces/SurfaceBoundsTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/SurfaceBoundsTests.cpp @@ -57,7 +57,9 @@ class SurfaceBoundsStub : public SurfaceBounds { } // namespace Acts namespace Acts::Test { + BOOST_AUTO_TEST_SUITE(Surfaces) + /// Unit test for creating compliant/non-compliant SurfaceBounds object BOOST_AUTO_TEST_CASE(SurfaceBoundsConstruction) { SurfaceBoundsStub u; @@ -65,6 +67,7 @@ BOOST_AUTO_TEST_CASE(SurfaceBoundsConstruction) { SurfaceBoundsStub t(s); SurfaceBoundsStub v(u); } + BOOST_AUTO_TEST_CASE(SurfaceBoundsProperties) { SurfaceBoundsStub surface(5); std::vector reference{0, 1, 2, 3, 4}; @@ -72,6 +75,7 @@ BOOST_AUTO_TEST_CASE(SurfaceBoundsProperties) { BOOST_CHECK_EQUAL_COLLECTIONS(reference.cbegin(), reference.cend(), boundValues.cbegin(), boundValues.cend()); } + /// Unit test for testing SurfaceBounds properties BOOST_AUTO_TEST_CASE(SurfaceBoundsEquality) { SurfaceBoundsStub surface(1); @@ -79,15 +83,18 @@ BOOST_AUTO_TEST_CASE(SurfaceBoundsEquality) { SurfaceBoundsStub differentSurface(2); BOOST_CHECK_EQUAL(surface, copiedSurface); BOOST_CHECK_NE(surface, differentSurface); + SurfaceBoundsStub assignedSurface; assignedSurface = surface; BOOST_CHECK_EQUAL(surface, assignedSurface); + const auto& surfaceboundValues = surface.values(); const auto& assignedboundValues = assignedSurface.values(); BOOST_CHECK_EQUAL_COLLECTIONS( surfaceboundValues.cbegin(), surfaceboundValues.cend(), assignedboundValues.cbegin(), assignedboundValues.cend()); } + BOOST_AUTO_TEST_SUITE_END() } // namespace Acts::Test diff --git a/Tests/UnitTests/Core/Surfaces/SurfaceIntersectionTests.cpp b/Tests/UnitTests/Core/Surfaces/SurfaceIntersectionTests.cpp index fed41d3fdde..e6294fc27ca 100644 --- a/Tests/UnitTests/Core/Surfaces/SurfaceIntersectionTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/SurfaceIntersectionTests.cpp @@ -23,6 +23,7 @@ #include #include +#include #include using namespace Acts::UnitLiterals; @@ -42,8 +43,8 @@ BOOST_AUTO_TEST_SUITE(Surfaces) /// This tests the intersection with cylinders /// and looks for valid, non-valid, solutions BOOST_AUTO_TEST_CASE(CylinderIntersectionTests) { - double radius = 1_m; - double halfZ = 10_m; + const double radius = 1_m; + const double halfZ = 10_m; auto testCylinderIntersection = [&](const Transform3& transform) -> void { // A cylinder created aligned with a provided transform @@ -169,7 +170,7 @@ BOOST_AUTO_TEST_CASE(CylinderIntersectionTests) { /// This tests the intersection with cylinders /// and looks for valid, non-valid, solutions BOOST_AUTO_TEST_CASE(ConeIntersectionTest) { - double alpha = 0.25 * M_PI; + const double alpha = std::numbers::pi / 4.; auto testConeIntersection = [&](const Transform3& transform) -> void { // A cone surface ready to use @@ -179,7 +180,8 @@ BOOST_AUTO_TEST_CASE(ConeIntersectionTest) { auto lTransform = transform.linear(); // An onCylinder solution - Vector3 onCone = transform * Vector3(std::sqrt(2.), std::sqrt(2.), 2.); + Vector3 onCone = + transform * Vector3(std::numbers::sqrt2, std::numbers::sqrt2, 2.); Vector3 outCone = transform * Vector3(std::sqrt(4.), std::sqrt(4.), 2.); // Simply along the x axis Vector3 perpXY = lTransform * Vector3(1., -1., 0.).normalized(); @@ -224,8 +226,8 @@ BOOST_AUTO_TEST_CASE(ConeIntersectionTest) { /// sufficient /// - it looks for valid, non-valid, solutions BOOST_AUTO_TEST_CASE(PlanarIntersectionTest) { - double halfX = 1_m; - double halfY = 10_m; + const double halfX = 1_m; + const double halfY = 10_m; auto testPlanarIntersection = [&](const Transform3& transform) -> void { // A Plane created with a specific transform @@ -323,8 +325,8 @@ BOOST_AUTO_TEST_CASE(PlanarIntersectionTest) { /// sufficient /// - it looks for valid, non-valid, solutions BOOST_AUTO_TEST_CASE(LineIntersectionTest) { - double radius = 1_m; - double halfZ = 10_m; + const double radius = 1_m; + const double halfZ = 10_m; auto testLineAppraoch = [&](const Transform3& transform) -> void { // A Plane created with a specific transform diff --git a/Tests/UnitTests/Core/Surfaces/SurfaceLocalToGlobalRoundtripTests.cpp b/Tests/UnitTests/Core/Surfaces/SurfaceLocalToGlobalRoundtripTests.cpp index b1b56b18d59..11c66abf303 100644 --- a/Tests/UnitTests/Core/Surfaces/SurfaceLocalToGlobalRoundtripTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/SurfaceLocalToGlobalRoundtripTests.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -75,14 +76,17 @@ void runTest(const Surface& surface, double l0, double l1, double phi, // test datasets // local positions -const auto posAngle = bdata::xrange(-M_PI, M_PI, 0.25); -const auto posPositiveNonzero = bdata::xrange(0.25, 1.0, 0.25); -const auto posPositive = bdata::make(0.0) + posPositiveNonzero; -const auto posSymmetric = bdata::xrange(-1.0, 1.0, 0.25); +const auto posAngle = bdata::xrange(-std::numbers::pi, std::numbers::pi, 0.25); +const auto posPositiveNonzero = bdata::xrange(0.25, 1., 0.25); +const auto posPositive = bdata::make(0.) + posPositiveNonzero; +const auto posSymmetric = bdata::xrange(-1., 1., 0.25); // direction angles -const auto phis = bdata::xrange(-M_PI, M_PI, M_PI_4); -const auto thetasNoForwardBackward = bdata::xrange(M_PI_4, M_PI, M_PI_4); -const auto thetas = bdata::make({0.0, M_PI}) + thetasNoForwardBackward; +const auto phis = + bdata::xrange(-std::numbers::pi, std::numbers::pi, std::numbers::pi / 4.); +const auto thetasNoForwardBackward = bdata::xrange( + std::numbers::pi / 4., std::numbers::pi, std::numbers::pi / 4.); +const auto thetas = + bdata::make({0., std::numbers::pi}) + thetasNoForwardBackward; // different surfaces // parameters must be chosen such that all possible local positions (as defined @@ -93,7 +97,7 @@ const auto cones = bdata::make({ }); const auto cylinders = bdata::make({ Surface::makeShared(Transform3::Identity(), - 10.0 /* radius */, 100 /* half z */), + 10. /* radius */, 100 /* half z */), }); const auto discs = bdata::make({ Surface::makeShared(Transform3::Identity(), 0 /* radius min */, @@ -108,8 +112,8 @@ const auto planes = bdata::make({ CurvilinearSurface(Vector3(3, -4, 5), Vector3::UnitZ()).planeSurface(), }); const auto straws = bdata::make({ - Surface::makeShared(Transform3::Identity(), 2.0 /* radius */, - 200.0 /* half z */), + Surface::makeShared(Transform3::Identity(), 2. /* radius */, + 200. /* half z */), }); } // namespace @@ -123,7 +127,7 @@ BOOST_DATA_TEST_CASE(ConeSurface, // local parameter r*phi has limits that depend on the z position const auto r = lz * surface->bounds().tanAlpha(); // local coordinates are singular at z = 0 -> normalize local phi - runTest(*surface, (0 < lz) ? (r * lphi) : 0.0, lz, phi, theta); + runTest(*surface, (0 < lz) ? (r * lphi) : 0., lz, phi, theta); } BOOST_DATA_TEST_CASE(CylinderSurface, @@ -135,7 +139,7 @@ BOOST_DATA_TEST_CASE(CylinderSurface, BOOST_DATA_TEST_CASE(DiscSurface, discs* posPositive* posAngle* phis* thetas, surface, lr, lphi, phi, theta) { // local coordinates are singular at r = 0 -> normalize local phi - runTest(*surface, lr, (0 < lr) ? lphi : 0.0, phi, theta); + runTest(*surface, lr, (0 < lr) ? lphi : 0., phi, theta); } BOOST_DATA_TEST_CASE( diff --git a/Tests/UnitTests/Core/Surfaces/SurfaceStub.hpp b/Tests/UnitTests/Core/Surfaces/SurfaceStub.hpp index ce745bec85c..c61508a6d89 100644 --- a/Tests/UnitTests/Core/Surfaces/SurfaceStub.hpp +++ b/Tests/UnitTests/Core/Surfaces/SurfaceStub.hpp @@ -78,7 +78,7 @@ class SurfaceStub : public RegularSurface { /// Inherited from GeometryObject base Vector3 binningPosition(const GeometryContext& /*txt*/, BinningValue /*bValue*/) const final { - const Vector3 v{0.0, 0.0, 0.0}; + const Vector3 v{0., 0., 0.}; return v; } diff --git a/Tests/UnitTests/Core/Surfaces/SurfaceTests.cpp b/Tests/UnitTests/Core/Surfaces/SurfaceTests.cpp index 654bed3b8ff..e4c214b53d8 100644 --- a/Tests/UnitTests/Core/Surfaces/SurfaceTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/SurfaceTests.cpp @@ -82,52 +82,60 @@ BOOST_AUTO_TEST_CASE(SurfaceProperties) { std::make_shared(makePercentSlab()); DetectorElementStub detElement{pTransform, pPlanarBound, 0.2, pMaterial}; SurfaceStub surface(detElement); + // associatedDetectorElement BOOST_CHECK_EQUAL(surface.associatedDetectorElement(), &detElement); - // test associatelayer, associatedLayer + + // test associatelayer, associatedLayer surface.associateLayer(*pLayer); BOOST_CHECK_EQUAL(surface.associatedLayer(), pLayer.get()); + // associated Material is not set to the surface // it is set to the detector element surface though BOOST_CHECK_NE(surface.surfaceMaterial(), pMaterial.get()); + // center() CHECK_CLOSE_OR_SMALL(reference, surface.center(tgContext), 1e-6, 1e-9); + // insideBounds - Vector2 localPosition{0.1, 3.0}; + Vector2 localPosition{0.1, 3.}; BOOST_CHECK(surface.insideBounds(localPosition)); Vector2 outside{20., 20.}; BOOST_CHECK(surface.insideBounds( outside)); // should return false, but doesn't because SurfaceStub has // "no bounds" hard-coded Vector3 mom{100., 200., 300.}; + // isOnSurface BOOST_CHECK(surface.isOnSurface(tgContext, reference, mom, BoundaryTolerance::Infinite())); BOOST_CHECK(surface.isOnSurface( tgContext, reference, mom, BoundaryTolerance::None())); // need to improve bounds() + // referenceFrame() RotationMatrix3 unitary; unitary << 1, 0, 0, 0, 1, 0, 0, 0, 1; auto referenceFrame = - surface.referenceFrame(tgContext, Vector3{1, 2, 3}.normalized(), - mom); // need more complex case to test + surface.referenceFrame(tgContext, Vector3{1, 2, 3}.normalized(), mom); BOOST_CHECK_EQUAL(referenceFrame, unitary); + // normal() auto normal = surface.normal(tgContext, Vector3{1, 2, 3}.normalized(), - Vector3::UnitZ()); // needs more - // complex test + Vector3::UnitZ()); Vector3 zero{0., 0., 0.}; BOOST_CHECK_EQUAL(zero, normal); + // pathCorrection is pure virtual + // surfaceMaterial() auto pNewMaterial = std::make_shared(makePercentSlab()); surface.assignSurfaceMaterial(pNewMaterial); - BOOST_CHECK_EQUAL(surface.surfaceMaterial(), - pNewMaterial.get()); // passes ?? - // + BOOST_CHECK_EQUAL(surface.surfaceMaterial(), pNewMaterial.get()); + CHECK_CLOSE_OR_SMALL(surface.transform(tgContext), pTransform, 1e-6, 1e-9); + // type() is pure virtual } @@ -140,6 +148,7 @@ BOOST_AUTO_TEST_CASE(EqualityOperators) { Translation3 translation2{1., 1., 2.}; auto pTransform1 = Transform3(translation1); auto pTransform2 = Transform3(translation2); + // build a planeSurface to be compared auto planeSurface = Surface::makeShared(pTransform1, pPlanarBound); @@ -149,27 +158,20 @@ BOOST_AUTO_TEST_CASE(EqualityOperators) { DetectorElementStub detElement1{pTransform1, pPlanarBound, 0.2, pMaterial}; DetectorElementStub detElement2{pTransform1, pPlanarBound, 0.3, pMaterial}; DetectorElementStub detElement3{pTransform2, pPlanarBound, 0.3, pMaterial}; - // + SurfaceStub surface1(detElement1); SurfaceStub surface2(detElement1); // 1 and 2 are the same SurfaceStub surface3(detElement2); // 3 differs in thickness SurfaceStub surface4(detElement3); // 4 has a different transform and id SurfaceStub surface5(detElement1); surface5.assignSurfaceMaterial(pMaterial); // 5 has non-null surface material - // + BOOST_CHECK(surface1 == surface2); - // - // remove test for the moment, - // surfaces do not have a concept of thickness (only detector elements have) - // only thickness is different here - // - // BOOST_CHECK_NE(surface1, surface3); // will fail - // + BOOST_CHECK(surface1 != surface3); BOOST_CHECK(surface1 != surface4); - // BOOST_CHECK(surface1 != surface5); - // BOOST_CHECK(surface1 != *planeSurface); + // Test the getSharedPtr const auto surfacePtr = Surface::makeShared(detElement1); const auto sharedSurfacePtr = surfacePtr->getSharedPtr(); diff --git a/Tests/UnitTests/Core/Surfaces/TrapezoidBoundsTests.cpp b/Tests/UnitTests/Core/Surfaces/TrapezoidBoundsTests.cpp index 35fb2cfb343..0e9f1bba029 100644 --- a/Tests/UnitTests/Core/Surfaces/TrapezoidBoundsTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/TrapezoidBoundsTests.cpp @@ -32,13 +32,15 @@ namespace Acts::Test { BOOST_AUTO_TEST_SUITE(Surfaces) +const double minHalfX = 1.; +const double maxHalfX = 6.; +const double halfY = 2.; + /// Unit test for creating compliant/non-compliant TrapezoidBounds object BOOST_AUTO_TEST_CASE(TrapezoidBoundsConstruction) { - double minHalfX(1.), maxHalfX(6.), halfY(2.); - // - // default construction deleted - // TrapezoidBounds defaultConstructedTrapezoidBounds; - // + /// Test default construction + // default construction is deleted + /// Test construction with defining half lengths BOOST_CHECK_EQUAL(TrapezoidBounds(minHalfX, maxHalfX, halfY).type(), SurfaceBounds::eTrapezoid); @@ -50,7 +52,6 @@ BOOST_AUTO_TEST_CASE(TrapezoidBoundsConstruction) { /// Unit test for creating compliant/non-compliant TrapezoidBounds object BOOST_AUTO_TEST_CASE(TrapezoidBoundsRecreated) { - double minHalfX(1.), maxHalfX(6.), halfY(2.); /// Copy constructor TrapezoidBounds original(minHalfX, maxHalfX, halfY); // const bool symmetric(false); @@ -63,8 +64,6 @@ BOOST_AUTO_TEST_CASE(TrapezoidBoundsRecreated) { // Exception tests BOOST_AUTO_TEST_CASE(TrapezoidBoundsException) { - double minHalfX(1.), maxHalfX(6.), halfY(2.); - // Negative x at min y BOOST_CHECK_THROW(TrapezoidBounds(-minHalfX, maxHalfX, halfY), std::logic_error); @@ -84,25 +83,23 @@ BOOST_AUTO_TEST_CASE(TrapezoidBoundsException) { /// Unit tests for TrapezoidBounds properties BOOST_AUTO_TEST_CASE(TrapezoidBoundsProperties) { - double minHalfX(1.), maxHalfX(6.), halfY(2.); - // TrapezoidBounds trapezoidBoundsObject(minHalfX, maxHalfX, halfY); - // + /// Test type() (redundant; already used in constructor confirmation) BOOST_CHECK_EQUAL(trapezoidBoundsObject.type(), SurfaceBounds::eTrapezoid); - // + /// Test minHalflengthX BOOST_CHECK_EQUAL( trapezoidBoundsObject.get(TrapezoidBounds::eHalfLengthXnegY), minHalfX); - // + /// Test maxHalfLengthX BOOST_CHECK_EQUAL( trapezoidBoundsObject.get(TrapezoidBounds::eHalfLengthXposY), maxHalfX); - // + /// Test halflengthY BOOST_CHECK_EQUAL(trapezoidBoundsObject.get(TrapezoidBounds::eHalfLengthY), halfY); - // + /// Test distanceToBoundary Vector2 outside(30., 0.); Vector2 inRectangle(2., 0.5); @@ -114,24 +111,18 @@ BOOST_AUTO_TEST_CASE(TrapezoidBoundsProperties) { BOOST_CHECK_EQUAL_COLLECTIONS(actualVertices.cbegin(), actualVertices.cend(), expectedVertices.cbegin(), expectedVertices.cend()); - /** - for (auto i: trapezoidBoundsObject.vertices()){ - std::cout<(-3, 3))) ^ - bdata::xrange(1000) * bdata::make({0.0, 0.1, 0.2, 0.3}), + bdata::xrange(1000) * bdata::make({0., 0.1, 0.2, 0.3}), x, y, index, tol) { (void)index; - double minHalfX(1.), maxHalfX(6.), halfY(2.); + static const TrapezoidBounds trapezoidBoundsObject(minHalfX, maxHalfX, halfY); static const auto vertices = trapezoidBoundsObject.vertices(); BoundaryTolerance tolerance = BoundaryTolerance::None(); - if (tol != 0.0) { + if (tol != 0.) { tolerance = BoundaryTolerance::AbsoluteBound{tol, tol}; } @@ -211,10 +201,11 @@ BOOST_DATA_TEST_CASE( /// Unit test for testing TrapezoidBounds assignment BOOST_AUTO_TEST_CASE(TrapezoidBoundsAssignment) { - double minHalfX(1.), maxHalfX(6.), halfY(2.); TrapezoidBounds trapezoidBoundsObject(minHalfX, maxHalfX, halfY); - // operator == not implemented in this class - // + + /// Test operator == + // not implemented in this class + /// Test assignment TrapezoidBounds assignedTrapezoidBoundsObject(10., 20., 14.2); assignedTrapezoidBoundsObject = trapezoidBoundsObject; diff --git a/Tests/UnitTests/Core/Surfaces/VerticesHelperTests.cpp b/Tests/UnitTests/Core/Surfaces/VerticesHelperTests.cpp index 2b52064cb8d..ecd464b42d7 100644 --- a/Tests/UnitTests/Core/Surfaces/VerticesHelperTests.cpp +++ b/Tests/UnitTests/Core/Surfaces/VerticesHelperTests.cpp @@ -12,6 +12,7 @@ #include "Acts/Surfaces/detail/VerticesHelper.hpp" #include +#include #include #include @@ -158,7 +159,8 @@ BOOST_AUTO_TEST_CASE(GenerateSegmentVertices) { vertices = VerticesHelper::segmentVertices( {rx, ry}, minPhi, maxPhi, {}, quarterVertices); expectedVertices = - static_cast((maxPhi - minPhi) / M_PI_2 * quarterVertices) + + static_cast((maxPhi - minPhi) / (std::numbers::pi / 2.) * + quarterVertices) + 2u; BOOST_CHECK_EQUAL(vertices.size(), expectedVertices); @@ -175,7 +177,8 @@ BOOST_AUTO_TEST_CASE(GenerateSegmentVertices) { {rx, ry}, minPhi, maxPhi, {}, quarterVertices); // Extrema will be covered by the segments expectedVertices = - static_cast((maxPhi - minPhi) / M_PI_2 * quarterVertices) + + static_cast((maxPhi - minPhi) / (std::numbers::pi / 2.) * + quarterVertices) + 2u; BOOST_CHECK_EQUAL(vertices.size(), expectedVertices); } @@ -186,7 +189,8 @@ BOOST_AUTO_TEST_CASE(GenerateCircleEllipseVertices) { ActsScalar ro = 10.; // Extreme points in phi - only outer radius - auto vertices = VerticesHelper::circularVertices(ri, ro, 0., M_PI, 1u); + auto vertices = + VerticesHelper::circularVertices(ri, ro, 0., std::numbers::pi, 1u); unsigned int expectedVertices = 5u; BOOST_CHECK_EQUAL(vertices.size(), expectedVertices); @@ -194,21 +198,23 @@ BOOST_AUTO_TEST_CASE(GenerateCircleEllipseVertices) { ri = 3.; // Extreme points in phi - only outer radius - vertices = VerticesHelper::circularVertices(ri, ro, 0., M_PI, 1u); + vertices = VerticesHelper::circularVertices(ri, ro, 0., std::numbers::pi, 1u); expectedVertices = 10u; BOOST_CHECK_EQUAL(vertices.size(), expectedVertices); // Now with 10 bins per sector ri = 0.; - vertices = VerticesHelper::circularVertices(ri, ro, 0., M_PI, 10u); + vertices = + VerticesHelper::circularVertices(ri, ro, 0., std::numbers::pi, 10u); expectedVertices = 41u; // 4 sectors + 1 overlap at (-pi/pi) BOOST_CHECK_EQUAL(vertices.size(), expectedVertices); - // Now ellipsiod + // Now ellipsoid ActsScalar riy = 4.; ActsScalar roy = 14.; - vertices = VerticesHelper::ellipsoidVertices(ri, riy, ro, roy, 0., M_PI, 10u); + vertices = VerticesHelper::ellipsoidVertices(ri, riy, ro, roy, 0., + std::numbers::pi, 10u); expectedVertices = 41u; // 4 sectors + 1 overlap at (-pi/pi) BOOST_CHECK_EQUAL(vertices.size(), expectedVertices); } diff --git a/Tests/UnitTests/Core/TrackFitting/FitterTestsCommon.hpp b/Tests/UnitTests/Core/TrackFitting/FitterTestsCommon.hpp index 6692974ef63..269370d4fc4 100644 --- a/Tests/UnitTests/Core/TrackFitting/FitterTestsCommon.hpp +++ b/Tests/UnitTests/Core/TrackFitting/FitterTestsCommon.hpp @@ -77,7 +77,7 @@ struct TestReverseFilteringLogic { template bool operator()(typename traj_t::ConstTrackStateProxy state) const { // can't determine an outlier w/o a measurement or predicted parameters - auto momentum = fabs(1 / state.filtered()[Acts::eBoundQOverP]); + auto momentum = std::abs(1 / state.filtered()[Acts::eBoundQOverP]); std::cout << "momentum : " << momentum << std::endl; return (momentum <= momentumMax); } diff --git a/Tests/UnitTests/Core/Vertexing/ImpactPointEstimatorTests.cpp b/Tests/UnitTests/Core/Vertexing/ImpactPointEstimatorTests.cpp index c9743e90d7f..279f2c1a739 100644 --- a/Tests/UnitTests/Core/Vertexing/ImpactPointEstimatorTests.cpp +++ b/Tests/UnitTests/Core/Vertexing/ImpactPointEstimatorTests.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -371,6 +372,9 @@ BOOST_DATA_TEST_CASE(VertexCompatibility4D, IPs* vertices, d0, l0, vx0, vy0, BoundVector paramVecClose = BoundVector::Zero(); paramVecClose[eBoundLoc0] = d0; paramVecClose[eBoundLoc1] = l0; + paramVecClose[eBoundPhi] = 0; + paramVecClose[eBoundTheta] = std::numbers::pi / 2; + paramVecClose[eBoundQOverP] = 0; paramVecClose[eBoundTime] = vt0 + sgnClose * timeDiffClose; BoundVector paramVecFar = paramVecClose; diff --git a/Tests/UnitTests/Core/Vertexing/SingleSeedVertexFinderTests.cpp b/Tests/UnitTests/Core/Vertexing/SingleSeedVertexFinderTests.cpp index 95ba93c0efb..7be7e174e6a 100644 --- a/Tests/UnitTests/Core/Vertexing/SingleSeedVertexFinderTests.cpp +++ b/Tests/UnitTests/Core/Vertexing/SingleSeedVertexFinderTests.cpp @@ -294,10 +294,10 @@ BOOST_AUTO_TEST_CASE(single_seed_vertex_finder_full_planes_test) { double x1 = (D * dirY + sgn * dirX * std::sqrt(r * r * dirR2 - D * D)) / dirR2; double y1 = - (-D * dirX + std::fabs(dirY) * std::sqrt(r * r * dirR2 - D * D)) / + (-D * dirX + std::abs(dirY) * std::sqrt(r * r * dirR2 - D * D)) / dirR2; // how many units from the vertex to the intersection - double zDist = std::fabs((x1 - posX) / dirX); + double zDist = std::abs((x1 - posX) / dirX); // position of the new spacepoint posX = x1; @@ -411,11 +411,11 @@ BOOST_AUTO_TEST_CASE(single_seed_vertex_finder_full_rays_test) { double x1 = (D * dirY + part * sgn * dirX * std::sqrt(r * r * dirR2 - D * D)) / dirR2; - double y1 = (-D * dirX + part * std::fabs(dirY) * - std::sqrt(r * r * dirR2 - D * D)) / + double y1 = (-D * dirX + + part * std::abs(dirY) * std::sqrt(r * r * dirR2 - D * D)) / dirR2; // how many units from the vertex to the intersection - double zDist = std::fabs((x1 - vtxX) / dirX); + double zDist = std::abs((x1 - vtxX) / dirX); // use the same amount of units for distance in Z inputSpacepoints.emplace_back(x1, y1, zDist * dirZ + vtxZ); } diff --git a/Tests/UnitTests/Examples/EventData/MeasurementTests.cpp b/Tests/UnitTests/Examples/EventData/MeasurementTests.cpp index d59ff4a135e..2428aa2429f 100644 --- a/Tests/UnitTests/Examples/EventData/MeasurementTests.cpp +++ b/Tests/UnitTests/Examples/EventData/MeasurementTests.cpp @@ -85,7 +85,8 @@ BOOST_DATA_TEST_CASE(VariableBoundOneEmplace, bd::make(boundIndices), index) { BOOST_AUTO_TEST_CASE(VariableBoundAll) { MeasurementContainer container; - auto [params, cov] = generateBoundParametersCovariance(rng); + auto [params, cov] = + generateParametersCovariance(rng); FixedBoundMeasurementProxy meas = container.makeMeasurement(geoId); @@ -106,7 +107,8 @@ BOOST_AUTO_TEST_CASE(VariableBoundAll) { BOOST_AUTO_TEST_CASE(VariableBoundAllEmplace) { MeasurementContainer container; - auto [params, cov] = generateBoundParametersCovariance(rng); + auto [params, cov] = + generateParametersCovariance(rng); FixedBoundMeasurementProxy meas = container.emplaceMeasurement( @@ -144,7 +146,8 @@ BOOST_AUTO_TEST_CASE(VariableBoundReassign) { BOOST_CHECK(!meas.contains(eBoundQOverP)); // reassign w/ all parameters - auto [paramsN, covN] = generateBoundParametersCovariance(rng); + auto [paramsN, covN] = + generateParametersCovariance(rng); meas = container.makeMeasurement(eBoundSize, geoId); meas.setSubspaceIndices(std::array{eBoundLoc0, eBoundLoc1, eBoundTime, diff --git a/Tests/UnitTests/Examples/Io/Json/JsonDigitizationConfigTests.cpp b/Tests/UnitTests/Examples/Io/Json/JsonDigitizationConfigTests.cpp index ab30e2a98f0..f7c1db0f496 100644 --- a/Tests/UnitTests/Examples/Io/Json/JsonDigitizationConfigTests.cpp +++ b/Tests/UnitTests/Examples/Io/Json/JsonDigitizationConfigTests.cpp @@ -57,7 +57,7 @@ struct Fixture { // generate random track parameters auto [par, cov] = - Acts::detail::Test::generateBoundParametersCovariance(rng); + Acts::detail::Test::generateBoundParametersCovariance(rng, {}); boundParams = par; freeParams = diff --git a/Tests/UnitTests/Fatras/Digitization/UncorrelatedHitSmearerTests.cpp b/Tests/UnitTests/Fatras/Digitization/UncorrelatedHitSmearerTests.cpp index e4fde7f3b2d..2a4ad0b2a6e 100644 --- a/Tests/UnitTests/Fatras/Digitization/UncorrelatedHitSmearerTests.cpp +++ b/Tests/UnitTests/Fatras/Digitization/UncorrelatedHitSmearerTests.cpp @@ -96,7 +96,7 @@ struct Fixture { // generate random track parameters auto [par, cov] = - Acts::detail::Test::generateBoundParametersCovariance(rng); + Acts::detail::Test::generateBoundParametersCovariance(rng, {}); boundParams = par; freeParams = diff --git a/Tests/UnitTests/Plugins/GeoModel/GeoDetectorObjectTest.cpp b/Tests/UnitTests/Plugins/GeoModel/GeoDetectorObjectTest.cpp index f281c7c1095..033f2c9cb4a 100644 --- a/Tests/UnitTests/Plugins/GeoModel/GeoDetectorObjectTest.cpp +++ b/Tests/UnitTests/Plugins/GeoModel/GeoDetectorObjectTest.cpp @@ -101,9 +101,9 @@ GeoGeometry constructGeoModel() { {123, 50}, {-123, 50}, {-153, 0}}; geoDims.tube = {5, 6, 100}; geoDims.trapHls = { - fabs(geoDims.trapVerts[0][0] - geoDims.trapVerts[1][0]) / 2, - fabs(geoDims.trapVerts[2][0] - geoDims.trapVerts[3][0]) / 2, - fabs(geoDims.trapVerts[0][1] - geoDims.trapVerts[2][1]) / 2}; + std::abs(geoDims.trapVerts[0][0] - geoDims.trapVerts[1][0]) / 2, + std::abs(geoDims.trapVerts[2][0] - geoDims.trapVerts[3][0]) / 2, + std::abs(geoDims.trapVerts[0][1] - geoDims.trapVerts[2][1]) / 2}; // create shapes GeoIntrusivePtr boxXY( diff --git a/Tests/UnitTests/Plugins/Json/TrackParametersJsonConverterTests.cpp b/Tests/UnitTests/Plugins/Json/TrackParametersJsonConverterTests.cpp index 566464a1889..5c0882cb12c 100644 --- a/Tests/UnitTests/Plugins/Json/TrackParametersJsonConverterTests.cpp +++ b/Tests/UnitTests/Plugins/Json/TrackParametersJsonConverterTests.cpp @@ -8,12 +8,12 @@ #include +#include "Acts/EventData/ParticleHypothesis.hpp" +#include "Acts/EventData/TrackParameters.hpp" #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 diff --git a/cmake/ActsConfig.cmake.in b/cmake/ActsConfig.cmake.in index 7ed4b3884a5..97d510f1319 100644 --- a/cmake/ActsConfig.cmake.in +++ b/cmake/ActsConfig.cmake.in @@ -52,9 +52,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/Modules) # `find_dependency` is a wrapper around `find_package` that automatically # handles QUIET and REQUIRED parameters. include(CMakeFindDependencyMacro) -if(@ACTS_USE_SYSTEM_BOOST@) - find_dependency(Boost @Boost_VERSION_STRING@ CONFIG EXACT) -endif() +find_dependency(Boost @Boost_VERSION_STRING@ CONFIG EXACT) if(@ACTS_USE_SYSTEM_EIGEN3@) find_dependency(Eigen3 @Eigen3_VERSION@ CONFIG EXACT) endif() @@ -86,10 +84,6 @@ endif() # dependencies that we have built ourselves but cannot be # straightforwardly handed to cmake -if(NOT @ACTS_USE_SYSTEM_BOOST@) - add_library(Boost::boost INTERFACE IMPORTED GLOBAL) - target_include_directories(Boost::boost INTERFACE "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}") -endif() if(NOT @ACTS_USE_SYSTEM_EIGEN3@) add_library(Eigen3::Eigen INTERFACE IMPORTED GLOBAL) target_include_directories(Eigen3::Eigen INTERFACE "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}") diff --git a/docs/getting_started.md b/docs/getting_started.md index f17ec5abcf1..aff8e38a3b0 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -301,7 +301,6 @@ components. | ACTS_BUILD_EXAMPLES_HASHING | Build Hashing-based code in the examples
type: `bool`, default: `OFF` | | ACTS_BUILD_EXAMPLES_PYTHIA8 | Build Pythia8-based code in the examples
type: `bool`, default: `OFF` | | ACTS_BUILD_EXAMPLES_PYTHON_BINDINGS | Build python bindings for the examples
type: `bool`, default: `OFF` | -| ACTS_USE_EXAMPLES_TBB | Use Threading Building Blocks library in
the examples
type: `bool`, default: `ON` | | ACTS_BUILD_ANALYSIS_APPS | Build Analysis applications in the
examples
type: `bool`, default: `OFF` | | ACTS_BUILD_BENCHMARKS | Build benchmarks
type: `bool`, default: `OFF` | | ACTS_BUILD_INTEGRATIONTESTS | Build integration tests
type: `bool`, default: `OFF` | diff --git a/thirdparty/README.md b/thirdparty/README.md index bd271826e1c..243479db0aa 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -17,9 +17,7 @@ CMake instructions to build [nlohmann::json](https://github.com/nlohmann/json). ## boost For convenience, it's possible to use the ACTS build system to build the minimum -required version of [boost](https://www.boost.org/) (currently 1.71.0). No source is -bundled here, and if requested via "-DACTS_USE_SYSTEM_BOOST=OFF", only the filesystem, -program_options, and test libraries will be built. +required version of [boost](https://www.boost.org/) (currently 1.71.0). Warning: during installation, the built boost libraries will be installed alongside the ACTS libraries, with a version suffix. This location may be known to the system linker.